diff --git a/_maps/RandomZLevels/blackmarketpackers.dmm b/_maps/RandomZLevels/blackmarketpackers.dmm index 12f9ed60419..4b869922bd8 100644 --- a/_maps/RandomZLevels/blackmarketpackers.dmm +++ b/_maps/RandomZLevels/blackmarketpackers.dmm @@ -32,7 +32,7 @@ "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) -"aI" = (/obj/item/weapon/handcuffs,/obj/item/weapon/handcuffs,/obj/structure/closet/crate,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) +"aI" = (/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/restraints/handcuffs,/obj/structure/closet/crate,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "aJ" = (/obj/item/weapon/scalpel,/obj/structure/closet/crate,/obj/item/weapon/tank/anesthetic,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "aK" = (/obj/item/bodybag,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "aL" = (/obj/item/weapon/storage/box/syringes,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) diff --git a/_maps/RandomZLevels/centcomAway.dmm b/_maps/RandomZLevels/centcomAway.dmm index bacbe6b4aa9..6d922312984 100644 --- a/_maps/RandomZLevels/centcomAway.dmm +++ b/_maps/RandomZLevels/centcomAway.dmm @@ -591,7 +591,7 @@ "ls" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/awaymission/centcomAway/thunderdome) "lt" = (/obj/structure/stool/bed/chair,/turf/simulated/floor{tag = "icon-redbluefull (WEST)"; icon_state = "redbluefull"; dir = 8},/area/awaymission/centcomAway/thunderdome) "lu" = (/turf/simulated/floor{dir = 8; icon_state = "red"},/area/awaymission/centcomAway/thunderdome) -"lv" = (/obj/structure/rack,/obj/item/weapon/legcuffs/beartrap,/obj/item/weapon/twohanded/fireaxe,/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/thunderdome) +"lv" = (/obj/structure/rack,/obj/item/weapon/restraints/legcuffs/beartrap,/obj/item/weapon/twohanded/fireaxe,/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/thunderdome) "lw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/awaymission/centcomAway/thunderdome) "lx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/awaymission/centcomAway/thunderdome) "ly" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/awaymission/centcomAway/thunderdome) diff --git a/_maps/RandomZLevels/moonoutpost19.dmm b/_maps/RandomZLevels/moonoutpost19.dmm index 9c6f4f43367..b9a24574087 100644 --- a/_maps/RandomZLevels/moonoutpost19.dmm +++ b/_maps/RandomZLevels/moonoutpost19.dmm @@ -29,7 +29,7 @@ "aC" = (/turf/simulated/floor{dir = 4; heat_capacity = 1e+006; icon_state = "darkredcorners"; tag = "icon-darkredcorners (EAST)"},/area/awaycontent/a4{name = "Syndicate Outpost"}) "aD" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 5; heat_capacity = 1e+006; icon_state = "darkred"; tag = "icon-darkred (NORTHEAST)"},/area/awaycontent/a4{name = "Syndicate Outpost"}) "aE" = (/obj/structure/alien/weeds/node,/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored) -"aF" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/gibs,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/obj/item/clothing/under/rank/security/science,/obj/item/clothing/suit/armor/vest,/obj/item/weapon/melee/baton/loaded,/obj/item/clothing/head/helmet,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored) +"aF" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/gibs,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/obj/item/clothing/under/rank/security,/obj/item/clothing/suit/armor/vest,/obj/item/weapon/melee/baton/loaded,/obj/item/clothing/head/helmet,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored) "aG" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "darkredcorners"; tag = "icon-darkredcorners (NORTH)"},/area/awaycontent/a4{name = "Syndicate Outpost"}) "aH" = (/obj/machinery/gateway{dir = 9},/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{name = "Syndicate Outpost"}) "aI" = (/obj/machinery/gateway{dir = 1},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{name = "Syndicate Outpost"}) diff --git a/_maps/RandomZLevels/spacebattle.dmm b/_maps/RandomZLevels/spacebattle.dmm index 2bc373f7cf5..e7293b97535 100644 --- a/_maps/RandomZLevels/spacebattle.dmm +++ b/_maps/RandomZLevels/spacebattle.dmm @@ -64,15 +64,15 @@ "bl" = (/obj/structure/table/reinforced,/obj/item/clothing/head/helmet/swat,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate3) "bm" = (/obj/machinery/computer/pod{id = "spacebattlepod3"; name = "Hull Door Control"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate2) "bn" = (/obj/machinery/door/poddoor{icon_state = "pdoor1"; id = "spacebattlepod3"; name = "Front Hull Door"; opacity = 1},/turf/simulated/shuttle/plating,/area/awaymission/spacebattle/syndicate2) -"bo" = (/obj/structure/table/reinforced,/obj/item/weapon/plastique,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate3) +"bo" = (/obj/structure/table/reinforced,/obj/item/weapon/c4,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate3) "bp" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate1) -"bq" = (/obj/structure/table/reinforced,/obj/item/weapon/plastique,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate1) +"bq" = (/obj/structure/table/reinforced,/obj/item/weapon/c4,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate1) "br" = (/obj/structure/table/reinforced,/obj/item/weapon/grenade/spawnergrenade/manhacks,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate1) -"bs" = (/obj/structure/table/reinforced,/obj/item/weapon/handcuffs,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate1) +"bs" = (/obj/structure/table/reinforced,/obj/item/weapon/restraints/handcuffs,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate1) "bt" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/awaymission/spacebattle/syndicate3) "bu" = (/obj/structure/stool/bed/chair,/mob/living/simple_animal/hostile/syndicate,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate3) "bv" = (/turf/space,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/awaymission/spacebattle/syndicate3) -"bw" = (/obj/structure/table/reinforced,/obj/item/weapon/melee/energy/sword/red,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate1) +"bw" = (/obj/structure/table/reinforced,/obj/item/weapon/melee/energy/sword/saber/red,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate1) "bx" = (/obj/machinery/computer/shuttle,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate3) "by" = (/turf/simulated/shuttle/floor{icon_state = "floor4"},/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/awaymission/spacebattle/syndicate3) "bz" = (/turf/simulated/shuttle/floor{icon_state = "floor4"},/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/awaymission/spacebattle/syndicate3) @@ -257,7 +257,7 @@ "eW" = (/obj/structure/closet/crate,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) "eX" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/food/condiment/saltshaker,/turf/simulated/floor{icon_state = "bar"},/area/awaymission/spacebattle/cruiser) "eY" = (/obj/structure/table/reinforced,/obj/item/weapon/kitchen/utensil/fork,/turf/simulated/floor{icon_state = "bar"},/area/awaymission/spacebattle/cruiser) -"eZ" = (/obj/effect/landmark/corpse/syndicatesoldier,/obj/item/weapon/melee/energy/sword/red,/obj/effect/decal/cleanable/blood,/turf/simulated/floor,/area/awaymission/spacebattle/cruiser) +"eZ" = (/obj/effect/landmark/corpse/syndicatesoldier,/obj/item/weapon/melee/energy/sword/saber/red,/obj/effect/decal/cleanable/blood,/turf/simulated/floor,/area/awaymission/spacebattle/cruiser) "fa" = (/obj/effect/landmark/corpse/bridgeofficer{mobname = "Kurt Kliest"; name = "Kurt Kliest"},/obj/item/weapon/gun/projectile/shotgun/combat,/obj/item/ammo_casing/shotgun,/turf/simulated/floor,/area/awaymission/spacebattle/cruiser) "fb" = (/obj/item/ammo_casing/shotgun,/obj/effect/decal/cleanable/blood,/turf/simulated/floor,/area/awaymission/spacebattle/cruiser) "fc" = (/obj/machinery/computer/crew,/turf/simulated/floor{tag = "icon-bluefull"; icon_state = "bluefull"},/area/awaymission/spacebattle/cruiser) @@ -359,7 +359,7 @@ "gU" = (/turf/space,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/awaymission/spacebattle/syndicate7) "gV" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/awaymission/spacebattle/syndicate4) "gW" = (/obj/structure/reagent_dispensers/beerkeg,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) -"gX" = (/obj/item/weapon/ore/clown,/obj/item/weapon/ore/clown,/obj/item/weapon/ore/clown,/obj/item/weapon/ore/clown,/obj/item/weapon/ore/clown,/obj/structure/closet/crate,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) +"gX" = (/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,/obj/structure/closet/crate,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) "gY" = (/obj/machinery/computer/operating,/turf/simulated/floor{icon_state = "white"},/area/awaymission/spacebattle/cruiser) "gZ" = (/obj/effect/landmark/corpse/doctor{mobname = "Allan Yoshimaru"; name = "Allan Yoshimaru"},/obj/effect/decal/cleanable/blood,/turf/simulated/floor{icon_state = "white"},/area/awaymission/spacebattle/cruiser) "ha" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor{icon_state = "white"},/area/awaymission/spacebattle/cruiser) diff --git a/_maps/RandomZLevels/spacehotel.dmm b/_maps/RandomZLevels/spacehotel.dmm index 37119d795d7..bbd30554a64 100644 --- a/_maps/RandomZLevels/spacehotel.dmm +++ b/_maps/RandomZLevels/spacehotel.dmm @@ -229,7 +229,7 @@ "eu" = (/obj/structure/rack,/obj/item/key,/obj/item/key,/obj/item/key,/obj/item/key,/obj/item/key,/turf/simulated/floor/carpet,/area/awaymission) "ev" = (/obj/structure/stool/bed/chair/comfy,/obj/effect/decal/cleanable/flour{desc = "Probably."},/obj/effect/decal/cleanable/pie_smudge,/turf/simulated/floor/carpet,/area/awaymission) "ew" = (/obj/structure/stool/bed/chair/comfy,/obj/effect/decal/cleanable/flour{desc = "Probably."},/obj/effect/decal/cleanable/flour{desc = "Probably."},/obj/effect/decal/cleanable/pie_smudge,/turf/simulated/floor/carpet,/area/awaymission) -"ex" = (/obj/item/weapon/legcuffs,/turf/simulated/floor/engine/cult,/area/awaymission) +"ex" = (/obj/item/weapon/restraints/legcuffs,/turf/simulated/floor/engine/cult,/area/awaymission) "ey" = (/obj/machinery/space_heater,/turf/simulated/floor/carpet,/area/awaymission) "ez" = (/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/awaymission) "eA" = (/obj/structure/table,/obj/machinery/computer/security/telescreen{desc = "Not used to spy on hotel rooms."; dir = 1; network = "Hotel"; use_power = 0},/turf/simulated/floor/carpet,/area/awaymission) diff --git a/_maps/RandomZLevels/stationCollision.dmm b/_maps/RandomZLevels/stationCollision.dmm index 878dbb8e934..72197b4a527 100644 --- a/_maps/RandomZLevels/stationCollision.dmm +++ b/_maps/RandomZLevels/stationCollision.dmm @@ -362,7 +362,7 @@ "gX" = (/obj/effect/decal/remains/human,/turf/simulated/floor{tag = "icon-warningcorner (NORTH)"; icon_state = "warningcorner"; dir = 1},/area/awaymission/arrivalblock) "gY" = (/obj/machinery/computer/security,/turf/simulated/floor{icon_state = "red"; dir = 9},/area/awaymission/arrivalblock) "gZ" = (/obj/machinery/computer/secure_data,/turf/simulated/floor{icon_state = "red"; dir = 1},/area/awaymission/arrivalblock) -"ha" = (/obj/structure/table,/obj/item/weapon/book/manual/wiki/security_space_law,/obj/item/weapon/melee/baton,/obj/item/clothing/head/helmet/warden,/turf/simulated/floor{icon_state = "red"; dir = 1},/area/awaymission/arrivalblock) +"ha" = (/obj/structure/table,/obj/item/weapon/book/manual/wiki/security_space_law,/obj/item/weapon/melee/baton,/obj/item/clothing/head/warden,/turf/simulated/floor{icon_state = "red"; dir = 1},/area/awaymission/arrivalblock) "hb" = (/obj/structure/closet/wardrobe/red,/obj/machinery/light{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/awaymission/arrivalblock) "hc" = (/obj/structure/closet/secure_closet/security,/turf/simulated/floor{icon_state = "red"; dir = 1},/area/awaymission/arrivalblock) "hd" = (/obj/structure/closet/secure_closet/security,/turf/simulated/floor{icon_state = "red"; dir = 5},/area/awaymission/arrivalblock) @@ -400,7 +400,7 @@ "hJ" = (/turf/simulated/floor{icon_state = "red"; dir = 8},/area/awaymission/arrivalblock) "hK" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor,/area/awaymission/arrivalblock) "hL" = (/obj/structure/table,/obj/item/weapon/storage/fancy/donut_box,/turf/simulated/floor,/area/awaymission/arrivalblock) -"hM" = (/obj/structure/table,/obj/item/weapon/handcuffs,/obj/item/device/flash,/turf/simulated/floor,/area/awaymission/arrivalblock) +"hM" = (/obj/structure/table,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flash,/turf/simulated/floor,/area/awaymission/arrivalblock) "hN" = (/turf/simulated/floor{icon_state = "red"; dir = 4},/area/awaymission/arrivalblock) "hO" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/blue,/obj/effect/decal/remains/human,/turf/simulated/floor,/area/awaymission/midblock) "hP" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/purple,/turf/simulated/floor,/area/awaymission/midblock) @@ -557,7 +557,7 @@ "kK" = (/obj/machinery/vending/hydronutrients,/turf/simulated/floor,/area/awaymission/arrivalblock) "kL" = (/obj/machinery/vending/hydroseeds,/turf/simulated/floor,/area/awaymission/arrivalblock) "kM" = (/obj/structure/sink/kitchen{pixel_y = 32},/turf/simulated/floor,/area/awaymission/arrivalblock) -"kN" = (/obj/item/weapon/melee/energy/sword/red,/obj/item/clothing/shoes/syndigaloshes,/obj/item/clothing/under/syndicate,/obj/effect/decal/remains/human{desc = "This guy seemed to have died in terrible way! Half his remains are dust."; icon_state = "remains"; name = "Syndicate agent remains"},/obj/item/weapon/paper/sc_safehint_paper_hydro,/turf/simulated/floor,/area/awaymission/arrivalblock) +"kN" = (/obj/item/weapon/melee/energy/sword/saber/red,/obj/item/clothing/shoes/syndigaloshes,/obj/item/clothing/under/syndicate,/obj/effect/decal/remains/human{desc = "This guy seemed to have died in terrible way! Half his remains are dust."; icon_state = "remains"; name = "Syndicate agent remains"},/obj/item/weapon/paper/sc_safehint_paper_hydro,/turf/simulated/floor,/area/awaymission/arrivalblock) "kO" = (/obj/machinery/hydroponics,/turf/simulated/floor,/area/awaymission/arrivalblock) "kP" = (/obj/structure/morgue,/turf/simulated/floor{icon_state = "white"},/area/awaymission/southblock) "kQ" = (/obj/machinery/vending/medical,/turf/simulated/floor{icon_state = "white"},/area/awaymission/southblock) diff --git a/_maps/map_files/MetaStation.v39K.dmm b/_maps/map_files/MetaStation.v39K.dmm index de4bcd71301..19460c3ab6b 100644 --- a/_maps/map_files/MetaStation.v39K.dmm +++ b/_maps/map_files/MetaStation.v39K.dmm @@ -339,7 +339,7 @@ "agA" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor{dir = 8; icon_state = "whiteredcorner"},/area/security/brig) "agB" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Firing Range"; req_access_txt = "0"; req_one_access_txt = "1;4"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/security/range) "agC" = (/turf/simulated/wall,/area/engine/gravity_generator) -"agD" = (/obj/structure/table,/obj/item/weapon/folder/red,/obj/item/weapon/book/manual/wiki/security_space_law{pixel_x = -3; pixel_y = 5},/obj/item/weapon/packageWrap,/turf/simulated/floor,/area/security/main) +"agD" = (/obj/structure/table,/obj/item/weapon/folder/red,/obj/item/weapon/book/manual/wiki/security_space_law{pixel_x = -3; pixel_y = 5},/obj/item/stack/packageWrap,/turf/simulated/floor,/area/security/main) "agE" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 9},/turf/simulated/floor{dir = 8; icon_state = "neutralcorner"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) "agF" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5},/turf/simulated/floor{dir = 8; icon_state = "neutralcorner"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) "agG" = (/turf/simulated/floor{dir = 4; icon_state = "neutralcorner"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) @@ -721,7 +721,7 @@ "anS" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/flasher_button{id = "holdingflash"; pixel_x = 0; pixel_y = -26; req_access_txt = "1"},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/brig) "anT" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/engine/engineering) "anU" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor,/area/engine/engineering) -"anV" = (/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/wrench,/obj/machinery/light{dir = 8},/obj/item/weapon/hand_labeler,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/engine/engineering) +"anV" = (/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/weapon/wrench,/obj/machinery/light{dir = 8},/obj/item/weapon/hand_labeler,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/engine/engineering) "anW" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/door/airlock/glass_security{name = "Prison Wing"; req_access_txt = "1"},/turf/simulated/floor{icon_state = "red"},/area/security/brig) "anX" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/starboard) "anY" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor{tag = "icon-vault"; icon_state = "vault"},/area/security/main) @@ -1477,7 +1477,7 @@ "aCu" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/machinery/power/apc{dir = 2; name = "Storage Wing APC"; pixel_x = 0; pixel_y = -27},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{dir = 4; icon_state = "browncorner"},/area/construction/Storage{name = "Storage Wing"}) "aCv" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/carpet,/area/security/hos) "aCw" = (/obj/structure/table/woodentable,/obj/item/weapon/stamp/hos,/turf/simulated/floor/carpet,/area/security/hos) -"aCx" = (/obj/structure/rack,/obj/item/weapon/shield/riot{pixel_x = -3; pixel_y = 3},/obj/item/weapon/shield/riot,/obj/item/weapon/shield/riot{pixel_x = 3; pixel_y = -3},/obj/item/weapon/gun/projectile/shotgun/sc_pump{name = "riot shotgun"; pixel_x = 4; pixel_y = -3},/obj/item/weapon/gun/projectile/shotgun/sc_pump{name = "riot shotgun"; pixel_x = -2; pixel_y = 3},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/security/warden) +"aCx" = (/obj/structure/rack,/obj/item/weapon/shield/riot{pixel_x = -3; pixel_y = 3},/obj/item/weapon/shield/riot,/obj/item/weapon/shield/riot{pixel_x = 3; pixel_y = -3},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/item/weapon/gun/projectile/shotgun/riot{pixel_x = 3; pixel_y = 3},/obj/item/weapon/gun/projectile/shotgun/riot,/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/security/warden) "aCy" = (/obj/structure/closet/crate/internals,/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/sorting{name = "\improper Warehouse"}) "aCz" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/door/poddoor{density = 0; icon_state = "open"; id = "Prison Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/security/brig) "aCA" = (/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/security/range) @@ -1809,7 +1809,7 @@ "aIO" = (/obj/structure/disposalpipe/segment,/obj/machinery/hologram/holopad,/turf/simulated/floor{dir = 2; icon_state = "brown"},/area/quartermaster/office{name = "\improper Cargo Office"}) "aIP" = (/obj/item/weapon/storage/box/lights/mixed,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/hallway/primary/central) "aIQ" = (/obj/structure/closet{name = "Contraband Locker"},/obj/item/weapon/contraband/poster,/obj/item/weapon/contraband/poster,/obj/item/weapon/contraband/poster,/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap,/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/reishi,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus,/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom,/obj/item/weapon/suppressor,/obj/effect/spawner/lootdrop/armory_contraband,/turf/simulated/floor{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/security/warden) -"aIR" = (/obj/structure/table,/obj/item/weapon/wrapping_paper,/obj/item/weapon/wrapping_paper,/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_y = -30},/obj/item/weapon/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/weapon/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/weapon/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/weapon/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/weapon/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/weapon/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/weapon/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/weapon/packageWrap{pixel_x = 2; pixel_y = -3},/turf/simulated/floor{dir = 2; icon_state = "arrival"},/area/quartermaster/office{name = "\improper Cargo Office"}) +"aIR" = (/obj/structure/table,/obj/item/stack/wrapping_paper,/obj/item/stack/wrapping_paper,/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_y = -30},/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/turf/simulated/floor{dir = 2; icon_state = "arrival"},/area/quartermaster/office{name = "\improper Cargo Office"}) "aIS" = (/obj/item/weapon/storage/box,/obj/structure/table,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/item/weapon/hand_labeler,/turf/simulated/floor{icon_state = "arrival"; dir = 6},/area/quartermaster/office{name = "\improper Cargo Office"}) "aIT" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "L10"},/area/hallway/primary/central) "aIU" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -30},/turf/simulated/floor{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/starboard) @@ -1901,7 +1901,7 @@ "aKC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/disposal) "aKD" = (/obj/structure/table,/obj/item/device/toner,/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/floor{dir = 6; icon_state = "brown"},/area/hallway/primary/port) "aKE" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/door/firedoor,/turf/simulated/floor{dir = 1; icon_state = "neutralcorner"},/area/hallway/primary/central) -"aKF" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 9; pixel_y = 0},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/weapon/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/weapon/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/weapon/hand_labeler,/turf/simulated/floor{dir = 2; icon_state = "brown"},/area/hallway/primary/port) +"aKF" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 9; pixel_y = 0},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/weapon/hand_labeler,/turf/simulated/floor{dir = 2; icon_state = "brown"},/area/hallway/primary/port) "aKG" = (/obj/effect/decal/cleanable/cobweb2,/obj/structure/table,/obj/item/weapon/stock_parts/manipulator,/turf/simulated/floor/plating,/area/maintenance/fore) "aKH" = (/obj/structure/closet/crate{icon_state = "crateopen"; opened = 1},/turf/simulated/floor{dir = 10; icon_state = "brown"},/area/hallway/primary/port) "aKI" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{dir = 2; icon_state = "browncorner"},/area/hallway/primary/port) @@ -2242,7 +2242,7 @@ "aRf" = (/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engine/engineering) "aRg" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engine/engineering) "aRh" = (/obj/machinery/power/apc{dir = 8; name = "Engineering Security APC"; pixel_x = -24},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/checkpoint/engineering) -"aRi" = (/obj/item/weapon/hand_labeler,/obj/item/weapon/packageWrap,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table,/turf/simulated/floor{tag = "icon-darkblue"; icon_state = "darkblue"; dir = 0},/area/crew_quarters/heads) +"aRi" = (/obj/item/weapon/hand_labeler,/obj/item/stack/packageWrap,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table,/turf/simulated/floor{tag = "icon-darkblue"; icon_state = "darkblue"; dir = 0},/area/crew_quarters/heads) "aRj" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/security/checkpoint/engineering) "aRk" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{req_access_txt = 1},/turf/simulated/floor{dir = 4; icon_state = "neutralcorner"},/area/hallway/primary/central) "aRl" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) @@ -2979,7 +2979,7 @@ "bfo" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/floor{tag = "icon-warningcorner (NORTH)"; icon_state = "warningcorner"; dir = 1},/area/engine/break_room) "bfp" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{icon_state = "bot"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) "bfq" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/turf/simulated/floor{icon_state = "warning"},/area/engine/break_room) -"bfr" = (/obj/structure/table/woodentable,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/gun/projectile/revolver/doublebarrel,/turf/simulated/floor/wood,/area/crew_quarters/bar{name = "\improper Maltese Falcon"}) +"bfr" = (/obj/structure/table/woodentable,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/weapon/gun/projectile/revolver/doublebarrel,/turf/simulated/floor/wood,/area/crew_quarters/bar{name = "\improper Maltese Falcon"}) "bfs" = (/obj/machinery/door/airlock/hatch{icon_state = "door_closed"; name = "MiniSat West Wing"; req_one_access_txt = "32;19"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/turret_protected/tcomwest{name = "\improper MiniSat West Wing"}) "bft" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "QM #3"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/bot/mulebot{home_destination = "QM #3"; suffix = "#3"},/turf/simulated/floor{icon_state = "delivery"},/area/quartermaster/storage) "bfu" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor,/area/hallway/primary/port) @@ -3962,7 +3962,7 @@ "byj" = (/obj/structure/window/reinforced{dir = 1; pixel_y = 1},/obj/structure/closet/crate/internals,/turf/simulated/floor{icon_state = "delivery"},/area/storage/primary) "byk" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 8},/turf/simulated/floor{dir = 8; icon_state = "yellow"},/area/hallway/primary/aft) "byl" = (/obj/structure/table,/obj/item/weapon/airlock_painter,/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/engine/engineering) -"bym" = (/obj/machinery/light{dir = 4},/obj/structure/reagent_dispensers/peppertank{pixel_x = 30; pixel_y = 0},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 29},/obj/structure/closet/wardrobe/hos,/turf/simulated/floor{icon_state = "dark"},/area/security/hos) +"bym" = (/obj/machinery/light{dir = 4},/obj/structure/reagent_dispensers/peppertank{pixel_x = 30; pixel_y = 0},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 29},/turf/simulated/floor{icon_state = "dark"},/area/security/hos) "byn" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/fore) "byo" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor,/area/engine/engineering) "byp" = (/turf/simulated/floor{tag = "icon-warningcorner (NORTH)"; icon_state = "warningcorner"; dir = 1},/area/engine/engineering) @@ -4031,7 +4031,7 @@ "bzA" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=4"; freq = 1400; location = "Tool Storage"},/turf/simulated/floor{icon_state = "delivery"},/area/storage/primary) "bzB" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 8},/obj/structure/disposalpipe/segment,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/shower{dir = 4},/turf/simulated/floor{dir = 10; icon_state = "warnwhite"},/area/medical/research{name = "Research Division"}) "bzC" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/wood,/area/lawoffice) -"bzD" = (/obj/structure/table,/obj/item/weapon/weldingtool,/obj/item/weapon/crowbar,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{dir = 2; icon_state = "browncorner"},/area/storage/primary) +"bzD" = (/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,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{dir = 2; icon_state = "browncorner"},/area/storage/primary) "bzE" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 4; initialize_directions = 11},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay{name = "Medbay Central"}) "bzF" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/storage/primary) "bzG" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/floor{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/locker) @@ -4149,7 +4149,7 @@ "bBO" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/spawner/lootdrop{loot = list("/obj/structure/grille","/obj/structure/grille","/obj/structure/grille","/obj/structure/grille","/obj/structure/grille","/obj/item/weapon/cigbutt","/obj/item/trash/cheesie","/obj/item/trash/candy","/obj/item/trash/chips","/obj/item/trash/deadmouse","/obj/item/trash/pistachios","/obj/item/trash/plate","/obj/item/trash/popcorn","/obj/item/trash/raisins","/obj/item/trash/sosjerky","/obj/item/trash/syndi_cakes"); name = "maint grille or trash spawner"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "bBP" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/engine/engineering) "bBQ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/engine/engineering) -"bBR" = (/obj/structure/rack,/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/clothing/glasses/welding,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/item/weapon/packageWrap,/obj/item/borg/upgrade/rename,/turf/simulated/floor{icon_state = "bot"},/area/assembly/robotics) +"bBR" = (/obj/structure/rack,/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/clothing/glasses/welding,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/item/stack/packageWrap,/obj/item/borg/upgrade/rename,/turf/simulated/floor{icon_state = "bot"},/area/assembly/robotics) "bBS" = (/obj/machinery/computer/pandemic{layer = 2.5; pixel_x = -4},/obj/machinery/light_switch{pixel_x = 26; pixel_y = 0},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/medical/virology) "bBT" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 8},/turf/simulated/floor{dir = 8; icon_state = "whitepurplecorner"},/area/medical/research{name = "Research Division"}) "bBU" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor{dir = 10; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) @@ -4500,7 +4500,7 @@ "bIB" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/obj/machinery/door/window/westright{dir = 4},/obj/item/weapon/soap/deluxe,/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bIC" = (/obj/machinery/vending/snack,/obj/machinery/newscaster{pixel_y = -29},/turf/simulated/floor/carpet,/area/crew_quarters/bar{name = "\improper Maltese Falcon"}) "bID" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_Toxins = 0},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) -"bIE" = (/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor{dir = 4; icon_state = "whiteyellowfull"; tag = "icon-whitehall (WEST)"},/area/medical/chemistry) +"bIE" = (/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor{dir = 4; icon_state = "whiteyellowfull"; tag = "icon-whitehall (WEST)"},/area/medical/chemistry) "bIF" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 8; icon_state = "whitepurple"},/area/toxins/telesci) "bIG" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Mech Bay"; req_access_txt = "29"; req_one_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor{icon_state = "purplefull"},/area/assembly/chargebay) "bIH" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;5"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) @@ -4879,7 +4879,7 @@ "bPQ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay{name = "Medbay Central"}) "bPR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/cable/yellow,/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/turret_protected/ai_upload) "bPS" = (/obj/structure/table,/obj/item/weapon/retractor,/obj/item/weapon/hemostat,/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29},/turf/simulated/floor{dir = 4; icon_state = "whitecorner"},/area/assembly/robotics) -"bPT" = (/obj/item/weapon/packageWrap,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) +"bPT" = (/obj/item/stack/packageWrap,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "bPU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/chapel/main) "bPV" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) "bPW" = (/obj/structure/table/reinforced,/obj/machinery/door/window/eastleft{dir = 1; name = "Kitchen Window"; req_access_txt = "28"; req_one_access_txt = "0"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/item/weapon/paper,/obj/machinery/door/window/eastleft{dir = 2; name = "Hydroponics Window"; req_access_txt = "0"; req_one_access_txt = "30;35"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/hydroponics) @@ -4962,7 +4962,7 @@ "bRv" = (/turf/simulated/floor{icon_state = "purplefull"},/area/hallway/primary/aft) "bRw" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor{dir = 5; icon_state = "whiteblue"},/area/medical/medbay2{name = "Medbay Storage"}) "bRx" = (/obj/structure/closet/secure_closet/medical3,/obj/item/device/radio/intercom{broadcasting = 1; freerange = 0; frequency = 1485; listening = 0; name = "Station Intercom (Medbay)"; pixel_x = 0; pixel_y = 30},/turf/simulated/floor{dir = 1; icon_state = "whiteblue"},/area/medical/medbay2{name = "Medbay Storage"}) -"bRy" = (/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/obj/machinery/door_control{id = "kitchenhydro"; name = "Service Shutter Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "28"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"bRy" = (/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/obj/machinery/door_control{id = "kitchenhydro"; name = "Service Shutter Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "28"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bRz" = (/obj/structure/closet/l3closet/general,/obj/structure/noticeboard{pixel_y = 32},/turf/simulated/floor{dir = 1; icon_state = "whiteblue"},/area/medical/medbay2{name = "Medbay Storage"}) "bRA" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{dir = 2; icon_state = "neutralcorner"},/area/hallway/primary/central) "bRB" = (/obj/structure/table,/obj/machinery/light{dir = 4},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/machinery/flasher{id = "AI"; pixel_x = 0; pixel_y = -24},/obj/item/weapon/aiModule/supplied/protectStation,/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) @@ -5941,7 +5941,7 @@ "ckr" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/ai_monitored/storage/eva{name = "E.V.A. Storage"}) "cks" = (/obj/machinery/atmospherics/pipe/simple/green/visible{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4; pixel_x = 0},/obj/structure/grille,/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/storage) "ckt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4; pixel_x = 0},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "open"; id = "kitchenwindow"; name = "kitchen shutters"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/crew_quarters/kitchen) -"cku" = (/obj/structure/rack,/obj/item/weapon/book/manual/chef_recipes{pixel_x = 2; pixel_y = 6},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/item/weapon/packageWrap,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"cku" = (/obj/structure/rack,/obj/item/weapon/book/manual/chef_recipes{pixel_x = 2; pixel_y = 6},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/item/stack/packageWrap,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "ckv" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 2},/turf/simulated/floor/plating,/area/maintenance/starboard) "ckw" = (/obj/structure/table,/obj/item/weapon/stock_parts/subspace/filter,/obj/item/weapon/stock_parts/subspace/filter,/obj/item/weapon/stock_parts/subspace/filter,/obj/item/weapon/stock_parts/subspace/filter,/obj/item/weapon/stock_parts/subspace/filter,/turf/simulated/floor{icon_state = "dark"},/area/maintenance/atmos_control{name = "Telecoms Storage"}) "ckx" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 4; icon_state = "neutralcorner"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) @@ -5966,7 +5966,7 @@ "ckQ" = (/obj/machinery/hologram/holopad,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/toxins/telesci) "ckR" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5},/turf/simulated/floor/wood,/area/crew_quarters/theatre) "ckS" = (/obj/structure/table/woodentable,/obj/machinery/light/small{dir = 8},/obj/item/clothing/mask/pig,/obj/item/weapon/bikehorn,/turf/simulated/floor/wood,/area/crew_quarters/theatre) -"ckT" = (/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/toxins/mineral_storeroom) +"ckT" = (/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/toxins/mineral_storeroom) "ckU" = (/turf/simulated/wall/r_wall,/area/assembly/chargebay) "ckV" = (/obj/machinery/bookbinder,/turf/simulated/floor/wood,/area/library) "ckW" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 6},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/floor/wood,/area/library) @@ -6437,7 +6437,7 @@ "ctW" = (/obj/structure/toilet{pixel_y = 8},/obj/machinery/light/small{dir = 4},/obj/machinery/door_control{id = "AuxToilet3"; name = "Lock Control"; normaldoorcontrol = 1; pixel_x = 25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/obj/machinery/newscaster{pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plating,/area/crew_quarters/toilet{name = "\improper Auxiliary Restrooms"}) "ctX" = (/obj/machinery/shower{dir = 8},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plating,/area/crew_quarters/toilet{name = "\improper Auxiliary Restrooms"}) "ctY" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) -"ctZ" = (/obj/structure/table,/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = 27; pixel_y = 0},/obj/item/weapon/hand_labeler,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_tele,/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/camera{c_tag = "Teleporter Room"; dir = 8; network = list("SS13")},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/teleporter{name = "\improper Teleporter Room"}) +"ctZ" = (/obj/structure/table,/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = 27; pixel_y = 0},/obj/item/weapon/hand_labeler,/obj/item/stack/packageWrap,/obj/item/weapon/hand_tele,/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/camera{c_tag = "Teleporter Room"; dir = 8; network = list("SS13")},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/teleporter{name = "\improper Teleporter Room"}) "cua" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) "cub" = (/obj/machinery/door/airlock/external{req_access_txt = "0"; req_one_access_txt = "13,8"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cuc" = (/obj/structure/closet,/obj/item/weapon/reagent_containers/glass/beaker{pixel_x = 8; pixel_y = 2},/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline{pixel_x = 7; pixel_y = -3},/obj/item/weapon/reagent_containers/glass/bottle/antitoxin{pixel_x = -4; pixel_y = -3},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) @@ -6892,7 +6892,7 @@ "cCJ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cCK" = (/obj/machinery/camera{active_power_usage = 0; c_tag = "Bomb Test Site"; desc = "A specially-reinforced camera with a long lasting battery, used to monitor the bomb testing site. An external light is attached to the top."; dir = 8; invuln = 1; light = null; luminosity = 3; name = "Hardened Bomb-Test Camera"; network = list("Toxins"); use_power = 0},/obj/item/target/alien{anchored = 1},/turf/simulated/shuttle/plating{dir = 4; icon_state = "warnplate"; luminosity = 2; nitrogen = 0.01; oxygen = 0.01; temperature = 2.7},/area/toxins/test_area) "cCL" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/yellow,/turf/simulated/floor/plating,/area/assembly/showroom{name = "\improper Corporate Showroom"}) -"cCM" = (/obj/structure/table,/obj/item/weapon/folder/white,/obj/item/weapon/packageWrap,/obj/item/weapon/pen,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/genetics) +"cCM" = (/obj/structure/table,/obj/item/weapon/folder/white,/obj/item/stack/packageWrap,/obj/item/weapon/pen,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/genetics) "cCN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/door/poddoor/preopen{id = "xenobio3"; name = "containment blast door"},/turf/simulated/floor/engine,/area/toxins/xenobiology) "cCO" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio3"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/toxins/xenobiology) "cCP" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) @@ -6997,7 +6997,7 @@ "cEK" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating/airless,/area/space) "cEL" = (/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating/airless,/area/space) "cEM" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 10},/obj/machinery/computer/cloning,/obj/machinery/light{dir = 4},/turf/simulated/floor{dir = 5; icon_state = "whiteblue"},/area/medical/genetics_cloning) -"cEN" = (/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor{icon_state = "greenfull"},/area/hydroponics) +"cEN" = (/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor{icon_state = "greenfull"},/area/hydroponics) "cEO" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/machinery/atmospherics/unary/cold_sink/freezer,/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/toxins/mixing{name = "\improper Toxins Lab"}) "cEP" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 5},/turf/simulated/floor{icon_state = "white"},/area/toxins/mixing{name = "\improper Toxins Lab"}) "cEQ" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{},/turf/simulated/floor{icon_state = "white"},/area/toxins/mixing{name = "\improper Toxins Lab"}) @@ -9477,7 +9477,7 @@ "dAu" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{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{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/locker) "dAv" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor{dir = 4; icon_state = "whitecorner"},/area/medical/medbay3{name = "Medbay Aft"}) "dAw" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/assembly/robotics) -"dAx" = (/obj/structure/table/reinforced,/obj/item/weapon/packageWrap,/obj/structure/sign/nosmoking_2{pixel_x = 0; pixel_y = -28},/obj/item/weapon/pen,/turf/simulated/floor{dir = 1; icon_state = "whitehall"},/area/medical/medbay3{name = "Medbay Aft"}) +"dAx" = (/obj/structure/table/reinforced,/obj/item/stack/packageWrap,/obj/structure/sign/nosmoking_2{pixel_x = 0; pixel_y = -28},/obj/item/weapon/pen,/turf/simulated/floor{dir = 1; icon_state = "whitehall"},/area/medical/medbay3{name = "Medbay Aft"}) "dAy" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/assembly/robotics) "dAz" = (/obj/effect/landmark/start{name = "Roboticist"},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/assembly/robotics) "dAA" = (/obj/structure/table,/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/box/syringes,/obj/machinery/power/apc{cell_type = 5000; dir = 1; name = "Virology APC"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{dir = 9; icon_state = "whitegreen"},/area/medical/virology) @@ -10329,7 +10329,7 @@ "dQP" = (/obj/structure/table,/obj/item/weapon/stock_parts/cell{charge = 100; maxcharge = 15000},/turf/simulated/floor/airless,/area/derelict/teleporter) "dQQ" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) "dQR" = (/obj/machinery/atmospherics/pipe/simple{dir = 6},/obj/machinery/camera{c_tag = "EVA"; dir = 4; network = list("MINE")},/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/table,/obj/item/device/gps/mining,/obj/item/device/gps/mining,/obj/item/device/gps/mining,/obj/item/device/gps/mining,/turf/simulated/floor,/area/mine/eva) -"dQS" = (/obj/machinery/power/apc{dir = 2; name = "Mining EVA APC"; pixel_x = 1; pixel_y = -23},/obj/structure/cable,/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor,/area/mine/eva) +"dQS" = (/obj/machinery/power/apc{dir = 2; name = "Mining EVA APC"; pixel_x = 1; pixel_y = -23},/obj/structure/cable,/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor,/area/mine/eva) "dQT" = (/obj/structure/sign/nosmoking_2,/turf/simulated/shuttle/wall{tag = "icon-swall3"; icon_state = "swall3"; dir = 2},/area/shuttle/escape/centcom) "dQU" = (/obj/structure/table,/obj/item/weapon/scalpel{pixel_y = 12},/obj/item/weapon/circular_saw,/obj/item/weapon/retractor{pixel_x = 4},/obj/item/weapon/hemostat{pixel_x = -4},/obj/item/clothing/gloves/latex,/obj/item/clothing/mask/surgical,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = -27},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) "dQV" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline{pixel_x = 6; pixel_y = 0},/obj/item/weapon/reagent_containers/glass/bottle/antitoxin{pixel_x = -3},/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline{pixel_x = -3; pixel_y = 8},/obj/item/weapon/reagent_containers/glass/bottle/antitoxin{pixel_x = 6; pixel_y = 8},/obj/item/weapon/reagent_containers/syringe/inaprovaline{pixel_x = 3; pixel_y = -2},/obj/item/weapon/reagent_containers/syringe/inaprovaline{pixel_x = 4; pixel_y = 1},/obj/item/weapon/reagent_containers/syringe/inaprovaline{pixel_x = -2; pixel_y = 5},/obj/item/weapon/reagent_containers/syringe/inaprovaline{pixel_x = 2; pixel_y = 8},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) diff --git a/_maps/map_files/MiniStation/MiniStation.dmm b/_maps/map_files/MiniStation/MiniStation.dmm index 8eaf087773a..2ff5f3b70b7 100644 --- a/_maps/map_files/MiniStation/MiniStation.dmm +++ b/_maps/map_files/MiniStation/MiniStation.dmm @@ -403,7 +403,7 @@ "ahM" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/turf/simulated/floor/carpet,/area/security/brig) "ahN" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor,/area/hallway/primary/central) "ahO" = (/turf/simulated/floor{icon_state = "purplecorner"; dir = 4},/area/hallway/primary/central) -"ahP" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/pen,/obj/machinery/door/firedoor/border_only{dir = 8; name = "hazard door west"},/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_x = -30; pixel_y = 0},/turf/simulated/floor{icon_state = "whitepurple"; dir = 8},/area/medical/research{name = "Research Division"}) +"ahP" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/weapon/pen,/obj/machinery/door/firedoor/border_only{dir = 8; name = "hazard door west"},/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_x = -30; pixel_y = 0},/turf/simulated/floor{icon_state = "whitepurple"; dir = 8},/area/medical/research{name = "Research Division"}) "ahQ" = (/turf/simulated/floor{dir = 4; icon_state = "warnwhite"},/area/medical/research{name = "Research Division"}) "ahR" = (/obj/machinery/r_n_d/destructive_analyzer,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/medical/research{name = "Research Division"}) "ahS" = (/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/medical/research{name = "Research Division"}) @@ -979,7 +979,7 @@ "asQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/crew_quarters/heads{name = "\improper Job Assignment"}) "asR" = (/obj/structure/table/reinforced,/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 2; icon_state = "rightsecure"; name = "Head of Personnel's Desk"; req_access_txt = "57"},/obj/machinery/door/window/northright{name = "Reception Window"},/turf/simulated/floor/plating,/area/crew_quarters/heads{name = "\improper Job Assignment"}) "asS" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 8},/turf/simulated/wall/r_wall,/area/crew_quarters/heads{name = "\improper Job Assignment"}) -"asT" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/table,/obj/item/weapon/book/manual/wiki/security_space_law,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor,/area/crew_quarters/heads{name = "\improper Job Assignment"}) +"asT" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/table,/obj/item/weapon/book/manual/wiki/security_space_law,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor,/area/crew_quarters/heads{name = "\improper Job Assignment"}) "asU" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/table,/obj/item/weapon/folder/blue,/obj/item/weapon/stamp/hop,/obj/machinery/requests_console{announcementConsole = 1; department = "Lieutenant Office"; departmentType = 5; name = "Lieutenant RC"; pixel_y = 30},/turf/simulated/floor,/area/crew_quarters/heads{name = "\improper Job Assignment"}) "asV" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/closet/crate/bin,/turf/simulated/floor,/area/crew_quarters/heads{name = "\improper Job Assignment"}) "asW" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/wall/r_wall,/area/crew_quarters/heads{name = "\improper Job Assignment"}) @@ -995,13 +995,13 @@ "atg" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/turf/simulated/floor{icon_state = "bar"},/area/crew_quarters/bar) "ath" = (/obj/structure/closet/crate/bin,/obj/structure/noticeboard{pixel_y = 32},/turf/simulated/floor{icon_state = "bar"},/area/crew_quarters/bar) "ati" = (/obj/machinery/vending/boozeomat,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/crew_quarters/bar) -"atj" = (/obj/structure/table,/obj/item/weapon/book/manual/barman_recipes,/obj/item/weapon/packageWrap,/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/crew_quarters/bar) +"atj" = (/obj/structure/table,/obj/item/weapon/book/manual/barman_recipes,/obj/item/stack/packageWrap,/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/crew_quarters/bar) "atk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/hallway/primary/central) "atl" = (/obj/structure/table,/obj/machinery/door/window/southleft{layer = 3.1},/turf/simulated/floor,/area/hallway/primary/central) "atm" = (/obj/structure/table,/obj/machinery/door/window/southright{layer = 3.1},/turf/simulated/floor,/area/hallway/primary/central) "atn" = (/obj/structure/table/reinforced,/obj/machinery/door/window/eastright{dir = 2; name = "Chemistry Desk"; req_access_txt = "33"},/obj/item/clothing/glasses/science,/turf/simulated/floor/plating,/area/medical/medbay) "ato" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/structure/table,/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/box/syringes,/obj/item/weapon/storage/pill_bottle/inaprovaline{pixel_x = 5; pixel_y = -2},/obj/item/weapon/storage/pill_bottle/inaprovaline{pixel_x = 5; pixel_y = -2},/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/dropper,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) -"atp" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/obj/item/device/radio/headset/headset_med,/obj/item/device/radio/intercom{broadcasting = 0; freerange = 0; listening = 1; name = "Common Channel"; pixel_y = 25},/obj/machinery/camera/autoname,/turf/simulated/floor{tag = "icon-whiteyellowcorner"; icon_state = "whiteyellowcorner"; dir = 2},/area/medical/medbay) +"atp" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/obj/item/device/radio/headset/headset_med,/obj/item/device/radio/intercom{broadcasting = 0; freerange = 0; listening = 1; name = "Common Channel"; pixel_y = 25},/obj/machinery/camera/autoname,/turf/simulated/floor{tag = "icon-whiteyellowcorner"; icon_state = "whiteyellowcorner"; dir = 2},/area/medical/medbay) "atq" = (/obj/machinery/smartfridge/chemistry,/turf/simulated/wall,/area/medical/medbay) "atr" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{tag = "icon-whiteyellowcorner (WEST)"; icon_state = "whiteyellowcorner"; dir = 8},/area/medical/medbay) "ats" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 6},/obj/machinery/door/firedoor/border_only{dir = 4; name = "hazard door east"},/turf/simulated/floor{dir = 4; icon_state = "whiteblue"},/area/medical/medbay) diff --git a/_maps/map_files/tgstation.2.1.3.dmm b/_maps/map_files/tgstation.2.1.3.dmm index bddc2eab970..d52354c6d5e 100644 --- a/_maps/map_files/tgstation.2.1.3.dmm +++ b/_maps/map_files/tgstation.2.1.3.dmm @@ -343,7 +343,7 @@ "agE" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 32},/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/hallway/primary/fore) "agF" = (/turf/simulated/floor{icon_state = "red"; dir = 5},/area/security/brig) "agG" = (/obj/machinery/hologram/holopad,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor,/area/security/main) -"agH" = (/obj/structure/table,/obj/item/device/flash,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor,/area/security/main) +"agH" = (/obj/structure/table,/obj/item/device/flash/handheld,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor,/area/security/main) "agI" = (/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/security/processing) "agJ" = (/obj/machinery/door/airlock/glass_security{id_tag = "innerbrig"; name = "Brig"; req_access_txt = "63"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "red"; dir = 5},/area/security/brig) "agK" = (/obj/machinery/door/airlock/glass_security{id_tag = "innerbrig"; name = "Brig"; req_access_txt = "63"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "red"; dir = 9},/area/security/brig) @@ -393,7 +393,7 @@ "ahC" = (/obj/machinery/seed_extractor,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) "ahD" = (/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/brig) "ahE" = (/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/security/prison) -"ahF" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint) +"ahF" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "ahG" = (/obj/item/weapon/wrench,/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (EAST)"; dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/fsmaint) "ahH" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/hallway/primary/fore) "ahI" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = "90Curve"},/obj/machinery/camera{c_tag = "Labor Shuttle Dock South"; dir = 1},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 9},/turf/simulated/floor{icon_state = "red"; dir = 6},/area/security/processing) @@ -587,7 +587,7 @@ "alo" = (/obj/machinery/door/airlock/glass_security{name = "Equipment Room"; req_access_txt = "1"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{icon_state = "showroomfloor"},/area/security/main) "alp" = (/obj/machinery/door/window/southleft{name = "Armory"; req_access_txt = "3"},/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/ai_monitored/security/armory) "alq" = (/obj/machinery/door/window/southleft{base_state = "right"; icon_state = "right"; name = "Armory"; req_access_txt = "3"},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/ai_monitored/security/armory) -"alr" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint) +"alr" = (/obj/structure/closet/wardrobe/mixed,/obj/item/clothing/shoes/jackboots,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "als" = (/obj/structure/lattice,/turf/space,/area/maintenance/auxsolarstarboard) "alt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "alu" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) @@ -640,7 +640,7 @@ "amp" = (/turf/simulated/floor{icon_state = "whitehall"; dir = 2},/area/security/prison) "amq" = (/obj/structure/extinguisher_cabinet{pixel_x = 1; pixel_y = -27},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{icon_state = "whitehall"; dir = 2},/area/security/prison) "amr" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/fsmaint) -"ams" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/turf/simulated/floor/plating,/area/maintenance/fsmaint) +"ams" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "amt" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/security/prison) "amu" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/wall,/area/maintenance/fsmaint) "amv" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/wall,/area/maintenance/fsmaint) @@ -717,7 +717,7 @@ "anO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "anP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "anQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) -"anR" = (/obj/structure/closet/wardrobe/mixed,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) +"anR" = (/obj/machinery/light/small{dir = 4},/obj/structure/rack,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "anS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "anT" = (/obj/structure/closet,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/port) "anU" = (/obj/machinery/atmospherics/portables_connector/visible,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/fpmaint2) @@ -786,9 +786,9 @@ "apf" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "apg" = (/obj/machinery/door/airlock/external{name = "External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aph" = (/obj/structure/stool,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/fpmaint2) -"api" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 5},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"api" = (/obj/machinery/atmospherics/pipe/simple/supplymain/hidden{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "apj" = (/obj/machinery/atmospherics/valve{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) -"apk" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"apk" = (/obj/machinery/atmospherics/pipe/simple/supplymain/hidden{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "apl" = (/obj/structure/closet,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "apm" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "apn" = (/obj/machinery/power/apc{dir = 1; name = "Arrivals North Maintenance APC"; pixel_x = -1; pixel_y = 26},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) @@ -817,7 +817,7 @@ "apK" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/obj/item/device/radio/intercom{pixel_y = 25},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor{icon_state = "bar"},/area/crew_quarters/bar) "apL" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/wall,/area/crew_quarters/kitchen) "apM" = (/obj/machinery/door/airlock{name = "Kitchen cold room"; req_access_txt = "28"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) -"apN" = (/obj/item/weapon/packageWrap,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/table,/obj/item/weapon/reagent_containers/glass/rag,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{icon_state = "bar"},/area/crew_quarters/bar) +"apN" = (/obj/item/stack/packageWrap,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/table,/obj/item/weapon/reagent_containers/glass/rag,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{icon_state = "bar"},/area/crew_quarters/bar) "apO" = (/turf/simulated/floor{dir = 9; icon_state = "green"},/area/hydroponics) "apP" = (/obj/structure/table,/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor,/area/hallway/primary/port) "apQ" = (/turf/simulated/wall,/area/crew_quarters/fitness) @@ -898,7 +898,7 @@ "arn" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aro" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "arp" = (/obj/structure/table,/obj/item/weapon/kitchen/utensil/fork,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor{icon_state = "bar"},/area/crew_quarters/bar) -"arq" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"arq" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/supplymain/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "arr" = (/obj/structure/stool{pixel_y = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor{icon_state = "bar"},/area/crew_quarters/bar) "ars" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor{icon_state = "bar"},/area/crew_quarters/bar) "art" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) @@ -1078,7 +1078,7 @@ "auL" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) "auM" = (/obj/structure/table,/obj/item/weapon/shard,/obj/item/weapon/shard{icon_state = "medium"},/obj/item/weapon/shard{icon_state = "small"},/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "auN" = (/obj/machinery/light/small{dir = 4},/obj/structure/stool,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) -"auO" = (/obj/structure/rack{dir = 1},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"auO" = (/obj/structure/closet,/obj/item/weapon/crowbar,/obj/item/device/flash/handheld,/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/checkpoint2) "auP" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Hydroponics Maintenance"; req_access_txt = "35"},/turf/simulated/floor/plating,/area/hydroponics) "auQ" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Kitchen"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor{dir = 2; icon_state = "bot"},/area/crew_quarters/kitchen) "auR" = (/obj/machinery/door/airlock/maintenance{name = "Kitchen Maintenance"; req_access_txt = "28"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/crew_quarters/kitchen) @@ -1188,7 +1188,7 @@ "awR" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/hallway/secondary/entry) "awS" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/turf/simulated/floor,/area/hallway/secondary/entry) "awT" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry) -"awU" = (/obj/structure/closet/wardrobe/white,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"awU" = (/obj/structure/closet/wardrobe/white,/obj/item/clothing/shoes/jackboots,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "awV" = (/obj/structure/table,/obj/item/weapon/hemostat,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "awW" = (/obj/structure/table,/obj/item/weapon/restraints/handcuffs/cable/zipties,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "awX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/wood,/area/bridge/meeting_room) @@ -1566,8 +1566,8 @@ "aEf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aEg" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/wall,/area/maintenance/fpmaint2) "aEh" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor,/area/hallway/primary/port) -"aEi" = (/obj/item/weapon/paper,/obj/structure/table/reinforced,/turf/simulated/floor{icon_state = "red"},/area/security/checkpoint2) -"aEj" = (/obj/machinery/recharger{pixel_y = 4},/obj/structure/table/reinforced,/turf/simulated/floor{icon_state = "red"},/area/security/checkpoint2) +"aEi" = (/obj/machinery/recharger{pixel_y = 4},/obj/structure/table/reinforced,/turf/simulated/floor{icon_state = "red"},/area/security/checkpoint2) +"aEj" = (/obj/item/device/radio/off,/turf/simulated/floor{icon_state = "red"; dir = 6},/area/security/checkpoint2) "aEk" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/wall,/area/maintenance/fpmaint2) "aEl" = (/obj/structure/table,/obj/item/weapon/minihoe,/obj/item/weapon/hatchet,/obj/item/weapon/crowbar,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor{icon_state = "green"; dir = 4},/area/hallway/secondary/construction{name = "\improper Garden"}) "aEm" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/turf/simulated/wall,/area/maintenance/fpmaint2) @@ -1616,10 +1616,10 @@ "aFd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aFe" = (/obj/machinery/light_switch{pixel_x = 27},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aFf" = (/obj/structure/table/woodentable,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/wood,/area/security/vacantoffice) -"aFg" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (WEST)"; dir = 8},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"aFg" = (/obj/machinery/atmospherics/pipe/simple/supplymain/hidden{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/wall,/area/maintenance/fpmaint2) "aFh" = (/obj/machinery/power/apc{dir = 1; name = "Law Office APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/lawoffice) "aFi" = (/obj/machinery/power/apc{dir = 8; name = "Detective APC"; pixel_x = -24},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/security/detectives_office) -"aFj" = (/obj/structure/table/woodentable,/obj/structure/mirror{pixel_x = -28},/turf/simulated/floor{tag = "icon-redbluefull"; icon_state = "redbluefull"},/area/crew_quarters/theatre) +"aFj" = (/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/light{dir = 1},/obj/structure/table/woodentable,/obj/item/weapon/lipstick,/turf/simulated/floor/wood,/area/crew_quarters/theatre) "aFk" = (/obj/machinery/door/airlock/maintenance{name = "Detective Maintenance"; req_access_txt = "4"},/turf/simulated/floor/plating,/area/security/detectives_office) "aFl" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (EAST)"; dir = 4},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/crew_quarters/sleep) "aFm" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (WEST)"; dir = 8},/turf/simulated/floor{icon_state = "neutralcorner"; dir = 4},/area/crew_quarters/sleep) @@ -1648,7 +1648,7 @@ "aFJ" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/turf/simulated/floor,/area/hallway/primary/fore) "aFK" = (/obj/machinery/door/airlock/maintenance{name = "Library Maintenance"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/library) "aFL" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/pill_bottle/dice,/turf/simulated/floor/wood,/area/library) -"aFM" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/packageWrap,/turf/simulated/floor/wood,/area/library) +"aFM" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/stack/packageWrap,/turf/simulated/floor/wood,/area/library) "aFN" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor/wood,/area/library) "aFO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor,/area/hallway/primary/fore) "aFP" = (/obj/structure/closet/wardrobe/chaplain_black,/obj/item/device/radio/intercom{pixel_y = 25},/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) @@ -1682,10 +1682,10 @@ "aGr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/turf/simulated/floor/plating,/area/maintenance/fpmaint) "aGs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint) "aGt" = (/obj/effect/landmark/start{name = "Assistant"},/obj/structure/stool{pixel_y = 8},/turf/simulated/floor,/area/storage/primary) -"aGu" = (/obj/structure/table,/obj/item/weapon/weldingtool,/obj/item/weapon/crowbar,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/turf/simulated/floor,/area/storage/primary) +"aGu" = (/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,/area/storage/primary) "aGv" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/turf/simulated/wall,/area/maintenance/fpmaint2) "aGw" = (/obj/machinery/light/small{dir = 1},/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor{icon_state = "vault"},/area/ai_monitored/nuke_storage) -"aGx" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"aGx" = (/obj/machinery/atmospherics/pipe/simple/supplymain/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/wall,/area/maintenance/fpmaint2) "aGy" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/fpmaint) "aGz" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/wall,/area/maintenance/electrical) "aGA" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) @@ -1867,13 +1867,13 @@ "aJU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/hallway/primary/central) "aJV" = (/obj/machinery/vending/snack,/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central) "aJW" = (/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/hallway/primary/central) -"aJX" = (/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/light{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/theatre) +"aJX" = (/obj/structure/table/woodentable,/obj/structure/mirror{pixel_x = -28},/obj/item/weapon/lipstick/random,/turf/simulated/floor{icon_state = "whitehall"; dir = 4},/area/crew_quarters/theatre) "aJY" = (/turf/simulated/floor/wood,/area/crew_quarters/theatre) -"aJZ" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"aJZ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supplymain/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aKa" = (/obj/structure/closet/lasertag/blue,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/crew_quarters/fitness) "aKb" = (/obj/structure/closet/lasertag/red,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/floor{icon_state = "neutral"; dir = 5},/area/crew_quarters/fitness) "aKc" = (/turf/simulated/floor{icon_state = "bar"},/area/crew_quarters/bar) -"aKd" = (/obj/structure/closet/boxinggloves,/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/crew_quarters/fitness) +"aKd" = (/obj/structure/closet/wardrobe/black,/obj/item/clothing/shoes/jackboots,/turf/simulated/floor,/area/crew_quarters/locker) "aKe" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor{icon_state = "bar"},/area/crew_quarters/bar) "aKf" = (/obj/machinery/camera{c_tag = "Fitness Room"},/obj/structure/closet/masks,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/crew_quarters/fitness) "aKg" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/wall,/area/crew_quarters/fitness) @@ -1925,12 +1925,12 @@ "aLa" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/port) "aLb" = (/obj/machinery/light{dir = 1},/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 32},/turf/simulated/floor{icon_state = "warningcorner"; dir = 8},/area/hallway/primary/port) "aLc" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/turf/simulated/wall,/area/lawoffice) -"aLd" = (/obj/effect/spawner/lootdrop/maintenance{lootcount = 2; name = "2maintenance loot spawner"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"aLd" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/supplymain/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aLe" = (/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/hallway/primary/port) -"aLf" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/fpmaint2) +"aLf" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supplymain/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aLg" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/hallway/primary/port) "aLh" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 32},/turf/simulated/floor{icon_state = "warningcorner"; dir = 4},/area/hallway/primary/port) -"aLi" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"aLi" = (/obj/machinery/atmospherics/pipe/simple/supplymain/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/fpmaint2) "aLj" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor{icon_state = "warningcorner"; dir = 8},/area/hallway/primary/port) "aLk" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/turf/simulated/floor{icon_state = "warningcorner"; dir = 4},/area/hallway/primary/port) "aLl" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor,/area/hallway/primary/central) @@ -1958,11 +1958,11 @@ "aLH" = (/obj/structure/piano,/turf/simulated/floor/wood,/area/crew_quarters/theatre) "aLI" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aLJ" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor{icon_state = "bar"},/area/crew_quarters/bar) -"aLK" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"aLK" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/supplymain/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aLL" = (/obj/structure/disposalpipe/segment,/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aLM" = (/obj/machinery/vending/cola,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aLN" = (/obj/machinery/vending/coffee,/turf/simulated/floor/wood,/area/crew_quarters/bar) -"aLO" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"aLO" = (/obj/effect/spawner/lootdrop/maintenance{lootcount = 2; name = "2maintenance loot spawner"},/obj/machinery/atmospherics/pipe/simple/supplymain/hidden{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aLP" = (/turf/simulated/floor,/area/crew_quarters/fitness) "aLQ" = (/obj/machinery/chem_master/condimaster{name = "CondiMaster Neo"},/obj/machinery/camera{c_tag = "Kitchen Cold Room"},/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aLR" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{icon_state = "red"; dir = 4},/area/crew_quarters/fitness) @@ -2062,7 +2062,6 @@ "aNH" = (/obj/machinery/camera{c_tag = "Port Hallway 3"; dir = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/hallway/primary/port) "aNI" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-j1"; dir = 4},/turf/simulated/floor,/area/hallway/primary/port) "aNJ" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-j2"; dir = 4},/turf/simulated/floor,/area/hallway/primary/port) -"aNK" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/hallway/primary/port) "aNL" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/port) "aNM" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/turf/simulated/floor{icon_state = "barber"},/area/crew_quarters/locker) "aNN" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/crew_quarters/locker) @@ -2089,7 +2088,7 @@ "aOi" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (EAST)"; dir = 4},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/crew_quarters/sleep) "aOj" = (/obj/machinery/gibber,/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aOk" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor{icon_state = "dark"},/area/hydroponics) -"aOl" = (/obj/structure/table/woodentable,/obj/structure/mirror{pixel_x = -28},/turf/simulated/floor{icon_state = "whitehall"; dir = 4},/area/crew_quarters/theatre) +"aOl" = (/obj/item/clothing/under/rank/vice,/obj/structure/closet,/obj/item/clothing/shoes/jackboots,/turf/simulated/floor/plating,/area/maintenance/aft) "aOm" = (/obj/machinery/hydroponics/constructable,/turf/simulated/floor{icon_state = "dark"},/area/hydroponics) "aOn" = (/obj/machinery/hydroponics/constructable,/obj/machinery/camera{c_tag = "Hydroponics North"; dir = 2},/turf/simulated/floor{icon_state = "dark"},/area/hydroponics) "aOo" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{icon_state = "dark"},/area/hydroponics) @@ -2276,7 +2275,7 @@ "aRN" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/wall,/area/library) "aRO" = (/obj/structure/table,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/rods{amount = 50},/turf/simulated/floor,/area/storage/tools) "aRP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/storage/tools) -"aRQ" = (/obj/structure/table/reinforced,/obj/item/device/flash,/obj/item/device/flash,/turf/simulated/floor,/area/bridge) +"aRQ" = (/obj/item/weapon/paper,/obj/structure/table/reinforced,/obj/machinery/door/window/brigdoor{dir = 2; name = "Arrivals Security Checkpoint"; pixel_y = -8; req_access_txt = "1"},/turf/simulated/floor{icon_state = "red"},/area/security/checkpoint2) "aRR" = (/turf/simulated/floor{dir = 1; icon_state = "yellowcorner"},/area/bridge) "aRS" = (/obj/structure/stool/bed/chair{dir = 1; name = "Engineering Station"},/turf/simulated/floor,/area/bridge) "aRT" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "yellowcorner"},/area/bridge) @@ -2326,7 +2325,7 @@ "aSL" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aSM" = (/turf/simulated/wall,/area/security/vacantoffice) "aSN" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/carpet,/area/security/vacantoffice) -"aSO" = (/obj/item/weapon/crowbar,/obj/item/device/flash,/turf/simulated/floor{icon_state = "red"; dir = 6},/area/security/checkpoint2) +"aSO" = (/obj/structure/table/reinforced,/obj/item/device/flash/handheld,/obj/item/device/flash/handheld,/turf/simulated/floor,/area/bridge) "aSP" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor,/area/hallway/secondary/construction{name = "\improper Garden"}) "aSQ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/port) "aSR" = (/obj/structure/closet/wardrobe/green,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor,/area/crew_quarters/locker) @@ -2372,7 +2371,7 @@ "aTF" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/closet,/obj/item/clothing/under/suit_jacket/female{pixel_x = 3; pixel_y = 1},/obj/item/clothing/under/suit_jacket/really_black{pixel_x = -2; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor{icon_state = "barber"},/area/crew_quarters/locker) "aTG" = (/obj/structure/table,/obj/item/stack/sheet/rglass{amount = 50},/obj/item/stack/sheet/rglass{amount = 50},/obj/item/stack/rods{amount = 50},/obj/item/stack/rods{amount = 50},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/ai_monitored/storage/eva) "aTH" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) -"aTI" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/port) +"aTI" = (/obj/machinery/atmospherics/pipe/simple/supplymain/hidden{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aTJ" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "cafeteria"},/area/crew_quarters/kitchen) "aTK" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/machinery/light{dir = 4},/turf/simulated/floor,/area/storage/primary) "aTL" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor,/area/storage/primary) @@ -2439,7 +2438,7 @@ "aUU" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "bar"},/area/crew_quarters/bar) "aUV" = (/obj/structure/table/reinforced,/obj/item/clothing/head/that{throwforce = 1; throwing = 1},/turf/simulated/floor{icon_state = "bar"},/area/crew_quarters/bar) "aUW" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/food/snacks/pie,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/turf/simulated/floor{icon_state = "cafeteria"},/area/crew_quarters/kitchen) -"aUX" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/condiment/enzyme{layer = 5},/obj/item/weapon/packageWrap,/turf/simulated/floor{icon_state = "cafeteria"},/area/crew_quarters/kitchen) +"aUX" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/condiment/enzyme{layer = 5},/obj/item/stack/packageWrap,/turf/simulated/floor{icon_state = "cafeteria"},/area/crew_quarters/kitchen) "aUY" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/reagent_containers/glass/beaker{pixel_x = 5},/turf/simulated/floor{icon_state = "cafeteria"},/area/crew_quarters/kitchen) "aUZ" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/condiment/saltshaker{pixel_x = -3; pixel_y = 0},/obj/item/weapon/reagent_containers/food/condiment/peppermill{pixel_x = 3},/turf/simulated/floor{icon_state = "cafeteria"},/area/crew_quarters/kitchen) "aVa" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) @@ -2482,7 +2481,7 @@ "aVL" = (/obj/machinery/light_switch{pixel_x = -20; pixel_y = 0},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/gateway) "aVM" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor,/area/gateway) "aVN" = (/obj/machinery/door/airlock/vault{icon_state = "door_locked"; locked = 1; req_access_txt = "53"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/ai_monitored/nuke_storage) -"aVO" = (/obj/structure/closet/wardrobe/black,/turf/simulated/floor,/area/crew_quarters/locker) +"aVO" = (/obj/structure/closet/boxinggloves,/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/item/clothing/shoes/jackboots,/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/crew_quarters/fitness) "aVP" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/hydroponics) "aVQ" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/obj/effect/landmark/start{name = "Assistant"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/wood,/area/library) "aVR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor,/area/storage/primary) @@ -2755,8 +2754,8 @@ "baY" = (/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/quartermaster/office) "baZ" = (/turf/simulated/floor,/area/quartermaster/office) "bba" = (/obj/item/weapon/storage/box,/obj/structure/table,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor{icon_state = "arrival"; dir = 1},/area/quartermaster/office) -"bbb" = (/obj/structure/table,/obj/item/weapon/wrapping_paper,/obj/item/weapon/wrapping_paper,/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_y = 30},/turf/simulated/floor{icon_state = "arrival"; dir = 1},/area/quartermaster/office) -"bbc" = (/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/turf/simulated/floor{icon_state = "arrival"; dir = 5},/area/quartermaster/office) +"bbb" = (/obj/structure/table,/obj/item/stack/wrapping_paper,/obj/item/stack/wrapping_paper,/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_y = 30},/turf/simulated/floor{icon_state = "arrival"; dir = 1},/area/quartermaster/office) +"bbc" = (/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/turf/simulated/floor{icon_state = "arrival"; dir = 5},/area/quartermaster/office) "bbd" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor,/area/hallway/primary/central) "bbe" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/turf/simulated/floor,/area/ai_monitored/storage/eva) "bbf" = (/obj/machinery/porta_turret{ai = 1; dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) @@ -2939,7 +2938,7 @@ "beA" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "beB" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor,/area/atmos) "beC" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{dir = 8; icon_state = "brown"},/area/quartermaster/office) -"beD" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor,/area/atmos) +"beD" = (/obj/structure/table/woodentable,/obj/structure/mirror{pixel_x = -28},/obj/item/weapon/lipstick/random,/turf/simulated/floor{tag = "icon-redbluefull"; icon_state = "redbluefull"},/area/crew_quarters/theatre) "beE" = (/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/structure/table/reinforced,/turf/simulated/floor{icon_state = "arrival"; dir = 4},/area/quartermaster/office) "beF" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/quartermaster/office) "beG" = (/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central) @@ -3195,7 +3194,7 @@ "bjw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/chemistry) "bjx" = (/obj/structure/sign/atmosplaque{pixel_x = 0; pixel_y = -32},/obj/structure/table,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor,/area/atmos) "bjy" = (/obj/effect/spawner/lootdrop/maintenance,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"bjz" = (/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"bjz" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/supplymain/hidden{tag = "icon-manifold (WEST)"; icon_state = "manifold"; dir = 8},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "bjA" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"},/area/medical/medbay) "bjB" = (/obj/machinery/door/airlock/research{name = "Testing Lab"; req_access_txt = "47"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab) "bjC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/toxins/misc_lab) @@ -3312,7 +3311,7 @@ "blJ" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/quartermaster/storage) "blK" = (/obj/structure/closet/emcloset,/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/quartermaster/storage) "blL" = (/obj/structure/closet/emcloset,/obj/machinery/alarm{dir = 2; pixel_y = 24},/turf/simulated/floor,/area/quartermaster/storage) -"blM" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"blM" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{dir = 5},/turf/simulated/floor/plating/airless,/area/space) "blN" = (/obj/structure/closet/secure_closet/security,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor{icon_state = "red"; dir = 9},/area/security/checkpoint2) "blO" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (EAST)"; dir = 4},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/checkpoint2) "blP" = (/obj/machinery/computer/security,/obj/structure/reagent_dispensers/peppertank{pixel_x = 0; pixel_y = 30},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/checkpoint2) @@ -3332,7 +3331,7 @@ "bmd" = (/turf/simulated/wall,/area/crew_quarters/heads) "bme" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "bmf" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor,/area/security/checkpoint2) -"bmg" = (/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/checkpoint2) +"bmg" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor,/area/atmos) "bmh" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/glass_engineering{name = "Gravity Generator"; req_access_txt = "11"; req_one_access_txt = "0"},/turf/simulated/floor{icon_state = "dark"},/area/engine/gravity_generator) "bmi" = (/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/turret_protected/ai_upload) "bmj" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (NORTH)"; dir = 1},/turf/simulated/floor,/area/storage/primary) @@ -3371,7 +3370,7 @@ "bmQ" = (/obj/machinery/light{dir = 8},/obj/machinery/camera{c_tag = "Mech Bay"; dir = 4},/turf/simulated/floor,/area/assembly/chargebay) "bmR" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/assembly/chargebay) "bmS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/assembly/robotics) -"bmT" = (/obj/structure/table,/obj/item/stack/sheet/plasteel{amount = 10},/obj/item/stack/cable_coil,/obj/item/device/flash,/obj/item/device/flash,/turf/simulated/floor,/area/assembly/robotics) +"bmT" = (/obj/machinery/ai_status_display{pixel_x = 32; pixel_y = 0},/obj/structure/table,/obj/item/device/flash/handheld,/obj/item/device/flash/handheld,/obj/item/device/flash/handheld,/obj/item/device/flash/handheld,/obj/item/device/flash/handheld,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bmU" = (/obj/structure/stool,/turf/simulated/floor,/area/assembly/robotics) "bmV" = (/turf/simulated/floor{icon_state = "bot"},/area/assembly/robotics) "bmW" = (/turf/simulated/floor{dir = 8; icon_state = "warnwhite"},/area/assembly/robotics) @@ -3393,7 +3392,7 @@ "bnm" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (WEST)"; dir = 8},/turf/simulated/floor/plating,/area/maintenance/fpmaint) "bnn" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "bno" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/security/checkpoint2) -"bnp" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/door/window/brigdoor{dir = 1; name = "Arrivals Security Checkpoint"; req_access_txt = "63"},/turf/simulated/floor{icon_state = "delivery"},/area/hallway/secondary/entry) +"bnp" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/turf/simulated/floor{icon_state = "delivery"},/area/hallway/secondary/entry) "bnq" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Dormitory"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/crew_quarters/sleep) "bnr" = (/obj/item/weapon/stamp{pixel_x = -3; pixel_y = 3},/obj/item/weapon/stamp/denied{pixel_x = 4; pixel_y = -2},/obj/structure/table,/turf/simulated/floor,/area/quartermaster/office) "bns" = (/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/clipboard,/obj/item/weapon/pen/red,/obj/structure/table,/turf/simulated/floor,/area/quartermaster/office) @@ -3490,7 +3489,7 @@ "bpf" = (/obj/structure/disposalpipe/segment,/obj/machinery/light{dir = 8},/turf/simulated/floor,/area/hallway/primary/central) "bpg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "bph" = (/obj/structure/closet/emcloset,/obj/machinery/camera{c_tag = "Virology Airlock"; dir = 2; network = list("SS13")},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 9},/turf/simulated/floor{icon_state = "warnwhite"; dir = 5},/area/medical/virology) -"bpi" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/obj/item/weapon/packageWrap,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) +"bpi" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/obj/item/stack/packageWrap,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bpj" = (/obj/structure/stool/bed/roller,/obj/machinery/door_control{desc = "A remote control switch for the medbay foyer."; id = "MedbayFoyer"; name = "Medbay Exit Button"; normaldoorcontrol = 1; pixel_x = 0; pixel_y = 26},/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bpk" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor,/area/security/transfer) "bpl" = (/obj/machinery/status_display,/turf/simulated/wall,/area/medical/medbay) @@ -3546,7 +3545,7 @@ "bqj" = (/turf/simulated/floor{icon_state = "bot"},/area/quartermaster/office) "bqk" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/quartermaster/office) "bql" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/turf/simulated/floor,/area/quartermaster/office) -"bqm" = (/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/pen,/obj/machinery/requests_console{announcementConsole = 0; department = "Medbay"; departmentType = 1; name = "Medbay RC"; pixel_x = 0; pixel_y = 30; pixel_z = 0},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) +"bqm" = (/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/weapon/pen,/obj/machinery/requests_console{announcementConsole = 0; department = "Medbay"; departmentType = 1; name = "Medbay RC"; pixel_x = 0; pixel_y = 30; pixel_z = 0},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bqn" = (/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/hallway/primary/central) "bqo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/hallway/primary/central) "bqp" = (/turf/simulated/floor{icon_state = "bot"},/area/hallway/primary/central) @@ -3643,7 +3642,7 @@ "bsc" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (WEST)"; dir = 8},/turf/simulated/floor{dir = 9; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "bsd" = (/obj/structure/sign/nosmoking_2{pixel_x = -32},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "bse" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{icon_state = "bot"},/area/toxins/storage) -"bsf" = (/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/asmaint) +"bsf" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{dir = 4},/turf/simulated/floor/plating/airless,/area/space) "bsg" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor,/area/hallway/primary/aft) "bsh" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (WEST)"; dir = 8},/turf/simulated/floor{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "bsi" = (/obj/structure/table,/obj/item/weapon/storage/box/disks{pixel_x = 2; pixel_y = 2},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) @@ -3660,7 +3659,7 @@ "bst" = (/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor{dir = 8; icon_state = "warnwhite"},/area/assembly/robotics) "bsu" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters/preopen{id = "rnd2"; name = "research lab shutters"},/turf/simulated/floor/plating,/area/toxins/lab) "bsv" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"bsw" = (/obj/structure/table,/obj/item/weapon/pen,/obj/machinery/camera{c_tag = "Telescience Lab"; dir = 2; network = list("SS13","RD")},/obj/item/weapon/hand_labeler,/obj/item/weapon/packageWrap,/turf/simulated/floor{icon_state = "whitehall"; dir = 2},/area/toxins/telesci) +"bsw" = (/obj/structure/table,/obj/item/weapon/pen,/obj/machinery/camera{c_tag = "Telescience Lab"; dir = 2; network = list("SS13","RD")},/obj/item/weapon/hand_labeler,/obj/item/stack/packageWrap,/turf/simulated/floor{icon_state = "whitehall"; dir = 2},/area/toxins/telesci) "bsx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint) "bsy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) "bsz" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) @@ -3917,7 +3916,7 @@ "bxq" = (/turf/simulated/floor,/area/medical/sleeper) "bxr" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 5},/turf/simulated/floor,/area/medical/sleeper) "bxs" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 4},/turf/simulated/floor,/area/medical/sleeper) -"bxt" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{},/turf/simulated/floor,/area/medical/sleeper) +"bxt" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,/turf/simulated/wall/r_wall,/area/atmos) "bxu" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 10; pixel_x = 0; initialize_directions = 10},/turf/simulated/floor,/area/medical/sleeper) "bxv" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/turf/simulated/floor{icon_state = "delivery"},/area/medical/sleeper) "bxw" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) @@ -4358,7 +4357,7 @@ "bFP" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/toxins/telesci) "bFQ" = (/turf/simulated/floor{icon_state = "white"},/area/toxins/mixing) "bFR" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 5},/turf/simulated/floor{icon_state = "white"},/area/toxins/mixing) -"bFS" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{},/obj/machinery/meter,/turf/simulated/floor{icon_state = "white"},/area/toxins/mixing) +"bFS" = (/obj/machinery/atmospherics/pipe/simple/supply/visible,/turf/simulated/wall/r_wall,/area/atmos) "bFT" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 9},/turf/simulated/floor{icon_state = "white"},/area/toxins/mixing) "bFU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/crew_quarters/hor) "bFV" = (/obj/machinery/doppler_array{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "bot"},/area/toxins/mixing) @@ -4543,7 +4542,7 @@ "bJs" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/powermonitor{pixel_x = -2; pixel_y = 2},/obj/item/weapon/circuitboard/stationalert{pixel_x = 1; pixel_y = -1},/obj/item/weapon/circuitboard/atmos_alert{pixel_x = 3; pixel_y = -3},/turf/simulated/floor/plating,/area/storage/tech) "bJt" = (/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/plating,/area/storage/tech) "bJu" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/hallway/primary/starboard) -"bJv" = (/obj/structure/table,/obj/machinery/newscaster/security_unit{pixel_x = 0; pixel_y = 32},/obj/item/weapon/hand_labeler,/obj/item/weapon/packageWrap,/turf/simulated/floor,/area/crew_quarters/heads) +"bJv" = (/obj/structure/table,/obj/machinery/newscaster/security_unit{pixel_x = 0; pixel_y = 32},/obj/item/weapon/hand_labeler,/obj/item/stack/packageWrap,/turf/simulated/floor,/area/crew_quarters/heads) "bJw" = (/obj/machinery/pdapainter,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor,/area/crew_quarters/heads) "bJx" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_x = -32; pixel_y = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/engine/gravity_generator) "bJy" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 32; pixel_y = 0},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/engine/gravity_generator) @@ -4695,8 +4694,8 @@ "bMo" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/wall/r_wall,/area/atmos) "bMp" = (/obj/structure/closet/firecloset,/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor{dir = 10; icon_state = "warnwhite"},/area/medical/research{name = "Research Division"}) "bMq" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor{dir = 6; icon_state = "warnwhite"},/area/medical/research{name = "Research Division"}) -"bMr" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{},/turf/simulated/wall/r_wall,/area/atmos) -"bMs" = (/obj/machinery/atmospherics/pipe/simple/supply/visible{},/turf/simulated/wall/r_wall,/area/atmos) +"bMr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/cyan/visible,/obj/machinery/atmospherics/pipe/simple/green/visible{dir = 4},/turf/simulated/floor/plating,/area/atmos) +"bMs" = (/obj/machinery/atmospherics/pipe/manifold/general/visible,/turf/simulated/floor/engine,/area/toxins/misc_lab) "bMt" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/disposalpipe/sortjunction{dir = 1; icon_state = "pipe-j2s"; sortType = 3},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor,/area/quartermaster/miningdock) "bMu" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/checkpoint/supply) "bMv" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor,/area/quartermaster/storage) @@ -4817,7 +4816,7 @@ "bOG" = (/turf/simulated/floor,/area/atmos) "bOH" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engine/engineering) "bOI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/atmos) -"bOJ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{},/turf/simulated/floor,/area/atmos) +"bOJ" = (/obj/machinery/atmospherics/pipe/simple/green/visible,/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/atmos) "bOK" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engine/engineering) "bOL" = (/obj/machinery/atmospherics/binary/pump{dir = 1; name = "Mix to Distro"; on = 0},/turf/simulated/floor,/area/atmos) "bOM" = (/obj/machinery/atmospherics/pipe/manifold/cyan/visible{dir = 8; initialize_directions = 11},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) @@ -4871,7 +4870,7 @@ "bPI" = (/obj/structure/closet/crate,/turf/simulated/floor,/area/atmos) "bPJ" = (/obj/structure/disposalpipe/sortjunction{dir = 8; icon_state = "pipe-j1s"; sortType = 15},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/aft) "bPK" = (/obj/machinery/atmospherics/pipe/simple/yellow/visible{dir = 6},/turf/simulated/floor,/area/atmos) -"bPL" = (/obj/machinery/atmospherics/pipe/manifold/yellow/visible{},/turf/simulated/floor,/area/atmos) +"bPL" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/yellow/visible,/turf/simulated/floor/plating,/area/atmos) "bPM" = (/obj/machinery/atmospherics/pipe/simple/yellow/visible{dir = 4},/turf/simulated/floor,/area/atmos) "bPN" = (/obj/machinery/atmospherics/binary/pump{dir = 0; name = "Air to Mix"; on = 0},/obj/machinery/atmospherics/pipe/simple/yellow/visible{dir = 4},/turf/simulated/floor,/area/atmos) "bPO" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/atmospherics/binary/pump{dir = 8; name = "Mix Outlet Pump"; on = 0},/turf/simulated/floor{dir = 5; icon_state = "green"},/area/atmos) @@ -4941,7 +4940,7 @@ "bRa" = (/obj/machinery/atmospherics/pipe/manifold/green/visible{dir = 1},/turf/simulated/floor,/area/atmos) "bRb" = (/obj/machinery/atmospherics/pipe/manifold/green/visible{dir = 4},/turf/simulated/floor,/area/atmos) "bRc" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "waste_in"; name = "Gas Mix Tank Control"; output_tag = "waste_out"; sensors = list("waste_sensor" = "Tank")},/turf/simulated/floor{icon_state = "green"; dir = 4},/area/atmos) -"bRd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/cyan/visible{},/turf/simulated/floor/plating,/area/atmos) +"bRd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/obj/machinery/atmospherics/pipe/simple/yellow/visible,/turf/simulated/floor/plating,/area/atmos) "bRe" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/atmos) "bRf" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "waste_sensor"; output = 63},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) "bRg" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) @@ -5003,7 +5002,7 @@ "bSk" = (/obj/machinery/atmospherics/pipe/simple/green/visible{dir = 5; initialize_directions = 12},/turf/simulated/floor,/area/atmos) "bSl" = (/obj/machinery/atmospherics/binary/pump{dir = 1; name = "Unfiltered to Mix"; on = 1},/obj/machinery/atmospherics/pipe/simple/green/visible{dir = 4; initialize_directions = 12},/turf/simulated/floor,/area/atmos) "bSm" = (/obj/machinery/atmospherics/pipe/simple/green/visible{dir = 4},/turf/simulated/floor{icon_state = "green"; dir = 6},/area/atmos) -"bSn" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"bSn" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{dir = 4},/turf/simulated/floor/plating,/area/maintenance/incinerator) "bSo" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/green/visible{dir = 4},/turf/space,/area/space) "bSp" = (/obj/machinery/atmospherics/unary/outlet_injector/on{dir = 8; frequency = 1441; id = "waste_in"; pixel_y = 1},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) "bSq" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) @@ -5032,7 +5031,7 @@ "bSN" = (/obj/structure/table,/obj/structure/window/reinforced{dir = 4},/obj/item/device/electropack,/obj/item/device/healthanalyzer,/obj/item/device/assembly/signaler,/turf/simulated/floor,/area/toxins/misc_lab) "bSO" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{dir = 4; initialize_directions = 11},/turf/simulated/floor/engine,/area/toxins/misc_lab) "bSP" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{dir = 8},/turf/simulated/floor/engine,/area/toxins/misc_lab) -"bSQ" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{},/turf/simulated/floor/engine,/area/toxins/misc_lab) +"bSQ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/atmos) "bSR" = (/obj/machinery/atmospherics/unary/cold_sink/freezer{dir = 8},/turf/simulated/floor/engine,/area/toxins/misc_lab) "bSS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/toxins/misc_lab) "bST" = (/obj/machinery/magnetic_module,/obj/effect/landmark{name = "blobstart"},/obj/structure/target_stake,/turf/simulated/floor{dir = 2; icon_state = "bot"},/area/toxins/misc_lab) @@ -5055,14 +5054,14 @@ "bTk" = (/obj/structure/table,/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 7},/obj/item/clothing/head/welding{pixel_x = -5; pixel_y = 3},/obj/machinery/light{dir = 8},/obj/item/device/multitool,/turf/simulated/floor,/area/atmos) "bTl" = (/obj/structure/table,/obj/item/stack/sheet/glass{amount = 50},/obj/item/weapon/storage/belt/utility,/obj/item/device/t_scanner,/obj/item/device/t_scanner,/obj/item/device/t_scanner,/turf/simulated/floor,/area/atmos) "bTm" = (/obj/structure/table,/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/turf/simulated/floor,/area/atmos) -"bTn" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/atmos) +"bTn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/cyan/visible,/obj/machinery/atmospherics/pipe/simple/yellow/visible{dir = 4},/turf/simulated/floor/plating,/area/atmos) "bTo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/atmos) "bTp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 6; initialize_directions = 6},/turf/simulated/floor/plating,/area/atmos) -"bTq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/obj/machinery/atmospherics/pipe/simple/yellow/visible{},/turf/simulated/floor/plating,/area/atmos) +"bTq" = (/obj/machinery/atmospherics/pipe/manifold/yellow/visible,/turf/simulated/floor,/area/atmos) "bTr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/turf/simulated/floor/plating,/area/atmos) -"bTs" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/yellow/visible{},/turf/simulated/floor/plating,/area/atmos) +"bTs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/cyan/visible,/turf/simulated/floor/plating,/area/atmos) "bTt" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/atmos) -"bTu" = (/obj/machinery/atmospherics/pipe/simple/green/visible{},/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/atmos) +"bTu" = (/obj/machinery/atmospherics/pipe/manifold/general/visible,/obj/machinery/meter,/turf/simulated/floor{icon_state = "white"},/area/toxins/mixing) "bTv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/manifold/cyan/visible{dir = 4; initialize_directions = 11},/turf/simulated/floor/plating,/area/atmos) "bTw" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "bTx" = (/obj/machinery/camera{c_tag = "Testing Lab South"; dir = 8; network = list("SS13","RD"); pixel_y = -22},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor,/area/toxins/misc_lab) @@ -5104,12 +5103,12 @@ "bUh" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor,/area/hallway/primary/central) "bUi" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 6; initialize_directions = 6},/turf/simulated/floor,/area/atmos) "bUj" = (/obj/machinery/atmospherics/pipe/manifold/cyan/visible{dir = 4; initialize_directions = 11},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"bUk" = (/obj/machinery/atmospherics/pipe/simple/yellow/visible{},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) +"bUk" = (/obj/machinery/atmospherics/pipe/manifold/general/visible,/turf/simulated/floor,/area/medical/sleeper) "bUl" = (/obj/machinery/atmospherics/pipe/simple/yellow/visible{dir = 6},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) "bUm" = (/obj/machinery/atmospherics/pipe/manifold/yellow/visible{dir = 1},/turf/simulated/floor,/area/atmos) -"bUn" = (/obj/machinery/atmospherics/pipe/simple/green/visible{},/obj/machinery/atmospherics/pipe/simple/yellow/visible{dir = 4},/turf/simulated/floor,/area/atmos) +"bUn" = (/obj/machinery/atmospherics/pipe/simple/green/visible,/turf/simulated/floor,/area/atmos) "bUo" = (/obj/machinery/atmospherics/binary/pump{dir = 8; name = "N2O Outlet Pump"; on = 0},/turf/simulated/floor{icon_state = "escape"; dir = 5},/area/atmos) -"bUp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/cyan/visible{},/obj/machinery/atmospherics/pipe/simple/yellow/visible{dir = 4},/turf/simulated/floor/plating,/area/atmos) +"bUp" = (/obj/machinery/atmospherics/pipe/simple/green/visible,/obj/machinery/atmospherics/pipe/simple/yellow/visible{dir = 4},/turf/simulated/floor,/area/atmos) "bUq" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 0; frequency = 1441; id_tag = "n2o_out"; initialize_directions = 1; internal_pressure_bound = 4000; on = 1; pressure_checks = 2; pump_direction = 0},/turf/simulated/floor/engine/n20,/area/atmos) "bUr" = (/turf/simulated/floor/engine/n20,/area/atmos) "bUs" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) @@ -5136,12 +5135,12 @@ "bUN" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) "bUO" = (/obj/structure/disposalpipe/trunk{dir = 4},/obj/structure/disposaloutlet{dir = 8},/turf/simulated/floor/plating/airless,/area/space) "bUP" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating/airless,/area/space) -"bUQ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/insulated{dir = 5},/turf/simulated/floor/plating/airless,/area/space) -"bUR" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 4},/turf/simulated/floor/plating/airless,/area/space) +"bUQ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/reagent_dispensers/fueltank,/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/plating,/area/maintenance/incinerator) +"bUR" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/closet/emcloset,/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{dir = 4},/turf/simulated/floor/plating,/area/maintenance/incinerator) "bUS" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/binary/pump{dir = 8; name = "Gas Pump"; on = 1},/turf/simulated/floor/plating/airless,/area/space) -"bUT" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 4},/turf/simulated/floor/plating,/area/maintenance/incinerator) -"bUU" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 4},/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/maintenance/incinerator) -"bUV" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/insulated{dir = 10},/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/incinerator) +"bUT" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,/turf/simulated/floor/plating,/area/maintenance/incinerator) +"bUU" = (/obj/machinery/atmospherics/pipe/simple/yellow/visible{dir = 4},/turf/simulated/wall/r_wall,/area/maintenance/incinerator) +"bUV" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,/obj/machinery/atmospherics/pipe/simple/yellow/visible{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "bUW" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/obj/structure/sign/deathsposal{pixel_y = 32},/turf/simulated/floor/plating,/area/maintenance/incinerator) "bUX" = (/obj/machinery/atmospherics/pipe/tank/toxins{volume = 3200},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "bUY" = (/obj/machinery/atmospherics/pipe/tank/oxygen{volume = 3200},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) @@ -5166,14 +5165,14 @@ "bVr" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bVs" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/atmos{name = "Atmospherics"; req_access_txt = "24"},/turf/simulated/floor,/area/atmos) "bVt" = (/obj/machinery/atmospherics/binary/pump{dir = 8; name = "Air to External"; on = 1},/turf/simulated/floor,/area/atmos) -"bVu" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{},/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/turf/simulated/floor,/area/atmos) +"bVu" = (/obj/machinery/atmospherics/pipe/manifold/general/visible,/obj/item/weapon/cigbutt,/turf/simulated/floor,/area/atmos) "bVv" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 9},/turf/simulated/floor,/area/atmos) "bVw" = (/obj/item/device/radio/beacon,/turf/simulated/floor,/area/atmos) "bVx" = (/obj/machinery/atmospherics/binary/pump{dir = 0; name = "Air to Port"; on = 0},/turf/simulated/floor,/area/atmos) "bVy" = (/obj/machinery/atmospherics/binary/pump{dir = 0; name = "Mix to Port"; on = 0},/turf/simulated/floor,/area/atmos) "bVz" = (/obj/machinery/atmospherics/binary/pump{dir = 0; name = "Pure to Port"; on = 0},/turf/simulated/floor,/area/atmos) -"bVA" = (/obj/machinery/atmospherics/pipe/simple/yellow/visible{},/turf/simulated/floor,/area/atmos) -"bVB" = (/obj/machinery/atmospherics/pipe/simple/green/visible{},/turf/simulated/floor,/area/atmos) +"bVA" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,/turf/simulated/floor,/area/atmos) +"bVB" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible,/turf/simulated/floor,/area/atmos) "bVC" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "n2o_in"; name = "Nitrous Oxide Supply Control"; output_tag = "n2o_out"; sensors = list("n2o_sensor" = "Tank")},/turf/simulated/floor{icon_state = "escape"; dir = 4},/area/atmos) "bVD" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "n2o_sensor"},/turf/simulated/floor/engine/n20,/area/atmos) "bVE" = (/obj/machinery/portable_atmospherics/canister/sleeping_agent,/turf/simulated/floor/engine/n20,/area/atmos) @@ -5204,7 +5203,7 @@ "bWd" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/asmaint2) "bWe" = (/turf/simulated/wall/r_wall,/area/maintenance/incinerator) "bWf" = (/obj/structure/sign/nosmoking_2{pixel_x = -28},/turf/simulated/floor/plating,/area/maintenance/incinerator) -"bWg" = (/obj/machinery/atmospherics/pipe/simple/insulated,/turf/simulated/floor/plating,/area/maintenance/incinerator) +"bWg" = (/obj/machinery/embedded_controller/radio/access_controller{exterior_door_tag = "incinerator_airlock_exterior"; id_tag = "incinerator_access_control"; interior_door_tag = "incinerator_airlock_interior"; name = "Incinerator Access Console"; pixel_x = -26; pixel_y = 6; req_access_txt = "12"},/obj/machinery/ignition_switch{id = "Incinerator"; pixel_x = -24; pixel_y = -6},/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/yellow/visible{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "bWh" = (/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "bWi" = (/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "bWj" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/simulated/floor/plating,/area/maintenance/aft) @@ -5228,11 +5227,11 @@ "bWB" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor,/area/atmos) "bWC" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/suit/hazardvest,/obj/item/clothing/suit/hazardvest,/obj/item/clothing/suit/hazardvest,/obj/item/clothing/suit/hazardvest,/obj/item/clothing/gloves/black,/obj/item/clothing/gloves/black,/obj/item/clothing/gloves/black,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/turf/simulated/floor,/area/atmos) "bWD" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{dir = 8},/turf/simulated/floor,/area/atmos) -"bWE" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) +"bWE" = (/obj/machinery/atmospherics/pipe/manifold/cyan/visible,/turf/simulated/floor,/area/atmos) "bWF" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{dir = 4; initialize_directions = 11},/turf/simulated/floor,/area/atmos) "bWG" = (/obj/machinery/atmospherics/trinary/filter{dir = 1; filter_type = 4; on = 1},/turf/simulated/floor,/area/atmos) "bWH" = (/obj/machinery/atmospherics/pipe/simple/green/visible{dir = 4},/turf/simulated/floor{icon_state = "escape"; dir = 6},/area/atmos) -"bWI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/cyan/visible{},/obj/machinery/atmospherics/pipe/simple/green/visible{dir = 4},/turf/simulated/floor/plating,/area/atmos) +"bWI" = (/obj/machinery/atmospherics/pipe/simple/green/visible,/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/atmos) "bWJ" = (/obj/machinery/atmospherics/unary/outlet_injector/on{dir = 8; frequency = 1441; id = "n2o_in"; pixel_y = 1},/turf/simulated/floor/engine/n20,/area/atmos) "bWK" = (/obj/structure/rack,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bWL" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor,/area/quartermaster/office) @@ -5254,12 +5253,12 @@ "bXb" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5},/turf/simulated/wall,/area/maintenance/asmaint) "bXc" = (/obj/machinery/door/poddoor{id = "disvent"; name = "Incinerator Vent"},/turf/simulated/floor/engine/vacuum,/area/maintenance/incinerator) "bXd" = (/obj/machinery/atmospherics/unary/outlet_injector/on{dir = 4; frequency = 1443; id = "air_in"},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/engine/vacuum,/area/maintenance/incinerator) -"bXe" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 4},/turf/simulated/wall/r_wall,/area/maintenance/incinerator) +"bXe" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible,/turf/simulated/floor{icon_state = "arrival"; dir = 10},/area/atmos) "bXf" = (/obj/machinery/atmospherics/binary/pump{dir = 8; on = 1},/obj/machinery/access_button{command = "cycle_exterior"; layer = 3.1; master_tag = "incinerator_access_control"; name = "Incinerator airlock control"; pixel_x = -22; pixel_y = -10},/obj/structure/sign/fire{pixel_y = 32},/turf/simulated/floor/plating,/area/maintenance/incinerator) -"bXg" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 4},/obj/machinery/embedded_controller/radio/access_controller{exterior_door_tag = "incinerator_airlock_exterior"; id_tag = "incinerator_access_control"; interior_door_tag = "incinerator_airlock_interior"; name = "Incinerator Access Console"; pixel_x = -26; pixel_y = 6; req_access_txt = "12"},/obj/machinery/ignition_switch{id = "Incinerator"; pixel_x = -24; pixel_y = -6},/obj/machinery/meter,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"bXh" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 4},/obj/machinery/atmospherics/pipe/simple/insulated,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"bXi" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"bXj" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) +"bXg" = (/obj/machinery/atmospherics/pipe/manifold/yellow/visible,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) +"bXh" = (/obj/machinery/atmospherics/pipe/simple/yellow/visible{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) +"bXi" = (/obj/machinery/atmospherics/pipe/simple/green/visible,/obj/machinery/portable_atmospherics/pump,/turf/simulated/floor{icon_state = "red"; dir = 10},/area/atmos) +"bXj" = (/obj/machinery/atmospherics/pipe/simple/green/visible{dir = 4},/obj/machinery/atmospherics/pipe/simple/cyan/visible,/turf/simulated/floor,/area/atmos) "bXk" = (/obj/machinery/atmospherics/portables_connector/visible{dir = 8},/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "bXl" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/maintenance/aft) "bXm" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/simulated/floor/plating,/area/maintenance/aft) @@ -5280,7 +5279,7 @@ "bXB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bXC" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{dir = 9},/obj/machinery/door/poddoor/preopen{id = "atmos"; name = "atmos blast door"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/atmos) "bXD" = (/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30},/turf/simulated/floor,/area/atmos) -"bXE" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/camera{c_tag = "Atmospherics West"; dir = 8; network = list("SS13")},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor,/area/atmos) +"bXE" = (/obj/machinery/atmospherics/pipe/simple/green/visible,/obj/machinery/portable_atmospherics/pump,/turf/simulated/floor,/area/atmos) "bXF" = (/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/machinery/atmospherics/binary/pump{dir = 0; name = "Air to Port"; on = 0},/obj/machinery/light{dir = 8},/turf/simulated/floor,/area/atmos) "bXG" = (/obj/machinery/light{dir = 4},/turf/simulated/floor,/area/atmos) "bXH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/asmaint) @@ -5367,13 +5366,13 @@ "bZk" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor{tag = "icon-warningcorner (EAST)"; icon_state = "warningcorner"; dir = 4},/area/toxins/misc_lab) "bZl" = (/obj/structure/closet/crate,/obj/item/clothing/under/color/lightpurple,/obj/item/weapon/spacecash/c200,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bZm" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; external_pressure_bound = 0; initialize_directions = 1; internal_pressure_bound = 4000; on = 1; pressure_checks = 2; pump_direction = 0},/turf/simulated/floor/engine/vacuum,/area/maintenance/incinerator) -"bZn" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 4},/turf/simulated/wall/r_wall,/area/maintenance/incinerator) +"bZn" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/manifold/yellow/visible,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "bZo" = (/obj/machinery/atmospherics/binary/pump{dir = 4; on = 1},/obj/structure/sign/fire{pixel_y = -32},/obj/machinery/access_button{command = "cycle_interior"; master_tag = "incinerator_access_control"; name = "Incinerator airlock control"; pixel_x = 24; pixel_y = 8},/turf/simulated/floor/plating,/area/maintenance/incinerator) -"bZp" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 4},/obj/machinery/door_control{id = "disvent"; name = "Incinerator Vent Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "12"},/obj/machinery/meter,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"bZq" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{},/obj/machinery/light,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) +"bZp" = (/obj/machinery/door_control{id = "disvent"; name = "Incinerator Vent Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "12"},/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/yellow/visible{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) +"bZq" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/cyan/visible,/turf/space,/area/space) "bZr" = (/obj/machinery/atmospherics/valve{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"bZs" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"bZt" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 4},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) +"bZs" = (/obj/machinery/atmospherics/valve/open{tag = "icon-mvalve_map (EAST)"; icon_state = "mvalve_map"; dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/medical/virology) +"bZt" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (NORTH)"; dir = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint) "bZu" = (/obj/machinery/atmospherics/portables_connector/visible{dir = 8},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "bZv" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/maintenance/aft) "bZw" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area/maintenance/aft) @@ -5444,7 +5443,7 @@ "caJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/port) "caK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/port) "caL" = (/obj/machinery/power/apc{dir = 8; name = "Atmospherics APC"; pixel_x = -24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor,/area/atmos) -"caM" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/atmos) +"caM" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/yellow/visible,/turf/space,/area/space) "caN" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{dir = 4; initialize_directions = 11},/obj/item/weapon/wrench,/turf/simulated/floor,/area/atmos) "caO" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{dir = 8},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) "caP" = (/obj/machinery/atmospherics/trinary/filter{dir = 1; on = 1},/turf/simulated/floor,/area/atmos) @@ -5492,7 +5491,7 @@ "cbF" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/toxins/misc_lab) "cbG" = (/obj/machinery/atmospherics/trinary/filter{dir = 4; req_access = null},/turf/simulated/floor/engine,/area/toxins/misc_lab) "cbH" = (/obj/machinery/door/airlock/engineering{name = "Aft Port Solar Access"; req_access_txt = "10"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/portsolar) -"cbI" = (/obj/machinery/requests_console{department = "Atmospherics"; departmentType = 4; name = "Atmos RC"; pixel_x = 30; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor,/area/atmos) +"cbI" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/green/visible,/turf/space,/area/space) "cbJ" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/camera{c_tag = "Atmospherics Central"; dir = 4; network = list("SS13")},/obj/machinery/atmospherics/binary/pump{dir = 0; name = "Port to Filter"; on = 0},/turf/simulated/floor,/area/atmos) "cbK" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{dir = 8},/obj/structure/stool,/turf/simulated/floor,/area/atmos) "cbL" = (/obj/machinery/atmospherics/unary/heat_reservoir/heater{dir = 8},/turf/simulated/floor,/area/atmos) @@ -5543,7 +5542,7 @@ "ccE" = (/obj/machinery/space_heater,/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/atmos) "ccF" = (/obj/machinery/space_heater,/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/atmos) "ccG" = (/obj/machinery/atmospherics/binary/pump{dir = 8; name = "Port to Filter"; on = 0},/turf/simulated/floor,/area/atmos) -"ccH" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{},/obj/item/weapon/cigbutt,/turf/simulated/floor,/area/atmos) +"ccH" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible,/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/atmos) "ccI" = (/obj/machinery/atmospherics/unary/cold_sink/freezer{dir = 8},/turf/simulated/floor,/area/atmos) "ccJ" = (/obj/machinery/atmospherics/binary/pump{dir = 8; name = "CO2 Outlet Pump"; on = 0},/turf/simulated/floor{dir = 5; icon_state = "yellow"},/area/atmos) "ccK" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 0; frequency = 1441; id_tag = "co2_out"; initialize_directions = 1; internal_pressure_bound = 4000; on = 1; pressure_checks = 2; pump_direction = 0},/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/atmos) @@ -5643,7 +5642,7 @@ "ceA" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 6},/turf/simulated/floor/plating,/area/maintenance/port) "ceB" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor,/area/atmos) "ceC" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"ceD" = (/obj/machinery/atmospherics/pipe/manifold/cyan/visible{},/turf/simulated/floor,/area/atmos) +"ceD" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/yellow/visible,/turf/simulated/floor/plating,/area/atmos) "ceE" = (/obj/machinery/atmospherics/trinary/mixer{dir = 4; node1_concentration = 0.8; node2_concentration = 0.2; on = 1; pixel_x = 0; pixel_y = 0; target_pressure = 4500},/turf/simulated/floor,/area/atmos) "ceF" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/obj/machinery/atmospherics/binary/pump{dir = 1; name = "O2 to Pure"; on = 0},/turf/simulated/floor,/area/atmos) "ceG" = (/obj/machinery/atmospherics/trinary/filter{dir = 1; filter_type = 3; on = 1},/turf/simulated/floor,/area/atmos) @@ -5698,7 +5697,7 @@ "cfD" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor,/area/aisat) "cfE" = (/obj/structure/stool/bed/chair,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "cfF" = (/obj/machinery/atmospherics/trinary/filter{dir = 2; filter_type = 2; on = 1},/turf/simulated/floor,/area/atmos) -"cfG" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible{},/turf/simulated/floor,/area/atmos) +"cfG" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/green/visible,/turf/simulated/floor/plating,/area/atmos) "cfH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cfI" = (/obj/machinery/door/airlock/external{req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cfJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 0},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint) @@ -5734,8 +5733,8 @@ "cgn" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/port) "cgo" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 9},/turf/simulated/floor/plating,/area/maintenance/port) "cgp" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/port) -"cgq" = (/obj/machinery/atmospherics/pipe/simple/green/visible{},/obj/machinery/portable_atmospherics/pump,/turf/simulated/floor,/area/atmos) -"cgr" = (/obj/machinery/atmospherics/pipe/simple/green/visible{dir = 4},/obj/machinery/atmospherics/pipe/simple/cyan/visible{},/turf/simulated/floor,/area/atmos) +"cgq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/turf/simulated/floor,/area/atmos) +"cgr" = (/obj/machinery/atmospherics/pipe/simple/yellow/visible,/turf/simulated/floor,/area/atmos) "cgs" = (/obj/machinery/atmospherics/pipe/simple/green/visible{dir = 4},/turf/simulated/floor,/area/atmos) "cgt" = (/obj/machinery/atmospherics/trinary/filter{dir = 4; filter_type = 1; on = 1},/turf/simulated/floor,/area/atmos) "cgu" = (/obj/machinery/atmospherics/pipe/simple/green/visible{dir = 4; initialize_directions = 12},/turf/simulated/floor,/area/atmos) @@ -5744,7 +5743,7 @@ "cgx" = (/obj/machinery/portable_atmospherics/canister,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/maintenance/asmaint) "cgy" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/port) "cgz" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/maintenance/asmaint) -"cgA" = (/obj/machinery/door/airlock/maintenance{name = "Biohazard Disposals"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"cgA" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/asmaint) "cgB" = (/obj/machinery/power/apc{dir = 1; name = "Locker Room APC"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/crew_quarters/locker) "cgC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cgD" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/asmaint2) @@ -5775,14 +5774,14 @@ "chc" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden,/turf/simulated/wall,/area/maintenance/disposal) "chd" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor{dir = 8; icon_state = "loadingarea"},/area/quartermaster/office) "che" = (/obj/machinery/portable_atmospherics/scrubber,/turf/simulated/floor,/area/atmos) -"chf" = (/obj/machinery/atmospherics/pipe/simple/green/visible{},/obj/machinery/portable_atmospherics/pump,/turf/simulated/floor{icon_state = "red"; dir = 10},/area/atmos) +"chf" = (/obj/machinery/atmospherics/pipe/simple/yellow/visible,/obj/machinery/meter,/turf/simulated/floor,/area/atmos) "chg" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "n2_in"; name = "Nitrogen Supply Control"; output_tag = "n2_out"; sensors = list("n2_sensor" = "Tank")},/turf/simulated/floor{icon_state = "red"},/area/atmos) "chh" = (/obj/machinery/atmospherics/binary/pump{dir = 1; name = "N2 Outlet Pump"; on = 1},/turf/simulated/floor{icon_state = "red"; dir = 6},/area/atmos) "chi" = (/obj/machinery/light,/turf/simulated/floor,/area/atmos) -"chj" = (/obj/machinery/atmospherics/pipe/simple/green/visible{},/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/atmos) +"chj" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/camera{c_tag = "Atmospherics West"; dir = 8; network = list("SS13")},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor,/area/atmos) "chk" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "o2_in"; name = "Oxygen Supply Control"; output_tag = "o2_out"; sensors = list("o2_sensor" = "Tank")},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/atmos) "chl" = (/obj/machinery/atmospherics/binary/pump{dir = 1; name = "O2 Outlet Pump"; on = 1},/turf/simulated/floor{icon_state = "blue"; dir = 6},/area/atmos) -"chm" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible{},/turf/simulated/floor{icon_state = "arrival"; dir = 10},/area/atmos) +"chm" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "chn" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1443; input_tag = "air_in"; name = "Mixed Air Supply Control"; output_tag = "air_out"; pressure_setting = 2000; sensors = list("air_sensor" = "Tank")},/turf/simulated/floor{icon_state = "arrival"},/area/atmos) "cho" = (/obj/machinery/camera{c_tag = "Atmospherics South East"; dir = 1},/obj/machinery/atmospherics/binary/pump{dir = 1; name = "Air Outlet Pump"; on = 1},/turf/simulated/floor{icon_state = "arrival"; dir = 6},/area/atmos) "chp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/asmaint) @@ -5836,10 +5835,10 @@ "cil" = (/obj/machinery/door/airlock/maintenance{name = "Cargo Bay Maintenance"; req_access_txt = "31"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/quartermaster/storage) "cim" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/turf/simulated/floor,/area/quartermaster/office) "cin" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/atmos) -"cio" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/green/visible{},/turf/simulated/floor/plating,/area/atmos) +"cio" = (/obj/machinery/atmospherics/pipe/manifold/general/visible,/obj/machinery/meter,/turf/simulated/floor,/area/atmos) "cip" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/atmos) -"ciq" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/yellow/visible{},/turf/simulated/floor/plating,/area/atmos) -"cir" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible{},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/atmos) +"ciq" = (/obj/machinery/atmospherics/pipe/simple/cyan/hidden{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"cir" = (/obj/machinery/requests_console{department = "Atmospherics"; departmentType = 4; name = "Atmos RC"; pixel_x = 30; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor,/area/atmos) "cis" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/atmos) "cit" = (/obj/structure/disposalpipe/sortjunction{dir = 1; icon_state = "pipe-j2s"; sortType = 2},/obj/structure/noticeboard{pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor,/area/quartermaster/office) "ciu" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor{icon_state = "bot"},/area/quartermaster/office) @@ -5908,9 +5907,9 @@ "cjF" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor,/area/engine/engineering) "cjG" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "cjH" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor,/area/engine/engineering) -"cjI" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/green/visible{},/turf/space,/area/space) -"cjJ" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/yellow/visible{},/turf/space,/area/space) -"cjK" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/cyan/visible{},/turf/space,/area/space) +"cjI" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/atmos) +"cjJ" = (/obj/structure/table,/obj/item/stack/sheet/plasteel{amount = 10},/obj/item/stack/cable_coil,/obj/item/device/flash/handheld,/obj/item/device/flash/handheld,/turf/simulated/floor,/area/assembly/robotics) +"cjK" = (/obj/structure/table,/obj/item/device/flashlight{pixel_x = 1; pixel_y = 5},/obj/item/device/flashlight{pixel_x = 1; pixel_y = 5},/obj/item/device/flash/handheld,/obj/item/device/flash/handheld,/obj/machinery/ai_status_display{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plating,/area/storage/tech) "cjL" = (/obj/machinery/light/small,/turf/simulated/floor/plating,/area/maintenance/asmaint) "cjM" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cjN" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (EAST)"; dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) @@ -5963,7 +5962,7 @@ "ckI" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/starboardsolar) "ckJ" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/solar/port) "ckK" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/maintenance/portsolar) -"ckL" = (/obj/item/clothing/under/rank/vice,/obj/structure/closet,/turf/simulated/floor/plating,/area/maintenance/aft) +"ckL" = (/obj/structure/table,/obj/item/device/flash/handheld,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) "ckM" = (/obj/machinery/flasher{id = "shuttle_flasher"; pixel_x = -24; pixel_y = 6},/obj/machinery/flasher_button{id = "shuttle_flasher"; pixel_x = -24; pixel_y = -6},/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) "ckN" = (/turf/simulated/wall/r_wall,/area/engine/gravity_generator) "ckO" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5},/turf/simulated/floor,/area/engine/engineering) @@ -6715,7 +6714,7 @@ "czg" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) "czh" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) "czi" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/stamp,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) -"czj" = (/obj/structure/table,/obj/item/device/flash,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) +"czj" = (/obj/structure/closet/secure_closet/hos,/turf/simulated/floor/carpet,/area/security/hos) "czk" = (/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) "czl" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor,/area/centcom/evac) "czm" = (/turf/space,/area/shuttle/escape_pod3/centcom) @@ -7093,7 +7092,7 @@ "cGu" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/maintenance{name = "Xenobiology Maintenance"; req_access_txt = "55"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/toxins/xenobiology) "cGv" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden,/turf/simulated/floor,/area/engine/engineering) "cGw" = (/obj/structure/table,/obj/item/weapon/book/manual/wiki/engineering_guide,/obj/item/weapon/book/manual/engineering_particle_accelerator{pixel_y = 6},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor,/area/engine/engineering) -"cGx" = (/obj/structure/table,/obj/item/device/flashlight{pixel_x = 1; pixel_y = 5},/obj/item/device/flashlight{pixel_x = 1; pixel_y = 5},/obj/item/device/flash,/obj/item/device/flash,/obj/machinery/ai_status_display{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plating,/area/storage/tech) +"cGx" = (/obj/machinery/alarm{pixel_y = 23},/obj/structure/reagent_dispensers/peppertank{pixel_x = 30; pixel_y = 0},/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka{pixel_x = 6; pixel_y = 6},/obj/item/weapon/reagent_containers/food/drinks/drinkingglass{pixel_x = -4; pixel_y = 3},/obj/item/weapon/reagent_containers/food/drinks/drinkingglass,/turf/simulated/floor/carpet,/area/security/hos) "cGy" = (/obj/item/device/transfer_valve{pixel_x = -5},/obj/item/device/transfer_valve{pixel_x = -5},/obj/item/device/transfer_valve{pixel_x = 0},/obj/item/device/transfer_valve{pixel_x = 0},/obj/item/device/transfer_valve{pixel_x = 5},/obj/item/device/transfer_valve{pixel_x = 5},/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_x = 0; pixel_y = -30},/obj/structure/table/reinforced,/turf/simulated/floor{icon_state = "white"},/area/toxins/mixing) "cGz" = (/obj/structure/stool/bed/chair{dir = 8},/obj/effect/landmark/start{name = "Assistant"},/turf/simulated/floor,/area/quartermaster/office) "cGA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/medical/medbay) @@ -7131,7 +7130,7 @@ "cHg" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/turf/simulated/floor/wood,/area/crew_quarters/captain) "cHh" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/medbay) "cHi" = (/obj/machinery/door/window{dir = 1; name = "Secure Storage"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) -"cHj" = (/obj/machinery/ai_status_display{pixel_x = 32; pixel_y = 0},/obj/structure/table,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) +"cHj" = (/obj/structure/stool/bed/chair/comfy/black,/turf/simulated/floor/carpet,/area/security/hos) "cHk" = (/obj/structure/bookcase,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "cHl" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "cHm" = (/obj/structure/table/woodentable,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) @@ -7499,7 +7498,7 @@ "cOk" = (/obj/item/weapon/shard,/obj/item/weapon/module/power_control,/turf/simulated/floor/plating/airless,/area/AIsattele) "cOl" = (/obj/structure/closet,/turf/simulated/floor/plating/airless,/area/AIsattele) "cOm" = (/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = -1},/turf/simulated/floor/plating/airless,/area/AIsattele) -"cOn" = (/obj/structure/closet/wardrobe/hos,/turf/simulated/floor/carpet,/area/security/hos) +"cOn" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/cyan/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cOo" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating/airless,/area/AIsattele) "cOp" = (/obj/machinery/power/solar/fake,/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/djstation/solars) "cOq" = (/turf/simulated/floor/plating/airless,/area/djstation/solars) @@ -8838,7 +8837,7 @@ "dnX" = (/turf/simulated/wall/r_wall,/area/mine/explored) "dnY" = (/turf/simulated/wall/r_wall,/area/mine/production) "dnZ" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/engine/break_room) -"doa" = (/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/pen,/turf/simulated/floor,/area/security/main) +"doa" = (/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/weapon/pen,/turf/simulated/floor,/area/security/main) "dob" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor,/area/mine/production) "doc" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/mine/production) "dod" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/mine/production) @@ -8870,7 +8869,7 @@ "doD" = (/obj/machinery/power/port_gen/pacman,/obj/structure/cable,/turf/simulated/floor{dir = 6; icon_state = "yellow"},/area/ai_monitored/storage/secure) "doE" = (/obj/structure/rack,/obj/item/clothing/suit/armor/bulletproof{pixel_x = -4; pixel_y = 3},/obj/item/clothing/suit/armor/laserproof,/turf/simulated/floor{dir = 2; icon_state = "bot"},/area/ai_monitored/security/armory) "doF" = (/obj/structure/rack,/obj/item/weapon/storage/box/chemimp{pixel_x = 4; pixel_y = 3},/obj/item/weapon/storage/box/trackimp,/obj/item/weapon/storage/box/teargas,/turf/simulated/floor{dir = 2; icon_state = "bot"},/area/ai_monitored/security/armory) -"doG" = (/obj/structure/rack,/obj/item/weapon/gun/projectile/shotgun{desc = "Primarily used as a non-letheal alternative to riot control."; name = "riot shotgun"},/obj/item/weapon/gun/projectile/shotgun{desc = "Primarily used as a non-letheal alternative to riot control."; name = "riot shotgun"; pixel_x = 3; pixel_y = 3},/turf/simulated/floor{dir = 2; icon_state = "bot"},/area/ai_monitored/security/armory) +"doG" = (/obj/structure/rack,/obj/item/weapon/gun/projectile/shotgun/riot{pixel_x = 3; pixel_y = 3},/obj/item/weapon/gun/projectile/shotgun/riot,/turf/simulated/floor{dir = 2; icon_state = "bot"},/area/ai_monitored/security/armory) "doH" = (/obj/structure/table,/obj/item/stack/sheet/mineral/plasma{layer = 2.9},/turf/simulated/floor{icon_state = "yellow"},/area/ai_monitored/storage/secure) "doI" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/wiki/security_space_law,/turf/simulated/floor/carpet,/area/security/hos) "doJ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 0; pixel_y = 0},/turf/simulated/wall/r_wall,/area/space) @@ -8893,14 +8892,14 @@ "dpa" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/turf/simulated/floor,/area/engine/break_room) "dpb" = (/obj/machinery/atmospherics/pipe/manifold{dir = 4},/obj/machinery/mineral/labor_points_checker,/turf/simulated/wall,/area/mine/laborcamp) "dpc" = (/obj/machinery/computer/shuttle/ferry/request,/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) -"dpd" = (/obj/machinery/alarm{pixel_y = 23},/obj/structure/reagent_dispensers/peppertank{pixel_x = 30; pixel_y = 0},/obj/structure/closet/secure_closet/hos,/turf/simulated/floor/carpet,/area/security/hos) +"dpd" = (/obj/machinery/door/airlock/maintenance{name = "Biohazard Disposals"; req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint) "dpe" = (/obj/machinery/computer/mech_bay_power_console,/turf/unsimulated/floor/plating,/area/syndicate_mothership) "dpf" = (/turf/unsimulated/floor{icon_state = "recharge_floor"; name = "mech bay recharge floor"; tag = "icon-recharge_floor"},/area/syndicate_mothership) "dpg" = (/obj/machinery/door/airlock/glass_large{name = "Equipment Room"; opacity = 1; req_access_txt = "150"; text = "g"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "dph" = (/obj/machinery/door/window{dir = 4; name = "EVA Storage"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) "dpi" = (/obj/structure/stool,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) "dpj" = (/obj/machinery/door/airlock/centcom{name = "Transport Shuttle"; opacity = 1; req_access_txt = "109"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/ferry) -"dpk" = (/obj/structure/stool/bed/chair/office/dark,/turf/simulated/floor/carpet,/area/security/hos) +"dpk" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/general/hidden{tag = "icon-manifold (NORTH)"; icon_state = "manifold"; dir = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint) "dpl" = (/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plating,/area/security/prison) "dpm" = (/obj/structure/table,/obj/item/weapon/c4{pixel_x = 2; pixel_y = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) "dpn" = (/obj/item/weapon/soap/syndie,/obj/structure/mopbucket,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) @@ -8919,7 +8918,7 @@ "dpA" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/wall/r_wall,/area/atmos) "dpB" = (/obj/machinery/atmospherics/portables_connector/visible{dir = 8},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/medical/virology) "dpC" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/medical/virology) -"dpD" = (/obj/machinery/atmospherics/valve{dir = 4; icon_state = "valve1"; open = 1; openDuringInit = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/medical/virology) +"dpD" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 9},/turf/simulated/floor/plating,/area/maintenance/asmaint) "dpE" = (/obj/machinery/camera{c_tag = "Atmospherics South West"; dir = 4; network = list("SS13")},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor,/area/atmos) "dpF" = (/obj/structure/table,/obj/item/clothing/glasses/meson,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor,/area/engine/break_room) "dpG" = (/obj/machinery/bot/secbot/pingsky,/turf/simulated/floor/carpet,/area/turret_protected/aisat_interior) @@ -9192,6 +9191,12 @@ "duN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/aft) "duO" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/obj/item/weapon/wrench,/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (WEST)"; dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/medical/virology) "duP" = (/obj/machinery/door/airlock/maintenance_hatch{req_access_txt = "65"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/aisat_interior) +"duQ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"duR" = (/obj/machinery/atmospherics/pipe/simple/general/hidden{dir = 9},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"duS" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint) +"duT" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint) +"duU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint) +"duV" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating/airless,/area/space) (1,1,1) = {" ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl @@ -9265,8 +9270,8 @@ ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlah ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaiJaiNajlajxaiJdsiaaiaaiamHaaxaaqaaqaayaazaaxaaqaataaAaaiahlaahahjahlahlahlahlahlahlahlahjahjahjahjahjahlahjahlahjahlahjahlahlahlahlahlahldsiahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaiJaiKaikaiIaiJdsiaaiaaBaaqaaqaaqaaxaaCafYaaqaaqaaEaaFaaiaaiaaiahjahlahlahlahlahlahjahlaahahlahlahlahjahjahjahjahjahjahjahjahlahlahlahlahldsiahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXdpXdpXaaHaaHahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaiJaiMaiLaiMaiJdsiaaiaaIaaqaaJaaqaaqaaqaaqaaqaaqaaKaaqaaLaaMaaiahjahjahjahjahjahjahjahjabkabkablabkabkaaNaaNaaOaaPaaQaaNaaNahlahlahlahlahldsiahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXahlahjahlaaRahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaiJaSyaVqaYTaiJbRJaaiaaSaaqaaqaoFaoEaoDaaqaoKaoHaoGaaqaaVaaWaaiahjahlahlahlahlahlahlahlablafmabBadTagYaaNcuUaaYaaZcOndpdaaNahlahlahlahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXahjabcahjdpXahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlaaHaaHdpXaaHaaHahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaiJbaHbnWbpkaoMaoNaaiabdabeabdabdabdaoUabdabdabdaptabdabdabjaaiahjahlahjahjahjahjahlahjabkabCabBadUafmaaNdnDdpkaboabobmDaaNahlahjabqahjahlahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXdpXdpXdpXdpXahlahlahlabrahlahlahldpXdpXaaHaaHaaHahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaiJaSyaVqaYTaiJbRJaaiaaSaaqaaqaoFaoEaoDaaqaoKaoHaoGaaqaaVaaWaaiahjahlahlahlahlahlahlahlablafmabBadTagYaaNcuUaaYaaZczjcGxaaNahlahlahlahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXahjabcahjdpXahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlaaHaaHdpXaaHaaHahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaiJbaHbnWbpkaoMaoNaaiabdabeabdabdabdaoUabdabdabdaptabdabdabjaaiahjahlahjahjahjahjahlahjabkabCabBadUafmaaNdnDcHjaboabobmDaaNahlahjabqahjahlahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXdpXdpXdpXdpXahlahlahlabrahlahlahldpXdpXaaHaaHaaHahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHahlahjahlaaRahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlajzaoyaiLaovaiJaowaaiabsaaqabtabdabuaorabvabdabwaosabxabdabyaaiabzabzabzabzabzabzabzabzabzabAabBamJafmabDaXPaXMdoIabobwDaaNahlahjabIabJabIahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaRahlahlahjahjahjahlahlabrahjahjahlahjahjahlahlaaHahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXahjabKahjdpXahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahjahjaiJaoCaoAaoBaiJaozaaiabLaaqabPabdabOaorabPabdabQaosabPabdabRaaiabSabTabVabVabWabXabYdoOabzacaabBamJafmacdacebGrbPhabobQsaaNahjahjabIaciabIahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXahjacjacjacjacjacjahjackahjacjacjacjacjacjahjdpXahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHaaHaaHdpXdpXahlahlahlaclahlahlahldpXdpXaaHaaHaaHahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaiJaiJajzajCaiJamtaaiabhacmabfabdabhamIabfabdabhamGabfabdabdaaiabSacpacqacqacqacqdoCdoAabzacsabBamJafmaaNadRacvacwacxacyaaNafOabkacBabJabIabIacCahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXahjacDacEacEacEacEacFacGacHacIacIacIacIacJahjdpXahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl @@ -9284,40 +9289,40 @@ ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlah ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaRahlaePaePaePaePaePahjaegahjaePaePaePaePaePahldpXahlahlahlahlahlahlahlahlahlahlahlahjahlaiCajfajfajfaiCajgajhajiajjajdaiSaiTaeRaeSaiiaeSaeSaiUajoaiWajqaiVajsaiWajqajtajuaiXajqallagSajqagKagJajqajbaiZaiYaeRajDajcaiuajFaiuajGajeaiuahuahvahwahxahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahlahjahlahlajIahlahlahjahlahlahjahlahlahjahjahlahlahlahlahlahlahjahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXahlahjahlahjahjahlahlajJahlahlahjahlahlahjahldpXahlahlahlahlahlahlaaeahlahlahjahjahjahlaiCajKajKajKajLajMajNajMajjaiHahSaifaeRafrahoafraeSajSajTajUaeSajVajTajUaeSajVajTajUaeSagvajXalkajZagFaeSaitaivakbaeRakcaiPakeakfakeakgaiRaiQahuahvahwahXahjahlahlahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahjahjahjahlakkaklakkahlahjahlahlahjahlahlahlahjahjahlahlahlahlahlakmaknakmahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXdpXdpXahlahlahjahlakoakpakoahjahjahjahjdpXdpXdpXahlahlahlahlahlahlahlahlahlahlahlahjahlaiCakqajKajKaiCajgajhakrahnahkaioakvaeRafrahoafraeSakwajTakxaeSakyajTakzaeSakAajTakBaeSakCakDahrajZagqaeSakFajTakGaeRakHairakJakKakHakIaisakJahuahvahwabIabIahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahlakMakNakMahlahjahlahlahjahlahlahlahjahjahjahlahlahlahlakmakOakmahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahjahlahlahlahlahjahlakPakQakPahjahlahjahlahlahjahjahlahlahlahlahlahlahlahlahlahlahlahjahlaiCakRakSakTakUahlahlakVahyakWailalGaeRafragOafraeRalcaldalealfalgaldalealfalgaldalealfakEagLaljajYajWaeRaeRaeRaeRaeRalmaigalmalnalmalmaihalnahuainaimalrabIabIabIahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjalsaltalualtakkahjahjahjahjahlahjahlahlahlahjahjahlahlahlakmalvakmahjahjahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahjahlahlahlahlahjahlakPakQakPahjahlahjahlahlahjahjahlahlahlahlahlahlahlahlahlahlahlahjahlaiCakRakSakTakUahlahlakVahyakWailalGaeRafragOafraeRalcaldalealfalgaldalealfalgaldalealfakEagLaljajYajWaeRaeRaeRaeRaeRalmaigalmalnalmalmaihalnahuainaimanRabIabIabIahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjalsaltalualtakkahjahjahjahjahlahjahlahlahlahjahjahlahlahlakmalvakmahjahjahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahjalwalxalyalzalAahlahjahlahlahjahjahlahlahlahlahlahlahlahlahlahlahlahjahlaiCalBalCalCaiCajgajhalDaijalEahVahWadcaeRaeRaeRaeRalHalHalHalJalHalHalHalIalHalHalHalJalHalHalHalKalKalLalMalMalMalNalmaigalmalnalmalmaihalnabIahvalPadYalQalRalQahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjalSalTakNalUalVahjahlahlahjahlahjahlahlahlahlahjahjahlahlakmalvakmahlahlahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahlahlahlahlahjalWalXalYalZalWamaamaahlahlahjahjahlahlahlahlahlahlahlahlahlahlahlahjahlaiCalCalCalCambamcajNamcajjaiHahSaiHamgalKalKalKagEalKalKamjalKalKalKalKalKalKalKamialKagjalKamhalKalKalKalKalKalKamkalnahRamlammamnalnahUalnamramsahTamuamuamvabIahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjamwamxamyamzamwahjahlahlahjahlahjahlahjahlahlahlahjakmakmakmalvakmakmakmakmakmakmahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahlahlahlahlahjalWalXalYalZalWamaamaahlahlahjahjahlahlahlahlahlahlahlahlahlahlahlahjahlaiCalCalCalCambamcajNamcajjaiHahSaiHamgalKalKalKagEalKalKamjalKalKalKalKalKalKalKamialKagjalKamhalKalKalKalKalKalKamkalnahRamlammamnalnahUalnamrahFahTamuamuamvabIahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjamwamxamyamzamwahjahlahlahjahlahjahlahjahlahlahlahjakmakmakmalvakmakmakmakmakmakmahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlamaamaamaamaamaahjahjalWamAamBamCalWamDamaahlahlahjahjahlahlahlahlahlahlahlahlahlahlahjahjahlaiCamEamEamEaiCajgajhamFagIafZahIahLahyamKamKamKamKamKamLahHamKamKamKamKamKamKamKamNamOamOamOahNamQamOamRagDagCagBalNamSamTahuahuahuahuahuahuabIamWahPabIamYamZabIahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjamwanaanbancamwahjahlahlahjahlahjahlahjakmaknakmaknakmandalvalvalvalvalvalvaneakmahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlamaamaamaamaanfanganhamaahlahlalWaniacZankalWanlamaahlahlahjahjahlahlahlahlahlahlahlahlahlahjahjahlahlaiCanmanmanmaiCahlahjadcaebabUahyahianpanpanqanranqanpanpagZantantantanuantantanvanwanxagXamuagUamuamuamuamuagRamuamuamuamuamuahtahsahqahmanEanEahFahzanHanIahGabIahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlamwanKafDanMamwanNanNanNanNanNanOanPanQakmanRalvaneakmakmalvakmakmakmakmanSakmakmahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlamaamaamaamaanfanganhamaahlahlalWaniacZankalWanlamaahlahlahjahjahlahlahlahlahlahlahlahlahlahjahjahlahlaiCanmanmanmaiCahlahjadcaebabUahyahianpanpanqanranqanpanpagZantantantanuantantanvanwanxagXamuagUamuamuamuamuagRamuamuamuamuamuahtahsahqahmanEanEamsahzanHanIahGabIahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlamwanKafDanMamwanNanNanNanNanNanOanPanQakmalralvaneakmakmalvakmakmakmakmanSakmakmahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahjamaasianUanVanlanWanlamaanXanYalWalWanZaoaalWanlamaamaanXaobaocamaamaahlahjahlahlahlahlahlahlahjahjahlaodaoeaoeaoeaofahlahjahyaKUajNahyaIUanpaomaonaonaonaooanpaJaatXaJcaJeaJdaotantalHalKaouaGQaIPaoxaoxaoxaoxaoxaISaITaoxaoxaoxaoxaoxaIOaIJaIKaIGaIHaIEaIFabIaoIaoJabIahjaIyaANaANaIhaANaANaIgahlahlahlahlahlahjaoOaoPaoOahlanNamwamwaoQaoRamwaoSalvalvalvakmarualvarwakmalvalvalvaoWakmalvakmdtNdtLakmalvaoYakmahlahlahlahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaoZapaapbahlapcapdapeahlahjapfapgapfahlahlahjamaaphapiapjaJZapkapVamaapmanlapnapoasGanlanlanlanlanlanlanlanlanlamaahlappahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahjahyaKUaSvahyaJDanpapuapvapwapxapyanpapsantapzapAaJGapCapDalHalKalMaGQaguaqHaqHaqHaqHaqHaJHanyaqHaqHaqHaqHaqHaqHaqHaqHapQaJsaJAaJgaJgaJgaJgaJgaJfayNapSapSapSapSapSayNapQahlahlahlahlahjapTalvapUahlanNasjapWapXapYalvalvalvakmalvakmapZalvalvakmalvaqaaqbaqcanSalvakmdtPasDakmalvasnakmahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaqfaqgbahaqgaqfaqibcpaqiaqfahjaqkanlaqlahlahlamaamaamaamaamaaLIaHgaEkaEkaLKarqaLOarqaLiaLfaLdasNamaanlamaamaamaanlamaahlahjahlahlahlahlahlahlahjahlahjahjahjahjaogaogaogaogaogaogaogaogaKDanpaquapvaqvaqwaqxanpapsaLcaKVaKFaKEaKGaqBalHalKaXOaGQaguaqHaFsaFtaKxapGaKyaKzaqHaKraqLaKsaqHaqNaKhaKiapQaKqaKlaKmaKdaKfaKaaKbaKgayNapSapSapSapSapSayNapQahjahjahjahjaqYaqZaoParaarbanNasLalvardalvandalvakmakmarfakmakmargakmakmaqcasEarialvakmalvarjarjarjarjarjarjarjarjarjbRJbRJbRJbRJdsibRJbRJahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlarkaqgarlaqgarkaqiarmaqiarkamaarnapgaroaobanYamaaNaaFdaFdaFdaFdaFdaFdaNeaNiamaamaamaamaamablMamaamaanlartamaatzanlamaamaamaahlahlahlahlahlahjahjahjahjahjahlahlaogarvauSaogarxaryarzaogaKDanpaMxaMkaMeaMeaMdarBaMIaMHarGarGaMGarGaMAalHalKarLaGQaguaqHaFHaMJaFBaMYaFDaMWaqHaMVarUaMKaqHarUaLVaLXapQaLYaLZawGaLPaLPaLPaELaLRaLUapSapSapSapSapSaMbapQapQapQahlahlashalvalvalvaoSanNauMaqcardalvatOaskaslanSalvalvalvalvasmalvalvasEasoalvaspalvarjasqbcDassarjastasuasvarjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaoZapaapbahlapcapdapeahlahjapfapgapfahlahlahjamaaphapiapjarqapkapVamaapmanlapnapoasGanlanlanlanlanlanlanlanlanlamaahlappahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahjahyaKUaSvahyaJDanpapuapvapwapxapyanpapsantapzapAaJGapCapDalHalKalMaGQaguaqHaqHaqHaqHaqHaJHanyaqHaqHaqHaqHaqHaqHaqHaqHapQaJsaJAaJgaJgaJgaJgaJgaJfayNapSapSapSapSapSayNapQahlahlahlahlahjapTalvapUahlanNasjapWapXapYalvalvalvakmalvakmapZalvalvakmalvaqaaqbaqcanSalvakmdtPasDakmalvasnakmahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaqfaqgbahaqgaqfaqibcpaqiaqfahjaqkanlaqlahlahlamaamaamaamaamaaLIaFgaGxaGxaLdaJZaLfaJZaLKaLiaLOasNamaanlamaamaamaanlamaahlahjahlahlahlahlahlahlahjahlahjahjahjahjaogaogaogaogaogaogaogaogaKDanpaquapvaqvaqwaqxanpapsaLcaKVaKFaKEaKGaqBalHalKaXOaGQaguaqHaFsaFtaKxapGaKyaKzaqHaKraqLaKsaqHaqNaKhaKiapQaKqaKlaKmaVOaKfaKaaKbaKgayNapSapSapSapSapSayNapQahjahjahjahjaqYaqZaoParaarbanNasLalvardalvandalvakmakmarfakmakmargakmakmaqcasEarialvakmalvarjarjarjarjarjarjarjarjarjbRJbRJbRJbRJdsibRJbRJahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlarkaqgarlaqgarkaqiarmaqiarkamaarnapgaroaobanYamaaNaaFdaFdaFdaFdaFdaFdaNeaNiamaamaamaamaamaaTIamaamaanlartamaatzanlamaamaamaahlahlahlahlahlahjahjahjahjahjahlahlaogarvauSaogarxaryarzaogaKDanpaMxaMkaMeaMeaMdarBaMIaMHarGarGaMGarGaMAalHalKarLaGQaguaqHaFHaMJaFBaMYaFDaMWaqHaMVarUaMKaqHarUaLVaLXapQaLYaLZawGaLPaLPaLPaELaLRaLUapSapSapSapSapSaMbapQapQapQahlahlashalvalvalvaoSanNauMaqcardalvatOaskaslanSalvalvalvalvasmalvalvasEasoalvaspalvarjasqbcDassarjastasuasvarjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlarkaswasxasyarkaszasAasBarkasCanlanlbknbknartasFaEYaGvaEkaEkaEkaEkaEkaEkaEfaEgcUbdsiakjamaavUaplasManlasFamaaoVanlanlanlapfahlahlahlahlahlahjahlahlahjahlaogaogaogapqapqaogapqapqapqaogayganpaEDaEGaEFaEIaEHatTaExaEzantasUaECasWantaEvalKalMaGQaguaqHaqHaqHaqHaqHaEsaEtaqHaEuasYaqDaqHaqHaDNaqDapQataaDMcECaDWaDWaDTaDUaDQaDSapSapSapSapSapSaDLaDKaDJatkahlahlatlalvalvatmalvanNatnalvatoatpatpatpatpatqatpatralvalvalvalvalvalvalvalvakmaskarjatsattattarjbbmavFbgharjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlarkatvatwatxarkatyatwatxarkapVbkrbkoaqoaqoaqobkDbksaEZatDatEatFatGatHamaaEYaEZdsiasIcUbatJaFgatLamaamaamaamaamaamaamaanlatMahjahlahlahlahlahjahlahjdsidsiatNaqeatNapqapqaogaogatPaogaogayganpanpanpaFkanpanpanpaFiaFhantantantantantaFralKauaaGQaguaqHaFsaFtaFnapGaFlaFmaFpaFqaujaFoaKTaulaEJaEKaunarXaDMauoauqauqauraELautauuapSapSapSapSapSauuauvauwauxahjahjakmalvalvakmakmanNanNanNanNanNanNanNanNanNakmauyauzakmakmakmakmakmakmakmaDFaBaaEPaEOaENaEMauBaEQatsauDarjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlaqfarkauEauFaqfarkauGauFaqfamaauHamaamaamaamaamaaEYaEZanlauIaavanlanlamaaEYaEZcUZahjcUZamaaGxatLamaarhauNamaauOapVaGvaEraEkaGlaGsaGpaGpaGpaGpaGraGpaGpaGoaGlaGnaGlaGlaGjaGlaGmaGjaGkaGiaGhauWauWauWauWauWauWauWaFSaFWauWauWauWauWaFRaFJaFOaFOaFQaFGaqHaFHaFIaFBaFCaFDaFEavhaFzavjaFAavlaviaFwaFxavmavnaFyauoauqauqauraELavpavqapSapSapSapSapSavqavrauwauxahlahlakmaqralvalvarcakmaqsaneavvavwandakmatnandakmavzalvakmavAalvakmaqaaqbavBaFuatpatpavCavDavEbjOaFvavHavIarjbRJbRJdsidsibRJbRJbRJbRJahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlarkatvatwatxarkatyatwatxarkapVbkrbkoaqoaqoaqobkDbksaEZatDatEatFatGatHamaaEYaEZdsiasIcUbatJbjzatLamaamaamaamaamaamaamaanlatMahjahlahlahlahlahjahlahjdsidsiatNaqeatNapqapqaogaogatPaogaogayganpanpanpaFkanpanpanpaFiaFhantantantantantaFralKauaaGQaguaqHaFsaFtaFnapGaFlaFmaFpaFqaujaFoaKTaulaEJaEKaunarXaDMauoauqauqauraELautauuapSapSapSapSapSauuauvauwauxahjahjakmalvalvakmakmanNanNanNanNanNanNanNanNanNakmauyauzakmakmakmakmakmakmakmaDFaBaaEPaEOaENaEMauBaEQatsauDarjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlaqfarkauEauFaqfarkauGauFaqfamaauHamaamaamaamaamaaEYaEZanlauIaavanlanlamaaEYaEZcUZahjcUZamaapiatLamaarhauNamaaoVapVaGvaEraEkaGlaGsaGpaGpaGpaGpaGraGpaGpaGoaGlaGnaGlaGlaGjaGlaGmaGjaGkaGiaGhauWauWauWauWauWauWauWaFSaFWauWauWauWauWaFRaFJaFOaFOaFQaFGaqHaFHaFIaFBaFCaFDaFEavhaFzavjaFAavlaviaFwaFxavmavnaFyauoauqauqauraELavpavqapSapSapSapSapSavqavrauwauxahlahlakmaqralvalvarcakmaqsaneavvavwandakmatnandakmavzalvakmavAalvakmaqaaqbavBaFuatpatpavCavDavEbjOaFvavHavIarjbRJbRJdsidsibRJbRJbRJbRJahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlavJavKavKavKavLavKavKavKavMavNavOavMavMavMavPamaaHhaEZanlauJavSanlavTamaaEYaHgaEkaEkaEkaEkaEkaEkaEganlavSavVanlanlaopaHLaHFaHEaHIaHIaHIaHRaHIaHTaHIaHIaHPaHQaHOaHMaHMaHMaHMaHMaHMaHNaHlaHkaHiaHiaHiaHiaHiaHiaHiaHjaHiaGHaGHaGHaGHaGHaHuaHCaHtawkaHsaqHaqHaqHaqHaqHaHqaHraHoaHpaHmaHnaGFaGGaGIaGJawuawvaGXaGYaGZaGZaHaaHbaHcaHdapSapSapSapSapSaHeascaHfawHahlahlakmalvalvalvalvalvalvavBatpatpatpatpatpatpatpawIalvalvalvalvaspalvalvardaGAayOaGzaGDaGCaGBattattattawKarjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjawLawMawNawMawOawNawNawPawMawNawQawRawSawSawTamaaHhaEZawUanlanlawVawWamaaXzaFdaFdaFdaFdaFdaFdaWMaEZavuanlamaasCasCaWPapsaogaxbaxcaxdaxdaWRaxdaWQaxdaxdaxeaxbaGyaxgaxgaxgaxgaxgaxgaxgaopaWSawfaxiaWUaWTaXfaWVaXgaxoaXqaXpaXraxsaxtawhaXsalKaXtabIadYaqHaFsaFtaXuapGaXvaXwaXxaXxaXxaXyaXRaYaaXKaXQaunaxEaXJaxGaxHaxIaxJaDUaxLaXAapSapSapSapSapSaYiapQapQapQakmakmakmandakmakmanSakmakmardakmakmaxPakmakmanSakmardaqrakmakmaxRakmalvaqrardaGAaYnarjaxTavDaYmaxVaYjavDaxXarjahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlarkavJaxYavJaxZawNawNcFUavJaxYavJaybaycawOaydamaaHhaHgaEmaEkaEkaEgayeayeakmaspakmayeayeayeayeaYFaYGaGnaGlaGlaGlaGlaYSapsarvaxbahlahjahlaYrahlaIeahlahjahlaxbaGyaxgayhayiayjaykaylaxgaopaZEaZzaZyaZPaZOaZNaZMaZRaZRaZQaywaywaywayxawhaxualKaxvabIadYaqHaFHaFBaFBaZraFDaYXaZxayBayCayDayEayFayFayGayFapQbasbaGbacbajbakbarapQaZUapSapSapSapSapSaZUapQasnalvayOayPakmakmakmasnalvakmasnardakmaxaalvakmavyalvakmayUayVakmavxalvakmanOanQardbaPbaNarjayXavDbaIayZbaIavDcbBarjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjazbaqfazcatwazdazeazfazgazhazdatwaziazjaqfazkazlamabbSbcdboAaznaqobcgayeazpbcrazrazsaztazuazpayebbObbNbbMaHIaHIaHIaHIaHIbbPazyaxbahjazzazzbbRazzaEAazzazzahjaxbaGyaxgazAazBazCazDazAaxgbbobbkbbwbbvbaWbaRbbhbbebbGbbFbbIbbHaywaywaywazOaxualKazPabIadYaqHaqHaqHaqHaqHboabbLbbJayFayFayFayFayFazRazSazTayFapQapQapQapQbcvayfapQaZUapSapSapSapSapSaZUapQakmalvboBayPakmazWakmalvalvakmalvardakmalvalvakmalvalvakmardaskakmalvalvakmazXalvardaGAbcuarjarjarjarjarjarjarjarjarjbRJbRJbRJbRJbRJahjahjahlahlahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlawLaxYaAaaAbaAbaAbaAbaAcaxYawLaAdaqfaAeaydaAfaAfbdlboCaAfaAfbdmayeazpazrcFZaAiazrazrazpayeaogbdebcZaAkaAkaAkaAkaAkaAkaAkaAlahlazzbcJbcKaGwbcPdteazzahlaxbaGyaxgazAaAraAsaAtazAaxgaHLbbPawfaAubcHaAwayobcGbbebcIaAAaywaywaABaywaACaxualKaxvabIadYaqHaFsaFtbcCapGaXvbcBayFaAEazSaAFaAFayFazRaAGazTayFaAHbdPbdNaAKaSpayfahjbdOaoLaoLaoLaoLaoLbdGahlakmalvaAPaAQakmakmakmakmakmakmaARaASakmakmakmakmakmakmbdAbdwbdxaVuaVuaVubdzbdyaPcaSibdrbdqaVubdvbdnbdubdtbdnaCoaqcaBhahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlaBiaBjaBkaBjaBjaBlaBmaBjaBjaBkaBnaBoaqfaxZaBpblYblNblOblPaBuaBvaNCayeazpazrazraBxazrazrazpayeaByaNPaNOaBBaBCaBDaBEaBFaBGaBHaAlahjazzaObaOcaAmaOaaOdazzahjaxbaGyaxgaNQaNRaBPaNTaNSaxgapsavsawfaBSaBTazIaywazIaOgaBWaBXaBYaBZawhaCaawhaxualKaxvabIadYaqHaFHaMJaFBaOhaFDaOiayFaCcazSazSazSayGaCfaCeaCdayFaOlaOsaOPaOVaOBayfahlahjahlahjahlahjahlahjahlakmaqrbmeaPcaCoaCpakmatOalvaqrardalvakmahlakmayOaPcaPcaPvaPBaPxaPxaPxaPxaPxaPyaPAaPGaPDaPCaPCaPCaPCaPCaPCaPTaPPaCCaCDahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaBiaBnaBjaCEaCFaCFaCGaCHaCIaCJaCKaCFaCFaCLaCMavJaxZaCNaAfbmgaQgbmfaCRaCQaPUayeaCTazrazrazrazraEoaRaaRcbmjaRgaRdaBGaBGaBGaBGaBGaBGaBGaAlahlazzaQyaApaQAaAnaQXazzahlaxbaGyaxgaQhaQiaDeaQqaQuaxgapsaDhawfawfaDiaDjaJMaDjaShawfawfaDmaDnawhaDoawhaxualKaxvabIadYaqHaqHaqHaqHaqHaRjaRqaRBaRJaRraDwaDwaDwaSnayFaIDayFaSlaSmaSoaAKaSpayfakmakmakmakmakmakmakmakmakmakmakmakmakmbmkakmakmakmakmayOaSiaSAaStaEwaStaSraSsaSqaSqbmlaDOaDOaDOaDOaDOaDPaSLaDRaDRaDRaDRaDRaDRaDVakmaDXayfaDVaDVaDVahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaCLaDYaDZaEaaCFaEbaCFaEbaCFaEbaCFaEbaCFaEcaEdazdaxZaEeaAfaTeaTCbmraEiaEjaSOayeaElazraSPaTaaTaaUiaUhaUgbnlaTZaTOaTNaTNaTNaTNaTNaTLaTKaAlahjazzaUraApaUpaUqaUoazzahjaxbbnmaEEaUlaUmaDeaUkaUjaGEbmwaTEawhaTGaTDaDmaDmaDmaBUaERawhaESaESawhaDmawhaETaEUaEVabIadYadYadYadYadYamraHqaFbaFcaTHaFeaFcaUIaFcaUHaFcaUKayFaFjaUJaUNaAKaULaUMaUQaVaaUOaUPaVfaCsaCsaCsaCsaVmaVkaCsaCsbnnaVpaVnaVBaVuaVsaVraUvaUwaUxaUwaUyaUzaDOaDOaFKaDOaFLaFMaFNaDOaDRaUAaDRaFPaUFaUEaUGaFTaFUaFVawaatbaFYaFZaGaahjahlahjahlahjahlahjahlahjahjahlaGbaGbaGbaGbaGbaGbaGbahlahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaGcahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlaBiaBjaBkaBjaBjaBlaBmaBjaBjaBkaBnaBoaqfaxZaBpblYblNblOblPaBuaBvaNCayeazpazrazraBxazrazrazpayeaByaNPaNOaBBaBCaBDaBEaBFaBGaBHaAlahjazzaObaOcaAmaOaaOdazzahjaxbaGyaxgaNQaNRaBPaNTaNSaxgapsavsawfaBSaBTazIaywazIaOgaBWaBXaBYaBZawhaCaawhaxualKaxvabIadYaqHaFHaMJaFBaOhaFDaOiayFaCcazSazSazSayGaCfaCeaCdayFaJXaOsaOPaOVaOBayfahlahjahlahjahlahjahlahjahlakmaqrbmeaPcaCoaCpakmatOalvaqrardalvakmahlakmayOaPcaPcaPvaPBaPxaPxaPxaPxaPxaPyaPAaPGaPDaPCaPCaPCaPCaPCaPCaPTaPPaCCaCDahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaBiaBnaBjaCEaCFaCFaCGaCHaCIaCJaCKaCFaCFaCLaCMavJaxZaCNaAfauOaQgbmfaCRaCQaPUayeaCTazrazrazrazraEoaRaaRcbmjaRgaRdaBGaBGaBGaBGaBGaBGaBGaAlahlazzaQyaApaQAaAnaQXazzahlaxbaGyaxgaQhaQiaDeaQqaQuaxgapsaDhawfawfaDiaDjaJMaDjaShawfawfaDmaDnawhaDoawhaxualKaxvabIadYaqHaqHaqHaqHaqHaRjaRqaRBaRJaRraDwaDwaDwaSnayFaIDayFaSlaSmaSoaAKaSpayfakmakmakmakmakmakmakmakmakmakmakmakmakmbmkakmakmakmakmayOaSiaSAaStaEwaStaSraSsaSqaSqbmlaDOaDOaDOaDOaDOaDPaSLaDRaDRaDRaDRaDRaDRaDVakmaDXayfaDVaDVaDVahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaCLaDYaDZaEaaCFaEbaCFaEbaCFaEbaCFaEbaCFaEcaEdazdaxZaEeaAfaTeaTCbmraRQaEiaEjayeaElazraSPaTaaTaaUiaUhaUgbnlaTZaTOaTNaTNaTNaTNaTNaTLaTKaAlahjazzaUraApaUpaUqaUoazzahjaxbbnmaEEaUlaUmaDeaUkaUjaGEbmwaTEawhaTGaTDaDmaDmaDmaBUaERawhaESaESawhaDmawhaETaEUaEVabIadYadYadYadYadYamraHqaFbaFcaTHaFeaFcaUIaFcaUHaFcaUKayFbeDaUJaUNaAKaULaUMaUQaVaaUOaUPaVfaCsaCsaCsaCsaVmaVkaCsaCsbnnaVpaVnaVBaVuaVsaVraUvaUwaUxaUwaUyaUzaDOaDOaFKaDOaFLaFMaFNaDOaDRaUAaDRaFPaUFaUEaUGaFTaFUaFVawaatbaFYaFZaGaahjahlahjahlahjahlahjahlahjahjahlaGbaGbaGbaGbaGbaGbaGbahlahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaGcahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaGdaCFaCFaGeaCFaEbaCFaEbaGfaEbaCFaEbaCFaEcaEdazdaxZbdiaAfaAfaVFbnobnpaVCaAfayeayeayeayeaVDazrazraVSayebnAaVRaBGaBGaBGaGtaBGaBGaBGaGuaAlahlazzazzaEyaVNaEyazzazzahlaxbaGyaxgaVLaVMaVIaVJaVKaxgapsaVHawhaVGaTDaDmaDmaDmaBUaGKawhaGLaGMawhaCaawhaGNaGOaGPabIamrabIabIabIabIabIbnqaGSayFaGTazSayFaGUayFaGVayFaGWayFaWvaWwaUNaAKaWxaWyaWJaWLaWlaWlaWmaWlaWlaWnaWlaWoaWpaBaaBaaBaaBaaWqaWsaWraWuaWtalvaIRaIRaIRaIRapBaDOaHvaHwaHxaHyaHzaHAaDOaHBaWkaDRaHDaVVaVUaVZaFTaHHaFXawaaWjaDVaDVaDVahjahjahjahjahjahjahjahjahjahlaGbaGbaGbaGbaGbaGbaGbaGbaGbdsiahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaCLaHJaDZaEaaCFaEbaCFaEbaCFaEbaCFaEbaCFaEcaEdazdaHKaCwaBAaBtaBtaBwauZawNavbavdavcavaayeaukazrazraqCayeaBsaBzaBGaHXaHYaHZaIaaIbaIcaIdaAlahlahjahlaIfauYaIfahlahjahlaxbaGyaxgaDeaIiaIjaIkaIlaxgapsapqawhaImaInaDmaDmaDmaIoaIpawhahlahlaIqaIraIsaItaIuaIvaIwaIxaIqahlahlaTkaIzaAoaIBayFaICazSazSazSaCeazSazSazSayFaAKauXauVaAKaAKayfauUaIIaIIauTaMZaILaIIaIMaIIaINauRaINauQaINaIQaIRaIRauPaIRaIRaIRaIRaCkaKwaIRapBaDOaHwaIVaIWaIXaIYaIZaDOauLauAauiaumaupausaueaufaugauhaucaudaJhaJiaJjahlahlahlahlahlahlahjahlahjahlaGbaGbaGbaGbaGbaGbaGbaGbaGbahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaJkaJlaBjaCEaCFaCFaCFaJmaCFaCFaJnaCFaCFaCLaJoawLaxZawNaJpaJqaJqaJqaJqaJqaJqaJqaJrawNayeapraubaprayeayeaBqaJvaJwaAkaAkaAkaAkaJuaJxaJyaAlaJzaJBaJBaJCatWaJEaJBaJBaJFaxbaBraxgatZaxgaJIaJJaJKaxgazGavWawhawhawhaJLaJMaJLawhawhawhaJOaJPaJQaJRaIuaIuaIuaIuaIuaJSaJTaJPaJUaTkaJVaAoaJWayFayFayFayFayFayFayFayFayFayFaJXatQatBatAatCaPuatjaKeaIIatuaMZaKjatVaKjaINaKkatUaINatSaINaKnaKoaKpatRasXasXasXasVasTaMaaIRapBaDOasSaIVaKAaIXaIYaKBaDOaKCasRathatiatfatgatdateaVlatcasZatbaKIaKJaKKahlahjahlahlahlahlahjahlahjahlaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaJkaJlaBjaCEaCFaCFaCFaJmaCFaCFaJnaCFaCFaCLaJoawLaxZawNaJpaJqaJqaJqaJqaJqaJqaJqaJrawNayeapraubaprayeayeaBqaJvaJwaAkaAkaAkaAkaJuaJxaJyaAlaJzaJBaJBaJCatWaJEaJBaJBaJFaxbaBraxgatZaxgaJIaJJaJKaxgazGavWawhawhawhaJLaJMaJLawhawhawhaJOaJPaJQaJRaIuaIuaIuaIuaIuaJSaJTaJPaJUaTkaJVaAoaJWayFayFayFayFayFayFayFayFayFayFaFjatQatBatAatCaPuatjaKeaIIatuaMZaKjatVaKjaINaKkatUaINatSaINaKnaKoaKpatRasXasXasXasVasTaMaaIRapBaDOasSaIVaKAaIXaIYaKBaDOaKCasRathatiatfatgatdateaVlatcasZatbaKIaKJaKKahlahjahlahlahlahlahjahlahjahlaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaJkaBjaBkaBjaBjaKLaBmaBjaBjaBkaJlaKMaqfaKNawNavJaKOaKOaKPaKOaKQarkaKRaKSawNaGgaMzaKYaKYaKXaKYaEpaKZaKYaKYaKYaKYaKYaKYaKYaLaaLbawCawDaLeaLeawBaLgaLeaLeaLeaLhaEnaLjawBaLeaLeaLeaLkaLlaLmaIuaLnaLoaIvaIwaIwaIwaItaIuaIuaLpaIuaLqaLraLsaLtaLuaLvaLwaLxaIuaIuaLybzVaEqaEWaLAaLCaLDaLEaLFaIuaLGaIuaAKaLHawraJYatQawpawoawnawmaqFdrhaIIawqaLLawjaLMaLNaINawlatUaLQaqAaINaIRaLSbgAawiaPSaLWawyawxawzaDCaIRapBaDOawAawtawsawwaMcaMfaDOaMgaMhaDRaHGaHGaHGaHGaDRaMiaMjasZatbaDVaDVaDVaMlaMlaMlaMmaMnaMoahjahlahjaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlavJaxYaMpaAbaAbaAbaAbaMqaxYavJaAdaqfaAeaMrazdaMsaMtaMuaMuaMvarkaMwaKSawgaMyaMzaweaMBaMCaMDaMEaMFaKYaKYaKYaKYaKYaKYaKYaLaaKYaMzaKYaKYaKYaDgaDfaCxaCxaCxaCxaDlaCxaEhaCxaCxaDkaMLaLlaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaLpaIuaMMaMNaMOaMPaMQaMRaMSaMTaIuaIuaLyaIuaIuaIuaIuaIuaIuaIuaIuaIuaMUaIuaAKaJYaJYaJYavGavfaveavkavgavoaQSaIIavtaMZavQaIIaIIaINaNbatUaNcaqAaNdaINaIRaIRaIRaIRaIRaIRavZaNgaNfaIRapBaDOaNhaHwavYavXaHwaNjaDOaDRaDRaDRaDRaDRaDRaNkaDRaFXaFXawaatbaNlaNmaDVaNnaNoafJaNqaNraNsahjahlahjaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjazbaqfazdatwazdaNtaNuaNvaNwazdatwaNxaNyaqfaxZawNazdaNzaNAaMuaMuaMvarkaNBaKSawNaMyaMzaKYaNDaNEaNEaNEaNFaNGaNHaNEaNIaNEaNEaNEaNJaNKaqSaNEaNEaNEaqQaqPatKasaasaaqRaqOaqMaqKaNUaKYanLaMLaLlaIuaNVaIuaNWaNWaNWaNWaNWaNWaNWaNWaNXaNWaNWaNWaNWaNWaNWaNWaNWaNWaNWaNWaNYaNWaNWaNWaNWaNWaNWaNWaNWaIuaIuaIuaAKaNZaNZaNZaNZaNZaqIaqGaPuaqFaqdaIIaqEaOeaqyaIIaOfaINaqtaqpaqqaqAaOjaINaIRaOkaqzaOmaOnaOmaqnaOoaOpaIRapBaDOaOqaOqapHapFaOtaOtaOuaDOaOvaOwaOxaDVaOyaOzaOAaFXaFXaqjaqmaDVaOCaDVaODaqhaOFaOFaOGaOHaMnaMnaOIaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjazbaqfazdatwazdaNtaNuaNvaNwazdatwaNxaNyaqfaxZawNazdaNzaNAaMuaMuaMvarkaNBaKSawNaMyaMzaKYaNDaNEaNEaNEaNFaNGaNHaNEaNIaNEaNEaNEaNJaNEaqSaNEaNEaNEaqQaqPatKasaasaaqRaqOaqMaqKaNUaKYanLaMLaLlaIuaNVaIuaNWaNWaNWaNWaNWaNWaNWaNWaNXaNWaNWaNWaNWaNWaNWaNWaNWaNWaNWaNWaNYaNWaNWaNWaNWaNWaNWaNWaNWaIuaIuaIuaAKaNZaNZaNZaNZaNZaqIaqGaPuaqFaqdaIIaqEaOeaqyaIIaOfaINaqtaqpaqqaqAaOjaINaIRaOkaqzaOmaOnaOmaqnaOoaOpaIRapBaDOaOqaOqapHapFaOtaOtaOuaDOaOvaOwaOxaDVaOyaOzaOAaFXaFXaqjaqmaDVaOCaDVaODaqhaOFaOFaOGaOHaMnaMnaOIaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlarkawLaxYawLaxZawNawNayaawLaxYawLaOJaOKaOLawNawLaOMaOMaKPaOMaKQarkaONaKSawNaOOaOOaOOaOQaOOaORaORaORaORaORaOSaOTaORaOUaORaORaORaOYaOWaOXaOWaqJapRaPaaKYaKYaPbapPaPdanjaKZaKYanLaPeaPeaIuaIuaIvaPfaJPaJPaPgaPgaPgaPgaPhaPiaPjaPkaPlaPmaPnaPmaPoaPmaPpaPkaPqaPiaPraPgaPgaPgaPgaJPaJPaPsaItaIuaIuaIIaoXaMXaKcaKcaKcaKcaKcaPuaQUaKcaIIapKaPzapNaINaINaINapLapMaINaINaINaINaIRaOmapOaPEaPEaPEapEaPFaOmaIRapBaDOaPHaHwapHapFaHwaHwaPIaDOaPJaPKaPLaDVaFXaPMaPNaPOaPOapIapJaPQaPRaDVafsaSEaOFaOEaOFaPWaPXaPXaPWaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaGcahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjavJaPZawNavKaOLawNawNaQaavKawNaPZaOLawNawNawNaQbaQcaQcaQcaQcaQcaQcaQcaQdawNaOOanTaOOaRDaORasQaQnaQkaQlaQmaQnaQoaQpbKEaQraQsaQtaOYaQvaQwaQxaqJaxfaPaaPaaQzaPaaPaaPeazEaQBaQCaxyaPeaPeaQDaIuaIvaQEahlahlahlahlahlahlahlaPiaQFaQGaQHaQIaQJaQKaQLaQMaQNaQOaQPaPiahlahlahlahlahlahlahlaQQaItaIuaQRaIIaPtaKcaQTaKcaKcaKcbKcaPuaQUaLJaQVaPuaQWasbaINaQYaQZasfasdaseasgaReaRfaINaOmasraRhaRhaRhasKaRiaOmaIRasOaDOaRkaRkapHapFaRlaRlaRmaDOaDOaRnaDOaDVaRoaOzaOAaRpaRpaqjaqmaDVaDVaDVaMmasHasJasPaMnaMnaMnaMnaRsaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlahlawLaRtaRuaRuaRuaRuaRuaRuaRuaRuaRtaRuaRvawNawNaRwawNaRzawcawNaRyawbawNaRAarYaOOaRCaOOaRDaORaREaQnawdaQnaQnaQnaQoaRFaQnaQnaQnaQtaOYaRGaQwaQwaqJaxfaPaaRHaRIaRIarZaPeawZaRLaRMawYaROaRPaIuaIuaIvaQEahlahlahlahlaPiaPiaPiaPiaRQaRRaRSaRTaRUaRVaRWaRXaRYaRZaSaaPiaPiaPiaPiahlahlahlahlaQQaItaIuaIuaSbaKcaqTaqVaqUaqXaqWarparearsarrarCarAarDarEatYarFarFarHarIarJarJarKarFarMarNarOarParQarSarRaRiaOmaIRapBaDOaHwaHwapHapFaHwaHwaHwaolaSwaHwaSxaDVaKHbDuaSzaRpaRparTarVaSBaDVaSCaSDaSEaOFarWaOFaSFaPXaPXaSGaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlahlawLaRtaRuaRuaRuaRuaRuaRuaRuaRuaRtaRuaRvawNawNaRwawNaRzawcawNaRyawbawNaRAarYaOOaRCaOOaRDaORaREaQnawdaQnaQnaQnaQoaRFaQnaQnaQnaQtaOYaRGaQwaQwaqJaxfaPaaRHaRIaRIarZaPeawZaRLaRMawYaROaRPaIuaIuaIvaQEahlahlahlahlaPiaPiaPiaPiaSOaRRaRSaRTaRUaRVaRWaRXaRYaRZaSaaPiaPiaPiaPiahlahlahlahlaQQaItaIuaIuaSbaKcaqTaqVaqUaqXaqWarparearsarrarCarAarDarEatYarFarFarHarIarJarJarKarFarMarNarOarParQarSarRaRiaOmaIRapBaDOaHwaHwapHapFaHwaHwaHwaolaSwaHwaSxaDVaKHbDuaSzaRpaRparTarVaSBaDVaSCaSDaSEaOFarWaOFaSFaPXaPXaSGaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjaqfaqfaSHaSIaSIaSIaSIaSIaSIaSJaqfaqfarkaSKaJtaSMaSMaYxaSMaSMaSMaXoaSMaSMaSMaOOaRCbbYaSQaORaSRaQnaOZaSSaSTaSUaSVaSSaQnaQnaQnaSWaOYaSXaSYaSZaqJaxfaPaaTbaTcaTdaAhaPebaeaTgaThbafaTiaTjaIuaIuaIvaJTaPhaTkaTlaPiaPiaTmaTnaToaTpazZaTqaTraTsaTqaTtaTqaTqaAgaTuaTvaTwaTxaPiaPiaTlaTkaJOaTyaItaIuaIuaIIaTzaPuaTAaKcaKcaKccEyaKcaAIaADaAzaAyaPwaBcaBbaAOaAYaAZaAWaAXaAUaAVaAOaATaALaAMaAjaAJbagaAjaAqaTQaIRapBaDOaTRaTRapHapFaTSaHwaHwaTTaHwaTUaTVaDVaTWaTXaTYaRpaRpaAvaAxaFXaDVaUaaOFaSEaOFarWcElaUbaMnaMnaOIaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUdazeawOaUeaSMaWZaZSaZIazxaZIaZTaWZaZIaSMaRCaRCazFbfBaORaUsaQnaYBaYEaZoaUtaUuaSSaQnaQnaQnaQtaOYaOYaOYaOYaqJaxfaPaaPaaPaaPaaPaaPeazwaRMaRMaRMaRMaTjaIuaIuaIvaIwaIwaUBaUCaUDaPiazaayWayYazmazqazmazoayKayJayIayHayQayMayHayLayTaySaPiaURaUCaUSaUTaIwaItaIuaIuaSbaKcaPuaQTaKcaUUaKcaQTaKcaQUaLJaUVaKcaKcaKcaUWaSkazYaUXaUYaUZazVaTJaVbaINaVcaTMaVdaRhbadaRhaSuaVeaIRazUaDOaDOaDOapHapFaVgaVhaHwaViaVjaKAazQaDVaFXazNaSzaRpaRparTazMazLaDVazKaOFaSEazJazHaVwaNsahlahjahjaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaVxaVyaVzaxZaVAbjabjjbjhbjlbjkbjXbjraWZaZIaSMaDpaDqaxkaOOaORaVObhlbhfbhkbhfbhjbhLbhjbhjbhjbhrbhJaORbhnbiRbiQbiGbiFaVWaVXaVYaOOaCyaPebiWaWbaWcaWdaWdaWeaIuaIuaIuaIuaIuaWfaWgaWhaWiaCPaCSaCUaCzaCAaCBaCOaCZaCYaDbaDaaCWaCVaCXaCUaDdaDcaWzaWAaWBaWCaWDaWEaWFaIuaIuaIIdtFaScaSgaSeaKcaSfaSdaSeaQUaLJaTBaTBaWGaWHaINaSkaSkaSkaWIaSkaSkaTJaWKaINaOmaTMaRhaRhbadaRhaTPaOmaIRaDuaDvaWNaWOaDraDtaDsaDsaDsaDsaDsaDsaDEaDHaVoaVoaVoaVoaVoaDxaDyaDzaDAaDBaVtaVvaDDaOFaWWaNsahjahjahlaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaVxaVyaVzaxZaVAbjabjjbjhbjlbjkbjXbjraWZaZIaSMaDpaDqaxkaOOaORaKdbhlbhfbhkbhfbhjbhLbhjbhjbhjbhrbhJaORbhnbiRbiQbiGbiFaVWaVXaVYaOOaCyaPebiWaWbaWcaWdaWdaWeaIuaIuaIuaIuaIuaWfaWgaWhaWiaCPaCSaCUaCzaCAaCBaCOaCZaCYaDbaDaaCWaCVaCXaCUaDdaDcaWzaWAaWBaWCaWDaWEaWFaIuaIuaIIdtFaScaSgaSeaKcaSfaSdaSeaQUaLJaTBaTBaWGaWHaINaSkaSkaSkaWIaSkaSkaTJaWKaINaOmaTMaRhaRhbadaRhaTPaOmaIRaDuaDvaWNaWOaDraDtaDsaDsaDsaDsaDsaDsaDEaDHaVoaVoaVoaVoaVoaDxaDyaDzaDAaDBaVtaVvaDDaOFaWWaNsahjahjahlaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaWXatwaWXawNawNaSMberbemaXaaXaaXabfAbfjaXcaSMaXdaRCaxkaXhaXhaXhbcTbchaXhbcibcSbehbekbelbelbcVbcWaORbdIbbKbaObcebcabbZbbZaBfaBeaBeaXBaXBaXBaXBaXBaXCaPeaIuaIuaXDaXEaXFaXGaXHaXIaPiaBKaBNaXLdnJaBMbnGbnGaxqauCaxwaBJbrHaBIdnFaXLaBLaBKaPiaXSaXHaXTaXUaXEaXVaIuaIuaSbaKcaXWaTAaKcaKcaKcaTAaKcaQUaKcaLJaLJaKcaKcaXXaXYaXZaSkaSkaSkaSkaYbaYcaINaYdaYeaRhaYfbheaYgaYeaYhaIRaCvaYkaYkaYlaOraCtaCnbfUaCuaCnaCnaCnaCraCjaCmaBVaBVaBVaBVaBVaCbaBOaBQaCibbQaCgaChaOFaYoaNsahlahjahjaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaYpaYqaVzaxZawNaxlaWZaTfaXaaXaaXaaSNaYsaWZaSMaYtaSjaxkaXhaYvaYwaUfaVEaXhaUnaYAaTFaORaYCaYDaNNaOZaORaTIaNLaYHaYHaYHaYHaYIaYHaYHaYJaYKaYKaYKaYLaYKaYMaYNaYOaYOaYPaYQaYQaYQaYQaYQaYQaxmaxnaYRaxpaxqaYVbkMbkMbrIbambkMaYVaxwaxxaYWaxrbkQaYWaYWaYWaYWaYWaYWaYZaYOaYOaIIaZaaZbaZcaZdaKcaKcaKcaZeaZfaZgaKcaZhaZiaZjaINaINaINaZkaZlaZlaZlaINaINaINaZmaRhaRhaZnaVPaZpaZqaNfaIRaxjaYkaZsaDOaZtcesaZvaVQaxzaZuaTTaVhbbsaDVaxAaFXaZAaRpaRpaZAaFXaZBaDVaZCaZDaxBarWaOFaOGaZFaMnaMnaOIaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaYpaYqaVzaxZawNaxlaWZaTfaXaaXaaXaaSNaYsaWZaSMaYtaSjaxkaXhaYvaYwaUfaVEaXhaUnaYAaTFaORaYCaYDaNNaOZaORaQfaNLaYHaYHaYHaYHaYIaYHaYHaYJaYKaYKaYKaYLaYKaYMaYNaYOaYOaYPaYQaYQaYQaYQaYQaYQaxmaxnaYRaxpaxqaYVbkMbkMbrIbambkMaYVaxwaxxaYWaxrbkQaYWaYWaYWaYWaYWaYWaYZaYOaYOaIIaZaaZbaZcaZdaKcaKcaKcaZeaZfaZgaKcaZhaZiaZjaINaINaINaZkaZlaZlaZlaINaINaINaZmaRhaRhaZnaVPaZpaZqaNfaIRaxjaYkaZsaDOaZtcesaZvaVQaxzaZuaTTaVhbbsaDVaxAaFXaZAaRpaRpaZAaFXaZBaDVaZCaZDaxBarWaOFaOGaZFaMnaMnaOIaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcaUcawLaZGaOLaZHaSMaZIaFfaZIaWZaZJaFaaZKaZIaSMaZLaEXawEaXhaXhaXhaQjaRbaXhaRxbNPaNMaORaYCaYDaNNaOZaORaQfaNLaYHaZVaZWaZWaZWaZXaYHaZYaZZbaababaYNaYNaYNaYNaIuaIuaHWaIAaLzaLBaJNaKWaGRaHSawXbalbqybNHbkMbkMbnIaGqbnIbkMbkMbMVbhzbaqawJawFbatbaubavbawbaxaYWaXVaIuaIuaIIaIIaIIaIIaIIbayaSbbaybazbaAaIIaIIaIIaIIaIIbaBbaCbaCbaCbaCbaCbaCbaDbaCbaBaNfbaEbaEbaFaRKaYkaYkaYkbaBaxjaYkaZsaDOaDOaDOaZwaRNaZwaDOaZwaDOaDOaDVaDVbaJbaKbaKbaKbaKbaLaDVaDVbaMaOFaxharWaOFaOFaSGaPXaPXaSGaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjaqfaqfaSHaSIaSIaSIaSIaSIaSIaSJaqfaqfarkaRzawNaSMaSMaYxaSMaSMaSMaXoaSMaSMaSMbaQaYuaxWaXhcqfbaSaQjbaTaXhbaUbaVbaUaORaYCaYDaNNaOZaORaQfaNLaYHaZWbaXbaXaZWbaXaYHaZYbaYbaZbaZbbabbbbbcaYNbbdaIuaXDbcxbbgbaibbibbjbbjaymaynbblbqyaHVbkMbkMbnIbaobnIbkMbkMbczbhzbbtayqaypaysayrbbxbaxbbyaYWaXVbbzaIubdpbbBaYkaYkaYkaYkaYkaYkaYkaYkbbCaYkaYkaYkaYkbbDaYkaYkaYkaYkaYkaYkaYkaYkbbBaYkaYkaYkaYkaRKaYkaYkaYkbbEaytaYkaYkayuaYkaYkaYkaYzaYkaYkaYkaYkaYkbbDayvaYkaYkaYkaYkaYkaYkbdSayyaSDaOFayzayAaPVbbTbbUaMnaMnbbVaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlavJavNavMavMavMavMavMavMavMavMavNavMbbWaXbawNbbXbbYaXebbZbbZbbZaWaaVTbcbaOOaoTaWYaxCaXhaXhaXhaXkbcfaXhaORaORaORaORaYCaYDaXiaXjaORaQfaNLaYHaZWbcjaZWbaXbckaYHaZYbclbaZbaZbaZbcmbcnaYNbcoaIuaXDbbpbcqbaibcsbctaxNaxOaxMbcwbqybbnbnIbkMbmiaYUbmibkMbnIbbfbhzbcAbbuaxKaxFaxDbbxbaxbaxaYWaHUaIuaIubdpbbBaYkaYkaYkaYkaYkaYkaYkaYkbcEaYkaYkaYkaYkaYkaYkbcFaXlaXlaXlaXmaYkaYkbbBaYkaYkaYkaYkaRKaYkaYkaxSaWNaxUaWNaWNaWNaWNaWNaWNaXnaWNaWNaWNaWNaWNaWNaWNaWNaWNaWNaWNaWNbcLbcMbcNbcObcOaxQarWaOFaOFbcQaPXaPXbcQaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl @@ -9326,8 +9331,8 @@ ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlah ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjazbaqfazcatwazdazeazfbfvbfwazdatwaziazjaqfazbarkbcRbfxbfybfybfybfzcdBcdxcdycaocaocczccCaXhaYvbfDaYybfEaXhbHpbHpaRCaRCceNceAcfzcfrcfzcfzcenaYHceqbHlaZWaZWcetbHmbHiaYNcdRbaZbaZcdSbfWbfXbeGaIubfYaYQbfZaYRbgbdtQbgcbGMaynbgfaYQahjbxycltcltcltboXbHgbHhahjaYWbgjbHcbHdbgmbaxbgnbaxbHfaYWaXVaIubgpbeVbgqbgrbgsbgtbgubeVbgvcGZbgwcfEbgybgybgybgzboLbjpbgCbfbbgDbgEbMfbgEbgEbgFbHsbfcbfgbHtbfgbfgbfgccNbgMbgMbgNbgMbgObgObflbgPbgQbgRbfldombgTdombflcmCbpOcmCbfqdolbgVdolbfqbgWbgXbfqbHrbLEaMmaMnbhaahjahlahjaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbaGbahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjawLbdYaAaaAbaAbaAbaAbaAcbdZawLahjahjahjahlbcRbhbbcRbhcbfybhdbZKbZTbiQbZGbZHbZIbZJcaAcaAcaAcaAcaAcaAcaKcaJcazcaocajcaiaYHaYHaYHaYHaYHaYHcbiaYHaYHaYHcbCbhobGPbGQcaYbaZbaZbQRbhtbeFbeGaIubhuaYQbhvaYRaYRaYRaYRbGMaynbhxaYQahjbxycltboTboUboWcltbxmahjaYWaLTbbubGNbhDbaxbeRbaxbaxaYWaXVaIuaIubeVbhKbAIbGXbhNbhObhPbgybhSbgybhRbgybgybhQbhTbhVbhUbhWbfbbhXbgEccybgEbhXbhYbgEbfcbhZcGObiabibbfgbGVbgMbidbiebifbigbigbflbihbiibijbikbilbimbinbflbGWblsbltbfqbiqbirbiqbisbitbitbfqbBBbLEahlahjahlahjahlahjahlaGbaGbaGbaGbaGbaGbaGbaGbaGbahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahjahjahlahlahlahlahlahjahjahlbcRbivbiwbixbiybiybizbiAbbZbhgaOOcjkcjlcjccjccjccjacjacjacjacjacjacjacjjcbCbiHbiIbMvbiKbiLbiMbRmbiOaYHbiPciKciLciNciNciWbaZbaZbQRbaZaYNbeGaIuaXDblZbMDbMCbMBbMAaYRbMEaynaYQaYQahjbxycltboUcltboUcltbxmahjaYWaYWbMybhBbjnbaxbjobMxbMwaYWaXVaIubmucjwcjBcjGcjNbjubjvbjwbgybMKbMLcjmbjAbjAbMIbMHbMJbhUbjFbfbbhXbgEccyblfbhXbMGbjGbfcbjHbjIbjJbjKbfgccNbgMbOvbOabOabNObNYbjQbNNbjSbjSbjSbNZbNxbNwbflbNpblsbNGbfqbNBbNgbNcbMWbkdbkebfqbBBbLEbgZbgZbgZbgZahjahjahjahjahjahjahjahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaGcahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahlahlahlahlahlahjahjahlahlahlahlahlahjahjahlbcRbkfbcRbkgbkhbkhbkibcRbkjbkkaOObklbkmbklbklbklbkmbklaOOaOOaYHaYHaYHcilcbCbiNbiNcikbiNbiNbiNbRmbiNbkpbkqcimcitcixbRhbRhbRhbRhciwciucivciBciyciEbLCbLnbLmbLpbLoaYRbGMaynaYQahjahjbxycltboWcmWboTbLXbxmahjahjaYWaYYbMdaYWaYWaYWaYWbMcaYWbkTaIuaIubeVbkUbAIbAJbhNbhObkWbgybqLbLfbkYbkZblabMnbfbblcbMhblebfbbhXbgEciJciHbhXbMebgEbfcbfgbfgbfgbfgbfgccNbgMdqNblhblibljblkblldsVblnblobloblpbxEcHjbflbMpblsbMqbfqblublvblwbKOblydtabfqbBBbPqceYblBblCblBahlahlahlahlahlahlahjahjahjahjahjahjahjdsiahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahjahjahlahlahlahlahlahjahlahlahlahlahlahlahlahjahlbcRblDblEblFbkhblGblHbcRahlahjdsiblIblIblIblIblIblIblIahlahlblJblKblLcihcigchJchJcijchJchJchJchVchJchWchXcibcidblQblRblSblTbKKaYNblVaYNbKFblXbqFblZbmabmdbmdbmdbmdbmcbKHbmbahjahlbKJbKIbzTcltcltbJXbxmahlahjbmsbKgbKibJYbKdbKDbmsbBVbmsbmtaIuaIubeVbLgbAIbAJbmybmzbeVbmAbqLbLfbkZbmBbgybLcbfbbYFbLebLabfbbmGbLbbKXbKWbKZbKYbKUbKTbKRbKVbKRbKRbKRbKSbgMbmQbiedqCdqobmRbmSbmTbmUbmVbmVbmWbKQbmYbflbpPbpObKPbfqbnbbncbndbKObitbnebfqbBBbKNbKLchEchEchEchEchEchEbKMahlahlahjahlahlahjahlahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahlahlahlahlahlahjahjahlahlahlahlahlahjahjahlbcRbkfbcRbkgbkhbkhbkibcRbkjbkkaOObklbkmbklbklbklbkmbklaOOaOOaYHaYHaYHcilcbCbiNbiNcikbiNbiNbiNbRmbiNbkpbkqcimcitcixbRhbRhbRhbRhciwciucivciBciyciEbLCbLnbLmbLpbLoaYRbGMaynaYQahjahjbxycltboWcmWboTbLXbxmahjahjaYWaYYbMdaYWaYWaYWaYWbMcaYWbkTaIuaIubeVbkUbAIbAJbhNbhObkWbgybqLbLfbkYbkZblabMnbfbblcbMhblebfbbhXbgEciJciHbhXbMebgEbfcbfgbfgbfgbfgbfgccNbgMdqNblhblibljblkblldsVblnblobloblpbxEbmTbflbMpblsbMqbfqblublvblwbKOblydtabfqbBBbPqceYblBblCblBahlahlahlahlahlahlahjahjahjahjahjahjahjdsiahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahjahjahlahlahlahlahlahjahlahlahlahlahlahlahlahjahlbcRblDblEblFbkhblGblHbcRahlahjdsiblIblIblIblIblIblIblIahlahlblJblKblLcihcigchJchJcijchJchJchJchVchJchWchXcibcidblQblRblSblTbKKaYNblVaYNbKFblXbqFblZbmabmdbmdbmdbmdbmcbKHbmbahjahlbKJbKIbzTcltcltbJXbxmahlahjbmsbKgbKibJYbKdbKDbmsbBVbmsbmtaIuaIubeVbLgbAIbAJbmybmzbeVbmAbqLbLfbkZbmBbgybLcbfbbYFbLebLabfbbmGbLbbKXbKWbKZbKYbKUbKTbKRbKVbKRbKRbKRbKSbgMbmQbiedqCdqobmRbmScjJbmUbmVbmVbmWbKQbmYbflbpPbpObKPbfqbnbbncbndbKObitbnebfqbBBbKNbKLchEchEchEchEchEchEbKMahlahlahjahlahlahjahlahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahjahlahlahlahlahlahlahlahjahlbcRbnfbngbnhbnibcRbcRbcRahlahldsiblIblIblIblIblIblIblIahlahlbnjbnkbiNchAchzchBchzchzchzchzchzchCchzchHchIchDchFbnrbnsbntbnubaZbJBbnwbnxbeGbnzchyblZblZbmbbnBbJvbnDbJwbumbmbahlahlbxybJxbvJbmhbyDbJybxmahlahlbmsbJzbJAbnNbmsbnObmsbBVbmsbmtaIuaIubeVbnQbAIbAJbnRbnSbeVbnTbJJbnUcHhbnXbgybJPbfbbJObJNbJMbfbbfcbodbfcbJLbJKboeboeboeboeboeboeboeboeccNbgMblgblhblibofbogbohboibojbojbojbmWbxEdsUbrebJIbrfbJHbrhbonboobonbJGbitboqbfqbJEbJCbJCbJCbJCbJCbJCbJCbJDbLEbgZbgZbgZahlahlahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlbRJahlahlahjblIblIblIblIblIblIblIboubovbowboxbiNbiNbiNbRrboyboyboybiNbiNbiNbiNbkpbozbQRbUgbTQbUabUbbUcbTIbTPbaZboGbBNboIboJboKbNoaNpboNbBMboPbBLbBKbmbahjahlbxybBDcoCcoCcoCbCcbxmahlahjbmsbCabCbbpdbmsbpebmsbBVbmsbpfaIubRTbRUbRVbRWbTybTHbpibeVbpjbqLbhRcGAbplbpmbnTbnTbpobAKbAWbprbpsbptbgybAZbBgbpwbpxbpybBibBhbBjbslboeccNbgMbpGbpFbBkbBtbBvbflbpJbojbojbpKbpLbxEbpMbsAbBwbxSbBybrhbpQbLzbitbBzbpUbpVbfqbpWbpXbpXbpXbpXbpXbpXbpXbBBbLEbpYbfGbgZbgZahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahldsiahlahlahjblIblIblIblIblIblIblIbqabqbbqabqcbqdbiNbiNbRmbiNbiNbiNbiNbiNbqeaYHaYHbqfbRSbRhbRQbRRbqibqjbaZbqkbaZbqlbmtbnzbqnbqobqpbqqbqrbvGbqtbAHbqvbmbahlahlbxydrNcpgdrkcpgbbrbxmahlahlbqCbxgbqBbqCbqCbqCbqCbAGbqCbqEbqFbqFbeVbeVbAdbAabAbbqJbeVbqKbqLbAebrcbrcbrcbrcbrcbLhbzQbzWbzUbrcbzSbrcbLibzZbqObqPbqQbqRbqSbqTbqUboebApbAqboVbqXbqXbqZbArbAzbABbACbACbADbAEbxEbrdbrjbAfbAgbepbrhbrhbAhbrlbAibsubrhbfqbpXbpXbrkbswbrmbrnbrobpXbAFbqsbrrbrsbrtbgZahlahjahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl @@ -9335,43 +9340,43 @@ ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlah ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlbRJahlahlahjblIblIblIblIblIblIblIbsObovbsPbsQbiNbiNbiNbRmbiNbiNbiNbiNbiNbrxbsRaYHbsSbQUbRhbQSbQTbsTbQRbaZbaZcGzbnxbnZbrBaIuaQQbqpbmbbsWbQQbsYbsXbxxbmbahlahlahjbxyckNbhyckNbxmahjahlahlbxnbtcbxibtebkKbtgbtgbxkbtibtjaIuaIubtkbtlbgybwBbwXbtnbtobtnbxfbxcbpqbwYbpqbpqbpqbttbwvbgybhRbwubtvbtvbwybwxbtybtzbwwbtAbtBbqTbslboebwnbgMbtCbtCbtCbtCbtCbflbrebrebrebrebBAbQPbtEbreboMbwlbscdtndtndtndtnbwmbtLbtMbtNbtObtPbtQbtRbtRbtSbtTbpXbNhbLEbsNblAbgZahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlbRJahjahjahjblIblIblIblIblIblIblIbrubrvbrubnkbtVbiNbiNbXLbiNbtVbiNbiNbiNbrxbGDaYHbGCbXMbTIbXNbYSbeFbRSbRhbuebufboGbnZbrBaXDbugbuhbmbbuibZibukbulbumbmbahlahlahjbGFbGIcoCbGGbGHahjahlahlbxnbGJbGLbutbuubuvbuwbEYbqCbuyaIuaIubnTbnTbFnbFqbLhbFbbsUbFcbFdbFlbuGbuCbuDbuCbuDbuCbuDbuCbFAbFBbtvbuHbFsbFubFtbFxbFwbuKbuLbuMbuNboebFIbFObpNbFMbFNblsblsbFDblsblsbFGbFEbFFbGubGkdtnbGhbGxbtmbvabvbbFUbvdbvdbvdbvdbvdbvfbvgbvhbvibvhbvjbvhbpXbNhbLEbsNaBRbgZbgZahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahjahlblIblIblIblIblIblIblIbvlbvmbvlbvnbvobvnbvnbvnbvnbvnbvpbvqbiNbrxbvraYHbvsbaZbvtbWLbWMbvwbEDbvybvzbvwbvwbEZbrBaJSbvBbqpbmbbvDbWObvFbsZbFabmbahlahlahjbdsbEObbqbEWbEXahjahlahlbxnbvKbvLbvMbvNbuvbuwbEYbqCbvOaIuaIubvPbvQbDSbqMbDRbvTbuCbvUbDTboZbvXbvYbvZbwabwbbwabwcbuCbhRbqLbtvbwdbDMbDLbDKbDQbDPbDObDNbDNbEnbEzbEAbEBbwobwpbwqbwrbwsbwrbwrbwtbwrbwrbEmbEabDXbDXbEbbEkbepbwzbwAbDUbwCbDWbwEbwFbvdbwGbwHbwIbwJbwKbwHbwLbpXbNhbLEbwMbrsbWubgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahjahlblIblIblIblIblIblIblIbwObwPbovbwQaYHbwRbovbwQbwSbwSbwSbwSbwTbwUbwVbwSbwSbwWbwWbWmbWtbvwbDJbwZbxabxbbvwbnZbrBaIvaTkaTkbmbbmbbVNbmbbmbbDDbmbaJOaJPaJUbDEbDHbhybDFbDGaJOaJPaJUbqCbqCbqCbqCbqCbqCbqCbqCbqCbvOaIubxhbuCbuCbuCbxjbuCbuCbuCbxlbDTbDrbFybxpbxqbxrbxsbxtbxubxvbhRbqLbtvbxwbDzbDCbDAbDtbDsbsjbsjbsjbDhbzbbDgbDfbxHbxHbxHbxHbxIbxHbxHbxHbxJbxJbDebDqbxNbxObDpbDobepbwzbLAbDnbxUbDmbxWbxXbxYbpXbpXbxZbyabybbpXbycbpXbNhbLEbsNblAbgZbgZahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahjahlblIblIblIblIblIblIblIbwObwPbovbwQaYHbwRbovbwQbwSbwSbwSbwSbwTbwUbwVbwSbwSbwWbwWbWmbWtbvwbDJbwZbxabxbbvwbnZbrBaIvaTkaTkbmbbmbbVNbmbbmbbDDbmbaJOaJPaJUbDEbDHbhybDFbDGaJOaJPaJUbqCbqCbqCbqCbqCbqCbqCbqCbqCbvOaIubxhbuCbuCbuCbxjbuCbuCbuCbxlbDTbDrbFybxpbxqbxrbxsbUkbxubxvbhRbqLbtvbxwbDzbDCbDAbDtbDsbsjbsjbsjbDhbzbbDgbDfbxHbxHbxHbxHbxIbxHbxHbxHbxJbxJbDebDqbxNbxObDpbDobepbwzbLAbDnbxUbDmbxWbxXbxYbpXbpXbxZbyabybbpXbycbpXbNhbLEbsNblAbgZbgZahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlblIblIblIblIblIblIblIahlahjahlahlahjahlahlahjahlbwSbydbyebyfbygbyhbyibyjbykbylbVcbVMbUubUvbyqbyrbysbvwbnZbrBaIuaIuaIubCXaLFbUhbbAbyzbCZbCYaWEaWEaWEbDabCTbyIbCUbyJaIuaIuaIuaIuaLFaIuaLpaIuaIuaIubCXaIubvOaIubyMbuCbCNbCObyPbCLbCKbuCbySblrbCHbCIbxpbxqbxqbyUbyVbyWbxvbhRbCFbtvbsjbyYbyZbzabzbbzcbzdbzebzfboeboebwnbCDbxHbzhbzibzjbzkbzlbzmbxHbAVbCubCybCtbzrbzsbribCgbCfbCrbChbCdbzwbCebzybzzbxYbzAbzAbzAbzAbzAbzAbzAbpXbNhbLEbsNblAbgZahlahjahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaGcahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahjahlblIblIblIblIblIblIblIahlahjahlahlahjahlahlahjahlbzBbzCbzDbzEbzFbzGbzHbzIbzJbzKbMtbMgbMFbMubLqbyrbzPbvwbnZbzRaIuaIuaIuaIuaIuaIubbAaIubrBaIuaIuaIuaIuaIubnYbeKbnVaIuaIuaIuaIuaIuaIuaIuaLpbLjaIuaIuaIuaIubvObzXbzYbsUbMMboObAcboOboRbuCboYbDTboZbAjbuCbAkbAlbAmbAnbAobuCbhRbqLbtvbtvbtvbtvbtvboeboeboeboeboeboebXKccNbotbxHbAsbAtbAubAvbAwbAxbxHbAyboHbAAbobbocbzsbribopborbolbombosbosbosbALbAMbxYbzAbANbzAbAObzAbzAbzAbpXbNhbLEbsNblAbgZbgZahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlblIblIblIblIblIahlahlahjahlahlahjahlahlahjahlbwSbAPbAQbARbASbATbAUbyjbylbylbPebOWbyobznbpubAXbAYbvwbpbbBabBbbBbbBbbBcbBbbBbbBdbBbbBeaIubBfbNMbOybOybOUbOQbOVbBlbBmbBnaWEaWEbBoaWEbBpbOCaWEbBrbBsbpcbBuaIuaIubuCbpRbpIbBxbpHbpTbuCbuDbpSbpZbuCbuCbuCbuCbuCbuCbuCbuCbhRbqLbgybBCbqmbuBbBEbBFbBGbBHbBIbBJbBFbXKccNbYQbxHbBObBPbBQbBRbBSbBTbxHbBUbpvbBWbBXbBYbBZbribpzbpAbvdbpBbpCbpDbpEbCibCjbxYbzAbzAbzAbCkbzAbzAbzAbpXbNhbqsbClbrsbrtbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjbwSbwSbCmbCnbCnbCobwSbwSbCpbCqbENbEMbvwbvwbvwbvwbvwbvwbkHbCvaTkaTkaTkaTkbCwbCwbCwbCwbCwbCwbCwbCwbCwbCwbkGbkFbkEbCAbCAbCAbCAbCAbCCbCAbCAbqxbCAbCDbCEbCDaIzaJVbCGbuCbkSbkRbCJbkVblqbuCbCMblrblbbkXblmbldbCPbCQbCRbCSbuDbkIbkJbMzbMzbggbkObkPbkLbkNbCWbCVblWbBFbXKccNbDcbDcbDcbDcbDcbDcbDcbDcbDcbDdbDdbDdbDdbDdbDdblUblxblzbvdbvdbvdbvdbvdbvdbvdbxYbpXbpXbpXbpXbpXbpXbpXbpXbNhbLEaDGaCqbgZbgZahjahjahjdsidsidsidsidsidsidsidsiahjahjahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlbDjahlahlahlahjahlahlbwWbDkbDlbHjbGObGEbGlbIdbHvbHnbHkbIhbIvahlahlahjahlbCwcGxbDvbDwbDxbDybmnbmobmpbmqbmHbmFbmIbCAbmKbmJbmLbFhbmvbFhbFhbIIbmCbmxbmEbCDbCDbCDbCDbuCbmMbxobyTbxobnybuCbDVbDTbnvbmXbmPbmObmPbmPbnFbDYbDZbnEbnCbnCbnCbnJbnHbqMbEcbEdbEebEfbEgbBFbXKccNbDcbEhbEhbEhbEibEhbEhbEhbDcbEjbEjbElbEjbEjbDdbnLbnKbepaKtbEobEpbEqbErbEsbEtbEubEvbEwbExbEyaQebnMciIciIciObnPbEobEobgZahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlbEEbEFbEGbEFbEHahlahjahlbwWbwWbEIbylbQcbQbbQtbQebPGbPGbPPbPJbPzbppahjbEPbEQbERbESbETbDBbEUbDBbEVbDBbDBbDBbCwbQLbQMbtxbCAbtwbtubFebFfbFgbFhbFibqxbCAbFjbFkbtDbFmbuJbFobFpbuObxobFrbxoblrbuxbuEbuzbuFbuCbFvbuIbxobxobusbFzbnTbnTbnTbnTbnTbudbuobLhbupburbFCbCVbucbBFbXKccNbDcbEhbEhbEhbEhbEhbEhbEhbDcbFHbubbFJbFKbFLbDdbtUbtZbuabtXbtYbHqbtKbFQbFQbFQbFQbFRbFSbFTbEybgZbLFbtIbQxbQxbtJbFVbFWahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjbFXbFYbFXahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlbFZbGabGbbGabFZbGcbGdbGebwWbGfbylbGgbQCbQvbGibwWbCvbGjbCvbCvboEbqNahlbGmbGnbGobGpbDBbDBbGqbDBdnRbGsbGtbDBbCwbQLbuQbuRbCAbuPbGybGzbGAbGBbFhbuUbqxbsfbuScdQbuTcdQbwebGKbuCbwgbmPbwfbmPbvVbsUbvSbmObvWbuCbGRbxobxobxobGSbGTbnTbGUbwjbwkbwibggbwhbqMbGYbCVbCVbGZbHabHbccPbvcbDcbEhbEhbEhbEhbEhbEhbEhbDcbHebuZbuYbvubvxbvAbvHbvIbscbvRbHobFQbvebFQbFQbFQbFQbFQbFQbFQbEybuXbuWbuVbHwbHxbHybHzbHAahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjbHBbFXbHCbFXbHBahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahjahlbEGbHDbHEbHDbEGbHFbHGbHHbwWbHIbylbHJbylbylbGibwWbHKbHLbELbCvboEboFahjbGmbHNbHObHPbHQbHRbHQbHQbHSbHTbHQbHQbHUbqubeLbHXbCAbCBbCAbCAbCAbCAbHYbPxbPmbHZbIabIbbIcbrObIcbIfbuCbrMbrLbIibrNbrGbuCbrKbrJbrpbuCbIobrEbIqbrgbIsbItbnTbgdbrbbrcbqWbqYbrabIxbIybIzbCVbCVbIAbBFbsfccNbDcbDcbICbEhbEhbIDbICbDcbDcbIEbIFbIGbsebIHbDdbsdbhibscbsabsbbrVbrVbrWbrXbrUbrVbrPbrQbqGbqDbqIbqHbqVbPybIWbIXbIYbIZahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjbJabJbbJcbJdbJebJbbJaahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlbDjahlahlahlahjahlahlbwWbDkbDlbHjbGObGEbGlbIdbHvbHnbHkbIhbIvahlahlahjahlbCwcjKbDvbDwbDxbDybmnbmobmpbmqbmHbmFbmIbCAbmKbmJbmLbFhbmvbFhbFhbIIbmCbmxbmEbCDbCDbCDbCDbuCbmMbxobyTbxobnybuCbDVbDTbnvbmXbmPbmObmPbmPbnFbDYbDZbnEbnCbnCbnCbnJbnHbqMbEcbEdbEebEfbEgbBFbXKccNbDcbEhbEhbEhbEibEhbEhbEhbDcbEjbEjbElbEjbEjbDdbnLbnKbepaKtbEobEpbEqbErbEsbEtbEubEvbEwbExbEyaQebnMciIciIciObnPbEobEobgZahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlbEEbEFbEGbEFbEHahlahjahlbwWbwWbEIbylbQcbQbbQtbQebPGbPGbPPbPJbPzbppahjbEPbEQbERbESbETbDBbEUbDBbEVbDBbDBbDBbCwbQLbQMbtxbCAbtwbtubFebFfbFgbFhbFibqxbCAbFjbFkbtDbFmbuJbFobFpbuObxobFrbxoblrbuxbuEbuzbuFbuCbFvbuIbxobxobusbFzbnTbnTbnTbnTbnTbudbuobLhbupburbFCbCVbucbBFbXKccNbDcbEhbEhbEhbEhbEhbEhbEhbDcbFHbubbFJbFKbFLbDdbtUbtZbuabtXbtYbHqbtKbFQbFQbFQbFQbFRbTubFTbEybgZbLFbtIbQxbQxbtJbFVbFWahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjbFXbFYbFXahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlbFZbGabGbbGabFZbGcbGdbGebwWbGfbylbGgbQCbQvbGibwWbCvbGjbCvbCvboEbqNahlbGmbGnbGobGpbDBbDBbGqbDBdnRbGsbGtbDBbCwbQLbuQbuRbCAbuPbGybGzbGAbGBbFhbuUbqxbXKbuScdQbuTcdQbwebGKbuCbwgbmPbwfbmPbvVbsUbvSbmObvWbuCbGRbxobxobxobGSbGTbnTbGUbwjbwkbwibggbwhbqMbGYbCVbCVbGZbHabHbccPbvcbDcbEhbEhbEhbEhbEhbEhbEhbDcbHebuZbuYbvubvxbvAbvHbvIbscbvRbHobFQbvebFQbFQbFQbFQbFQbFQbFQbEybuXbuWbuVbHwbHxbHybHzbHAahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjbHBbFXbHCbFXbHBahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahjahlbEGbHDbHEbHDbEGbHFbHGbHHbwWbHIbylbHJbylbylbGibwWbHKbHLbELbCvboEboFahjbGmbHNbHObHPbHQbHRbHQbHQbHSbHTbHQbHQbHUbqubeLbHXbCAbCBbCAbCAbCAbCAbHYbPxbPmbHZbIabIbbIcbrObIcbIfbuCbrMbrLbIibrNbrGbuCbrKbrJbrpbuCbIobrEbIqbrgbIsbItbnTbgdbrbbrcbqWbqYbrabIxbIybIzbCVbCVbIAbBFbXKccNbDcbDcbICbEhbEhbIDbICbDcbDcbIEbIFbIGbsebIHbDdbsdbhibscbsabsbbrVbrVbrWbrXbrUbrVbrPbrQbqGbqDbqIbqHbqVbPybIWbIXbIYbIZahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjbJabJbbJcbJdbJebJbbJaahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlbFZbHDbHDbHDbJfbJgbylbylbJhbHIbylbylbylbylbGibwWbfFbELbccbCvboEbtFahlbGmbJmbJnbJobDBbDBbJpbDBbJqbJrbJsbJtbCwbshbsgbsobsmbsxbsvbsvbsvbsvbsvbsybsvbsBbszbsFbsCbsVcePchtbsUbsUbsUbsUbsUbsUbsUbsUbsUbsUbsUbsUbsUbsUbsUbsUbtbbnTbnTbnTbnTbnTbtabuAbhSbBFbBFbBFbBFbBFbBFbXKccNbDcbJQbJRbJSbJTbJUbJVbJQbJWbIEbIFbIGbtpbtqbtrbtsbthbtmaKvbEobKabKabKbcGybtdbKebFQbFQbKfbEybsHbKhbsMbEobKjbKkbKlbEoahjahlahlahjahlahlahlahlahjahlahlahlahlahjahlahlahlahlahjahlahjahjbKmbKnbKobKpbKpbKpbKqbKmbKnahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlbEGbHEbHEbHEbEGbKrbKsbKtbKubKvbylbylbKwbEKbKxbwWbCvbCvbCvbCvboEbppahjbKybEQbKzbKAbKBbDBbKCbDBbDBbDBbDBbDBbCwbQLbhhbgYbgLbgKbgKbgKbgKbgKbgKbgJbgIbgHbfLbgGbgBbfRbfQbfSbmNbfTbmNbmNbmNbmNbmNbmNbmNbmNbmNbmNbmNbmNbmNbfVbgabnTbgdbLdbMzbgebggbgibgkbglbgobgobgxbfMbfLbfKbfJbDcbLrbLsbLtbLubLvbLwbLxbJWbJWbJWbJWbJWbJWbLybfNbfObfPbLBbEobEybEybEybEybEybEybLDbFQbFQbEybgZbLFbLEbEobLGbLHbLIbLJdsidsiahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjahjbLKbLLbLKbKpbLMbKpbLNbLObFXahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlbFZbLPbLQbLRbFZbLSbGdbGebwWbwWbLTbLUbLVbwWbwWbwWahlahlahlbLWbqhbqNahlahlahjahlbCwbLYbLZbMabDBbMbbiEbiJbiSbKGbiDbiCbfIbMibMjbMkbMlbMmbesbMjbMjbMjbMjbMjbMobiBbMjbMjbMrbMjbMsbMjbMjbMjbMjbMjbCDbCDbCDbCDbCDbCDbCDbCDbNIbXIbnTbhHbhFbhGbhMbicbhIbqgbipbhpbhpbiobhpbhpbhsbhqbDcbhwbMNbhCbMNbhEbMNbMObMPbMQbMRbMSbMTbMUbgUbribhibepbMXahjbMYbMZbNabNbbhmbNbbNdbNebNfbEyckEbNhbiubEobEobEobEobEoahjahlahlahjahlahlahlahlahjahlahlahlahlahjahlahlahlahlahjahlahjahjbKmbKnbNjbKpbKpbKpbNkbKmbKnahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlbFZbLPbLQbLRbFZbLSbGdbGebwWbwWbLTbLUbLVbwWbwWbwWahlahlahlbLWbqhbqNahlahlahjahlbCwbLYbLZbMabDBbMbbiEbiJbiSbKGbiDbiCbfIbMibMjbMkbMlbMmbesbMjbMjbMjbMjbMjbMobiBbMjbMjbxtbMjbFSbMjbMjbMjbMjbMjbCDbCDbCDbCDbCDbCDbCDbCDbNIbXIbnTbhHbhFbhGbhMbicbhIbqgbipbhpbhpbiobhpbhpbhsbhqbDcbhwbMNbhCbMNbhEbMNbMObMPbMQbMRbMSbMTbMUbgUbribhibepbMXahjbMYbMZbNabNbbhmbNbbNdbNebNfbEyckEbNhbiubEobEobEobEobEoahjahlahlahjahlahlahlahlahjahlahlahlahlahjahlahlahlahlahjahlahjahjbKmbKnbNjbKpbKpbKpbNkbKmbKnahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlbNlbEFbNmbEFbNnahlahjahlahjdsiahjahlahjdsiahjahlahlahlahjbHMboEboFahjahjahjahjbCwbCwbCwbCwbCwbCwbCwbCwbCwbCwbeybexbewbevbMjbMkbMlbMmbesbNrbNrbNtbNubNvbeubetbNybNzbNAbdWbNCbNDbNEbNFbOGcGaahjahlahlahlahlahlahjbCDbNIbSubNJbNJbNJbNJbNJbNKbNLboDbNJbNJbNJbNJbNJbNJbSubencGubNQbNRbNSbNRbNTbNUbNVbNWbNWbNWbNWbNWbNWbNXbeqbeobepbObahjbMYbOcbOcbOdbOebOfbOgbOhbOibEycoxbNhbPqbgZbOkayRbgZahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahjahjbJabHBbOmbOnbOobOpbJaahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahjahlahjdsiahjahlahjdsiahjahlahlahlahlbHMboEboFahlahlahlahjbOqbOrbOrbOsbOtbOubOubOwbOwbOqbQLbfHbfIbOzbMjbOAbOBbOBbfibODbNrbOEbOFbfrbfCbfsbeMbeHbeDbeBbOGbOLbOGbOMbONbOOahjbOPbOPbOPbOPbOPahjbCDbNIbpaboQbezbOSbOTbNJbpnbpgbphbNJbOXbOYbOZbOYbOXbSubeTbDcbMNbMNbMNbeZbMNbMNbfhbeUbPcbPcbPgbPcbPcbgSbePbeNbeObPkahjbMYbOcbPlbNbbeSbNbbPnbPobPpbEyblAbNhbPqbgZblAblAbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjbJbbFXbPrbFXbPsahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjahjahjahjahjahjahjahjbCvbCvbPtbPubPvbCvbCvahlahlahlahlbHMboEboFahlahlahlahjbOqbPwbOsbOsbOsbOsbOubCsbzObBqbDIbiCbjWbPBbPCbjVbjUbjTbkabkcbkbbjUbjUbjUbkabjZbjEbjDbjMbPHbPKbPLbPMbPNbPObUpbPQbPRbPSbPTbPUbOPahjbjRbNIbSubPWbOXbOXbOXbNJbjNbeAbjPbNJbOYbQdbOYbzNbzMbyObjLbDcbQfbQgbQhbQibQjbQkbQlbQmbQnbQobQpbQqbQrbJWbSSbjBbjCbQubQubEybEybEybEybEybEybEobEobEobEybjzbNhbjyblAblAbQzbgZahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjbFXbFYbFXahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlbCvbQAbELbQBbELaClbCvahlahlahlahlbHMbqhboFahlahjbQDbQEbOqbQFbQGbQHbOsbOsbQIbQJbOubQKbQLbfHcerbQNbQObkubkwbkvbkBbkAbkCbkvbkxbkvbkzbkybPIbQVbQWbQXbQYbQZbRabRbbRcbRdahjbRebRfbPUbRgbOPahjcbMbNIbSubRibRjbOXbRkbNJbRlbEJbktbNJbOXbvEbRpbOXbOXbSubNIbDcbJWbJWbJWbJWbLybRtbRubRvbLybJWbJWbJWbJWbJWbRwcfbbUIbRzbRAbRBbRCcbGbRCbREbQubRFbRybRGbRHcjSbNhbPqbgZbgZbgZbgZbRJahjahjahjdsidsidsidsidsidsiahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjahjahjbCvazvbELbELbELaBdbCvahlahlahlahlbHMboEbtFahlahjbTabRNbRObRPbtWbtHbtHbtHbtHbtHbujbvkbvvbfHcerbNqbjdbjcbjbbOGbjebRZbQVbSbbScbSdbSebSfbSfbSgbShbPKbSibSjbSkbSlbSmbWIbSobPRbSpbPUbPUbOPahjbiXbNIbSubdobOXbSsbNKbNJbNJbrFbNJbNJbSvbrAbStbSvbSzbSubNIbDcbSDbSEbSEbSFbSGbMNbSHbSIbSJbSKbEhbEhbEhbJWbSLbiYbiZbSMbSNbRBbSObSPbSQbSRbSSbRybSTbRybRHaDGbiUbiVbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlbCvazvbELbELbSYaBgbCvahlahjahlahlbJlboEbppbCvbCvbCvbTbbOqbTcbOsbOsbOsbTdbTebTfbTgbOqbQLbfHcerbNqbQObjtbjxbOGbOGbTjbNrbTkbTlbTmbTnbOGbOGbTobTpbTqbTrbTsbTtbTubTtbTvahjbOPbOPbOPbOPbOPahjbCDbNIbSubTwbyybyybyKbynbypbwNbjibjgbOXbvEbOXbOXbOXbSubNIbDcbEhbEhbEhbTJbTKbMNbTLbMNbTMbTNbEhbEhbEhbJWbTObjmbjqbYbbjsbTRbTSbTTbTRbTUbQubTVbRybTWbRHbgZcgFbjfbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlbTXahlahjahjbTYbTYbTYbTYbTYbTYbTYbTYbCvbCvbTZbCvbCvbCvbPtbPubPvducduddujduidukdrBdudduhbvkbvkbvkbvkbvkbvkbvkbvkbvkdugduedufcerbUdbMjbNscaGbUebUfbUebNrbOGbOGbOGbTnbUibONbONbUjbUkbUlbPLbUmbUnbUobUpbPQbPRbUqbUrbUrbOPahjbCDbNIcaVbPZbPZbPZcbhbUsbOXdulbOXbOXbOXbvEbOXbOXbOXbSubNIbDcbEhbEhbEhbUAbUBbSIbUCbMNbUDbUEbSEbSEbUFbJWbUGbUHbUIcbzcbjbRBbSQbUKbTRbULbQubUMbUMbUMbRHcaUbZPbjfbgZahjahjahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlbUObUPbUQbURbUSbURbUTbUUbUVbUWbUXbUYbUZbTYbVabVbbVbbVbbVbbVbbVbbVbbVbdsHdtidtJdrldrldrldrldtHdtpdtpdtpdtxdtpdtmbPGbPGdtkbppbQLbfHcerbVobVpbZNbZMbONbONbZLbVsbONbONbVtbVubVvbOGbVwbVxbVybVzbOGbVAbVBbVCbRdahjbRebVDbVEbVFbOPahjcaSbZRbZQbZQbZQbZSbSubVKbTwdtRdtOdtVdtSdtYdtXduadubbSubNIbDcbJWbJWbJWbJWbVRbVSbTLbVTbVRbJWbJWbJWbJWbJWbVUbVVbVWcaCcaBbVZbVZbVZbVZcaFbSSbUMbUMbWcbRHbZObZPbjfbgZbgZbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlbWebWebWebWebWebWfbWgbWhbWibWibWhbTYbELbWjbWkbWkbWkbWkbWkbWkbWlbppdcdbWnbWnbWnbWnbWnbWnbWnbWnbWobWobWobWobWocbNdumbppbQLbfHcerbVobWscceccfbWvbSfcbVbWxbSfbSfbWybWzbWAbWBbWCbWDbWEbWFbOGbVAbWGbWHbWIbSobPRbWJbUrbUrbOPahjcbMbXKbCDbCDbCDbjLbSubWNbOXbOXbWPduwbUtbWTcbUbWTbUtbSubNIbDcbSDbSEbSEbWUbSGbMNbSHbSIbWVbWWbEhbEhbEhbJWbWXbWYbWZbRxbjmbYbccuccwccvccibQubUMbUMbUMbRHbZObZPbjfblAblAbgZahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjbXcbXdbXebXfbXebXgbXhbXibXjbXjbXkbTYbXlbXmahlahlahjahlahlahjahlbppdcdbWnbXnbXobXpbXqbXrbXsbXnbXtbXubXvbXwbWobWodumbppdunbfHcerbXybXzcbDcbDbXCbMjbMjbMjbMjbMjbXDbXEbNrbNrbNrbXFbOGbVybOGbVAbVBbXGbRdahjbOPbOPbOPbOPbOPahjbXHbXKbCDcbobXKbjLbpadusdurduvdutduqdupbXPcbUbXPbXQbSubNIbDcbEhbXRbEhbXSbTKbMNbTLbMNbTMbXTbEhbXRbEhbJWbXUbXVbXWbXXbXYbXZbYacbQcbPcbFbSSbCxbYfchUbRHbUMbZPbUwbgZblAbgZbgZbgZdsidsiahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjbXcbYjbYkbYlbYmbWhbYnbWhbYobWhbWhbYpbELbXmahlahlahjahlahlahjahlbppdcdbWnbXnbYqbYrbYsbYtbYubXnbYvbYwbYxbYybYzbWodumbppbQLbfHcerbYAbYBbMjcdvbYDbMjcdwcuLbYGbMjbYHbTnbZUbNrbYJbWFbOGbWDbYKbYLbUnbYMbUpbPQbPRbYNbYObYPbOPahjbCDbXKbCDbYQbXKbjLbSubYRduzbYTbYUduAduzcdHcdAcdHbzNbyObNIbDcbEhbEhbEhbYZbZabSIbUCbMNbUDbZbbSEbSEbUFbDcbRHbZcbZdbZebRHbRHbZfbZgcdMcdNbZjbVYbVZbZkbUMbUMbZPbjfbgZbrqbgZbZlbgZahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjbXcbZmbZnbZobZnbZpbZqbZrbZsbZtbZubTYbZvbZwahlahlahlahlahlahlahlbppdcdbWnbZxbZybZzbYsbZAbZxbZxbYvbZBbZCbYyccAbWodumbppbQLbfHbGwcbAcbAccWccBccQcdbcdlccXduxbMjbOGbTndjybZVbYJbZWbOGbWDbYKbVAbVBbZXbRdahjbReclkbZZcaabOPahjbCDbXKbCDcabcacbjLbSubNJcadcaebNJduybNJbNJbNJbNJbNJbSubNIbDcbJWbJWbJWbJWbVRcafbTLcagbVRbJWbJWbJWbJWbDcbTRcahbTRbTRbTRbRHbZfbZgcdtcducakcalbRxbCzbRHbUMbZPbjfbgZblAblAblAcanahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaGcahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjahjahjahjahjahjahjahjahjbWebWebWebWebWebTYbTYbYpbTYbTYbTYbTYahjahlahlaPYahlahlahlahlahlduNdcdbWnbZxbZxcarcasbXnbZxcatcaucavcawcaxcaybWodumduMduJduKcexcbAcaDcaEcaEceJcaHcaIceKduLbMjcaLcaMbZUbNrbYJcaNbOGcaObYKbVAcaPcaQbWIbSobPRcaRbYObYObOPahjcaSbXKbCDcaTbXKbjLceQbPZbPZceObNJduOdpDdpCbNKcaZccmbXIbNIbDcbSDbSEbSEcbbbSGbMNbSHbSIcbccbdbEhbEhbEhbDccbebTRbTRbTRbTRbRHcbfcbgceMceLbQubQubRxbQubRHbQubZPbjfbgZcbkcblcbmcbnahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHaaHaaHdpXdpXaaHdpXdpXdpXaaRdpXdpXdpXaaHdpXahjahjbCvbELbELbELbELbELbELbELbELbJjcbpahjahlahlahjdsiaFFahlahlahldotdcdbWncbscbtcascbubXnbXncbvcbwcbvcbxbYycbybWoduCduBduDduEbHXcbAdpFcaEcdOcdzcbEduGcdPduFduHbPHcbIbNrbNrbNrcbJbOGcbKcbLbVAbVBbOGbRdahjbOPbOPbOPbOPbOPahjcbMbXKbCDcchcbObZRbZQbZQceocepbNKduIcuYdpBbNKceabhpcdTcbWbDcbEhbEhbEhcbXbTKbMNbTLbMNbTMcbYbEhbEhbEhbDccbZbTRccabTRbTRccbcccccdcemcebbQubRxbRxccgbRHaDGbPdbWdbgZccjcckblAcclahjahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHahlahlahjahjahlahjahjahlahlahjahjahjahldpXahlahlbCvbRKbELbCvbCvbCvbTZbCvbCvbCvbCvahlahlahldsiaDIauKdsidsiahjdotdcdbWnccpbZxbXnbXnbXnbZxcatccqccrbYyccscctbWobCvbCvbTzbTAbTBcbAcbAccxcaEdoZdoKdoMdoNdoQbMjbOGbOJccDccEccFbQWccGccHccIbYLbUnccJbUpbPQbPRccKccLccLbOPahjbXHbXKbCDbCDbCDbXKbCDbCDccMbDbbCDbCDcuBbCDbCDbDbbSWbSXbThbDcbEhbEhbEhccRccSbSIccTbMNbUDccUbSEbSEbUFbDcbTRbTRccVbTRbTRbRHcbfcbgbTibTxbQuccYccZcdabRHbfGbPdbjfbgZbgZbgZblAbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHahlcdccddcdeahlcdccddcdeahlcdccddcdeahjdpXahlahlbCvcdfcdgbCvcdhbELbELbOlaClcdkbCvahlahlahlatIdsidsiahjahlahldbVdcdbWnbZxcdncdobXncdpbZxbZxbYvcdqbYybYycdrbWocdsbSVbSCbSUbSBdoidnZdcNdctdcNdctdcvdctdcubMjcdCcdDcdEbSfbSfbShbUicdFbUmbSibVBcdGbRdahjbReclhcdIcdJbOPahjbCDbXKbXKcdKbXKbXKcdLbCDccMbSabRYbSqbSnbSwbRYbSAccMbLEcdVbDcbDcbDcbDcbDcbDccdWcdXcdYbDcbDcbDcbDcbDcbDcbRHbRHbRHbRHbRHbRHcdZcdZbSxbSybRHbRHbRHbRHbRHbgZcgFbjfbgZbNibOjblAbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHahlcdcceecdeahlcdcceecdeahlcdcceecdeahjahjahlahlbCvbPtbPvbCvbCvcefcegaClbELbSYbCvahlahlahlahlahjahlahlahlahlbppdcdbWnbXncehceibXncejcekbXnbYvcelbYxbYybYybVebVfbfIcercHqbVgceucevcewbVhceycezdpYcaEdqsbMjceBbOGbOJbUibONceCceDceEceFbNFceGceHbWIbSobPRceIccLccLbOPahjbCDbXKbXKbXKbXKbXKbUzbCDbVdbUxbUNbJFbfKbJFbUJbUxbUybLEbTEbgZahlahlahlahjahlahlceVahlahjahlahlahlahlbgZceWayRceYceZceZbRHcfacfabSxbiZcfccfdblAblAblAaDGcgFbUwbgZcffblAblAbgZbgZbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXahjcdcceecdeahlcdcceecdeahjcdcceecdeahjahjahlahlahlahlahjahjbCvbCvbCvbCvbTZbCvbCvahlahlahlahlahjahlahlahjahlbppdcdbWnbXncfgcfhcficfjcfkbXncflcfmcfncfocfpbWocfqdpVdpPdpQdpNdpOdpTdpUdpRdpSdpsdpzdpadprdpAdpEbQZcfFcfGbOGbOGbOGbOMbVvcfGbVBbXGbRdahjbOPbOPbOPbOPbOPahjbCDcabcfHcfIcfJcacbCDbCDbCDcfKbTGcdUbXKcfMbTFbCDbCDbLEbTEbgZahlahlahlahjahlahlceVahlahjahlahlahlahlbgZblAbjzbrsbjzblAbRHcfScfSbTDbiZbRHbQubgZcfUcfVaDGcgFbTCbECbECbECcfYcfZcgacfZcgbdsiahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlcdcceecdeahjcdcceecdeahlcdcceecdeahlahjahlahlahlahlahlahlbCvckLbCvbELbELbCvahjahlahjahlahlahjahlahlahjahlbppdcdbWnbWnbWnbWnbWnbWnbWnbWnbWobWobWobWobWobWobCvbWpbCvcggcghcghcghcgicgjcgkcghbWrdqEdqRbMjchecgqbSkcgrcgscgtcgscgrcgucgrcgvbUicgwahjahjahjahjahjahjahjahlahjcbMbXKcbMahjahlbCDcgxbCDcgzcgzcgAcgzcgzbCDbYQbzgbTEbgZcgCcgDcgEbgZcgCcgDcuncgEbgZcgCcgDcgDcgEbgZbgZbgZcgGbgZbgZbRHbRHbRHbWabWbbRHaDGbgZcbmblAbpYcgFbWdbgZbgZcgLbgZbgZbgZbgZahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHaaHdpXahjahlcdcceecdeahjcdcceecdeahlcdcceecdeahjahjahjahjcgMcgNcgNcgNcgNbCvbCvcgObELbCvcgPbWkbWkbWkbWkbWkbWkbWkbWlbCvbppdcdbCvcgQbVPbVObVObVObVObVObVObVObVObVObVXbVXbVObVQcefcggcnjcgWcgXcgYcgZchacghdoBcmIdqxbMjchechfchgchhchichjchkchlbOGchmchnchobOIahjahjahlahlahlahlahjahlahjchpcfIchpahjahlbCDchqbsfbVicdUbsfcdUcdUbXKbXKbzgbJEbVHbVHbVHbVHbVHbVHbVHbVIbVqbVqbVqbVqbVqbVqbVrbVqbVqbVqbVqbVGciFbVlbVkbVjbVnbgZbgZbVmciFbVJciFbVLbjfbgZchLblAblAbgZahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHahlahjahlahjahjchMahjahjahjchMahjahlahjchMahjahlahjchNchOchPchQchRchSchTcgebELchYchZciachZchZchZchZchZchZchZchZchZchZdsrdsydrBdrAbiTcicciccicciccicciccicciccicciccicciccicciccggcghciecifdsbbZDbZEbZFckUckbdspciccinciocipciqcipciocipciqcipcircipcircisahjahjahlahlahlahlahjahlahjahlahlahlahjahlbCDchqbXKcdUcjMbYWbYVceTbFobXabXbbWQbWQbWQbWQbWQbWQbWQbWRbWSbWQbWQbWQbWQbWQbWQbYIbYEbYhchEbYCbYibYcbYcbYcbYdbXAbXxbXObXBbYYbYcbYcbYXbZhbgZbOjblAcbabgZahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXahjciRciSciSciTciUciUciUciUciUciUciUciUciUciUciUciVciXciYciXciZdrvcjbcbHchZcjdcjeaClbCvcjgcjhcjhcjhcjhcjhcjhcjhcjibCvbCvdrqdrldrjdrgciccjncjncjociccjpcpFcpEcpCcpOcpNcjvcmvcjxcjycghcjzcjAdracjCcjDcjEcjHdrbdrdcicahjcjIahjcjJahjcjIahjcjJahjcjKahjcjKahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlbCDbXKcjLcjMccPcjObXJbFobSZbWqbCDbgZcgCcgDcgDcgEbgZcgCcgDcgDcgEbgZcgCcgDcgDcgEbgZcpGblAbgZbWKbWwbgZbgZcgCcgEbgZbgZcjTbPdbPbbgZcjUcjVbpWbgZbgZbgZbgZbgZahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahjahlahjdsiahjahlahjdsiahjahlahlahlahlbHMboEboFahlahlahlahjbOqbOrbOrbOsbOtbOubOubOwbOwbOqbQLbfHbfIbOzbMjbOAbOBbOBbfibODbNrbOEbOFbfrbfCbfsbeMbeHbmgbeBbOGbOLbOGbOMbONbOOahjbOPbOPbOPbOPbOPahjbCDbNIbpaboQbezbOSbOTbNJbpnbpgbphbNJbOXbOYbOZbOYbOXbSubeTbDcbMNbMNbMNbeZbMNbMNbfhbeUbPcbPcbPgbPcbPcbgSbePbeNbeObPkahjbMYbOcbPlbNbbeSbNbbPnbPobPpbEyblAbNhbPqbgZblAblAbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjbJbbFXbPrbFXbPsahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjahjahjahjahjahjahjahjbCvbCvbPtbPubPvbCvbCvahlahlahlahlbHMboEboFahlahlahlahjbOqbPwbOsbOsbOsbOsbOubCsbzObBqbDIbiCbjWbPBbPCbjVbjUbjTbkabkcbkbbjUbjUbjUbkabjZbjEbjDbjMbPHbPKbTqbPMbPNbPObTnbPQbPRbPSbPTbPUbOPahjbjRbNIbSubPWbOXbOXbOXbNJbjNbeAbjPbNJbOYbQdbOYbzNbzMbyObjLbDcbQfbQgbQhbQibQjbQkbQlbQmbQnbQobQpbQqbQrbJWbSSbjBbjCbQubQubEybEybEybEybEybEybEobEobEobEyblAbNhbjyblAblAbQzbgZahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjbFXbFYbFXahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlbCvbQAbELbQBbELaClbCvahlahlahlahlbHMbqhboFahlahjbQDbQEbOqbQFbQGbQHbOsbOsbQIbQJbOubQKbQLbfHcerbQNbQObkubkwbkvbkBbkAbkCbkvbkxbkvbkzbkybPIbQVbQWbQXbQYbQZbRabRbbRcbTsahjbRebRfbPUbRgbOPahjcbMbNIbSubRibRjbOXbRkbNJbRlbEJbktbNJbOXbvEbRpbOXbOXbSubNIbDcbJWbJWbJWbJWbLybRtbRubRvbLybJWbJWbJWbJWbJWbRwcfbbUIbRzbRAbRBbRCcbGbRCbREbQubRFbRybRGbRHcjSbNhbPqbgZbgZbgZbgZbRJahjahjahjdsidsidsidsidsidsiahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjahjahjbCvazvbELbELbELaBdbCvahlahlahlahlbHMboEbtFahlahjbTabRNbRObRPbtWbtHbtHbtHbtHbtHbujbvkbvvbfHcerbNqbjdbjcbjbbOGbjebRZbQVbSbbScbSdbSebSfbSfbSgbShbPKbSibSjbSkbSlbSmbMrbSobPRbSpbPUbPUbOPahjbiXbNIbSubdobOXbSsbNKbNJbNJbrFbNJbNJbSvbrAbStbSvbSzbSubNIbDcbSDbSEbSEbSFbSGbMNbSHbSIbSJbSKbEhbEhbEhbJWbSLbiYbiZbSMbSNbRBbSObSPbMsbSRbSSbRybSTbRybRHaDGbiUbiVbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlbCvazvbELbELbSYaBgbCvahlahjahlahlbJlboEbppbCvbCvbCvbTbbOqbTcbOsbOsbOsbTdbTebTfbTgbOqbQLbfHcerbNqbQObjtbjxbOGbOGbTjbNrbTkbTlbTmbSQbOGbOGbTobTpbRdbTrbPLbTtbOJbTtbTvahjbOPbOPbOPbOPbOPahjbCDbNIbSubTwbyybyybyKbynbypbwNbjibjgbOXbvEbOXbOXbOXbSubNIbDcbEhbEhbEhbTJbTKbMNbTLbMNbTMbTNbEhbEhbEhbJWbTObjmbjqbYbbjsbTRbTSbTTbTRbTUbQubTVbRybTWbRHbgZcgFbjfbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlbTXahlahjahjbTYbTYbTYbTYbTYbTYbTYbTYbCvbCvbTZbCvbCvbCvbPtbPubPvducduddujduidukdrBdudduhbvkbvkbvkbvkbvkbvkbvkbvkbvkdugduedufcerbUdbMjbNscaGbUebUfbUebNrbOGbOGbOGbSQbUibONbONbUjchfbUlbTqbUmbUpbUobTnbPQbPRbUqbUrbUrbOPahjbCDbNIcaVbPZbPZbPZcbhbUsbOXdulbOXbOXbOXbvEbOXbOXbOXbSubNIbDcbEhbEhbEhbUAbUBbSIbUCbMNbUDbUEbSEbSEbUFbJWbUGbUHbUIcbzcbjbRBbMsbUKbTRbULbQubUMbUMbUMbRHcaUbZPbjfbgZahjahjahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlbUObUPblMbsfbUSbsfbSnbURbUQbUWbUXbUYbUZbTYbVabVbbVbbVbbVbbVbbVbbVbbVbdsHdtidtJdrldrldrldrldtHdtpdtpdtpdtxdtpdtmbPGbPGdtkbppbQLbfHcerbVobVpbZNbZMbONbONbZLbVsbONbONbVtcgqbVvbOGbVwbVxbVybVzbOGcgrbUnbVCbTsahjbRebVDbVEbVFbOPahjcaSbZRbZQbZQbZQbZSbSubVKbTwdtRdtOdtVdtSdtYdtXduadubbSubNIbDcbJWbJWbJWbJWbVRbVSbTLbVTbVRbJWbJWbJWbJWbJWbVUbVVbVWcaCcaBbVZbVZbVZbVZcaFbSSbUMbUMbWcbRHbZObZPbjfbgZbgZbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlbWebWebWebWebWebWfbUTbWhbWibWibWhbTYbELbWjbWkbWkbWkbWkbWkbWkbWlbppdcdbWnbWnbWnbWnbWnbWnbWnbWnbWobWobWobWobWocbNdumbppbQLbfHcerbVobWscceccfbWvbSfcbVbWxbSfbSfbWybWzbWAbWBbWCbWDciobWFbOGcgrbWGbWHbMrbSobPRbWJbUrbUrbOPahjcbMbXKbCDbCDbCDbjLbSubWNbOXbOXbWPduwbUtbWTcbUbWTbUtbSubNIbDcbSDbSEbSEbWUbSGbMNbSHbSIbWVbWWbEhbEhbEhbJWbWXbWYbWZbRxbjmbYbccuccwccvccibQubUMbUMbUMbRHbZObZPbjfblAblAbgZahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjbXcbXdbUUbXfbUUbWgbUVbXhbXgbXgbXkbTYbXlbXmahlahlahjahlahlahjahlbppdcdbWnbXnbXobXpbXqbXrbXsbXnbXtbXubXvbXwbWobWodumbppdunbfHcerbXybXzcbDcbDbXCbMjbMjbMjbMjbMjbXDchjbNrbNrbNrbXFbOGbVybOGcgrbUnbXGbTsahjbOPbOPbOPbOPbOPahjbXHbXKbCDcbobXKbjLbpadusdurduvdutduqdupbXPcbUbXPbXQbSubNIbDcbEhbXRbEhbXSbTKbMNbTLbMNbTMbXTbEhbXRbEhbJWbXUbXVbXWbXXbXYbXZbYacbQcbPcbFbSSbCxbYfchUbRHbUMbZPbUwbgZblAbgZbgZbgZdsidsiahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjbXcbYjbYkbYlbYmbWhbYnbWhbYobWhbWhbYpbELbXmahlahlahjahlahlahjahlbppdcdbWnbXnbYqbYrbYsbYtbYubXnbYvbYwbYxbYybYzbWodumbppbQLbfHcerbYAbYBbMjcdvbYDbMjcdwcuLbYGbMjbYHbSQbZUbNrbYJbWFbOGbWDbYKbYLbUpbYMbTnbPQbPRbYNbYObYPbOPahjbCDbXKbCDbYQbXKbjLbSubYRduzbYTbYUduAduzcdHcdAcdHbzNbyObNIbDcbEhbEhbEhbYZbZabSIbUCbMNbUDbZbbSEbSEbUFbDcbRHbZcbZdbZebRHbRHbZfbZgcdMcdNbZjbVYbVZbZkbUMbUMbZPbjfbgZbrqbgZbZlbgZahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjbXcbZmbUUbZobUUbZpbZnbZrbXhbXhbZubTYbZvbZwahlahlahlahlahlahlahlbppdcdbWnbZxbZybZzbYsbZAbZxbZxbYvbZBbZCbYyccAbWodumbppbQLbfHbGwcbAcbAccWccBccQcdbcdlccXduxbMjbOGbSQdjybZVbYJbZWbOGbWDbYKcgrbUnbZXbTsahjbReclkbZZcaabOPahjbCDbXKbCDcabcacbjLbSubNJcadcaebNJduybNJbNJbNJbNJbNJbSubNIbDcbJWbJWbJWbJWbVRcafbTLcagbVRbJWbJWbJWbJWbDcbTRcahbTRbTRbTRbRHbZfbZgcdtcducakcalbRxbCzbRHbUMbZPbjfbgZblAblAblAcanahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaGcahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahjahjahjahjahjahjahjahjahjahjahjbWebWebWebWebWebTYbTYbYpbTYbTYbTYbTYahjahlahlaPYahlahlahlahlahlduNdcdbWnbZxbZxcarcasbXnbZxcatcaucavcawcaxcaybWodumduMduJduKcexcbAcaDcaEcaEceJcaHcaIceKduLbMjcaLcjIbZUbNrbYJcaNbOGcaObYKcgrcaPcaQbMrbSobPRcaRbYObYObOPahjcaSbXKbCDcaTbXKbjLceQbPZbPZceObNJduObZsdpCbNKcaZccmbXIbNIbDcbSDbSEbSEcbbbSGbMNbSHbSIcbccbdbEhbEhbEhbDccbebTRbTRbTRbTRbRHcbfcbgceMceLbQubQubRxbQubRHbQubZPbjfbgZcbkcblcbmcbnahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHaaHaaHdpXdpXaaHdpXdpXdpXaaRdpXdpXdpXaaHdpXahjahjbCvbELbELbELbELbELbELbELbELbJjcbpahjahlahlahjdsiaFFahlahlahldotdcdbWncbscbtcascbubXnbXncbvcbwcbvcbxbYycbybWoduCduBduDduEbHXcbAdpFcaEcdOcdzcbEduGcdPduFduHbPHcirbNrbNrbNrcbJbOGcbKcbLcgrbUnbOGbTsahjbOPbOPbOPbOPbOPahjcbMbXKbCDcchcbObZRbZQbZQceocepbNKduIcuYdpBbNKceabhpcdTcbWbDcbEhbEhbEhcbXbTKbMNbTLbMNbTMcbYbEhbEhbEhbDccbZbTRccabTRbTRccbcccccdcemcebbQubRxbRxccgbRHaDGbPdbWdbgZccjcckblAcclahjahlahlahlahlahlaaeahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHahlahlahjahjahlahjahjahlahlahjahjahjahldpXahlahlbCvbRKbELbCvbCvbCvbTZbCvbCvbCvbCvahlahlahldsiaDIauKdsidsiahjdotdcdbWnccpbZxbXnbXnbXnbZxcatccqccrbYyccscctbWobCvbCvbTzbTAbTBcbAcbAccxcaEdoZdoKdoMdoNdoQbMjbOGbVAccDccEccFbQWccGbVuccIbYLbUpccJbTnbPQbPRccKccLccLbOPahjbXHbXKbCDbCDbCDbXKbCDbCDccMbDbbCDbCDcuBbCDbCDbDbbSWbSXbThbDcbEhbEhbEhccRccSbSIccTbMNbUDccUbSEbSEbUFbDcbTRbTRccVbTRbTRbRHcbfcbgbTibTxbQuccYccZcdabRHbfGbPdbjfbgZbgZbgZblAbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHahlcdccddcdeahlcdccddcdeahlcdccddcdeahjdpXahlahlbCvcdfcdgbCvcdhbELbELbOlaClcdkbCvahlahlahlatIdsidsiahjahlahldbVdcdbWnbZxcdncdobXncdpbZxbZxbYvcdqbYybYycdrbWocdsbSVbSCbSUbSBdoidnZdcNdctdcNdctdcvdctdcubMjcdCcdDcdEbSfbSfbShbUicdFbUmbSibUncdGbTsahjbReclhcdIcdJbOPahjbCDbXKbXKcdKbXKbXKcdLbCDccMbSabRYbSqbZtbSwbRYbSAccMbLEcdVbDcbDcbDcbDcbDcbDccdWcdXcdYbDcbDcbDcbDcbDcbDcbRHbRHbRHbRHbRHbRHcdZcdZbSxbSybRHbRHbRHbRHbRHbgZcgFbjfbgZbNibOjblAbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHahlcdcceecdeahlcdcceecdeahlcdcceecdeahjahjahlahlbCvbPtbPvbCvbCvcefcegaClbELbSYbCvahlahlahlahlahjahlahlahlahlbppdcdbWnbXncehceibXncejcekbXnbYvcelbYxbYybYybVebVfbfIcercHqbVgceucevcewbVhceycezdpYcaEdqsbMjceBbOGbVAbUibONceCbWEceEceFbNFceGceHbMrbSobPRceIccLccLbOPahjbCDbXKbXKbXKbXKbXKbUzbCDbVdbUxbUNbJFcgAbJFbUJbUxbUybLEbTEbgZahlahlahlahjahlahlceVahlahjahlahlahlahlbgZceWayRceYceZceZbRHcfacfabSxbiZcfccfdblAblAblAaDGcgFbUwbgZcffblAblAbgZbgZbgZahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXahjcdcceecdeahlcdcceecdeahjcdcceecdeahjahjahlahlahlahlahjahjbCvbCvbCvbCvbTZbCvbCvahlahlahlahlahjahlahlahjahlbppdcdbWnbXncfgcfhcficfjcfkbXncflcfmcfncfocfpbWocfqdpVdpPdpQdpNdpOdpTdpUdpRdpSdpsdpzdpadprdpAdpEbQZcfFbVBbOGbOGbOGbOMbVvbVBbUnbXGbTsahjbOPbOPbOPbOPbOPahjbCDcabcfHcfIcfJcacbCDbCDbCDcfKbTGcdUbXIcfMbTFbCDbCDbLEbTEbgZahlahlahlahjahlahlceVahlahjahlahlahlahlbgZblAchmbrscOnciqbRHcfScfSbTDbiZbRHbQubgZcfUcfVaDGcgFbTCbECbECbECcfYcfZcgacfZcgbdsiahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlcdcceecdeahjcdcceecdeahlcdcceecdeahlahjahlahlahlahlahlahlbCvaOlbCvbELbELbCvahjahlahjahlahlahjahlahlahjahlbppdcdbWnbWnbWnbWnbWnbWnbWnbWnbWobWobWobWobWobWobCvbWpbCvcggcghcghcghcgicgjcgkcghbWrdqEdqRbMjchebXEbSkbXjcgscgtcgsbXjcgubXjcgvbUicgwahjahjahjahjahjahjahjahlahjcbMbXKcbMahjahlbCDcgxbCDcgzcgzdpdcgzcgzbCDbYQbzgbTEbgZcgCcgDcgEbgZcgCcgDcuncgEbgZcgCcgDcgDcgEbgZbgZcgFcgGbgZbgZbRHbRHbRHbWabWbbRHaDGbgZcbmblAbpYcgFbWdbgZbgZcgLbgZbgZbgZbgZahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHaaHdpXahjahlcdcceecdeahjcdcceecdeahlcdcceecdeahjahjahjahjcgMcgNcgNcgNcgNbCvbCvcgObELbCvcgPbWkbWkbWkbWkbWkbWkbWkbWlbCvbppdcdbCvcgQbVPbVObVObVObVObVObVObVObVObVObVXbVXbVObVQcefcggcnjcgWcgXcgYcgZchacghdoBcmIdqxbMjchebXichgchhchibWIchkchlbOGbXechnchobOIahjahjahlahlahlahlahjahlahjchpcfIchpahjahlbCDchqdpkbVichtdpDcdUcdUbXKbXKbzgbJEbVHbVHbVHbVHbVHbVHbVHbVIbVqbVqbVqbVqbVqbVqbVrbVqduQbVqbVqbVGciFbVlbVkbVjbVnbgZbgZbVmciFbVJciFbVLbjfbgZchLblAblAbgZahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHahlahjahlahjahjchMahjahjahjchMahjahlahjchMahjahlahjchNchOchPchQchRchSchTcgebELchYchZciachZchZchZchZchZchZchZchZchZchZdsrdsydrBdrAbiTcicciccicciccicciccicciccicciccicciccicciccggcghciecifdsbbZDbZEbZFckUckbdspciccincfGcipceDcipcfGcipceDcipccHcipccHcisahjahjahlahlahlahlahjahlahjahlahlahlahjahlbCDchqduRcdUduSbYWbYVceTbFobXabXbbWQbWQbWQbWQbWQbWQbWQbWRbWSbWQbWQbWQbWQbWQbWQbYIbYEbYhchEbYCbYibYcbYcbYcbYdbXAbXxbXObXBbYYbYcbYcbYXbZhbgZbOjblAcbabgZahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXahjciRciSciSciTciUciUciUciUciUciUciUciUciUciUciUciVciXciYciXciZdrvcjbcbHchZcjdcjeaClbCvcjgcjhcjhcjhcjhcjhcjhcjhcjibCvbCvdrqdrldrjdrgciccjncjncjociccjpcpFcpEcpCcpOcpNcjvcmvcjxcjycghcjzcjAdracjCcjDcjEcjHdrbdrdcicahjcbIahjcaMahjcbIahjcaMahjbZqahjbZqahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlbCDbXKcjLcjMduTcjObXJbFobSZbWqbCDbgZcgCcgDcgDcgEbgZcgCcgDcgDcgEbgZcgCcgDcgDcgEbgZcpGblAbgZbWKbWwbgZbgZcgCcgEbgZbgZcjTbPdbPbbgZcjUcjVbpWbgZbgZbgZbgZbgZahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHahlahjahlahjahjcjWahjahlahjcjWahjahlahjcjWahjahlahlchNchOcjXcjYcjZckacgNbELbELbELbELbCvahlahlahjahlahlahjahlahlahjahlbCvckdbCvcmacmhcicckfckgckhckickjbhAckUckUckUbOHbOKbORckrbhAcghbvCckuclScjCckwcghaJbclRclMcicbOPckzbReckzbOPckzbReckzbOPckAbReckBbOPahlahlahlahlahlahlahlahlahlahlahlahlahjahlbCDbCDbCDbXKckCcjMccPcnCbCDbCDbCDahlahlahjahlahjahjahlahlahlahlahlahlahlahlahlbgZcnyckEbgZbPbbPdbgZahlahlahlahlbgZblAbPdbPackGckGckHckIckGahlahjahjahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHaaHdpXahjahjcdcckJcdeahlcdcckJcdeahlcdcckJcdeahjahjahjahjckKcgNcgNcgNcgNbJibJjbELbELbCvahjahjcjtcjtcjtcjtcjtcjtcjtahjbCvbCvbCvcmBcmxcicckPckhckhckickQckxckxcmwcmjcmqcmicmiciickUcghckWcmQcmJckZclacghclbcmIcmDcicbOPcldcnDclfbOPclgcnXclibOPcljcnYcllbOPahlahlahlahlahlahlahlahlahlahlahlahlahjahlbRJahlbCDcfKcabcnZcacbCDbCDahlbRJahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlbgZcnUbgZbgZbPibPdbgZbgZcgCcgEbgZbgZblAbPjbPfckGclqclrclsckGahlahlahjahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlcdcckJcdeahjcdcckJcdeahlcdcckJcdeahlahlahlahlahlahlahlahlbCvbCvbCvbXlbELbCvahlahlcjtclFclzclEclzclucjtahlbCvbSYbELcnzcmxcicclAclAclBcicclCclDcmmcnpckbcmFbPAcksckockocghclKcnmcncclNclOclPclQcmScmRcicbOPclTclUclTbOPclVclWclVbOPclXclYclZbOPahlahlahlahlahlahlahlahlahlahlahlahlahlahlbRJahlahlahjdsiahlahlahjahlahlbRJahlahlahlahlahjahjahlahlahlahlahlahlcmccmdcmebgZbJkaDGbgZbPEbPFciCciFciCciCciCciCciGcfRbPDckGcnBcnAcmkckGahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaGcahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaHaaHdpXahjahjcdcckJcdeahlcdcckJcdeahlcdcckJcdeahjahjahjahjckKcgNcgNcgNcgNbJibJjbELbELbCvahjahjcjtcjtcjtcjtcjtcjtcjtahjbCvbCvbCvcmBcmxcicckPckhckhckickQckxckxcmwcmjcmqcmicmiciickUcghckWcmQcmJckZclacghclbcmIcmDcicbOPcldcnDclfbOPclgcnXclibOPcljcnYcllbOPahlahlahlahlahlahlahlahlahlahlahlahlahjahlbRJahlbCDcfKduUcnZcacbCDbCDahlbRJahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlbgZcnUbgZbgZbPibPdbgZbgZcgCcgEbgZbgZblAbPjbPfckGclqclrclsckGahlahlahjahjahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlcdcckJcdeahjcdcckJcdeahlcdcckJcdeahlahlahlahlahlahlahlahlbCvbCvbCvbXlbELbCvahlahlcjtclFclzclEclzclucjtahlbCvbSYbELcnzcmxcicclAclAclBcicclCclDcmmcnpckbcmFbPAcksckockocghclKcnmcncclNclOclPclQcmScmRcicbOPclTclUclTbOPclVclWclVbOPclXclYclZbOPahlahlahlahlahlahlahlahlahlahlahlahlahlahlbRJahlahlahjduVahlahlahjahlahlbRJahlahlahlahlahjahjahlahlahlahlahlahlcmccmdcmebgZbJkaDGbgZbPEbPFciCciFciCciCciCciCciGcfRbPDckGcnBcnAcmkckGahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaGcahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXahjcdcckJcdeahlcdcckJcdeahlcdcckJcdeahjahlahlahlahlahlahlahlcgccgdcgcbELbELbCvahlahlcjtcmscmocmncmrcmpcjtahlbCvcegbELcnzcmxcicclAclAclBciccmucmvcmtcnFcnHckVcmAcmvcmzcmAcmvdtocnOcnMcmFcmGcmHcmEckbcnIcicbOPclTcmKclTbOPclVcmLclVbOPclZcmMclZbOPahlahlahlahlahlahlaaeahlahlahlahlahlahlahlbRJahlahlahjcmNahlahlahlahlahlbRJahlahlahlahlahjahjahlahlahlahlahlahjcbnblAcmObgZcphblAbgZbPVbKLbKLbQabKLchEchEchEbPXbPYchKckGcnQcnPcmTckGahlahlahjahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahldpXahjcdcckJcdeahlcdcckJcdeahjcdcckJcdeahjahjahjahjahjahjahjahjbCvbCvbCvbCvbELbCvahjahjcjtcmPcoZcoUcoPcmPcjtahjbCvciccnbclecoccicclAclBclBciccndcnecmycodckbclHclGclJclGclGcnkcnlcnScnRcnocnncnncnncobcoacicbOPbOPbOPbOPbOPbOPbOPbOPbOPbOPbOPbOPbOPahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlahlahlahlahlahlahlahlahlbRJahlahlahlahlahjahjahlahlahlahlahjdsicbncnrblAbrqcpGblAbgZbgZbgZbgZbgZblAbgZahlahjahlahjahlcnscntcnucnvcnwahjahjahjahjahjahjahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlaaRahjcdccnxcdeahlcdccnxcdeahlcdccnxcdeahjdpXahjahlahlahlahlahlahlahlahlbLWbELcaqahlahlcjtcmZcnfcpkcnqcngcjtcjtcjtciccnEclecoeciccicciccicciccnGckUcofcnpckbckUckUckUbQybQwccOckbckbcnpckUcopckUckUcohcogcicahjahlahlahlahjahjahlahlahjahlahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahjahlaaeahlahlahlahlahlahlahlbRJahlahlahlahlahlahjahlahlahlahlahldsicbnblAaBRbgZbLkblAblAblAblAblAblAblAbgZahlahjahlahjahlahjcnVcnWcnVahjahlahlahjahlahlahjahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl @@ -9570,7 +9575,7 @@ ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlah ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlcyVcyScyJcyFcyUcyNcyNcyNcyNcyNcyNcyNcyUcyFcyJcyKcyWahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlcyVcyHcyXcyYcyZczaczbcyNczccyUcyNczdczecyHcyWahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlcyBczfczgczhczicyNcyUcyUcyNczdcyBahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl -ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlcyBczjczkczkczbcyNczdczlcyNczdcyTczmczmczmczmahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl +ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlcyBckLczkczkczbcyNczdczlcyNczdcyTczmczmczmczmahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlcyBcznczkczkczocyNczdczlcyNcyNcyFczmczmczmczmahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlcyDcyHcyHcyHcyXcyNcyUcyUcyNczdczpczmczmczmczmahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl ahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlcyBczqcyNczqcyBcyNczdczlcyNczdczrahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahlahl diff --git a/bot/NanoTrasenBot.py b/bot/NanoTrasenBot.py index e86009ef580..af97829d22d 100644 --- a/bot/NanoTrasenBot.py +++ b/bot/NanoTrasenBot.py @@ -902,41 +902,34 @@ while True: print truesender+":"+temdata arg = temdata check = temdata.lower() - if check[0:5] == "https": + + if cache_youtube_links == True: + result = YTCV2(arg) + else: + result = YTCV2(arg,0) + if type(result) == str: + ### To remove =" + if result[0:4] == 'nt="': + result = result[4:] + pass + elif result[0:2] == '="': + result = result[2:] + pass + else: + pass + if """ in result: + result.replace(""",'"') if len(temporal_list) == 1: - conn.privmsg(targetchannel,sender+" :Secure Youtube does NOT exist") + conn.privmsg(targetchannel,sender+" : "+result) break else: - temporal_list2.append("Secure Youtube does NOT exist") - break + temporal_list2.append(result) else: - if cache_youtube_links == True: - result = YTCV2(arg) + if len(temporal_list) == 1: + conn.privmsg(targetchannel,sender+" : The video does not exist") + break else: - result = YTCV2(arg,0) - if type(result) == str: - ### To remove =" - if result[0:4] == 'nt="': - result = result[4:] - pass - elif result[0:2] == '="': - result = result[2:] - pass - else: - pass - if """ in result: - result.replace(""",'"') - if len(temporal_list) == 1: - conn.privmsg(targetchannel,sender+" : "+result) - break - else: - temporal_list2.append(result) - else: - if len(temporal_list) == 1: - conn.privmsg(targetchannel,sender+" : The video does not exist") - break - else: - temporal_list2.append("The video does not exist") + temporal_list2.append("The video does not exist") if len(temporal_list) == 1: pass else: diff --git a/code/ATMOSPHERICS/components/unary/unary_base.dm b/code/ATMOSPHERICS/components/unary/unary_base.dm index 962ed99f871..b19b3a82531 100644 --- a/code/ATMOSPHERICS/components/unary/unary_base.dm +++ b/code/ATMOSPHERICS/components/unary/unary_base.dm @@ -36,12 +36,14 @@ Iconnery if(showpipe) var/state + var/col if(node) state = "pipe_intact" + col = node.pipe_color else state = "pipe_exposed" - underlays += getpipeimage('icons/obj/atmospherics/binary_devices.dmi', state, initialize_directions, node.pipe_color) + underlays += getpipeimage('icons/obj/atmospherics/binary_devices.dmi', state, initialize_directions, col) /obj/machinery/atmospherics/unary/hide(var/intact) showpipe = !intact diff --git a/code/ATMOSPHERICS/pipes/tank.dm b/code/ATMOSPHERICS/pipes/tank.dm index 658bc60381f..0c5dfe53a23 100644 --- a/code/ATMOSPHERICS/pipes/tank.dm +++ b/code/ATMOSPHERICS/pipes/tank.dm @@ -15,41 +15,57 @@ Atmospheric Tanks initialize_directions = SOUTH density = 1 can_unwrench = 0 - var/obj/machinery/atmospherics/node1 + var/obj/machinery/atmospherics/node + var/showpipe = 0 /obj/machinery/atmospherics/pipe/tank/New() initialize_directions = dir ..() +/obj/machinery/atmospherics/pipe/tank/hide(var/intact) + showpipe = !intact + update_icon() + + ..(intact) /obj/machinery/atmospherics/pipe/tank/Destroy() - if(node1) - node1.disconnect(src) + if(node) + node.disconnect(src) ..() /obj/machinery/atmospherics/pipe/tank/pipeline_expansion() - return list(node1) + return list(node) /obj/machinery/atmospherics/pipe/tank/update_icon() - if(node1) - icon_state = "intact" - dir = get_dir(src, node1) - else - icon_state = "exposed" + underlays.Cut() + if(showpipe) + var/state + var/col + if(node) + state = "pipe_intact" + col = node.pipe_color + else + state = "pipe_exposed" + + underlays += getpipeimage('icons/obj/atmospherics/pipe_tank.dmi', state, initialize_directions, col) /obj/machinery/atmospherics/pipe/tank/initialize() var/connect_direction = dir for(var/obj/machinery/atmospherics/target in get_step(src,connect_direction)) if(target.initialize_directions & get_dir(target,src)) - node1 = target + node = target break + + if(level == 2) + showpipe = 1 + update_icon() /obj/machinery/atmospherics/pipe/tank/disconnect(obj/machinery/atmospherics/reference) - if(reference == node1) - if(istype(node1, /obj/machinery/atmospherics/pipe)) + if(reference == node) + if(istype(node, /obj/machinery/atmospherics/pipe)) del(parent) - node1 = null + node = null update_icon() diff --git a/code/LINDA/LINDA_system.dm b/code/LINDA/LINDA_system.dm index 63bc81b63f4..2a5b98202f9 100644 --- a/code/LINDA/LINDA_system.dm +++ b/code/LINDA/LINDA_system.dm @@ -168,10 +168,10 @@ datum/controller/air_system atom/movable/proc/CanAtmosPass() return 1 -atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0) - return (!density || !height || air_group) +atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5) + return (!density || !height) -turf/CanPass(atom/movable/mover, turf/target, height=1.5,air_group=0) +turf/CanPass(atom/movable/mover, turf/target, height=1.5) if(!target) return 0 if(istype(mover)) // turf/Enter(...) will perform more advanced checks @@ -182,10 +182,10 @@ turf/CanPass(atom/movable/mover, turf/target, height=1.5,air_group=0) return 0 for(var/obj/obstacle in src) - if(!obstacle.CanPass(mover, target, height, air_group)) + if(!obstacle.CanPass(mover, target, height)) return 0 for(var/obj/obstacle in target) - if(!obstacle.CanPass(mover, src, height, air_group)) + if(!obstacle.CanPass(mover, src, height)) return 0 return 1 diff --git a/code/WorkInProgress/Sigyn/Softcurity/jobs.dm b/code/WorkInProgress/Sigyn/Softcurity/jobs.dm index 31012173420..7ef0b8ccddb 100644 --- a/code/WorkInProgress/Sigyn/Softcurity/jobs.dm +++ b/code/WorkInProgress/Sigyn/Softcurity/jobs.dm @@ -49,7 +49,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/boots(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/warden(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(H), slot_glasses) - H.equip_to_slot_or_del(new /obj/item/device/flash(H), slot_l_store) + H.equip_to_slot_or_del(new /obj/item/device/flash/handheld(H), slot_l_store) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) H.equip_to_slot_or_del(new /obj/item/weapon/handcuffs(H), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) @@ -115,7 +115,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/boots(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/security(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/weapon/handcuffs(H), slot_r_store) - H.equip_to_slot_or_del(new /obj/item/device/flash(H), slot_l_store) + H.equip_to_slot_or_del(new /obj/item/device/flash/handheld(H), slot_l_store) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) H.equip_to_slot_or_del(new /obj/item/weapon/handcuffs(H), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) diff --git a/code/WorkInProgress/Sigyn/Softcurity/secure_closet.dm b/code/WorkInProgress/Sigyn/Softcurity/secure_closet.dm index 3631930e596..49ae813fab0 100644 --- a/code/WorkInProgress/Sigyn/Softcurity/secure_closet.dm +++ b/code/WorkInProgress/Sigyn/Softcurity/secure_closet.dm @@ -49,7 +49,7 @@ new /obj/item/clothing/shoes/brown(src) new /obj/item/weapon/storage/id_kit(src) new /obj/item/weapon/storage/id_kit( src ) - new /obj/item/device/flash(src) + new /obj/item/device/flash/handheld(src) new /obj/item/clothing/glasses/sunglasses(src) return @@ -73,7 +73,7 @@ new /obj/item/weapon/storage/lockbox/loyalty(src) new /obj/item/weapon/storage/flashbang_kit(src) new /obj/item/weapon/storage/belt/security(src) - new /obj/item/device/flash(src) + new /obj/item/device/flash/handheld(src) new /obj/item/weapon/melee/baton(src) new /obj/item/weapon/gun/energy/taser(src) new /obj/item/weapon/reagent_containers/spray/pepper(src) @@ -122,7 +122,7 @@ new /obj/item/weapon/storage/backpack/satchel_sec(src) new /obj/item/device/radio/headset/headset_sec(src) new /obj/item/weapon/storage/belt/security(src) - new /obj/item/device/flash(src) + new /obj/item/device/flash/handheld(src) new /obj/item/weapon/reagent_containers/spray/pepper(src) new /obj/item/weapon/reagent_containers/spray/pepper(src) new /obj/item/clothing/glasses/sunglasses(src) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 0d328b256bf..512768419be 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -34,8 +34,9 @@ #define CLICK_CD_MELEE 8 #define CLICK_CD_RANGE 4 -#define CLICK_CD_HANDCUFFED 10 #define CLICK_CD_BREAKOUT 100 +#define CLICK_CD_HANDCUFFED 10 +#define CLICK_CD_TKSTRANGLE 10 #define CLICK_CD_RESIST 20 //click cooldowns, in tenths of a second diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 6724122a501..60eae92ba1d 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -25,6 +25,19 @@ * Text sanitization */ +//this proc strips html properly, but it's not lazy like the other procs. +//this means that it doesn't just remove < and > and call it a day. seriously, who the fuck thought that would be useful. +/proc/strip_html_properly(var/input) + var/opentag = 1 //These store the position of < and > respectively. + var/closetag = 1 + while(1) + opentag = findtext(input, "<") + closetag = findtext(input, ">") + if(!closetag || !opentag) + break + input = copytext(input, 1, opentag) + copytext(input, (closetag + 1)) + return input + //Simply removes < and > and limits the length of the message /proc/strip_html_simple(var/t,var/limit=MAX_MESSAGE_LEN) var/list/strip_chars = list("<",">") @@ -363,16 +376,3 @@ var/list/binary = list("0","1") temp = findtextEx(haystack, ascii2text(text2ascii(needles,i)), start, end) //Note: ascii2text(text2ascii) is faster than copytext() if(temp) end = temp return end - -//this proc strips html properly, but it's not lazy like the other procs. -//this means that it doesn't just remove < and > and call it a day. seriously, who the fuck thought that would be useful. -/proc/strip_html_properly(var/input) - var/opentag = 1 //These store the position of < and > respectively. - var/closetag = 1 - while(1) - opentag = findtext(input, "<") - closetag = findtext(input, ">") - if(!closetag || !opentag) - break - input = copytext(input, 1, opentag) + copytext(input, (closetag + 1)) - return input diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 4a2f23792b3..a6ecae8b300 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -763,17 +763,23 @@ Turf and target are seperate in case you want to teleport some distance from a t else return get_step(ref, base_dir) -/proc/do_mob(var/mob/user , var/mob/target, var/time = 30) //This is quite an ugly solution but i refuse to use the old request system. - if(!user || !target) return 0 +/proc/do_mob(var/mob/user , var/mob/target, var/time = 30, numticks = 5) //This is quite an ugly solution but i refuse to use the old request system. + if(!user || !target) + return 0 + if(numticks == 0) + return 0 var/user_loc = user.loc var/target_loc = target.loc var/holding = user.get_active_hand() - sleep(time) - if(!user || !target) return 0 - if ( user.loc == user_loc && target.loc == target_loc && user.get_active_hand() == holding && !( user.stat ) && ( !user.stunned && !user.weakened && !user.paralysis && !user.lying ) ) - return 1 - else - return 0 + var/timefraction = round(time/numticks) + for(var/i = 0, i[src] has been hit by [user] with [W].") /mob/living/attackby(obj/item/I, mob/user) + user.changeNext_move(CLICK_CD_MELEE) I.attack(src, user) /mob/living/proc/attacked_by(var/obj/item/I, var/mob/living/user, var/def_zone) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index ead5f6100d7..34df3fa6245 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -81,7 +81,8 @@ var/security_scaling_coeff = 8 //how much does the amount of players get divided by to determine open security officer positions var/traitor_objectives_amount = 2 - var/protect_roles_from_antagonist = 0// If security and such can be traitor/cult/other + var/protect_roles_from_antagonist = 0 //If security and such can be traitor/cult/other + var/protect_assistant_from_antagonist = 0 //If assistants can be traitor/cult/other var/enforce_human_authority = 0 //If non-human species are barred from joining as a head of staff var/allow_latejoin_antagonists = 0 // If late-joining players can be traitor/changeling var/continuous_round_rev = 0 // Gamemodes which end instantly will instead keep on going until the round ends by escape shuttle or nuke. @@ -375,6 +376,8 @@ if("protect_roles_from_antagonist") config.protect_roles_from_antagonist = 1 + if("protect_assistant_from_antagonist") + config.protect_assistant_from_antagonist = 1 if("enforce_human_authority") config.enforce_human_authority = 1 if("allow_latejoin_antagonists") diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm index 8a59e405b29..fbe97494514 100644 --- a/code/controllers/shuttle_controller.dm +++ b/code/controllers/shuttle_controller.dm @@ -242,6 +242,6 @@ var/global/datum/shuttle_controller/emergency_shuttle/emergency_shuttle var/turf/T = get_step(L, dir) if(T) for(var/obj/O in T) // For doors and such (kinda ugly but we can't have people opening doors) - if(!O.CanPass(L, L.loc, 1, 0)) + if(!O.CanPass(L, L.loc, 1)) return L.Move(get_step(L, dir), dir) \ No newline at end of file diff --git a/code/controllers/supply_shuttle.dm b/code/controllers/supply_shuttle.dm index b9265cecc5e..defa56ba515 100644 --- a/code/controllers/supply_shuttle.dm +++ b/code/controllers/supply_shuttle.dm @@ -420,8 +420,8 @@ var/global/datum/controller/supply_shuttle/supply_shuttle if(temp) dat = temp else - dat += {"Shuttle Location: [supply_shuttle.moving ? "Moving to station ([supply_shuttle.eta] Mins.)":supply_shuttle.at_station ? "Station":"Dock"]
-
Supply Points: [supply_shuttle.points]
+ dat += {"
Shuttle Location: [supply_shuttle.moving ? "Moving to station ([supply_shuttle.eta] Mins.)":supply_shuttle.at_station ? "Station":"Dock"]
+
Supply Points: [supply_shuttle.points]

\nRequest items

View approved orders

@@ -451,22 +451,21 @@ var/global/datum/controller/supply_shuttle/supply_shuttle //all_supply_groups //Request what? last_viewed_group = "categories" - temp = "Supply points: [supply_shuttle.points]
" - temp += "Main Menu


" + temp = "
Supply points: [supply_shuttle.points]
" + temp += "Main Menu

" temp += "Select a category

" for(var/cat in all_supply_groups ) temp += "[get_supply_group_name(cat)]
" else last_viewed_group = href_list["order"] var/cat = text2num(last_viewed_group) - temp = "Supply points: [supply_shuttle.points]
" - temp += "Back to all categories


" + temp = "
Supply points: [supply_shuttle.points]
" + temp += "Back to all categories

" temp += "Request from: [get_supply_group_name(cat)]

" for(var/supply_name in supply_shuttle.supply_packs ) var/datum/supply_packs/N = supply_shuttle.supply_packs[supply_name] if(N.hidden || N.contraband || N.group != cat) continue //Have to send the type instead of a reference to temp += "[supply_name] Cost: [N.cost]
" //the obj because it would get caught by the garbage - else if (href_list["doorder"]) if(world.time < reqtime) say("[world.time - reqtime] seconds remaining until another requisition form may be printed.") @@ -556,19 +555,20 @@ var/global/datum/controller/supply_shuttle/supply_shuttle if (temp) dat = temp else - dat += {"
Supply shuttle
+ dat += {"
Supply shuttle
\nLocation: [supply_shuttle.moving ? "Moving to station ([supply_shuttle.eta] Mins.)":supply_shuttle.at_station ? "Station":"Away"]
-
\nSupply Points: [supply_shuttle.points]
\n
+
\nSupply Points: [supply_shuttle.points]
\n

[supply_shuttle.moving ? "\n*Must be away to order items*
\n
":supply_shuttle.at_station ? "\n*Must be away to order items*
\n
":"\nOrder items
\n
"] [supply_shuttle.moving ? "\n*Shuttle already called*
\n
":supply_shuttle.at_station ? "\nSend away
\n
":"\nSend to station
\n
"] [supply_shuttle.shuttle_loan ? (supply_shuttle.shuttle_loan.dispatched ? "\n*Shuttle loaned to Centcom*
\n
" : "\nLoan shuttle to Centcom (5 mins duration)
\n
") : "\n*No pending external shuttle requests*
\n
"] \nView requests
\n
\nView orders
\n
\nClose
-
\nCentral Command messages
[supply_shuttle.centcom_message ? supply_shuttle.centcom_message : "Remember to stamp and send back the supply manifests."]"} +
\nCentral Command messages:
[supply_shuttle.centcom_message ? supply_shuttle.centcom_message : "Remember to stamp and send back the supply manifests."]"} - user << browse(dat, "window=computer;size=700x450") - onclose(user, "computer") + var/datum/browser/popup = new(user, "computer", "Supply Shuttle Console", 700, 455) + popup.set_content(dat) + popup.open() return /obj/machinery/computer/supplycomp/attackby(I as obj, user as mob) @@ -635,16 +635,16 @@ var/global/datum/controller/supply_shuttle/supply_shuttle //all_supply_groups //Request what? last_viewed_group = "categories" - temp = "Supply points: [supply_shuttle.points]
" - temp += "Main Menu


" + temp = "
Supply points: [supply_shuttle.points]
" + temp += "Main Menu

" temp += "Select a category

" for(var/cat in all_supply_groups ) temp += "[get_supply_group_name(cat)]
" else last_viewed_group = href_list["order"] var/cat = text2num(last_viewed_group) - temp = "Supply points: [supply_shuttle.points]
" - temp += "Back to all categories


" + temp = "
Supply points: [supply_shuttle.points]
" + temp += "Back to all categories

" temp += "Request from: [get_supply_group_name(cat)]

" for(var/supply_name in supply_shuttle.supply_packs ) var/datum/supply_packs/N = supply_shuttle.supply_packs[supply_name] diff --git a/code/datums/diseases/advance/symptoms/vomit.dm b/code/datums/diseases/advance/symptoms/vomit.dm index 67f53564deb..55fd92863e0 100644 --- a/code/datums/diseases/advance/symptoms/vomit.dm +++ b/code/datums/diseases/advance/symptoms/vomit.dm @@ -43,7 +43,8 @@ Bonus /datum/symptom/vomit/proc/Vomit(var/mob/living/M) - M.visible_message("[M] vomits on the floor!") + M.visible_message("[M] vomits on the floor!", \ + "You throw up on the floor!") M.nutrition -= 20 M.adjustToxLoss(-3) @@ -84,7 +85,8 @@ Bonus /datum/symptom/vomit/blood/Vomit(var/mob/living/M) M.Stun(1) - M.visible_message("[M] vomits on the floor!") + M.visible_message("[M] vomits on the floor!", \ + "You throw up on the floor!") // They lose blood and health. var/brute_dam = M.getBruteLoss() diff --git a/code/datums/diseases/appendicitis.dm b/code/datums/diseases/appendicitis.dm index 8a628eefd62..f3a2432ebe5 100644 --- a/code/datums/diseases/appendicitis.dm +++ b/code/datums/diseases/appendicitis.dm @@ -44,7 +44,7 @@ affected_mob.nutrition -= 95 affected_mob.adjustToxLoss(-1) else - affected_mob << "You gag as you want to throw up, but there's nothing in your stomach!" + affected_mob << "You gag as you want to throw up, but there's nothing in your stomach!" affected_mob.Weaken(10) affected_mob.adjustToxLoss(3) diff --git a/code/datums/diseases/dna_spread.dm b/code/datums/diseases/dna_spread.dm index 764119b587c..df96b3ca231 100644 --- a/code/datums/diseases/dna_spread.dm +++ b/code/datums/diseases/dna_spread.dm @@ -3,8 +3,8 @@ max_stages = 4 spread = "On contact" spread_type = CONTACT_GENERAL - cure = "Ryetalin" - cure = "ryetalyn" + cure = "Ryetalyn" + cure_id = "ryetalyn" curable = 0 agent = "S4E1 retrovirus" affected_species = list("Human") diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index a4897448f17..91826c2d749 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -35,6 +35,8 @@ client/verb/showrevinfo() src << "Revision unknown" src << "Current Infomational Settings:" src << "Protect Authority Roles From Traitor: [config.protect_roles_from_antagonist]" + src << "Protect Assistant Role From Traitor: [config.protect_assistant_from_antagonist]" src << "Enforce Human Authority: [config.enforce_human_authority]" src << "Allow Latejoin Antagonists: [config.allow_latejoin_antagonists]" - return \ No newline at end of file + src << "Protect Assistant From Antagonist: [config.protect_assistant_from_antagonist]" + return diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index e4d700689fa..d3088c624a6 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -1105,8 +1105,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/misc/randomised/contraband num_contained = 5 contains = list(/obj/item/weapon/contraband/poster, - /obj/item/weapon/storage/fancy/cigarettes/dromedaryco, - /obj/item/weapon/lipstick/random) + /obj/item/weapon/storage/fancy/cigarettes/dromedaryco) name = "Contraband crate" cost = 30 containername = "crate" //let's keep it subtle, eh? @@ -1146,6 +1145,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/clothing/under/suit_jacket/navy, /obj/item/clothing/under/suit_jacket/burgundy, /obj/item/clothing/under/suit_jacket/checkered, - /obj/item/clothing/under/suit_jacket/tan) + /obj/item/clothing/under/suit_jacket/tan, + /obj/item/weapon/lipstick/random) cost = 30 //Lots of very expensive items. You gotta pay up to look good! containername = "formal-wear crate" diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 9deaf9d74fb..329e9db7804 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -381,19 +381,24 @@ // find the turf to move things to var/turf/D = locate(T.x, throwy - 1, T.z) for(var/atom/movable/AM as mob|obj in T) - //mobs take damage - if(istype(AM, /mob/living)) - var/mob/living/living_mob = AM - living_mob.Paralyse(10) - living_mob.take_organ_damage(80) - living_mob.anchored = 0 //Unbuckle them so they can be moved + if(ismob(AM)) + if(istype(AM, /mob/living))//mobs take damage + var/mob/living/living_mob = AM + living_mob.Paralyse(10) + living_mob.take_organ_damage(80) + living_mob.anchored = 0 //Unbuckle them so they can be moved + else + continue + //Anything not bolted down is moved, everything else is destroyed if(!AM.anchored) - AM.Move(D) + AM.Move(D, SOUTH) else qdel(AM) if(istype(T, /turf/simulated)) del(T) - for(var/atom/movable/bug in src) // If someone (or something) is somehow still in the shuttle's docking area... - qdel(bug) + /*for(var/atom/movable/bug in src) // If someone (or something) is somehow still in the shuttle's docking area... + if(ismob(bug)) + continue + qdel(bug)*/ diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 4502ff7675f..3688fa4ca3d 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -203,7 +203,7 @@ its easier to just keep the beam vertical. /atom/proc/examine(mob/user) //This reformat names to get a/an properly working on item descriptions when they are bloody var/f_name = "\a [src]." - if(src.blood_DNA) + if(src.blood_DNA && !istype(src, /obj/effect/decal)) if(gender == PLURAL) f_name = "some " else @@ -380,3 +380,5 @@ var/list/blood_splatter_icons = list() /atom/proc/handle_slip() return +/atom/proc/singularity_act() + return diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 0d5a26dba65..af888fa3c1f 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -4,23 +4,58 @@ var/anchored = 0 var/move_speed = 10 var/l_move_time = 1 - var/m_flag = 1 var/throwing = 0 var/throw_speed = 2 var/throw_range = 7 var/mob/pulledby = null var/languages = 0 //For say() and Hear() + var/inertia_dir = 0 glide_size = 8 -/atom/movable/Move() - var/atom/A = src.loc - . = ..() +/atom/movable/Move(atom/newloc, direct = 0) + if(!loc || !newloc) return 0 + last_move = direct + var/atom/oldloc = loc + + if(loc != newloc) + if (!(direct & (direct - 1))) //Cardinal move + . = ..() + else //Diagonal move, split it into cardinal moves + if (direct & 1) + if (direct & 4) + if (step(src, NORTH)) + . = step(src, EAST) + else if (step(src, EAST)) + . = step(src, NORTH) + else if (direct & 8) + if (step(src, NORTH)) + . = step(src, WEST) + else if (step(src, WEST)) + . = step(src, NORTH) + else if (direct & 2) + if (direct & 4) + if (step(src, SOUTH)) + . = step(src, EAST) + else if (step(src, EAST)) + . = step(src, SOUTH) + else if (direct & 8) + if (step(src, SOUTH)) + . = step(src, WEST) + else if (step(src, WEST)) + . = step(src, SOUTH) + + + if(!loc || (loc == oldloc && oldloc != newloc)) + last_move = 0 + return + src.move_speed = world.timeofday - src.l_move_time src.l_move_time = world.timeofday - src.m_flag = 1 - if ((A != src.loc && A && A.z == src.z)) - src.last_move = get_dir(A, src.loc) - return + + spawn(5) // Causes space drifting. /tg/station has no concept of speed, we just use 5 + if(loc && direct && last_move == direct) + if(loc == newloc) //Remove this check and people can accelerate. Not opening that can of worms just yet. + newtonian_move(last_move) /atom/movable/Del() if(isnull(gc_destroyed) && loc) @@ -69,6 +104,39 @@ return 1 return 0 +//Called whenever an object moves and by mobs when they attempt to move themselves through space +//And when an object or action applies a force on src, see newtonian_move() below +//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting +//Mobs should return 1 if they should be able to move of their own volition, see client/Move() in mob_movement.dm +//movement_dir == 0 when stopping or any dir when trying to move +/atom/movable/proc/Process_Spacemove(var/movement_dir = 0) + if(has_gravity(src)) + return 1 + + if(pulledby) + return 1 + + if(locate(/obj/structure/lattice) in orange(1, get_turf(src))) //Not realistic but makes pushing things in space easier + return 1 + + return 0 + +/atom/movable/proc/newtonian_move(direction) //Only moves the object if it's under no gravity + + if(!loc || Process_Spacemove(0)) + inertia_dir = 0 + return 0 + + inertia_dir = direction + if(!direction) + return 1 + + + var/old_dir = dir + . = step(src, direction) + dir = old_dir + + /atom/movable/proc/hit_check() // todo: this is partly obsolete due to passflags already, add throwing stuff to mob CanPass and finish it if(src.throwing) for(var/atom/A in get_turf(src)) @@ -116,7 +184,7 @@ var/atom/step = get_step(src, (error < 0) ? tdy : tdx) if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge break - src.Move(step) + src.Move(step, get_dir(loc, step)) hit_check() error += (error < 0) ? tdist_x : -tdist_y; dist_travelled++ diff --git a/code/game/communications.dm b/code/game/communications.dm index ac4576042c2..3b5faf29f8b 100644 --- a/code/game/communications.dm +++ b/code/game/communications.dm @@ -176,6 +176,9 @@ var/const/RADIO_AIRLOCK = "6" var/const/RADIO_SECBOT = "7" var/const/RADIO_MULEBOT = "8" var/const/RADIO_MAGNETS = "9" +var/const/RADIO_CLEANBOT = "10" +var/const/RADIO_FLOORBOT = "11" +var/const/RADIO_MEDBOT = "12" var/global/datum/controller/radio/radio_controller diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index c7663326236..1cbf0f81d72 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -38,7 +38,7 @@ /mob/living/simple_animal/hostile/blobspore/blob_act() return -/mob/living/simple_animal/hostile/blobspore/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/mob/living/simple_animal/hostile/blobspore/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover, /obj/effect/blob)) return 1 return ..() @@ -131,6 +131,7 @@ maxbodytemp = 360 force_threshold = 10 environment_smash = 3 + mob_size = 2 /mob/living/simple_animal/hostile/blobbernaut/AttackingTarget() diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm index e954cba6a4d..1c145f4404f 100644 --- a/code/game/gamemodes/blob/blobs/shield.dm +++ b/code/game/gamemodes/blob/blobs/shield.dm @@ -16,6 +16,6 @@ /obj/effect/blob/shield/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) return -/obj/effect/blob/shield/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/obj/effect/blob/shield/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover) && mover.checkpass(PASSBLOB)) return 1 return 0 diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index d4f0d21229e..c1325118245 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -30,8 +30,8 @@ ..() -/obj/effect/blob/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 +/obj/effect/blob/CanPass(atom/movable/mover, turf/target, height=0) + if(height==0) return 1 if(istype(mover) && mover.checkpass(PASSBLOB)) return 1 return 0 diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index e3a47377733..d0a5ec0ba2c 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -43,6 +43,9 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" if(config.protect_roles_from_antagonist) restricted_jobs += protected_jobs + if(config.protect_assistant_from_antagonist) + restricted_jobs += "Assistant" + var/num_changelings = 1 if(config.changeling_scaling_coeff) diff --git a/code/game/gamemodes/changeling/powers/humanform.dm b/code/game/gamemodes/changeling/powers/humanform.dm index 06c59138291..951cdf80f54 100644 --- a/code/game/gamemodes/changeling/powers/humanform.dm +++ b/code/game/gamemodes/changeling/powers/humanform.dm @@ -20,7 +20,8 @@ var/datum/dna/chosen_dna = changeling.get_dna(chosen_name) if(!chosen_dna) return - + if(!user || user.notransform) + return 0 user << "We transform our appearance." user.dna = chosen_dna diff --git a/code/game/gamemodes/changeling/powers/lesserform.dm b/code/game/gamemodes/changeling/powers/lesserform.dm index 10f61e1b6e0..b9220f4044b 100644 --- a/code/game/gamemodes/changeling/powers/lesserform.dm +++ b/code/game/gamemodes/changeling/powers/lesserform.dm @@ -8,6 +8,8 @@ //Transform into a monkey. /obj/effect/proc_holder/changeling/lesserform/sting_action(var/mob/living/carbon/human/user) + if(!user || user.notransform) + return 0 user << "Our genes cry out!" user.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPDAMAGE | TR_KEEPSE | TR_KEEPSRC) diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm index e1f84aeecde..6f13e670890 100644 --- a/code/game/gamemodes/changeling/traitor_chan.dm +++ b/code/game/gamemodes/changeling/traitor_chan.dm @@ -26,6 +26,9 @@ if(config.protect_roles_from_antagonist) restricted_jobs += protected_jobs + if(config.protect_assistant_from_antagonist) + restricted_jobs += "Assistant" + var/list/datum/mind/possible_changelings = get_players_for_role(BE_CHANGELING) var/num_changelings = 1 diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index c99942aee3e..eb67ca4895d 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -62,6 +62,9 @@ if(config.protect_roles_from_antagonist) restricted_jobs += protected_jobs + if(config.protect_assistant_from_antagonist) + restricted_jobs += "Assistant" + for(var/datum/mind/player in antag_candidates) for(var/job in restricted_jobs)//Removing heads and such from the list if(player.assigned_role == job) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index fb07c3c966c..c4eede9feff 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -57,7 +57,7 @@ var/list/sacrificed = list() if (istype(user, /mob/living)) user.take_overall_damage(5, 0) qdel(src) - for(var/mob/living/carbon/C in orange(1,src)) + for(var/mob/living/C in orange(1,src)) if(iscultist(C) && !C.stat) culcount++ if(user.loc==src.loc) @@ -98,13 +98,13 @@ var/list/sacrificed = list() /////////////////////////////////////////THIRD RUNE /obj/effect/rune/proc/convert() - var/list/mob/living/carbon/human/cultsinrange = list() + var/list/mob/living/cultsinrange = list() for(var/mob/living/carbon/M in src.loc) if(iscultist(M)) continue if(M.stat==2) continue - for(var/mob/living/carbon/C in orange(1,src)) + for(var/mob/living/C in orange(1,src)) if(iscultist(C) && !C.stat) //converting requires three cultists cultsinrange += C C.say("Mah[pick("'","`")]weyh pleggh at e'ntrath!") @@ -792,12 +792,12 @@ var/list/sacrificed = list() /obj/effect/rune/proc/freedom() var/mob/living/user = usr - var/list/mob/living/carbon/cultists = new + var/list/mob/living/cultists = new for(var/datum/mind/H in ticker.mode.cult) if (istype(H.current,/mob/living/carbon)) cultists+=H.current - var/list/mob/living/carbon/users = new - for(var/mob/living/carbon/C in orange(1,src)) + var/list/mob/living/users = new + for(var/mob/living/C in orange(1,src)) if(iscultist(C) && !C.stat) users+=C if(users.len>=1) @@ -832,7 +832,7 @@ var/list/sacrificed = list() cultist.loc:locked = 0 if(istype(cultist.loc, /obj/machinery/dna_scannernew)&&cultist.loc:locked) cultist.loc:locked = 0 - for(var/mob/living/carbon/C in users) + for(var/mob/living/C in users) user.take_overall_damage(15, 0) C.say("Khari[pick("'","`")]d! Gual'te nikka!") qdel(src) @@ -846,8 +846,8 @@ var/list/sacrificed = list() for(var/datum/mind/H in ticker.mode.cult) if (istype(H.current,/mob/living/carbon)) cultists+=H.current - var/list/mob/living/carbon/users = new - for(var/mob/living/carbon/C in orange(1,src)) + var/list/mob/living/users = new + for(var/mob/living/C in orange(1,src)) if(iscultist(C) && !C.stat) users+=C if(users.len>=3) @@ -862,7 +862,7 @@ var/list/sacrificed = list() cultist.loc = src.loc cultist.Weaken(5) cultist.regenerate_icons() - for(var/mob/living/carbon/human/C in orange(1,src)) + for(var/mob/living/C in orange(1,src)) if(iscultist(C) && !C.stat) C.say("N'ath reth sh'yro eth d[pick("'","`")]rekkathnor!") C.take_overall_damage(25, 0) diff --git a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm index 0ff21b4c6b8..9a4374959f7 100644 --- a/code/game/gamemodes/gang/gang.dm +++ b/code/game/gamemodes/gang/gang.dm @@ -33,6 +33,9 @@ if(config.protect_roles_from_antagonist) restricted_jobs += protected_jobs + if(config.protect_assistant_from_antagonist) + restricted_jobs += "Assistant" + for(var/datum/mind/player in antag_candidates) for(var/job in restricted_jobs)//Removing heads and such from the list if(player.assigned_role == job) diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index b9ed5c88c54..3ca592195fc 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -8,6 +8,8 @@ /var/list/meteorsC = list(/obj/effect/meteor/dust) //for space dust event +/var/list/meteorsSPOOKY = list(/obj/effect/meteor/pumpkin) + /proc/spawn_meteors(var/number = 10, var/list/meteortypes) for(var/i = 0; i < number; i++) spawn_meteor(meteortypes) @@ -132,6 +134,25 @@ heavy = 1 meteordrop = /obj/item/weapon/ore/uranium +/obj/effect/meteor/pumpkin + name = "PUMPKING" + desc = "THE PUMPKING'S COMING!" + icon = 'icons/obj/meteor_spooky.dmi' + icon_state = "pumpkin" + hits = 10 + heavy = 1 + meteordrop = /obj/item/clothing/head/hardhat/pumpkinhead + meteorsound = 'sound/hallucinations/im_here1.ogg' + dropamt = 1 + bound_width = 96 + bound_height = 96 + +/obj/effect/meteor/pumpkin/New() + ..() + if(prob(50)) + meteordrop = /obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin + meteorsound = 'sound/hallucinations/im_here2.ogg' + /obj/effect/meteor/meaty name = "meaty ore" icon_state = "meateor" diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 8a78f9b33ae..6b7cefc3cc8 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -16,6 +16,7 @@ var/bomb_set var/obj/item/weapon/disk/nuclear/auth = null use_power = 0 var/previous_level = "" + var/lastentered = "" /obj/machinery/nuclearbomb/process() if (src.timing) @@ -98,9 +99,15 @@ var/bomb_set src.yes_code = 0 src.code = null else - src.code += text("[]", href_list["type"]) - if (length(src.code) > 5) - src.code = "ERROR" + lastentered = text("[]", href_list["type"]) + if (text2num(lastentered) == null) + var/turf/LOC = get_turf(usr) + message_admins("[key_name_admin(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered] ! ([LOC ? "JMP" : "null"])", 0) + log_admin("EXPLOIT : [key_name(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered] !") + else + src.code += lastentered + if (length(src.code) > 5) + src.code = "ERROR" if (src.yes_code) if (href_list["time"]) var/time = text2num(href_list["time"]) @@ -232,9 +239,10 @@ var/bomb_set if(blobstart.len > 0) var/obj/item/weapon/disk/nuclear/NEWDISK = new(pick(blobstart)) transfer_fingerprints_to(NEWDISK) - message_admins("[src] has been destroyed in ([x], [y] ,[z] - JMP). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z] - JMP).") - log_game("[src] has been destroyed in ([x], [y] ,[z]). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z]).") + var/turf/diskturf = get_turf(src) + message_admins("[src] has been destroyed in ([diskturf.x], [diskturf.y] ,[diskturf.z] - JMP). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z] - JMP).") + log_game("[src] has been destroyed in ([diskturf.x], [diskturf.y] ,[diskturf.z]). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z]).") del(src) //Needed to clear all references to it else ERROR("[src] was supposed to be destroyed, but we were unable to locate a blobstart landmark to spawn a new one.") - return 1 // Cancel destruction. \ No newline at end of file + return 1 // Cancel destruction. diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 11dac93a53a..b7dbbce85bc 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -17,7 +17,7 @@ antag_flag = BE_REV restricted_jobs = list("Security Officer", "Warden", "Detective", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer") required_players = 20 - required_enemies = 3 + required_enemies = 1 recommended_enemies = 3 var/finished = 0 @@ -41,6 +41,9 @@ if(config.protect_roles_from_antagonist) restricted_jobs += protected_jobs + if(config.protect_assistant_from_antagonist) + restricted_jobs += "Assistant" + var/head_check = 0 for(var/mob/new_player/player in player_list) if(player.mind.assigned_role in command_positions) @@ -52,17 +55,12 @@ if(player.assigned_role == job) antag_candidates -= player - var/list/heads = get_living_heads() - if(heads.len < max_headrevs) - max_headrevs = heads.len - for (var/i=1 to max_headrevs) if (antag_candidates.len==0) break var/datum/mind/lenin = pick(antag_candidates) antag_candidates -= lenin head_revolutionaries += lenin - log_game("[lenin.key] (ckey) has been selected as a head rev") if((head_revolutionaries.len < required_enemies)||(!head_check)) return 0 @@ -73,9 +71,14 @@ /datum/game_mode/revolution/post_setup() var/list/heads = get_living_heads() - heads_to_kill = heads + while(heads.len < head_revolutionaries.len) //das vi danya + var/datum/mind/trotsky = pick(head_revolutionaries) + antag_candidates += trotsky + head_revolutionaries -= trotsky + update_rev_icons_removed(trotsky) for(var/datum/mind/rev_mind in head_revolutionaries) + log_game("[rev_mind.key] (ckey) has been selected as a head rev") for(var/datum/mind/head_mind in heads) mark_for_death(rev_mind, head_mind) @@ -160,6 +163,7 @@ rev_obj.target = head_mind rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]." rev_mind.objectives += rev_obj + heads_to_kill += head_mind //////////////////////////////////////////// //Checks if new heads have joined midround// diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index b60b0881165..d1c5b769b03 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -30,6 +30,9 @@ if(config.protect_roles_from_antagonist) restricted_jobs += protected_jobs + if(config.protect_assistant_from_antagonist) + restricted_jobs += "Assistant" + var/num_traitors = 1 if(config.traitor_scaling_coeff) diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm index e8560103ecc..1aaee715f37 100644 --- a/code/game/gamemodes/wizard/rightandwrong.dm +++ b/code/game/gamemodes/wizard/rightandwrong.dm @@ -58,7 +58,7 @@ if("doublebarrel") new /obj/item/weapon/gun/projectile/revolver/doublebarrel(get_turf(H)) if("shotgun") - new /obj/item/weapon/gun/projectile/shotgun/(get_turf(H)) + new /obj/item/weapon/gun/projectile/shotgun(get_turf(H)) if("combatshotgun") new /obj/item/weapon/gun/projectile/shotgun/combat(get_turf(H)) if("mateba") diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 5aa5448c8c3..613b07e545c 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -84,7 +84,7 @@ Warden H.equip_to_slot_or_del(new /obj/item/clothing/head/warden(H), slot_head) H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(H), slot_gloves) H.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/security/sunglasses(H), slot_glasses) - H.equip_to_slot_or_del(new /obj/item/device/flash(H), slot_l_store) + H.equip_to_slot_or_del(new /obj/item/device/flash/handheld(H), slot_l_store) if(H.backbag == 1) H.equip_to_slot_or_del(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand) @@ -175,7 +175,7 @@ Security Officer H.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/clothing/head/helmet(H), slot_head) H.equip_to_slot_or_del(new /obj/item/weapon/restraints/handcuffs(H), slot_s_store) - H.equip_to_slot_or_del(new /obj/item/device/flash(H), slot_l_store) + H.equip_to_slot_or_del(new /obj/item/device/flash/handheld(H), slot_l_store) if(H.backbag == 1) H.equip_to_slot_or_del(new /obj/item/weapon/restraints/handcuffs(H), slot_r_store) diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 0467c3c3d62..f64917ebf06 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -851,7 +851,8 @@ table tr:first-child th:first-child { border: none;} else stat |= NOPOWER spawn(rand(0,15)) - update_icon() + if(loc) + update_icon() /* AIR ALARM CIRCUIT @@ -1084,10 +1085,10 @@ FIRE ALARM /obj/machinery/firealarm/power_change() if(powered(ENVIRON)) stat &= ~NOPOWER - update_icon() else - spawn(rand(0,15)) - stat |= NOPOWER + stat |= NOPOWER + spawn(rand(0,15)) + if(loc) update_icon() /obj/machinery/firealarm/attack_hand(mob/user as mob) diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index e897262769f..5268cd43732 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -6,6 +6,7 @@ luminosity = 3 use_power = 0 var/obj/item/weapon/card/id/botcard // the ID card that the bot "holds" + var/list/prev_access = list() var/on = 1 var/health = 0 //do not forget to set health for your bot! var/maxhealth = 0 @@ -14,7 +15,74 @@ var/open = 0//Maint panel var/locked = 1 var/hacked = 0 //Used to differentiate between being hacked by silicons and emagged by humans. + var/text_hack = "" //Custom text returned to a silicon upon hacking a bot. + var/text_dehack = "" //Text shown when resetting a bots hacked status to normal. + var/text_dehack_fail = "" //Shown when a silicon tries to reset a bot emagged with the emag item, which cannot be reset. + var/declare_message = "" //What the bot will display to the HUD user. + var/frustration = 0 //Used by some bots for tracking failures to reach their target. + var/speed = 2 //The speed at which the bot moves, or the number of times it moves per process() tick. + var/turf/ai_waypoint //The end point of a bot's path, or the target location. + var/list/path = list() //List of turfs through which a bot 'steps' to reach the waypoint. + var/pathset = 0 + var/list/ignore_list = list() //List of unreachable targets for an ignore-list enabled bot to ignore. + var/mode = 0 //Standardizes the vars that indicate the bot is busy with its function. + var/tries = 0 //Number of times the bot tried and failed to move. + var/remote_disabled = 0 //If enabled, the AI cannot *Remotely* control a bot. It can still control it through cameras. + var/mob/living/silicon/ai/calling_ai //Links a bot to the AI calling it. + var/obj/item/device/radio/Radio //The bot's radio, for speaking to people. + var/radio_frequency //The bot's default radio speaking freqency. Recommended to be on a department frequency. //var/emagged = 0 //Urist: Moving that var to the general /bot tree as it's used by most bots + var/auto_patrol = 0// set to make bot automatically patrol + var/turf/patrol_target // this is turf to navigate to (location of beacon) + var/turf/summon_target // The turf of a user summoning a bot. + var/new_destination // pending new destination (waiting for beacon response) + var/destination // destination description tag + var/next_destination // the next destination in the patrol route + + var/blockcount = 0 //number of times retried a blocked path + var/awaiting_beacon = 0 // count of pticks awaiting a beacon response + + var/nearest_beacon // the nearest beacon's tag + var/turf/nearest_beacon_loc // the nearest beacon's location + + var/beacon_freq = 1445 // navigation beacon frequency + var/control_freq = 1447 // bot control frequency + + var/bot_filter // The radio filter the bot uses to identify itself on the network. + + var/bot_type = 0 //The type of bot it is, for radio control. + #define SEC_BOT 1 // Secutritrons (Beepsky) and ED-209s + #define MULE_BOT 2 // MULEbots + #define FLOOR_BOT 3 // Floorbots + #define CLEAN_BOT 4 // Cleanbots + #define MED_BOT 5 // Medibots + + #define DEFAULT_SCAN_RANGE 7 //default view range for finding targets. + + //Mode defines + #define BOT_IDLE 0 // idle + #define BOT_HUNT 1 // found target, hunting + #define BOT_PREP_ARREST 2 // at target, preparing to arrest + #define BOT_ARREST 3 // arresting target + #define BOT_START_PATROL 4 // start patrol + #define BOT_PATROL 5 // patrolling + #define BOT_SUMMON 6 // summoned by PDA + #define BOT_CLEANING 7 // cleaning (cleanbots) + #define BOT_REPAIRING 8 // repairing hull breaches (floorbots) + #define BOT_MOVING 9 // for clean/floor bots, when moving. + #define BOT_HEALING 10 // healing people (medbots) + #define BOT_RESPONDING 11 // responding to a call from the AI + #define BOT_LOADING 12 // loading/unloading + #define BOT_DELIVER 13 // moving to deliver + #define BOT_GO_HOME 14 // returning to home + #define BOT_BLOCKED 15 // blocked + #define BOT_NAV 16 // computing navigation + #define BOT_WAIT_FOR_NAV 17 // waiting for nav computation + #define BOT_NO_ROUTE 18 // no destination beacon found (or no route) + var/list/mode_name = list("In Pursuit","Preparing to Arrest","Arresting","Beginning Patrol","Patrolling","Summoned by PDA", \ + "Cleaning", "Repairing", "Proceeding to work site","Healing","Responding","Loading/Unloading","Navigating to Delivery Location","Navigating to Home", \ + "Waiting for clear path","Calculating navigation path","Pinging beacon network","Unable to reach destination") + //This holds text for what the bot is mode doing, reported on the AI's bot control interface. /obj/machinery/bot/proc/turn_on() @@ -26,26 +94,46 @@ /obj/machinery/bot/proc/turn_off() on = 0 SetLuminosity(0) + bot_reset() //Resets an AI's call, should it exist. + +/obj/machinery/bot/New() + ..() + botcard = new /obj/item/weapon/card/id(src) + set_custom_texts() + Radio = new /obj/item/device/radio(src) + Radio.listening = 0 //Makes bot radios transmit only so no one hears things while adjacent to one. + +/obj/machinery/bot/proc/add_to_beacons(bot_filter) //Master filter control for bots. Must be placed in the bot's local New() to support map spawned bots. + if(radio_controller) + radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS) + if(bot_filter) + radio_controller.add_object(src, control_freq, filter = bot_filter) /obj/machinery/bot/proc/explode() qdel(src) /obj/machinery/bot/proc/healthcheck() - if (src.health <= 0) - src.explode() + if (health <= 0) + explode() -/obj/machinery/bot/proc/Emag(mob/user as mob) - if(locked) +/obj/machinery/bot/proc/Emag(mob/user as mob) //Master Emag proc. Ensure this is called in your bot before setting unique functions. + if(locked) //First emag application unlocks the bot's interface. Apply a screwdriver to use the emag again. locked = 0 emagged = 1 user << "You bypass [src]'s controls." - if(!locked && open) + if(!locked && open) //Bot panel is unlocked by ID or emag, and the panel is screwed open. Ready for emagging. emagged = 2 + remote_disabled = 1 //Manually emagging the bot locks out the AI built in panel. + locked = 1 //Access denied forever! + bot_reset() + turn_on() //The bot automatically turns on when emagged, unless recently hit with EMP. + else //Bot is unlocked, but the maint panel has not been opened with a screwdriver yet. + user << "You need to open maintenance panel first." /obj/machinery/bot/examine(mob/user) ..() - if (src.health < maxhealth) - if (src.health > maxhealth/3) + if (health < maxhealth) + if (health > maxhealth/3) user << "[src]'s parts look loose." else user << "[src]'s parts look very loose." @@ -54,32 +142,96 @@ /obj/machinery/bot/attack_alien(var/mob/living/carbon/alien/user as mob) user.changeNext_move(CLICK_CD_MELEE) - src.health -= rand(15,30)*brute_dam_coeff - src.visible_message("[user] has slashed [src]!") - playsound(src.loc, 'sound/weapons/slice.ogg', 25, 1, -1) + health -= rand(15,30)*brute_dam_coeff + visible_message("[user] has slashed [src]!") + playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) if(prob(10)) - new /obj/effect/decal/cleanable/oil(src.loc) + new /obj/effect/decal/cleanable/oil(loc) healthcheck() /obj/machinery/bot/attack_animal(var/mob/living/simple_animal/M as mob) - if(M.melee_damage_upper == 0) return + if(M.melee_damage_upper == 0) + return M.changeNext_move(CLICK_CD_MELEE) - src.health -= M.melee_damage_upper - src.visible_message("[M] has [M.attacktext] [src]!") + health -= M.melee_damage_upper + visible_message("[M] has [M.attacktext] [src]!") add_logs(M, src, "attacked", admin=0) if(prob(10)) - new /obj/effect/decal/cleanable/oil(src.loc) + new /obj/effect/decal/cleanable/oil(loc) healthcheck() +/obj/machinery/bot/Topic(href, href_list) //Master Topic to handle common functions. + . = ..() + if (.) + return + if(topic_denied(usr)) + usr << "[src]'s interface is not responding!" + href_list = list() + return + usr.set_machine(src) + add_fingerprint(usr) + if((href_list["power"]) && (allowed(usr) || !locked)) + if (on) + turn_off() + else + turn_on() + + switch(href_list["operation"]) + if("patrol") + auto_patrol = !auto_patrol + mode = BOT_IDLE + if("remote") + remote_disabled = !remote_disabled + if("hack") + if(emagged != 2) + emagged = 2 + hacked = 1 + locked = 1 + usr << "[text_hack]" + bot_reset() + else if(!hacked) + usr << "[text_dehack_fail]" + else + emagged = 0 + hacked = 0 + usr << "[text_dehack]" + bot_reset() + updateUsrDialog() + +/obj/machinery/bot/proc/topic_denied(mob/user) //Access check proc for bot topics! Remember to place in a bot's individual Topic if desired. + // 0 for access, 1 for denied. + if(emagged == 2) //An emagged bot cannot be controlled by humans, silicons can if one hacked it. + if(!hacked) //Manually emagged by a human - access denied to all. + return 1 + else if(!issilicon(user)) //Bot is hacked, so only silicons are allowed access. + return 1 + else + return 0 + +/obj/machinery/bot/process() //Master process which handles code common across most bots. + + set background = BACKGROUND_ENABLED + + if(!on) + return + + switch(mode) //High-priority overrides are processed first. Bots can do nothing else while under direct command. + if(BOT_RESPONDING) //Called by the AI. + call_mode() + return + if(BOT_SUMMON) //Called by PDA + bot_summon() + return + return 1 //Successful completion. Used to prevent child process() continuing if this one is ended early. /obj/machinery/bot/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/screwdriver)) if(!locked) open = !open - user << "Maintenance panel is now [src.open ? "opened" : "closed"]." + user << "Maintenance panel is now [open ? "opened" : "closed"]." else user << "Maintenance panel is locked." else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm") @@ -103,10 +255,10 @@ s.set_up(5, 1, src) switch(W.damtype) if("fire") - src.health -= W.force * fire_dam_coeff + health -= W.force * fire_dam_coeff s.start() if("brute") - src.health -= W.force * brute_dam_coeff + health -= W.force * brute_dam_coeff s.start() ..() healthcheck() @@ -124,24 +276,24 @@ return /obj/machinery/bot/blob_act() - src.health -= rand(20,40)*fire_dam_coeff + health -= rand(20,40)*fire_dam_coeff healthcheck() return /obj/machinery/bot/ex_act(severity) switch(severity) if(1.0) - src.explode() + explode() return if(2.0) - src.health -= rand(5,10)*fire_dam_coeff - src.health -= rand(10,20)*brute_dam_coeff + health -= rand(5,10)*fire_dam_coeff + health -= rand(10,20)*brute_dam_coeff healthcheck() return if(3.0) if (prob(50)) - src.health -= rand(1,5)*fire_dam_coeff - src.health -= rand(1,5)*brute_dam_coeff + health -= rand(1,5)*fire_dam_coeff + health -= rand(1,5)*brute_dam_coeff healthcheck() return return @@ -149,7 +301,7 @@ /obj/machinery/bot/emp_act(severity) var/was_on = on stat |= EMPED - var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( src.loc ) + var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( loc ) pulse2.icon = 'icons/effects/effects.dmi' pulse2.icon_state = "empdisable" pulse2.name = "emp sparks" @@ -167,17 +319,468 @@ /obj/machinery/bot/proc/hack(mob/user) var/hack - if(issilicon(user)) - hack += "[src.emagged ? "Software compromised! Unit may exhibit dangerous or erratic behavior." : "Unit operating normally. Release safety lock?"]
" - hack += "Harm Prevention Safety System: [src.emagged ? "DANGER" : "Engaged"]
" + if(issilicon(user)) //Allows silicons to toggle the emag status of a bot. + hack += "[emagged == 2 ? "Software compromised! Unit may exhibit dangerous or erratic behavior." : "Unit operating normally. Release safety lock?"]
" + hack += "Harm Prevention Safety System: [emagged ? "DANGER" : "Engaged"]
" + else if(!locked) //Humans with access can use this option to hide a bot from the AI's remote control panel and PDA control. + hack += "Remote network control radio: [remote_disabled ? "Disconnected" : "Connected"]

" return hack -/obj/machinery/bot/attack_ai(mob/user as mob) - src.attack_hand(user) +/obj/machinery/bot/proc/set_custom_texts() //Superclass for setting hack texts. Appears only if a set is not given to a bot locally. + text_hack = "You hack [name]." + text_dehack = "You reset [name]." + text_dehack_fail = "You fail to reset [name]." -/obj/machinery/bot/proc/speak(var/message) - if((!src.on) || (!message)) +/obj/machinery/bot/attack_ai(mob/user as mob) + attack_hand(user) + +/obj/machinery/bot/proc/speak(var/message, freq) //Pass a message to have the bot say() it. Pass a frequency to say it on the radio. + if((!on) || (!message)) return - audible_message("[src] beeps, \"[message]\"",2) + if(freq) + Radio.set_frequency(radio_frequency) + Radio.talk_into(src, message, radio_frequency) + else + say(message) return + //Generalized behavior code, override where needed! + +/* +scan() will search for a given type (such as turfs, human mobs, or objects) in the bot's view range, and return a single result. +Arguments: The object type to be searched (such as "/mob/living/carbon/human"), the old scan result to be ignored, if one exists, +and the view range, which defaults to 7 (full screen) if an override is not passed. +If the bot maintains an ignore list, it is also checked here. + +Example usage: patient = scan(/mob/living/carbon/human, oldpatient, 1) +The proc would return a human next to the bot to be set to the patient var. +Pass the desired type path itself, declaring a temporary var beforehand is not required. +*/ +obj/machinery/bot/proc/scan(var/scan_type, var/old_target, var/scan_range) + var/final_result + for (var/scan in view (scan_range ? scan_range : DEFAULT_SCAN_RANGE, src) ) //Search for something in range! + if(!istype(scan, scan_type)) //Check that the thing we found is the type we want! + continue //If not, keep searching! + if( !(scan in ignore_list) && !(scan in old_target) ) //Filter for blacklisted elements, usually unreachable or previously processed oness + var/scan_result = process_scan(scan) //Some bots may require additional processing when a result is selected. + if( scan_result ) + final_result = scan_result + else + continue //The current element failed assessment, move on to the next. + return final_result + +//When the scan finds a target, run bot specific processing to select it for the next step. Empty by default. +obj/machinery/bot/proc/process_scan(var/scan_target) + return scan_target + + +/obj/machinery/bot/proc/add_to_ignore(var/subject) + if(ignore_list.len < 50) //This will help keep track of them, so the bot is always trying to reach a blocked spot. + ignore_list |= subject + else if (ignore_list.len >= subject) //If the list is full, insert newest, delete oldest. + ignore_list -= ignore_list[1] + ignore_list |= subject + +/* +Movement proc for stepping a bot through a path generated through A-star. +Pass a positive integer as an argument to override a bot's default speed. +*/ +obj/machinery/bot/proc/bot_move(var/dest, var/move_speed) + + if(!dest || !path || path.len == 0) //A-star failed or a path/destination was not set. + path = list() + return 0 + if(get_turf(src) == get_turf(dest)) //We have arrived, no need to move again. + return 1 + var/success + var/step_count = move_speed ? move_speed : speed //If a value is passed into move_speed, use that instead of the default speed var. + if(step_count >= 1 && tries < 4) + for(step_count, step_count >= 1,step_count--) + success = bot_step(dest) + if (success) + tries = 0 + else + tries++ + break + sleep(4) + else + return 0 + return 1 + + +obj/machinery/bot/proc/bot_step(var/dest) + if(path && path.len > 1) + step_to(src, path[1]) + if(get_turf(src) == path[1]) //Successful move + path -= path[1] + else + return 0 + else if(path.len == 1) + step_to(src, dest) + path = list() + return 1 + + +/obj/machinery/bot/proc/check_bot_access() + if(mode != BOT_SUMMON && mode != BOT_RESPONDING) + botcard.access = prev_access + +/obj/machinery/bot/proc/call_bot(var/caller, var/turf/waypoint) + bot_reset() //Reset a bot before setting it to call mode. + var/area/end_area = get_area(waypoint) + + //For giving the bot temporary all-access. + var/obj/item/weapon/card/id/all_access = new /obj/item/weapon/card/id + var/datum/job/captain/All = new/datum/job/captain + all_access.access = All.get_access() + + path = AStar(src, waypoint, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 200, id=all_access) + calling_ai = caller //Link the AI to the bot! + ai_waypoint = waypoint + + if(path && path.len) //Ensures that a valid path is calculated! + if(!on) + turn_on() //Saves the AI the hassle of having to activate a bot manually. + botcard = all_access //Give the bot all-access while under the AI's command. + calling_ai << "\icon[src] [name] called to [end_area.name]. [path.len-1] meters to destination." + pathset = 1 + mode = BOT_RESPONDING + tries = 0 + else + calling_ai << "Failed to calculate a valid route. Ensure destination is clear of obstructions and within range." + calling_ai = null + path = list() + +/obj/machinery/bot/proc/call_mode() //Handles preparing a bot for a call, as well as calling the move proc. +//Handles the bot's movement during a call. + var/success = bot_move(ai_waypoint, 3) + if (!success) + if(calling_ai) + calling_ai << "\icon[src] [get_turf(src) == ai_waypoint ? "[src] successfully arrived to waypoint." : "[src] failed to reach waypoint."]" + calling_ai = null + bot_reset() + +obj/machinery/bot/proc/bot_reset() + if(calling_ai) //Simple notification to the AI if it called a bot. It will not know the cause or identity of the bot. + calling_ai << "Call command to a bot has been reset." + calling_ai = null + path = list() + summon_target = null + pathset = 0 + botcard.access = prev_access + tries = 0 + mode = BOT_IDLE + + + + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//Patrol and summon code! +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +/obj/machinery/bot/proc/bot_patrol() + patrol_step() + spawn(5) + if(mode == BOT_PATROL) + patrol_step() + return + +obj/machinery/bot/proc/start_patrol() + + if(tries >= 4) //Bot is trapped, so stop trying to patrol. + auto_patrol = 0 + tries = 0 + speak("Unable to start patrol.") + + return + + if(!auto_patrol) //A bot not set to patrol should not be patrolling. + mode = BOT_IDLE + return + + if(patrol_target) // has patrol target + spawn(0) + calc_path() // Find a route to it + if(path.len == 0) + patrol_target = 0 + return + mode = BOT_PATROL + else // no patrol target, so need a new one + find_patrol_target() + speak("Engaging patrol mode.") + tries++ + return + +// perform a single patrol step + +/obj/machinery/bot/proc/patrol_step() + + if(loc == patrol_target) // reached target + + at_patrol_target() + return + + else if(path.len > 0 && patrol_target) // valid path + var/turf/next = path[1] + if(next == loc) + path -= next + return + + + var/moved = bot_move(patrol_target)//step_towards(src, next) // attempt to move + if(moved) // successful move + blockcount = 0 + + else // failed to move + blockcount++ + + if(blockcount > 5) // attempt 5 times before recomputing + // find new path excluding blocked turf + + spawn(2) + calc_path(next) + if(path.len == 0) + find_patrol_target() + else + blockcount = 0 + tries = 0 + + return + + return + + else // no path, so calculate new one + mode = BOT_START_PATROL + + return + +// finds a new patrol target +/obj/machinery/bot/proc/find_patrol_target() + send_status() + if(awaiting_beacon) // awaiting beacon response + awaiting_beacon++ + if(awaiting_beacon > 5) // wait 5 secs for beacon response + find_nearest_beacon() // then go to nearest instead + return + if(next_destination) + set_destination(next_destination) + else + + find_nearest_beacon() + return + + +// finds the nearest beacon to self +// signals all beacons matching the patrol code +/obj/machinery/bot/proc/find_nearest_beacon() + nearest_beacon = null + new_destination = "__nearest__" + post_signal(beacon_freq, "findbeacon", "patrol") + awaiting_beacon = 1 + spawn(10) + awaiting_beacon = 0 + if(nearest_beacon) + set_destination(nearest_beacon) + tries = 0 + else + auto_patrol = 0 + mode = BOT_IDLE + speak("Disengaging patrol mode.") + send_status() + + +/obj/machinery/bot/proc/at_patrol_target() + + find_patrol_target() + return + + +// sets the current destination +// signals all beacons matching the patrol code +// beacons will return a signal giving their locations +/obj/machinery/bot/proc/set_destination(var/new_dest) + new_destination = new_dest + post_signal(beacon_freq, "findbeacon", "patrol") + awaiting_beacon = 1 + + +// receive a radio signal +// used for beacon reception + +/obj/machinery/bot/receive_signal(datum/signal/signal) + //log_admin("DEBUG \[[// world.timeofday]\]: /obj/machinery/bot/receive_signal([signal.debug_print()])") + if(!on) + return +/* + if(!signal.data["beacon"]) + + for(var/x in signal.data) + world << "* [x] = [signal.data[x]]" + */ + + var/recv = signal.data["command"] + // process all-bot input + + if(recv=="bot_status") + send_status() + + // check to see if we are the commanded bot + if(signal.data["active"] == src) + if(emagged == 2 || remote_disabled) //Emagged bots do not respect anyone's authority! Bots with their remote controls off cannot get commands. + return + // process control input + switch(recv) + if("stop") + bot_reset() //HOLD IT!! + auto_patrol = 0 + return + + if("go") + auto_patrol = 1 + return + + if("summon") + bot_reset() + var/list/user_access = signal.data["useraccess"] + summon_target = signal.data["target"] //Location of the user + if(user_access.len != 0) + botcard.access = user_access + prev_access //Adds the user's access, if any. + mode = BOT_SUMMON + calc_summon_path() + speak("Responding.", radio_frequency) + return + + // receive response from beacon + recv = signal.data["beacon"] + var/valid = signal.data["patrol"] + if(!recv || !valid) + return + if(recv == new_destination) // if the recvd beacon location matches the set destination + // the we will navigate there + destination = new_destination + patrol_target = signal.source.loc + next_destination = signal.data["next_patrol"] + awaiting_beacon = 0 + + // if looking for nearest beacon + else if(new_destination == "__nearest__") + var/dist = get_dist(src,signal.source.loc) + if(nearest_beacon) + // note we ignore the beacon we are located at + if(dist>1 && dist 1) + nearest_beacon = recv + nearest_beacon_loc = signal.source.loc + return + + +// send a radio signal with a single data key/value pair +/obj/machinery/bot/proc/post_signal(var/freq, var/key, var/value) + post_signal_multiple(freq, list("[key]" = value) ) + +// send a radio signal with multiple data key/values +/obj/machinery/bot/proc/post_signal_multiple(var/freq, var/list/keyval) + if(!z || z != 1) //Bot control will only work on station. + return + var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq) + + if(!frequency) return + + var/datum/signal/signal = new() + signal.source = src + signal.transmission_method = 1 +// for(var/key in keyval) +// signal.data[key] = keyval[key] + signal.data = keyval +// world << "sent [key],[keyval[key]] on [freq]" + if(signal.data["findbeacon"]) + frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS) + else if(signal.data["type"] == bot_type) + frequency.post_signal(src, signal, filter = bot_filter) + else + frequency.post_signal(src, signal) + +// signals bot status etc. to controller +/obj/machinery/bot/proc/send_status() + if(remote_disabled || emagged == 2) + return + var/list/kv = list( + "type" = bot_type, + "name" = name, + "loca" = get_area(src), // area + "mode" = mode + ) + post_signal_multiple(control_freq, kv) + + +obj/machinery/bot/proc/bot_summon() + // summoned to PDA + summon_step() + return + +// calculates a path to the current destination +// given an optional turf to avoid +/obj/machinery/bot/proc/calc_path(var/turf/avoid) + check_bot_access() + path = AStar(loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 120, id=botcard, exclude=avoid) + if(!path) + path = list() + +/obj/machinery/bot/proc/calc_summon_path(var/turf/avoid) + check_bot_access() + path = AStar(loc, summon_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 150, id=botcard, exclude=avoid) + if(!path || tries >= 5) //Cannot reach target. Give up and announce the issue. + speak("Summon command failed, destination unreachable.",radio_frequency) + bot_reset() + +/obj/machinery/bot/proc/summon_step() + + if(loc == summon_target) // Arrived to summon location. + bot_reset() + return + + else if(path.len > 0 && summon_target) //Proper path acquired! + var/turf/next = path[1] + if(next == loc) + path -= next + return + + var/moved = bot_move(summon_target, 3) // Move attempt + if(moved) + blockcount = 0 + + else // failed to move + blockcount++ + + if(blockcount > 5) // attempt 5 times before recomputing + // find new path excluding blocked turf + spawn(2) + calc_summon_path(next) + tries++ + return + + return + + else // no path, so calculate new one + calc_summon_path() + + return + + +/obj/machinery/bot/Bump(M as mob|obj) //Leave no door unopened! + if((istype(M, /obj/machinery/door/airlock) || istype(M, /obj/machinery/door/window)) && (!isnull(botcard))) + var/obj/machinery/door/D = M + if(D.check_access(botcard)) + D.open() + frustration = 0 + else if((istype(M, /mob/living/)) && (!anchored)) + var/mob/living/Mb = M + loc = Mb.loc + frustration = 0 + return \ No newline at end of file diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm index f27815a0a3c..8a3b033d149 100644 --- a/code/game/machinery/bots/cleanbot.dm +++ b/code/game/machinery/bots/cleanbot.dm @@ -24,51 +24,57 @@ //weight = 1.0E7 health = 25 maxhealth = 25 - var/cleaning = 0 var/blood = 1 var/list/target_types = list() var/obj/effect/decal/cleanable/target var/obj/effect/decal/cleanable/oldtarget + var/max_targets = 50 //Maximum number of targets a cleanbot can ignore. var/oldloc = null - req_access = list(access_janitor) - var/path[] = new() - var/patrol_path[] = null - var/beacon_freq = 1445 // navigation beacon frequency + req_one_access = list(access_janitor, access_robotics) +// var/patrol_path[] = null +// var/beacon_freq = 1445 // navigation beacon frequency var/closest_dist var/closest_loc var/failed_steps - var/should_patrol var/next_dest var/next_dest_loc + radio_frequency = SERV_FREQ //Service + bot_type = CLEAN_BOT + bot_filter = RADIO_CLEANBOT /obj/machinery/bot/cleanbot/New() ..() - src.get_targets() - src.icon_state = "cleanbot[src.on]" + get_targets() + icon_state = "cleanbot[on]" - should_patrol = 1 - - src.botcard = new /obj/item/weapon/card/id(src) var/datum/job/janitor/J = new/datum/job/janitor - src.botcard.access = J.get_access() - - if(radio_controller) - radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS) + botcard.access = J.get_access() + prev_access = botcard.access + spawn(5) + add_to_beacons(bot_filter) /obj/machinery/bot/cleanbot/turn_on() - . = ..() - src.icon_state = "cleanbot[src.on]" - src.updateUsrDialog() + ..() + icon_state = "cleanbot[on]" + updateUsrDialog() /obj/machinery/bot/cleanbot/turn_off() ..() - src.target = null - src.oldtarget = null - src.oldloc = null - src.icon_state = "cleanbot[src.on]" - src.path = new() - src.updateUsrDialog() + icon_state = "cleanbot[on]" + updateUsrDialog() + +/obj/machinery/bot/cleanbot/bot_reset() + ..() + ignore_list = list() //Allows the bot to clean targets it previously ignored due to being unreachable. + target = null + oldtarget = null + oldloc = null + +/obj/machinery/bot/cleanbot/set_custom_texts() + text_hack = "You corrupt [name]'s cleaning software." + text_dehack = "[name]'s software has been reset!" + text_dehack_fail = "[name] does not seem to respond to your repair code!" /obj/machinery/bot/cleanbot/attack_hand(mob/user as mob) . = ..() @@ -81,76 +87,39 @@ var/dat dat += hack(user) dat += text({" -Automatic Station Cleaner v1.0

+Cleaner v1.1 controls

Status: []
-Behaviour controls are [src.locked ? "locked" : "unlocked"]
-Maintenance panel panel is [src.open ? "opened" : "closed"]"}, -text("[src.on ? "On" : "Off"]")) - if(!src.locked || issilicon(user)) - dat += text({"
Cleans Blood: []
"}, text("[src.blood ? "Yes" : "No"]")) - dat += text({"
Patrol station: []
"}, text("[src.should_patrol ? "Yes" : "No"]")) - // dat += text({"
Beacon frequency: []
"}, text("[src.beacon_freq]")) -/* if(src.open && !src.locked) - dat += text({" -Odd looking screw twiddled: []
-Weird button pressed: []"}, -text("[src.screwloose ? "Yes" : "No"]"), -text("[src.oddbutton ? "Yes" : "No"]"))*/ +Behaviour controls are [locked ? "locked" : "unlocked"]
+Maintenance panel panel is [open ? "opened" : "closed"]"}, +text("[on ? "On" : "Off"]")) + if(!locked || issilicon(user)) + dat += text({"
Cleans Blood: []
"}, text("[blood ? "Yes" : "No"]")) + dat += text({"
Patrol station: []
"}, text("[auto_patrol ? "Yes" : "No"]")) - user << browse("Cleaner v1.0 controls[dat]", "window=autocleaner") - onclose(user, "autocleaner") + var/datum/browser/popup = new(user, "autoclean", "Automatic Station Cleaner v1.1") + popup.set_content(dat) + popup.open() return /obj/machinery/bot/cleanbot/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - src.add_fingerprint(usr) + + ..() switch(href_list["operation"]) - if("start") - if (src.on && !src.emagged) - turn_off() - else - turn_on() if("blood") - src.blood =!src.blood - src.get_targets() - src.updateUsrDialog() - if("patrol") - src.should_patrol =!src.should_patrol - src.patrol_path = null - src.updateUsrDialog() + blood =!blood + get_targets() + updateUsrDialog() if("freq") var/freq = text2num(input("Select frequency for navigation beacons", "Frequency", num2text(beacon_freq / 10))) * 10 if (freq > 0) - src.beacon_freq = freq - src.updateUsrDialog() -/* if("screw") - src.screwloose = !src.screwloose - usr << "You press the weird button." - src.updateUsrDialog() */ - if("hack") - if(!src.emagged) - src.emagged = 2 - src.hacked = 1 - usr << "You corrupt [src]'s cleaning software." - else if(!src.hacked) - usr << "[src] does not seem to respond to your repair code!" - else - src.hacked = 0 - src.emagged = 0 - usr << "[src]'s software has been reset!" - src.updateUsrDialog() + beacon_freq = freq + updateUsrDialog() /obj/machinery/bot/cleanbot/attackby(obj/item/weapon/W, mob/user as mob) if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) - if(src.allowed(usr) && !open && !emagged) - src.locked = !src.locked - user << "You [ src.locked ? "lock" : "unlock"] the [src] behaviour controls." + if(allowed(usr) && !open && !emagged) + locked = !locked + user << "You [ locked ? "lock" : "unlock"] the [src] behaviour controls." else if(emagged) user << "ERROR" @@ -163,135 +132,77 @@ text("[src.oddbutton ? "Yes" : "No" /obj/machinery/bot/cleanbot/Emag(mob/user as mob) ..() - if(open && !locked) - if(user) user << "[src] buzzes and beeps." - src.emagged = 2 + if(emagged == 2) + if(user) + user << "[src] buzzes and beeps." + +/obj/machinery/bot/cleanbot/process_scan(var/obj/effect/decal/cleanable/D) + for(var/T in target_types) + if(istype(D, T)) + return D /obj/machinery/bot/cleanbot/process() - set background = BACKGROUND_ENABLED - - if(!src.on) + if (!..()) return - if(src.cleaning) - return - var/list/cleanbottargets = list() - if(!src.emagged && prob(5)) + if(mode == BOT_CLEANING) + return + + if(emagged == 2) //Emag functions + if(istype(loc,/turf/simulated)) + + if(prob(10)) //Wets floors randomly + var/turf/simulated/T = loc + T.MakeSlippery() + + if(prob(5)) //Spawns foam! + visible_message("[src] whirs and bubbles violently, before releasing a plume of froth!") + new /obj/effect/effect/foam(loc) + + else if (prob(5)) visible_message("[src] makes an excited beeping booping sound!") - if(src.emagged && prob(10)) //Wets floors randomly - if(istype(loc,/turf/simulated)) - var/turf/simulated/T = src.loc - T.MakeSlippery() + if(!target) //Search for cleanables it can see. + target = scan(/obj/effect/decal/cleanable/, oldtarget) + oldtarget = target - if(src.emagged && prob(5)) //Spawns foam! - visible_message("[src] whirs and bubbles violently, before releasing a plume of froth!") - new /obj/effect/effect/foam(src.loc) + if(!target) + if(loc != oldloc) + oldtarget = null - if(!src.target || src.target == null) - for (var/obj/effect/decal/cleanable/D in view(7,src)) - for(var/T in src.target_types) - if(!(D in cleanbottargets) && (D.type == T || D.parent_type == T) && D != src.oldtarget) - src.oldtarget = D - src.target = D - return + if(auto_patrol) + if(mode == BOT_IDLE || mode == BOT_START_PATROL) + start_patrol() - if(!src.target || src.target == null) - if(src.loc != src.oldloc) - src.oldtarget = null + if(mode == BOT_PATROL) + bot_patrol() - if (!should_patrol) + return + + if(target) + if(!path || path.len == 0) //No path, need a new one + //Try to produce a path to the target, and ignore airlocks to which it has access. + path = AStar(loc, target.loc, /turf/proc/AdjacentTurfsWithAccess, /turf/proc/Distance, 0, 30, id=botcard) + if (!bot_move(target)) + add_to_ignore(target) + target = null + path = list() + return + mode = BOT_MOVING + else if (!bot_move(target)) + target = null + mode = BOT_IDLE return - if (!patrol_path || patrol_path.len < 1) - var/datum/radio_frequency/frequency = radio_controller.return_frequency(beacon_freq) + if(target && loc == target.loc) + clean(target) + path = list() + target = null - if(!frequency) return - - closest_dist = 9999 - closest_loc = null - next_dest_loc = null - - var/datum/signal/signal = new() - signal.source = src - signal.transmission_method = 1 - signal.data = list("findbeacon" = "patrol") - frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS) - spawn(5) - if (!next_dest_loc) - next_dest_loc = closest_loc - if (next_dest_loc) - src.patrol_path = AStar(src.loc, next_dest_loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 120, id=botcard, exclude=null) - if(!patrol_path) - patrol_path = list() - else - patrol_move() - - return - - if(target && path.len == 0) - spawn(0) - if(!src || !target) return - src.path = AStar(src.loc, src.target.loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 30) - if(!src.path) - src.path = list() - if(src.path.len == 0) - src.oldtarget = src.target - src.target = null - return - if(src.path.len > 0 && src.target && (src.target != null)) - step_to(src, src.path[1]) - src.path -= src.path[1] - else if(src.path.len == 1) - step_to(src, target) - - if(src.target && (src.target != null)) - patrol_path = null - if(src.loc == src.target.loc) - clean(src.target) - src.path = new() - src.target = null - return - - src.oldloc = src.loc - -/obj/machinery/bot/cleanbot/proc/patrol_move() - if (src.patrol_path.len <= 0) - return - - var/next = src.patrol_path[1] - src.patrol_path -= next - if (next == src.loc) - return - - var/moved = step_towards(src, next) - if (!moved) - failed_steps++ - if (failed_steps > 4) - patrol_path = null - next_dest = null - failed_steps = 0 - else - failed_steps = 0 - -/obj/machinery/bot/cleanbot/receive_signal(datum/signal/signal) - var/recv = signal.data["beacon"] - var/valid = signal.data["patrol"] - if(!recv || !valid) - return - - var/dist = get_dist(src, signal.source.loc) - if (dist < closest_dist && signal.source.loc != src.loc) - closest_dist = dist - closest_loc = signal.source.loc - next_dest = signal.data["next_patrol"] - - if (recv == next_dest) - next_dest_loc = signal.source.loc - next_dest = signal.data["next_patrol"] + oldloc = loc /obj/machinery/bot/cleanbot/proc/get_targets() - src.target_types = new/list() + target_types = new/list() target_types += /obj/effect/decal/cleanable/oil target_types += /obj/effect/decal/cleanable/vomit @@ -306,7 +217,7 @@ text("[src.oddbutton ? "Yes" : "No" target_types += /obj/effect/decal/cleanable/greenglow target_types += /obj/effect/decal/cleanable/dirt - if(src.blood) + if(blood) target_types += /obj/effect/decal/cleanable/xenoblood/ target_types += /obj/effect/decal/cleanable/xenoblood/xgibs target_types += /obj/effect/decal/cleanable/blood/ @@ -314,20 +225,21 @@ text("[src.oddbutton ? "Yes" : "No" target_types += /obj/effect/decal/cleanable/trail_holder /obj/machinery/bot/cleanbot/proc/clean(var/obj/effect/decal/cleanable/target) - src.anchored = 1 - src.icon_state = "cleanbot-c" - visible_message("[src] begins to clean up [target]") - src.cleaning = 1 + anchored = 1 + icon_state = "cleanbot-c" + visible_message("[src] begins to clean up [target]") + mode = BOT_CLEANING spawn(50) - src.cleaning = 0 - qdel(target) - src.icon_state = "cleanbot[src.on]" - src.anchored = 0 - src.target = null + if(mode == BOT_CLEANING) + qdel(target) + anchored = 0 + target = null + mode = BOT_IDLE + icon_state = "cleanbot[on]" /obj/machinery/bot/cleanbot/explode() - src.on = 0 - src.visible_message("[src] blows apart!") + on = 0 + visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) new /obj/item/weapon/reagent_containers/glass/bucket(Tsec) @@ -348,17 +260,17 @@ text("[src.oddbutton ? "Yes" : "No" if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm)) user.drop_item() qdel(W) - var/turf/T = get_turf(src.loc) + var/turf/T = get_turf(loc) var/obj/machinery/bot/cleanbot/A = new /obj/machinery/bot/cleanbot(T) - A.name = src.created_name + A.name = created_name user << "You add the robot arm to the bucket and sensor assembly. Beep boop!" user.unEquip(src, 1) qdel(src) else if (istype(W, /obj/item/weapon/pen)) - var/t = copytext(stripped_input(user, "Enter new robot name", src.name, src.created_name),1,MAX_NAME_LEN) + var/t = copytext(stripped_input(user, "Enter new robot name", name, created_name),1,MAX_NAME_LEN) if (!t) return - if (!in_range(src, usr) && src.loc != usr) + if (!in_range(src, usr) && loc != usr) return - src.created_name = t + created_name = t \ No newline at end of file diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index 657c55ffec4..fd42c38f7b1 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -25,7 +25,6 @@ var/threatlevel = 0 var/target_lastloc //Loc of target when arrested. var/last_found //There's a delay - var/frustration = 0 //var/emagged = 0 //Emagged Secbots view everyone as a criminal var/declare_arrests = 1 //When making an arrest, should it notify everyone wearing sechuds? var/idcheck = 1 //If true, arrest people with no IDs @@ -34,38 +33,17 @@ var/arrest_type = 0 //If true, don't handcuff var/projectile = /obj/item/projectile/energy/electrode //Holder for projectile type var/shoot_sound = 'sound/weapons/Taser.ogg' - - var/mode = 0 -#define SECBOT_IDLE 0 // idle -#define SECBOT_HUNT 1 // found target, hunting -#define SECBOT_PREP_ARREST 2 // at target, preparing to arrest -#define SECBOT_ARREST 3 // arresting target -#define SECBOT_START_PATROL 4 // start patrol -#define SECBOT_PATROL 5 // patrolling -#define SECBOT_SUMMON 6 // summoned by PDA - - var/auto_patrol = 0 // set to make bot automatically patrol - - var/beacon_freq = 1445 // navigation beacon frequency - var/control_freq = 1447 // bot control frequency - + radio_frequency = SEC_FREQ + bot_type = SEC_BOT + bot_filter = RADIO_SECBOT +/ //List of weapons that secbots will not arrest for var/safe_weapons = list(\ /obj/item/weapon/gun/energy/laser/bluetag,\ /obj/item/weapon/gun/energy/laser/redtag,\ - /obj/item/weapon/gun/energy/laser/practice) - - var/turf/patrol_target // this is turf to navigate to (location of beacon) - var/new_destination // pending new destination (waiting for beacon response) - var/destination // destination description tag - var/next_destination // the next destination in the patrol route - var/list/path = new // list of path turfs - - var/blockcount = 0 //number of times retried a blocked path - var/awaiting_beacon = 0 // count of pticks awaiting a beacon response - - var/nearest_beacon // the nearest beacon's tag - var/turf/nearest_beacon_loc // the nearest beacon's location + /obj/item/weapon/gun/energy/laser/practice,\ + /obj/item/weapon/melee/telebaton,\ + /obj/item/weapon/gun/energy/kinetic_accelerator) /obj/item/weapon/ed209_assembly @@ -85,16 +63,15 @@ name = created_name if(created_lasercolor) lasercolor = created_lasercolor - src.icon_state = "[lasercolor]ed209[src.on]" - src.set_weapon() //giving it the right projectile and firing sound. + icon_state = "[lasercolor]ed209[on]" + set_weapon() //giving it the right projectile and firing sound. spawn(3) - src.botcard = new /obj/item/weapon/card/id(src) var/datum/job/detective/J = new/datum/job/detective - src.botcard.access = J.get_access() + botcard.access = J.get_access() + prev_access = botcard.access - if(radio_controller) - radio_controller.add_object(src, control_freq, filter = RADIO_SECBOT) - radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS) + + add_to_beacons(bot_filter) if(lasercolor) shot_delay = 6//Longer shot delay because JESUS CHRIST check_records = 0//Don't actively target people set to arrest @@ -108,19 +85,28 @@ /obj/machinery/bot/ed209/turn_on() . = ..() - src.icon_state = "[lasercolor]ed209[src.on]" - src.mode = SECBOT_IDLE - src.updateUsrDialog() + icon_state = "[lasercolor]ed209[on]" + mode = BOT_IDLE + updateUsrDialog() /obj/machinery/bot/ed209/turn_off() ..() - src.target = null - src.oldtarget_name = null - src.anchored = 0 - src.mode = SECBOT_IDLE + icon_state = "[lasercolor]ed209[on]" + updateUsrDialog() + +/obj/machinery/bot/ed209/bot_reset() + ..() + target = null + oldtarget_name = null + anchored = 0 walk_to(src,0) - src.icon_state = "[lasercolor]ed209[src.on]" - src.updateUsrDialog() + last_found = world.time + set_weapon() + +/obj/machinery/bot/ed209/set_custom_texts() + text_hack = "You disable [name]'s combat inhibitor." + text_dehack = "You restore [name]'s combat inhibitor." + text_dehack_fail = "[name] ignores your attempts to restrict him!" /obj/machinery/bot/ed209/attack_hand(mob/user as mob) . = ..() @@ -129,13 +115,14 @@ var/dat dat += hack(user) dat += text({" +Security Unit v2.6 controls

Status: []
-Behaviour controls are [src.locked ? "locked" : "unlocked"]
-Maintenance panel panel is [src.open ? "opened" : "closed"]
"}, +Behaviour controls are [locked ? "locked" : "unlocked"]
+Maintenance panel panel is [open ? "opened" : "closed"]
"}, -"
[src.on ? "On" : "Off"]" ) +"[on ? "On" : "Off"]" ) - if(!src.locked || issilicon(user)) + if(!locked || issilicon(user)) if(!lasercolor) dat += text({"
Arrest Unidentifiable Persons: []
@@ -143,82 +130,50 @@ Arrest for Unauthorized Weapons: []
Arrest for Warrant: []

Operating Mode: []
-Report Arrests[]"}, - -"[src.idcheck ? "Yes" : "No"]", -"[src.weaponscheck ? "Yes" : "No"]", -"[src.check_records ? "Yes" : "No"]", -"[src.arrest_type ? "Detain" : "Arrest"]", -"[src.declare_arrests ? "Yes" : "No"]" ) - - dat += text({"
-Auto Patrol: []"}, +Report Arrests[]
+Auto Patrol[]"}, +"[idcheck ? "Yes" : "No"]", +"[weaponscheck ? "Yes" : "No"]", +"[check_records ? "Yes" : "No"]", +"[arrest_type ? "Detain" : "Arrest"]", +"[declare_arrests ? "Yes" : "No"]", "[auto_patrol ? "On" : "Off"]" ) - - var/datum/browser/popup = new(user, "autosec", "Securitron v2.0.9 controls") + var/datum/browser/popup = new(user, "autoed209", "Automatic Security Unit v2.6") popup.set_content(dat) popup.open() return /obj/machinery/bot/ed209/Topic(href, href_list) - if (..()) - return - usr.set_machine(src) - src.add_fingerprint(usr) if(lasercolor && (istype(usr,/mob/living/carbon/human))) var/mob/living/carbon/human/H = usr if((lasercolor == "b") && (istype(H.wear_suit, /obj/item/clothing/suit/redtag)))//Opposing team cannot operate it return else if((lasercolor == "r") && (istype(H.wear_suit, /obj/item/clothing/suit/bluetag))) return - if ((href_list["power"]) && (src.allowed(usr))) - if (src.on && !src.emagged) - turn_off() - else - turn_on() - return + ..() switch(href_list["operation"]) if ("idcheck") - src.idcheck = !src.idcheck - src.updateUsrDialog() + idcheck = !idcheck if("weaponscheck") - src.weaponscheck = !src.weaponscheck - src.updateUsrDialog() - if("ignorerec") - src.check_records = !src.check_records - src.updateUsrDialog() - if("switchmode") - src.arrest_type = !src.arrest_type - src.updateUsrDialog() - if("patrol") - auto_patrol = !auto_patrol - mode = SECBOT_IDLE + weaponscheck = !weaponscheck + updateUsrDialog() + if ("ignorerec") + check_records = !check_records + updateUsrDialog() + if ("switchmode") + arrest_type = !arrest_type updateUsrDialog() if("declarearrests") - src.declare_arrests = !src.declare_arrests - src.updateUsrDialog() - if("hack") - if(!src.emagged) - src.emagged = 2 - src.hacked = 1 - src.set_weapon() - usr << "You disable [src]'s combat inhibitor." - else if(!src.hacked) - usr << "[src] ignores your attempts to restrict it!" - else - src.emagged = 0 - src.hacked = 0 - src.set_weapon() - usr << "You restore [src]'s combat inhibitor." - src.updateUsrDialog() + declare_arrests = !declare_arrests + updateUsrDialog() /obj/machinery/bot/ed209/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) - if (src.allowed(user) && !open && !emagged) - src.locked = !src.locked - user << "Controls are now [src.locked ? "locked" : "unlocked"]." + if (allowed(user) && !open && !emagged) + locked = !locked + user << "Controls are now [locked ? "locked" : "unlocked"]." else if(emagged) user << "ERROR" @@ -230,79 +185,75 @@ Auto Patrol: []"}, ..() if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm") // Any intent but harm will heal, so we shouldn't get angry. return - if (!istype(W, /obj/item/weapon/screwdriver) && (!src.target)) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass. + if (!istype(W, /obj/item/weapon/screwdriver) && (!target)) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass. if(W.force && W.damtype != STAMINA)//If force is non-zero and damage type isn't stamina. threatlevel = user.assess_threat(src) threatlevel += 6 if(threatlevel >= 4) - src.target = user + target = user if(lasercolor)//To make up for the fact that lasertag bots don't hunt - src.shootAt(user) - src.mode = SECBOT_HUNT + shootAt(user) + mode = BOT_HUNT /obj/machinery/bot/ed209/Emag(mob/user as mob) ..() - if(open && !locked) - if(user) user << "You short out [src]'s target assessment circuits." - spawn(0) - audible_message("[src] buzzes oddly!") - src.target = null - if(user) src.oldtarget_name = user.name - src.last_found = world.time - src.anchored = 0 - src.declare_arrests = 0 - src.emagged = 2 - src.on = 1 - src.icon_state = "[lasercolor]ed209[src.on]" - src.set_weapon() - mode = SECBOT_IDLE + if(emagged == 2) + if(user) + user << "You short out [src]'s target assessment circuits." + oldtarget_name = user.name + audible_message("[src] buzzes oddly!") + declare_arrests = 0 + icon_state = "[lasercolor]ed209[on]" + set_weapon() /obj/machinery/bot/ed209/process() - set background = BACKGROUND_ENABLED - - if (!src.on || src.disabled) + if (!..()) return + + if(disabled) + return + var/list/targets = list() - for (var/mob/living/carbon/C in view(9,src)) //Let's find us a target + for (var/mob/living/carbon/C in view(7,src)) //Let's find us a target var/threatlevel = 0 if ((C.stat) || (C.lying)) continue threatlevel = C.assess_threat(src, lasercolor) - //src.speak(C.real_name + text(": threat: []", threatlevel)) + //speak(C.real_name + text(": threat: []", threatlevel)) if (threatlevel < 4 ) continue var/dst = get_dist(src, C) - if ( dst <= 1 || dst > 12) + if ( dst <= 1 || dst > 7) continue targets += C if (targets.len>0) var/mob/living/carbon/t = pick(targets) if ((t.stat!=2) && (t.lying != 1) && (!t.handcuffed)) //we don't shoot people who are dead, cuffed or lying down. - src.shootAt(t) + shootAt(t) switch(mode) - if(SECBOT_IDLE) // idle + if(BOT_IDLE) // idle walk_to(src,0) - if(!src.lasercolor) //lasertag bots don't want to arrest anyone + if(!lasercolor) //lasertag bots don't want to arrest anyone look_for_perp() // see if any criminals are in range if(!mode && auto_patrol) // still idle, and set to patrol - mode = SECBOT_START_PATROL // switch to patrol mode + mode = BOT_START_PATROL // switch to patrol mode - if(SECBOT_HUNT) // hunting for perp + if(BOT_HUNT) // hunting for perp // if can't reach perp for long enough, go idle - if(src.frustration >= 8) + if (frustration >= 8) walk_to(src,0) back_to_idle() if(target) // make sure target exists - if(src.Adjacent(target) && isturf(src.target.loc)) // if right next to perp - playsound(src.loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) - src.icon_state = "[lasercolor]ed209-c" + if(Adjacent(target) && isturf(target.loc)) // if right next to perp + playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) + icon_state = "[lasercolor]ed209-c" spawn(2) - src.icon_state = "[lasercolor]ed209[src.on]" - var/mob/living/carbon/M = src.target + icon_state = "[lasercolor]ed209[on]" + var/mob/living/carbon/M = target if(istype(M, /mob/living/carbon/human)) if( M.stuttering < 5 && !(HULK in M.mutations) ) M.stuttering = 5 @@ -315,45 +266,45 @@ Auto Patrol: []"}, if(declare_arrests) var/area/location = get_area(src) - broadcast_hud_message("[src.name] is [arrest_type ? "detaining" : "arresting"] level [threatlevel] scumbag [target.name] in [location]", src) - target.visible_message("[src.target] has been stunned by [src]!",\ - "[src.target] has been stunned by [src]!") + speak("[arrest_type ? "Detaining" : "Arresting"] level [threatlevel] scumbag [target] in [location].", radio_frequency) + target.visible_message("[target] has been stunned by [src]!",\ + "[target] has been stunned by [src]!") - mode = SECBOT_PREP_ARREST - src.anchored = 1 - src.target_lastloc = M.loc + mode = BOT_PREP_ARREST + anchored = 1 + target_lastloc = M.loc return else // not next to perp - var/turf/olddist = get_dist(src, src.target) - walk_to(src, src.target,1,4) - if((get_dist(src, src.target)) >= (olddist)) - src.frustration++ + var/turf/olddist = get_dist(src, target) + walk_to(src, target,1,4) + if ((get_dist(src, target)) >= (olddist)) + frustration++ else - src.frustration = 0 + frustration = 0 else back_to_idle() - if(SECBOT_PREP_ARREST) // preparing to arrest target + if(BOT_PREP_ARREST) // preparing to arrest target // see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again. - if( !src.Adjacent(target) || !isturf(src.target.loc) || src.target.weakened < 2 ) + if( !Adjacent(target) || !isturf(target.loc) || target.weakened < 2 ) back_to_hunt() return if(iscarbon(target) && target.canBeHandcuffed()) - if(!src.arrest_type) - if(!src.target.handcuffed) //he's not cuffed? Try to cuff him! - mode = SECBOT_ARREST - playsound(src.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) - target.visible_message("[src] is trying to put handcuffs on [src.target]!",\ - "[src] is trying to put handcuffs on [src.target]!") + if(!arrest_type) + if(!target.handcuffed) //he's not cuffed? Try to cuff him! + mode = BOT_ARREST + playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) + target.visible_message("[src] is trying to put zipties on [target]!",\ + "[src] is trying to put zipties on [target]!") spawn(60) - if( !src.Adjacent(target) || !isturf(src.target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing. + if( !Adjacent(target) || !isturf(target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing. return - if(!src.target.handcuffed) - src.target.handcuffed = new /obj/item/weapon/restraints/handcuffs(src.target) + if(!target.handcuffed) + target.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(target) target.update_inv_handcuffed(0) //update the handcuffs overlay back_to_idle() else @@ -363,325 +314,78 @@ Auto Patrol: []"}, back_to_idle() return - if(SECBOT_ARREST) + if(BOT_ARREST) if (!target) - src.anchored = 0 - mode = SECBOT_IDLE - src.last_found = world.time + anchored = 0 + mode = BOT_IDLE + last_found = world.time frustration = 0 return - if(src.target.handcuffed) //no target or target cuffed? back to idle. + if(target.handcuffed) //no target or target cuffed? back to idle. back_to_idle() return - if( !src.Adjacent(target) || !isturf(src.target.loc) || (src.target.loc != src.target_lastloc && src.target.weakened < 2) ) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. + if( !Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.weakened < 2) ) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. back_to_hunt() return + else + mode = BOT_PREP_ARREST + anchored = 0 + + if(BOT_START_PATROL) + look_for_perp() + start_patrol() + + if(BOT_PATROL) + look_for_perp() + bot_patrol() - if(SECBOT_START_PATROL) // start a patrol - - if(path.len > 0 && patrol_target) // have a valid path, so just resume - mode = SECBOT_PATROL - return - - else if(patrol_target) // has patrol target already - spawn(0) - calc_path() // so just find a route to it - if(path.len == 0) - patrol_target = 0 - return - mode = SECBOT_PATROL - - - else // no patrol target, so need a new one - find_patrol_target() - speak("Engaging patrol mode.") - - - if(SECBOT_PATROL) // patrol mode - patrol_step() - spawn(5) - if(mode == SECBOT_PATROL) - patrol_step() - - if(SECBOT_SUMMON) // summoned to PDA - patrol_step() - spawn(4) - if(mode == SECBOT_SUMMON) - patrol_step() - sleep(4) - patrol_step() return /obj/machinery/bot/ed209/proc/back_to_idle() - src.anchored = 0 - mode = SECBOT_IDLE - src.target = null - src.last_found = world.time + anchored = 0 + mode = BOT_IDLE + target = null + last_found = world.time frustration = 0 spawn(0) process() //ensure bot quickly responds /obj/machinery/bot/ed209/proc/back_to_hunt() - src.anchored = 0 - src.frustration = 0 - mode = SECBOT_HUNT + anchored = 0 + frustration = 0 + mode = BOT_HUNT spawn(0) process() //ensure bot quickly responds -// perform a single patrol step -/obj/machinery/bot/ed209/proc/patrol_step() - - if(loc == patrol_target) // reached target - at_patrol_target() - return - - else if(path.len > 0 && patrol_target) // valid path - - var/turf/next = path[1] - if(next == loc) - path -= next - return - - - if(istype( next, /turf/simulated)) - - var/moved = step_towards(src, next) // attempt to move - if(moved) // successful move - blockcount = 0 - path -= loc - - if(lasercolor) - sleep(20) - else - look_for_perp() - else // failed to move - - blockcount++ - - if(blockcount > 5) // attempt 5 times before recomputing - // find new path excluding blocked turf - - spawn(2) - calc_path(next) - if(path.len == 0) - find_patrol_target() - else - blockcount = 0 - - return - - return - - else // not a valid turf - mode = SECBOT_IDLE - return - - else // no path, so calculate new one - mode = SECBOT_START_PATROL - - -// finds a new patrol target -/obj/machinery/bot/ed209/proc/find_patrol_target() - send_status() - if(awaiting_beacon) // awaiting beacon response - awaiting_beacon++ - if(awaiting_beacon > 5) // wait 5 secs for beacon response - find_nearest_beacon() // then go to nearest instead - return - - if(next_destination) - set_destination(next_destination) - else - find_nearest_beacon() - return - - -// finds the nearest beacon to self -// signals all beacons matching the patrol code -/obj/machinery/bot/ed209/proc/find_nearest_beacon() - nearest_beacon = null - new_destination = "__nearest__" - post_signal(beacon_freq, "findbeacon", "patrol") - awaiting_beacon = 1 - spawn(10) - awaiting_beacon = 0 - if(nearest_beacon) - set_destination(nearest_beacon) - else - auto_patrol = 0 - mode = SECBOT_IDLE - speak("Disengaging patrol mode.") - send_status() - - -/obj/machinery/bot/ed209/proc/at_patrol_target() - if(auto_patrol) - find_patrol_target() - else - mode = SECBOT_IDLE - return - - -// sets the current destination -// signals all beacons matching the patrol code -// beacons will return a signal giving their locations -/obj/machinery/bot/ed209/proc/set_destination(var/new_dest) - new_destination = new_dest - post_signal(beacon_freq, "findbeacon", "patrol") - awaiting_beacon = 1 - - -// receive a radio signal -// used for beacon reception - -/obj/machinery/bot/ed209/receive_signal(datum/signal/signal) - - if(!on) - return - - /* - world << "rec signal: [signal.source]" - for(var/x in signal.data) - world << "* [x] = [signal.data[x]]" - */ - - var/recv = signal.data["command"] - // process all-bot input - if(recv=="bot_status") - send_status() - - // check to see if we are the commanded bot - if(signal.data["active"] == src) - // process control input - switch(recv) - if("stop") - mode = SECBOT_IDLE - auto_patrol = 0 - return - - if("go") - mode = SECBOT_IDLE - auto_patrol = 1 - return - - if("summon") - patrol_target = signal.data["target"] - next_destination = destination - destination = null - awaiting_beacon = 0 - mode = SECBOT_SUMMON - calc_path() - speak("Responding.") - - return - - - - // receive response from beacon - recv = signal.data["beacon"] - var/valid = signal.data["patrol"] - if(!recv || !valid) - return - - if(recv == new_destination) // if the recvd beacon location matches the set destination - // the we will navigate there - destination = new_destination - patrol_target = signal.source.loc - next_destination = signal.data["next_patrol"] - awaiting_beacon = 0 - - // if looking for nearest beacon - else if(new_destination == "__nearest__") - var/dist = get_dist(src,signal.source.loc) - if(nearest_beacon) - - // note we ignore the beacon we are located at - if(dist>1 && dist 1) - nearest_beacon = recv - nearest_beacon_loc = signal.source.loc - return - - -// send a radio signal with a single data key/value pair -/obj/machinery/bot/ed209/proc/post_signal(var/freq, var/key, var/value) - post_signal_multiple(freq, list("[key]" = value) ) - -// send a radio signal with multiple data key/values -/obj/machinery/bot/ed209/proc/post_signal_multiple(var/freq, var/list/keyval) - - var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq) - - if(!frequency) return - - var/datum/signal/signal = new() - signal.source = src - signal.transmission_method = 1 - //for(var/key in keyval) - // signal.data[key] = keyval[key] - //world << "sent [key],[keyval[key]] on [freq]" - signal.data = keyval - if (signal.data["findbeacon"]) - frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS) - else if (signal.data["type"] == "secbot") - frequency.post_signal(src, signal, filter = RADIO_SECBOT) - else - frequency.post_signal(src, signal) - -// signals bot status etc. to controller -/obj/machinery/bot/ed209/proc/send_status() - var/list/kv = list( - "type" = "secbot", - "name" = name, - "loca" = loc.loc, // area - "mode" = mode, - ) - post_signal_multiple(control_freq, kv) - - - -// calculates a path to the current destination -// given an optional turf to avoid -/obj/machinery/bot/ed209/proc/calc_path(var/turf/avoid = null) - src.path = AStar(src.loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 120, id=botcard, exclude=avoid) - if(!src.path) - src.path = list() - - // look for a criminal in view of the bot /obj/machinery/bot/ed209/proc/look_for_perp() - if(src.disabled) + if(disabled) return - src.anchored = 0 - src.threatlevel = 0 - for (var/mob/living/carbon/C in view(12,src)) //Let's find us a criminal + anchored = 0 + threatlevel = 0 + for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal if ((C.stat) || (C.handcuffed)) continue - if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) + if ((C.name == oldtarget_name) && (world.time < last_found + 100)) continue - src.threatlevel = C.assess_threat(src, lasercolor) + threatlevel = C.assess_threat(src, lasercolor) - if (!src.threatlevel) + if (!threatlevel) continue - else if (src.threatlevel >= 4) - src.target = C - src.oldtarget_name = C.name - src.speak("Level [src.threatlevel] infraction alert!") - playsound(src.loc, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/EDPlaceholder.ogg'), 50, 0) - src.visible_message("[src] points at [C.name]!") - mode = SECBOT_HUNT + else if (threatlevel >= 4) + target = C + oldtarget_name = C.name + speak("Level [threatlevel] infraction alert!") + playsound(loc, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/EDPlaceholder.ogg'), 50, 0) + visible_message("[src] points at [C.name]!") + mode = BOT_HUNT spawn(0) process() // ensure bot quickly responds to a perp break @@ -695,14 +399,14 @@ Auto Patrol: []"}, return 0 /obj/machinery/bot/ed209/Bump(M as mob|obj) //Leave no door unopened! - if ((istype(M, /obj/machinery/door)) && (!isnull(src.botcard))) + if ((istype(M, /obj/machinery/door)) && (!isnull(botcard))) var/obj/machinery/door/D = M - if (!istype(D, /obj/machinery/door/firedoor) && D.check_access(src.botcard)) + if (!istype(D, /obj/machinery/door/firedoor) && D.check_access(botcard)) D.open() - src.frustration = 0 - else if ((istype(M, /mob/living/)) && (!src.anchored)) - src.loc = M:loc - src.frustration = 0 + frustration = 0 + else if ((istype(M, /mob/living/)) && (!anchored)) + loc = M:loc + frustration = 0 return /* terrible @@ -715,13 +419,13 @@ Auto Patrol: []"}, /obj/machinery/bot/ed209/explode() walk_to(src,0) - src.visible_message("[src] blows apart!") + visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) var/obj/item/weapon/ed209_assembly/Sa = new /obj/item/weapon/ed209_assembly(Tsec) Sa.build_step = 1 Sa.overlays += image('icons/obj/aibots.dmi', "hs_hole") - Sa.created_name = src.name + Sa.created_name = name new /obj/item/device/assembly/prox_sensor(Tsec) if(!lasercolor) @@ -756,12 +460,12 @@ Auto Patrol: []"}, s.set_up(3, 1, src) s.start() - new /obj/effect/decal/cleanable/oil(src.loc) + new /obj/effect/decal/cleanable/oil(loc) qdel(src) /obj/machinery/bot/ed209/proc/set_weapon() //used to update the projectile type and firing sound shoot_sound = 'sound/weapons/laser.ogg' - if(src.emagged == 2) + if(emagged == 2) if(lasercolor) projectile = /obj/item/projectile/lasertag else @@ -796,7 +500,7 @@ Auto Patrol: []"}, if (!( istype(U, /turf) )) return var/obj/item/projectile/A = new projectile (loc) - playsound(src.loc, shoot_sound, 50, 1) + playsound(loc, shoot_sound, 50, 1) A.current = U A.yo = U.y - T.y A.xo = U.x - T.x @@ -808,8 +512,8 @@ Auto Patrol: []"}, /obj/machinery/bot/ed209/attack_alien(var/mob/living/carbon/alien/user as mob) ..() if (!isalien(target)) - src.target = user - src.mode = SECBOT_HUNT + target = user + mode = BOT_HUNT /obj/machinery/bot/ed209/emp_act(severity) @@ -817,7 +521,7 @@ Auto Patrol: []"}, if(severity==2 && prob(70)) ..(severity-1) else - var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( src.loc ) + var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( loc ) pulse2.icon = 'icons/effects/effects.dmi' pulse2.icon_state = "empdisable" pulse2.name = "emp sparks" @@ -847,8 +551,8 @@ Auto Patrol: []"}, if(targets.len) var/mob/toarrest = pick(targets) if (toarrest) - src.target = toarrest - src.mode = SECBOT_HUNT + target = toarrest + mode = BOT_HUNT @@ -856,9 +560,9 @@ Auto Patrol: []"}, ..() if(istype(W, /obj/item/weapon/pen)) - var/t = copytext(stripped_input(user, "Enter new robot name", src.name, src.created_name),1,MAX_NAME_LEN) + var/t = copytext(stripped_input(user, "Enter new robot name", name, created_name),1,MAX_NAME_LEN) if(!t) return - if(!in_range(src, usr) && src.loc != usr) return + if(!in_range(src, usr) && loc != usr) return created_name = t return @@ -962,14 +666,14 @@ Auto Patrol: []"}, return build_step++ user << "You add [W] to [src]." - src.item_state = "[lasercolor]ed209_taser" - src.icon_state = "[lasercolor]ed209_taser" + item_state = "[lasercolor]ed209_taser" + icon_state = "[lasercolor]ed209_taser" user.drop_item() qdel(W) if(8) if(istype(W, /obj/item/weapon/screwdriver)) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1) + playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1) var/turf/T = get_turf(user) user << "Now attaching the gun to the frame..." sleep(40) @@ -993,18 +697,18 @@ Auto Patrol: []"}, /obj/machinery/bot/ed209/bullet_act(var/obj/item/projectile/Proj) if(!disabled) var/lasertag_check = 0 - if((src.lasercolor == "b")) + if((lasercolor == "b")) if(istype(Proj, /obj/item/projectile/lasertag/redtag)) lasertag_check++ - else if((src.lasercolor == "r")) + else if((lasercolor == "r")) if(istype(Proj, /obj/item/projectile/lasertag/bluetag)) lasertag_check++ if(lasertag_check) icon_state = "[lasercolor]ed2090" - src.disabled = 1 + disabled = 1 target = null spawn(100) - src.disabled = 0 + disabled = 0 icon_state = "[lasercolor]ed2091" return 1 else diff --git a/code/game/machinery/bots/floorbot.dm b/code/game/machinery/bots/floorbot.dm index 195c07958a6..889bd774238 100644 --- a/code/game/machinery/bots/floorbot.dm +++ b/code/game/machinery/bots/floorbot.dm @@ -36,35 +36,64 @@ maxhealth = 25 //weight = 1.0E7 var/amount = 10 - var/repairing = 0 - var/improvefloors = 0 + var/replacetiles = 0 var/eattiles = 0 var/maketiles = 0 + var/fixfloors = 0 + var/autotile = 0 + var/nag_on_empty = 1 + var/nagged = 0 //Prevents the Floorbot nagging more than once per refill. + var/max_targets = 50 var/turf/target var/turf/oldtarget var/oldloc = null - req_access = list(access_construction) - var/path[] = new() + req_one_access = list(access_construction, access_robotics) var/targetdirection - + radio_frequency = ENG_FREQ //Engineering channel + bot_type = FLOOR_BOT + bot_filter = RADIO_FLOORBOT + var/process_type //Determines what to do when process_scan() recieves a target. See process_scan() for details. + #define HULL_BREACH 1 + #define BRIDGE_MODE 2 + #define FIX_TILE 3 + #define AUTO_TILE 4 + #define REPLACE_TILE 5 + #define TILE_EMAG 6 /obj/machinery/bot/floorbot/New() ..() - src.updateicon() + updateicon() + var/datum/job/engineer/J = new/datum/job/engineer + botcard.access = J.get_access() + prev_access = botcard.access + + spawn(5) + add_to_beacons(bot_filter) /obj/machinery/bot/floorbot/turn_on() . = ..() - src.updateicon() - src.updateUsrDialog() + updateicon() + updateUsrDialog() /obj/machinery/bot/floorbot/turn_off() ..() - src.target = null - src.oldtarget = null - src.oldloc = null - src.updateicon() - src.path = new() - src.updateUsrDialog() + updateicon() + updateUsrDialog() + +/obj/machinery/bot/floorbot/bot_reset() + ..() + target = null + oldtarget = null + oldloc = null + ignore_list = list() + nagged = 0 + anchored = 0 + update_icon() + +/obj/machinery/bot/floorbot/set_custom_texts() + text_hack = "You corrupt [name]'s construction protocols." + text_dehack = "You detect errors in [name] and reset his programming." + text_dehack_fail = "[name] is not responding to reset commands!" /obj/machinery/bot/floorbot/attack_hand(mob/user as mob) . = ..() @@ -76,44 +105,50 @@ /obj/machinery/bot/floorbot/interact(mob/user as mob) var/dat dat += hack(user) - dat += "Automatic Station Floor Repairer v1.0

" - dat += "Status: [src.on ? "On" : "Off"]
" - dat += "Maintenance panel panel is [src.open ? "opened" : "closed"]
" - dat += "Tiles left: [src.amount]
" - dat += "Behvaiour controls are [src.locked ? "locked" : "unlocked"]
" - if(!src.locked || issilicon(user)) - dat += "Improves floors: [src.improvefloors ? "Yes" : "No"]
" - dat += "Finds tiles: [src.eattiles ? "Yes" : "No"]
" - dat += "Make singles pieces of metal into tiles when empty: [src.maketiles ? "Yes" : "No"]
" + dat += "Floor Repairer Controls v1.1

" + dat += "Status: [on ? "On" : "Off"]
" + dat += "Maintenance panel panel is [open ? "opened" : "closed"]
" + dat += "Tiles left: [amount]
" + dat += "Behvaiour controls are [locked ? "locked" : "unlocked"]
" + if(!locked || issilicon(user)) + dat += "Add tiles to new hull plating: [autotile ? "Yes" : "No"]
" + dat += "Replace floor tiles: [replacetiles ? "Yes" : "No"]
" + dat += "Finds tiles: [eattiles ? "Yes" : "No"]
" + dat += "Make pieces of metal into tiles when empty: [maketiles ? "Yes" : "No"]
" + dat += "Transmit notice when empty: [nag_on_empty ? "Yes" : "No"]
" + dat += "Repair damaged tiles and platings: [fixfloors ? "Yes" : "No"]
" + dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
" var/bmode - if (src.targetdirection) - bmode = dir2text(src.targetdirection) + if (targetdirection) + bmode = dir2text(targetdirection) else - bmode = "Disabled" - dat += "

Bridge Mode : [bmode]
" + bmode = "disabled" + dat += "Bridge Mode : [bmode]
" - user << browse("Repairbot v1.0 controls[dat]", "window=autorepair") - onclose(user, "autorepair") + var/datum/browser/popup = new(user, "autofloor", "Automatic Station Floor Repairer v1.1") + popup.set_content(dat) + popup.open() return /obj/machinery/bot/floorbot/attackby(var/obj/item/W , mob/user as mob) if(istype(W, /obj/item/stack/tile/plasteel)) var/obj/item/stack/tile/plasteel/T = W - if(src.amount >= 50) + if(amount >= 50) return - var/loaded = min(50 - src.amount, T.get_amount()) + var/loaded = min(50-amount, T.amount) T.use(loaded) - src.amount += loaded + amount += loaded if (loaded > 0) - user << "You load [loaded] tiles into the floorbot. He now contains [src.amount] tiles." - src.updateicon() + user << "You load [loaded] tiles into the floorbot. He now contains [amount] tiles." + nagged = 0 + updateicon() else - user << "You need at least one floor tile to put into the floorbot." + user << "You need at least one floor tile to put into [src]" else if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) - if(src.allowed(usr) && !open && !emagged) - src.locked = !src.locked - user << "You [src.locked ? "lock" : "unlock"] the [src] behaviour controls." + if(allowed(user) && !open && !emagged) + locked = !locked + user << "You [locked ? "lock" : "unlock"] \the [src] behaviour controls." else if(emagged) user << "ERROR" @@ -121,265 +156,297 @@ user << "Please close the access panel before locking it." else user << "Access denied." - src.updateUsrDialog() + updateUsrDialog() else ..() /obj/machinery/bot/floorbot/Emag(mob/user as mob) ..() - if(open && !locked) - if(user) user << "The [src] buzzes and beeps." + if(emagged == 2) + if(user) + user << "[src] buzzes and beeps." /obj/machinery/bot/floorbot/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - src.add_fingerprint(usr) + ..() switch(href_list["operation"]) - if("start") - if (src.on && !src.emagged) - turn_off() - else - turn_on() - if("improve") - src.improvefloors = !src.improvefloors - src.updateUsrDialog() + if("replace") + replacetiles = !replacetiles if("tiles") - src.eattiles = !src.eattiles - src.updateUsrDialog() + eattiles = !eattiles if("make") - src.maketiles = !src.maketiles - src.updateUsrDialog() - if("hack") - if(!src.emagged) - src.emagged = 2 - src.hacked = 1 - usr << "You corrupt [src]'s construction protocols." - else if(!src.hacked) - usr << "[src] is not responding to reset commands!" - else - src.emagged = 0 - src.hacked = 0 - usr << "You detect errors in [src] and reset its programming." - src.updateUsrDialog() + maketiles = !maketiles + if("fix") + fixfloors = !fixfloors + if("autotile") + autotile = !autotile + if("emptynag") + nag_on_empty = !nag_on_empty + if("bridgemode") - switch(src.targetdirection) - if(null) + var/setdir = input("Select construction direction:") as null|anything in list("north","east","south","west","disable") + switch(setdir) + if("north") targetdirection = 1 - if(1) + if("south") targetdirection = 2 - if(2) + if("east") targetdirection = 4 - if(4) + if("west") targetdirection = 8 - if(8) + if("disable") targetdirection = null - else - targetdirection = null - src.updateUsrDialog() + updateUsrDialog() /obj/machinery/bot/floorbot/process() - set background = BACKGROUND_ENABLED + if (!..()) + return - if(!src.on) + if(mode == BOT_REPAIRING) return - if(src.repairing) - return - var/list/floorbottargets = list() - if(src.amount <= 0 && ((src.target == null) || !src.target)) - if(src.eattiles) - for(var/obj/item/stack/tile/plasteel/T in view(7, src)) - if(T != src.oldtarget && !(target in floorbottargets)) - src.oldtarget = T - src.target = T - break - if(src.target == null || !src.target) - if(src.maketiles) - if(src.target == null || !src.target) - for(var/obj/item/stack/sheet/metal/M in view(7, src)) - if(!(M in floorbottargets) && M != src.oldtarget && M.amount == 1 && !(istype(M.loc, /turf/simulated/wall))) - src.oldtarget = M - src.target = M - break - else + + if(amount <= 0 && !target) //Out of tiles! We must refill! + if(eattiles) //Configured to find and consume floortiles! + target = scan(/obj/item/stack/tile/plasteel, oldtarget) + process_type = null + + if(!target && maketiles) //We did not manage to find any floor tiles! Scan for metal stacks and make our own! + target = scan(/obj/item/stack/sheet/metal, oldtarget) + process_type = null return + else + if(nag_on_empty) //Floorbot is empty and cannot acquire more tiles, nag the engineers for more! + nag() + if(prob(5)) visible_message("[src] makes an excited booping beeping sound!") - if((!src.target || src.target == null) && emagged < 2) - if(targetdirection != null) - /* - for (var/turf/space/D in view(7,src)) - if(!(D in floorbottargets) && D != src.oldtarget) // Added for bridging mode - if(get_dir(src, D) == targetdirection) - src.oldtarget = D - src.target = D - break - */ + //Normal scanning procedure. We have tiles loaded, are not emagged. + if(!target && emagged < 2 && amount > 0) + if(targetdirection != null) //The bot is in bridge mode. + //Try to find a space tile immediately in our selected direction. var/turf/T = get_step(src, targetdirection) if(istype(T, /turf/space)) - src.oldtarget = T - src.target = T - if(!src.target || src.target == null) - for (var/turf/space/D in view(7,src)) - if(!(D in floorbottargets) && D != src.oldtarget && (D.loc.name != "Space")) - src.oldtarget = D - src.target = D - break - if((!src.target || src.target == null ) && src.improvefloors) - for (var/turf/simulated/floor/F in view(7,src)) - if(!(F in floorbottargets) && F != src.oldtarget && F.icon_state == "Floor1" && !(istype(F, /turf/simulated/floor/plating))) - src.oldtarget = F - src.target = F - break - if((!src.target || src.target == null) && src.eattiles) - for(var/obj/item/stack/tile/plasteel/T in view(7, src)) - if(!(T in floorbottargets) && T != src.oldtarget) - src.oldtarget = T - src.target = T - break + target = T - if((!src.target || src.target == null) && emagged == 2) - if(!src.target || src.target == null) - for (var/turf/simulated/floor/D in view(7,src)) - if(!(D in floorbottargets) && D != src.oldtarget && D.floor_tile) - src.oldtarget = D - src.target = D - break - - if(!src.target || src.target == null) - if(src.loc != src.oldloc) - src.oldtarget = null - return - - if(src.target && (src.target != null) && src.path.len == 0) - spawn(0) - if(!istype(src.target, /turf/)) - var/turf/TL = get_turf(target) - src.path = AStar(src.loc, TL, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30) - else - src.path = AStar(src.loc, src.target, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30) - if(!src.path) - src.path = list() - if(src.path.len == 0) - src.oldtarget = src.target - src.target = null - return - if(src.path.len > 0 && src.target && (src.target != null)) - step_to(src, src.path[1]) - src.path -= src.path[1] - else if(src.path.len == 1) - step_to(src, target) - src.path = new() - - if(src.loc == src.target || src.loc == src.target.loc) - if(istype(src.target, /obj/item/stack/tile/plasteel)) - src.eattile(src.target) - else if(istype(src.target, /obj/item/stack/sheet/metal)) - src.maketile(src.target) - else if(istype(src.target, /turf/) && emagged < 2) - repair(src.target) - else if(emagged == 2 && istype(src.target,/turf/simulated/floor)) - var/turf/simulated/floor/F = src.target - src.anchored = 1 - src.repairing = 1 - if(prob(90)) - F.break_tile_to_plating() - else - F.ReplaceWithLattice() - visible_message("[src] makes an excited booping sound.") - spawn(50) - src.amount ++ - src.anchored = 0 - src.repairing = 0 - src.target = null - src.path = new() - return - - src.oldloc = src.loc - - -/obj/machinery/bot/floorbot/proc/repair(var/turf/target) - if(istype(target, /turf/space/)) - if(target.loc.name == "Space") + else //Find a space tile farther way! + target = scan(/turf/space, oldtarget) + anchored = 1 + process_type = BRIDGE_MODE return - else if(!istype(target, /turf/simulated/floor)) + + if(!target) + process_type = HULL_BREACH //Ensures the floorbot does not try to "fix" space areas or shuttle docking zones. + target = scan(/turf/space, oldtarget) + anchored = 1 //Prevent the floorbot being blown off-course while trying to reach a hull breach. + return + + if(!target && replacetiles) //Finds a floor without a tile and gives it one. + process_type = REPLACE_TILE //The target must be the floor and not a tile. The floor must not already have a floortile. + //target = scan(/turf/simulated/floor, oldtarget) + return + + if(!target && fixfloors) //Repairs damaged floors and tiles. + process_type = FIX_TILE + target = scan(/turf/simulated/floor, oldtarget) + return + + if(!target && emagged == 2) //We are emagged! Time to rip up the floors! + process_type = TILE_EMAG + target = scan(/turf/simulated/floor, oldtarget) return - if(src.amount <= 0) + + + if(!target) + + if(auto_patrol) + if(mode == BOT_IDLE || mode == BOT_START_PATROL) + start_patrol() + + if(mode == BOT_PATROL) + bot_patrol() + + if(!target) + if(loc != oldloc) + oldtarget = null return - src.anchored = 1 - src.icon_state = "floorbot-c" - if(istype(target, /turf/space/)) - visible_message("[src] begins to repair the hole.") - var/obj/item/stack/tile/plasteel/T = new /obj/item/stack/tile/plasteel - src.repairing = 1 - spawn(50) - T.build(src.loc) - src.repairing = 0 - src.amount -= 1 - src.updateicon() - src.anchored = 0 - src.target = null + + if(target) + if(path.len == 0) + if(!istype(target, /turf/)) + var/turf/TL = get_turf(target) + path = AStar(loc, TL, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30, id=botcard) + else + path = AStar(loc, target, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30, id=botcard) + + if(!bot_move(target)) + add_to_ignore(target) + oldtarget = target + target = null + mode = BOT_IDLE + return + else if( !bot_move(target) ) + oldtarget = target + target = null + mode = BOT_IDLE + return + + if(loc == target || loc == target.loc) + if(istype(target, /obj/item/stack/tile/plasteel)) + eattile(target) + else if(istype(target, /obj/item/stack/sheet/metal)) + maketile(target) + else if(istype(target, /turf/) && emagged < 2) + repair(target) + else if(emagged == 2 && istype(target,/turf/simulated/floor)) + var/turf/simulated/floor/F = target + anchored = 1 + mode = BOT_REPAIRING + if(prob(90)) + F.break_tile_to_plating() + else + F.ReplaceWithLattice() + visible_message("[src] makes an excited booping sound.") + spawn(50) + amount ++ + anchored = 0 + mode = BOT_IDLE + target = null + path = new() + return + + oldloc = loc + +/obj/machinery/bot/floorbot/proc/nag() //Annoy everyone on the channel to refill us! + if(!nagged) + speak("Requesting refill at [get_area(src)]!", radio_frequency) + nagged = 1 + +/obj/machinery/bot/floorbot/proc/is_hull_breach(var/turf/t) //Ignore space tiles not considered part of a structure, also ignores shuttle docking areas. + var/area/t_area = get_area(t) + if (t_area && (t_area.name == "Space" || findtext(t_area.name, "huttle"))) + return 0 else - visible_message("[src] begins to improve the floor.") - src.repairing = 1 + return 1 + +//Floorbots, having several functions, need sort out special conditions here. +obj/machinery/bot/floorbot/process_scan(var/scan_target) + var/result + var/turf/simulated/floor/F + switch(process_type) + if(HULL_BREACH) //The most common job, patching breaches in the station's hull. + if(is_hull_breach(scan_target)) //Ensure that the targeted space turf is actually part of the station, and not random space. + result = scan_target + if(BRIDGE_MODE) //Only space turfs in our chosen direction are considered. + if(get_dir(src, scan_target) == targetdirection) + result = scan_target + if(REPLACE_TILE) + F = scan_target + if(istype(F, /turf/simulated/floor/plating)) //The floor must not already have a tile. + result = F + if(FIX_TILE) //Selects only damaged floors. + F = scan_target + if(F.broken || F.burnt) + result = F + if(TILE_EMAG) //Emag mode! Rip up the floor and cause breaches to space! + F = scan_target + if(!istype(F, /turf/simulated/floor/plating)) + result = F + else //If no special processing is needed, simply return the result. + result = scan_target + return result + +/obj/machinery/bot/floorbot/proc/repair(var/turf/target_turf) + + if(istype(target_turf, /turf/space/)) + //Must be a hull breach or in bridge mode to continue. + if(!is_hull_breach(target_turf) && !targetdirection) + target = null + return + else if(!istype(target_turf, /turf/simulated/floor)) + return + if(amount <= 0) + mode = BOT_IDLE + target = null + return + anchored = 1 + icon_state = "floorbot-c" + if(istype(target_turf, /turf/space/)) //If we are fixing an area not part of pure space, it is + visible_message(" [targetdirection ? "[src] begins installing a bridge plating." : "[src] begins to repair the hole."] ") + mode = BOT_REPAIRING spawn(50) - src.loc.icon_state = "floor" - src.repairing = 0 - src.amount -= 1 - src.updateicon() - src.anchored = 0 - src.target = null + if(mode == BOT_REPAIRING) + if(autotile) //Build the floor and include a tile. + target_turf.ChangeTurf(/turf/simulated/floor) + else //Build a hull plating without a floor tile. + target_turf.ChangeTurf(/turf/simulated/floor/plating) + mode = BOT_IDLE + amount -= 1 + updateicon() + anchored = 0 + target = null + else + var/turf/simulated/floor/F = target_turf + mode = BOT_REPAIRING + visible_message(" [src] begins repairing the floor.") + spawn(50) + if(mode == BOT_REPAIRING) + F.make_floor(/turf/simulated/floor) + mode = BOT_IDLE + amount -= 1 + updateicon() + anchored = 0 + target = null /obj/machinery/bot/floorbot/proc/eattile(var/obj/item/stack/tile/plasteel/T) if(!istype(T, /obj/item/stack/tile/plasteel)) return - visible_message("[src] begins to collect tiles.") - src.repairing = 1 + visible_message(" [src] begins to collect tiles.") + mode = BOT_REPAIRING spawn(20) if(isnull(T)) - src.target = null - src.repairing = 0 + target = null + mode = BOT_IDLE return - if(src.amount + T.amount > 50) - var/i = 50 - src.amount - src.amount += i + if(amount + T.amount > 50) + var/i = 50 - amount + amount += i T.amount -= i else - src.amount += T.amount + amount += T.amount qdel(T) - src.updateicon() - src.target = null - src.repairing = 0 + updateicon() + target = null + mode = BOT_IDLE /obj/machinery/bot/floorbot/proc/maketile(var/obj/item/stack/sheet/metal/M) if(!istype(M, /obj/item/stack/sheet/metal)) return - if(M.amount > 1) - return - visible_message("[src] begins to create tiles.") - src.repairing = 1 + visible_message(" [src] begins to create tiles.") + mode = BOT_REPAIRING spawn(20) if(isnull(M)) - src.target = null - src.repairing = 0 + target = null + mode = BOT_IDLE return var/obj/item/stack/tile/plasteel/T = new /obj/item/stack/tile/plasteel T.amount = 4 T.loc = M.loc - qdel(M) - src.target = null - src.repairing = 0 + if(M.amount > 1) + M.amount-- + else + qdel(M) + target = null + mode = BOT_IDLE /obj/machinery/bot/floorbot/proc/updateicon() - if(src.amount > 0) - src.icon_state = "floorbot[src.on]" + if(amount > 0) + icon_state = "floorbot[on]" else - src.icon_state = "floorbot[src.on]e" + icon_state = "floorbot[on]e" /obj/machinery/bot/floorbot/explode() - src.on = 0 - src.visible_message("[src] blows apart!") + on = 0 + visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) var/obj/item/weapon/storage/toolbox/mechanical/N = new /obj/item/weapon/storage/toolbox/mechanical(Tsec) @@ -397,7 +464,7 @@ amount -= 16 else var/obj/item/stack/tile/plasteel/T = new (Tsec) - T.amount = src.amount + T.amount = amount amount = 0 var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread @@ -411,7 +478,7 @@ if(!istype(T, /obj/item/stack/tile/plasteel)) ..() return - if(src.contents.len >= 1) + if(contents.len >= 1) user << "They won't fit in, as there is already stuff inside." return if(T.use(10)) @@ -431,20 +498,20 @@ if(isprox(W)) qdel(W) var/obj/item/weapon/toolbox_tiles_sensor/B = new /obj/item/weapon/toolbox_tiles_sensor() - B.created_name = src.created_name + B.created_name = created_name user.put_in_hands(B) user << "You add the sensor to the toolbox and tiles!" user.unEquip(src, 1) qdel(src) else if (istype(W, /obj/item/weapon/pen)) - var/t = copytext(stripped_input(user, "Enter new robot name", src.name, src.created_name),1,MAX_NAME_LEN) + var/t = copytext(stripped_input(user, "Enter new robot name", name, created_name),1,MAX_NAME_LEN) if (!t) return - if (!in_range(src, usr) && src.loc != usr) + if (!in_range(src, usr) && loc != usr) return - src.created_name = t + created_name = t /obj/item/weapon/toolbox_tiles_sensor/attackby(var/obj/item/W, mob/user as mob) ..() @@ -452,16 +519,16 @@ qdel(W) var/turf/T = get_turf(user.loc) var/obj/machinery/bot/floorbot/A = new /obj/machinery/bot/floorbot(T) - A.name = src.created_name + A.name = created_name user << "You add the robot arm to the odd looking toolbox assembly! Boop beep!" user.unEquip(src, 1) qdel(src) else if (istype(W, /obj/item/weapon/pen)) - var/t = stripped_input(user, "Enter new robot name", src.name, src.created_name) + var/t = stripped_input(user, "Enter new robot name", name, created_name) if (!t) return - if (!in_range(src, usr) && src.loc != usr) + if (!in_range(src, usr) && loc != usr) return - src.created_name = t \ No newline at end of file + created_name = t \ No newline at end of file diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm index 6642dcbbe41..7fe74099a1a 100644 --- a/code/game/machinery/bots/medbot.dm +++ b/code/game/machinery/bots/medbot.dm @@ -13,31 +13,34 @@ anchored = 0 health = 20 maxhealth = 20 - req_access =list(access_medical) + req_one_access =list(access_medical, access_robotics) var/stunned = 0 //It can be stunned by tasers. Delicate circuits. // var/emagged = 0 var/list/botcard_access = list(access_medical) var/obj/item/weapon/reagent_containers/glass/reagent_glass = null //Can be set to draw from this for reagents. var/skin = null //Set to "tox", "ointment" or "o2" for the other two firstaid kits. - var/frustration = 0 - var/path[] = new() var/mob/living/carbon/patient = null var/mob/living/carbon/oldpatient = null var/oldloc = null var/last_found = 0 var/last_newpatient_speak = 0 //Don't spam the "HEY I'M COMING" messages - var/currently_healing = 0 var/injection_amount = 15 //How much reagent do we inject at a time? var/heal_threshold = 10 //Start healing when they have this much damage in a category var/use_beaker = 0 //Use reagents in beaker instead of default treatment agents. - + var/declare_crit = 1 //If active, the bot will transmit a critical patient alert to MedHUD users. + var/declare_cooldown = 0 //Prevents spam of critical patient alerts. + var/stationary_mode = 0 //If enabled, the Medibot will not move automatically. + radio_frequency = MED_FREQ //Medical frequency //Setting which reagents to use to treat what by default. By id. var/treatment_brute = "tricordrazine" var/treatment_oxy = "tricordrazine" var/treatment_fire = "tricordrazine" var/treatment_tox = "tricordrazine" var/treatment_virus = "spaceacillin" + var/treat_virus = 1 //If on, the bot will attempt to treat viral infections, curing them if possible. var/shut_up = 0 //self explanatory :) + bot_type = MED_BOT + bot_filter = RADIO_MEDBOT /obj/machinery/bot/medbot/mysterious name = "\improper Mysterious Medibot" @@ -58,43 +61,63 @@ var/skin = null //Same as medbot, set to tox or ointment for the respective kits. w_class = 3.0 - New() + /obj/item/weapon/firstaid_arm_assembly/New() ..() spawn(5) - if(src.skin) - src.overlays += image('icons/obj/aibots.dmi', "kit_skin_[src.skin]") + if(skin) + overlays += image('icons/obj/aibots.dmi', "kit_skin_[skin]") +/obj/machinery/bot/medbot/proc/updateicon() + if(!on) + icon_state = "medibot0" + return + if(mode == BOT_HEALING) + icon_state = "medibots[stationary_mode]" + return + else if(stationary_mode) //Bot has yellow light to indicate stationary mode. + icon_state = "medibot2" + else + icon_state = "medibot1" /obj/machinery/bot/medbot/New() ..() - src.icon_state = "medibot[src.on]" + updateicon() spawn(4) - if(src.skin) - src.overlays += image('icons/obj/aibots.dmi', "medskin_[src.skin]") + if(skin) + overlays += image('icons/obj/aibots.dmi', "medskin_[skin]") - src.botcard = new /obj/item/weapon/card/id(src) - if(isnull(src.botcard_access) || (src.botcard_access.len < 1)) + if(isnull(botcard_access) || (botcard_access.len < 1)) var/datum/job/doctor/J = new/datum/job/doctor - src.botcard.access = J.get_access() + botcard.access = J.get_access() else - src.botcard.access = src.botcard_access + botcard.access = botcard_access + prev_access = botcard.access + add_to_beacons(bot_filter) /obj/machinery/bot/medbot/turn_on() . = ..() - src.icon_state = "medibot[src.on]" - src.updateUsrDialog() + updateicon() + updateUsrDialog() /obj/machinery/bot/medbot/turn_off() ..() - src.patient = null - src.oldpatient = null - src.oldloc = null - src.path = new() - src.currently_healing = 0 - src.last_found = world.time - src.icon_state = "medibot[src.on]" - src.updateUsrDialog() + updateicon() + updateUsrDialog() + +/obj/machinery/bot/medbot/bot_reset() + ..() + patient = null + oldpatient = null + oldloc = null + last_found = world.time + declare_cooldown = 0 + +/obj/machinery/bot/medbot/set_custom_texts() + + text_hack = "You corrupt [name]'s reagent processor circuits." + text_dehack = "You reset [name]'s reagent processor circuits." + text_dehack_fail = "[name] seems damaged and does not respond to reprogramming!" /obj/machinery/bot/medbot/attack_paw(mob/user as mob) return attack_hand(user) @@ -105,99 +128,93 @@ return var/dat dat += hack(user) - dat += "Automatic Medical Unit v1.0

" - dat += "Status: [src.on ? "On" : "Off"]
" - dat += "Maintenance panel panel is [src.open ? "opened" : "closed"]
" + dat += "Medical Unit Controls v1.1

" + dat += "Status: [on ? "On" : "Off"]
" + dat += "Maintenance panel panel is [open ? "opened" : "closed"]
" dat += "Beaker: " - if (src.reagent_glass) - dat += "Loaded \[[src.reagent_glass.reagents.total_volume]/[src.reagent_glass.reagents.maximum_volume]\]" + if (reagent_glass) + dat += "Loaded \[[reagent_glass.reagents.total_volume]/[reagent_glass.reagents.maximum_volume]\]" else dat += "None Loaded" - dat += "
Behaviour controls are [src.locked ? "locked" : "unlocked"]
" - if(!src.locked || issilicon(user)) + dat += "
Behaviour controls are [locked ? "locked" : "unlocked"]
" + if(!locked || issilicon(user)) dat += "Healing Threshold: " dat += "-- " dat += "- " - dat += "[src.heal_threshold] " + dat += "[heal_threshold] " dat += "+ " dat += "++" dat += "
" dat += "Injection Level: " dat += "- " - dat += "[src.injection_amount] " + dat += "[injection_amount] " dat += "+ " dat += "
" dat += "Reagent Source: " - dat += "[src.use_beaker ? "Loaded Beaker (When available)" : "Internal Synthesizer"]
" + dat += "[use_beaker ? "Loaded Beaker (When available)" : "Internal Synthesizer"]
" - dat += "The speaker switch is [src.shut_up ? "off" : "on"]. Toggle" + dat += "Treat Viral Infections: [treat_virus ? "Yes" : "No"]
" + dat += "The speaker switch is [shut_up ? "off" : "on"]. Toggle
" + dat += "Critical Patient Alerts: [declare_crit ? "Yes" : "No"]
" + dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
" + dat += "Stationary Mode: [stationary_mode ? "Yes" : "No"]
" - user << browse("Medibot v1.0 controls[dat]", "window=automed") - onclose(user, "automed") + var/datum/browser/popup = new(user, "automed", "Automatic Medical Unit v1.1") + popup.set_content(dat) + popup.open() return /obj/machinery/bot/medbot/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - src.add_fingerprint(usr) - if ((href_list["power"]) && (src.allowed(usr))) - if (src.on && !src.emagged) - turn_off() - else - turn_on() + ..() - else if((href_list["adj_threshold"]) && (!src.locked || issilicon(usr))) + if(href_list["adj_threshold"]) var/adjust_num = text2num(href_list["adj_threshold"]) - src.heal_threshold += adjust_num - if(src.heal_threshold < 5) - src.heal_threshold = 5 - if(src.heal_threshold > 75) - src.heal_threshold = 75 + heal_threshold += adjust_num + if(heal_threshold < 5) + heal_threshold = 5 + if(heal_threshold > 75) + heal_threshold = 75 - else if((href_list["adj_inject"]) && (!src.locked || issilicon(usr))) + else if(href_list["adj_inject"]) var/adjust_num = text2num(href_list["adj_inject"]) - src.injection_amount += adjust_num - if(src.injection_amount < 5) - src.injection_amount = 5 - if(src.injection_amount > 15) - src.injection_amount = 15 + injection_amount += adjust_num + if(injection_amount < 5) + injection_amount = 5 + if(injection_amount > 15) + injection_amount = 15 - else if((href_list["use_beaker"]) && (!src.locked || issilicon(usr))) - src.use_beaker = !src.use_beaker + else if(href_list["use_beaker"]) + use_beaker = !use_beaker - else if (href_list["eject"] && (!isnull(src.reagent_glass))) - if(!src.locked) - src.reagent_glass.loc = get_turf(src) - src.reagent_glass = null - else - usr << "You cannot eject the beaker because the panel is locked." + else if (href_list["eject"] && (!isnull(reagent_glass))) + reagent_glass.loc = get_turf(src) + reagent_glass = null - else if ((href_list["togglevoice"]) && (!src.locked || issilicon(usr))) - src.shut_up = !src.shut_up + else if (href_list["togglevoice"]) + shut_up = !shut_up - else if (href_list["operation"]) - if(!src.emagged) - src.emagged = 2 - src.hacked = 1 - usr << "You corrupt [src]'s reagent processor circuits." - else if(!src.hacked) - usr << "[src] seems damaged and does not respond to reprogramming!" - else - src.hacked = 0 - src.emagged = 0 - usr << "You reset [src]'s reagent circuits." - src.updateUsrDialog() + else if (href_list["critalerts"]) + declare_crit = !declare_crit + + else if (href_list["stationary"]) + stationary_mode = !stationary_mode + path = list() + updateicon() + + else if (href_list["virus"]) + treat_virus = !treat_virus + + updateUsrDialog() return /obj/machinery/bot/medbot/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) - if (src.allowed(user) && !open && !emagged) - src.locked = !src.locked - user << "Controls are now [src.locked ? "locked." : "unlocked."]" - src.updateUsrDialog() + if (allowed(user) && !open && !emagged) + locked = !locked + user << "Controls are now [locked ? "locked." : "unlocked."]" + updateUsrDialog() else if(emagged) user << "ERROR" @@ -207,18 +224,18 @@ user << "Access denied." else if (istype(W, /obj/item/weapon/reagent_containers/glass)) - if(src.locked) + if(locked) user << "You cannot insert a beaker because the panel is locked." return - if(!isnull(src.reagent_glass)) + if(!isnull(reagent_glass)) user << "There is already a beaker loaded." return user.drop_item() W.loc = src - src.reagent_glass = W + reagent_glass = W user << "You insert [W]." - src.updateUsrDialog() + updateUsrDialog() return else @@ -229,106 +246,105 @@ /obj/machinery/bot/medbot/Emag(mob/user as mob) ..() - if(open && !locked) - if(user) user << "You short out [src]'s reagent synthesis circuits." + if(emagged == 2) + declare_crit = 0 + if(user) + user << "You short out [src]'s reagent synthesis circuits." spawn(0) audible_message("[src] buzzes oddly!") flick("medibot_spark", src) - src.patient = null - if(user) src.oldpatient = user - src.currently_healing = 0 - src.last_found = world.time - src.anchored = 0 - src.emagged = 2 - src.on = 1 - src.icon_state = "medibot[src.on]" + if(user) + oldpatient = user + +/obj/machinery/bot/medbot/process_scan(var/mob/living/carbon/human/H) + if (H.stat == 2) + return + + if ((H == oldpatient) && (world.time < last_found + 100)) + return + + if(assess_patient(H)) + last_found = world.time + if((last_newpatient_speak + 300) < world.time) //Don't spam these messages! + var/message = pick("Hey, [H.name]! Hold on, I'm coming.","Wait [H.name]! I want to help!","[H.name], you appear to be injured!") + speak(message) + last_newpatient_speak = world.time + return H + else + return /obj/machinery/bot/medbot/process() - set background = BACKGROUND_ENABLED - - if(!src.on) - src.stunned = 0 + if (!..()) return - if(src.stunned) - src.icon_state = "medibota" - src.stunned-- - - src.oldpatient = src.patient - src.patient = null - src.currently_healing = 0 - - if(src.stunned <= 0) - src.icon_state = "medibot[src.on]" - src.stunned = 0 + if(mode == BOT_HEALING) return - if(src.frustration > 8) - src.oldpatient = src.patient - src.patient = null - src.currently_healing = 0 - src.last_found = world.time - src.path = new() + if(stunned) + icon_state = "medibota" + stunned-- - if(!src.patient) - if(!src.shut_up && prob(1)) + oldpatient = patient + patient = null + mode = BOT_IDLE + + if(stunned <= 0) + updateicon() + stunned = 0 + return + + if(frustration > 8) + oldpatient = patient + patient = null + mode = BOT_IDLE + last_found = world.time + path = list() + + if(!patient) + if(!shut_up && prob(1)) var/message = pick("Radar, put a mask on!","There's always a catch, and it's the best there is.","I knew it, I should've been a plastic surgeon.","What kind of medbay is this? Everyone's dropping like dead flies.","Delicious!") - src.speak(message) + speak(message) + var/scan_range = (stationary_mode ? 1 : DEFAULT_SCAN_RANGE) //If in stationary mode, scan range is limited to adjacent patients. + patient = scan(/mob/living/carbon/human, oldpatient, scan_range) + oldpatient = patient - for (var/mob/living/carbon/C in view(7,src)) //Time to find a patient! - if ((C.stat == 2) || !istype(C, /mob/living/carbon/human)) - continue - - if ((C == src.oldpatient) && (world.time < src.last_found + 100)) - continue - - if(src.assess_patient(C)) - src.patient = C - src.oldpatient = C - src.last_found = world.time - if((src.last_newpatient_speak + 300) < world.time) //Don't spam these messages! - var/message = pick("Hey, [C.name]! Hold on, I'm coming.","Wait [C.name]! I want to help!","[C.name], you appear to be injured!") - src.speak(message) - src.last_newpatient_speak = world.time - break - else - continue - - - if(src.patient && (get_dist(src,src.patient) <= 1)) - if(!src.currently_healing) - src.currently_healing = 1 - src.frustration = 0 - src.medicate_patient(src.patient) + if(patient && (get_dist(src,patient) <= 1)) //Patient is next to us, begin treatment! + if(mode != BOT_HEALING) + mode = BOT_HEALING + updateicon() + frustration = 0 + medicate_patient(patient) return - else if(src.patient && (src.path.len) && (get_dist(src.patient,src.path[src.path.len]) > 2)) - src.path = new() - src.currently_healing = 0 - src.last_found = world.time + //Patient has moved away from us! + else if(patient && path && path.len && (get_dist(patient,path[path.len]) > 2)) + path = list() + mode = BOT_IDLE + last_found = world.time - if(src.patient && src.path.len == 0 && (get_dist(src,src.patient) > 1)) + if(!stationary_mode && patient && path.len == 0 && (get_dist(src,patient) > 1)) spawn(0) - src.path = AStar(src.loc, get_turf(src.patient), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 30,id=botcard) - if(!src.path) - src.path = list() - if(src.path.len == 0) - src.oldpatient = src.patient - src.patient = null - src.currently_healing = 0 - src.last_found = world.time + path = AStar(loc, get_turf(patient), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 30,id=botcard) + if(!path) + path = list() + + if(path.len > 0 && patient) + if(!bot_move(patient)) + oldpatient = patient + patient = null + mode = BOT_IDLE + last_found = world.time return - if(src.path.len > 0 && src.patient) - step_to(src, src.path[1]) - src.path -= src.path[1] - spawn(3) - if(src.path.len) - step_to(src, src.path[1]) - src.path -= src.path[1] + if(path.len > 8 && patient) + frustration++ - if(src.path.len > 8 && src.patient) - src.frustration++ + if(auto_patrol && !stationary_mode && !patient) + if(mode == BOT_IDLE || mode == BOT_START_PATROL) + start_patrol() + + if(mode == BOT_PATROL) + bot_patrol() return @@ -340,127 +356,131 @@ if(C.suiciding) return 0 //Kevorkian school of robotic medical assistants. - if(src.emagged == 2) //Everyone needs our medicine. (Our medicine is toxins) + if(emagged == 2) //Everyone needs our medicine. (Our medicine is toxins) return 1 + if(declare_crit && C.health <= 0) //Critical condition! Call for help! + declare(C) + //If they're injured, we're using a beaker, and don't have one of our WONDERCHEMS. - if((src.reagent_glass) && (src.use_beaker) && ((C.getBruteLoss() >= heal_threshold) || (C.getToxLoss() >= heal_threshold) || (C.getToxLoss() >= heal_threshold) || (C.getOxyLoss() >= (heal_threshold + 15)))) - for(var/datum/reagent/R in src.reagent_glass.reagents.reagent_list) + if((reagent_glass) && (use_beaker) && ((C.getBruteLoss() >= heal_threshold) || (C.getToxLoss() >= heal_threshold) || (C.getToxLoss() >= heal_threshold) || (C.getOxyLoss() >= (heal_threshold + 15)))) + for(var/datum/reagent/R in reagent_glass.reagents.reagent_list) if(!C.reagents.has_reagent(R.id)) return 1 //They're injured enough for it! - if((C.getBruteLoss() >= heal_threshold) && (!C.reagents.has_reagent(src.treatment_brute))) + if((C.getBruteLoss() >= heal_threshold) && (!C.reagents.has_reagent(treatment_brute))) return 1 //If they're already medicated don't bother! - if((C.getOxyLoss() >= (15 + heal_threshold)) && (!C.reagents.has_reagent(src.treatment_oxy))) + if((C.getOxyLoss() >= (15 + heal_threshold)) && (!C.reagents.has_reagent(treatment_oxy))) return 1 - if((C.getFireLoss() >= heal_threshold) && (!C.reagents.has_reagent(src.treatment_fire))) + if((C.getFireLoss() >= heal_threshold) && (!C.reagents.has_reagent(treatment_fire))) return 1 - if((C.getToxLoss() >= heal_threshold) && (!C.reagents.has_reagent(src.treatment_tox))) + if((C.getToxLoss() >= heal_threshold) && (!C.reagents.has_reagent(treatment_tox))) return 1 + if(treat_virus) + for(var/datum/disease/D in C.viruses) + if((D.hidden[SCANNER]) || (D.hidden[PANDEMIC])) //the medibot can't detect viruses that are undetectable to Health Analyzers or Pandemic machines. + return 0 + if(D.severity == D.non_threat) // medibot doesn't try to heal truly harmless viruses + return 0 + if((D.stage > 1) || (D.spread_type == AIRBORNE)) // medibot can't detect a virus in its initial stage unless it spreads airborne. - for(var/datum/disease/D in C.viruses) - if((D.hidden[SCANNER]) || (D.hidden[PANDEMIC])) //the medibot can't detect viruses that are undetectable to Health Analyzers or Pandemic machines. - return 0 - if(D.severity == D.non_threat) // medibot doesn't try to heal truly harmless viruses - return 0 - if((D.stage > 1) || (D.spread_type == AIRBORNE)) // medibot can't detect a virus in its initial stage unless it spreads airborne. - - if (!C.reagents.has_reagent(src.treatment_virus)) - return 1 //STOP DISEASE FOREVER + if (!C.reagents.has_reagent(treatment_virus)) + return 1 //STOP DISEASE FOREVER return 0 /obj/machinery/bot/medbot/proc/medicate_patient(mob/living/carbon/C as mob) - if(!src.on) + if(!on) return if(!istype(C)) - src.oldpatient = src.patient - src.patient = null - src.currently_healing = 0 - src.last_found = world.time + oldpatient = patient + patient = null + mode = BOT_IDLE + last_found = world.time return if(C.stat == 2) var/death_message = pick("No! NO!","Live, damnit! LIVE!","I...I've never lost a patient before. Not today, I mean.") - src.speak(death_message) - src.oldpatient = src.patient - src.patient = null - src.currently_healing = 0 - src.last_found = world.time + speak(death_message) + oldpatient = patient + patient = null + mode = BOT_IDLE + last_found = world.time return var/reagent_id = null - if(src.emagged == 2) //Emagged! Time to poison everybody. + if(emagged == 2) //Emagged! Time to poison everybody. reagent_id = "toxin" else - var/virus = 0 - for(var/datum/disease/D in C.viruses) - if((!D.hidden[SCANNER]) && (!D.hidden[PANDEMIC])) //detectable virus - if(D.severity != D.non_threat) //virus is harmful - if((D.stage > 1) || (D.spread_type == AIRBORNE)) - virus = 1 + if(treat_virus) + var/virus = 0 + for(var/datum/disease/D in C.viruses) + if((!D.hidden[SCANNER]) && (!D.hidden[PANDEMIC])) //detectable virus + if(D.severity != D.non_threat) //virus is harmful + if((D.stage > 1) || (D.spread_type == AIRBORNE)) + virus = 1 - if (!reagent_id && (virus)) - if(!C.reagents.has_reagent(src.treatment_virus)) - reagent_id = src.treatment_virus + if (!reagent_id && (virus)) + if(!C.reagents.has_reagent(treatment_virus)) + reagent_id = treatment_virus if (!reagent_id && (C.getBruteLoss() >= heal_threshold)) - if(!C.reagents.has_reagent(src.treatment_brute)) - reagent_id = src.treatment_brute + if(!C.reagents.has_reagent(treatment_brute)) + reagent_id = treatment_brute if (!reagent_id && (C.getOxyLoss() >= (15 + heal_threshold))) - if(!C.reagents.has_reagent(src.treatment_oxy)) - reagent_id = src.treatment_oxy + if(!C.reagents.has_reagent(treatment_oxy)) + reagent_id = treatment_oxy if (!reagent_id && (C.getFireLoss() >= heal_threshold)) - if(!C.reagents.has_reagent(src.treatment_fire)) - reagent_id = src.treatment_fire + if(!C.reagents.has_reagent(treatment_fire)) + reagent_id = treatment_fire if (!reagent_id && (C.getToxLoss() >= heal_threshold)) - if(!C.reagents.has_reagent(src.treatment_tox)) - reagent_id = src.treatment_tox + if(!C.reagents.has_reagent(treatment_tox)) + reagent_id = treatment_tox //If the patient is injured but doesn't have our special reagent in them then we should give it to them first - if(reagent_id && src.use_beaker && src.reagent_glass && src.reagent_glass.reagents.total_volume) - for(var/datum/reagent/R in src.reagent_glass.reagents.reagent_list) + if(reagent_id && use_beaker && reagent_glass && reagent_glass.reagents.total_volume) + for(var/datum/reagent/R in reagent_glass.reagents.reagent_list) if(!C.reagents.has_reagent(R.id)) reagent_id = "internal_beaker" break if(!reagent_id) //If they don't need any of that they're probably cured! - src.oldpatient = src.patient - src.patient = null - src.currently_healing = 0 - src.last_found = world.time + oldpatient = patient + patient = null + mode = BOT_IDLE + last_found = world.time var/message = pick("All patched up!","An apple a day keeps me away.","Feel better soon!") - src.speak(message) + speak(message) + updateicon() return else - src.icon_state = "medibots" - C.visible_message("[src] is trying to inject [src.patient]!", \ - "[src] is trying to inject [src.patient]!") + C.visible_message("[src] is trying to inject [patient]!", \ + "[src] is trying to inject [patient]!") spawn(30) - if ((get_dist(src, src.patient) <= 1) && (src.on)) + if ((get_dist(src, patient) <= 1) && (on)) if(reagent_id == "internal_beaker") - if(src.use_beaker && src.reagent_glass && src.reagent_glass.reagents.total_volume) - src.reagent_glass.reagents.trans_to(src.patient,src.injection_amount) //Inject from beaker instead. - src.reagent_glass.reagents.reaction(src.patient, 2) + if(use_beaker && reagent_glass && reagent_glass.reagents.total_volume) + reagent_glass.reagents.trans_to(patient,injection_amount) //Inject from beaker instead. + reagent_glass.reagents.reaction(patient, 2) else - src.patient.reagents.add_reagent(reagent_id,src.injection_amount) - C.visible_message("[src] injects [src.patient] with the syringe!", \ - "[src] injects [src.patient] with the syringe!") + patient.reagents.add_reagent(reagent_id,injection_amount) + C.visible_message("[src] injects [patient] with the syringe!", \ + "[src] injects [patient] with the syringe!") - src.icon_state = "medibot[src.on]" - src.currently_healing = 0 + mode = BOT_IDLE + updateicon() return reagent_id = null @@ -468,11 +488,11 @@ /obj/machinery/bot/medbot/bullet_act(var/obj/item/projectile/Proj) if(Proj.flag == "taser") - src.stunned = min(stunned+10,20) + stunned = min(stunned+10,20) ..() /obj/machinery/bot/medbot/explode() - src.on = 0 + on = 0 visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) @@ -482,9 +502,9 @@ new /obj/item/device/healthanalyzer(Tsec) - if(src.reagent_glass) - src.reagent_glass.loc = Tsec - src.reagent_glass = null + if(reagent_glass) + reagent_glass.loc = Tsec + reagent_glass = null if (prob(50)) new /obj/item/robot_parts/l_arm(Tsec) @@ -495,54 +515,14 @@ qdel(src) return -/obj/machinery/bot/medbot/Bump(M as mob|obj) //Leave no door unopened! - if ((istype(M, /obj/machinery/door)) && (!isnull(src.botcard))) - var/obj/machinery/door/D = M - if (!istype(D, /obj/machinery/door/firedoor) && D.check_access(src.botcard)) - D.open() - src.frustration = 0 - else if ((istype(M, /mob/living/)) && (!src.anchored)) - src.loc = M:loc - src.frustration = 0 - return - -/* terrible -/obj/machinery/bot/medbot/Bumped(atom/movable/M as mob|obj) - spawn(0) - if (M) - var/turf/T = get_turf(src) - M:loc = T -*/ - -/* - * Pathfinding procs, allow the medibot to path through doors it has access to. - */ - -//Pretty ugh -/* -/turf/proc/AdjacentTurfsAllowMedAccess() - var/L[] = new() - for(var/turf/t in oview(src,1)) - if(!t.density) - if(!LinkBlocked(src, t) && !TurfBlockedNonWindowNonDoor(t,get_access("Medical Doctor"))) - L.Add(t) - return L - - -//It isn't blocked if we can open it, man. -/proc/TurfBlockedNonWindowNonDoor(turf/loc, var/list/access) - for(var/obj/O in loc) - if(O.density && !istype(O, /obj/structure/window) && !istype(O, /obj/machinery/door)) - return 1 - - if (O.density && (istype(O, /obj/machinery/door)) && (access.len)) - var/obj/machinery/door/D = O - for(var/req in D.req_access) - if(!(req in access)) //doesn't have this access - return 1 - - return 0 -*/ +/obj/machinery/bot/medbot/proc/declare(var/crit_patient) + if(declare_cooldown) + return + var/area/location = get_area(src) + speak("Medical emergency! [crit_patient ? "[crit_patient]" : "A patient"] is in critical condition at [location]!",radio_frequency) + declare_cooldown = 1 + spawn(200) //Twenty seconds + declare_cooldown = 0 /* * Medbot Assembly -- Can be made out of all three medkits. @@ -555,7 +535,7 @@ return //Making a medibot! - if(src.contents.len >= 1) + if(contents.len >= 1) user << "You need to empty [src] out first." return @@ -577,33 +557,33 @@ /obj/item/weapon/firstaid_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob) ..() if(istype(W, /obj/item/weapon/pen)) - var/t = copytext(stripped_input(user, "Enter new robot name", src.name, src.created_name),1,MAX_NAME_LEN) + var/t = copytext(stripped_input(user, "Enter new robot name", name, created_name),1,MAX_NAME_LEN) if (!t) return - if (!in_range(src, usr) && src.loc != usr) + if (!in_range(src, usr) && loc != usr) return - src.created_name = t + created_name = t else switch(build_step) if(0) if(istype(W, /obj/item/device/healthanalyzer)) user.drop_item() qdel(W) - src.build_step++ + build_step++ user << "You add the health sensor to [src]." - src.name = "First aid/robot arm/health analyzer assembly" - src.overlays += image('icons/obj/aibots.dmi', "na_scanner") + name = "First aid/robot arm/health analyzer assembly" + overlays += image('icons/obj/aibots.dmi', "na_scanner") if(1) if(isprox(W)) user.drop_item() qdel(W) - src.build_step++ + build_step++ user << "You complete the Medibot! Beep boop." var/turf/T = get_turf(src) var/obj/machinery/bot/medbot/S = new /obj/machinery/bot/medbot(T) - S.skin = src.skin - S.name = src.created_name + S.skin = skin + S.name = created_name user.unEquip(src, 1) qdel(src) diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index bad30b9b2e5..e796be551c6 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -19,34 +19,28 @@ var/global/mulebot_count = 0 fire_dam_coeff = 0.7 brute_dam_coeff = 0.5 var/atom/movable/load = null // the loaded crate (usually) - var/beacon_freq = 1400 - var/control_freq = 1447 + var/list/delivery_beacons = list() //List of beacons that serve as delivery locations. + beacon_freq = 1400 + control_freq = 1447 + bot_type = MULE_BOT + bot_filter = RADIO_MULEBOT suffix = "" var/turf/target // this is turf to navigate to (location of beacon) var/loaddir = 0 // this the direction to unload onto/load from - var/new_destination = "" // pending new destination (waiting for beacon response) - var/destination = "" // destination description var/home_destination = "" // tag of home beacon req_access = list(access_cargo) // added robotics access so assembly line drop-off works properly -veyveyr //I don't think so, Tim. You need to add it to the MULE's hidden robot ID card. -NEO - var/path[] = new() - var/mode = 0 //0 = idle/ready - //1 = loading/unloading - //2 = moving to deliver - //3 = returning to home - //4 = blocked - //5 = computing navigation - //6 = waiting for nav computation - //7 = no destination beacon found (or no route) + mode = BOT_IDLE - var/blockcount = 0 //number of times retried a blocked path + blockcount = 0 //number of times retried a blocked path var/reached_target = 1 //true if already reached the target - var/refresh = 1 // true to refresh dialogue - var/auto_return = 1 // true if auto return to home beacon after unload - var/auto_pickup = 1 // true if auto-pickup at beacon + var/refresh = 1 // true to refresh dialogue + var/auto_return = 1 // true if auto return to home beacon after unload + var/auto_pickup = 1 // true if auto-pickup at beacon + var/report_delivery = 1 // true if bot will announce an arrival to a location. var/obj/item/weapon/stock_parts/cell/cell var/datum/wires/mulebot/wires = null @@ -67,18 +61,16 @@ var/global/mulebot_count = 0 /obj/machinery/bot/mulebot/New() ..() wires = new(src) - botcard = new(src) var/datum/job/cargo_tech/J = new/datum/job/cargo_tech botcard.access = J.get_access() + prev_access = botcard.access // botcard.access += access_robotics //Why --Ikki cell = new(src) cell.charge = 2000 cell.maxcharge = 2000 spawn(5) // must wait for map loading to finish - if(radio_controller) - radio_controller.add_object(src, control_freq, filter = RADIO_MULEBOT) - radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS) + add_to_beacons(bot_filter) mulebot_count += 1 if(!suffix) @@ -100,8 +92,8 @@ var/global/mulebot_count = 0 locked = !locked user << "You [locked ? "lock" : "unlock"] the mulebot's controls!" flick("mulebot-emagged", src) - playsound(src.loc, 'sound/effects/sparks1.ogg', 100, 0) - else if(istype(I, /obj/item/weapon/card/id)) + playsound(loc, 'sound/effects/sparks1.ogg', 100, 0) + else if(istype(I, /obj/item/weapon/card/id) || istype(I, /obj/item/device/pda)) if(toggle_lock(user)) user << "Controls [(locked ? "locked" : "unlocked")]." @@ -118,30 +110,30 @@ var/global/mulebot_count = 0 open = !open if(open) - src.visible_message("[user] opens the maintenance hatch of [src]", "You open [src]'s maintenance hatch.") + visible_message("[user] opens the maintenance hatch of [src]", "You open [src]'s maintenance hatch.") on = 0 icon_state="mulebot-hatch" else - src.visible_message("[user] closes the maintenance hatch of [src]", "You close [src]'s maintenance hatch.") + visible_message("[user] closes the maintenance hatch of [src]", "You close [src]'s maintenance hatch.") icon_state = "mulebot0" updateDialog() else if (istype(I, /obj/item/weapon/wrench)) - if (src.health < maxhealth) - src.health = min(maxhealth, src.health+25) + if (health < maxhealth) + health = min(maxhealth, health+25) user.visible_message( - "[user] repairs [src]!", + "[user] repairs [src]!", "You repair [src]!" ) else - user << "[src] does not need a repair!" + user << " [src] does not need a repair!" else if(istype(I, /obj/item/device/multitool) || istype(I, /obj/item/weapon/wirecutters)) if(open) attack_hand(usr) else if(load && ismob(load)) // chance to knock off rider if(prob(1+I.force * 2)) unload(0) - user.visible_message("[user] knocks [load] off [src] with \the [I]!", "You knock [load] off [src] with \the [I]!") + user.visible_message(" [user] knocks [load] off [src] with \the [I]!", " You knock [load] off [src] with \the [I]!") else user << "You hit [src] with \the [I] but to no effect." else @@ -164,7 +156,7 @@ var/global/mulebot_count = 0 if(prob(50) && !isnull(load)) unload(0) if(prob(25)) - src.visible_message("Something shorts out inside [src]!") + visible_message(" Something shorts out inside [src]!") wires.RandomCut() ..() @@ -182,29 +174,30 @@ var/global/mulebot_count = 0 /obj/machinery/bot/mulebot/interact(var/mob/user, var/ai=0) var/dat - dat += "

Multiple Utility Load Effector Mk. IV

" + dat += "

Multiple Utility Load Effector Mk. V

" dat += "ID: [suffix]
" dat += "Power: [on ? "On" : "Off"]
" if(!open) dat += "

Status

" + dat += "
" switch(mode) - if(0) - dat += "Ready" - if(1) - dat += "Loading/Unloading" - if(2) - dat += "Navigating to Delivery Location" - if(3) - dat += "Navigating to Home" - if(4) - dat += "Waiting for clear path" - if(5,6) - dat += "Calculating navigation path" - if(7) - dat += "Unable to reach destination" + if(BOT_IDLE) + dat += "Ready" + if(BOT_LOADING) + dat += "[mode_name[BOT_LOADING]]" + if(BOT_DELIVER) + dat += "[mode_name[BOT_DELIVER]]" + if(BOT_GO_HOME) + dat += "[mode_name[BOT_GO_HOME]]" + if(BOT_BLOCKED) + dat += "[mode_name[BOT_BLOCKED]]" + if(BOT_NAV,BOT_WAIT_FOR_NAV) + dat += "[mode_name[BOT_NAV]]" + if(BOT_NO_ROUTE) + dat += "[mode_name[BOT_NO_ROUTE]]" dat += "
" dat += "Current Load: [load ? load.name : "none"]
" @@ -225,6 +218,7 @@ var/global/mulebot_count = 0 dat += "Set Home
" dat += "Toggle Auto Return Home ([auto_return ? "On":"Off"])
" dat += "Toggle Auto Pickup Crate ([auto_pickup ? "On":"Off"])
" + dat += "Toggle Delivery Reporting ([report_delivery ? "On" : "Off"])
" if(load) dat += "Unload Now
" @@ -245,9 +239,9 @@ var/global/mulebot_count = 0 //user << browse("M.U.L.E. Mk. III [suffix ? "([suffix])" : ""][dat]", "window=mulebot;size=350x500") //onclose(user, "mulebot") - var/datum/browser/popup = new(user, "mulebot", "M.U.L.E. Mk. III [suffix ? "([suffix])" : ""]", 350, 500) + var/datum/browser/popup = new(user, "mulebot", "M.U.L.E. Mk. V [suffix ? "([suffix])" : ""]", 350, 500) popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) popup.open() return @@ -261,7 +255,7 @@ var/global/mulebot_count = 0 return if (usr.stat) return - if ((in_range(src, usr) && istype(src.loc, /turf)) || (istype(usr, /mob/living/silicon))) + if ((in_range(src, usr) && istype(loc, /turf)) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) switch(href_list["op"]) @@ -269,7 +263,7 @@ var/global/mulebot_count = 0 toggle_lock(usr) if("power") - if (src.on) + if (on) turn_off() else if (cell && !open) if (!turn_on()) @@ -305,23 +299,23 @@ var/global/mulebot_count = 0 if("stop") - if(mode >=2) - mode = 0 + if(mode >= BOT_DELIVER) + bot_reset() updateDialog() if("go") - if(mode == 0) + if(mode == BOT_IDLE) start() updateDialog() if("home") - if(mode == 0 || mode == 2) + if(mode == BOT_IDLE || mode == BOT_DELIVER) start_home() updateDialog() if("destination") refresh=0 - var/new_dest = input("Enter new destination tag", "Mulebot [suffix ? "([suffix])" : ""]", destination) as text|null + var/new_dest = input("Select M.U.L.E. Destination", "Mulebot [suffix ? "([suffix])" : ""]", destination) as null|anything in delivery_beacons refresh=1 if(new_dest) set_destination(new_dest) @@ -357,12 +351,15 @@ var/global/mulebot_count = 0 if("autopick") auto_pickup = !auto_pickup + if("report") + report_delivery = !report_delivery + if("close") usr.unset_machine() usr << browse(null,"window=mulebot") updateDialog() - //src.updateUsrDialog() + //updateUsrDialog() else usr << browse(null, "window=mulebot") usr.unset_machine() @@ -375,7 +372,7 @@ var/global/mulebot_count = 0 return !open && cell && cell.charge > 0 && wires.HasPower() /obj/machinery/bot/mulebot/proc/toggle_lock(var/mob/user) - if(src.allowed(user)) + if(allowed(user)) locked = !locked updateDialog() return 1 @@ -403,8 +400,8 @@ var/global/mulebot_count = 0 // called to load a crate /obj/machinery/bot/mulebot/proc/load(var/atom/movable/C) if(wires.LoadCheck() && !istype(C,/obj/structure/closet/crate)) - src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.") - playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) + visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.") + playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0) return // if not emagged, only allow crates to be loaded //I'm sure someone will come along and ask why this is here... well people were dragging screen items onto the mule, and that was not cool. @@ -416,16 +413,16 @@ var/global/mulebot_count = 0 if(get_dist(C, src) > 1 || load || !on) return - mode = 1 + mode = BOT_LOADING // if a create, close before loading var/obj/structure/closet/crate/crate = C if(istype(crate)) crate.close() - C.loc = src.loc + C.loc = loc sleep(2) - if(C.loc != src.loc) //To prevent you from going onto more thano ne bot. + if(C.loc != loc) //To prevent you from going onto more thano ne bot. return C.loc = src load = C @@ -441,7 +438,7 @@ var/global/mulebot_count = 0 M.client.perspective = EYE_PERSPECTIVE M.client.eye = src - mode = 0 + mode = BOT_IDLE send_status() // called to unload the bot @@ -451,7 +448,7 @@ var/global/mulebot_count = 0 if(!load) return - mode = 1 + mode = BOT_LOADING overlays.Cut() if(ismob(load)) @@ -461,11 +458,11 @@ var/global/mulebot_count = 0 M.client.eye = src - load.loc = src.loc + load.loc = loc load.pixel_y -= 9 load.layer = initial(load.layer) if(dirn) - var/turf/T = src.loc + var/turf/T = loc var/turf/newT = get_step(T,dirn) if(load.CanPass(load,newT)) //Can't get off onto anything that wouldn't let you pass normally step(load, dirn) @@ -477,9 +474,9 @@ var/global/mulebot_count = 0 // with items dropping as mobs are loaded for(var/atom/movable/AM in src) - if(AM == cell || AM == botcard) continue + if(AM == cell || istype(AM , botcard) || AM == Radio) continue - AM.loc = src.loc + AM.loc = loc AM.layer = initial(AM.layer) AM.pixel_y = initial(AM.pixel_y) if(ismob(AM)) @@ -487,8 +484,17 @@ var/global/mulebot_count = 0 if(M.client) M.client.perspective = MOB_PERSPECTIVE M.client.eye = src - mode = 0 + mode = BOT_IDLE +/obj/machinery/bot/mulebot/call_bot() + ..() + var/area/dest_area + if (path && path.len) + target = ai_waypoint //Target is the end point of the path, the waypoint set by the AI. + dest_area = get_area(target) + destination = format_text(dest_area.name) + pathset = 1 //Indicates the AI's custom path is initialized. + start() /obj/machinery/bot/mulebot/process() if(!has_power()) @@ -520,13 +526,14 @@ var/global/mulebot_count = 0 /obj/machinery/bot/mulebot/proc/process_bot() //if(mode) world << "Mode: [mode]" + switch(mode) - if(0) // idle + if(BOT_IDLE) // idle icon_state = "mulebot0" return - if(1) // loading/unloading + if(BOT_LOADING) // loading/unloading return - if(2,3,4) // navigating to deliver,home, or blocked + if(BOT_DELIVER,BOT_GO_HOME,BOT_BLOCKED) // navigating to deliver,home, or blocked if(loc == target) // reached target at_target() @@ -569,14 +576,14 @@ var/global/mulebot_count = 0 path -= loc - if(mode==4) + if(mode == BOT_BLOCKED) spawn(1) send_status() if(destination == home_destination) - mode = 3 + mode = BOT_GO_HOME else - mode = 2 + mode = BOT_DELIVER else // failed to move @@ -585,73 +592,74 @@ var/global/mulebot_count = 0 blockcount++ - mode = 4 + mode = BOT_BLOCKED if(blockcount == 3) - src.visible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.") - playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0) + visible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.") + playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0) if(blockcount > 10) // attempt 10 times before recomputing // find new path excluding blocked turf - src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.") - playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) + visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.") + playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0) spawn(2) calc_path(next) if(path.len > 0) - src.visible_message("[src] makes a delighted ping!", "You hear a ping.") - playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) - mode = 4 - mode =6 + visible_message("[src] makes a delighted ping!", "You hear a ping.") + playsound(loc, 'sound/machines/ping.ogg', 50, 0) + mode = BOT_BLOCKED + mode = BOT_WAIT_FOR_NAV return return else - src.visible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.") - playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0) + visible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.") + playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0) //world << "Bad turf." - mode = 5 + mode = BOT_NAV return else //world << "No path." - mode = 5 + mode = BOT_NAV return - if(5) // calculate new path + if(BOT_NAV) // calculate new path //world << "Calc new path." - mode = 6 + mode = BOT_WAIT_FOR_NAV spawn(0) calc_path() if(path.len > 0) blockcount = 0 - mode = 4 - src.visible_message("[src] makes a delighted ping!", "You hear a ping.") - playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) + mode = BOT_BLOCKED + visible_message("[src] makes a delighted ping!", "You hear a ping.") + playsound(loc, 'sound/machines/ping.ogg', 50, 0) else - src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.") - playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) + visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.") + playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0) - mode = 7 + mode = BOT_NO_ROUTE //if(6) //world << "Pending path calc." //if(7) //world << "No dest / no route." + return // calculates a path to the current destination // given an optional turf to avoid -/obj/machinery/bot/mulebot/proc/calc_path(var/turf/avoid = null) - src.path = AStar(src.loc, src.target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 250, id=botcard, exclude=avoid) - if(!src.path) - src.path = list() +/obj/machinery/bot/mulebot/calc_path(var/turf/avoid = null) + path = AStar(loc, target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 250, id=botcard, exclude=avoid) + if(!path) + path = list() // sets the current destination // signals all beacons matching the delivery code // beacons will return a signal giving their locations -/obj/machinery/bot/mulebot/proc/set_destination(var/new_dest) +/obj/machinery/bot/mulebot/set_destination(var/new_dest) spawn(0) new_destination = new_dest post_signal(beacon_freq, "findbeacon", "delivery") @@ -660,9 +668,9 @@ var/global/mulebot_count = 0 // starts bot moving to current destination /obj/machinery/bot/mulebot/proc/start() if(destination == home_destination) - mode = 3 + mode = BOT_GO_HOME else - mode = 2 + mode = BOT_DELIVER icon_state = "mulebot[(wires.MobAvoid() != 0)]" // starts bot moving to home @@ -670,17 +678,27 @@ var/global/mulebot_count = 0 /obj/machinery/bot/mulebot/proc/start_home() spawn(0) set_destination(home_destination) - mode = 4 + mode = BOT_BLOCKED icon_state = "mulebot[(wires.MobAvoid() != 0)]" // called when bot reaches current target /obj/machinery/bot/mulebot/proc/at_target() if(!reached_target) - src.visible_message("[src] makes a chiming sound!", "You hear a chime.") - playsound(src.loc, 'sound/machines/chime.ogg', 50, 0) + radio_frequency = SUPP_FREQ //Supply channel + visible_message("[src] makes a chiming sound!", "You hear a chime.") + playsound(loc, 'sound/machines/chime.ogg', 50, 0) reached_target = 1 + 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) + calling_ai << "\icon[src] [src] wirelessly plays a chiming sound!" + playsound(calling_ai, 'sound/machines/chime.ogg',40, 0) + calling_ai = null + radio_frequency = AIPRIV_FREQ //Report on AI Private instead if the AI is controlling us. + if(load) // if loaded, unload at target + speak("Destination [destination] reached. Unloading [load].",radio_frequency) unload(loaddir) else // not loaded @@ -695,14 +713,16 @@ var/global/mulebot_count = 0 AM = locate(/obj/structure/closet/crate) in get_step(loc,loaddir) if(AM) load(AM) + if(report_delivery) + speak("Now loading [load] at [get_area(src)].", radio_frequency) // whatever happened, check to see if we return home if(auto_return && destination != home_destination) // auto return set and not at home already start_home() - mode = 4 + mode = BOT_BLOCKED else - mode = 0 // otherwise go idle + bot_reset() // otherwise go idle send_status() // report status to anyone listening @@ -714,13 +734,12 @@ var/global/mulebot_count = 0 var/mob/M = obs if(ismob(M)) if(istype(M,/mob/living/silicon/robot)) - src.visible_message("[src] bumps into [M]!") + visible_message("[src] bumps into [M]!") else - src.visible_message("[src] knocks over [M]!") + visible_message("[src] knocks over [M]!") M.stop_pulling() M.Stun(8) M.Weaken(5) - M.lying = 1 ..() /obj/machinery/bot/mulebot/alter_health() @@ -730,8 +749,8 @@ var/global/mulebot_count = 0 // called from mob/living/carbon/human/Crossed() // when mulebot is in the same loc /obj/machinery/bot/mulebot/proc/RunOver(var/mob/living/carbon/human/H) - src.visible_message("[src] drives over [H]!") - playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) + visible_message("[src] drives over [H]!") + playsound(loc, 'sound/effects/splat.ogg', 50, 1) var/damage = rand(5,15) H.apply_damage(2*damage, BRUTE, "head") @@ -741,7 +760,7 @@ var/global/mulebot_count = 0 H.apply_damage(0.5*damage, BRUTE, "l_arm") H.apply_damage(0.5*damage, BRUTE, "r_arm") - var/obj/effect/decal/cleanable/blood/B = new(src.loc) + var/obj/effect/decal/cleanable/blood/B = new(loc) B.blood_DNA = list() B.blood_DNA[H.dna.unique_enzymes] = H.dna.blood_type @@ -779,7 +798,7 @@ var/global/mulebot_count = 0 // process control input switch(recv) if("stop") - mode = 0 + bot_reset() return if("go") @@ -815,6 +834,7 @@ var/global/mulebot_count = 0 // receive response from beacon recv = signal.data["beacon"] + if(wires.BeaconRX()) if(recv == new_destination) // if the recvd beacon location matches the set destination // the we will navigate there @@ -829,12 +849,18 @@ var/global/mulebot_count = 0 calc_path() updateDialog() + //Detects and stores current active delivery beacons. + if(signal.data["beacon"]) + if(!delivery_beacons) + delivery_beacons = new() + delivery_beacons[signal.data["beacon"] ] = signal.source + // send a radio signal with a single data key/value pair -/obj/machinery/bot/mulebot/proc/post_signal(var/freq, var/key, var/value) +/obj/machinery/bot/mulebot/post_signal(var/freq, var/key, var/value) post_signal_multiple(freq, list("[key]" = value) ) // send a radio signal with multiple data key/values -/obj/machinery/bot/mulebot/proc/post_signal_multiple(var/freq, var/list/keyval) +/obj/machinery/bot/mulebot/post_signal_multiple(var/freq, var/list/keyval) if(freq == beacon_freq && !(wires.BeaconRX())) return @@ -856,17 +882,17 @@ var/global/mulebot_count = 0 //world << "sent [key],[keyval[key]] on [freq]" if (signal.data["findbeacon"]) frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS) - else if (signal.data["type"] == "mulebot") + else if (signal.data["type"] == MULE_BOT) frequency.post_signal(src, signal, filter = RADIO_MULEBOT) else frequency.post_signal(src, signal) // signals bot status etc. to controller -/obj/machinery/bot/mulebot/proc/send_status() +/obj/machinery/bot/mulebot/send_status() var/list/kv = list( - "type" = "mulebot", + "type" = MULE_BOT, "name" = suffix, - "loca" = (loc ? loc.loc : "Unknown"), // somehow loc can be null and cause a runtime - Quarxink + "loca" = get_area(src), "mode" = mode, "powr" = (cell ? cell.percent() : 0), "dest" = destination, @@ -886,7 +912,7 @@ var/global/mulebot_count = 0 /obj/machinery/bot/mulebot/explode() - src.visible_message("[src] blows apart!") + visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) new /obj/item/device/assembly/prox_sensor(Tsec) @@ -902,6 +928,6 @@ var/global/mulebot_count = 0 s.set_up(3, 1, src) s.start() - new /obj/effect/decal/cleanable/oil(src.loc) + new /obj/effect/decal/cleanable/oil(loc) unload(0) qdel(src) diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index dc7a6800c8a..25c76ba6872 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -17,45 +17,23 @@ var/threatlevel = 0 var/target_lastloc //Loc of target when arrested. var/last_found //There's a delay - var/frustration = 0 // var/emagged = 0 //Emagged Secbots view everyone as a criminal - var/declare_arrests = 1 //When making an arrest, should it notify everyone wearing sechuds? + var/declare_arrests = 1 //When making an arrest, should it notify everyone on the security channel? var/idcheck = 0 //If true, arrest people with no IDs - var/weaponscheck = 0 //If true, arrest people for weapons if they don't have access + var/weaponscheck = 0 //If true, arrest people for weapons if they lack access var/check_records = 1 //Does it check security records? var/arrest_type = 0 //If true, don't handcuff - - var/mode = 0 -#define SECBOT_IDLE 0 // idle -#define SECBOT_HUNT 1 // found target, hunting -#define SECBOT_PREP_ARREST 2 // at target, preparing to arrest -#define SECBOT_ARREST 3 // arresting target -#define SECBOT_START_PATROL 4 // start patrol -#define SECBOT_PATROL 5 // patrolling -#define SECBOT_SUMMON 6 // summoned by PDA - - var/auto_patrol = 0 // set to make bot automatically patrol - - var/beacon_freq = 1445 // navigation beacon frequency - var/control_freq = 1447 // bot control frequency + radio_frequency = SEC_FREQ //Security channel + bot_type = SEC_BOT + bot_filter = RADIO_SECBOT //List of weapons that secbots will not arrest for var/safe_weapons = list(\ /obj/item/weapon/gun/energy/laser/bluetag,\ /obj/item/weapon/gun/energy/laser/redtag,\ - /obj/item/weapon/gun/energy/laser/practice) - - var/turf/patrol_target // this is turf to navigate to (location of beacon) - var/new_destination // pending new destination (waiting for beacon response) - var/destination // destination description tag - var/next_destination // the next destination in the patrol route - var/list/path = new // list of path turfs - - var/blockcount = 0 //number of times retried a blocked path - var/awaiting_beacon = 0 // count of pticks awaiting a beacon response - - var/nearest_beacon // the nearest beacon's tag - var/turf/nearest_beacon_loc // the nearest beacon's location + /obj/item/weapon/gun/energy/laser/practice,\ + /obj/item/weapon/melee/telebaton,\ + /obj/item/weapon/gun/energy/kinetic_accelerator) /obj/machinery/bot/secbot/beepsky @@ -68,7 +46,7 @@ /obj/machinery/bot/secbot/pingsky name = "Officer Pingsky" desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment." - declare_arrests = 0 + radio_frequency = AIPRIV_FREQ /obj/item/weapon/secbot_assembly name = "incomplete securitron assembly" @@ -83,30 +61,38 @@ /obj/machinery/bot/secbot/New() ..() - src.icon_state = "secbot[src.on]" + icon_state = "secbot[on]" spawn(3) - src.botcard = new /obj/item/weapon/card/id(src) - var/datum/job/detective/J = new /datum/job/detective - src.botcard.access = J.get_access() - if(radio_controller) - radio_controller.add_object(src, control_freq, filter = RADIO_SECBOT) - radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS) + + var/datum/job/detective/J = new/datum/job/detective + botcard.access = J.get_access() + prev_access = botcard.access + add_to_beacons(bot_filter) /obj/machinery/bot/secbot/turn_on() ..() - src.icon_state = "secbot[src.on]" - src.updateUsrDialog() + icon_state = "secbot[on]" + updateUsrDialog() /obj/machinery/bot/secbot/turn_off() ..() - src.target = null - src.oldtarget_name = null - src.anchored = 0 - src.mode = SECBOT_IDLE + icon_state = "secbot[on]" + updateUsrDialog() + +/obj/machinery/bot/secbot/bot_reset() + ..() + target = null + oldtarget_name = null + anchored = 0 walk_to(src,0) - src.icon_state = "secbot[src.on]" - src.updateUsrDialog() + last_found = world.time + +/obj/machinery/bot/secbot/set_custom_texts() + + text_hack = "You overload [name]'s target identification system." + text_dehack = "You reboot [name] and restore the target identification." + text_dehack_fail = "[name] refuses to accept your authority!" /obj/machinery/bot/secbot/attack_hand(mob/user as mob) . = ..() @@ -119,147 +105,118 @@ var/dat dat += hack(user) dat += text({" +Securitron v1.6 controls

Status: []
-Behaviour controls are [src.locked ? "locked" : "unlocked"]
-Maintenance panel panel is [src.open ? "opened" : "closed"]
"}, +Behaviour controls are [locked ? "locked" : "unlocked"]
+Maintenance panel panel is [open ? "opened" : "closed"]"}, -"[src.on ? "On" : "Off"]" ) +"[on ? "On" : "Off"]" ) - if(!src.locked || issilicon(user)) + if(!locked || issilicon(user)) dat += text({"
Arrest Unidentifiable Persons: []
Arrest for Unauthorized Weapons: []
Arrest for Warrant: []
-
Operating Mode: []
Report Arrests[]
Auto Patrol: []"}, -"[src.idcheck ? "Yes" : "No"]", -"[src.weaponscheck ? "Yes" : "No"]", -"[src.check_records ? "Yes" : "No"]", -"[src.arrest_type ? "Detain" : "Arrest"]", -"[src.declare_arrests ? "Yes" : "No"]", +"[idcheck ? "Yes" : "No"]", +"[weaponscheck ? "Yes" : "No"]", +"[check_records ? "Yes" : "No"]", +"[arrest_type ? "Detain" : "Arrest"]", +"[declare_arrests ? "Yes" : "No"]", "[auto_patrol ? "On" : "Off"]" ) - var/datum/browser/popup = new(user, "autosec", "Securitron v1.5.1 controls") + var/datum/browser/popup = new(user, "autosec", "Automatic Security Unit v1.6") popup.set_content(dat) popup.open() return /obj/machinery/bot/secbot/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - if((href_list["power"]) && (src.allowed(usr))) - if (src.on && !src.emagged) - turn_off() - else - turn_on() - return + + ..() switch(href_list["operation"]) if("idcheck") - src.idcheck = !src.idcheck - src.updateUsrDialog() + idcheck = !idcheck + updateUsrDialog() if("weaponscheck") - src.weaponscheck = !src.weaponscheck - src.updateUsrDialog() + weaponscheck = !weaponscheck + updateUsrDialog() if("ignorerec") - src.check_records = !src.check_records - src.updateUsrDialog() + check_records = !check_records + updateUsrDialog() if("switchmode") - src.arrest_type = !src.arrest_type - src.updateUsrDialog() - if("patrol") - auto_patrol = !auto_patrol - mode = SECBOT_IDLE + arrest_type = !arrest_type updateUsrDialog() if("declarearrests") - src.declare_arrests = !src.declare_arrests - src.updateUsrDialog() - if("hack") - if(!src.emagged) - src.emagged = 2 - src.hacked = 1 - usr << "You overload [src]'s target identification system." - else if(!src.hacked) - usr << "[src] refuses to accept your authority!" - else - src.emagged = 0 - src.hacked = 0 - usr << "You reboot [src] and restore the target identification." - src.updateUsrDialog() + declare_arrests = !declare_arrests + updateUsrDialog() + /obj/machinery/bot/secbot/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) - if(src.allowed(user) && !open && !emagged) - src.locked = !src.locked - user << "Controls are now [src.locked ? "locked." : "unlocked."]" + if(allowed(user) && !open && !emagged) + locked = !locked + user << "Controls are now [locked ? "locked." : "unlocked."]" else if(emagged) user << "ERROR" if(open) user << "Please close the access panel before locking it." else - user << "Access denied." + user << " Access denied." else ..() if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm") // Any intent but harm will heal, so we shouldn't get angry. return - if(!istype(W, /obj/item/weapon/screwdriver) && (W.force) && (!src.target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass. + if(!istype(W, /obj/item/weapon/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass. threatlevel = user.assess_threat(src) threatlevel += 6 if(threatlevel >= 4) - src.target = user - src.mode = SECBOT_HUNT + target = user + mode = BOT_HUNT /obj/machinery/bot/secbot/Emag(mob/user as mob) ..() - if(open && !locked) - if(user) user << "You short out [src]'s target assessment circuits." - spawn(0) - audible_message("[src] buzzes oddly!") - src.target = null - if(user) src.oldtarget_name = user.name - src.last_found = world.time - src.anchored = 0 - src.declare_arrests = 0 - src.emagged = 2 - src.on = 1 - src.icon_state = "secbot[src.on]" - mode = SECBOT_IDLE + + if(emagged == 2) + if(user) + user << " You short out [src]'s target assessment circuits." + oldtarget_name = user.name + audible_message("[src] buzzes oddly!") + declare_arrests = 0 + icon_state = "secbot[on]" /obj/machinery/bot/secbot/process() - set background = BACKGROUND_ENABLED - - if(!src.on) + if (!..()) return switch(mode) - if(SECBOT_IDLE) // idle + if(BOT_IDLE) // idle walk_to(src,0) look_for_perp() // see if any criminals are in range if(!mode && auto_patrol) // still idle, and set to patrol - mode = SECBOT_START_PATROL // switch to patrol mode + mode = BOT_START_PATROL // switch to patrol mode - if(SECBOT_HUNT) // hunting for perp + if(BOT_HUNT) // hunting for perp // if can't reach perp for long enough, go idle - if(src.frustration >= 8) + if(frustration >= 8) walk_to(src,0) back_to_idle() return if(target) // make sure target exists - if(src.Adjacent(target) && isturf(src.target.loc)) // if right next to perp - playsound(src.loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) - src.icon_state = "secbot-c" + if(Adjacent(target) && isturf(target.loc)) // if right next to perp + playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) + icon_state = "secbot-c" spawn(2) - src.icon_state = "secbot[src.on]" - var/mob/living/carbon/M = src.target + icon_state = "secbot[on]" + var/mob/living/carbon/M = target if(istype(M, /mob/living/carbon/human)) if( M.stuttering < 5 && !(HULK in M.mutations) ) M.stuttering = 5 @@ -272,46 +229,46 @@ Auto Patrol: []"}, if(declare_arrests) var/area/location = get_area(src) - broadcast_hud_message("[src.name] is [arrest_type ? "detaining" : "arresting"] level [threatlevel] scumbag [target.name] in [location]", src) - target.visible_message("[src.target] has been stunned by [src]!",\ - "[src.target] has been stunned by [src]!") + speak("[arrest_type ? "Detaining" : "Arresting"] level [threatlevel] scumbag [target] in [location].", radio_frequency) + target.visible_message("[target] has been stunned by [src]!",\ + "[target] has been stunned by [src]!") - mode = SECBOT_PREP_ARREST - src.anchored = 1 - src.target_lastloc = M.loc + mode = BOT_PREP_ARREST + anchored = 1 + target_lastloc = M.loc return else // not next to perp - var/turf/olddist = get_dist(src, src.target) - walk_to(src, src.target,1,4) - if((get_dist(src, src.target)) >= (olddist)) - src.frustration++ + var/turf/olddist = get_dist(src, target) + walk_to(src, target,1,4) + if((get_dist(src, target)) >= (olddist)) + frustration++ else - src.frustration = 0 + frustration = 0 else back_to_idle() - if(SECBOT_PREP_ARREST) // preparing to arrest target + if(BOT_PREP_ARREST) // preparing to arrest target // see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again. - if( !src.Adjacent(target) || !isturf(src.target.loc) || src.target.weakened < 2 ) + if( !Adjacent(target) || !isturf(target.loc) || target.weakened < 2 ) back_to_hunt() return if(iscarbon(target) && target.canBeHandcuffed()) - if(!src.arrest_type) - if(!src.target.handcuffed) //he's not cuffed? Try to cuff him! - mode = SECBOT_ARREST - playsound(src.loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) - target.visible_message("[src] is trying to put zipties on [src.target]!",\ - "[src] is trying to put zipties on [src.target]!") + if(!arrest_type) + if(!target.handcuffed) //he's not cuffed? Try to cuff him! + mode = BOT_ARREST + playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) + target.visible_message("[src] is trying to put zipties on [target]!",\ + "[src] is trying to put zipties on [target]!") spawn(60) - if( !src.Adjacent(target) || !isturf(src.target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing. + if( !Adjacent(target) || !isturf(target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing. return - if(!src.target.handcuffed) + if(!target.handcuffed) target.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(target) target.update_inv_handcuffed(0) //update the handcuffs overlay - playsound(src.loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0) + playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0) back_to_idle() else back_to_idle() @@ -320,362 +277,95 @@ Auto Patrol: []"}, back_to_idle() return - if(SECBOT_ARREST) - + if(BOT_ARREST) if (!target) - src.anchored = 0 - mode = SECBOT_IDLE - src.last_found = world.time + anchored = 0 + mode = BOT_IDLE + last_found = world.time frustration = 0 return - if(src.target.handcuffed) //no target or target cuffed? back to idle. + if(target.handcuffed) //no target or target cuffed? back to idle. back_to_idle() return - if( !src.Adjacent(target) || !isturf(src.target.loc) || (src.target.loc != src.target_lastloc && src.target.weakened < 2) ) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. + if( !Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.weakened < 2) ) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. back_to_hunt() return + else //Try arresting again if the target escapes. + mode = BOT_PREP_ARREST + anchored = 0 + + if(BOT_START_PATROL) + look_for_perp() + start_patrol() + + if(BOT_PATROL) + look_for_perp() + bot_patrol() - if(SECBOT_START_PATROL) // start a patrol - - if(path.len > 0 && patrol_target) // have a valid path, so just resume - mode = SECBOT_PATROL - return - - else if(patrol_target) // has patrol target already - spawn(0) - calc_path() // so just find a route to it - if(path.len == 0) - patrol_target = 0 - return - mode = SECBOT_PATROL - - - else // no patrol target, so need a new one - find_patrol_target() - speak("Engaging patrol mode.") - - - if(SECBOT_PATROL) // patrol mode - - patrol_step() - spawn(5) - if(mode == SECBOT_PATROL) - patrol_step() - - if(SECBOT_SUMMON) // summoned to PDA - patrol_step() - spawn(4) - if(mode == SECBOT_SUMMON) - patrol_step() - sleep(4) - patrol_step() return /obj/machinery/bot/secbot/proc/back_to_idle() - src.anchored = 0 - mode = SECBOT_IDLE - src.target = null - src.last_found = world.time + anchored = 0 + mode = BOT_IDLE + target = null + last_found = world.time frustration = 0 spawn(0) process() //ensure bot quickly responds /obj/machinery/bot/secbot/proc/back_to_hunt() - src.anchored = 0 - src.frustration = 0 - mode = SECBOT_HUNT + anchored = 0 + frustration = 0 + mode = BOT_HUNT spawn(0) process() //ensure bot quickly responds - -// perform a single patrol step -/obj/machinery/bot/secbot/proc/patrol_step() - - if(loc == patrol_target) // reached target - at_patrol_target() - return - - else if(path.len > 0 && patrol_target) // valid path - - var/turf/next = path[1] - if(next == loc) - path -= next - return - - - if(istype( next, /turf/simulated)) - - var/moved = step_towards(src, next) // attempt to move - if(moved) // successful move - blockcount = 0 - path -= loc - - look_for_perp() - else // failed to move - - blockcount++ - - if(blockcount > 5) // attempt 5 times before recomputing - // find new path excluding blocked turf - - spawn(2) - calc_path(next) - if(path.len == 0) - find_patrol_target() - else - blockcount = 0 - - return - - return - - else // not a valid turf - mode = SECBOT_IDLE - return - - else // no path, so calculate new one - mode = SECBOT_START_PATROL - - -// finds a new patrol target -/obj/machinery/bot/secbot/proc/find_patrol_target() - send_status() - if(awaiting_beacon) // awaiting beacon response - awaiting_beacon++ - if(awaiting_beacon > 5) // wait 5 secs for beacon response - find_nearest_beacon() // then go to nearest instead - return - - if(next_destination) - set_destination(next_destination) - else - find_nearest_beacon() - return - - -// finds the nearest beacon to self -// signals all beacons matching the patrol code -/obj/machinery/bot/secbot/proc/find_nearest_beacon() - nearest_beacon = null - new_destination = "__nearest__" - post_signal(beacon_freq, "findbeacon", "patrol") - awaiting_beacon = 1 - spawn(10) - awaiting_beacon = 0 - if(nearest_beacon) - set_destination(nearest_beacon) - else - auto_patrol = 0 - mode = SECBOT_IDLE - speak("Disengaging patrol mode.") - send_status() - - -/obj/machinery/bot/secbot/proc/at_patrol_target() - if(auto_patrol) - find_patrol_target() - else - mode = SECBOT_IDLE - return - - -// sets the current destination -// signals all beacons matching the patrol code -// beacons will return a signal giving their locations -/obj/machinery/bot/secbot/proc/set_destination(var/new_dest) - new_destination = new_dest - post_signal(beacon_freq, "findbeacon", "patrol") - awaiting_beacon = 1 - - -// receive a radio signal -// used for beacon reception - -/obj/machinery/bot/secbot/receive_signal(datum/signal/signal) - //log_admin("DEBUG \[[world.timeofday]\]: /obj/machinery/bot/secbot/receive_signal([signal.debug_print()])") - if(!on) - return - - /* - world << "rec signal: [signal.source]" - for(var/x in signal.data) - world << "* [x] = [signal.data[x]]" - */ - - var/recv = signal.data["command"] - // process all-bot input - if(recv=="bot_status") - send_status() - - // check to see if we are the commanded bot - if(signal.data["active"] == src) - // process control input - switch(recv) - if("stop") - mode = SECBOT_IDLE - auto_patrol = 0 - return - - if("go") - mode = SECBOT_IDLE - auto_patrol = 1 - return - - if("summon") - patrol_target = signal.data["target"] - next_destination = destination - destination = null - awaiting_beacon = 0 - mode = SECBOT_SUMMON - calc_path() - speak("Responding.") - - return - - - - // receive response from beacon - recv = signal.data["beacon"] - var/valid = signal.data["patrol"] - if(!recv || !valid) - return - - if(recv == new_destination) // if the recvd beacon location matches the set destination - // the we will navigate there - destination = new_destination - patrol_target = signal.source.loc - next_destination = signal.data["next_patrol"] - awaiting_beacon = 0 - - // if looking for nearest beacon - else if(new_destination == "__nearest__") - var/dist = get_dist(src,signal.source.loc) - if(nearest_beacon) - - // note we ignore the beacon we are located at - if(dist>1 && dist 1) - nearest_beacon = recv - nearest_beacon_loc = signal.source.loc - return - - -// send a radio signal with a single data key/value pair -/obj/machinery/bot/secbot/proc/post_signal(var/freq, var/key, var/value) - post_signal_multiple(freq, list("[key]" = value) ) - -// send a radio signal with multiple data key/values -/obj/machinery/bot/secbot/proc/post_signal_multiple(var/freq, var/list/keyval) - - var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq) - - if(!frequency) return - - var/datum/signal/signal = new() - signal.source = src - signal.transmission_method = 1 - //for(var/key in keyval) - // signal.data[key] = keyval[key] - signal.data = keyval - //world << "sent [key],[keyval[key]] on [freq]" - if(signal.data["findbeacon"]) - frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS) - else if(signal.data["type"] == "secbot") - frequency.post_signal(src, signal, filter = RADIO_SECBOT) - else - frequency.post_signal(src, signal) - -// signals bot status etc. to controller -/obj/machinery/bot/secbot/proc/send_status() - var/list/kv = list( - "type" = "secbot", - "name" = name, - "loca" = loc.loc, // area - "mode" = mode - ) - post_signal_multiple(control_freq, kv) - - - -// calculates a path to the current destination -// given an optional turf to avoid -/obj/machinery/bot/secbot/proc/calc_path(var/turf/avoid = null) - src.path = AStar(src.loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 120, id=botcard, exclude=avoid) - if(!src.path) - src.path = list() - - // look for a criminal in view of the bot /obj/machinery/bot/secbot/proc/look_for_perp() - src.anchored = 0 + anchored = 0 for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal if((C.stat) || (C.handcuffed)) continue - if((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) + if((C.name == oldtarget_name) && (world.time < last_found + 100)) continue - src.threatlevel = C.assess_threat(src) + threatlevel = C.assess_threat(src) - if(!src.threatlevel) + if(!threatlevel) continue - else if(src.threatlevel >= 4) - src.target = C - src.oldtarget_name = C.name - src.speak("Level [src.threatlevel] infraction alert!") - playsound(src.loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, 0) - src.visible_message("[src] points at [C.name]!") - mode = SECBOT_HUNT + else if(threatlevel >= 4) + target = C + oldtarget_name = C.name + speak("Level [threatlevel] infraction alert!") + playsound(loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, 0) + visible_message("[src] points at [C.name]!") + mode = BOT_HUNT spawn(0) process() // ensure bot quickly responds to a perp break else continue - /obj/machinery/bot/secbot/proc/check_for_weapons(var/obj/item/slot_item) if(istype(slot_item, /obj/item/weapon/gun) || istype(slot_item, /obj/item/weapon/melee)) if(!(slot_item.type in safe_weapons)) return 1 return 0 -/obj/machinery/bot/secbot/Bump(M as mob|obj) //Leave no door unopened! - if((istype(M, /obj/machinery/door)) && (!isnull(src.botcard))) - var/obj/machinery/door/D = M - if(!istype(D, /obj/machinery/door/firedoor) && D.check_access(src.botcard)) - D.open() - src.frustration = 0 - else if((istype(M, /mob/living/)) && (!src.anchored)) - src.loc = M:loc - src.frustration = 0 - return - -/* terrible -/obj/machinery/bot/secbot/Bumped(atom/movable/M as mob|obj) - spawn(0) - if(M) - var/turf/T = get_turf(src) - M:loc = T -*/ - /obj/machinery/bot/secbot/explode() walk_to(src,0) - src.visible_message("[src] blows apart!") + visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) var/obj/item/weapon/secbot_assembly/Sa = new /obj/item/weapon/secbot_assembly(Tsec) Sa.build_step = 1 Sa.overlays += "hs_hole" - Sa.created_name = src.name + Sa.created_name = name new /obj/item/device/assembly/prox_sensor(Tsec) new /obj/item/weapon/melee/baton(Tsec) @@ -686,14 +376,14 @@ Auto Patrol: []"}, s.set_up(3, 1, src) s.start() - new /obj/effect/decal/cleanable/oil(src.loc) + new /obj/effect/decal/cleanable/oil(loc) qdel(src) /obj/machinery/bot/secbot/attack_alien(var/mob/living/carbon/alien/user as mob) ..() if(!isalien(target)) - src.target = user - src.mode = SECBOT_HUNT + target = user + mode = BOT_HUNT //Secbot Construction @@ -703,7 +393,7 @@ Auto Patrol: []"}, ..() return - if(src.type != /obj/item/clothing/head/helmet) //Eh, but we don't want people making secbots out of space helmets. + if(type != /obj/item/clothing/head/helmet) //Eh, but we don't want people making secbots out of space helmets. return if(S.secured) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 0bd36e3f74e..b76e33dad0b 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -76,14 +76,15 @@ emped = emped+1 //Increase the number of consecutive EMP's var/thisemp = emped //Take note of which EMP this proc is for spawn(900) - if(emped == thisemp) //Only fix it if the camera hasn't been EMP'd again - network = previous_network - icon_state = initial(icon_state) - stat &= ~EMPED - cancelCameraAlarm() - if(can_use()) - cameranet.addCamera(src) - emped = 0 //Resets the consecutive EMP count + if(loc) //qdel limbo + if(emped == thisemp) //Only fix it if the camera hasn't been EMP'd again + network = previous_network + icon_state = initial(icon_state) + stat &= ~EMPED + cancelCameraAlarm() + if(can_use()) + cameranet.addCamera(src) + emped = 0 //Resets the consecutive EMP count for(var/mob/O in mob_list) if (O.client && O.client.eye == src) O.unset_machine() diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm index dbba680f885..e7a8f509cd9 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -281,25 +281,22 @@ // Holographic Items! -/turf/simulated/floor/holofloor/ +/turf/simulated/floor/holofloor thermal_conductivity = 0 /turf/simulated/floor/holofloor/grass gender = PLURAL name = "lush grass" icon_state = "grass1" - floor_tile = new/obj/item/stack/tile/grass + floor_tile = /obj/item/stack/tile/grass - New() - floor_tile.New() //I guess New() isn't run on objects spawned without the definition of a turf to house them, ah well. - icon_state = "grass[pick("1","2","3","4")]" - ..() - spawn(4) +/turf/simulated/floor/holofloor/grass/New() + ..() + icon_state = "grass[pick("1","2","3","4")]" + spawn(1) + if(src) update_icon() - for(var/direction in cardinal) - if(istype(get_step(src,direction),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,direction) - FF.update_icon() //so siding get updated properly + fancy_update(type) /turf/simulated/floor/holofloor/attackby(obj/item/weapon/W as obj, mob/user as mob) return @@ -456,7 +453,7 @@ visible_message(" [user] dunks [W] into the [src]!", 3) return -/obj/structure/holohoop/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/obj/structure/holohoop/CanPass(atom/movable/mover, turf/target, height=0) if (istype(mover,/obj/item) && mover.throwing) var/obj/item/I = mover if(istype(I, /obj/item/projectile)) @@ -468,7 +465,7 @@ visible_message(" \the [I] bounces off of \the [src]'s rim!", 3) return 0 else - return ..(mover, target, height, air_group) + return ..(mover, target, height) /obj/machinery/readybutton diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index c4e52d403ad..f68c7bf7c36 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -34,6 +34,37 @@ proc/crewmonitor(mob/user,var/atom/source) + var/jobs[0] + jobs["Captain"] = 00 + jobs["Head of Personnel"] = 50 + jobs["Head of Security"] = 10 + jobs["Warden"] = 11 + jobs["Security Officer"] = 12 + jobs["Detective"] = 13 + jobs["Chief Medical Officer"] = 20 + jobs["Chemist"] = 21 + jobs["Geneticist"] = 22 + jobs["Virologist"] = 23 + jobs["Medical Doctor"] = 24 + jobs["Research Director"] = 30 + jobs["Scientist"] = 31 + jobs["Roboticist"] = 32 + jobs["Chief Engineer"] = 40 + jobs["Station Engineer"] = 41 + jobs["Atmospheric Technician"] = 42 + jobs["Quartermaster"] = 51 + jobs["Shaft Miner"] = 52 + jobs["Cargo Technician"] = 53 + jobs["Bartender"] = 61 + jobs["Chef"] = 62 + jobs["Botanist"] = 63 + jobs["Librarian"] = 64 + jobs["Chaplain"] = 65 + jobs["Clown"] = 66 + jobs["Mime"] = 67 + jobs["Janitor"] = 68 + jobs["Assistant"] = 99 //Unknowns/custom jobs should appear after civilians, and before assistants + var/t = "" var/list/logs = list() var/list/tracked = crewscan() @@ -44,17 +75,30 @@ proc/crewmonitor(mob/user,var/atom/source) if(istype(H.w_uniform, /obj/item/clothing/under)) var/obj/item/clothing/under/U = H.w_uniform if(pos && pos.z == srcturf.z && U.sensor_mode) - var/obj/item/ID = null + var/obj/item/weapon/card/id/I = null if(H.wear_id) - ID = H.wear_id.GetID() - + I = H.wear_id.GetID() var/life_status = "[H.stat > 1 ? "Deceased" : "Living"]" - if(ID) - log += "" + if(I) + var/style = null + var/ijob = jobs[I.assignment] + if(ijob % 10 == 0) + style += "font-weight: bold; " //head roles always end in 0 + if(ijob >= 10 && ijob < 20) + style += "color: #E74C3C; " //security + if(ijob >= 20 && ijob < 30) + style += "color: #3498DB; " //medical + if(ijob >= 30 && ijob < 40) + style += "color: #9B59B6; " //science + if(ijob >= 40 && ijob < 50) + style += "color: #F1C40F; " //engineering + if(ijob >= 50 && ijob < 60) + style += "color: #F39C12; " //cargo + log += "[ijob]]" //ijob does not get displayed, nor does it take up space, it's just used for the positioning of an entry else - log += "" + log += "80" var/damage_report if(U.sensor_mode > 1) @@ -62,13 +106,13 @@ proc/crewmonitor(mob/user,var/atom/source) var/dam2 = round(H.getToxLoss(),1) var/dam3 = round(H.getFireLoss(),1) var/dam4 = round(H.getBruteLoss(),1) - damage_report = "([dam1]/[dam2]/[dam3]/[dam4])" + damage_report = "([dam1]/[dam2]/[dam3]/[dam4])" switch(U.sensor_mode) if(1) - log += "" + log += "" if(2) - log += "" + log += "" if(3) var/area/player_area = get_area(H) log += "" diff --git a/code/game/machinery/computer/shuttle.dm b/code/game/machinery/computer/shuttle.dm index 414bd7a56f2..2f8881e4c4c 100644 --- a/code/game/machinery/computer/shuttle.dm +++ b/code/game/machinery/computer/shuttle.dm @@ -38,8 +38,9 @@ log_game("[user.ckey]([user]) has authorized early shuttle launch in ([x],[y],[z])") minor_announce("[src.auth_need - src.authorized.len] more authorization(s) needed until shuttle is launched early",null,1) else - message_admins("[key_name(user.client)](?) has launched the emergency shuttle in ([x],[y],[z] - JMP)",0,1) - log_game("[user.ckey]([user]) has launched the emergency shuttle in ([x],[y],[z])") + var/time = emergency_shuttle.timeleft() + message_admins("[key_name(user.client)](?) has launched the emergency shuttle in ([x],[y],[z] - JMP) [time] seconds before launch.",0,1) + log_game("[user.ckey]([user]) has launched the emergency shuttle in ([x],[y],[z]) [time] seconds before launch.") minor_announce("The emergency shuttle will launch in 10 seconds",null,1) emergency_shuttle.online = 1 emergency_shuttle.settimeleft(10) @@ -62,8 +63,9 @@ if(!emagged && emergency_shuttle.location == DOCKED && user.get_active_hand() == W) switch(choice) if("Launch") - message_admins("[key_name(user.client)](?) has emagged the emergency shuttle in ([x],[y],[z] - JMP)",0,1) - log_game("[user.ckey]([user]) has emagged the emergency shuttle in ([x],[y],[z])") + var/time = emergency_shuttle.timeleft() + message_admins("[key_name(user.client)](?) has emagged the emergency shuttle in ([x],[y],[z] - JMP) [time] seconds before launch.",0,1) + log_game("[user.ckey]([user]) has emagged the emergency shuttle in ([x],[y],[z]) [time] seconds before launch.") minor_announce("The emergency shuttle will launch in 10 seconds", "SYSTEM ERROR:",null,1) emergency_shuttle.settimeleft( 10 ) emagged = 1 diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index 4434006a2ef..a5ca16a2368 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -114,8 +114,8 @@ for reference: qdel(src) return -/obj/structure/barricade/wooden/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)//So bullets will fly over and stuff. - if(air_group || (height==0)) +/obj/structure/barricade/wooden/CanPass(atom/movable/mover, turf/target, height=0)//So bullets will fly over and stuff. + if(height==0) return 1 if(istype(mover) && mover.checkpass(PASSTABLE)) return 1 @@ -235,8 +235,8 @@ for reference: src.explode() return -/obj/machinery/deployable/barrier/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)//So bullets will fly over and stuff. - if(air_group || (height==0)) +/obj/machinery/deployable/barrier/CanPass(atom/movable/mover, turf/target, height=0)//So bullets will fly over and stuff. + if(height==0) return 1 if(istype(mover) && mover.checkpass(PASSTABLE)) return 1 diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 715a50195b6..91890d4b665 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -75,8 +75,7 @@ ..() move_update_air(T) -/obj/machinery/door/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group) return 0 +/obj/machinery/door/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover) && mover.checkpass(PASSGLASS)) return !opacity return !density diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 97e1a4f7f6a..4f3c30e26bf 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -110,11 +110,10 @@ flags = ON_BORDER -/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover) && mover.checkpass(PASSGLASS)) return 1 if(get_dir(loc, target) == dir) //Make sure looking at appropriate border - if(air_group) return 0 return !density else return 1 diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 0d7284f2a4a..fa3d6098f00 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -71,11 +71,10 @@ flick(text("[]deny", src.base_state), src) return -/obj/machinery/door/window/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/obj/machinery/door/window/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover) && mover.checkpass(PASSGLASS)) return 1 if(get_dir(loc, target) == dir) //Make sure looking at appropriate border - if(air_group) return 0 return !density else return 1 diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index 72e0126433d..c75dd415940 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -5,7 +5,7 @@ desc = "A wall-mounted flashbulb device." icon = 'icons/obj/stationobjs.dmi' icon_state = "mflash1" - var/obj/item/device/flash/bulb = null + var/obj/item/device/flash/handheld/bulb = null var/id = null var/range = 2 //this is roughly the size of brig cell var/last_flash = 0 //Don't want it getting spammed like regular flashes @@ -23,7 +23,7 @@ density = 1 /obj/machinery/flasher/New() - bulb = new /obj/item/device/flash(src) + bulb = new /obj/item/device/flash/handheld(src) /obj/machinery/flasher/power_change() if (powered() && anchored && bulb) @@ -40,13 +40,15 @@ /obj/machinery/flasher/attackby(obj/item/weapon/W, mob/user) if (istype(W, /obj/item/weapon/wirecutters)) if (bulb) + user.visible_message("[user] begins to disconnect [src]'s flashbulb.", "You begin to disconnect [src]'s flashbulb.") playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) - user.visible_message("[user] has disconnected [src]'s flashbulb!", "You disconnect [src]'s flashbulb!") - bulb.loc = src.loc - bulb = null - power_change() + if(do_after(user, 30)) + user.visible_message("[user] has disconnected [src]'s flashbulb!", "You disconnect [src]'s flashbulb!") + bulb.loc = src.loc + bulb = null + power_change() - else if (istype(W, /obj/item/device/flash)) + else if (istype(W, /obj/item/device/flash/handheld)) if (!bulb) user.visible_message("[user] installs [W] into [src].", "You install [W] into [src].") user.drop_item() @@ -174,4 +176,4 @@ icon_state = "launcherbtt" active = 0 - return \ No newline at end of file + return diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 52e3037b635..0d8bc250c32 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -364,9 +364,9 @@ emagged = 1 on=0 - sleep(rand(60,600)) - if(!on) - on=1 + spawn(rand(60,600)) + if(!on) + on=1 ..() @@ -459,31 +459,18 @@ targets += C //if the perp has passed all previous tests, congrats, it is now a "shoot-me!" nominee - if(targets.len > 0) //if there are targets to shoot - - var/atom/t = pick(targets) //pick a perp from the list of targets. Targets go first because they are the most important - - if(istype(t, /mob/living)) //if a mob - var/mob/living/M = t //simple typecasting - if(M.stat != DEAD) //if the target is not dead - spawn() - popUp() //pop the turret up if it's not already up. - dir = get_dir(src, M) //even if you can't shoot, follow the target - spawn() - shootAt(M) //shoot the target, finally - - else - if(secondarytargets.len > 0) //if there are no primary targets, go for secondary targets - var/mob/t = pick(secondarytargets) - if(istype(t, /mob/living)) - if(t.stat != DEAD) - spawn() - popUp() - dir=get_dir(src, t) - shootAt(t) - else + if(!tryToShootAt(targets)) + if(!tryToShootAt(secondarytargets)) // if no valid targets, go for secondary targets spawn() - popDown() + popDown() // no valid targets, close the cover + + +/obj/machinery/porta_turret/proc/tryToShootAt(var/list/mob/living/targets) + while(targets.len > 0) + var/mob/living/M = pick(targets) + targets -= M + if(target(M)) + return 1 /obj/machinery/porta_turret/proc/popUp() //pops the turret up @@ -573,15 +560,19 @@ return threatcount -/obj/machinery/porta_turret/proc/shootAt(atom/movable/target) //shoots at a target +/obj/machinery/porta_turret/proc/target(var/mob/living/target) if(disabled) return + if(target && (target.stat != DEAD) && (!(target.lying) || emagged)) + spawn() + popUp() //pop the turret up if it's not already up. + dir = get_dir(src, target) //even if you can't shoot, follow the target + spawn() + shootAt(target) + return 1 + return - if(lasercolor && istype(target,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = target - if(H.lying) - return - +/obj/machinery/porta_turret/proc/shootAt(var/mob/living/target) 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 return diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 2220eb7c732..a5006803963 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -26,8 +26,8 @@ ..() move_update_air(T) -/obj/machinery/shield/CanPass(atom/movable/mover, turf/target, height, air_group) - if(!height || air_group) return 0 +/obj/machinery/shield/CanPass(atom/movable/mover, turf/target, height) + if(!height) return 0 else return ..() /obj/machinery/shield/CanAtmosPass(var/turf/T) @@ -594,8 +594,8 @@ return -/obj/machinery/shieldwall/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 +/obj/machinery/shieldwall/CanPass(atom/movable/mover, turf/target, height=0) + if(height==0) return 1 if(istype(mover) && mover.checkpass(PASSGLASS)) return prob(20) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 1c03577f66c..2cacd1b075e 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -428,7 +428,7 @@ var/mob/living/user = usr if(islocked) user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT + user.last_special = world.time + CLICK_CD_BREAKOUT var/breakout_time = 2 user << "You start kicking against the doors to escape! (This will take about [breakout_time] minutes.)" visible_message("You see [user] kicking against the doors of the [src]!") diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index 5f00666e819..a4c672dc38a 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -42,7 +42,7 @@ AM.loc = src.loc do_transform(AM) -/obj/machinery/transformer/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/obj/machinery/transformer/CanPass(atom/movable/mover, turf/target, height=0) if(!ishuman(mover)) // Allows items to go through, to stop them from blocking the conveyour belt. var/dir = get_dir(src, mover) if(dir == EAST) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 2670407895f..a5342f470df 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -715,7 +715,7 @@ icon_state = "sec" icon_deny = "sec-deny" req_access_txt = "1" - products = list(/obj/item/weapon/restraints/handcuffs = 8,/obj/item/weapon/restraints/handcuffs/cable/zipties = 10,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, + products = list(/obj/item/weapon/restraints/handcuffs = 8,/obj/item/weapon/restraints/handcuffs/cable/zipties = 10,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash/handheld = 5, /obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6,/obj/item/device/flashlight/seclite = 4) contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/fancy/donut_box = 2) @@ -757,7 +757,7 @@ vend_delay = 15 vend_reply = "Have an enchanted evening!" product_ads = "FJKLFJSD;AJKFLBJAKL;1234 LOONIES LOL!;>MFW;Kill them fuckers!;GET DAT FUKKEN DISK;HONK!;EI NATH;Destroy the station!;Admin conspiracies since forever!;Space-time bending hardware!" - products = list(/obj/item/clothing/head/wizard = 1,/obj/item/clothing/suit/wizrobe = 1,/obj/item/clothing/head/wizard/red = 1,/obj/item/clothing/suit/wizrobe/red = 1,/obj/item/clothing/shoes/sandal = 1,/obj/item/weapon/staff = 2) + products = list(/obj/item/clothing/head/wizard = 1,/obj/item/clothing/suit/wizrobe = 1,/obj/item/clothing/head/wizard/red = 1,/obj/item/clothing/suit/wizrobe/red = 1,/obj/item/clothing/head/wizard/yellow = 1,/obj/item/clothing/suit/wizrobe/yellow = 1,/obj/item/clothing/shoes/sandal = 1,/obj/item/weapon/staff = 2) contraband = list(/obj/item/weapon/reagent_containers/glass/bottle/wizarditis = 1) //No one can get to the machine to hack it anyways; for the lulz - Microwave /obj/machinery/vending/autodrobe @@ -773,8 +773,7 @@ /obj/item/clothing/head/helmet/gladiator = 1,/obj/item/clothing/under/gimmick/rank/captain/suit = 1,/obj/item/clothing/head/flatcap = 1, /obj/item/clothing/suit/labcoat/mad = 1,/obj/item/clothing/glasses/gglasses = 1,/obj/item/clothing/shoes/jackboots = 1, /obj/item/clothing/under/schoolgirl = 1,/obj/item/clothing/head/kitty = 1,/obj/item/clothing/under/blackskirt = 1,/obj/item/clothing/head/beret = 1, - /obj/item/clothing/tie/waistcoat = 1,/obj/item/clothing/under/suit_jacket = 1,/obj/item/clothing/head/that =1,/obj/item/clothing/head/cueball = 1, - /obj/item/clothing/under/scratch = 1,/obj/item/clothing/under/kilt = 1,/obj/item/clothing/head/beret = 1,/obj/item/clothing/tie/waistcoat = 1, + /obj/item/clothing/tie/waistcoat = 1,/obj/item/clothing/under/suit_jacket = 1,/obj/item/clothing/head/that =1,/obj/item/clothing/under/kilt = 1,/obj/item/clothing/head/beret = 1,/obj/item/clothing/tie/waistcoat = 1, /obj/item/clothing/glasses/monocle =1,/obj/item/clothing/head/bowler = 1,/obj/item/weapon/cane = 1,/obj/item/clothing/under/sl_suit = 1, /obj/item/clothing/mask/fakemoustache = 1,/obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 1,/obj/item/clothing/head/plaguedoctorhat = 1, /obj/item/clothing/under/owl = 1,/obj/item/clothing/mask/gas/owl_mask = 1,/obj/item/clothing/suit/apron = 1,/obj/item/clothing/under/waiter = 1, @@ -858,7 +857,7 @@ icon_state = "robotics" icon_deny = "robotics-deny" req_access_txt = "29" - products = list(/obj/item/clothing/suit/labcoat = 4,/obj/item/clothing/under/rank/roboticist = 4,/obj/item/stack/cable_coil = 4,/obj/item/device/flash = 4, + products = list(/obj/item/clothing/suit/labcoat = 4,/obj/item/clothing/under/rank/roboticist = 4,/obj/item/stack/cable_coil = 4,/obj/item/device/flash/handheld = 4, /obj/item/weapon/stock_parts/cell/high = 12, /obj/item/device/assembly/prox_sensor = 3,/obj/item/device/assembly/signaler = 3,/obj/item/device/healthanalyzer = 3, /obj/item/weapon/scalpel = 2,/obj/item/weapon/circular_saw = 2,/obj/item/weapon/tank/anesthetic = 2,/obj/item/clothing/mask/breath/medical = 5, /obj/item/weapon/screwdriver = 5,/obj/item/weapon/crowbar = 5) diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index 7ebf0183f41..65b49cca717 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -5,20 +5,9 @@ var/list/destroyable_obj = list(/obj/mecha, /obj/structure/window, /obj/structure/grille, /turf/simulated/wall) internal_damage_threshold = 50 maint_access = 0 - //add_req_access = 0 - //operation_req_access = list(access_hos) damage_absorption = list("brute"=0.7,"fire"=1,"bullet"=0.7,"laser"=0.85,"energy"=1,"bomb"=0.8) var/am = "d3c2fbcadca903a41161ccc9df9cf948" -/* -/obj/mecha/combat/range_action(target as obj|mob|turf) - if(internal_damage&MECHA_INT_CONTROL_LOST) - target = pick(view(3,target)) - if(selected_weapon) - selected_weapon.fire(target) - return -*/ - /obj/mecha/combat/melee_action(target as obj|mob|turf) if(internal_damage&MECHA_INT_CONTROL_LOST) target = safepick(oview(1,src)) @@ -26,21 +15,10 @@ if(istype(target, /mob/living)) var/mob/living/M = target if(src.occupant.a_intent == "harm") - playsound(src, 'sound/weapons/punch4.ogg', 50, 1) if(damtype == "brute") step_away(M,src,15) - /* - if(M.stat>1) - M.gib() - melee_can_hit = 0 - if(do_after(melee_cooldown)) - melee_can_hit = 1 - return - */ if(istype(target, /mob/living/carbon/human)) var/mob/living/carbon/human/H = target - // if (M.health <= 0) return - var/obj/item/organ/limb/temp = H.get_organ(pick("chest", "chest", "chest", "head")) if(temp) var/update = 0 @@ -48,14 +26,17 @@ if("brute") H.Paralyse(1) update |= temp.take_damage(rand(force/2, force), 0) + playsound(src, 'sound/weapons/punch4.ogg', 50, 1) if("fire") update |= temp.take_damage(0, rand(force/2, force)) + playsound(src, 'sound/items/Welder.ogg', 50, 1) if("tox") + playsound(src, 'sound/effects/spray2.ogg', 50, 1) if(H.reagents) - if(H.reagents.get_reagent_amount("carpotoxin") + force < force*2) - H.reagents.add_reagent("carpotoxin", force) if(H.reagents.get_reagent_amount("cryptobiolin") + force < force*2) - H.reagents.add_reagent("cryptobiolin", force) + H.reagents.add_reagent("cryptobiolin", force/2) + if(H.reagents.get_reagent_amount("toxin") + force < force*2) + H.reagents.add_reagent("toxin", force/2.5) else return if(update) H.update_damage_overlays(0) @@ -66,14 +47,17 @@ if("brute") M.Paralyse(1) M.take_overall_damage(rand(force/2, force)) + playsound(src, 'sound/weapons/punch4.ogg', 50, 1) if("fire") M.take_overall_damage(0, rand(force/2, force)) + playsound(src, 'sound/items/Welder.ogg', 50, 1) if("tox") + playsound(src, 'sound/effects/spray2.ogg', 50, 1) if(M.reagents) - if(M.reagents.get_reagent_amount("carpotoxin") + force < force*2) - M.reagents.add_reagent("carpotoxin", force) if(M.reagents.get_reagent_amount("cryptobiolin") + force < force*2) - M.reagents.add_reagent("cryptobiolin", force) + M.reagents.add_reagent("cryptobiolin", force/2) + if(M.reagents.get_reagent_amount("toxin") + force < force*2) + M.reagents.add_reagent("toxin", force/2.5) else return M.updatehealth() @@ -109,134 +93,6 @@ break return -/* -/obj/mecha/combat/proc/mega_shake(target) - if(!istype(target, /obj) && !istype(target, /mob)) return - if(istype(target, /mob)) - var/mob/M = target - M.Dizzy(3) - M.adjustBruteLoss(1) - M.updatehealth() - for (var/mob/V in viewers(src)) - V.show_message("[src.name] shakes [M] like a rag doll.") - return -*/ - -/* - if(energy>0 && can_move) - if(step(src,direction)) - can_move = 0 - spawn(step_in) can_move = 1 - if(overload) - energy = energy-2 - health-- - else - energy-- - return 1 - - return 0 -*/ -/* -/obj/mecha/combat/hear_talk(mob/M as mob, text) - ..() - if(am && M==occupant) - if(findtext(text,"")) - sam() - return - -/obj/mecha/combat/proc/sam() - if(am) - var/window = {" - - - - - -
-
- - - -
- - - "} - occupant << browse(window, "window=sam;size=800x600;") - onclose(occupant, "sam", src) - return -*/ /obj/mecha/combat/moved_inside(var/mob/living/carbon/human/H as mob) if(..()) if(H.client) diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm index a0010e1a893..52818f4c72a 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/game/mecha/combat/marauder.dm @@ -94,50 +94,21 @@ return /obj/mecha/combat/marauder/relaymove(mob/user,direction) - if(user != src.occupant) //While not "realistic", this piece is player friendly. - user.loc = get_turf(src) - user << "You climb out from [src]" - return 0 - if(!can_move) - return 0 if(zoom) if(world.time - last_message > 20) src.occupant_message("Unable to move while in zoom mode.") last_message = world.time return 0 - if(connected_port) - if(world.time - last_message > 20) - src.occupant_message("Unable to move while connected to the air system port") - last_message = world.time - return 0 - if(!thrusters && pr_inertial_movement && src.pr_inertial_movement.active()) - return 0 - if(state || !has_charge(step_energy_drain)) - return 0 - var/tmp_step_in = step_in - var/tmp_step_energy_drain = step_energy_drain - var/move_result = 0 - if(internal_damage&MECHA_INT_CONTROL_LOST) - move_result = mechsteprand() - else if(src.dir!=direction) - move_result = mechturn(direction) - else - move_result = mechstep(direction) - if(move_result) - if(istype(src.loc, /turf/space)) - if(!src.check_for_support() && pr_inertial_movement) - src.pr_inertial_movement.start(list(src,direction)) - if(thrusters) - src.pr_inertial_movement.set_process_args(list(src,direction)) - tmp_step_energy_drain = step_energy_drain*2 + return ..() - can_move = 0 - spawn(tmp_step_in) can_move = 1 - use_power(tmp_step_energy_drain) + +/obj/mecha/combat/marauder/Process_Spacemove(var/movement_dir = 0) + if(..()) + return 1 + if(thrusters && movement_dir && use_power(step_energy_drain)) return 1 return 0 - /obj/mecha/combat/marauder/verb/toggle_thrusters() set category = "Exosuit Interface" set name = "Toggle thrusters" diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm index 465a1b7a06e..4260976a41a 100644 --- a/code/game/mecha/combat/phazon.dm +++ b/code/game/mecha/combat/phazon.dm @@ -1,9 +1,9 @@ /obj/mecha/combat/phazon - desc = "An exosuit which can only be described as 'WTF?'." + desc = "This is a Phazon exosuit. The pinnacle of scientific research and pride of Nanotrasen, it uses cutting edge bluespace technology and expensive materials." name = "\improper Phazon" icon_state = "phazon" - step_in = 1 - dir_in = 1 //Facing North. + step_in = 2 + dir_in = 2 //Facing South. step_energy_drain = 3 health = 200 deflect_chance = 30 @@ -12,21 +12,11 @@ infra_luminosity = 3 wreckage = /obj/structure/mecha_wreckage/phazon add_req_access = 1 - //operation_req_access = list() internal_damage_threshold = 25 force = 15 var/phasing = 0 var/phasing_energy_drain = 200 - max_equip = 4 - - -/obj/mecha/combat/phazon/New() - ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tool/rcd - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/gravcatapult - ME.attach(src) - return + max_equip = 3 /obj/mecha/combat/phazon/Bump(var/atom/obstacle) if(phasing && get_charge()>=phasing_energy_drain) @@ -51,20 +41,23 @@ /obj/mecha/combat/phazon/verb/switch_damtype() set category = "Exosuit Interface" - set name = "Change melee damage type" + set name = "Reconfigure arm microtool arrays" set src = usr.loc set popup_menu = 0 if(usr!=src.occupant) return - var/new_damtype = alert(src.occupant,"Melee Damage Type",null,"Brute","Fire","Toxic") + var/new_damtype = alert(src.occupant,"Arm tool selection",null,"Fists","Torch","Toxic injector") switch(new_damtype) - if("Brute") + if("Fists") damtype = "brute" - if("Fire") + src.occupant_message("Your exosuit's hands form into fists.") + if("Torch") damtype = "fire" - if("Toxic") + src.occupant_message("A torch tip extends from your exosuit's hand, glowing red.") + if("Toxic injector") damtype = "tox" - src.occupant_message("Melee damage type switched to [new_damtype ]") + src.occupant_message("A bone-chillingly thick plasteel needle protracts from the exosuit's palm.") + playsound(src, 'sound/mecha/mechmove01.ogg', 50, 1) return /obj/mecha/combat/phazon/get_commands() @@ -72,7 +65,7 @@
Special
"} diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index 4cfc457473d..8b98ccf7021 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -233,164 +233,12 @@ M.AdjustStunned(-4) M.AdjustWeakened(-4) M.AdjustStunned(-4) - M.Paralyse(2) - M.Weaken(2) - M.Stun(2) if(M.reagents.get_reagent_amount("inaprovaline") < 5) M.reagents.add_reagent("inaprovaline", 5) S.chassis.use_power(S.energy_drain) S.update_equip_info() return - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer - name = "cable layer" - desc = "Equipment for engineering exosuits. Lays cable along the exosuit's path." - icon_state = "mecha_wire" - var/datum/event/event - var/turf/old_turf - var/obj/structure/cable/last_piece - var/obj/item/stack/cable_coil/cable - var/max_cable = 1000 - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/New() - cable = new(src) - cable.amount = 0 - ..() - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/can_attach(obj/mecha/working/M) - if(..()) - if(istype(M)) - return 1 - return 0 - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/attach() - ..() - event = chassis.events.addEvent("onMove",src,"layCable") - return - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/detach() - chassis.events.clearEvent("onMove",event) - return ..() - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/destroy() - chassis.events.clearEvent("onMove",event) - return ..() - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/action(var/obj/item/stack/cable_coil/target) - if(!action_checks(target)) - return - var/result = load_cable(target) - var/message - if(isnull(result)) - message = "Unable to load [target] - no cable found." - else if(!result) - message = "Reel is full." - else - message = "[result] meters of cable successfully loaded." - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - occupant_message(message) - return - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/Topic(href,href_list) - ..() - if(href_list["toggle"]) - set_ready_state(!equip_ready) - occupant_message("[src] [equip_ready?"dea":"a"]ctivated.") - log_message("[equip_ready?"Dea":"A"]ctivated.") - return - if(href_list["cut"]) - if(cable && cable.amount) - var/m = round(input(chassis.occupant,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1) - m = min(m, cable.amount) - if(m) - use_cable(m) - var/obj/item/stack/cable_coil/CC = new (get_turf(chassis)) - CC.amount = m - else - occupant_message("There's no more cable on the reel.") - return - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/get_equip_info() - var/output = ..() - if(output) - return "[output] \[Cable: [cable ? cable.amount : 0] m\][(cable && cable.amount) ? "- [!equip_ready?"Dea":"A"]ctivate|Cut" : null]" - return - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/load_cable(var/obj/item/stack/cable_coil/CC) - if(istype(CC) && CC.amount) - var/cur_amount = cable? cable.amount : 0 - var/to_load = max(max_cable - cur_amount,0) - if(to_load) - to_load = min(CC.amount, to_load) - if(!cable) - cable = new(src) - cable.amount = 0 - cable.amount += to_load - CC.use(to_load) - return to_load - else - return 0 - return - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/use_cable(amount) - if(!cable || cable.amount<1) - set_ready_state(1) - occupant_message("Cable depleted, [src] deactivated.") - log_message("Cable depleted, [src] deactivated.") - return - if(cable.amount < amount) - occupant_message("No enough cable to finish the task.") - return - cable.use(amount) - update_equip_info() - return 1 - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/reset() - last_piece = null - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/dismantleFloor(var/turf/new_turf) - if(istype(new_turf, /turf/simulated/floor)) - var/turf/simulated/floor/T = new_turf - if(!T.is_plating()) - if(!T.broken && !T.burnt) - new T.floor_tile.type(T) - T.make_plating() - return !new_turf.intact - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/layCable(var/turf/new_turf) - if(equip_ready || !istype(new_turf) || !dismantleFloor(new_turf)) - return reset() - var/fdirn = turn(chassis.dir,180) - for(var/obj/structure/cable/LC in new_turf) // check to make sure there's not a cable there already - if(LC.d1 == fdirn || LC.d2 == fdirn) - return reset() - if(!use_cable(1)) - return reset() - var/obj/structure/cable/NC = new(new_turf) - NC.cableColor("red") - NC.d1 = 0 - NC.d2 = fdirn - NC.updateicon() - - var/datum/powernet/PN - if(last_piece && last_piece.d2 != chassis.dir) - last_piece.d1 = min(last_piece.d2, chassis.dir) - last_piece.d2 = max(last_piece.d2, chassis.dir) - last_piece.updateicon() - PN = last_piece.powernet - - if(!PN) - PN = new() - powernets += PN - NC.powernet = PN - PN.cables += NC - NC.mergeConnectedNetworks(NC.d2) - - //NC.mergeConnectedNetworksOnTurf() - last_piece = NC - return 1 - /obj/item/mecha_parts/mecha_equipment/tool/syringe_gun name = "exosuit syringe gun" desc = "Equipment for medical exosuits. A chem synthesizer with syringe gun. Reagents inside are held in stasis, so no reactions will occur." diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index 70051b606d6..e646edb306d 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -214,8 +214,8 @@ range = MELEE|RANGED /obj/item/mecha_parts/mecha_equipment/tool/extinguisher/New() - create_reagents(200) - reagents.add_reagent("water", 200) + create_reagents(1000) + reagents.add_reagent("water", 1000) ..() return @@ -226,7 +226,7 @@ if(do_after_cooldown(target)) if(istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1) var/obj/o = target - o.reagents.trans_to(src, 200) + o.reagents.trans_to(src, 1000) occupant_message("Extinguisher refilled.") playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6) else @@ -379,6 +379,153 @@ return "[..()] \[D|C|A\]" +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer + name = "cable layer" + desc = "Equipment for engineering exosuits. Lays cable along the exosuit's path." + icon_state = "mecha_wire" + var/datum/event/event + var/turf/old_turf + var/obj/structure/cable/last_piece + var/obj/item/stack/cable_coil/cable + var/max_cable = 1000 + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/New() + cable = new(src) + cable.amount = 0 + ..() + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/can_attach(obj/mecha/working/M) + if(..()) + if(istype(M)) + return 1 + return 0 + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/attach() + ..() + event = chassis.events.addEvent("onMove",src,"layCable") + return + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/detach() + chassis.events.clearEvent("onMove",event) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/destroy() + chassis.events.clearEvent("onMove",event) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/action(var/obj/item/stack/cable_coil/target) + if(!action_checks(target)) + return + var/result = load_cable(target) + var/message + if(isnull(result)) + message = "Unable to load [target] - no cable found." + else if(!result) + message = "Reel is full." + else + message = "[result] meters of cable successfully loaded." + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + occupant_message(message) + return + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/Topic(href,href_list) + ..() + if(href_list["toggle"]) + set_ready_state(!equip_ready) + occupant_message("[src] [equip_ready?"dea":"a"]ctivated.") + log_message("[equip_ready?"Dea":"A"]ctivated.") + return + if(href_list["cut"]) + if(cable && cable.amount) + var/m = round(input(chassis.occupant,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1) + m = min(m, cable.amount) + if(m) + use_cable(m) + var/obj/item/stack/cable_coil/CC = new (get_turf(chassis)) + CC.amount = m + else + occupant_message("There's no more cable on the reel.") + return + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/get_equip_info() + var/output = ..() + if(output) + return "[output] \[Cable: [cable ? cable.amount : 0] m\][(cable && cable.amount) ? "- [!equip_ready?"Dea":"A"]ctivate|Cut" : null]" + return + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/load_cable(var/obj/item/stack/cable_coil/CC) + if(istype(CC) && CC.amount) + var/cur_amount = cable? cable.amount : 0 + var/to_load = max(max_cable - cur_amount,0) + if(to_load) + to_load = min(CC.amount, to_load) + if(!cable) + cable = new(src) + cable.amount = 0 + cable.amount += to_load + CC.use(to_load) + return to_load + else + return 0 + return + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/use_cable(amount) + if(!cable || cable.amount<1) + set_ready_state(1) + occupant_message("Cable depleted, [src] deactivated.") + log_message("Cable depleted, [src] deactivated.") + return + if(cable.amount < amount) + occupant_message("No enough cable to finish the task.") + return + cable.use(amount) + update_equip_info() + return 1 + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/reset() + last_piece = null + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/dismantleFloor(var/turf/new_turf) + if(istype(new_turf, /turf/simulated/floor)) + var/turf/simulated/floor/T = new_turf + if(!istype(T, /turf/simulated/floor/plating)) + if(!T.broken && !T.burnt) + new T.floor_tile(T) + T.make_plating() + return !new_turf.intact + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/layCable(var/turf/new_turf) + if(equip_ready || !istype(new_turf) || !dismantleFloor(new_turf)) + return reset() + var/fdirn = turn(chassis.dir,180) + for(var/obj/structure/cable/LC in new_turf) // check to make sure there's not a cable there already + if(LC.d1 == fdirn || LC.d2 == fdirn) + return reset() + if(!use_cable(1)) + return reset() + var/obj/structure/cable/NC = new(new_turf) + NC.cableColor("red") + NC.d1 = 0 + NC.d2 = fdirn + NC.updateicon() + + var/datum/powernet/PN + if(last_piece && last_piece.d2 != chassis.dir) + last_piece.d1 = min(last_piece.d2, chassis.dir) + last_piece.d2 = max(last_piece.d2, chassis.dir) + last_piece.updateicon() + PN = last_piece.powernet + + if(!PN) + PN = new() + powernets += PN + NC.powernet = PN + PN.cables += NC + NC.mergeConnectedNetworks(NC.d2) + + //NC.mergeConnectedNetworksOnTurf() + last_piece = NC + return 1 /obj/item/mecha_parts/mecha_equipment/teleporter @@ -869,8 +1016,8 @@ var/coeff = 100 var/obj/item/stack/sheet/fuel var/max_fuel = 150000 - var/fuel_per_cycle_idle = 100 - var/fuel_per_cycle_active = 500 + var/fuel_per_cycle_idle = 25 + var/fuel_per_cycle_active = 200 var/power_per_cycle = 20 reliability = 1000 diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index 23417f8f67b..53e3d9ed383 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -3,6 +3,8 @@ icon = 'icons/turf/floors.dmi' // That are set in stone to check the west turf for recharge port icon_state = "recharge_floor" // Some people just want to watch the world burn i guess +/turf/simulated/floor/mech_bay_recharge_floor/break_tile() + src.ChangeTurf(/turf/simulated/floor/plating) /turf/simulated/floor/mech_bay_recharge_floor/airless icon_state = "recharge_floor_asteroid" diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 0447d2cd81e..5e844cdcdf7 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -49,6 +49,7 @@ ), "Ripley"=list( /obj/item/mecha_parts/chassis/ripley, + /obj/item/mecha_parts/chassis/firefighter, /obj/item/mecha_parts/part/ripley_torso, /obj/item/mecha_parts/part/ripley_left_arm, /obj/item/mecha_parts/part/ripley_right_arm, @@ -93,7 +94,17 @@ /obj/item/mecha_parts/part/honker_right_arm, /obj/item/mecha_parts/part/honker_left_leg, /obj/item/mecha_parts/part/honker_right_leg - ), + ), + "Phazon"=list( + /obj/item/mecha_parts/chassis/phazon, + /obj/item/mecha_parts/part/phazon_torso, + /obj/item/mecha_parts/part/phazon_head, + /obj/item/mecha_parts/part/phazon_left_arm, + /obj/item/mecha_parts/part/phazon_right_arm, + /obj/item/mecha_parts/part/phazon_left_leg, + /obj/item/mecha_parts/part/phazon_right_leg, + /obj/item/mecha_parts/part/phazon_armor + ), "Exosuit Equipment"=list( /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp, /obj/item/mecha_parts/mecha_equipment/tool/drill, @@ -101,8 +112,7 @@ /obj/item/mecha_parts/mecha_equipment/tool/cable_layer, /obj/item/mecha_parts/mecha_equipment/tool/sleeper, /obj/item/mecha_parts/mecha_equipment/tool/syringe_gun, - /obj/item/mecha_parts/chassis/firefighter, - ///obj/item/mecha_parts/mecha_equipment/repair_droid, + /obj/item/mecha_parts/mecha_equipment/repair_droid, /obj/item/mecha_parts/mecha_equipment/generator, ///obj/item/mecha_parts/mecha_equipment/jetpack, //TODO MECHA JETPACK SPRITE MISSING /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser, @@ -729,17 +739,19 @@ return 0 var/result = 0 var/obj/item/stack/sheet/res = new type(src) - var/total_amount = round(resources[mat_string]/MINERAL_MATERIAL_AMOUNT) - res.amount = min(total_amount,res.max_amount) - if(res.amount>0) + if(amount>0 && amount<=50) + var/total_amount = round(resources[mat_string]/MINERAL_MATERIAL_AMOUNT) + res.amount = min(amount,total_amount) resources[mat_string] -= res.amount*MINERAL_MATERIAL_AMOUNT res.Move(src.loc) result = res.amount else + result = 0 qdel(res) return result + /obj/machinery/mecha_part_fabricator/attackby(obj/W as obj, mob/user as mob) if(default_deconstruction_screwdriver(user, "fab-o", "fab-idle", W)) return diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 1096f5d5533..acbe4455335 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -57,7 +57,6 @@ var/list/internals_req_access = list(access_engine,access_robotics)//required access level to open cell compartment var/datum/global_iterator/pr_int_temp_processor //normalizes internal air mixture temperature - var/datum/global_iterator/pr_inertial_movement //controls intertial movement in spesss var/datum/global_iterator/pr_give_air //moves air from tank to cabin var/datum/global_iterator/pr_internal_damage //processes internal damage @@ -130,12 +129,10 @@ internal_tank = null qdel(pr_int_temp_processor) - qdel(pr_inertial_movement) qdel(pr_give_air) qdel(pr_internal_damage) qdel(spark_system) pr_int_temp_processor = null - pr_inertial_movement = null pr_give_air = null pr_internal_damage = null spark_system = null @@ -183,7 +180,6 @@ /obj/mecha/proc/add_iterators() pr_int_temp_processor = new /datum/global_iterator/mecha_preserve_temp(list(src)) - pr_inertial_movement = new /datum/global_iterator/mecha_intertial_movement(null,0) pr_give_air = new /datum/global_iterator/mecha_tank_give_air(list(src)) pr_internal_damage = new /datum/global_iterator/mecha_internal_damage(list(src),0) @@ -206,13 +202,6 @@ return 1 - -/obj/mecha/proc/check_for_support() - if(locate(/obj/structure/grille, orange(1, src)) || locate(/obj/structure/lattice, orange(1, src)) || locate(/turf/simulated, orange(1, src)) || locate(/turf/unsimulated, orange(1, src))) - return 1 - else - return 0 - /obj/mecha/examine(mob/user) ..() var/integrity = health/initial(health)*100 @@ -304,11 +293,15 @@ //////// Movement procs //////// ////////////////////////////////// -/obj/mecha/Move() +/obj/mecha/Move(atom/newloc, direct) . = ..() if(.) events.fireEvent("onMove",get_turf(src)) - return + +/obj/mecha/Process_Spacemove(var/movement_dir = 0) + if(occupant) + return occupant.Process_Spacemove(movement_dir) //We'll just say you used the clamp to grab the wall + return ..() /obj/mecha/relaymove(mob/user,direction) if(user != src.occupant) //While not "realistic", this piece is player friendly. @@ -331,7 +324,7 @@ /obj/mecha/proc/dyndomove(direction) if(!can_move) return 0 - if(pr_inertial_movement && src.pr_inertial_movement.active()) + if(!Process_Spacemove(direction)) return 0 if(!has_charge(step_energy_drain)) return 0 @@ -341,14 +334,9 @@ else if(src.dir!=direction) move_result = mechturn(direction) else - move_result = mechstep(direction) + move_result = mechstep(direction) if(move_result) can_move = 0 - use_power(step_energy_drain) - if(istype(src.loc, /turf/space)) - if(!src.check_for_support() && pr_inertial_movement) - src.pr_inertial_movement.start(list(src,direction)) - src.log_message("Movement control lost. Inertial movement started.") if(do_after(step_in)) can_move = 1 return 1 @@ -468,9 +456,10 @@ if ((HULK in user.mutations) && !prob(src.deflect_chance)) src.take_damage(15) src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - user.visible_message("[user] hits [src.name], doing some damage.", "You hit [src.name] with all your might. The metal creaks and bends.") + user.visible_message("[user] hits [src.name], doing some damage.", "You hit [src.name] with all your might. The metal creaks and bends.") + src.occupant_message("[user] hits [src.name], doing some damage.") else - user.visible_message("[user] hits [src.name]. Nothing happens","You hit [src.name] with no visible effect.") + user.visible_message("[user] hits [src.name]. Nothing happens","You hit [src.name] with no visible effect.") src.log_append_to_last("Armor saved.") return @@ -480,12 +469,14 @@ /obj/mecha/attack_alien(mob/user as mob) src.log_message("Attack by alien. Attacker - [user].",1) + user.changeNext_move(CLICK_CD_MELEE) //Now stompy alien killer mechs are actually scary to aliens! if(!prob(src.deflect_chance)) src.take_damage(15) src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1) user << "You slash at the armored suit!" visible_message("The [user] slashes at [src.name]'s armor!") + src.occupant_message("The [user] slashes at [src.name]'s armor!") else src.log_append_to_last("Armor saved.") playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1) @@ -504,12 +495,13 @@ var/damage = rand(user.melee_damage_lower, user.melee_damage_upper) src.take_damage(damage) src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - visible_message("[user] [user.attacktext] [src]!") + visible_message("[user] [user.attacktext] [src]!") + src.occupant_message("[user] [user.attacktext] [src]!") add_logs(user, src, "attacked", admin=0) else src.log_append_to_last("Armor saved.") playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1) - src.occupant_message("The [user]'s attack is stopped by the armor.") + src.occupant_message("[user]'s attack is stopped by the armor.") visible_message("The [user] rebounds off [src.name]'s armor!") add_logs(user, src, "attacked", admin=0) return @@ -537,6 +529,8 @@ else if(istype(A, /obj)) var/obj/O = A if(O.throwforce) + src.occupant_message("[src.name] is hit by [A].") + src.visible_message("[src.name] is hit by [A].") src.take_damage(O.throwforce) src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) return @@ -562,6 +556,8 @@ ignore_threshold = 1 if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) src.take_damage(Proj.damage,Proj.flag) + src.occupant_message("[src.name] is hit by [Proj]!") + src.visible_message("[src.name] is hit by [Proj].") src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),ignore_threshold) Proj.on_hit(src) return @@ -644,7 +640,7 @@ return 0 else src.occupant_message("[user] hits [src] with [W].") - user.visible_message("[user] hits [src] with [W].", "You hit [src] with [W].") + user.visible_message("[user] hits [src] with [W].", "You hit [src] with [W].") src.take_damage(W.force,W.damtype) src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) return 1 @@ -653,7 +649,7 @@ ////// AttackBy ////// ////////////////////// -/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/mecha/attackby(obj/item/W as obj, mob/user as mob) if(istype(W, /obj/item/device/mmi)) if(mmi_move_inside(W,user)) @@ -764,7 +760,7 @@ user.visible_message("[user] attaches [W] to [src].", "You attach [W] to [src]") return - else + else if(!(W.flags&NOBLUDGEON)) call((proc_res["dynattackby"]||src), "dynattackby")(W,user) /* src.log_message("Attacked by [W]. Attacker - [user]") @@ -784,8 +780,6 @@ */ return - - /* /obj/mecha/attack_ai(var/mob/living/silicon/ai/user as mob) if(!istype(user, /mob/living/silicon/ai)) @@ -797,6 +791,8 @@ return */ + + ///////////////////////////////////// //////// Atmospheric stuff //////// ///////////////////////////////////// @@ -1706,16 +1702,6 @@ var/year_integer = text2num(year) // = 2013??? return stop() return -/datum/global_iterator/mecha_intertial_movement //inertial movement in space - delay = 7 - - process(var/obj/mecha/mecha as obj,direction) - if(direction) - if(!step(mecha, direction)||mecha.check_for_support()) - src.stop() - else - src.stop() - return /datum/global_iterator/mecha_internal_damage // processing internal damage diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index a26c10644b4..5ff59260334 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -76,7 +76,7 @@ ) /datum/construction/mecha/ripley_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to [holder].", "You connect [used_atom] to [holder]") + user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") holder.overlays += used_atom.icon_state+"+o" qdel(used_atom) return 1 @@ -113,35 +113,35 @@ //4 list("key"=/obj/item/weapon/weldingtool, "backkey"=/obj/item/weapon/wrench, - "desc"="Internal armor is wrenched"), + "desc"="Internal armor is wrenched."), //5 list("key"=/obj/item/weapon/wrench, "backkey"=/obj/item/weapon/crowbar, - "desc"="Internal armor is installed"), + "desc"="Internal armor is installed."), //6 list("key"=/obj/item/stack/sheet/metal, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Peripherals control module is secured"), + "desc"="Peripherals control module is secured."), //7 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Peripherals control module is installed"), + "desc"="Peripherals control module is installed."), //8 list("key"=/obj/item/weapon/circuitboard/mecha/ripley/peripherals, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Central control module is secured"), + "desc"="Central control module is secured."), //9 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Central control module is installed"), + "desc"="Central control module is installed."), //10 list("key"=/obj/item/weapon/circuitboard/mecha/ripley/main, "backkey"=/obj/item/weapon/screwdriver, - "desc"="The wiring is adjusted"), + "desc"="The wiring is adjusted."), //11 list("key"=/obj/item/weapon/wirecutters, "backkey"=/obj/item/weapon/screwdriver, - "desc"="The wiring is added"), + "desc"="The wiring is added."), //12 list("key"=/obj/item/stack/cable_coil, "backkey"=/obj/item/weapon/screwdriver, @@ -165,50 +165,50 @@ //TODO: better messages. switch(index) if(14) - user.visible_message("[user] connects [holder] hydraulic systems", "You connect [holder] hydraulic systems.") + user.visible_message("[user] connects the [holder] hydraulic systems", "You connect the [holder] hydraulic systems.") holder.icon_state = "ripley1" if(13) if(diff==FORWARD) - user.visible_message("[user] activates [holder] hydraulic systems.", "You activate [holder] hydraulic systems.") + user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") holder.icon_state = "ripley2" else - user.visible_message("[user] disconnects [holder] hydraulic systems", "You disconnect [holder] hydraulic systems.") + user.visible_message("[user] disconnects the [holder] hydraulic systems", "You disconnect the [holder] hydraulic systems.") holder.icon_state = "ripley0" if(12) if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [holder].", "You add the wiring to [holder].") + user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") holder.icon_state = "ripley3" else - user.visible_message("[user] deactivates [holder] hydraulic systems.", "You deactivate [holder] hydraulic systems.") + user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") holder.icon_state = "ripley1" if(11) if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [holder].", "You adjust the wiring of [holder].") + user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") holder.icon_state = "ripley4" else - user.visible_message("[user] removes the wiring from [holder].", "You remove the wiring from [holder].") + user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) coil.amount = 4 holder.icon_state = "ripley2" if(10) if(diff==FORWARD) - user.visible_message("[user] installs the central control module into [holder].", "You install the central computer mainboard into [holder].") + user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") qdel(used_atom) holder.icon_state = "ripley5" else - user.visible_message("[user] disconnects the wiring of [holder].", "You disconnect the wiring of [holder].") + user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") holder.icon_state = "ripley3" if(9) if(diff==FORWARD) user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") holder.icon_state = "ripley6" else - user.visible_message("[user] removes the central control module from [holder].", "You remove the central computer mainboard from [holder].") + user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") new /obj/item/weapon/circuitboard/mecha/ripley/main(get_turf(holder)) holder.icon_state = "ripley4" if(8) if(diff==FORWARD) - user.visible_message("[user] installs the peripherals control module into [holder].", "You install the peripherals control module into [holder].") + user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") qdel(used_atom) holder.icon_state = "ripley7" else @@ -219,51 +219,51 @@ user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") holder.icon_state = "ripley8" else - user.visible_message("[user] removes the peripherals control module from [holder].", "You remove the peripherals control module from [holder].") + user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") new /obj/item/weapon/circuitboard/mecha/ripley/peripherals(get_turf(holder)) holder.icon_state = "ripley6" if(6) if(diff==FORWARD) - user.visible_message("[user] installs internal armor layer to [holder].", "You install internal armor layer to [holder].") + user.visible_message("[user] installs the internal armor layer to the [holder].", "You install the internal armor layer to the [holder].") holder.icon_state = "ripley9" else user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") holder.icon_state = "ripley7" if(5) if(diff==FORWARD) - user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.") + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") holder.icon_state = "ripley10" else - user.visible_message("[user] pries internal armor layer from [holder].", "You pry internal armor layer from [holder].") + user.visible_message("[user] pries internal armor layer from the [holder].", "You pry internal armor layer from the [holder].") var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder)) MS.amount = 5 holder.icon_state = "ripley8" if(4) if(diff==FORWARD) - user.visible_message("[user] welds internal armor layer to [holder].", "You weld the internal armor layer to [holder].") + user.visible_message("[user] welds the internal armor layer to the [holder].", "You weld the internal armor layer to the [holder].") holder.icon_state = "ripley11" else user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") holder.icon_state = "ripley9" if(3) if(diff==FORWARD) - user.visible_message("[user] installs external reinforced armor layer to [holder].", "You install external reinforced armor layer to [holder].") + user.visible_message("[user] installs the external reinforced armor layer to the [holder].", "You install the external reinforced armor layer to the [holder].") holder.icon_state = "ripley12" else - user.visible_message("[user] cuts internal armor layer from [holder].", "You cut the internal armor layer from [holder].") + user.visible_message("[user] cuts the internal armor layer from the [holder].", "You cut the internal armor layer from the [holder].") holder.icon_state = "ripley10" if(2) if(diff==FORWARD) - user.visible_message("[user] secures external armor layer.", "You secure external reinforced armor layer.") + user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") holder.icon_state = "ripley13" else - user.visible_message("[user] pries external armor layer from [holder].", "You pry external armor layer from [holder].") + user.visible_message("[user] pries external armor layer from the [holder].", "You pry external armor layer from the [holder].") var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) MS.amount = 5 holder.icon_state = "ripley11" if(1) if(diff==FORWARD) - user.visible_message("[user] welds external armor layer to [holder].", "You weld external armor layer to [holder].") + user.visible_message("[user] welds the external armor layer to the [holder].", "You weld the external armor layer to the [holder].") else user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") holder.icon_state = "ripley12" @@ -286,7 +286,7 @@ ) /datum/construction/mecha/gygax_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to [holder].", "You connect [used_atom] to [holder]") + user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") holder.overlays += used_atom.icon_state+"+o" qdel(used_atom) return 1 @@ -322,59 +322,59 @@ //4 list("key"=/obj/item/weapon/weldingtool, "backkey"=/obj/item/weapon/wrench, - "desc"="Internal armor is wrenched"), + "desc"="Internal armor is wrenched."), //5 list("key"=/obj/item/weapon/wrench, "backkey"=/obj/item/weapon/crowbar, - "desc"="Internal armor is installed"), + "desc"="Internal armor is installed."), //6 list("key"=/obj/item/stack/sheet/metal, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Advanced capacitor is secured"), + "desc"="Advanced capacitor is secured."), //7 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Advanced capacitor is installed"), + "desc"="Advanced capacitor is installed."), //8 list("key"=/obj/item/weapon/stock_parts/capacitor/adv, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Advanced scanner module is secured"), + "desc"="Advanced scanner module is secured."), //9 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Advanced scanner module is installed"), + "desc"="Advanced scanner module is installed."), //10 list("key"=/obj/item/weapon/stock_parts/scanning_module/adv, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Scanning module is secured"), + "desc"="Scanning module is secured."), //11 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Scanning module is installed"), + "desc"="Scanning module is installed."), //12 list("key"=/obj/item/weapon/circuitboard/mecha/gygax/targeting, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Peripherals control module is secured"), + "desc"="Peripherals control module is secured."), //13 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Peripherals control module is installed"), + "desc"="Peripherals control module is installed."), //14 list("key"=/obj/item/weapon/circuitboard/mecha/gygax/peripherals, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Central control module is secured"), + "desc"="Central control module is secured."), //15 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Central control module is installed"), + "desc"="Central control module is installed."), //16 list("key"=/obj/item/weapon/circuitboard/mecha/gygax/main, "backkey"=/obj/item/weapon/screwdriver, - "desc"="The wiring is adjusted"), + "desc"="The wiring is adjusted."), //17 list("key"=/obj/item/weapon/wirecutters, "backkey"=/obj/item/weapon/screwdriver, - "desc"="The wiring is added"), + "desc"="The wiring is added."), //18 list("key"=/obj/item/stack/cable_coil, "backkey"=/obj/item/weapon/screwdriver, @@ -398,50 +398,50 @@ //TODO: better messages. switch(index) if(20) - user.visible_message("[user] connects [holder] hydraulic systems", "You connect [holder] hydraulic systems.") + user.visible_message("[user] connects the [holder] hydraulic systems", "You connect the [holder] hydraulic systems.") holder.icon_state = "gygax1" if(19) if(diff==FORWARD) - user.visible_message("[user] activates [holder] hydraulic systems.", "You activate [holder] hydraulic systems.") + user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") holder.icon_state = "gygax2" else - user.visible_message("[user] disconnects [holder] hydraulic systems", "You disconnect [holder] hydraulic systems.") + user.visible_message("[user] disconnects the [holder] hydraulic systems", "You disconnect the [holder] hydraulic systems.") holder.icon_state = "gygax0" if(18) if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [holder].", "You add the wiring to [holder].") + user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") holder.icon_state = "gygax3" else - user.visible_message("[user] deactivates [holder] hydraulic systems.", "You deactivate [holder] hydraulic systems.") + user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") holder.icon_state = "gygax1" if(17) if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [holder].", "You adjust the wiring of [holder].") + user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") holder.icon_state = "gygax4" else - user.visible_message("[user] removes the wiring from [holder].", "You remove the wiring from [holder].") + user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) coil.amount = 4 holder.icon_state = "gygax2" if(16) if(diff==FORWARD) - user.visible_message("[user] installs the central control module into [holder].", "You install the central computer mainboard into [holder].") + user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") qdel(used_atom) holder.icon_state = "gygax5" else - user.visible_message("[user] disconnects the wiring of [holder].", "You disconnect the wiring of [holder].") + user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") holder.icon_state = "gygax3" if(15) if(diff==FORWARD) user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") holder.icon_state = "gygax6" else - user.visible_message("[user] removes the central control module from [holder].", "You remove the central computer mainboard from [holder].") + user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") new /obj/item/weapon/circuitboard/mecha/gygax/main(get_turf(holder)) holder.icon_state = "gygax4" if(14) if(diff==FORWARD) - user.visible_message("[user] installs the peripherals control module into [holder].", "You install the peripherals control module into [holder].") + user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") qdel(used_atom) holder.icon_state = "gygax7" else @@ -452,12 +452,12 @@ user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") holder.icon_state = "gygax8" else - user.visible_message("[user] removes the peripherals control module from [holder].", "You remove the peripherals control module from [holder].") + user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") new /obj/item/weapon/circuitboard/mecha/gygax/peripherals(get_turf(holder)) holder.icon_state = "gygax6" if(12) if(diff==FORWARD) - user.visible_message("[user] installs the weapon control module into [holder].", "You install the weapon control module into [holder].") + user.visible_message("[user] installs the weapon control module into the [holder].", "You install the weapon control module into the [holder].") qdel(used_atom) holder.icon_state = "gygax9" else @@ -468,12 +468,12 @@ user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") holder.icon_state = "gygax10" else - user.visible_message("[user] removes the weapon control module from [holder].", "You remove the weapon control module from [holder].") + user.visible_message("[user] removes the weapon control module from the [holder].", "You remove the weapon control module from the [holder].") new /obj/item/weapon/circuitboard/mecha/gygax/targeting(get_turf(holder)) holder.icon_state = "gygax8" if(10) if(diff==FORWARD) - user.visible_message("[user] installs advanced scanner module to [holder].", "You install advanced scanner module to [holder].") + user.visible_message("[user] installs advanced scanner module to the [holder].", "You install advanced scanner module to the [holder].") qdel(used_atom) holder.icon_state = "gygax11" else @@ -484,12 +484,12 @@ user.visible_message("[user] secures the advanced scanner module.", "You secure the advanced scanner module.") holder.icon_state = "gygax12" else - user.visible_message("[user] removes the advanced scanner module from [holder].", "You remove the advanced scanner module from [holder].") + user.visible_message("[user] removes the advanced scanner module from the [holder].", "You remove the advanced scanner module from the [holder].") new /obj/item/weapon/stock_parts/scanning_module/adv(get_turf(holder)) holder.icon_state = "gygax10" if(8) if(diff==FORWARD) - user.visible_message("[user] installs advanced capacitor to [holder].", "You install advanced capacitor to [holder].") + user.visible_message("[user] installs advanced capacitor to the [holder].", "You install advanced capacitor to the [holder].") qdel(used_atom) holder.icon_state = "gygax13" else @@ -500,51 +500,51 @@ user.visible_message("[user] secures the advanced capacitor.", "You secure the advanced capacitor.") holder.icon_state = "gygax14" else - user.visible_message("[user] removes the advanced capacitor from [holder].", "You remove the advanced capacitor from [holder].") + user.visible_message("[user] removes the advanced capacitor from the [holder].", "You remove the advanced capacitor from the [holder].") new /obj/item/weapon/stock_parts/capacitor/adv(get_turf(holder)) holder.icon_state = "gygax12" if(6) if(diff==FORWARD) - user.visible_message("[user] installs internal armor layer to [holder].", "You install internal armor layer to [holder].") + user.visible_message("[user] installs the internal armor layer to the [holder].", "You install the internal armor layer to the [holder].") holder.icon_state = "gygax15" else user.visible_message("[user] unfastens the advanced capacitor.", "You unfasten the advanced capacitor.") holder.icon_state = "gygax13" if(5) if(diff==FORWARD) - user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.") + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") holder.icon_state = "gygax16" else - user.visible_message("[user] pries internal armor layer from [holder].", "You pry internal armor layer from [holder].") + user.visible_message("[user] pries internal armor layer from the [holder].", "You pry internal armor layer from the [holder].") var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder)) MS.amount = 5 holder.icon_state = "gygax14" if(4) if(diff==FORWARD) - user.visible_message("[user] welds internal armor layer to [holder].", "You weld the internal armor layer to [holder].") + user.visible_message("[user] welds the internal armor layer to the [holder].", "You weld the internal armor layer to the [holder].") holder.icon_state = "gygax17" else user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") holder.icon_state = "gygax15" if(3) if(diff==FORWARD) - user.visible_message("[user] installs Gygax Armor Plates to [holder].", "You install Gygax Armor Plates to [holder].") + user.visible_message("[user] installs Gygax Armor Plates to the [holder].", "You install Gygax Armor Plates to the [holder].") qdel(used_atom) holder.icon_state = "gygax18" else - user.visible_message("[user] cuts internal armor layer from [holder].", "You cut the internal armor layer from [holder].") + user.visible_message("[user] cuts the internal armor layer from the [holder].", "You cut the internal armor layer from the [holder].") holder.icon_state = "gygax16" if(2) if(diff==FORWARD) user.visible_message("[user] secures Gygax Armor Plates.", "You secure Gygax Armor Plates.") holder.icon_state = "gygax19" else - user.visible_message("[user] pries Gygax Armor Plates from [holder].", "You pry Gygax Armor Plates from [holder].") + user.visible_message("[user] pries Gygax Armor Plates from the [holder].", "You pry Gygax Armor Plates from the [holder].") new /obj/item/mecha_parts/part/gygax_armor(get_turf(holder)) holder.icon_state = "gygax17" if(1) if(diff==FORWARD) - user.visible_message("[user] welds Gygax Armor Plates to [holder].", "You weld Gygax Armor Plates to [holder].") + user.visible_message("[user] welds Gygax Armor Plates to the [holder].", "You weld Gygax Armor Plates to the [holder].") else user.visible_message("[user] unfastens Gygax Armor Plates.", "You unfasten Gygax Armor Plates.") holder.icon_state = "gygax18" @@ -565,7 +565,7 @@ ) /datum/construction/mecha/firefighter_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to [holder].", "You connect [used_atom] to [holder]") + user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") holder.overlays += used_atom.icon_state+"+o" qdel(used_atom) return 1 @@ -605,36 +605,36 @@ //5 list("key"=/obj/item/weapon/weldingtool, "backkey"=/obj/item/weapon/wrench, - "desc"="Internal armor is wrenched"), + "desc"="Internal armor is wrenched."), //6 list("key"=/obj/item/weapon/wrench, "backkey"=/obj/item/weapon/crowbar, - "desc"="Internal armor is installed"), + "desc"="Internal armor is installed."), //7 list("key"=/obj/item/stack/sheet/plasteel, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Peripherals control module is secured"), + "desc"="Peripherals control module is secured."), //8 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Peripherals control module is installed"), + "desc"="Peripherals control module is installed."), //9 list("key"=/obj/item/weapon/circuitboard/mecha/ripley/peripherals, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Central control module is secured"), + "desc"="Central control module is secured."), //10 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Central control module is installed"), + "desc"="Central control module is installed."), //11 list("key"=/obj/item/weapon/circuitboard/mecha/ripley/main, "backkey"=/obj/item/weapon/screwdriver, - "desc"="The wiring is adjusted"), + "desc"="The wiring is adjusted."), //12 list("key"=/obj/item/weapon/wirecutters, "backkey"=/obj/item/weapon/screwdriver, - "desc"="The wiring is added"), + "desc"="The wiring is added."), //13 list("key"=/obj/item/stack/cable_coil, "backkey"=/obj/item/weapon/screwdriver, @@ -658,50 +658,50 @@ //TODO: better messages. switch(index) if(15) - user.visible_message("[user] connects [holder] hydraulic systems", "You connect [holder] hydraulic systems.") + user.visible_message("[user] connects the [holder] hydraulic systems", "You connect the [holder] hydraulic systems.") holder.icon_state = "fireripley1" if(14) if(diff==FORWARD) - user.visible_message("[user] activates [holder] hydraulic systems.", "You activate [holder] hydraulic systems.") + user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") holder.icon_state = "fireripley2" else - user.visible_message("[user] disconnects [holder] hydraulic systems", "You disconnect [holder] hydraulic systems.") + user.visible_message("[user] disconnects the [holder] hydraulic systems", "You disconnect the [holder] hydraulic systems.") holder.icon_state = "fireripley0" if(13) if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [holder].", "You add the wiring to [holder].") + user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") holder.icon_state = "fireripley3" else - user.visible_message("[user] deactivates [holder] hydraulic systems.", "You deactivate [holder] hydraulic systems.") + user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") holder.icon_state = "fireripley1" if(12) if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [holder].", "You adjust the wiring of [holder].") + user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") holder.icon_state = "fireripley4" else - user.visible_message("[user] removes the wiring from [holder].", "You remove the wiring from [holder].") + user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) coil.amount = 4 holder.icon_state = "fireripley2" if(11) if(diff==FORWARD) - user.visible_message("[user] installs the central control module into [holder].", "You install the central computer mainboard into [holder].") + user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") qdel(used_atom) holder.icon_state = "fireripley5" else - user.visible_message("[user] disconnects the wiring of [holder].", "You disconnect the wiring of [holder].") + user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") holder.icon_state = "fireripley3" if(10) if(diff==FORWARD) user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") holder.icon_state = "fireripley6" else - user.visible_message("[user] removes the central control module from [holder].", "You remove the central computer mainboard from [holder].") + user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") new /obj/item/weapon/circuitboard/mecha/ripley/main(get_turf(holder)) holder.icon_state = "fireripley4" if(9) if(diff==FORWARD) - user.visible_message("[user] installs the peripherals control module into [holder].", "You install the peripherals control module into [holder].") + user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") qdel(used_atom) holder.icon_state = "fireripley7" else @@ -712,12 +712,12 @@ user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") holder.icon_state = "fireripley8" else - user.visible_message("[user] removes the peripherals control module from [holder].", "You remove the peripherals control module from [holder].") + user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") new /obj/item/weapon/circuitboard/mecha/ripley/peripherals(get_turf(holder)) holder.icon_state = "fireripley6" if(7) if(diff==FORWARD) - user.visible_message("[user] installs internal armor layer to [holder].", "You install internal armor layer to [holder].") + user.visible_message("[user] installs the internal armor layer to the [holder].", "You install the internal armor layer to the [holder].") holder.icon_state = "fireripley9" else user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") @@ -725,48 +725,48 @@ if(6) if(diff==FORWARD) - user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.") + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") holder.icon_state = "fireripley10" else - user.visible_message("[user] pries internal armor layer from [holder].", "You pry internal armor layer from [holder].") + user.visible_message("[user] pries internal armor layer from the [holder].", "You pry internal armor layer from the [holder].") var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) MS.amount = 5 holder.icon_state = "fireripley8" if(5) if(diff==FORWARD) - user.visible_message("[user] welds internal armor layer to [holder].", "You weld the internal armor layer to [holder].") + user.visible_message("[user] welds the internal armor layer to the [holder].", "You weld the internal armor layer to the [holder].") holder.icon_state = "fireripley11" else user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") holder.icon_state = "fireripley9" if(4) if(diff==FORWARD) - user.visible_message("[user] starts to install the external armor layer to [holder].", "You start to install the external armor layer to [holder].") + user.visible_message("[user] starts to install the external armor layer to the [holder].", "You start to install the external armor layer to the [holder].") holder.icon_state = "fireripley12" else - user.visible_message("[user] cuts internal armor layer from [holder].", "You cut the internal armor layer from [holder].") + user.visible_message("[user] cuts the internal armor layer from the [holder].", "You cut the internal armor layer from the [holder].") holder.icon_state = "fireripley10" if(3) if(diff==FORWARD) - user.visible_message("[user] installs external reinforced armor layer to [holder].", "You install external reinforced armor layer to [holder].") + user.visible_message("[user] installs the external reinforced armor layer to the [holder].", "You install the external reinforced armor layer to the [holder].") holder.icon_state = "fireripley13" else - user.visible_message("[user] removes the external armor from [holder].", "You remove the external armor from [holder].") + user.visible_message("[user] removes the external armor from the [holder].", "You remove the external armor from the [holder].") var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) MS.amount = 5 holder.icon_state = "fireripley11" if(2) if(diff==FORWARD) - user.visible_message("[user] secures external armor layer.", "You secure external reinforced armor layer.") + user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") holder.icon_state = "fireripley14" else - user.visible_message("[user] pries external armor layer from [holder].", "You pry external armor layer from [holder].") + user.visible_message("[user] pries external armor layer from the [holder].", "You pry external armor layer from the [holder].") var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) MS.amount = 5 holder.icon_state = "fireripley12" if(1) if(diff==FORWARD) - user.visible_message("[user] welds external armor layer to [holder].", "You weld external armor layer to [holder].") + user.visible_message("[user] welds the external armor layer to the [holder].", "You weld the external armor layer to the [holder].") else user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") holder.icon_state = "fireripley13" @@ -792,7 +792,7 @@ return check_all_steps(used_atom,user) /datum/construction/mecha/honker_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to [holder].", "You connect [used_atom] to [holder]") + user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") holder.overlays += used_atom.icon_state+"+o" qdel(used_atom) return 1 @@ -834,19 +834,19 @@ //TODO: better messages. switch(step) if(10) - user.visible_message("[user] installs the central control module into [holder].", "You install the central control module into [holder].") + user.visible_message("[user] installs the central control module into the [holder].", "You install the central control module into the [holder].") qdel(used_atom) if(8) - user.visible_message("[user] installs the peripherals control module into [holder].", "You install the peripherals control module into [holder].") + user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") qdel(used_atom) if(6) - user.visible_message("[user] installs the weapon control module into [holder].", "You install the weapon control module into [holder].") + user.visible_message("[user] installs the weapon control module into the [holder].", "You install the weapon control module into the [holder].") qdel(used_atom) if(4) - user.visible_message("[user] puts clown wig and mask on [holder].", "You put clown wig and mask on [holder].") + user.visible_message("[user] puts clown wig and mask on the [holder].", "You put clown wig and mask on the [holder].") qdel(used_atom) if(2) - user.visible_message("[user] puts clown boots on [holder].", "You put clown boots on [holder].") + user.visible_message("[user] puts clown boots on the [holder].", "You put clown boots on the [holder].") qdel(used_atom) return 1 @@ -865,7 +865,7 @@ ) /datum/construction/mecha/durand_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to [holder].", "You connect [used_atom] to [holder]") + user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") holder.overlays += used_atom.icon_state+"+o" qdel(used_atom) return 1 @@ -900,59 +900,59 @@ //4 list("key"=/obj/item/weapon/weldingtool, "backkey"=/obj/item/weapon/wrench, - "desc"="Internal armor is wrenched"), + "desc"="Internal armor is wrenched."), //5 list("key"=/obj/item/weapon/wrench, "backkey"=/obj/item/weapon/crowbar, - "desc"="Internal armor is installed"), + "desc"="Internal armor is installed."), //6 list("key"=/obj/item/stack/sheet/metal, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Advanced capacitor is secured"), + "desc"="Super capacitor is secured."), //7 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Advanced capacitor is installed"), + "desc"="Super capacitor is installed."), //8 - list("key"=/obj/item/weapon/stock_parts/capacitor/adv, + list("key"=/obj/item/weapon/stock_parts/capacitor/super, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Advanced scanner module is secured"), + "desc"="Phasic scanner module is secured."), //9 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Advanced scanner module is installed"), + "desc"="Phasic scanner module is installed."), //10 - list("key"=/obj/item/weapon/stock_parts/scanning_module/adv, + list("key"=/obj/item/weapon/stock_parts/scanning_module/phasic, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Scanning module is secured"), + "desc"="Scanning module is secured."), //11 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Scanning module is installed"), + "desc"="Scanning module is installed."), //12 list("key"=/obj/item/weapon/circuitboard/mecha/durand/targeting, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Peripherals control module is secured"), + "desc"="Peripherals control module is secured."), //13 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Peripherals control module is installed"), + "desc"="Peripherals control module is installed."), //14 list("key"=/obj/item/weapon/circuitboard/mecha/durand/peripherals, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Central control module is secured"), + "desc"="Central control module is secured."), //15 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Central control module is installed"), + "desc"="Central control module is installed."), //16 list("key"=/obj/item/weapon/circuitboard/mecha/durand/main, "backkey"=/obj/item/weapon/screwdriver, - "desc"="The wiring is adjusted"), + "desc"="The wiring is adjusted."), //17 list("key"=/obj/item/weapon/wirecutters, "backkey"=/obj/item/weapon/screwdriver, - "desc"="The wiring is added"), + "desc"="The wiring is added."), //18 list("key"=/obj/item/stack/cable_coil, "backkey"=/obj/item/weapon/screwdriver, @@ -977,50 +977,50 @@ //TODO: better messages. switch(index) if(20) - user.visible_message("[user] connects [holder] hydraulic systems", "You connect [holder] hydraulic systems.") + user.visible_message("[user] connects the [holder] hydraulic systems", "You connect the [holder] hydraulic systems.") holder.icon_state = "durand1" if(19) if(diff==FORWARD) - user.visible_message("[user] activates [holder] hydraulic systems.", "You activate [holder] hydraulic systems.") + user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") holder.icon_state = "durand2" else - user.visible_message("[user] disconnects [holder] hydraulic systems", "You disconnect [holder] hydraulic systems.") + user.visible_message("[user] disconnects the [holder] hydraulic systems", "You disconnect the [holder] hydraulic systems.") holder.icon_state = "durand0" if(18) if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [holder].", "You add the wiring to [holder].") + user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") holder.icon_state = "durand3" else - user.visible_message("[user] deactivates [holder] hydraulic systems.", "You deactivate [holder] hydraulic systems.") + user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") holder.icon_state = "durand1" if(17) if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [holder].", "You adjust the wiring of [holder].") + user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") holder.icon_state = "durand4" else - user.visible_message("[user] removes the wiring from [holder].", "You remove the wiring from [holder].") + user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) coil.amount = 4 holder.icon_state = "durand2" if(16) if(diff==FORWARD) - user.visible_message("[user] installs the central control module into [holder].", "You install the central computer mainboard into [holder].") + user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") qdel(used_atom) holder.icon_state = "durand5" else - user.visible_message("[user] disconnects the wiring of [holder].", "You disconnect the wiring of [holder].") + user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") holder.icon_state = "durand3" if(15) if(diff==FORWARD) user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") holder.icon_state = "durand6" else - user.visible_message("[user] removes the central control module from [holder].", "You remove the central computer mainboard from [holder].") + user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") new /obj/item/weapon/circuitboard/mecha/durand/main(get_turf(holder)) holder.icon_state = "durand4" if(14) if(diff==FORWARD) - user.visible_message("[user] installs the peripherals control module into [holder].", "You install the peripherals control module into [holder].") + user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") qdel(used_atom) holder.icon_state = "durand7" else @@ -1031,12 +1031,12 @@ user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") holder.icon_state = "durand8" else - user.visible_message("[user] removes the peripherals control module from [holder].", "You remove the peripherals control module from [holder].") + user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") new /obj/item/weapon/circuitboard/mecha/durand/peripherals(get_turf(holder)) holder.icon_state = "durand6" if(12) if(diff==FORWARD) - user.visible_message("[user] installs the weapon control module into [holder].", "You install the weapon control module into [holder].") + user.visible_message("[user] installs the weapon control module into the [holder].", "You install the weapon control module into the [holder].") qdel(used_atom) holder.icon_state = "durand9" else @@ -1047,12 +1047,12 @@ user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") holder.icon_state = "durand10" else - user.visible_message("[user] removes the weapon control module from [holder].", "You remove the weapon control module from [holder].") + user.visible_message("[user] removes the weapon control module from the [holder].", "You remove the weapon control module from the [holder].") new /obj/item/weapon/circuitboard/mecha/durand/targeting(get_turf(holder)) holder.icon_state = "durand8" if(10) if(diff==FORWARD) - user.visible_message("[user] installs advanced scanner module to [holder].", "You install advanced scanner module to [holder].") + user.visible_message("[user] installs phasic scanner module to the [holder].", "You install phasic scanner module to the [holder].") qdel(used_atom) holder.icon_state = "durand11" else @@ -1060,70 +1060,70 @@ holder.icon_state = "durand9" if(9) if(diff==FORWARD) - user.visible_message("[user] secures the advanced scanner module.", "You secure the advanced scanner module.") + user.visible_message("[user] secures the phasic scanner module.", "You secure the phasic scanner module.") holder.icon_state = "durand12" else - user.visible_message("[user] removes the advanced scanner module from [holder].", "You remove the advanced scanner module from [holder].") - new /obj/item/weapon/stock_parts/scanning_module/adv(get_turf(holder)) + user.visible_message("[user] removes the phasic scanner module from the [holder].", "You remove the phasic scanner module from the [holder].") + new /obj/item/weapon/stock_parts/scanning_module/phasic(get_turf(holder)) holder.icon_state = "durand10" if(8) if(diff==FORWARD) - user.visible_message("[user] installs advanced capacitor to [holder].", "You install advanced capacitor to [holder].") + user.visible_message("[user] installs super capacitor to the [holder].", "You install super capacitor to the [holder].") qdel(used_atom) holder.icon_state = "durand13" else - user.visible_message("[user] unfastens the advanced scanner module.", "You unfasten the advanced scanner module.") + user.visible_message("[user] unfastens the phasic scanner module.", "You unfasten the phasic scanner module.") holder.icon_state = "durand11" if(7) if(diff==FORWARD) - user.visible_message("[user] secures the advanced capacitor.", "You secure the advanced capacitor.") + user.visible_message("[user] secures the super capacitor.", "You secure the super capacitor.") holder.icon_state = "durand14" else - user.visible_message("[user] removes the advanced capacitor from [holder].", "You remove the advanced capacitor from [holder].") - new /obj/item/weapon/stock_parts/capacitor/adv(get_turf(holder)) + user.visible_message("[user] removes the super capacitor from the [holder].", "You remove the super capacitor from the [holder].") + new /obj/item/weapon/stock_parts/capacitor/super(get_turf(holder)) holder.icon_state = "durand12" if(6) if(diff==FORWARD) - user.visible_message("[user] installs internal armor layer to [holder].", "You install internal armor layer to [holder].") + user.visible_message("[user] installs the internal armor layer to the [holder].", "You install the internal armor layer to the [holder].") holder.icon_state = "durand15" else - user.visible_message("[user] unfastens the advanced capacitor.", "You unfasten the advanced capacitor.") + user.visible_message("[user] unfastens the super capacitor.", "You unfasten the super capacitor.") holder.icon_state = "durand13" if(5) if(diff==FORWARD) - user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.") + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") holder.icon_state = "durand16" else - user.visible_message("[user] pries internal armor layer from [holder].", "You pry internal armor layer from [holder].") + user.visible_message("[user] pries internal armor layer from the [holder].", "You pry internal armor layer from the [holder].") var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder)) MS.amount = 5 holder.icon_state = "durand14" if(4) if(diff==FORWARD) - user.visible_message("[user] welds internal armor layer to [holder].", "You weld the internal armor layer to [holder].") + user.visible_message("[user] welds the internal armor layer to the [holder].", "You weld the internal armor layer to the [holder].") holder.icon_state = "durand17" else user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") holder.icon_state = "durand15" if(3) if(diff==FORWARD) - user.visible_message("[user] installs Durand Armor Plates to [holder].", "You install Durand Armor Plates to [holder].") + user.visible_message("[user] installs Durand Armor Plates to the [holder].", "You install Durand Armor Plates to the [holder].") qdel(used_atom) holder.icon_state = "durand18" else - user.visible_message("[user] cuts internal armor layer from [holder].", "You cut the internal armor layer from [holder].") + user.visible_message("[user] cuts the internal armor layer from the [holder].", "You cut the internal armor layer from the [holder].") holder.icon_state = "durand16" if(2) if(diff==FORWARD) user.visible_message("[user] secures Durand Armor Plates.", "You secure Durand Armor Plates.") holder.icon_state = "durand19" else - user.visible_message("[user] pries Durand Armor Plates from [holder].", "You pry Durand Armor Plates from [holder].") + user.visible_message("[user] pries Durand Armor Plates from the [holder].", "You pry Durand Armor Plates from the [holder].") new /obj/item/mecha_parts/part/durand_armor(get_turf(holder)) holder.icon_state = "durand17" if(1) if(diff==FORWARD) - user.visible_message("[user] welds Durand Armor Plates to [holder].", "You weld Durand Armor Plates to [holder].") + user.visible_message("[user] welds Durand Armor Plates to the [holder].", "You weld Durand Armor Plates to the [holder].") else user.visible_message("[user] unfastens Durand Armor Plates.", "You unfasten Durand Armor Plates.") holder.icon_state = "durand18" @@ -1134,6 +1134,7 @@ feedback_inc("mecha_durand_created",1) return +//PHAZON /datum/construction/mecha/phazon_chassis result = "/obj/mecha/combat/phazon" @@ -1146,7 +1147,7 @@ ) /datum/construction/mecha/phazon_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to [holder].", "You connect [used_atom] to [holder]") + user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") holder.overlays += used_atom.icon_state+"+o" qdel(used_atom) return 1 @@ -1154,8 +1155,303 @@ /datum/construction/mecha/phazon_chassis/action(atom/used_atom,mob/user as mob) return check_all_steps(used_atom,user) +/datum/construction/mecha/phazon_chassis/spawn_result() + var/obj/item/mecha_parts/chassis/const_holder = holder + const_holder.construct = new /datum/construction/reversible/mecha/phazon(const_holder) + const_holder.icon = 'icons/mecha/mech_construction.dmi' + const_holder.icon_state = "phazon0" + const_holder.density = 1 + del src + return + +/datum/construction/reversible/mecha/phazon + result = "/obj/mecha/combat/phazon" + steps = list( + //1 + list("key"=/obj/item/weapon/weldingtool, + "backkey"=/obj/item/weapon/wrench, + "desc"="External armor is wrenched."), + //2 + list("key"=/obj/item/weapon/wrench, + "backkey"=/obj/item/weapon/crowbar, + "desc"="External armor is installed."), + //3 + list("key"=/obj/item/mecha_parts/part/phazon_armor, + "backkey"=/obj/item/weapon/weldingtool, + "desc"="Phase armor is welded."), + //4 + list("key"=/obj/item/weapon/weldingtool, + "backkey"=/obj/item/weapon/wrench, + "desc"="Phase armor is wrenched."), + //5 + list("key"=/obj/item/weapon/wrench, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Phase armor is installed."), + //6 + list("key"=/obj/item/stack/sheet/plasteel, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The bluespace crystal is engaged."), + //7 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/wirecutters, + "desc"="The bluespace crystal is connected."), + //8 + list("key"=/obj/item/stack/cable_coil, + "backkey"=/obj/item/weapon/crowbar, + "desc"="The bluespace crystal is installed."), + //9 + list("key"=/obj/item/bluespace_crystal, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Super capacitor is secured."), + //10 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Super capacitor is installed."), + //11 + list("key"=/obj/item/weapon/stock_parts/capacitor/super, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Phasic scanner module is secured."), + //12 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Phasic scanner module is installed."), + //13 + list("key"=/obj/item/weapon/stock_parts/scanning_module/phasic, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Scanning module is secured."), + //14 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Scanning module is installed."), + //15 + list("key"=/obj/item/weapon/circuitboard/mecha/phazon/targeting, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Peripherals control module is secured."), + //16 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Peripherals control module is installed"), + //17 + list("key"=/obj/item/weapon/circuitboard/mecha/phazon/peripherals, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Central control module is secured."), + //18 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Central control module is installed."), + //19 + list("key"=/obj/item/weapon/circuitboard/mecha/phazon/main, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The wiring is adjusted."), + //20 + list("key"=/obj/item/weapon/wirecutters, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The wiring is added."), + //21 + list("key"=/obj/item/stack/cable_coil, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The hydraulic systems are active."), + //22 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/wrench, + "desc"="The hydraulic systems are connected."), + //23 + list("key"=/obj/item/weapon/wrench, + "desc"="The hydraulic systems are disconnected.") + ) +/datum/construction/reversible/mecha/phazon/action(atom/used_atom,mob/user as mob) + return check_step(used_atom,user) + +/datum/construction/reversible/mecha/phazon/custom_action(index, diff, atom/used_atom, mob/user) + if(!..()) + return 0 + + //TODO: better messages. + switch(index) + if(23) + user.visible_message("[user] connects the [holder] hydraulic systems", "You connect the [holder] hydraulic systems.") + holder.icon_state = "phazon1" + if(22) + if(diff==FORWARD) + user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") + holder.icon_state = "phazon2" + else + user.visible_message("[user] disconnects the [holder] hydraulic systems", "You disconnect the [holder] hydraulic systems.") + holder.icon_state = "phazon0" + if(21) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") + holder.icon_state = "phazon3" + else + user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") + holder.icon_state = "phazon1" + if(20) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") + holder.icon_state = "phazon4" + else + user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") + var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) + coil.amount = 4 + holder.icon_state = "phazon2" + if(19) + if(diff==FORWARD) + user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") + qdel(used_atom) + holder.icon_state = "phazon5" + else + user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") + holder.icon_state = "phazon3" + if(18) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + holder.icon_state = "phazon6" + else + user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") + new /obj/item/weapon/circuitboard/mecha/phazon/main(get_turf(holder)) + holder.icon_state = "phazon4" + if(17) + if(diff==FORWARD) + user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") + qdel(used_atom) + holder.icon_state = "phazon7" + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + holder.icon_state = "phazon5" + if(16) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + holder.icon_state = "phazon8" + else + user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") + new /obj/item/weapon/circuitboard/mecha/phazon/peripherals(get_turf(holder)) + holder.icon_state = "phazon6" + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs the weapon control module into the [holder].", "You install the weapon control module into the [holder].") + qdel(used_atom) + holder.icon_state = "phazon9" + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + holder.icon_state = "phazon7" + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") + holder.icon_state = "phazon10" + else + user.visible_message("[user] removes the weapon control module from the [holder].", "You remove the weapon control module from the [holder].") + new /obj/item/weapon/circuitboard/mecha/phazon/targeting(get_turf(holder)) + holder.icon_state = "phazon8" + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs phasic scanner module to the [holder].", "You install phasic scanner module to the [holder].") + qdel(used_atom) + holder.icon_state = "phazon11" + else + user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") + holder.icon_state = "phazon9" + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures the phasic scanner module.", "You secure the phasic scanner module.") + holder.icon_state = "phazon12" + else + user.visible_message("[user] removes the phasic scanner module from the [holder].", "You remove the phasic scanner module from the [holder].") + new /obj/item/weapon/stock_parts/scanning_module/phasic(get_turf(holder)) + holder.icon_state = "phazon10" + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs super capacitor to the [holder].", "You install super capacitor to the [holder].") + qdel(used_atom) + holder.icon_state = "phazon13" + else + user.visible_message("[user] unfastens the phasic scanner module.", "You unfasten the phasic scanner module.") + holder.icon_state = "phazon11" + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the super capacitor.", "You secure the super capacitor.") + holder.icon_state = "phazon14" + else + user.visible_message("[user] removes the super capacitor from the [holder].", "You remove the super capacitor from the [holder].") + new /obj/item/weapon/stock_parts/capacitor/super(get_turf(holder)) + holder.icon_state = "phazon12" + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs the bluespace crystal.", "You install the bluespace crystal.") + qdel(used_atom) + holder.icon_state = "phazon15" + else + user.visible_message("[user] unsecures the super capacitor from the [holder].", "You unsecure the super capacitor from the [holder].") + holder.icon_state = "phazon13" + if(8) + if(diff==FORWARD) + user.visible_message("[user] connects the bluespace crystal.", "You connect the bluespace crystal.") + holder.icon_state = "phazon16" + else + user.visible_message("[user] removes the bluespace crystal from the [holder].", "You remove the bluespace crystal from the [holder].") + new /obj/item/bluespace_crystal(get_turf(holder)) + holder.icon_state = "phazon14" + if(7) + if(diff==FORWARD) + user.visible_message("[user] engages the bluespace crystal.", "You engage the bluespace crystal.") + holder.icon_state = "phazon17" + else + user.visible_message("[user] disconnects the bluespace crystal from the [holder].", "You disconnect the bluespace crystal from the [holder].") + holder.icon_state = "phazon15" + if(6) + if(diff==FORWARD) + user.visible_message("[user] installs the phase armor layer to the [holder].", "You install the phase armor layer to the [holder].") + holder.icon_state = "phazon18" + else + user.visible_message("[user] disengages the bluespace crystal.", "You disengage the bluespace crystal.") + holder.icon_state = "phazon16" + if(5) + if(diff==FORWARD) + user.visible_message("[user] secures the phase armor layer.", "You secure the phase armor layer.") + holder.icon_state = "phazon19" + else + user.visible_message("[user] pries the phase armor layer from the [holder].", "You pry the phase armor layer from the [holder].") + var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) + MS.amount = 5 + holder.icon_state = "phazon17" + if(4) + if(diff==FORWARD) + user.visible_message("[user] welds the phase armor layer to the [holder].", "You weld the phase armor layer to the [holder].") + holder.icon_state = "phazon20" + else + user.visible_message("[user] unfastens the phase armor layer.", "You unfasten the phase armor layer.") + holder.icon_state = "phazon18" + if(3) + if(diff==FORWARD) + user.visible_message("[user] installs Phazon Armor Plates to the [holder].", "You install Phazon Armor Plates to the [holder].") + qdel(used_atom) + holder.icon_state = "phazon21" + else + user.visible_message("[user] cuts phase armor layer from the [holder].", "You cut the phase armor layer from the [holder].") + holder.icon_state = "phazon19" + if(2) + if(diff==FORWARD) + user.visible_message("[user] secures Phazon Armor Plates.", "You secure Phazon Armor Plates.") + holder.icon_state = "phazon22" + else + user.visible_message("[user] pries Phazon Armor Plates from the [holder].", "You pry Phazon Armor Plates from the [holder].") + new /obj/item/mecha_parts/part/phazon_armor(get_turf(holder)) + holder.icon_state = "phazon20" + if(1) + if(diff==FORWARD) + user.visible_message("[user] welds Phazon Armor Plates to the [holder].", "You weld Phazon Armor Plates to the [holder].") + else + user.visible_message("[user] unfastens Phazon Armor Plates.", "You unfasten Phazon Armor Plates.") + holder.icon_state = "phazon21" + return 1 + +/datum/construction/reversible/mecha/phazon/spawn_result() + ..() + feedback_inc("mecha_phazon_created",1) + return + +//ODYSSEUS /datum/construction/mecha/odysseus_chassis steps = list(list("key"=/obj/item/mecha_parts/part/odysseus_torso),//1 @@ -1167,7 +1463,7 @@ ) /datum/construction/mecha/odysseus_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to [holder].", "You connect [used_atom] to [holder]") + user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") holder.overlays += used_atom.icon_state+"+o" qdel(used_atom) return 1 @@ -1203,35 +1499,35 @@ //4 list("key"=/obj/item/weapon/weldingtool, "backkey"=/obj/item/weapon/wrench, - "desc"="Internal armor is wrenched"), + "desc"="Internal armor is wrenched."), //5 list("key"=/obj/item/weapon/wrench, "backkey"=/obj/item/weapon/crowbar, - "desc"="Internal armor is installed"), + "desc"="Internal armor is installed."), //6 list("key"=/obj/item/stack/sheet/metal, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Peripherals control module is secured"), + "desc"="Peripherals control module is secured."), //7 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Peripherals control module is installed"), + "desc"="Peripherals control module is installed."), //8 list("key"=/obj/item/weapon/circuitboard/mecha/odysseus/peripherals, "backkey"=/obj/item/weapon/screwdriver, - "desc"="Central control module is secured"), + "desc"="Central control module is secured."), //9 list("key"=/obj/item/weapon/screwdriver, "backkey"=/obj/item/weapon/crowbar, - "desc"="Central control module is installed"), + "desc"="Central control module is installed."), //10 list("key"=/obj/item/weapon/circuitboard/mecha/odysseus/main, "backkey"=/obj/item/weapon/screwdriver, - "desc"="The wiring is adjusted"), + "desc"="The wiring is adjusted."), //11 list("key"=/obj/item/weapon/wirecutters, "backkey"=/obj/item/weapon/screwdriver, - "desc"="The wiring is added"), + "desc"="The wiring is added."), //12 list("key"=/obj/item/stack/cable_coil, "backkey"=/obj/item/weapon/screwdriver, @@ -1255,50 +1551,50 @@ //TODO: better messages. switch(index) if(14) - user.visible_message("[user] connects [holder] hydraulic systems", "You connect [holder] hydraulic systems.") + user.visible_message("[user] connects the [holder] hydraulic systems", "You connect the [holder] hydraulic systems.") holder.icon_state = "odysseus1" if(13) if(diff==FORWARD) - user.visible_message("[user] activates [holder] hydraulic systems.", "You activate [holder] hydraulic systems.") + user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") holder.icon_state = "odysseus2" else - user.visible_message("[user] disconnects [holder] hydraulic systems", "You disconnect [holder] hydraulic systems.") + user.visible_message("[user] disconnects the [holder] hydraulic systems", "You disconnect the [holder] hydraulic systems.") holder.icon_state = "odysseus0" if(12) if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [holder].", "You add the wiring to [holder].") + user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") holder.icon_state = "odysseus3" else - user.visible_message("[user] deactivates [holder] hydraulic systems.", "You deactivate [holder] hydraulic systems.") + user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") holder.icon_state = "odysseus1" if(11) if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [holder].", "You adjust the wiring of [holder].") + user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") holder.icon_state = "odysseus4" else - user.visible_message("[user] removes the wiring from [holder].", "You remove the wiring from [holder].") + user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) coil.amount = 4 holder.icon_state = "odysseus2" if(10) if(diff==FORWARD) - user.visible_message("[user] installs the central control module into [holder].", "You install the central computer mainboard into [holder].") + user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") qdel(used_atom) holder.icon_state = "odysseus5" else - user.visible_message("[user] disconnects the wiring of [holder].", "You disconnect the wiring of [holder].") + user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") holder.icon_state = "odysseus3" if(9) if(diff==FORWARD) user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") holder.icon_state = "odysseus6" else - user.visible_message("[user] removes the central control module from [holder].", "You remove the central computer mainboard from [holder].") + user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") new /obj/item/weapon/circuitboard/mecha/odysseus/main(get_turf(holder)) holder.icon_state = "odysseus4" if(8) if(diff==FORWARD) - user.visible_message("[user] installs the peripherals control module into [holder].", "You install the peripherals control module into [holder].") + user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") qdel(used_atom) holder.icon_state = "odysseus7" else @@ -1309,52 +1605,52 @@ user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") holder.icon_state = "odysseus8" else - user.visible_message("[user] removes the peripherals control module from [holder].", "You remove the peripherals control module from [holder].") + user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") new /obj/item/weapon/circuitboard/mecha/odysseus/peripherals(get_turf(holder)) holder.icon_state = "odysseus6" if(6) if(diff==FORWARD) - user.visible_message("[user] installs internal armor layer to [holder].", "You install internal armor layer to [holder].") + user.visible_message("[user] installs the internal armor layer to the [holder].", "You install the internal armor layer to the [holder].") holder.icon_state = "odysseus9" else user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") holder.icon_state = "odysseus7" if(5) if(diff==FORWARD) - user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.") + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") holder.icon_state = "odysseus10" else - user.visible_message("[user] pries internal armor layer from [holder].", "You pry internal armor layer from [holder].") + user.visible_message("[user] pries internal armor layer from the [holder].", "You pry internal armor layer from the [holder].") var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder)) MS.amount = 5 holder.icon_state = "odysseus8" if(4) if(diff==FORWARD) - user.visible_message("[user] welds internal armor layer to [holder].", "You weld the internal armor layer to [holder].") + user.visible_message("[user] welds the internal armor layer to the [holder].", "You weld the internal armor layer to the [holder].") holder.icon_state = "odysseus11" else user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") holder.icon_state = "odysseus9" if(3) if(diff==FORWARD) - user.visible_message("[user] installs [used_atom] layer to [holder].", "You install external reinforced armor layer to [holder].") + user.visible_message("[user] installs [used_atom] layer to the [holder].", "You install the external reinforced armor layer to the [holder].") holder.icon_state = "odysseus12" else - user.visible_message("[user] cuts internal armor layer from [holder].", "You cut the internal armor layer from [holder].") + user.visible_message("[user] cuts the internal armor layer from the [holder].", "You cut the internal armor layer from the [holder].") holder.icon_state = "odysseus10" if(2) if(diff==FORWARD) - user.visible_message("[user] secures external armor layer.", "You secure external reinforced armor layer.") + user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") holder.icon_state = "odysseus13" else var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) MS.amount = 5 - user.visible_message("[user] pries [MS] from [holder].", "You pry [MS] from [holder].") + user.visible_message("[user] pries [MS] from the [holder].", "You pry [MS] from the [holder].") holder.icon_state = "odysseus11" if(1) if(diff==FORWARD) - user.visible_message("[user] welds external armor layer to [holder].", "You weld external armor layer to [holder].") + user.visible_message("[user] welds the external armor layer to the [holder].", "You weld the external armor layer to the [holder].") holder.icon_state = "odysseus14" else user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") diff --git a/code/game/mecha/mecha_parts.dm b/code/game/mecha/mecha_parts.dm index e360a94d5c5..068d175c06e 100644 --- a/code/game/mecha/mecha_parts.dm +++ b/code/game/mecha/mecha_parts.dm @@ -296,7 +296,7 @@ /obj/item/mecha_parts/chassis/phazon name = "\improper Phazon chassis" - origin_tech = "materials=7" + origin_tech = "materials=6" /obj/item/mecha_parts/chassis/phazon/New() ..() @@ -304,20 +304,23 @@ /obj/item/mecha_parts/part/phazon_torso name="\improper Phazon torso" + desc="A Phazon torso part. The socket for the bluespace core that powers the exosuit's unique phase drives is located in the middle." icon_state = "phazon_harness" construction_time = 300 construction_cost = list("metal"=35000,"glass"=10000,"plasma"=20000) - origin_tech = "programming=5;materials=7;bluespace=6;powerstorage=6" + origin_tech = "programming=5;materials=6;bluespace=5;powerstorage=5" /obj/item/mecha_parts/part/phazon_head name="\improper Phazon head" + desc="A Phazon head. Its sensors are carefully calibrated to provide vision and data even when the exosuit is phasing." icon_state = "phazon_head" construction_time = 200 construction_cost = list("metal"=15000,"glass"=5000,"plasma"=10000) - origin_tech = "programming=4;materials=5;magnets=6" + origin_tech = "programming=4;materials=5;magnets=5" /obj/item/mecha_parts/part/phazon_left_arm name="\improper Phazon left arm" + desc="A Phazon left arm. Several microtool arrays are located under the armor plating, which can be adjusted to the situation at hand." icon_state = "phazon_l_arm" construction_time = 200 construction_cost = list("metal"=20000,"plasma"=10000) @@ -325,6 +328,7 @@ /obj/item/mecha_parts/part/phazon_right_arm name="\improper Phazon right arm" + desc="A Phazon right arm. Several microtool arrays are located under the armor plating, which can be adjusted to the situation at hand." icon_state = "phazon_r_arm" construction_time = 200 construction_cost = list("metal"=20000,"plasma"=10000) @@ -332,6 +336,7 @@ /obj/item/mecha_parts/part/phazon_left_leg name="\improper Phazon left leg" + desc="A Phazon left leg. It contains the unique phase drives that allow the exosuit to phase through solid matter when engaged." icon_state = "phazon_l_leg" construction_time = 200 construction_cost = list("metal"=20000,"plasma"=10000) @@ -339,11 +344,19 @@ /obj/item/mecha_parts/part/phazon_right_leg name="\improper Phazon right leg" + desc="A Phazon right leg. It contains the unique phase drives that allow the exosuit to phase through solid matter when engaged." icon_state = "phazon_r_leg" construction_time = 200 construction_cost = list("metal"=20000,"plasma"=10000) origin_tech = "materials=5;bluespace=3;magnets=3" +/obj/item/mecha_parts/part/phazon_armor + name="Phazon armor" + desc="Phazon armor plates. They are layered with plasma to protect the pilot from the stress of phasing and have unusual properties." + icon_state = "phazon_armor" + construction_time = 300 + construction_cost = list("metal"=45000,"plasma"=30000) + origin_tech = "materials=6;bluespace=5;magnets=5" ///////// Odysseus @@ -494,4 +507,16 @@ name = "circuit board (Odysseus Central Control module)" icon_state = "mainboard" +/obj/item/weapon/circuitboard/mecha/phazon + origin_tech = "programming=5" +/obj/item/weapon/circuitboard/mecha/phazon/peripherals + name = "circuit board (Phazon Peripherals Control module)" + icon_state = "mcontroller" + +/obj/item/weapon/circuitboard/mecha/phazon/targeting + name = "circuit board (Phazon Weapon Control and Targeting module)" + icon_state = "mcontroller" + +/obj/item/weapon/circuitboard/mecha/phazon/main + name = "circuit board (Phazon Central Control module)" \ No newline at end of file diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index 73c06025803..0b74b55d837 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -1,10 +1,13 @@ /obj/mecha/working/ripley - desc = "Autonomous Power Loader Unit. The workhorse of the exosuit world." + desc = "Autonomous Power Loader Unit. This newer model is refitted with powerful armour against the dangers of the EVA mining process." name = "\improper APLU \"Ripley\"" icon_state = "ripley" - step_in = 6 + step_in = 5 max_temperature = 20000 health = 200 + lights_power = 7 + deflect_chance = 15 + damage_absorption = list("brute"=0.6,"bomb"=0.2) wreckage = /obj/structure/mecha_wreckage/ripley var/list/cargo = new var/cargo_capacity = 15 @@ -16,19 +19,49 @@ */ /obj/mecha/working/ripley/Destroy() + while(src.damage_absorption.["brute"] < 0.6) + new /obj/item/asteroid/goliath_hide(src.loc) + src.damage_absorption.["brute"] = src.damage_absorption.["brute"] + 0.1 //If a goliath-plated ripley gets killed, all the plates drop for(var/atom/movable/A in src.cargo) A.loc = loc step_rand(A) cargo.Cut() ..() +/obj/mecha/working/ripley/go_out() + ..() + if (src.damage_absorption.["brute"] < 0.6 && src.damage_absorption.["brute"] > 0.3) + src.overlays = null + src.overlays += image("icon" = "mecha.dmi", "icon_state" = "ripley-g-open") + else if (src.damage_absorption.["brute"] == 0.3) + src.overlays = null + src.overlays += image("icon" = "mecha.dmi", "icon_state" = "ripley-g-full-open") + +/obj/mecha/working/ripley/moved_inside(var/mob/living/carbon/human/H as mob) + ..() + if (src.damage_absorption.["brute"] < 0.6 && src.damage_absorption.["brute"] > 0.3) + src.overlays = null + src.overlays += image("icon" = "mecha.dmi", "icon_state" = "ripley-g") + else if (src.damage_absorption.["brute"] == 0.3) + src.overlays = null + src.overlays += image("icon" = "mecha.dmi", "icon_state" = "ripley-g-full") + +/obj/mecha/working/ripley/mmi_moved_inside(var/obj/item/device/mmi/mmi_as_oc as obj,mob/user as mob) + ..() + if (src.damage_absorption.["brute"] < 0.6 && src.damage_absorption.["brute"] > 0.3) + src.overlays = null + src.overlays += image("icon" = "mecha.dmi", "icon_state" = "ripley-g") + else if (src.damage_absorption.["brute"] == 0.3) + src.overlays = null + src.overlays += image("icon" = "mecha.dmi", "icon_state" = "ripley-g-full") + /obj/mecha/working/ripley/firefighter desc = "Standart APLU chassis was refitted with additional thermal protection and cistern." name = "\improper APLU \"Firefighter\"" icon_state = "firefighter" max_temperature = 65000 health = 250 - lights_power = 8 + lights_power = 7 damage_absorption = list("fire"=0.5,"bullet"=0.8,"bomb"=0.5) wreckage = /obj/structure/mecha_wreckage/ripley/firefighter @@ -38,7 +71,7 @@ icon_state = "deathripley" step_in = 3 opacity=0 - lights_power = 60 + lights_power = 7 wreckage = /obj/structure/mecha_wreckage/ripley/deathripley step_energy_drain = 0 diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index 60cd23d6c97..2bff7dd60a5 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -140,8 +140,7 @@ ..() -/obj/structure/alien/resin/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group) return 0 +/obj/structure/alien/resin/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover) && mover.checkpass(PASSGLASS)) return !opacity return !density diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 362b3eeb27b..70ebc8bc021 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -85,7 +85,7 @@ /obj/effect/anomaly/flux/New() ..() - aSignal.origin_tech = "powerstorage=5;programming=3;plasmatech=2" + aSignal.origin_tech = "powerstorage=6;programming=4;plasmatech=4" ///////////////////// @@ -97,7 +97,7 @@ /obj/effect/anomaly/bluespace/New() ..() - aSignal.origin_tech = "bluespace=5;magnets=3;powerstorage=2" + aSignal.origin_tech = "bluespace=5;magnets=5;powerstorage=3" /obj/effect/anomaly/bluespace/Bumped(atom/A) if(isliving(A)) @@ -112,7 +112,7 @@ /obj/effect/anomaly/pyro/New() ..() - aSignal.origin_tech = "plasmatech=5;powerstorage=3;biotech=3" + aSignal.origin_tech = "plasmatech=5;powerstorage=4;biotech=6" /obj/effect/anomaly/pyro/anomalyEffect() ..() @@ -129,7 +129,7 @@ /obj/effect/anomaly/bhole/New() ..() - aSignal.origin_tech = "materials=5;combat=4;engineering=3" + aSignal.origin_tech = "materials=5;combat=4;engineering=4" /obj/effect/anomaly/bhole/anomalyEffect() ..() diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm index 2919abd0090..c8cb4754943 100644 --- a/code/game/objects/effects/decals/misc.dm +++ b/code/game/objects/effects/decals/misc.dm @@ -6,11 +6,6 @@ anchored = 1 mouse_opacity = 0 -/obj/effect/decal/point/point() - set src in oview() - set hidden = 1 - return - // Used for spray that you spray at walls, tables, hydrovats etc /obj/effect/decal/spraystill density = 0 diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 62f0c9ba91a..34979a6dae0 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -370,8 +370,8 @@ steam.start() -- spawns the effect return -/obj/effect/effect/bad_smoke/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 +/obj/effect/effect/bad_smoke/CanPass(atom/movable/mover, turf/target, height=0) + if(height==0) return 1 if(istype(mover, /obj/item/projectile/beam)) var/obj/item/projectile/beam/B = mover B.damage = (B.damage/2) @@ -684,9 +684,9 @@ steam.start() -- spawns the effect /datum/effect/effect/system/ion_trail_follow/set_up(atom/atom) attach(atom) - oldposition = get_turf(atom) -/datum/effect/effect/system/ion_trail_follow/start() + +/datum/effect/effect/system/ion_trail_follow/start() //Whoever is responsible for this abomination of code should become an hero if(!src.on) src.on = 1 src.processing = 1 @@ -696,26 +696,22 @@ steam.start() -- spawns the effect if(T != src.oldposition) if(!has_gravity(T)) var/obj/effect/effect/ion_trails/I = new /obj/effect/effect/ion_trails(src.oldposition) - src.oldposition = T I.dir = src.holder.dir flick("ion_fade", I) I.icon_state = "blank" spawn( 20 ) if(I) I.delete() - spawn(2) - if(src.on) - src.processing = 1 - src.start() - else - spawn(2) - if(src.on) - src.processing = 1 - src.start() + src.oldposition = T + spawn(2) + if(src.on) + src.processing = 1 + src.start() /datum/effect/effect/system/ion_trail_follow/proc/stop() src.processing = 0 src.on = 0 + oldposition = null @@ -993,8 +989,7 @@ steam.start() -- spawns the effect else user << "You hit the metal foam to no effect." -/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0) - if(air_group) return 0 +/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target, height=1.5) return !density /obj/structure/foamedmetal/CanAtmosPass() diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 94915cfa2cc..ff65e9a4ecd 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -141,14 +141,6 @@ new /obj/item/clothing/head/that(src.loc) qdel(src) -/obj/effect/landmark/costume/scratch/New() - new /obj/item/clothing/gloves/white(src.loc) - new /obj/item/clothing/shoes/sneakers/white(src.loc) - new /obj/item/clothing/under/scratch(src.loc) - if (prob(30)) - new /obj/item/clothing/head/cueball(src.loc) - qdel(src) - /obj/effect/landmark/costume/highlander/New() new /obj/item/clothing/under/kilt(src.loc) new /obj/item/clothing/head/beret(src.loc) diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 0cc1312bb81..84099ef3522 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -3,6 +3,9 @@ unacidable = 1 var/i_attached//Added for possible image attachments to objects. For hallucinations and the like. +obj/effect/overlay/singularity_act() + return + /obj/effect/overlay/beam//Not actually a projectile, just an effect. name="beam" icon='icons/effects/beam.dmi' diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 3f9a060c5e7..75bb884316e 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -59,8 +59,8 @@ if(prob(50)) icon_state = "stickyweb2" -/obj/effect/spider/stickyweb/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 +/obj/effect/spider/stickyweb/CanPass(atom/movable/mover, turf/target, height=0) + if(height==0) return 1 if(istype(mover, /mob/living/simple_animal/hostile/giant_spider)) return 1 else if(istype(mover, /mob/living)) @@ -213,7 +213,7 @@ var/mob/living/user = usr var/breakout_time = 2 user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT + user.last_special = world.time + CLICK_CD_BREAKOUT user << "You struggle against the tight bonds! (This will take about [breakout_time] minutes.)" visible_message("You see something struggling and writhing in the [src]!") if(do_after(user,(breakout_time*60*10))) diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index 2ca6409b563..153ce9426ce 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -5,10 +5,11 @@ desc = "A folded bag designed for the storage and transportation of cadavers." icon = 'icons/obj/bodybag.dmi' icon_state = "bodybag_folded" + var/unfoldedbag_path = /obj/structure/closet/body_bag w_class = 2 /obj/item/bodybag/attack_self(mob/user) - var/obj/structure/closet/body_bag/R = new /obj/structure/closet/body_bag(user.loc) + var/obj/structure/closet/body_bag/R = new unfoldedbag_path(user.loc) R.add_fingerprint(user) qdel(src) @@ -36,7 +37,9 @@ icon_state = "bodybag_closed" icon_closed = "bodybag_closed" icon_opened = "bodybag_open" + var/foldedbag_path = /obj/item/bodybag density = 0 + mob_storage_capacity = 2 /obj/structure/closet/body_bag/attackby(obj/item/I, mob/user) @@ -77,13 +80,36 @@ if(contents.len) return 0 visible_message("[usr] folds up [src].") - var/obj/item/bodybag/B = new /obj/item/bodybag(get_turf(src)) + var/obj/item/bodybag/B = new foldedbag_path(get_turf(src)) usr.put_in_hands(B) qdel(src) -/obj/structure/closet/bodybag/update_icon() +/obj/structure/closet/body_bag/update_icon() if(!opened) icon_state = icon_closed else icon_state = icon_opened + + +// Bluespace bodybag + +/obj/item/bodybag/bluespace + name = "bluespace body bag" + desc = "A folded bluespace body bag designed for the storage and transportation of cadavers." + icon = 'icons/obj/bodybag.dmi' + icon_state = "bluebodybag_folded" + unfoldedbag_path = /obj/structure/closet/body_bag/bluespace + w_class = 2 + +/obj/structure/closet/body_bag/bluespace + name = "bluespace body bag" + desc = "A bluespace body bag designed for the storage and transportation of cadavers." + icon = 'icons/obj/bodybag.dmi' + icon_state = "bluebodybag_closed" + icon_closed = "bluebodybag_closed" + icon_opened = "bluebodybag_open" + foldedbag_path = /obj/item/bodybag/bluespace + density = 0 + mob_storage_capacity = 15 + max_mob_size = 2 \ No newline at end of file diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 06a5fb632d6..89021490262 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -297,12 +297,18 @@ var/global/list/obj/item/device/pda/PDAs = list() dat += "

Engineering Functions

" dat += "" if (cartridge.access_medical) dat += "

Medical Functions

" dat += "" + else dat += "" if (cartridge.access_security) dat += "

Security Functions

" @@ -325,6 +331,8 @@ var/global/list/obj/item/device/pda/PDAs = list() if (cartridge) if (cartridge.access_janitor) dat += "
  • Custodial Locator
  • " + if(istype(cartridge.radio, /obj/item/radio/integrated/cleanbot)) + dat += "
  • Cleanbot Access
  • " if (istype(cartridge.radio, /obj/item/radio/integrated/signal)) dat += "
  • Signaler System
  • " if (cartridge.access_reagent_scanner) @@ -467,9 +475,9 @@ var/global/list/obj/item/device/pda/PDAs = list() mode = 0 else mode = round(mode/10) - if(mode==4)//Fix for cartridges. Redirects to hub. + if(mode==4 || mode == 5)//Fix for cartridges. Redirects to hub. mode = 0 - else if(mode >= 40 && mode <= 49)//Fix for cartridges. Redirects to refresh the menu. + else if(mode >= 40 && mode <= 59)//Fix for cartridges. Redirects to refresh the menu. cartridge.mode = mode cartridge.unlock() if ("Authenticate")//Checks for ID @@ -1082,4 +1090,4 @@ var/global/list/obj/item/device/pda/PDAs = list() for(var/obj/item/device/pda/P in PDAs) if(!P.owner || P.toff || P.hidden) continue . += P - return . + return . diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index 79ca2f0b61b..e42c3cf453a 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -38,21 +38,37 @@ icon_state = "cart-e" access_engine = 1 + /obj/item/weapon/cartridge/engineering/New() + ..() + radio = new /obj/item/radio/integrated/floorbot(src) + /obj/item/weapon/cartridge/atmos name = "\improper BreatheDeep cartridge" icon_state = "cart-a" access_atmos = 1 + /obj/item/weapon/cartridge/atmos/New() + ..() + radio = new /obj/item/radio/integrated/floorbot(src) + /obj/item/weapon/cartridge/medical name = "\improper Med-U cartridge" icon_state = "cart-m" access_medical = 1 + /obj/item/weapon/cartridge/medical/New() + ..() + radio = new /obj/item/radio/integrated/medbot(src) + /obj/item/weapon/cartridge/chemistry name = "\improper ChemWhiz cartridge" icon_state = "cart-chem" access_reagent_scanner = 1 + /obj/item/weapon/cartridge/chemistry/New() + ..() + radio = new /obj/item/radio/integrated/medbot(src) + /obj/item/weapon/cartridge/security name = "\improper R.O.B.U.S.T. cartridge" icon_state = "cart-s" @@ -79,6 +95,10 @@ icon_state = "cart-j" access_janitor = 1 +/obj/item/weapon/cartridge/janitor/New() + ..() + radio = new /obj/item/radio/integrated/cleanbot(src) + /obj/item/weapon/cartridge/lawyer name = "\improper P.R.O.V.E. cartridge" icon_state = "cart-s" @@ -167,6 +187,10 @@ access_engine = 1 access_atmos = 1 +/obj/item/weapon/cartridge/ce/New() + ..() + radio = new /obj/item/radio/integrated/floorbot(src) + /obj/item/weapon/cartridge/cmo name = "\improper Med-U DELUXE cartridge" icon_state = "cart-cmo" @@ -175,6 +199,10 @@ access_reagent_scanner = 1 access_medical = 1 +/obj/item/weapon/cartridge/cmo/New() + ..() + radio = new /obj/item/radio/integrated/medbot(src) + /obj/item/weapon/cartridge/rd name = "\improper Signal Ace DELUXE cartridge" icon_state = "cart-rd" @@ -249,6 +277,67 @@ frequency.post_signal(src, status_signal) +/obj/item/weapon/cartridge/proc/bot_control(var/obj/item/radio/integrated/SC) + + + if(!SC) + menu = "Interlink Error - Please reinsert cartridge." + return + + if(!SC.active) + // list of bots + if(!SC.botlist || (SC.botlist && SC.botlist.len==0)) + menu += "No bots found.
    " + + else + for(var/obj/machinery/bot/B in SC.botlist) + menu += "[B] at [get_area(B)]
    " + + menu += "
    Scan for active bots
    " + + else // bot selected, control it + + menu += "[SC.active]
    Status: (refresh)
    " + + if(!SC.botstatus) + menu += "Waiting for response...
    " + else + + menu += "Location: [SC.botstatus["loca"] ]
    " + menu += "Mode: " + + switch(SC.botstatus["mode"]) + if(BOT_IDLE) + menu += "Ready" + if(BOT_HUNT) + menu += "Apprehending target" + if(BOT_PREP_ARREST,BOT_ARREST) + menu += "Arresting target" + if(BOT_START_PATROL) + menu += "Starting patrol" + if(BOT_PATROL) + menu += "On patrol" + if(BOT_SUMMON) + menu += "Responding to summons" + if(BOT_CLEANING) + menu += "Cleaning" + if(BOT_MOVING) + menu += "Proceeding to work site" + if(BOT_REPAIRING) + menu += "Performing repairs" + if(BOT_HEALING) + menu += "Medicating patient" + if(BOT_RESPONDING) + menu += "Proceeding to AI waypoint" + + menu += "
    \[Stop Patrol\] " + menu += "\[Start Patrol\] " + menu += "\[Summon Bot\]
    " + menu += "
    Return to bot list
    " + menu += "Keep an ID inserted to upload access codes upon summoning." + return menu + + /obj/item/weapon/cartridge/proc/generate_menu() switch(mode) if(40) //signaller @@ -457,55 +546,8 @@ Code: menu += "
    " if (46) //beepsky control var/obj/item/radio/integrated/beepsky/SC = radio - if(!SC) - menu = "Interlink Error - Please reinsert cartridge." - return - menu = "

    Securitron Interlink

    " - - if(!SC.active) - // list of bots - if(!SC.botlist || (SC.botlist && SC.botlist.len==0)) - menu += "No bots found.
    " - - else - for(var/obj/machinery/bot/secbot/B in SC.botlist) - menu += "[B] at [B.loc.loc]
    " - - for(var/obj/machinery/bot/ed209/B in SC.botlist) - menu += "[B] at [B.loc.loc]
    " - - menu += "
    Scan for active bots
    " - - else // bot selected, control it - - menu += "[SC.active]
    Status: (refresh)
    " - - if(!SC.botstatus) - menu += "Waiting for response...
    " - else - - menu += "Location: [SC.botstatus["loca"] ]
    " - menu += "Mode: " - - switch(SC.botstatus["mode"]) - if(0) - menu += "Ready" - if(1) - menu += "Apprehending target" - if(2,3) - menu += "Arresting target" - if(4) - menu += "Starting patrol" - if(5) - menu += "On patrol" - if(6) - menu += "Responding to summons" - - menu += "
    \[Stop Patrol\] " - menu += "\[Start Patrol\] " - menu += "\[Summon Bot\]
    " - menu += "
    Return to bot list" + bot_control(SC) if (47) //quartermaster order records menu = "

    Supply Record Interlink

    " @@ -529,7 +571,6 @@ Code: if(!QC) menu = "Interlink Error - Please reinsert cartridge." return - menu = "

    M.U.L.E. bot Interlink V0.8

    " if(!QC.active) @@ -555,19 +596,19 @@ Code: menu += "Mode: " switch(QC.botstatus["mode"]) - if(0) + if(BOT_IDLE) menu += "Ready" - if(1) + if(BOT_LOADING) menu += "Loading/Unloading" - if(2) + if(BOT_DELIVER) menu += "Navigating to Delivery Location" - if(3) + if(BOT_GO_HOME) menu += "Navigating to Home" - if(4) + if(BOT_BLOCKED) menu += "Waiting for clear path" - if(5,6) + if(BOT_NAV,BOT_WAIT_FOR_NAV) menu += "Calculating navigation path" - if(7) + if(BOT_NO_ROUTE) menu += "Unable to locate destination" var/obj/structure/closet/crate/C = QC.botstatus["load"] menu += "
    Current Load: [ !C ? "none" : "[C.name] (unload)" ]
    " @@ -644,6 +685,20 @@ Code: menu += "ERROR: Unable to determine current location." menu += "

    Refresh GPS Locator" + if (50) //Cleanbot control + menu = "

    Cleanbot Interlink

    " + var/obj/item/radio/integrated/cleanbot/SC = radio + bot_control(SC) + + if (51) //floorbot control + menu = "

    Floorbot Interlink

    " + var/obj/item/radio/integrated/floorbot/SC = radio + bot_control(SC) + + if (52) //Medibot control + menu = "

    Medibot Interlink

    " + var/obj/item/radio/integrated/medbot/SC = radio + bot_control(SC) /obj/item/weapon/cartridge/Topic(href, href_list) ..() diff --git a/code/game/objects/items/devices/PDA/radio.dm b/code/game/objects/items/devices/PDA/radio.dm index e576cc2e109..ca45bc45567 100644 --- a/code/game/objects/items/devices/PDA/radio.dm +++ b/code/game/objects/items/devices/PDA/radio.dm @@ -4,6 +4,13 @@ icon = 'icons/obj/module.dmi' icon_state = "power_mod" var/obj/item/device/pda/hostpda = null + var/list/botlist = null // list of bots + var/obj/machinery/bot/active // the active bot; if null, show bot list + var/list/botstatus // the status signal sent by the bot + var/bot_type //The type of bot it is. + var/bot_filter //Determines which radio filter to use. + + var/control_freq = 1447 var/on = 0 //Are we currently active?? var/menu_message = "" @@ -12,13 +19,17 @@ ..() if (istype(loc.loc, /obj/item/device/pda)) hostpda = loc.loc + if (bot_filter) + spawn(5) + add_to_radio(bot_filter) -/obj/item/radio/integrated/proc/post_signal(var/freq, var/key, var/value, var/key2, var/value2, var/key3, var/value3, s_filter) +/obj/item/radio/integrated/proc/post_signal(var/freq, var/key, var/value, var/key2, var/value2, var/key3, var/value3,var/key4, var/value4, s_filter) //world << "Post: [freq]: [key]=[value], [key2]=[value2]" var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq) - if(!frequency) return + if(!frequency) + return var/datum/signal/signal = new() signal.source = src @@ -28,6 +39,8 @@ signal.data[key2] = value2 if(key3) signal.data[key3] = value3 + if(key4) + signal.data[key4] = value4 frequency.post_signal(src, signal, filter = s_filter) @@ -44,33 +57,18 @@ /obj/item/radio/integrated/proc/generate_menu() -/obj/item/radio/integrated/beepsky - var/list/botlist = null // list of bots - var/obj/machinery/bot/secbot/active // the active bot; if null, show bot list - var/list/botstatus // the status signal sent by the bot - var/control_freq = 1447 -// create a new QM cartridge, and register to receive bot control & beacon message -/obj/item/radio/integrated/beepsky/New() - ..() - spawn(5) - if(radio_controller) - radio_controller.add_object(src, control_freq, filter = RADIO_SECBOT) +/obj/item/radio/integrated/receive_signal(datum/signal/signal) + /*var/obj/item/device/pda/P = src.loc -// receive radio signals -// can detect bot status signals -// create/populate list as they are recvd -/obj/item/radio/integrated/beepsky/receive_signal(datum/signal/signal) -// var/obj/item/device/pda/P = src.loc - - /* world << "recvd:[P] : [signal.source]" for(var/d in signal.data) world << "- [d] = [signal.data[d]]" - */ - if (signal.data["type"] == "secbot") + */ + + if (signal.data["type"] == bot_type) if(!botlist) botlist = new() @@ -81,9 +79,7 @@ var/list/b = signal.data botstatus = b.Copy() -// if (istype(P)) P.updateSelfDialog() - -/obj/item/radio/integrated/beepsky/Topic(href, href_list) +/obj/item/radio/integrated/Topic(href, href_list) ..() var/obj/item/device/pda/PDA = src.hostpda @@ -91,32 +87,53 @@ if("control") active = locate(href_list["bot"]) - post_signal(control_freq, "command", "bot_status", "active", active, s_filter = RADIO_SECBOT) + post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) if("scanbots") // find all bots botlist = null - post_signal(control_freq, "command", "bot_status", s_filter = RADIO_SECBOT) + post_signal(control_freq, "command", "bot_status", s_filter = bot_filter) if("botlist") active = null if("stop", "go") - post_signal(control_freq, "command", href_list["op"], "active", active, s_filter = RADIO_SECBOT) - post_signal(control_freq, "command", "bot_status", "active", active, s_filter = RADIO_SECBOT) + post_signal(control_freq, "command", href_list["op"], "active", active, s_filter = bot_filter) + post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) if("summon") - post_signal(control_freq, "command", "summon", "active", active, "target", get_turf(PDA) , s_filter = RADIO_SECBOT) - post_signal(control_freq, "command", "bot_status", "active", active, s_filter = RADIO_SECBOT) + post_signal(control_freq, "command", "summon", "active", active, "target", get_turf(PDA) , "useraccess", PDA.GetAccess(), s_filter = bot_filter) + post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) PDA.cartridge.unlock() +/obj/item/radio/integrated/proc/add_to_radio(bot_filter) //Master filter control for bots. Must be placed in the bot's local New() to support map spawned bots. + if(radio_controller) + radio_controller.add_object(src, control_freq, filter = bot_filter) + + +/obj/item/radio/integrated/beepsky + bot_filter = RADIO_SECBOT + bot_type = SEC_BOT + +/obj/item/radio/integrated/medbot + bot_filter = RADIO_MEDBOT + bot_type = MED_BOT + +/obj/item/radio/integrated/floorbot + bot_filter = RADIO_FLOORBOT + bot_type = FLOOR_BOT + +/obj/item/radio/integrated/cleanbot + bot_filter = RADIO_CLEANBOT + bot_type = CLEAN_BOT + /obj/item/radio/integrated/mule - var/list/botlist = null // list of bots - var/obj/machinery/bot/mulebot/active // the active bot; if null, show bot list - var/list/botstatus // the status signal sent by the bot + //var/list/botlist = null // list of bots + //var/obj/machinery/bot/mulebot/active // the active bot; if null, show bot list + //var/list/botstatus // the status signal sent by the bot var/list/beacons var/beacon_freq = 1400 - var/control_freq = 1447 + control_freq = 1447 // create a new QM cartridge, and register to receive bot control & beacon message /obj/item/radio/integrated/mule/New() @@ -141,7 +158,7 @@ for(var/d in signal.data) world << "- [d] = [signal.data[d]]" */ - if(signal.data["type"] == "mulebot") + if(signal.data["type"] == MULE_BOT) if(!botlist) botlist = new() @@ -162,52 +179,46 @@ // if(istype(P)) P.updateSelfDialog() /obj/item/radio/integrated/mule/Topic(href, href_list) - ..() + //..() var/obj/item/device/pda/PDA = src.hostpda var/cmd = "command" - if(active) cmd = "command [active.suffix]" + if(active) + cmd = "command [active.suffix]" switch(href_list["op"]) if("control") active = locate(href_list["bot"]) - post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT) if("scanbots") // find all bots botlist = null - post_signal(control_freq, "command", "bot_status", s_filter = RADIO_MULEBOT) if("botlist") active = null - if("unload") post_signal(control_freq, cmd, "unload", s_filter = RADIO_MULEBOT) - post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT) if("setdest") if(beacons) var/dest = input("Select Bot Destination", "Mulebot [active.suffix] Interlink", active.destination) as null|anything in beacons if(dest) post_signal(control_freq, cmd, "target", "destination", dest, s_filter = RADIO_MULEBOT) - post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT) if("retoff") post_signal(control_freq, cmd, "autoret", "value", 0, s_filter = RADIO_MULEBOT) - post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT) if("reton") post_signal(control_freq, cmd, "autoret", "value", 1, s_filter = RADIO_MULEBOT) - post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT) if("pickoff") post_signal(control_freq, cmd, "autopick", "value", 0, s_filter = RADIO_MULEBOT) - post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT) + if("pickon") post_signal(control_freq, cmd, "autopick", "value", 1, s_filter = RADIO_MULEBOT) - post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT) if("stop", "go", "home") post_signal(control_freq, cmd, href_list["op"], s_filter = RADIO_MULEBOT) - post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT) + + post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT) PDA.cartridge.unlock() @@ -227,10 +238,10 @@ ..() if(radio_controller) initialize() - + /obj/item/radio/integrated/signal/initialize() if (src.frequency < 1441 || src.frequency > 1489) - src.frequency = sanitize_frequency(src.frequency) + src.frequency = sanitize_frequency(src.frequency) set_frequency(frequency) @@ -256,4 +267,4 @@ radio_connection.post_signal(src, signal) - return + return \ No newline at end of file diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index 1c41c285f3e..48de883c68c 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -23,15 +23,15 @@ return 1 -/obj/item/device/flash/proc/burn_out(var/mob/user) //Made so you can override it if you want to have an invincible flash from R&D or something. +/obj/item/device/flash/proc/burn_out() //Made so you can override it if you want to have an invincible flash from R&D or something. broken = 1 icon_state = "[initial(icon_state)]burnt" - user.visible_message("The [src.name] burns out!") + visible_message("The [src.name] burns out!") /obj/item/device/flash/proc/flash_recharge(var/mob/user) if(prob(times_used * 2)) //if you use it 5 times in a minute it has a 10% chance to break! - burn_out(user) + burn_out() return 0 var/deciseconds_passed = world.time - last_used @@ -156,4 +156,6 @@ name = "memorizer" desc = "If you see this, you're not likely to remember it any time soon." icon_state = "memorizer" - item_state = "nullrod" \ No newline at end of file + item_state = "nullrod" + +/obj/item/device/flash/handheld //this is now the regular pocket flashes \ No newline at end of file diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index c765eff2eb3..26b79a0988c 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -20,6 +20,13 @@ keyslot1 = new /obj/item/device/encryptionkey/ recalculateChannels() +/obj/item/device/radio/headset/Destroy() + qdel(keyslot1) + qdel(keyslot2) + keyslot1 = null + keyslot2 = null + ..() + /obj/item/device/radio/headset/talk_into(mob/living/M as mob, message, channel) if (!listening) return diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index e41c84f971f..60b7a1d6c8e 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -50,7 +50,10 @@ initialize() /obj/item/device/radio/Destroy() - remove_radio_all(src) //Just to be sure. + qdel(wires) + wires = null + remove_radio_all(src) //Just to be sure + ..() /obj/item/device/radio/MouseDrop(obj/over_object as obj, src_location, over_location) var/mob/M = usr @@ -218,7 +221,7 @@ the signal gets processed and logged, and an audible transmission gets sent to each individual headset. */ - + /* be prepared to disregard any comments in all of tcomms code. i tried my best to keep them somewhat up-to-date, but eh */ diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 0aef25a67fd..03f27edd891 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -141,6 +141,6 @@ effective or pretty fucking useless. amount += wavelength wavelength = max(1,(min(120,amount))) - updateUsrDialog() + attack_self(usr) add_fingerprint(usr) return \ No newline at end of file diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 3deee5d8cdc..6c2d4fc600c 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -51,8 +51,8 @@ icon_state = "head" construction_time = 350 construction_cost = list("metal"=5000) - var/obj/item/device/flash/flash1 = null - var/obj/item/device/flash/flash2 = null + var/obj/item/device/flash/handheld/flash1 = null + var/obj/item/device/flash/handheld/flash2 = null /obj/item/robot_parts/robot_suit name = "cyborg endoskeleton" @@ -331,8 +331,8 @@ /obj/item/robot_parts/head/attackby(obj/item/W as obj, mob/user as mob) ..() - if(istype(W, /obj/item/device/flash)) - var/obj/item/device/flash/F = W + if(istype(W, /obj/item/device/flash/handheld)) + var/obj/item/device/flash/handheld/F = W if(src.flash1 && src.flash2) user << "You have already inserted the eyes!" return diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index 8d974017521..8f822385dd1 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -95,9 +95,7 @@ hp -= Proj.damage if(hp <= 0) - for(var/mob/O in oviewers()) - if ((O.client && !( O.blinded ))) - O << "[src] breaks into tiny pieces and collapses!" + visible_message("[src] breaks into tiny pieces and collapses!") qdel(src) // Create a temporary object to represent the damage diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 8951c278576..15c4ab31162 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -92,6 +92,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ new/datum/stack_recipe("wooden sandals", /obj/item/clothing/shoes/sandal, 1), \ new/datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20), \ new/datum/stack_recipe("table parts", /obj/item/weapon/table_parts/wood, 2), \ + new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40), \ new/datum/stack_recipe("wooden chair", /obj/structure/stool/bed/chair/wood/normal, 3, time = 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, 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 38c95e33cfd..9ab05593915 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -89,7 +89,7 @@ title+= "[R.title]" title+= " ([R.req_amount] [src.singular_name]\s)" if (can_build) - t1 += text("[] ", src, i, title) + t1 += text("[] ", src, i, title) else t1 += text("[]", title) continue @@ -117,7 +117,8 @@ var/datum/stack_recipe/R = recipes[text2num(href_list["make"])] var/multiplier = text2num(href_list["multiplier"]) - if (!multiplier) multiplier = 1 + if (!multiplier ||(multiplier <= 0)) //href protection + return if (src.get_amount() < R.req_amount*multiplier) if (R.req_amount*multiplier>1) usr << "You haven't got enough [src] to build \the [R.req_amount*multiplier] [R.title]\s!" @@ -227,7 +228,7 @@ spawn(0) src.interact(usr) else if (S.amount >= max_amount) - return 1 + return var/to_transfer as num if (user.get_inactive_hand()==src) to_transfer = 1 diff --git a/code/game/objects/items/stacks/tiles/light.dm b/code/game/objects/items/stacks/tiles/light.dm index 429829cc7fc..2a208746460 100644 --- a/code/game/objects/items/stacks/tiles/light.dm +++ b/code/game/objects/items/stacks/tiles/light.dm @@ -11,8 +11,8 @@ flags = CONDUCT max_amount = 60 attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed") - var/on = 1 - var/state //0 = fine, 1 = flickering, 2 = breaking, 3 = broken + turf_type = /turf/simulated/floor/light + var/state = 0 /obj/item/stack/tile/light/New(var/loc, var/amount=null) ..() diff --git a/code/game/objects/items/stacks/tiles/plasteel.dm b/code/game/objects/items/stacks/tiles/plasteel.dm index 5e922c9a6c5..bad34a66578 100644 --- a/code/game/objects/items/stacks/tiles/plasteel.dm +++ b/code/game/objects/items/stacks/tiles/plasteel.dm @@ -11,6 +11,7 @@ throw_range = 7 flags = CONDUCT max_amount = 60 + turf_type = /turf/simulated/floor /obj/item/stack/tile/plasteel/cyborg desc = "The ground you walk on" //Not the usual floor tile desc as that refers to throwing, Cyborgs can't do that - RR @@ -47,29 +48,3 @@ return else ..() - -/* -/obj/item/stack/tile/plasteel/attack_self(mob/user as mob) - if (usr.stat) - return - var/T = user.loc - if (!( istype(T, /turf) )) - user << "\red You must be on the ground!" - return - if (!( istype(T, /turf/space) )) - user << "\red You cannot build on or repair this turf!" - return - src.build(T) - src.add_fingerprint(user) - use(1) - return -*/ - -/obj/item/stack/tile/plasteel/proc/build(turf/S as turf) - S.ChangeTurf(/turf/simulated/floor/plating) -// var/turf/simulated/floor/W = S.ReplaceWithFloor() -// W.make_plating() - return - - - diff --git a/code/game/objects/items/stacks/tiles/tile_mineral.dm b/code/game/objects/items/stacks/tiles/tile_mineral.dm index 05177a54409..3a94618d548 100644 --- a/code/game/objects/items/stacks/tiles/tile_mineral.dm +++ b/code/game/objects/items/stacks/tiles/tile_mineral.dm @@ -10,6 +10,7 @@ throw_range = 7 max_amount = 60 origin_tech = "plasma=1" + turf_type = /turf/simulated/floor/mineral/plasma /obj/item/stack/tile/mineral/uranium name = "uranium tile" @@ -23,6 +24,7 @@ throw_range = 7 max_amount = 60 origin_tech = "material=1" + turf_type = /turf/simulated/floor/mineral/uranium /obj/item/stack/tile/mineral/gold name = "gold tile" @@ -36,6 +38,7 @@ throw_range = 7 max_amount = 60 origin_tech = "material=1" + turf_type = /turf/simulated/floor/mineral/gold /obj/item/stack/tile/mineral/silver name = "silver tile" @@ -49,6 +52,7 @@ throw_range = 7 max_amount = 60 origin_tech = "material=1" + turf_type = /turf/simulated/floor/mineral/silver /obj/item/stack/tile/mineral/diamond name = "diamond tile" @@ -62,6 +66,7 @@ throw_range = 7 max_amount = 60 origin_tech = "material=2" + turf_type = /turf/simulated/floor/mineral/diamond /obj/item/stack/tile/mineral/bananium name = "bananium tile" @@ -75,4 +80,5 @@ throw_range = 7 max_amount = 60 origin_tech = "material=1" + turf_type = /turf/simulated/floor/mineral/bananium diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index c44038b6638..e33991a7186 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -1,10 +1,20 @@ -/* Diffrent misc types of tiles +/* Diffrent misc types of tiles & the tile prototype * Contains: + Tile * Grass * Wood * Carpet */ +/* + * Tile + */ +/obj/item/stack/tile + name = "broken tile" + singular_name = "broken tile" + desc = "A broken tile. This should not exist." + var/turf_type = null + /* * Grass */ @@ -20,6 +30,7 @@ throw_range = 7 max_amount = 60 origin_tech = "biotech=1" + turf_type = /turf/simulated/floor/grass /* * Wood @@ -36,6 +47,8 @@ throw_range = 7 max_amount = 60 origin_tech = "biotech=1" + turf_type = /turf/simulated/floor/wood + /* * Carpets */ @@ -50,3 +63,4 @@ throw_speed = 3 throw_range = 7 max_amount = 60 + turf_type = /turf/simulated/floor/carpet diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm index b6201fbefba..455c87b9f4c 100644 --- a/code/game/objects/items/weapons/extinguisher.dm +++ b/code/game/objects/items/weapons/extinguisher.dm @@ -67,27 +67,29 @@ var/direction = get_dir(src,target) - if(usr.buckled && isobj(usr.buckled) && !usr.buckled.anchored ) + if(usr.buckled && isobj(usr.buckled) && !usr.buckled.anchored) spawn(0) var/obj/B = usr.buckled var/movementdirection = turn(direction,180) - B.Move(get_step(usr,movementdirection), movementdirection) + step(B, movementdirection) sleep(1) - B.Move(get_step(usr,movementdirection), movementdirection) + step(B, movementdirection) sleep(1) - B.Move(get_step(usr,movementdirection), movementdirection) + step(B, movementdirection) sleep(1) - B.Move(get_step(usr,movementdirection), movementdirection) + step(B, movementdirection) sleep(2) - B.Move(get_step(usr,movementdirection), movementdirection) + step(B, movementdirection) sleep(2) - B.Move(get_step(usr,movementdirection), movementdirection) + step(B, movementdirection) sleep(3) - B.Move(get_step(usr,movementdirection), movementdirection) + step(B, movementdirection) sleep(3) - B.Move(get_step(usr,movementdirection), movementdirection) + step(B, movementdirection) sleep(3) - B.Move(get_step(usr,movementdirection), movementdirection) + step(B, movementdirection) + + else user.newtonian_move(turn(direction, 180)) var/turf/T = get_turf(target) var/turf/T1 = get_step(T,turn(direction, 90)) @@ -118,9 +120,5 @@ if(W.loc == my_target) break sleep(2) - if(!has_gravity(user)) - user.inertia_dir = get_dir(target, user) - step(user, user.inertia_dir) else - return ..() - return + return ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index e7e379530b0..5396cdd8940 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -79,12 +79,14 @@ /* * Wrapping Paper */ -/obj/item/weapon/wrapping_paper +/obj/item/stack/wrapping_paper name = "wrapping paper" desc = "You can use this to wrap items in." icon = 'icons/obj/items.dmi' icon_state = "wrap_paper" + flags = NOBLUDGEON + amount = 25 + max_amount = 25 - -/obj/item/weapon/wrapping_paper/attack_self(mob/user) +/obj/item/stack/wrapping_paper/attack_self(mob/user) user << "You need to use it on a package that has already been wrapped!" diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index e4d8a1dc467..8118a8f4412 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -117,7 +117,6 @@ trashtype = /obj/item/weapon/restraints/handcuffs/cable/zipties/used /obj/item/weapon/restraints/handcuffs/cable/zipties/used - name = "used zipties" desc = "A pair of broken zipties." icon_state = "cuff_white_used" diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 776dca795a5..0f09d860cca 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -62,6 +62,11 @@ crit_fail = 1 icon_state = "brokenpack" +/obj/item/weapon/storage/backpack/holding/singularity_act(current_size) + var/dist = max((current_size - 2),1) + explosion(src.loc,(dist),(dist*2),(dist*4)) + return + /obj/item/weapon/storage/backpack/santabag name = "Santa's Gift Bag" diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index f17a2d7d7c7..6e7efa8bf50 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -112,7 +112,7 @@ /obj/item/weapon/grenade/flashbang, /obj/item/weapon/reagent_containers/spray/pepper, /obj/item/weapon/restraints/handcuffs, - /obj/item/device/flash, + /obj/item/device/flash/handheld, /obj/item/clothing/glasses, /obj/item/ammo_casing/shotgun, /obj/item/ammo_box, diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 8f9d3250b30..f404c37e711 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -50,6 +50,11 @@ user.update_inv_r_hand() qdel(src) +/obj/item/weapon/storage/box/attackby(obj/item/W, mob/user) + if(istype(W, /obj/item/stack/packageWrap)) + return 0 + ..() + /obj/item/weapon/storage/box/survival @@ -183,12 +188,12 @@ /obj/item/weapon/storage/box/flashes/New() ..() - new /obj/item/device/flash(src) - new /obj/item/device/flash(src) - new /obj/item/device/flash(src) - new /obj/item/device/flash(src) - new /obj/item/device/flash(src) - new /obj/item/device/flash(src) + new /obj/item/device/flash/handheld(src) + new /obj/item/device/flash/handheld(src) + new /obj/item/device/flash/handheld(src) + new /obj/item/device/flash/handheld(src) + new /obj/item/device/flash/handheld(src) + new /obj/item/device/flash/handheld(src) /obj/item/weapon/storage/box/teargas name = "box of tear gas grenades (WARNING)" diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index f45a8b5766f..20805e43bdf 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -134,3 +134,8 @@ var/obj/Loc=loc Loc.on_log() +/obj/singularity_act() + ex_act(1.0) + if(src && isnull(gc_destroyed)) + qdel(src) + return 2 \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 74ad8e6d453..c07ca884aea 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -14,6 +14,8 @@ var/wall_mounted = 0 //never solid (You can always pass over it) var/health = 100 var/lastbang + var/max_mob_size = 1 //Biggest mob_size accepted by the container + var/mob_storage_capacity = 3 // how many human sized mob/living can fit together inside a closet. var/storage_capacity = 30 //This is so that someone can't pack hundreds of items in a locker/crate //then open it in a populated area to crash clients. @@ -25,8 +27,8 @@ /obj/structure/closet/alter_health() return get_turf(src) -/obj/structure/closet/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0 || wall_mounted)) return 1 +/obj/structure/closet/CanPass(atom/movable/mover, turf/target, height=0) + if(height==0 || wall_mounted) return 1 return (!density) /obj/structure/closet/proc/can_open() @@ -82,8 +84,14 @@ if(istype(AM, /mob/living)) var/mob/living/L = AM - if(L.buckled) + if(L.buckled || L.mob_size > max_mob_size) //buckled mobs and mobs too big for the container don't get inside closets. return 0 + if(L.mob_size > 0) + var/mobs_stored = 0 + for(var/mob/living/M in contents) + mobs_stored++ + if(mobs_stored >= mob_storage_capacity) + return 0 if(L.client) L.client.perspective = EYE_PERSPECTIVE L.client.eye = src @@ -197,7 +205,7 @@ if(user.drop_item()) W.Move(loc) - else if(istype(W, /obj/item/weapon/packageWrap)) + else if(istype(W, /obj/item/stack/packageWrap)) return else if(istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index f0163f1279f..13e18c8e65b 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -30,7 +30,7 @@ new /obj/item/weapon/airlock_painter(src) new /obj/item/clothing/mask/gas(src) new /obj/item/device/multitool(src) - new /obj/item/device/flash(src) + new /obj/item/device/flash/handheld(src) return /obj/structure/closet/secure_closet/engineering_electrical diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 896b0408417..5bf51ea6e1e 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -120,7 +120,7 @@ new /obj/item/clothing/shoes/sneakers/brown (src) new /obj/item/device/radio/headset/heads/cmo(src) new /obj/item/weapon/storage/belt/medical(src) - new /obj/item/device/flash(src) + new /obj/item/device/flash/handheld(src) new /obj/item/weapon/reagent_containers/hypospray/CMO(src) return diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm index 9b0cef34c99..40a861b0c4b 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm @@ -46,7 +46,7 @@ new /obj/item/weapon/tank/air(src) new /obj/item/clothing/mask/gas(src) new /obj/item/clothing/suit/armor/reactive(src) - new /obj/item/device/flash(src) + new /obj/item/device/flash/handheld(src) new /obj/item/device/laser_pointer(src) new /obj/item/clothing/under/rank/research_director/alt(src) return 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 c65fcfa194e..4903468b036 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -49,7 +49,7 @@ new /obj/item/weapon/storage/box/ids(src) new /obj/item/clothing/suit/armor/vest(src) new /obj/item/weapon/gun/energy/gun(src) - new /obj/item/device/flash(src) + new /obj/item/device/flash/handheld(src) new /obj/item/clothing/glasses/sunglasses(src) new /obj/item/weapon/mining_voucher(src) return @@ -70,8 +70,10 @@ ..() sleep(2) new /obj/item/clothing/suit/armor/vest(src) - new /obj/item/clothing/suit/armor/hos/jensen(src) - new /obj/item/clothing/head/HoS/dermal(src) + new /obj/item/clothing/under/hosformalfem(src) + new /obj/item/clothing/under/hosformalmale(src) + new /obj/item/clothing/suit/armor/hos/trenchcoat(src) + new /obj/item/clothing/head/HoS/drill(src) new /obj/item/weapon/cartridge/hos(src) new /obj/item/device/radio/headset/heads/hos/alt(src) new /obj/item/clothing/glasses/hud/security/eyepatch(src) @@ -79,7 +81,7 @@ new /obj/item/weapon/shield/riot/tele(src) new /obj/item/clothing/mask/gas/sechailer/hos(src) new /obj/item/weapon/storage/box/flashbangs(src) - new /obj/item/device/flash(src) + new /obj/item/device/flash/handheld(src) new /obj/item/weapon/melee/baton/loaded(src) new /obj/item/weapon/gun/energy/gun(src) new /obj/item/weapon/storage/belt/security(src) @@ -134,7 +136,7 @@ new /obj/item/clothing/head/helmet(src) new /obj/item/device/radio/headset/headset_sec/alt(src) new /obj/item/clothing/mask/gas/sechailer(src) - new /obj/item/device/flash(src) + new /obj/item/device/flash/handheld(src) new /obj/item/weapon/reagent_containers/spray/pepper(src) new /obj/item/weapon/grenade/flashbang(src) new /obj/item/weapon/gun/energy/taser(src) diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index b3df16856cb..fc7b6800bd5 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -38,17 +38,6 @@ new /obj/item/clothing/head/beret/sec(src) return -/obj/structure/closet/wardrobe/hos - name = "\proper head of security's wardrobe" - icon_state = "red" - icon_closed = "red" - -/obj/structure/closet/wardrobe/hos/New() - new /obj/item/clothing/under/hosformalfem(src) - new /obj/item/clothing/under/hosformalmale(src) - new /obj/item/clothing/under/rank/head_of_security/jensen(src) - return - /obj/structure/closet/wardrobe/pink name = "pink wardrobe" icon_state = "pink" @@ -72,6 +61,8 @@ new /obj/item/clothing/under/color/black(src) new /obj/item/clothing/under/color/black(src) new /obj/item/clothing/under/color/black(src) + if(prob(25)) + new /obj/item/clothing/suit/jacket/leather(src) new /obj/item/clothing/shoes/sneakers/black(src) new /obj/item/clothing/shoes/sneakers/black(src) new /obj/item/clothing/shoes/sneakers/black(src) @@ -328,6 +319,10 @@ icon_closed = "mixed" /obj/structure/closet/wardrobe/mixed/New() + if(prob(25)) + new /obj/item/clothing/suit/jacket(src) + if(prob(25)) + new /obj/item/clothing/suit/jacket(src) new /obj/item/clothing/under/color/white(src) new /obj/item/clothing/under/color/blue(src) new /obj/item/clothing/under/color/yellow(src) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 7a91f06455c..53488cc89cb 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -333,7 +333,7 @@ return if(W) W.loc = src.loc - else if(istype(W, /obj/item/weapon/packageWrap)) + else if(istype(W, /obj/item/stack/packageWrap)) return else if(istype(W, /obj/item/stack/cable_coil)) if(rigged) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 63817318c05..0c4558d1bac 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -85,16 +85,14 @@ user.changeNext_move(CLICK_CD_MELEE) if (src.destroyed && src.occupied) new /obj/item/weapon/gun/energy/laser/captain( src.loc ) - user << "\b You deactivate the hover field built into the case." + user << "You deactivate the hover field built into the case." src.occupied = 0 src.add_fingerprint(user) update_icon() return else - usr << text("You kick the display case.") - for(var/mob/O in oviewers()) - if ((O.client && !( O.blinded ))) - O << text("[] kicks the display case.", usr) + user.visible_message("[user] kicks the display case.", \ + "You kick the display case.") src.health -= 2 healthcheck() return diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 22308b79619..cf2a205f65a 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -1,9 +1,11 @@ /obj/structure/girder + name = "girder" icon_state = "girder" anchored = 1 density = 1 layer = 2 var/state = 0 + var/girderpasschance = 20 // percentage chance that a projectile passes through the girder. /obj/structure/girder/attackby(obj/item/W as obj, mob/user as mob) add_fingerprint(user) @@ -180,6 +182,17 @@ ..() +/obj/structure/girder/CanPass(atom/movable/mover, turf/target, height=0) + if(height==0) + return 1 + if(istype(mover) && mover.checkpass(PASSGRILLE)) + return prob(girderpasschance) + else + if(istype(mover, /obj/item/projectile)) + return prob(girderpasschance) + else + return 0 + /obj/structure/girder/blob_act() if(prob(40)) qdel(src) @@ -206,12 +219,16 @@ return /obj/structure/girder/displaced + name = "displaced girder" icon_state = "displaced" anchored = 0 + girderpasschance = 25 /obj/structure/girder/reinforced + name = "reinforced girder" icon_state = "reinforced" state = 2 + girderpasschance = 0 /obj/structure/cultgirder icon= 'icons/obj/cult.dmi' diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 340933e8184..b94c5588c60 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -80,8 +80,8 @@ return -/obj/structure/grille/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 +/obj/structure/grille/CanPass(atom/movable/mover, turf/target, height=0) + if(height==0) return 1 if(istype(mover) && mover.checkpass(PASSGRILLE)) return 1 else diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 0e6416867dd..ee907422628 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -156,7 +156,7 @@ name = "janicart" icon = 'icons/obj/vehicles.dmi' icon_state = "pussywagon" - anchored = 1 + anchored = 0 density = 1 flags = OPENCONTAINER //copypaste sorry @@ -206,6 +206,8 @@ if(user.stat || user.stunned || user.weakened || user.paralysis) unbuckle() if(istype(user.l_hand, /obj/item/key) || istype(user.r_hand, /obj/item/key)) + if(!Process_Spacemove(direction)) + return step(src, direction) update_mob() handle_rotation() @@ -213,13 +215,6 @@ user << "You'll need the keys in one of your hands to drive this [callme]." -/obj/structure/stool/bed/chair/janicart/Move() - ..() - if(buckled_mob) - if(buckled_mob.buckled == src) - buckled_mob.loc = loc - - /obj/structure/stool/bed/chair/janicart/buckle_mob(mob/M, mob/user) if(M != user || !ismob(M) || get_dist(src, user) > 1 || user.restrained() || user.lying || user.stat || M.buckled || istype(user, /mob/living/silicon)) return diff --git a/code/game/objects/structures/lamarr_cage.dm b/code/game/objects/structures/lamarr_cage.dm index 69a6626d69a..b95ec7128c4 100644 --- a/code/game/objects/structures/lamarr_cage.dm +++ b/code/game/objects/structures/lamarr_cage.dm @@ -75,10 +75,8 @@ if (src.destroyed) return else - usr << text("You kick the lab cage.") - for(var/mob/O in oviewers()) - if ((O.client && !( O.blinded ))) - O << text("[] kicks the lab cage.", usr) + user.visible_message("[user] kicks the lab cage.", \ + "You kick the lab cage.") src.health -= 2 healthcheck() return diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index e163f334470..0ce35f52907 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -55,8 +55,7 @@ /obj/structure/mineral_door/attack_hand(mob/user) return TryToSwitchState(user) -/obj/structure/mineral_door/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group) return 0 +/obj/structure/mineral_door/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover, /obj/effect/beam)) return !opacity return !density diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index ba98fa3d0de..bf542a54c9c 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -25,7 +25,7 @@ CheckHardness() /obj/structure/statue/attack_hand(mob/user) - visible_message("[user] rubs some dust off from the [name]'s surface.") + visible_message("[user] rubs some dust off from the [name]'s surface.") /obj/structure/statue/CanAtmosPass() return !density 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 b5e4b9c1f0c..f4a0a0a6ed9 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -22,6 +22,28 @@ unbuckle() ..() +/obj/structure/stool/bed/Move(atom/newloc, direct) //Some bed children move + . = ..() + if(buckled_mob) + buckled_mob.buckled = null + if(!buckled_mob.Move(loc, direct)) + loc = buckled_mob.loc //we gotta go back + last_move = buckled_mob.last_move + inertia_dir = last_move + buckled_mob.inertia_dir = last_move + . = 0 + buckled_mob.buckled = src + +/obj/structure/stool/bed/Process_Spacemove(var/movement_dir = 0) + if(buckled_mob) + return buckled_mob.Process_Spacemove(movement_dir) + return ..() + +/obj/structure/stool/bed/CanPass(atom/movable/mover, turf/target, height=1.5) + if(mover == buckled_mob) + return 1 + return ..() + /obj/structure/stool/bed/attack_paw(mob/user as mob) return src.attack_hand(user) @@ -49,9 +71,10 @@ buckled_mob.anchored = initial(buckled_mob.anchored) buckled_mob.update_canmove() - var/M = buckled_mob + var/mob/M = buckled_mob buckled_mob = null + M.newtonian_move(inertia_dir) afterbuckle(M) return @@ -135,13 +158,6 @@ icon_state = "down" M.pixel_y -= buckled_pixel_y_offset -/obj/structure/stool/bed/roller/Move() - ..() - if(buckled_mob) - if(buckled_mob.buckled == src) - buckled_mob.loc = src.loc - else - buckled_mob = null /obj/item/roller name = "roller bed" diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index 8838ba46f78..be89e7e6a5c 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -11,6 +11,10 @@ handle_layer() return +/obj/structure/stool/bed/chair/Move(atom/newloc, direct) + ..() + handle_rotation() + /obj/structure/stool/bed/chair/attackby(obj/item/weapon/W as obj, mob/user as mob) ..() if(istype(W, /obj/item/assembly/shock_kit)) @@ -30,10 +34,10 @@ rotate() return -/obj/structure/stool/bed/chair/proc/handle_rotation(direction) //making this into a seperate proc so office chairs can call it on Move() +/obj/structure/stool/bed/chair/proc/handle_rotation(direction) if(buckled_mob) buckled_mob.buckled = null //Temporary, so Move() succeeds. - if(!buckled_mob.Move(direction)) + if(!direction || !buckled_mob.Move(get_step(src, direction), direction)) buckled_mob.buckled = src dir = buckled_mob.dir return 0 @@ -127,11 +131,6 @@ /obj/structure/stool/bed/chair/office anchored = 0 -/obj/structure/stool/bed/chair/office/Move(direction) - if(handle_rotation(direction)) - ..() - handle_layer() - /obj/structure/stool/bed/chair/office/light icon_state = "officechair_white" diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 7282c72c177..82b9f69e9bd 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -262,8 +262,8 @@ /obj/structure/table/attack_tk() // no telehulk sorry return -/obj/structure/table/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 +/obj/structure/table/CanPass(atom/movable/mover, turf/target, height=0) + if(height==0) return 1 if(istype(mover) && mover.checkpass(PASSTABLE)) return 1 @@ -468,8 +468,8 @@ Destroy type values: qdel(src) return -/obj/structure/rack/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 +/obj/structure/rack/CanPass(atom/movable/mover, turf/target, height=0) + if(height==0) return 1 if(src.density == 0) //Because broken racks -Agouri |TODO: SPRITE!| return 1 if(istype(mover) && mover.checkpass(PASSTABLE)) diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm index ed395cc19e5..9e9afcc61dc 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -55,6 +55,11 @@ for(var/atom/movable/M in src.contents) M.loc = src.loc +/obj/structure/transit_tube_pod/Process_Spacemove() + if(moving) //No drifting while moving in the tubes + return 1 + else return ..() + /obj/structure/transit_tube_pod/proc/follow_tube(var/reverse_launch) if(moving) return @@ -97,7 +102,7 @@ if(current_tube == null) dir = next_dir - Move(get_step(loc, dir)) // Allow collisions when leaving the tubes. + Move(get_step(loc, dir), dir) // Allow collisions when leaving the tubes. break last_delay = current_tube.enter_delay(src, next_dir) @@ -111,22 +116,6 @@ break density = 1 - - // If the pod is no longer in a tube, move in a line until stopped or slowed to a halt. - // /turf/inertial_drift appears to only work on mobs, and re-implementing some of the - // logic allows a gradual slowdown and eventual stop when passing over non-space turfs. - if(!current_tube && last_delay <= 10) - do - sleep(last_delay) - - if(!istype(loc, /turf/space)) - last_delay++ - - if(last_delay > 10) - break - - while(isturf(loc) && Move(get_step(loc, dir))) - moving = 0 diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index d1dbc0e6a22..fbb5a473b1d 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -45,11 +45,10 @@ obj/structure/windoor_assembly/Destroy() /obj/structure/windoor_assembly/update_icon() icon_state = "[facing]_[secure ? "secure_" : ""]windoor_assembly[state]" -/obj/structure/windoor_assembly/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/obj/structure/windoor_assembly/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover) && mover.checkpass(PASSGLASS)) return 1 if(get_dir(loc, target) == dir) //Make sure looking at appropriate border - if(air_group) return 0 return !density else return 1 diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index a50ec4e2d06..415360bb913 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -51,7 +51,7 @@ qdel(src) -/obj/structure/window/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/obj/structure/window/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover) && mover.checkpass(PASSGLASS)) return 1 if(dir == SOUTHWEST || dir == SOUTHEAST || dir == NORTHWEST || dir == NORTHEAST) @@ -206,7 +206,7 @@ if(!is_fulltile()) if(get_dir(user,src) & dir) for(var/obj/O in loc) - if(!O.CanPass(user, user.loc, 1, 0)) + if(!O.CanPass(user, user.loc, 1)) return 0 return 1 diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 8e38ac30808..acdb0fab9c4 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -37,18 +37,6 @@ if (istype(A,/mob/living/carbon)) var/mob/living/carbon/M = A if(M.lying) return - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(istype(H.shoes, /obj/item/clothing/shoes/clown_shoes)) - var/obj/item/clothing/shoes/clown_shoes/O = H.shoes - if(H.m_intent == "run") - if(O.footstep >= 2) - O.footstep = 0 - playsound(src, "clownstep", 50, 1) // this will get annoying very fast. - else - O.footstep++ - else - playsound(src, "clownstep", 20, 1) switch (src.wet) if(1) //wet floor diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 4e8ae18a48c..a075d11a87d 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -12,22 +12,14 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3"," "ironsand6", "ironsand7", "ironsand8", "ironsand9", "ironsand10", "ironsand11", "ironsand12", "ironsand13", "ironsand14", "ironsand15") -var/list/plating_icons = list("plating","platingdmg1","platingdmg2","platingdmg3","asteroid","asteroid_dug", - "ironsand1", "ironsand2", "ironsand3", "ironsand4", "ironsand5", "ironsand6", "ironsand7", - "ironsand8", "ironsand9", "ironsand10", "ironsand11", - "ironsand12", "ironsand13", "ironsand14", "ironsand15") -var/list/wood_icons = list("wood","wood-broken") -var/list/gold_icons = list("gold","gold_dam") -var/list/silver_icons = list("silver","silver_dam") -var/list/plasma_icons = list("plasma","plasma_dam") -var/list/diamond_icons = list("diamond","diamond_dam") -var/list/uranium_icons = list("uranium","uranium_dam") -var/list/bananium_icons = list("bananium","bananium_dam") - /turf/simulated/floor - - //Note to coders, the 'intact' var can no longer be used to determine if the floor is a plating or not. - //Use the is_plating(), is_plasteel_floor() and is_light_floor() procs instead. --Errorage + //NOTE: Floor code has been refactored, many procs were removed + //using intact should be safe, you can also use istype + //also worhy of note: floor_tile is now a path, and not a tile obj + //future improvements: + //- move fancy_update() to a new /turf/simulated/floor/fancy + //- move the default floor to /turf/simulated/floor/plasteel + //- unsnowflake the light floors somehow name = "floor" icon = 'icons/turf/floors.dmi' icon_state = "floor" @@ -36,13 +28,14 @@ var/list/bananium_icons = list("bananium","bananium_dam") var/icon_plating = "plating" thermal_conductivity = 0.040 heat_capacity = 10000 + intact = 1 var/lava = 0 var/broken = 0 var/burnt = 0 - var/mineral = "metal" - var/floortype = "metal" - var/obj/item/stack/tile/floor_tile = new/obj/item/stack/tile/plasteel - + var/floor_tile = /obj/item/stack/tile/plasteel + var/obj/item/stack/tile/builtin_tile = null //needed for performance reasons when the singularity rips off floor tiles + var/list/broken_states = list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5") + var/list/burnt_states = list() /turf/simulated/floor/New() ..() @@ -50,15 +43,16 @@ var/list/bananium_icons = list("bananium","bananium_dam") icon_regular_floor = "floor" else icon_regular_floor = icon_state + if(floor_tile) + builtin_tile = new floor_tile -//turf/simulated/floor/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +//turf/simulated/floor/CanPass(atom/movable/mover, turf/target, height=0) // if ((istype(mover, /obj/machinery/vehicle) && !(src.burnt))) // if (!( locate(/obj/machinery/mass_driver, src) )) // return 0 // return ..() /turf/simulated/floor/ex_act(severity) - //set src in oview(1) switch(severity) if(1.0) src.ChangeTurf(/turf/space) @@ -85,506 +79,92 @@ var/list/bananium_icons = list("bananium","bananium_dam") /turf/simulated/floor/blob_act() return -turf/simulated/floor/proc/update_icon() +/turf/simulated/floor/proc/update_icon() if(lava) - return + return 0 else if(is_plasteel_floor()) if(!broken && !burnt) icon_state = icon_regular_floor - else if(is_plating()) - if(!broken && !burnt) - icon_state = icon_plating //Because asteroids are 'platings' too. - else if(is_light_floor()) - var/obj/item/stack/tile/light/T = floor_tile - if(T.on) - switch(T.state) - if(0) - icon_state = "light_on" - SetLuminosity(1) - if(1) - var/num = pick("1","2","3","4") - icon_state = "light_on_flicker[num]" - SetLuminosity(1) - if(2) - icon_state = "light_on_broken" - SetLuminosity(1) - if(3) - icon_state = "light_off" - SetLuminosity(0) - else - SetLuminosity(0) - icon_state = "light_off" - else if(is_grass_floor()) - if(!broken && !burnt) - if(!(icon_state in list("grass1","grass2","grass3","grass4"))) - icon_state = "grass[pick("1","2","3","4")]" - else if(is_carpet_floor()) - if(!broken && !burnt) - if(icon_state == "carpetsymbol") //le snowflake :^) - return - - var/connectdir = 0 - for(var/direction in cardinal) - if(istype(get_step(src,direction),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,direction) - if(FF.is_carpet_floor()) - connectdir |= direction - - //Check the diagonal connections for corners, where you have, for example, connections both north and east. In this case it checks for a north-east connection to determine whether to add a corner marker or not. - var/diagonalconnect = 0 //1 = NE; 2 = SE; 4 = NW; 8 = SW - - //Northeast - if(connectdir & NORTH && connectdir & EAST) - if(istype(get_step(src,NORTHEAST),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,NORTHEAST) - if(FF.is_carpet_floor()) - diagonalconnect |= 1 - - //Southeast - if(connectdir & SOUTH && connectdir & EAST) - if(istype(get_step(src,SOUTHEAST),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,SOUTHEAST) - if(FF.is_carpet_floor()) - diagonalconnect |= 2 - - //Northwest - if(connectdir & NORTH && connectdir & WEST) - if(istype(get_step(src,NORTHWEST),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,NORTHWEST) - if(FF.is_carpet_floor()) - diagonalconnect |= 4 - - //Southwest - if(connectdir & SOUTH && connectdir & WEST) - if(istype(get_step(src,SOUTHWEST),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,SOUTHWEST) - if(FF.is_carpet_floor()) - diagonalconnect |= 8 - - icon_state = "carpet[connectdir]-[diagonalconnect]" - - else if(is_wood_floor()) - if(!broken && !burnt) - if( !(icon_state in wood_icons) ) - icon_state = "wood" - //world << "[icon_state]y's got [icon_state]" - - else if(is_gold_floor()) - if(!broken && !burnt) - if( !(icon_state in gold_icons) ) - icon_state = "gold" - - else if(is_silver_floor()) - if(!broken && !burnt) - if( !(icon_state in silver_icons) ) - icon_state = "silver" - - else if(is_plasma_floor()) - if(!broken && !burnt) - if( !(icon_state in plasma_icons) ) - icon_state = "plasma" - - else if(is_uranium_floor()) - if(!broken && !burnt) - if( !(icon_state in uranium_icons) ) - icon_state = "uranium" - - else if(is_diamond_floor()) - if(!broken && !burnt) - if( !(icon_state in diamond_icons) ) - icon_state = "diamond" - - else if(is_bananium_floor()) - if(!broken && !burnt) - if( !(icon_state in bananium_icons) ) - icon_state = "bananium" - - spawn(1) - if(istype(src,/turf/simulated/floor)) //Was throwing runtime errors due to a chance of it changing to space halfway through. - if(air) - update_visuals(air) - -/turf/simulated/floor/return_siding_icon_state() - ..() - if(is_grass_floor()) - var/dir_sum = 0 - for(var/direction in cardinal) - var/turf/T = get_step(src,direction) - if(!(T.is_grass_floor())) - dir_sum += direction - if(dir_sum) - return "wood_siding[dir_sum]" - else - return 0 - + return 0 + if(air) + update_visuals(air) + return 1 /turf/simulated/floor/attack_paw(mob/user as mob) return src.attack_hand(user) -/turf/simulated/floor/attack_hand(mob/user as mob) - if (is_light_floor()) - var/obj/item/stack/tile/light/T = floor_tile - T.on = !T.on - update_icon() - ..() - /turf/simulated/floor/proc/gets_drilled() return -/turf/simulated/floor/proc/break_tile_to_plating() - if(!is_plating()) - make_plating() - break_tile() - /turf/simulated/floor/is_plasteel_floor() - if(istype(floor_tile, /obj/item/stack/tile/plasteel)) + if(ispath(floor_tile, /obj/item/stack/tile/plasteel)) return 1 else return 0 -/turf/simulated/floor/is_light_floor() - if(istype(floor_tile, /obj/item/stack/tile/light)) - return 1 - else - return 0 +//updates neighboring carpet & grass +/turf/simulated/floor/proc/fancy_update(fancy_type) + for(var/direction in list(1,2,4,8,5,6,9,10)) + if(istype(get_step(src,direction), fancy_type)) + var/turf/simulated/floor/FF = get_step(src,direction) + FF.update_icon() -/turf/simulated/floor/is_grass_floor() - if(istype(floor_tile, /obj/item/stack/tile/grass)) - return 1 - else - return 0 - -/turf/simulated/floor/is_wood_floor() - if(istype(floor_tile, /obj/item/stack/tile/wood)) - return 1 - else - return 0 - -/turf/simulated/floor/is_gold_floor() - if(istype(floor_tile, /obj/item/stack/tile/mineral/gold)) - return 1 - else - return 0 - -/turf/simulated/floor/is_silver_floor() - if(istype(floor_tile, /obj/item/stack/tile/mineral/silver)) - return 1 - else - return 0 - -/turf/simulated/floor/is_plasma_floor() - if(istype(floor_tile, /obj/item/stack/tile/mineral/plasma)) - return 1 - else - return 0 - -/turf/simulated/floor/is_uranium_floor() - if(istype(floor_tile, /obj/item/stack/tile/mineral/uranium)) - return 1 - else - return 0 - -/turf/simulated/floor/is_diamond_floor() - if(istype(floor_tile, /obj/item/stack/tile/mineral/diamond)) - return 1 - else - return 0 - -/turf/simulated/floor/is_bananium_floor() - if(istype(floor_tile, /obj/item/stack/tile/mineral/bananium)) - return 1 - else - return 0 - -/turf/simulated/floor/is_carpet_floor() - if(istype(floor_tile, /obj/item/stack/tile/carpet)) - return 1 - else - return 0 - -/turf/simulated/floor/is_plating() - if(!floor_tile) - return 1 - return 0 +/turf/simulated/floor/proc/break_tile_to_plating() + var/turf/simulated/floor/plating/T = make_plating() + T.break_tile() /turf/simulated/floor/proc/break_tile() - if(istype(src,/turf/simulated/floor/engine)) return - if(istype(src,/turf/simulated/floor/mech_bay_recharge_floor)) - src.ChangeTurf(/turf/simulated/floor/plating) - if(broken) return - if(is_plasteel_floor()) - src.icon_state = "damaged[pick(1,2,3,4,5)]" - broken = 1 - else if(is_light_floor()) - src.icon_state = "light_broken" - broken = 1 - else if(is_plating()) - src.icon_state = "platingdmg[pick(1,2,3)]" - broken = 1 - else if(is_wood_floor()) - src.icon_state = "wood-broken" - broken = 1 - else if(is_carpet_floor()) - src.icon_state = "carpet-broken" - broken = 1 - else if(is_grass_floor()) - src.icon_state = "sand[pick("1","2","3")]" - broken = 1 - else if(is_gold_floor()) - src.icon_state = "gold_dam" - broken = 1 - else if(is_silver_floor()) - src.icon_state = "silver_dam" - broken = 1 - else if(is_diamond_floor()) - src.icon_state = "diamond_dam" - broken = 1 - else if(is_bananium_floor()) - src.icon_state = "bananium_dam" - broken = 1 - else if(is_uranium_floor()) - src.icon_state = "uranium_dam" - broken = 1 - else if(is_plasma_floor()) - src.icon_state = "plasma_dam" - broken = 1 + if(broken) + return + icon_state = pick(broken_states) + broken = 1 /turf/simulated/floor/proc/burn_tile() - if(istype(src,/turf/simulated/floor/engine)) return - if(istype(src,/turf/simulated/floor/plating/asteroid/airless)) return//Asteroid tiles don't burn - if(broken || burnt) return - if(is_plasteel_floor()) - src.icon_state = "damaged[pick(1,2,3,4,5)]" - burnt = 1 - else if(is_plasteel_floor()) - src.icon_state = "floorscorched[pick(1,2)]" - burnt = 1 - else if(is_plating()) - src.icon_state = "panelscorched" - burnt = 1 - else if(is_wood_floor()) - src.icon_state = "wood-broken" - burnt = 1 - else if(is_carpet_floor()) - src.icon_state = "carpet-broken" - burnt = 1 - else if(is_grass_floor()) - src.icon_state = "sand[pick("1","2","3")]" - burnt = 1 - else if(is_gold_floor()) - src.icon_state = "gold_dam" - burnt = 1 - else if(is_silver_floor()) - src.icon_state = "silver_dam" - burnt = 1 - else if(is_diamond_floor()) - src.icon_state = "diamond_dam" - burnt = 1 - else if(is_bananium_floor()) - src.icon_state = "bananium_dam" - burnt = 1 - else if(is_uranium_floor()) - src.icon_state = "uranium_dam" - burnt = 1 - -//This proc will delete the floor_tile and the update_iocn() proc will then change the icon_state of the turf -//This proc auto corrects the grass tiles' siding. -/turf/simulated/floor/proc/make_plating() - if(istype(src,/turf/simulated/floor/engine)) return - - if(is_grass_floor()) - for(var/direction in cardinal) - if(istype(get_step(src,direction),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,direction) - FF.update_icon() //so siding get updated properly - else if(is_carpet_floor()) - spawn(5) - if(src) - for(var/direction in list(1,2,4,8,5,6,9,10)) - if(istype(get_step(src,direction),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,direction) - FF.update_icon() //so siding get updated properly - - if (icon_plating) - icon_state = icon_plating - else - icon_state = "plating" //Nothing is defined, so just make it plating - icon_plating = "plating" - if(floor_tile) - qdel(floor_tile) - - SetLuminosity(0) - floor_tile = null - intact = 0 - broken = 0 - burnt = 0 - - update_icon() - levelupdate() - -//This proc will make the turf a plasteel floor tile. The expected argument is the tile to make the turf with -//If none is given it will make a new object. dropping or unequipping must be handled before or after calling -//this proc. -/turf/simulated/floor/proc/make_plasteel_floor(var/obj/item/stack/tile/plasteel/T = null) - broken = 0 - burnt = 0 - intact = 1 - SetLuminosity(0) - if(T) - if(istype(T, /obj/item/stack/tile/plasteel)) - floor_tile = T - if (icon_regular_floor) - icon_state = icon_regular_floor - else - icon_state = "floor" - icon_regular_floor = "floor" - update_icon() - levelupdate() - return - //if you gave a valid parameter, it won't get this far. - floor_tile = new/obj/item/stack/tile/plasteel - icon_state = "floor" - icon_regular_floor = "floor" - - update_icon() - levelupdate() - -/turf/simulated/floor/proc/make_floor(floor_tile, T) - broken = 0 - burnt = 0 - intact = 1 - if(T) - floor_tile = T - update_icon() - levelupdate() + if(broken || burnt) return -//This proc will make the turf a light floor tile. The expected argument is the tile to make the turf with -//If none is given it will make a new object. dropping or unequipping must be handled before or after calling -//this proc. + if(is_plasteel_floor()) + icon_state = "floorscorched[pick(1,2)]" + else if(burnt_states) + icon_state = pick(burnt_states) + else + icon_state = pick(broken_states) + burnt = 1 + +/turf/simulated/floor/proc/make_plating() + return make_floor(/turf/simulated/floor/plating) + +//wrapper for ChangeTurf that handles flooring properly +/turf/simulated/floor/proc/make_floor(turf/simulated/floor/T as turf) + SetLuminosity(0) + var/old_type = type + var/old_icon = icon_regular_floor + var/old_dir = dir + var/turf/simulated/floor/W = ChangeTurf(T) + W.icon_regular_floor = old_icon + W.dir = old_dir + W.update_icon() + W.fancy_update(old_type) + return W /turf/simulated/floor/attackby(obj/item/C as obj, mob/user as mob) - if(!C || !user) - return 0 - - if(istype(C,/obj/item/weapon/light/bulb)) //only for light tiles - if(is_light_floor()) - var/obj/item/stack/tile/light/T = floor_tile - if(T.state) - user.drop_item() - qdel(C) - T.state = C //fixing it by bashing it with a light bulb, fun eh? - update_icon() - user << "You replace the light bulb." - else - user << "The lightbulb seems fine, no need to replace it." - - if(istype(C, /obj/item/weapon/crowbar) && (!(is_plating()))) + return 1 + if(istype(C, /obj/item/weapon/crowbar)) if(broken || burnt) + broken = 0 + burnt = 0 user << "You remove the broken plating." else - if(is_wood_floor()) + if(istype(src, /turf/simulated/floor/wood)) user << "You forcefully pry off the planks, destroying them in the process." else - user << "You remove the [floor_tile.name]." - new floor_tile.type(src) - + user << "You remove the floor tile." + var/obj/item/stack/tile/T = new floor_tile(src) + if(istype(T, /obj/item/stack/tile/light)) + var/obj/item/stack/tile/light/L = T + var/turf/simulated/floor/light/F = src + L.state = F.state make_plating() playsound(src, 'sound/items/Crowbar.ogg', 80, 1) - - return - - if(istype(C, /obj/item/weapon/screwdriver) && is_wood_floor()) - if(broken || burnt) - return - else - if(is_wood_floor()) - user << "You unscrew the planks." - new floor_tile.type(src) - - make_plating() - playsound(src, 'sound/items/Screwdriver.ogg', 80, 1) - - return - - if(istype(C, /obj/item/stack/rods)) - var/obj/item/stack/rods/R = C - if (is_plating()) - if (R.get_amount() < 2) - user << "You need two rods to make a reinforced floor." - return - else - user << "Reinforcing the floor..." - if(do_after(user, 30)) - if (R.get_amount() >= 2 && is_plating()) - ChangeTurf(/turf/simulated/floor/engine) - playsound(src, 'sound/items/Deconstruct.ogg', 80, 1) - R.use(2) - user << "You have reinforced the floor." - return - else - user << "You must remove the plating first." - return - - if(istype(C, /obj/item/stack/tile)) - if(is_plating()) - if(!broken && !burnt) - var/obj/item/stack/tile/T = C - if(istype(T, /obj/item/stack/tile/plasteel/cyborg)) - floor_tile = new /obj/item/stack/tile/plasteel - else - floor_tile = new T.type - intact = 1 - if(istype(T,/obj/item/stack/tile/light)) - var/obj/item/stack/tile/light/L = T - var/obj/item/stack/tile/light/F = floor_tile - F.state = L.state - F.on = L.on - if(istype(T,/obj/item/stack/tile/grass)) - for(var/direction in cardinal) - if(istype(get_step(src,direction),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,direction) - FF.update_icon() //so siding gets updated properly - else if(istype(T,/obj/item/stack/tile/carpet)) - for(var/direction in list(1,2,4,8,5,6,9,10)) - if(istype(get_step(src,direction),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,direction) - FF.update_icon() //so siding gets updated properly - T.use(1) - update_icon() - levelupdate() - playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) - else - user << "This section is too damaged to support a tile. Use a welder to fix the damage." - - - if(istype(C, /obj/item/stack/cable_coil)) - if(is_plating()) - var/obj/item/stack/cable_coil/coil = C - for(var/obj/structure/cable/LC in src) - if((LC.d1==0)||(LC.d2==0)) - LC.attackby(C,user) - return - coil.turf_place(src, user) - else - user << "You must remove the plating first." - - if(istype(C, /obj/item/weapon/shovel)) - if(is_grass_floor()) - new /obj/item/weapon/ore/glass(src) - new /obj/item/weapon/ore/glass(src) //Make some sand if you shovel grass - user << "You shovel the grass." - make_plating() - else - user << "You cannot shovel this." - - if(istype(C, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/welder = C - if(welder.isOn() && (is_plating())) - if(broken || burnt) - if(welder.remove_fuel(0,user)) - user << "You fix some dents on the broken plating." - playsound(src, 'sound/items/Welder.ogg', 80, 1) - icon_state = icon_plating - burnt = 0 - broken = 0 + return 1 + return 0 diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm new file mode 100644 index 00000000000..fb9b6b7caac --- /dev/null +++ b/code/game/turfs/simulated/floor/fancy_floor.dm @@ -0,0 +1,115 @@ +/* In this file: + * Wood floor + * Grass floor + * Carpet floor + */ + +/turf/simulated/floor/wood + name = "floor" + icon_state = "wood" + floor_tile = /obj/item/stack/tile/wood + broken_states = list("wood-broken", "wood-broken2", "wood-broken3", "wood-broken4", "wood-broken5", "wood-broken6", "wood-broken7") + +/turf/simulated/floor/wood/attackby(obj/item/C as obj, mob/user as mob) + if(..()) + return + if(istype(C, /obj/item/weapon/screwdriver)) + if(broken || burnt) + return + user << "You unscrew the planks." + new floor_tile(src) + make_plating() + playsound(src, 'sound/items/Screwdriver.ogg', 80, 1) + return + +/turf/simulated/floor/grass + name = "Grass patch" + icon_state = "grass1" + floor_tile = /obj/item/stack/tile/grass + broken_states = list("sand1", "sand2", "sand3") + +/turf/simulated/floor/grass/New() + ..() + icon_state = "grass[pick("1","2","3","4")]" + spawn(1) + if(src) + update_icon() + fancy_update(type) + +/turf/simulated/floor/grass/attackby(obj/item/C as obj, mob/user as mob) + if(..()) + return + if(istype(C, /obj/item/weapon/shovel)) + new /obj/item/weapon/ore/glass(src) + new /obj/item/weapon/ore/glass(src) //Make some sand if you shovel grass + user << "You shovel the grass." + make_plating() + +/turf/simulated/floor/grass/return_siding_icon_state() + ..() + var/dir_sum = 0 + for(var/direction in cardinal) + if(!istype(get_step(src,direction), /turf/simulated/floor/grass)) + dir_sum += direction + if(dir_sum) + return "wood_siding[dir_sum]" + else + return 0 + +/turf/simulated/floor/carpet + name = "Carpet" + icon_state = "carpet" + floor_tile = /obj/item/stack/tile/carpet + broken_states = list("carpet-broken") + +/turf/simulated/floor/carpet/New() + ..() + spawn(1) + if(src) + update_icon() + fancy_update(type) + +/turf/simulated/floor/carpet/update_icon() + if(!broken && !burnt) + if(icon_state == "carpetsymbol") //le snowflake :^) + return + + var/connectdir = 0 + for(var/direction in cardinal) + if(istype(get_step(src,direction),/turf/simulated/floor/carpet)) + var/turf/simulated/floor/carpet/FF = get_step(src,direction) + if(istype(FF, /turf/simulated/floor/carpet)) + connectdir |= direction + + //Check the diagonal connections for corners, where you have, for example, connections both north and east. In this case it checks for a north-east connection to determine whether to add a corner marker or not. + var/diagonalconnect = 0 //1 = NE; 2 = SE; 4 = NW; 8 = SW + + //Northeast + if(connectdir & NORTH && connectdir & EAST) + if(istype(get_step(src,NORTHEAST),/turf/simulated/floor)) + var/turf/simulated/floor/FF = get_step(src,NORTHEAST) + if(istype(FF, /turf/simulated/floor/carpet)) + diagonalconnect |= 1 + + //Southeast + if(connectdir & SOUTH && connectdir & EAST) + if(istype(get_step(src,SOUTHEAST),/turf/simulated/floor)) + var/turf/simulated/floor/FF = get_step(src,SOUTHEAST) + if(istype(FF, /turf/simulated/floor/carpet)) + diagonalconnect |= 2 + + //Northwest + if(connectdir & NORTH && connectdir & WEST) + if(istype(get_step(src,NORTHWEST),/turf/simulated/floor)) + var/turf/simulated/floor/FF = get_step(src,NORTHWEST) + if(istype(FF, /turf/simulated/floor/carpet)) + diagonalconnect |= 4 + + //Southwest + if(connectdir & SOUTH && connectdir & WEST) + if(istype(get_step(src,SOUTHWEST),/turf/simulated/floor)) + var/turf/simulated/floor/FF = get_step(src,SOUTHWEST) + if(istype(FF, /turf/simulated/floor/carpet)) + diagonalconnect |= 8 + + icon_state = "carpet[connectdir]-[diagonalconnect]" diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm new file mode 100644 index 00000000000..2b0296246d9 --- /dev/null +++ b/code/game/turfs/simulated/floor/light_floor.dm @@ -0,0 +1,56 @@ +/* In this file: + * + * Light floor + */ + +/turf/simulated/floor/light + name = "Light floor" + luminosity = 5 + icon_state = "light_on" + floor_tile = /obj/item/stack/tile/light + broken_states = list("light-broken") + var/on = 1 + var/state //0 = fine, 1 = flickering, 2 = breaking, 3 = broken + +/turf/simulated/floor/light/New() + ..() + update_icon() + +/turf/simulated/floor/light/update_icon() + if(on) + switch(state) + if(0) + icon_state = "light_on" + SetLuminosity(1) + if(1) + var/num = pick("1","2","3","4") + icon_state = "light_on_flicker[num]" + SetLuminosity(1) + if(2) + icon_state = "light_on_broken" + SetLuminosity(1) + if(3) + icon_state = "light_off" + SetLuminosity(0) + else + SetLuminosity(0) + icon_state = "light_off" + +/turf/simulated/floor/light/attack_hand(mob/user as mob) + on = !on + update_icon() + ..() + +/turf/simulated/floor/light/attackby(obj/item/C as obj, mob/user as mob) + if(..()) + return + if(istype(C,/obj/item/weapon/light/bulb)) //only for light tiles + if(state) + user.drop_item() + qdel(C) + state = 0 //fixing it by bashing it with a light bulb, fun eh? + update_icon() + user << "You replace the light bulb." + else + user << "The lightbulb seems fine, no need to replace it." + return diff --git a/code/game/turfs/simulated/floor/mineral_floor.dm b/code/game/turfs/simulated/floor/mineral_floor.dm new file mode 100644 index 00000000000..29242623f91 --- /dev/null +++ b/code/game/turfs/simulated/floor/mineral_floor.dm @@ -0,0 +1,64 @@ +/* In this file: + * + * Plasma floor + * Gold floor + * Silver floor + * Bananium floor + * Diamond floor + * Uranium floor + */ + +/turf/simulated/floor/mineral + name = "mineral floor" + icon_state = "" + var/list/icons = list() + +/turf/simulated/floor/mineral/New() + ..() + broken_states = list("[initial(icon_state)]_dam") + +/turf/simulated/floor/mineral/update_icon() + if(!broken && !burnt) + if( !(icon_state in icons) ) + icon_state = initial(icon_state) + +/turf/simulated/floor/mineral/plasma + name = "plasma floor" + icon_state = "plasma" + floor_tile = /obj/item/stack/tile/mineral/plasma + icons = list("plasma","plasma_dam") + +/turf/simulated/floor/mineral/gold + name = "gold floor" + icon_state = "gold" + floor_tile = /obj/item/stack/tile/mineral/gold + icons = list("gold","gold_dam") + +/turf/simulated/floor/mineral/silver + name = "silver floor" + icon_state = "silver" + floor_tile = /obj/item/stack/tile/mineral/silver + icons = list("silver","silver_dam") + +/turf/simulated/floor/mineral/bananium + name = "bananium floor" + icon_state = "bananium" + floor_tile = /obj/item/stack/tile/mineral/bananium + icons = list("bananium","bananium_dam") + +/turf/simulated/floor/mineral/bananium/airless + oxygen = 0.01 + nitrogen = 0.01 + temperature = TCMB + +/turf/simulated/floor/mineral/diamond + name = "diamond floor" + icon_state = "diamond" + floor_tile = /obj/item/stack/tile/mineral/diamond + icons = list("diamond","diamond_dam") + +/turf/simulated/floor/mineral/uranium + name = "uranium floor" + icon_state = "uranium" + floor_tile = /obj/item/stack/tile/mineral/uranium + icons = list("uranium","uranium_dam") \ No newline at end of file diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm new file mode 100644 index 00000000000..b5ebf04f44e --- /dev/null +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -0,0 +1,93 @@ +/* In this file: + * + * Commemorative Plaque + * Vault floor + * Vault wall (why) + * Blue grid + * Green grid + * Shuttle floor + * Beach + * Ocean + * Iron Sand + * Snow + */ + +/turf/simulated/floor/goonplaque + name = "Commemorative Plaque" + icon_state = "plaque" + desc = "\"This is a plaque in honour of our comrades on the G4407 Stations. Hopefully TG4407 model can live up to your fame and fortune.\" Scratched in beneath that is a crude image of a meteor and a spaceman. The spaceman is laughing. The meteor is exploding." + +/turf/simulated/floor/vault + icon_state = "rockvault" + +/turf/simulated/wall/vault + icon_state = "rockvault" + +/turf/simulated/floor/bluegrid + icon = 'icons/turf/floors.dmi' + icon_state = "bcircuit" + +/turf/simulated/floor/greengrid + icon = 'icons/turf/floors.dmi' + icon_state = "gcircuit" + + +/turf/simulated/shuttle + name = "shuttle" + icon = 'icons/turf/shuttle.dmi' + thermal_conductivity = 0.05 + heat_capacity = 0 + layer = 2 + +/turf/simulated/shuttle/wall + name = "wall" + icon_state = "wall1" + opacity = 1 + density = 1 + blocks_air = 1 + +/turf/simulated/shuttle/floor + name = "floor" + icon_state = "floor" + +/turf/simulated/shuttle/plating + name = "plating" + icon = 'icons/turf/floors.dmi' + icon_state = "plating" + +/turf/simulated/shuttle/floor4 // Added this floor tile so that I have a seperate turf to check in the shuttle -- Polymorph + name = "Brig floor" // Also added it into the 2x3 brig area of the shuttle. + icon_state = "floor4" + +/turf/simulated/floor/beach + name = "Beach" + icon = 'icons/misc/beach.dmi' + +/turf/simulated/floor/beach/ex_act(severity) + return + +/turf/simulated/floor/beach/sand + name = "Sand" + icon_state = "sand" + +/turf/simulated/floor/beach/coastline + name = "Coastline" + icon = 'icons/misc/beach2.dmi' + icon_state = "sandwater" + +/turf/simulated/floor/beach/water + name = "Water" + icon_state = "water" + +/turf/simulated/floor/plating/ironsand/New() + ..() + name = "Iron Sand" + icon_state = "ironsand[rand(1,15)]" + +/turf/simulated/floor/plating/snow + name = "snow" + icon = 'icons/turf/snow.dmi' + icon_state = "snow" + +/turf/simulated/floor/plating/snow/ex_act(severity) + return diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm new file mode 100644 index 00000000000..827c8922c8e --- /dev/null +++ b/code/game/turfs/simulated/floor/plating.dm @@ -0,0 +1,145 @@ +/* In this file: + * + * Plating + * Airless + * Airless plating + * Engine floor + */ +// note that plating and engine floor do not call their parent attackby, unlike other flooring +// this is done in order to avoid inheriting the crowbar attackby + +/turf/simulated/floor/plating + name = "plating" + icon_state = "plating" + floor_tile = null + intact = 0 + broken_states = list("platingdmg1", "platingdmg2", "platingdmg3") + burnt_states = list("panelscorched") + +/turf/simulated/floor/plating/New() + ..() + icon_plating = icon_state + +/turf/simulated/floor/plating/update_icon() + if(..()) + return + if(!broken && !burnt) + icon_state = icon_plating //Because asteroids are 'platings' too. + +/turf/simulated/floor/plating/attackby(obj/item/C as obj, mob/user as mob) + if(!C || !user) + return + if(istype(C, /obj/item/stack/rods)) + var/obj/item/stack/rods/R = C + if (R.get_amount() < 2) + user << "You need two rods to make a reinforced floor." + return + else + user << "Reinforcing the floor..." + if(do_after(user, 30)) + if (R.get_amount() >= 2) + ChangeTurf(/turf/simulated/floor/engine) + playsound(src, 'sound/items/Deconstruct.ogg', 80, 1) + R.use(2) + user << "You have reinforced the floor." + return + else if(istype(C, /obj/item/stack/tile)) + if(!broken && !burnt) + var/obj/item/stack/tile/W = C + var/turf/simulated/floor/T = make_floor(W.turf_type) + if(istype(W,/obj/item/stack/tile/light)) + var/obj/item/stack/tile/light/L = W + var/turf/simulated/floor/light/F = T + F.state = L.state + W.use(1) + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + else + user << "This section is too damaged to support a tile. Use a welder to fix the damage." + else if(istype(C, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/coil = C + for(var/obj/structure/cable/LC in src) + if((LC.d1==0)||(LC.d2==0)) + LC.attackby(C,user) + return + coil.turf_place(src, user) + else if(istype(C, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/welder = C + if( welder.isOn() && (broken || burnt) ) + if(welder.remove_fuel(0,user)) + user << "You fix some dents on the broken plating." + playsound(src, 'sound/items/Welder.ogg', 80, 1) + icon_state = icon_plating + burnt = 0 + broken = 0 + +/turf/simulated/floor/plating/airless + icon_state = "plating" + name = "airless plating" + oxygen = 0.01 + nitrogen = 0.01 + temperature = TCMB + +/turf/simulated/floor/plating/airless/New() + ..() + name = "plating" + +/turf/simulated/floor/engine + name = "reinforced floor" + icon_state = "engine" + thermal_conductivity = 0.025 + heat_capacity = 325000 + +/turf/simulated/floor/engine/break_tile() + return //unbreakable + +/turf/simulated/floor/engine/burn_tile() + return //unburnable + +/turf/simulated/floor/engine/make_plating() + return //unplateable + +/turf/simulated/floor/engine/attackby(obj/item/weapon/C as obj, mob/user as mob) + if(!C || !user) + return + if(istype(C, /obj/item/weapon/wrench)) + user << "Removing rods..." + playsound(src, 'sound/items/Ratchet.ogg', 80, 1) + if(do_after(user, 30)) + new /obj/item/stack/rods(src, 2) + make_plating() + return + +/turf/simulated/floor/engine/cult + name = "engraved floor" + icon_state = "cult" + +/turf/simulated/floor/engine/n20/New() + ..() + var/datum/gas_mixture/adding = new + var/datum/gas/sleeping_agent/trace_gas = new + + trace_gas.moles = 6000 + adding.trace_gases += trace_gas + adding.temperature = T20C + + assume_air(adding) + +/turf/simulated/floor/engine/vacuum + name = "vacuum floor" + icon_state = "engine" + oxygen = 0 + nitrogen = 0.001 + temperature = TCMB + + + +/turf/simulated/floor/airless + icon_state = "floor" + name = "airless floor" + oxygen = 0.01 + nitrogen = 0.01 + temperature = TCMB + +/turf/simulated/floor/airless/New() + ..() + name = "floor" \ No newline at end of file diff --git a/code/game/turfs/simulated/floor_mineral.dm b/code/game/turfs/simulated/floor_mineral.dm deleted file mode 100644 index 018887a3dda..00000000000 --- a/code/game/turfs/simulated/floor_mineral.dm +++ /dev/null @@ -1,53 +0,0 @@ - -/turf/simulated/floor/mineral - name = "mineral floor" - icon_state = "" - var/last_event = 0 - var/active = null - -/turf/simulated/floor/mineral/plasma - name = "plasma floor" - icon_state = "plasma" - mineral = "plasma" - floortype = "plasma" - floor_tile = new/obj/item/stack/tile/mineral/plasma - -/turf/simulated/floor/mineral/gold - name = "gold floor" - icon_state = "gold" - mineral = "gold" - floortype = "gold" - floor_tile = new/obj/item/stack/tile/mineral/gold - -/turf/simulated/floor/mineral/silver - name = "silver floor" - icon_state = "silver" - mineral = "silver" - floortype = "silver" - floor_tile = new/obj/item/stack/tile/mineral/silver - -/turf/simulated/floor/mineral/bananium - name = "bananium floor" - icon_state = "bananium" - mineral = "bananium" - floortype = "bananium" - floor_tile = new/obj/item/stack/tile/mineral/bananium - -/turf/simulated/floor/mineral/bananium/airless - oxygen = 0.01 - nitrogen = 0.01 - temperature = TCMB - -/turf/simulated/floor/mineral/diamond - name = "diamond floor" - icon_state = "diamond" - mineral = "diamond" - floortype = "diamond" - floor_tile = new/obj/item/stack/tile/mineral/diamond - -/turf/simulated/floor/mineral/uranium - name = "uranium floor" - icon_state = "uranium" - mineral = "uranium" - floortype = "uranium" - floor_tile = new/obj/item/stack/tile/mineral/uranium \ No newline at end of file diff --git a/code/game/turfs/simulated/floor_types.dm b/code/game/turfs/simulated/floor_types.dm deleted file mode 100644 index b446d3f03c7..00000000000 --- a/code/game/turfs/simulated/floor_types.dm +++ /dev/null @@ -1,208 +0,0 @@ -/turf/simulated/floor/airless - icon_state = "floor" - name = "airless floor" - oxygen = 0.01 - nitrogen = 0.01 - temperature = TCMB - -/turf/simulated/floor/airless/New() - ..() - name = "floor" - -/turf/simulated/floor/light - name = "Light floor" - luminosity = 5 - icon_state = "light_on" - floor_tile = new/obj/item/stack/tile/light - -/turf/simulated/floor/light/New() - floor_tile.New() //I guess New() isn't run on objects spawned without the definition of a turf to house them, ah well. - var/n = name //just in case commands rename it in the ..() call - ..() - spawn(4) - if(src) - update_icon() - name = n - - - -/turf/simulated/floor/wood - name = "floor" - icon_state = "wood" - floor_tile = new/obj/item/stack/tile/wood - -/turf/simulated/floor/goonplaque - name = "Commemorative Plaque" - icon_state = "plaque" - desc = "\"This is a plaque in honour of our comrades on the G4407 Stations. Hopefully TG4407 model can live up to your fame and fortune.\" Scratched in beneath that is a crude image of a meteor and a spaceman. The spaceman is laughing. The meteor is exploding." - -/turf/simulated/floor/vault - icon_state = "rockvault" - -/turf/simulated/wall/vault - icon_state = "rockvault" - -/turf/simulated/floor/engine - name = "reinforced floor" - icon_state = "engine" - thermal_conductivity = 0.025 - heat_capacity = 325000 - -/turf/simulated/floor/engine/attackby(obj/item/weapon/C as obj, mob/user as mob) - if(!C) - return - if(!user) - return - if(istype(C, /obj/item/weapon/wrench)) - user << "Removing rods..." - playsound(src, 'sound/items/Ratchet.ogg', 80, 1) - if(do_after(user, 30)) - new /obj/item/stack/rods(src, 2) - ChangeTurf(/turf/simulated/floor) - var/turf/simulated/floor/F = src - F.make_plating() - return - -/turf/simulated/floor/engine/cult - name = "engraved floor" - icon_state = "cult" - - -/turf/simulated/floor/engine/n20/New() - ..() - var/datum/gas_mixture/adding = new - var/datum/gas/sleeping_agent/trace_gas = new - - trace_gas.moles = 6000 - adding.trace_gases += trace_gas - adding.temperature = T20C - - assume_air(adding) - -/turf/simulated/floor/engine/vacuum - name = "vacuum floor" - icon_state = "engine" - oxygen = 0 - nitrogen = 0.001 - temperature = TCMB - -/turf/simulated/floor/plating - name = "plating" - icon_state = "plating" - floor_tile = null - intact = 0 - -/turf/simulated/floor/plating/airless - icon_state = "plating" - name = "airless plating" - oxygen = 0.01 - nitrogen = 0.01 - temperature = TCMB - -/turf/simulated/floor/plating/airless/New() - ..() - name = "plating" - -/turf/simulated/floor/bluegrid - icon = 'icons/turf/floors.dmi' - icon_state = "bcircuit" - -/turf/simulated/floor/greengrid - icon = 'icons/turf/floors.dmi' - icon_state = "gcircuit" - - -/turf/simulated/shuttle - name = "shuttle" - icon = 'icons/turf/shuttle.dmi' - thermal_conductivity = 0.05 - heat_capacity = 0 - layer = 2 - -/turf/simulated/shuttle/wall - name = "wall" - icon_state = "wall1" - opacity = 1 - density = 1 - blocks_air = 1 - -/turf/simulated/shuttle/floor - name = "floor" - icon_state = "floor" - -/turf/simulated/shuttle/plating - name = "plating" - icon = 'icons/turf/floors.dmi' - icon_state = "plating" - -/turf/simulated/shuttle/floor4 // Added this floor tile so that I have a seperate turf to check in the shuttle -- Polymorph - name = "Brig floor" // Also added it into the 2x3 brig area of the shuttle. - icon_state = "floor4" - -/turf/simulated/floor/beach - name = "Beach" - icon = 'icons/misc/beach.dmi' - -/turf/simulated/floor/beach/sand - name = "Sand" - icon_state = "sand" - -/turf/simulated/floor/beach/coastline - name = "Coastline" - icon = 'icons/misc/beach2.dmi' - icon_state = "sandwater" - -/turf/simulated/floor/beach/water - name = "Water" - icon_state = "water" - - -/turf/simulated/floor/grass - name = "Grass patch" - icon_state = "grass1" - floor_tile = new/obj/item/stack/tile/grass - -/turf/simulated/floor/grass/New() - floor_tile.New() //I guess New() isn't ran on objects spawned without the definition of a turf to house them, ah well. - icon_state = "grass[pick("1","2","3","4")]" - ..() - spawn(4) - if(src) - update_icon() - for(var/direction in cardinal) - if(istype(get_step(src,direction),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,direction) - FF.update_icon() //so siding get updated properly - -/turf/simulated/floor/carpet - name = "Carpet" - icon_state = "carpet" - floor_tile = new/obj/item/stack/tile/carpet - -/turf/simulated/floor/carpet/New() - floor_tile.New() //I guess New() isn't ran on objects spawned without the definition of a turf to house them, ah well. - if(!icon_state) - icon_state = "carpet" - ..() - spawn(4) - if(src) - update_icon() - for(var/direction in list(1,2,4,8,5,6,9,10)) - if(istype(get_step(src,direction),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,direction) - FF.update_icon() //so siding get updated properly - - - -/turf/simulated/floor/plating/ironsand/New() - ..() - name = "Iron Sand" - icon_state = "ironsand[rand(1,15)]" - -/turf/simulated/floor/plating/snow - name = "snow" - icon = 'icons/turf/snow.dmi' - icon_state = "snow" - -/turf/simulated/floor/plating/snow/ex_act(severity) - return diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index fe355624d19..86a8d0bdd4e 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -41,7 +41,7 @@ qdel(L) playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) user << "You build a floor." - S.build(src) + ChangeTurf(/turf/simulated/floor) else user << "You need one floor tile to build a floor." else @@ -52,8 +52,6 @@ if ((!(A) || src != A.loc)) return - inertial_drift(A) - if(transition) if(destination_x) @@ -71,8 +69,8 @@ L.pulling.loc = T //now we're on the new z_level, proceed the space drifting - if ((A && A.loc)) - A.loc.Entered(A) + sleep(0)//Let a diagonal move finish, if necessary + A.newtonian_move(A.inertia_dir) /turf/space/proc/Sandbox_Spacemove(atom/movable/A) var/cur_x @@ -208,4 +206,7 @@ proc/setup_map_transitions() //listamania else S.transition = directions[Z_NORTH] - S.Assign_Destination() \ No newline at end of file + S.Assign_Destination() + +/turf/space/singularity_act() + return diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index c5a7f9d6c33..f00b9e16186 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -2,7 +2,6 @@ icon = 'icons/turf/floors.dmi' level = 1.0 - //for floors, use is_plating(), is_plasteel_floor() and is_light_floor() var/intact = 1 //Properties for open tiles (/floor) @@ -62,7 +61,7 @@ //Next, check objects to block entry that are on the border for(var/atom/movable/border_obstacle in src) if(border_obstacle.flags&ON_BORDER) - if(!border_obstacle.CanPass(mover, mover.loc, 1, 0) && (forget != border_obstacle)) + if(!border_obstacle.CanPass(mover, mover.loc, 1) && (forget != border_obstacle)) mover.Bump(border_obstacle, 1) return 0 else @@ -75,7 +74,7 @@ //Finally, check objects/mobs to block entry that are not on the border for(var/atom/movable/obstacle in large_dense) - if(!obstacle.CanPass(mover, mover.loc, 1, 0) && (forget != obstacle)) + if(!obstacle.CanPass(mover, mover.loc, 1) && (forget != obstacle)) mover.Bump(obstacle, 1) return 0 return 1 //Nothing found to block so return success! @@ -85,12 +84,7 @@ var/mob/O = M if(!O.lastarea) O.lastarea = get_area(O.loc) - var/has_gravity = O.mob_has_gravity(src) - O.update_gravity(has_gravity) - if(!has_gravity) - inertial_drift(O) - else if(!istype(src, /turf/space)) - O.inertia_dir = 0 + O.update_gravity(O.mob_has_gravity()) var/loopsanity = 100 for(var/atom/A in range(1)) @@ -99,54 +93,11 @@ loopsanity-- A.HasProximity(M, 1) -/turf/proc/is_plating() - return 0 -/turf/proc/is_asteroid_floor() - return 0 /turf/proc/is_plasteel_floor() return 0 -/turf/proc/is_light_floor() - return 0 -/turf/proc/is_grass_floor() - return 0 -/turf/proc/is_wood_floor() - return 0 -/turf/proc/is_gold_floor() - return 0 -/turf/proc/is_silver_floor() - return 0 -/turf/proc/is_plasma_floor() - return 0 -/turf/proc/is_uranium_floor() - return 0 -/turf/proc/is_bananium_floor() - return 0 -/turf/proc/is_diamond_floor() - return 0 -/turf/proc/is_carpet_floor() - return 0 /turf/proc/return_siding_icon_state() //used for grass floors, which have siding. return 0 -/turf/proc/inertial_drift(atom/movable/A as mob|obj) - if(!(A.last_move)) - return - if (A.pulledby) - return - if((istype(A, /mob/) && src.x > 2 && src.x < (world.maxx - 1) && src.y > 2 && src.y < (world.maxy-1))) - var/mob/M = A - if(M.Process_Spacemove(1)) - M.inertia_dir = 0 - return - spawn(5) - if((M && !(M.anchored) && (M.loc == src))) - if(M.inertia_dir & M.last_move) - step(M, M.inertia_dir) - return - M.inertia_dir = M.last_move - step(M, M.inertia_dir) - return - /turf/proc/levelupdate() for(var/obj/O in src) if(O.level == 1) @@ -352,7 +303,7 @@ var/mob/living/carbon/M = slipper if (M.m_intent=="walk" && (lube&NO_SLIP_WHEN_WALKING)) return 0 - if(!M.lying) + if(!M.lying && (M.status_flags & CANWEAKEN)) // we slip those who are standing and can fall. var/olddir = M.dir M.Stun(s_amount) M.Weaken(w_amount) @@ -370,4 +321,14 @@ M << "You slipped!" playsound(M.loc, 'sound/misc/slip.ogg', 50, 1, -3) return 1 - return 0 // no success. Used in clown pda and wet floors \ No newline at end of file + return 0 // no success. Used in clown pda and wet floors + +/turf/singularity_act() + if(intact) + for(var/obj/O in contents) //this is for deleting things like wires contained in the turf + if(O.level != 1) + continue + if(O.invisibility == 101) + O.singularity_act() + ChangeTurf(/turf/space) + return(2) diff --git a/code/game/verbs/atom_verbs.dm b/code/game/verbs/atom_verbs.dm index 2ff6efcf260..2726c11875f 100644 --- a/code/game/verbs/atom_verbs.dm +++ b/code/game/verbs/atom_verbs.dm @@ -6,28 +6,3 @@ if(Adjacent(usr)) usr.start_pulling(src) return - -/atom/verb/point() - set name = "Point To" - set category = "Object" - set src in oview() - var/atom/this = src//detach proc from src - src = null - - if(!usr || !isturf(usr.loc)) - return - if(usr.stat || usr.restrained()) - return - if(usr.status_flags & FAKEDEATH) - return - - var/tile = get_turf(this) - if (!tile) - return - - var/obj/P = new /obj/effect/decal/point(tile) - spawn (20) - if(P) - P.loc = null - - usr.visible_message("[usr] points to [this]") diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index c7d9b68037d..329fac62e98 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -113,7 +113,7 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = else adminwho += ", [C]" - reason = sql_sanitize_text(reason) + reason = sanitizeSQL(reason) if(maxadminbancheck) var/DBQuery/adm_query = dbcon.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey = '[a_ckey]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)") @@ -235,14 +235,14 @@ datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null) usr << "Invalid ban id. Contact the database admin" return - reason = sql_sanitize_text(reason) + reason = sanitizeSQL(reason) var/value switch(param) if("reason") if(!value) value = input("Insert the new reason for [pckey]'s ban", "New Reason", "[reason]", null) as null|text - value = sql_sanitize_text(value) + value = sanitizeSQL(value) if(!value) usr << "Cancelled" return diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 7412a768e39..95ec12426c6 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -794,26 +794,39 @@ var/global/floorIsLava = 0 if(!ai_number) usr << "No AIs located" //Just so you know the thing is actually working and not just ignoring you. -/datum/admins/proc/list_free_slots() +/datum/admins/proc/manage_free_slots() if(!check_rights()) return - var/dat = "List Free Slots" + var/dat = "Manage Free Slots" var/count = 0 + if(ticker && !ticker.mode) + alert(usr, "You cannot manage jobs before the round starts!") + return + if(job_master) for(var/datum/job/job in job_master.occupations) count++ var/J_title = html_encode(job.title) + var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions)) var/J_totPos = html_encode(job.total_positions) - dat += "[J_title]: [J_totPos]
    " + if(job.total_positions <= 0) + dat += "[J_title]: [J_opPos]" + else + dat += "[J_title]: [J_opPos]/[J_totPos]" + if(initial(job.total_positions) > 0) + dat += " Add | " + if(job.total_positions > job.current_positions) + dat += "Remove" + else + dat += "Remove" + dat += "
    " dat += "" var/winheight = 100 + (count * 20) winheight = min(winheight, 690) usr << browse(dat, "window=players;size=316x[winheight]") - - // // //ALL DONE diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 32a874d0f51..7fc699f736a 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -222,6 +222,10 @@ var/list/admin_ranks = list() //list of all admin_rank datums if("remove") if(alert("Are you sure you want to remove [adm_ckey]?","Message","Yes","Cancel") == "Yes") if(!D) return + if(!check_if_greater_rights_than_holder(D)) + message_admins("[key_name_admin(usr)] attempted to remove [adm_ckey] from the admins list without sufficient rights.") + log_admin("[key_name(usr)] attempted to remove [adm_ckey] from the admins list without sufficient rights.") + return admin_datums -= adm_ckey D.disassociate() @@ -244,6 +248,12 @@ var/list/admin_ranks = list() //list of all admin_rank datums new_rank = ckeyEx(input("Please input a new rank", "New custom rank", null, null) as null|text) if(!new_rank) return + if(D) + if(!check_if_greater_rights_than_holder(D)) + message_admins("[key_name_admin(usr)] attempted to change the rank of [adm_ckey] to [new_rank] without sufficient rights.") + log_admin("[key_name(usr)] attempted to change the rank of [adm_ckey] to [new_rank] without sufficient rights.") + return + R = rank_names[new_rank] if(!R) //rank with that name doesn't exist yet - make it if(D) R = new(new_rank, D.rank.rights, D.rank.adds, D.rank.subs) //duplicate our previous admin_rank but with a new name @@ -269,6 +279,11 @@ var/list/admin_ranks = list() //list of all admin_rank datums var/keyword = input("Input permission keyword (one at a time):\ne.g. +BAN or -FUN or +/client/proc/someverb", "Permission toggle", null, null) as null|text if(!keyword) return + if(!check_if_greater_rights_than_holder(D)) + message_admins("[key_name_admin(usr)] attempted to give [adm_ckey] the keyword [keyword] without sufficient rights.") + log_admin("[key_name(usr)] attempted to give [adm_ckey] the keyword [keyword] without sufficient rights.") + return + D.disassociate() if(!findtext(D.rank.name, "([adm_ckey])")) //not a modified subrank, need to duplicate the admin_rank datum to prevent modifying others too diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index b7bd3c8019c..fa48db048c4 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -14,6 +14,7 @@ var/list/admin_verbs_default = list( /client/proc/investigate_show, /*various admintools for investigation. Such as a singulo grief-log*/ /client/proc/secrets, /client/proc/reload_admins, + /client/proc/reestablish_db_connection,/*reattempt a connection to the database*/ /client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/ /client/proc/cmd_admin_pm_panel /*admin-pm list*/ ) @@ -184,7 +185,8 @@ var/list/admin_verbs_hideable = list( /client/proc/cmd_debug_del_all, /client/proc/enable_debug_verbs, /proc/possess, - /proc/release + /proc/release, + /client/proc/reload_admins ) /client/proc/add_admin_verbs() diff --git a/code/modules/admin/banappearance.dm b/code/modules/admin/banappearance.dm index 991fa9ad362..be59efff4f7 100644 --- a/code/modules/admin/banappearance.dm +++ b/code/modules/admin/banappearance.dm @@ -99,7 +99,7 @@ proc/DB_ban_isappearancebanned(var/playerckey) if(!dbcon.IsConnected()) return - var/sqlplayerckey = sql_sanitize_text(ckey(playerckey)) + var/sqlplayerckey = sanitizeSQL(ckey(playerckey)) var/DBQuery/query = dbcon.NewQuery("SELECT id FROM [format_table_name("ban")] WHERE CKEY = '[sqlplayerckey]' AND ((bantype = 'APPEARANCE_PERMABAN') OR (bantype = 'APPEARANCE_TEMPBAN' AND expiration_time > Now())) AND unbanned != 1") query.Execute() diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index eb1445669f5..8b289da6f70 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -40,6 +40,16 @@ var/list/admin_datums = list() owner.holder = null owner = null +/datum/admins/proc/check_if_greater_rights_than_holder(datum/admins/other) + if(!other) + return 1 //they have no rights + if(rank.rights == 65535) + return 1 //we have all the rights + if(rank.rights != other.rank.rights) + if( (rank.rights & other.rank.rights) == other.rank.rights ) + return 1 //we have all the rights they have and more + return 0 + /* checks if usr is an admin with at least ONE of the flags in rights_required. (Note, they don't need all the flags) if rights_required == 0, then it simply checks if they are an admin. @@ -68,13 +78,9 @@ you will have to do something like if(client.rights & R_ADMIN) yourself. if(usr.client.holder) if(!other || !other.holder) return 1 - if(usr.client.holder.rank.rights != other.holder.rank.rights) //Check values smaller than 65536 - if( (usr.client.holder.rank.rights & other.holder.rank.rights) == other.holder.rank.rights ) - return 1 //we have all the rights they have and more - usr << "Error: Cannot proceed. They have greater or equal rights to us." + return usr.client.holder.check_if_greater_rights_than_holder(other.holder) return 0 - /client/proc/deadmin() admin_datums -= ckey if(holder) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index f188e1f34ff..767627aa68a 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -784,6 +784,7 @@ var/mob/M = locate(href_list["boot2"]) if (ismob(M)) if(!check_if_greater_rights_than(M.client)) + usr << "Error: They have more rights than you do." return M << "You have been kicked from the server." log_admin("[key_name(usr)] booted [key_name(M)].") @@ -1324,6 +1325,30 @@ src.owner << "[special_role_description]" src.owner << "(PM) (PP) (VV) (SM) (JMP) (CA)" + else if(href_list["addjobslot"]) + if(!check_rights(R_ADMIN)) return + + var/Add = href_list["addjobslot"] + + for(var/datum/job/job in job_master.occupations) + if(job.title == Add) + job.total_positions += 1 + break + + src.manage_free_slots() + + else if(href_list["removejobslot"]) + if(!check_rights(R_ADMIN)) return + + var/Remove = href_list["removejobslot"] + + for(var/datum/job/job in job_master.occupations) + if(job.title == Remove && job.total_positions - job.current_positions > 0) + job.total_positions -= 1 + break + + src.manage_free_slots() + else if(href_list["adminspawncookie"]) if(!check_rights(R_ADMIN|R_FUN)) return diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index a5e4f9e9ac4..baa7c73549f 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -384,30 +384,6 @@ var/global/list/g_fancy_list_of_types = null g_fancy_list_of_types[typename] = type return g_fancy_list_of_types -var/global/list/g_fancy_list_of_safe_types = null -/proc/get_fancy_list_of_safe_types() - if (isnull(g_fancy_list_of_safe_types)) //init - var/blocked = list( - /turf, - /obj, - /mob, - /mob/living, - /mob/living/carbon, - /mob/living/carbon/human, - /mob/dead, - /mob/dead/observer, - /mob/living/silicon, - /mob/living/silicon/robot, - /mob/living/silicon/ai - ) - var/list/source = get_fancy_list_of_types() - g_fancy_list_of_safe_types = new - for(var/typename in source) - var/type = source[typename] - if(!(type in blocked)) - g_fancy_list_of_safe_types[typename] = type - return g_fancy_list_of_safe_types - /proc/filter_fancy_list(list/L, filter as text) var/list/matches = new for(var/key in L) @@ -421,8 +397,7 @@ var/global/list/g_fancy_list_of_safe_types = null set category = "Debug" set name = "Del-All" - // usng "safe" to prevent REALLY stupid deletions - var/list/matches = get_fancy_list_of_safe_types() + var/list/matches = get_fancy_list_of_types() if (!isnull(object) && object!="") matches = filter_fancy_list(matches, object) diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 19db9821666..4a5110e6016 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -62,6 +62,9 @@ client/proc/one_click_antag() if(config.protect_roles_from_antagonist) temp.restricted_jobs += temp.protected_jobs + if(config.protect_assistant_from_antagonist) + temp.restricted_jobs += "Assistant" + var/list/mob/living/carbon/human/candidates = list() var/mob/living/carbon/human/H = null @@ -94,6 +97,9 @@ client/proc/one_click_antag() if(config.protect_roles_from_antagonist) temp.restricted_jobs += temp.protected_jobs + if(config.protect_assistant_from_antagonist) + temp.restricted_jobs += "Assistant" + var/list/mob/living/carbon/human/candidates = list() var/mob/living/carbon/human/H = null @@ -124,6 +130,9 @@ client/proc/one_click_antag() if(config.protect_roles_from_antagonist) temp.restricted_jobs += temp.protected_jobs + if(config.protect_assistant_from_antagonist) + temp.restricted_jobs += "Assistant" + var/list/mob/living/carbon/human/candidates = list() var/mob/living/carbon/human/H = null @@ -189,6 +198,9 @@ client/proc/one_click_antag() if(config.protect_roles_from_antagonist) temp.restricted_jobs += temp.protected_jobs + if(config.protect_assistant_from_antagonist) + temp.restricted_jobs += "Assistant" + var/list/mob/living/carbon/human/candidates = list() var/mob/living/carbon/human/H = null @@ -391,6 +403,9 @@ client/proc/one_click_antag() if(config.protect_roles_from_antagonist) temp.restricted_jobs += temp.protected_jobs + if(config.protect_assistant_from_antagonist) + temp.restricted_jobs += "Assistant" + var/list/mob/living/carbon/human/candidates = list() var/mob/living/carbon/human/H = null diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 7841ef4e761..b7131a68b98 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -29,10 +29,10 @@ /proc/Centcomm_announce(var/text , var/mob/Sender) var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN) - msg = " CENTCOM:[key_name(Sender, 1)] (PP) (VV) (SM) (JMP) (CA) (BSA) (RPLY): [msg]" + msg = " CENTCOM:[key_name(Sender, 1)] (?) (PP) (VV) (SM) (JMP) (CA) (BSA) (RPLY): [msg]" admins << msg /proc/Syndicate_announce(var/text , var/mob/Sender) var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN) - msg = "SYNDICATE:[key_name(Sender, 1)] (PP) (VV) (SM) (JMP) (CA) (BSA) (RPLY): [msg]" + msg = "SYNDICATE:[key_name(Sender, 1)] (?) (PP) (VV) (SM) (JMP) (CA) (BSA) (RPLY): [msg]" admins << msg diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 1e63312b6f2..67d8d55ff8a 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -449,13 +449,13 @@ Traitors and the like can also be revived with the previous role mostly intact. /client/proc/cmd_admin_list_open_jobs() set category = "Admin" - set name = "List free slots" + set name = "Manage Job Slots" if (!holder) src << "Only administrators may use this command." return - holder.list_free_slots() - feedback_add_details("admin_verb","LFS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + holder.manage_free_slots() + feedback_add_details("admin_verb","MFS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world) set category = "Special Verbs" diff --git a/code/modules/admin/verbs/reestablish_db_connection.dm b/code/modules/admin/verbs/reestablish_db_connection.dm new file mode 100644 index 00000000000..146b8481a19 --- /dev/null +++ b/code/modules/admin/verbs/reestablish_db_connection.dm @@ -0,0 +1,31 @@ +/client/proc/reestablish_db_connection() + set category = "Special Verbs" + set name = "Reestablish DB Connection" + if (!config.sql_enabled) + usr << "The Database is not enabled!" + return + + if (dbcon && dbcon.IsConnected()) + if (!check_rights(R_DEBUG,0)) + alert("The database is already connected! (Only those with +debug can force a reconnection)", "The database is already connected!") + return + + var/reconnect = alert("The database is already connected! If you *KNOW* that this is incorrect, you can force a reconnection", "The database is already connected!", "Force Reconnect", "Cancel") + if (reconnect != "Force Reconnect") + return + + dbcon.Disconnect() + failed_db_connections = 0 + log_admin("[key_name(usr)] has forced the database to disconnect") + message_admins("[key_name_admin(usr)] has forced the database to disconnect!") + feedback_add_details("admin_verb","FRDB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + log_admin("[key_name(usr)] is attempting to re-established the DB Connection") + message_admins("[key_name_admin(usr)] is attempting to re-established the DB Connection") + feedback_add_details("admin_verb","RDB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + failed_db_connections = 0 + if (!establish_db_connection()) + message_admins("Database connection failed: " + dbcon.ErrorMsg()) + else + message_admins("Database connection re-established") \ No newline at end of file diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 7577a7a025c..c970cd62d5f 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -178,7 +178,10 @@ Code: item_state = "electronic" /obj/item/device/assembly/signaler/anomaly/receive_signal(datum/signal/signal) - ..() + if(!signal) + return 0 + if(signal.encryption != code) + return 0 for(var/obj/effect/anomaly/A in orange(0, src)) A.anomalyNeutralize() diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 9cec6893165..f64d1590071 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -133,7 +133,14 @@ var/next_external_rsc = 0 if((global.comms_key == "default_pwd" || length(global.comms_key) <= 6) && global.comms_allowed) //It's the default value or less than 6 characters long, but it somehow didn't disable comms. src << "The server's API key is either too short or is the default value! Consider changing it immediately!" - log_client_to_db() + set_client_age_from_db() + + if (!ticker || ticker.current_state == GAME_STATE_PREGAME) + spawn (rand(10,150)) + if (src) + sync_client_with_db() + else + sync_client_with_db() send_resources() @@ -153,64 +160,58 @@ var/next_external_rsc = 0 return ..() - -/client/proc/log_client_to_db() - - if ( IsGuestKey(src.key) ) +/client/proc/set_client_age_from_db() + if (IsGuestKey(src.key)) return establish_db_connection() if(!dbcon.IsConnected()) return - var/sql_ckey = sql_sanitize_text(src.ckey) + var/sql_ckey = sanitizeSQL(src.ckey) var/DBQuery/query = dbcon.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'") query.Execute() - var/sql_id = 0 - while(query.NextRow()) - sql_id = query.item[1] + + while (query.NextRow()) player_age = text2num(query.item[2]) break - var/DBQuery/query_ip = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ip = '[address]'") + +/client/proc/sync_client_with_db() + if (IsGuestKey(src.key)) + return + + establish_db_connection() + if (!dbcon.IsConnected()) + return + + var/sql_ckey = sanitizeSQL(src.ckey) + + var/DBQuery/query_ip = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ip = '[address]' AND ckey != '[sql_ckey]'") query_ip.Execute() related_accounts_ip = "" while(query_ip.NextRow()) related_accounts_ip += "[query_ip.item[1]], " - break - var/DBQuery/query_cid = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE computerid = '[computer_id]'") + var/DBQuery/query_cid = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE computerid = '[computer_id]' AND ckey != '[sql_ckey]'") query_cid.Execute() related_accounts_cid = "" - while(query_cid.NextRow()) + while (query_cid.NextRow()) related_accounts_cid += "[query_cid.item[1]], " - break - //Just the standard check to see if it's actually a number - if(sql_id) - if(istext(sql_id)) - sql_id = text2num(sql_id) - if(!isnum(sql_id)) - return var/admin_rank = "Player" - if(src.holder && src.holder.rank) + if (src.holder && src.holder.rank) admin_rank = src.holder.rank.name - var/sql_ip = sql_sanitize_text(src.address) - var/sql_computerid = sql_sanitize_text(src.computer_id) - var/sql_admin_rank = sql_sanitize_text(admin_rank) + var/sql_ip = sanitizeSQL(src.address) + var/sql_computerid = sanitizeSQL(src.computer_id) + var/sql_admin_rank = sanitizeSQL(admin_rank) - if(sql_id) - //Player already identified previously, we need to just update the 'lastseen', 'ip' and 'computer_id' variables - var/DBQuery/query_update = dbcon.NewQuery("UPDATE [format_table_name("player")] SET lastseen = Now(), ip = '[sql_ip]', computerid = '[sql_computerid]', lastadminrank = '[sql_admin_rank]' WHERE id = [sql_id]") - query_update.Execute() - else - //New player!! Need to insert all the stuff - var/DBQuery/query_insert = dbcon.NewQuery("INSERT INTO [format_table_name("player")] (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, '[sql_ckey]', Now(), Now(), '[sql_ip]', '[sql_computerid]', '[sql_admin_rank]')") - query_insert.Execute() + var/DBQuery/query_insert = dbcon.NewQuery("INSERT INTO [format_table_name("player")] (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, '[sql_ckey]', Now(), Now(), '[sql_ip]', '[sql_computerid]', '[sql_admin_rank]') ON DUPLICATE KEY UPDATE lastseen = VALUES(lastseen), ip = VALUES(ip), computerid = VALUES(computerid)") + query_insert.Execute() //Logging player access var/serverip = "[world.internet_address]:[world.port]" @@ -258,6 +259,9 @@ var/next_external_rsc = 0 'icons/pda_icons/pda_blank.png', 'icons/pda_icons/pda_boom.png', 'icons/pda_icons/pda_bucket.png', + 'icons/pda_icons/pda_medbot.png', + 'icons/pda_icons/pda_floorbot.png', + 'icons/pda_icons/pda_cleanbot.png', 'icons/pda_icons/pda_crate.png', 'icons/pda_icons/pda_cuffs.png', 'icons/pda_icons/pda_eject.png', diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 5911f0178d8..054c7d2acab 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -147,10 +147,4 @@ name = "Optical Thermal Eyepatch" desc = "An eyepatch with built-in thermal optics" icon_state = "eyepatch" - item_state = "eyepatch" - -/obj/item/clothing/glasses/thermal/jensen - name = "Optical Thermal Implants" - desc = "A set of implantable lenses designed to augment your vision" - icon_state = "thermalimplants" - item_state = "syringe_kit" \ No newline at end of file + item_state = "eyepatch" \ No newline at end of file diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 505c336b6aa..25e6b20f94a 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -68,13 +68,5 @@ emagged = 1 desc = desc + " The display flickers slightly." -/obj/item/clothing/glasses/hud/security/jensenshades - name = "Augmented shades" - desc = "Polarized bioneural eyewear, designed to augment your vision." - icon_state = "jensenshades" - item_state = "jensenshades" - vision_flags = SEE_MOBS - invis_view = 2 - /obj/item/clothing/glasses/hud/security/process_hud(var/mob/M) process_data_hud(M,DATA_HUD_SECURITY,DATA_HUD_ADVANCED) diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 360e6e52e63..88db2bd9160 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -21,6 +21,26 @@ armor = list(melee = 82, bullet = 15, laser = 5,energy = 5, bomb = 5, bio = 2, rad = 0) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE strip_delay = 80 + action_button_name = "Toggle Helmet Visor" + visor_flags = HEADCOVERSEYES | HEADCOVERSMOUTH + visor_flags_inv = HIDEMASK|HIDEEYES|HIDEFACE + +/obj/item/clothing/head/helmet/riot/attack_self() + if(usr.canmove && !usr.stat && !usr.restrained()) + if(up) + up = !up + flags |= (visor_flags) + flags_inv |= (visor_flags_inv) + icon_state = initial(icon_state) + usr << "You pull the [src] down." + usr.update_inv_head(0) + else + up = !up + flags &= ~(visor_flags) + flags_inv &= ~(visor_flags_inv) + icon_state = "[initial(icon_state)]up" + usr << "You push the [src] up." + usr.update_inv_head(0) /obj/item/clothing/head/helmet/swat name = "\improper SWAT helmet" diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 64a9336b2ca..bfa388ae031 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -63,23 +63,21 @@ //Security /obj/item/clothing/head/HoS - name = "head of security hat" - desc = "The robust hat of the Head of Security. For showing the officers who's in charge." + name = "head of security cap" + desc = "The robust standard-issue cap of the Head of Security. For showing the officers who's in charge." icon_state = "hoscap" armor = list(melee = 80, bullet = 60, laser = 50, energy = 10, bomb = 25, bio = 10, rad = 0) flags = 0 flags_inv = HIDEEARS strip_delay = 80 -/obj/item/clothing/head/HoS/dermal - name = "Dermal Armor Patch" - desc = "An armored implant that automatically integrates just below the scalp for robust protection without sacrificing style." - icon_state = "dermal" - item_state = "dermal" - flags_inv = 0 +/obj/item/clothing/head/HoS/drill + name = "head of security drill hat" + desc = "A robust drill hat for the Head of Security. For keeping the officers in line." + icon_state = "hosdrill" /obj/item/clothing/head/warden - name = "warden's hat" + name = "warden's police hat" desc = "It's a special armored hat issued to the Warden of a security force. Protects the head from impacts." icon_state = "policehelm" armor = list(melee = 60, bullet = 5, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 84f1d7ca791..132d31c2cc0 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -56,14 +56,6 @@ flags = BLOCKHAIR flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE -/obj/item/clothing/head/cueball - name = "cueball helmet" - desc = "A large, featureless white orb mean to be worn on your head. How do you even see out of this thing?" - icon_state = "cueball" - flags = HEADCOVERSEYES|BLOCKHAIR - item_state="cueball" - flags_inv = 0 - /obj/item/clothing/head/that name = "sturdy top-hat" desc = "It's an amish looking armored top hat." diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 8c16e3d746d..496fd90507f 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -1,3 +1,5 @@ +/obj/item/clothing/shoes/proc/step_action() //this was made to rewrite clown shoes squeaking + /obj/item/clothing/shoes/syndigaloshes desc = "A pair of brown shoes. They seem to have extra grip." name = "brown shoes" @@ -75,6 +77,13 @@ item_color = "clown" var/footstep = 1 //used for squeeks whilst walking +/obj/item/clothing/shoes/clown_shoes/step_action() + if(footstep > 1) + playsound(src, "clownstep", 50, 1) + footstep = 0 + else + footstep++ + /obj/item/clothing/shoes/jackboots name = "jackboots" desc = "Nanotrasen-issue Security combat boots for combat scenarios or combat situations. All combat, all the time." diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 3e33b19cd4a..4fac7f71965 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -17,8 +17,8 @@ armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0) /obj/item/clothing/suit/armor/hos - name = "armored coat" - desc = "A greatcoat enchanced with a special alloy for some protection and style." + name = "armored greatcoat" + desc = "A greatcoat enchanced with a special alloy for some protection and style for those with a commanding presence." icon_state = "hos" item_state = "hos" body_parts_covered = CHEST|GROIN|ARMS|LEGS @@ -29,6 +29,15 @@ strip_delay = 80 put_on_delay = 40 +/obj/item/clothing/suit/armor/hos/trenchcoat + name = "armored trenchoat" + desc = "A trenchcoat enchanced with a special lightweight kevlar. The epitome of tactical plainclothes." + icon_state = "jensencoat" + item_state = "jensencoat" + flags_inv = 0 + strip_delay = 80 + put_on_delay = 40 + /obj/item/clothing/suit/armor/vest/warden name = "warden's jacket" desc = "An armored jacket with silver rank pips and livery." diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index fbacb60a169..3fe024e44e8 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -20,7 +20,7 @@ item_state = "bio_suit" body_parts_covered = CHEST|GROIN|LEGS|ARMS flags_inv = HIDEJUMPSUIT - allowed = list(/obj/item/weapon/disk, /obj/item/weapon/stamp, /obj/item/weapon/reagent_containers/food/drinks/flask, /obj/item/weapon/melee, /obj/item/weapon/storage/lockbox/medal, /obj/item/device/flash, /obj/item/weapon/storage/box/matches, /obj/item/weapon/lighter, /obj/item/clothing/mask/cigarette, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/tank/emergency_oxygen) + allowed = list(/obj/item/weapon/disk, /obj/item/weapon/stamp, /obj/item/weapon/reagent_containers/food/drinks/flask, /obj/item/weapon/melee, /obj/item/weapon/storage/lockbox/medal, /obj/item/device/flash/handheld, /obj/item/weapon/storage/box/matches, /obj/item/weapon/lighter, /obj/item/clothing/mask/cigarette, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/tank/emergency_oxygen) //Chaplain /obj/item/clothing/suit/chaplain_hoodie diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index a5fbc8e3d6d..e3b75febb8b 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -1,97 +1,55 @@ /obj/item/clothing/suit/labcoat name = "labcoat" desc = "A suit that protects against minor chemical spills." - icon_state = "labcoat_open" + icon_state = "labcoat" item_state = "labcoat" blood_overlay_type = "coat" body_parts_covered = CHEST|ARMS allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper,/obj/item/weapon/melee/telebaton) armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0) + var/open = 0 - verb/toggle() - set name = "Toggle Labcoat Buttons" - set category = "Object" - set src in usr +/obj/item/clothing/suit/labcoat/verb/toggle() + set name = "Toggle Labcoat Buttons" + set category = "Object" + set src in usr - if(!usr.canmove || usr.stat || usr.restrained()) - return 0 + if(!usr.canmove || usr.stat || usr.restrained()) + return 0 - switch(icon_state) //n-nooooo - if("labcoat_open") - src.icon_state = "labcoat" - usr << "You button up the labcoat." - if("labcoat") - src.icon_state = "labcoat_open" - usr << "You unbutton the labcoat." - if("labcoat_cmo_open") - src.icon_state = "labcoat_cmo" - usr << "You button up the labcoat." - if("labcoat_cmo") - src.icon_state = "labcoat_cmo_open" - usr << "You unbutton the labcoat." - if("labcoat_gen_open") - src.icon_state = "labcoat_gen" - usr << "You button up the labcoat." - if("labcoat_gen") - src.icon_state = "labcoat_gen_open" - usr << "You unbutton the labcoat." - if("labcoat_chem_open") - src.icon_state = "labcoat_chem" - usr << "You button up the labcoat." - if("labcoat_chem") - src.icon_state = "labcoat_chem_open" - usr << "You unbutton the labcoat." - if("labcoat_vir_open") - src.icon_state = "labcoat_vir" - usr << "You button up the labcoat." - if("labcoat_vir") - src.icon_state = "labcoat_vir_open" - usr << "You unbutton the labcoat." - if("labcoat_tox_open") - src.icon_state = "labcoat_tox" - usr << "You button up the labcoat." - if("labcoat_tox") - src.icon_state = "labcoat_tox_open" - usr << "You unbutton the labcoat." - if("labgreen_open") - src.icon_state = "labgreen" - usr << "You button up the labcoat." - if("labgreen") - src.icon_state = "labgreen_open" - usr << "You unbutton the labcoat." - else - usr << "You attempt to button-up the velcro on your [src], before promptly realising how retarded you are." - return - usr.update_inv_wear_suit() //so our overlays update + open = !open + icon_state = "[initial(icon_state)][open ? "_open":""]" + usr << "You [open ? "unbutton":"button up"] the labcoat" + usr.update_inv_wear_suit() /obj/item/clothing/suit/labcoat/cmo name = "chief medical officer's labcoat" desc = "Bluer than the standard model." - icon_state = "labcoat_cmo_open" + icon_state = "labcoat_cmo" item_state = "labcoat_cmo" /obj/item/clothing/suit/labcoat/mad name = "\improper The Mad's labcoat" desc = "It makes you look capable of konking someone on the noggin and shooting them into space." - icon_state = "labgreen_open" + icon_state = "labgreen" item_state = "labgreen" /obj/item/clothing/suit/labcoat/genetics name = "geneticist labcoat" desc = "A suit that protects against minor chemical spills. Has a blue stripe on the shoulder." - icon_state = "labcoat_gen_open" + icon_state = "labcoat_gen" /obj/item/clothing/suit/labcoat/chemist name = "chemist labcoat" desc = "A suit that protects against minor chemical spills. Has an orange stripe on the shoulder." - icon_state = "labcoat_chem_open" + icon_state = "labcoat_chem" /obj/item/clothing/suit/labcoat/virologist name = "virologist labcoat" desc = "A suit that protects against minor chemical spills. Offers slightly more protection against biohazards than the standard model. Has a green stripe on the shoulder." - icon_state = "labcoat_vir_open" + icon_state = "labcoat_vir" /obj/item/clothing/suit/labcoat/science name = "scientist labcoat" desc = "A suit that protects against minor chemical spills. Has a purple stripe on the shoulder." - icon_state = "labcoat_tox_open" + icon_state = "labcoat_tox" diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 76f209e90ce..c2373675872 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -210,6 +210,18 @@ icon_state = "nerdshirt" item_state = "nerdshirt" +/obj/item/clothing/suit/jacket + name = "bomber jacket" + desc = "Aviators not included." + icon_state = "bomberjacket" + item_state = "johnny" + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter) + +/obj/item/clothing/suit/jacket/leather + name = "leather jacket" + desc = "Pompadour not included." + icon_state = "leatherjacket" + //Blue suit jacket toggle /obj/item/clothing/suit/suit/verb/toggle() set name = "Toggle Jacket Buttons" diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm index 0dea814a1cc..de249c00557 100644 --- a/code/modules/clothing/suits/wiz_robe.dm +++ b/code/modules/clothing/suits/wiz_robe.dm @@ -13,6 +13,11 @@ desc = "Strange-looking, red, hat-wear that most certainly belongs to a real magic user." icon_state = "redwizard" +/obj/item/clothing/head/wizard/yellow + name = "yellow wizard hat" + desc = "Strange-looking, yellow, hat-wear that most certainly belongs to a powerful magic user." + icon_state = "yellowwizard" + /obj/item/clothing/head/wizard/fake name = "wizard hat" desc = "It has WIZZARD written across it in sequins. Comes with a cool beard." @@ -54,6 +59,11 @@ icon_state = "redwizard" item_state = "redwizrobe" +/obj/item/clothing/suit/wizrobe/yellow + name = "yellow wizard robe" + desc = "A magnificant, yellow, gem-lined robe that seems to radiate power." + icon_state = "yellowwizard" + item_state = "yellowwizrobe" /obj/item/clothing/suit/wizrobe/marisa name = "witch robe" diff --git a/code/modules/clothing/under/color.dm b/code/modules/clothing/under/color.dm index 1b1da0d3f34..2e331e46790 100644 --- a/code/modules/clothing/under/color.dm +++ b/code/modules/clothing/under/color.dm @@ -1,12 +1,15 @@ /obj/item/clothing/under/color - desc = "A standard issue colored jumpsuit for assistants. Variety is the spice of life!" + desc = "A standard issue colored jumpsuit. Variety is the spice of life!" /obj/item/clothing/under/color/random/New() - var/obj/item/clothing/under/color/C = pick(typesof(/obj/item/clothing/under/color) - /obj/item/clothing/under/color/random) + ..() + var/list/excluded = list(/obj/item/clothing/under/color/random, /obj/item/clothing/under/color) + var/obj/item/clothing/under/color/C = pick(typesof(/obj/item/clothing/under/color) - excluded) name = initial(C.name) icon_state = initial(C.icon_state) item_state = initial(C.item_state) item_color = initial(C.item_color) + suit_color = initial(C.item_color) /obj/item/clothing/under/color/black name = "black jumpsuit" @@ -14,6 +17,12 @@ item_state = "bl_suit" item_color = "black" +/obj/item/clothing/under/color/grey + name = "grey jumpsuit" + icon_state = "grey" + item_state = "gy_suit" + item_color = "grey" + /obj/item/clothing/under/color/blue name = "blue jumpsuit" icon_state = "blue" @@ -26,12 +35,6 @@ item_state = "g_suit" item_color = "green" -/obj/item/clothing/under/color/grey - name = "grey jumpsuit" - icon_state = "grey" - item_state = "gy_suit" - item_color = "grey" - /obj/item/clothing/under/color/orange name = "orange jumpsuit" desc = "Don't wear this near paranoid security officers." diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index f7ada882d0a..658c78b3698 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -2,7 +2,6 @@ * Contains: * Security * Detective - * Head of Security + Jensen cosplay gear * Navy uniforms */ @@ -59,26 +58,6 @@ armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) strip_delay = 60 -/* - * Jensen cosplay gear - */ -/obj/item/clothing/under/rank/head_of_security/jensen - desc = "You never asked for anything that stylish." - name = "head of security's jumpsuit" - icon_state = "jensen" - item_state = "jensen" - item_color = "jensen" - can_adjust = 0 - -/obj/item/clothing/suit/armor/hos/jensen - name = "armored trenchoat" - desc = "A trenchoat augmented with a special alloy for some protection and style" - icon_state = "jensencoat" - item_state = "jensencoat" - flags_inv = 0 - strip_delay = 80 - put_on_delay = 40 - /* * Navy uniforms diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 5e76a853eac..c46f5def722 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -14,14 +14,6 @@ item_state = "w_suit" can_adjust = 0 -/obj/item/clothing/under/scratch - name = "white suit" - desc = "A white suit, suitable for an excellent host" - icon_state = "scratch" - item_state = "scratch" - item_color = "scratch" - can_adjust = 0 - /obj/item/clothing/under/sl_suit desc = "It's a very amish looking suit." name = "amish suit" diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index 8ba79e8d250..0ad173c2391 100644 --- a/code/modules/clothing/under/syndicate.dm +++ b/code/modules/clothing/under/syndicate.dm @@ -15,5 +15,4 @@ desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-." icon_state = "tactifool" item_state = "bl_suit" - item_color = "tactifool" - can_adjust = 0 \ No newline at end of file + item_color = "tactifool" \ No newline at end of file diff --git a/code/modules/crafting/guncrafting.dm b/code/modules/crafting/guncrafting.dm new file mode 100644 index 00000000000..ba354b64915 --- /dev/null +++ b/code/modules/crafting/guncrafting.dm @@ -0,0 +1,83 @@ +// This file is for projectile weapon crafting. All parts and construction paths will be contained here. +// The weapons themselves are children of other weapons and should be contained in their respective files. + +// PARTS // + +/obj/item/weaponcrafting/reciever + name = "modular reciever" + desc = "A prototype modular reciever and trigger assembly for a firearm." + icon = 'icons/obj/improvised.dmi' + icon_state = "reciever" + +/obj/item/weaponcrafting/stock + name = "rifle stock" + desc = "A classic rifle stock that doubles as a grip, roughly carved out of wood." + icon = 'icons/obj/improvised.dmi' + icon_state = "riflestock" + + +// CRAFTING // + +/obj/item/weaponcrafting/reciever/attackby(obj/item/W as obj, mob/user as mob) + if(istype(W,/obj/item/pipe)) + user << "You attach the shotgun barrel to the reciever. The pins seem loose." + var/obj/item/weaponcrafting/ishotgunconstruction/I = new /obj/item/weaponcrafting/ishotgunconstruction + user.unEquip(src) + user.put_in_hands(I) + del(W) + del(src) + return + +// SHOTGUN // + +/obj/item/weaponcrafting/ishotgunconstruction + name = "slightly conspicuous metal construction" + desc = "A long pipe attached to a firearm reciever. The pins seem loose." + icon = 'icons/obj/improvised.dmi' + icon_state = "ishotgunstep1" + +/obj/item/weaponcrafting/ishotgunconstruction/attackby(var/obj/item/I, mob/user as mob) + ..() + if(istype(I, /obj/item/weapon/screwdriver)) + var/obj/item/weaponcrafting/ishotgunconstruction2/C = new /obj/item/weaponcrafting/ishotgunconstruction2 + user.unEquip(src) + user.put_in_hands(C) + user << "You screw the pins into place, securing the pipe to the reciever." + qdel(src) + +/obj/item/weaponcrafting/ishotgunconstruction2 + name = "very conspicuous metal construction" + desc = "A long pipe attached to a trigger assembly." + icon = 'icons/obj/improvised.dmi' + icon_state = "ishotgunstep1" + +/obj/item/weaponcrafting/ishotgunconstruction2/attackby(obj/item/W as obj, mob/user as mob) + if(istype(W,/obj/item/weaponcrafting/stock)) + user << "You attach the stock to the reciever-barrel assembly." + var/obj/item/weaponcrafting/ishotgunconstruction3/I = new /obj/item/weaponcrafting/ishotgunconstruction3 + user.unEquip(src) + user.put_in_hands(I) + del(W) + del(src) + return + +/obj/item/weaponcrafting/ishotgunconstruction3 + name = "extremely conspicuous metal construction" + desc = "A reciever-barrel shotgun assembly with a loose wooden stock. There's no way you can fire it without the stock coming loose." + icon = 'icons/obj/improvised.dmi' + icon_state = "ishotgunstep2" + +/obj/item/weaponcrafting/ishotgunconstruction3/attackby(var/obj/item/I, mob/user as mob) + ..() + if(istype(I, /obj/item/stack/packageWrap)) + var/obj/item/stack/packageWrap/C = I + if (C.use(5)) + var/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/W = new /obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised + user.unEquip(src) + user.put_in_hands(W) + user << "You tie the wrapping paper around the stock and the barrel to secure it." + qdel(src) + else + user << "You need at least five feet of wrapping paper to secure the stock." + return + diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index 77ecd48a2ae..6a53af52426 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -115,4 +115,14 @@ reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, /datum/reagent/phosphorus = 5,) tools = list(/obj/item/weapon/screwdriver) - time = 5 \ No newline at end of file + time = 5 + +/datum/table_recipe/ishotgun + name = "Improvised Shotgun" + result = /obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised + reqs = list(/obj/item/weaponcrafting/reciever = 1, + /obj/item/pipe = 1, + /obj/item/weaponcrafting/stock = 1, + /obj/item/stack/packageWrap = 5,) + tools = list(/obj/item/weapon/screwdriver) + time = 200 \ No newline at end of file diff --git a/code/modules/events/anomaly.dm b/code/modules/events/anomaly.dm index 9062ed7e4a3..6ffb171e387 100644 --- a/code/modules/events/anomaly.dm +++ b/code/modules/events/anomaly.dm @@ -1,5 +1,5 @@ /datum/round_event_control/anomaly - name = "Energetic Flux" + name = "Anomaly: Energetic Flux" typepath = /datum/round_event/anomaly max_occurrences = 0 //This one probably shouldn't occur! It'd work, but it wouldn't be very fun. weight = 15 @@ -23,7 +23,7 @@ setup(safety_loop) /datum/round_event/anomaly/announce() - priority_announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert") + priority_announce("Localized energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert") /datum/round_event/anomaly/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/anomaly_bluespace.dm b/code/modules/events/anomaly_bluespace.dm index 256a4322c81..5171ca6a4b6 100644 --- a/code/modules/events/anomaly_bluespace.dm +++ b/code/modules/events/anomaly_bluespace.dm @@ -1,5 +1,5 @@ /datum/round_event_control/anomaly/anomaly_bluespace - name = "Bluespace Anomaly" + name = "Anomaly: Bluespace" typepath = /datum/round_event/anomaly/anomaly_bluespace max_occurrences = 1 weight = 5 @@ -7,7 +7,7 @@ /datum/round_event/anomaly/anomaly_bluespace startWhen = 3 announceWhen = 10 - endWhen = 55 + endWhen = 95 /datum/round_event/anomaly/anomaly_bluespace/announce() @@ -21,7 +21,7 @@ /datum/round_event/anomaly/anomaly_bluespace/end() - if(newAnomaly)//If it hasn't been neutralized, it's time to warp half the station away jeez + if(newAnomaly.loc)//If it hasn't been neutralized, it's time to warp half the station away jeez var/turf/T = pick(get_area_turfs(impact_area)) if(T) // Calculate new position (searches through beacons in world) @@ -52,9 +52,7 @@ var/x_distance = TO.x - FROM.x for (var/atom/movable/A in range(12, FROM )) // iterate thru list of mobs in the area if(istype(A, /obj/item/device/radio/beacon)) continue // don't teleport beacons because that's just insanely stupid - if(A.anchored && istype(A, /obj/machinery)) continue - if(istype(A, /obj/structure/disposalpipe )) continue - if(istype(A, /obj/structure/cable )) continue + if(A.anchored) continue var/turf/newloc = locate(A.x + x_distance, A.y + y_distance, TO.z) // calculate the new place if(!A.Move(newloc)) // if the atom, for some reason, can't move, FORCE them to move! :) We try Move() first to invoke any movement-related checks the atom needs to perform after moving diff --git a/code/modules/events/anomaly_flux.dm b/code/modules/events/anomaly_flux.dm index dc7e9d4b219..fd4a10270b4 100644 --- a/code/modules/events/anomaly_flux.dm +++ b/code/modules/events/anomaly_flux.dm @@ -1,13 +1,13 @@ /datum/round_event_control/anomaly/anomaly_flux - name = "Energetic Flux" + name = "Anomaly: Hyper-Energetic Flux" typepath = /datum/round_event/anomaly/anomaly_flux - max_occurrences = 2 - weight = 15 + max_occurrences = 5 + weight = 20 /datum/round_event/anomaly/anomaly_flux startWhen = 3 announceWhen = 20 - endWhen = 60 + endWhen = 80 /datum/round_event/anomaly/anomaly_flux/announce() @@ -21,6 +21,6 @@ /datum/round_event/anomaly/anomaly_flux/end() - if(newAnomaly)//If it hasn't been neutralized, it's time to blow up. + if(newAnomaly.loc)//If it hasn't been neutralized, it's time to blow up. explosion(newAnomaly, -1, 3, 5, 5) qdel(newAnomaly) \ No newline at end of file diff --git a/code/modules/events/anomaly_grav.dm b/code/modules/events/anomaly_grav.dm index 69d38c62231..4b44e18ba2a 100644 --- a/code/modules/events/anomaly_grav.dm +++ b/code/modules/events/anomaly_grav.dm @@ -1,13 +1,13 @@ /datum/round_event_control/anomaly/anomaly_grav - name = "Gravitational Anomaly" + name = "Anomaly: Gravitational" typepath = /datum/round_event/anomaly/anomaly_grav - max_occurrences = 2 - weight = 15 + max_occurrences = 5 + weight = 20 /datum/round_event/anomaly/anomaly_grav startWhen = 3 announceWhen = 20 - endWhen = 50 + endWhen = 120 /datum/round_event/anomaly/anomaly_grav/announce() diff --git a/code/modules/events/anomaly_pyro.dm b/code/modules/events/anomaly_pyro.dm index 49600a58136..237e59a1d48 100644 --- a/code/modules/events/anomaly_pyro.dm +++ b/code/modules/events/anomaly_pyro.dm @@ -1,17 +1,17 @@ /datum/round_event_control/anomaly/anomaly_pyro - name = "Pyroclastic Anomaly" + name = "Anomaly: Pyroclastic" typepath = /datum/round_event/anomaly/anomaly_pyro - max_occurrences = 2 - weight = 15 + max_occurrences = 5 + weight = 20 /datum/round_event/anomaly/anomaly_pyro startWhen = 10 announceWhen = 3 - endWhen = 70 + endWhen = 85 /datum/round_event/anomaly/anomaly_pyro/announce() - priority_announce("Atmospheric anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + priority_announce("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") /datum/round_event/anomaly/anomaly_pyro/start() var/turf/T = pick(get_area_turfs(impact_area)) @@ -23,4 +23,14 @@ kill() return if(IsMultiple(activeFor, 5)) - newAnomaly.anomalyEffect() \ No newline at end of file + newAnomaly.anomalyEffect() + + +/datum/round_event/anomaly/anomaly_pyro/end() + if(newAnomaly.loc) + explosion(get_turf(newAnomaly), -1,0,3, flame_range = 4) + + var/mob/living/carbon/slime/S = new/mob/living/carbon/slime(get_turf(newAnomaly)) + S.colour = pick("red", "orange") + + qdel(newAnomaly) \ No newline at end of file diff --git a/code/modules/events/anomaly_vortex.dm b/code/modules/events/anomaly_vortex.dm index 993bec48862..aed3d4a1320 100644 --- a/code/modules/events/anomaly_vortex.dm +++ b/code/modules/events/anomaly_vortex.dm @@ -1,13 +1,13 @@ /datum/round_event_control/anomaly/anomaly_vortex - name = "Vortex Anomaly" + name = "Anomaly: Vortex" typepath = /datum/round_event/anomaly/anomaly_vortex - max_occurrences = 5 - weight = 2 + max_occurrences = 2 + weight = 5 /datum/round_event/anomaly/anomaly_vortex startWhen = 10 announceWhen = 3 - endWhen = 80 + endWhen = 95 /datum/round_event/anomaly/anomaly_vortex/announce() diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index 72cea9209af..0b65480c830 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -22,4 +22,6 @@ if(prob(95)) new /mob/living/simple_animal/hostile/carp(C.loc) else - new /mob/living/simple_animal/hostile/carp/megacarp(C.loc) \ No newline at end of file + new /mob/living/simple_animal/hostile/carp/megacarp(C.loc) + + diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm index ad6a82e04df..bcd9a0ef3bb 100644 --- a/code/modules/events/holiday/halloween.dm +++ b/code/modules/events/holiday/halloween.dm @@ -7,11 +7,35 @@ earliest_start = 0 /datum/round_event/spooky/start() + ..() for(var/mob/living/carbon/human/H in mob_list) if(H.dna) - hardset_dna(H, null, null, null, null, /datum/species/skeleton) + if(prob(50)) + hardset_dna(H, null, null, null, null, /datum/species/skeleton) + else + hardset_dna(H, null, null, null, null, /datum/species/zombie) + for(var/mob/living/simple_animal/corgi/Ian/Ian in mob_list) Ian.place_on_head(new /obj/item/weapon/bedsheet(Ian)) + spawn_meteors(5, meteorsSPOOKY) + + var/datum/round_event_control/carp_migration/eyeballs/SpookyMigration = locate() in events.control + SpookyMigration.runEvent() + /datum/round_event/spooky/announce() priority_announce(pick("RATTLE ME BONES!","THE RIDE NEVER ENDS!", "A SKELETON POPS OUT!", "SPOOKY SCARY SKELETONS!", "CREWMEMBERS BEWARE, YOU'RE IN FOR A SCARE!") , "THE CALL IS COMING FROM INSIDE THE HOUSE") + +//Eyeball migration +/datum/round_event_control/carp_migration/eyeballs + name = "Eyeball Migration" + typepath = /datum/round_event/carp_migration/eyeballs + holidayID = "Halloween" + weight = 0 + earliest_start = 0 + +/datum/round_event/carp_migration/eyeballs/start() + for(var/obj/effect/landmark/C in landmarks_list) + if(C.name == "carpspawn") + new /mob/living/simple_animal/hostile/carp/eyeball(C.loc) + diff --git a/code/modules/events/ninja.dm b/code/modules/events/ninja.dm index 540741dcc32..4efc4c100ce 100644 --- a/code/modules/events/ninja.dm +++ b/code/modules/events/ninja.dm @@ -623,7 +623,7 @@ spideros = text2num(return_to)//Maximum length here is 6. Use (return_to, X) to var/mob/living/carbon/human/U = loc if(candrain&&!draining) var/turf/T = U.loc - if(isturf(T) && T.is_plating()) + if(isturf(T) && istype(T, /turf/simulated/floor/plating) attached = locate() in T if(!attached) U << "\red Warning: no exposed cable available." @@ -2207,9 +2207,8 @@ ________________________________________________________________________________ anim(U.loc,U,'icons/mob/mob.dmi',,"cloak",,U.dir) s_active=!s_active U.alpha = 0 - U << "You are now invisible to normal detection." - for(var/mob/O in oviewers(U)) - O.show_message("[U.name] vanishes into thin air!",1) + U.visible_message("[U.name] vanishes into thin air!", \ + "You are now invisible to normal detection.") return /obj/item/clothing/suit/space/space_ninja/proc/cancel_stealth() @@ -2219,9 +2218,8 @@ ________________________________________________________________________________ anim(U.loc,U,'icons/mob/mob.dmi',,"uncloak",,U.dir) s_active=!s_active U.alpha = 255 - U << "You are now visible." - for(var/mob/O in oviewers(U)) - O.show_message("[U.name] appears from thin air!",1) + U.visible_message("[U.name] appears from thin air!", \ + "You are now visible.") return 1 return 0 @@ -2610,147 +2608,143 @@ It is possible to destroy the net by the occupant or someone else. var/mob/living/affecting = null//Who it is currently affecting, if anyone. var/mob/living/master = null//Who shot web. Will let this person know if the net was successful or failed. - proc - healthcheck() - if(health <=0) - density = 0 - if(affecting) - var/mob/living/carbon/M = affecting - M.anchored = 0 - for(var/mob/O in viewers(src, 3)) - O.show_message(text("[] was recovered from the energy net!", M.name), 1, text("You hear a grunt."), 2) - if(!isnull(master))//As long as they still exist. - master << "ERROR: \black unable to initiate transport protocol. Procedure terminated." - qdel(src) - return - - process(var/mob/living/carbon/M as mob) - var/check = 30//30 seconds before teleportation. Could be extended I guess. - var/mob_name = affecting.name//Since they will report as null if terminated before teleport. - //The person can still try and attack the net when inside. - while(!isnull(M)&&!isnull(src)&&check>0)//While M and net exist, and 30 seconds have not passed. - check-- - sleep(10) - - if(isnull(M)||M.loc!=loc)//If mob is gone or not at the location. - if(!isnull(master))//As long as they still exist. - master << "ERROR: \black unable to locate \the [mob_name]. Procedure terminated." - qdel(src)//Get rid of the net. - return - - if(!isnull(src))//As long as both net and person exist. - //No need to check for countdown here since while() broke, it's implicit that it finished. - - density = 0//Make the net pass-through. - invisibility = 101//Make the net invisible so all the animations can play out. - health = INFINITY//Make the net invincible so that an explosion/something else won't kill it while, spawn() is running. - for(var/obj/item/W in M) - if(istype(M,/mob/living/carbon/human)) - if(W==M:w_uniform) continue//So all they're left with are shoes and uniform. - if(W==M:shoes) continue - M.unEquip(W) - - spawn(0) - playsound(M.loc, 'sound/effects/sparks4.ogg', 50, 1) - anim(M.loc,M,'icons/mob/mob.dmi',,"phaseout",,M.dir) - - M.loc = pick(holdingfacility)//Throw mob in to the holding facility. - M << "You appear in a strange place!" - - spawn(0) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, M.loc) - spark_system.start() - playsound(M.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(M.loc, 'sound/effects/sparks2.ogg', 50, 1) - anim(M.loc,M,'icons/mob/mob.dmi',,"phasein",,M.dir) - qdel(src)//Wait for everything to finish, delete the net. Else it will stop everything once net is deleted, including the spawn(0). - +/obj/effect/energy_net/proc/healthcheck() + if(health <=0) + density = 0 + if(affecting) + var/mob/living/carbon/M = affecting + M.anchored = 0 for(var/mob/O in viewers(src, 3)) - O.show_message(text("[] vanished!", M), 1, text("You hear sparks flying!"), 2) - + O.show_message("[M.name] was recovered from the energy net!", 1, "You hear a grunt.", 2) if(!isnull(master))//As long as they still exist. - master << "SUCCESS: \black transport procedure of \the [affecting] complete." + master << "ERROR: \black unable to initiate transport protocol. Procedure terminated." + qdel(src) + return - M.anchored = 0//Important. +/obj/effect/energy_net/process(var/mob/living/carbon/M as mob) + var/check = 30//30 seconds before teleportation. Could be extended I guess. + var/mob_name = affecting.name//Since they will report as null if terminated before teleport. + //The person can still try and attack the net when inside. + while(!isnull(M)&&!isnull(src)&&check>0)//While M and net exist, and 30 seconds have not passed. + check-- + sleep(10) - else//And they are free. - M << "You are free of the net!" + if(isnull(M)||M.loc!=loc)//If mob is gone or not at the location. + if(!isnull(master))//As long as they still exist. + master << "ERROR: \black unable to locate \the [mob_name]. Procedure terminated." + qdel(src)//Get rid of the net. return - bullet_act(var/obj/item/projectile/Proj) - health -= Proj.damage - healthcheck() - ..() + if(!isnull(src))//As long as both net and person exist. + //No need to check for countdown here since while() broke, it's implicit that it finished. - ex_act(severity) - switch(severity) - if(1.0) - health-=50 - if(2.0) - health-=50 - if(3.0) - health-=prob(50)?50:25 - healthcheck() - return + density = 0//Make the net pass-through. + invisibility = 101//Make the net invisible so all the animations can play out. + health = INFINITY//Make the net invincible so that an explosion/something else won't kill it while, spawn() is running. + for(var/obj/item/W in M) + if(istype(M,/mob/living/carbon/human)) + if(W==M:w_uniform) continue//So all they're left with are shoes and uniform. + if(W==M:shoes) continue + M.unEquip(W) - blob_act() - health-=50 - healthcheck() - return + spawn(0) + playsound(M.loc, 'sound/effects/sparks4.ogg', 50, 1) + anim(M.loc,M,'icons/mob/mob.dmi',,"phaseout",,M.dir) - hitby(AM as mob|obj) - ..() - for(var/mob/O in viewers(src, null)) - O.show_message(text("[src] was hit by [AM]."), 1) - var/tforce = 0 - if(ismob(AM)) - tforce = 10 - else - tforce = AM:throwforce - playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) - health = max(0, health - tforce) - healthcheck() - ..() - return + M.loc = pick(holdingfacility)//Throw mob in to the holding facility. + M << "You appear in a strange place!" - attack_hand() - if (HULK in usr.mutations) - usr << text("You easily destroy the energy net.") - for(var/mob/O in oviewers(src)) - O.show_message(text("[] rips the energy net apart!", usr), 1) + spawn(0) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, M.loc) + spark_system.start() + playsound(M.loc, 'sound/effects/phasein.ogg', 25, 1) + playsound(M.loc, 'sound/effects/sparks2.ogg', 50, 1) + anim(M.loc,M,'icons/mob/mob.dmi',,"phasein",,M.dir) + qdel(src)//Wait for everything to finish, delete the net. Else it will stop everything once net is deleted, including the spawn(0). + + for(var/mob/O in viewers(src, 3)) + O.show_message("[M] vanished!", 1, "You hear sparks flying!", 2) + + if(!isnull(master))//As long as they still exist. + master << "SUCCESS: \black transport procedure of \the [affecting] complete." + + M.anchored = 0//Important. + + else//And they are free. + M << "You are free of the net!" + return + +/obj/effect/energy_net/bullet_act(var/obj/item/projectile/Proj) + health -= Proj.damage + healthcheck() + ..() + +/obj/effect/energy_net/ex_act(severity) + switch(severity) + if(1.0) health-=50 - healthcheck() - return + if(2.0) + health-=50 + if(3.0) + health-=prob(50)?50:25 + healthcheck() + return - attack_paw() - return attack_hand() +/obj/effect/energy_net/blob_act() + health-=50 + healthcheck() + return - attack_alien() - if (islarva(usr)) - return - usr << text("\green You claw at the net.") - for(var/mob/O in oviewers(src)) - O.show_message(text("[] claws at the energy net!", usr), 1) - playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) - health -= rand(10, 20) - if(health <= 0) - usr << text("\green You slice the energy net to pieces.") - for(var/mob/O in oviewers(src)) - O.show_message(text("[] slices the energy net apart!", usr), 1) - healthcheck() - return +/obj/effect/energy_net/hitby(AM as mob|obj) + ..() + visible_message("[src] was hit by [AM].") + var/tforce = 0 + if(ismob(AM)) + tforce = 10 + else + tforce = AM:throwforce + playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) + health = max(0, health - tforce) + healthcheck() + ..() + return - attackby(obj/item/weapon/W as obj, mob/user as mob) - var/aforce = W.force - health = max(0, health - aforce) - healthcheck() - ..() +/obj/effect/energy_net/attack_hand(mob/user) + if (HULK in user.mutations) + user.visible_message("[user] rips the energy net apart!", \ + "You easily destroy the energy net.") + health-=50 + healthcheck() + return + +/obj/effect/energy_net/attack_paw(mob/user) + return attack_hand() + +/obj/effect/energy_net/attack_alien(mob/user as mob) + if (islarva(user)) return + playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) + health -= rand(10, 20) + if(health > 0) + user.visible_message("[user] claws at the energy net!", \ + "\green You claw at the net.") + else + user.visible_message("[user] slices the energy net apart!", \ + "\green You slice the energy net to pieces.") + healthcheck() + return + +/obj/effect/energy_net/attackby(obj/item/weapon/W as obj, mob/user as mob) + var/aforce = W.force + health = max(0, health - aforce) + healthcheck() + ..() + return proc/create_ninja_mind(key) var/datum/mind/Mind = new /datum/mind(key) Mind.assigned_role = "MODE" Mind.special_role = "Space Ninja" ticker.mode.traitors |= Mind //Adds them to current traitor list. Which is really the extra antagonist list. - return Mind \ No newline at end of file + return Mind diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index c7207e99bb8..312635711ff 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -247,9 +247,8 @@ proc/check_panel(mob/M) /obj/effect/fake_attacker/attackby(var/obj/item/weapon/P as obj, mob/user as mob) step_away(src,my_target,2) - for(var/mob/M in oviewers(world.view,my_target)) - M << "[my_target] flails around wildly." - my_target.show_message("[src] has been attacked by [my_target] ", 1) //Lazy. + my_target.visible_message("[my_target] flails around wildly.", \ + "[src] has been attacked by [my_target] ") src.health -= P.force @@ -261,7 +260,7 @@ proc/check_panel(mob/M) step_away(src,my_target,2) if(prob(30)) for(var/mob/O in oviewers(world.view , my_target)) - O << "[my_target] stumbles around." + O << "[my_target] stumbles around." /obj/effect/fake_attacker/New() ..() diff --git a/code/modules/food&drinks/food/snacks/meat.dm b/code/modules/food&drinks/food/snacks/meat.dm index 91b2c27b243..9397cd6b40f 100644 --- a/code/modules/food&drinks/food/snacks/meat.dm +++ b/code/modules/food&drinks/food/snacks/meat.dm @@ -61,6 +61,11 @@ icon_state = "skeletonmeat" desc = "There's a point where this needs to stop and clearly we have passed it" +/obj/item/weapon/reagent_containers/food/snacks/meat/human/mutant/zombie + name = "-meat (rotten)" + icon_state = "lizardmeat" //Close enough. + desc = "Halfway to becoming fertilizer for your garden." + /obj/item/weapon/reagent_containers/food/snacks/meat/monkey //same as plain meat diff --git a/code/modules/holiday/halloween.dm b/code/modules/holiday/halloween.dm new file mode 100644 index 00000000000..4e2de9e5c6e --- /dev/null +++ b/code/modules/holiday/halloween.dm @@ -0,0 +1,337 @@ +//spooky halloween stuff. only tick on halloween!!! +/datum/round_event/spooky/start() //This has to be here because else you get errors with spooky storage not being a defined type. + ..() + for(var/mob/living/carbon/human/H) + for(var/obj/item/weapon/storage/backpack/b in H.contents) + new /obj/item/weapon/storage/spooky(b) + +//uses super seekrit double proc definition stuffs. remember to call ..()! +/*/mob/dead/observer/say(var/message) //this doesn't actually work vOv + ..() + for(var/mob/M in hearers(src, 1)) + 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)*/ + + +/////////////////////////////////////// +///////////HALLOWEEN CONTENT/////////// +/////////////////////////////////////// + +//spooky foods +/obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookyskull + name = "skull cookie" + desc = "Spooky! It's got delicious calcium flavouring!" + icon = 'icons/obj/halloween_items.dmi' + icon_state = "skeletoncookie" + +/obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookycoffin + name = "coffin cookie" + desc = "Spooky! It's got delicious coffee flavouring!" + icon = 'icons/obj/halloween_items.dmi' + icon_state = "coffincookie" + +//spooky recipes + +/datum/recipe/sugarcookie/spookyskull + reagents = list("flour" = 5, "sugar" = 5, "milk" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/egg, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookyskull + +/datum/recipe/sugarcookie/spookycoffin + reagents = list("flour" = 5, "sugar" = 5, "coffee" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/egg, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookycoffin + +//spooky items + +/obj/item/weapon/storage/spooky + name = "trick-o-treat bag" + desc = "A Pumpkin shaped bag that holds all sorts of goodies!" + icon = 'icons/obj/halloween_items.dmi' + icon_state = "treatbag" + +/obj/item/weapon/storage/spooky/New() + ..() + for(var/distrobuteinbag=0 to 6) + var/type = pick(/obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookyskull, + /obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookycoffin, + /obj/item/weapon/reagent_containers/food/snacks/candy_corn, + /obj/item/weapon/reagent_containers/food/snacks/candy, + /obj/item/weapon/reagent_containers/food/snacks/chocolatebar) + new type(src) + +////////////////////////////// +//Spookoween trapped closets// +////////////////////////////// + +#define SPOOKY_SKELETON 1 +#define ANGRY_FAITHLESS 2 +#define SCARY_BATS 3 +#define INSANE_CLOWN 4 +#define HOWLING_GHOST 5 + +//Spookoween variables +/obj/structure/closet + var/trapped = 0 + var/mob/trapped_mob + +/obj/structure/closet/initialize() + ..() + if(prob(30)) + set_spooky_trap() + +/obj/structure/closet/dump_contents() + ..() + trigger_spooky_trap() + +/obj/structure/closet/proc/set_spooky_trap() + if(prob(0.1)) + trapped = INSANE_CLOWN + return + if(prob(1)) + trapped = ANGRY_FAITHLESS + return + if(prob(15)) + trapped = SCARY_BATS + return + if(prob(20)) + trapped = HOWLING_GHOST + return + else + var/mob/living/carbon/human/H = new (loc) + H.makeSkeleton() + H.health = 1e5 + insert(H) + trapped_mob = H + trapped = SPOOKY_SKELETON + return + +/obj/structure/closet/proc/trigger_spooky_trap() + if(!trapped) + return + + if(trapped == SPOOKY_SKELETON) + src.visible_message("BOO!"); + playsound(src.loc, pick('sound/effects/xylophone1.ogg','sound/effects/xylophone2.ogg','sound/effects/xylophone3.ogg','sound/spookoween/girlscream.ogg'), 300, 1) + trapped = 0 + spawn(60) + if(trapped_mob.loc != loc) + var/datum/effect/effect/system/harmless_smoke_spread/smoke = new + smoke.set_up(1,0, trapped_mob.loc, 0) + smoke.start() + trapped_mob.loc = loc + src.close() + trapped = SPOOKY_SKELETON + return + + if(trapped == ANGRY_FAITHLESS) + src.visible_message("The closet bursts open!"); + src.visible_message("THIS BEING RADIATES PURE EVIL! YOU BETTER RUN !!!"); + playsound(src.loc, 'sound/hallucinations/wail.ogg', 300, 1) + var/mob/living/simple_animal/hostile/faithless/F = new (loc) + F.health =1e5 + F.stance = HOSTILE_STANCE_ATTACK + F.GiveTarget(usr) + trapped = 0 + qdel(src) + spawn(120) + var/datum/effect/effect/system/harmless_smoke_spread/smoke = new + smoke.set_up(1,0, F.loc, 0) + smoke.start() + qdel(F) + return + + if(trapped == SCARY_BATS) + src.visible_message("Protect your hairs !!!"); + playsound(src.loc, 'sound/spookoween/bats.ogg', 300, 1) + var/number = rand(1,4) + for(var/i=0,i < number,i++) + new /mob/living/simple_animal/hostile/retaliate/bat (loc) + trapped = 0 + return + + + if(trapped == INSANE_CLOWN) + src.visible_message("..."); + playsound(src.loc, 'sound/spookoween/scary_clown_appear.ogg', 300, 1) + var/mob/living/simple_animal/hostile/retaliate/clown/insane/IC = new (loc) + IC.GiveTarget(usr) + trapped = 0 + return + + if(trapped == HOWLING_GHOST) + src.visible_message("Woo Woo"); + playsound(src.loc, 'sound/spookoween/ghosty_wind.ogg', 300, 1) + new /mob/living/simple_animal/shade/howling_ghost (loc) + trapped = 0 + return + +//don't spawn in crates +/obj/structure/closet/crate/trigger_spooky_trap() + return 0 + +/obj/structure/closet/crate/set_spooky_trap() + return 0 + + +//////////////////// +//Spookoween Ghost// +//////////////////// + +/mob/living/simple_animal/shade/howling_ghost + name ="Ghost" + real_name = "Ghost" + icon = 'icons/mob/mob.dmi' + maxHealth = 1e6 + health = 1e6 + speak_emote = list("howls") + emote_hear = list("wails","screeches") + density = 0 + anchored = 1 + incorporeal_move = 1 + layer = 4 + var/timer = 0 + +/mob/living/simple_animal/shade/howling_ghost/New() + ..() + icon_state = pick("ghost","ghostian","ghostian2","ghostking","ghost1","ghost2") + icon_living = icon_state + status_flags |= GODMODE + timer = rand(1,15) + +/mob/living/simple_animal/shade/howling_ghost/Life() + ..() + timer-- + if(timer == 0) + roam() + spooky_ghosty() + timer = rand(1,15) + +/mob/living/simple_animal/shade/howling_ghost/proc/EtherealMove(direction) + loc = get_step(src, direction) + dir = direction + +/mob/living/simple_animal/shade/howling_ghost/proc/roam() + if(prob(80)) + var/direction = pick(NORTH,SOUTH,EAST,WEST,NORTHEAST,NORTHWEST,SOUTHEAST,SOUTHWEST) + EtherealMove(direction) + +/mob/living/simple_animal/shade/howling_ghost/proc/spooky_ghosty() + if(prob(20)) //haunt + playsound(src.loc, pick('sound/spookoween/ghosty_wind.ogg','sound/spookoween/ghost_whisper.ogg','sound/spookoween/chain_rattling.ogg'), 300, 1) + if(prob(10)) //flickers + var/obj/machinery/light/L = locate(/obj/machinery/light) in view(5, src) + if(L) + L.flicker() + if(prob(5)) //poltergeist + var/obj/item/I = locate(/obj/item) in view(3, src) + if(I) + var/direction = pick(NORTH,SOUTH,EAST,WEST,NORTHEAST,NORTHWEST,SOUTHEAST,SOUTHWEST) + step(I,direction) + return + +/mob/living/simple_animal/shade/howling_ghost/adjustBruteLoss() + return + +/mob/living/simple_animal/shade/howling_ghost/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + return 1 + + +/////////////////////////// +//Spookoween Insane Clown// +/////////////////////////// + +/mob/living/simple_animal/hostile/retaliate/clown/insane + name = "Insane Clown" + desc = "May the HonkMother have mercy..." + icon_state = "scary_clown" + icon_living = "scary_clown" + icon_dead = "scary_clown" + icon_gib = "scary_clown" + speak = list("...", ". . .") + maxHealth = 1e6 + health = 1e6 + emote_see = list("silently stares") + heat_damage_per_tick = 0 + cold_damage_per_tick = 0 + unsuitable_atmos_damage = 0 + + var/timer + +/mob/living/simple_animal/hostile/retaliate/clown/insane/New() + ..() + timer = rand(5,15) + status_flags = (status_flags | GODMODE) + return + +/mob/living/simple_animal/hostile/retaliate/clown/insane/Retaliate() + return + +/mob/living/simple_animal/hostile/retaliate/clown/insane/ex_act() + return + +/mob/living/simple_animal/hostile/retaliate/clown/insane/Life() + timer-- + if(target) + stalk() + return + +/mob/living/simple_animal/hostile/retaliate/clown/insane/proc/stalk() + var/mob/living/M = target + if(M.stat == DEAD) + playsound(M.loc, 'sound/spookoween/insane_low_laugh.ogg', 300, 1) + qdel(src) + if(timer == 0) + timer = rand(5,15) + playsound(M.loc, pick('sound/spookoween/scary_horn.ogg','sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 300, 1) + spawn(12) + loc = M.loc + return + +/mob/living/simple_animal/hostile/retaliate/clown/insane/MoveToTarget() + return + +/mob/living/simple_animal/hostile/retaliate/clown/insane/AttackTarget() + return + +/mob/living/simple_animal/hostile/retaliate/clown/insane/adjustBruteLoss() + if(prob(5)) + playsound(src.loc, 'sound/spookoween/insane_low_laugh.ogg', 300, 1) + return + +/mob/living/simple_animal/hostile/retaliate/clown/insane/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(istype(O,/obj/item/weapon/nullrod)) + if(prob(5)) + visible_message("[src] finally found the peace it deserves. HONK for the HonkMother !"); + playsound(src.loc, 'sound/spookoween/insane_low_laugh.ogg', 300, 1) + qdel(src) + return + else + visible_message("It seems to be resisting the effect!!!"); + return + ..() + diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index 3b76c06082c..dce78028dd3 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -151,6 +151,7 @@ dat += "Botanical gloves: Make ([250/efficiency])
    " dat += "Utility belt: Make ([300/efficiency])
    " dat += "Leather Satchel: Make ([400/efficiency])
    " + dat += "Leather Jacket: Make ([500/efficiency])
    " dat += "" else dat += "
    No container inside, please insert container.
    " @@ -243,6 +244,9 @@ if("satchel") if (check_cost(400/efficiency)) return 0 else new/obj/item/weapon/storage/backpack/satchel(src.loc) + if("jacket") + if (check_cost(500/efficiency)) return 0 + else new/obj/item/clothing/suit/jacket/leather(src.loc) //if("monkey") // if (check_cost(500)) return 0 // else new/mob/living/carbon/monkey(src.loc) diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 0ae9d2fea75..1b37c72e8ba 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -758,14 +758,19 @@ obj/item/weapon/reagent_containers/food/snacks/grown/shell/eggy/add_juice() /obj/item/weapon/reagent_containers/food/snacks/grown/carpet/attack_self(mob/user as mob) user << "You roll out the red carpet." - var/location = get_turf(user) var/carpetAmt = 1 + round(potency / 50) // The carpet we're holding - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/carpet/carpetToConvert in location) // The carpet on the floor - carpetAmt += 1 - qdel(carpetToConvert) - var/obj/item/stack/tile/newAstroturf = new /obj/item/stack/tile/carpet(location) - newAstroturf.amount = carpetAmt + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/carpet/C in user.loc) // The carpet on the floor + carpetAmt += 1 + round(C.potency / 50) + qdel(C) + while(carpetAmt > 0) + var/obj/item/stack/tile/CT = new /obj/item/stack/tile/carpet(user.loc) + if(carpetAmt >= CT.max_amount) + CT.amount = CT.max_amount + else + CT.amount = carpetAmt + carpetAmt -= CT.max_amount qdel(src) + return /obj/item/weapon/reagent_containers/food/snacks/grown/kudzupod seed = /obj/item/seeds/kudzuseed diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index eadd1e62fb1..396ad4bb5ef 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -265,6 +265,7 @@ var/obj/item/weapon/storage/book/B = new B.name = src.name B.title = src.title + B.icon_state = src.icon_state if(user.l_hand == src || user.r_hand == src) qdel(src) user.put_in_hands(B) diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm index 284922a5e8f..fbc21838808 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -102,7 +102,6 @@ var/obj/item/stack/sheet/s var/dat - dat += text("Ore Redemption Machine

    ") dat += text("This machine only accepts ore. Gibtonite and Slag are not accepted.

    ") dat += text("Current unclaimed points: [points]
    ") @@ -115,6 +114,8 @@ for(var/O in stack_list) s = stack_list[O] if(s.amount > 0) + if(O == stack_list[1]) + dat += "
    " //just looks nicer dat += text("[capitalize(s.name)]: [s.amount] Release
    ") if((/obj/item/stack/sheet/metal in stack_list) && (/obj/item/stack/sheet/mineral/plasma in stack_list)) @@ -123,10 +124,11 @@ if(min(metalstack.amount, plasmastack.amount)) dat += text("Plasteel Alloy (Metal + Plasma): Smelt
    ") - dat += text("
    Mineral Value List:
    [get_ore_values()]") - - user << browse("[dat]", "window=console_stacking_machine") + dat += text("
    Mineral Value List:
    [get_ore_values()]
    ") + var/datum/browser/popup = new(user, "console_stacking_machine", "Ore Redemption Machine", 400, 500) + popup.set_content(dat) + popup.open() return /obj/machinery/mineral/ore_redemption/proc/get_ore_values() @@ -274,19 +276,20 @@ /obj/machinery/mineral/equipment_vendor/interact(mob/user) var/dat - dat += text("Mining Equipment vendor

    ") - + dat +="
    " if(istype(inserted_id)) dat += "You have [inserted_id.mining_points] mining points collected. Eject ID.
    " else dat += "No ID inserted. Insert ID.
    " - - dat += "
    Equipment point cost list:

    Name

    Vitals

    Position

    [ID.name]
    [I.registered_name] ([I.assignment])
    Unknown
    Unknown[life_status]Not Available
    [life_status]Not Available
    [life_status] [damage_report]Not Available
    [life_status] [damage_report]Not Available
    [life_status] [damage_report][format_text(player_area.name)] ([pos.x], [pos.y])
    " + dat += "" + dat += "
    Equipment point cost list:
    " for(var/datum/data/mining_equipment/prize in prize_list) dat += "" dat += "
    [prize.equipment_name][prize.cost]Purchase
    " - user << browse("[dat]", "window=mining_equipment_vendor") + var/datum/browser/popup = new(user, "miningvendor", "Mining Equipment Vendor", 400, 350) + popup.set_content(dat) + popup.open() return /obj/machinery/mineral/equipment_vendor/Topic(href, href_list) @@ -453,7 +456,7 @@ shake_camera(L, 20, 1) spawn(20) if(L) - L.visible_message("[L.name] vomits from travelling through the [src.name]!") + L.visible_message("[L.name] vomits from travelling through the [src.name]!", "You throw up from travelling through the [src.name]!") L.nutrition -= 20 L.adjustToxLoss(-3) var/turf/T = get_turf(L) diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index 43d53825aaf..c39d03f38ac 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -490,6 +490,9 @@ // spawn(2) //O updateMineralOverlays() +/turf/simulated/floor/plating/asteroid/burn_tile() + return + /turf/simulated/floor/plating/asteroid/ex_act(severity) switch(severity) if(3.0) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index a1e9c378f4e..9274b09145d 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -56,7 +56,7 @@ ..() -/mob/dead/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/mob/dead/CanPass(atom/movable/mover, turf/target, height=0) return 1 /* Transfer_mind is there to check if mob is being deleted/not going to have a body. diff --git a/code/modules/mob/dead/observer/say.dm b/code/modules/mob/dead/observer/say.dm index 37831db6f0a..c173f406e2f 100644 --- a/code/modules/mob/dead/observer/say.dm +++ b/code/modules/mob/dead/observer/say.dm @@ -18,29 +18,3 @@ /mob/dead/observer/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) src << 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) -*/ \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index d2845a672ed..9e5285b6cf1 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -158,9 +158,6 @@ /mob/living/carbon/alien/SpeciesCanConsume() return 1 // Aliens can eat, and they can be fed food/drink -/mob/living/carbon/alien/Process_Spaceslipping() - return 0 // Don't slip in space. - /mob/living/carbon/alien/Stat() statpanel("Status") 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 2c372c6497b..513c7b2b6e6 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -150,8 +150,7 @@ Doesn't work on other aliens/AI.*/ if(!choice || !powerc(55)) return adjustToxLoss(-55) src << "You shape a [choice]." - for(var/mob/O in viewers(src, null)) - O.show_message(text("[src] vomits up a thick purple substance and begins to shape it."), 1) + visible_message("[src] vomits up a thick purple substance and begins to shape it.") switch(choice) if("resin wall") new /obj/structure/alien/resin/wall(loc) diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index dcbcba1ded8..68c63a16410 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -136,7 +136,7 @@ var/atom/step = get_step(src, get_dir(src,target)) if(!step) break - src.Move(step) + src.Move(step, get_dir(src, step)) hit_check() error += (error < 0) ? tdist_x : -tdist_y; dist_travelled++ diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index 4b47808e80a..8473fa5e8e1 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -74,6 +74,7 @@ icon = 'icons/mob/alienqueen.dmi' icon_state = "queen_s" pixel_x = -16 + mob_size = 2 /mob/living/carbon/alien/humanoid/queen/large/update_icons() update_hud() //TODO: remove the need for this to be here diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 9c191d338ae..9e4041d3aa3 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -3,6 +3,7 @@ real_name = "alien larva" icon_state = "larva0" pass_flags = PASSTABLE | PASSMOB + mob_size = 0 maxHealth = 25 health = 25 diff --git a/code/modules/mob/living/carbon/alien/larva/powers.dm b/code/modules/mob/living/carbon/alien/larva/powers.dm index 46097e7c411..efbdcdafe9b 100644 --- a/code/modules/mob/living/carbon/alien/larva/powers.dm +++ b/code/modules/mob/living/carbon/alien/larva/powers.dm @@ -9,16 +9,12 @@ if (layer != TURF_LAYER+0.2) layer = TURF_LAYER+0.2 - src << text("You are now hiding.") - for(var/mob/O in oviewers(src, null)) - if ((O.client && !( O.blinded ))) - O << text("[] scurries to the ground!", src) + visible_message("[src] scurries to the ground!", \ + "You are now hiding.") else layer = MOB_LAYER - src << text("You have stopped hiding.") - for(var/mob/O in oviewers(src, null)) - if ((O.client && !( O.blinded ))) - O << text("[] slowly peaks up from the ground...", src) + visible_message("[src] slowly peaks up from the ground...", \ + "You have stopped hiding.") /mob/living/carbon/alien/larva/verb/evolve() set name = "Evolve" diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index fecd02cc271..bc11bcd2490 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -137,7 +137,8 @@ var/const/MAX_ACTIVE_TIME = 400 if(W.flags & NODROP) return 0 target.unEquip(W) - target.visible_message("[src] tears [W] off of [target]'s face!") + target.visible_message("[src] tears [W] off of [target]'s face!", \ + "[src] tears [W] off of [target]'s face!") src.loc = target target.equip_to_slot(src, slot_wear_mask,,0) @@ -166,7 +167,8 @@ var/const/MAX_ACTIVE_TIME = 400 if(!sterile) //target.contract_disease(new /datum/disease/alien_embryo(0)) //so infection chance is same as virus infection chance - target.visible_message("[src] falls limp after violating [target]'s face!") + target.visible_message("[src] falls limp after violating [target]'s face!", \ + "[src] falls limp after violating [target]'s face!") Die() icon_state = "[initial(icon_state)]_impregnated" @@ -180,7 +182,8 @@ var/const/MAX_ACTIVE_TIME = 400 src.loc = get_turf(C) C.facehugger = null else - target.visible_message("[src] violates [target]'s face!") + target.visible_message("[src] violates [target]'s face!", \ + "[src] violates [target]'s face!") return /obj/item/clothing/mask/facehugger/proc/GoActive() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 55076006232..52ae23cc879 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -309,20 +309,7 @@ item.layer = initial(item.layer) src.visible_message("[src] has thrown [item].") - if(!src.lastarea) - src.lastarea = get_area(src.loc) - if(!has_gravity(src)) - src.inertia_dir = get_dir(target, src) - step(src, inertia_dir) - - -/* - if(istype(src.loc, /turf/space) || (src.flags & NOGRAV)) //they're in space, move em one space in the opposite direction - src.inertia_dir = get_dir(target, src) - step(src, inertia_dir) -*/ - - + newtonian_move(get_dir(target, src)) item.throw_at(target, item.throw_range, item.throw_speed) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index e9c20065506..84d3f094d59 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -43,7 +43,7 @@ return ..() /mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes) - if ((!( yes ) || now_pushing)) + if ((!( yes ) || now_pushing || buckled)) return now_pushing = 1 if (ismob(AM)) @@ -111,7 +111,7 @@ if(pulling == AM) stop_pulling() var/t = get_dir(src, AM) - AM.Move(get_step(AM, t)) + AM.Move(get_step(AM, t), t) now_pushing = 0 /mob/living/carbon/human/Stat() @@ -705,4 +705,15 @@ facial_hair_style = "Shaved" hair_style = pick("Bedhead", "Bedhead 2", "Bedhead 3") underwear = "Nude" - regenerate_icons() \ No newline at end of file + regenerate_icons() + +/mob/living/carbon/human/singularity_act() + var/gain = 20 + if(mind) + if((mind.assigned_role == "Station Engineer") || (mind.assigned_role == "Chief Engineer") ) + gain = 100 + if(mind.assigned_role == "Clown") + gain = rand(-300, 300) + investigate_log(" has consumed [key_name(src)].","singulo") //Oh that's where the clown ended up! + gib() + return(gain) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 438fb8c650b..b5ad5610e7e 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -5,40 +5,20 @@ . += ..() . += config.human_delay -/mob/living/carbon/human/Process_Spacemove(var/check_drift = 0) - //Can we act - if(!canmove) return 0 +/mob/living/carbon/human/Process_Spacemove(var/movement_dir = 0) + + if(..()) + return 1 //Do we have a working jetpack - if(istype(back, /obj/item/weapon/tank/jetpack)) + if(istype(back, /obj/item/weapon/tank/jetpack) && isturf(loc)) //Second check is so you can't use a jetpack in a mech var/obj/item/weapon/tank/jetpack/J = back - if(((!check_drift) || (check_drift && J.stabilization_on)) && (!lying) && (J.allow_thrust(0.01, src))) - inertia_dir = 0 + if((movement_dir || J.stabilization_on) && J.allow_thrust(0.01, src)) return 1 - //If no working jetpack or magboots then use the other checks - if(..()) return 1 + return 0 -/mob/living/carbon/human/Process_Spaceslipping(var/prob_slip = 5) - //If knocked out we might just hit it and stop. This makes it possible to get dead bodies and such. - if(stat) - prob_slip = 0 // Changing this to zero to make it line up with the comment, and also, make more sense. - - //Do we have magboots or such on if so no slip - if(istype(shoes, /obj/item/clothing/shoes/magboots) && (shoes.flags & NOSLIP)) - prob_slip = 0 - - //Check hands and mod slip - if(!l_hand) prob_slip -= 2 - else if(l_hand.w_class <= 2) prob_slip -= 1 - if (!r_hand) prob_slip -= 2 - else if(r_hand.w_class <= 2) prob_slip -= 1 - - prob_slip = round(prob_slip) - return(prob_slip) - - /mob/living/carbon/human/slip(var/s_amount, var/w_amount, var/obj/O, var/lube) if(isobj(shoes) && (shoes.flags&NOSLIP) && !(lube&GALOSHES_DONT_HELP)) return 0 @@ -52,3 +32,11 @@ /mob/living/carbon/human/mob_negates_gravity() return shoes && shoes.negates_gravity() + +/mob/living/carbon/human/Move(NewLoc, direct) + ..() + if(shoes) + if(loc == NewLoc) + var/obj/item/clothing/shoes/S = shoes + S.step_action() + diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index e64fb179545..546384be6c1 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -578,13 +578,13 @@ else switch(H.radiation) - if(1 to 49) + if(0 to 50) H.radiation-- if(prob(25)) H.adjustToxLoss(1) H.updatehealth() - if(50 to 74) + if(50 to 75) H.radiation -= 2 H.adjustToxLoss(1) if(prob(5)) @@ -617,13 +617,24 @@ /datum/species/proc/movement_delay(var/mob/living/carbon/human/H) var/mspeed = 0 + if(H.status_flags & GOTTAGOFAST) + mspeed -= 1 if(!has_gravity(H)) - return -1 //It's hard to be slowed down in space by... anything - else if(H.status_flags & GOTTAGOFAST) - return -1 + mspeed += 2 //Carefully propelling yourself along the walls is actually quite slow + + if(istype(H.back, /obj/item/weapon/tank/jetpack)) + var/obj/item/weapon/tank/jetpack/J = H.back + if(J.allow_thrust(0.01, H)) + mspeed -= 3 + + if(H.l_hand) //Having your hands full makes movement harder when you're weightless. You try climbing around while holding a gun! + mspeed += 0.5 + if(H.r_hand) + mspeed += 0.5 + if(H.r_hand && H.l_hand) + mspeed += 0.5 - mspeed = 0 var/health_deficiency = (100 - H.health + H.staminaloss) if(health_deficiency >= 40) mspeed += (health_deficiency / 25) diff --git a/code/modules/mob/living/carbon/human/species_types.dm b/code/modules/mob/living/carbon/human/species_types.dm index e3e42effb46..99cb7f8eece 100644 --- a/code/modules/mob/living/carbon/human/species_types.dm +++ b/code/modules/mob/living/carbon/human/species_types.dm @@ -214,10 +214,7 @@ return 1 /datum/species/fly/handle_speech(message) - if(copytext(message, 1, 2) != "*") - message = replacetext(message, "z", stutter("zz")) - - return message + return replacetext(message, "z", stutter("zz")) /* SKELETONS @@ -229,3 +226,30 @@ id = "skeleton" sexes = 0 meat = /obj/item/weapon/reagent_containers/food/snacks/meat/human/mutant/skeleton +/* + ZOMBIES +*/ + +/datum/species/zombie + // 1spooky + name = "Brain-Munching Zombie" + id = "zombie" + say_mod = "moans" + sexes = 0 + meat = /obj/item/weapon/reagent_containers/food/snacks/meat/human/mutant/zombie + +/datum/species/zombie/handle_speech(message) + var/list/message_list = text2list(message, " ") + var/maxchanges = max(round(message_list.len / 1.5), 2) + + for(var/i = rand(maxchanges / 2, maxchanges), i > 0, i--) + var/insertpos = rand(1, message_list.len - 1) + var/inserttext = message_list[insertpos] + + if(!(copytext(inserttext, length(inserttext) - 2) == "...")) + message_list[insertpos] = inserttext + "..." + + if(prob(20) && message_list.len > 3) + message_list.Insert(insertpos, "[pick("BRAINS", "Brains", "Braaaiinnnsss", "BRAAAIIINNSSS")]...") + + return list2text(message_list, " ") diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm index 3d1a66a3702..3b1095043bc 100644 --- a/code/modules/mob/living/carbon/slime/slime.dm +++ b/code/modules/mob/living/carbon/slime/slime.dm @@ -151,7 +151,7 @@ step(AM, t) now_pushing = null -/mob/living/carbon/slime/Process_Spacemove() +/mob/living/carbon/slime/Process_Spacemove(var/movement_dir = 0) return 2 /mob/living/carbon/slime/Stat() diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 38586236e9a..ed75ad5e894 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -158,19 +158,16 @@ if ("point") if (!src.restrained()) - var/mob/M = null + var/atom/M = null if (param) - for (var/atom/A as mob|obj|turf|area in view(1, src)) + for (var/atom/A as mob|obj|turf in view()) if (param == A.name) M = A break if (!M) message = "[src] points." else - M.point() - if (M) - message = "[src] points to [M]." - else + pointed(M) m_type = 1 if ("scream") diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index fad2f1154e8..b29b0885b40 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -315,9 +315,9 @@ return -/mob/living/Move(a, b, flag) - if (buckled) - return +/mob/living/Move(atom/newloc, direct) + if (buckled && buckled.loc != newloc && !buckled.anchored) + return buckled.Move(newloc, direct) if (restrained()) stop_pulling() @@ -328,7 +328,7 @@ for(var/mob/living/M in range(src, 1)) if ((M.pulling == src && M.stat == 0 && !( M.restrained() ))) t7 = null - if ((t7 && (pulling && ((get_dist(src, pulling) <= 1 || pulling.loc == loc) && (client && client.moving))))) + if (t7 && pulling && (get_dist(src, pulling) <= 1 || pulling.loc == loc)) var/turf/T = loc . = ..() @@ -395,12 +395,12 @@ if(check_dna_integrity(M)) //blood DNA var/mob/living/carbon/DNA_helper = pulling H.blood_DNA[DNA_helper.dna.unique_enzymes] = DNA_helper.dna.blood_type - pulling.Move(T) + pulling.Move(T, get_dir(pulling, T)) if(M) M.start_pulling(t) else if (pulling) - pulling.Move(T) + pulling.Move(T, get_dir(pulling, T)) else stop_pulling() . = ..() @@ -630,3 +630,9 @@ src.unEquip(what) who.equip_to_slot_if_possible(what, where, 0, 1) add_logs(src, who, "equipped", object=what) + +/mob/living/singularity_act() + var/gain = 20 + investigate_log(" has consumed [key_name(src)].","singulo") //Oh that's where the clown ended up! + gib() + return(gain) \ No newline at end of file diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 508e9505895..dc7b9cd2f44 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -39,4 +39,5 @@ var/ventcrawler = 0 //0 No vent crawling, 1 vent crawling in the nude, 2 vent crawling always var/floating = 0 - var/nightvision = 0 + var/nightvision = 0 + var/mob_size = 1 //size of the mob. 0 is small, 1 is human sized, and 2 is large. diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 78489511a0c..e390d9e58c5 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -31,6 +31,7 @@ var/list/ai_list = list() var/obj/item/device/pda/ai/aiPDA = null var/obj/item/device/multitool/aiMulti = null var/obj/item/device/camera/siliconcam/aicamera = null + var/obj/machinery/bot/Bot //MALFUNCTION var/datum/module_picker/malf_picker @@ -54,6 +55,8 @@ var/list/ai_list = list() var/last_paper_seen = null var/can_shunt = 1 var/last_announcement = "" // For AI VOX, if enabled + var/turf/waypoint //Holds the turf of the currently selected waypoint. + var/waypoint_mode = 0 //Waypoint mode is for selecting a turf via clicking. /mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0) var/list/possibleNames = ai_names @@ -94,7 +97,7 @@ var/list/ai_list = list() if (istype(loc, /turf)) verbs.Add(/mob/living/silicon/ai/proc/ai_network_change, \ /mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \ - /mob/living/silicon/ai/proc/toggle_camera_light) + /mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/botcall) if(!safety)//Only used by AIize() to successfully spawn an AI. if (!B)//If there is no player/brain inside. @@ -355,6 +358,24 @@ var/list/ai_list = list() A.ai_actual_track(target) return + if (href_list["callbot"]) //Command a bot to move to a selected location. + Bot = locate(href_list["callbot"]) in machines + if(!Bot || Bot.remote_disabled || src.control_disabled) + return //True if there is no bot found, the bot is manually emagged, or the AI is carded with wireless off. + waypoint_mode = 1 + src << "Set your waypoint by clicking on a valid location free of obstructions." + return + + if (href_list["interface"]) //Remotely connect to a bot! + Bot = locate(href_list["interface"]) in machines + if(!Bot || Bot.remote_disabled || src.control_disabled) + return + Bot.attack_ai(src) + + if (href_list["botrefresh"]) //Refreshes the bot control panel. + botcall() + return + else if (href_list["faketrack"]) var/mob/target = locate(href_list["track"]) in mob_list var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list @@ -449,6 +470,61 @@ var/list/ai_list = list() return 1 +/mob/living/silicon/ai/proc/botcall() + set category = "AI Commands" + set name = "Access Robot Control" + set desc = "Wirelessly control various automatic robots." + if(stat == 2) + src << "Critical error. System offline." + return + + if(control_disabled) + src << "Wireless communication is disabled." + return + var/turf/ai_current_turf = get_turf(src) + var/ai_Zlevel = ai_current_turf.z + var/d + var/area/bot_area + d += "Query network status
    " + d += "" + + for (Bot in machines) + if(Bot.z == ai_Zlevel && !Bot.remote_disabled) //Only non-emagged bots on the same Z-level are detected! + bot_area = get_area(Bot) + d += "" + //If the bot is on, it will display the bot's current mode status. If the bot is not mode, it will just report "Idle". "Inactive if it is not on at all. + d += "" + d += "" + d += "" + d += "" + d += "" + d = format_text(d) + + var/datum/browser/popup = new(src, "botcall", "Remote Robot Control", 700, 400) + popup.set_content(d) + popup.open() + +/mob/living/silicon/ai/proc/set_waypoint(var/atom/A) + var/turf/turf_check = get_turf(A) + //The target must be in view of a camera or near the core. + if(turf_check in range(get_turf(src))) + call_bot(turf_check) + else if(cameranet && cameranet.checkTurfVis(turf_check)) + call_bot(turf_check) + else + src << "Selected location is not visible." + +/mob/living/silicon/ai/proc/call_bot(var/turf/waypoint) + + if(!Bot) + return + + if(Bot.calling_ai && Bot.calling_ai != src) //Prevents an override if another AI is controlling this bot. + src << "Interface error. Unit is already in use." + return + + Bot.call_bot(src, waypoint) + /mob/living/silicon/ai/triggerAlarm(var/class, area/A, var/O, var/alarmsource) if (stat == 2) return 1 diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 042f0430361..9e0c0f08e7f 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -3,6 +3,7 @@ icon = 'icons/obj/status_display.dmi' //invisibility! mouse_opacity density = 0 + mob_size = 0 var/network = "SS13" var/obj/machinery/camera/current = null diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 290132a23d5..8b4076e265b 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1081,7 +1081,7 @@ new /obj/item/robot_parts/head(T) var/b for(b=0, b!=2, b++) - var/obj/item/device/flash/F = new /obj/item/device/flash(T) + var/obj/item/device/flash/handheld/F = new /obj/item/device/flash/handheld(T) F.burn_out() if (cell) //Sanity check. cell.loc = T diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm index 158d11795fb..fe89288765e 100644 --- a/code/modules/mob/living/silicon/robot/robot_movement.dm +++ b/code/modules/mob/living/silicon/robot/robot_movement.dm @@ -1,4 +1,4 @@ -/mob/living/silicon/robot/Process_Spacemove() +/mob/living/silicon/robot/Process_Spacemove(var/movement_dir = 0) if(module) for(var/obj/item/weapon/tank/jetpack/J in module.modules) if(J && istype(J, /obj/item/weapon/tank/jetpack)) diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index db36be554f2..4ff94d16b97 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -131,6 +131,7 @@ environment_smash = 2 attack_sound = 'sound/weapons/punch3.ogg' status_flags = 0 + mob_size = 2 force_threshold = 11 construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall) playstyle_string = "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, \ @@ -237,5 +238,5 @@ playstyle_string = "You are a Harvester. You are not strong, but your powers of domination will assist you in your role: \ Bring those who still cling to this world of illusion back to the Geometer so they may know Truth." -/mob/living/simple_animal/construct/harvester/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_animal/construct/harvester/Process_Spacemove(var/movement_dir = 0) return 1 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index bd6115a84e0..b449ffb30bf 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -77,3 +77,4 @@ icon_living = "kitten" icon_dead = "kitten_dead" gender = NEUTER + mob_size = 0 diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index ce2c5b8a562..68f68f57d4b 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -477,6 +477,7 @@ icon_state = "puppy" icon_living = "puppy" icon_dead = "puppy_dead" + mob_size = 0 //puppies cannot wear anything. /mob/living/simple_animal/corgi/puppy/Topic(href, href_list) diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm index 5cc28028e21..0ac3781a406 100644 --- a/code/modules/mob/living/simple_animal/friendly/crab.dm +++ b/code/modules/mob/living/simple_animal/friendly/crab.dm @@ -28,8 +28,10 @@ if(isturf(src.loc) && !resting && !buckled) //This is so it only moves if it's not inside a closet, gentics machine, etc. turns_since_move++ if(turns_since_move >= turns_per_move) - Move(get_step(src,pick(4,8))) - turns_since_move = 0 + var/east_vs_west = pick(4,8) + if(Process_Spacemove(east_vs_west)) + Move(get_step(src,east_vs_west), east_vs_west) + turns_since_move = 0 regenerate_icons() //COFFEE! SQUEEEEEEEEE! diff --git a/code/modules/mob/living/simple_animal/friendly/drone.dm b/code/modules/mob/living/simple_animal/friendly/drone.dm index a1ac622b9aa..7bbb99df1e9 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone.dm @@ -29,6 +29,7 @@ gender = NEUTER voice_name = "synthesized chirp" languages = DRONE + mob_size = 0 var/picked = FALSE var/list/drone_overlays[TOTAL_LAYERS] var/laws = \ @@ -94,6 +95,8 @@ health = health_repair_max stat = CONSCIOUS icon_state = icon_living + dead_mob_list -= src + living_mob_list += src D.visible_message("[D] reactivates [src]!") alert_drones(DRONE_NET_CONNECT) if(G) @@ -494,6 +497,10 @@ else mode() +/mob/living/simple_animal/drone/assess_threat() //Secbots won't hunt maintenance drones. + return -10 + + #undef HANDS_LAYER #undef HEAD_LAYER #undef TOTAL_LAYERS diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index f45daf9abd3..ebb220c9a72 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -57,7 +57,7 @@ var/step = get_step(src, direction) if(step) if(locate(/obj/effect/spacevine) in step) - Move(step) + Move(step, get_dir(src, step)) /mob/living/simple_animal/hostile/retaliate/goat/Retaliate() ..() @@ -168,6 +168,7 @@ ventcrawler = 2 var/amount_grown = 0 pass_flags = PASSTABLE | PASSGRILLE + mob_size = 0 /mob/living/simple_animal/chick/New() ..() diff --git a/code/modules/mob/living/simple_animal/friendly/lizard.dm b/code/modules/mob/living/simple_animal/friendly/lizard.dm index 5cfb67fa0e3..c9b23b18904 100644 --- a/code/modules/mob/living/simple_animal/friendly/lizard.dm +++ b/code/modules/mob/living/simple_animal/friendly/lizard.dm @@ -14,4 +14,5 @@ response_help = "pets" response_disarm = "shoos" response_harm = "stomps on" - ventcrawler = 2 \ No newline at end of file + ventcrawler = 2 + mob_size = 0 \ 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 fd288285169..ae67489e9e0 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -20,6 +20,8 @@ response_harm = "splats" density = 0 ventcrawler = 2 + pass_flags = PASSTABLE | PASSGRILLE + mob_size = 0 var/body_color //brown, gray and white, leave blank for random /mob/living/simple_animal/mouse/New() diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index 0f96399a3c9..e35eaa148dd 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -84,6 +84,7 @@ move_to_delay = 4 maxHealth = 400 health = 400 + mob_size = 2 /obj/item/projectile/neurotox name = "neurotoxin" diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index 7953f92cdae..748e216feed 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -54,7 +54,7 @@ else icon_state = "bearfloor" -/mob/living/simple_animal/hostile/bear/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_animal/hostile/bear/Process_Spacemove(var/movement_dir = 0) return 1 //No drifting in space for space bears! /mob/living/simple_animal/hostile/bear/FindTarget() diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index 24390b58870..a543b85b750 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -38,7 +38,7 @@ F faction = list("carp") -/mob/living/simple_animal/hostile/carp/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_animal/hostile/carp/Process_Spacemove(var/movement_dir = 0) return 1 //No drifting in space for space carp! //original comments do not steal /mob/living/simple_animal/hostile/carp/FindTarget() diff --git a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm new file mode 100644 index 00000000000..46f2e679e22 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm @@ -0,0 +1,34 @@ + + +/mob/living/simple_animal/hostile/carp/eyeball + name = "eyeball" + desc = "An odd looking creature, it won't stop staring..." + icon_state = "eyeball" + icon_living = "eyeball" + icon_dead = "" + icon_gib = "" + meat_type = null + meat_amount = 0 + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "hits" + maxHealth = 45 + health = 45 + + harm_intent_damage = 15 + melee_damage_lower = 20 + melee_damage_upper = 25 + attacktext = "blinks at" + attack_sound = 'sound/weapons/pierce.ogg' + + faction = list("spooky") + + +/mob/living/simple_animal/hostile/carp/eyeball/FindTarget() + . = ..() + if(.) + emote("me", 1, "glares at [.]") + +/mob/living/simple_animal/hostile/carp/eyeball/Die() + qdel(src) + return \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm index 5753a93cb96..b818475bb03 100644 --- a/code/modules/mob/living/simple_animal/hostile/faithless.dm +++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm @@ -31,7 +31,7 @@ faction = list("faithless") -/mob/living/simple_animal/hostile/faithless/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_animal/hostile/faithless/Process_Spacemove(var/movement_dir = 0) return 1 /mob/living/simple_animal/hostile/faithless/FindTarget() diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm index 5a36143768c..f4313a84f77 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm @@ -348,6 +348,7 @@ aggro_vision_range = 9 idle_vision_range = 5 anchored = 1 //Stays anchored until death as to be unpullable + mob_size = 2 /mob/living/simple_animal/hostile/asteroid/goliath/revive() anchored = 1 @@ -416,6 +417,7 @@ desc = "Pieces of a goliath's rocky hide, these might be able to make your suit a bit more durable to attack from the local fauna." icon = 'icons/obj/items.dmi' icon_state = "goliath_hide" + flags = NOBLUDGEON w_class = 3 layer = 4 @@ -423,11 +425,32 @@ if(proximity_flag) if(istype(target, /obj/item/clothing/suit/space/hardsuit/mining) || istype(target, /obj/item/clothing/head/helmet/space/hardsuit/mining)) var/obj/item/clothing/C = target - var/current_armor = C.armor + var/list/current_armor = C.armor if(current_armor.["melee"] < 80) current_armor.["melee"] = min(current_armor.["melee"] + 10, 80) user << "You strengthen [target], improving its resistance against melee attacks." qdel(src) else user << "You can't improve [C] any further." - return + return + if(istype(target, /obj/mecha/working/ripley)) + var/obj/mecha/D = target + var/list/damage_absorption = D.damage_absorption + if(damage_absorption.["brute"] > 0.3) + damage_absorption.["brute"] = max(damage_absorption.["brute"] - 0.1, 0.3) + user << "You strengthen [target], improving its resistance against melee attacks." + qdel(src) + if(D.icon_state == "ripley-open") + D.overlays += image("icon"="mecha.dmi", "icon_state"="ripley-g-open") + D.desc = "Autonomous Power Loader Unit. Its armour is enhanced with some goliath hide plates." + else + user << "You can't add armour onto the mech while someone is inside!" + if(damage_absorption.["brute"] == 0.3) + if(D.icon_state == "ripley-open") + D.overlays += image("icon"="mecha.dmi", "icon_state"="ripley-g-full-open") + D.desc = "Autonomous Power Loader Unit. It's wearing a fearsome carapace entirely composed of goliath hide plates - the pilot must be an experienced monster hunter." + else + user << "You can't add armour onto the mech while someone is inside!" + else + user << "You can't improve [D] any further." + return diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm index e3e2cd9b3d7..ea55fb94082 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm @@ -24,6 +24,7 @@ attack_sound = 'sound/weapons/bite.ogg' environment_smash = 0 ventcrawler = 2 + mob_size = 0 //Space bats need no air to fly in. diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 34feb25b086..de4d1fd2b3b 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -99,7 +99,7 @@ corpse = /obj/effect/landmark/mobcorpse/syndicatecommando speed = 1 -/mob/living/simple_animal/hostile/syndicate/melee/space/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_animal/hostile/syndicate/melee/space/Process_Spacemove(var/movement_dir = 0) return /mob/living/simple_animal/hostile/syndicate/ranged @@ -131,7 +131,7 @@ corpse = /obj/effect/landmark/mobcorpse/syndicatecommando speed = 1 -/mob/living/simple_animal/hostile/syndicate/ranged/space/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_animal/hostile/syndicate/ranged/space/Process_Spacemove(var/movement_dir = 0) return @@ -158,6 +158,7 @@ min_n2 = 0 max_n2 = 0 minbodytemp = 0 + mob_size = 0 /mob/living/simple_animal/hostile/viscerator/Die() ..() diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm index 7c20ba05a39..2feb135ecdc 100644 --- a/code/modules/mob/living/simple_animal/hostile/tree.dm +++ b/code/modules/mob/living/simple_animal/hostile/tree.dm @@ -14,6 +14,7 @@ speed = 1 maxHealth = 250 health = 250 + mob_size = 2 pixel_x = -16 diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 8b16e97ca9d..137c47efa8e 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -54,6 +54,7 @@ a_intent = "harm" //parrots now start "aggressive" since only player parrots will nuzzle. attacktext = "chomps" friendly = "grooms" + mob_size = 0 var/parrot_damage_upper = 10 var/parrot_state = PARROT_WANDER //Hunt for a perch when created diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 4de5f76c5e1..1b720f37540 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -115,8 +115,10 @@ turns_since_move++ if(turns_since_move >= turns_per_move) if(!(stop_automated_movement_when_pulled && pulledby)) //Soma animals don't move when pulled - Move(get_step(src,pick(cardinal))) - turns_since_move = 0 + var/anydir = pick(cardinal) + if(Process_Spacemove(anydir)) + Move(get_step(src, anydir), anydir) + turns_since_move = 0 //Speaking if(!client && speak_chance) @@ -429,6 +431,7 @@ if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch)) harvest() + user.changeNext_move(CLICK_CD_MELEE) var/damage = 0 if(O.force) if(O.force >= force_threshold) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index a8a5cb65d9b..9e989a38ae7 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -298,6 +298,34 @@ var/list/slot_equipment_priority = list( \ face_atom(A) A.examine(src) +//same as above +/mob/verb/pointed(atom/A as mob|obj|turf in view()) + set name = "Point To" + set category = "Object" + + if(!src || !isturf(src.loc)) + return + if(src.stat || src.restrained()) + return + if(src.status_flags & FAKEDEATH) + return + if(!(A in view(src.loc))) + return + if(istype(A, /obj/effect/decal/point)) + return + + var/tile = get_turf(A) + if (!tile) + return + + var/obj/P = new /obj/effect/decal/point(tile) + spawn (20) + if(P) + P.loc = null + + usr.visible_message("[src] points to [A]") + + /mob/verb/mode() set name = "Activate Held Object" set category = "Object" @@ -703,7 +731,6 @@ var/list/slot_equipment_priority = list( \ canmove = 1 if(buckled) lying = 90 * bed - anchored = buckled else if((ko || resting) && !lying) fall(ko) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index cd9d0a0f0e0..f13d82a7c8e 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -106,8 +106,6 @@ var/coughedtime = null - var/inertia_dir = 0 - var/music_lastplayed = "null" var/job = null//Living diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 66d7ea2edec..8b1abe2ca52 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -169,7 +169,7 @@ assailant.visible_message("[assailant] has tightened \his grip on [affecting]'s neck!") add_logs(assailant, affecting, "strangled") - assailant.changeNext_move(10) + assailant.changeNext_move(CLICK_CD_TKSTRANGLE) affecting.losebreath += 1 else if(assailant) @@ -218,4 +218,4 @@ qdel(src) #undef UPGRADE_COOLDOWN -#undef UPGRADE_KILL_TIMER \ No newline at end of file +#undef UPGRADE_KILL_TIMER diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 42b25fe0a5f..e0f206cc726 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -1,5 +1,5 @@ -/mob/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 +/mob/CanPass(atom/movable/mover, turf/target, height=0) + if(height==0) return 1 if(istype(mover) && mover.checkpass(PASSMOB)) return 1 @@ -86,42 +86,6 @@ return -/atom/movable/Move(NewLoc, direct) - if (direct & (direct - 1)) - if (direct & 1) - if (direct & 4) - if (step(src, NORTH)) - step(src, EAST) - else - if (step(src, EAST)) - step(src, NORTH) - else - if (direct & 8) - if (step(src, NORTH)) - step(src, WEST) - else - if (step(src, WEST)) - step(src, NORTH) - else - if (direct & 2) - if (direct & 4) - if (step(src, SOUTH)) - step(src, EAST) - else - if (step(src, EAST)) - step(src, SOUTH) - else - if (direct & 8) - if (step(src, SOUTH)) - step(src, WEST) - else - if (step(src, WEST)) - step(src, SOUTH) - else - . = ..() - return - - /client/proc/Move_object(direct) if(mob && mob.control_object) if(mob.control_object.density) @@ -167,15 +131,14 @@ if(!mob.lastarea) mob.lastarea = get_area(mob.loc) - if(!has_gravity(mob)) - if(!mob.Process_Spacemove(0)) - return 0 - if(isobj(mob.loc) || ismob(mob.loc)) //Inside an object, tell it we moved var/atom/O = mob.loc return O.relaymove(mob, direct) + if(!mob.Process_Spacemove(direct)) + return 0 + if(isturf(mob.loc)) if(mob.restrained()) //Why being pulled while cuffed prevents you from moving @@ -244,6 +207,8 @@ . = ..() moving = 0 + if(mob && .) + mob.throwing = 0 return . @@ -342,51 +307,46 @@ ///Called by /client/Move() ///For moving in space ///Return 1 for movement 0 for none -/mob/proc/Process_Spacemove(var/check_drift = 0) - //First check to see if we can do things - if(!canmove) - return 0 +/mob/Process_Spacemove(var/movement_dir = 0) - if(!isturf(loc)) //if they're in a disposal unit, for example + if(..()) return 1 - var/dense_object = 0 - for(var/turf/turf in oview(1,src)) - if(istype(turf,/turf/space)) + var/atom/movable/dense_object_backup + for(var/atom/A in orange(1, get_turf(src))) + if(isarea(A)) continue - if(!turf.density && !mob_negates_gravity()) - continue + else if(isturf(A)) + var/turf/turf = A + if(istype(turf,/turf/space)) + continue - dense_object++ - break + if(!turf.density && !mob_negates_gravity()) + continue - if(!dense_object && (locate(/obj/structure/lattice) in oview(1, src))) - dense_object++ + return 1 - //Lastly attempt to locate any dense objects we could push off of - //TODO: If we implement objects drifing in space this needs to really push them - //Due to a few issues only anchored and dense objects will now work. - if(!dense_object) - for(var/obj/O in oview(1, src)) - if((O) && (O.density) && (O.anchored)) - dense_object++ - break + else + var/atom/movable/AM = A + if(AM == buckled) //Kind of unnecessary but let's just be sure + continue + if(AM.density) + if(AM.anchored) + if(istype(AM, /obj/item/projectile)) //"You grab the bullet and push off of it!" No + continue + return 1 + if(pulling == AM) + continue + dense_object_backup = AM - //Nothing to push off of so end here - if(!dense_object) - return 0 + if(movement_dir && dense_object_backup) + if(dense_object_backup.newtonian_move(turn(movement_dir, 180))) //You're pushing off something movable, so it moves + src << "You push off of [dense_object_backup] to propel yourself." - //Check to see if we slipped - if(prob(Process_Spaceslipping(5))) - src << "You slipped!" - src.inertia_dir = src.last_move - step(src, src.inertia_dir) - return 0 - //If not then we can reset inertia and move - inertia_dir = 0 - return 1 + return 1 + return 0 /mob/proc/mob_has_gravity(turf/T) return has_gravity(src, T) @@ -394,15 +354,6 @@ /mob/proc/mob_negates_gravity() return 0 -/mob/proc/Process_Spaceslipping(var/prob_slip = 5) - //Setup slipage - //If knocked out we might just hit it and stop. This makes it possible to get dead bodies and such. - if(stat) - prob_slip = 0 // Changing this to zero to make it line up with the comment. - - prob_slip = round(prob_slip) - return(prob_slip) - /mob/proc/Move_Pulled(var/atom/A) if (!canmove || restrained() || !pulling) return @@ -410,6 +361,10 @@ return if (!pulling.Adjacent(src)) return + if (A == loc && pulling.density) + return + if (!Process_Spacemove(get_dir(pulling.loc, A))) + return if (ismob(pulling)) var/mob/M = pulling var/atom/movable/t = M.pulling diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index b064a960cb4..6c69df11a4b 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -66,7 +66,7 @@ if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) else if(backbag == 3) - clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-norm"), ICON_OVERLAY) else if(job_civilian_high)//I hate how this looks, but there's no reason to go through this switch if it's empty switch(job_civilian_high) @@ -94,11 +94,12 @@ if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) else if(backbag == 3) - clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-hyd"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-norm"), ICON_OVERLAY) if(CHEF) clothes_s = new /icon('icons/mob/uniform.dmi', "chef_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) clothes_s.Blend(new /icon('icons/mob/head.dmi', "chef"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/suit.dmi', "chef"), ICON_OVERLAY) if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) if(backbag == 3) @@ -120,17 +121,15 @@ if(QUARTERMASTER) clothes_s = new /icon('icons/mob/uniform.dmi', "qm_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/hands.dmi', "bgloves"), ICON_UNDERLAY) clothes_s.Blend(new /icon('icons/mob/eyes.dmi', "sun"), ICON_OVERLAY) - clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "clipboard"), ICON_UNDERLAY) + clothes_s.Blend(new /icon('icons/mob/items_lefthand.dmi', "clipboard"), ICON_OVERLAY) if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) if(backbag == 3) clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-norm"), ICON_OVERLAY) if(CARGOTECH) - clothes_s = new /icon('icons/mob/uniform.dmi', "cargotech_s") + clothes_s = new /icon('icons/mob/uniform.dmi', "cargo_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/hands.dmi', "bgloves"), ICON_UNDERLAY) if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) if(backbag == 3) @@ -138,15 +137,15 @@ if(MINER) clothes_s = new /icon('icons/mob/uniform.dmi', "miner_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/hands.dmi', "bgloves"), ICON_UNDERLAY) if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "engiepack"), ICON_OVERLAY) if(backbag == 3) clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-eng"), ICON_OVERLAY) if(LAWYER) - clothes_s = new /icon('icons/mob/uniform.dmi', "lawyer_blue_s") + clothes_s = new /icon('icons/mob/uniform.dmi', "bluesuit_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "briefcase"), ICON_UNDERLAY) + clothes_s.Blend(new /icon('icons/mob/suit.dmi', "suitjacket_blue_open"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/items_lefthand.dmi', "briefcase"), ICON_OVERLAY) if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) if(backbag == 3) @@ -154,6 +153,7 @@ if(CHAPLAIN) clothes_s = new /icon('icons/mob/uniform.dmi', "chapblack_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) + clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "bible"), ICON_OVERLAY) if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) if(backbag == 3) @@ -180,12 +180,12 @@ if(RD) clothes_s = new /icon('icons/mob/uniform.dmi', "director_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "clipboard"), ICON_UNDERLAY) clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/items_lefthand.dmi', "clipboard"), ICON_OVERLAY) if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) if(backbag == 3) - clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-tox"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-norm"), ICON_OVERLAY) if(SCIENTIST) clothes_s = new /icon('icons/mob/uniform.dmi', "toxinswhite_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY) @@ -193,7 +193,7 @@ if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) if(backbag == 3) - clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-tox"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-norm"), ICON_OVERLAY) if(CHEMIST) clothes_s = new /icon('icons/mob/uniform.dmi', "chemistrywhite_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY) @@ -201,12 +201,12 @@ if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) if(backbag == 3) - clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-chem"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-norm"), ICON_OVERLAY) if(CMO) clothes_s = new /icon('icons/mob/uniform.dmi', "cmo_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/items_lefthand.dmi', "firstaid"), ICON_UNDERLAY) clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_cmo_open"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/items_lefthand.dmi', "firstaid"), ICON_OVERLAY) if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "medicalpack"), ICON_OVERLAY) if(backbag == 3) @@ -214,8 +214,8 @@ if(DOCTOR) clothes_s = new /icon('icons/mob/uniform.dmi', "medical_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/items_lefthand.dmi', "firstaid"), ICON_UNDERLAY) clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/items_lefthand.dmi', "firstaid"), ICON_OVERLAY) if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "medicalpack"), ICON_OVERLAY) if(backbag == 3) @@ -227,7 +227,7 @@ if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) if(backbag == 3) - clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-gen"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-norm"), ICON_OVERLAY) if(VIROLOGIST) clothes_s = new /icon('icons/mob/uniform.dmi', "virologywhite_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY) @@ -236,13 +236,12 @@ if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "medicalpack"), ICON_OVERLAY) if(backbag == 3) - clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-vir"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-med"), ICON_OVERLAY) if(ROBOTICIST) clothes_s = new /icon('icons/mob/uniform.dmi', "robotics_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/hands.dmi', "bgloves"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "toolbox_blue"), ICON_OVERLAY) clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/items_lefthand.dmi', "toolbox_blue"), ICON_OVERLAY) if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) if(backbag == 3) @@ -257,9 +256,9 @@ clothes_s.Blend(new /icon('icons/mob/eyes.dmi', "sun"), ICON_OVERLAY) clothes_s.Blend(new /icon('icons/mob/suit.dmi', "capcarapace"), ICON_OVERLAY) if(backbag == 2) - clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/back.dmi', "captainpack"), ICON_OVERLAY) if(backbag == 3) - clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-norm"), ICON_OVERLAY) + clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-cap"), ICON_OVERLAY) if(HOS) clothes_s = new /icon('icons/mob/uniform.dmi', "hosred_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "jackboots"), ICON_UNDERLAY) @@ -325,26 +324,11 @@ if(ATMOSTECH) clothes_s = new /icon('icons/mob/uniform.dmi', "atmos_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/hands.dmi', "bgloves"), ICON_UNDERLAY) clothes_s.Blend(new /icon('icons/mob/belt.dmi', "utility"), ICON_OVERLAY) if(backbag == 2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) - if(backbag == 3) + else if(backbag == 3) clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-norm"), ICON_OVERLAY) - if(AI)//Gives AI and borgs assistant-wear, so they can still customize their character - clothes_s = new /icon('icons/mob/uniform.dmi', "grey_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - if(backbag == 2) - clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) - else if(backbag == 3) - clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel"), ICON_OVERLAY) - if(CYBORG) - clothes_s = new /icon('icons/mob/uniform.dmi', "grey_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - if(backbag == 2) - clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) - else if(backbag == 3) - clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel"), ICON_OVERLAY) preview_icon.Blend(eyes_s, ICON_OVERLAY) if(clothes_s) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 0482bee113c..d11418c2cf3 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -14,7 +14,7 @@ w_class = 1.0 throw_range = 1 throw_speed = 1 - layer = 4 + layer = 3 pressure_resistance = 1 slot_flags = SLOT_HEAD body_parts_covered = HEAD @@ -272,8 +272,12 @@ clown = 1 if(istype(P, /obj/item/weapon/pen) || istype(P, /obj/item/toy/crayon)) - user << browse("[name][info_links]
    [stamps]", "window=[name]") - return + if(user.IsAdvancedToolUser()) + user << browse("[name][info_links]
    [stamps]", "window=[name]") + return + else + user << "You don't know how to read or write." + return else if(istype(P, /obj/item/weapon/stamp)) if(!in_range(src, usr) && loc != user && !istype(loc, /obj/item/weapon/clipboard) && loc.loc != user && user.get_active_hand() != P) diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 0c1045050c8..c3482e4c7e0 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -123,8 +123,9 @@ var/icon/temp_img if(ishuman(ass) && (ass.get_item_by_slot(slot_w_uniform) || ass.get_item_by_slot(slot_wear_suit))) usr << "You feel kind of silly copying [ass == usr ? "your" : ass][ass == usr ? "" : "\'s"] ass with [ass == usr ? "your" : "their"] clothes on." + break else if(toner >= 5 && !busy && check_ass()) //You have to be sitting on the copier and either be a xeno or a human without clothes on. - if(isalien(ass) || istype(ass,/mob/living/simple_animal/hostile/alien)) //Xenos have their own asses, thanks to Pybro. + if(isalienadult(ass) || istype(ass,/mob/living/simple_animal/hostile/alien)) //Xenos have their own asses, thanks to Pybro. temp_img = icon("icons/ass/assalien.png") else if(ishuman(ass)) //Suit checks are in check_ass if(ass.gender == MALE) diff --git a/code/modules/power/antimatter/shielding.dm b/code/modules/power/antimatter/shielding.dm index 33df680089e..2a852ee8205 100644 --- a/code/modules/power/antimatter/shielding.dm +++ b/code/modules/power/antimatter/shielding.dm @@ -71,8 +71,8 @@ proc/cardinalrange(var/center) ..() -/obj/machinery/am_shielding/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 +/obj/machinery/am_shielding/CanPass(atom/movable/mover, turf/target, height=0) + if(height==0) return 1 return 0 diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm index 4158e2e1fec..7a7e4bbd7c5 100644 --- a/code/modules/power/singularity/containment_field.dm +++ b/code/modules/power/singularity/containment_field.dm @@ -60,7 +60,7 @@ /obj/machinery/field var/hasShocked = 0 //Used to add a delay between shocks. In some cases this used to crash servers by spawning hundreds of sparks every second. -/obj/machinery/field/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/obj/machinery/field/CanPass(atom/movable/mover, turf/target, height=0) if(isliving(mover)) // Don't let mobs through shock(mover) return 0 diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 68fe80c0780..9253dfde465 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -10,7 +10,7 @@ move_self = 1 //Do we move on our own? grav_pull = 5 //How many tiles out do we pull? consume_range = 6 //How many tiles out do we eat - uneatable = list(/turf/space, /obj/effect/overlay, /mob/living/simple_animal/construct) + var/uneatable = list(/turf/space, /obj/effect/overlay, /mob/living/simple_animal/construct) /obj/machinery/singularity/narsie/large name = "Nar-Sie" @@ -40,6 +40,9 @@ /obj/machinery/singularity/narsie/large/attack_ghost(mob/dead/observer/user as mob) + if(!(src in view())) + user << "Your soul is too far away." + return makeNewConstruct(/mob/living/simple_animal/construct/harvester, user, null, 1) new /obj/effect/effect/sleep_smoke(user.loc) diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 770cd676ed8..1e810d75970 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -25,9 +25,7 @@ var/event_chance = 15 //Prob for event each tick var/target = null //its target. moves towards the target if it has one var/last_failed_movement = 0//Will not move in the same dir if it couldnt before, will help with the getting stuck on fields thing - var/teleport_del = 0 var/last_warning - var/list/uneatable = list(/turf/space, /obj/effect/overlay) /obj/machinery/singularity/New(loc, var/starting_energy = 50, var/temp = 0) //CARN: admin-alert for chuckle-fuckery. @@ -42,6 +40,15 @@ return +/obj/machinery/singularity/Move(atom/newloc, direct) + if(current_size >= 9 || check_turfs_in(direct)) + last_failed_movement = 0//Reset this because we moved + return ..() + else + last_failed_movement = direct + return 0 + + /obj/machinery/singularity/attack_hand(mob/user as mob) consume(user) return 1 @@ -212,7 +219,6 @@ var/dist = get_dist(X, src) // Movable atoms only if(dist > consume_range && istype(X, /atom/movable)) - if(is_type_in_list(X, uneatable)) continue if(((X) &&(!X:anchored) && (!istype(X,/mob/living/carbon/human)))|| (src.current_size >= 9)) step_towards(X,src) @@ -244,60 +250,7 @@ /obj/machinery/singularity/proc/consume(var/atom/A) - var/gain = 0 - if(is_type_in_list(A, uneatable)) - return 0 - if (istype(A,/mob/living))//Mobs get gibbed - var/mob/living/M = A - gain = 20 - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(H.mind) - - if((H.mind.assigned_role == "Station Engineer") || (H.mind.assigned_role == "Chief Engineer") ) - gain = 100 - - if(H.mind.assigned_role == "Clown") - gain = rand(-300, 300) // HONK - - investigate_log(" has consumed [key_name(M)].","singulo") //Oh that's where the clown ended up! - M.gib() - sleep(1) - else if(istype(A,/obj/)) - - if (istype(A,/obj/item/weapon/storage/backpack/holding)) - var/dist = max((current_size - 2),1) - explosion(src.loc,(dist),(dist*2),(dist*4)) - return - - if(istype(A, /obj/machinery/singularity))//Welp now you did it - var/obj/machinery/singularity/S = A - src.energy += (S.energy/2)//Absorb most of it - qdel(S) - var/dist = max((current_size - 2),1) - explosion(src.loc,(dist),(dist*2),(dist*4)) - return//Quits here, the obj should be gone, hell we might be - - if((teleport_del) && (!istype(A, /obj/machinery)))//Going to see if it does not lag less to tele items over to Z 2 - var/obj/O = A - O.x = 2 - O.y = 2 - O.z = 2 - else - A.ex_act(1.0) - if(A && isnull(A.gc_destroyed)) - qdel(A) - gain = 2 - else if(isturf(A)) - var/turf/T = A - if(T.intact) - for(var/obj/O in T.contents) - if(O.level != 1) - continue - if(O.invisibility == 101) - src.consume(O) - T.ChangeTurf(/turf/space) - gain = 2 + var/gain = A.singularity_act(current_size) src.energy += gain return @@ -314,20 +267,7 @@ if(target && prob(60)) movement_dir = get_dir(src,target) //moves to a singulo beacon, if there is one - if(current_size >= 9)//The superlarge one does not care about things in its way - spawn(0) - step(src, movement_dir) - spawn(1) - step(src, movement_dir) - return 1 - else if(check_turfs_in(movement_dir)) - last_failed_movement = 0//Reset this because we moved - spawn(0) - step(src, movement_dir) - return 1 - else - last_failed_movement = movement_dir - return 0 + step(src, movement_dir) /obj/machinery/singularity/proc/check_turfs_in(var/direction = 0, var/step = 0) @@ -438,12 +378,11 @@ if (istype(M,/mob/living/carbon/human)) var/mob/living/carbon/human/H = M if(istype(H.glasses,/obj/item/clothing/glasses/meson)) - H << "You look directly into The [src.name], good thing you had your protective eyewear on!" + H << "You look directly into the [src.name], good thing you had your protective eyewear on!" return - M << "You look directly into The [src.name] and feel weak." M.apply_effect(3, STUN) - for(var/mob/O in viewers(M, null)) - O.show_message(text("[] stares blankly at The []!", M, src), 1) + M.visible_message("[M] stares blankly at the [src.name]!", \ + "You look directly into the [src.name] and feel weak.") return @@ -457,4 +396,11 @@ for(var/obj/machinery/power/rad_collector/R in rad_collectors) if(get_dist(R, src) <= 15) // Better than using orange() every process R.receive_pulse(energy) - return \ No newline at end of file + return + +/obj/machinery/singularity/singularity_act() + var/gain = (energy/2) + var/dist = max((current_size - 2),1) + explosion(src.loc,(dist),(dist*2),(dist*4)) + qdel(src) + return(gain) diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index cf1d7517db1..ea569bfd9c2 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -95,7 +95,7 @@ // Crucial to make things work!!!! // OLD FIX - explanation given down below. -// /obj/machinery/power/compressor/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +// /obj/machinery/power/compressor/CanPass(atom/movable/mover, turf/target, height=0) // return !density /obj/machinery/power/compressor/RefreshParts() @@ -209,7 +209,7 @@ // OLD FIX . Dunno how other engines handle this but this is how it should work: Turbine and compressor should be // treated as walls to avoid conductivity and gas spread. This was the problem of the original turbine which was just // a machinery - it didn't block the gas passage. -// /obj/machinery/power/turbine/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +// /obj/machinery/power/turbine/CanPass(atom/movable/mover, turf/target, height=0) // return !density /obj/machinery/power/turbine/RefreshParts() diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index dbde10cfe56..a07e745b516 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -70,6 +70,16 @@ m_amt = 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 + m_amt = 250 + pellets = 5 + variance = 0.8 + + /obj/item/ammo_casing/shotgun/stunslug name = "taser slug" desc = "A stunning taser slug." diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 4ea3e418f69..3f05446bf84 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -59,6 +59,22 @@ max_ammo = 2 multiload = 0 +/obj/item/ammo_box/magazine/internal/cylinder/improvised + name = "improvised shotgun internal magazine" + desc = "This doesn't even exist" + ammo_type = /obj/item/ammo_casing/shotgun/improvised + caliber = "shotgun" + max_ammo = 1 + multiload = 0 + +/obj/item/ammo_box/magazine/internal/shotriot + name = "riot shotgun internal magazine" + desc = "Oh god, this shouldn't be here" + ammo_type = /obj/item/ammo_casing/shotgun/beanbag + caliber = "shotgun" + max_ammo = 6 + multiload = 0 + ///////////EXTERNAL MAGAZINES//////////////// /obj/item/ammo_box/magazine/m9mm name = "handgun magazine (9mm)" diff --git a/code/modules/projectiles/firing.dm b/code/modules/projectiles/firing.dm index 652aaf954f6..e99ce0b32eb 100644 --- a/code/modules/projectiles/firing.dm +++ b/code/modules/projectiles/firing.dm @@ -11,6 +11,7 @@ if(i > 1) newshot() user.changeNext_move(CLICK_CD_RANGE) + user.newtonian_move(get_dir(target, user)) update_icon() return 1 diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 4caf9eb7aa7..2b96a86960e 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -21,6 +21,7 @@ var/clumsy_check = 1 var/obj/item/ammo_casing/chambered = null var/trigger_guard = 1 + var/sawn_desc = null /obj/item/weapon/gun/proc/process_chamber() return 0 diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index f1ee2f12a74..08351551243 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -68,6 +68,8 @@ var/ratio = power_supply.charge / power_supply.maxcharge ratio = Ceiling(ratio*4) * 25 var/obj/item/ammo_casing/energy/shot = ammo_type[select] + if(power_supply.charge < shot.e_cost) + ratio = 0 //so the icon changes to empty if the charge isn't zero but not enough for a shot. switch(modifystate) if (0) icon_state = "[initial(icon_state)][ratio]" diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 019396875d7..0d7d5122307 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -60,6 +60,18 @@ mag_type = /obj/item/ammo_box/magazine/internal/shotcom w_class = 5 +/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 + 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) + ..() + if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter)) + sawoff(user) + /obj/item/weapon/gun/projectile/revolver/doublebarrel name = "double-barreled shotgun" desc = "A true classic." @@ -71,28 +83,32 @@ 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) ..() - if (istype(A,/obj/item/ammo_box) || istype(A,/obj/item/ammo_casing)) + 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/pickaxe/plasmacutter)) - user << "You begin to shorten the barrel of \the [src]." - if(get_ammo()) - afterattack(user, user) //will this work? - afterattack(user, user) //it will. we call it twice, for twice the FUN - playsound(user, fire_sound, 50, 1) - user.visible_message("The shotgun goes off!", "The shotgun goes off in your face!") - return - if(do_after(user, 30)) //SHIT IS STEALTHY EYYYYY - icon_state = "sawnshotgun" - 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) - user << "You shorten the barrel of \the [src]!" - name = "sawn-off shotgun" - desc = "Omar's coming!" + sawoff(user) + +/obj/item/weapon/gun/projectile/proc/sawoff(mob/user as mob) + user << "You begin to shorten \the [src]." + if(get_ammo()) + afterattack(user, user) + user.visible_message("The [src] goes off!", "The [src] goes off in your face!") + return + if(do_after(user, 30)) + name = "sawn-off [src.name]" + desc = sawn_desc + icon_state = initial(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) + user << "You shorten \the [src]!" + update_icon() + return /obj/item/weapon/gun/projectile/revolver/doublebarrel/attack_self(mob/living/user as mob) var/num_unloaded = 0 @@ -107,3 +123,31 @@ user << "You break open \the [src] and unload [num_unloaded] shell\s." else user << "[src] is empty." + + +// 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 + 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) + ..() + if(istype(A, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = A + if(C.use(10)) + flags = CONDUCT + slot_flags = SLOT_BACK + icon_state = "ishotgunsling" + user << "You tie the lengths of cable to the shotgun, making a sling." + update_icon() + else + user << "You need at least ten lengths of cable if you want to make a sling." + return diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index e5213d7c967..69f63100241 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -129,14 +129,17 @@ return 1 -/obj/item/projectile/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 +/obj/item/projectile/CanPass(atom/movable/mover, turf/target, height=0) + if(height==0) return 1 if(istype(mover, /obj/item/projectile)) return prob(95) else return 1 +/obj/item/projectile/Process_Spacemove(var/movement_dir = 0) + return 1 //Bullets don't drift in space + /obj/item/projectile/process() if(kill_count < 1) diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index f56e641c8e2..9769a10dad7 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -23,6 +23,8 @@ name = "pellet" damage = 15 +/obj/item/projectile/bullet/pellet/weak + damage = 3 /obj/item/projectile/bullet/midbullet damage = 20 diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index 2973bfcc363..f2fbbce3172 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -708,7 +708,7 @@ obj/machinery/computer/pandemic/proc/replicator_cooldown(var/waittime) if(!R.total_volume||!R.reagent_list.len) dat += "The beaker is empty
    " else if(!Blood) - dat += "No blood sample found in beaker" + dat += "No blood sample found in beaker." else if(!Blood.data) dat += "No blood data found in beaker." else @@ -749,6 +749,10 @@ obj/machinery/computer/pandemic/proc/replicator_cooldown(var/waittime) english_symptoms += S.name dat += english_list(english_symptoms) + else + dat += "No detectable virus in the sample." + else + dat += "No detectable virus in the sample." dat += "
    Contains antibodies to: " if(Blood.data["resistances"]) diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index b5fcb1ae5c2..60fb6d1f946 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -68,6 +68,7 @@ amount_per_transfer_from_this = 10 volume = 10 ignore_flags = 1 //so you can medipen through hardsuits + flags = null /obj/item/weapon/reagent_containers/hypospray/medipen/New() ..() @@ -75,10 +76,9 @@ update_icon() return + /obj/item/weapon/reagent_containers/hypospray/medipen/attack(mob/M as mob, mob/user as mob) ..() - if(reagents.total_volume <= 0) //Prevents medipens from being refilled. - flags &= ~OPENCONTAINER update_icon() return diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 87b82950be1..ddfb006ba68 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -58,6 +58,7 @@ playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6) user.changeNext_move(CLICK_CD_RANGE) + user.newtonian_move(get_dir(A, user)) if(reagents.has_reagent("sacid")) message_admins("[key_name_admin(user)] fired sulphuric acid from \a [src].") diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index e33b55290ec..e610c07f1ac 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -438,19 +438,19 @@ H.vent_gas(loc) qdel(H) -/obj/machinery/disposal/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/obj/machinery/disposal/CanPass(atom/movable/mover, turf/target, height=0) if (istype(mover,/obj/item) && mover.throwing) var/obj/item/I = mover if(istype(I, /obj/item/projectile)) return if(prob(75)) I.loc = src - visible_message("\the [I] lands in \the [src].") + visible_message("\the [I] lands in \the [src].") else - visible_message("\the [I] bounces off of \the [src]'s rim!") + visible_message("\the [I] bounces off of \the [src]'s rim!") return 0 else - return ..(mover, target, height, air_group) + return ..(mover, target, height) // virtual disposal object // travels through pipes in lieu of actual items @@ -692,12 +692,10 @@ var/turf/target - if(istype(T, /turf/simulated/floor)) //intact floor, pop the tile - var/turf/simulated/floor/F = T - if(F.floor_tile) - F.floor_tile.loc = H //It took me a day to figure out this was the right way to do it. - F.floor_tile = null //So it doesn't get deleted in make_plating() - F.make_plating() + if(istype(T, /turf/simulated/floor) && !istype(T, /turf/simulated/floor/plating)) //intact floor, pop the tile + var/turf/simulated/floor/myturf = T + new myturf.floor_tile(T) + myturf.make_plating() if(direction) // direction is specified if(istype(T, /turf/space)) // if ended in space, then range is unlimited diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 38ad69d80a1..3f8c1819d04 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -6,6 +6,7 @@ density = 1 mouse_drag_pointer = MOUSE_ACTIVE_POINTER var/obj/wrapped = null + var/giftwrapped = 0 var/sortTag = 0 @@ -41,12 +42,19 @@ user.visible_message("[user] labels [src] as [str].") name = "[name] ([str])" - else if(istype(W, /obj/item/weapon/wrapping_paper)) - user.visible_message("[user] wraps the package in festive paper!") - if(istype(wrapped, /obj/structure/closet/crate)) - icon_state = "giftcrate" + else if(istype(W, /obj/item/stack/wrapping_paper) && !giftwrapped) + var/obj/item/stack/wrapping_paper/WP = W + if(WP.use(3)) + user.visible_message("[user] wraps the package in festive paper!") + giftwrapped = 1 + if(istype(wrapped, /obj/structure/closet/crate)) + icon_state = "giftcrate" + else + icon_state = "giftcloset" + if(WP.amount <= 0 && !WP.loc) //if we used our last wrapping paper, drop a cardboard tube + new /obj/item/weapon/c_tube( get_turf(user) ) else - icon_state = "giftcloset" + user << "You need more paper." /obj/item/smallDelivery @@ -55,11 +63,12 @@ icon = 'icons/obj/storage.dmi' icon_state = "deliverycrateSmall" var/obj/item/wrapped = null + var/giftwrapped = 0 var/sortTag = 0 /obj/item/smallDelivery/attack_self(mob/user as mob) - if(wrapped) //sometimes items can disappear. For example, bombs. --rastaf0 + if(wrapped && wrapped.loc) //sometimes items can disappear. For example, bombs. --rastaf0 wrapped.loc = user.loc if(ishuman(user)) user.put_in_hands(wrapped) @@ -87,21 +96,29 @@ user.visible_message("[user] labels [src] as [str].") name = "[name] ([str])" - else if(istype(W, /obj/item/weapon/wrapping_paper)) - icon_state = "giftcrate[wrapped.w_class]" - user.visible_message("[user] wraps the package in festive paper!") + else if(istype(W, /obj/item/stack/wrapping_paper) && !giftwrapped) + var/obj/item/stack/wrapping_paper/WP = W + if(WP.use(1)) + icon_state = "giftcrate[wrapped.w_class]" + giftwrapped = 1 + user.visible_message("[user] wraps the package in festive paper!") + if(WP.amount <= 0 && !WP.loc) //if we used our last wrapping paper, drop a cardboard tube + new /obj/item/weapon/c_tube( get_turf(user) ) + else + user << "You need more paper." -/obj/item/weapon/packageWrap + +/obj/item/stack/packageWrap name = "package wrapper" icon = 'icons/obj/items.dmi' icon_state = "deliveryPaper" flags = NOBLUDGEON - w_class = 3.0 - var/amount = 25.0 + amount = 25 + max_amount = 25 -/obj/item/weapon/packageWrap/afterattack(var/obj/target as obj, mob/user as mob, proximity) +/obj/item/stack/packageWrap/afterattack(var/obj/target as obj, mob/user as mob, proximity) if(!proximity) return if(!istype(target)) //this really shouldn't be necessary (but it is). -Pete return @@ -113,11 +130,11 @@ if(target in user) return - user.attack_log += text("\[[time_stamp()]\] Has used [name] on \ref[target]") + if(istype(target, /obj/item) && !(istype(target, /obj/item/weapon/storage) && !istype(target,/obj/item/weapon/storage/box))) var/obj/item/O = target - if(amount > 1) + if(use(1)) var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(get_turf(O.loc)) //Aaannd wrap it up! if(!istype(O.loc, /turf)) if(user.client) @@ -131,41 +148,44 @@ P.add_fingerprint(usr) O.add_fingerprint(usr) add_fingerprint(usr) - amount -= 1 + else + return else if(istype(target, /obj/structure/closet/crate)) var/obj/structure/closet/crate/O = target - if(amount > 3 && !O.opened) + if(O.opened) + return + if(use(3)) var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) P.icon_state = "deliverycrate" P.wrapped = O O.loc = P - amount -= 3 - else if(amount < 3) + else user << "You need more paper." + return else if(istype (target, /obj/structure/closet)) var/obj/structure/closet/O = target - if(amount > 3 && !O.opened) + if(O.opened) + return + if(use(3)) var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) P.wrapped = O O.welded = 1 O.loc = P - amount -= 3 - else if(amount < 3) + else user << "You need more paper." + return else user << "The object you are trying to wrap is unsuitable for the sorting machinery." - if(amount <= 0) - new /obj/item/weapon/c_tube( loc ) - qdel(src) return + + user.visible_message("[user] wraps [target].") + user.attack_log += text("\[[time_stamp()]\] Has used [name] on [target]") + + if(amount <= 0 && !src.loc) //if we used our last wrapping paper, drop a cardboard tube + new /obj/item/weapon/c_tube( get_turf(user) ) return -/obj/item/weapon/packageWrap/examine(mob/user) - ..() - user << "There are [amount] units of package wrap left." - - /obj/item/device/destTagger name = "destination tagger" desc = "Used to set the destination of properly wrapped packages." diff --git a/code/modules/research/designs/mecha_designs.dm b/code/modules/research/designs/mecha_designs.dm index f50c4b9b256..82a242fa775 100644 --- a/code/modules/research/designs/mecha_designs.dm +++ b/code/modules/research/designs/mecha_designs.dm @@ -119,6 +119,33 @@ datum/design/honker_targ materials = list("$glass" = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/honker/targeting +datum/design/phazon_main + name = "Exosuit Design (\"Phazon\" Central Control module)" + desc = "Allows for the construction of a \"Phazon\" Central Control module." + id = "phazon_main" + req_tech = list("programming" = 5, "materials" = 7, "powerstorage" = 6) + build_type = IMPRINTER + materials = list("$glass" = 1000, "sacid" = 20) + build_path = /obj/item/weapon/circuitboard/mecha/phazon/main + +datum/design/phazon_peri + name = "Exosuit Design (\"Phazon\" Peripherals Control module)" + desc = "Allows for the construction of a \"Phazon\" Peripheral Control module." + id = "phazon_peri" + req_tech = list("programming" = 5, "bluespace" = 6) + build_type = IMPRINTER + materials = list("$glass" = 1000, "sacid" = 20) + build_path = /obj/item/weapon/circuitboard/mecha/phazon/peripherals + +datum/design/phazon_targ + name = "Exosuit Design (\"Phazon\" Weapons & Targeting Control module)" + desc = "Allows for the construction of a \"Phazon\" Weapons & Targeting Control module." + id = "phazon_targ" + req_tech = list("programming" = 5, "magnets" = 6) + build_type = IMPRINTER + materials = list("$glass" = 1000, "sacid" = 20) + build_path = /obj/item/weapon/circuitboard/mecha/phazon/targeting + //////////////////////////////////////// /////////// Mecha Equpment ///////////// //////////////////////////////////////// diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index c2e2ebf5e6a..df2779e3118 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -52,7 +52,7 @@ datum/design/synthetic_flash build_type = MECHFAB materials = list("$metal" = 750, "$glass" = 750) reliability = 76 - build_path = /obj/item/device/flash/ + build_path = /obj/item/device/flash/handheld category = "Misc" datum/design/bluespacebeaker @@ -75,4 +75,15 @@ datum/design/noreactbeaker materials = list("$metal" = 3000) reliability = 76 build_path = /obj/item/weapon/reagent_containers/glass/beaker/noreact + category = "Misc" + +datum/design/bluespacebodybag + name = "Bluespace body bag" + desc = "A bluespace body bag, powered by experimental bluespace technology. It can hold loads of bodies and the largest of creatures." + id = "bluespacebodybag" + req_tech = list("bluespace" = 2, "materials" = 6) + build_type = PROTOLATHE + materials = list("$metal" = 3000, "$plasma" = 2000, "$diamond" = 500) + reliability = 76 + build_path = /obj/item/bodybag/bluespace category = "Misc" \ 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 a1a4d361ccb..c585150a334 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -141,6 +141,15 @@ datum/design/ionrifle build_path = /obj/item/weapon/gun/energy/ionrifle locked = 1 +datum/design/reciever + name = "Modular Reciever" + desc = "A prototype modular reciever and trigger assembly for a variety of firearms." + id = "reciever" + req_tech = list("combat" = 5, "materials" = 4) + build_type = PROTOLATHE + materials = list("$metal" = 6500, "$silver" = 500) + build_path = /obj/item/weaponcrafting/reciever + datum/design/ammo_9mm name = "Ammunition Box (9mm)" desc = "A box of prototype 9mm ammunition." diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index c5dd5d2ae50..9bcc805b2c6 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -123,42 +123,44 @@ var/global/list/obj/machinery/message_server/message_servers = list() value = param_value /datum/feedback_variable/proc/inc(var/num = 1) - if(isnum(value)) + if (isnum(value)) value += num else value = text2num(value) - if(isnum(value)) + if (isnum(value)) value += num else value = num /datum/feedback_variable/proc/dec(var/num = 1) - if(isnum(value)) + if (isnum(value)) value -= num else value = text2num(value) - if(isnum(value)) + if (isnum(value)) value -= num else value = -num /datum/feedback_variable/proc/set_value(var/num) - if(isnum(num)) + if (isnum(num)) value = num /datum/feedback_variable/proc/get_value() + if (!isnum(value)) + return 0 return value /datum/feedback_variable/proc/get_variable() return variable /datum/feedback_variable/proc/set_details(var/text) - if(istext(text)) + if (istext(text)) details = text /datum/feedback_variable/proc/add_details(var/text) - if(istext(text)) - if(!details) + if (istext(text)) + if (!details) details = text else details += " [text]" @@ -198,14 +200,14 @@ var/obj/machinery/blackbox_recorder/blackbox //Only one can exsist in the world! /obj/machinery/blackbox_recorder/New() - if(blackbox) - if(istype(blackbox,/obj/machinery/blackbox_recorder)) + if (blackbox) + if (istype(blackbox,/obj/machinery/blackbox_recorder)) qdel(src) blackbox = src /obj/machinery/blackbox_recorder/Destroy() var/turf/T = locate(1,1,2) - if(T) + if (T) blackbox = null var/obj/machinery/blackbox_recorder/BR = new/obj/machinery/blackbox_recorder(T) BR.msg_common = msg_common @@ -226,8 +228,8 @@ var/obj/machinery/blackbox_recorder/blackbox ..() /obj/machinery/blackbox_recorder/proc/find_feedback_datum(var/variable) - for(var/datum/feedback_variable/FV in feedback) - if(FV.get_variable() == variable) + for (var/datum/feedback_variable/FV in feedback) + if (FV.get_variable() == variable) return FV var/datum/feedback_variable/FV = new(variable) feedback += FV @@ -241,10 +243,10 @@ var/obj/machinery/blackbox_recorder/blackbox var/pda_msg_amt = 0 var/rc_msg_amt = 0 - for(var/obj/machinery/message_server/MS in world) - if(MS.pda_msgs.len > pda_msg_amt) + for (var/obj/machinery/message_server/MS in world) + if (MS.pda_msgs.len > pda_msg_amt) pda_msg_amt = MS.pda_msgs.len - if(MS.rc_msgs.len > rc_msg_amt) + if (MS.rc_msgs.len > rc_msg_amt) rc_msg_amt = MS.rc_msgs.len feedback_set_details("radio_usage","") @@ -269,72 +271,67 @@ var/obj/machinery/blackbox_recorder/blackbox //This proc is only to be called at round end. /obj/machinery/blackbox_recorder/proc/save_all_data_to_sql() - if(!feedback) return + if (!feedback) return round_end_data_gathering() //round_end time logging and some other data processing establish_db_connection() - if(!dbcon.IsConnected()) return + if (!dbcon.IsConnected()) return var/round_id var/DBQuery/query = dbcon.NewQuery("SELECT MAX(round_id) AS round_id FROM [format_table_name("feedback")]") query.Execute() - while(query.NextRow()) + while (query.NextRow()) round_id = query.item[1] - if(!isnum(round_id)) + if (!isnum(round_id)) round_id = text2num(round_id) round_id++ - for(var/datum/feedback_variable/FV in feedback) - var/sql = "INSERT INTO [format_table_name("feedback")] VALUES (null, Now(), [round_id], \"[FV.get_variable()]\", [FV.get_value()], \"[FV.get_details()]\")" - var/DBQuery/query_insert = dbcon.NewQuery(sql) - query_insert.Execute() + var/sqlrowlist = "" + + + for (var/datum/feedback_variable/FV in feedback) + if (sqlrowlist != "") + sqlrowlist += ", " //a comma (,) at the start of the first row to insert will trigger a SQL error + + sqlrowlist += "(null, Now(), [round_id], \"[sanitizeSQL(FV.get_variable())]\", [FV.get_value()], \"[sanitizeSQL(FV.get_details())]\")" + + if (sqlrowlist == "") + return + + var/DBQuery/query_insert = dbcon.NewQuery("INSERT DELAYED IGNORE INTO [format_table_name("feedback")] VALUES " + sqlrowlist) + query_insert.Execute() -// Sanitize inputs to avoid SQL injection attacks -proc/sql_sanitize_text(var/text) - text = replacetext(text, "'", "''") - text = replacetext(text, ";", "") - text = replacetext(text, "&", "") - return text proc/feedback_set(var/variable,var/value) - if(!blackbox) return - - variable = sql_sanitize_text(variable) + if (!blackbox) return var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable) - if(!FV) return + if (!FV) return FV.set_value(value) proc/feedback_inc(var/variable,var/value) - if(!blackbox) return - - variable = sql_sanitize_text(variable) + if (!blackbox) return var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable) - if(!FV) return + if (!FV) return FV.inc(value) proc/feedback_dec(var/variable,var/value) - if(!blackbox) return - - variable = sql_sanitize_text(variable) + if (!blackbox) return var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable) - if(!FV) return + if (!FV) return FV.dec(value) proc/feedback_set_details(var/variable,var/details) - if(!blackbox) return - - variable = sql_sanitize_text(variable) - details = sql_sanitize_text(details) + if (!blackbox) return var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable) @@ -343,13 +340,10 @@ proc/feedback_set_details(var/variable,var/details) FV.set_details(details) proc/feedback_add_details(var/variable,var/details) - if(!blackbox) return - - variable = sql_sanitize_text(variable) - details = sql_sanitize_text(details) + if (!blackbox) return var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable) - if(!FV) return + if (!FV) return FV.add_details(details) \ No newline at end of file diff --git a/code/unused/hivebot/hive_modules.dm b/code/unused/hivebot/hive_modules.dm index c0ae3196ca9..56951dee480 100644 --- a/code/unused/hivebot/hive_modules.dm +++ b/code/unused/hivebot/hive_modules.dm @@ -14,7 +14,7 @@ name = "HiveBot engineering robot module" /obj/item/weapon/hive_module/New()//Shit all the mods have - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/handheld(src) /obj/item/weapon/hive_module/standard/New() diff --git a/config/admins.txt b/config/admins.txt index 31a3f30183c..34d7fe5b413 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -65,4 +65,5 @@ paprka = Game Master cookingboy3 = Game Master limeliz = Game Master steelpoint = Game Master -phil235 = Game Master \ No newline at end of file +phil235 = Game Master +xxnoob = Game Master \ No newline at end of file diff --git a/config/game_options.txt b/config/game_options.txt index 107dceb009f..c1cce91ee72 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -129,6 +129,9 @@ TRAITOR_OBJECTIVES_AMOUNT 2 ## implants from being most antagonists. #PROTECT_ROLES_FROM_ANTAGONIST +## Uncomment to prohibit assistants from becoming most antagonists. +#PROTECT_ASSISTANT_FROM_ANTAGONIST + ## If non-human species are barred from joining as a head of staff #ENFORCE_HUMAN_AUTHORITY diff --git a/html/changelog.html b/html/changelog.html index 7df9840a60f..bb75a0bf2cb 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,84 @@ --> +
    +

    27 October 2014

    +

    Jordie0608 updated:

    +
      +
    • Adds a new riot shotgun that spawns in the armory with a 6 round beanbag magazine.
    • +
    +

    Paprika updated:

    +
      +
    • Allowed constructs to assist in activating most runes. This includes conversion runes, but does NOT include sacrifice runes.
    • +
    +

    Patchouli Knowledge updated:

    +
      +
    • In light of the recent achievements of the Robotics department, new and upgraded exosuit schematics were delivered to SS13 exosuit fabricators as a reward from CentComm.
    • +
    • The countless hours of research, experimentation, and reverse-engineering of wrecks from the mining asteroid have paid off - the Research team has rediscovered the process of building Phazon exosuits. The parts and circuits have been made available in the exofabs and circuit printers.
    • +
    • The APLU Ripley exosuit has been refitted with asteroid mining purposes in mind. Its armour plating will provide extra protection against the brute attacks of asteroid alien lifeforms, and protect from gibtonite explosions. The leg servos were upgraded to provide faster movement.
    • +
    • There are rumours of some creative shaft miners discovering a way of augmenting APLU Ripley armour with trophy hides from goliath-type asteroid lifeforms...
    • +
    • Durand construction routines now require a phasic scanner module and a super capacitor to match Nanotrasen industry standards.
    • +
    • The exosuit fire extinguisher now boasts a larger watertank, and carries a whole 1000u of water from the old 200u tank.
    • +
    • The exosuit plasma converter's efficiency has been vastly improved upon, and its fuel consumption has been cut to nearly half of old values.
    • +
    • The exosuit sleeper interiors have been refitted to allow the occupants more freedom of movement, and the occupants may now eject at will.
    • +
    • The armour plating on all exosuits was fitted with reactive deflection systems specifically designed to stop the rapid slashes from xenomorph threats.
    • +
    • The Firefighter Ripley chassis were moved from the Exosuit Equipment section to the APLU Ripley section of exofab menus.
    • +
    • Fixed some minor errors in the exosuit construction message syntax.
    • +
    +

    phil235 updated:

    +
      +
    • Closets and its children can no longer contain a near infinite amount of mobs. Large mobs (juggernaut, alien emperess, etc) don't fit, small mobs (mouse, parrot, etc) still fit in the same amounts, human-sized mob (humanoid, slime, etc) fit but maximum two per body bag and three for all the other closets. Adding bluespace body bag to R&D, it can hold even large mobs and in large amounts.
    • +
    • girders and displaced girders now have a chance to let projectiles pass through them.
    • +
    +
    + +
    +

    19 October 2014

    +

    Donkie updated:

    +
      +
    • Major atmos update. Featuring pretty colors.
    • +
    • 4-Way pipes added.
    • +
    • Flip-able trinary devices (mixer & filter).
    • +
    • Pipe-painter added.
    • +
    • Most pipe icons have been tweaked with shading and such, making it look more uniform.
    • +
    +

    JJRcop updated:

    +
      +
    • We have managed to re-discover drones! We improved the formula, and have discovered some cool stuff.
    • +
    • After some fiddling with audio recognition, drones can now understand human speech!
    • +
    • One of our engineers found some screws that were loose on some of our tests, screwing them in made the drone work as if it had just come out of robotics.
    • +
    • We had to sacrifice some of our NT brand EMP protection for the speech recognition, so drones can get damaged if subjected to heavy EMP radiation.
    • +
    • We figured out why drones couldn't remove objects from people, that has been fixed.
    • +
    • The standby light wasn't wired correctly.
    • +
    • Unfortunately one of our assistants tasked with transporting the only copy of the data dropped the flash drive in hot water because he wanted to see what "drone tea" tasted like. You'll have to discover them again.
    • +
    +

    Lo6a4evskiy updated:

    +
      +
    • Station's crayons have been upgraded to the version 2.0 of ColourOS. Don't worry, they are still edible!
    • +
    • Many items now have different stripping delays. Heavier and more armored pieces of clothing are generally more difficult to take off someone else, while smaller items can be very easy to snatch. Pockets always take 4 seconds to search.
    • +
    +

    MrPerson updated:

    +
      +
    • Implants are activated via action buttons on the top-left corner of your screen instead of emotes.
    • +
    +

    Paprika updated:

    +
      +
    • Added zipties for security and nuke operatives. These have a slightly shorter 'breakout time' as normal cuffs but they are destroyed upon removal. Beepsky and sec borgs now use these by default.
    • +
    • Changed the medical HUD in the tactical medkit to a night vision HUD so syndicate medics don't stumble around in the dark. Can be purchased through nuke op uplinks.
    • +
    • Added a second roboticist roundstart job slot.
    • +
    • Added a third cargo tech job slot.
    • +
    +

    Paprka updated:

    +
      +
    • Added undershirts as a companion piece to jumpsuit adjusting. Beat the heat with a comfortable tank top, or warm up with an extra layer tshirt!
    • +
    • Added a holographic sign projector to replace the old wet floor signs to encourage janitors to warn crewmembers about wet floors.
    • +
    +

    optimumtact updated:

    +
      +
    • Medical supplies crate now comes with a boxy full of bodybags
    • +
    +
    +

    09 October 2014

    Paprika updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 1b538c51b16..e5ed90c6360 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -1944,3 +1944,93 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. capacity of the jetpack has been reduced as well, however. - experiment: Removed resonator from the mining voucher redemption. Replaced it with a mining drill. +2014-10-19: + Donkie: + - rscadd: Major atmos update. Featuring pretty colors. + - rscadd: 4-Way pipes added. + - rscadd: Flip-able trinary devices (mixer & filter). + - rscadd: Pipe-painter added. + - tweak: Most pipe icons have been tweaked with shading and such, making it look + more uniform. + JJRcop: + - rscadd: We have managed to re-discover drones! We improved the formula, and have + discovered some cool stuff. + - rscadd: After some fiddling with audio recognition, drones can now understand + human speech! + - rscadd: One of our engineers found some screws that were loose on some of our + tests, screwing them in made the drone work as if it had just come out of robotics. + - tweak: We had to sacrifice some of our NT brand EMP protection for the speech + recognition, so drones can get damaged if subjected to heavy EMP radiation. + - bugfix: We figured out why drones couldn't remove objects from people, that has + been fixed. + - bugfix: The standby light wasn't wired correctly. + - rscdel: Unfortunately one of our assistants tasked with transporting the only + copy of the data dropped the flash drive in hot water because he wanted to see + what "drone tea" tasted like. You'll have to discover them again. + Lo6a4evskiy: + - rscadd: Station's crayons have been upgraded to the version 2.0 of ColourOS. Don't + worry, they are still edible! + - tweak: Many items now have different stripping delays. Heavier and more armored + pieces of clothing are generally more difficult to take off someone else, while + smaller items can be very easy to snatch. Pockets always take 4 seconds to search. + MrPerson: + - rscadd: Implants are activated via action buttons on the top-left corner of your + screen instead of emotes. + Paprika: + - rscadd: Added zipties for security and nuke operatives. These have a slightly + shorter 'breakout time' as normal cuffs but they are destroyed upon removal. + Beepsky and sec borgs now use these by default. + - bugfix: Changed the medical HUD in the tactical medkit to a night vision HUD so + syndicate medics don't stumble around in the dark. Can be purchased through + nuke op uplinks. + - rscadd: Added a second roboticist roundstart job slot. + - rscadd: Added a third cargo tech job slot. + Paprka: + - rscadd: Added undershirts as a companion piece to jumpsuit adjusting. Beat the + heat with a comfortable tank top, or warm up with an extra layer tshirt! + - rscadd: Added a holographic sign projector to replace the old wet floor signs + to encourage janitors to warn crewmembers about wet floors. + optimumtact: + - rscadd: Medical supplies crate now comes with a boxy full of bodybags +2014-10-27: + Jordie0608: + - rscadd: Adds a new riot shotgun that spawns in the armory with a 6 round beanbag + magazine. + Paprika: + - experiment: Allowed constructs to assist in activating most runes. This includes + conversion runes, but does NOT include sacrifice runes. + Patchouli Knowledge: + - rscadd: In light of the recent achievements of the Robotics department, new and + upgraded exosuit schematics were delivered to SS13 exosuit fabricators as a + reward from CentComm. + - rscadd: The countless hours of research, experimentation, and reverse-engineering + of wrecks from the mining asteroid have paid off - the Research team has rediscovered + the process of building Phazon exosuits. The parts and circuits have been made + available in the exofabs and circuit printers. + - rscadd: The APLU Ripley exosuit has been refitted with asteroid mining purposes + in mind. Its armour plating will provide extra protection against the brute + attacks of asteroid alien lifeforms, and protect from gibtonite explosions. + The leg servos were upgraded to provide faster movement. + - rscadd: There are rumours of some creative shaft miners discovering a way of augmenting + APLU Ripley armour with trophy hides from goliath-type asteroid lifeforms... + - tweak: Durand construction routines now require a phasic scanner module and a + super capacitor to match Nanotrasen industry standards. + - tweak: The exosuit fire extinguisher now boasts a larger watertank, and carries + a whole 1000u of water from the old 200u tank. + - tweak: The exosuit plasma converter's efficiency has been vastly improved upon, + and its fuel consumption has been cut to nearly half of old values. + - bugfix: The exosuit sleeper interiors have been refitted to allow the occupants + more freedom of movement, and the occupants may now eject at will. + - bugfix: The armour plating on all exosuits was fitted with reactive deflection + systems specifically designed to stop the rapid slashes from xenomorph threats. + - bugfix: The Firefighter Ripley chassis were moved from the Exosuit Equipment section + to the APLU Ripley section of exofab menus. + - spellcheck: Fixed some minor errors in the exosuit construction message syntax. + phil235: + - rscadd: Closets and its children can no longer contain a near infinite amount + of mobs. Large mobs (juggernaut, alien emperess, etc) don't fit, small mobs + (mouse, parrot, etc) still fit in the same amounts, human-sized mob (humanoid, + slime, etc) fit but maximum two per body bag and three for all the other closets. + Adding bluespace body bag to R&D, it can hold even large mobs and in large amounts. + - experiment: girders and displaced girders now have a chance to let projectiles + pass through them. diff --git a/html/changelogs/Donkie-PR-4759.yml b/html/changelogs/Donkie-PR-4759.yml deleted file mode 100644 index 97156691aec..00000000000 --- a/html/changelogs/Donkie-PR-4759.yml +++ /dev/null @@ -1,31 +0,0 @@ - -# bugfix -# wip (For works in progress) -# tweak -# soundadd -# sounddel -# rscdel (general adding of nice things) -# rscadd (general deleting of nice things) -# imageadd -# imagedel -# spellcheck (typo fixes) -# experiment -# tgs (TG-ported fixes?) - -# Your name. -author: Donkie - -# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. -delete-after: True - -# Any changes you've made. See valid prefix list above. -# INDENT WITH TWO SPACES. NOT TABS. SPACES. -# SCREW THIS UP AND IT WON'T WORK. -# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. -changes: - - rscadd: Major atmos update. Featuring pretty colors. - - rscadd: 4-Way pipes added. - - rscadd: Flip-able trinary devices (mixer & filter). - - rscadd: Pipe-painter added. - - tweak: Most pipe icons have been tweaked with shading and such, making it look more uniform. - diff --git a/html/changelogs/JJRcop-PR-5185.yml b/html/changelogs/JJRcop-PR-5185.yml deleted file mode 100644 index 6c72197236b..00000000000 --- a/html/changelogs/JJRcop-PR-5185.yml +++ /dev/null @@ -1,11 +0,0 @@ -author: JJRcop -delete-after: True -changes: - - rscadd: "We have managed to re-discover drones! We improved the formula, and have discovered some cool stuff." - - rscadd: "After some fiddling with audio recognition, drones can now understand human speech!" - - rscadd: "One of our engineers found some screws that were loose on some of our tests, screwing them in made the drone work as if it had just come out of robotics." - - tweak: "We had to sacrifice some of our NT brand EMP protection for the speech recognition, so drones can get damaged if subjected to heavy EMP radiation." - - bugfix: "We figured out why drones couldn't remove objects from people, that has been fixed." - - bugfix: "The standby light wasn't wired correctly." -# ^ These aren't actually code bugs, but I'm writing this all In Character from Nanotrasen, and the icons fit well - - rscdel: "Unfortunately one of our assistants tasked with transporting the only copy of the data dropped the flash drive in hot water because he wanted to see what \"drone tea\" tasted like. You'll have to discover them again." \ No newline at end of file diff --git a/html/changelogs/Lo6a4evskiy-PR-4861.yml b/html/changelogs/Lo6a4evskiy-PR-4861.yml deleted file mode 100644 index 99c6b5694bf..00000000000 --- a/html/changelogs/Lo6a4evskiy-PR-4861.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: Lo6a4evskiy - -delete-after: True - -changes: - - rscadd: Station's crayons have been upgraded to the version 2.0 of ColourOS. Don't worry, they are still edible! \ No newline at end of file diff --git a/html/changelogs/Lo6a4evskiy-PR-5100.yml b/html/changelogs/Lo6a4evskiy-PR-5100.yml deleted file mode 100644 index 932d1d032f5..00000000000 --- a/html/changelogs/Lo6a4evskiy-PR-5100.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: Lo6a4evskiy - -delete-after: True - -changes: - - tweak: Many items now have different stripping delays. Heavier and more armored pieces of clothing are generally more difficult to take off someone else, while smaller items can be very easy to snatch. Pockets always take 4 seconds to search. \ No newline at end of file diff --git a/html/changelogs/MrPerson.yml b/html/changelogs/MrPerson.yml index a97817867cd..4f610d483e2 100644 --- a/html/changelogs/MrPerson.yml +++ b/html/changelogs/MrPerson.yml @@ -1,3 +1,8 @@ author: MrPerson -changes: - - rscadd: Implants are activated via action buttons on the top-left corner of your screen instead of emotes. \ No newline at end of file +changes: + - rscadd: "Everything now drifts in space, not just mobs." + - rscadd: "Mechs are just as maneuverable in space as you are." + - tweak: "Being weightless now slows movement down by a lot rather than speeding it up. Having your hands full will make movement even slower." + - rscdel: "Removed spaceslipping (You slipped! x1000)" + - bugfix: "Jetpacking after being thrown out a mass driver will cancel out your momentum." + - bugfix: "Shooting a gun causes you to drift the other direction like spraying a fire extinguisher." \ No newline at end of file diff --git a/html/changelogs/Paprka-PR-5123.yml b/html/changelogs/Paprka-PR-5123.yml deleted file mode 100644 index f0323cd6a7a..00000000000 --- a/html/changelogs/Paprka-PR-5123.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Paprika -delete-after: True -changes: - - rscadd: "Added zipties for security and nuke operatives. These have a slightly shorter 'breakout time' as normal cuffs but they are destroyed upon removal. Beepsky and sec borgs now use these by default." \ No newline at end of file diff --git a/html/changelogs/Paprka-PR-5132.yml b/html/changelogs/Paprka-PR-5132.yml deleted file mode 100644 index 07b8090aa77..00000000000 --- a/html/changelogs/Paprka-PR-5132.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Paprika -delete-after: True -changes: - - bugfix: Changed the medical HUD in the tactical medkit to a night vision HUD so syndicate medics don't stumble around in the dark. Can be purchased through nuke op uplinks. \ No newline at end of file diff --git a/html/changelogs/Paprka-PR-5135.yml b/html/changelogs/Paprka-PR-5135.yml deleted file mode 100644 index d31426110ae..00000000000 --- a/html/changelogs/Paprka-PR-5135.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: Paprka - -delete-after: True - -changes: - - rscadd: "Added undershirts as a companion piece to jumpsuit adjusting. Beat the heat with a comfortable tank top, or warm up with an extra layer tshirt!" \ No newline at end of file diff --git a/html/changelogs/Paprka-PR-5137.yml b/html/changelogs/Paprka-PR-5137.yml deleted file mode 100644 index 9a277d228ec..00000000000 --- a/html/changelogs/Paprka-PR-5137.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Paprka -delete-after: True -changes: - - rscadd: "Added a holographic sign projector to replace the old wet floor signs to encourage janitors to warn crewmembers about wet floors." \ No newline at end of file diff --git a/html/changelogs/Paprka-PR-5202.yml b/html/changelogs/Paprka-PR-5202.yml deleted file mode 100644 index fa15d19cf93..00000000000 --- a/html/changelogs/Paprka-PR-5202.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: Paprika -delete-after: True -changes: - - rscadd: "Added a second roboticist roundstart job slot." - - rscadd: "Added a third cargo tech job slot." diff --git a/html/changelogs/optimumtact-PR-5141.yml b/html/changelogs/optimumtact-PR-5141.yml deleted file mode 100644 index 226ba3a2542..00000000000 --- a/html/changelogs/optimumtact-PR-5141.yml +++ /dev/null @@ -1,21 +0,0 @@ -# Valid Prefixes: -# bugfix -# wip (For works in progress) -# tweak -# soundadd -# sounddel -# rscdel (general adding of nice things) -# rscadd (general deleting of nice things) -# imageadd -# imagedel -# spellcheck (typo fixes) -# experiment -# tgs (TG-ported fixes?) - -# Your name. -author: optimumtact - -delete-after: True - -changes: - - rscadd: "Medical supplies crate now comes with a boxy full of bodybags" diff --git a/icons/mecha/mech_construct.dmi b/icons/mecha/mech_construct.dmi index bdce08c8022..bf8ba802916 100644 Binary files a/icons/mecha/mech_construct.dmi and b/icons/mecha/mech_construct.dmi differ diff --git a/icons/mecha/mech_construction.dmi b/icons/mecha/mech_construction.dmi index d0a145caff5..393cead765e 100644 Binary files a/icons/mecha/mech_construction.dmi and b/icons/mecha/mech_construction.dmi differ diff --git a/icons/mecha/mecha.dmi b/icons/mecha/mecha.dmi index 772b4fa1513..c9e3455fa55 100644 Binary files a/icons/mecha/mecha.dmi and b/icons/mecha/mecha.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index 6466f049aed..0547d648086 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 1e73c5f4889..b06f7b07a95 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi index c9de1a58cc2..e711157e2e5 100644 Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 36882e647f3..41b93e38b63 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/human.dmi b/icons/mob/human.dmi index 8b586b4fab9..ff3073b2ddd 100644 Binary files a/icons/mob/human.dmi and b/icons/mob/human.dmi differ diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index 47328e6fa81..3c890f83a2a 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi index 1123fab1a60..e67c7873aa8 100644 Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ diff --git a/icons/mob/screen_gen_old.dmi b/icons/mob/screen_gen_old.dmi new file mode 100644 index 00000000000..fc1872ad594 Binary files /dev/null and b/icons/mob/screen_gen_old.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 208e04669ee..2572ffae3a7 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/underwear.dmi b/icons/mob/underwear.dmi index 18f7783d003..6a16f7002c2 100644 Binary files a/icons/mob/underwear.dmi and b/icons/mob/underwear.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 9e5cd3210a5..3ed28b85624 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/aibots.dmi b/icons/obj/aibots.dmi index 7b559aad634..7039ec43103 100644 Binary files a/icons/obj/aibots.dmi and b/icons/obj/aibots.dmi differ diff --git a/icons/obj/bodybag.dmi b/icons/obj/bodybag.dmi index a1f99031280..caa12c04ffa 100644 Binary files a/icons/obj/bodybag.dmi and b/icons/obj/bodybag.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 5a2d9dcac64..602df9fc9d0 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index dd7a68ce4fb..1dcfa6357a1 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index 3de2bb7aae5..e10e9746760 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ diff --git a/icons/obj/halloween_items.dmi b/icons/obj/halloween_items.dmi new file mode 100644 index 00000000000..c08ea711488 Binary files /dev/null and b/icons/obj/halloween_items.dmi differ diff --git a/icons/obj/harvest.dmi b/icons/obj/harvest.dmi index db6cd7e0573..acf3b39ea00 100644 Binary files a/icons/obj/harvest.dmi and b/icons/obj/harvest.dmi differ diff --git a/icons/obj/improvised.dmi b/icons/obj/improvised.dmi new file mode 100644 index 00000000000..9c32333ae03 Binary files /dev/null and b/icons/obj/improvised.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 7c4e43a241c..c03fa5e244e 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index ed57a390a27..042bda052f6 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/meteor_spooky.dmi b/icons/obj/meteor_spooky.dmi new file mode 100644 index 00000000000..287d5b47bd0 Binary files /dev/null and b/icons/obj/meteor_spooky.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index b6789863ebc..ff07bda85f6 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi index eeb1db6b29c..0f7700a18ea 100644 Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ diff --git a/icons/pda_icons/pda_cleanbot.png b/icons/pda_icons/pda_cleanbot.png new file mode 100644 index 00000000000..cecbcf40773 Binary files /dev/null and b/icons/pda_icons/pda_cleanbot.png differ diff --git a/icons/pda_icons/pda_floorbot.png b/icons/pda_icons/pda_floorbot.png new file mode 100644 index 00000000000..999e45aed25 Binary files /dev/null and b/icons/pda_icons/pda_floorbot.png differ diff --git a/icons/pda_icons/pda_medbot.png b/icons/pda_icons/pda_medbot.png new file mode 100644 index 00000000000..24ae212be2e Binary files /dev/null and b/icons/pda_icons/pda_medbot.png differ diff --git a/icons/turf/walls.dmi b/icons/turf/walls.dmi index 6d65684a300..b4a89332495 100644 Binary files a/icons/turf/walls.dmi and b/icons/turf/walls.dmi differ diff --git a/sound/spookoween/bats.ogg b/sound/spookoween/bats.ogg new file mode 100644 index 00000000000..fb428debcb3 Binary files /dev/null and b/sound/spookoween/bats.ogg differ diff --git a/sound/spookoween/chain_rattling.ogg b/sound/spookoween/chain_rattling.ogg new file mode 100644 index 00000000000..9ff9913b2b2 Binary files /dev/null and b/sound/spookoween/chain_rattling.ogg differ diff --git a/sound/spookoween/ghost_whisper.ogg b/sound/spookoween/ghost_whisper.ogg new file mode 100644 index 00000000000..660b04c786d Binary files /dev/null and b/sound/spookoween/ghost_whisper.ogg differ diff --git a/sound/spookoween/ghosty_wind.ogg b/sound/spookoween/ghosty_wind.ogg new file mode 100644 index 00000000000..b1c8c2f3a8c Binary files /dev/null and b/sound/spookoween/ghosty_wind.ogg differ diff --git a/sound/spookoween/girlscream.ogg b/sound/spookoween/girlscream.ogg new file mode 100644 index 00000000000..8ded518f47f Binary files /dev/null and b/sound/spookoween/girlscream.ogg differ diff --git a/sound/spookoween/insane_low_laugh.ogg b/sound/spookoween/insane_low_laugh.ogg new file mode 100644 index 00000000000..6f1ba277783 Binary files /dev/null and b/sound/spookoween/insane_low_laugh.ogg differ diff --git a/sound/spookoween/scary_clown_appear.ogg b/sound/spookoween/scary_clown_appear.ogg new file mode 100644 index 00000000000..05ab18f70b0 Binary files /dev/null and b/sound/spookoween/scary_clown_appear.ogg differ diff --git a/sound/spookoween/scary_horn.ogg b/sound/spookoween/scary_horn.ogg new file mode 100644 index 00000000000..a0b05821bb2 Binary files /dev/null and b/sound/spookoween/scary_horn.ogg differ diff --git a/sound/spookoween/scary_horn2.ogg b/sound/spookoween/scary_horn2.ogg new file mode 100644 index 00000000000..fb2805bd2cd Binary files /dev/null and b/sound/spookoween/scary_horn2.ogg differ diff --git a/sound/spookoween/scary_horn3.ogg b/sound/spookoween/scary_horn3.ogg new file mode 100644 index 00000000000..0aaefe1583a Binary files /dev/null and b/sound/spookoween/scary_horn3.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 03fce853a7c..c9c8e882932 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -689,12 +689,15 @@ #include "code\game\turfs\unsimulated.dm" #include "code\game\turfs\simulated\dirtystation.dm" #include "code\game\turfs\simulated\floor.dm" -#include "code\game\turfs\simulated\floor_mineral.dm" -#include "code\game\turfs\simulated\floor_types.dm" #include "code\game\turfs\simulated\walls.dm" #include "code\game\turfs\simulated\walls_mineral.dm" #include "code\game\turfs\simulated\walls_misc.dm" #include "code\game\turfs\simulated\walls_reinforced.dm" +#include "code\game\turfs\simulated\floor\fancy_floor.dm" +#include "code\game\turfs\simulated\floor\light_floor.dm" +#include "code\game\turfs\simulated\floor\mineral_floor.dm" +#include "code\game\turfs\simulated\floor\misc_floor.dm" +#include "code\game\turfs\simulated\floor\plating.dm" #include "code\game\turfs\space\space.dm" #include "code\game\turfs\space\transit.dm" #include "code\game\turfs\unsimulated\beach.dm" @@ -748,6 +751,7 @@ #include "code\modules\admin\verbs\possess.dm" #include "code\modules\admin\verbs\pray.dm" #include "code\modules\admin\verbs\randomverbs.dm" +#include "code\modules\admin\verbs\reestablish_db_connection.dm" #include "code\modules\admin\verbs\ticklag.dm" #include "code\modules\admin\verbs\tripAI.dm" #include "code\modules\admin\verbs\SDQL2\SDQL_2.dm" @@ -829,6 +833,7 @@ #include "code\modules\clothing\under\jobs\engineering.dm" #include "code\modules\clothing\under\jobs\medsci.dm" #include "code\modules\clothing\under\jobs\security.dm" +#include "code\modules\crafting\guncrafting.dm" #include "code\modules\crafting\recipes.dm" #include "code\modules\crafting\table.dm" #include "code\modules\detectivework\detective_work.dm" @@ -1111,6 +1116,7 @@ #include "code\modules\mob\living\simple_animal\hostile\bear.dm" #include "code\modules\mob\living\simple_animal\hostile\carp.dm" #include "code\modules\mob\living\simple_animal\hostile\creature.dm" +#include "code\modules\mob\living\simple_animal\hostile\eyeballs.dm" #include "code\modules\mob\living\simple_animal\hostile\faithless.dm" #include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm" #include "code\modules\mob\living\simple_animal\hostile\hivebot.dm"

    Name

    Status

    Location

    Control

    [Bot.hacked ? "(!) [Bot.name]" : Bot.name][Bot.on ? "[Bot.mode ? "[ Bot.mode_name[Bot.mode] ]": "Idle"]" : "Inactive"][bot_area.name]InterfaceCall