mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-27 22:17:32 +01:00
Ports tg simple_animal bots
This commit is contained in:
@@ -378,7 +378,7 @@
|
||||
"ahn" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
"aho" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/machinery/recharger{pixel_y = 0},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
"ahp" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weed_extract,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
"ahq" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/machinery/bot/floorbot{on = 0},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
"ahq" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/mob/living/simple_animal/bot/floorbot{on = 0},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
"ahr" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/broken_device,/obj/item/robot_parts/chest,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
"ahs" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/pickaxe,/obj/item/weapon/storage/firstaid/toxin,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
"aht" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/scalpel,/obj/item/stack/cable_coil,/obj/item/weapon/storage/firstaid/regular,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
@@ -511,7 +511,7 @@
|
||||
"ajQ" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/security/prison)
|
||||
"ajR" = (/obj/machinery/flasher/portable,/obj/machinery/firealarm{dir = 8; pixel_x = -26; pixel_y = 0},/obj/machinery/flasher/portable,/turf/simulated/floor/plasteel{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/security/warden)
|
||||
"ajS" = (/obj/structure/rack,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/weapon/gun/projectile/shotgun/riot{pixel_x = -3; pixel_y = 3},/obj/item/weapon/gun/projectile/shotgun/riot{pixel_x = 2; pixel_y = -1},/turf/simulated/floor/plasteel{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/security/warden)
|
||||
"ajT" = (/obj/machinery/bot/secbot{health = 35; name = "Securitron #359"; on = 0},/turf/simulated/floor/plasteel{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/security/warden)
|
||||
"ajT" = (/mob/living/simple_animal/bot/secbot{health = 35; name = "Securitron #359"; on = 0},/turf/simulated/floor/plasteel{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/security/warden)
|
||||
"ajU" = (/obj/structure/rack,/obj/item/weapon/gun/energy/gun{pixel_x = -3; pixel_y = 3},/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun{pixel_x = 3; pixel_y = -3},/turf/simulated/floor/plasteel{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/security/warden)
|
||||
"ajV" = (/obj/structure/rack,/obj/item/clothing/suit/armor/bulletproof,/obj/item/clothing/head/helmet/alt,/obj/item/clothing/suit/armor/bulletproof,/obj/item/clothing/head/helmet/alt,/obj/item/clothing/suit/armor/bulletproof,/obj/item/clothing/head/helmet/alt,/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden)
|
||||
"ajW" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow,/obj/machinery/door/poddoor/preopen{id_tag = "hosprivacy"; name = "privacy shutters"},/turf/simulated/floor/plating,/area/security/hos)
|
||||
@@ -951,7 +951,7 @@
|
||||
"aso" = (/obj/structure/table,/obj/item/weapon/folder/red,/obj/item/weapon/book/manual/security_space_law{pixel_x = -3; pixel_y = 5},/obj/item/stack/packageWrap,/turf/simulated/floor/plasteel,/area/security/main)
|
||||
"asp" = (/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/main)
|
||||
"asq" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Security Delivery"; req_access_txt = "1"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/security/main)
|
||||
"asr" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "Security"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/security/main)
|
||||
"asr" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "Security"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/security/main)
|
||||
"ass" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/maintenance/fore)
|
||||
"ast" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fore)
|
||||
"asu" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating{tag = "icon-platingdmg2"; icon_state = "platingdmg2"},/area/maintenance/fore)
|
||||
@@ -987,7 +987,7 @@
|
||||
"asY" = (/obj/structure/rack,/obj/item/weapon/tank/jetpack/oxygen,/obj/item/weapon/tank/air,/obj/item/clothing/mask/breath,/obj/item/clothing/shoes/magboots,/obj/machinery/camera{c_tag = "Engineering Secure Storage South"; dir = 4; network = list("SS13")},/obj/item/clothing/suit/space/rig/security,/obj/item/clothing/head/helmet/space/rig/security,/turf/simulated/floor/plasteel,/area/security/podbay)
|
||||
"asZ" = (/turf/simulated/floor/engine,/area/security/podbay)
|
||||
"ata" = (/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating/airless,/area/space)
|
||||
"atb" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=1"; freq = 1400; location = "Disposals"},/obj/structure/plasticflaps{opacity = 0},/obj/machinery/conveyor{dir = 2; id = "garbage"},/obj/machinery/door/window/northright{dir = 2; name = "delivery door"; pixel_y = 0; req_access_txt = "31"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/disposal)
|
||||
"atb" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 1; location = "Disposals"},/obj/structure/plasticflaps{opacity = 0},/obj/machinery/conveyor{dir = 2; id = "garbage"},/obj/machinery/door/window/northright{dir = 2; name = "delivery door"; pixel_y = 0; req_access_txt = "31"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/disposal)
|
||||
"atc" = (/obj/machinery/door/airlock/maintenance{name = "Disposal Conveyor Access"; req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/disposal)
|
||||
"atd" = (/obj/structure/sign/securearea{name = "\improper STAY CLEAR HEAVY MACHINERY"; pixel_y = 0},/turf/simulated/wall,/area/maintenance/disposal)
|
||||
"ate" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"})
|
||||
@@ -999,7 +999,7 @@
|
||||
"atk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"})
|
||||
"atl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/maintenance/fore)
|
||||
"atm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/fore)
|
||||
"atn" = (/obj/machinery/bot/cleanbot{name = "Mopfficer Sweepsky"; on = 0},/turf/simulated/floor/plating{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/maintenance/fore)
|
||||
"atn" = (/mob/living/simple_animal/bot/cleanbot{name = "Mopfficer Sweepsky"; on = 0},/turf/simulated/floor/plating{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/maintenance/fore)
|
||||
"ato" = (/obj/item/weapon/storage/box/lights/mixed,/obj/item/device/flashlight{pixel_x = 1; pixel_y = 5},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fore)
|
||||
"atp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/security/brig)
|
||||
"atq" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/security/brig)
|
||||
@@ -1455,7 +1455,7 @@
|
||||
"aBY" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/maintenance/starboard)
|
||||
"aBZ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/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/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/starboard)
|
||||
"aCa" = (/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/simple/hidden/supply{dir = 9},/turf/simulated/floor/plating,/area/maintenance/starboard)
|
||||
"aCb" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=4"; freq = 1400; location = "Engineering"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/maintenance/starboard)
|
||||
"aCb" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 4; location = "Engineering"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/maintenance/starboard)
|
||||
"aCc" = (/obj/machinery/door/window/southright{dir = 4; name = "Engineering Deliveries"; req_access_txt = "10"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/engine/engineering)
|
||||
"aCd" = (/obj/structure/sign/securearea{pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/engine/engineering)
|
||||
"aCe" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/engine/engineering)
|
||||
@@ -1830,7 +1830,7 @@
|
||||
"aJj" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
"aJk" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
"aJl" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
"aJm" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=1-BrigCells"; location = "0-SecurityDesk"},/obj/machinery/bot/secbot/beepsky{desc = "It's Officer Beepsky! Powered by a potato and a shot of whiskey, and with a sturdier reinforced chassis, too. "; health = 45; maxhealth = 45; name = "Officer Beepsky"},/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
"aJm" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=1-BrigCells"; location = "0-SecurityDesk"},/mob/living/simple_animal/bot/secbot/beepsky,/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
"aJn" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
"aJo" = (/obj/structure/table/reinforced,/obj/machinery/door/window/westleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Outer Window"; req_access_txt = "0"},/obj/machinery/door/window/brigdoor{dir = 4; name = "Security Desk"; req_access_txt = "1"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/item/device/radio/off,/obj/machinery/door/poddoor/shutters/preopen{id_tag = "briglockdown"; name = "brig shutters"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/brig)
|
||||
"aJp" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/brig)
|
||||
@@ -2101,7 +2101,7 @@
|
||||
"aOu" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/quartermaster/storage)
|
||||
"aOv" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{tag = "icon-warningcorner (WEST)"; icon_state = "warningcorner"; dir = 8},/area/quartermaster/storage)
|
||||
"aOw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/window/reinforced{dir = 1; pixel_y = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "loadingarea"; tag = "loading"},/area/quartermaster/storage)
|
||||
"aOx" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "QM #1"},/obj/machinery/bot/mulebot{beacon_freq = 1400; home_destination = "QM #1"; suffix = "#1"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/window/northleft,/obj/machinery/light{dir = 4},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/quartermaster/storage)
|
||||
"aOx" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "QM #1"},/mob/living/simple_animal/bot/mulebot{home_destination = "QM #1"; suffix = "#1"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/window/northleft,/obj/machinery/light{dir = 4},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/quartermaster/storage)
|
||||
"aOy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;63;48;50"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"})
|
||||
"aOz" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;63;48;50"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"})
|
||||
"aOA" = (/turf/simulated/wall,/area/storage/primary)
|
||||
@@ -2172,7 +2172,7 @@
|
||||
"aPN" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/storage)
|
||||
"aPO" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/quartermaster/storage)
|
||||
"aPP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 8; icon_state = "loadingarea"; tag = "loading"},/area/quartermaster/storage)
|
||||
"aPQ" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "QM #2"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/quartermaster/storage)
|
||||
"aPQ" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "QM #2"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/quartermaster/storage)
|
||||
"aPR" = (/obj/machinery/door/window/northleft{dir = 8; name = "MuleBot Supply Access"; req_access_txt = "50"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"})
|
||||
"aPS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating{tag = "icon-warnplate (NORTHWEST)"; icon_state = "warnplate"; dir = 9},/area/maintenance/fpmaint2{name = "Port Maintenance"})
|
||||
"aPT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"})
|
||||
@@ -2252,7 +2252,7 @@
|
||||
"aRp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel,/area/quartermaster/storage)
|
||||
"aRq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/landmark/start{name = "Cargo Technician"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/quartermaster/storage)
|
||||
"aRr" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "loadingarea"; tag = "loading"},/area/quartermaster/storage)
|
||||
"aRs" = (/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/plasteel{icon_state = "delivery"},/area/quartermaster/storage)
|
||||
"aRs" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "QM #3"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/mob/living/simple_animal/bot/mulebot{home_destination = "QM #3"; suffix = "#3"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/quartermaster/storage)
|
||||
"aRt" = (/obj/structure/mirror{pixel_x = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/obj/structure/curtain/open/shower,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"})
|
||||
"aRu" = (/turf/simulated/floor/plasteel,/area/storage/primary)
|
||||
"aRv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel,/area/storage/primary)
|
||||
@@ -2318,7 +2318,7 @@
|
||||
"aSD" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/storage)
|
||||
"aSE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 2; icon_state = "warningcorner"; tag = "icon-warningcorner (EAST)"},/area/quartermaster/storage)
|
||||
"aSF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plasteel{dir = 8; icon_state = "loadingarea"; tag = "loading"},/area/quartermaster/storage)
|
||||
"aSG" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "QM #4"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/window/southleft,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/quartermaster/storage)
|
||||
"aSG" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "QM #4"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/window/southleft,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/quartermaster/storage)
|
||||
"aSH" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/quartermaster/qm)
|
||||
"aSI" = (/obj/structure/closet/secure_closet/quartermaster,/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 9; icon_state = "brown"},/area/quartermaster/qm)
|
||||
"aSJ" = (/obj/machinery/camera/autoname{dir = 2; network = list("SS13")},/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/power/apc{dir = 1; name = "Quartermaster's Office APC"; pixel_x = 0; pixel_y = 30},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "brown"},/area/quartermaster/qm)
|
||||
@@ -2392,7 +2392,7 @@
|
||||
"aTZ" = (/obj/effect/landmark/start{name = "Quartermaster"},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/qm)
|
||||
"aUa" = (/obj/structure/table,/obj/item/weapon/folder/yellow,/obj/item/weapon/pen{pixel_x = 4; pixel_y = 4},/obj/item/weapon/pen/red,/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel,/area/quartermaster/qm)
|
||||
"aUb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/fpmaint2{name = "Port Maintenance"})
|
||||
"aUc" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=4"; freq = 1400; location = "Tool Storage"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/storage/primary)
|
||||
"aUc" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 4; location = "Tool Storage"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/storage/primary)
|
||||
"aUd" = (/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/storage/primary)
|
||||
"aUe" = (/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/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 2; icon_state = "browncorner"},/area/storage/primary)
|
||||
"aUf" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/security_space_law,/obj/item/weapon/book/manual/security_space_law,/obj/machinery/computer/security/telescreen{desc = "Used for watching Prison Wing holding areas."; name = "Prison Monitor"; network = list("Prison"); pixel_x = 0; pixel_y = 30},/obj/item/weapon/cartridge/lawyer,/obj/item/weapon/pen/multi,/turf/simulated/floor/wood,/area/lawoffice)
|
||||
@@ -3633,7 +3633,7 @@
|
||||
"brS" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"})
|
||||
"brT" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"})
|
||||
"brU" = (/obj/item/device/radio/off,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/maintcentral{name = "Central Maintenance"})
|
||||
"brV" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=4"; freq = 1400; location = "Bridge"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/maintenance/maintcentral{name = "Central Maintenance"})
|
||||
"brV" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 4; location = "Bridge"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/maintenance/maintcentral{name = "Central Maintenance"})
|
||||
"brW" = (/obj/machinery/door/window/westleft{dir = 4; name = "Bridge Deliveries"; req_access_txt = "19"},/obj/machinery/door/poddoor/preopen{id_tag = "bridge blast"; name = "bridge blast door"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/bridge)
|
||||
"brX" = (/obj/structure/closet/crate{icon_state = "crateopen"; opened = 1},/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/hallway/primary/port)
|
||||
"brY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge)
|
||||
@@ -3762,7 +3762,7 @@
|
||||
"bur" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge)
|
||||
"bus" = (/obj/structure/sink/kitchen{pixel_y = 28},/turf/simulated/floor/wood,/area/crew_quarters/bar)
|
||||
"but" = (/obj/machinery/door/window/southleft{base_state = "left"; dir = 2; icon_state = "left"; name = "Bar Delivery"; req_access_txt = "25"},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/crew_quarters/bar)
|
||||
"buu" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=1"; freq = 1400; location = "Bar"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/crew_quarters/bar)
|
||||
"buu" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 1; location = "Bar"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/crew_quarters/bar)
|
||||
"buv" = (/obj/item/weapon/storage/box/lights/mixed,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/starboard)
|
||||
"buw" = (/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/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{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/maintenance/starboard)
|
||||
"bux" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/starboard)
|
||||
@@ -4669,7 +4669,7 @@
|
||||
"bLO" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/scrubber,/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/window/reinforced,/turf/simulated/floor/plasteel{dir = 8; icon_state = "escape"},/area/hallway/primary/starboard)
|
||||
"bLP" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/hallway/primary/starboard)
|
||||
"bLQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "caution"; dir = 4},/area/hallway/primary/starboard)
|
||||
"bLR" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=4"; freq = 1400; location = "Atmospherics"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/atmos)
|
||||
"bLR" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 4; location = "Atmospherics"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/atmos)
|
||||
"bLS" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "loadingarea"; tag = "loading"},/area/atmos)
|
||||
"bLT" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/atmos)
|
||||
"bLU" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/atmos)
|
||||
@@ -5452,7 +5452,7 @@
|
||||
"caR" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/shovel/spade,/obj/item/weapon/wrench,/obj/item/weapon/screwdriver,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/minihoe,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hydroponics)
|
||||
"caS" = (/obj/structure/closet{name = "spare parts locker"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/item/weapon/rack_parts,/obj/item/weapon/rack_parts,/obj/item/weapon/wrench,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/crew_quarters/kitchen)
|
||||
"caT" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/window/eastright{dir = 1; name = "Kitchen Delivery"; req_access_txt = "28"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/crew_quarters/kitchen)
|
||||
"caU" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "Kitchen"},/obj/structure/plasticflaps{opacity = 1},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/crew_quarters/kitchen)
|
||||
"caU" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "Kitchen"},/obj/structure/plasticflaps{opacity = 1},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/crew_quarters/kitchen)
|
||||
"caV" = (/obj/structure/disposalpipe/sortjunction{dir = 2; sortType = 20},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating{tag = "icon-warnplate (WEST)"; icon_state = "warnplate"; dir = 8},/area/maintenance/starboard)
|
||||
"caW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/starboard)
|
||||
"caX" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plating,/area/maintenance/starboard)
|
||||
@@ -5721,7 +5721,7 @@
|
||||
"cga" = (/obj/machinery/light/small{dir = 1},/obj/structure/mopbucket,/obj/item/weapon/mop,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"})
|
||||
"cgb" = (/obj/item/weapon/storage/toolbox/emergency,/obj/item/weapon/hand_labeler,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"})
|
||||
"cgc" = (/obj/item/weapon/cigbutt,/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/aft{name = "Aft Maintenance"})
|
||||
"cgd" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=4"; freq = 1400; location = "Medbay"},/obj/structure/plasticflaps{opacity = 1},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/window/northleft{dir = 8; name = "MuleBot Access"; req_access_txt = "50"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/medical/medbay2{name = "Medbay Storage"})
|
||||
"cgd" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 4; location = "Medbay"},/obj/structure/plasticflaps{opacity = 1},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/window/northleft{dir = 8; name = "MuleBot Access"; req_access_txt = "50"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/medical/medbay2{name = "Medbay Storage"})
|
||||
"cge" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whiteblue"},/area/medical/medbay2{name = "Medbay Storage"})
|
||||
"cgf" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay2{name = "Medbay Storage"})
|
||||
"cgg" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay2{name = "Medbay Storage"})
|
||||
@@ -5849,7 +5849,7 @@
|
||||
"ciy" = (/obj/item/weapon/wrench,/obj/item/clothing/suit/apron,/obj/item/clothing/accessory/armband/hydro,/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/hydroponics)
|
||||
"ciz" = (/obj/item/weapon/reagent_containers/spray/plantbgone{pixel_x = 0; pixel_y = 3},/obj/item/weapon/reagent_containers/spray/plantbgone{pixel_x = 8; pixel_y = 8},/obj/item/weapon/reagent_containers/spray/plantbgone{pixel_x = 13; pixel_y = 5},/obj/item/weapon/watertank,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/item/weapon/grenade/chem_grenade/antiweed,/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hydroponics)
|
||||
"ciA" = (/obj/machinery/door/window/eastright{dir = 1; name = "Hydroponics Delivery"; req_access_txt = "35"},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/hydroponics)
|
||||
"ciB" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "Hydroponics"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/hydroponics)
|
||||
"ciB" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "Hydroponics"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/hydroponics)
|
||||
"ciC" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating{tag = "icon-warnplate (WEST)"; icon_state = "warnplate"; dir = 8},/area/maintenance/starboard)
|
||||
"ciD" = (/obj/effect/decal/cleanable/cobweb,/obj/machinery/atmospherics/unary/tank/toxins{dir = 4},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/incinerator)
|
||||
"ciE" = (/obj/machinery/atmospherics/binary/pump{dir = 4; name = "plasma tank pump"},/obj/structure/sign/nosmoking_2{pixel_x = 0; pixel_y = 28},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/incinerator)
|
||||
@@ -6027,7 +6027,7 @@
|
||||
"clU" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 4},/obj/machinery/light_switch{pixel_x = 11; pixel_y = 23},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/medical/sleeper{name = "Sleepers"})
|
||||
"clV" = (/obj/item/weapon/storage/firstaid/regular{pixel_x = 3; pixel_y = -3},/obj/item/weapon/storage/firstaid/brute{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/brute,/obj/item/weapon/storage/firstaid/brute{pixel_x = -3; pixel_y = -3},/obj/machinery/power/apc{dir = 2; name = "Medbay Storage APC"; pixel_y = -24},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/machinery/light_switch{pixel_x = -26; pixel_y = 0},/obj/machinery/light/small,/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 10; icon_state = "whiteblue"},/area/medical/medbay2{name = "Medbay Storage"})
|
||||
"clW" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/medical/medbay2{name = "Medbay Storage"})
|
||||
"clX" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/bot/cleanbot{name = "Scrubs, MD"; on = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/medical/medbay2{name = "Medbay Storage"})
|
||||
"clX" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/mob/living/simple_animal/bot/cleanbot{name = "Scrubs, MD"; on = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/medical/medbay2{name = "Medbay Storage"})
|
||||
"clY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/medical/medbay2{name = "Medbay Storage"})
|
||||
"clZ" = (/obj/item/weapon/storage/firstaid/regular{pixel_x = 3; pixel_y = -3},/obj/item/weapon/storage/firstaid/o2{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/o2,/obj/item/weapon/storage/firstaid/o2{pixel_x = -3; pixel_y = -3},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 6; icon_state = "whiteblue"},/area/medical/medbay2{name = "Medbay Storage"})
|
||||
"cma" = (/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 10; icon_state = "whiteblue"},/area/medical/medbay{name = "Medbay Central"})
|
||||
@@ -6335,7 +6335,7 @@
|
||||
"crQ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/research{name = "Research Division"})
|
||||
"crR" = (/obj/machinery/shower{tag = "icon-shower (WEST)"; icon_state = "shower"; dir = 8},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = -28},/turf/simulated/floor/plasteel{dir = 6; icon_state = "warnwhite"},/area/medical/research{name = "Research Division"})
|
||||
"crS" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/closet/firecloset,/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/medical/research{name = "Research Division"})
|
||||
"crT" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Research Division"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/maintenance/aft{name = "Aft Maintenance"})
|
||||
"crT" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 2; location = "Research Division"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/maintenance/aft{name = "Aft Maintenance"})
|
||||
"crU" = (/turf/simulated/wall/r_wall,/area/maintenance/aft{name = "Aft Maintenance"})
|
||||
"crV" = (/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,/obj/structure/table/glass,/obj/item/weapon/folder/white{pixel_y = 2},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellowfull"; tag = "icon-whitehall (WEST)"},/area/medical/chemistry)
|
||||
"crW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atm{pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/hallway/primary/aft)
|
||||
@@ -6640,7 +6640,7 @@
|
||||
"cxJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29},/turf/simulated/floor/plasteel{dir = 1; icon_state = "yellowcorner"},/area/hallway/primary/aft)
|
||||
"cxK" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/hallway/primary/aft)
|
||||
"cxL" = (/obj/machinery/power/apc{cell_type = 5000; dir = 4; name = "Aft Hallway APC"; pixel_x = 24; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "purplecorner"},/area/hallway/primary/aft)
|
||||
"cxM" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=1"; freq = 1400; location = "Research and Development"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/toxins/lab)
|
||||
"cxM" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 1; location = "Research and Development"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/toxins/lab)
|
||||
"cxN" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Research Lab Maintenance"; req_access_txt = "7"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/toxins/lab)
|
||||
"cxO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/medical/research{name = "Research Division"})
|
||||
"cxP" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"})
|
||||
@@ -7630,7 +7630,7 @@
|
||||
"cQL" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
|
||||
"cQM" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
|
||||
"cQN" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 5; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
|
||||
"cQO" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=1"; freq = 1400; location = "Robotics"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/assembly/robotics)
|
||||
"cQO" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 1; location = "Robotics"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/assembly/robotics)
|
||||
"cQP" = (/obj/machinery/door/airlock/maintenance{name = "Robotics Maintenance"; req_access_txt = "29"},/turf/simulated/floor/plating,/area/assembly/robotics)
|
||||
"cQQ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/research{name = "Research Shuttle and Xenobiology"; req_access_txt = "47"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"})
|
||||
"cQR" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/aft{name = "Aft Maintenance"})
|
||||
@@ -7906,7 +7906,7 @@
|
||||
"cWb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-warningcorner (WEST)"; icon_state = "warningcorner"; dir = 8},/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
|
||||
"cWc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/item/device/radio/beacon,/obj/machinery/embedded_controller/radio/airlock/docking_port_multi{id_tag = "escape_dock_north_airlock"; master_tag = "escape_dock"; pixel_y = 30; req_one_access_txt = "13"; tag_airpump = "escape_dock_north_pump"; tag_chamber_sensor = "escape_dock_north_sensor"; tag_exterior_door = "escape_dock_north_outer"; tag_interior_door = "escape_dock_north_inner"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
|
||||
"cWd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-warningcorner (EAST)"; icon_state = "warningcorner"; dir = 4},/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
|
||||
"cWe" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=9.5-Escape2"; location = "9-Escape"},/obj/machinery/bot/secbot{auto_patrol = 1; health = 35; maxhealth = 35; name = "Inspector Johnson"},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
|
||||
"cWe" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=9.5-Escape2"; location = "9-Escape"},/mob/living/simple_animal/bot/secbot{auto_patrol = 1; health = 35; maxHealth = 35; name = "Inspector Johnson"},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
|
||||
"cWf" = (/obj/machinery/camera{c_tag = "Departure Lounge - Starboard Aft"; dir = 8; network = list("SS13")},/obj/machinery/light{dir = 4},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/obj/structure/flora/kirbyplants{icon_state = "plant-16"; layer = 4.1; tag = "icon-plant-16"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
|
||||
"cWg" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -26; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/toxins/xenobiology{name = "\improper Secure Lab"})
|
||||
"cWh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{tag = "icon-warnwhite (NORTH)"; icon_state = "warnwhite"; dir = 1},/area/toxins/xenobiology{name = "\improper Secure Lab"})
|
||||
@@ -8106,7 +8106,7 @@
|
||||
"cZT" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape)
|
||||
"cZU" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape)
|
||||
"cZV" = (/obj/item/weapon/cigbutt,/turf/simulated/shuttle/plating{icon_state = "floorgrime"},/area/shuttle/escape)
|
||||
"cZW" = (/obj/machinery/bot/medbot{name = "\improper emergency medibot"; pixel_x = -3; pixel_y = 2},/obj/structure/closet/crate/medical{name = "medical crate"},/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/o2{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/toxin{pixel_x = -4; pixel_y = 3},/obj/item/device/healthanalyzer{pixel_x = 3; pixel_y = 3},/obj/item/weapon/lazarus_injector,/turf/simulated/shuttle/plating{icon_state = "bot"},/area/shuttle/escape)
|
||||
"cZW" = (/mob/living/simple_animal/bot/medbot{name = "\improper emergency medibot"; pixel_x = -3; pixel_y = 2},/obj/structure/closet/crate/medical{name = "medical crate"},/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/o2{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/toxin{pixel_x = -4; pixel_y = 3},/obj/item/device/healthanalyzer{pixel_x = 3; pixel_y = 3},/obj/item/weapon/lazarus_injector,/turf/simulated/shuttle/plating{icon_state = "bot"},/area/shuttle/escape)
|
||||
"cZX" = (/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen #1"; req_access_txt = "55"},/obj/machinery/door/poddoor/preopen{id_tag = "xenobio3"; name = "containment blast door"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel,/area/toxins/xenobiology{name = "\improper Secure Lab"})
|
||||
"cZY" = (/obj/machinery/door/window/northleft{dir = 4; name = "Containment Pen #1"; req_access_txt = "55"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/toxins/xenobiology{name = "\improper Secure Lab"})
|
||||
"cZZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology{name = "\improper Secure Lab"})
|
||||
|
||||
@@ -938,7 +938,7 @@
|
||||
"sb" = (/obj/machinery/light/small{dir = 4},/obj/structure/stool/bed/roller,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/mine/laborcamp)
|
||||
"sc" = (/obj/structure/closet/crate/internals,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "floorgrime"; temperature = 273.15},/area/mine/laborcamp)
|
||||
"sd" = (/obj/machinery/light/small,/turf/simulated/floor/plasteel{icon_state = "floorgrime"; temperature = 273.15},/area/mine/laborcamp)
|
||||
"se" = (/obj/machinery/bot/secbot/beepsky{desc = "Powered by tears and swet of laborer."; name = "Prison Ofitser"},/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=2-NMine"; location = "1-Storage"},/turf/simulated/floor/plasteel{icon_state = "asteroidfloor"; temperature = 273.15},/area/mine/laborcamp)
|
||||
"se" = (/mob/living/simple_animal/bot/secbot/beepsky{desc = "Powered by tears and swet of laborer."; name = "Prison Ofitser"},/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=2-NMine"; location = "1-Storage"},/turf/simulated/floor/plasteel{icon_state = "asteroidfloor"; temperature = 273.15},/area/mine/laborcamp)
|
||||
"sf" = (/obj/structure/plasticflaps/mining,/turf/simulated/floor/plasteel{icon_state = "asteroidfloor"; temperature = 273.15},/area/mine/laborcamp)
|
||||
"sg" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=3-SMine"; location = "2-NMine"},/turf/simulated/floor/plasteel{icon_state = "asteroidfloor"; temperature = 273.15},/area/mine/laborcamp)
|
||||
"sh" = (/turf/simulated/floor/plating{icon_plating = "asteroidplating"; icon_state = "asteroidplating"; temperature = 273.15},/area/mine/explored)
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
"bo" = (/obj/structure/table,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/storage/box/syringes,/turf/simulated/floor/wood,/area/awaymission/challenge/main)
|
||||
"bp" = (/turf/simulated/floor/wood,/area/awaymission/challenge/main)
|
||||
"bq" = (/obj/structure/mineral_door/wood{tag = "icon-wood"; icon_state = "wood"},/turf/simulated/floor/wood,/area/awaymission/challenge/main)
|
||||
"br" = (/obj/machinery/bot/medbot/mysterious,/turf/simulated/floor/wood,/area/awaymission/challenge/main)
|
||||
"br" = (/mob/living/simple_animal/bot/medbot/mysterious,/turf/simulated/floor/wood,/area/awaymission/challenge/main)
|
||||
"bs" = (/obj/machinery/space_heater,/turf/simulated/floor/wood,/area/awaymission/challenge/main)
|
||||
"bt" = (/obj/structure/table,/obj/item/clothing/accessory/stethoscope,/obj/item/bodybag,/obj/item/weapon/storage/box/beakers,/turf/simulated/floor/wood,/area/awaymission/challenge/main)
|
||||
"bu" = (/obj/machinery/vending/cola,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main)
|
||||
|
||||
@@ -254,7 +254,7 @@
|
||||
"eT" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 120; icon_state = "in"; initialize_directions = 1; internal_pressure_bound = 4000; on = 1; pressure_checks = 2; pump_direction = 0},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/awaymission/research)
|
||||
"eU" = (/obj/machinery/r_n_d/server{stat = 1},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/awaymission/research)
|
||||
"eV" = (/obj/machinery/power/emitter{anchored = 1; dir = 1; icon_state = "emitter"; state = 2},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/research)
|
||||
"eW" = (/obj/machinery/bot/medbot/mysterious{desc = "A dark little medical robot. She looks somewhat underwhelmed."; name = "Nightingale"},/turf/simulated/shuttle/floor{icon_state = "floor4"; nitrogen = 0.01; oxygen = 0.01; temperature = 2.7},/area/awaymission/syndishuttle)
|
||||
"eW" = (/mob/living/simple_animal/bot/medbot/mysterious{desc = "A dark little medical robot. She looks somewhat underwhelmed."; name = "Nightingale"},/turf/simulated/shuttle/floor{icon_state = "floor4"; nitrogen = 0.01; oxygen = 0.01; temperature = 2.7},/area/awaymission/syndishuttle)
|
||||
"eX" = (/obj/structure/table,/turf/simulated/shuttle/floor{icon_state = "floor4"; nitrogen = 0.01; oxygen = 0.01; temperature = 2.7},/area/awaymission/syndishuttle)
|
||||
"eY" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel/airless{icon_state = "floorscorched1"},/area/awaymission/northblock)
|
||||
"eZ" = (/turf/simulated/floor/plasteel,/area/awaymission/northblock)
|
||||
|
||||
@@ -690,7 +690,7 @@
|
||||
"ann" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/security/main)
|
||||
"ano" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Security Office"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/security/main)
|
||||
"anp" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Security Office"; req_access_txt = "63"},/turf/simulated/floor/plasteel,/area/security/main)
|
||||
"anq" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=1"; dir = 1; freq = 1400; location = "Security"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
|
||||
"anq" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/mob/living/simple_animal/bot/floorbot{on = 0},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
"anr" = (/obj/machinery/light/small{dir = 1},/obj/structure/closet/emcloset,/obj/machinery/camera{c_tag = "Security Pod"; dir = 2; network = list("SS13")},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
|
||||
"ans" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"; dir = 2},/area/shuttle/pod_3)
|
||||
"ant" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst{dir = 4},/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/shuttle/pod_3)
|
||||
@@ -1255,7 +1255,7 @@
|
||||
"ayg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
"ayh" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
"ayi" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
"ayj" = (/obj/machinery/bot/secbot/beepsky{name = "Officer Beepsky"},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
"ayj" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 1; location = "Security"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
|
||||
"ayk" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
"ayl" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
"aym" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
@@ -2334,7 +2334,7 @@
|
||||
"aST" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/sign/securearea{desc = "Under the painting a plaque reads: 'While the meat grinder may not have spared you, fear not. Not one part of you has gone to waste... You were delicious.'"; icon_state = "monkey_painting"; name = "Mr. Deempisi portrait"; pixel_x = -28; pixel_y = 4},/obj/structure/reagent_dispensers/beerkeg,/turf/simulated/floor/wood,/area/crew_quarters/bar)
|
||||
"aSU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/crew_quarters/bar)
|
||||
"aSV" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/window/southleft{tag = "icon-left (WEST)"; name = "Bar Delivery"; icon_state = "left"; dir = 8; req_access_txt = "25"; base_state = "left"},/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel,/area/crew_quarters/bar)
|
||||
"aSW" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Bar"},/obj/structure/plasticflaps{opacity = 1},/obj/effect/decal/warning_stripes/yellow/hollow,/turf/simulated/floor/plasteel,/area/maintenance/fsmaint2)
|
||||
"aSW" = (/obj/machinery/hologram/holopad,/mob/living/simple_animal/bot/secbot/beepsky{name = "Officer Beepsky"},/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
|
||||
"aSX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
|
||||
"aSY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
|
||||
"aSZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
|
||||
@@ -2342,7 +2342,7 @@
|
||||
"aTb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/wall,/area/crew_quarters/kitchen)
|
||||
"aTc" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/wall,/area/crew_quarters/kitchen)
|
||||
"aTd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Kitchen Maintenance"; req_access_txt = "28"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
|
||||
"aTe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Kitchen"},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/maintenance/fsmaint2)
|
||||
"aTe" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "Bar"},/obj/structure/plasticflaps{opacity = 1},/obj/effect/decal/warning_stripes/yellow/hollow,/turf/simulated/floor/plasteel,/area/maintenance/fsmaint2)
|
||||
"aTf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
|
||||
"aTg" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
|
||||
"aTh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
|
||||
@@ -2399,7 +2399,7 @@
|
||||
"aUg" = (/obj/structure/table,/obj/item/weapon/storage/belt/utility,/obj/item/weapon/storage/firstaid/regular,/turf/simulated/floor/plasteel,/area/storage/primary)
|
||||
"aUh" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plasteel,/area/storage/primary)
|
||||
"aUi" = (/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/storage/primary)
|
||||
"aUj" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "Tool Storage"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/storage/primary)
|
||||
"aUj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery"; location = "Kitchen"},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/maintenance/fsmaint2)
|
||||
"aUk" = (/obj/structure/disposalpipe/trunk,/obj/machinery/disposal,/turf/simulated/floor/plasteel,/area/storage/primary)
|
||||
"aUl" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/obj/structure/cable{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/hallway/primary/port)
|
||||
"aUm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/hallway/primary/port)
|
||||
@@ -2441,7 +2441,7 @@
|
||||
"aUW" = (/obj/machinery/light/small{dir = 1},/obj/item/device/radio/intercom{broadcasting = 0; name = "station intercom (General)"; pixel_y = 25},/obj/structure/closet/chefcloset,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen)
|
||||
"aUX" = (/obj/machinery/camera{c_tag = "Kitchen Freezer"; network = list("SS13")},/obj/machinery/chem_master/condimaster{name = "CondiMaster Neo"; pixel_x = -5},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen)
|
||||
"aUY" = (/obj/machinery/door/window/southleft{base_state = "left"; dir = 2; icon_state = "left"; name = "Kitchen Delivery"; req_access_txt = "28"},/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen)
|
||||
"aUZ" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Hydroponics"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/maintenance/fsmaint2)
|
||||
"aUZ" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "Tool Storage"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/storage/primary)
|
||||
"aVa" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/hydroponics)
|
||||
"aVb" = (/turf/simulated/wall,/area/hydroponics)
|
||||
"aVc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall,/area/hydroponics)
|
||||
@@ -3885,7 +3885,7 @@
|
||||
"bwK" = (/obj/item/weapon/folder/yellow,/obj/item/weapon/pen{pixel_x = 4; pixel_y = 4},/obj/structure/table/reinforced,/turf/simulated/floor/plasteel{icon_state = "arrival"; dir = 4},/area/quartermaster/office)
|
||||
"bwL" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/west)
|
||||
"bwM" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "bluecorner"},/area/hallway/primary/central/west)
|
||||
"bwN" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=1"; dir = 1; freq = 1400; location = "Bridge"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/bridge/meeting_room)
|
||||
"bwN" = (/obj/machinery/navbeacon{codes_txt = "delivery"; location = "Hydroponics"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/maintenance/fsmaint2)
|
||||
"bwO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "Conference Room"; req_access = null; req_access_txt = "19"},/turf/simulated/floor/wood,/area/bridge/meeting_room)
|
||||
"bwP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/lattice,/turf/space,/area/space)
|
||||
"bwQ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/space,/area/space)
|
||||
@@ -4499,7 +4499,7 @@
|
||||
"bIA" = (/turf/simulated/floor/plating,/area/quartermaster/storage)
|
||||
"bIB" = (/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/quartermaster/storage)
|
||||
"bIC" = (/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/quartermaster/storage)
|
||||
"bID" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "QM #1"},/obj/machinery/bot/mulebot{beacon_freq = 1400; home_destination = "QM #1"; suffix = "#1"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/storage)
|
||||
"bID" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 1; location = "Bridge"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/bridge/meeting_room)
|
||||
"bIE" = (/obj/structure/table,/obj/machinery/requests_console{department = "Cargo Bay"; name = "Cargo Requests Console"; departmentType = 2; pixel_x = -30; pixel_y = 0},/obj/machinery/camera{c_tag = "Cargo Office"; dir = 4; network = list("SS13")},/obj/item/stack/sheet/glass{amount = 50; pixel_x = 3; pixel_y = 3},/obj/item/stack/sheet/metal{amount = 50},/obj/item/device/multitool,/turf/simulated/floor/plasteel,/area/quartermaster/office)
|
||||
"bIF" = (/obj/structure/filingcabinet/filingcabinet,/turf/simulated/floor/plasteel,/area/quartermaster/office)
|
||||
"bIG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/office)
|
||||
@@ -4588,7 +4588,7 @@
|
||||
"bKl" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "swall_f5"; dir = 2},/area/shuttle/research)
|
||||
"bKm" = (/obj/machinery/door/firedoor{dir = 2},/obj/machinery/door/airlock/external{id_tag = "supply_home"; name = "Cargo Docking Hatch"; req_access_txt = "31"},/turf/simulated/floor/plating,/area/quartermaster/storage)
|
||||
"bKn" = (/obj/effect/decal/warning_stripes/southeastcorner,/obj/effect/decal/warning_stripes/northeastcorner,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit)
|
||||
"bKo" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "QM #2"},/obj/machinery/bot/mulebot{home_destination = "QM #2"; suffix = "#2"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/storage)
|
||||
"bKo" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "QM #1"},/mob/living/simple_animal/bot/mulebot{home_destination = "QM #1"; suffix = "#1"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/storage)
|
||||
"bKp" = (/obj/structure/table,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/item/weapon/folder/yellow,/obj/item/device/eftpos,/turf/simulated/floor/plasteel,/area/quartermaster/office)
|
||||
"bKq" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/office)
|
||||
"bKr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/quartermaster/office)
|
||||
@@ -4648,7 +4648,7 @@
|
||||
"bLt" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"})
|
||||
"bLu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"})
|
||||
"bLv" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Research Division Delivery"; req_access_txt = "47"},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/medical/research{name = "Research Division"})
|
||||
"bLw" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "Research Division"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/medical/research{name = "Research Division"})
|
||||
"bLw" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "QM #2"},/mob/living/simple_animal/bot/mulebot{home_destination = "QM #2"; suffix = "#2"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/storage)
|
||||
"bLx" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/medical/research{name = "Research Division"})
|
||||
"bLy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/medical/research{name = "Research Division"})
|
||||
"bLz" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/glass_research{name = "Research Shuttle Dock"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research_shuttle_dock)
|
||||
@@ -4660,7 +4660,7 @@
|
||||
"bLF" = (/obj/machinery/door/airlock/external{id_tag = "s_docking_airlock"; name = "Shuttle Hatch"; req_access_txt = "31"},/turf/simulated/shuttle/floor,/area/shuttle/supply)
|
||||
"bLG" = (/obj/machinery/conveyor_switch/oneway{convdir = -1; id = "QMLoad"},/turf/simulated/floor/plasteel,/area/quartermaster/storage)
|
||||
"bLH" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1},/turf/simulated/floor/plasteel,/area/quartermaster/storage)
|
||||
"bLI" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "QM #3"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/storage)
|
||||
"bLI" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "Research Division"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/medical/research{name = "Research Division"})
|
||||
"bLJ" = (/obj/structure/table,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/item/weapon/storage/belt/utility,/turf/simulated/floor/plasteel,/area/quartermaster/office)
|
||||
"bLK" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/plasteel,/area/quartermaster/office)
|
||||
"bLL" = (/obj/machinery/light,/obj/machinery/computer/merch,/turf/simulated/floor/plasteel,/area/quartermaster/office)
|
||||
@@ -4747,7 +4747,7 @@
|
||||
"bNo" = (/obj/machinery/light,/turf/simulated/floor/plasteel{dir = 8; icon_state = "loadingarea"},/area/quartermaster/storage)
|
||||
"bNp" = (/obj/machinery/camera{c_tag = "Cargo Bay South"; dir = 1},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable,/turf/simulated/floor/plasteel,/area/quartermaster/storage)
|
||||
"bNq" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/plasteel,/area/quartermaster/storage)
|
||||
"bNr" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "QM #4"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/storage)
|
||||
"bNr" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "QM #3"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/storage)
|
||||
"bNs" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{pixel_x = 6; pixel_y = -5},/obj/machinery/newscaster{pixel_x = -27; pixel_y = 1},/turf/simulated/floor/plasteel,/area/quartermaster/office)
|
||||
"bNt" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable{d2 = 4; icon_state = "0-4"},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/quartermaster/office)
|
||||
"bNu" = (/obj/machinery/light,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/computer/guestpass{pixel_y = -28},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "browncorner"},/area/quartermaster/office)
|
||||
@@ -5242,7 +5242,7 @@
|
||||
"bWP" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/janitor)
|
||||
"bWQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/reagent_dispensers/spacecleanertank{pixel_y = 30},/turf/simulated/floor/plasteel,/area/janitor)
|
||||
"bWR" = (/obj/machinery/door/window/westleft{name = "Janitoral Delivery"; req_access_txt = "26"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/janitor)
|
||||
"bWS" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "Janitor"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/maintenance/asmaint)
|
||||
"bWS" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "QM #4"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/storage)
|
||||
"bWT" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/asmaint)
|
||||
"bWU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/medical/paramedic)
|
||||
"bWV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light{dir = 8},/obj/item/device/radio/intercom{broadcasting = 0; name = "station intercom (General)"; pixel_y = 25},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/paramedic)
|
||||
@@ -5651,7 +5651,7 @@
|
||||
"ceI" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/simulated/floor/plating,/area/maintenance/asmaint)
|
||||
"ceJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint)
|
||||
"ceK" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint)
|
||||
"ceL" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=4"; freq = 1400; location = "Medbay"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/maintenance/asmaint)
|
||||
"ceL" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "Janitor"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/maintenance/asmaint)
|
||||
"ceM" = (/obj/machinery/door/window/eastleft{name = "Medical Delivery"; req_access_txt = "5"},/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel,/area/medical/sleeper)
|
||||
"ceN" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"},/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 8},/area/medical/sleeper)
|
||||
"ceO" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"},/turf/simulated/floor/plasteel,/area/medical/sleeper)
|
||||
@@ -5791,7 +5791,7 @@
|
||||
"chs" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/obj/structure/disposalpipe/junction{tag = "icon-pipe-j2"; icon_state = "pipe-j2"; dir = 2},/turf/simulated/floor/plasteel{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft)
|
||||
"cht" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/aft)
|
||||
"chu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft)
|
||||
"chv" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/navbeacon{codes_txt = "delivery;dir=4"; freq = 1400; location = "Engineering"},/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/window/westright{name = "Engineering Monitoring Station"; req_access = null; req_access_txt = "0"; req_one_access_txt = "11;24"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/engine/controlroom)
|
||||
"chv" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 4; location = "Medbay"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/maintenance/asmaint)
|
||||
"chw" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/window/northleft{dir = 4; icon_state = "left"; name = "Engineering Monitoring Station"; req_access_txt = "0"; req_one_access_txt = "11;24"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/engine/controlroom)
|
||||
"chx" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "loadingarea"; tag = "loading"},/area/engine/controlroom)
|
||||
"chy" = (/turf/simulated/floor/plasteel,/area/engine/controlroom)
|
||||
@@ -7917,17 +7917,17 @@
|
||||
"cWm" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior)
|
||||
"cWn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior)
|
||||
"cWo" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior)
|
||||
"cWp" = (/obj/machinery/bot/secbot/pingsky,/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior)
|
||||
"cWp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 4; location = "Engineering"},/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/window/westright{name = "Engineering Monitoring Station"; req_access = null; req_access_txt = "0"; req_one_access_txt = "11;24;34"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/engine/controlroom)
|
||||
"cWq" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior)
|
||||
"cWr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior)
|
||||
"cWs" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/structure/cable,/obj/machinery/power/apc{dir = 4; name = "AI Satellite Antechamber APC"; pixel_x = 25},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior)
|
||||
"cWt" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/light/small{dir = 4},/obj/machinery/camera/motion{c_tag = "Mini Satellite Exterior North-West"; dir = 8; network = list("SS13","MiniSat")},/turf/simulated/floor/plating,/area/aisat)
|
||||
"cWu" = (/turf/simulated/wall,/area/aisat)
|
||||
"cWv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/bot/floorbot{on = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/turret_protected/aisat_interior)
|
||||
"cWv" = (/mob/living/simple_animal/bot/secbot/pingsky,/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior)
|
||||
"cWw" = (/obj/machinery/ai_status_display{pixel_y = -32},/obj/machinery/porta_turret{dir = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior)
|
||||
"cWx" = (/obj/machinery/camera/motion{c_tag = "Mini Satellite Antechamber"; dir = 1; network = list("SS13","MiniSat")},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior)
|
||||
"cWy" = (/obj/machinery/status_display{pixel_x = 0; pixel_y = -32},/obj/machinery/porta_turret{dir = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior)
|
||||
"cWz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/bot/cleanbot{on = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/turret_protected/aisat_interior)
|
||||
"cWz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/mob/living/simple_animal/bot/floorbot{on = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/turret_protected/aisat_interior)
|
||||
"cWA" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small{dir = 8},/obj/machinery/camera/motion{c_tag = "Mini Satellite Exterior North-East"; dir = 4; network = list("SS13","MiniSat")},/turf/simulated/floor/plating,/area/aisat)
|
||||
"cWB" = (/turf/simulated/wall/r_wall,/area/turret_protected/ai)
|
||||
"cWC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/turret_protected/ai)
|
||||
@@ -8472,7 +8472,7 @@
|
||||
"dgV" = (/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id_tag = "voxshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/shuttle/window{dir = 4; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_mid"; tag = "icon-window5 (EAST)"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox)
|
||||
"dgW" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/machinery/recharger{pixel_y = 0},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
"dgX" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
"dgY" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/machinery/bot/floorbot{on = 0},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
"dgY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/mob/living/simple_animal/bot/cleanbot{on = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/turret_protected/aisat_interior)
|
||||
"dgZ" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weed_extract,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
"dha" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/broken_device,/obj/item/robot_parts/chest,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
"dhb" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/scalpel,/obj/item/stack/cable_coil,/obj/item/weapon/storage/firstaid/regular,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
|
||||
@@ -8781,7 +8781,7 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFldiSdiUdiTbFlbikbFldiVdiVdiVbFlbikbFldiWdiYdiXbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaalabXabYabZacaacbaccacdaceacfacfaalbikbikbikbikbikabKabLabLabKbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgwdgNdgwbikbikdgOdgGdgydgPdgQdgydgydgGdgRbikbikdgwdgNdgwbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFldiVdiVdiVbFlbikcVGdiZdjbdjadelbikbFldiVdiVdiVbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacgacgacgacgacgacgachaciacjackaclaalacmbikbikbikbikbikabKabLabLabKbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgwdgNdgwdgwdgwdgwdgwdgwdgwdgSdgwdgwdgwdgwdgwdgwdgwdgNdgwbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcVGdiZdjbdjadelbikbikbikbikbikbikbikcVGdiZdjbdjadelbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacgacnacoacpacqacracsacdaalaalaalaalbikbikbikbikbikbikbikabKabLabLabKactactactacuacvactactactabKabKabKabKabKbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgHdgNdgTdgTdgTdgTdgTdgTdgmdgUdgmdgTdgTdgTdgTdgTdgTdgNdgJbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacgacwacxacyaczacAacBacCaalacDacEacEacEacEacEbikbikbikbikbikabKacFacGactacHacIacJacKacLacMactabLabLabLabLabLabKbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgVdgXdgWdgZdgYdhadgmdgSdgwdgSdgwdgSdgmdhcdhbdhedhddgXdhfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacgacwacxacyaczacAacBacCaalacDacEacEacEacEacEbikbikbikbikbikabKacFacGactacHacIacJacKacLacMactabLabLabLabLabLabKbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgVdgXdgWdgZanqdhadgmdgSdgwdgSdgwdgSdgmdhcdhbdhedhddgXdhfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikacgacNacOacPacQacRacSacCaalacEacEacUacTacVacEacEacEbikbikbikbikabKacGactacWacXacYacXacXacZactadaadaadaadaadaadaabLadbbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgOdgXdgydgydgydhgdgmdgydgydgydgydgydgmdgydgydhhdgydgXdgRbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacgacgacgacgacgacgadcaddacEacEadeadgadfadiadhacEacEbikbikbikbikbikabKactadjadkadladmadnadoactadpadqadradsadtaduadvbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgmdhjdhidhldhkdhmdgmdhndgydgydgydhodgmdhqdhpdhsdhrdhjdgmbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikadwadxadyadzadAadwadBadCacEadEadDadGadFadIadHadJacEbikbikbikbikbikbikactadKadLadMadNacXadOactadPadtadtadtadtaduadvbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgmdhtdhtdgwdgwdgwdgmdhudgydgydgydhvdgmdgwdgwdgwdhtdhtdgmbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
@@ -8800,7 +8800,7 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikbikaabbikaabbikbikajQbikbikaabbikaabbikbikacGbikbikbikbikbikbikbikbikbikbikbikbikaeAakFafyakGakHakIakJakKakLajtakMakNakOakOakPakQakRajuakSakTakUakVakiakWakXakYakZalaalbalcaldaleakqalfalgalhalialjalkallalmaiCaiCaiCalnajOaieaieaieaieaieaieaieaieahAaabaloaabaabaabaloaabbikbikaabaloaabaabbikbikaloaabbikaabaabajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGaabalpalpalpalpalpbikalqbikalpalpalpalpalpaabacGbikbikbikbikbikbikbikbikbikbikbikbikaeAalralsakGafyaltakJalualvajtalwalxalyalzakQakQakRajualAalBalCalDalEajBalFalGaklalHalIajFajXalKalLalLalMajdalNalOalPalQaiCaiFaiGaiCalRahAahAahAahAahAahAahAahAahAahAaabaloaabbikajkajlajmbikbikajkajlajmbikbikajkajlajmaabaabbikajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikalSalTalTalTalTalUalValWalXalXalXalXalYbikacGbikbikbikamaalZaowanxambbikbikbikamcaeAaeAaeAamdamdameamfamgamdajuamhamiamjamkamlammamnajuamoampamqakVamrajGamsamtaXNamvamwajGamxamyamzamAamBamCamDamEamFamGaiCajhamHamIamJahAamKamKamKamKamKbikbikbikbikaabaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmbikbikbikajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGaabamLamLamLamLamLbikamMbikamLamLamLamLamLaabacGbikbikbikamOamNamQamPamOamRamSamSamTamUamVamWamXamYamZanaanbancajuajuandaneajuajuajuajuajuanfanganhanianfajGajBajCanjajEajFajGankanlanmannahUahUahUahUannanoanpanmahUahAanqahAanrantansansanubikbikbikbikbikaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmbikbikbikajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGaabamLamLamLamLamLbikamMbikamLamLamLamLamLaabacGbikbikbikamOamNamQamPamOamRamSamSamTamUamVamWamXamYamZanaanbancajuajuandaneajuajuajuajuajuanfanganhanianfajGajBajCanjajEajFajGankanlanmannahUahUahUahUannanoanpanmahUahAayjahAanrantansansanubikbikbikbikbikaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmbikbikbikajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikbikbikaabbikbikbikanvbikbikbikaabbikbikbikaabbikbikbikaEEanwanzanyanBanAanDanCanAanGanGanHanIanJanKanLanManNanOanPanQanRanSanTanSanSanUanVanWanXanYanSanZaoaaobaocaodaoeaofaogaohanSaoiaojaokaolaomaonaooaopaoqaoraosaplaotaovaEHaouaoyaoxbikbikbikbikbikaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmbikbikbikajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGaabalpalpalpalpalpbikamMbikalpalpalpalpalpaabacGbikbikbikamOanEaoAanFamOamRamSamSamSaoBaoHaoIaoJaoKaoLaoMaoNaoOaoPaoQaoRaoSaoTaoUaoVaoWaoXaoYaoWaoZapaaoTapbapcapdaoTaoTapdaoXapcapeaoTaoTapbapcaoVapfapgaphapiapjapkaplapmapnaovaozansansapobikaacapqaacbikaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmbikaabaabajkajPajmaabaabagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikbikbikbikbikbikajjbikalSalTalTalTalTalUalValWalXalXalXalXalYbikacGbikbikbikamOaoCaoCaoDamObikbikbikapwapwapxapyapzapAapAapAapBapBapBapBapCapDapEapEapEapFapGapHapFapEapEapEapIapJapKapLapMapKapNapJapOapOapOapPapQapOapRapSapTapUapVapWapXapmapnapYapYamKapZapZapZamKaqaamKaabaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmaabaabbikaabaiIaabbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
@@ -8813,7 +8813,7 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikbikbikbikbikbikacGacGacGaabaabaabaabavtavuavtaabaabaabaabacGacGacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapwavvanGavwasUascavxavyavzavAashasiavBashavCavDashavEaspashavFavGavHavGavGavHavGavIapOatiavJapOavKapOavLavMavNavOavPavQavRavSavTavUavUavUavVavWavXavYavYavYbikbikbikbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikaabaabavZawaavZaabaabbikaabbikbikaabaabbikbikbikbikbikbikasMawbawcawdaweawfawgatJatJatJawhawiatJawjasMbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikaahbikbikbikbikaabbikaabbikbikaabbikavtawkawlbikbikaabbikbikaabbikbikbikbikbikbikbikbikbikbikawmawmawmawmawmawmapwapwawnapwasUasUasUawoawpawqawrawrawsawrawsawrawrawtasZasZasvawvawwawuawvawwawuawyawzawzawzawzawzapOawAawBawCawCawDawCawEawFavUawGawHawIavVawJawKawLawMavWbikbikbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikaabbikavZawNavZbikaabbikaabbikbikbikaabaabbikbikbikbikbikasMawOawPavlawQawRawSawTatJawUawVawWawXasMawYaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikbikbikbikbikbikaabbikaabbikbikaabavtavtawZaxaavtbikaabbikbikaabbikbikbikbikbikbikbikbikbikbikawmaxbaxcaxdaxeaxfaxgaxhaxiaxhaxjaxhaxhaxkaxlaxlaxlaxlaxlaxmaxnaxoaxlaxlaxlaxlaxpaxlaxlaxlaxlaxqaxraxsaxtaxuaxvaxwaxxapWaxyaxzaxAaxBaxCaxDaxEaxFavUaxGaxHaxIavVaxKaxLaxJaAZavWbikbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikbikaabavZavZaxMavZavZaabbikaabbikbikbikbikaabaabbikbikbikbikasMaxNaxOavlasMavlavlaxPaxQasMasMasMasMasMasMaabaabbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsbikbikbikbikbikbikaabaabbikaabbikbikaabaxRaxSaxTaxUaxRaxVaxVbikbikaabbikbikbikbikbikbikbikbikbikbikawmaxWaxXaxYaxZayaaybaycaydayeayfaxqaxqaygaxqaxqaxqaxqaxqayhaxqaxqaxqaxqaxqaxqayiaxqaxqaxqaxqayjaxqaykaxqaylaxqaymaynapWayoaypayqayraysaytaxEayuavUayvaywayxayyayzayAayBawMavWbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikbikbikaabayCayDayEayFayCaabbikaabbikbikaabbikbikaabaabbikbikayGasMavlasMavlayHayIayHayJayHayHayHayKayGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsbikbikbikbikbikbikaabaabbikaabbikbikaabaxRaxSaxTaxUaxRaxVaxVbikbikaabbikbikbikbikbikbikbikbikbikbikawmaxWaxXaxYaxZayaaybaycaydayeayfaxqaxqaygaxqaxqaxqaxqaxqayhaxqaxqaxqaxqaxqaxqayiaxqaxqaxqaxqaSWaxqaykaxqaylaxqaymaynapWayoaypayqayraysaytaxEayuavUayvaywayxayyayzayAayBawMavWbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikbikbikaabayCayDayEayFayCaabbikaabbikbikaabbikbikaabaabbikbikayGasMavlasMavlayHayIayHayJayHayHayHayKayGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikaxVaxVaxVaxVaxVaabaabaxRayLayMayNaxRayOaxVbikbikaabbikbikbikbikbikbikbikbikbikbikawmayPayQayRaySayTawmayUayVayWayXayYayZazaazbazcayXayXayXazdayXayXayXayXayXayXazeazfazgazgazgazhaziazjaziazkazlazmaznapWazoazoazoazoazoazoaxEaxFavUazpaxHazqavVcscazraxJcvYavWbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikbikbikbikaabayCazsaztazuayCaabbikaabbikbikaabbikbikayGazvayGazvayGayKayHayHayHayHayHayHayHayHayHazwazxayGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikazyazzazybikbikbikaxVaxVaxVaxVazAazBazCaxVbikbikaxRazDazEazFazGazHaxVbikbikaabbikbikbikbikbikbikbikbikbikbikawmawmawmawmawmawmawmazIazIazJazKazKazLazMazNazOazPazPazOazQazOazRazRazRazRazRazRazSazRazRazTazUazVazWazIazXazIazYazIazIaqVazZaovaovaovaovaAaaxFavUaAbaxHaAcavVaAdayAayBawMavWbikbikbikbikbikbikbikbikaabaabbikbikbikbikazyaAeazybikaabayCaAfaAgaAhayCaAiaAiaAiaAiaAiazvazvazvayGaAjayHazwazxayJayHayJayJayJayGaAkayGayGayGayGayGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikaAlaAmaAlbikbikaabaxVaAnaAoaApazHaAqazHaxVaAlaAlaxRaxRaAraAsazGazHaxVaxVaAlaAlaAlaxVaxVbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikazJaAtaAuaAvazMaAwazOaAxaAyaAzaAAaABaACaADaAEaAFaAGaAHaAIaAJaAKaALaxqaxraAMaANaAOaAPaAQaAPaAPaAPaARaAPaAPaAPaAPaASaATaAUaAVaAWaAXaAYcNsaBaaUadcuavWaabaBbaBcaBcaBcaBcaBcaBdaabaabbikbikbikbikazvaBeazvbikaAiayCayCaBfaBgayCaBhayHayHayHayJaBiayHaBjayGayHayHayHaBkayJayHayGaBlaBmayGayHaBnayGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
@@ -8831,8 +8831,8 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaNhaNiaNjaNiaNiaNkaNlaNiaNiaNjaNmaNnaCuaKBaNoaMoaNpaNqaNraNsaNtaNuaKHaLHaMqaLJaNvaMqaMqaLHaKHaNwaNxaNyaNzaNAaNBaNCaNDaNEaNFaMvaabaLRaNGaNHaNIaNJaNKaLRaabaJGaJLaJMaNLaNMaNNaNOaNPaJMaGvaIKaJNaJOaNQaNRaLXaJOaNSaJOaLXaNTaNUaJOaJYaIKaJZaxqaNVazIaKbaEeaEfaCZaDaaDbaNWaNXaMcaNYaMQaMQaMQaNZaOaaObaOcaMeaOdaOeaOfaOgaOhazxbikbikbikbikbikbikbikbikbikayGaOiaOjaOkaOlaOmayGaEtayHaHVaDxayHayGbikayGayHayHayHayHaDxaOnaOoaOpaOpaOpaOpaOqaOraOsaOtaOuaOvaOuaOwaOxaOxaOyaOzaOAaOBaOCaOCbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaNhaNmaNiaODaOEaOFaOGaOHaOIaOJaOKaOLaOMaONaOOaKzaKBaOPaMoaOQaORaOSaOTaOSaOUaKHaOVaMqaOWaOXaOYaOXaOZaPaaPbaPcaPdaPdaPdaPdaPdaPdaPeaPfaMvbikaLRaPgaNHaPhaNJaPiaLRbikaJGaJLaJMaPjaPkaPlaPmaPnaJMaGvaIKaPoaPoaKPaPpaMHaKSaPqaKSaMHaPraKWaPsaPsaIKaPtazUaPuazIaKbaEeaPvaPvaPvaPvaPwaPxaPyaPzaPAaPBaPBaPBaPCaPBaPDaPEaPFaPGaPHaPEaPIaPJazxayGayGayGayGayGayGayGayGayGayGayGayGaBMayGayGayGayGayHaDxaOiazvaabazvayHaPLaPMaPNaPOaPPaPQaPRaPRaPRaPRaPSaPTaPUaPVaPWaPXaPWaPYaPWaPWaPZaQaaQbaQbaQcaQdaQeaQeaQeaQeaQeaQeaQeaQeaQeabLadbbikbikbikbikbikbikbikaaabdBaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaONaQgaQhaQiaOMaQjaOFaQjaOFaQjaOFaQjaOMaQkaQlaKzaKBaQmaMoaQnaQoaQpaQqaQraQsaKHaQtaMqaQuaQvaQwaQxaQyaKHaQzaPdaPdaPdaPdaPdaPdaPdaPeaQAaMvaabaLRaQBaQCaQDaQEaQFaLRaabaJGaJLaJMaQGaQHaQIaQJaQKaJMaGvaIKaIKaIKaIKaQLaLXaJOaLYaJOaLXaQMaIKaIKaIKaIKaQNaQOaQPazIaMKaQQaQRaQRaQRaQSaQTaQUaQVaQWaQXaQVaQYaQZaRaaQVaRbaRcaRdaReaRfaMeaRgaRhaRiaRjaRjaRhaRkaRlaRlaRlaRlaRlaRmaRnaRlaRoaRpaRqaRraRsaRvaRuaTkaRwaRxaRwaRyaRzayHayGaRAaRBaRCaRDaREaRFaRGaRHaRIaRJaRIaRKaRLaRMaRNaROaRPaRQaRRaRSaRTaRUaQdaRVaRWaRXaRYaRZaSaaSbaScaSdaprbikbikbikbikbikbikbikaaabfmbifbieaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaSfaOFaOFaNjaOMaQjaOFaQjaSgaQjaOFaQjaOMaQkaQlaKzaKBaShaMoaMoaSiaSjaSkaSjaMoaKHaKHaKHaKHaSlaSmaSnaSoaKHaSpaSqaSraPdaPdaSsaPdaStaSuaSvaMvbikaLRaLRaSwaSxaSwaLRaLRbikaJGaJLaJMaSyaSzaSAaQJaSBaJMaGvaIKaJNaJOaSCaNRaLXaJOaLYaJOaLXaNTaSDaIKaIKaIKaSEaSFaSGaSHaSIaSJamKamKaSKaSLaSMaSNaMcaSOaMQaMcaSPaMcaSQaMcaSRaSSaSTaSUaSVaSWaSXaSYaSZaTaaTbaTcaTdaTbaTbaTeaTbaSYaTfaSYaOvaTgaSYaThaTiaTjaTmaTlaToaTnaTqaTpaWIaTraOuaTsaTtaTuaTvaTwaTxaTyaTzaRHaTAaTBaRIaTCaTDaTEaTFaROaTGaRQaRRaRSaTHaTIaQdaTJaTKaTKaTLaScaScaScaScaSdaprbikbikbikbikbikbikaaabfmbigbijbihbieaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaONaTMaTNaQiaOMaQjaOFaQjaOFaQjaOFaQjaOMaQkaQlaKzaKBaTOaTPaTQaTRaTSaTSaJraTTaTUaTVaTWaTXaTYaTZaMqcoCaKHaUbaUcaUdaUeaUfaUgaUhaUiaUjaUkaMvbikaabbikaUlaUmaUlbikaabbikaCuaJLaJMaUnaUoaUpaUqaUraJMaGvaIKaUsaUtaKPaUuaUvaKSaUwaKSaUxaUyaUzaIKaUAaUBaUCaUDaUEaUFaUGaUHbikbikaSKaUIaUJaUKaMcaULaUMaMQaMQaUNaMQaMQaMQaUOaMeaUPaMeaUQaURaMeaUSaMeaUTaUUaUVaUWaUXaUYaUTaUZaVaaVbaVcaVbaVbaVbaVbaVdaWLaVbaVeaYEaVfaVgaVbaVhayHaRDaViaTvaVjaVkaVlaVmaVnaVoaVpaVqaRIaVraVsaVtaVuaVvaTGaRQaRRaRSaRTaVwaQdaVxaTKaTKaTLaScaScaScaScaSdaprbikbikbikbikbikbikbdBblqbjMbmKbjMbqQbdBbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaSfaOFaOFaNjaOMaQjaOFaQjaSgaQjaOFaQjaOMaQkaQlaKzaKBaShaMoaMoaSiaSjaSkaSjaMoaKHaKHaKHaKHaSlaSmaSnaSoaKHaSpaSqaSraPdaPdaSsaPdaStaSuaSvaMvbikaLRaLRaSwaSxaSwaLRaLRbikaJGaJLaJMaSyaSzaSAaQJaSBaJMaGvaIKaJNaJOaSCaNRaLXaJOaLYaJOaLXaNTaSDaIKaIKaIKaSEaSFaSGaSHaSIaSJamKamKaSKaSLaSMaSNaMcaSOaMQaMcaSPaMcaSQaMcaSRaSSaSTaSUaSVaTeaSXaSYaSZaTaaTbaTcaTdaTbaTbaUjaTbaSYaTfaSYaOvaTgaSYaThaTiaTjaTmaTlaToaTnaTqaTpaWIaTraOuaTsaTtaTuaTvaTwaTxaTyaTzaRHaTAaTBaRIaTCaTDaTEaTFaROaTGaRQaRRaRSaTHaTIaQdaTJaTKaTKaTLaScaScaScaScaSdaprbikbikbikbikbikbikaaabfmbigbijbihbieaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaONaTMaTNaQiaOMaQjaOFaQjaOFaQjaOFaQjaOMaQkaQlaKzaKBaTOaTPaTQaTRaTSaTSaJraTTaTUaTVaTWaTXaTYaTZaMqcoCaKHaUbaUcaUdaUeaUfaUgaUhaUiaUZaUkaMvbikaabbikaUlaUmaUlbikaabbikaCuaJLaJMaUnaUoaUpaUqaUraJMaGvaIKaUsaUtaKPaUuaUvaKSaUwaKSaUxaUyaUzaIKaUAaUBaUCaUDaUEaUFaUGaUHbikbikaSKaUIaUJaUKaMcaULaUMaMQaMQaUNaMQaMQaMQaUOaMeaUPaMeaUQaURaMeaUSaMeaUTaUUaUVaUWaUXaUYaUTbwNaVaaVbaVcaVbaVbaVbaVbaVdaWLaVbaVeaYEaVfaVgaVbaVhayHaRDaViaTvaVjaVkaVlaVmaVnaVoaVpaVqaRIaVraVsaVtaVuaVvaTGaRQaRRaRSaRTaVwaQdaVxaTKaTKaTLaScaScaScaScaSdaprbikbikbikbikbikbikbdBblqbjMbmKbjMbqQbdBbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaVyaVzaNiaODaOMaOFaVAaVBaOFaOFaVCaVAaOMaONaVDaKzaKBaVEaVFaVGaVHaVGaVGaVGaVGaVGaVIaJraKHaVJaVKaVJaKHaKHaVLaVMaVLaMuaMuaMuaMuaVLaVNaVOaMvaVPaVQaVQaVRaVSaVRaVQaVQaVTaVUaVVaJMaVWaJMaVXaVYaVZaJMaWaaIKaIKaIKaIKaWbaWcaWdaWeaWdaWcaWbaIKaIKaWfaUDaUDaUDaUDaWgaWhaWiaWjaWkaSKaWlaUJaWmaMcaMcaMcaMcaMcaMcaMcaMeaMeaUOaWnaWoaWpaWqaWraWsaWuaWtaUTaWvaWwaWxaWyaWzaUTaWAaWBaWCaWDaWCaWEaWFaWGaWHaYFaWJaWKaYGaWMaWNaVbaWOaRtaWPaWQaWRaVjaWSaVlaVmaWTaRIaWUaWVaWWaWXaWYaTFaTFaRIaRIaRQaRRaRSaTHaWZaQdaXaaXbaXcaXdaXeaXfaScaScaXgaprbikbikbikbikbikaaabfmbqRbmKbmKbmKbqSbieaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaVyaNiaNjaNiaNiaNkaNlaNiaNiaNjaVzaXhaCuaXiaVEaInaXjaXjaXkaXjaXlaDEaXmaXnaJraXoaXpaXqaXqaXraXsaXqaXtaXqaXqaXqaXuaXqaXqaXvaXwaXxaXyaXzaXAaXyaXBaXyaXyaXyaXyaXCaXDaXEaXqaXqaXFaXGaXHaXIaXJaXKaXLaXMaXRaXPaXPaXPaXPaXPaXPaXPaXQaXWaXXaXSaXTaXUaXVaXYaZHaXZaUDaUDaYaaYbaYcaYbaYcaYdaYeaYfaYgaYhaYiaMeaYkaYjaYmaYlaYnaYnaYoaYpaYqaYraUTaYsaYtaYuaYuaYvaUTaYwaYxaYyaYzaYAaYAaYBaYCaYDbbHaYHcIgbjrcYtcSNaVbaVhaKsaRDaYIaYJaYJaYKaYLaYJaYMaRIaYNaYOaRIaYPaYQaTFaYRaRIaYSaYTaYUaRSaQbaQbaQdaYVaQeaYWaYXaQeaQeaQeaQeaQeabLadbbikbikbikbikbqUbqTbqVbmKbmKbrUbthbmKbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaInaYYaKzaKzaKzaKzaKzaKzaYYaInaMlaCuaYZaZaaInaZbaZcaZdaZdaZeaDEaZfaXnaZgaZhaXpaZiaZjaZkaZlaZlaZmaZnaZnaZnaZoaZpaZpaZqaZraZsaZlaZlaZtaZpaZvaZwaZxaZxaZyaZzaZAaZuaZuaZuaZBaXGaXHaXIaXJaXJaXJaXJaZCaXJaXJaXJaXJaXJaXJaZDaZEaZNaZFaZGaZJaZIaZLaZKaZMaZNaZNaZNaZOaZPaZPaZPaZQaYiaYiaYiaZRaZSaYiaMebbsaZUaYnaYnaZVaYnaZWaZXaYqaZYaUTaZZbaababbacbadaUTbaebafbagbahbaibajaVbbakbalcZqaVbaVbaVbaVeaVbaVbaVhayHaRDbamaTvaTvaTvbanaTvbaoaRIaRIaRIaRIaRIaRIaRIbapaRIaRSaRSaRRaRSbaqbaraQbbasbatbaubavbawbaxbaybazbaAbikbikbikbikaaabtibtjbtibtibtibtkbtibtlbtibtjbtiaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
@@ -8851,30 +8851,30 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCbBHdjhbDDdjidjidjkdjjbtqbxZbjNaInaInaKBbrWbrXbrYbrXbrXbrXbrXbrZbsabsbbcsbcsbscbsdblCbmUbsebsfbpAblCbsgbshbsgbcobcobcobcobsibcobsjbskbngbslbsmbpFbsnbsobngboCbnmbspbpIbpIbpIbsqbnmbsrbpNboIbpObssbrwbrxbstbsubrAbpTbsvbmgbswbsxbnvbsybszbsAboSbsBbsCbsDbsEbsFbsGbsHbsIbsJbqbbsKbnAbsLbsMbqibqjbqkbqlbqnbsNbqnbqnbqnbqnbsObsPbsPbsPbsPbsQbqnbqnbqnbqnbsRbqnbsNbsSbqnbsTbsUbsVbqnbsWbsXbsXbsYbsZbtabtbbmFbmFbmFbmFbmFbmFbmFbtcbtdbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbtebtfbtfbtgddSddRddUddTddTddTddTddVddWbaAaabbikbikaabbqUddXddZddYdeabqUbikbqUdecdebdecdecbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjldjidjidjidjidjidjidjideHdjnaGddjnaJrbtrbrXbtsbttbtubtvbtwbrZbtxbtybtzbtzbtAbtBblCblCblCbosbtCborbcsbcsbcsbcsbtDbejbejbskbejbsjbskbngbtEbtFbtGbtHboAbngbtIbnmbtJbpIbpIbpIbtKbtLbtMbpNbtNbnqbtObtPbpRbpRbpRbpRbpTbtQbmgbtRbtSbmgbmgbmgbmgbmgbmgbmgbnzbnAbqrbtUbtVbtWbtXbtYbtZbnAbvubuabuabucbucbucbucbucbucbucbudbudbuebufbugbugbufbuebudbudbuhbuhbuhbuhbuhbuhbuibuibujbuibuibuibuibuibukafkbumbunbmFbmFbuobuobupbupbupbupbupbuqbtfbtfbtebtfbmFbtfbtfbtfbtfburbusbusbusbusdedbuubuubuubuubuubuubuubuubuubikbikbikbikbdBddYddYddYdeebqUbikbqUdefdebdebdegbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjodjpdjpdjidjpdjpdjpbtqdjqaInaInaInaKBbuvbrXbuwbuxbuxbuxbuybrZbejbuzbuAbuBbuCbuDblCbmUbuEbosbuFborbuGbuHbuIbuJbuKbuLbuLbuMbuLbuNbuObngbuPbuQbuRbuSbuTbuUbuVbnmbuWbpIbpIbuXbuYbuZbtMbpNbvabnqbvbbvcbvdbvebvfbvgbvhbnqbnqbvibvjbvkbvlbvmbvlbvnbvjbikbvobnAbvpbvqbvrbvsbtXbqbbvtbnAbxebvwbxfbucbzcbvybvzbvAbvBbvCbvDbvEbvFbvGbvHbvHbvGbvIbvJbvKbuhbvLbvMbvNbvObuhbvPbvQbvRbvSbvTbvUbvUbvVbukafNbvXbvYbvZbvYbwabwabupbwbbwcbwdbupbwebwfbwebupbwgbtfburbusbwhbwibwhbusbwjbwkbusdeicngbxXbwobikbikbikbikbikbikbikbikbikbikbqUddXddZddYdejbqUbikbqUdekdekdekdekbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjrbtqbtqbtqbtqbtqbtqbtqbtqdjqbikbikaInbwqbdFbwrbrXbwsbrXbwtbuxbwubwvbrZbwwbwxbwybwzbuDblCblCblCblCblCblCbwAbwBbwCbwDbwEbngbngbngbngbngbngbngbwFbngbngbngbwGbngbwHbwIbwJbpIbpIbpIbwKbtLbwLbpNbwMbnqbwNbvcbnrbnrbnrbnqbwObnqbwPbwQbwRbwSbwTbwUbwVbwWbwXbwYbwZbnAbxabqbbxbbxcbtXbxdbqbbnAbzbbxgbANbucbxhbxibxjbxkbxlbxmbxnbvHbvHbvHbvHbvHbvHbvHbvHbxobxpbxqbxrbxsbxtbuhbxubxvbxwbxxbxybxzbxvbxAbukbDdbvXbxCbxDbxEbxFbxFbxGbxHbxIbxJbxKbxLbxMbxNbupbxObxPbxQbusbxRbxSbxTbxUbxUbxVbusbxWbxXbxYbwobikbikbikbikbikbikbikbikbikbikbDybtldemdemdemdenbikdeodepdepdepbtlbDzbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjrbtqbtqbtqbtqbtqbtqbtqbtqdjqbikbikaInbwqbdFbwrbrXbwsbrXbwtbuxbwubwvbrZbwwbwxbwybwzbuDblCblCblCblCblCblCbwAbwBbwCbwDbwEbngbngbngbngbngbngbngbwFbngbngbngbwGbngbwHbwIbwJbpIbpIbpIbwKbtLbwLbpNbwMbnqbIDbvcbnrbnrbnrbnqbwObnqbwPbwQbwRbwSbwTbwUbwVbwWbwXbwYbwZbnAbxabqbbxbbxcbtXbxdbqbbnAbzbbxgbANbucbxhbxibxjbxkbxlbxmbxnbvHbvHbvHbvHbvHbvHbvHbvHbxobxpbxqbxrbxsbxtbuhbxubxvbxwbxxbxybxzbxvbxAbukbDdbvXbxCbxDbxEbxFbxFbxGbxHbxIbxJbxKbxLbxMbxNbupbxObxPbxQbusbxRbxSbxTbxUbxUbxVbusbxWbxXbxYbwobikbikbikbikbikbikbikbikbikbikbDybtldemdemdemdenbikdeodepdepdepbtlbDzbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaLyaCuaKzaKzaInaInaInaInaInaInaInaKBaJrbyabrXbybbycbydbyebyebyfbygbyhbyibyibyjbykbtzbtzbtzbtzbtzbtzbylbymbymbynbyobngbypbyqbyrbysbytbyubyvbywbngbyxbyybyzbuVbtLbwJbpIbpIbyAbnmbnmbyBbyCbyDbyEbyFbyGbyHbyIbyJbyKbyLbyMbyNbyObwXbyPbyQbyPbyQbyRbwXbwYbySbyTbyUbyVbyWbyXbyYbyZbzabyTbAObvwbvwbucbzebzdcSCbzfbzgbucbxnbvHbvHbvHbvHbvHbvHbvHbzhbzibzjbzkbzlbxqbzmbuhbznbzobzpbxxbxAbxzbzqbzrbukbIbbztbzubzvbzvbzwbzxbzybzzbzAbzAbzAbzBbzAbzCbzDbzEbzFbzGbzHbzIbzJbzKbzKbzKbzLbusbzMbxXbzNbwobikbikbikbikbikbikbikbikbikbikbikbDyderderderbDzbikbDyderderderbDzbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjtdjsdjuaIoaIoaIobdFaJraJrbrXbzVbrXbzWbzXbzYbzZbrXbcsbAabAabAbbAcbAbbAbbAbbAcbAbbcsbcsbngbngbngbAdbngbAebAebAebAebAebAebyvbAfbAgbAhbAibAjbAkbAlbAmbAnbAobApbAqbArbAsbAtbAubAvbAwbAwbAxbAybAzbAAbABbACbADbAEbvjbAFbwVbAGbwTbAHbvjbikbAIbAJbAKbALbAJbAJbAJbAJbAMbnAbCBbvwbCCbAPbAQbARbASbATbAUbucbAVbAWbAXbAYbAZbBabBbbBcbvHbBdbuhbBebzlbBfbBgbuhbBhbBibxwbxxbxAbxzbxvbxAbukbDdbvXbBjbBkbBlbBmbBnbBobBpbBqbBrbBsbBtbBubBvbupbBwbBxbBybusbBzbBAbBBbxUbBCbBDbusbzMbxXbBEbwobikbikbikbikaabaabaabaabaabaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjwdjvdjuaJqaJqbBIbBJaJqbBKbrXbBLbycbBMbBNbBObBPbrXbikaabaabdetdesdesdesdesdesdeubikbikbBRbBSbBTbBUbBVbAebAebAebAebAebAebBWbBXbBYbBZbCabCbbCcbCdbnmbnmbCebCfbnmbnmbCgbChbCibCjbCkbClbClbCmbClbCnbCobCpbCqbAEbvjbCrbvlbvlbvlbCsbvjbikbAIbAJbCtbCubCvbCwbCxbCybCzbCAbEsbvwbEtbucbvxbCDbCEbCFbCGbCHbCIbCJbCKbCLbCMbCNbCObCPbCQbCRbCSbCTbzlbCUbCVbuhbCWbCXbCYbCZbDabDbbDcbvVbukbIcbDebDfbDgbDgbDhbDibDjbDkbDlbDmbDnbDobDpbDqbupbDrbBxbDsbusbDtbDubDvbxUbxUbDwbusbxWbxXbDxbwobikbikbikbikaabbDAbFfbDBbFfbDBbFfbFgaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjudjubDEaInaInaLyaCubDFbDGbrXbDHbycbycbycbrXbrXbrXbikbikbikdewdevdevdexdevdevdewbikbikbBRbDIbAebDJbDKbDKbDKbDKbDKbDLbDMbDKbDNbDObDPbDQbDRbDSbDTbnmbDUbpIbDVbDWbtLbDXbDYbDZbCjbCjbCpbEabEbbEcbEdbEebCpbvibAEbvjbEfbEgbEhbqtbEjbvjbikbEkbAJbElbEmbEnbEobEpbEobEqbErbFWbvwbHBbucbEubEubEvbEwbExbEybEzbEAbEBbECbEDbEDbEEbEFbEGbEHbuhbCTbEIaJSbuhbuhbuibEKbELbEMbuibukbukbukbENbIdbvXbEPbBkbBlbEQbDgbDjbERbESbESbETbxJbEUbEVbEWbEXbxPbEYbusbEZbFabxUbFbbFcbFdbusbzMbFebwobwobikbikbikbikaabbFhbFjbFibGSbFkbGTbFhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjydjydjydjAdjzdjydjydjydjydjBbikbikbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdewbFnbBRbBRbFobFpbFqbFrbFrbFrbFpbAebyvbAfbAebAebAgbFsbFtbFubFvbFwbFxbFybpIbpIbFzbtLbDXbDYbFAbFBbFCbFDbFEbFFbFGbFHbFIbCpbFJbFKbwRbFLbFMbFNbFObFPbwXbwYbFQbAJbFRbFSbFTbEobFUbEobFVbErbJebvwbKObucbFYbFZbGabGbbGcbGdbGebGfbGgbGgbGhbGibGgbGgbGjbGkbGlbGmbGnbGobGpbGqbGrbGsbGtbGubGvbGwbKhbIebKjbKibvXbGBbGCbGDbGEbGFbxGbGGbESbESbGHbGIbEUbGJbupbGKbGKbGLbusbGMbGNbGObGPbxUbGQbusbzMbGRbwobikbikbikbikbikaabbGUbIybFibFkbFibKkbDBaabbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjCdjEdjDdjGdjFdjIdjHdjFdjJdjLdjKdjydjydjBbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbGWbmrbNkbmrbGXbGYbGZbGYbGYbGYbGYbHabyvbAfbHbbngbngbHcbpIbAibFvbHdbtLbHebHfbHfbHgbHhbHibHjbHkbHlbHmbHnbHobHpbHqbHrbHsbCpbCqbAEbvjbEibHubHvbHwbHxbvjbikbEkbHybHzbHybHybHybHybHybHAbHybKPbvwbKObucbHCbHDbHDbHEbHFbEybHGbHHbHIbHJbHKbHLbHMbHIbHNbHObHPbHQbHRbHSbHTbHTbHUbHVbHWbHXbHYbLibLCbLBbNdbNcbNebIfbIfbIgbIhbIibxGbIjbxJbxJbIkbIlbEUbImbInbIobIpbIqbIrbIsbItbIubIvbIubusbusbIwbEXbGxbLDbLDbLDbLDbLDbGxbFhbFkbFibFkbFkbGTbFhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjHdjHdjHdjMdjFdjNdjNdjFdjOdjHdjHdjQdjPdjydjBbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbLFbKmbIAbKmbIBbAebFqbFrbFrbFrbAebAebyvbAfbICbIDbngbIEbpIbAibFvbIFbtLbIGbpIbrsbpIbIHbDXbvvbIIbHlbHmbIJbIKbILbIMbINbIObIPbIQbIRbISbISbITbIUbIVbvjbvjbikbEkbHybIWbIXbIYbIZbJabJbbJcbJdbMhbvwbKObCHbJfbJgbJhbJibJjbEybJkbJlbJmbJnbJobJpbJqbJrbJsbJtbJubJvbJwbJxbJybJzbJAbJBbJCbJDbJEbGwchEbIecnfcjubvYbJIbJJbJKbJLbJLbxGbJMbJNbJObxGbJPbEUbJQbxGbJRbJSbJTbJUbJVbJWbJXbJYbJZbKabKbbKcbKdbKebKfbKfbIxbJFbJHbKgbKlbFfbDBbNhbDBbFfbLEaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjSdjRdjUdjTdjVdjFdjWdjHdjXdjHdjHdjHdjHdjHdjMdjFbikbikbikbikbikbikbikbikbikbikdewdeCdevdevdevcOfdewbFnbBRbBRdezbAebFqbAebAebAebAebAebyvbAfbICbKobngbKpbpIbKqbKrbpIbKsbpHbpIbpIbKtbtLbDXbvvbIIbHlbHmbCpbKubKvbqzbKxbKybKzbKAbKBbKCbKDbwXbKEbKFbwXbwYbwYbKGbHybKHbKIbKJbKKbKLbKLbKMbKNbMibvwbMjbucbEybKQbEubKRbKSbEybJkbKTbKUbKVbKWbKXbKYbKUbJkbKZbLabLbcchbLbbLcbLbbLdbLdbLebLfbLgbLhbLhcpLbLgbLgbLhbLhbLjbLkbLjbLjbxGbxGbxGbxGbxGbLlbLmbBobxGbLnbLobLpbLqbLqbLrbLsbLtbLubLvbLwbLxbLybLzbLAbLAbEObGAbHZbGxbGzbGzbGzbIabGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjZdjYdjHdjHdkadkadkadjFdjHdjHdjFdkbdkddkcdkfdkedkgdjFbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbWobKmbIAbKmbFobLGbLHbAebAebAebLGbAebyvbAfbICbLIbngbLJbpIbAibFvbpIbnmbLKbpIbpIbLLbtLbDXbvvbLMbHlbLNbCpbLObLPbLQbLRbLSbKzbLTbLUbLVbLWbLXbLYbLZbMabikbikbikbHybMbbMcbMdbMdbMebMfbMgbHybNSbNRbKObNTbMkbMlbMmbMnbMobMpbMqbJlbMrbMsbMtbMubMvbMrbJkbKZbMwbMxbMybMzbMAbMBbLdbMCbMDbMEbLgbMFbMGbMHbMIbMJbMKbMLbKabMMbLqbLqbMNbMObLqbMPbMQbMRbMSbMTbLqbMUbiTbMWbMXbMYbMZbNabNbbNabNabNabIwbEXbGxbLDbLDbGxcnccndcnebOQbOSbUHbYdbGzbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkhdjYdjHdjHdjHdjHdjHdkidjHdjHdjFdjydjydjydjydjydjydkjbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdeEdeDdeGdeDbNlbNmbNnbNnbNnbNnbNnbNobNpbNqbICbNrbngbNsbNtbNubNvbNwbNxbNybNybNybNzbNzbNAbvvbNBbNCbHmbCpbNDbNEbNFbKvbNGbKzbNHbNIbNJbNKbNLbFNbNMbMabikbikbikbHybNNbNObNPbNQbMebMfbMgbHybPibNUbQObPjbNVbNWbNXbNYbNZbOabObbOcbKUbKUbOdbOebKUbKUbJkbKZbOfbOgbOhbOibOjbOkbLdbOlbOmbOnbOobOpbOqbOrbOrbOsbOtbOubOvbOwbJVbJVbOxbJVbOybJVbOzbJVbOAbOBbOBbOCbODbOEbOFbOGbOHcsjbOJbOKbOLbNabOMbONbikbikbikbGxbORbJFbOPbOQbKgbOObNibGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjHdjHdjHdjMdjFdjNdjNdjFdjOdjHdjHdjQdjPdjydjBbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbLFbKmbIAbKmbIBbAebFqbFrbFrbFrbAebAebyvbAfbICbKobngbIEbpIbAibFvbIFbtLbIGbpIbrsbpIbIHbDXbvvbIIbHlbHmbIJbIKbILbIMbINbIObIPbIQbIRbISbISbITbIUbIVbvjbvjbikbEkbHybIWbIXbIYbIZbJabJbbJcbJdbMhbvwbKObCHbJfbJgbJhbJibJjbEybJkbJlbJmbJnbJobJpbJqbJrbJsbJtbJubJvbJwbJxbJybJzbJAbJBbJCbJDbJEbGwchEbIecnfcjubvYbJIbJJbJKbJLbJLbxGbJMbJNbJObxGbJPbEUbJQbxGbJRbJSbJTbJUbJVbJWbJXbJYbJZbKabKbbKcbKdbKebKfbKfbIxbJFbJHbKgbKlbFfbDBbNhbDBbFfbLEaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjSdjRdjUdjTdjVdjFdjWdjHdjXdjHdjHdjHdjHdjHdjMdjFbikbikbikbikbikbikbikbikbikbikdewdeCdevdevdevcOfdewbFnbBRbBRdezbAebFqbAebAebAebAebAebyvbAfbICbLwbngbKpbpIbKqbKrbpIbKsbpHbpIbpIbKtbtLbDXbvvbIIbHlbHmbCpbKubKvbqzbKxbKybKzbKAbKBbKCbKDbwXbKEbKFbwXbwYbwYbKGbHybKHbKIbKJbKKbKLbKLbKMbKNbMibvwbMjbucbEybKQbEubKRbKSbEybJkbKTbKUbKVbKWbKXbKYbKUbJkbKZbLabLbcchbLbbLcbLbbLdbLdbLebLfbLgbLhbLhcpLbLgbLgbLhbLhbLjbLkbLjbLjbxGbxGbxGbxGbxGbLlbLmbBobxGbLnbLobLpbLqbLqbLrbLsbLtbLubLvbLIbLxbLybLzbLAbLAbEObGAbHZbGxbGzbGzbGzbIabGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjZdjYdjHdjHdkadkadkadjFdjHdjHdjFdkbdkddkcdkfdkedkgdjFbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbWobKmbIAbKmbFobLGbLHbAebAebAebLGbAebyvbAfbICbNrbngbLJbpIbAibFvbpIbnmbLKbpIbpIbLLbtLbDXbvvbLMbHlbLNbCpbLObLPbLQbLRbLSbKzbLTbLUbLVbLWbLXbLYbLZbMabikbikbikbHybMbbMcbMdbMdbMebMfbMgbHybNSbNRbKObNTbMkbMlbMmbMnbMobMpbMqbJlbMrbMsbMtbMubMvbMrbJkbKZbMwbMxbMybMzbMAbMBbLdbMCbMDbMEbLgbMFbMGbMHbMIbMJbMKbMLbKabMMbLqbLqbMNbMObLqbMPbMQbMRbMSbMTbLqbMUbiTbMWbMXbMYbMZbNabNbbNabNabNabIwbEXbGxbLDbLDbGxcnccndcnebOQbOSbUHbYdbGzbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkhdjYdjHdjHdjHdjHdjHdkidjHdjHdjFdjydjydjydjydjydjydkjbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdeEdeDdeGdeDbNlbNmbNnbNnbNnbNnbNnbNobNpbNqbICbWSbngbNsbNtbNubNvbNwbNxbNybNybNybNzbNzbNAbvvbNBbNCbHmbCpbNDbNEbNFbKvbNGbKzbNHbNIbNJbNKbNLbFNbNMbMabikbikbikbHybNNbNObNPbNQbMebMfbMgbHybPibNUbQObPjbNVbNWbNXbNYbNZbOabObbOcbKUbKUbOdbOebKUbKUbJkbKZbOfbOgbOhbOibOjbOkbLdbOlbOmbOnbOobOpbOqbOrbOrbOsbOtbOubOvbOwbJVbJVbOxbJVbOybJVbOzbJVbOAbOBbOBbOCbODbOEbOFbOGbOHcsjbOJbOKbOLbNabOMbONbikbikbikbGxbORbJFbOPbOQbKgbOObNibGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkmdkldkodkndjHdjFdjHdjHdjFdjHdkqdkpdkrbikbikbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdewbFnbBRbBRbngbngbBRbBRbBRbBRbBRbngbngbBRbBRbBRbngbOVbOVbOVbOWbOVbNzbOXbOYbOZbPabNzbDXbvvbPbbPcbPcbCpbCpbCpbCpbCpbPdbKzbISbIRbPebNKbPgbPhbMabMabvjbvjbvjbHybHzbHybHybHybHybHybHybHybQPbvwbQQbPkbPlbPmbPnbPlbPlbPobPpbPqbPrbPsbPtbPubPvbPwbMqbPxbPybPzbPAbPBbPCbPDbPEbPFbPGbPHbPIbPJbPKbPLbMHbPMbLhbLhbPNbPObPNbPPbPQbPPbPPbPPbPRbPSbPTbPTbPUbPVbPWbPXbOFbPYbPZbQabQbbQcbQdbNabOMbONbikbikbikbGxbNfbNgbGxbKgbGxbGxbKgbGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjydjydjydjydjydjydjFdjOdjHdksdjHdkudktdkvbikbikbikbikbikbikbikbikbikbikbikbikbikdeJdeIdevdeKdevdeLdeMbikbikbikbikbikbikbikbikbikbikbQgaabbikbikbikbikbOVbQhbQibQjbQkbNzbQlbQmbQnbQobNzbDXbvvbQpbQqbQrbQsbQtbQubQvbQwbQxbQybQzbQAbQBbQCbQDbQEbQFbQGbQHbQIbQJbQKbQLbQMbQRbuabQSbvwbShbSgbSibvwbSjbPlbQTbQUbQVbQWbQXbJkbQYbQZbRabRbbRcbRdbRebRfbRgbRhbRibLbbRjbOibRkbRlbRmbRnbRobRpbLgbRqbMHbMHbMHbRrbLhbPNbRsbRtbRubRvbRwbRxbRybPPbRzbRAbRBbPTbPTbRCbPWbRDbREbtTbRGbRHbRIbRJbRKbNabRLbwobikbikbikbGxbGxbGxbGxbikbikaabbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydkxdkwdkydkxdkzdjFdjHdjHdjFdjHdkBdkAdkCbikbikbikbikbikbikbikbikbikbikbikbikbikdeOdeNdePdePdePdeNdeQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbOVbRMbRNbRObRPbNybRQbRRbRSbRTbNzbDXbRUbRVbvvbvvbFXbRWbubbQNbQMbRXbRYbRXbRZbSabSabSbbScbSdbSabSabSebSabSfbSabQMbQRbuabSlbSkbTJbTIbTLbTKbvwbPlbSmbQUbSnbSobSpbJkbSqbSrbSsbStbSubSvbSwbSxbJkbSybSzbLbbSAbSBbSBbSCbSDbSEbSFbSGbLgbSHbSIbMHbSJbSKbLhbPNbSLbSMbSNbSObSPbSQbSRbPPbSSbRAbSTbSTbPTbSUbSVbSWbSXbSYbSZbTabTbbTcbTdbNabOMbwobTebikbikbikbikbikbikbikbikaabbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjZdjYdkDdkDdkDdkDdkDdkEdjHdjHdjFdjydjydjydjydjydjydjBbikbikbikbikbikbikbikbikbikbikbikdeRdeSdeSdeSdeTbikbikbikbikbikbikbikbikbOUbOTbQebOTbQfbikbikbikbOVbOVbTjbTkbRObTlbNybTmbQnbTnbTobNzbDXbTpbTqbTrbTsbTtbTubTvbTwbTxbTybTzbTAbTBbTCbTCbTDbTEbTEbTEbTEbTEbTEbTFbTGbTHbTNbTMbTPbTOdlidjmdlkdljdllbPlbTQbQUbQVbTRbSpbJkbSqbSrbTSbTTbTUbTVbTWbTXbJsbTYbTZbLbbLbbUabUabLbbSDbLdbUbbUcbLgbUdbUebUfbUgbUhbLhbPNbUibUjbUkbUlbUmbUnbUobPPbUpbRAbSTbSTbPTbUqbUrbUsbUtbUubUvbUwbUxbUybUzbNabOMbUAbUBbUAbUCbUDbUCbUCbUCbikbikbikbikaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikaabaabaabaabaabbikbikbikbikaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkhdjYdkDdkDdkDdkFdkGdjFdjHdjHdjFdjHdjHdjHdkHdjHdkIdjFbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbTgbTfbTibThbTgbUIbUIbUIbOVbUJbUKbULbUMbUNbUObUPbUQbUQbURbNzbUSbUTbUUbUVbUVbUWbUXbUYbUVbUZbUZbVabVbbVcbUZbUZbVdbQMbQMbVebVfbVfbVfbVgbVhbVfbVfbVibVjbVkbVkbVlbVkbVmbVnbVkbVobVpbVqbPlbVrbVsbSqbVtbVubVvbVwbVxbVybVubJkbSybVzbVAbVBbVCbVDbVEbVFbVGbVHbVIbVJbVKbVLbVMbVNbVObLhbPNbPNbVPbVQbVRbVSbVRbVTbPPbVUbVVbVWbVWbPTbVXbVYbVZbNabNabNabNabNabNabNabNabOMbUAbWabWbbWcbWdbWdbWebUCbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikaabbWfbWfbWfbWfbWgbWgbWhbWhbWhbWhbWiaabaabbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkKdkJdkDdkLdkMdjFdjHdjHdkNdjHdjHdjHdkOdjHdkPdjFbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbQebUEbUFbUEbQebUIbWmbWlbOVbWnbWpbWqbWrbWsbNzbWtbWubWvbWwbNzbUTbUTbWxbUVbWybWzbWAbWBbWCbUZbWDbWEbWFbWGbWHbUZbWIbWJbWKbVfbWLbWMbWObWNbWPbWQbWRbWSbWTbWUbWVbWWbWXbWYbWZbXabXbbXcbXdbXebXfbXgbXhbSrbXibXjbXkbXlbXmbXnbJsbXobXpbXqbXrbVDbXsbXsbXtbXubLgbXvbXwbXxbXybXzbXAbXBbLhbXCbXDbXEbXFbXEbXEbXGbXHbXIbXJbXKbXLbXMbPTbXNbXObPXbEXbxXbXPbXQbXRbXRbXQbXRbXSbUAbXTbXUbWcbWdbXWbXVbUCbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbWfbXXbXYbXXbWgbWhbWhbXZbYabXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkKdkJdkDdkLdkMdjFdjHdjHdkNdjHdjHdjHdkOdjHdkPdjFbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbQebUEbUFbUEbQebUIbWmbWlbOVbWnbWpbWqbWrbWsbNzbWtbWubWvbWwbNzbUTbUTbWxbUVbWybWzbWAbWBbWCbUZbWDbWEbWFbWGbWHbUZbWIbWJbWKbVfbWLbWMbWObWNbWPbWQbWRceLbWTbWUbWVbWWbWXbWYbWZbXabXbbXcbXdbXebXfbXgbXhbSrbXibXjbXkbXlbXmbXnbJsbXobXpbXqbXrbVDbXsbXsbXtbXubLgbXvbXwbXxbXybXzbXAbXBbLhbXCbXDbXEbXFbXEbXEbXGbXHbXIbXJbXKbXLbXMbPTbXNbXObPXbEXbxXbXPbXQbXRbXRbXQbXRbXSbUAbXTbXUbWcbWdbXWbXVbUCbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbWfbXXbXYbXXbWgbWhbWhbXZbYabXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkQdkDdkDdkRdjFdjHdjHdjFdkSdjHdjHdkUdkTdjydkjbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbTgbUGbUEbUEdeycOWbTkbTkdeAbZAbTkbWqbYhbYibNzbNzbNzbNzbNzbNzbYjbUTbYkbYlbYmbYnbYnbYnbYobUZbYpbYqbYqbYqbYrbYsbYtbYubYvbYwbYxbYybYzbYAbYBbYCbVfbVibYDbVkbYEbYFbYGbYHbYIbVkbSmbQVbSnbSobYJbYKbYLbYMbYNbYObYPbYQbYRbVubYSbYTbYUbYVbYWbYXbYYbYZbZabZbbLgbLgbLgbLgbLgbZcbZdbZebLhbZfbXEbXEbZgbZhbXEbZibZjbZkbZlbRAbZmbZmbPTbPVbZnbPXbEXbUAbZobUAbUAbUAbUAbUAbUAbUAbZpbZqbUCbZrbZtbZsbUCaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacbZubXXbXXbZvbWhbWhbXZbXZbZwbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkWdkVdkXdjFdjHdkYdjFdkZdladjHdjydjydkjbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbQebUFbUFbUFbQebUIbYfbYebZzbZAbTkbZBbZCbZDbZEbZFbZFbZFbZGbUTbUTbUTbWxbUVbZHbYnbZIbYnbZJbUZbYpbYqbZKbYqbZLbUZbZMbZNbZObVfbZPbZQbZRbZSbZTbZUbZVbZWbZXbZYbZZcaacabcaccadbVkbTQbQVbQVcaebYJbYKcafcagcahbXjcaicajbKwcalcamcancaocapcaqcarcascasbXscatbVAcaucavcawcaxcaycazcaAbZjbZfcaBbXEbXEbXEcaCcaDbZjbZkcaEbRAbZmbZmbPTcaFcaGbPXbEXcaHcaIcaJbUAcaKcaLcaMcaNcaOcaPcaQbUCcaRcaScaTbUCbUAbUAbUAbUAbUAbUAbUAbUAbikbikbikbikbikaabbikbikbikbikbikbikbikcaUbWhbZubWhbWhbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydjydjydjydjydjydjydjydjydjydkjbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbTgbWjbYbbWkbTgbUIbUIbUIbOVcaYcaZcaZcaZbOVbOVbUTcbacbacbbcbcbUTcbdcbebUVbZHbYnbYnbYncbfbUZbYpbYqbYqcbgcbhcbicbjcbkcblbVfbVfbVfbVfbVfcbmbVfbVfcbncbobVkbVkcbpbVkbVnbVkbVkbPlcbqcbqbPlccicbrcbscbtcbucbvcbwcbxcbycbzcbAcbBcaocapcbCcbDcbEcbFcbGcbHbVAcbIcbJcbKcbLcbMcbNcbOcbPcbQcbPcbRcbRcbRcbPcbScbPcbPcbTcbUbZmbZmbPTcbVbZnbPXcbWcbXcbYcbZccaccbccccccccdcceccfccgcckccjcdqcclcfeccmccnccoccpccqccrccscctaabaabaabaabaabaabaabaabbikbikbikbikbikbWgbWhccuccvccvbXZbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbYcbOTbYgbOTbZxbikaabbikbOVbOVbUIbUIbUIbOVbikbUTccAccBccCccDbZFccEccFbUVccGccHccIbYnccJccKccLccMccNccOccPbUZccQccRccSccTccUccUccUccUccVccWccXccYccYccZccZcdacdbcdcbVibPlcddcdecdfcdgcdhbYKcdicbtcdjcdkcdlcdmbSwcdncdocdpcffcdrcdrcdscdrcdrcdrcdtbVAcducdvcdwcdxcdycdzcdAcbPcdBcdCcdDcdEcdFcdCcdGcdHcdCcdIcdJbRBbPTbPTcdKcdLcdMcdNcdOcdPcdQcdRcdScdTcdUcdVcdWcdXcdYcdZceacebceaceccebcebcebcedceecefcegcehaabbikbikbikbikaabbikbikbikbikbikbikbikbWhbWhceibXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabcejbUTbUTbUTcekbUTbUTcelbUVcemcenceocepceqcercescetceucevcewccKcexceycezceAceBceBceBceBceCceDceEceFceGceFceHceIceJceKceLceMceNceOcePceQceRceSceTceUceVceWceXceYceZcfacfbcfccfgbMmbMmcfichOcgHceYchVcfjcfjcfkcfjcflcfmcfncfocbPcfpcfqcfrcfscfrcftcfucfvcdCbPTcfwbPTbPTcfxcfybZnbBxbEXbUAcfzbUAbUAcfAcfBcfCcfDcfEcebcfFcfGcfHcdUcfHcdUcfIcdUcdUbUAcfJcfKcfLcfMaabaabaabaabaabaabaabaabbikbikbikbikbikbWhbXZbXZbXZbXZbXZbXZcfNbXZcfObXZbXZbXZbXZbXZbWhbWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabcejbUTbUTbUTcekbUTbUTcelbUVcemcenceocepceqcercescetceucevcewccKcexceycezceAceBceBceBceBceCceDceEceFceGceFceHceIceJceKchvceMceNceOcePceQceRceSceTceUceVceWceXceYceZcfacfbcfccfgbMmbMmcfichOcgHceYchVcfjcfjcfkcfjcflcfmcfncfocbPcfpcfqcfrcfscfrcftcfucfvcdCbPTcfwbPTbPTcfxcfybZnbBxbEXbUAcfzbUAbUAcfAcfBcfCcfDcfEcebcfFcfGcfHcdUcfHcdUcfIcdUcdUbUAcfJcfKcfLcfMaabaabaabaabaabaabaabaabbikbikbikbikbikbWhbXZbXZbXZbXZbXZbXZcfNbXZcfObXZbXZbXZbXZbXZbWhbWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcejcfPcfQcfRbUTcfSbUVcfTcfUcfVbZHcfWcfXcfYbYpcfZcgacgbcfXcgccgdcgecgfcgfcggcghcgicgjcgkcglcgmbGycgnbVicgobGybGycgpcgqcgrcgscgtceQcgucgvcgwcgxcgycgzbMVcgBcgCcgzcgzcgDcgEcgEcgEcgEcgEcgGcgFciOcgJcgJcgKcgLcgMcgNcgOcgPcbPcgQcgRcgScgTcgScgUcgVcfrcgWcgXcgYbBxcgZbBxcfybZnbBxbEXchachbchcbUAbUAbUAbUAbUAchdcdUchechfcfIcdUchgcdUbZpcdUchhbUAchichjchkbUAaabbikbikbikbikaabbikbikbikbikbikbikbikbWhchlchlchlchlchlchlchmbXZchnchlcfObXZbXZbXZbXZbWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcejchochpchqbUTcfSchrchrchrchrchrchrbUZbUZbUZbUZbUZbUZbUZchschtchuchvchwchxchychychzchAcglbGybGychBchCchDbGybGybGycqOchFchGceOchHchIchJcgEchKchLchMbSqchLchNcfdcfdcfdcjncjlcjlcjlcjlckacgIbSqclPchPchQchRchSchTchUclQcbPchWchXcfrchYcfrchZciacibciccidciecifbBxcigcfybZncihbEXbFeciicijcikbwobxXbxXbUAcilcimcinciocipciqcirciscitciucivbUAciwciycixcizbikbikbikbikaahbikbikbikbikbikbikbikbikciAbXXbXXbXXbXXbXXbXXbXXciBciCbXZbXZbXZbXZciDbYabWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcejchochpchqbUTcfSchrchrchrchrchrchrbUZbUZbUZbUZbUZbUZbUZchschtchucWpchwchxchychychzchAcglbGybGychBchCchDbGybGybGycqOchFchGceOchHchIchJcgEchKchLchMbSqchLchNcfdcfdcfdcjncjlcjlcjlcjlckacgIbSqclPchPchQchRchSchTchUclQcbPchWchXcfrchYcfrchZciacibciccidciecifbBxcigcfybZncihbEXbFeciicijcikbwobxXbxXbUAcilcimcinciocipciqcirciscitciucivbUAciwciycixcizbikbikbikbikaahbikbikbikbikbikbikbikbikciAbXXbXXbXXbXXbXXbXXbXXciBciCbXZbXZbXZbXZciDbYabWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcejcejcejcejbUTcfScejbikbikbikbikciEbaTciGciHciIciJciKciLciMciNcmPciPciQciRciSciSciTciUciVciWciWciWciWciXciWbGybGybPlciYciZcjacjbcjccjdchScjecjfcjgcjhcjicjjcjkcjlcfdcnicjpcjpcjpcjpckNclSckUcnjcjqcjrcjscjtcbAcwncjvcbPcjwcjxcjycjzcjAcfrcjBcbPcbPbEXcjCbEXbEXbEXcjDcjEcjFbEXbxXciicjGcjHbwobwobwobUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbikbikbikbikbikaabbikbikbikbikbikbikbikbWhccvccvccvccvccvccvcjIbXZccuccvcjJbXZbXZbXZbXZbWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcAjbikaabaabcjKcjKcjKcjKcjKcjKcjLcjKbUTcelcjMbikcjNcjOcjPcjQcjRcjScjTcjUcjVcjWcjXcjYcjZcosckbckcckdckeckfckgckhciVckickjckjckjckkciWbGybGycklcklcklcklckmcklckncknckocklcklckpcklckqckrckscktcksclZaPKcmacmmcmlcmocmnckzckAckBckCckDckEckFcdccbPcbPckGcbPckHcbPckIckJckKcgnckLckMckvckOckPckQckRckSckPbxXciickTbxXbxXckVckWckXchabxXbxXbxXbxXbxXbxXbxXckYckZbONbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbWhbXZbXZbXZbXZbXZbXZcfNbXZcjJbXZbXZbXZbXZbXZbWhbWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikclaclbclbclbclccldcleclfclgclhclicjLcljcelcjMbikclkcllclmclnclocjSclpclqclrclsciLcltcgdcoaciPcluchyclvchyclwclxclyclzclAclAclAclBciWbGybGycklclCclDclEclFclGclHclHclIclJclKclLclMclNclOcotcfhcpwcmpcmrcmqctbcsZcuoctcckDclVclWclXckzclYcmtcmscmbcmbcmccmdcmecmfcmgcmhcmfcmfcmfcmicmfcmfcmjcmucnpcnlcqRcoXcrGcqScrHcrHcrIcrHcrHcrHcrHcrJcrKcrHcrHcrHcrMcmvbxXbONbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbWhbWhceibXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
@@ -8941,8 +8941,8 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGcVucVvcVEcVHcVIcVJcVJcVKcVLcVJcVMcVNcVJcVJcVIcVOcVvcVEcVFacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikagQbikaabbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGcVucVPcVQcVRcVRcVScVTcVUcVVcVWcVWcVXcVYcVZcWacWacWbcWccVFacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikagQagQagQagQagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGcVucWdcWecWfcWfcVJcWgcWhcWhcWicWhcWhcWjcVJcWfcWfcWkcWlcVFacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGcVucWdcVFbikbikcVJcWmcWncWocWpcWqcWrcWscVJbikbikcVucWlcVFacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGcVucWtcWucWucWucVJcWvcWwcWhcWhcWxcWycWzcVJcWucWucWucWAcVFacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGcVucWdcVFbikbikcVJcWmcWncWocWvcWqcWrcWscVJbikbikcVucWlcVFacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGcVucWtcWucWucWucVJcWzcWwcWhcWhcWxcWydgYcVJcWucWucWucWAcVFacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGcVucWdcVFbikbikcWBcWCcWBcWDcWEcWBcWBcWFcWBbikbikcVucWlcVFacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikacGcVucWdcVFbikbikcWBcWGcWHcWIcWJcWKcWLcWMcWBbikbikcVucWlcVFacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGcVucWdcVFbikcWBcWBcWNcWLboSboSboScWLcWOcWBcWBbikcVucWlcVFacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik
|
||||
|
||||
@@ -886,7 +886,7 @@
|
||||
"rc" = (/obj/machinery/light/small{dir = 4},/obj/structure/stool/bed/roller,/obj/machinery/light_switch{pixel_x = 27; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/mine/laborcamp)
|
||||
"rd" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/closet/crate/internals,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/mine/laborcamp)
|
||||
"re" = (/obj/machinery/light/small,/obj/machinery/light_switch{pixel_y = -28},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/mine/laborcamp)
|
||||
"rf" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=2-NMine"; location = "1-Storage"},/obj/machinery/bot/secbot/ofitser,/turf/simulated/floor/plasteel{icon_state = "asteroidfloor"},/area/mine/laborcamp)
|
||||
"rf" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=2-NMine"; location = "1-Storage"},/mob/living/simple_animal/bot/secbot/ofitser,/turf/simulated/floor/plasteel{icon_state = "asteroidfloor"},/area/mine/laborcamp)
|
||||
"rg" = (/obj/structure/plasticflaps/mining,/turf/simulated/floor/plasteel{icon_state = "asteroidfloor"},/area/mine/laborcamp)
|
||||
"rh" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=3-SMine"; location = "2-NMine"},/turf/simulated/floor/plasteel{icon_state = "asteroidfloor"},/area/mine/laborcamp)
|
||||
"ri" = (/turf/simulated/floor/plating{icon_plating = "asteroidplating"; icon_state = "asteroidplating"},/area/mine/laborcamp)
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
"dI" = (/turf/simulated/floor/plasteel/airless{icon_state = "damaged2"},/area/derelict/singularity_engine)
|
||||
"dJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel,/area/derelict/bridge/access)
|
||||
"dK" = (/obj/machinery/door/window/eastleft{name = "Heads of Staff"; req_access_txt = "19"},/turf/simulated/floor/plasteel,/area/derelict/bridge/access)
|
||||
"dL" = (/obj/machinery/bot/secbot/buzzsky,/turf/simulated/floor/plasteel,/area/derelict/bridge)
|
||||
"dL" = (/mob/living/simple_animal/bot/secbot/buzzsky,/turf/simulated/floor/plasteel,/area/derelict/bridge)
|
||||
"dM" = (/obj/structure/table,/obj/item/device/paicard,/turf/simulated/floor/plasteel,/area/derelict/bridge)
|
||||
"dN" = (/obj/structure/stool,/turf/simulated/floor/plasteel,/area/derelict/bridge)
|
||||
"dO" = (/obj/structure/table,/obj/item/weapon/stock_parts/cell,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel,/area/derelict/bridge)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
//Bot defines, placed here so they can be read by other things!
|
||||
|
||||
#define BOT_STEP_DELAY 4 //Delay between movemements
|
||||
#define BOT_STEP_MAX_RETRIES 5 //Maximum times a bot will retry to step from its position
|
||||
|
||||
#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/med bots, when moving.
|
||||
#define BOT_HEALING 10 // healing people (medbots)
|
||||
#define BOT_RESPONDING 11 // responding to a call from the AI
|
||||
#define BOT_DELIVER 12 // moving to deliver
|
||||
#define BOT_GO_HOME 13 // returning to home
|
||||
#define BOT_BLOCKED 14 // blocked
|
||||
#define BOT_NAV 15 // computing navigation
|
||||
#define BOT_WAIT_FOR_NAV 16 // waiting for nav computation
|
||||
#define BOT_NO_ROUTE 17 // no destination beacon found (or no route)
|
||||
|
||||
//Bot types
|
||||
#define SEC_BOT 1 // Secutritrons (Beepsky) and ED-209s
|
||||
#define MULE_BOT 2 // MULEbots
|
||||
#define FLOOR_BOT 4 // Floorbots
|
||||
#define CLEAN_BOT 8 // Cleanbots
|
||||
#define MED_BOT 16 // Medibots
|
||||
|
||||
//Sentience types
|
||||
#define SENTIENCE_ORGANIC 1
|
||||
#define SENTIENCE_ARTIFICIAL 2
|
||||
#define SENTIENCE_OTHER 3
|
||||
@@ -14,7 +14,8 @@
|
||||
#define DIAG_HUD "9" // Silicon health bar
|
||||
#define DIAG_BATT_HUD "10"// Borg/Mech power meter
|
||||
#define DIAG_MECH_HUD "11"// Mech health bar
|
||||
#define STATUS_HUD_OOC "12" // STATUS_HUD without virus db check for someone being ill.
|
||||
#define STATUS_HUD_OOC "12"// STATUS_HUD without virus db check for someone being ill.
|
||||
#define DIAG_BOT_HUD "13"// Bot HUDS
|
||||
|
||||
//for antag huds. these are used at the /mob level
|
||||
#define SPECIALROLE_HUD "13"
|
||||
|
||||
@@ -22,6 +22,7 @@ var/global/list/spirits = list() //List of all the spirits, including Masks
|
||||
var/global/list/living_mob_list = list() //List of all alive mobs, including clientless. Excludes /mob/new_player
|
||||
var/global/list/dead_mob_list = list() //List of all dead mobs, including clientless. Excludes /mob/new_player
|
||||
var/global/list/respawnable_list = list() //List of all mobs, dead or in mindless creatures that still be respawned.
|
||||
var/global/list/simple_animal_list = list() //List of all simple animals, including clientless
|
||||
|
||||
//global var of unsafe-to-spawn-on-reaction mobs
|
||||
var/global/list/blocked_mobs = list(/mob/living/simple_animal,
|
||||
|
||||
@@ -11,8 +11,6 @@ var/global/list/joblist = list() //list of all jobstypes, minus borg and AI
|
||||
var/global/list/airlocks = list() //list of all airlocks
|
||||
var/global/list/singularities = list() //list of all singularities
|
||||
var/global/list/janitorial_equipment = list() //list of janitorial equipment
|
||||
|
||||
var/global/list/aibots = list() // AI controlled bots
|
||||
var/global/list/table_recipes = list() //list of all table craft recipes
|
||||
|
||||
var/global/list/all_areas = list()
|
||||
@@ -24,6 +22,10 @@ var/global/list/apcs = list()
|
||||
var/global/list/air_alarms = list()
|
||||
var/global/list/power_monitors = list()
|
||||
|
||||
var/global/list/navbeacons = list() //list of all bot nagivation beacons, used for patrolling.
|
||||
var/global/list/deliverybeacons = list() //list of all MULEbot delivery beacons.
|
||||
var/global/list/deliverybeacontags = list() //list of all tags associated with delivery beacons.
|
||||
|
||||
var/global/list/beacons = list()
|
||||
var/global/list/shuttle_caller_list = list() //list of all communication consoles and AIs, for automatic shuttle calls when there are none.
|
||||
var/global/list/tracked_implants = list() //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented...
|
||||
|
||||
@@ -130,4 +130,8 @@
|
||||
#define ui_ai_pda_log "SOUTH:6,WEST+11"
|
||||
#define ui_ai_take_picture "SOUTH:6,WEST+12"
|
||||
#define ui_ai_view_images "SOUTH:6,WEST+13"
|
||||
#define ui_ai_sensor "SOUTH:6,WEST+14"
|
||||
#define ui_ai_sensor "SOUTH:6,WEST+14"
|
||||
|
||||
// Bots
|
||||
#define ui_bot_radio "EAST-1:28,SOUTH:7"
|
||||
#define ui_bot_pull "EAST-2:26,SOUTH:7"
|
||||
@@ -0,0 +1,70 @@
|
||||
/obj/screen/bot
|
||||
icon = 'icons/mob/screen1_bot.dmi'
|
||||
|
||||
/obj/screen/bot/radio
|
||||
name = "radio"
|
||||
icon_state = "radio"
|
||||
|
||||
/obj/screen/bot/radio/Click()
|
||||
if(isbot(usr))
|
||||
var/mob/living/simple_animal/bot/B = usr
|
||||
B.Radio.interact(usr)
|
||||
|
||||
/datum/hud/proc/bot_hud()
|
||||
src.adding = list()
|
||||
src.other = list()
|
||||
|
||||
var/obj/screen/using
|
||||
|
||||
using = new /obj/screen/bot/radio()
|
||||
using.name = "radio"
|
||||
using.dir = SOUTHWEST
|
||||
using.icon_state = "radio"
|
||||
using.screen_loc = ui_bot_radio
|
||||
using.layer = 20
|
||||
src.adding += using
|
||||
|
||||
mymob.healths = new /obj/screen()
|
||||
mymob.healths.icon = 'icons/mob/screen1_bot.dmi'
|
||||
mymob.healths.icon_state = "health0"
|
||||
mymob.healths.name = "health"
|
||||
mymob.healths.screen_loc = ui_borg_health
|
||||
|
||||
mymob.oxygen = new /obj/screen()
|
||||
mymob.oxygen.icon = 'icons/mob/screen1_bot.dmi'
|
||||
mymob.oxygen.icon_state = "oxy0"
|
||||
mymob.oxygen.name = "oxygen"
|
||||
mymob.oxygen.screen_loc = ui_oxygen
|
||||
|
||||
mymob.fire = new /obj/screen()
|
||||
mymob.fire.icon = 'icons/mob/screen1_bot.dmi'
|
||||
mymob.fire.icon_state = "fire0"
|
||||
mymob.fire.name = "fire"
|
||||
mymob.fire.screen_loc = ui_fire
|
||||
|
||||
mymob.pullin = new /obj/screen/pull()
|
||||
mymob.pullin.icon = 'icons/mob/screen1_bot.dmi'
|
||||
mymob.pullin.update_icon(mymob)
|
||||
mymob.pullin.screen_loc = ui_bot_pull
|
||||
|
||||
mymob.blind = new /obj/screen()
|
||||
mymob.blind.icon = 'icons/mob/screen1_full.dmi'
|
||||
mymob.blind.icon_state = "blackimageoverlay"
|
||||
mymob.blind.name = " "
|
||||
mymob.blind.screen_loc = "CENTER-7,CENTER-7"
|
||||
mymob.blind.layer = 0
|
||||
mymob.blind.mouse_opacity = 0
|
||||
|
||||
mymob.flash = new /obj/screen()
|
||||
mymob.flash.icon = 'icons/mob/screen1_bot.dmi'
|
||||
mymob.flash.icon_state = "blank"
|
||||
mymob.flash.name = "flash"
|
||||
mymob.flash.screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
mymob.flash.layer = 17
|
||||
|
||||
mymob.client.screen = list()
|
||||
|
||||
mymob.client.screen += list(mymob.oxygen, mymob.fire, mymob.healths, mymob.pullin, mymob.blind, mymob.flash)
|
||||
mymob.client.screen += adding + other
|
||||
mymob.client.screen += mymob.client.void
|
||||
return
|
||||
@@ -194,6 +194,8 @@ datum/hud/New(mob/owner)
|
||||
ai_hud()
|
||||
else if(isrobot(mymob))
|
||||
robot_hud()
|
||||
else if(isbot(mymob))
|
||||
bot_hud()
|
||||
else if(isobserver(mymob))
|
||||
ghost_hud()
|
||||
else if(isovermind(mymob))
|
||||
@@ -206,6 +208,8 @@ datum/hud/New(mob/owner)
|
||||
guardian_hud()
|
||||
else if(ispet(mymob))
|
||||
corgi_hud()
|
||||
else
|
||||
|
||||
|
||||
//Triggered when F12 is pressed (Unless someone changed something in the DMF)
|
||||
/mob/verb/button_pressed_F12(var/full = 0 as null)
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
var/global/datum/controller/process/animal/animal_master
|
||||
|
||||
/datum/controller/process/animal
|
||||
var/current_cycle
|
||||
|
||||
/datum/controller/process/animal/setup()
|
||||
name = "animal"
|
||||
schedule_interval = 20 // every 2 seconds
|
||||
start_delay = 16
|
||||
log_startup_progress("Simple animal ticker starting up.")
|
||||
if(animal_master)
|
||||
qdel(animal_master) //only one mob master
|
||||
animal_master = src
|
||||
|
||||
/datum/controller/process/animal/started()
|
||||
..()
|
||||
if(!simple_animal_list)
|
||||
simple_animal_list = list()
|
||||
|
||||
/datum/controller/process/animal/statProcess()
|
||||
..()
|
||||
stat(null, "[simple_animal_list.len] simple animals")
|
||||
|
||||
/datum/controller/process/animal/doWork()
|
||||
for(last_object in simple_animal_list)
|
||||
var/mob/living/simple_animal/M = last_object
|
||||
if(istype(M) && isnull(M.gcDestroyed))
|
||||
if(!M.client && M.stat == CONSCIOUS)
|
||||
try
|
||||
M.process_ai()
|
||||
catch(var/exception/e)
|
||||
catchException(e, M)
|
||||
SCHECK
|
||||
else
|
||||
catchBadType(M)
|
||||
simple_animal_list -= M
|
||||
current_cycle++
|
||||
@@ -277,7 +277,7 @@
|
||||
name = "Completed Robots"
|
||||
id = "finished"
|
||||
blacklist = null
|
||||
whitelist = list(/obj/mecha,/obj/machinery/bot,/mob/living/silicon/robot)
|
||||
whitelist = list(/obj/mecha,/mob/living/simple_animal/bot,/mob/living/silicon/robot)
|
||||
mobcheck = 1
|
||||
//todo: detect and allow finished cyborg endoskeletons with no brain
|
||||
contains(var/atom/A)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
desc = "This spell conjures objs of the specified types in range."
|
||||
|
||||
var/list/summon_type = list() //determines what exactly will be summoned
|
||||
//should be text, like list("/obj/machinery/bot/ed209")
|
||||
//should be text, like list("/mob/simple_animal/bot/ed209")
|
||||
|
||||
var/summon_lifespan = 0 // 0=permanent, any other time in deciseconds
|
||||
var/summon_amt = 1 //amount of objects summoned
|
||||
@@ -61,7 +61,7 @@
|
||||
name = "Dispense Wizard Justice"
|
||||
desc = "This spell dispenses wizard justice."
|
||||
|
||||
summon_type = list(/obj/machinery/bot/ed209)
|
||||
summon_type = list(/mob/living/simple_animal/bot/ed209)
|
||||
summon_amt = 10
|
||||
range = 3
|
||||
newVars = list("emagged" = 1,"name" = "Wizard's Justicebot")
|
||||
@@ -77,10 +77,10 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
|
||||
|
||||
/datum/supply_packs/emergency/evac
|
||||
name = "Emergency Equipment Crate"
|
||||
contains = list(/obj/machinery/bot/floorbot,
|
||||
/obj/machinery/bot/floorbot,
|
||||
/obj/machinery/bot/medbot,
|
||||
/obj/machinery/bot/medbot,
|
||||
contains = list(/mob/living/simple_animal/bot/floorbot,
|
||||
/mob/living/simple_animal/bot/floorbot,
|
||||
/mob/living/simple_animal/bot/medbot,
|
||||
/mob/living/simple_animal/bot/medbot,
|
||||
/obj/item/weapon/tank/air,
|
||||
/obj/item/weapon/tank/air,
|
||||
/obj/item/weapon/tank/air,
|
||||
@@ -1145,7 +1145,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
|
||||
|
||||
/datum/supply_packs/misc/mule
|
||||
name = "MULEbot Crate"
|
||||
contains = list(/obj/machinery/bot/mulebot)
|
||||
contains = list(/mob/living/simple_animal/bot/mulebot)
|
||||
cost = 20
|
||||
containertype = /obj/structure/largecrate/mule
|
||||
containername = "\improper MULEbot crate"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/wires/mulebot
|
||||
random = 1
|
||||
holder_type = /obj/machinery/bot/mulebot
|
||||
holder_type = /mob/living/simple_animal/bot/mulebot
|
||||
wire_count = 10
|
||||
|
||||
var/const/WIRE_POWER1 = 1 // power connections
|
||||
@@ -14,7 +14,7 @@ var/const/WIRE_REMOTE_TX = 128 // remote trans status
|
||||
var/const/WIRE_BEACON_RX = 256 // beacon ping recv
|
||||
|
||||
/datum/wires/mulebot/CanUse(var/mob/living/L)
|
||||
var/obj/machinery/bot/mulebot/M = holder
|
||||
var/mob/living/simple_animal/bot/mulebot/M = holder
|
||||
if(M.open)
|
||||
return 1
|
||||
return 0
|
||||
@@ -22,7 +22,7 @@ var/const/WIRE_BEACON_RX = 256 // beacon ping recv
|
||||
// So the wires do not open a new window, handle the interaction ourselves.
|
||||
/datum/wires/mulebot/Interact(var/mob/living/user)
|
||||
if(CanUse(user))
|
||||
var/obj/machinery/bot/mulebot/M = holder
|
||||
var/mob/living/simple_animal/bot/mulebot/M = holder
|
||||
M.interact(user)
|
||||
|
||||
/datum/wires/mulebot/UpdatePulsed(var/index)
|
||||
|
||||
+22
-41
@@ -62,14 +62,19 @@ Actual Adjacent procs :
|
||||
return b.f - a.f
|
||||
|
||||
//wrapper that returns an empty list if A* failed to find a path
|
||||
/proc/get_path_to(start, end, atom, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableAdjacentTurfs, id=null, turf/exclude=null, simulated_only = 1)
|
||||
var/list/path = AStar(start, end, atom, dist, maxnodes, maxnodedepth, mintargetdist, adjacent,id, exclude, simulated_only)
|
||||
/proc/get_path_to(caller, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableAdjacentTurfs, id=null, turf/exclude=null, simulated_only = 1)
|
||||
var/list/path = AStar(caller, end, dist, maxnodes, maxnodedepth, mintargetdist, adjacent, id, exclude, simulated_only)
|
||||
if(!path)
|
||||
path = list()
|
||||
return path
|
||||
|
||||
//the actual algorithm
|
||||
/proc/AStar(start, end, atom, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableAdjacentTurfs, id=null, turf/exclude=null, simulated_only = 1)
|
||||
/proc/AStar(caller, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableAdjacentTurfs, id=null, turf/exclude=null, simulated_only = 1)
|
||||
|
||||
//sanitation
|
||||
var/start = get_turf(caller)
|
||||
if(!start)
|
||||
return 0
|
||||
|
||||
if(maxnodes)
|
||||
//if start turf is farther than maxnodes from end turf, no need to do anything
|
||||
@@ -82,11 +87,6 @@ Actual Adjacent procs :
|
||||
var/list/path = null //the returned path, if any
|
||||
var/PathNode/cur //current processed turf
|
||||
|
||||
//sanitation
|
||||
start = get_turf(start)
|
||||
if(!start)
|
||||
return 0
|
||||
|
||||
//initialization
|
||||
open.Insert(new /PathNode(start,null,0,call(start,dist)(end),0))
|
||||
|
||||
@@ -118,9 +118,9 @@ Actual Adjacent procs :
|
||||
break
|
||||
|
||||
//get adjacents turfs using the adjacent proc, checking for access with id
|
||||
var/list/L = call(cur.source,adjacent)(atom,id, simulated_only)
|
||||
var/list/L = call(cur.source,adjacent)(caller, id, simulated_only)
|
||||
for(var/turf/T in L)
|
||||
if(T == exclude || T in closed)
|
||||
if(T == exclude || (T in closed))
|
||||
continue
|
||||
|
||||
var/newg = cur.g + call(cur.source,dist)(T)
|
||||
@@ -151,7 +151,7 @@ Actual Adjacent procs :
|
||||
|
||||
//Returns adjacent turfs in cardinal directions that are reachable
|
||||
//simulated_only controls whether only simulated turfs are considered or not
|
||||
/turf/proc/reachableAdjacentTurfs(atom, ID, simulated_only)
|
||||
/turf/proc/reachableAdjacentTurfs(caller, ID, simulated_only)
|
||||
var/list/L = new()
|
||||
var/turf/simulated/T
|
||||
|
||||
@@ -159,45 +159,26 @@ Actual Adjacent procs :
|
||||
T = get_step(src,dir)
|
||||
if(simulated_only && !istype(T))
|
||||
continue
|
||||
if(!T.density && !LinkBlockedWithAccess(T, ID))
|
||||
if(!T.density && !LinkBlockedWithAccess(T,caller, ID))
|
||||
L.Add(T)
|
||||
return L
|
||||
|
||||
//Returns adjacent turfs in cardinal directions that are reachable via atmos
|
||||
/turf/proc/reachableAdjacentAtmosTurfs()
|
||||
var/list/L = new()
|
||||
var/turf/simulated/T
|
||||
return atmos_adjacent_turfs
|
||||
|
||||
for(var/dir in cardinal)
|
||||
if(dir & atmos_adjacent_turfs)
|
||||
T = get_step(src,dir)
|
||||
if(!istype(T))
|
||||
continue
|
||||
if(CanAtmosPass(T))
|
||||
L.Add(T)
|
||||
return L
|
||||
|
||||
/turf/proc/LinkBlockedWithAccess(turf/T, obj/item/weapon/card/id/ID)
|
||||
/turf/proc/LinkBlockedWithAccess(turf/T, caller, ID)
|
||||
var/adir = get_dir(src, T)
|
||||
var/rdir = get_dir(T, src)
|
||||
if(DirBlockedWithAccess(src, adir, ID))
|
||||
return 1
|
||||
if(DirBlockedWithAccess(T, rdir, ID))
|
||||
return 1
|
||||
for(var/obj/O in T)
|
||||
if(O.density && !istype(O, /obj/machinery/door) && !(O.flags & ON_BORDER))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/DirBlockedWithAccess(turf/T, dir, ID)
|
||||
for(var/obj/structure/window/D in T)
|
||||
if(!D.density)
|
||||
continue
|
||||
if(D.dir == SOUTHWEST)
|
||||
for(var/obj/structure/window/W in src)
|
||||
if(!W.CanAStarPass(ID, adir))
|
||||
return 1
|
||||
if(D.dir == dir)
|
||||
for(var/obj/machinery/door/window/W in src)
|
||||
if(!W.CanAStarPass(ID, adir))
|
||||
return 1
|
||||
for(var/obj/machinery/door/D in T)
|
||||
if(!D.CanAStarPass(ID, dir))
|
||||
for(var/obj/O in T)
|
||||
if(!O.CanAStarPass(ID, rdir, caller))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
return 0
|
||||
@@ -60,7 +60,7 @@ var/global/max_secret_rooms = 6
|
||||
if("organharvest")
|
||||
walltypes = list(/turf/simulated/wall/r_wall=2,/turf/simulated/wall=2,/turf/simulated/mineral/random/high_chance=1)
|
||||
floortypes = list(/turf/simulated/floor,/turf/simulated/floor/engine)
|
||||
treasureitems = list(/obj/machinery/bot/medbot/mysterious=1, /obj/item/weapon/circular_saw=1, /obj/structure/closet/critter/cat=2)
|
||||
treasureitems = list(/mob/living/simple_animal/bot/medbot/mysterious=1, /obj/item/weapon/circular_saw=1, /obj/structure/closet/critter/cat=2)
|
||||
fluffitems = list(/obj/effect/decal/cleanable/blood=5,/obj/item/organ/internal/appendix=2,/obj/structure/closet/crate/freezer=2,
|
||||
/obj/machinery/optable=1,/obj/item/weapon/scalpel=1,/obj/item/weapon/storage/firstaid/regular=3,
|
||||
/obj/item/weapon/tank/anesthetic=1, /obj/item/weapon/surgical_drapes=2, /obj/item/device/mass_spectrometer/adv=1,/obj/item/clothing/glasses/hud/health=1)
|
||||
|
||||
+41
-2
@@ -44,7 +44,7 @@
|
||||
hud_icons = list(ID_HUD, IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD, WANTED_HUD)
|
||||
|
||||
/datum/atom_hud/data/diagnostic
|
||||
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD)
|
||||
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD)
|
||||
|
||||
/* MED/SEC/DIAG HUD HOOKS */
|
||||
|
||||
@@ -253,4 +253,43 @@
|
||||
var/image/holder = hud_list[DIAG_STAT_HUD]
|
||||
holder.icon_state = null
|
||||
if(internal_damage)
|
||||
holder.icon_state = "hudwarn"
|
||||
holder.icon_state = "hudwarn"
|
||||
|
||||
/*~~~~~~~~~
|
||||
Bots!
|
||||
~~~~~~~~~~*/
|
||||
/mob/living/simple_animal/bot/proc/diag_hud_set_bothealth()
|
||||
var/image/holder = hud_list[DIAG_HUD]
|
||||
if(stat == DEAD)
|
||||
holder.icon_state = "huddiagdead"
|
||||
else
|
||||
holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]"
|
||||
|
||||
/mob/living/simple_animal/bot/proc/diag_hud_set_botstat() //On (With wireless on or off), Off, EMP'ed
|
||||
var/image/holder = hud_list[DIAG_STAT_HUD]
|
||||
if(on)
|
||||
holder.icon_state = "hudstat"
|
||||
else if(stat) //Generally EMP causes this
|
||||
holder.icon_state = "hudoffline"
|
||||
else //Bot is off
|
||||
holder.icon_state = "huddead2"
|
||||
|
||||
/mob/living/simple_animal/bot/proc/diag_hud_set_botmode() //Shows a bot's current operation
|
||||
var/image/holder = hud_list[DIAG_BOT_HUD]
|
||||
if(client) //If the bot is player controlled, it will not be following mode logic!
|
||||
holder.icon_state = "hudsentient"
|
||||
return
|
||||
|
||||
switch(mode)
|
||||
if(BOT_SUMMON, BOT_RESPONDING) //Responding to PDA or AI summons
|
||||
holder.icon_state = "hudcalled"
|
||||
if(BOT_CLEANING, BOT_REPAIRING, BOT_HEALING) //Cleanbot cleaning, Floorbot fixing, or Medibot Healing
|
||||
holder.icon_state = "hudworking"
|
||||
if(BOT_PATROL, BOT_START_PATROL) //Patrol mode
|
||||
holder.icon_state = "hudpatrol"
|
||||
if(BOT_PREP_ARREST, BOT_ARREST, BOT_HUNT, BOT_BLOCKED, BOT_NO_ROUTE) //STOP RIGHT THERE, CRIMINAL SCUM!
|
||||
holder.icon_state = "hudalert"
|
||||
if(BOT_MOVING, BOT_DELIVER, BOT_GO_HOME, BOT_NAV, BOT_WAIT_FOR_NAV) //Moving to target for normal bots, moving to deliver or go home for MULES.
|
||||
holder.icon_state = "hudmove"
|
||||
else
|
||||
holder.icon_state = ""
|
||||
@@ -8,14 +8,7 @@
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
pass_flags = PASSBLOB
|
||||
faction = list("blob")
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 360
|
||||
universal_speak = 1 //So mobs can understand them when a blob uses Blob Broadcast
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
|
||||
return 0
|
||||
|
||||
/obj/effect/blob/CanAStarPass(ID, dir, caller)
|
||||
. = 0
|
||||
if(ismovableatom(caller))
|
||||
var/atom/movable/mover = caller
|
||||
. = . || mover.checkpass(PASSBLOB)
|
||||
|
||||
/obj/effect/blob/process()
|
||||
Life()
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
return
|
||||
if(!isturf(user.loc))
|
||||
return
|
||||
if(!AStar(user.loc, target.loc, null, /turf/proc/Distance, user.mind.changeling.sting_range, simulated_only = 0))
|
||||
if(!AStar(user, target.loc, /turf/proc/Distance, user.mind.changeling.sting_range, simulated_only = 0))
|
||||
return
|
||||
if(target.mind && target.mind.changeling)
|
||||
sting_feedback(user,target)
|
||||
|
||||
@@ -46,19 +46,12 @@
|
||||
harm_intent_damage = 5
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 500
|
||||
min_oxy = 0
|
||||
max_oxy = INFINITY
|
||||
min_tox = 0
|
||||
max_tox = INFINITY
|
||||
min_co2 = 0
|
||||
max_co2 = INFINITY
|
||||
min_n2 = 0
|
||||
max_n2 = INFINITY
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
unsuitable_atmos_damage = 0
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
melee_damage_type = STAMINA
|
||||
ignored_damage_types = list(BRUTE = 0, BURN = 0, TOX = 1, CLONE = 1, STAMINA = 1, OXY = 1)
|
||||
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
environment_smash = 0
|
||||
attacktext = "shocks"
|
||||
attack_sound = 'sound/effects/EMPulse.ogg'
|
||||
|
||||
@@ -17,14 +17,7 @@
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
minbodytemp = 0
|
||||
maxbodytemp = INFINITY
|
||||
min_oxy = 0
|
||||
max_oxy = INFINITY
|
||||
min_tox = 0
|
||||
max_tox = INFINITY
|
||||
min_co2 = 0
|
||||
max_co2 = INFINITY
|
||||
min_n2 = 0
|
||||
max_n2 = INFINITY
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
attacktext = "punches"
|
||||
maxHealth = INFINITY //The spirit itself is invincible
|
||||
health = INFINITY
|
||||
|
||||
@@ -17,14 +17,7 @@
|
||||
pass_flags = PASSTABLE
|
||||
ventcrawler = 2
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
|
||||
minbodytemp = 0
|
||||
maxHealth = 150
|
||||
|
||||
@@ -164,18 +164,18 @@
|
||||
if(attempt_cast(user))
|
||||
for(var/turf/T in targets)
|
||||
spawn(0)
|
||||
for(var/obj/machinery/bot/bot in T.contents)
|
||||
for(var/mob/living/simple_animal/bot/bot in T.contents)
|
||||
if(!bot.emagged)
|
||||
new/obj/effect/overlay/temp/revenant(bot.loc)
|
||||
bot.locked = 0
|
||||
bot.open = 1
|
||||
bot.Emag(null)
|
||||
bot.emag_act(null)
|
||||
for(var/mob/living/carbon/human/human in T.contents)
|
||||
human << "<span class='warning'>You feel [pick("your sense of direction flicker out", "a stabbing pain in your head", "your mind fill with static")].</span>"
|
||||
new/obj/effect/overlay/temp/revenant(human.loc)
|
||||
human.emp_act(1)
|
||||
for(var/obj/thing in T.contents)
|
||||
if(istype(thing, /obj/machinery/power/apc) || istype(thing, /obj/machinery/power/smes) || istype(thing, /obj/machinery/bot)) //Doesn't work on dominators, SMES and APCs, to prevent kekkery
|
||||
if(istype(thing, /obj/machinery/power/apc) || istype(thing, /obj/machinery/power/smes)) //Doesn't work on dominators, SMES and APCs, to prevent kekkery
|
||||
continue
|
||||
if(prob(20))
|
||||
if(prob(50))
|
||||
|
||||
@@ -18,14 +18,7 @@
|
||||
stop_automated_movement = 1
|
||||
status_flags = CANPUSH
|
||||
attack_sound = 'sound/misc/demon_attack1.ogg'
|
||||
min_oxy = 0
|
||||
max_oxy = INFINITY
|
||||
min_tox = 0
|
||||
max_tox = INFINITY
|
||||
min_co2 = 0
|
||||
max_co2 = INFINITY
|
||||
min_n2 = 0
|
||||
max_n2 = INFINITY
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
maxbodytemp = INFINITY
|
||||
faction = list("slaughter")
|
||||
|
||||
@@ -389,7 +389,7 @@
|
||||
if(locs.len == num_bats) //we found 2 locations and thats all we need
|
||||
break
|
||||
var/turf/T = get_step(usr, direction) //getting a loc in that direction
|
||||
if(AStar(usr.loc, T, /turf/proc/AdjacentTurfs, /turf/proc/Distance, 1, simulated_only = 0)) // if a path exists, so no dense objects in the way its valid salid
|
||||
if(AStar(user, T, /turf/proc/Distance, 1, simulated_only = 0)) // if a path exists, so no dense objects in the way its valid salid
|
||||
locs += T
|
||||
|
||||
// pad with player location
|
||||
|
||||
@@ -108,7 +108,6 @@
|
||||
|
||||
//returns 1 if this mob has sufficient access to use this object
|
||||
/obj/proc/allowed(mob/M)
|
||||
generate_req_lists()
|
||||
//check if we don't require any access at all
|
||||
if(check_access())
|
||||
return 1
|
||||
@@ -151,23 +150,12 @@
|
||||
req_one_access += n
|
||||
|
||||
/obj/proc/check_access(obj/item/I)
|
||||
if(!istype(req_access, /list))
|
||||
return 1
|
||||
|
||||
if(!req_access.len && (!req_one_access || !req_one_access.len))
|
||||
return 1
|
||||
if(!I)
|
||||
return 0
|
||||
for(var/req in src.req_access)
|
||||
if(!(req in I.GetAccess())) //doesn't have this access
|
||||
return 0
|
||||
if(req_one_access && req_one_access.len)
|
||||
for(var/req in req_one_access)
|
||||
if(req in I.GetAccess()) //has an access from the single access list
|
||||
return 1
|
||||
return 0
|
||||
return 1
|
||||
|
||||
var/list/L
|
||||
if(I)
|
||||
L = I.GetAccess()
|
||||
else
|
||||
L = list()
|
||||
return check_access_list(L)
|
||||
|
||||
/obj/proc/check_access_list(var/list/L)
|
||||
generate_req_lists()
|
||||
|
||||
@@ -1,801 +0,0 @@
|
||||
// AI (i.e. game AI, not the AI player) controlled bots
|
||||
/obj/machinery/bot
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
layer = MOB_LAYER
|
||||
light_range = 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
|
||||
var/fire_dam_coeff = 1.0
|
||||
var/brute_dam_coeff = 1.0
|
||||
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_name = "Common"
|
||||
//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 = BOT_FREQ // 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
|
||||
var/bot_type_name = "Bot"
|
||||
|
||||
#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()
|
||||
if(stat) return 0
|
||||
on = 1
|
||||
set_light(initial(light_range))
|
||||
return 1
|
||||
|
||||
/obj/machinery/bot/proc/turn_off()
|
||||
on = 0
|
||||
set_light(0)
|
||||
bot_reset() //Resets an AI's call, should it exist.
|
||||
|
||||
/obj/machinery/bot/New()
|
||||
..()
|
||||
aibots += src //Global bot list
|
||||
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.
|
||||
Radio.config(list("[radio_name]" = 0))
|
||||
Radio.follow_target = src
|
||||
|
||||
|
||||
/obj/machinery/bot/Destroy()
|
||||
aibots -= src
|
||||
qdel(Radio)
|
||||
Radio = null
|
||||
qdel(botcard)
|
||||
botcard = null
|
||||
return ..()
|
||||
|
||||
/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.
|
||||
spawn(20)
|
||||
if(radio_controller)
|
||||
radio_controller.add_object(src, beacon_freq, RADIO_NAVBEACONS)
|
||||
if(bot_filter)
|
||||
radio_controller.add_object(src, control_freq, bot_filter)
|
||||
|
||||
/obj/machinery/bot/proc/explode()
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/bot/proc/healthcheck()
|
||||
if (health <= 0)
|
||||
explode()
|
||||
|
||||
/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 << "<span class='warning'>You bypass [src]'s controls.</span>"
|
||||
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 << "<span class='notice'>You need to open maintenance panel first.</span>"
|
||||
|
||||
/obj/machinery/bot/examine(mob/user)
|
||||
..(user)
|
||||
if (health < maxhealth)
|
||||
if (health > maxhealth/3)
|
||||
user << "<span class='danger'>[src]'s parts look loose.</span>"
|
||||
else
|
||||
user << "<span class='danger'>[src]'s parts look very loose.</span>"
|
||||
else
|
||||
user << "[src] is in pristine condition."
|
||||
|
||||
/obj/machinery/bot/attack_alien(var/mob/living/carbon/alien/user as mob)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.do_attack_animation(src)
|
||||
health -= rand(15,30)*brute_dam_coeff
|
||||
visible_message("<span class='userdanger'>[user] has slashed [src]!</span>")
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
if(prob(10))
|
||||
new /obj/effect/decal/cleanable/blood/oil(loc)
|
||||
healthcheck()
|
||||
|
||||
|
||||
/obj/machinery/bot/attack_animal(var/mob/living/simple_animal/M as mob)
|
||||
M.do_attack_animation(src)
|
||||
if(M.melee_damage_upper == 0)
|
||||
return
|
||||
health -= M.melee_damage_upper
|
||||
visible_message("<span class='userdanger'>[M] has [M.attacktext] [src]!</span>")
|
||||
add_logs(M, src, "attacked", admin=0)
|
||||
if(prob(10))
|
||||
new /obj/effect/decal/cleanable/blood/oil(loc)
|
||||
healthcheck()
|
||||
|
||||
/obj/machinery/bot/Topic(href, href_list) //Master Topic to handle common functions.
|
||||
. = ..()
|
||||
if (.)
|
||||
return
|
||||
if(topic_denied(usr))
|
||||
usr << "<span class='warning'>[src]'s interface is not responding!</span>"
|
||||
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 << "<span class='warning'>[text_hack]</span>"
|
||||
bot_reset()
|
||||
else if(!hacked)
|
||||
usr << "<span class='userdanger'>[text_dehack_fail]</span>"
|
||||
else
|
||||
emagged = 0
|
||||
hacked = 0
|
||||
usr << "<span class='notice'>[text_dehack]</span>"
|
||||
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/proc/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, params)
|
||||
if(istype(W, /obj/item/weapon/screwdriver))
|
||||
if(!locked)
|
||||
open = !open
|
||||
user << "<span class='notice'>Maintenance panel is now [open ? "opened" : "closed"].</span>"
|
||||
else
|
||||
user << "<span class='warning'>Maintenance panel is locked.</span>"
|
||||
else
|
||||
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != I_HARM)
|
||||
if(health >= maxhealth)
|
||||
user << "<span class='warning'>[src] does not need a repair.</span>"
|
||||
return
|
||||
if(!open)
|
||||
user << "<span class='warning'>Unable to repair with the maintenance panel closed.</span>"
|
||||
return
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(WT.remove_fuel(0, user))
|
||||
health = min(maxhealth, health+10)
|
||||
user.visible_message("<span class='notice'>[user] repairs [src]!</span>","<span class='notice'>You repair [src]!</span>")
|
||||
else
|
||||
user << "<span class='warning'>The welder must be on for this task.</span>"
|
||||
else
|
||||
if(W.force) //if force is non-zero
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
switch(W.damtype)
|
||||
if("fire")
|
||||
health -= W.force * fire_dam_coeff
|
||||
s.start()
|
||||
if("brute")
|
||||
health -= W.force * brute_dam_coeff
|
||||
s.start()
|
||||
..()
|
||||
healthcheck()
|
||||
|
||||
/obj/machinery/bot/emag_act(user as mob)
|
||||
if (emagged < 2)
|
||||
Emag(user)
|
||||
|
||||
/obj/machinery/bot/bullet_act(var/obj/item/projectile/Proj)
|
||||
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
health -= Proj.damage
|
||||
if(prob(75) && Proj.damage > 0)
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
..()
|
||||
healthcheck()
|
||||
return
|
||||
|
||||
/obj/machinery/bot/blob_act()
|
||||
health -= rand(20,40)*fire_dam_coeff
|
||||
healthcheck()
|
||||
return
|
||||
|
||||
/obj/machinery/bot/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
explode()
|
||||
return
|
||||
if(2.0)
|
||||
health -= rand(5,10)*fire_dam_coeff
|
||||
health -= rand(10,20)*brute_dam_coeff
|
||||
healthcheck()
|
||||
return
|
||||
if(3.0)
|
||||
if (prob(50))
|
||||
health -= rand(1,5)*fire_dam_coeff
|
||||
health -= rand(1,5)*brute_dam_coeff
|
||||
healthcheck()
|
||||
return
|
||||
return
|
||||
|
||||
/obj/machinery/bot/emp_act(severity)
|
||||
var/was_on = on
|
||||
stat |= EMPED
|
||||
var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( loc )
|
||||
pulse2.icon = 'icons/effects/effects.dmi'
|
||||
pulse2.icon_state = "empdisable"
|
||||
pulse2.name = "emp sparks"
|
||||
pulse2.anchored = 1
|
||||
pulse2.dir = pick(cardinal)
|
||||
|
||||
spawn(10)
|
||||
pulse2.delete()
|
||||
if (on)
|
||||
turn_off()
|
||||
spawn(severity*300)
|
||||
stat &= ~EMPED
|
||||
if (was_on)
|
||||
turn_on()
|
||||
|
||||
/obj/machinery/bot/proc/hack(mob/user)
|
||||
var/hack
|
||||
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?"]<BR>"
|
||||
hack += "Harm Prevention Safety System: <A href='?src=\ref[src];operation=hack'>[emagged ? "<span class='bad'>DANGER</span>" : "Engaged"]</A><BR>"
|
||||
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: <A href='?src=\ref[src];operation=remote'>[remote_disabled ? "Disconnected" : "Connected"]</A><BR><BR>"
|
||||
return hack
|
||||
|
||||
/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/attack_ai(mob/user as mob)
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/bot/proc/speak(var/message, var/freqname = null) //Pass a message to have the bot say() it. Pass a frequency to say it on the radio.
|
||||
if((!on) || (!message))
|
||||
return
|
||||
if(freqname)
|
||||
Radio.autosay(message, src.name, freqname, list(src.z))
|
||||
else
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("<span class='game say'><span class='name'>[src]</span> beeps, \"[message]\"</span>",2)
|
||||
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.
|
||||
else
|
||||
continue
|
||||
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_towards(src, path[1])
|
||||
if(get_turf(src) == path[1]) //Successful move
|
||||
path -= path[1]
|
||||
else
|
||||
return 0
|
||||
else if(path.len == 1)
|
||||
step_towards(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 = get_path_to(src, waypoint, src, /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 << "<span class='notice'>\icon[src] [name] called to [end_area.name]. [path.len-1] meters to destination.</span>"
|
||||
pathset = 1
|
||||
mode = BOT_RESPONDING
|
||||
tries = 0
|
||||
else
|
||||
calling_ai << "<span class='danger'>Failed to calculate a valid route. Ensure destination is clear of obstructions and within range.</span>"
|
||||
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 ? "<span class='notice'>[src] successfully arrived to waypoint.</span>" : "<span class='danger'>[src] failed to reach waypoint.</span>"]"
|
||||
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 << "<span class='danger'>Call command to a bot has been reset.</span>"
|
||||
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 if(!awaiting_beacon) // 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 > 40) // wait 40 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(200)
|
||||
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_name)
|
||||
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<get_dist(src,nearest_beacon_loc))
|
||||
nearest_beacon = recv
|
||||
nearest_beacon_loc = signal.source.loc
|
||||
return
|
||||
else
|
||||
return
|
||||
else if(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 = get_path_to(loc, patrol_target, src, /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 = get_path_to(loc, summon_target, src, /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_name)
|
||||
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
|
||||
@@ -1,696 +0,0 @@
|
||||
/obj/machinery/bot/ed209
|
||||
name = "\improper ED-209 Security Robot"
|
||||
desc = "A security robot. He looks less than thrilled."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "ed2090"
|
||||
layer = 5.0
|
||||
density = 1
|
||||
anchored = 0
|
||||
// weight = 1.0E7
|
||||
req_access = list(access_security)
|
||||
health = 100
|
||||
maxhealth = 100
|
||||
fire_dam_coeff = 0.7
|
||||
brute_dam_coeff = 0.5
|
||||
|
||||
var/lastfired = 0
|
||||
var/shot_delay = 3 //.3 seconds between shots
|
||||
var/lasercolor = ""
|
||||
var/disabled = 0//A holder for if it needs to be disabled, if true it will not seach for targets, shoot at targets, or move, currently only used for lasertag
|
||||
|
||||
//var/lasers = 0
|
||||
|
||||
var/mob/living/carbon/target
|
||||
var/oldtarget_name
|
||||
var/threatlevel = 0
|
||||
var/target_lastloc //Loc of target when arrested.
|
||||
var/last_found //There's a delay
|
||||
//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 = 0 //If true, arrest people with no IDs
|
||||
var/weaponscheck = 1 //If true, arrest people for weapons if they don't have access
|
||||
var/check_records = 1 //Does it check security records?
|
||||
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'
|
||||
radio_name = "Security"
|
||||
bot_type = SEC_BOT
|
||||
bot_type_name = "ED-209"
|
||||
bot_filter = RADIO_SECBOT
|
||||
|
||||
/obj/item/weapon/ed209_assembly
|
||||
name = "\improper ED-209 assembly"
|
||||
desc = "Some sort of bizarre assembly."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "ed209_frame"
|
||||
item_state = "ed209_frame"
|
||||
var/build_step = 0
|
||||
var/created_name = "ED-209 Security Robot" //To preserve the name if it's a unique securitron I guess
|
||||
var/lasercolor = ""
|
||||
|
||||
/obj/machinery/bot/ed209/New(loc,created_name,created_lasercolor)
|
||||
..()
|
||||
if(created_name)
|
||||
name = created_name
|
||||
if(created_lasercolor)
|
||||
lasercolor = created_lasercolor
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
set_weapon() //giving it the right projectile and firing sound.
|
||||
spawn(3)
|
||||
var/datum/job/officer/J = new/datum/job/officer
|
||||
botcard.access = J.get_access()
|
||||
prev_access = botcard.access
|
||||
|
||||
|
||||
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
|
||||
arrest_type = 1//Don't even try to cuff
|
||||
req_access = list(access_maint_tunnels, access_theatre)
|
||||
arrest_type = 1
|
||||
if((lasercolor == "b") && (name == "\improper ED-209 Security Robot"))//Picks a name if there isn't already a custome one
|
||||
name = pick("BLUE BALLER","SANIC","BLUE KILLDEATH MURDERBOT")
|
||||
if((lasercolor == "r") && (name == "\improper ED-209 Security Robot"))
|
||||
name = pick("RED RAMPAGE","RED ROVER","RED KILLDEATH MURDERBOT")
|
||||
|
||||
/obj/machinery/bot/ed209/turn_on()
|
||||
. = ..()
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
mode = BOT_IDLE
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/bot/ed209/turn_off()
|
||||
..()
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/bot/ed209/bot_reset()
|
||||
..()
|
||||
target = null
|
||||
oldtarget_name = null
|
||||
anchored = 0
|
||||
walk_to(src,0)
|
||||
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)
|
||||
. = ..()
|
||||
if (.)
|
||||
return
|
||||
usr.set_machine(src)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += text({"
|
||||
<TT><B>Security Unit v2.6 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]<BR>"},
|
||||
|
||||
"<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>" )
|
||||
|
||||
if(!locked || issilicon(user))
|
||||
if(!lasercolor)
|
||||
dat += text({"<BR>
|
||||
Arrest Unidentifiable Persons: []<BR>
|
||||
Arrest for Unauthorized Weapons: []<BR>
|
||||
Arrest for Warrant: []<BR>
|
||||
<BR>
|
||||
Operating Mode: []<BR>
|
||||
Report Arrests[]<BR>
|
||||
Auto Patrol[]"},
|
||||
|
||||
"<A href='?src=\ref[src];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
|
||||
"<A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
|
||||
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(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
|
||||
..()
|
||||
|
||||
switch(href_list["operation"])
|
||||
if ("idcheck")
|
||||
idcheck = !idcheck
|
||||
if("weaponscheck")
|
||||
weaponscheck = !weaponscheck
|
||||
updateUsrDialog()
|
||||
if ("ignorerec")
|
||||
check_records = !check_records
|
||||
updateUsrDialog()
|
||||
if ("switchmode")
|
||||
arrest_type = !arrest_type
|
||||
updateUsrDialog()
|
||||
if("declarearrests")
|
||||
declare_arrests = !declare_arrests
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/bot/ed209/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
|
||||
if (allowed(user) && !open && !emagged)
|
||||
locked = !locked
|
||||
user << "<span class='notice'>Controls are now [locked ? "locked" : "unlocked"].</span>"
|
||||
updateUsrDialog()
|
||||
else
|
||||
if(emagged)
|
||||
user << "<span class='warning'>ERROR</span>"
|
||||
if(open)
|
||||
user << "<span class='warning'>Please close the access panel before locking it.</span>"
|
||||
else
|
||||
user << "<span class='notice'>Access denied.</span>"
|
||||
else
|
||||
..()
|
||||
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != I_HARM) // Any intent but harm will heal, so we shouldn't get angry.
|
||||
return
|
||||
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)//If force is non-zero and damage type isn't stamina.
|
||||
threatlevel = user.assess_threat(src)
|
||||
threatlevel += 6
|
||||
if(threatlevel >= 4)
|
||||
target = user
|
||||
if(lasercolor)//To make up for the fact that lasertag bots don't hunt
|
||||
shootAt(user)
|
||||
mode = BOT_HUNT
|
||||
|
||||
/obj/machinery/bot/ed209/Emag(mob/user as mob)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
user << "<span class='warning'>You short out [src]'s target assessment circuits.</span>"
|
||||
oldtarget_name = user.name
|
||||
visible_message("<span class='danger'>[src] buzzes oddly!</span>")
|
||||
declare_arrests = 0
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
set_weapon()
|
||||
|
||||
/obj/machinery/bot/ed209/bot_process()
|
||||
if (!..())
|
||||
return
|
||||
|
||||
if(disabled)
|
||||
return
|
||||
|
||||
var/list/targets = list()
|
||||
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)
|
||||
//speak(C.real_name + text(": threat: []", threatlevel))
|
||||
if (threatlevel < 4 )
|
||||
continue
|
||||
|
||||
var/dst = get_dist(src, C)
|
||||
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.
|
||||
shootAt(t)
|
||||
switch(mode)
|
||||
|
||||
if(BOT_IDLE) // idle
|
||||
walk_to(src,0)
|
||||
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 = BOT_START_PATROL // switch to patrol mode
|
||||
|
||||
if(BOT_HUNT) // hunting for perp
|
||||
// if can't reach perp for long enough, go idle
|
||||
if (frustration >= 8)
|
||||
walk_to(src,0)
|
||||
back_to_idle()
|
||||
|
||||
if(target) // make sure target exists
|
||||
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)
|
||||
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
|
||||
M.Stun(5)
|
||||
M.Weaken(5)
|
||||
else
|
||||
M.Weaken(5)
|
||||
M.stuttering = 5
|
||||
M.Stun(5)
|
||||
|
||||
if(declare_arrests)
|
||||
var/area/location = get_area(src)
|
||||
speak("[arrest_type ? "Detaining" : "Arresting"] level [threatlevel] scumbag <b>[target]</b> in [location].", radio_name)
|
||||
target.visible_message("<span class='danger'>[target] has been stunned by [src]!</span>",\
|
||||
"<span class='userdanger'>[target] has been stunned by [src]!</span></span>")
|
||||
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = 1
|
||||
target_lastloc = M.loc
|
||||
return
|
||||
|
||||
else // not next to perp
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
walk_to(src, target,1,4)
|
||||
if ((get_dist(src, target)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
frustration = 0
|
||||
else
|
||||
back_to_idle()
|
||||
|
||||
if(BOT_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( !Adjacent(target) || !isturf(target.loc) || target.weakened < 2 )
|
||||
back_to_hunt()
|
||||
return
|
||||
|
||||
if(iscarbon(target) && target.canBeHandcuffed())
|
||||
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("<span class='danger'>[src] is trying to put zipties on [target]!</span>",\
|
||||
"<span class='userdanger'>[src] is trying to put zipties on [target]!</span>")
|
||||
spawn(30)
|
||||
if( !Adjacent(target) || !isturf(target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
|
||||
return
|
||||
if(!target.handcuffed)
|
||||
target.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(target)
|
||||
target.update_inv_handcuffed(1) //update the handcuffs overlay
|
||||
back_to_idle()
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(BOT_ARREST)
|
||||
if (!target)
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
return
|
||||
|
||||
if(target.handcuffed) //no target or target cuffed? back to idle.
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
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()
|
||||
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/bot/ed209/proc/back_to_idle()
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
spawn(0)
|
||||
bot_process() //ensure bot quickly responds
|
||||
|
||||
/obj/machinery/bot/ed209/proc/back_to_hunt()
|
||||
anchored = 0
|
||||
frustration = 0
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
bot_process() //ensure bot quickly responds
|
||||
|
||||
// look for a criminal in view of the bot
|
||||
|
||||
/obj/machinery/bot/ed209/proc/look_for_perp()
|
||||
if(disabled)
|
||||
return
|
||||
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 == oldtarget_name) && (world.time < last_found + 100))
|
||||
continue
|
||||
|
||||
threatlevel = C.assess_threat(src, lasercolor)
|
||||
|
||||
if (!threatlevel)
|
||||
continue
|
||||
|
||||
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("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
bot_process() // ensure bot quickly responds to a perp
|
||||
break
|
||||
else
|
||||
continue
|
||||
|
||||
/obj/machinery/bot/ed209/proc/check_for_weapons(var/obj/item/slot_item)
|
||||
if(slot_item && slot_item.needs_permit)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/bot/ed209/explode()
|
||||
walk_to(src,0)
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
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 = name
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
if(!lasercolor)
|
||||
var/obj/item/weapon/gun/energy/advtaser/G = new /obj/item/weapon/gun/energy/advtaser(Tsec)
|
||||
G.power_supply.charge = 0
|
||||
G.update_icon()
|
||||
else if(lasercolor == "b")
|
||||
var/obj/item/weapon/gun/energy/laser/bluetag/G = new /obj/item/weapon/gun/energy/laser/bluetag(Tsec)
|
||||
G.power_supply.charge = 0
|
||||
G.update_icon()
|
||||
else if(lasercolor == "r")
|
||||
var/obj/item/weapon/gun/energy/laser/redtag/G = new /obj/item/weapon/gun/energy/laser/redtag(Tsec)
|
||||
G.power_supply.charge = 0
|
||||
G.update_icon()
|
||||
|
||||
if (prob(50))
|
||||
new /obj/item/robot_parts/l_leg(Tsec)
|
||||
if (prob(25))
|
||||
new /obj/item/robot_parts/r_leg(Tsec)
|
||||
if (prob(25))//50% chance for a helmet OR vest
|
||||
if (prob(50))
|
||||
new /obj/item/clothing/head/helmet(Tsec)
|
||||
else
|
||||
if(!lasercolor)
|
||||
new /obj/item/clothing/suit/armor/vest(Tsec)
|
||||
if(lasercolor == "b")
|
||||
new /obj/item/clothing/suit/bluetag(Tsec)
|
||||
if(lasercolor == "r")
|
||||
new /obj/item/clothing/suit/redtag(Tsec)
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(loc)
|
||||
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(emagged == 2)
|
||||
if(lasercolor)
|
||||
projectile = /obj/item/projectile/lasertag
|
||||
else
|
||||
projectile = /obj/item/projectile/beam
|
||||
else
|
||||
if(!lasercolor)
|
||||
shoot_sound = 'sound/weapons/Taser.ogg'
|
||||
projectile = /obj/item/projectile/energy/electrode
|
||||
else if(lasercolor == "b")
|
||||
projectile = /obj/item/projectile/lasertag/blue
|
||||
else if(lasercolor == "r")
|
||||
projectile = /obj/item/projectile/lasertag/red
|
||||
|
||||
/obj/machinery/bot/ed209/proc/shootAt(var/mob/target)
|
||||
if(lastfired && world.time - lastfired < shot_delay)
|
||||
return
|
||||
lastfired = world.time
|
||||
var/turf/T = loc
|
||||
var/atom/U = (istype(target, /atom/movable) ? target.loc : target)
|
||||
if ((!( U ) || !( T )))
|
||||
return
|
||||
while(!( istype(U, /turf) ))
|
||||
U = U.loc
|
||||
if (!( istype(T, /turf) ))
|
||||
return
|
||||
|
||||
//if(lastfired && world.time - lastfired < 100)
|
||||
|
||||
if(!projectile)
|
||||
return
|
||||
|
||||
if (!( istype(U, /turf) ))
|
||||
return
|
||||
var/obj/item/projectile/A = new projectile (loc)
|
||||
playsound(loc, shoot_sound, 50, 1)
|
||||
A.current = U
|
||||
A.yo = U.y - T.y
|
||||
A.xo = U.x - T.x
|
||||
spawn( 0 )
|
||||
A.process()
|
||||
return
|
||||
return
|
||||
|
||||
/obj/machinery/bot/ed209/attack_alien(var/mob/living/carbon/alien/user as mob)
|
||||
..()
|
||||
if (!isalien(target))
|
||||
target = user
|
||||
mode = BOT_HUNT
|
||||
|
||||
|
||||
/obj/machinery/bot/ed209/emp_act(severity)
|
||||
|
||||
if(severity==2 && prob(70))
|
||||
..(severity-1)
|
||||
else
|
||||
var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( loc )
|
||||
pulse2.icon = 'icons/effects/effects.dmi'
|
||||
pulse2.icon_state = "empdisable"
|
||||
pulse2.name = "emp sparks"
|
||||
pulse2.anchored = 1
|
||||
pulse2.dir = pick(cardinal)
|
||||
spawn(10)
|
||||
pulse2.delete()
|
||||
var/list/mob/living/carbon/targets = new
|
||||
for (var/mob/living/carbon/C in view(12,src))
|
||||
if (C.stat==2)
|
||||
continue
|
||||
targets += C
|
||||
if(targets.len)
|
||||
if(prob(50))
|
||||
var/mob/toshoot = pick(targets)
|
||||
if (toshoot)
|
||||
targets-=toshoot
|
||||
if (prob(50) && emagged < 2)
|
||||
emagged = 2
|
||||
set_weapon()
|
||||
shootAt(toshoot)
|
||||
emagged = 0
|
||||
set_weapon()
|
||||
else
|
||||
shootAt(toshoot)
|
||||
else if(prob(50))
|
||||
if(targets.len)
|
||||
var/mob/toarrest = pick(targets)
|
||||
if (toarrest)
|
||||
target = toarrest
|
||||
mode = BOT_HUNT
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/ed209_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
..()
|
||||
|
||||
if(istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t) return
|
||||
if(!in_range(src, usr) && loc != usr) return
|
||||
created_name = t
|
||||
return
|
||||
|
||||
switch(build_step)
|
||||
if(0,1)
|
||||
if(istype(W, /obj/item/robot_parts/l_leg) || istype(W, /obj/item/robot_parts/r_leg))
|
||||
user.drop_item()
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the robot leg to [src].</span>"
|
||||
name = "legs/frame assembly"
|
||||
if(build_step == 1)
|
||||
item_state = "ed209_leg"
|
||||
icon_state = "ed209_leg"
|
||||
else
|
||||
item_state = "ed209_legs"
|
||||
icon_state = "ed209_legs"
|
||||
|
||||
if(2)
|
||||
if(istype(W, /obj/item/clothing/suit/redtag))
|
||||
lasercolor = "r"
|
||||
else if(istype(W, /obj/item/clothing/suit/bluetag))
|
||||
lasercolor = "b"
|
||||
if(lasercolor || istype(W, /obj/item/clothing/suit/armor/vest))
|
||||
user.drop_item()
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the armor to [src].</span>"
|
||||
name = "vest/legs/frame assembly"
|
||||
item_state = "[lasercolor]ed209_shell"
|
||||
icon_state = "[lasercolor]ed209_shell"
|
||||
|
||||
if(3)
|
||||
if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(WT.remove_fuel(0,user))
|
||||
build_step++
|
||||
name = "shielded frame assembly"
|
||||
user << "<span class='notice'>You welded the vest to [src].</span>"
|
||||
if(4)
|
||||
switch(lasercolor)
|
||||
//if("b")
|
||||
//if(!istype(W, /obj/item/clothing/head/helmet/bluetaghelm))
|
||||
//return
|
||||
|
||||
//if("r")
|
||||
//if(!istype(W, /obj/item/clothing/head/helmet/redtaghelm))
|
||||
//return
|
||||
|
||||
if("")
|
||||
if(!istype(W, /obj/item/clothing/head/helmet))
|
||||
return
|
||||
|
||||
user.drop_item()
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the helmet to [src].</span>"
|
||||
name = "covered and shielded frame assembly"
|
||||
item_state = "[lasercolor]ed209_hat"
|
||||
icon_state = "[lasercolor]ed209_hat"
|
||||
|
||||
if(5)
|
||||
if(isprox(W))
|
||||
user.drop_item()
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the prox sensor to [src].</span>"
|
||||
name = "covered, shielded and sensored frame assembly"
|
||||
item_state = "[lasercolor]ed209_prox"
|
||||
icon_state = "[lasercolor]ed209_prox"
|
||||
|
||||
if(6)
|
||||
if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/coil = W
|
||||
if (coil.amount < 1)
|
||||
user << "<span class='warning'>You need one length of cable to wire the ED-209.</span>"
|
||||
return
|
||||
user << "<span class='notice'>You start to wire [src]...</span>"
|
||||
if (do_after(user, 40, target = src))
|
||||
if (coil.amount >= 1 && build_step == 6)
|
||||
coil.use(1)
|
||||
build_step = 7
|
||||
user << "<span class='notice'>You wire the ED-209 assembly.</span>"
|
||||
name = "wired ED-209 assembly"
|
||||
|
||||
if(7)
|
||||
switch(lasercolor)
|
||||
if("b")
|
||||
if(!istype(W, /obj/item/weapon/gun/energy/laser/bluetag))
|
||||
return
|
||||
name = "bluetag ED-209 assembly"
|
||||
if("r")
|
||||
if(!istype(W, /obj/item/weapon/gun/energy/laser/redtag))
|
||||
return
|
||||
name = "redtag ED-209 assembly"
|
||||
if("")
|
||||
if(!istype(W, /obj/item/weapon/gun/energy/advtaser))
|
||||
return
|
||||
name = "taser ED-209 assembly"
|
||||
else
|
||||
return
|
||||
build_step++
|
||||
user << "<span class='notice'>You add [W] to [src].</span>"
|
||||
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(loc, 'sound/items/Screwdriver.ogg', 100, 1)
|
||||
var/turf/T = get_turf(user)
|
||||
if(get_turf(user) == T)
|
||||
build_step++
|
||||
name = "armed [name]"
|
||||
user << "<span class='notice'>Taser gun attached.</span>"
|
||||
|
||||
if(9)
|
||||
if(istype(W, /obj/item/weapon/stock_parts/cell))
|
||||
build_step++
|
||||
user << "<span class='notice'>You complete the ED-209.</span>"
|
||||
var/turf/T = get_turf(src)
|
||||
new /obj/machinery/bot/ed209(T,created_name,lasercolor)
|
||||
user.drop_item()
|
||||
qdel(W)
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/machinery/bot/ed209/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(!disabled)
|
||||
var/lasertag_check = 0
|
||||
if((lasercolor == "b"))
|
||||
if(istype(Proj, /obj/item/projectile/lasertag/red))
|
||||
lasertag_check++
|
||||
else if((lasercolor == "r"))
|
||||
if(istype(Proj, /obj/item/projectile/lasertag/blue))
|
||||
lasertag_check++
|
||||
if(lasertag_check)
|
||||
icon_state = "[lasercolor]ed2090"
|
||||
disabled = 1
|
||||
target = null
|
||||
spawn(100)
|
||||
disabled = 0
|
||||
icon_state = "[lasercolor]ed2091"
|
||||
return 1
|
||||
else
|
||||
..(Proj)
|
||||
else
|
||||
..(Proj)
|
||||
|
||||
/obj/machinery/bot/ed209/bluetag/New()//If desired, you spawn red and bluetag bots easily
|
||||
new /obj/machinery/bot/ed209(get_turf(src),null,"b")
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/machinery/bot/ed209/redtag/New()
|
||||
new /obj/machinery/bot/ed209(get_turf(src),null,"r")
|
||||
qdel(src)
|
||||
@@ -1,942 +0,0 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
|
||||
// Mulebot - carries crates around for Quartermaster
|
||||
// Navigates via floor navbeacons
|
||||
// Remote Controlled from QM's PDA
|
||||
|
||||
var/global/mulebot_count = 0
|
||||
|
||||
/obj/machinery/bot/mulebot
|
||||
name = "\improper MULEbot"
|
||||
desc = "A Multiple Utility Load Effector bot."
|
||||
icon_state = "mulebot0"
|
||||
layer = MOB_LAYER
|
||||
density = 1
|
||||
anchored = 1
|
||||
animate_movement=1
|
||||
health = 150 //yeah, it's tougher than ed209 because it is a big metal box with wheels --rastaf0
|
||||
maxhealth = 150
|
||||
fire_dam_coeff = 0.7
|
||||
brute_dam_coeff = 0.5
|
||||
var/atom/movable/load = null // the loaded crate (usually)
|
||||
var/list/delivery_beacons = list() //List of beacons that serve as delivery locations.
|
||||
beacon_freq = 1400
|
||||
bot_type = MULE_BOT
|
||||
bot_type_name = "MULEbot"
|
||||
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/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
|
||||
|
||||
mode = BOT_IDLE
|
||||
|
||||
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/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
|
||||
// the installed power cell
|
||||
|
||||
// constants for internal wiring bitflags
|
||||
/*
|
||||
|
||||
var/wires = 1023 // all flags on
|
||||
|
||||
var/list/wire_text // list of wire colours
|
||||
var/list/wire_order // order of wire indices
|
||||
*/
|
||||
|
||||
|
||||
var/bloodiness = 0 // count of bloodiness
|
||||
var/currentBloodColor = "#A10808"
|
||||
|
||||
/obj/machinery/bot/mulebot/New()
|
||||
..()
|
||||
wires = 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
|
||||
add_to_beacons(bot_filter)
|
||||
|
||||
mulebot_count += 1
|
||||
if(!suffix)
|
||||
suffix = "#[mulebot_count]"
|
||||
name = "\improper Mulebot ([suffix])"
|
||||
|
||||
/obj/machinery/bot/mulebot/Destroy()
|
||||
unload(0)
|
||||
qdel(wires)
|
||||
wires = null
|
||||
if(cell)
|
||||
qdel(cell)
|
||||
cell = null
|
||||
return ..()
|
||||
|
||||
// attack by item
|
||||
// emag : lock/unlock,
|
||||
// screwdriver: open/close hatch
|
||||
// cell: insert it
|
||||
// other: chance to knock rider off bot
|
||||
/obj/machinery/bot/mulebot/attackby(var/obj/item/I, var/mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/card/id) || istype(I, /obj/item/device/pda))
|
||||
if(toggle_lock(user))
|
||||
user << "<span class='notice'>Controls [(locked ? "locked" : "unlocked")].</span>"
|
||||
updateUsrDialog()
|
||||
else if(istype(I,/obj/item/weapon/stock_parts/cell) && open && !cell)
|
||||
var/obj/item/weapon/stock_parts/cell/C = I
|
||||
user.drop_item()
|
||||
C.loc = src
|
||||
cell = C
|
||||
updateDialog()
|
||||
else if(istype(I,/obj/item/weapon/screwdriver))
|
||||
if(locked)
|
||||
user << "<span class='notice'>The maintenance hatch cannot be opened or closed while the controls are locked.</span>"
|
||||
return
|
||||
|
||||
open = !open
|
||||
if(open)
|
||||
visible_message("[user] opens the maintenance hatch of [src]", "<span class='notice'>You open [src]'s maintenance hatch.</span>")
|
||||
on = 0
|
||||
icon_state="mulebot-hatch"
|
||||
else
|
||||
visible_message("[user] closes the maintenance hatch of [src]", "<span class='notice'>You close [src]'s maintenance hatch.</span>")
|
||||
icon_state = "mulebot0"
|
||||
|
||||
updateDialog()
|
||||
else if (istype(I, /obj/item/weapon/wrench))
|
||||
if (health < maxhealth)
|
||||
health = min(maxhealth, health+25)
|
||||
user.visible_message(
|
||||
"<span class='notice'>[user] repairs [src]!</span>",
|
||||
"<span class='notice'>You repair [src]!</span>"
|
||||
)
|
||||
else
|
||||
user << "<span class='notice'> [src] does not need a repair!</span>"
|
||||
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("<span class='danger'> [user] knocks [load] off [src] with \the [I]!</span>", "<span class='danger'> You knock [load] off [src] with \the [I]!</span>")
|
||||
else
|
||||
user << "You hit [src] with \the [I] but to no effect."
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/machinery/bot/mulebot/emag_act(user as mob)
|
||||
locked = !locked
|
||||
user << "<span class='notice'>You [locked ? "lock" : "unlock"] the mulebot's controls!</span>"
|
||||
flick("mulebot-emagged", src)
|
||||
playsound(loc, 'sound/effects/sparks1.ogg', 100, 0)
|
||||
|
||||
/obj/machinery/bot/mulebot/ex_act(var/severity)
|
||||
unload(0)
|
||||
switch(severity)
|
||||
if(2)
|
||||
for(var/i = 1; i < 3; i++)
|
||||
wires.RandomCut()
|
||||
if(3)
|
||||
wires.RandomCut()
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/machinery/bot/mulebot/bullet_act()
|
||||
if(prob(50) && !isnull(load))
|
||||
unload(0)
|
||||
if(prob(25))
|
||||
visible_message("<span class='danger'> Something shorts out inside [src]!</span>")
|
||||
wires.RandomCut()
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/bot/mulebot/attack_ai(var/mob/user)
|
||||
user.set_machine(src)
|
||||
interact(user, 1)
|
||||
|
||||
/obj/machinery/bot/mulebot/attack_hand(var/mob/user)
|
||||
. = ..()
|
||||
if (.)
|
||||
return
|
||||
user.set_machine(src)
|
||||
interact(user, 0)
|
||||
|
||||
/obj/machinery/bot/mulebot/interact(var/mob/user, var/ai=0)
|
||||
var/dat
|
||||
dat += "<h3>Multiple Utility Load Effector Mk. V</h3>"
|
||||
dat += "<b>ID:</b> [suffix]<BR>"
|
||||
dat += "<b>Power:</b> [on ? "On" : "Off"]<BR>"
|
||||
|
||||
if(!open)
|
||||
|
||||
dat += "<h3>Status</h3>"
|
||||
|
||||
dat += "<div class='statusDisplay'>"
|
||||
switch(mode)
|
||||
if(BOT_IDLE)
|
||||
dat += "<span class='good'>Ready</span>"
|
||||
if(BOT_LOADING)
|
||||
dat += "<span class='good'>[mode_name[BOT_LOADING]]</span>"
|
||||
if(BOT_DELIVER)
|
||||
dat += "<span class='good'>[mode_name[BOT_DELIVER]]</span>"
|
||||
if(BOT_GO_HOME)
|
||||
dat += "<span class='good'>[mode_name[BOT_GO_HOME]]</span>"
|
||||
if(BOT_BLOCKED)
|
||||
dat += "<span class='average'>[mode_name[BOT_BLOCKED]]</span>"
|
||||
if(BOT_NAV,BOT_WAIT_FOR_NAV)
|
||||
dat += "<span class='average'>[mode_name[BOT_NAV]]</span>"
|
||||
if(BOT_NO_ROUTE)
|
||||
dat += "<span class='bad'>[mode_name[BOT_NO_ROUTE]]</span>"
|
||||
dat += "</div>"
|
||||
|
||||
dat += "<b>Current Load:</b> [load ? load.name : "<i>none</i>"]<BR>"
|
||||
dat += "<b>Destination:</b> [!destination ? "<i>none</i>" : destination]<BR>"
|
||||
dat += "<b>Power level:</b> [cell ? cell.percent() : 0]%"
|
||||
|
||||
if(locked && !ai)
|
||||
dat += " <br /><div class='notice'>Controls are locked</div><A href='byond://?src=\ref[src];op=unlock'>Unlock Controls</A>"
|
||||
else
|
||||
dat += " <br /><div class='notice'>Controls are unlocked</div><A href='byond://?src=\ref[src];op=lock'>Lock Controls</A><BR><BR>"
|
||||
|
||||
dat += "<A href='byond://?src=\ref[src];op=power'>Toggle Power</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=stop'>Stop</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=go'>Proceed</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=home'>Return to Home</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=destination'>Set Destination</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=setid'>Set Bot ID</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=sethome'>Set Home</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=autoret'>Toggle Auto Return Home</A> ([auto_return ? "On":"Off"])<BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=autopick'>Toggle Auto Pickup Crate</A> ([auto_pickup ? "On":"Off"])<BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=report'>Toggle Delivery Reporting</A> ([report_delivery ? "On" : "Off"])<BR>"
|
||||
|
||||
if(load)
|
||||
dat += "<A href='byond://?src=\ref[src];op=unload'>Unload Now</A><BR>"
|
||||
dat += "<div class='notice'>The maintenance hatch is closed.</div>"
|
||||
|
||||
else
|
||||
if(!ai)
|
||||
dat += "<div class='notice'>The maintenance hatch is open.</div><BR>"
|
||||
dat += "<b>Power cell:</b> "
|
||||
if(cell)
|
||||
dat += "<A href='byond://?src=\ref[src];op=cellremove'>Installed</A><BR>"
|
||||
else
|
||||
dat += "<A href='byond://?src=\ref[src];op=cellinsert'>Removed</A><BR>"
|
||||
|
||||
dat += wires()
|
||||
else
|
||||
dat += "<div class='notice'>The bot is in maintenance mode and cannot be controlled.</div><BR>"
|
||||
|
||||
//user << browse("<HEAD><TITLE>M.U.L.E. Mk. III [suffix ? "([suffix])" : ""]</TITLE></HEAD>[dat]", "window=mulebot;size=350x500")
|
||||
//onclose(user, "mulebot")
|
||||
var/datum/browser/popup = new(user, "mulebot", "M.U.L.E. Mk. V [suffix ? "([suffix])" : ""]", 350, 620)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
popup.open()
|
||||
return
|
||||
|
||||
// returns the wire panel text
|
||||
/obj/machinery/bot/mulebot/proc/wires()
|
||||
return wires.GetInteractWindow()
|
||||
|
||||
|
||||
/obj/machinery/bot/mulebot/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
if (usr.stat)
|
||||
return
|
||||
if ((in_range(src, usr) && istype(loc, /turf)) || (istype(usr, /mob/living/silicon)))
|
||||
usr.set_machine(src)
|
||||
|
||||
switch(href_list["op"])
|
||||
if("lock", "unlock")
|
||||
toggle_lock(usr)
|
||||
|
||||
if("power")
|
||||
if (on)
|
||||
turn_off()
|
||||
else if (cell && !open)
|
||||
if (!turn_on())
|
||||
usr << "<span class='danger'>You can't switch on [src].</span>"
|
||||
return
|
||||
else
|
||||
return
|
||||
visible_message("[usr] switches [on ? "on" : "off"] [src].")
|
||||
updateDialog()
|
||||
|
||||
|
||||
if("cellremove")
|
||||
if(open && cell && !usr.get_active_hand())
|
||||
cell.updateicon()
|
||||
usr.put_in_active_hand(cell)
|
||||
cell.add_fingerprint(usr)
|
||||
cell = null
|
||||
|
||||
usr.visible_message("<span class='notice'>[usr] removes the power cell from [src].</span>", "<span class='notice'>You remove the power cell from [src].</span>")
|
||||
updateDialog()
|
||||
|
||||
if("cellinsert")
|
||||
if(open && !cell)
|
||||
var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand()
|
||||
if(istype(C))
|
||||
usr.drop_item()
|
||||
cell = C
|
||||
C.loc = src
|
||||
C.add_fingerprint(usr)
|
||||
|
||||
usr.visible_message("<span class='notice'>[usr] inserts a power cell into [src].</span>", "<span class='notice'>You insert the power cell into [src].</span>")
|
||||
updateDialog()
|
||||
|
||||
|
||||
if("stop")
|
||||
if(mode >= BOT_DELIVER)
|
||||
bot_reset()
|
||||
updateDialog()
|
||||
|
||||
if("go")
|
||||
if(mode == BOT_IDLE)
|
||||
start()
|
||||
updateDialog()
|
||||
|
||||
if("home")
|
||||
if(mode == BOT_IDLE || mode == BOT_DELIVER)
|
||||
start_home()
|
||||
updateDialog()
|
||||
|
||||
if("destination")
|
||||
if(!delivery_beacons.len)
|
||||
post_signal(beacon_freq, "findbeacon", "delivery")
|
||||
refresh=0
|
||||
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)
|
||||
|
||||
|
||||
if("setid")
|
||||
refresh=0
|
||||
var/new_id = sanitize(copytext(input("Enter new bot ID", "Mulebot [suffix ? "([suffix])" : ""]", suffix) as text|null,1,MAX_NAME_LEN))
|
||||
refresh=1
|
||||
if(new_id)
|
||||
suffix = new_id
|
||||
name = "\improper Mulebot ([suffix])"
|
||||
updateDialog()
|
||||
|
||||
if("sethome")
|
||||
refresh=0
|
||||
var/new_home = input("Enter new home tag", "Mulebot [suffix ? "([suffix])" : ""]", home_destination) as text|null
|
||||
refresh=1
|
||||
if(new_home)
|
||||
home_destination = new_home
|
||||
updateDialog()
|
||||
|
||||
if("unload")
|
||||
if(load && mode !=1)
|
||||
if(loc == target)
|
||||
unload(loaddir)
|
||||
else
|
||||
unload(0)
|
||||
|
||||
if("autoret")
|
||||
auto_return = !auto_return
|
||||
|
||||
if("autopick")
|
||||
auto_pickup = !auto_pickup
|
||||
|
||||
if("report")
|
||||
report_delivery = !report_delivery
|
||||
|
||||
if("close")
|
||||
usr.unset_machine()
|
||||
usr << browse(null,"window=mulebot")
|
||||
|
||||
updateDialog()
|
||||
//updateUsrDialog()
|
||||
else
|
||||
usr << browse(null, "window=mulebot")
|
||||
usr.unset_machine()
|
||||
return
|
||||
|
||||
|
||||
|
||||
// returns true if the bot has power
|
||||
/obj/machinery/bot/mulebot/proc/has_power()
|
||||
return !open && cell && cell.charge > 0 && wires.HasPower()
|
||||
|
||||
/obj/machinery/bot/mulebot/proc/toggle_lock(var/mob/user)
|
||||
if(allowed(user))
|
||||
locked = !locked
|
||||
updateDialog()
|
||||
return 1
|
||||
else
|
||||
user << "<span class='danger'>Access denied.</span>"
|
||||
return 0
|
||||
|
||||
// mousedrop a crate to load the bot
|
||||
// can load anything if emagged
|
||||
|
||||
/obj/machinery/bot/mulebot/MouseDrop_T(var/atom/movable/C, mob/user)
|
||||
|
||||
if(user.stat)
|
||||
return
|
||||
|
||||
if (!on || !istype(C)|| C.anchored || get_dist(user, src) > 1 || get_dist(src,C) > 1 )
|
||||
return
|
||||
|
||||
if(load)
|
||||
return
|
||||
|
||||
load(C)
|
||||
|
||||
|
||||
// called to load a crate
|
||||
/obj/machinery/bot/mulebot/proc/load(var/atom/movable/C)
|
||||
if(wires.LoadCheck() && !istype(C,/obj/structure/closet/crate))
|
||||
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.
|
||||
//So this is a simple fix that only allows a selection of item types to be considered. Further narrowing-down is below.
|
||||
if(!istype(C,/obj/item) && !istype(C,/obj/machinery) && !istype(C,/obj/structure) && !ismob(C))
|
||||
return
|
||||
if(!isturf(C.loc)) //To prevent the loading from stuff from someone's inventory, which wouldn't get handled properly.
|
||||
return
|
||||
|
||||
if(get_dist(C, src) > 1 || load || !on)
|
||||
return
|
||||
mode = BOT_LOADING
|
||||
|
||||
// if a create, close before loading
|
||||
var/obj/structure/closet/crate/crate = C
|
||||
if(istype(crate))
|
||||
crate.close()
|
||||
|
||||
C.loc = loc
|
||||
sleep(2)
|
||||
if(C.loc != loc) //To prevent you from going onto more thano ne bot.
|
||||
return
|
||||
C.loc = src
|
||||
load = C
|
||||
|
||||
C.pixel_y += 9
|
||||
if(C.layer < layer)
|
||||
C.layer = layer + 0.1
|
||||
overlays += C
|
||||
|
||||
if(ismob(C))
|
||||
var/mob/M = C
|
||||
if(M.client)
|
||||
M.client.perspective = EYE_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
|
||||
mode = BOT_IDLE
|
||||
send_status()
|
||||
|
||||
// called to unload the bot
|
||||
// argument is optional direction to unload
|
||||
// if zero, unload at bot's location
|
||||
/obj/machinery/bot/mulebot/proc/unload(var/dirn)
|
||||
if(!load)
|
||||
return
|
||||
|
||||
mode = BOT_LOADING
|
||||
overlays.Cut()
|
||||
|
||||
if(ismob(load))
|
||||
var/mob/M = load
|
||||
if(M.client)
|
||||
M.client.perspective = MOB_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
|
||||
|
||||
load.loc = loc
|
||||
load.pixel_y -= 9
|
||||
load.layer = initial(load.layer)
|
||||
if(dirn)
|
||||
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)
|
||||
|
||||
load = null
|
||||
|
||||
// in case non-load items end up in contents, dump every else too
|
||||
// this seems to happen sometimes due to race conditions
|
||||
// with items dropping as mobs are loaded
|
||||
|
||||
for(var/atom/movable/AM in src)
|
||||
if(AM == cell || istype(AM , botcard) || AM == Radio) continue
|
||||
|
||||
AM.loc = loc
|
||||
AM.layer = initial(AM.layer)
|
||||
AM.pixel_y = initial(AM.pixel_y)
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(M.client)
|
||||
M.client.perspective = MOB_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
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/bot_process()
|
||||
if(!has_power())
|
||||
on = 0
|
||||
return
|
||||
if(on)
|
||||
var/speed = (wires.Motor1() ? 1 : 0) + (wires.Motor2() ? 2 : 0)
|
||||
//world << "speed: [speed]"
|
||||
var/num_steps = 0
|
||||
switch(speed)
|
||||
if(0)
|
||||
// do nothing
|
||||
if(1)
|
||||
num_steps = 10
|
||||
if(2)
|
||||
num_steps = 5
|
||||
if(3)
|
||||
num_steps = 3
|
||||
|
||||
if(num_steps)
|
||||
process_bot()
|
||||
num_steps--
|
||||
spawn(0)
|
||||
for(var/i=num_steps,i>0,i--)
|
||||
sleep(2)
|
||||
process_bot()
|
||||
|
||||
if(refresh) updateDialog()
|
||||
|
||||
/obj/machinery/bot/mulebot/proc/process_bot()
|
||||
//if(mode) world << "Mode: [mode]"
|
||||
|
||||
switch(mode)
|
||||
if(BOT_IDLE) // idle
|
||||
icon_state = "mulebot0"
|
||||
return
|
||||
if(BOT_LOADING) // loading/unloading
|
||||
return
|
||||
if(BOT_DELIVER,BOT_GO_HOME,BOT_BLOCKED) // navigating to deliver,home, or blocked
|
||||
|
||||
if(loc == target) // reached target
|
||||
at_target()
|
||||
return
|
||||
|
||||
else if(path.len > 0 && target) // valid path
|
||||
|
||||
var/turf/next = path[1]
|
||||
reached_target = 0
|
||||
if(next == loc)
|
||||
path -= next
|
||||
return
|
||||
|
||||
|
||||
if(istype( next, /turf/simulated))
|
||||
//world << "at ([x],[y]) moving to ([next.x],[next.y])"
|
||||
|
||||
|
||||
if(bloodiness)
|
||||
var/obj/effect/decal/cleanable/blood/tracks/B = new(loc)
|
||||
var/newdir = get_dir(next, loc)
|
||||
if(newdir == dir)
|
||||
B.dir = newdir
|
||||
else
|
||||
newdir = newdir | dir
|
||||
if(newdir == 3)
|
||||
newdir = 1
|
||||
else if(newdir == 12)
|
||||
newdir = 4
|
||||
B.dir = newdir
|
||||
bloodiness--
|
||||
|
||||
|
||||
|
||||
var/moved = step_towards(src, next) // attempt to move
|
||||
if(cell) cell.use(1)
|
||||
if(moved) // successful move
|
||||
//world << "Successful move."
|
||||
blockcount = 0
|
||||
path -= loc
|
||||
|
||||
|
||||
if(mode == BOT_BLOCKED)
|
||||
spawn(1)
|
||||
send_status()
|
||||
|
||||
if(destination == home_destination)
|
||||
mode = BOT_GO_HOME
|
||||
else
|
||||
mode = BOT_DELIVER
|
||||
|
||||
else // failed to move
|
||||
|
||||
//world << "Unable to move."
|
||||
|
||||
|
||||
|
||||
blockcount++
|
||||
mode = BOT_BLOCKED
|
||||
if(blockcount == 3)
|
||||
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
|
||||
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)
|
||||
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
|
||||
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 = BOT_NAV
|
||||
return
|
||||
else
|
||||
//world << "No path."
|
||||
mode = BOT_NAV
|
||||
return
|
||||
|
||||
if(BOT_NAV) // calculate new path
|
||||
//world << "Calc new path."
|
||||
mode = BOT_WAIT_FOR_NAV
|
||||
spawn(0)
|
||||
|
||||
calc_path()
|
||||
|
||||
if(path.len > 0)
|
||||
blockcount = 0
|
||||
mode = BOT_BLOCKED
|
||||
visible_message("[src] makes a delighted ping!", "You hear a ping.")
|
||||
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
|
||||
else
|
||||
visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
|
||||
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
|
||||
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/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/set_destination(var/new_dest)
|
||||
spawn(0)
|
||||
new_destination = new_dest
|
||||
post_signal(beacon_freq, "findbeacon", "delivery")
|
||||
updateDialog()
|
||||
|
||||
// starts bot moving to current destination
|
||||
/obj/machinery/bot/mulebot/proc/start()
|
||||
if(destination == home_destination)
|
||||
mode = BOT_GO_HOME
|
||||
else
|
||||
mode = BOT_DELIVER
|
||||
icon_state = "mulebot[(wires.MobAvoid() != 0)]"
|
||||
|
||||
// starts bot moving to home
|
||||
// sends a beacon query to find
|
||||
/obj/machinery/bot/mulebot/proc/start_home()
|
||||
spawn(0)
|
||||
set_destination(home_destination)
|
||||
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)
|
||||
radio_name = "Supply"
|
||||
Radio.config(list("[radio_name]" = 0))
|
||||
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 << "<span class='notice'>\icon[src] [src] wirelessly plays a chiming sound!</span>"
|
||||
playsound(calling_ai, 'sound/machines/chime.ogg',40, 0)
|
||||
calling_ai = null
|
||||
radio_name = "AI Private"
|
||||
Radio.config(list("[radio_name]" = 0))
|
||||
|
||||
if(load) // if loaded, unload at target
|
||||
speak("Destination <b>[destination]</b> reached. Unloading [load].", radio_name)
|
||||
if(istype(load, /obj/structure/closet/crate))
|
||||
var/obj/structure/closet/crate/C = load
|
||||
C.notifyRecipient(destination)
|
||||
unload(loaddir)
|
||||
else
|
||||
// not loaded
|
||||
if(auto_pickup) // find a crate
|
||||
var/atom/movable/AM
|
||||
if(!wires.LoadCheck()) // if emagged, load first unanchored thing we find
|
||||
for(var/atom/movable/A in get_step(loc, loaddir))
|
||||
if(!A.anchored)
|
||||
AM = A
|
||||
break
|
||||
else // otherwise, look for crates only
|
||||
AM = locate(/obj/structure/closet/crate) in get_step(loc,loaddir)
|
||||
if(AM)
|
||||
load(AM)
|
||||
if(report_delivery)
|
||||
speak("Now loading [load] at <b>[get_area(src)]</b>.", radio_name)
|
||||
// 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 = BOT_BLOCKED
|
||||
else
|
||||
bot_reset() // otherwise go idle
|
||||
|
||||
send_status() // report status to anyone listening
|
||||
|
||||
return
|
||||
|
||||
// called when bot bumps into anything
|
||||
/obj/machinery/bot/mulebot/Bump(var/atom/obs)
|
||||
if(!wires.MobAvoid()) //usually just bumps, but if avoidance disabled knock over mobs
|
||||
var/mob/M = obs
|
||||
if(ismob(M))
|
||||
if(istype(M,/mob/living/silicon/robot))
|
||||
visible_message("<span class='danger'>[src] bumps into [M]!</span>")
|
||||
else
|
||||
visible_message("<span class='danger'>[src] knocks over [M]!</span>")
|
||||
M.stop_pulling()
|
||||
M.Stun(8)
|
||||
M.Weaken(5)
|
||||
..()
|
||||
|
||||
/obj/machinery/bot/mulebot/alter_health()
|
||||
return get_turf(src)
|
||||
|
||||
|
||||
// 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)
|
||||
visible_message("\red [src] drives over [H]!")
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
|
||||
var/damage = rand(5,15)
|
||||
H.apply_damage(2*damage, BRUTE, "head")
|
||||
H.apply_damage(2*damage, BRUTE, "chest")
|
||||
H.apply_damage(0.5*damage, BRUTE, "l_leg")
|
||||
H.apply_damage(0.5*damage, BRUTE, "r_leg")
|
||||
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)
|
||||
B.blood_DNA = list()
|
||||
B.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type
|
||||
|
||||
bloodiness += 4
|
||||
currentBloodColor="#A10808" // For if species get different blood colors.
|
||||
|
||||
// player on mulebot attempted to move
|
||||
/obj/machinery/bot/mulebot/relaymove(var/mob/user)
|
||||
if(user.stat)
|
||||
return
|
||||
if(load == user)
|
||||
unload(0)
|
||||
return
|
||||
|
||||
// receive a radio signal
|
||||
// used for control and beacon reception
|
||||
|
||||
/obj/machinery/bot/mulebot/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" && wires.RemoteRX())
|
||||
send_status()
|
||||
|
||||
|
||||
recv = signal.data["command [suffix]"]
|
||||
if(wires.RemoteRX())
|
||||
// process control input
|
||||
switch(recv)
|
||||
if("stop")
|
||||
bot_reset()
|
||||
return
|
||||
|
||||
if("go")
|
||||
start()
|
||||
return
|
||||
|
||||
if("target")
|
||||
set_destination(signal.data["destination"] )
|
||||
return
|
||||
|
||||
if("unload")
|
||||
if(loc == target)
|
||||
unload(loaddir)
|
||||
else
|
||||
unload(0)
|
||||
return
|
||||
|
||||
if("home")
|
||||
start_home()
|
||||
return
|
||||
|
||||
if("bot_status")
|
||||
send_status()
|
||||
return
|
||||
|
||||
if("autoret")
|
||||
auto_return = text2num(signal.data["value"])
|
||||
return
|
||||
|
||||
if("autopick")
|
||||
auto_pickup = text2num(signal.data["value"])
|
||||
return
|
||||
|
||||
// receive response from beacon
|
||||
recv = signal.data["beacon"]
|
||||
|
||||
if(wires.BeaconRX())
|
||||
if((recv == new_destination) && (destination != new_destination)) // if the recvd beacon location matches the set destination
|
||||
// the we will navigate there
|
||||
destination = new_destination
|
||||
target = signal.source.loc
|
||||
var/direction = signal.data["dir"] // this will be the load/unload dir
|
||||
if(direction)
|
||||
loaddir = text2num(direction)
|
||||
else
|
||||
loaddir = 0
|
||||
icon_state = "mulebot[(wires.MobAvoid() != null)]"
|
||||
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 multiple data key/values
|
||||
/obj/machinery/bot/mulebot/post_signal_multiple(var/freq, var/list/keyval)
|
||||
|
||||
if(freq == beacon_freq && !(wires.BeaconRX()))
|
||||
return
|
||||
if(freq == control_freq && !(wires.RemoteTX()))
|
||||
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"] == 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/send_status()
|
||||
var/list/kv = list(
|
||||
"type" = MULE_BOT,
|
||||
"name" = suffix,
|
||||
"loca" = get_area(src),
|
||||
"mode" = mode,
|
||||
"powr" = (cell ? cell.percent() : 0),
|
||||
"dest" = destination,
|
||||
"home" = home_destination,
|
||||
"load" = load,
|
||||
"retn" = auto_return,
|
||||
"pick" = auto_pickup,
|
||||
)
|
||||
post_signal_multiple(control_freq, kv)
|
||||
|
||||
/obj/machinery/bot/mulebot/emp_act(severity)
|
||||
if (cell)
|
||||
cell.emp_act(severity)
|
||||
if(load)
|
||||
load.emp_act(severity)
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/bot/mulebot/explode()
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
new /obj/item/stack/rods(Tsec)
|
||||
new /obj/item/stack/rods(Tsec)
|
||||
new /obj/item/stack/cable_coil/cut(Tsec)
|
||||
if (cell)
|
||||
cell.loc = Tsec
|
||||
cell.update_icon()
|
||||
cell = null
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(loc)
|
||||
unload(0)
|
||||
qdel(src)
|
||||
@@ -1,502 +0,0 @@
|
||||
/obj/machinery/bot/secbot
|
||||
name = "\improper Securitron"
|
||||
desc = "A little security robot. He looks less than thrilled."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "secbot0"
|
||||
light_color = LIGHT_COLOR_PURE_RED
|
||||
layer = 5.0
|
||||
density = 0
|
||||
anchored = 0
|
||||
health = 25
|
||||
maxhealth = 25
|
||||
fire_dam_coeff = 0.7
|
||||
brute_dam_coeff = 0.5
|
||||
// weight = 1.0E7
|
||||
req_access = list(access_security)
|
||||
var/mob/living/carbon/target
|
||||
var/oldtarget_name
|
||||
var/threatlevel = 0
|
||||
var/target_lastloc //Loc of target when arrested.
|
||||
var/last_found //There's a delay
|
||||
// var/emagged = 0 //Emagged Secbots view everyone as a criminal
|
||||
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 = 1 //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/harmbaton = 0
|
||||
var/base_icon = "secbot"
|
||||
radio_name = "Security"
|
||||
bot_type = SEC_BOT
|
||||
bot_type_name = "Secbot"
|
||||
bot_filter = RADIO_SECBOT
|
||||
|
||||
/obj/machinery/bot/secbot/beepsky
|
||||
name = "Officer Beepsky"
|
||||
desc = "It's Officer Beepsky! Powered by a potato and a shot of whiskey."
|
||||
idcheck = 0
|
||||
weaponscheck = 1
|
||||
auto_patrol = 1
|
||||
|
||||
/obj/machinery/bot/secbot/pingsky
|
||||
name = "Officer Pingsky"
|
||||
desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment."
|
||||
radio_name = "AI Private"
|
||||
|
||||
/obj/machinery/bot/secbot/ofitser
|
||||
name = "Prison Ofitser"
|
||||
desc = "It's Prison Ofitser! Powered by the tears and sweat of prisoners."
|
||||
idcheck = 0
|
||||
weaponscheck = 1
|
||||
auto_patrol = 1
|
||||
|
||||
/obj/machinery/bot/secbot/buzzsky
|
||||
name = "Officer Buzzsky"
|
||||
desc = "It's Officer Buzzsky! Rusted and falling apart, he seems less than thrilled with the crew for leaving him in his current state."
|
||||
base_icon = "rustbot"
|
||||
icon_state = "rustbot0"
|
||||
declare_arrests = 0
|
||||
arrest_type = 1
|
||||
harmbaton = 1
|
||||
emagged = 2
|
||||
|
||||
/obj/item/weapon/secbot_assembly
|
||||
name = "incomplete securitron assembly"
|
||||
desc = "Some sort of bizarre assembly made from a proximity sensor, helmet, and signaler."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "helmet_signaler"
|
||||
item_state = "helmet"
|
||||
var/build_step = 0
|
||||
var/created_name = "Securitron" //To preserve the name if it's a unique securitron I guess
|
||||
|
||||
|
||||
|
||||
/obj/machinery/bot/secbot/New()
|
||||
..()
|
||||
icon_state = "[base_icon][on]"
|
||||
spawn(3)
|
||||
|
||||
var/datum/job/officer/J = new/datum/job/officer
|
||||
botcard.access = J.get_access()
|
||||
prev_access = botcard.access
|
||||
add_to_beacons(bot_filter)
|
||||
|
||||
|
||||
/obj/machinery/bot/secbot/turn_on()
|
||||
..()
|
||||
icon_state = "[base_icon][on]"
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/bot/secbot/turn_off()
|
||||
..()
|
||||
icon_state = "[base_icon][on]"
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/bot/secbot/bot_reset()
|
||||
..()
|
||||
target = null
|
||||
oldtarget_name = null
|
||||
anchored = 0
|
||||
walk_to(src,0)
|
||||
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)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
usr.set_machine(src)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/bot/secbot/interact(mob/user as mob)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += text({"
|
||||
<TT><B>Securitron v1.6 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
|
||||
"<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>" )
|
||||
|
||||
if(!locked || issilicon(user))
|
||||
dat += text({"<BR>
|
||||
Arrest Unidentifiable Persons: []<BR>
|
||||
Arrest for Unauthorized Weapons: []<BR>
|
||||
Arrest for Warrant: []<BR>
|
||||
Operating Mode: []<BR>
|
||||
Report Arrests[]<BR>
|
||||
Auto Patrol: []"},
|
||||
|
||||
"<A href='?src=\ref[src];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
|
||||
"<A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
|
||||
|
||||
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)
|
||||
|
||||
..()
|
||||
|
||||
switch(href_list["operation"])
|
||||
if("idcheck")
|
||||
idcheck = !idcheck
|
||||
updateUsrDialog()
|
||||
if("weaponscheck")
|
||||
weaponscheck = !weaponscheck
|
||||
updateUsrDialog()
|
||||
if("ignorerec")
|
||||
check_records = !check_records
|
||||
updateUsrDialog()
|
||||
if("switchmode")
|
||||
arrest_type = !arrest_type
|
||||
updateUsrDialog()
|
||||
if("declarearrests")
|
||||
declare_arrests = !declare_arrests
|
||||
updateUsrDialog()
|
||||
|
||||
|
||||
/obj/machinery/bot/secbot/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
|
||||
if(allowed(user) && !open && !emagged)
|
||||
locked = !locked
|
||||
user << "Controls are now [locked ? "locked." : "unlocked."]"
|
||||
updateUsrDialog()
|
||||
else
|
||||
if(emagged)
|
||||
user << "<span class='warning'>ERROR</span>"
|
||||
if(open)
|
||||
user << "<span class='danger'>Please close the access panel before locking it.</span>"
|
||||
else
|
||||
user << "<span class='danger'> Access denied.</span>"
|
||||
else
|
||||
..()
|
||||
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != I_HARM) // Any intent but harm will heal, so we shouldn't get angry.
|
||||
return
|
||||
if(!istype(W, /obj/item/weapon/screwdriver) && (W.force) && (!target)) // 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)
|
||||
target = user
|
||||
mode = BOT_HUNT
|
||||
|
||||
/obj/machinery/bot/secbot/Emag(mob/user as mob)
|
||||
..()
|
||||
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
user << "<span class='danger'> You short out [src]'s target assessment circuits.</span>"
|
||||
oldtarget_name = user.name
|
||||
visible_message("<span class='danger'>[src] buzzes oddly!</span>")
|
||||
declare_arrests = 0
|
||||
icon_state = "[base_icon][on]"
|
||||
|
||||
/obj/machinery/bot/secbot/bot_process()
|
||||
if (!..())
|
||||
return
|
||||
|
||||
switch(mode)
|
||||
|
||||
if(BOT_IDLE) // idle
|
||||
flashing_lights() //make sure they disengage properly
|
||||
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 = BOT_START_PATROL // switch to patrol mode
|
||||
|
||||
if(BOT_HUNT) // hunting for perp
|
||||
flashing_lights()
|
||||
// if can't reach perp for long enough, go idle
|
||||
if(frustration >= 8)
|
||||
walk_to(src,0)
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(target) // make sure target exists
|
||||
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
|
||||
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
|
||||
if(harmbaton)
|
||||
playsound(loc, 'sound/weapons/genhit1.ogg', 50, 1, -1)
|
||||
icon_state = "[base_icon]-c"
|
||||
spawn(2)
|
||||
icon_state = "[base_icon][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
|
||||
if(harmbaton) // Bots with harmbaton enabled become shitcurity. - Dave
|
||||
M.apply_damage(10)
|
||||
M.Stun(5)
|
||||
M.Weaken(5)
|
||||
else
|
||||
M.Weaken(5)
|
||||
M.stuttering = 5
|
||||
M.Stun(5)
|
||||
|
||||
if(declare_arrests)
|
||||
var/area/location = get_area(src)
|
||||
speak("[arrest_type ? "Detaining" : "Arresting"] level [threatlevel] scumbag <b>[target]</b> in [location].", radio_name)
|
||||
target.visible_message("<span class='danger'>[target] has been [harmbaton ? "beaten" : "stunned"] by [src]!</span>",\
|
||||
"<span class='userdanger'>[target] has been [harmbaton ? "beaten" : "stunned"] by [src]!</span>")
|
||||
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = 1
|
||||
target_lastloc = M.loc
|
||||
return
|
||||
|
||||
else // not next to perp
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
walk_to(src, target,1,4)
|
||||
if((get_dist(src, target)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
frustration = 0
|
||||
else
|
||||
back_to_idle()
|
||||
|
||||
if(BOT_PREP_ARREST) // preparing to arrest target
|
||||
flashing_lights() //make sure they disengage properly
|
||||
// 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( !Adjacent(target) || !isturf(target.loc) || target.weakened < 2 )
|
||||
back_to_hunt()
|
||||
return
|
||||
|
||||
if(iscarbon(target) && target.canBeHandcuffed())
|
||||
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("<span class='danger'>[src] is trying to put zipties on [target]!</span>",\
|
||||
"<span class='userdanger'>[src] is trying to put zipties on [target]!</span>")
|
||||
spawn(30)
|
||||
if( !Adjacent(target) || !isturf(target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
|
||||
return
|
||||
if(!target.handcuffed)
|
||||
target.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(target)
|
||||
target.update_inv_handcuffed(1) //update the handcuffs overlay
|
||||
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()
|
||||
return
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(BOT_ARREST)
|
||||
if (!target)
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
return
|
||||
|
||||
if(target.handcuffed) //no target or target cuffed? back to idle.
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
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()
|
||||
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/bot/secbot/proc/back_to_idle()
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
spawn(0)
|
||||
bot_process() //ensure bot quickly responds
|
||||
|
||||
/obj/machinery/bot/secbot/proc/back_to_hunt()
|
||||
anchored = 0
|
||||
frustration = 0
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
bot_process() //ensure bot quickly responds
|
||||
// look for a criminal in view of the bot
|
||||
|
||||
/obj/machinery/bot/secbot/proc/look_for_perp()
|
||||
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 == oldtarget_name) && (world.time < last_found + 100))
|
||||
continue
|
||||
|
||||
threatlevel = C.assess_threat(src)
|
||||
|
||||
if(!threatlevel)
|
||||
continue
|
||||
|
||||
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("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
bot_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(slot_item && slot_item.needs_permit)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/bot/secbot/explode()
|
||||
|
||||
walk_to(src,0)
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
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 = name
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
new /obj/item/weapon/melee/baton(Tsec)
|
||||
|
||||
if(prob(50))
|
||||
new /obj/item/robot_parts/l_arm(Tsec)
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/bot/secbot/attack_alien(var/mob/living/carbon/alien/user as mob)
|
||||
..()
|
||||
if(!isalien(target))
|
||||
target = user
|
||||
mode = BOT_HUNT
|
||||
|
||||
/obj/machinery/bot/secbot/proc/flashing_lights()
|
||||
if(mode == BOT_HUNT)
|
||||
switch(light_color)
|
||||
if(LIGHT_COLOR_PURE_RED)
|
||||
light_color = LIGHT_COLOR_PURE_BLUE
|
||||
if(LIGHT_COLOR_PURE_BLUE)
|
||||
light_color = LIGHT_COLOR_PURE_RED
|
||||
else
|
||||
light_color = LIGHT_COLOR_PURE_RED
|
||||
|
||||
//Secbot Construction
|
||||
|
||||
/obj/item/clothing/head/helmet/attackby(var/obj/item/device/assembly/signaler/S, mob/user as mob, params)
|
||||
..()
|
||||
if(!issignaler(S))
|
||||
..()
|
||||
return
|
||||
|
||||
if(type != /obj/item/clothing/head/helmet) //Eh, but we don't want people making secbots out of space helmets.
|
||||
return
|
||||
|
||||
if(S.secured)
|
||||
qdel(S)
|
||||
var/obj/item/weapon/secbot_assembly/A = new /obj/item/weapon/secbot_assembly
|
||||
user.put_in_hands(A)
|
||||
user << "<span class='notice'>You add the signaler to the helmet.</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
else
|
||||
return
|
||||
|
||||
/obj/item/weapon/secbot_assembly/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/weapon/weldingtool))
|
||||
if(!build_step)
|
||||
var/obj/item/weapon/weldingtool/WT = I
|
||||
if(WT.remove_fuel(0, user))
|
||||
build_step++
|
||||
overlays += "hs_hole"
|
||||
user << "<span class='notice'>You weld a hole in [src]!</span>"
|
||||
else if(build_step == 1)
|
||||
var/obj/item/weapon/weldingtool/WT = I
|
||||
if(WT.remove_fuel(0, user))
|
||||
build_step--
|
||||
overlays -= "hs_hole"
|
||||
user << "<span class='notice'>You weld the hole in [src] shut!</span>"
|
||||
|
||||
else if(isprox(I) && (build_step == 1))
|
||||
user.drop_item()
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the prox sensor to [src]!</span>"
|
||||
overlays += "hs_eye"
|
||||
name = "helmet/signaler/prox sensor assembly"
|
||||
qdel(I)
|
||||
|
||||
else if(((istype(I, /obj/item/robot_parts/l_arm)) || (istype(I, /obj/item/robot_parts/r_arm))) && (build_step == 2))
|
||||
user.drop_item()
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the robot arm to [src]!</span>"
|
||||
name = "helmet/signaler/prox sensor/robot arm assembly"
|
||||
overlays += "hs_arm"
|
||||
qdel(I)
|
||||
|
||||
else if((istype(I, /obj/item/weapon/melee/baton)) && (build_step >= 3))
|
||||
user.drop_item()
|
||||
build_step++
|
||||
user << "<span class='notice'>You complete the Securitron! Beep boop.</span>"
|
||||
var/obj/machinery/bot/secbot/S = new /obj/machinery/bot/secbot
|
||||
S.loc = get_turf(src)
|
||||
S.name = created_name
|
||||
qdel(I)
|
||||
qdel(src)
|
||||
|
||||
else if(istype(I, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
created_name = t
|
||||
|
||||
else if(istype(I, /obj/item/weapon/screwdriver))
|
||||
if(!build_step)
|
||||
new /obj/item/device/assembly/signaler(get_turf(src))
|
||||
new /obj/item/clothing/head/helmet(get_turf(src))
|
||||
user << "<span class='notice'>You disconnect the signaler from the helmet.</span>"
|
||||
qdel(src)
|
||||
|
||||
else if(build_step == 2)
|
||||
overlays -= "hs_eye"
|
||||
new /obj/item/device/assembly/prox_sensor(get_turf(src))
|
||||
user << "<span class='notice'>You detach the proximity sensor from [src].</span>"
|
||||
build_step--
|
||||
|
||||
else if(build_step == 3)
|
||||
overlays -= "hs_arm"
|
||||
new /obj/item/robot_parts/l_arm(get_turf(src))
|
||||
user << "<span class='notice'>You remove the robot arm from [src].</span>"
|
||||
build_step--
|
||||
@@ -103,7 +103,7 @@
|
||||
dat += "<a href='?src=\ref[src];screen=1'>Back</a>"
|
||||
dat += "<br><b>Medical Robots:</b>"
|
||||
var/bdat = null
|
||||
for(var/obj/machinery/bot/medbot/M in world)
|
||||
for(var/mob/living/simple_animal/bot/medbot/M in world)
|
||||
|
||||
if(M.z != src.z) continue //only find medibots on the same z-level as the computer
|
||||
var/turf/bl = get_turf(M)
|
||||
|
||||
@@ -1046,7 +1046,7 @@ About the new airlock wires panel:
|
||||
|
||||
/obj/machinery/door/airlock/CanAStarPass(var/obj/item/weapon/card/id/ID)
|
||||
//Airlock is passable if it is open (!density), bot has access, and is not bolted shut)
|
||||
return !density || (check_access(ID) && !locked)
|
||||
return !density || (check_access(ID) && !locked && arePowerSystemsOn())
|
||||
|
||||
/obj/machinery/door/airlock/emp_act(var/severity)
|
||||
if(prob(40/severity))
|
||||
|
||||
@@ -68,13 +68,6 @@
|
||||
bumpopen(M)
|
||||
return
|
||||
|
||||
if(istype(AM, /obj/machinery/bot))
|
||||
var/obj/machinery/bot/bot = AM
|
||||
if(src.check_access(bot.botcard) || emergency == 1)
|
||||
if(density)
|
||||
open()
|
||||
return
|
||||
|
||||
if(istype(AM, /obj/mecha))
|
||||
var/obj/mecha/mecha = AM
|
||||
if(density)
|
||||
@@ -95,20 +88,19 @@
|
||||
/obj/machinery/door/CanAtmosPass()
|
||||
return !density
|
||||
|
||||
//used in the AStar algorithm to determinate if the turf the door is on is passable
|
||||
/obj/machinery/door/proc/CanAStarPass(var/obj/item/weapon/card/id/ID)
|
||||
return !density
|
||||
|
||||
/obj/machinery/door/proc/bumpopen(mob/user as mob)
|
||||
if(operating)
|
||||
return
|
||||
src.add_fingerprint(user)
|
||||
if(!src.requiresID())
|
||||
add_fingerprint(user)
|
||||
if(!requiresID())
|
||||
user = null
|
||||
|
||||
if(density)
|
||||
if(allowed(user) || src.emergency == 1)
|
||||
if(allowed(user) || emergency == 1)
|
||||
open()
|
||||
if(istype(user, /mob/living/simple_animal/bot))
|
||||
var/mob/living/simple_animal/bot/B = user
|
||||
B.door_opened(src)
|
||||
else
|
||||
flick("door_deny", src)
|
||||
return
|
||||
|
||||
@@ -40,23 +40,17 @@
|
||||
close()
|
||||
|
||||
/obj/machinery/door/window/Bumped(atom/movable/AM as mob|obj)
|
||||
if( operating || !src.density )
|
||||
if(operating || !density)
|
||||
return
|
||||
if (!( ismob(AM) ))
|
||||
var/obj/machinery/bot/bot = AM
|
||||
if(istype(bot))
|
||||
if(src.check_access(bot.botcard))
|
||||
open_and_close()
|
||||
else
|
||||
flick(text("[]deny", src.base_state), src)
|
||||
else if(istype(AM, /obj/mecha))
|
||||
if (!ismob(AM))
|
||||
if(istype(AM, /obj/mecha))
|
||||
var/obj/mecha/mecha = AM
|
||||
if(mecha.occupant && src.allowed(mecha.occupant))
|
||||
open_and_close()
|
||||
else
|
||||
flick(text("[]deny", src.base_state), src)
|
||||
return
|
||||
if (!( ticker ))
|
||||
if (!ticker)
|
||||
return
|
||||
var/mob/M = AM
|
||||
if(!M.restrained() && !M.small)
|
||||
@@ -92,7 +86,7 @@
|
||||
|
||||
//used in the AStar algorithm to determinate if the turf the door is on is passable
|
||||
/obj/machinery/door/window/CanAStarPass(var/obj/item/weapon/card/id/ID, var/to_dir)
|
||||
return !density || (dir != to_dir) || check_access(ID)
|
||||
return !density || (dir != to_dir) || (check_access(ID) && !(stat & NOPOWER))
|
||||
|
||||
/obj/machinery/door/window/CheckExit(atom/movable/mover as mob|obj, turf/target as turf)
|
||||
if(istype(mover) && mover.checkpass(PASSGLASS))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Navigation beacon for AI robots
|
||||
// Functions as a transponder: looks for incoming signal matching
|
||||
// No longer exists on the radio controller, it is managed by a global list.
|
||||
|
||||
/obj/machinery/navbeacon
|
||||
|
||||
@@ -13,12 +13,11 @@
|
||||
|
||||
var/open = 0 // true if cover is open
|
||||
var/locked = 1 // true if controls are locked
|
||||
var/freq = 1445 // radio frequency
|
||||
var/location = "" // location response text
|
||||
var/list/codes // assoc. list of transponder codes
|
||||
var/codes_txt = "" // codes as set on map: "tag1;tag2" or "tag1=value;tag2=value"
|
||||
|
||||
req_access = list(access_engine)
|
||||
req_access = list(access_engine, access_robotics)
|
||||
|
||||
/obj/machinery/navbeacon/New()
|
||||
..()
|
||||
@@ -27,14 +26,17 @@
|
||||
|
||||
var/turf/T = loc
|
||||
hide(T.intact)
|
||||
|
||||
spawn(50) // must wait for map loading to finish
|
||||
if(radio_controller)
|
||||
radio_controller.add_object(src, freq, RADIO_NAVBEACONS)
|
||||
if(codes["patrol"])
|
||||
if(!navbeacons["[z]"])
|
||||
navbeacons["[z]"] = list()
|
||||
navbeacons["[z]"] += src //Register with the patrol list!
|
||||
if(codes["delivery"])
|
||||
deliverybeacons += src
|
||||
deliverybeacontags += location
|
||||
|
||||
/obj/machinery/navbeacon/Destroy()
|
||||
if(radio_controller)
|
||||
radio_controller.remove_object(src, freq)
|
||||
navbeacons["[z]"] -= src //Remove from beacon list, if in one.
|
||||
deliverybeacons -= src
|
||||
return ..()
|
||||
|
||||
// set the transponder codes assoc list from codes_txt
|
||||
@@ -58,7 +60,7 @@
|
||||
|
||||
// called when turf state changes
|
||||
// hide the object if turf is intact
|
||||
/obj/machinery/navbeacon/hide(var/intact)
|
||||
/obj/machinery/navbeacon/hide(intact)
|
||||
invisibility = intact ? 101 : 0
|
||||
updateicon()
|
||||
|
||||
@@ -72,36 +74,7 @@
|
||||
else
|
||||
icon_state = "[state]"
|
||||
|
||||
|
||||
// look for a signal of the form "findbeacon=X"
|
||||
// where X is any
|
||||
// or the location
|
||||
// or one of the set transponder keys
|
||||
// if found, return a signal
|
||||
/obj/machinery/navbeacon/receive_signal(datum/signal/signal)
|
||||
var/request = signal.data["findbeacon"]
|
||||
if(request && ((request in codes) || request == "any" || request == location))
|
||||
spawn(1)
|
||||
post_signal()
|
||||
|
||||
// return a signal giving location and transponder codes
|
||||
|
||||
/obj/machinery/navbeacon/proc/post_signal()
|
||||
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
|
||||
signal.data["beacon"] = location
|
||||
|
||||
for(var/key in codes)
|
||||
signal.data[key] = codes[key]
|
||||
frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS)
|
||||
|
||||
|
||||
/obj/machinery/navbeacon/attackby(var/obj/item/I, var/mob/user, params)
|
||||
/obj/machinery/navbeacon/attackby(obj/item/I, mob/user, params)
|
||||
var/turf/T = loc
|
||||
if(T.intact)
|
||||
return // prevent intraction when T-scanner revealed
|
||||
@@ -109,7 +82,7 @@
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
open = !open
|
||||
|
||||
user.visible_message("[user] [open ? "opens" : "closes"] the beacon's cover.", "You [open ? "open" : "close"] the beacon's cover.")
|
||||
user.visible_message("[user] [open ? "opens" : "closes"] the beacon's cover.", "<span class='notice'>You [open ? "open" : "close"] the beacon's cover.</span>")
|
||||
|
||||
updateicon()
|
||||
|
||||
@@ -117,30 +90,30 @@
|
||||
if(open)
|
||||
if (src.allowed(user))
|
||||
src.locked = !src.locked
|
||||
user << "Controls are now [src.locked ? "locked." : "unlocked."]"
|
||||
user << "<span class='notice'>Controls are now [src.locked ? "locked" : "unlocked"].</span>"
|
||||
else
|
||||
user << "<span class='danger'>Access denied.</span>"
|
||||
updateDialog()
|
||||
else
|
||||
user << "You must open the cover first!"
|
||||
user << "<span class='warning'>You must open the cover first!</span>"
|
||||
return
|
||||
|
||||
/obj/machinery/navbeacon/attack_ai(var/mob/user)
|
||||
/obj/machinery/navbeacon/attack_ai(mob/user)
|
||||
interact(user, 1)
|
||||
|
||||
/obj/machinery/navbeacon/attack_animal()
|
||||
return
|
||||
|
||||
/obj/machinery/navbeacon/attack_hand(var/mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
return 0
|
||||
/obj/machinery/navbeacon/attack_hand(mob/user)
|
||||
interact(user, 0)
|
||||
|
||||
/obj/machinery/navbeacon/interact(var/mob/user, var/ai = 0)
|
||||
/obj/machinery/navbeacon/interact(mob/user, ai = 0)
|
||||
var/turf/T = loc
|
||||
if(T.intact)
|
||||
return // prevent intraction when T-scanner revealed
|
||||
|
||||
if(!open && !ai) // can't alter controls if not open, unless you're an AI
|
||||
user << "The beacon's control cover is closed."
|
||||
user << "<span class='warning'>The beacon's control cover is closed!</span>"
|
||||
return
|
||||
|
||||
|
||||
@@ -149,7 +122,6 @@
|
||||
if(locked && !ai)
|
||||
t = {"<TT><B>Navigation Beacon</B><HR><BR>
|
||||
<i>(swipe card to unlock controls)</i><BR>
|
||||
Frequency: [format_frequency(freq)]<BR><HR>
|
||||
Location: [location ? location : "(none)"]</A><BR>
|
||||
Transponder Codes:<UL>"}
|
||||
|
||||
@@ -161,25 +133,21 @@ Transponder Codes:<UL>"}
|
||||
|
||||
t = {"<TT><B>Navigation Beacon</B><HR><BR>
|
||||
<i>(swipe card to lock controls)</i><BR>
|
||||
Frequency:
|
||||
<A href='byond://?src=\ref[src];freq=-10'>-</A>
|
||||
<A href='byond://?src=\ref[src];freq=-2'>-</A>
|
||||
[format_frequency(freq)]
|
||||
<A href='byond://?src=\ref[src];freq=2'>+</A>
|
||||
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
|
||||
|
||||
<HR>
|
||||
Location: <A href='byond://?src=\ref[src];locedit=1'>[location ? location : "(none)"]</A><BR>
|
||||
Location: <A href='byond://?src=\ref[src];locedit=1'>[location ? location : "None"]</A><BR>
|
||||
Transponder Codes:<UL>"}
|
||||
|
||||
for(var/key in codes)
|
||||
t += "<LI>[key] ... [codes[key]]"
|
||||
t += " <small><A href='byond://?src=\ref[src];edit=1;code=[key]'>(edit)</A>"
|
||||
t += " <A href='byond://?src=\ref[src];delete=1;code=[key]'>(delete)</A></small><BR>"
|
||||
t += "<small><A href='byond://?src=\ref[src];add=1;'>(add new)</A></small><BR>"
|
||||
t += " <A href='byond://?src=\ref[src];edit=1;code=[key]'>Edit</A>"
|
||||
t += " <A href='byond://?src=\ref[src];delete=1;code=[key]'>Delete</A><BR>"
|
||||
t += " <A href='byond://?src=\ref[src];add=1;'>Add New</A><BR>"
|
||||
t+= "<UL></TT>"
|
||||
|
||||
user << browse(t, "window=navbeacon")
|
||||
onclose(user, "navbeacon")
|
||||
var/datum/browser/popup = new(user, "navbeacon", "Navigation Beacon", 300, 400)
|
||||
popup.set_content(t)
|
||||
popup.open()
|
||||
return
|
||||
|
||||
/obj/machinery/navbeacon/Topic(href, href_list)
|
||||
@@ -188,12 +156,8 @@ Transponder Codes:<UL>"}
|
||||
if(open && !locked)
|
||||
usr.set_machine(src)
|
||||
|
||||
if (href_list["freq"])
|
||||
freq = sanitize_frequency(freq + text2num(href_list["freq"]))
|
||||
updateDialog()
|
||||
|
||||
else if(href_list["locedit"])
|
||||
var/newloc = sanitize(copytext(input("Enter New Location", "Navigation Beacon", location) as text|null,1,MAX_MESSAGE_LEN))
|
||||
if(href_list["locedit"])
|
||||
var/newloc = copytext(sanitize(input("Enter New Location", "Navigation Beacon", location) as text|null),1,MAX_MESSAGE_LEN)
|
||||
if(newloc)
|
||||
location = newloc
|
||||
updateDialog()
|
||||
@@ -201,12 +165,12 @@ Transponder Codes:<UL>"}
|
||||
else if(href_list["edit"])
|
||||
var/codekey = href_list["code"]
|
||||
|
||||
var/newkey = input("Enter Transponder Code Key", "Navigation Beacon", codekey) as text|null
|
||||
var/newkey = stripped_input(usr, "Enter Transponder Code Key", "Navigation Beacon", codekey)
|
||||
if(!newkey)
|
||||
return
|
||||
|
||||
var/codeval = codes[codekey]
|
||||
var/newval = input("Enter Transponder Code Value", "Navigation Beacon", codeval) as text|null
|
||||
var/newval = stripped_input(usr, "Enter Transponder Code Value", "Navigation Beacon", codeval)
|
||||
if(!newval)
|
||||
newval = codekey
|
||||
return
|
||||
@@ -223,11 +187,11 @@ Transponder Codes:<UL>"}
|
||||
|
||||
else if(href_list["add"])
|
||||
|
||||
var/newkey = input("Enter New Transponder Code Key", "Navigation Beacon") as text|null
|
||||
var/newkey = stripped_input(usr, "Enter New Transponder Code Key", "Navigation Beacon")
|
||||
if(!newkey)
|
||||
return
|
||||
|
||||
var/newval = input("Enter New Transponder Code Value", "Navigation Beacon") as text|null
|
||||
var/newval = stripped_input(usr, "Enter New Transponder Code Value", "Navigation Beacon")
|
||||
if(!newval)
|
||||
newval = "1"
|
||||
return
|
||||
|
||||
@@ -157,8 +157,8 @@ var/global/list/image/fluidtrack_cache=list()
|
||||
dryname = "dried tracks"
|
||||
desc = "Whoops..."
|
||||
drydesc = "Whoops..."
|
||||
coming_state = "wheels"
|
||||
going_state = ""
|
||||
coming_state = "wheels1"
|
||||
going_state = "wheels2"
|
||||
desc = "They look like tracks left by wheels."
|
||||
gender = PLURAL
|
||||
random_icon_states = null
|
||||
|
||||
@@ -268,3 +268,6 @@ a {
|
||||
tesla_zap(src, 3, power_bounced)
|
||||
spawn(10)
|
||||
being_shocked = 0
|
||||
|
||||
/obj/proc/CanAStarPass()
|
||||
. = !density
|
||||
@@ -122,6 +122,12 @@
|
||||
else
|
||||
return !density
|
||||
|
||||
/obj/structure/grille/CanAStarPass(ID, dir, caller)
|
||||
. = !density
|
||||
if(ismovableatom(caller))
|
||||
var/atom/movable/mover = caller
|
||||
. = . || mover.checkpass(PASSGRILLE)
|
||||
|
||||
/obj/structure/grille/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(!Proj)
|
||||
return
|
||||
|
||||
@@ -201,6 +201,22 @@
|
||||
connected = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/tray/m_tray/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
if(height == 0)
|
||||
return 1
|
||||
|
||||
if(istype(mover) && mover.checkpass(PASSTABLE))
|
||||
return 1
|
||||
if(locate(/obj/structure/table) in get_turf(mover))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/structure/tray/m_tray/CanAStarPass(ID, dir, caller)
|
||||
. = !density
|
||||
if(ismovableatom(caller))
|
||||
var/atom/movable/mover = caller
|
||||
. = . || mover.checkpass(PASSTABLE)
|
||||
|
||||
/*
|
||||
* Crematorium
|
||||
@@ -479,5 +495,4 @@
|
||||
if (istype(B.loc,/obj/structure/morgue))
|
||||
Morgue = B.loc
|
||||
if (Morgue)
|
||||
Morgue.update()
|
||||
|
||||
Morgue.update()
|
||||
@@ -140,6 +140,12 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/structure/table/CanAStarPass(ID, dir, caller)
|
||||
. = !density
|
||||
if(ismovableatom(caller))
|
||||
var/atom/movable/mover = caller
|
||||
. = . || mover.checkpass(PASSTABLE)
|
||||
|
||||
//checks if projectile 'P' from turf 'from' can hit whatever is behind the table. Returns 1 if it can, 0 if bullet stops.
|
||||
/obj/structure/table/proc/check_cover(obj/item/projectile/P, turf/from)
|
||||
var/turf/cover = flipped ? get_turf(src) : get_step(loc, get_dir(from, loc))
|
||||
@@ -661,6 +667,12 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/structure/rack/CanAStarPass(ID, dir, caller)
|
||||
. = !density
|
||||
if(ismovableatom(caller))
|
||||
var/atom/movable/mover = caller
|
||||
. = . || mover.checkpass(PASSTABLE)
|
||||
|
||||
/obj/structure/rack/MouseDrop_T(obj/O as obj, mob/user as mob)
|
||||
if ((!( istype(O, /obj/item/weapon) ) || user.get_active_hand() != O))
|
||||
return
|
||||
|
||||
@@ -97,6 +97,14 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
|
||||
else
|
||||
return 1
|
||||
|
||||
/obj/structure/window/CanAStarPass(ID, to_dir)
|
||||
if(!density)
|
||||
return 1
|
||||
if((dir == SOUTHWEST) || (dir == to_dir))
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/obj/structure/window/hitby(AM as mob|obj)
|
||||
..()
|
||||
var/tforce = 0
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
dat += "<a href='?src=\ref[src];screen=1'>Back</a>"
|
||||
dat += "<br><b>Medical Robots:</b>"
|
||||
var/bdat = null
|
||||
for(var/obj/machinery/bot/medbot/M in world)
|
||||
for(var/mob/living/simple_animal/bot/medbot/M in world)
|
||||
|
||||
if(M.z != computer.z) continue //only find medibots on the same z-level as the computer
|
||||
var/turf/bl = get_turf(M)
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
/datum/table_recipe/ed209
|
||||
name = "ED209"
|
||||
result = /obj/machinery/bot/ed209
|
||||
result = /mob/living/simple_animal/bot/ed209
|
||||
reqs = list(/obj/item/robot_parts/robot_suit = 1,
|
||||
/obj/item/clothing/head/helmet = 1,
|
||||
/obj/item/clothing/suit/armor/vest = 1,
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
/datum/table_recipe/secbot
|
||||
name = "Secbot"
|
||||
result = /obj/machinery/bot/secbot
|
||||
result = /mob/living/simple_animal/bot/secbot
|
||||
reqs = list(/obj/item/device/assembly/signaler = 1,
|
||||
/obj/item/clothing/head/helmet = 1,
|
||||
/obj/item/weapon/melee/baton = 1,
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
/datum/table_recipe/cleanbot
|
||||
name = "Cleanbot"
|
||||
result = /obj/machinery/bot/cleanbot
|
||||
result = /mob/living/simple_animal/bot/cleanbot
|
||||
reqs = list(/obj/item/weapon/reagent_containers/glass/bucket = 1,
|
||||
/obj/item/device/assembly/prox_sensor = 1,
|
||||
/obj/item/robot_parts/r_arm = 1)
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
/datum/table_recipe/floorbot
|
||||
name = "Floorbot"
|
||||
result = /obj/machinery/bot/floorbot
|
||||
result = /mob/living/simple_animal/bot/floorbot
|
||||
reqs = list(/obj/item/weapon/storage/toolbox/mechanical = 1,
|
||||
/obj/item/stack/tile/plasteel = 1,
|
||||
/obj/item/device/assembly/prox_sensor = 1,
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
/datum/table_recipe/medbot
|
||||
name = "Medbot"
|
||||
result = /obj/machinery/bot/medbot
|
||||
result = /mob/living/simple_animal/bot/medbot
|
||||
reqs = list(/obj/item/device/healthanalyzer = 1,
|
||||
/obj/item/weapon/storage/firstaid = 1,
|
||||
/obj/item/device/assembly/prox_sensor = 1,
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
M << "<br>"
|
||||
|
||||
if(botEmagChance)
|
||||
for(var/obj/machinery/bot/bot in machines)
|
||||
for(var/mob/living/simple_animal/bot/bot in machines)
|
||||
if(prob(botEmagChance))
|
||||
bot.Emag()
|
||||
bot.emag_act()
|
||||
|
||||
/proc/generate_ion_law(ionMessage)
|
||||
if(ionMessage)
|
||||
|
||||
@@ -693,14 +693,7 @@
|
||||
mouse_opacity = 1
|
||||
faction = list("neutral")
|
||||
a_intent = I_HARM
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
wander = 0
|
||||
idle_vision_range = 5
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
message = stars(message)
|
||||
|
||||
var/speaker_name = "unknown"
|
||||
if(speaker)
|
||||
if(speaker)
|
||||
speaker_name = speaker.name
|
||||
|
||||
if(vname)
|
||||
@@ -160,7 +160,7 @@
|
||||
else
|
||||
track = "[speaker_name] ([jobname])"
|
||||
else
|
||||
if(istype(follow_target, /obj/machinery/bot))
|
||||
if(istype(follow_target, /mob/living/simple_animal/bot))
|
||||
track = "<a href='byond://?src=\ref[src];trackbot=\ref[follow_target]'>[speaker_name] ([jobname])</a>"
|
||||
else
|
||||
track = "<a href='byond://?src=\ref[src];track=\ref[speaker]'>[speaker_name] ([jobname])</a>"
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
usr.hud_used.nightvisionicon.icon_state = "nightvision0"
|
||||
|
||||
|
||||
/mob/living/carbon/alien/assess_threat(var/obj/machinery/bot/secbot/judgebot, var/lasercolor)
|
||||
/mob/living/carbon/alien/assess_threat(var/mob/living/simple_animal/bot/secbot/judgebot, var/lasercolor)
|
||||
if(judgebot.emagged == 2)
|
||||
return 10 //Everyone is a criminal!
|
||||
var/threatcount = 0
|
||||
|
||||
@@ -636,8 +636,8 @@
|
||||
// called when something steps onto a human
|
||||
// this handles mulebots and vehicles
|
||||
/mob/living/carbon/human/Crossed(var/atom/movable/AM)
|
||||
if(istype(AM, /obj/machinery/bot/mulebot))
|
||||
var/obj/machinery/bot/mulebot/MB = AM
|
||||
if(istype(AM, /mob/living/simple_animal/bot/mulebot))
|
||||
var/mob/living/simple_animal/bot/mulebot/MB = AM
|
||||
MB.RunOver(src)
|
||||
|
||||
if(istype(AM, /obj/vehicle))
|
||||
@@ -1753,7 +1753,7 @@
|
||||
if(M.stat == 2)
|
||||
M.gib()
|
||||
|
||||
/mob/living/carbon/human/assess_threat(var/obj/machinery/bot/secbot/judgebot, var/lasercolor)
|
||||
/mob/living/carbon/human/assess_threat(var/mob/living/simple_animal/bot/secbot/judgebot, var/lasercolor)
|
||||
if(judgebot.emagged == 2)
|
||||
return 10 //Everyone is a criminal!
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ var/list/ai_verbs_default = list(
|
||||
anchored = 1 // -- TLE
|
||||
density = 1
|
||||
status_flags = CANSTUN|CANPARALYSE|CANPUSH
|
||||
can_strip = 0
|
||||
var/list/network = list("SS13","Telecomms","Research Outpost","Mining Outpost")
|
||||
var/obj/machinery/camera/current = null
|
||||
var/list/connected_robots = list()
|
||||
@@ -80,7 +81,7 @@ var/list/ai_verbs_default = list(
|
||||
var/can_shunt = 1
|
||||
var/last_announcement = ""
|
||||
var/datum/announcement/priority/announcement
|
||||
var/obj/machinery/bot/Bot
|
||||
var/mob/living/simple_animal/bot/Bot
|
||||
var/turf/waypoint //Holds the turf of the currently selected waypoint.
|
||||
var/waypoint_mode = 0 //Waypoint mode is for selecting a turf via clicking.
|
||||
|
||||
@@ -513,7 +514,7 @@ var/list/ai_verbs_default = list(
|
||||
return
|
||||
|
||||
if (href_list["trackbot"])
|
||||
var/obj/machinery/bot/target = locate(href_list["trackbot"]) in aibots
|
||||
var/mob/living/simple_animal/bot/target = locate(href_list["trackbot"]) in simple_animal_list
|
||||
if(target)
|
||||
ai_actual_track(target)
|
||||
else
|
||||
@@ -521,7 +522,7 @@ var/list/ai_verbs_default = list(
|
||||
return
|
||||
|
||||
if (href_list["callbot"]) //Command a bot to move to a selected location.
|
||||
Bot = locate(href_list["callbot"]) in aibots
|
||||
Bot = locate(href_list["callbot"]) in simple_animal_list
|
||||
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
|
||||
@@ -529,7 +530,7 @@ var/list/ai_verbs_default = list(
|
||||
return
|
||||
|
||||
if (href_list["interface"]) //Remotely connect to a bot!
|
||||
Bot = locate(href_list["interface"]) in aibots
|
||||
Bot = locate(href_list["interface"]) in simple_animal_list
|
||||
if(!Bot || Bot.remote_disabled || src.control_disabled)
|
||||
return
|
||||
Bot.attack_ai(src)
|
||||
@@ -643,10 +644,10 @@ var/list/ai_verbs_default = list(
|
||||
d += "<A HREF=?src=\ref[src];botrefresh=\ref[Bot]>Query network status</A><br>"
|
||||
d += "<table width='100%'><tr><td width='40%'><h3>Name</h3></td><td width='20%'><h3>Status</h3></td><td width='30%'><h3>Location</h3></td><td width='10%'><h3>Control</h3></td></tr>"
|
||||
|
||||
for (Bot in aibots)
|
||||
for (var/mob/living/simple_animal/bot/Bot in simple_animal_list)
|
||||
if((Bot.z in ai_allowed_Zlevel) && !Bot.remote_disabled) //Only non-emagged bots on the allowed Z-level are detected!
|
||||
bot_area = get_area(Bot)
|
||||
d += "<tr><td width='30%'>[Bot.hacked ? "<span class='bad'>(!) </span>[Bot.name]" : Bot.name] ([Bot.bot_type_name])</td>"
|
||||
d += "<tr><td width='30%'>[Bot.hacked ? "<span class='bad'>(!) </span>[Bot.name]" : Bot.name] ([Bot.model])</td>"
|
||||
//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 += "<td width='20%'>[Bot.on ? "[Bot.mode ? "<span class='average'>[ Bot.mode_name[Bot.mode] ]</span>": "<span class='good'>Idle</span>"]" : "<span class='bad'>Inactive</span>"]</td>"
|
||||
d += "<td width='30%'>[bot_area.name]</td>"
|
||||
|
||||
@@ -17,14 +17,6 @@
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/my_hydrotray
|
||||
|
||||
// Allow final solutions.
|
||||
min_oxy = 5
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 1
|
||||
min_co2 = 0
|
||||
max_co2 = 5
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 360
|
||||
|
||||
@@ -37,145 +29,143 @@
|
||||
parent.owned_bee_swarms.Remove(src)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bee/Life()
|
||||
..()
|
||||
/mob/living/simple_animal/bee/process_ai()
|
||||
//if we're strong enough, sting some people
|
||||
var/mob/living/carbon/human/M = target_mob
|
||||
var/sting_prob = 100 // Bees will always try to sting.
|
||||
if(M in view(src,1)) // Can I see my target?
|
||||
if(prob(max(feral * 10, 0))) // Am I mad enough to want to sting? And yes, when I initially appear, I AM mad enough
|
||||
var/obj/item/clothing/worn_suit = M.wear_suit
|
||||
var/obj/item/clothing/worn_helmet = M.head
|
||||
if(worn_suit) // Are you wearing clothes?
|
||||
sting_prob -= min(worn_suit.armor["bio"],70) // Is it sealed? I can't get to 70% of your body.
|
||||
if(worn_helmet)
|
||||
sting_prob -= min(worn_helmet.armor["bio"],30) // Is your helmet sealed? I can't get to 30% of your body.
|
||||
if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) ) // Try to sting! If you're not moving, think about stinging.
|
||||
M.apply_damage(min(strength,2)+mut, BRUTE, sharp=1) // Stinging. The more mutated I am, the harder I sting.
|
||||
M.apply_damage((round(feral/10,1)*(max((round(strength/20,1)),1)))+toxic, TOX) // Bee venom based on how angry I am and how many there are of me!
|
||||
M << "\red You have been stung!"
|
||||
|
||||
if(stat == CONSCIOUS)
|
||||
//if we're strong enough, sting some people
|
||||
var/mob/living/carbon/human/M = target_mob
|
||||
var/sting_prob = 100 // Bees will always try to sting.
|
||||
if(M in view(src,1)) // Can I see my target?
|
||||
if(prob(max(feral * 10, 0))) // Am I mad enough to want to sting? And yes, when I initially appear, I AM mad enough
|
||||
var/obj/item/clothing/worn_suit = M.wear_suit
|
||||
var/obj/item/clothing/worn_helmet = M.head
|
||||
if(worn_suit) // Are you wearing clothes?
|
||||
sting_prob -= min(worn_suit.armor["bio"],70) // Is it sealed? I can't get to 70% of your body.
|
||||
if(worn_helmet)
|
||||
sting_prob -= min(worn_helmet.armor["bio"],30) // Is your helmet sealed? I can't get to 30% of your body.
|
||||
if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) ) // Try to sting! If you're not moving, think about stinging.
|
||||
M.apply_damage(min(strength,2)+mut, BRUTE, sharp=1) // Stinging. The more mutated I am, the harder I sting.
|
||||
M.apply_damage((round(feral/10,1)*(max((round(strength/20,1)),1)))+toxic, TOX) // Bee venom based on how angry I am and how many there are of me!
|
||||
M << "\red You have been stung!"
|
||||
M.flash_pain()
|
||||
//if we're chasing someone, get a little bit angry
|
||||
if(target_mob && prob(10))
|
||||
feral++
|
||||
M.flash_pain()
|
||||
|
||||
//if we're chasing someone, get a little bit angry
|
||||
if(target_mob && prob(10))
|
||||
feral++
|
||||
|
||||
//calm down a little bit
|
||||
if(feral > 0)
|
||||
if(prob(feral * 10))
|
||||
feral -= 1
|
||||
else
|
||||
//if feral is less than 0, we're becalmed by smoke or steam
|
||||
if(feral < 0)
|
||||
feral += 1
|
||||
|
||||
if(target_mob)
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
if(strength > 5)
|
||||
//calm down and spread out a little
|
||||
var/mob/living/simple_animal/bee/B = new(get_turf(pick(orange(src,1))))
|
||||
B.strength = rand(1,5)
|
||||
src.strength -= B.strength
|
||||
if(src.strength <= 5)
|
||||
src.icon_living = "bees[src.strength]"
|
||||
B.icon_living = "bees[B.strength]"
|
||||
if(src.parent)
|
||||
B.parent = src.parent
|
||||
src.parent.owned_bee_swarms.Add(B)
|
||||
|
||||
//make some noise
|
||||
if(prob(0.5))
|
||||
src.visible_message("\blue [pick("Buzzzz.","Hmmmmm.","Bzzz.")]")
|
||||
|
||||
//smoke, water and steam calms us down
|
||||
var/calming = 0
|
||||
var/list/calmers = list(/obj/effect/effect/chem_smoke, \
|
||||
/obj/effect/effect/water, \
|
||||
/obj/effect/effect/foam, \
|
||||
/obj/effect/effect/steam, \
|
||||
/obj/effect/mist)
|
||||
|
||||
for(var/obj/effect/check_effect in src.loc)
|
||||
if(check_effect.type in calmers)
|
||||
calming = 1
|
||||
break
|
||||
|
||||
if(calming)
|
||||
if(feral > 0)
|
||||
src.visible_message("\blue The bees calm down!")
|
||||
feral = -10
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
wander = 1
|
||||
|
||||
for(var/mob/living/simple_animal/bee/B in src.loc)
|
||||
if(B == src)
|
||||
continue
|
||||
|
||||
if(feral > 0)
|
||||
src.strength += B.strength
|
||||
qdel(B)
|
||||
src.icon_living = "bees[src.strength]"
|
||||
if(strength > 5)
|
||||
icon_living = "bees_swarm"
|
||||
else if(prob(10))
|
||||
//make the other swarm of bees stronger, then move away
|
||||
var/total_bees = B.strength + src.strength
|
||||
if(total_bees < 10)
|
||||
B.strength = min(5, total_bees)
|
||||
src.strength = total_bees - B.strength
|
||||
|
||||
B.icon_living = "bees[B.strength]"
|
||||
if(src.strength <= 0)
|
||||
qdel(src)
|
||||
return
|
||||
src.icon_living = "bees[B.strength]"
|
||||
var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
|
||||
density = 1
|
||||
if(T.Enter(src, get_turf(src)))
|
||||
src.loc = T
|
||||
density = 0
|
||||
break
|
||||
//calm down a little bit
|
||||
if(feral > 0)
|
||||
if(prob(feral * 10))
|
||||
feral -= 1
|
||||
else
|
||||
//if feral is less than 0, we're becalmed by smoke or steam
|
||||
if(feral < 0)
|
||||
feral += 1
|
||||
|
||||
if(target_mob)
|
||||
if(target_mob in view(src,7))
|
||||
target_turf = get_turf(target_mob)
|
||||
wander = 0
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
if(strength > 5)
|
||||
//calm down and spread out a little
|
||||
var/mob/living/simple_animal/bee/B = new(get_turf(pick(orange(src,1))))
|
||||
B.strength = rand(1,5)
|
||||
src.strength -= B.strength
|
||||
if(src.strength <= 5)
|
||||
src.icon_living = "bees[src.strength]"
|
||||
B.icon_living = "bees[B.strength]"
|
||||
if(src.parent)
|
||||
B.parent = src.parent
|
||||
src.parent.owned_bee_swarms.Add(B)
|
||||
|
||||
else // My target's gone! But I might still be pissed! You there. You look like a good stinging target!
|
||||
for(var/mob/living/carbon/G in view(src,7))
|
||||
target_mob = G
|
||||
break
|
||||
//make some noise
|
||||
if(prob(0.5))
|
||||
src.visible_message("\blue [pick("Buzzzz.","Hmmmmm.","Bzzz.")]")
|
||||
|
||||
if(target_turf)
|
||||
if (!(DirBlocked(get_step(src, get_dir(src,target_turf)),get_dir(src,target_turf)))) // Check for windows and doors!
|
||||
Move(get_step(src, get_dir(src,target_turf)))
|
||||
if (prob(0.1))
|
||||
src.visible_message("\blue The bees swarm after [target_mob]!")
|
||||
if(src.loc == target_turf)
|
||||
target_turf = null
|
||||
wander = 1
|
||||
else
|
||||
//find some flowers, harvest
|
||||
//angry bee swarms don't hang around
|
||||
if(feral > 0)
|
||||
turns_per_move = rand(1,3)
|
||||
else if(feral < 0)
|
||||
turns_since_move = 0
|
||||
else if(!my_hydrotray || my_hydrotray.loc != src.loc || my_hydrotray.dead || !my_hydrotray.seed)
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/my_hydrotray = locate() in src.loc
|
||||
if(my_hydrotray)
|
||||
if(!my_hydrotray.dead && my_hydrotray.seed)
|
||||
turns_per_move = rand(20,50)
|
||||
else
|
||||
my_hydrotray = null
|
||||
//smoke, water and steam calms us down
|
||||
var/calming = 0
|
||||
var/list/calmers = list(/obj/effect/effect/chem_smoke, \
|
||||
/obj/effect/effect/water, \
|
||||
/obj/effect/effect/foam, \
|
||||
/obj/effect/effect/steam, \
|
||||
/obj/effect/mist)
|
||||
|
||||
pixel_x = rand(-12,12)
|
||||
pixel_y = rand(-12,12)
|
||||
for(var/obj/effect/check_effect in src.loc)
|
||||
if(check_effect.type in calmers)
|
||||
calming = 1
|
||||
break
|
||||
|
||||
if(calming)
|
||||
if(feral > 0)
|
||||
src.visible_message("\blue The bees calm down!")
|
||||
feral = -10
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
wander = 1
|
||||
|
||||
for(var/mob/living/simple_animal/bee/B in src.loc)
|
||||
if(B == src)
|
||||
continue
|
||||
|
||||
if(feral > 0)
|
||||
src.strength += B.strength
|
||||
qdel(B)
|
||||
src.icon_living = "bees[src.strength]"
|
||||
if(strength > 5)
|
||||
icon_living = "bees_swarm"
|
||||
else if(prob(10))
|
||||
//make the other swarm of bees stronger, then move away
|
||||
var/total_bees = B.strength + src.strength
|
||||
if(total_bees < 10)
|
||||
B.strength = min(5, total_bees)
|
||||
src.strength = total_bees - B.strength
|
||||
|
||||
B.icon_living = "bees[B.strength]"
|
||||
if(src.strength <= 0)
|
||||
qdel(src)
|
||||
return
|
||||
src.icon_living = "bees[B.strength]"
|
||||
var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
|
||||
density = 1
|
||||
if(T.Enter(src, get_turf(src)))
|
||||
src.loc = T
|
||||
density = 0
|
||||
break
|
||||
|
||||
if(target_mob)
|
||||
if(target_mob in view(src,7))
|
||||
target_turf = get_turf(target_mob)
|
||||
wander = 0
|
||||
|
||||
else // My target's gone! But I might still be pissed! You there. You look like a good stinging target!
|
||||
for(var/mob/living/carbon/G in view(src,7))
|
||||
target_mob = G
|
||||
break
|
||||
|
||||
if(target_turf)
|
||||
if (!(DirBlocked(get_step(src, get_dir(src,target_turf)),get_dir(src,target_turf)))) // Check for windows and doors!
|
||||
Move(get_step(src, get_dir(src,target_turf)))
|
||||
if (prob(0.1))
|
||||
src.visible_message("\blue The bees swarm after [target_mob]!")
|
||||
if(src.loc == target_turf)
|
||||
target_turf = null
|
||||
wander = 1
|
||||
else
|
||||
//find some flowers, harvest
|
||||
//angry bee swarms don't hang around
|
||||
if(feral > 0)
|
||||
turns_per_move = rand(1,3)
|
||||
else if(feral < 0)
|
||||
turns_since_move = 0
|
||||
else if(!my_hydrotray || my_hydrotray.loc != src.loc || my_hydrotray.dead || !my_hydrotray.seed)
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/my_hydrotray = locate() in src.loc
|
||||
if(my_hydrotray)
|
||||
if(!my_hydrotray.dead && my_hydrotray.seed)
|
||||
turns_per_move = rand(20,50)
|
||||
else
|
||||
my_hydrotray = null
|
||||
|
||||
pixel_x = rand(-12,12)
|
||||
pixel_y = rand(-12,12)
|
||||
|
||||
/mob/living/simple_animal/bee/handle_state_icons()
|
||||
if(!parent && prob(10))
|
||||
strength -= 1
|
||||
if(strength <= 0)
|
||||
@@ -187,3 +177,5 @@
|
||||
/*icon_living = "[strength]"
|
||||
if(strength > 5)
|
||||
icon_living = "unknown"*/
|
||||
|
||||
..()
|
||||
File diff suppressed because it is too large
Load Diff
+227
-282
@@ -1,282 +1,227 @@
|
||||
//Cleanbot assembly
|
||||
/obj/item/weapon/bucket_sensor
|
||||
desc = "It's a bucket. With a sensor attached."
|
||||
name = "proxy bucket"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "bucket_proxy"
|
||||
force = 3.0
|
||||
throwforce = 5.0
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = 3.0
|
||||
var/created_name = "Cleanbot"
|
||||
|
||||
|
||||
//Cleanbot
|
||||
/obj/machinery/bot/cleanbot
|
||||
name = "\improper Cleanbot"
|
||||
desc = "A little cleaning robot, he looks so excited!"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "cleanbot0"
|
||||
layer = 5.0
|
||||
density = 0
|
||||
anchored = 0
|
||||
//weight = 1.0E7
|
||||
health = 25
|
||||
maxhealth = 25
|
||||
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_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/next_dest
|
||||
var/next_dest_loc
|
||||
radio_name = "Service"
|
||||
bot_type = CLEAN_BOT
|
||||
bot_type_name = "Cleanbot"
|
||||
bot_filter = RADIO_CLEANBOT
|
||||
|
||||
/obj/machinery/bot/cleanbot/New()
|
||||
..()
|
||||
get_targets()
|
||||
icon_state = "cleanbot[on]"
|
||||
|
||||
var/datum/job/janitor/J = new/datum/job/janitor
|
||||
botcard.access = J.get_access()
|
||||
prev_access = botcard.access
|
||||
|
||||
spawn(5)
|
||||
add_to_beacons(bot_filter)
|
||||
|
||||
/obj/machinery/bot/cleanbot/turn_on()
|
||||
..()
|
||||
icon_state = "cleanbot[on]"
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/bot/cleanbot/turn_off()
|
||||
..()
|
||||
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)
|
||||
. = ..()
|
||||
if (.)
|
||||
return
|
||||
usr.set_machine(src)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/bot/cleanbot/interact(mob/user as mob)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += text({"
|
||||
<TT><B>Cleaner v1.1 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
text("<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>"))
|
||||
if(!locked || issilicon(user))
|
||||
dat += text({"<BR>Cleans Blood: []<BR>"}, text("<A href='?src=\ref[src];operation=blood'>[blood ? "Yes" : "No"]</A>"))
|
||||
dat += text({"<BR>Patrol station: []<BR>"}, text("<A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A>"))
|
||||
|
||||
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)
|
||||
|
||||
..()
|
||||
switch(href_list["operation"])
|
||||
if("blood")
|
||||
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)
|
||||
beacon_freq = freq
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/bot/cleanbot/attackby(obj/item/weapon/W, mob/user as mob, params)
|
||||
if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
|
||||
if(allowed(usr) && !open && !emagged)
|
||||
locked = !locked
|
||||
user << "<span class='notice'>You [ locked ? "lock" : "unlock"] the [src] behaviour controls.</span>"
|
||||
updateUsrDialog()
|
||||
else
|
||||
if(emagged)
|
||||
user << "<span class='warning'>ERROR</span>"
|
||||
if(open)
|
||||
user << "<span class='warning'>Please close the access panel before locking it.</span>"
|
||||
else
|
||||
user << "<span class='notice'>This [src] doesn't seem to respect your authority.</span>"
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/bot/cleanbot/Emag(mob/user as mob)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
user << "<span class='danger'>[src] buzzes and beeps.</span>"
|
||||
|
||||
/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/bot_process()
|
||||
if (!..())
|
||||
return
|
||||
|
||||
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("<span class='danger'>[src] whirs and bubbles violently, before releasing a plume of froth!</span>")
|
||||
new /obj/effect/effect/foam(loc)
|
||||
|
||||
else if (prob(5))
|
||||
visible_message("[src] makes an excited beeping booping sound!")
|
||||
|
||||
if(!target) //Search for cleanables it can see.
|
||||
target = scan(/obj/effect/decal/cleanable/, oldtarget)
|
||||
oldtarget = target
|
||||
|
||||
if(!target)
|
||||
if(loc != oldloc)
|
||||
oldtarget = null
|
||||
|
||||
if(auto_patrol)
|
||||
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
|
||||
start_patrol()
|
||||
|
||||
if(mode == BOT_PATROL)
|
||||
bot_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 = get_path_to(loc, target.loc, src, /turf/proc/Distance_cardinal, 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(target && loc == target.loc)
|
||||
clean(target)
|
||||
path = list()
|
||||
target = null
|
||||
|
||||
oldloc = loc
|
||||
|
||||
/obj/machinery/bot/cleanbot/proc/get_targets()
|
||||
target_types = new/list()
|
||||
|
||||
target_types += /obj/effect/decal/cleanable/blood/oil
|
||||
target_types += /obj/effect/decal/cleanable/vomit
|
||||
target_types += /obj/effect/decal/cleanable/poop
|
||||
target_types += /obj/effect/decal/cleanable/blood/gibs/robot
|
||||
target_types += /obj/effect/decal/cleanable/crayon
|
||||
target_types += /obj/effect/decal/cleanable/liquid_fuel
|
||||
target_types += /obj/effect/decal/cleanable/molten_item
|
||||
target_types += /obj/effect/decal/cleanable/tomato_smudge
|
||||
target_types += /obj/effect/decal/cleanable/egg_smudge
|
||||
target_types += /obj/effect/decal/cleanable/pie_smudge
|
||||
target_types += /obj/effect/decal/cleanable/flour
|
||||
target_types += /obj/effect/decal/cleanable/ash
|
||||
target_types += /obj/effect/decal/cleanable/greenglow
|
||||
target_types += /obj/effect/decal/cleanable/dirt
|
||||
target_types += /obj/effect/decal/cleanable/mucus
|
||||
|
||||
if(blood)
|
||||
target_types += /obj/effect/decal/cleanable/blood/xeno/
|
||||
target_types += /obj/effect/decal/cleanable/blood/gibs/xeno
|
||||
target_types += /obj/effect/decal/cleanable/blood/
|
||||
target_types += /obj/effect/decal/cleanable/blood/gibs/
|
||||
target_types += /obj/effect/decal/cleanable/blood/tracks
|
||||
target_types += /obj/effect/decal/cleanable/dirt
|
||||
|
||||
/obj/machinery/bot/cleanbot/proc/clean(var/obj/effect/decal/cleanable/target)
|
||||
anchored = 1
|
||||
icon_state = "cleanbot-c"
|
||||
visible_message("<span class='notice'>[src] begins to clean up [target]</span>")
|
||||
mode = BOT_CLEANING
|
||||
spawn(25)
|
||||
if(mode == BOT_CLEANING)
|
||||
qdel(target)
|
||||
anchored = 0
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
icon_state = "cleanbot[on]"
|
||||
|
||||
/obj/machinery/bot/cleanbot/explode()
|
||||
on = 0
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
new /obj/item/weapon/reagent_containers/glass/bucket(Tsec)
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
if (prob(50))
|
||||
new /obj/item/robot_parts/l_arm(Tsec)
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/bucket_sensor/attackby(var/obj/item/W, mob/user as mob, params)
|
||||
..()
|
||||
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(loc)
|
||||
var/obj/machinery/bot/cleanbot/A = new /obj/machinery/bot/cleanbot(T)
|
||||
A.name = created_name
|
||||
user << "<span class='notice'>You add the robot arm to the bucket and sensor assembly. Beep boop!</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
else if (istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if (!t)
|
||||
return
|
||||
if (!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
created_name = t
|
||||
//Cleanbot
|
||||
/mob/living/simple_animal/bot/cleanbot
|
||||
name = "\improper Cleanbot"
|
||||
desc = "A little cleaning robot, he looks so excited!"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "cleanbot0"
|
||||
density = 0
|
||||
anchored = 0
|
||||
health = 25
|
||||
maxHealth = 25
|
||||
radio_channel = "Service" //Service
|
||||
bot_filter = RADIO_CLEANBOT
|
||||
bot_type = CLEAN_BOT
|
||||
model = "Cleanbot"
|
||||
bot_purpose = "seek out messes and clean them"
|
||||
bot_core_type = /obj/machinery/bot_core/cleanbot
|
||||
window_id = "autoclean"
|
||||
window_name = "Automatic Station Cleaner v1.1"
|
||||
pass_flags = PASSMOB
|
||||
|
||||
var/blood = 1
|
||||
var/list/target_types = list()
|
||||
var/obj/effect/decal/cleanable/target
|
||||
var/max_targets = 50 //Maximum number of targets a cleanbot can ignore.
|
||||
var/oldloc = null
|
||||
var/closest_dist
|
||||
var/closest_loc
|
||||
var/failed_steps
|
||||
var/next_dest
|
||||
var/next_dest_loc
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/New()
|
||||
..()
|
||||
get_targets()
|
||||
icon_state = "cleanbot[on]"
|
||||
|
||||
var/datum/job/janitor/J = new/datum/job/janitor
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/turn_on()
|
||||
..()
|
||||
icon_state = "cleanbot[on]"
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/turn_off()
|
||||
..()
|
||||
icon_state = "cleanbot[on]"
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/bot_reset()
|
||||
..()
|
||||
ignore_list = list() //Allows the bot to clean targets it previously ignored due to being unreachable.
|
||||
target = null
|
||||
oldloc = null
|
||||
|
||||
/mob/living/simple_animal/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!"
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
|
||||
if(bot_core.allowed(user) && !open && !emagged)
|
||||
locked = !locked
|
||||
user << "<span class='notice'>You [ locked ? "lock" : "unlock"] \the [src] behaviour controls.</span>"
|
||||
else
|
||||
if(emagged)
|
||||
user << "<span class='warning'>ERROR</span>"
|
||||
if(open)
|
||||
user << "<span class='warning'>Please close the access panel before locking it.</span>"
|
||||
else
|
||||
user << "<span class='notice'>\The [src] doesn't seem to respect your authority.</span>"
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
user << "<span class='danger'>[src] buzzes and beeps.</span>"
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/process_scan(obj/effect/decal/cleanable/D)
|
||||
for(var/T in target_types)
|
||||
if(istype(D, T))
|
||||
return D
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
|
||||
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("<span class='danger'>[src] whirs and bubbles violently, before releasing a plume of froth!</span>")
|
||||
new /obj/effect/effect/foam(loc)
|
||||
|
||||
else if(prob(5))
|
||||
audible_message("[src] makes an excited beeping booping sound!")
|
||||
|
||||
if(!target) //Search for cleanables it can see.
|
||||
target = scan(/obj/effect/decal/cleanable/)
|
||||
|
||||
if(!target && auto_patrol) //Search for cleanables it can see.
|
||||
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
|
||||
start_patrol()
|
||||
|
||||
if(mode == BOT_PATROL)
|
||||
bot_patrol()
|
||||
|
||||
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 = get_path_to(src, target.loc, /turf/proc/Distance_cardinal, 0, 30, id=access_card)
|
||||
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(target && loc == target.loc)
|
||||
clean(target)
|
||||
path = list()
|
||||
target = null
|
||||
|
||||
oldloc = loc
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/proc/get_targets()
|
||||
target_types = new/list()
|
||||
|
||||
target_types += /obj/effect/decal/cleanable/blood/oil
|
||||
target_types += /obj/effect/decal/cleanable/vomit
|
||||
target_types += /obj/effect/decal/cleanable/poop
|
||||
target_types += /obj/effect/decal/cleanable/blood/gibs/robot
|
||||
target_types += /obj/effect/decal/cleanable/crayon
|
||||
target_types += /obj/effect/decal/cleanable/liquid_fuel
|
||||
target_types += /obj/effect/decal/cleanable/molten_item
|
||||
target_types += /obj/effect/decal/cleanable/tomato_smudge
|
||||
target_types += /obj/effect/decal/cleanable/egg_smudge
|
||||
target_types += /obj/effect/decal/cleanable/pie_smudge
|
||||
target_types += /obj/effect/decal/cleanable/flour
|
||||
target_types += /obj/effect/decal/cleanable/ash
|
||||
target_types += /obj/effect/decal/cleanable/greenglow
|
||||
target_types += /obj/effect/decal/cleanable/dirt
|
||||
target_types += /obj/effect/decal/cleanable/mucus
|
||||
|
||||
if(blood)
|
||||
target_types += /obj/effect/decal/cleanable/blood/xeno/
|
||||
target_types += /obj/effect/decal/cleanable/blood/gibs/xeno
|
||||
target_types += /obj/effect/decal/cleanable/blood/
|
||||
target_types += /obj/effect/decal/cleanable/blood/gibs/
|
||||
target_types += /obj/effect/decal/cleanable/blood/tracks
|
||||
target_types += /obj/effect/decal/cleanable/dirt
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/proc/clean(obj/effect/decal/cleanable/target)
|
||||
anchored = 1
|
||||
icon_state = "cleanbot-c"
|
||||
visible_message("<span class='notice'>[src] begins to clean up [target]</span>")
|
||||
mode = BOT_CLEANING
|
||||
spawn(50)
|
||||
if(mode == BOT_CLEANING)
|
||||
qdel(target)
|
||||
anchored = 0
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
icon_state = "cleanbot[on]"
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/explode()
|
||||
on = 0
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
new /obj/item/weapon/reagent_containers/glass/bucket(Tsec)
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
if(prob(50))
|
||||
new /obj/item/robot_parts/l_arm(Tsec)
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/cleanbot
|
||||
req_one_access = list(access_janitor, access_robotics)
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += text({"
|
||||
<TT><B>Cleaner v1.1 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
text("<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>"))
|
||||
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
|
||||
dat += text({"<BR>Cleans Blood: []<BR>"}, text("<A href='?src=\ref[src];operation=blood'>[blood ? "Yes" : "No"]</A>"))
|
||||
dat += text({"<BR>Patrol station: []<BR>"}, text("<A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A>"))
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
switch(href_list["operation"])
|
||||
if("blood")
|
||||
blood =!blood
|
||||
get_targets()
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/UnarmedAttack(atom/A)
|
||||
if(istype(A,/obj/effect/decal/cleanable))
|
||||
clean(A)
|
||||
else
|
||||
..()
|
||||
@@ -0,0 +1,480 @@
|
||||
//Bot Construction
|
||||
|
||||
//Cleanbot assembly
|
||||
/obj/item/weapon/bucket_sensor
|
||||
desc = "It's a bucket. With a sensor attached."
|
||||
name = "proxy bucket"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "bucket_proxy"
|
||||
force = 3
|
||||
throwforce = 5
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = 3
|
||||
var/created_name = "Cleanbot"
|
||||
|
||||
/obj/item/weapon/bucket_sensor/attackby(obj/item/W, mob/user as mob, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
qdel(W)
|
||||
var/turf/T = get_turf(loc)
|
||||
var/mob/living/simple_animal/bot/cleanbot/A = new /mob/living/simple_animal/bot/cleanbot(T)
|
||||
A.name = created_name
|
||||
user << "<span class='notice'>You add the robot arm to the bucket and sensor assembly. Beep boop!</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
else if(istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
created_name = t
|
||||
|
||||
//Edbot Assembly
|
||||
|
||||
/obj/item/weapon/ed209_assembly
|
||||
name = "\improper ED-209 assembly"
|
||||
desc = "Some sort of bizarre assembly."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "ed209_frame"
|
||||
item_state = "ed209_frame"
|
||||
var/build_step = 0
|
||||
var/created_name = "ED-209 Security Robot" //To preserve the name if it's a unique securitron I guess
|
||||
var/lasercolor = ""
|
||||
|
||||
/obj/item/weapon/ed209_assembly/attackby(obj/item/weapon/W, mob/user, params)
|
||||
..()
|
||||
|
||||
if(istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
created_name = t
|
||||
return
|
||||
|
||||
switch(build_step)
|
||||
if(0,1)
|
||||
if(istype(W, /obj/item/robot_parts/l_leg) || istype(W, /obj/item/robot_parts/r_leg))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the robot leg to [src].</span>"
|
||||
name = "legs/frame assembly"
|
||||
if(build_step == 1)
|
||||
item_state = "ed209_leg"
|
||||
icon_state = "ed209_leg"
|
||||
else
|
||||
item_state = "ed209_legs"
|
||||
icon_state = "ed209_legs"
|
||||
|
||||
if(2)
|
||||
var/newcolor = ""
|
||||
if(istype(W, /obj/item/clothing/suit/redtag))
|
||||
newcolor = "r"
|
||||
else if(istype(W, /obj/item/clothing/suit/bluetag))
|
||||
newcolor = "b"
|
||||
if(newcolor || istype(W, /obj/item/clothing/suit/armor/vest))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
lasercolor = newcolor
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the armor to [src].</span>"
|
||||
name = "vest/legs/frame assembly"
|
||||
item_state = "[lasercolor]ed209_shell"
|
||||
icon_state = "[lasercolor]ed209_shell"
|
||||
|
||||
if(3)
|
||||
if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(WT.remove_fuel(0,user))
|
||||
build_step++
|
||||
name = "shielded frame assembly"
|
||||
user << "<span class='notice'>You weld the vest to [src].</span>"
|
||||
if(4)
|
||||
switch(lasercolor)
|
||||
if("b")
|
||||
if(!istype(W, /obj/item/clothing/head/helmet/bluetaghelm))
|
||||
return
|
||||
|
||||
if("r")
|
||||
if(!istype(W, /obj/item/clothing/head/helmet/redtaghelm))
|
||||
return
|
||||
|
||||
if("")
|
||||
if(!istype(W, /obj/item/clothing/head/helmet))
|
||||
return
|
||||
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the helmet to [src].</span>"
|
||||
name = "covered and shielded frame assembly"
|
||||
item_state = "[lasercolor]ed209_hat"
|
||||
icon_state = "[lasercolor]ed209_hat"
|
||||
|
||||
if(5)
|
||||
if(isprox(W))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the prox sensor to [src].</span>"
|
||||
name = "covered, shielded and sensored frame assembly"
|
||||
item_state = "[lasercolor]ed209_prox"
|
||||
icon_state = "[lasercolor]ed209_prox"
|
||||
|
||||
if(6)
|
||||
if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/coil = W
|
||||
if(coil.get_amount() < 1)
|
||||
user << "<span class='warning'>You need one length of cable to wire the ED-209!</span>"
|
||||
return
|
||||
user << "<span class='notice'>You start to wire [src]...</span>"
|
||||
if(do_after(user, 40, target = src))
|
||||
if(coil.get_amount() >= 1 && build_step == 6)
|
||||
coil.use(1)
|
||||
build_step = 7
|
||||
user << "<span class='notice'>You wire the ED-209 assembly.</span>"
|
||||
name = "wired ED-209 assembly"
|
||||
|
||||
if(7)
|
||||
var/newname = ""
|
||||
switch(lasercolor)
|
||||
if("b")
|
||||
if(!istype(W, /obj/item/weapon/gun/energy/laser/bluetag))
|
||||
return
|
||||
newname = "bluetag ED-209 assembly"
|
||||
if("r")
|
||||
if(!istype(W, /obj/item/weapon/gun/energy/laser/redtag))
|
||||
return
|
||||
newname = "redtag ED-209 assembly"
|
||||
if("")
|
||||
if(!istype(W, /obj/item/weapon/gun/energy/advtaser))
|
||||
return
|
||||
newname = "taser ED-209 assembly"
|
||||
else
|
||||
return
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
name = newname
|
||||
build_step++
|
||||
user << "<span class='notice'>You add [W] to [src].</span>"
|
||||
item_state = "[lasercolor]ed209_taser"
|
||||
icon_state = "[lasercolor]ed209_taser"
|
||||
qdel(W)
|
||||
|
||||
if(8)
|
||||
if(istype(W, /obj/item/weapon/screwdriver))
|
||||
playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1)
|
||||
user << "<span class='notice'>You start attaching the gun to the frame...</span>"
|
||||
if(do_after(user, 40, target = src))
|
||||
build_step++
|
||||
name = "armed [name]"
|
||||
user << "<span class='notice'>Taser gun attached.</span>"
|
||||
|
||||
if(9)
|
||||
if(istype(W, /obj/item/weapon/stock_parts/cell))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
build_step++
|
||||
user << "<span class='notice'>You complete the ED-209.</span>"
|
||||
var/turf/T = get_turf(src)
|
||||
new /mob/living/simple_animal/bot/ed209(T,created_name,lasercolor)
|
||||
qdel(W)
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
//Floorbot assemblies
|
||||
/obj/item/weapon/toolbox_tiles
|
||||
desc = "It's a toolbox with tiles sticking out the top"
|
||||
name = "tiles and toolbox"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "toolbox_tiles"
|
||||
force = 3
|
||||
throwforce = 10
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = 3
|
||||
var/created_name = "Floorbot"
|
||||
|
||||
/obj/item/weapon/toolbox_tiles_sensor
|
||||
desc = "It's a toolbox with tiles sticking out the top and a sensor attached"
|
||||
name = "tiles, toolbox and sensor arrangement"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "toolbox_tiles_sensor"
|
||||
force = 3
|
||||
throwforce = 10
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = 3
|
||||
var/created_name = "Floorbot"
|
||||
|
||||
/obj/item/weapon/storage/toolbox/mechanical/attackby(obj/item/stack/tile/plasteel/T, mob/user, params)
|
||||
if(!istype(T, /obj/item/stack/tile/plasteel))
|
||||
..()
|
||||
return
|
||||
if(contents.len >= 1)
|
||||
user << "<span class='warning'>They won't fit in, as there is already stuff inside.</span>"
|
||||
return
|
||||
if(T.use(10))
|
||||
if(user.s_active)
|
||||
user.s_active.close(user)
|
||||
var/obj/item/weapon/toolbox_tiles/B = new /obj/item/weapon/toolbox_tiles
|
||||
user.put_in_hands(B)
|
||||
user << "<span class='notice'>You add the tiles into the empty toolbox. They protrude from the top.</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='warning'>You need 10 floor tiles to start building a floorbot.</span>"
|
||||
return
|
||||
|
||||
/obj/item/weapon/toolbox_tiles/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(isprox(W))
|
||||
qdel(W)
|
||||
var/obj/item/weapon/toolbox_tiles_sensor/B = new /obj/item/weapon/toolbox_tiles_sensor()
|
||||
B.created_name = created_name
|
||||
user.put_in_hands(B)
|
||||
user << "<span class='notice'>You add the sensor to the toolbox and tiles.</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
else if(istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
|
||||
created_name = t
|
||||
|
||||
/obj/item/weapon/toolbox_tiles_sensor/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm))
|
||||
qdel(W)
|
||||
var/turf/T = get_turf(user.loc)
|
||||
var/mob/living/simple_animal/bot/floorbot/A = new /mob/living/simple_animal/bot/floorbot(T)
|
||||
A.name = created_name
|
||||
user << "<span class='notice'>You add the robot arm to the odd looking toolbox assembly. Boop beep!</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
else if(istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
|
||||
created_name = t
|
||||
|
||||
//Medbot Assembly
|
||||
/obj/item/weapon/firstaid_arm_assembly
|
||||
name = "incomplete medibot assembly."
|
||||
desc = "A first aid kit with a robot arm permanently grafted to it."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "firstaid_arm"
|
||||
var/build_step = 0
|
||||
var/created_name = "Medibot" //To preserve the name if it's a unique medbot I guess
|
||||
var/skin = null //Same as medbot, set to tox or ointment for the respective kits.
|
||||
w_class = 3
|
||||
var/treatment_brute = "salglu_solution"
|
||||
var/treatment_oxy = "salbutamol"
|
||||
var/treatment_fire = "salglu_solution"
|
||||
var/treatment_tox = "charcoal"
|
||||
var/treatment_virus = "spaceacillin"
|
||||
req_one_access = list(access_medical, access_robotics)
|
||||
|
||||
/obj/item/weapon/firstaid_arm_assembly/New()
|
||||
..()
|
||||
spawn(5)
|
||||
if(skin)
|
||||
overlays += image('icons/obj/aibots.dmi', "kit_skin_[skin]")
|
||||
|
||||
/obj/item/weapon/storage/firstaid/attackby(obj/item/robot_parts/S, mob/user, params)
|
||||
|
||||
if((!istype(S, /obj/item/robot_parts/l_arm)) && (!istype(S, /obj/item/robot_parts/r_arm)))
|
||||
..()
|
||||
return
|
||||
|
||||
//Making a medibot!
|
||||
if(contents.len >= 1)
|
||||
user << "<span class='warning'>You need to empty [src] out first!</span>"
|
||||
return
|
||||
|
||||
var/obj/item/weapon/firstaid_arm_assembly/A = new /obj/item/weapon/firstaid_arm_assembly
|
||||
if(istype(src,/obj/item/weapon/storage/firstaid/fire))
|
||||
A.skin = "ointment"
|
||||
else if(istype(src,/obj/item/weapon/storage/firstaid/toxin))
|
||||
A.skin = "tox"
|
||||
else if(istype(src,/obj/item/weapon/storage/firstaid/o2))
|
||||
A.skin = "o2"
|
||||
else if(istype(src,/obj/item/weapon/storage/firstaid/brute))
|
||||
A.skin = "brute"
|
||||
else if(istype(src,/obj/item/weapon/storage/firstaid/adv))
|
||||
A.skin = "adv"
|
||||
else if(istype(src,/obj/item/weapon/storage/firstaid/tactical))
|
||||
A.skin = "bezerk"
|
||||
else if(istype(src,/obj/item/weapon/storage/firstaid/aquatic_kit))
|
||||
A.skin = "fish"
|
||||
|
||||
A.req_one_access = req_one_access
|
||||
A.treatment_oxy = treatment_oxy
|
||||
A.treatment_brute = treatment_brute
|
||||
A.treatment_fire = treatment_fire
|
||||
A.treatment_tox = treatment_tox
|
||||
A.treatment_virus = treatment_virus
|
||||
|
||||
qdel(S)
|
||||
user.put_in_hands(A)
|
||||
user << "<span class='notice'>You add the robot arm to the first aid kit.</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/item/weapon/firstaid_arm_assembly/attackby(obj/item/weapon/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
created_name = t
|
||||
else
|
||||
switch(build_step)
|
||||
if(0)
|
||||
if(istype(W, /obj/item/device/healthanalyzer))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the health sensor to [src].</span>"
|
||||
name = "First aid/robot arm/health analyzer assembly"
|
||||
overlays += image('icons/obj/aibots.dmi', "na_scanner")
|
||||
|
||||
if(1)
|
||||
if(isprox(W))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You complete the Medibot. Beep boop!</span>"
|
||||
var/turf/T = get_turf(src)
|
||||
var/mob/living/simple_animal/bot/medbot/S = new /mob/living/simple_animal/bot/medbot(T)
|
||||
S.skin = skin
|
||||
S.name = created_name
|
||||
S.bot_core.req_one_access = req_one_access
|
||||
S.treatment_oxy = treatment_oxy
|
||||
S.treatment_brute = treatment_brute
|
||||
S.treatment_fire = treatment_fire
|
||||
S.treatment_tox = treatment_tox
|
||||
S.treatment_virus = treatment_virus
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
//Secbot Assembly
|
||||
/obj/item/weapon/secbot_assembly
|
||||
name = "incomplete securitron assembly"
|
||||
desc = "Some sort of bizarre assembly made from a proximity sensor, helmet, and signaler."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "helmet_signaler"
|
||||
item_state = "helmet"
|
||||
var/build_step = 0
|
||||
var/created_name = "Securitron" //To preserve the name if it's a unique securitron I guess
|
||||
|
||||
/obj/item/clothing/head/helmet/attackby(obj/item/device/assembly/signaler/S, mob/user, params)
|
||||
..()
|
||||
if(!issignaler(S))
|
||||
..()
|
||||
return
|
||||
|
||||
if(!S.secured)
|
||||
qdel(S)
|
||||
var/obj/item/weapon/secbot_assembly/A = new /obj/item/weapon/secbot_assembly
|
||||
user.put_in_hands(A)
|
||||
user << "<span class='notice'>You add the signaler to the helmet.</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
else
|
||||
return
|
||||
|
||||
/obj/item/weapon/secbot_assembly/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/weapon/weldingtool))
|
||||
if(!build_step)
|
||||
var/obj/item/weapon/weldingtool/WT = I
|
||||
if(WT.remove_fuel(0, user))
|
||||
build_step++
|
||||
overlays += "hs_hole"
|
||||
user << "<span class='notice'>You weld a hole in [src]!</span>"
|
||||
else if(build_step == 1)
|
||||
var/obj/item/weapon/weldingtool/WT = I
|
||||
if(WT.remove_fuel(0, user))
|
||||
build_step--
|
||||
overlays -= "hs_hole"
|
||||
user << "<span class='notice'>You weld the hole in [src] shut!</span>"
|
||||
|
||||
else if(isprox(I) && (build_step == 1))
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the prox sensor to [src]!</span>"
|
||||
overlays += "hs_eye"
|
||||
name = "helmet/signaler/prox sensor assembly"
|
||||
qdel(I)
|
||||
|
||||
else if(((istype(I, /obj/item/robot_parts/l_arm)) || (istype(I, /obj/item/robot_parts/r_arm))) && (build_step == 2))
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the robot arm to [src]!</span>"
|
||||
name = "helmet/signaler/prox sensor/robot arm assembly"
|
||||
overlays += "hs_arm"
|
||||
qdel(I)
|
||||
|
||||
else if((istype(I, /obj/item/weapon/melee/baton)) && (build_step >= 3))
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
build_step++
|
||||
user << "<span class='notice'>You complete the Securitron! Beep boop.</span>"
|
||||
var/mob/living/simple_animal/bot/secbot/S = new /mob/living/simple_animal/bot/secbot
|
||||
S.forceMove(get_turf(src))
|
||||
S.name = created_name
|
||||
qdel(I)
|
||||
qdel(src)
|
||||
|
||||
else if(istype(I, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
created_name = t
|
||||
|
||||
else if(istype(I, /obj/item/weapon/screwdriver))
|
||||
if(!build_step)
|
||||
new /obj/item/device/assembly/signaler(get_turf(src))
|
||||
new /obj/item/clothing/head/helmet(get_turf(src))
|
||||
user << "<span class='notice'>You disconnect the signaler from the helmet.</span>"
|
||||
qdel(src)
|
||||
|
||||
else if(build_step == 2)
|
||||
overlays -= "hs_eye"
|
||||
new /obj/item/device/assembly/prox_sensor(get_turf(src))
|
||||
user << "<span class='notice'>You detach the proximity sensor from [src].</span>"
|
||||
build_step--
|
||||
|
||||
else if(build_step == 3)
|
||||
overlays -= "hs_arm"
|
||||
new /obj/item/robot_parts/l_arm(get_turf(src))
|
||||
user << "<span class='notice'>You remove the robot arm from [src].</span>"
|
||||
build_step--
|
||||
@@ -0,0 +1,569 @@
|
||||
/mob/living/simple_animal/bot/ed209
|
||||
name = "\improper ED-209 Security Robot"
|
||||
desc = "A security robot. He looks less than thrilled."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "ed2090"
|
||||
density = 1
|
||||
anchored = 0
|
||||
health = 100
|
||||
maxHealth = 100
|
||||
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
|
||||
environment_smash = 2 //Walls can't stop THE LAW
|
||||
|
||||
radio_channel = "Security"
|
||||
bot_type = SEC_BOT
|
||||
bot_filter = RADIO_SECBOT
|
||||
model = "ED-209"
|
||||
bot_purpose = "seek out criminals, handcuff them, and report their location to security"
|
||||
bot_core = /obj/machinery/bot_core/secbot
|
||||
window_id = "autoed209"
|
||||
window_name = "Automatic Security Unit v2.6"
|
||||
|
||||
var/lastfired = 0
|
||||
var/shot_delay = 3 //.3 seconds between shots
|
||||
var/lasercolor = ""
|
||||
var/disabled = 0//A holder for if it needs to be disabled, if true it will not seach for targets, shoot at targets, or move, currently only used for lasertag
|
||||
|
||||
|
||||
var/mob/living/carbon/target
|
||||
var/oldtarget_name
|
||||
var/threatlevel = 0
|
||||
var/target_lastloc //Loc of target when arrested.
|
||||
var/last_found //There's a delay
|
||||
var/declare_arrests = 1 //When making an arrest, should it notify everyone wearing sechuds?
|
||||
var/idcheck = 1 //If true, arrest people with no IDs
|
||||
var/weaponscheck = 1 //If true, arrest people for weapons if they don't have access
|
||||
var/check_records = 1 //Does it check security records?
|
||||
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'
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/New(loc,created_name,created_lasercolor)
|
||||
..()
|
||||
if(created_name)
|
||||
name = created_name
|
||||
if(created_lasercolor)
|
||||
lasercolor = created_lasercolor
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
set_weapon() //giving it the right projectile and firing sound.
|
||||
spawn(3)
|
||||
var/datum/job/detective/J = new/datum/job/detective
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
|
||||
if(lasercolor)
|
||||
shot_delay = 6//Longer shot delay because JESUS CHRIST
|
||||
check_records = 0//Don't actively target people set to arrest
|
||||
arrest_type = 1//Don't even try to cuff
|
||||
bot_core.req_access = list(access_maint_tunnels, access_theatre)
|
||||
arrest_type = 1
|
||||
if((lasercolor == "b") && (name == "\improper ED-209 Security Robot"))//Picks a name if there isn't already a custome one
|
||||
name = pick("BLUE BALLER","SANIC","BLUE KILLDEATH MURDERBOT")
|
||||
if((lasercolor == "r") && (name == "\improper ED-209 Security Robot"))
|
||||
name = pick("RED RAMPAGE","RED ROVER","RED KILLDEATH MURDERBOT")
|
||||
|
||||
//SECHUD
|
||||
var/datum/atom_hud/secsensor = huds[DATA_HUD_SECURITY_ADVANCED]
|
||||
secsensor.add_hud_to(src)
|
||||
permanent_huds |= secsensor
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/turn_on()
|
||||
. = ..()
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
mode = BOT_IDLE
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/turn_off()
|
||||
..()
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/bot_reset()
|
||||
..()
|
||||
target = null
|
||||
oldtarget_name = null
|
||||
anchored = 0
|
||||
walk_to(src,0)
|
||||
last_found = world.time
|
||||
set_weapon()
|
||||
|
||||
/mob/living/simple_animal/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!"
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += text({"
|
||||
<TT><B>Security Unit v2.6 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]<BR>"},
|
||||
|
||||
"<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>" )
|
||||
|
||||
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
|
||||
if(!lasercolor)
|
||||
dat += text({"<BR>
|
||||
Arrest Unidentifiable Persons: []<BR>
|
||||
Arrest for Unauthorized Weapons: []<BR>
|
||||
Arrest for Warrant: []<BR>
|
||||
<BR>
|
||||
Operating Mode: []<BR>
|
||||
Report Arrests[]<BR>
|
||||
Auto Patrol[]"},
|
||||
|
||||
"<A href='?src=\ref[src];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
|
||||
"<A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
|
||||
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/Topic(href, href_list)
|
||||
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(..())
|
||||
return 1
|
||||
|
||||
switch(href_list["operation"])
|
||||
if("idcheck")
|
||||
idcheck = !idcheck
|
||||
update_controls()
|
||||
if("weaponscheck")
|
||||
weaponscheck = !weaponscheck
|
||||
update_controls()
|
||||
if("ignorerec")
|
||||
check_records = !check_records
|
||||
update_controls()
|
||||
if("switchmode")
|
||||
arrest_type = !arrest_type
|
||||
update_controls()
|
||||
if("declarearrests")
|
||||
declare_arrests = !declare_arrests
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/retaliate(mob/living/carbon/human/H)
|
||||
threatlevel = H.assess_threat(src)
|
||||
threatlevel += 6
|
||||
if(threatlevel >= 4)
|
||||
target = H
|
||||
mode = BOT_HUNT
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/attack_hand(mob/living/carbon/human/H)
|
||||
if(H.a_intent == "harm")
|
||||
retaliate(H)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/attackby(obj/item/weapon/W, mob/user, params)
|
||||
..()
|
||||
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) && (!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.
|
||||
retaliate(user)
|
||||
if(lasercolor)//To make up for the fact that lasertag bots don't hunt
|
||||
shootAt(user)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
user << "<span class='warning'>You short out [src]'s target assessment circuits.</span>"
|
||||
oldtarget_name = user.name
|
||||
audible_message("<span class='danger'>[src] buzzes oddly!</span>")
|
||||
declare_arrests = 0
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
set_weapon()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/bullet_act(obj/item/projectile/Proj)
|
||||
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
|
||||
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
|
||||
if(!Proj.nodamage && Proj.damage < src.health)
|
||||
retaliate(Proj.firer)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
|
||||
if(disabled)
|
||||
return
|
||||
|
||||
var/list/targets = list()
|
||||
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)
|
||||
//speak(C.real_name + text(": threat: []", threatlevel))
|
||||
if(threatlevel < 4)
|
||||
continue
|
||||
|
||||
var/dst = get_dist(src, C)
|
||||
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.
|
||||
shootAt(t)
|
||||
switch(mode)
|
||||
|
||||
if(BOT_IDLE) // idle
|
||||
walk_to(src,0)
|
||||
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 = BOT_START_PATROL // switch to patrol mode
|
||||
|
||||
if(BOT_HUNT) // hunting for perp
|
||||
// if can't reach perp for long enough, go idle
|
||||
if(frustration >= 8)
|
||||
walk_to(src,0)
|
||||
back_to_idle()
|
||||
|
||||
if(target) // make sure target exists
|
||||
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
|
||||
stun_attack(target)
|
||||
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = 1
|
||||
target_lastloc = target.loc
|
||||
return
|
||||
|
||||
else // not next to perp
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
walk_to(src, target,1,4)
|
||||
if((get_dist(src, target)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
frustration = 0
|
||||
else
|
||||
back_to_idle()
|
||||
|
||||
if(BOT_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(!Adjacent(target) || !isturf(target.loc) || target.weakened < 2)
|
||||
back_to_hunt()
|
||||
return
|
||||
|
||||
if(iscarbon(target) && target.canBeHandcuffed())
|
||||
if(!arrest_type)
|
||||
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
|
||||
cuff(target)
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(BOT_ARREST)
|
||||
if(!target)
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
return
|
||||
|
||||
if(target.handcuffed) //no target or target cuffed? back to idle.
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
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()
|
||||
|
||||
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/back_to_idle()
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
spawn(0)
|
||||
handle_automated_action() //ensure bot quickly responds
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/back_to_hunt()
|
||||
anchored = 0
|
||||
frustration = 0
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
handle_automated_action() //ensure bot quickly responds
|
||||
|
||||
// look for a criminal in view of the bot
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/look_for_perp()
|
||||
if(disabled)
|
||||
return
|
||||
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 == oldtarget_name) && (world.time < last_found + 100))
|
||||
continue
|
||||
|
||||
threatlevel = C.assess_threat(src, lasercolor)
|
||||
|
||||
if(!threatlevel)
|
||||
continue
|
||||
|
||||
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("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
handle_automated_action() // ensure bot quickly responds to a perp
|
||||
break
|
||||
else
|
||||
continue
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/check_for_weapons(var/obj/item/slot_item)
|
||||
if(slot_item && slot_item.needs_permit)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/explode()
|
||||
walk_to(src,0)
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
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 = name
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
if(!lasercolor)
|
||||
var/obj/item/weapon/gun/energy/advtaser/G = new /obj/item/weapon/gun/energy/advtaser(Tsec)
|
||||
G.power_supply.charge = 0
|
||||
G.update_icon()
|
||||
else if(lasercolor == "b")
|
||||
var/obj/item/weapon/gun/energy/laser/bluetag/G = new /obj/item/weapon/gun/energy/laser/bluetag(Tsec)
|
||||
G.power_supply.charge = 0
|
||||
G.update_icon()
|
||||
else if(lasercolor == "r")
|
||||
var/obj/item/weapon/gun/energy/laser/redtag/G = new /obj/item/weapon/gun/energy/laser/redtag(Tsec)
|
||||
G.power_supply.charge = 0
|
||||
G.update_icon()
|
||||
|
||||
if(prob(50))
|
||||
new /obj/item/robot_parts/l_leg(Tsec)
|
||||
if(prob(25))
|
||||
new /obj/item/robot_parts/r_leg(Tsec)
|
||||
if(prob(25))//50% chance for a helmet OR vest
|
||||
if(prob(50))
|
||||
new /obj/item/clothing/head/helmet(Tsec)
|
||||
else
|
||||
if(!lasercolor)
|
||||
new /obj/item/clothing/suit/armor/vest(Tsec)
|
||||
if(lasercolor == "b")
|
||||
new /obj/item/clothing/suit/bluetag(Tsec)
|
||||
if(lasercolor == "r")
|
||||
new /obj/item/clothing/suit/redtag(Tsec)
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(loc)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/set_weapon() //used to update the projectile type and firing sound
|
||||
shoot_sound = 'sound/weapons/laser.ogg'
|
||||
if(emagged == 2)
|
||||
if(lasercolor)
|
||||
projectile = /obj/item/projectile/lasertag
|
||||
else
|
||||
projectile = /obj/item/projectile/beam
|
||||
else
|
||||
if(!lasercolor)
|
||||
shoot_sound = 'sound/weapons/Taser.ogg'
|
||||
projectile = /obj/item/projectile/energy/electrode
|
||||
else if(lasercolor == "b")
|
||||
projectile = /obj/item/projectile/lasertag/blue
|
||||
else if(lasercolor == "r")
|
||||
projectile = /obj/item/projectile/lasertag/red
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/shootAt(mob/target)
|
||||
if(lastfired && world.time - lastfired < shot_delay)
|
||||
return
|
||||
lastfired = world.time
|
||||
var/turf/T = loc
|
||||
var/atom/U = (istype(target, /atom/movable) ? target.loc : target)
|
||||
if((!( U ) || !( T )))
|
||||
return
|
||||
while(!(istype(U, /turf)))
|
||||
U = U.loc
|
||||
if(!(istype(T, /turf)))
|
||||
return
|
||||
|
||||
if(!projectile)
|
||||
return
|
||||
|
||||
if(!(istype(U, /turf)))
|
||||
return
|
||||
var/obj/item/projectile/A = new projectile(loc)
|
||||
playsound(loc, shoot_sound, 50, 1)
|
||||
A.current = U
|
||||
A.yo = U.y - T.y
|
||||
A.xo = U.x - T.x
|
||||
spawn(0)
|
||||
A.process()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/attack_alien(mob/living/carbon/alien/user)
|
||||
..()
|
||||
if(!isalien(target))
|
||||
target = user
|
||||
mode = BOT_HUNT
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/emp_act(severity)
|
||||
|
||||
if(severity==2 && prob(70))
|
||||
..(severity-1)
|
||||
else
|
||||
var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( loc )
|
||||
pulse2.icon = 'icons/effects/effects.dmi'
|
||||
pulse2.icon_state = "empdisable"
|
||||
pulse2.name = "emp sparks"
|
||||
pulse2.anchored = 1
|
||||
pulse2.dir = pick(cardinal)
|
||||
spawn(10)
|
||||
qdel(pulse2)
|
||||
var/list/mob/living/carbon/targets = new
|
||||
for(var/mob/living/carbon/C in view(12,src))
|
||||
if(C.stat==2)
|
||||
continue
|
||||
targets += C
|
||||
if(targets.len)
|
||||
if(prob(50))
|
||||
var/mob/toshoot = pick(targets)
|
||||
if(toshoot)
|
||||
targets-=toshoot
|
||||
if(prob(50) && emagged < 2)
|
||||
emagged = 2
|
||||
set_weapon()
|
||||
shootAt(toshoot)
|
||||
emagged = 0
|
||||
set_weapon()
|
||||
else
|
||||
shootAt(toshoot)
|
||||
else if(prob(50))
|
||||
if(targets.len)
|
||||
var/mob/toarrest = pick(targets)
|
||||
if(toarrest)
|
||||
target = toarrest
|
||||
mode = BOT_HUNT
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/bullet_act(obj/item/projectile/Proj)
|
||||
if(!disabled)
|
||||
var/lasertag_check = 0
|
||||
if((lasercolor == "b"))
|
||||
if(istype(Proj, /obj/item/projectile/lasertag/red))
|
||||
lasertag_check++
|
||||
else if((lasercolor == "r"))
|
||||
if(istype(Proj, /obj/item/projectile/lasertag/blue))
|
||||
lasertag_check++
|
||||
if(lasertag_check)
|
||||
icon_state = "[lasercolor]ed2090"
|
||||
disabled = 1
|
||||
target = null
|
||||
spawn(100)
|
||||
disabled = 0
|
||||
icon_state = "[lasercolor]ed2091"
|
||||
return 1
|
||||
else
|
||||
..(Proj)
|
||||
else
|
||||
..(Proj)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/bluetag
|
||||
lasercolor = "b"
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/redtag
|
||||
lasercolor = "r"
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/UnarmedAttack(atom/A)
|
||||
if(!on)
|
||||
return
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/C = A
|
||||
if(!C.stunned || arrest_type)
|
||||
stun_attack(A)
|
||||
else if(C.canBeHandcuffed() && !C.handcuffed)
|
||||
cuff(A)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/RangedAttack(atom/A)
|
||||
if(!on)
|
||||
return
|
||||
shootAt(A)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/stun_attack(mob/living/carbon/C)
|
||||
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
|
||||
icon_state = "[lasercolor]ed209-c"
|
||||
spawn(2)
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
var/threat = 5
|
||||
if(istype(C, /mob/living/carbon/human))
|
||||
C.stuttering = 5
|
||||
C.Stun(5)
|
||||
C.Weaken(5)
|
||||
var/mob/living/carbon/human/H = C
|
||||
threat = H.assess_threat(src)
|
||||
else
|
||||
C.Weaken(5)
|
||||
C.stuttering = 5
|
||||
C.Stun(5)
|
||||
add_logs(src,C,"stunned")
|
||||
if(declare_arrests)
|
||||
var/area/location = get_area(src)
|
||||
speak("[arrest_type ? "Detaining" : "Arresting"] level [threat] scumbag <b>[C]</b> in [location].", radio_channel)
|
||||
C.visible_message("<span class='danger'>[src] has stunned [C]!</span>",\
|
||||
"<span class='userdanger'>[src] has stunned you!</span>")
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/cuff(mob/living/carbon/C)
|
||||
mode = BOT_ARREST
|
||||
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
|
||||
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
|
||||
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
|
||||
|
||||
spawn(60)
|
||||
if( !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
|
||||
return
|
||||
if(!C.handcuffed)
|
||||
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.update_inv_handcuffed(1)
|
||||
back_to_idle()
|
||||
@@ -0,0 +1,119 @@
|
||||
/mob/living/simple_animal/bot/emote(var/act, var/m_type=1, var/message = null)
|
||||
var/param = null
|
||||
if (findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
|
||||
act = copytext(act,1,length(act))
|
||||
|
||||
//Emote Cooldown System (it's so simple!)
|
||||
// proc/handle_emote_CD() located in [code\modules\mob\emote.dm]
|
||||
var/on_CD = 0
|
||||
switch(act)
|
||||
//Cooldown-inducing emotes
|
||||
if("scream", "screams")
|
||||
on_CD = handle_emote_CD(50) //longer cooldown
|
||||
if("ping","buzz","beep","yes","no") //halt is exempt because it's used to stop criminal scum //WHOEVER THOUGHT THAT WAS A GOOD IDEA IS GOING TO GET SHOT.
|
||||
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
|
||||
//Everything else, including typos of the above emotes
|
||||
else
|
||||
on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown
|
||||
|
||||
if(on_CD == 1) // Check if we need to suppress the emote attempt.
|
||||
return // Suppress emote, you're still cooling off.
|
||||
//--FalseIncarnate
|
||||
|
||||
switch(act)
|
||||
if("ping")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<B>[src]</B> pings at [param]."
|
||||
else
|
||||
message = "<B>[src]</B> pings."
|
||||
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("buzz")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<B>[src]</B> buzzes at [param]."
|
||||
else
|
||||
message = "<B>[src]</B> buzzes."
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("beep")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<B>[src]</B> beeps at [param]."
|
||||
else
|
||||
message = "<B>[src]</B> beeps."
|
||||
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("yes")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<B>[src]</B> emits an affirmative blip at [param]."
|
||||
else
|
||||
message = "<B>[src]</B> emits an affirmative blip."
|
||||
playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("no")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<B>[src]</B> emits a negative blip at [param]."
|
||||
else
|
||||
message = "<B>[src]</B> emits a negative blip."
|
||||
playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("scream", "screams")
|
||||
message = "<B>[src]</B> screams!"
|
||||
playsound(src.loc, 'sound/goonstation/voice/robot_scream.ogg', 80, 0)
|
||||
m_type = 2
|
||||
|
||||
..(act, m_type, message)
|
||||
+425
-538
@@ -1,538 +1,425 @@
|
||||
//Floorbot assemblies
|
||||
/obj/item/weapon/toolbox_tiles
|
||||
desc = "It's a toolbox with tiles sticking out the top"
|
||||
name = "tiles and toolbox"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "toolbox_tiles"
|
||||
force = 3.0
|
||||
throwforce = 10.0
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = 3.0
|
||||
var/created_name = "Floorbot"
|
||||
|
||||
/obj/item/weapon/toolbox_tiles_sensor
|
||||
desc = "It's a toolbox with tiles sticking out the top and a sensor attached"
|
||||
name = "tiles, toolbox and sensor arrangement"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "toolbox_tiles_sensor"
|
||||
force = 3.0
|
||||
throwforce = 10.0
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = 3.0
|
||||
var/created_name = "Floorbot"
|
||||
|
||||
//Floorbot
|
||||
/obj/machinery/bot/floorbot
|
||||
name = "\improper Floorbot"
|
||||
desc = "A little floor repairing robot, he looks so excited!"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "floorbot0"
|
||||
layer = 5.0
|
||||
density = 0
|
||||
anchored = 0
|
||||
health = 25
|
||||
maxhealth = 25
|
||||
//weight = 1.0E7
|
||||
var/amount = 10
|
||||
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_one_access = list(access_construction, access_robotics)
|
||||
var/targetdirection
|
||||
radio_name = "Engineering"
|
||||
bot_type = FLOOR_BOT
|
||||
bot_type_name = "Floorbot"
|
||||
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()
|
||||
..()
|
||||
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()
|
||||
. = ..()
|
||||
updateicon()
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/bot/floorbot/turn_off()
|
||||
..()
|
||||
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)
|
||||
. = ..()
|
||||
if (.)
|
||||
return
|
||||
usr.set_machine(src)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/bot/floorbot/interact(mob/user as mob)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += "<TT><B>Floor Repairer Controls v1.1</B></TT><BR><BR>"
|
||||
dat += "Status: <A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A><BR>"
|
||||
dat += "Maintenance panel panel is [open ? "opened" : "closed"]<BR>"
|
||||
dat += "Tiles left: [amount]<BR>"
|
||||
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
|
||||
if(!locked || issilicon(user))
|
||||
dat += "Add tiles to new hull plating: <A href='?src=\ref[src];operation=autotile'>[autotile ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Replace floor tiles: <A href='?src=\ref[src];operation=replace'>[replacetiles ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Finds tiles: <A href='?src=\ref[src];operation=tiles'>[eattiles ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Make pieces of metal into tiles when empty: <A href='?src=\ref[src];operation=make'>[maketiles ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Transmit notice when empty: <A href='?src=\ref[src];operation=emptynag'>[nag_on_empty ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Repair damaged tiles and platings: <A href='?src=\ref[src];operation=fix'>[fixfloors ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Traction Magnets: <A href='?src=\ref[src];operation=anchor'>[anchored ? "Engaged" : "Disengaged"]</A><BR>"
|
||||
dat += "Patrol Station: <A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A><BR>"
|
||||
var/bmode
|
||||
if (targetdirection)
|
||||
bmode = dir2text(targetdirection)
|
||||
else
|
||||
bmode = "disabled"
|
||||
dat += "Bridge Mode : <A href='?src=\ref[src];operation=bridgemode'>[bmode]</A><BR>"
|
||||
|
||||
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, params)
|
||||
if(istype(W, /obj/item/stack/tile/plasteel))
|
||||
var/obj/item/stack/tile/plasteel/T = W
|
||||
if(amount >= 50)
|
||||
return
|
||||
var/loaded = min(50-amount, T.amount)
|
||||
T.use(loaded)
|
||||
amount += loaded
|
||||
if (loaded > 0)
|
||||
user << "<span class='notice'>You load [loaded] tiles into the floorbot. He now contains [amount] tiles.</span>"
|
||||
nagged = 0
|
||||
updateicon()
|
||||
else
|
||||
user << "<span class='warning'>You need at least one floor tile to put into [src]</span>"
|
||||
else if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
|
||||
if(allowed(user) && !open && !emagged)
|
||||
locked = !locked
|
||||
user << "<span class='notice'>You [locked ? "lock" : "unlock"] \the [src] behaviour controls.</span>"
|
||||
updateUsrDialog()
|
||||
else
|
||||
if(emagged)
|
||||
user << "<span class='warning'>ERROR</span>"
|
||||
if(open)
|
||||
user << "<span class='warning'>Please close the access panel before locking it.</span>"
|
||||
else
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
updateUsrDialog()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/bot/floorbot/Emag(mob/user as mob)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
user << "<span class='danger'>[src] buzzes and beeps.</span>"
|
||||
|
||||
/obj/machinery/bot/floorbot/Topic(href, href_list)
|
||||
..()
|
||||
switch(href_list["operation"])
|
||||
if("replace")
|
||||
replacetiles = !replacetiles
|
||||
if("tiles")
|
||||
eattiles = !eattiles
|
||||
if("make")
|
||||
maketiles = !maketiles
|
||||
if("fix")
|
||||
fixfloors = !fixfloors
|
||||
if("autotile")
|
||||
autotile = !autotile
|
||||
if("emptynag")
|
||||
nag_on_empty = !nag_on_empty
|
||||
if("anchor")
|
||||
anchored = !anchored
|
||||
|
||||
if("bridgemode")
|
||||
var/setdir = input("Select construction direction:") as null|anything in list("north","east","south","west","disable")
|
||||
switch(setdir)
|
||||
if("north")
|
||||
targetdirection = 1
|
||||
if("south")
|
||||
targetdirection = 2
|
||||
if("east")
|
||||
targetdirection = 4
|
||||
if("west")
|
||||
targetdirection = 8
|
||||
if("disable")
|
||||
targetdirection = null
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/bot/floorbot/bot_process()
|
||||
if (!..())
|
||||
return
|
||||
|
||||
if(mode == BOT_REPAIRING)
|
||||
return
|
||||
|
||||
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!")
|
||||
|
||||
//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))
|
||||
target = T
|
||||
|
||||
else //Find a space tile farther way!
|
||||
target = scan(/turf/space, oldtarget)
|
||||
process_type = BRIDGE_MODE
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
if(!target && fixfloors) //Repairs damaged floors and tiles.
|
||||
process_type = FIX_TILE
|
||||
target = scan(/turf/simulated/floor, oldtarget)
|
||||
|
||||
if(!target && emagged == 2) //We are emagged! Time to rip up the floors!
|
||||
process_type = TILE_EMAG
|
||||
target = scan(/turf/simulated/floor, oldtarget)
|
||||
|
||||
|
||||
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
|
||||
|
||||
if(target)
|
||||
if(path.len == 0)
|
||||
if(!istype(target, /turf/))
|
||||
var/turf/TL = get_turf(target)
|
||||
path = get_path_to(loc, TL, src, /turf/proc/Distance_cardinal, 0, 30, id=botcard, simulated_only = 0)
|
||||
else
|
||||
path = get_path_to(loc, target, src, /turf/proc/Distance_cardinal, 0, 30, id=botcard, simulated_only = 0)
|
||||
|
||||
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
|
||||
|
||||
ignore_list = list() // Reset the ignore list
|
||||
|
||||
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("<span class='danger'>[src] makes an excited booping sound.</span>")
|
||||
spawn(50)
|
||||
amount++
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
path = list()
|
||||
return
|
||||
|
||||
oldloc = loc
|
||||
|
||||
/obj/machinery/bot/floorbot/proc/nag() //Annoy everyone on the channel to refill us!
|
||||
if(!nagged)
|
||||
var/area/location = get_area(src)
|
||||
speak("Requesting refill at <b>[location]</b>!", radio_name)
|
||||
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
|
||||
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
|
||||
anchored = 1 //Prevent the floorbot being blown off-course while trying to reach a hull breach.
|
||||
if(BRIDGE_MODE) //Only space turfs in our chosen direction are considered.
|
||||
if(get_dir(src, scan_target) == targetdirection)
|
||||
result = scan_target
|
||||
anchored = 1
|
||||
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(istype(F) && (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("<span class='notice'>[targetdirection ? "[src] begins installing a bridge plating." : "[src] begins to repair the hole."] </span>")
|
||||
mode = BOT_REPAIRING
|
||||
spawn(50)
|
||||
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("<span class='notice'>[src] begins repairing the floor.</span>")
|
||||
spawn(50)
|
||||
if(mode == BOT_REPAIRING)
|
||||
F.broken = 0
|
||||
F.burnt = 0
|
||||
F.ChangeTurf(/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("<span class='notice'> [src] begins to collect tiles.</span>")
|
||||
mode = BOT_REPAIRING
|
||||
spawn(20)
|
||||
if(isnull(T))
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
return
|
||||
if(amount + T.amount > 50)
|
||||
var/i = 50 - amount
|
||||
amount += i
|
||||
T.amount -= i
|
||||
else
|
||||
amount += T.amount
|
||||
qdel(T)
|
||||
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
|
||||
visible_message("<span class='notice'> [src] begins to create tiles.</span>")
|
||||
mode = BOT_REPAIRING
|
||||
spawn(20)
|
||||
if(isnull(M))
|
||||
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
|
||||
if(M.amount > 1)
|
||||
M.amount--
|
||||
else
|
||||
qdel(M)
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
|
||||
/obj/machinery/bot/floorbot/proc/updateicon()
|
||||
if(amount > 0)
|
||||
icon_state = "floorbot[on]"
|
||||
else
|
||||
icon_state = "floorbot[on]e"
|
||||
|
||||
/obj/machinery/bot/floorbot/explode()
|
||||
on = 0
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
var/obj/item/weapon/storage/toolbox/mechanical/N = new /obj/item/weapon/storage/toolbox/mechanical(Tsec)
|
||||
N.contents = list()
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
if (prob(50))
|
||||
new /obj/item/robot_parts/l_arm(Tsec)
|
||||
|
||||
while (amount)//Dumps the tiles into the appropriate sized stacks
|
||||
if(amount >= 16)
|
||||
var/obj/item/stack/tile/plasteel/T = new (Tsec)
|
||||
T.amount = 16
|
||||
amount -= 16
|
||||
else
|
||||
var/obj/item/stack/tile/plasteel/T = new (Tsec)
|
||||
T.amount = amount
|
||||
amount = 0
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/weapon/storage/toolbox/mechanical/attackby(var/obj/item/stack/tile/plasteel/T, mob/user as mob, params)
|
||||
if(!istype(T, /obj/item/stack/tile/plasteel))
|
||||
..()
|
||||
return
|
||||
if(contents.len >= 1)
|
||||
user << "<span class='alert'>They won't fit in, as there is already stuff inside.</span>"
|
||||
return
|
||||
if(T.use(10))
|
||||
if(user.s_active)
|
||||
user.s_active.close(user)
|
||||
var/obj/item/weapon/toolbox_tiles/B = new /obj/item/weapon/toolbox_tiles
|
||||
user.put_in_hands(B)
|
||||
user << "<span class='notice'>You add the tiles into the empty toolbox. They protrude from the top.</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='alert'>You need 10 floor tiles to start building a floorbot.</span>"
|
||||
return
|
||||
|
||||
/obj/item/weapon/toolbox_tiles/attackby(var/obj/item/W, mob/user as mob, params)
|
||||
..()
|
||||
if(isprox(W))
|
||||
qdel(W)
|
||||
var/obj/item/weapon/toolbox_tiles_sensor/B = new /obj/item/weapon/toolbox_tiles_sensor()
|
||||
B.created_name = created_name
|
||||
user.put_in_hands(B)
|
||||
user << "<span class='notice'>You add the sensor to the toolbox and tiles!</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
else if (istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if (!t)
|
||||
return
|
||||
if (!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
|
||||
created_name = t
|
||||
|
||||
/obj/item/weapon/toolbox_tiles_sensor/attackby(var/obj/item/W, mob/user as mob, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm))
|
||||
qdel(W)
|
||||
var/turf/T = get_turf(user.loc)
|
||||
var/obj/machinery/bot/floorbot/A = new /obj/machinery/bot/floorbot(T)
|
||||
A.name = created_name
|
||||
user << "<span class='notice'>You add the robot arm to the odd looking toolbox assembly! Boop beep!</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
else if (istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if (!t)
|
||||
return
|
||||
if (!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
|
||||
created_name = t
|
||||
//Floorbot
|
||||
/mob/living/simple_animal/bot/floorbot
|
||||
name = "\improper Floorbot"
|
||||
desc = "A little floor repairing robot, he looks so excited!"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "floorbot0"
|
||||
density = 0
|
||||
anchored = 0
|
||||
health = 25
|
||||
maxHealth = 25
|
||||
|
||||
radio_channel = "Engineering"
|
||||
bot_type = FLOOR_BOT
|
||||
bot_filter = RADIO_FLOORBOT
|
||||
model = "Floorbot"
|
||||
bot_purpose = "seek out damaged or missing floor tiles, and repair or replace them as necessary"
|
||||
bot_core = /obj/machinery/bot_core/floorbot
|
||||
window_id = "autofloor"
|
||||
window_name = "Automatic Station Floor Repairer v1.1"
|
||||
|
||||
var/process_type //Determines what to do when process_scan() recieves a target. See process_scan() for details.
|
||||
var/targetdirection
|
||||
var/amount = 10
|
||||
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/oldloc = null
|
||||
|
||||
#define HULL_BREACH 1
|
||||
#define BRIDGE_MODE 2
|
||||
#define FIX_TILE 3
|
||||
#define AUTO_TILE 4
|
||||
#define REPLACE_TILE 5
|
||||
#define TILE_EMAG 6
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/New()
|
||||
..()
|
||||
update_icon()
|
||||
var/datum/job/engineer/J = new/datum/job/engineer
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/bot_reset()
|
||||
..()
|
||||
target = null
|
||||
oldloc = null
|
||||
ignore_list = list()
|
||||
nagged = 0
|
||||
anchored = 0
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_animal/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!"
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += "<TT><B>Floor Repairer Controls v1.1</B></TT><BR><BR>"
|
||||
dat += "Status: <A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A><BR>"
|
||||
dat += "Maintenance panel panel is [open ? "opened" : "closed"]<BR>"
|
||||
dat += "Tiles left: [amount]<BR>"
|
||||
dat += "Behvaiour controls are [locked ? "locked" : "unlocked"]<BR>"
|
||||
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
|
||||
dat += "Add tiles to new hull plating: <A href='?src=\ref[src];operation=autotile'>[autotile ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Replace floor tiles: <A href='?src=\ref[src];operation=replace'>[replacetiles ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Finds tiles: <A href='?src=\ref[src];operation=tiles'>[eattiles ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Make pieces of metal into tiles when empty: <A href='?src=\ref[src];operation=make'>[maketiles ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Transmit notice when empty: <A href='?src=\ref[src];operation=emptynag'>[nag_on_empty ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Repair damaged tiles and platings: <A href='?src=\ref[src];operation=fix'>[fixfloors ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Traction Magnets: <A href='?src=\ref[src];operation=anchor'>[anchored ? "Engaged" : "Disengaged"]</A><BR>"
|
||||
dat += "Patrol Station: <A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A><BR>"
|
||||
var/bmode
|
||||
if(targetdirection)
|
||||
bmode = dir2text(targetdirection)
|
||||
else
|
||||
bmode = "disabled"
|
||||
dat += "Bridge Mode : <A href='?src=\ref[src];operation=bridgemode'>[bmode]</A><BR>"
|
||||
|
||||
return dat
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/attackby(obj/item/W , mob/user, params)
|
||||
if(istype(W, /obj/item/stack/tile/plasteel))
|
||||
var/obj/item/stack/tile/plasteel/T = W
|
||||
if(amount >= 50)
|
||||
return
|
||||
var/loaded = min(50-amount, T.amount)
|
||||
T.use(loaded)
|
||||
amount += loaded
|
||||
if(loaded > 0)
|
||||
user << "<span class='notice'>You load [loaded] tiles into the floorbot. He now contains [amount] tiles.</span>"
|
||||
nagged = 0
|
||||
update_icon()
|
||||
else
|
||||
user << "<span class='warning'>You need at least one floor tile to put into [src]!</span>"
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
user << "<span class='danger'>[src] buzzes and beeps.</span>"
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
switch(href_list["operation"])
|
||||
if("replace")
|
||||
replacetiles = !replacetiles
|
||||
if("tiles")
|
||||
eattiles = !eattiles
|
||||
if("make")
|
||||
maketiles = !maketiles
|
||||
if("fix")
|
||||
fixfloors = !fixfloors
|
||||
if("autotile")
|
||||
autotile = !autotile
|
||||
if("emptynag")
|
||||
nag_on_empty = !nag_on_empty
|
||||
if("anchor")
|
||||
anchored = !anchored
|
||||
|
||||
if("bridgemode")
|
||||
var/setdir = input("Select construction direction:") as null|anything in list("north","east","south","west","disable")
|
||||
switch(setdir)
|
||||
if("north")
|
||||
targetdirection = 1
|
||||
if("south")
|
||||
targetdirection = 2
|
||||
if("east")
|
||||
targetdirection = 4
|
||||
if("west")
|
||||
targetdirection = 8
|
||||
if("disable")
|
||||
targetdirection = null
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
|
||||
if(mode == BOT_REPAIRING)
|
||||
return
|
||||
|
||||
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)
|
||||
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)
|
||||
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))
|
||||
audible_message("[src] makes an excited booping beeping sound!")
|
||||
|
||||
//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))
|
||||
target = T
|
||||
|
||||
else //Find a space tile farther way!
|
||||
target = scan(/turf/space)
|
||||
process_type = BRIDGE_MODE
|
||||
|
||||
if(!target)
|
||||
process_type = HULL_BREACH //Ensures the floorbot does not try to "fix" space areas or shuttle docking zones.
|
||||
target = scan(/turf/space)
|
||||
|
||||
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)
|
||||
|
||||
if(!target && fixfloors) //Repairs damaged floors and tiles.
|
||||
process_type = FIX_TILE
|
||||
target = scan(/turf/simulated/floor)
|
||||
|
||||
if(!target && emagged == 2) //We are emagged! Time to rip up the floors!
|
||||
process_type = TILE_EMAG
|
||||
target = scan(/turf/simulated/floor)
|
||||
|
||||
|
||||
if(!target)
|
||||
|
||||
if(auto_patrol)
|
||||
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
|
||||
start_patrol()
|
||||
|
||||
if(mode == BOT_PATROL)
|
||||
bot_patrol()
|
||||
|
||||
if(target)
|
||||
if(path.len == 0)
|
||||
if(!istype(target, /turf/))
|
||||
var/turf/TL = get_turf(target)
|
||||
path = get_path_to(src, TL, /turf/proc/Distance_cardinal, 0, 30, id=access_card,simulated_only = 0)
|
||||
else
|
||||
path = get_path_to(src, target, /turf/proc/Distance_cardinal, 0, 30, id=access_card,simulated_only = 0)
|
||||
|
||||
if(!bot_move(target))
|
||||
add_to_ignore(target)
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
return
|
||||
else if( !bot_move(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()
|
||||
audible_message("<span class='danger'>[src] makes an excited booping sound.</span>")
|
||||
spawn(50)
|
||||
amount ++
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
path = list()
|
||||
return
|
||||
|
||||
oldloc = loc
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/nag() //Annoy everyone on the channel to refill us!
|
||||
if(!nagged)
|
||||
speak("Requesting refill at <b>[get_area(src)]</b>!", radio_channel)
|
||||
nagged = 1
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/is_hull_breach(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
|
||||
return 1
|
||||
|
||||
//Floorbots, having several functions, need sort out special conditions here.
|
||||
/mob/living/simple_animal/bot/floorbot/process_scan(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
|
||||
anchored = 1 //Prevent the floorbot being blown off-course while trying to reach a hull breach.
|
||||
if(BRIDGE_MODE) //Only space turfs in our chosen direction are considered.
|
||||
if(get_dir(src, scan_target) == targetdirection)
|
||||
result = scan_target
|
||||
anchored = 1
|
||||
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(istype(F) && (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
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/repair(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("<span class='notice'>[targetdirection ? "[src] begins installing a bridge plating." : "[src] begins to repair the hole."] </span>")
|
||||
mode = BOT_REPAIRING
|
||||
spawn(50)
|
||||
if(mode == BOT_REPAIRING)
|
||||
if(autotile) //Build the floor and include a tile.
|
||||
target_turf.ChangeTurf(/turf/simulated/floor/plasteel)
|
||||
else //Build a hull plating without a floor tile.
|
||||
target_turf.ChangeTurf(/turf/simulated/floor/plating)
|
||||
mode = BOT_IDLE
|
||||
amount -= 1
|
||||
update_icon()
|
||||
anchored = 0
|
||||
target = null
|
||||
else
|
||||
var/turf/simulated/floor/F = target_turf
|
||||
mode = BOT_REPAIRING
|
||||
visible_message("<span class='notice'>[src] begins repairing the floor.</span>")
|
||||
spawn(50)
|
||||
if(mode == BOT_REPAIRING)
|
||||
F.broken = 0
|
||||
F.burnt = 0
|
||||
F.ChangeTurf(/turf/simulated/floor/plasteel)
|
||||
mode = BOT_IDLE
|
||||
amount -= 1
|
||||
update_icon()
|
||||
anchored = 0
|
||||
target = null
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/eattile(obj/item/stack/tile/plasteel/T)
|
||||
if(!istype(T, /obj/item/stack/tile/plasteel))
|
||||
return
|
||||
visible_message("<span class='notice'>[src] begins to collect tiles.</span>")
|
||||
mode = BOT_REPAIRING
|
||||
spawn(20)
|
||||
if(isnull(T))
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
return
|
||||
if(amount + T.amount > 50)
|
||||
var/i = 50 - amount
|
||||
amount += i
|
||||
T.amount -= i
|
||||
else
|
||||
amount += T.amount
|
||||
qdel(T)
|
||||
update_icon()
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/maketile(obj/item/stack/sheet/metal/M)
|
||||
if(!istype(M, /obj/item/stack/sheet/metal))
|
||||
return
|
||||
visible_message("<span class='notice'>[src] begins to create tiles.</span>")
|
||||
mode = BOT_REPAIRING
|
||||
spawn(20)
|
||||
if(isnull(M))
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
return
|
||||
var/obj/item/stack/tile/plasteel/T = new /obj/item/stack/tile/plasteel
|
||||
T.amount = 4
|
||||
T.forceMove(M.loc)
|
||||
if(M.amount > 1)
|
||||
M.amount--
|
||||
else
|
||||
qdel(M)
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/update_icon()
|
||||
if(amount > 0)
|
||||
icon_state = "floorbot[on]"
|
||||
else
|
||||
icon_state = "floorbot[on]e"
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/explode()
|
||||
on = 0
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
var/obj/item/weapon/storage/toolbox/mechanical/N = new /obj/item/weapon/storage/toolbox/mechanical(Tsec)
|
||||
N.contents = list()
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
if(prob(50))
|
||||
new /obj/item/robot_parts/l_arm(Tsec)
|
||||
|
||||
while(amount)//Dumps the tiles into the appropriate sized stacks
|
||||
if(amount >= 16)
|
||||
var/obj/item/stack/tile/plasteel/T = new (Tsec)
|
||||
T.amount = 16
|
||||
amount -= 16
|
||||
else
|
||||
var/obj/item/stack/tile/plasteel/T = new (Tsec)
|
||||
T.amount = amount
|
||||
amount = 0
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/floorbot
|
||||
req_one_access = list(access_construction, access_robotics)
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/UnarmedAttack(atom/A)
|
||||
if(isturf(A))
|
||||
repair(A)
|
||||
else if(istype(A,/obj/item/stack/tile/plasteel))
|
||||
eattile(A)
|
||||
else if(istype(A,/obj/item/stack/sheet/metal))
|
||||
maketile(A)
|
||||
else
|
||||
..()
|
||||
+563
-659
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,869 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
|
||||
// Mulebot - carries crates around for Quartermaster
|
||||
// Navigates via floor navbeacons
|
||||
// Remote Controlled from QM's PDA
|
||||
|
||||
#define SIGH 0
|
||||
#define ANNOYED 1
|
||||
#define DELIGHT 2
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot
|
||||
name = "\improper MULEbot"
|
||||
desc = "A Multiple Utility Load Effector bot."
|
||||
icon_state = "mulebot0"
|
||||
density = 1
|
||||
anchored = 1
|
||||
animate_movement=1
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
a_intent = "harm" //No swapping
|
||||
buckle_lying = 0
|
||||
|
||||
radio_channel = "Supply"
|
||||
|
||||
bot_type = MULE_BOT
|
||||
bot_filter = RADIO_MULEBOT
|
||||
model = "MULE"
|
||||
bot_purpose = "deliver crates and other packages between departments, as requested"
|
||||
bot_core_type = /obj/machinery/bot_core/mulebot
|
||||
|
||||
suffix = ""
|
||||
|
||||
var/global/mulebot_count = 0
|
||||
var/atom/movable/load = null
|
||||
var/mob/living/passenger = null
|
||||
var/turf/target // this is turf to navigate to (location of beacon)
|
||||
var/loaddir = 0 // this the direction to unload onto/load from
|
||||
var/home_destination = "" // tag of home beacon
|
||||
|
||||
var/reached_target = 1 //true if already reached the target
|
||||
|
||||
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
|
||||
var/bloodiness = 0
|
||||
var/currentBloodColor = "#A10808"
|
||||
var/currentDNA = null
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/New()
|
||||
..()
|
||||
wires = new /datum/wires/mulebot(src)
|
||||
var/datum/job/cargo_tech/J = new/datum/job/cargo_tech
|
||||
access_card.access = J.get_access()
|
||||
prev_access = access_card.access
|
||||
cell = new(src)
|
||||
cell.charge = 2000
|
||||
cell.maxcharge = 2000
|
||||
|
||||
mulebot_count++
|
||||
set_suffix(suffix ? suffix : "#[mulebot_count]")
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/Destroy()
|
||||
unload(0)
|
||||
if(wires)
|
||||
qdel(wires)
|
||||
wires = null
|
||||
if(cell)
|
||||
qdel(cell)
|
||||
cell = null
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/set_suffix(suffix)
|
||||
src.suffix = suffix
|
||||
if(paicard)
|
||||
bot_name = "\improper MULEbot ([suffix])"
|
||||
else
|
||||
name = "\improper MULEbot ([suffix])"
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/bot_reset()
|
||||
..()
|
||||
reached_target = 0
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
..()
|
||||
if(open)
|
||||
on = FALSE
|
||||
update_controls()
|
||||
else if(istype(I,/obj/item/weapon/stock_parts/cell) && open && !cell)
|
||||
if(!user.drop_item())
|
||||
return
|
||||
var/obj/item/weapon/stock_parts/cell/C = I
|
||||
C.forceMove(src)
|
||||
cell = C
|
||||
visible_message("[user] inserts a cell into [src].",
|
||||
"<span class='notice'>You insert the new cell into [src].</span>")
|
||||
update_controls()
|
||||
else if(istype(I, /obj/item/weapon/crowbar) && open && cell)
|
||||
cell.add_fingerprint(usr)
|
||||
cell.forceMove(loc)
|
||||
cell = null
|
||||
visible_message("[user] crowbars out the power cell from [src].",
|
||||
"<span class='notice'>You pry the powercell out of [src].</span>")
|
||||
update_controls()
|
||||
else if (istype(I, /obj/item/weapon/wrench))
|
||||
if (health < maxHealth)
|
||||
adjustBruteLoss(-25)
|
||||
updatehealth()
|
||||
user.visible_message(
|
||||
"<span class='notice'>[user] repairs [src]!</span>",
|
||||
"<span class='notice'>You repair [src]!</span>"
|
||||
)
|
||||
else
|
||||
user << "<span class='notice'>[src] does not need a repair!</span>"
|
||||
else if((istype(I, /obj/item/device/multitool) || istype(I, /obj/item/weapon/wirecutters)) && open)
|
||||
return attack_hand(user)
|
||||
else if(load && ismob(load)) // chance to knock off rider
|
||||
if(prob(1 + I.force * 2))
|
||||
unload(0)
|
||||
user.visible_message("<span class='danger'>[user] knocks [load] off [src] with \the [I]!</span>",
|
||||
"<span class='danger'>You knock [load] off [src] with \the [I]!</span>")
|
||||
else
|
||||
user << "<span class='warning'>You hit [src] with \the [I] but to no effect!</span>"
|
||||
..()
|
||||
else
|
||||
..()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/emag_act(mob/user)
|
||||
if(emagged < 1)
|
||||
emagged = 1
|
||||
if(!open)
|
||||
locked = !locked
|
||||
user << "<span class='notice'>You [locked ? "lock" : "unlock"] the [src]'s controls!</span>"
|
||||
flick("mulebot-emagged", src)
|
||||
playsound(loc, 'sound/effects/sparks1.ogg', 100, 0)
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/update_icon()
|
||||
if(open)
|
||||
icon_state="mulebot-hatch"
|
||||
else
|
||||
icon_state = "mulebot[!wires.MobAvoid()]"
|
||||
overlays.Cut()
|
||||
if(load && !ismob(load))//buckling handles the mob offsets
|
||||
load.pixel_y = initial(load.pixel_y) + 9
|
||||
if(load.layer < layer)
|
||||
load.layer = layer + 0.1
|
||||
overlays += load
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/ex_act(severity)
|
||||
unload(0)
|
||||
switch(severity)
|
||||
if(1)
|
||||
qdel(src)
|
||||
if(2)
|
||||
for(var/i = 1; i < 3; i++)
|
||||
wires.RandomCut()
|
||||
if(3)
|
||||
wires.RandomCut()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/bullet_act(obj/item/projectile/Proj)
|
||||
if(..())
|
||||
if(prob(50) && !isnull(load))
|
||||
unload(0)
|
||||
if(prob(25))
|
||||
visible_message("<span class='danger'>Something shorts out inside [src]!</span>")
|
||||
wires.RandomCut()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/Topic(href, list/href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
switch(href_list["op"])
|
||||
if("lock")
|
||||
toggle_lock(usr)
|
||||
if("power")
|
||||
if(on)
|
||||
turn_off()
|
||||
else if(cell && !open)
|
||||
if(!turn_on())
|
||||
usr << "<span class='warning'>You can't switch on [src]!</span>"
|
||||
return
|
||||
else
|
||||
return
|
||||
visible_message("[usr] switches [on ? "on" : "off"] [src].")
|
||||
if("cellremove")
|
||||
if(open && cell && !usr.get_active_hand())
|
||||
cell.updateicon()
|
||||
usr.put_in_active_hand(cell)
|
||||
cell.add_fingerprint(usr)
|
||||
cell = null
|
||||
|
||||
usr.visible_message("<span class='notice'>[usr] removes the power cell from [src].</span>", "<span class='notice'>You remove the power cell from [src].</span>")
|
||||
if("cellinsert")
|
||||
if(open && !cell)
|
||||
var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand()
|
||||
if(istype(C))
|
||||
usr.drop_item()
|
||||
cell = C
|
||||
C.forceMove(src)
|
||||
C.add_fingerprint(usr)
|
||||
|
||||
usr.visible_message("<span class='notice'>[usr] inserts a power cell into [src].</span>", "<span class='notice'>You insert the power cell into [src].</span>")
|
||||
if("stop")
|
||||
if(mode >= BOT_DELIVER)
|
||||
bot_reset()
|
||||
if("go")
|
||||
if(mode == BOT_IDLE)
|
||||
start()
|
||||
if("home")
|
||||
if(mode == BOT_IDLE || mode == BOT_DELIVER)
|
||||
start_home()
|
||||
if("destination")
|
||||
var/new_dest = input(usr, "Enter Destination:", name, destination) as null|anything in deliverybeacontags
|
||||
if(new_dest)
|
||||
set_destination(new_dest)
|
||||
if("setid")
|
||||
var/new_id = stripped_input(usr, "Enter ID:", name, suffix, MAX_NAME_LEN)
|
||||
if(new_id)
|
||||
set_suffix(new_id)
|
||||
if("sethome")
|
||||
var/new_home = input(usr, "Enter Home:", name, home_destination) as null|anything in deliverybeacontags
|
||||
if(new_home)
|
||||
home_destination = new_home
|
||||
if("unload")
|
||||
if(load && mode != BOT_HUNT)
|
||||
if(loc == target)
|
||||
unload(loaddir)
|
||||
else
|
||||
unload(0)
|
||||
if("autoret")
|
||||
auto_return = !auto_return
|
||||
if("autopick")
|
||||
auto_pickup = !auto_pickup
|
||||
if("report")
|
||||
report_delivery = !report_delivery
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/toggle_lock(var/mob/user)
|
||||
if(bot_core.allowed(user))
|
||||
locked = !locked
|
||||
update_controls()
|
||||
return 1
|
||||
else
|
||||
user << "<span class='danger'>Access denied.</span>"
|
||||
return 0
|
||||
|
||||
// TODO: remove this; PDAs currently depend on it
|
||||
/mob/living/simple_animal/bot/mulebot/get_controls(mob/user)
|
||||
var/ai = issilicon(user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += "<h3>Multiple Utility Load Effector Mk. V</h3>"
|
||||
dat += "<b>ID:</b> [suffix]<BR>"
|
||||
dat += "<b>Power:</b> [on ? "On" : "Off"]<BR>"
|
||||
|
||||
if(!open)
|
||||
dat += "<h3>Status</h3>"
|
||||
dat += "<div class='statusDisplay'>"
|
||||
switch(mode)
|
||||
if(BOT_IDLE)
|
||||
dat += "<span class='good'>Ready</span>"
|
||||
if(BOT_DELIVER)
|
||||
dat += "<span class='good'>[mode_name[BOT_DELIVER]]</span>"
|
||||
if(BOT_GO_HOME)
|
||||
dat += "<span class='good'>[mode_name[BOT_GO_HOME]]</span>"
|
||||
if(BOT_BLOCKED)
|
||||
dat += "<span class='average'>[mode_name[BOT_BLOCKED]]</span>"
|
||||
if(BOT_NAV,BOT_WAIT_FOR_NAV)
|
||||
dat += "<span class='average'>[mode_name[BOT_NAV]]</span>"
|
||||
if(BOT_NO_ROUTE)
|
||||
dat += "<span class='bad'>[mode_name[BOT_NO_ROUTE]]</span>"
|
||||
dat += "</div>"
|
||||
|
||||
dat += "<b>Current Load:</b> [load ? load.name : "<i>none</i>"]<BR>"
|
||||
dat += "<b>Destination:</b> [!destination ? "<i>none</i>" : destination]<BR>"
|
||||
dat += "<b>Power level:</b> [cell ? cell.percent() : 0]%"
|
||||
|
||||
if(locked && !ai && !check_rights(R_ADMIN, 0, user))
|
||||
dat += " <br /><div class='notice'>Controls are locked</div><A href='?src=\ref[src];op=unlock'>Unlock Controls</A>"
|
||||
else
|
||||
dat += " <br /><div class='notice'>Controls are unlocked</div><A href='?src=\ref[src];op=lock'>Lock Controls</A><BR><BR>"
|
||||
|
||||
dat += "<A href='?src=\ref[src];op=power'>Toggle Power</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=stop'>Stop</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=go'>Proceed</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=home'>Return to Home</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=destination'>Set Destination</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=setid'>Set Bot ID</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=sethome'>Set Home</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=autoret'>Toggle Auto Return Home</A> ([auto_return ? "On":"Off"])<BR>"
|
||||
dat += "<A href='?src=\ref[src];op=autopick'>Toggle Auto Pickup Crate</A> ([auto_pickup ? "On":"Off"])<BR>"
|
||||
dat += "<A href='?src=\ref[src];op=report'>Toggle Delivery Reporting</A> ([report_delivery ? "On" : "Off"])<BR>"
|
||||
if(load)
|
||||
dat += "<A href='?src=\ref[src];op=unload'>Unload Now</A><BR>"
|
||||
dat += "<div class='notice'>The maintenance hatch is closed.</div>"
|
||||
else
|
||||
if(!ai)
|
||||
dat += "<div class='notice'>The maintenance hatch is open.</div><BR>"
|
||||
dat += "<b>Power cell:</b> "
|
||||
if(cell)
|
||||
dat += "<A href='?src=\ref[src];op=cellremove'>Installed</A><BR>"
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];op=cellinsert'>Removed</A><BR>"
|
||||
|
||||
dat += wires.GetInteractWindow()
|
||||
else
|
||||
dat += "<div class='notice'>The bot is in maintenance mode and cannot be controlled.</div><BR>"
|
||||
|
||||
return dat
|
||||
|
||||
|
||||
// returns true if the bot has power
|
||||
/mob/living/simple_animal/bot/mulebot/proc/has_power()
|
||||
return !open && cell && cell.charge > 0 && wires.HasPower()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/buzz(type)
|
||||
switch(type)
|
||||
if(SIGH)
|
||||
audible_message("[src] makes a sighing buzz.", "<span class='emote'>You hear an electronic buzzing sound.</span>")
|
||||
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
if(ANNOYED)
|
||||
audible_message("[src] makes an annoyed buzzing sound.", "<span class='emote'>You hear an electronic buzzing sound.</span>")
|
||||
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
if(DELIGHT)
|
||||
audible_message("[src] makes a delighted ping!", "<span class='emote'>You hear a ping.</span>")
|
||||
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
|
||||
|
||||
// mousedrop a crate to load the bot
|
||||
// can load anything if hacked
|
||||
/mob/living/simple_animal/bot/mulebot/MouseDrop_T(atom/movable/AM, mob/user)
|
||||
|
||||
if(user.incapacitated() || user.lying || get_dist(user, src) > 1)
|
||||
return
|
||||
|
||||
if(!istype(AM))
|
||||
return
|
||||
|
||||
load(AM)
|
||||
|
||||
// called to load a crate
|
||||
/mob/living/simple_animal/bot/mulebot/proc/load(atom/movable/AM)
|
||||
if(!on || load || AM.anchored || get_dist(src, AM) > 1)
|
||||
return
|
||||
|
||||
|
||||
//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.
|
||||
//So this is a simple fix that only allows a selection of item types to be considered. Further narrowing-down is below.
|
||||
if(!istype(AM, /obj/item) && !istype(AM, /obj/machinery) && !istype(AM, /obj/structure) && !ismob(AM))
|
||||
return
|
||||
if(!isturf(AM.loc)) //To prevent the loading from stuff from someone's inventory or screen icons.
|
||||
return
|
||||
|
||||
var/obj/structure/closet/crate/CRATE
|
||||
if(istype(AM,/obj/structure/closet/crate))
|
||||
CRATE = AM
|
||||
else
|
||||
if(wires.LoadCheck())
|
||||
buzz(SIGH)
|
||||
return // if not hacked, only allow crates to be loaded
|
||||
|
||||
if(CRATE) // if it's a crate, close before loading
|
||||
CRATE.close()
|
||||
|
||||
if(isobj(AM))
|
||||
var/obj/O = AM
|
||||
if(O.buckled_mob || (locate(/mob) in AM)) //can't load non crates objects with mobs buckled to it or inside it.
|
||||
buzz(SIGH)
|
||||
return
|
||||
|
||||
if(isliving(AM))
|
||||
if(!load_mob(AM))
|
||||
return
|
||||
else
|
||||
AM.forceMove(src)
|
||||
|
||||
load = AM
|
||||
mode = BOT_IDLE
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/load_mob(mob/living/M)
|
||||
can_buckle = TRUE
|
||||
if(buckle_mob(M))
|
||||
passenger = M
|
||||
load = M
|
||||
can_buckle = FALSE
|
||||
if(M.client)
|
||||
M.client.perspective = EYE_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/post_buckle_mob(mob/living/M)
|
||||
if(M == buckled_mob) //post buckling
|
||||
M.pixel_y = initial(M.pixel_y) + 9
|
||||
if(M.layer < layer)
|
||||
M.layer = layer + 0.1
|
||||
|
||||
else //post unbuckling
|
||||
load = null
|
||||
M.layer = initial(M.layer)
|
||||
M.pixel_y = initial(M.pixel_y)
|
||||
|
||||
// called to unload the bot
|
||||
// argument is optional direction to unload
|
||||
// if zero, unload at bot's location
|
||||
/mob/living/simple_animal/bot/mulebot/proc/unload(dirn)
|
||||
if(!load)
|
||||
return
|
||||
|
||||
mode = BOT_IDLE
|
||||
|
||||
overlays.Cut()
|
||||
|
||||
if(ismob(load))
|
||||
var/mob/M = load
|
||||
if(M.client)
|
||||
M.client.perspective = MOB_PERSPECTIVE
|
||||
M.client.eye = M
|
||||
unbuckle_mob()
|
||||
|
||||
if(load)
|
||||
load.forceMove(loc)
|
||||
load.pixel_y = initial(load.pixel_y)
|
||||
load.layer = initial(load.layer)
|
||||
if(dirn)
|
||||
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)
|
||||
load = null
|
||||
|
||||
// in case non-load items end up in contents, dump every else too
|
||||
// this seems to happen sometimes due to race conditions
|
||||
// with items dropping as mobs are loaded
|
||||
|
||||
for(var/atom/movable/AM in src)
|
||||
if(AM == cell || AM == access_card || AM == Radio || AM == bot_core || AM == paicard)
|
||||
continue
|
||||
|
||||
AM.forceMove(loc)
|
||||
AM.layer = initial(AM.layer)
|
||||
AM.pixel_y = initial(AM.pixel_y)
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(M.client)
|
||||
M.client.perspective = MOB_PERSPECTIVE
|
||||
M.client.eye = M
|
||||
|
||||
/mob/living/simple_animal/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()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/handle_automated_action()
|
||||
diag_hud_set_botmode()
|
||||
|
||||
if(!has_power())
|
||||
on = 0
|
||||
return
|
||||
if(on)
|
||||
var/speed = (wires.Motor1() ? 1 : 0) + (wires.Motor2() ? 2 : 0)
|
||||
//world << "speed: [speed]"
|
||||
var/num_steps = 0
|
||||
switch(speed)
|
||||
if(0)
|
||||
// do nothing
|
||||
if(1)
|
||||
num_steps = 10
|
||||
if(2)
|
||||
num_steps = 5
|
||||
if(3)
|
||||
num_steps = 3
|
||||
|
||||
if(num_steps)
|
||||
process_bot()
|
||||
num_steps--
|
||||
if(mode != BOT_IDLE)
|
||||
spawn(0)
|
||||
for(var/i=num_steps,i>0,i--)
|
||||
sleep(2)
|
||||
process_bot()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/process_bot()
|
||||
if(!on)
|
||||
return
|
||||
update_icon()
|
||||
|
||||
switch(mode)
|
||||
if(BOT_IDLE) // idle
|
||||
return
|
||||
|
||||
if(BOT_DELIVER, BOT_GO_HOME, BOT_BLOCKED) // navigating to deliver,home, or blocked
|
||||
if(loc == target) // reached target
|
||||
at_target()
|
||||
return
|
||||
|
||||
else if(path.len > 0 && target) // valid path
|
||||
var/turf/next = path[1]
|
||||
reached_target = 0
|
||||
if(next == loc)
|
||||
path -= next
|
||||
return
|
||||
if(istype(next, /turf/simulated))
|
||||
//world << "at ([x],[y]) moving to ([next.x],[next.y])"
|
||||
|
||||
var/oldloc = loc
|
||||
var/moved = step_towards(src, next) // attempt to move
|
||||
if(cell) cell.use(1)
|
||||
if(moved && oldloc!=loc) // successful move
|
||||
//world << "Successful move."
|
||||
blockcount = 0
|
||||
path -= loc
|
||||
|
||||
if(destination == home_destination)
|
||||
mode = BOT_GO_HOME
|
||||
else
|
||||
mode = BOT_DELIVER
|
||||
|
||||
else // failed to move
|
||||
|
||||
//world << "Unable to move."
|
||||
blockcount++
|
||||
mode = BOT_BLOCKED
|
||||
if(blockcount == 3)
|
||||
buzz(ANNOYED)
|
||||
|
||||
if(blockcount > 10) // attempt 10 times before recomputing
|
||||
// find new path excluding blocked turf
|
||||
buzz(SIGH)
|
||||
mode = BOT_WAIT_FOR_NAV
|
||||
blockcount = 0
|
||||
spawn(20)
|
||||
calc_path(avoid=next)
|
||||
if(path.len > 0)
|
||||
buzz(DELIGHT)
|
||||
mode = BOT_BLOCKED
|
||||
return
|
||||
return
|
||||
else
|
||||
buzz(ANNOYED)
|
||||
//world << "Bad turf."
|
||||
mode = BOT_NAV
|
||||
return
|
||||
else
|
||||
//world << "No path."
|
||||
mode = BOT_NAV
|
||||
return
|
||||
|
||||
if(BOT_NAV) // calculate new path
|
||||
//world << "Calc new path."
|
||||
mode = BOT_WAIT_FOR_NAV
|
||||
spawn(0)
|
||||
calc_path()
|
||||
|
||||
if(path.len > 0)
|
||||
blockcount = 0
|
||||
mode = BOT_BLOCKED
|
||||
buzz(DELIGHT)
|
||||
|
||||
else
|
||||
buzz(SIGH)
|
||||
|
||||
mode = BOT_NO_ROUTE
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/Move(turf/simulated/next)
|
||||
var/turf/simulated/last = loc
|
||||
|
||||
if(istype(last) && bloodiness)
|
||||
last.AddTracks(/obj/effect/decal/cleanable/blood/tracks/wheels, currentDNA, 0, get_dir(last, next), currentBloodColor)
|
||||
|
||||
. = ..()
|
||||
|
||||
if(. && istype(next) && bloodiness)
|
||||
next.AddTracks(/obj/effect/decal/cleanable/blood/tracks/wheels, currentDNA, get_dir(last, next), 0, currentBloodColor)
|
||||
bloodiness--
|
||||
|
||||
// calculates a path to the current destination
|
||||
// given an optional turf to avoid
|
||||
/mob/living/simple_animal/bot/mulebot/calc_path(turf/avoid = null)
|
||||
check_bot_access()
|
||||
path = get_path_to(src, target, /turf/proc/Distance_cardinal, 0, 250, id=access_card, exclude=avoid)
|
||||
|
||||
// sets the current destination
|
||||
// signals all beacons matching the delivery code
|
||||
// beacons will return a signal giving their locations
|
||||
/mob/living/simple_animal/bot/mulebot/proc/set_destination(new_dest)
|
||||
new_destination = new_dest
|
||||
get_nav()
|
||||
|
||||
// starts bot moving to current destination
|
||||
/mob/living/simple_animal/bot/mulebot/proc/start()
|
||||
if(!on)
|
||||
return
|
||||
if(destination == home_destination)
|
||||
mode = BOT_GO_HOME
|
||||
else
|
||||
mode = BOT_DELIVER
|
||||
update_icon()
|
||||
get_nav()
|
||||
|
||||
// starts bot moving to home
|
||||
// sends a beacon query to find
|
||||
/mob/living/simple_animal/bot/mulebot/proc/start_home()
|
||||
if(!on)
|
||||
return
|
||||
spawn(0)
|
||||
set_destination(home_destination)
|
||||
mode = BOT_BLOCKED
|
||||
update_icon()
|
||||
|
||||
// called when bot reaches current target
|
||||
/mob/living/simple_animal/bot/mulebot/proc/at_target()
|
||||
if(!reached_target)
|
||||
radio_channel = "Supply" //Supply channel
|
||||
audible_message("[src] makes a chiming sound!", "<span class='emote'>You hear a chime.</span>")
|
||||
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 << "<span class='notice'>\icon[src] [src] wirelessly plays a chiming sound!</span>"
|
||||
playsound(calling_ai, 'sound/machines/chime.ogg',40, 0)
|
||||
calling_ai = null
|
||||
radio_channel = "AI Private" //Report on AI Private instead if the AI is controlling us.
|
||||
|
||||
if(load) // if loaded, unload at target
|
||||
if(report_delivery)
|
||||
speak("Destination <b>[destination]</b> reached. Unloading [load].", radio_channel)
|
||||
if(istype(load, /obj/structure/closet/crate))
|
||||
var/obj/structure/closet/crate/C = load
|
||||
C.notifyRecipient(destination)
|
||||
unload(loaddir)
|
||||
else
|
||||
// not loaded
|
||||
if(auto_pickup) // find a crate
|
||||
var/atom/movable/AM
|
||||
if(wires.LoadCheck()) // if hacked, load first unanchored thing we find
|
||||
for(var/atom/movable/A in get_step(loc, loaddir))
|
||||
if(!A.anchored)
|
||||
AM = A
|
||||
break
|
||||
else // otherwise, look for crates only
|
||||
AM = locate(/obj/structure/closet/crate) in get_step(loc,loaddir)
|
||||
if(AM && AM.Adjacent(src))
|
||||
load(AM)
|
||||
if(report_delivery)
|
||||
speak("Now loading [load] at <b>[get_area(src)]</b>.", radio_channel)
|
||||
// whatever happened, check to see if we return home
|
||||
|
||||
if(auto_return && home_destination && destination != home_destination)
|
||||
// auto return set and not at home already
|
||||
start_home()
|
||||
mode = BOT_BLOCKED
|
||||
else
|
||||
bot_reset() // otherwise go idle
|
||||
|
||||
return
|
||||
|
||||
// called when bot bumps into anything
|
||||
/mob/living/simple_animal/bot/mulebot/Bump(atom/obs)
|
||||
if(!wires.MobAvoid()) // usually just bumps, but if avoidance disabled knock over mobs
|
||||
var/mob/M = obs
|
||||
if(ismob(M))
|
||||
if(istype(M,/mob/living/silicon/robot))
|
||||
visible_message("<span class='danger'>[src] bumps into [M]!</span>")
|
||||
else
|
||||
add_logs(src, M, "knocked down")
|
||||
visible_message("<span class='danger'>[src] knocks over [M]!</span>")
|
||||
M.stop_pulling()
|
||||
M.Stun(8)
|
||||
M.Weaken(5)
|
||||
return ..()
|
||||
|
||||
// called from mob/living/carbon/human/Crossed()
|
||||
// when mulebot is in the same loc
|
||||
/mob/living/simple_animal/bot/mulebot/proc/RunOver(mob/living/carbon/human/H)
|
||||
add_logs(src, H, "run over", null, "(DAMTYPE: [uppertext(BRUTE)])")
|
||||
H.visible_message("<span class='danger'>[src] drives over [H]!</span>", \
|
||||
"<span class='userdanger'>[src] drives over you!<span>")
|
||||
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
|
||||
var/damage = rand(5,15)
|
||||
H.apply_damage(2*damage, BRUTE, "head", run_armor_check("head", "melee"))
|
||||
H.apply_damage(2*damage, BRUTE, "chest", run_armor_check("chest", "melee"))
|
||||
H.apply_damage(0.5*damage, BRUTE, "l_leg", run_armor_check("l_leg", "melee"))
|
||||
H.apply_damage(0.5*damage, BRUTE, "r_leg", run_armor_check("r_leg", "melee"))
|
||||
H.apply_damage(0.5*damage, BRUTE, "l_arm", run_armor_check("l_arm", "melee"))
|
||||
H.apply_damage(0.5*damage, BRUTE, "r_arm", run_armor_check("r_arm", "melee"))
|
||||
|
||||
var/obj/effect/decal/cleanable/blood/B = new(loc)
|
||||
B.blood_DNA = list()
|
||||
B.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type
|
||||
currentDNA = B.blood_DNA
|
||||
|
||||
bloodiness += 4
|
||||
|
||||
currentBloodColor = "#A10808"
|
||||
if(istype(H))
|
||||
var/datum/reagent/blood/bld = H.get_blood(H.vessel)
|
||||
if(bld.data["blood_colour"])
|
||||
currentBloodColor = bld.data["blood_colour"]
|
||||
return
|
||||
B.basecolor = currentBloodColor
|
||||
B.update_icon()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/bot_control_message(command, mob/user, user_turf)
|
||||
switch(command)
|
||||
if("start")
|
||||
if(load)
|
||||
src << "<span class='warning big'>DELIVER [load] TO [destination]</span>"
|
||||
else
|
||||
src << "<span class='warning big'>PICK UP DELIVERY AT [destination]</span>"
|
||||
if("unload")
|
||||
if(load)
|
||||
src << "<span class='warning big'>UNLOAD</span>"
|
||||
else
|
||||
src << "<span class='warning big'>LOAD</span>"
|
||||
if("autoret", "autopick", "target")
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/receive_signal(datum/signal/signal)
|
||||
if(!wires.RemoteRX() || ..())
|
||||
return 1
|
||||
|
||||
var/recv = signal.data["command"]
|
||||
|
||||
// process control input
|
||||
switch(recv)
|
||||
if("start")
|
||||
start()
|
||||
|
||||
if("target")
|
||||
set_destination(signal.data["destination"])
|
||||
|
||||
if("unload")
|
||||
if(client)
|
||||
return 1
|
||||
if(loc == target)
|
||||
unload(loaddir)
|
||||
else
|
||||
unload(0)
|
||||
|
||||
if("home")
|
||||
start_home()
|
||||
|
||||
if("autoret")
|
||||
auto_return = text2num(signal.data["value"])
|
||||
|
||||
if("autopick")
|
||||
auto_pickup = text2num(signal.data["value"])
|
||||
|
||||
else
|
||||
return 0
|
||||
return 1
|
||||
|
||||
// send a radio signal with multiple data key/values
|
||||
/mob/living/simple_animal/bot/mulebot/post_signal_multiple(var/freq, var/list/keyval)
|
||||
if(!wires.RemoteTX())
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
// signals bot status etc. to controller
|
||||
/mob/living/simple_animal/bot/mulebot/send_status()
|
||||
var/list/kv = list(
|
||||
"type" = MULE_BOT,
|
||||
"name" = suffix,
|
||||
"loca" = get_area(src),
|
||||
"mode" = mode,
|
||||
"powr" = (cell ? cell.percent() : 0),
|
||||
"dest" = destination,
|
||||
"home" = home_destination,
|
||||
"load" = load,
|
||||
"retn" = auto_return,
|
||||
"pick" = auto_pickup,
|
||||
)
|
||||
post_signal_multiple(control_freq, kv)
|
||||
|
||||
// player on mulebot attempted to move
|
||||
/mob/living/simple_animal/bot/mulebot/relaymove(mob/user)
|
||||
if(user.incapacitated())
|
||||
return
|
||||
if(load == user)
|
||||
unload(0)
|
||||
|
||||
|
||||
//Update navigation data. Called when commanded to deliver, return home, or a route update is needed...
|
||||
/mob/living/simple_animal/bot/mulebot/proc/get_nav()
|
||||
if(!on || !wires.BeaconRX())
|
||||
return
|
||||
|
||||
for(var/obj/machinery/navbeacon/NB in deliverybeacons)
|
||||
if(NB.location == new_destination) // if the beacon location matches the set destination
|
||||
destination = new_destination // the we will navigate there
|
||||
target = NB.loc
|
||||
var/direction = NB.dir // this will be the load/unload dir
|
||||
loaddir = direction
|
||||
update_icon()
|
||||
calc_path()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/emp_act(severity)
|
||||
if(cell)
|
||||
cell.emp_act(severity)
|
||||
if(load)
|
||||
load.emp_act(severity)
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/explode()
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
new /obj/item/stack/rods(Tsec)
|
||||
new /obj/item/stack/rods(Tsec)
|
||||
new /obj/item/stack/cable_coil/cut(Tsec)
|
||||
if(cell)
|
||||
cell.forceMove(Tsec)
|
||||
cell.update_icon()
|
||||
cell = null
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(loc)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/remove_air(amount) //To prevent riders suffocating
|
||||
if(loc)
|
||||
return loc.remove_air(amount)
|
||||
else
|
||||
return null
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/resist()
|
||||
..()
|
||||
if(load)
|
||||
unload()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/UnarmedAttack(atom/A)
|
||||
if(isturf(A) && isturf(loc) && loc.Adjacent(A) && load)
|
||||
unload(get_dir(loc, A))
|
||||
else
|
||||
..()
|
||||
|
||||
#undef SIGH
|
||||
#undef ANNOYED
|
||||
#undef DELIGHT
|
||||
|
||||
/obj/machinery/bot_core/mulebot
|
||||
req_access = list(access_cargo)
|
||||
@@ -0,0 +1,462 @@
|
||||
/mob/living/simple_animal/bot/secbot
|
||||
name = "\improper Securitron"
|
||||
desc = "A little security robot. He looks less than thrilled."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "secbot0"
|
||||
density = 0
|
||||
anchored = 0
|
||||
health = 25
|
||||
maxHealth = 25
|
||||
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
pass_flags = PASSMOB
|
||||
|
||||
radio_channel = "Security" //Security channel
|
||||
bot_type = SEC_BOT
|
||||
bot_filter = RADIO_SECBOT
|
||||
model = "Securitron"
|
||||
bot_purpose = "seek out criminals, handcuff them, and report their location to security"
|
||||
bot_core_type = /obj/machinery/bot_core/secbot
|
||||
window_id = "autosec"
|
||||
window_name = "Automatic Security Unit v1.6"
|
||||
|
||||
var/base_icon = "secbot"
|
||||
var/mob/living/carbon/target
|
||||
var/oldtarget_name
|
||||
var/threatlevel = 0
|
||||
var/target_lastloc //Loc of target when arrested.
|
||||
var/last_found //There's a delay
|
||||
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 lack access
|
||||
var/check_records = 1 //Does it check security records?
|
||||
var/arrest_type = 0 //If true, don't handcuff
|
||||
var/harmbaton = 0 //If true, beat instead of stun
|
||||
var/flashing_lights = 0 //If true, flash lights
|
||||
var/prev_flashing_lights = 0
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky
|
||||
name = "Officer Beep O'sky"
|
||||
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
|
||||
idcheck = 0
|
||||
weaponscheck = 0
|
||||
auto_patrol = 1
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky/explode()
|
||||
var/turf/Tsec = get_turf(src)
|
||||
new /obj/item/weapon/stock_parts/cell/potato(Tsec)
|
||||
var/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/S = new(Tsec)
|
||||
S.reagents.add_reagent("whiskey", 15)
|
||||
S.on_reagent_change()
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/pingsky
|
||||
name = "Officer Pingsky"
|
||||
desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment."
|
||||
radio_channel = "AI Private"
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/ofitser
|
||||
name = "Prison Ofitser"
|
||||
desc = "It's Prison Ofitser! Powered by the tears and sweat of prisoners."
|
||||
idcheck = 0
|
||||
weaponscheck = 1
|
||||
auto_patrol = 1
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/buzzsky
|
||||
name = "Officer Buzzsky"
|
||||
desc = "It's Officer Buzzsky! Rusted and falling apart, he seems less than thrilled with the crew for leaving him in his current state."
|
||||
base_icon = "rustbot"
|
||||
icon_state = "rustbot0"
|
||||
declare_arrests = 0
|
||||
arrest_type = 1
|
||||
harmbaton = 1
|
||||
emagged = 2
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/New()
|
||||
..()
|
||||
icon_state = "[base_icon][on]"
|
||||
spawn(3)
|
||||
var/datum/job/detective/J = new/datum/job/detective
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
|
||||
//SECHUD
|
||||
var/datum/atom_hud/secsensor = huds[DATA_HUD_SECURITY_ADVANCED]
|
||||
secsensor.add_hud_to(src)
|
||||
permanent_huds |= secsensor
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/turn_on()
|
||||
..()
|
||||
icon_state = "[base_icon][on]"
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/turn_off()
|
||||
..()
|
||||
icon_state = "[base_icon][on]"
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/bot_reset()
|
||||
..()
|
||||
target = null
|
||||
oldtarget_name = null
|
||||
anchored = 0
|
||||
walk_to(src,0)
|
||||
last_found = world.time
|
||||
|
||||
/mob/living/simple_animal/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!"
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += text({"
|
||||
<TT><B>Securitron v1.6 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
|
||||
"<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>" )
|
||||
|
||||
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
|
||||
dat += text({"<BR>
|
||||
Arrest Unidentifiable Persons: []<BR>
|
||||
Arrest for Unauthorized Weapons: []<BR>
|
||||
Arrest for Warrant: []<BR>
|
||||
Operating Mode: []<BR>
|
||||
Report Arrests[]<BR>
|
||||
Auto Patrol: []"},
|
||||
|
||||
"<A href='?src=\ref[src];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
|
||||
"<A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
|
||||
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
switch(href_list["operation"])
|
||||
if("idcheck")
|
||||
idcheck = !idcheck
|
||||
update_controls()
|
||||
if("weaponscheck")
|
||||
weaponscheck = !weaponscheck
|
||||
update_controls()
|
||||
if("ignorerec")
|
||||
check_records = !check_records
|
||||
update_controls()
|
||||
if("switchmode")
|
||||
arrest_type = !arrest_type
|
||||
update_controls()
|
||||
if("declarearrests")
|
||||
declare_arrests = !declare_arrests
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/H)
|
||||
threatlevel = H.assess_threat(src)
|
||||
threatlevel += 6
|
||||
if(threatlevel >= 4)
|
||||
target = H
|
||||
mode = BOT_HUNT
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/H)
|
||||
if(H.a_intent == "harm")
|
||||
retaliate(H)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/attackby(obj/item/weapon/W, mob/user, params)
|
||||
..()
|
||||
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) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
|
||||
retaliate(user)
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
user << "<span class='danger'>You short out [src]'s target assessment circuits.</span>"
|
||||
oldtarget_name = user.name
|
||||
audible_message("<span class='danger'>[src] buzzes oddly!</span>")
|
||||
declare_arrests = 0
|
||||
icon_state = "[base_icon][on]"
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/bullet_act(obj/item/projectile/Proj)
|
||||
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
|
||||
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
|
||||
if(!Proj.nodamage && Proj.damage < src.health)
|
||||
retaliate(Proj.firer)
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/A)
|
||||
if(!on)
|
||||
return
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/C = A
|
||||
if(!C.stunned || arrest_type)
|
||||
stun_attack(A)
|
||||
else if(C.canBeHandcuffed() && !C.handcuffed)
|
||||
cuff(A)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
if(I.throwforce < src.health && I.thrower && (istype(I.thrower, /mob/living/carbon/human)))
|
||||
var/mob/living/carbon/human/H = I.thrower
|
||||
retaliate(H)
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/cuff(mob/living/carbon/C)
|
||||
mode = BOT_ARREST
|
||||
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
|
||||
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
|
||||
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
|
||||
spawn(60)
|
||||
if( !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
|
||||
return
|
||||
if(!C.handcuffed)
|
||||
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.update_inv_handcuffed(1)
|
||||
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()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C)
|
||||
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
|
||||
if(harmbaton)
|
||||
playsound(loc, 'sound/weapons/genhit1.ogg', 50, 1, -1)
|
||||
icon_state = "[base_icon]-c"
|
||||
spawn(2)
|
||||
icon_state = "[base_icon][on]"
|
||||
var/threat = 5
|
||||
if(istype(C, /mob/living/carbon/human))
|
||||
C.stuttering = 5
|
||||
if(harmbaton) // Bots with harmbaton enabled become shitcurity. - Dave
|
||||
C.apply_damage(10, BRUTE)
|
||||
C.Stun(5)
|
||||
C.Weaken(5)
|
||||
var/mob/living/carbon/human/H = C
|
||||
threat = H.assess_threat(src)
|
||||
else
|
||||
C.Weaken(5)
|
||||
C.stuttering = 5
|
||||
C.Stun(5)
|
||||
add_logs(src,C,"stunned")
|
||||
if(declare_arrests)
|
||||
var/area/location = get_area(src)
|
||||
speak("[arrest_type ? "Detaining" : "Arresting"] level [threat] scumbag <b>[C]</b> in [location].", radio_channel)
|
||||
C.visible_message("<span class='danger'>[src] has [harmbaton ? "beaten" : "stunned"] [C]!</span>",\
|
||||
"<span class='userdanger'>[src] has [harmbaton ? "beaten" : "stunned"] you!</span>")
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Life()
|
||||
. = ..()
|
||||
if(flashing_lights)
|
||||
switch(light_color)
|
||||
if(LIGHT_COLOR_PURE_RED)
|
||||
light_color = LIGHT_COLOR_PURE_BLUE
|
||||
if(LIGHT_COLOR_PURE_BLUE)
|
||||
light_color = LIGHT_COLOR_PURE_RED
|
||||
update_light()
|
||||
else if(prev_flashing_lights)
|
||||
light_color = LIGHT_COLOR_PURE_RED
|
||||
update_light()
|
||||
|
||||
prev_flashing_lights = flashing_lights
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/verb/toggle_flashing_lights()
|
||||
set name = "Toggle Flashing Lights"
|
||||
set category = "Object"
|
||||
set src = usr
|
||||
|
||||
flashing_lights = !flashing_lights
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
|
||||
flashing_lights = mode == BOT_HUNT
|
||||
|
||||
switch(mode)
|
||||
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 = BOT_START_PATROL // switch to patrol mode
|
||||
|
||||
if(BOT_HUNT) // hunting for perp
|
||||
// if can't reach perp for long enough, go idle
|
||||
if(frustration >= 8)
|
||||
walk_to(src,0)
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(target) // make sure target exists
|
||||
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
|
||||
stun_attack(target)
|
||||
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = 1
|
||||
target_lastloc = target.loc
|
||||
return
|
||||
|
||||
else // not next to perp
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
walk_to(src, target,1,4)
|
||||
if((get_dist(src, target)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
frustration = 0
|
||||
else
|
||||
back_to_idle()
|
||||
|
||||
if(BOT_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( !Adjacent(target) || !isturf(target.loc) || target.weakened < 2 )
|
||||
back_to_hunt()
|
||||
return
|
||||
|
||||
if(iscarbon(target) && target.canBeHandcuffed())
|
||||
if(!arrest_type)
|
||||
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
|
||||
cuff(target)
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(BOT_ARREST)
|
||||
if(!target)
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
return
|
||||
|
||||
if(target.handcuffed) //no target or target cuffed? back to idle.
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
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()
|
||||
|
||||
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/back_to_idle()
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
spawn(0)
|
||||
handle_automated_action() //ensure bot quickly responds
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/back_to_hunt()
|
||||
anchored = 0
|
||||
frustration = 0
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
handle_automated_action() //ensure bot quickly responds
|
||||
// look for a criminal in view of the bot
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/look_for_perp()
|
||||
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 == oldtarget_name) && (world.time < last_found + 100))
|
||||
continue
|
||||
|
||||
threatlevel = C.assess_threat(src)
|
||||
|
||||
if(!threatlevel)
|
||||
continue
|
||||
|
||||
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("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
handle_automated_action() // ensure bot quickly responds to a perp
|
||||
break
|
||||
else
|
||||
continue
|
||||
/mob/living/simple_animal/bot/secbot/proc/check_for_weapons(var/obj/item/slot_item)
|
||||
if(slot_item && slot_item.needs_permit)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/explode()
|
||||
|
||||
walk_to(src,0)
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
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 = name
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
new /obj/item/weapon/melee/baton(Tsec)
|
||||
|
||||
if(prob(50))
|
||||
new /obj/item/robot_parts/l_arm(Tsec)
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(loc)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/attack_alien(var/mob/living/carbon/alien/user as mob)
|
||||
..()
|
||||
if(!isalien(target))
|
||||
target = user
|
||||
mode = BOT_HUNT
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Crossed(atom/movable/AM)
|
||||
if(ismob(AM) && target)
|
||||
var/mob/living/carbon/C = AM
|
||||
if(!istype(C) || !C || in_range(src, target))
|
||||
return
|
||||
C.visible_message("<span class='warning'>[pick( \
|
||||
"[C] dives out of [src]'s way!", \
|
||||
"[C] stumbles over [src]!", \
|
||||
"[C] jumps out of [src]'s path!", \
|
||||
"[C] trips over [src] and falls!", \
|
||||
"[C] topples over [src]!", \
|
||||
"[C] leaps out of [src]'s way!")]</span>")
|
||||
C.Weaken(2)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/secbot
|
||||
req_access = list(access_security)
|
||||
@@ -14,14 +14,7 @@
|
||||
stop_automated_movement = 1
|
||||
status_flags = CANPUSH
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
faction = list("cult")
|
||||
flying = 1
|
||||
@@ -110,7 +103,7 @@
|
||||
|
||||
/mob/living/simple_animal/construct/armoured/Life()
|
||||
weakened = 0
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/construct/armoured/bullet_act(var/obj/item/projectile/P)
|
||||
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
|
||||
|
||||
@@ -399,11 +399,11 @@
|
||||
response_disarm = "bops"
|
||||
response_harm = "kicks"
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/Ian/Life()
|
||||
/mob/living/simple_animal/pet/corgi/Ian/process_ai()
|
||||
..()
|
||||
|
||||
//Feeding, chasing food, FOOOOODDDD
|
||||
if(!stat && !resting && !buckled && (ckey == null))
|
||||
if(!resting && !buckled)
|
||||
turns_since_scan++
|
||||
if(turns_since_scan > 5)
|
||||
turns_since_scan = 0
|
||||
@@ -450,10 +450,9 @@
|
||||
if(prob(1))
|
||||
custom_emote(1, pick("dances around.","chases its tail!"))
|
||||
spawn(0)
|
||||
if (ckey == null)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
dir = i
|
||||
sleep(1)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
dir = i
|
||||
sleep(1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/meat/corgi
|
||||
name = "Corgi meat"
|
||||
@@ -563,20 +562,18 @@
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/Lisa/Life()
|
||||
/mob/living/simple_animal/pet/corgi/Lisa/process_ai()
|
||||
..()
|
||||
|
||||
make_babies()
|
||||
|
||||
if(!stat && !resting && !buckled)
|
||||
if(!resting && !buckled)
|
||||
if(prob(1))
|
||||
if (ckey == null)
|
||||
custom_emote(1, pick("dances around.","chases her tail."))
|
||||
spawn(0)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
dir = i
|
||||
sleep(1)
|
||||
|
||||
custom_emote(1, pick("dances around.","chases her tail."))
|
||||
spawn(0)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
dir = i
|
||||
sleep(1)
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/attack_hand(mob/living/carbon/human/M)
|
||||
. = ..()
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
var/mouse_color //brown, gray and white, leave blank for random
|
||||
layer = MOB_LAYER
|
||||
min_oxy = 16 //Require atleast 16kPA oxygen
|
||||
atmos_requirements = list("min_oxy" = 16, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 223 //Below -50 Degrees Celcius
|
||||
maxbodytemp = 323 //Above 50 Degrees Celcius
|
||||
universal_speak = 0
|
||||
@@ -41,14 +41,7 @@
|
||||
|
||||
/mob/living/simple_animal/mouse/Life()
|
||||
. = ..()
|
||||
|
||||
if(!ckey && stat == CONSCIOUS && prob(0.5))
|
||||
stat = UNCONSCIOUS
|
||||
icon_state = "mouse_[mouse_color]_sleep"
|
||||
wander = 0
|
||||
speak_chance = 0
|
||||
//snuffles
|
||||
else if(stat == UNCONSCIOUS)
|
||||
if(stat == UNCONSCIOUS)
|
||||
if(ckey || prob(1))
|
||||
stat = CONSCIOUS
|
||||
icon_state = "mouse_[mouse_color]"
|
||||
@@ -56,6 +49,15 @@
|
||||
else if(prob(5))
|
||||
emote("snuffles")
|
||||
|
||||
/mob/living/simple_animal/mouse/process_ai()
|
||||
..()
|
||||
|
||||
if(prob(0.5))
|
||||
stat = UNCONSCIOUS
|
||||
icon_state = "mouse_[mouse_color]_sleep"
|
||||
wander = 0
|
||||
speak_chance = 0
|
||||
|
||||
/mob/living/simple_animal/mouse/New()
|
||||
..()
|
||||
if(!mouse_color)
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
response_harm = "kicks"
|
||||
see_in_dark = 5
|
||||
|
||||
/mob/living/simple_animal/pet/pug/Life()
|
||||
/mob/living/simple_animal/pet/pug/process_ai()
|
||||
..()
|
||||
|
||||
if(!stat && !resting && !buckled)
|
||||
if(!resting && !buckled)
|
||||
if(prob(1))
|
||||
custom_emote(1, pick("chases its tail."))
|
||||
spawn(0)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/mob/living/simple_animal/spiderbot
|
||||
|
||||
min_oxy = 0
|
||||
max_tox = 0
|
||||
max_co2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 500
|
||||
|
||||
|
||||
@@ -21,14 +21,7 @@
|
||||
speak_emote = list("hisses")
|
||||
a_intent = I_HARM
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
var/dead = 0
|
||||
unsuitable_atmos_damage = 15
|
||||
faction = list("alien")
|
||||
@@ -50,14 +43,16 @@
|
||||
var/plant_cooldown = 30
|
||||
var/plants_off = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/drone/Life()
|
||||
..()
|
||||
if(!stat)
|
||||
plant_cooldown--
|
||||
if(stance==HOSTILE_STANCE_IDLE)
|
||||
if(!plants_off && prob(10) && plant_cooldown<=0)
|
||||
plant_cooldown = initial(plant_cooldown)
|
||||
SpreadPlants()
|
||||
/mob/living/simple_animal/hostile/alien/drone/process_ai()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
plant_cooldown--
|
||||
if(stance==HOSTILE_STANCE_IDLE)
|
||||
if(!plants_off && prob(10) && plant_cooldown<=0)
|
||||
plant_cooldown = initial(plant_cooldown)
|
||||
SpreadPlants()
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/sentinel
|
||||
name = "alien sentinel"
|
||||
@@ -95,18 +90,18 @@
|
||||
var/egg_cooldown = 30
|
||||
var/plant_cooldown = 30
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/queen/Life()
|
||||
/mob/living/simple_animal/hostile/alien/queen/process_ai()
|
||||
..()
|
||||
if(!stat)
|
||||
egg_cooldown--
|
||||
plant_cooldown--
|
||||
if(stance==HOSTILE_STANCE_IDLE)
|
||||
if(!plants_off && prob(10) && plant_cooldown<=0)
|
||||
plant_cooldown = initial(plant_cooldown)
|
||||
SpreadPlants()
|
||||
if(!sterile && prob(10) && egg_cooldown<=0)
|
||||
egg_cooldown = initial(egg_cooldown)
|
||||
LayEggs()
|
||||
|
||||
egg_cooldown--
|
||||
plant_cooldown--
|
||||
if(stance==HOSTILE_STANCE_IDLE)
|
||||
if(!plants_off && prob(10) && plant_cooldown<=0)
|
||||
plant_cooldown = initial(plant_cooldown)
|
||||
SpreadPlants()
|
||||
if(!sterile && prob(10) && egg_cooldown<=0)
|
||||
egg_cooldown = initial(egg_cooldown)
|
||||
LayEggs()
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/proc/SpreadPlants()
|
||||
if(!isturf(loc) || istype(loc, /turf/space))
|
||||
|
||||
@@ -23,15 +23,7 @@
|
||||
attacktext = "bites"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
|
||||
//Space carp aren't affected by atmos.
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
// break_stuff_probability = 2
|
||||
|
||||
@@ -27,14 +27,7 @@
|
||||
attack_sound = 'sound/weapons/genhit3.ogg'
|
||||
|
||||
//Space bears aren't affected by atmos.
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
var/stance_step = 0
|
||||
|
||||
@@ -56,12 +49,11 @@
|
||||
else
|
||||
icon_state = "bearfloor"
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/Life()
|
||||
/mob/living/simple_animal/hostile/bear/process_ai()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
|
||||
switch(stance)
|
||||
|
||||
if(HOSTILE_STANCE_TIRED)
|
||||
|
||||
@@ -26,14 +26,7 @@
|
||||
speak_emote = list("gnashes")
|
||||
|
||||
//Space carp aren't affected by atmos.
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 1500
|
||||
|
||||
|
||||
@@ -20,14 +20,7 @@
|
||||
attack_sound = 'sound/hallucinations/growl1.ogg'
|
||||
speak_emote = list("growls")
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
speed = 4
|
||||
|
||||
|
||||
@@ -18,14 +18,7 @@
|
||||
projectilesound = 'sound/weapons/Gunshot.ogg'
|
||||
projectiletype = /obj/item/projectile/hivebotbullet
|
||||
faction = list("hivebot")
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
speak_emote = list("states")
|
||||
|
||||
@@ -79,37 +72,36 @@
|
||||
warpbots()
|
||||
|
||||
|
||||
New()
|
||||
..()
|
||||
var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread()
|
||||
smoke.set_up(5, 0, src.loc)
|
||||
smoke.start()
|
||||
visible_message("\red <B>The [src] warps in!</B>")
|
||||
playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
|
||||
/mob/living/simple_animal/hostile/hivebot/tele/New()
|
||||
..()
|
||||
var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread()
|
||||
smoke.set_up(5, 0, src.loc)
|
||||
smoke.start()
|
||||
visible_message("\red <B>The [src] warps in!</B>")
|
||||
playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
|
||||
|
||||
warpbots()
|
||||
icon_state = "def_radar"
|
||||
visible_message("\red The [src] turns on!")
|
||||
while(bot_amt > 0)
|
||||
bot_amt--
|
||||
switch(bot_type)
|
||||
if("norm")
|
||||
var/mob/living/simple_animal/hostile/hivebot/H = new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
|
||||
H.faction = faction
|
||||
if("range")
|
||||
var/mob/living/simple_animal/hostile/hivebot/range/R = new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
|
||||
R.faction = faction
|
||||
if("rapid")
|
||||
var/mob/living/simple_animal/hostile/hivebot/rapid/F = new /mob/living/simple_animal/hostile/hivebot/rapid(get_turf(src))
|
||||
F.faction = faction
|
||||
spawn(100)
|
||||
qdel(src)
|
||||
/mob/living/simple_animal/hostile/hivebot/tele/warpbots()
|
||||
icon_state = "def_radar"
|
||||
visible_message("\red The [src] turns on!")
|
||||
while(bot_amt > 0)
|
||||
bot_amt--
|
||||
switch(bot_type)
|
||||
if("norm")
|
||||
var/mob/living/simple_animal/hostile/hivebot/H = new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
|
||||
H.faction = faction
|
||||
if("range")
|
||||
var/mob/living/simple_animal/hostile/hivebot/range/R = new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
|
||||
R.faction = faction
|
||||
if("rapid")
|
||||
var/mob/living/simple_animal/hostile/hivebot/rapid/F = new /mob/living/simple_animal/hostile/hivebot/rapid(get_turf(src))
|
||||
F.faction = faction
|
||||
spawn(100)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/tele/process_ai()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
|
||||
Life()
|
||||
..()
|
||||
if(stat == 0)
|
||||
if(prob(2))//Might be a bit low, will mess with it likely
|
||||
warpbots()
|
||||
|
||||
if(prob(2))//Might be a bit low, will mess with it likely
|
||||
warpbots()
|
||||
@@ -32,33 +32,34 @@
|
||||
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_SLEEP (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
|
||||
|
||||
/mob/living/simple_animal/hostile/Life()
|
||||
|
||||
. = ..()
|
||||
if(!.)
|
||||
walk(src, 0)
|
||||
return 0
|
||||
if(ranged)
|
||||
ranged_cooldown--
|
||||
if(client)
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/hostile/process_ai()
|
||||
..()
|
||||
if(!AICanContinue())
|
||||
return 0
|
||||
if(!stat)
|
||||
switch(stance)
|
||||
if(HOSTILE_STANCE_IDLE)
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
switch(stance)
|
||||
if(HOSTILE_STANCE_IDLE)
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
|
||||
if(HOSTILE_STANCE_ATTACK)
|
||||
MoveToTarget()
|
||||
DestroySurroundings()
|
||||
if(HOSTILE_STANCE_ATTACK)
|
||||
MoveToTarget()
|
||||
DestroySurroundings()
|
||||
|
||||
if(HOSTILE_STANCE_ATTACKING)
|
||||
AttackTarget()
|
||||
DestroySurroundings()
|
||||
if(HOSTILE_STANCE_ATTACKING)
|
||||
AttackTarget()
|
||||
DestroySurroundings()
|
||||
|
||||
if(AIShouldSleep())
|
||||
AIStatus = AI_SLEEP
|
||||
if(AIShouldSleep())
|
||||
AIStatus = AI_SLEEP
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
//////////////HOSTILE MOB TARGETTING AND AGGRESSION////////////
|
||||
|
||||
@@ -23,14 +23,7 @@
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
speak_emote = list("creaks")
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
faction = list("mimic")
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/
|
||||
vision_range = 2
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
unsuitable_atmos_damage = 15
|
||||
faction = list("mining")
|
||||
environment_smash = 2
|
||||
@@ -387,7 +380,7 @@
|
||||
anchored = 1 //Stays anchored until death as to be unpullable
|
||||
var/pre_attack = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/Life()
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/process_ai()
|
||||
..()
|
||||
handle_preattack()
|
||||
|
||||
|
||||
@@ -19,14 +19,7 @@
|
||||
attacktext = "slashes"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
min_oxy = 5
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 1
|
||||
min_co2 = 0
|
||||
max_co2 = 5
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
unsuitable_atmos_damage = 15
|
||||
speak_emote = list("yarrs")
|
||||
var/corpse = /obj/effect/landmark/mobcorpse/pirate
|
||||
|
||||
@@ -22,14 +22,7 @@
|
||||
flying = 1
|
||||
|
||||
//Spaceborn beings don't get hurt by space
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/Process_Spacemove(var/check_drift = 0)
|
||||
|
||||
@@ -23,15 +23,6 @@
|
||||
attacktext = "attacks"
|
||||
attack_sound = 'sound/items/bikehorn.ogg'
|
||||
environment_smash = 0
|
||||
|
||||
min_oxy = 5
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 1
|
||||
min_co2 = 0
|
||||
max_co2 = 5
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
minbodytemp = 270
|
||||
maxbodytemp = 370
|
||||
heat_damage_per_tick = 15 //amount of damage applied if animal's body temperature is higher than maxbodytemp
|
||||
|
||||
@@ -35,14 +35,7 @@
|
||||
var/exploding = 0
|
||||
|
||||
//Drones aren't affected by atmos.
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
var/has_loot = 1
|
||||
|
||||
@@ -17,7 +17,4 @@
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 20
|
||||
|
||||
min_oxy = 5
|
||||
max_tox = 2
|
||||
max_co2 = 5
|
||||
|
||||
atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 2, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
|
||||
|
||||
@@ -41,14 +41,7 @@
|
||||
attacktext = "grips"
|
||||
attack_sound = 'sound/hallucinations/growl1.ogg'
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
faction = list("undead") // did I mention ghost
|
||||
@@ -93,14 +86,7 @@
|
||||
attacktext = "claws"
|
||||
attack_sound = 'sound/hallucinations/growl1.ogg'
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
faction = list("undead")
|
||||
@@ -131,14 +117,7 @@
|
||||
attacktext = "claws"
|
||||
attack_sound = 'sound/hallucinations/growl1.ogg'
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
faction = list("undead")
|
||||
|
||||
@@ -21,14 +21,6 @@
|
||||
a_intent = I_HARM
|
||||
var/corpse = /obj/effect/landmark/mobcorpse/russian
|
||||
var/weapon1 = /obj/item/weapon/kitchen/knife
|
||||
min_oxy = 5
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 1
|
||||
min_co2 = 0
|
||||
max_co2 = 5
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
unsuitable_atmos_damage = 15
|
||||
faction = list("russian")
|
||||
status_flags = CANPUSH
|
||||
|
||||
@@ -26,9 +26,7 @@
|
||||
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 350
|
||||
min_oxy = 0
|
||||
max_co2 = 0
|
||||
max_tox = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
|
||||
a_intent = I_HARM //so they don't get pushed around
|
||||
|
||||
|
||||
@@ -23,14 +23,7 @@
|
||||
attacktext = "claws"
|
||||
attack_sound = 'sound/hallucinations/growl1.ogg'
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
faction = list("statue")
|
||||
@@ -76,12 +69,12 @@
|
||||
icon_state = "angel"
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/statue/Life()
|
||||
if(..())
|
||||
if(!ckey)
|
||||
spawn() //for saftey
|
||||
checkTargets()
|
||||
. = 1
|
||||
/mob/living/simple_animal/hostile/statue/process_ai()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
spawn() //for saftey
|
||||
checkTargets()
|
||||
|
||||
/mob/living/simple_animal/hostile/statue/proc/checkTargets()
|
||||
if(target)
|
||||
@@ -195,6 +188,9 @@
|
||||
. = ..()
|
||||
return . - creator
|
||||
|
||||
/mob/living/simple_animal/hostile/statue/sentience_act()
|
||||
faction -= "neutral"
|
||||
|
||||
// Statue powers
|
||||
|
||||
// Flicker lights
|
||||
|
||||
@@ -22,14 +22,6 @@
|
||||
var/corpse = /obj/effect/landmark/mobcorpse/syndicatesoldier
|
||||
var/weapon1
|
||||
var/weapon2
|
||||
min_oxy = 5
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 1
|
||||
min_co2 = 0
|
||||
max_co2 = 5
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
unsuitable_atmos_damage = 15
|
||||
faction = list("syndicate")
|
||||
status_flags = CANPUSH
|
||||
@@ -85,14 +77,7 @@
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/melee/space
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
icon_state = "syndicatemeleespace"
|
||||
icon_living = "syndicatemeleespace"
|
||||
@@ -120,14 +105,7 @@
|
||||
icon_state = "syndicaterangedpsace"
|
||||
icon_living = "syndicaterangedpsace"
|
||||
name = "Syndicate Commando"
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
corpse = /obj/effect/landmark/mobcorpse/syndicatecommando
|
||||
speed = 1
|
||||
@@ -151,14 +129,7 @@
|
||||
attacktext = "cuts"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
faction = list("syndicate")
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
flying = 1
|
||||
|
||||
|
||||
@@ -24,15 +24,7 @@
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
speak_emote = list("pines")
|
||||
|
||||
//Space carp aren't affected by atmos.
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
faction = list("hostile", "winter")
|
||||
|
||||
@@ -14,14 +14,7 @@
|
||||
icon_living = "placeholder"
|
||||
icon_dead = "placeholder"
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
melee_damage_lower = 3
|
||||
|
||||
@@ -53,12 +53,12 @@
|
||||
universal_speak = 1
|
||||
|
||||
var/parrot_state = PARROT_WANDER //Hunt for a perch when created
|
||||
var/parrot_sleep_max = 25 //The time the parrot sits while perched before looking around. Mosly a way to avoid the parrot's AI in life() being run every single tick.
|
||||
var/parrot_sleep_max = 25 //The time the parrot sits while perched before looking around. Mosly a way to avoid the parrot's AI in process_ai() being run every single tick.
|
||||
var/parrot_sleep_dur = 25 //Same as above, this is the var that physically counts down
|
||||
var/parrot_dam_zone = list("chest", "head", "l_arm", "l_leg", "r_arm", "r_leg") //For humans, select a bodypart to attack
|
||||
|
||||
var/parrot_speed = 5 //"Delay in world ticks between movement." according to byond. Yeah, that's BS but it does directly affect movement. Higher number = slower.
|
||||
var/parrot_been_shot = 0 //Parrots get a speed bonus after being shot. This will deincrement every Life() and at 0 the parrot will return to regular speed.
|
||||
var/parrot_been_shot = 0 //Parrots get a speed bonus after being shot. This will deincrement every process_ai() and at 0 the parrot will return to regular speed.
|
||||
|
||||
var/list/speech_buffer = list()
|
||||
var/list/available_channels = list()
|
||||
@@ -273,14 +273,13 @@
|
||||
|
||||
//Sprite and AI update for when a parrot gets pulled
|
||||
if(pulledby && stat == CONSCIOUS)
|
||||
icon_state = "parrot_fly"
|
||||
if(!client)
|
||||
parrot_state = PARROT_WANDER
|
||||
icon_state = "parrot_fly"
|
||||
|
||||
/mob/living/simple_animal/parrot/process_ai()
|
||||
if(pulledby)
|
||||
parrot_state = PARROT_WANDER
|
||||
return
|
||||
|
||||
if(client || stat)
|
||||
return //Lets not force players or dead/incap parrots to move
|
||||
|
||||
|
||||
if(!isturf(src.loc) || !canmove || buckled)
|
||||
return //If it can't move, dont let it move. (The buckled check probably isn't necessary thanks to canmove)
|
||||
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
attacktext = "sends rainbows of power to"
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 4000
|
||||
min_oxy = 0
|
||||
max_co2 = 0
|
||||
max_tox = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
speed = 0
|
||||
stop_automated_movement = 0
|
||||
status_flags = 0
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
attacktext = "drains the life from"
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 4000
|
||||
min_oxy = 0
|
||||
max_co2 = 0
|
||||
max_tox = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
speed = -1
|
||||
stop_automated_movement = 1
|
||||
status_flags = 0
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
var/oxygen_alert = 0
|
||||
var/toxins_alert = 0
|
||||
var/fire_alert = 0
|
||||
var/healable = 1
|
||||
|
||||
var/list/speak = list()
|
||||
var/speak_chance = 0
|
||||
@@ -43,14 +44,7 @@
|
||||
var/cold_damage_per_tick = 2 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
|
||||
|
||||
//Atmos effect - Yes, you can make creatures that require plasma or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage
|
||||
var/min_oxy = 5
|
||||
var/max_oxy = 0 //Leaving something at 0 means it's off - has no maximum
|
||||
var/min_tox = 0
|
||||
var/max_tox = 1
|
||||
var/min_co2 = 0
|
||||
var/max_co2 = 5
|
||||
var/min_n2 = 0
|
||||
var/max_n2 = 0
|
||||
var/list/atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) //Leaving something at 0 means it's off - has no maximum
|
||||
var/unsuitable_atmos_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
|
||||
|
||||
|
||||
@@ -58,7 +52,7 @@
|
||||
var/melee_damage_lower = 0
|
||||
var/melee_damage_upper = 0
|
||||
var/melee_damage_type = BRUTE //Damage type of a simple mob's melee attack, should it do damage.
|
||||
var/list/ignored_damage_types = list(BRUTE = 0, BURN = 0, TOX = 0, CLONE = 0, STAMINA = 1, OXY = 0) //Set 0 to receive that damage type, 1 to ignore
|
||||
var/list/damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) // 1 for full damage , 0 for none , -1 for 1:1 heal from that source
|
||||
var/attacktext = "attacks"
|
||||
var/attack_sound = null
|
||||
var/friendly = "nuzzles" //If the mob does no damage with it's attack
|
||||
@@ -76,10 +70,12 @@
|
||||
var/simplespecies //Sorry, no spider+corgi buttbabies.
|
||||
|
||||
var/master_commander = null //holding var for determining who own/controls a sentient simple animal (for sentience potions).
|
||||
var/sentience_type = SENTIENCE_ORGANIC // Sentience type, for slime potions
|
||||
|
||||
|
||||
/mob/living/simple_animal/New()
|
||||
..()
|
||||
simple_animal_list += src
|
||||
verbs -= /mob/verb/observe
|
||||
if(!can_hide)
|
||||
verbs -= /mob/living/simple_animal/verb/hide
|
||||
@@ -92,6 +88,7 @@
|
||||
if(collar)
|
||||
collar.forceMove(loc)
|
||||
collar = null
|
||||
simple_animal_list -= src
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/Login()
|
||||
@@ -130,16 +127,14 @@
|
||||
if(0) healths.icon_state = "health7"
|
||||
|
||||
/mob/living/simple_animal/Life()
|
||||
|
||||
if(..())
|
||||
if(!ckey)
|
||||
handle_automated_movement()
|
||||
handle_automated_action()
|
||||
handle_automated_speech()
|
||||
. = 1
|
||||
|
||||
. = ..()
|
||||
handle_state_icons()
|
||||
|
||||
/mob/living/simple_animal/proc/process_ai()
|
||||
handle_automated_movement()
|
||||
handle_automated_action()
|
||||
handle_automated_speech()
|
||||
|
||||
/mob/living/simple_animal/proc/handle_state_icons()
|
||||
if(resting && icon_resting && stat != DEAD)
|
||||
icon_state = icon_resting
|
||||
@@ -218,32 +213,32 @@
|
||||
var/n2 = environment.nitrogen
|
||||
var/co2 = environment.carbon_dioxide
|
||||
|
||||
if(min_oxy && oxy < min_oxy)
|
||||
if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
|
||||
atmos_suitable = 0
|
||||
oxygen_alert = 1
|
||||
else if(max_oxy && oxy > max_oxy)
|
||||
else if(atmos_requirements["max_oxy"] && oxy > atmos_requirements["max_oxy"])
|
||||
atmos_suitable = 0
|
||||
oxygen_alert = 1
|
||||
else
|
||||
oxygen_alert = 0
|
||||
|
||||
if(min_tox && tox < min_tox)
|
||||
if(atmos_requirements["min_tox"] && tox < atmos_requirements["min_tox"])
|
||||
atmos_suitable = 0
|
||||
toxins_alert = 1
|
||||
else if(max_tox && tox > max_tox)
|
||||
else if(atmos_requirements["max_tox"] && tox > atmos_requirements["max_tox"])
|
||||
atmos_suitable = 0
|
||||
toxins_alert = 1
|
||||
else
|
||||
toxins_alert = 0
|
||||
|
||||
if(min_n2 && n2 < min_n2)
|
||||
if(atmos_requirements["min_n2"] && n2 < atmos_requirements["min_n2"])
|
||||
atmos_suitable = 0
|
||||
else if(max_n2 && n2 > max_n2)
|
||||
else if(atmos_requirements["max_n2"] && n2 > atmos_requirements["max_n2"])
|
||||
atmos_suitable = 0
|
||||
|
||||
if(min_co2 && co2 < min_co2)
|
||||
if(atmos_requirements["min_co2"] && co2 < atmos_requirements["min_co2"])
|
||||
atmos_suitable = 0
|
||||
else if(max_co2 && co2 > max_co2)
|
||||
else if(atmos_requirements["max_co2"] && co2 > atmos_requirements["max_co2"])
|
||||
atmos_suitable = 0
|
||||
|
||||
if(!atmos_suitable)
|
||||
@@ -414,7 +409,7 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/living/user as mob) //Marker -Agouri
|
||||
if(istype(O, /obj/item/stack/medical))
|
||||
if(istype(O, /obj/item/stack/medical) && healable)
|
||||
if(stat != DEAD)
|
||||
var/obj/item/stack/medical/MED = O
|
||||
if(health < maxHealth)
|
||||
@@ -510,21 +505,29 @@
|
||||
if(3.0)
|
||||
adjustBruteLoss(30)
|
||||
|
||||
/mob/living/simple_animal/adjustBruteLoss(damage)
|
||||
if(!ignored_damage_types[BRUTE])
|
||||
..()
|
||||
/mob/living/simple_animal/adjustBruteLoss(amount)
|
||||
if(damage_coeff[BRUTE])
|
||||
return ..(amount * damage_coeff[BRUTE])
|
||||
|
||||
/mob/living/simple_animal/adjustFireLoss(damage)
|
||||
if(!ignored_damage_types[BURN])
|
||||
..(damage)
|
||||
/mob/living/simple_animal/adjustFireLoss(amount)
|
||||
if(damage_coeff[BURN])
|
||||
return ..(amount * damage_coeff[BURN])
|
||||
|
||||
/mob/living/simple_animal/adjustToxLoss(damage)
|
||||
if(!ignored_damage_types[TOX])
|
||||
..(damage)
|
||||
/mob/living/simple_animal/adjustOxyLoss(amount)
|
||||
if(damage_coeff[OXY])
|
||||
return ..(amount * damage_coeff[OXY])
|
||||
|
||||
/mob/living/simple_animal/adjustCloneLoss(damage)
|
||||
if(!ignored_damage_types[CLONE])
|
||||
..(damage)
|
||||
/mob/living/simple_animal/adjustToxLoss(amount)
|
||||
if(damage_coeff[TOX])
|
||||
return ..(amount * damage_coeff[TOX])
|
||||
|
||||
/mob/living/simple_animal/adjustCloneLoss(amount)
|
||||
if(damage_coeff[CLONE])
|
||||
return ..(amount * damage_coeff[CLONE])
|
||||
|
||||
/mob/living/simple_animal/adjustStaminaLoss(amount)
|
||||
if(damage_coeff[STAMINA])
|
||||
return ..(amount*damage_coeff[STAMINA])
|
||||
|
||||
/mob/living/simple_animal/proc/CanAttack(var/atom/the_target)
|
||||
if(see_invisible < the_target.invisibility)
|
||||
@@ -544,11 +547,10 @@
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/proc/attack_threshold_check(damage, damagetype = BRUTE)
|
||||
if(damage <= force_threshold || ignored_damage_types[damagetype])
|
||||
if(damage <= force_threshold || !damage_coeff[damagetype])
|
||||
visible_message("<span class='warning'>[src] looks unharmed from the damage.</span>")
|
||||
else
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
apply_damage(damage, damagetype)
|
||||
|
||||
|
||||
/mob/living/simple_animal/update_fire()
|
||||
@@ -699,4 +701,7 @@
|
||||
/mob/living/simple_animal/get_access()
|
||||
. = ..()
|
||||
if(collar)
|
||||
. |= collar.GetAccess()
|
||||
. |= collar.GetAccess()
|
||||
|
||||
/mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion
|
||||
return
|
||||
+1
-11
@@ -749,16 +749,6 @@ var/list/slot_equipment_priority = list( \
|
||||
namecounts[name] = 1
|
||||
creatures[name] = O
|
||||
|
||||
if(istype(O, /obj/machinery/bot))
|
||||
var/name = "BOT: [O.name]"
|
||||
if (names.Find(name))
|
||||
namecounts[name]++
|
||||
name = "[name] ([namecounts[name]])"
|
||||
else
|
||||
names.Add(name)
|
||||
namecounts[name] = 1
|
||||
creatures[name] = O
|
||||
|
||||
|
||||
for(var/mob/M in sortAtom(mob_list))
|
||||
var/name = M.name
|
||||
@@ -861,9 +851,9 @@ var/list/slot_equipment_priority = list( \
|
||||
..()
|
||||
if(M != usr) return
|
||||
if(M.small) return // Stops pAI drones and small mobs (borers, parrots, crabs) from stripping people. --DZD
|
||||
if(!M.can_strip) return
|
||||
if(usr == src) return
|
||||
if(!Adjacent(usr)) return
|
||||
if(istype(M,/mob/living/silicon/ai)) return
|
||||
show_inv(usr)
|
||||
|
||||
//this and stop_pulling really ought to be /mob/living procs
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
var/lastpuke = 0
|
||||
var/unacidable = 0
|
||||
var/small = 0
|
||||
var/can_strip = 1
|
||||
var/list/pinned = list() //List of things pinning this creature to walls (see living_defense.dm)
|
||||
var/list/embedded = list() //Embedded items, since simple mobs don't have organs.
|
||||
var/list/languages = list() // For speaking/listening.
|
||||
|
||||
@@ -94,6 +94,11 @@ proc/isembryo(A)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/isbot(A)
|
||||
if(istype(A, /mob/living/simple_animal/bot))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/isclown(A)
|
||||
if(istype(A, /mob/living/simple_animal/hostile/retaliate/clown))
|
||||
return 1
|
||||
|
||||
@@ -96,4 +96,10 @@
|
||||
if(. != STATUS_CLOSE)
|
||||
. = min(., shared_living_nano_distance(src_object))
|
||||
if(!IsAdvancedToolUser())
|
||||
. = STATUS_CLOSE
|
||||
|
||||
/mob/living/simple_animal/bot/default_can_use_topic(var/src_object)
|
||||
. = shared_nano_interaction(src_object)
|
||||
if(. != STATUS_CLOSE)
|
||||
if(!(src_object in contents))
|
||||
. = STATUS_CLOSE
|
||||
@@ -187,7 +187,7 @@ nanoui is used to open and update nano browser uis
|
||||
"showMap" = show_map,
|
||||
"mapZLevel" = map_z_level,
|
||||
"user" = list(
|
||||
"name" = user.name,
|
||||
"name" = sanitize(user.name),
|
||||
"fancy" = user.client.prefs.nanoui_fancy
|
||||
),
|
||||
"window" = list(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user