conFLICTS
@@ -372,6 +372,8 @@
|
||||
"hh" = (/turf/simulated/floor/plasteel/yellowsiding{dir = 8},/area/centcom/evac)
|
||||
"hi" = (/turf/simulated/floor/plasteel/warning{dir = 4},/area/centcom/evac)
|
||||
"hj" = (/obj/structure/cult/talisman{desc = "A altar dedicated to the Wizard's Federation"},/obj/item/weapon/kitchen/knife/ritual,/obj/item/clothing/suit/wizrobe/santa,/obj/item/clothing/head/wizard/santa,/turf/simulated/floor/plasteel/cult,/area/wizard_station)
|
||||
"hk" = (/obj/item/weapon/disk/data,/turf/simulated/floor/plating/snow,/area/syndicate_mothership)
|
||||
"hl" = (/obj/item/toy/figure/syndie,/turf/simulated/floor/plating/snow,/area/syndicate_mothership)
|
||||
"hm" = (/turf/indestructible/riveted,/area/syndicate_mothership)
|
||||
"hn" = (/obj/structure/closet/wardrobe/cargotech,/turf/simulated/floor/plasteel/loadingarea,/area/centcom/supply)
|
||||
"ho" = (/obj/structure/closet,/turf/simulated/floor/plasteel/warning/corner{dir = 1},/area/centcom/supply)
|
||||
@@ -385,11 +387,15 @@
|
||||
"hw" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/turf/simulated/floor/plasteel/red/side{dir = 2},/area/centcom/evac)
|
||||
"hx" = (/obj/structure/table/reinforced,/obj/item/toy/carpplushie,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel/red/side{dir = 6},/area/centcom/evac)
|
||||
"hy" = (/obj/structure/table/reinforced,/obj/item/weapon/pen,/turf/simulated/floor/plasteel/red/side{dir = 2},/area/centcom/evac)
|
||||
"hz" = (/turf/simulated/floor/plating/snow,/obj/structure/flora/bush,/turf/simulated/floor/plating/snow/gravsnow/corner,/area/syndicate_mothership)
|
||||
"hA" = (/turf/simulated/floor/plating/snow,/obj/structure/flora/grass/brown,/turf/simulated/floor/plating/snow/gravsnow/corner,/area/syndicate_mothership)
|
||||
"hB" = (/obj/structure/table/wood,/obj/item/toy/nuke,/turf/simulated/floor/wood,/area/syndicate_mothership)
|
||||
"hC" = (/turf/simulated/floor/plating/snow,/area/syndicate_mothership)
|
||||
"hD" = (/obj/structure/flora/grass/brown,/turf/simulated/floor/plating/snow,/area/syndicate_mothership)
|
||||
"hE" = (/obj/structure/flora/tree/pine,/turf/simulated/floor/plating/snow,/area/syndicate_mothership)
|
||||
"hF" = (/obj/structure/flora/grass/both,/turf/simulated/floor/plating/snow,/area/syndicate_mothership)
|
||||
"hG" = (/turf/indestructible/fakeglass{icon_state = "fakewindows2"; dir = 6},/area/centcom/supply)
|
||||
"hH" = (/obj/structure/cult/tome,/turf/simulated/floor/plasteel/cult,/area/wizard_station)
|
||||
"hI" = (/turf/simulated/floor/plasteel,/area/centcom/supply)
|
||||
"hJ" = (/turf/simulated/floor/plasteel/warning{dir = 8},/area/centcom/supply)
|
||||
"hK" = (/turf/simulated/floor/plasteel/green/corner{dir = 1},/area/centcom/control)
|
||||
@@ -399,12 +405,15 @@
|
||||
"hO" = (/turf/simulated/floor/plasteel/yellowsiding{dir = 1},/area/centcom/evac)
|
||||
"hP" = (/turf/simulated/floor/plasteel/yellowsiding/corner{dir = 1},/area/centcom/evac)
|
||||
"hQ" = (/obj/machinery/door/airlock/external{name = "Supply Shuttle"; req_access_txt = "106"},/turf/simulated/floor/plasteel/delivery,/area/centcom/supply)
|
||||
"hR" = (/obj/item/toy/figure/syndie,/turf/simulated/floor/plating/snow/gravsnow,/area/syndicate_mothership)
|
||||
"hS" = (/obj/machinery/door/airlock/centcom{name = "Centcom Supply"; req_access_txt = "106"},/turf/simulated/floor/plasteel/brown{dir = 4},/area/centcom/supply)
|
||||
"hT" = (/turf/simulated/floor/plasteel/brown{dir = 8},/area/centcom/control)
|
||||
"hU" = (/obj/machinery/door/airlock/centcom{name = "Centcom Docks"; opacity = 1; req_access_txt = "101"},/turf/simulated/floor/plasteel/black,/area/centcom/control)
|
||||
"hV" = (/obj/machinery/door/poddoor/preopen{id = "CentComPort"; name = "security door"},/turf/simulated/floor/plasteel/loadingarea{dir = 8},/area/centcom/control)
|
||||
"hW" = (/turf/simulated/floor/plasteel/warning{dir = 8},/area/centcom/evac)
|
||||
"hX" = (/obj/structure/statue/uranium/nuke,/turf/simulated/floor/plating/snow/gravsnow,/area/syndicate_mothership)
|
||||
"hY" = (/obj/structure/flora/bush,/turf/simulated/floor/plating/snow,/area/syndicate_mothership)
|
||||
"hZ" = (/turf/simulated/floor/plating/snow,/turf/simulated/floor/plating/snow/gravsnow/corner{tag = "icon-gravsnow_corner (NORTHWEST)"; icon_state = "gravsnow_corner"; dir = 9},/area/syndicate_mothership)
|
||||
"ia" = (/obj/machinery/computer/supplycomp,/turf/simulated/floor/plasteel/warning{dir = 8},/area/centcom/supply)
|
||||
"ib" = (/turf/simulated/floor/plasteel/green/corner{dir = 8},/area/centcom/control)
|
||||
"ic" = (/turf/simulated/floor/plasteel/warning/corner{dir = 4},/area/centcom/evac)
|
||||
@@ -614,7 +623,6 @@
|
||||
"nw" = (/turf/simulated/floor/plasteel/green/side{dir = 4},/area/tdome/arena)
|
||||
"nx" = (/obj/effect/landmark{name = "tdome1"},/turf/simulated/floor/plasteel,/area/tdome/tdome1)
|
||||
"ny" = (/obj/structure/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/sneakers/brown,/obj/item/clothing/suit/armor/tdome/green,/obj/item/clothing/head/helmet/thunderdome,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/energy/sword/saber/green,/turf/simulated/floor/plasteel/black,/area/tdome/arena)
|
||||
"nz" = (/obj/structure/cult/tome,/turf/simulated/floor/plasteel/cult,/area/wizard_station)
|
||||
"nA" = (/turf/indestructible/fakeglass{color = "#008000"; dir = 1; icon_state = "fakewindows"},/area/wizard_station)
|
||||
"nB" = (/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel/cult,/area/wizard_station)
|
||||
"nC" = (/obj/structure/closet/crate{icon_state = "crateopen"; opened = 1},/obj/item/clothing/suit/wizrobe/red,/obj/item/clothing/head/wizard/red,/obj/item/weapon/staff,/obj/item/clothing/shoes/sandal,/turf/simulated/floor/plasteel/cult,/area/wizard_station)
|
||||
@@ -796,7 +804,7 @@
|
||||
"rw" = (/obj/effect/landmark/abductor/agent{team = 2},/turf/simulated/floor/plating/abductor,/area/abductor_ship)
|
||||
"rx" = (/obj/effect/landmark/abductor/scientist{team = 3},/turf/simulated/floor/plating/abductor,/area/abductor_ship)
|
||||
"ry" = (/obj/effect/landmark/abductor/agent{team = 3},/turf/simulated/floor/plating/abductor,/area/abductor_ship)
|
||||
|
||||
|
||||
(1,1,1) = {"
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacadaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaead
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacafaiagajajakahanalapaoaqaharararararahasasasasasahatatatatatahaxauauauayam
|
||||
@@ -953,37 +961,37 @@ acacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacfYgCfYgCfYgnfYgCfYgCfYfYfYfYflgEgDgDgDgDgDhghfhhgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacfYgQgbgRgngngngngngTgSgUgUgVflgEgDgDgDgDhwhyhxhhgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBgBgBgBgBgBgBgQhcgRgngngnhdfYgCfYfYgUheflgEgDgDgDgDhOhOhOhPgDgDhigygzacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBhohnhphnhqgBgQgmgRgngngnhrgCgQfYhthshuflhvgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChDhChChChEhFhChChChEhChChChChChChEhChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacachGhJhIhIhIhIgBgCfYhKgngngnhLfYgCfYgChMgCflhNgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChDhChChChChChChChChChChChEhChChChChChEhChChChChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacachQhJhIhIhIhIhShTgngngngngngngngThUgUgUgUhVhWgDgDgDgDgDhbgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChYhChChChChChDhChChFhEhChChEhChChEhFhChEhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacachGiahIhIhIhIgBgCfYibgngngnhdfYgCfYfYfYfYflicgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChChChChChChChChChChDhChChEhFhChChEhChFhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgAhQhJhIhIhIhIgBgQgbgRgngngniggbgQfYacacacflihgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChChChChChChChDhChChChChChFhChEhFhChEhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacilhJhIhIhIhIgBgQhcgRgngngnighcgQfYacacacflingDgDgDgDidididiegDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChCisisisisisisishChChChChChChChEhChChYhFhChChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacithJhIhIhIhIgBgQgmiuibgnhdivgmgQfYacacacflingDgDgDgDiiikijhhgDgDhigFacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCgGacacacacacacacgGhChChChChYhCishDishDhChEhChEhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciJhJhIhIhIhIgBiLiLiNiMiOiNiMiLiLiLacacacflingDgDgDgDgDipiohhgDgDhigHacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCacacacacacacacacaciYhChCishmhmjaiZhmhmisjbjcishmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBjijhjjhIhIgBjljkjnjmjpjojrjqjsiLacacacfljujtjtjtjwjvjygshhgDgDhigIacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCacacacacacacacacaciYhCjChmhmjDjEjEjDhmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBgBgBgBjIgBgBjJjpjKjmjpjojKjpjLiLacacacflflflflflflflflgWgvgxixguflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajQjPjSjRaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCacacacacacacacacaciYhYjChmjXjWjWjWjWjYkajZkckbkekdhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBkfkfkfgBkgjpjKjmjpjojKjpkhiLacacacacacacacacacacacflgDgDgDgDflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaknaakpkokqjRjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCgGacacacacacacacgGhChCkuhmkvjWkwkwkxjWjWjWkzkykykyhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBkfkfkfgBkAjpjKjmjpjojKjpkBiLacacacacacacacacacacacflgDjMikiiflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaknkEkGkFkqkHjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChCacacacacackKisisiskLhmjWkwkNkMkwjWkPkOkckQkRhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBkfkfkfgBkTkSkSkUjpkVkWkWkXiLacacacacacacacacacacacflgDkiipkjflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaajRlalbkHldlcjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChCacacacacaclhlglglgiZhmjWkwljlikwjWkPlkhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBgBgBgBgBiNlliMiLjpiLiNlliMiLacacacacacacacacacacackCgDgDgDgDflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaajRjRlnlmlnjRjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChCgGacacacacacacacacaclrlqlqlqlqlsjWjWjWjWjWjWkPlkhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLltltltlujplultltltiLacacacacacacacacacacacflkYjwjwkZflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaknknjRlwlvlxjRaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacaclBlAjalgiZhmlCkwkwkwjWjWkPlDhmlElFhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLiLiLiLiLiLiLiLiOiLiLiLiLiLiLiLiLacacacacacacacacflflflflflflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaalHlGlJlIlLlKlxlMknaaaaaaaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacacacgJacgGlShmlUlTlVlTlTjWjWjWlXlWlWlYhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLlZmamamamamalZlZlZmamamamamalZiLacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaambmdmcmfmelLlxmhmgmiknknaaaaaaaaaaaaaaaaacacacacacachmmjhCacacacacacacacacacacacacacackuhmmmmlmmmmmnjWjWjWhmmomplYhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmqlZlZlZmrlZlZlZlZlZlZlZmrlZlZlZmqacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaknaalJmsmsmtlLlxmumhmiaamwmvaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacacacacacacjChmhmkOmAmzmBhmmChmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLlZmamamamamalZlZlZmamamamamalZiLacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaalMknaaaaknmDmFmEmGmElMknknaaaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacacacacacacmKlShmhmhmhmhmhmmLmLmNmMmPmOhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLiNlllllllllllllllllllllllllliMiLacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaajRjRmQjRjRjRjRjRjRmRjRjRjRjRjRjRaaknaaaaaaaaaaacacacacacachmhCgGacacacacacacacacacacacacacacacgGmTmTmTmUlShmmLmLmLmLmLmLhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVmVmVmVmVmVmVmVmVmWmXmXmXmXmXmXmXmXmXmXmXmXmXmWmVmVmVmVmVmVmVmVmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaajRmYlxlxmYjRnamZlxlxlxnbncjRnendngnfknknaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChDhChChFkcmLmLmLmLmLnqhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsnsnsnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnxnxnxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaanAnzlxlxnznAnBnBlxlxlxlxnCnAnEnDmsmsnFaaaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChYhEhDhYhmnJnJnJnJnJnKhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnLnsnLnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnMnxnMnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaanOnNlxmhlxnPmumhlxhjlxlxnRnOnTnSnVnUnXnWaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChChEjChmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsobnsnsnvnumXmXmXmXmXocodocmXmXmXmXmXnwnvnxnxoenxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaofnzlxmEmuogmElxlxohlxlxlxofojoinFoklHaaaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChEhChYjChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsnsnsnsnvnumXmXmXmXmXocorocmXmXmXmXmXnwnvnxnxnxnxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaajRoslxlxosjRotlxmhmElxlxotjRovouoxowaaaaaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChDhCjChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnLnsnLnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnMnxnMnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaajRjRoBjRjRjRjRjRlnoClnjRjRjRjRjRknknknaaaaaaaaacacacacacachmhCacacacacachCacacacacachCacacacacachChChChCjChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsnsnsnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnxnxnxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaamDlbaaknaaknoKlKmDaaaaknaaaaaaaaknaaaaaaaaacacacacacachmhCacacacacachCgGacacacgGhCacacacacachChChChCjChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVmVmVoOoOoOoOoOmVmWmXmXmXmXmXmXmXmXmXmXmXmXmXmWmVoOoOoOoOoOmVmVmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaknknaaoPlbaaoRoQmDknaaoSaaaaaaaaaaaaaaaaaaacacacacacachmhCgGacacacgGhChChChChChChCgGacacacgGhChChChCjChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVoToToToToTmVoUoVoVoVoVoVoVoVoVoVoVoVoVoVoWmVoXoXoXoXoXmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaknknaaoYmhoZaaaaaaknaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChChChChChChChChChChChChChCjChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVmVmVmVmVmVmVpapbpbpbpbpbpcpepdpbpbpbpbpbpamVmVmVmVmVmVmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaknjRjRpfjRjRknaaknknaaaaaaaaaaaaaaacacacacacachmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacpgpapapaphpapipipipipipaphpapapapgacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBhohnhphnhqgBgQgmgRgngngnhrgCgQfYhthshuflhvgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChDhChChChEhFhChChChChChEhChChChChChkhEhChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacachGhJhIhIhIhIgBgCfYhKgngngnhLfYgCfYgChMgCflhNgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChDhChChChChChChChChChChChEhChChChChChChChEhChlhChChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacachQhJhIhIhIhIhShTgngngngngngngngThUgUgUgUhVhWgDgDgDgDgDhbgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChYhChChChChChDhChChFhChChEhChChEhChChEhFhChEhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacachGiahIhIhIhIgBgCfYibgngngnhdfYgCfYfYfYfYflicgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChChChChChChChChChEhChChDhChChEhFhChChEhChFhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgAhQhJhIhIhIhIgBgQgbgRgngngniggbgQfYacacacflihgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChChChChChChChDhChChChChChChChFhChEhFhChEhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacilhJhIhIhIhIgBgQhcgRgngngnighcgQfYacacacflingDgDgDgDidididiegDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChCisisisisisisishChChChChChFhChChChEhChChYhFhChChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacithJhIhIhIhIgBgQgmiuibgnhdivgmgQfYacacacflingDgDgDgDiiikijhhgDgDhigFacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCgGacacacacacacacgGhChChChChChChzisishAishAhChEhChEhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciJhJhIhIhIhIgBiLiLiNiMiOiNiMiLiLiLacacacflingDgDgDgDgDipiohhgDgDhigHacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCacacacacacacacacaciYhChChChCishmhmjaiZhmhmisjbjcishmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBjijhjjhIhIgBjljkjnjmjpjojrjqjsiLacacacfljujtjtjtjwjvjygshhgDgDhigIacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCacacacacacacacacaciYhChChCjChmhmjDjEjEjDhmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBgBgBgBjIgBgBjJjpjKjmjpjojKjpjLiLacacacflflflflflflflflgWgvgxixguflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajQjPjSjRaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCacacacacacacacacaciYhYhChCjChmjXjWjWjWjWjYkajZkckbkekdhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBkfkfkfgBkgjpjKjmjpjojKjpkhiLacacacacacacacacacacacflgDgDgDgDflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaknaakpkokqjRjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCgGacacacacacacacgGhChChChCkuhmkvjWkwkwkxjWjWjWkzkykykyhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBkfkfkfgBkAjpjKjmjpjojKjpkBiLacacacacacacacacacacacflgDjMikiiflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaknkEkGkFkqkHjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChCacacacacackKisisisisiskLhmjWkwkNkMkwjWkPkOkckQkRhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBkfkfkfgBkTkSkSkUjpkVkWkWkXiLacacacacacacacacacacacflgDkiipkjflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaajRlalbkHldlcjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChCacacacacaclhlglglglglgiZhmjWkwljlikwjWkPlkhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBgBgBgBgBiNlliMiLjpiLiNlliMiLacacacacacacacacacacackCgDgDgDgDflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaajRjRlnlmlnjRjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChCgGacacacacacacacacaclrlqlqlqlqlqlqlsjWjWjWjWjWjWkPlkhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLltltltlujplultltltiLacacacacacacacacacacacflkYjwjwkZflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaknknjRlwlvlxjRaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacaclBlAjalglglgiZhmlCkwkwkwjWjWkPlDhmlElFhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLiLiLiLiLiLiLiLiOiLiLiLiLiLiLiLiLacacacacacacacacflflflflflflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaalHlGlJlIlLlKlxlMknaaaaaaaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacacacgJacgGmTmTlShmlUlTlVlThBjWjWjWlXlWlWlYhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLlZmamamamamalZlZlZmamamamamalZiLacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaambmdmcmfmelLlxmhmgmiknknaaaaaaaaaaaaaaaaacacacacacachmmjhCacacacacacacacacacacacacacachChCkuhmmmmlmmmmmnjWjWjWhmmomplYhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmqlZlZlZmrlZlZlZlZlZlZlZmrlZlZlZmqacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaknaalJmsmsmtlLlxmumhmiaamwmvaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacacacacacachChYjChmhmkOmAmzmBhmmChmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLlZmamamamamalZlZlZmamamamamalZiLacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaalMknaaaaknmDmFmEmGmElMknknaaaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacacacacacacmKhChClShmhmhmhmhmhmmLmLmNmMmPmOhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLiNlllllllllllllllllllllllllliMiLacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaajRjRmQjRjRjRjRjRjRmRjRjRjRjRjRjRaaknaaaaaaaaaaacacacacacachmhCgGacacacacacacacacacacacacacacacgGhChCmTmTmTmUlShmmLmLmLmLmLmLhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVmVmVmVmVmVmVmVmVmWmXmXmXmXmXmXmXmXmXmXmXmXmXmWmVmVmVmVmVmVmVmVmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaajRmYlxlxmYjRnamZlxlxlxnbncjRnendngnfknknaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChChDhChChFkcmLmLmLmLmLnqhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsnsnsnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnxnxnxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaanAhHlxlxhHnAnBnBlxlxlxlxnCnAnEnDmsmsnFaaaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChChYhEhDhYhmnJnJnJnJnJnKhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnLnsnLnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnMnxnMnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaanOnNlxmhlxnPmumhlxhjlxlxnRnOnTnSnVnUnXnWaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChChChChEjChmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsobnsnsnvnumXmXmXmXmXocodocmXmXmXmXmXnwnvnxnxoenxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaofhHlxmEmuogmElxlxohlxlxlxofojoinFoklHaaaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChChEhChYhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsnsnsnsnvnumXmXmXmXmXocorocmXmXmXmXmXnwnvnxnxnxnxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaajRoslxlxosjRotlxmhmElxlxotjRovouoxowaaaaaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChChCishChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnLnsnLnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnMnxnMnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaajRjRoBjRjRjRjRjRlnoClnjRjRjRjRjRknknknaaaaaaaaacacacacacachmhCacacacacachCacacacacachCacacacacachChChCkLhRmKhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsnsnsnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnxnxnxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaamDlbaaknaaknoKlKmDaaaaknaaaaaaaaknaaaaaaaaacacacacacachmhCacacacacachCgGacacacgGhCacacacacachChCjChRhXhRiYhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVmVmVoOoOoOoOoOmVmWmXmXmXmXmXmXmXmXmXmXmXmXmXmWmVoOoOoOoOoOmVmVmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaknknaaoPlbaaoRoQmDknaaoSaaaaaaaaaaaaaaaaaaacacacacacachmhCgGacacacgGhChChChChChChCgGacacacgGhChChClShRhZhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVoToToToToTmVoUoVoVoVoVoVoVoVoVoVoVoVoVoVoWmVoXoXoXoXoXmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaknknaaoYmhoZaaaaaaknaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChChChChChChChChChChChChChCmThChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVmVmVmVmVmVmVpapbpbpbpbpbpcpepdpbpbpbpbpbpamVmVmVmVmVmVmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaknjRjRpfjRjRknaaknknaaaaaaaaaaaaaaacacacacacachmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacpgpapapaphpapipipipipipaphpapapapgacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaajRpkpjpjjRoPnDmeplpmknaaaaaaaaaaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacpgpgpnpgpgpgpgpopqpppgpgpgpgpnpgpgacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaalnpjprpjlnptpsmfpukqjRaaaaaaaaaaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacpgpgpgpgpgacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaapvknjRpwpjpxjRkFpymfpuaaknaaaaaaaaaaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
|
||||
|
||||
@@ -100,7 +100,7 @@ Passive gate is similar to the regular pump except:
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 400, 100)
|
||||
ui = new(user, src, ui_key, "atmos_pump", name, 400, 115)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/get_ui_data()
|
||||
@@ -144,28 +144,28 @@ Passive gate is similar to the regular pump except:
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/attack_hand(mob/user)
|
||||
if(..() || !user)
|
||||
return
|
||||
add_fingerprint(usr)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/Topic(href, href_list)
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
if(href_list["power"])
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
if(href_list["set_press"])
|
||||
switch(href_list["set_press"])
|
||||
if ("max")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
if ("set")
|
||||
target_pressure = max(0, min(MAX_OUTPUT_PRESSURE, safe_input("Pressure control", "Enter new output pressure (0-[MAX_OUTPUT_PRESSURE] kPa)", target_pressure)))
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
if("pressure")
|
||||
switch(params["set"])
|
||||
if ("max")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
if ("custom")
|
||||
target_pressure = max(0, min(MAX_OUTPUT_PRESSURE, safe_input("Pressure control", "Enter new output pressure (0-[MAX_OUTPUT_PRESSURE] kPa)", target_pressure)))
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/power_change()
|
||||
..()
|
||||
|
||||
@@ -108,7 +108,7 @@ Thus, the two variables affect pump operation are set in New():
|
||||
/obj/machinery/atmospherics/components/binary/pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 400, 100)
|
||||
ui = new(user, src, ui_key, "atmos_pump", name, 400, 115)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/get_ui_data()
|
||||
@@ -153,26 +153,27 @@ Thus, the two variables affect pump operation are set in New():
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/attack_hand(mob/user)
|
||||
if(..() | !user)
|
||||
if(..() || !user)
|
||||
return
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/Topic(href,href_list)
|
||||
/obj/machinery/atmospherics/components/binary/pump/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
if(href_list["power"])
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
if(href_list["set_press"])
|
||||
switch(href_list["set_press"])
|
||||
if ("max")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
if ("set")
|
||||
target_pressure = max(0, min(MAX_OUTPUT_PRESSURE, safe_input("Pressure control", "Enter new output pressure (0-[MAX_OUTPUT_PRESSURE] kPa)", target_pressure)))
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
|
||||
add_fingerprint(usr)
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
if("pressure")
|
||||
switch(params["set"])
|
||||
if ("max")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
if ("custom")
|
||||
target_pressure = max(0, min(MAX_OUTPUT_PRESSURE, safe_input("Pressure control", "Enter new output pressure (0-[MAX_OUTPUT_PRESSURE] kPa)", target_pressure)))
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/power_change()
|
||||
..()
|
||||
|
||||
@@ -105,7 +105,7 @@ Thus, the two variables affect pump operation are set in New():
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 400, 100)
|
||||
ui = new(user, src, ui_key, "atmos_pump", name, 400, 115)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/get_ui_data()
|
||||
@@ -147,29 +147,31 @@ Thus, the two variables affect pump operation are set in New():
|
||||
spawn(2)
|
||||
broadcast_status()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/attack_hand(mob/user)
|
||||
if(..() | !user)
|
||||
if(..() || !user)
|
||||
return
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/Topic(href,href_list)
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
if(href_list["power"])
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
if(href_list["set_transfer_rate"])
|
||||
switch(href_list["set_transfer_rate"])
|
||||
if ("max")
|
||||
transfer_rate = MAX_TRANSFER_RATE
|
||||
if ("set")
|
||||
transfer_rate = max(0, min(MAX_TRANSFER_RATE, safe_input("Pressure control", "Enter new transfer rate (0-[MAX_TRANSFER_RATE] L/s)", transfer_rate)))
|
||||
investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos")
|
||||
|
||||
add_fingerprint(usr)
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
if("transfer")
|
||||
switch(params)
|
||||
if ("max")
|
||||
transfer_rate = MAX_TRANSFER_RATE
|
||||
if ("custom")
|
||||
transfer_rate = max(0, min(MAX_TRANSFER_RATE, safe_input("Pressure control", "Enter new transfer rate (0-[MAX_TRANSFER_RATE] L/s)", transfer_rate)))
|
||||
investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos")
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/power_change()
|
||||
..()
|
||||
|
||||
@@ -137,10 +137,6 @@ Pipenet stuff; housekeeping
|
||||
T.assume_air(to_release)
|
||||
air_update_turf(1)
|
||||
|
||||
/*
|
||||
I think this is NanoUI?
|
||||
*/
|
||||
|
||||
/obj/machinery/atmospherics/components/proc/safe_input(var/title, var/text, var/default_set)
|
||||
var/new_value = input(usr,text,title,default_set) as num
|
||||
if(usr.canUseTopic(src))
|
||||
|
||||
@@ -11,12 +11,9 @@
|
||||
|
||||
name = "gas filter"
|
||||
|
||||
req_access = list(access_atmospherics)
|
||||
|
||||
can_unwrench = 1
|
||||
|
||||
var/on = 0
|
||||
var/temp = null
|
||||
|
||||
var/target_pressure = ONE_ATMOSPHERE
|
||||
|
||||
@@ -172,7 +169,7 @@ Filter types:
|
||||
/obj/machinery/atmospherics/components/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "atmos_filter.tmpl", name, 400, 120)
|
||||
ui = new(user, src, ui_key, "atmos_filter", name, 450, 145)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/get_ui_data()
|
||||
@@ -183,36 +180,35 @@ Filter types:
|
||||
data["filter_type"] = filter_type
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/Topic(href, href_list)
|
||||
/obj/machinery/atmospherics/components/trinary/filter/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
if(href_list["filterset"])
|
||||
src.filter_type = text2num(href_list["filterset"])
|
||||
var/filtering_name = "nothing"
|
||||
switch(filter_type)
|
||||
if(FILTER_PLASMA)
|
||||
filtering_name = "plasma"
|
||||
if(FILTER_OXYGEN)
|
||||
filtering_name = "oxygen"
|
||||
if(FILTER_NITROGEN)
|
||||
filtering_name = "nitrogen"
|
||||
if(FILTER_CARBONDIOXIDE)
|
||||
filtering_name = "carbon dioxide"
|
||||
if(FILTER_NITROUSOXIDE)
|
||||
filtering_name = "nitrous oxide"
|
||||
investigate_log("was set to filter [filtering_name] by [key_name(usr)]", "atmos")
|
||||
if (href_list["temp"])
|
||||
src.temp = null
|
||||
if(href_list["set_press"])
|
||||
switch(href_list["set_press"])
|
||||
if ("max")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
if ("set")
|
||||
target_pressure = max(0, min(MAX_OUTPUT_PRESSURE, safe_input("Pressure control", "Enter new output pressure (0-[MAX_OUTPUT_PRESSURE] kPa)", target_pressure)))
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
if(href_list["power"])
|
||||
on=!on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
|
||||
add_fingerprint(usr)
|
||||
switch(action)
|
||||
if("power")
|
||||
on=!on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
if("pressure")
|
||||
switch(params["set"])
|
||||
if("max")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
if("custom")
|
||||
target_pressure = max(0, min(MAX_OUTPUT_PRESSURE, safe_input("Pressure control", "Enter new output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", target_pressure)))
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
if("filter")
|
||||
src.filter_type = text2num(params["mode"])
|
||||
var/filtering_name = "nothing"
|
||||
switch(filter_type)
|
||||
if(FILTER_PLASMA)
|
||||
filtering_name = "plasma"
|
||||
if(FILTER_OXYGEN)
|
||||
filtering_name = "oxygen"
|
||||
if(FILTER_NITROGEN)
|
||||
filtering_name = "nitrogen"
|
||||
if(FILTER_CARBONDIOXIDE)
|
||||
filtering_name = "carbon dioxide"
|
||||
if(FILTER_NITROUSOXIDE)
|
||||
filtering_name = "nitrous oxide"
|
||||
investigate_log("was set to filter [filtering_name] by [key_name(usr)]", "atmos")
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
density = 0
|
||||
|
||||
name = "gas mixer"
|
||||
|
||||
req_access = list(access_atmospherics)
|
||||
|
||||
can_unwrench = 1
|
||||
|
||||
var/on = 0
|
||||
@@ -135,7 +132,7 @@
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "atmos_mixer.tmpl", name, 400, 145)
|
||||
ui = new(user, src, ui_key, "atmos_mixer", name, 450, 175)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/get_ui_data()
|
||||
@@ -147,29 +144,30 @@
|
||||
data["node2_concentration"] = round(node2_concentration*100)
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/Topic(href,href_list)
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
if(href_list["power"])
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
if(href_list["set_press"])
|
||||
switch(href_list["set_press"])
|
||||
if ("max")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
if ("set")
|
||||
target_pressure = max(0, min(MAX_OUTPUT_PRESSURE, safe_input("Pressure control", "Enter new output pressure (0-[MAX_OUTPUT_PRESSURE] kPa)", target_pressure)))
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
if(href_list["node1_c"])
|
||||
var/value = text2num(href_list["node1_c"])
|
||||
src.node1_concentration = max(0, min(1, src.node1_concentration + value))
|
||||
src.node2_concentration = max(0, min(1, src.node2_concentration - value))
|
||||
investigate_log("was set to [node1_concentration] % on node 1 by [key_name(usr)]", "atmos")
|
||||
if(href_list["node2_c"])
|
||||
var/value = text2num(href_list["node2_c"])
|
||||
src.node2_concentration = max(0, min(1, src.node2_concentration + value))
|
||||
src.node1_concentration = max(0, min(1, src.node1_concentration - value))
|
||||
investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", "atmos")
|
||||
|
||||
add_fingerprint(usr)
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
if("pressure")
|
||||
switch(params["set"])
|
||||
if("max")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
if("custom")
|
||||
target_pressure = max(0, min(MAX_OUTPUT_PRESSURE, safe_input("Pressure control", "Enter new output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", target_pressure)))
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
if("node1")
|
||||
var/value = text2num(params["concentration"])
|
||||
src.node1_concentration = max(0, min(1, src.node1_concentration + value))
|
||||
src.node2_concentration = max(0, min(1, src.node2_concentration - value))
|
||||
investigate_log("was set to [node1_concentration] % on node 1 by [key_name(usr)]", "atmos")
|
||||
if("node2")
|
||||
var/value = text2num(params["concentration"])
|
||||
src.node2_concentration = max(0, min(1, src.node2_concentration + value))
|
||||
src.node1_concentration = max(0, min(1, src.node1_concentration - value))
|
||||
investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", "atmos")
|
||||
update_icon()
|
||||
return 1
|
||||
@@ -113,7 +113,7 @@
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "cryo.tmpl", name, 520, 560, state = notcontained_state)
|
||||
ui = new(user, src, ui_key, "cryo", name, 520, 600, state = notcontained_state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/get_ui_data()
|
||||
@@ -166,33 +166,28 @@
|
||||
data["beakerContents"] = beakerContents
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/Topic(href, href_list)
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(href_list["switchOn"])
|
||||
if(!state_open)
|
||||
on = 1
|
||||
|
||||
if(href_list["switchOff"])
|
||||
on = 0
|
||||
|
||||
if(href_list["autoEject"])
|
||||
autoEject = !autoEject
|
||||
|
||||
if(href_list["openCell"])
|
||||
open_machine()
|
||||
|
||||
if(href_list["closeCell"])
|
||||
close_machine()
|
||||
|
||||
if(href_list["ejectBeaker"])
|
||||
if(beaker)
|
||||
beaker.loc = get_step(loc, SOUTH)
|
||||
beaker = null
|
||||
|
||||
add_fingerprint(usr)
|
||||
switch(action)
|
||||
if("open")
|
||||
open_machine()
|
||||
if("close")
|
||||
close_machine()
|
||||
if("autoeject")
|
||||
autoEject = !autoEject
|
||||
if("on")
|
||||
if(!state_open)
|
||||
on = 1
|
||||
if("off")
|
||||
on = 0
|
||||
if("ejectbeaker")
|
||||
if(beaker)
|
||||
beaker.loc = get_step(loc, SOUTH)
|
||||
beaker = null
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/glass))
|
||||
|
||||
@@ -944,7 +944,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
final_x = T.x + rough_x
|
||||
final_y = T.y + rough_y
|
||||
final_z = T.z
|
||||
else
|
||||
else
|
||||
final_x = AM.x + rough_x
|
||||
final_y = AM.y + rough_y
|
||||
final_z = AM.z
|
||||
@@ -1353,9 +1353,9 @@ B --><-- A
|
||||
return L
|
||||
|
||||
/atom/proc/contains(var/atom/location)
|
||||
if(!location)
|
||||
return 0
|
||||
for(location, location && location != src, location=location.loc); //semicolon is for the empty statement
|
||||
if(location == src)
|
||||
return 1
|
||||
return 0
|
||||
if(!location)
|
||||
return 0
|
||||
for(location, location && location != src, location=location.loc); //semicolon is for the empty statement
|
||||
if(location == src)
|
||||
return 1
|
||||
return 0
|
||||
@@ -170,7 +170,7 @@ var/datum/subsystem/minimap/SSminimap
|
||||
text2file(hash, hash_path)
|
||||
|
||||
/datum/subsystem/minimap/proc/getMinimapFile(zlevel)
|
||||
return "data/minimaps/map_[zlevel]"
|
||||
return "data/minimaps/[MAP_NAME]_[zlevel]"
|
||||
|
||||
/datum/subsystem/minimap/proc/sendMinimaps(client/client)
|
||||
for (var/z = 1 to world.maxz)
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
var/datum/subsystem/nano/SSnano
|
||||
|
||||
/datum/subsystem/nano
|
||||
name = "NanoUI"
|
||||
wait = 10
|
||||
priority = 16
|
||||
display = 6
|
||||
|
||||
can_fire = 1 // This needs to fire before round start.
|
||||
|
||||
var/list/open_uis = list() // A list of open NanoUIs, grouped by src_object and ui_key.
|
||||
var/list/processing_uis = list() // A list of processing NanoUIs, not grouped.
|
||||
|
||||
|
||||
/datum/subsystem/nano/New()
|
||||
NEW_SS_GLOBAL(SSnano)
|
||||
|
||||
/datum/subsystem/nano/stat_entry()
|
||||
..("O:[open_uis.len]|P:[processing_uis.len]") // Show how many interfaces we have open/are processing.
|
||||
|
||||
/datum/subsystem/nano/fire() // Process UIs.
|
||||
for(var/thing in processing_uis)
|
||||
var/datum/nanoui/ui = thing
|
||||
if(ui && ui.src_object && ui.user)
|
||||
ui.process()
|
||||
continue
|
||||
processing_uis.Remove(ui)
|
||||
var/datum/subsystem/nano/SSnano
|
||||
|
||||
/datum/subsystem/nano
|
||||
name = "NanoUI"
|
||||
wait = 10
|
||||
priority = 16
|
||||
display = 6
|
||||
|
||||
can_fire = 1 // This needs to fire before round start.
|
||||
|
||||
var/list/open_uis = list() // A list of open NanoUIs, grouped by src_object and ui_key.
|
||||
var/list/processing_uis = list() // A list of processing NanoUIs, not grouped.
|
||||
|
||||
|
||||
/datum/subsystem/nano/New()
|
||||
NEW_SS_GLOBAL(SSnano)
|
||||
|
||||
/datum/subsystem/nano/stat_entry()
|
||||
..("O:[open_uis.len]|P:[processing_uis.len]") // Show how many interfaces we have open/are processing.
|
||||
|
||||
/datum/subsystem/nano/fire() // Process UIs.
|
||||
for(var/thing in processing_uis)
|
||||
var/datum/nanoui/ui = thing
|
||||
if(ui && ui.user && ui.src_object)
|
||||
ui.process()
|
||||
continue
|
||||
processing_uis.Remove(ui)
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
var/list/datum/objective/objectives = list()
|
||||
var/list/datum/objective/special_verbs = list()
|
||||
|
||||
var/list/cult_words = list()
|
||||
var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button.
|
||||
|
||||
var/datum/faction/faction //associated faction
|
||||
@@ -147,12 +146,7 @@
|
||||
if(src in ticker.mode.cult)
|
||||
ticker.mode.cult -= src
|
||||
ticker.mode.update_cult_icons_removed(src)
|
||||
var/datum/game_mode/cult/cult = ticker.mode
|
||||
if(istype(cult))
|
||||
cult.memorize_cult_objectives(src)
|
||||
special_role = null
|
||||
remove_objectives()
|
||||
remove_antag_equip()
|
||||
|
||||
/datum/mind/proc/remove_rev()
|
||||
if(src in ticker.mode.revolutionaries)
|
||||
@@ -342,11 +336,8 @@
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if (src in ticker.mode.cult)
|
||||
text += "loyal|<a href='?src=\ref[src];cult=clear'>employee</a>|<b>CULTIST</b>"
|
||||
text += "<br>Give <a href='?src=\ref[src];cult=tome'>tome</a>|<a href='?src=\ref[src];cult=amulet'>amulet</a>."
|
||||
/*
|
||||
if (objectives.len==0)
|
||||
text += "<br>Objectives are empty! Set to sacrifice and <a href='?src=\ref[src];cult=escape'>escape</a> or <a href='?src=\ref[src];cult=summon'>summon</a>."
|
||||
*/
|
||||
text += "<br><a href='?src=\ref[src];cult=equip'>Equip</a>"
|
||||
|
||||
else if(isloyal(current))
|
||||
text += "<b>LOYAL</b>|employee|<a href='?src=\ref[src];cult=cultist'>cultist</a>"
|
||||
else
|
||||
@@ -1008,31 +999,9 @@
|
||||
ticker.mode.add_cultist(src)
|
||||
message_admins("[key_name_admin(usr)] has cult'ed [current].")
|
||||
log_admin("[key_name(usr)] has cult'ed [current].")
|
||||
if("tome")
|
||||
var/mob/living/carbon/human/H = current
|
||||
if (istype(H))
|
||||
var/obj/item/weapon/tome/T = new(H)
|
||||
|
||||
var/list/slots = list (
|
||||
"backpack" = slot_in_backpack,
|
||||
"left pocket" = slot_l_store,
|
||||
"right pocket" = slot_r_store,
|
||||
"left hand" = slot_l_hand,
|
||||
"right hand" = slot_r_hand,
|
||||
)
|
||||
var/where = H.equip_in_one_of_slots(T, slots)
|
||||
if (!where)
|
||||
usr << "<span class='danger'>Spawning tome failed!</span>"
|
||||
else
|
||||
H << "A tome, a message from your new master, appears in your [where]."
|
||||
if(where == "backpack")
|
||||
var/obj/item/weapon/storage/B = H.back
|
||||
B.orient2hud(H)
|
||||
B.show_to(H)
|
||||
|
||||
if("amulet")
|
||||
if("equip")
|
||||
if (!ticker.mode.equip_cultist(current))
|
||||
usr << "<span class='danger'>Spawning amulet failed!</span>"
|
||||
usr << "<span class='danger'>equip_cultist() failed! [current]'s starting equipment will be incomplete.</span>"
|
||||
|
||||
else if (href_list["wizard"])
|
||||
switch(href_list["wizard"])
|
||||
@@ -1430,34 +1399,8 @@
|
||||
special_role = "Cultist"
|
||||
current << "<font color=\"purple\"><b><i>You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie.</b></i></font>"
|
||||
current << "<font color=\"purple\"><b><i>Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.</b></i></font>"
|
||||
var/datum/game_mode/cult/cult = ticker.mode
|
||||
if (istype(cult))
|
||||
cult.memorize_cult_objectives(src)
|
||||
else
|
||||
var/explanation = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it."
|
||||
current << "<B>Objective #1</B>: [explanation]"
|
||||
current.memory += "<B>Objective #1</B>: [explanation]<BR>"
|
||||
current << "The convert rune is join blood self"
|
||||
current.memory += "The convert rune is join blood self<BR>"
|
||||
|
||||
var/mob/living/carbon/human/H = current
|
||||
if (istype(H))
|
||||
var/obj/item/weapon/tome/T = new(H)
|
||||
|
||||
var/list/slots = list (
|
||||
"backpack" = slot_in_backpack,
|
||||
"left pocket" = slot_l_store,
|
||||
"right pocket" = slot_r_store,
|
||||
"left hand" = slot_l_hand,
|
||||
"right hand" = slot_r_hand,
|
||||
)
|
||||
var/where = H.equip_in_one_of_slots(T, slots)
|
||||
if (!where)
|
||||
else
|
||||
H << "A tome, a message from your new master, appears in your [where]."
|
||||
|
||||
if (!ticker.mode.equip_cultist(current))
|
||||
H << "Spawning an amulet from your Master failed."
|
||||
current << "Your objective is to summon Nar-Sie by building and defending a suitable shell for the Geometer. Adequate supplies can be procured through human sacrifices."
|
||||
ticker.mode.equip_cultist(current)
|
||||
|
||||
/datum/mind/proc/make_Rev()
|
||||
if (ticker.mode.head_revolutionaries.len>0)
|
||||
|
||||
@@ -176,7 +176,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
|
||||
/obj/effect/proc_holder/spell/proc/perform(list/targets, recharge = 1, mob/user = usr) //if recharge is started is important for the trigger spells
|
||||
before_cast(targets)
|
||||
invocation(user)
|
||||
if(user.ckey)
|
||||
if(user && user.ckey)
|
||||
user.attack_log += text("\[[time_stamp()]\] <span class='danger'>[user.real_name] ([user.ckey]) cast the spell [name].</span>")
|
||||
spawn(0)
|
||||
if(charge_type == "recharge" && recharge)
|
||||
|
||||
@@ -727,6 +727,13 @@ var/list/uplink_items = list()
|
||||
gamemodes = list(/datum/game_mode/nuclear,/datum/game_mode/gang)
|
||||
surplus = 20
|
||||
|
||||
/datum/uplink_item/device_tools/medgun
|
||||
name = "Medbeam Gun"
|
||||
desc = "Medical Beam Gun, useful in prolonged firefights."
|
||||
item = /obj/item/weapon/gun/medbeam
|
||||
cost = 15
|
||||
gamemodes = list(/datum/game_mode/nuclear)
|
||||
|
||||
|
||||
// IMPLANTS
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
maxbodytemp = 360
|
||||
var/mob/camera/blob/overmind = null
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/proc/adjustcolors(a_color)
|
||||
if(a_color)
|
||||
color = a_color
|
||||
/mob/living/simple_animal/hostile/blob/update_icons()
|
||||
if(overmind)
|
||||
color = overmind.blob_reagent_datum.color
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blob_act()
|
||||
return
|
||||
@@ -58,7 +58,6 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobspore/Life()
|
||||
|
||||
if(!is_zombie && isturf(src.loc))
|
||||
for(var/mob/living/carbon/human/H in oview(src,1)) //Only for corpse right next to/on same tile
|
||||
if(H.stat == DEAD)
|
||||
@@ -121,19 +120,8 @@
|
||||
M.loc = src.loc
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobspore/update_icons()
|
||||
..()
|
||||
|
||||
if(overmind && overmind.blob_reagent_datum)
|
||||
adjustcolors(overmind.blob_reagent_datum.color)
|
||||
else
|
||||
adjustcolors(color) //to ensure zombie/other overlays update
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobspore/adjustcolors(a_color)
|
||||
color = a_color
|
||||
|
||||
if(is_zombie)
|
||||
overlays.Cut()
|
||||
overlays = human_overlays
|
||||
@@ -166,9 +154,6 @@
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
gold_core_spawnable = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/blob_act()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/death(gibbed)
|
||||
..(gibbed)
|
||||
flick("blobbernaut_death", src)
|
||||
|
||||
@@ -17,25 +17,28 @@
|
||||
/obj/effect/blob/core/New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 2, offspring)
|
||||
blob_cores += src
|
||||
SSobj.processing |= src
|
||||
adjustcolors(color) //so it atleast appears
|
||||
update_icon() //so it atleast appears
|
||||
if(!overmind)
|
||||
create_overmind(new_overmind)
|
||||
if(overmind)
|
||||
adjustcolors(overmind.blob_reagent_datum.color)
|
||||
update_icon()
|
||||
if(offspring)
|
||||
is_offspring = 1
|
||||
point_rate = new_rate
|
||||
..(loc, h)
|
||||
|
||||
/obj/effect/blob/core/adjustcolors(a_color)
|
||||
/obj/effect/blob/core/update_icon()
|
||||
overlays.Cut()
|
||||
color = null
|
||||
var/image/I = new('icons/mob/blob.dmi', "blob")
|
||||
I.color = a_color
|
||||
if(overmind)
|
||||
I.color = overmind.blob_reagent_datum.color
|
||||
overlays += I
|
||||
var/image/C = new('icons/mob/blob.dmi', "blob_core_overlay")
|
||||
overlays += C
|
||||
|
||||
/obj/effect/blob/core/PulseAnimation()
|
||||
return
|
||||
|
||||
/obj/effect/blob/core/Destroy()
|
||||
blob_cores -= src
|
||||
@@ -69,21 +72,18 @@
|
||||
health = min(maxhealth, health+health_regen)
|
||||
if(overmind)
|
||||
overmind.update_health()
|
||||
pulseLoop(0)
|
||||
Pulse_Area(overmind, 12, 4, 3)
|
||||
for(var/b_dir in alldirs)
|
||||
if(!prob(5))
|
||||
continue
|
||||
var/obj/effect/blob/normal/B = locate() in get_step(src, b_dir)
|
||||
if(B)
|
||||
var/obj/effect/blob/N = B.change_to(/obj/effect/blob/shield)
|
||||
if(overmind)
|
||||
N.color = overmind.blob_reagent_datum.color
|
||||
B.change_to(/obj/effect/blob/shield, overmind)
|
||||
color = null
|
||||
..()
|
||||
|
||||
|
||||
/obj/effect/blob/core/proc/create_overmind(client/new_overmind, override_delay)
|
||||
|
||||
if(overmind_get_delay > world.time && !override_delay)
|
||||
return
|
||||
|
||||
|
||||
@@ -31,8 +31,9 @@
|
||||
spore_delay = world.time + 100 // 10 seconds
|
||||
PulseAnimation(1)
|
||||
var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore(src.loc, src)
|
||||
BS.color = color
|
||||
BS.overmind = overmind
|
||||
overmind.blob_mobs.Add(BS)
|
||||
if(overmind) //if we don't have an overmind, we don't need to do anything but make a spore
|
||||
BS.overmind = overmind
|
||||
BS.update_icons()
|
||||
overmind.blob_mobs.Add(BS)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
desc = "A large, pulsating yellow mass."
|
||||
health = 200
|
||||
maxhealth = 200
|
||||
health_regen = 3
|
||||
point_return = 25
|
||||
atmosblock = 1
|
||||
|
||||
@@ -14,15 +15,19 @@
|
||||
SSobj.processing |= src
|
||||
..(loc, h)
|
||||
|
||||
/obj/effect/blob/node/adjustcolors(a_color)
|
||||
/obj/effect/blob/node/update_icon()
|
||||
overlays.Cut()
|
||||
color = null
|
||||
var/image/I = new('icons/mob/blob.dmi', "blob")
|
||||
I.color = a_color
|
||||
if(overmind)
|
||||
I.color = overmind.blob_reagent_datum.color
|
||||
src.overlays += I
|
||||
var/image/C = new('icons/mob/blob.dmi', "blob_node_overlay")
|
||||
src.overlays += C
|
||||
|
||||
/obj/effect/blob/node/PulseAnimation()
|
||||
return
|
||||
|
||||
/obj/effect/blob/node/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return
|
||||
|
||||
@@ -32,6 +37,5 @@
|
||||
return ..()
|
||||
|
||||
/obj/effect/blob/node/Life()
|
||||
pulseLoop(5)
|
||||
health = min(initial(health), health + 1)
|
||||
Pulse_Area(overmind, 10, 3, 2)
|
||||
color = null
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
PulseAnimation(1)
|
||||
|
||||
resource_delay = world.time + 40 // 4 seconds
|
||||
resource_delay = world.time + 45 // 4 and a half seconds
|
||||
|
||||
if(overmind)
|
||||
overmind.add_points(1)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/effect/blob/storage
|
||||
name = "storage blob"
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "blob_resource"
|
||||
icon_state = "blob_factory"
|
||||
desc = "A huge, smooth mass supported by tendrils."
|
||||
health = 60
|
||||
maxhealth = 60
|
||||
@@ -12,13 +12,10 @@
|
||||
/obj/effect/blob/storage/creation_action()
|
||||
if(overmind)
|
||||
overmind.max_blob_points += point_bonus
|
||||
overmind.storage_blobs++
|
||||
|
||||
/obj/effect/blob/storage/Destroy()
|
||||
if(overmind)
|
||||
if(overmind && overmind.storage_blobs) //if the overmind doesn't have any recorded storage blobs, don't TAKE ALL THE POINTS THEY HAVE
|
||||
overmind.max_blob_points -= point_bonus
|
||||
overmind.storage_blobs--
|
||||
return ..()
|
||||
|
||||
/obj/effect/blob/storage/PulseAnimation(activate = 0)
|
||||
if(activate)
|
||||
..()
|
||||
return
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
var/obj/effect/blob/core/blob_core = null // The blob overmind's core
|
||||
var/blob_points = 0
|
||||
var/max_blob_points = 100
|
||||
var/storage_blobs = 0
|
||||
var/last_attack = 0
|
||||
var/datum/reagent/blob/blob_reagent_datum = new/datum/reagent/blob()
|
||||
var/list/blob_mobs = list()
|
||||
@@ -29,7 +30,7 @@
|
||||
possible_reagents.Add(new type)
|
||||
blob_reagent_datum = pick(possible_reagents)
|
||||
if(blob_core)
|
||||
blob_core.adjustcolors(blob_reagent_datum.color)
|
||||
blob_core.update_icon()
|
||||
|
||||
ghostimage = image(src.icon,src,src.icon_state)
|
||||
ghost_darkness_images |= ghostimage //so ghosts can see the blob cursor when they disable darkness
|
||||
@@ -90,7 +91,7 @@
|
||||
return
|
||||
|
||||
var/message_a = say_quote(message, get_spans())
|
||||
var/rendered = "<font color=\"#EE4000\"><i><span class='game say'>Blob Telepathy, <span class='name'>[name]([blob_reagent_datum.name])</span> <span class='message'>[message_a]</span></span></i></font>"
|
||||
var/rendered = "<font color=\"#EE4000\">Blob Telepathy, <b>[name](<font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</font>)</b> [message_a]</font>"
|
||||
|
||||
for (var/mob/M in mob_list)
|
||||
if(isovermind(M) || isobserver(M))
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
/mob/camera/blob/verb/create_resource()
|
||||
set category = "Blob"
|
||||
set name = "Create Resource Blob (40)"
|
||||
set desc = "Create a resource tower which will generate points for you."
|
||||
set desc = "Create a resource tower which will generate resources for you."
|
||||
createSpecial(40, /obj/effect/blob/resource, 4)
|
||||
|
||||
/mob/camera/blob/verb/create_node()
|
||||
@@ -137,7 +137,7 @@
|
||||
return
|
||||
if(B.point_return)
|
||||
add_points(B.point_return)
|
||||
src << "<span class='notice'>Gained [B.point_return] resources from removing the [B].</span>"
|
||||
src << "<span class='notice'>Gained [B.point_return] resources from removing \the [B].</span>"
|
||||
qdel(B)
|
||||
|
||||
/mob/camera/blob/verb/expand_blob_power()
|
||||
@@ -161,14 +161,13 @@
|
||||
if(!can_buy(5))
|
||||
return
|
||||
last_attack = world.time
|
||||
OB.expand(T, 0, blob_reagent_datum.color)
|
||||
OB.expand(T, 0, src)
|
||||
for(var/mob/living/L in T)
|
||||
if("blob" in L.faction) //no friendly fire
|
||||
continue
|
||||
var/mob_protection = L.get_permeability_protection()
|
||||
blob_reagent_datum.reaction_mob(L, VAPOR, 25, 1, mob_protection)
|
||||
blob_reagent_datum.send_message(L)
|
||||
OB.color = blob_reagent_datum.color
|
||||
|
||||
/mob/camera/blob/verb/rally_spores_power()
|
||||
set category = "Blob"
|
||||
@@ -209,13 +208,13 @@
|
||||
set category = "Blob"
|
||||
set name = "Blob Broadcast"
|
||||
set desc = "Speak with your blob spores and blobbernauts as your mouthpieces. This action is free."
|
||||
var/speak_text = input(usr, "What would you like to say with your minions?", "Blob Broadcast", null) as text
|
||||
var/speak_text = input(src, "What would you like to say with your minions?", "Blob Broadcast", null) as text
|
||||
if(!speak_text)
|
||||
return
|
||||
else
|
||||
usr << "You broadcast with your minions, <B>[speak_text]</B>"
|
||||
for(var/mob/living/simple_animal/hostile/blob_minion in blob_mobs)
|
||||
if(blob_minion.stat == CONSCIOUS)
|
||||
src << "You broadcast with your minions, <B>[speak_text]</B>"
|
||||
for(var/mob/living/simple_animal/hostile/blob/blob_minion in blob_mobs)
|
||||
if(blob_minion.overmind == src && blob_minion.stat == CONSCIOUS)
|
||||
blob_minion.say(speak_text)
|
||||
|
||||
/mob/camera/blob/verb/chemical_reroll()
|
||||
@@ -227,9 +226,9 @@
|
||||
var/datum/reagent/blob/B = pick((subtypesof(/datum/reagent/blob) - blob_reagent_datum.type))
|
||||
blob_reagent_datum = new B
|
||||
for(var/obj/effect/blob/BL in blobs)
|
||||
BL.adjustcolors(blob_reagent_datum.color)
|
||||
BL.update_icon()
|
||||
for(var/mob/living/simple_animal/hostile/blob/BLO)
|
||||
BLO.adjustcolors(blob_reagent_datum.color)
|
||||
BLO.update_icons()
|
||||
src << "Your reagent is now: <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font>!"
|
||||
src << "The <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font> reagent [blob_reagent_datum.description]"
|
||||
|
||||
@@ -237,9 +236,9 @@
|
||||
set category = "Blob"
|
||||
set name = "*Blob Help*"
|
||||
set desc = "Help on how to blob."
|
||||
src << "<b>As the overmind, you can control the blob!</b>"
|
||||
src << "Your blob reagent is: <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font>!"
|
||||
src << "The <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font> reagent [blob_reagent_datum.description]"
|
||||
src << "<b>As the overmind, you can control the blob!</b>"
|
||||
src << "<b>You can expand, which will attack people, damage objects, or place a Normal Blob if the tile is clear.</b>"
|
||||
src << "<i>Normal Blobs</i> will expand your reach and can be upgraded into special blobs that perform certain functions."
|
||||
src << "<b>You can upgrade normal blobs into the following types of blob:</b>"
|
||||
|
||||
@@ -12,12 +12,14 @@
|
||||
var/health = 30
|
||||
var/maxhealth = 30
|
||||
var/health_regen = 2 //how much health this blob regens when pulsed
|
||||
var/health_timestamp = 0
|
||||
var/health_timestamp = 0 //we got healed when?
|
||||
var/pulse_timestamp = 0 //we got pulsed when?
|
||||
var/brute_resist = 2 //divides brute damage by this
|
||||
var/fire_resist = 1 //divides burn damage by this
|
||||
var/atmosblock = 0 //if the blob blocks atmos and heat spread
|
||||
var/mob/camera/blob/overmind
|
||||
|
||||
|
||||
/obj/effect/blob/New(loc)
|
||||
var/area/Ablob = get_area(loc)
|
||||
if(Ablob.blob_allowed) //Is this area allowed for winning as blob?
|
||||
@@ -34,15 +36,6 @@
|
||||
/obj/effect/blob/proc/creation_action() //When it's created by the overmind, do this.
|
||||
return
|
||||
|
||||
/obj/effect/blob/proc/check_health()
|
||||
if(health <= 0)
|
||||
qdel(src)
|
||||
return
|
||||
return
|
||||
|
||||
/obj/effect/blob/update_icon() //Used for normal blobs, to update icon when weakened.
|
||||
return
|
||||
|
||||
/obj/effect/blob/Destroy()
|
||||
if(atmosblock)
|
||||
atmosblock = 0
|
||||
@@ -69,6 +62,20 @@
|
||||
return 0
|
||||
|
||||
|
||||
/obj/effect/blob/proc/check_health()
|
||||
if(health <= 0)
|
||||
qdel(src) //we dead now
|
||||
return
|
||||
return
|
||||
|
||||
/obj/effect/blob/update_icon() //Updates color based on overmind color if we have an overmind.
|
||||
if(overmind)
|
||||
color = overmind.blob_reagent_datum.color
|
||||
else
|
||||
color = null
|
||||
return
|
||||
|
||||
|
||||
/obj/effect/blob/process()
|
||||
Life()
|
||||
return
|
||||
@@ -81,70 +88,57 @@
|
||||
/obj/effect/blob/proc/Life()
|
||||
return
|
||||
|
||||
/obj/effect/blob/proc/Pulse_Area(pulsing_overmind = overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
|
||||
src.Be_Pulsed()
|
||||
if(claim_range)
|
||||
for(var/obj/effect/blob/B in ultra_range(claim_range, src, 1))
|
||||
B.update_icon()
|
||||
if(!B.overmind && !istype(B, /obj/effect/blob/core) && prob(30))
|
||||
B.overmind = pulsing_overmind //reclaim unclaimed, non-core blobs.
|
||||
B.update_icon()
|
||||
if(pulse_range)
|
||||
for(var/obj/effect/blob/B in orange(pulse_range, src))
|
||||
B.Be_Pulsed()
|
||||
if(expand_range)
|
||||
src.expand()
|
||||
for(var/obj/effect/blob/B in orange(expand_range, src))
|
||||
if(prob(12))
|
||||
B.expand()
|
||||
return
|
||||
|
||||
/obj/effect/blob/proc/Be_Pulsed()
|
||||
if(pulse_timestamp <= world.time)
|
||||
PulseAnimation()
|
||||
ConsumeTile()
|
||||
RegenHealth()
|
||||
run_action()
|
||||
pulse_timestamp = world.time + 10
|
||||
return 1 //we did it, we were pulsed!
|
||||
return 0 //oh no we failed
|
||||
|
||||
/obj/effect/blob/proc/ConsumeTile()
|
||||
for(var/atom/A in loc)
|
||||
A.blob_act()
|
||||
|
||||
/obj/effect/blob/proc/PulseAnimation()
|
||||
if(!istype(src, /obj/effect/blob/core) || !istype(src, /obj/effect/blob/node))
|
||||
flick("[icon_state]_glow", src)
|
||||
return
|
||||
|
||||
/obj/effect/blob/proc/RegenHealth()
|
||||
// All blobs heal over time when pulsed, but it has a cool down
|
||||
if(health_timestamp > world.time)
|
||||
return 0
|
||||
health = min(maxhealth, health+health_regen)
|
||||
update_icon()
|
||||
health_timestamp = world.time + 10 // 1 seconds
|
||||
|
||||
/obj/effect/blob/proc/pulseLoop(num)
|
||||
var/a_color
|
||||
if(overmind)
|
||||
a_color = overmind.blob_reagent_datum.color
|
||||
for(var/i = 1; i < 8; i += i)
|
||||
Pulse(num, i, a_color)
|
||||
|
||||
/obj/effect/blob/proc/Pulse(pulse = 0, origin_dir = 0, a_color)//Todo: Fix spaceblob expand
|
||||
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
PulseAnimation()
|
||||
ConsumeTile()
|
||||
RegenHealth()
|
||||
|
||||
if(run_action())//If we can do something here then we dont need to pulse more
|
||||
return
|
||||
|
||||
if(pulse > 30)
|
||||
return//Inf loop check
|
||||
|
||||
//Looking for another blob to pulse
|
||||
var/list/dirs = list(1,2,4,8)
|
||||
dirs.Remove(origin_dir)//Dont pulse the guy who pulsed us
|
||||
for(var/i = 1 to 4)
|
||||
if(!dirs.len)
|
||||
break
|
||||
var/dirn = pick(dirs)
|
||||
dirs.Remove(dirn)
|
||||
var/turf/T = get_step(src, dirn)
|
||||
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
|
||||
if(!B)
|
||||
expand(T,1,a_color)//No blob here so try and expand
|
||||
return
|
||||
B.adjustcolors(a_color)
|
||||
|
||||
B.Pulse((pulse+1),get_dir(src.loc,T), a_color)
|
||||
return
|
||||
flick("[icon_state]_glow", src)
|
||||
return
|
||||
|
||||
/obj/effect/blob/proc/RegenHealth() //when pulsed, heal!
|
||||
if(health_timestamp <= world.time)
|
||||
health = min(maxhealth, health+health_regen)
|
||||
update_icon()
|
||||
health_timestamp = world.time + 10 //1 second between heals
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/effect/blob/proc/run_action()
|
||||
return 0
|
||||
|
||||
|
||||
/obj/effect/blob/proc/expand(turf/T = null, prob = 1, a_color)
|
||||
if(prob && !prob(health)) return
|
||||
/obj/effect/blob/proc/expand(turf/T = null, prob = 1, controller = null)
|
||||
if(prob && !prob(health))
|
||||
return
|
||||
if(!T)
|
||||
var/list/dirs = list(1,2,4,8)
|
||||
for(var/i = 1 to 4)
|
||||
@@ -157,20 +151,23 @@
|
||||
T = null
|
||||
if(!T)
|
||||
return 0
|
||||
var/Blob_spawnable = 1
|
||||
var/make_blob = 1 //can we make a blob?
|
||||
if(istype(T, /turf/space) && prob(65))
|
||||
Blob_spawnable = 0
|
||||
make_blob = 0
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) //Let's give some feedback that we DID try to spawn in space, since players are used to it
|
||||
for(var/atom/A in T)
|
||||
if(A.density) //Unless density is 0, don't spawn a blob
|
||||
Blob_spawnable = 0
|
||||
if(A.density)
|
||||
make_blob = 0
|
||||
A.blob_act() //Hit everything
|
||||
if(T.density) //Check for walls and such dense turfs
|
||||
Blob_spawnable = 0
|
||||
make_blob = 0
|
||||
T.blob_act() //Hit the turf
|
||||
if(Blob_spawnable)
|
||||
if(make_blob) //well, can we?
|
||||
var/obj/effect/blob/B = new /obj/effect/blob/normal(src.loc)
|
||||
B.color = a_color
|
||||
if(controller)
|
||||
B.overmind = controller
|
||||
else
|
||||
B.overmind = overmind
|
||||
B.density = 1
|
||||
if(T.Enter(B,src)) //NOW we can attempt to move into the tile
|
||||
B.density = initial(B.density)
|
||||
@@ -240,25 +237,19 @@
|
||||
if(controller)
|
||||
B.overmind = controller
|
||||
B.creation_action()
|
||||
B.adjustcolors(color)
|
||||
B.update_icon()
|
||||
qdel(src)
|
||||
return B
|
||||
|
||||
/obj/effect/blob/proc/adjustcolors(a_color)
|
||||
if(a_color)
|
||||
color = a_color
|
||||
return
|
||||
|
||||
/obj/effect/blob/examine(mob/user)
|
||||
..()
|
||||
user << "It seems to be made of [get_chem_name()]."
|
||||
return
|
||||
|
||||
/obj/effect/blob/proc/get_chem_name()
|
||||
for(var/mob/camera/blob/B in mob_list)
|
||||
if(lowertext(B.blob_reagent_datum.color) == lowertext(src.color)) // Goddamit why we use strings for these
|
||||
return B.blob_reagent_datum.name
|
||||
return "unknown"
|
||||
if(overmind)
|
||||
return overmind.blob_reagent_datum.name
|
||||
return "an unknown variant"
|
||||
|
||||
/obj/effect/blob/normal
|
||||
icon_state = "blob"
|
||||
@@ -269,6 +260,7 @@
|
||||
brute_resist = 4
|
||||
|
||||
/obj/effect/blob/normal/update_icon()
|
||||
..()
|
||||
if(health <= 10)
|
||||
icon_state = "blob_damaged"
|
||||
name = "fragile blob"
|
||||
|
||||
@@ -2,29 +2,11 @@
|
||||
|
||||
/datum/game_mode
|
||||
var/list/datum/mind/cult = list()
|
||||
var/list/cult_objectives = list()
|
||||
|
||||
|
||||
/proc/iscultist(mob/living/M)
|
||||
return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.cult)
|
||||
|
||||
/proc/is_sacrifice_target(datum/mind/mind)
|
||||
if(ticker.mode.name == "cult")
|
||||
var/datum/game_mode/cult/cult_mode = ticker.mode
|
||||
if(mind == cult_mode.sacrifice_target)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/is_convertable_to_cult(datum/mind/mind)
|
||||
if(!istype(mind)) return 0
|
||||
if(istype(mind.current, /mob/living/carbon/human) && (mind.assigned_role in list("Captain", "Chaplain"))) return 0
|
||||
if(isloyal(mind.current))
|
||||
return 0
|
||||
if (ticker.mode.name == "cult") //redundent?
|
||||
if(is_sacrifice_target(mind)) return 0
|
||||
return 1
|
||||
|
||||
/proc/cultist_commune(mob/living/user, clear = 0, say = 0, message)
|
||||
/proc/cultist_commune(mob/living/user, say = 0, message)
|
||||
if(!message)
|
||||
return
|
||||
if(say)
|
||||
@@ -40,10 +22,7 @@
|
||||
user.whisper(message)
|
||||
for(var/mob/M in mob_list)
|
||||
if(iscultist(M) || (M in dead_mob_list))
|
||||
if(clear || !ishuman(user))
|
||||
M << "<span class='cultitalic'><b>[(ishuman(user) ? "Acolyte" : "Construct")] [user]:</b> [message]</span>"
|
||||
else //Emergency comms
|
||||
M << "<span class='purple'><i>Acolyte ???:</i> <b>[message]</b></span>"
|
||||
M << "<span class='cultitalic'><b>[(ishuman(user) ? "Acolyte" : "Construct")] [user]:</b> [message]</span>"
|
||||
log_say("[user.real_name]/[user.key] : [message]")
|
||||
|
||||
|
||||
@@ -54,42 +33,31 @@
|
||||
antag_flag = ROLE_CULTIST
|
||||
restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel")
|
||||
protected_jobs = list()
|
||||
required_players = 20
|
||||
required_enemies = 4
|
||||
recommended_enemies = 4
|
||||
required_players = 10
|
||||
required_enemies = 2
|
||||
recommended_enemies = 2
|
||||
enemy_minimum_age = 14
|
||||
|
||||
|
||||
var/finished = 0
|
||||
|
||||
var/eldergod = 1 //for the summon god objective
|
||||
|
||||
var/acolytes_needed = 10 //for the survive objective
|
||||
var/acolytes_survived = 0
|
||||
|
||||
var/datum/mind/sacrifice_target = null//The target to be sacrificed
|
||||
|
||||
var/eldergod = 0
|
||||
var/orbs_needed = 3
|
||||
var/large_shell_summoned = 0
|
||||
var/attempts_left = 3
|
||||
|
||||
/datum/game_mode/cult/announce()
|
||||
world << "<B>The current game mode is - Cult!</B>"
|
||||
world << "<B>Some crewmembers are attempting to start a cult!<BR>\nCultists - complete your objectives. Convert crewmembers to your cause by using the convert rune. Remember - there is no you, there is only the cult.<BR>\nPersonnel - Do not let the cult succeed in its mission. Brainwashing them with the chaplain's bible reverts them to whatever Centcom-allowed faith they had.</B>"
|
||||
world << "<B>Some crewmembers are attempting to start a cult!<BR>\nCultists - summon the elder god. Sacrifice crewmembers and turn them into constructs. Remember - there is no you, there is only the cult.<BR>\nPersonnel - Do not let the cult succeed in its mission. Deal with the cultists and any constructs that they might summon.</B>"
|
||||
|
||||
|
||||
/datum/game_mode/cult/pre_setup()
|
||||
cult_objectives += "sacrifice"
|
||||
if(prob(50))
|
||||
cult_objectives += "survive"
|
||||
else
|
||||
cult_objectives += "eldergod"
|
||||
|
||||
if(config.protect_roles_from_antagonist)
|
||||
restricted_jobs += protected_jobs
|
||||
|
||||
if(config.protect_assistant_from_antagonist)
|
||||
restricted_jobs += "Assistant"
|
||||
|
||||
acolytes_needed = round(num_players()/5,1) //Scales the escape requirement with the amount of people in the round; for every 5 players, one cultist added to the count, i.e. 25 players = 5 to escape
|
||||
acolytes_needed = Clamp(acolytes_needed, 1, 15) //Max at 15 and minimum at 1 - before the update, people rarely got even 15
|
||||
//cult scaling goes here
|
||||
recommended_enemies = 1 + round(num_players()/8)
|
||||
orbs_needed = recommended_enemies
|
||||
|
||||
for(var/cultists_number = 1 to recommended_enemies)
|
||||
if(!antag_candidates.len)
|
||||
@@ -106,22 +74,6 @@
|
||||
|
||||
/datum/game_mode/cult/post_setup()
|
||||
modePlayer += cult
|
||||
if("sacrifice" in cult_objectives)
|
||||
var/list/possible_targets = get_unconvertables()
|
||||
|
||||
if(!possible_targets.len)
|
||||
message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.")
|
||||
for(var/mob/living/carbon/human/player in player_list)
|
||||
if(player.mind && !(player.mind in cult))
|
||||
possible_targets += player.mind
|
||||
|
||||
if(possible_targets.len > 0)
|
||||
sacrifice_target = pick(possible_targets)
|
||||
if(!sacrifice_target)
|
||||
message_admins("Cult Sacrifice: ERROR - Null target chosen!")
|
||||
else
|
||||
message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!")
|
||||
|
||||
for(var/datum/mind/cult_mind in cult)
|
||||
equip_cultist(cult_mind.current)
|
||||
update_cult_icons_added(cult_mind)
|
||||
@@ -131,20 +83,7 @@
|
||||
|
||||
|
||||
/datum/game_mode/cult/proc/memorize_cult_objectives(datum/mind/cult_mind)
|
||||
for(var/obj_count = 1,obj_count <= cult_objectives.len,obj_count++)
|
||||
var/explanation
|
||||
switch(cult_objectives[obj_count])
|
||||
if("survive")
|
||||
explanation = "Our knowledge must live on. Make sure at least [acolytes_needed] acolytes escape on the shuttle to spread their work on an another station."
|
||||
if("sacrifice")
|
||||
if(sacrifice_target)
|
||||
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. You will need the Sacrifice rune and three acolytes to do so."
|
||||
else
|
||||
explanation = "Free objective."
|
||||
if("eldergod")
|
||||
explanation = "Summon Nar-Sie via the rune 'Call Forth The Geometer'. It will only work if nine acolytes stand on and around it."
|
||||
cult_mind.current << "<B>Objective #[obj_count]</B>: [explanation]"
|
||||
cult_mind.memory += "<B>Objective #[obj_count]</B>: [explanation]<BR>"
|
||||
cult_mind.current << "Your objective is to summon Nar-Sie by building and defending a suitable shell for the Geometer. Adequate supplies can be procured through human sacrifices."
|
||||
|
||||
/datum/game_mode/proc/equip_cultist(mob/living/carbon/human/mob)
|
||||
if(!istype(mob))
|
||||
@@ -155,20 +94,27 @@
|
||||
mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself."
|
||||
mob.dna.remove_mutation(CLOWNMUT)
|
||||
|
||||
. += cult_give_item(/obj/item/weapon/tome, mob)
|
||||
. += cult_give_item(/obj/item/weapon/paper/talisman/supply, mob)
|
||||
. += cult_give_item(/obj/item/weapon/melee/cultblade/dagger, mob)
|
||||
mob << "These will help you start the cult on this station. Use them well, and remember - you are not the only one.</span>"
|
||||
|
||||
var/obj/item/weapon/paper/talisman/supply/T = new(mob)
|
||||
var/list/slots = list (
|
||||
/datum/game_mode/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob)
|
||||
var/list/slots = list(
|
||||
"backpack" = slot_in_backpack,
|
||||
"left pocket" = slot_l_store,
|
||||
"right pocket" = slot_r_store,
|
||||
"left hand" = slot_l_hand,
|
||||
"right hand" = slot_r_hand,
|
||||
)
|
||||
var/T = new item_path(mob)
|
||||
var/item_name = initial(item_path.name)
|
||||
var/where = mob.equip_in_one_of_slots(T, slots)
|
||||
if(!where)
|
||||
mob << "Unfortunately, you weren't able to get a talisman. This is very bad and you should adminhelp immediately."
|
||||
mob << "<span class='userdanger'>Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1).</span>"
|
||||
return 0
|
||||
else
|
||||
mob << "<span class='danger'>You have a talisman in your [where], one that will help you start the cult on this station. Use it well, and remember - you are not the only one.</span>"
|
||||
mob << "<span class='danger'>You have a [item_name] in your [where]."
|
||||
mob.update_icons()
|
||||
if(where == "backpack")
|
||||
var/obj/item/weapon/storage/B = mob.back
|
||||
@@ -176,20 +122,18 @@
|
||||
B.show_to(mob)
|
||||
return 1
|
||||
|
||||
|
||||
/datum/game_mode/proc/add_cultist(datum/mind/cult_mind) //BASE
|
||||
if (!istype(cult_mind))
|
||||
if (!istype(cult_mind) || (cult_mind in cult))
|
||||
return 0
|
||||
if(!(cult_mind in cult) && is_convertable_to_cult(cult_mind))
|
||||
cult_mind.current.Paralyse(5)
|
||||
cult += cult_mind
|
||||
cult_mind.current.faction |= "cult"
|
||||
cult_mind.current.cult_add_comm()
|
||||
update_cult_icons_added(cult_mind)
|
||||
cult_mind.current.attack_log += "\[[time_stamp()]\] <span class='danger'>Has been converted to the cult!</span>"
|
||||
if(jobban_isbanned(cult_mind.current, ROLE_CULTIST))
|
||||
replace_jobbaned_player(cult_mind.current, ROLE_CULTIST, ROLE_CULTIST)
|
||||
return 1
|
||||
cult_mind.current.Paralyse(5)
|
||||
cult += cult_mind
|
||||
cult_mind.current.faction |= "cult"
|
||||
cult_mind.current.cult_add_comm()
|
||||
update_cult_icons_added(cult_mind)
|
||||
cult_mind.current.attack_log += "\[[time_stamp()]\] <span class='danger'>Has been converted to the cult!</span>"
|
||||
if(jobban_isbanned(cult_mind.current, ROLE_CULTIST))
|
||||
replace_jobbaned_player(cult_mind.current, ROLE_CULTIST, ROLE_CULTIST)
|
||||
return 1
|
||||
|
||||
|
||||
/datum/game_mode/cult/add_cultist(datum/mind/cult_mind) //INHERIT
|
||||
@@ -222,85 +166,13 @@
|
||||
culthud.leave_hud(cult_mind.current)
|
||||
set_antag_hud(cult_mind.current, null)
|
||||
|
||||
/datum/game_mode/cult/proc/get_unconvertables()
|
||||
var/list/ucs = list()
|
||||
for(var/mob/living/carbon/human/player in player_list)
|
||||
if(player.mind && !is_convertable_to_cult(player.mind))
|
||||
ucs += player.mind
|
||||
return ucs
|
||||
|
||||
|
||||
/datum/game_mode/cult/proc/check_cult_victory()
|
||||
var/cult_fail = 0
|
||||
if(cult_objectives.Find("survive"))
|
||||
cult_fail += check_survive() //the proc returns 1 if there are not enough cultists on the shuttle, 0 otherwise
|
||||
if(cult_objectives.Find("eldergod"))
|
||||
cult_fail += eldergod //1 by default, 0 if the elder god has been summoned at least once
|
||||
if(cult_objectives.Find("sacrifice"))
|
||||
if(sacrifice_target && !sacrificed.Find(sacrifice_target)) //if the target has been sacrificed, ignore this step. otherwise, add 1 to cult_fail
|
||||
cult_fail++
|
||||
|
||||
return cult_fail //if any objectives aren't met, failure
|
||||
|
||||
|
||||
/datum/game_mode/cult/proc/check_survive()
|
||||
acolytes_survived = 0
|
||||
for(var/datum/mind/cult_mind in cult)
|
||||
if (cult_mind.current && cult_mind.current.stat != DEAD)
|
||||
if(cult_mind.current.onCentcom() || cult_mind.current.onSyndieBase())
|
||||
acolytes_survived++
|
||||
if(acolytes_survived>=acolytes_needed)
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
|
||||
/datum/game_mode/cult/declare_completion()
|
||||
|
||||
if(!check_cult_victory())
|
||||
if(eldergod)
|
||||
feedback_set_details("round_end_result","win - cult win")
|
||||
feedback_set("round_end_result",acolytes_survived)
|
||||
world << "<span class='greentext'>The cult wins! It has succeeded in serving its dark master!</span>"
|
||||
else
|
||||
feedback_set_details("round_end_result","loss - staff stopped the cult")
|
||||
feedback_set("round_end_result",acolytes_survived)
|
||||
world << "<span class='redtext'>The staff managed to stop the cult!</span>"
|
||||
|
||||
var/text = ""
|
||||
|
||||
if(cult_objectives.len)
|
||||
text += "<br><b>The cultists' objectives were:</b>"
|
||||
for(var/obj_count=1, obj_count <= cult_objectives.len, obj_count++)
|
||||
var/explanation
|
||||
switch(cult_objectives[obj_count])
|
||||
if("survive")
|
||||
if(!check_survive())
|
||||
explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) <span class='greenannounce'>Success!</span>"
|
||||
feedback_add_details("cult_objective","cult_survive|SUCCESS|[acolytes_needed]")
|
||||
else
|
||||
explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) <span class='boldannounce'>Fail.</span>"
|
||||
feedback_add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]")
|
||||
if("sacrifice")
|
||||
if(sacrifice_target)
|
||||
if(sacrifice_target in sacrificed)
|
||||
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. <span class='greenannounce'>Success!</span>"
|
||||
feedback_add_details("cult_objective","cult_sacrifice|SUCCESS")
|
||||
else if(sacrifice_target && sacrifice_target.current)
|
||||
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. <span class='boldannounce'>Fail.</span>"
|
||||
feedback_add_details("cult_objective","cult_sacrifice|FAIL")
|
||||
else
|
||||
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. <span class='boldannounce'>Fail (Gibbed).</span>"
|
||||
feedback_add_details("cult_objective","cult_sacrifice|FAIL|GIBBED")
|
||||
if("eldergod")
|
||||
if(!eldergod)
|
||||
explanation = "Summon Nar-Sie. <span class='greenannounce'>Success!</span>"
|
||||
feedback_add_details("cult_objective","cult_narsie|SUCCESS")
|
||||
else
|
||||
explanation = "Summon Nar-Sie. <span class='boldannounce'>Fail.</span>"
|
||||
feedback_add_details("cult_objective","cult_narsie|FAIL")
|
||||
text += "<br><B>Objective #[obj_count]</B>: [explanation]"
|
||||
|
||||
world << text
|
||||
..()
|
||||
return 1
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
icon_state = "cultblade"
|
||||
item_state = "cultblade"
|
||||
flags = CONDUCT
|
||||
sharpness = IS_SHARP
|
||||
w_class = 4
|
||||
force = 30
|
||||
throwforce = 10
|
||||
@@ -31,6 +32,21 @@
|
||||
user << "<span class='warning'>An overwhelming sense of nausea overpowers you!</span>"
|
||||
user.Dizzy(120)
|
||||
|
||||
/obj/item/weapon/melee/cultblade/dagger
|
||||
name = "sacrificial dagger"
|
||||
desc = "A strange dagger said to be used by sinister groups for \"preparing\" a corpse before sacrificing it to their dark gods."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "render"
|
||||
w_class = 2
|
||||
force = 15
|
||||
throwforce = 25
|
||||
embed_chance = 75
|
||||
|
||||
/obj/item/weapon/melee/cultblade/dagger/attack(mob/living/target, mob/living/carbon/human/user)
|
||||
..()
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
H.drip(50)
|
||||
|
||||
/obj/item/clothing/head/culthood
|
||||
name = "ancient cultist hood"
|
||||
@@ -108,3 +124,52 @@
|
||||
w_class = 3
|
||||
allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/internals/)
|
||||
armor = list(melee = 70, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
|
||||
/obj/item/summoning_orb
|
||||
name = "summoning orb"
|
||||
desc = "A mysterious orb that glows eerily. <span class='cult'>You could swear that it just moved on its own.</span>"
|
||||
icon = 'icons/obj/cult.dmi'
|
||||
icon_state = "summoning_orb"
|
||||
w_class = 1
|
||||
|
||||
/obj/item/summoning_orb/afterattack(atom/target, mob/user, proximity_flag)
|
||||
if(!iscultist(user))
|
||||
return ..()
|
||||
if(proximity_flag && isliving(target) && iscultist(target))
|
||||
var/mob/living/L = target
|
||||
if(L.stat == DEAD)
|
||||
user << "<span class='cultlarge'>You shouldn't waste that.</span>"
|
||||
return ..()
|
||||
target << "<span class='cult'>You feel the Geometer's essence violating your insides.</span>"
|
||||
target << "<span class='cult'>It feels... </span><span class='cultitalic'>good.</span>"
|
||||
target.reagents.add_reagent("unholywater", 15)
|
||||
qdel(src)
|
||||
..()
|
||||
|
||||
/obj/item/summoning_orb/attack_self(mob/user)
|
||||
if(!iscultist(user))
|
||||
return ..()
|
||||
if(ticker.mode.name != "cult")
|
||||
return
|
||||
var/datum/game_mode/cult/cult = ticker.mode
|
||||
if(!cult.attempts_left)
|
||||
user << "<span class='notice'>You attempt to call out to the Geometer, but there is no answer...</span>"
|
||||
return
|
||||
switch(alert(user,"Are you sure you wish to summon the large construct shell? [cult.attempts_left] attempts left!","Summoning Large Shell","Yes","No"))
|
||||
if("Yes")
|
||||
cult.attempts_left--
|
||||
place_down_large_shell(user)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/summoning_orb/proc/place_down_large_shell(mob/user)
|
||||
if(!(ticker.mode.name == "cult"))
|
||||
user << "<span class='notice'>You attempt to call out to the Geometer for Her shell, but you fail...</span>"
|
||||
return
|
||||
var/datum/game_mode/cult/cult = ticker.mode
|
||||
if(cult.large_shell_summoned)
|
||||
user << "<span class='cult'>Another Acolyte has already summoned Her shell. You must go forth and contact them.</span>"
|
||||
return
|
||||
if(cult.attempts_left <= 0)
|
||||
user << "<span class='cultlarge'>The Geometer is no longer interested in you.</span>"
|
||||
new /obj/structure/constructshell/large(get_turf(src))
|
||||
cult.large_shell_summoned = 1
|
||||
|
||||
@@ -1,3 +1,148 @@
|
||||
/obj/structure/constructshell/large
|
||||
name = "large empty shell"
|
||||
icon = 'icons/obj/cult_large.dmi'
|
||||
icon_state = "shell_narsie_grey"
|
||||
desc = "An oversized construct shell, fit for an elder god. Only a lunatic would even dream of such a crazed contraption."
|
||||
pixel_x = -16
|
||||
pixel_y = -16
|
||||
density = 1
|
||||
anchored = 0
|
||||
var/maxhealth = 200
|
||||
var/health = 200
|
||||
var/image/black_overlay = null
|
||||
var/orbs = 0
|
||||
var/orbs_needed = 1
|
||||
var/time_to_win = 1800 //3 minutes
|
||||
var/timer_id = null
|
||||
|
||||
/obj/structure/constructshell/large/New()
|
||||
..()
|
||||
if(ticker.mode.name == "cult")
|
||||
var/datum/game_mode/cult/cult = ticker.mode
|
||||
orbs_needed = cult.orbs_needed
|
||||
black_overlay = image('icons/obj/cult_large.dmi', "shell_narsie_black")
|
||||
|
||||
/obj/structure/constructshell/large/Destroy()
|
||||
priority_announce("The extra-dimensional flow has ceased. All personnel should return to their routine activities.","Central Command Higher Dimensions Affairs")
|
||||
if(get_security_level() == "delta")
|
||||
set_security_level("red")
|
||||
if(ticker.mode.name == "cult")
|
||||
var/datum/game_mode/cult/cult = ticker.mode
|
||||
cult.large_shell_summoned = 0
|
||||
black_overlay = null
|
||||
if(timer_id)
|
||||
deltimer(timer_id)
|
||||
..()
|
||||
|
||||
/obj/structure/constructshell/large/examine(mob/user)
|
||||
..()
|
||||
user << "<span class='cult'>You see a number of round holes on the surface of the shell. They number [orbs_needed], and [orbs ? orbs : "none"] of them [orbs > 1 ? "are" : "is"] filled.</span>"
|
||||
|
||||
/obj/structure/constructshell/large/update_icon()
|
||||
var/new_alpha = round((orbs/orbs_needed)*255)
|
||||
if(new_alpha)
|
||||
overlays -= black_overlay
|
||||
black_overlay.alpha = new_alpha
|
||||
overlays += black_overlay
|
||||
|
||||
/obj/structure/constructshell/large/attackby(obj/item/O, mob/user, params)
|
||||
if(istype(O, /obj/item/summoning_orb) && (orbs < orbs_needed))
|
||||
if(!iscultist(user))
|
||||
return
|
||||
visible_message("<span class='cult'>\The [src] glows.</span>")
|
||||
orbs++
|
||||
qdel(O)
|
||||
update_icon()
|
||||
if(orbs >= orbs_needed)
|
||||
start_takeover()
|
||||
return
|
||||
|
||||
if( (O.flags&NOBLUDGEON) || !O.force )
|
||||
return
|
||||
add_fingerprint(user)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.do_attack_animation(src)
|
||||
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
|
||||
visible_message("<span class='danger'>[user] has hit \the [src] with [O].</span>")
|
||||
if(O.damtype == BURN || O.damtype == BRUTE)
|
||||
damaged(O.force)
|
||||
|
||||
//this stuff is mostly copy-pasted from gang dominators, with some changes
|
||||
/obj/structure/constructshell/large/proc/start_takeover()
|
||||
anchored = 1
|
||||
animate(black_overlay, alpha = 255, 5, -1)
|
||||
set_security_level("delta")
|
||||
var/area/A = get_area(src)
|
||||
var/locname = initial(A.name)
|
||||
priority_announce("Figments from an eldritch god have begun pouring into [locname] from an unknown dimension. Eliminate its vessel before it reaches a critical point.","Central Command Higher Dimensions Affairs")
|
||||
timer_id = addtimer(src, "summon_narnar", time_to_win)
|
||||
|
||||
/obj/structure/constructshell/large/proc/damaged(damage)
|
||||
health -= damage
|
||||
if(health <= 0)
|
||||
new /obj/item/stack/sheet/plasteel(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/constructshell/large/bullet_act(obj/item/projectile/P)
|
||||
if(P.damage)
|
||||
playsound(src, 'sound/effects/bang.ogg', 50, 1)
|
||||
visible_message("<span class='danger'>[src] was hit by [P].</span>")
|
||||
damaged(P.damage)
|
||||
|
||||
/obj/structure/constructshell/large/attack_alien(mob/living/user)
|
||||
user.do_attack_animation(src)
|
||||
playsound(src, 'sound/effects/bang.ogg', 50, 1)
|
||||
user.visible_message("<span class='danger'>[user] smashes against [src] with its claws.</span>",\
|
||||
"<span class='danger'>You smash against [src] with your claws.</span>")
|
||||
damaged(15)
|
||||
|
||||
/obj/structure/constructshell/large/attack_animal(mob/living/user)
|
||||
if(!isanimal(user))
|
||||
return
|
||||
var/mob/living/simple_animal/M = user
|
||||
M.do_attack_animation(src)
|
||||
if(M.melee_damage_upper <= 0)
|
||||
return
|
||||
damaged(M.melee_damage_upper)
|
||||
|
||||
/obj/structure/constructshell/large/mech_melee_attack(obj/mecha/M)
|
||||
if(M.damtype == "brute")
|
||||
playsound(src, 'sound/effects/bang.ogg', 50, 1)
|
||||
visible_message("<span class='danger'>[M.name] has hit [src].</span>")
|
||||
damaged(M.force)
|
||||
|
||||
/obj/structure/constructshell/large/attack_hulk(mob/user)
|
||||
playsound(src, 'sound/effects/bang.ogg', 50, 1)
|
||||
user.visible_message("<span class='danger'>[user] smashes [src].</span>",\
|
||||
"<span class='danger'>You punch [src].</span>")
|
||||
damaged(5)
|
||||
|
||||
/obj/structure/constructshell/large/ex_act()
|
||||
return //nope
|
||||
|
||||
/obj/structure/constructshell/large/singularity_pull()
|
||||
return //nope
|
||||
|
||||
/obj/structure/constructshell/large/singularity_act(current_size, obj/singularity/S)
|
||||
var/atom/target = get_edge_target_turf(src, get_dir(src, S))
|
||||
S.throw_at(target, 5, 1) //aaand nope
|
||||
|
||||
/obj/structure/constructshell/large/proc/summon_narnar()
|
||||
if(ticker.mode.name != "cult")
|
||||
visible_message("<span class='warning'>\The [src] glows brightly once, then falls dark. It looks strangely dull and lifeless...</span>")
|
||||
log_game("Summon Nar-Sie rune failed - gametype is not cult")
|
||||
return
|
||||
var/datum/game_mode/cult/cult_mode = ticker.mode
|
||||
if(cult_mode.eldergod)
|
||||
return //this should never happen, so we don't need any special fluff
|
||||
world << 'sound/effects/dimensional_rend.ogg'
|
||||
world << "<span class='cultitalic'><b>Rip... <span class='big'>Rrrip...</span> <span class='reallybig'>RRRRRRRRRR--</span></b></span>"
|
||||
var/turf/target_turf = get_turf(src)
|
||||
spawn(40)
|
||||
new /obj/singularity/narsie/large(target_turf) //Causes Nar-Sie to spawn even if the rune has been removed
|
||||
cult_mode.eldergod = 1
|
||||
|
||||
|
||||
/obj/structure/cult
|
||||
density = 1
|
||||
anchored = 1
|
||||
@@ -8,7 +153,6 @@
|
||||
desc = "A bloodstained altar dedicated to Nar-Sie"
|
||||
icon_state = "talismanaltar"
|
||||
|
||||
|
||||
/obj/structure/cult/forge
|
||||
name = "daemon forge"
|
||||
desc = "A forge used in crafting the unholy weapons used by the armies of Nar-Sie"
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
/*
|
||||
|
||||
This file contains the arcane tome files as well as innate cultist emergency communications.
|
||||
It also contains rune words, which are soon to be removed.
|
||||
|
||||
*/
|
||||
|
||||
@@ -12,7 +9,7 @@ It also contains rune words, which are soon to be removed.
|
||||
|
||||
/mob/living/proc/cult_innate_comm()
|
||||
set category = "Cultist"
|
||||
set name = "Imperfect Communion"
|
||||
set name = "Communion"
|
||||
|
||||
if(!iscultist(usr)) //they shouldn't have this verb, but just to be sure...
|
||||
return
|
||||
@@ -24,24 +21,7 @@ It also contains rune words, which are soon to be removed.
|
||||
if(!input) // TO-DO: Add some kind of filter to corrupt the inputted text
|
||||
return
|
||||
|
||||
if(ishuman(usr) || ismonkey(usr)) //Damage only applies to humans and monkeys, to allow constructs to communicate
|
||||
usr.visible_message("<span class='warning'>[usr] starts clawing at \his arms with \his fingernails!</span>", "<span class='cultitalic'>You begin slicing open your arms with your fingernails!</span>")
|
||||
apply_damage(10,BRUTE, "l_arm")
|
||||
apply_damage(10,BRUTE, "r_arm")
|
||||
sleep(50)
|
||||
if(usr.incapacitated())
|
||||
return //Hard to drawn intrinsic symbols when you're bleeding out in your cell.
|
||||
var/turf/location = loc
|
||||
if(istype(location, /turf/simulated)) // tearing your arms apart is going to spill a bit of blood, in fact thats the idea
|
||||
location.add_blood(usr) // TO-DO change this to a badly drawn rune
|
||||
apply_damage(10,BRUTE, "l_arm") // does a metric fuck ton of damage because this meant to be an emergency method of communication.
|
||||
apply_damage(10,BRUTE, "r_arm")
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
usr.visible_message("<span class='warning'>[usr] paints strange symbols with their own blood.</span>", "<span class='cultitalic'>You paint a messy rune with your own blood.</span>")
|
||||
sleep(20)
|
||||
|
||||
cultist_commune(usr, 0, 1, input)
|
||||
cultist_commune(usr, 0, input)
|
||||
return
|
||||
|
||||
|
||||
@@ -52,6 +32,13 @@ It also contains rune words, which are soon to be removed.
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = 2
|
||||
var/list/known_runes = null
|
||||
|
||||
/obj/item/weapon/tome/New()
|
||||
..()
|
||||
known_runes = shuffle(subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed)
|
||||
var/known_amount = round((known_runes.len)/2)
|
||||
known_runes.Cut(known_amount)
|
||||
|
||||
/obj/item/weapon/tome/examine(mob/user)
|
||||
..()
|
||||
@@ -92,47 +79,20 @@ It also contains rune words, which are soon to be removed.
|
||||
open_tome(user)
|
||||
|
||||
/obj/item/weapon/tome/proc/open_tome(mob/user)
|
||||
var/choice = alert(user,"You open the tome...",,"Commune","Scribe Rune","Read Tome")
|
||||
var/choice = alert(user,"You open the tome...",,"Scribe Rune","Read Tome")
|
||||
switch(choice)
|
||||
if("Read Tome")
|
||||
read_tome(user)
|
||||
if("Scribe Rune")
|
||||
scribe_rune(user)
|
||||
if("Commune")
|
||||
var/input = stripped_input(usr, "Please enter a message to tell to the other acolytes.", "Voice of Blood", "")
|
||||
if(!input)
|
||||
return
|
||||
cultist_commune(user, 1, 0, input)
|
||||
|
||||
/obj/item/weapon/tome/proc/read_tome(mob/user)
|
||||
var/text = ""
|
||||
text += "<center><font color='red' size=3><b><i>Archives of the Dark One</i></b></font></center><br><br><br>"
|
||||
text += "As a member of the cult, your goals are almost or entirely impossible to complete without special aid from the Geometer's plane. The primary method of doing this are <b>runes</b>. These \
|
||||
scribings, drawn in blood, are concentrated nodes of the magic within Nar-Sie's realm and will allow the performance of many tasks to aid you and the rest of the cult in your objectives. Runes \
|
||||
have many different names, and almost all of them are known as Rites. The only rune that is not a Rite is the Ritual of Dimensional Rending, which can only be performed with nine cultists and calls \
|
||||
forth the avatar of the Geometer herself (so long as she consents). A small description of each rune can be found below.<br><br>A rune's name and effects can be \
|
||||
revealed by examining the rune.<br><br><br>"/*In order to write a rune, you must know the combination of words required for the rune. These words are in the tongue of the Geometer and must be written as such. \
|
||||
A rune will always have a specific combination, and the combination for runes may be revealed by perfomring actions such as conversion or sacrifice. Once a rune has been written, any cultists can \
|
||||
examine it to find out its \"grammar\", or the words required to scribe it. To scribe the rune, the words must be entered in lowercase and separated by exactly one space. For instance, to draw a \
|
||||
Rite of Enlightenment, one would enter the sentence \"certum nahlizet ego\", which means \"join blood self\". You may guess at combinations or perform actions to discover them.<br><br>A full list of \
|
||||
the Words of Power as well as their meanings in plain English are listed below, although a more complete archive may be accessed at a research desk.<br><br>\
|
||||
<b>The Words of Power</b><br>\
|
||||
\"ire\" is Travel<br>\
|
||||
\"ego\" is Self<br>\
|
||||
\"nahlizet\" is Blood<br>\
|
||||
\"certum\" is Join<br>\
|
||||
\"veri\" is Hell<br>\
|
||||
\"jatkaa\" is Other<br>\
|
||||
\"mgar\" is Destroy<br>\
|
||||
\"balaq\" is Technology<br>\
|
||||
\"karazet\" is See<br>\
|
||||
\"geeri\" is Hide<br><br>\
|
||||
<b>A few basic runes</b><br>\
|
||||
<i>Rite of Translocation:</i> \"ire ego\"<br>\
|
||||
<i>Rite of Enlightenment:</i> \"certum nahlizet ego\"<br>\
|
||||
<i>Rite of Tribute:</i> \"veri nahlizet certum\"<br>\
|
||||
<i>Rite of Knowledge:</i> \"karazet nahlizet ego\"<br>\
|
||||
<br><br><br>"*/
|
||||
have many different names, and almost all of them are known as Rites. Each follower of the Geometer is only able to use a subset of these, thus you must go forth and meet your fellow followers. \
|
||||
A small description of each rune can be found below.<br><br>A rune's name and effects can be revealed by examining the rune. <br><br><br>"
|
||||
|
||||
text += "<font color='red'><b>Teleport</b></font><br>The Rite of Translocation is a unique rite in that it requires a keyword before the scribing can begin. When invoked, the rune will \
|
||||
search for other Rites of Translocation with the same keyword. Assuming one is found, the user will be instantaneously transported to the location of the other rune. If more than two runes are scribed \
|
||||
@@ -141,13 +101,6 @@ It also contains rune words, which are soon to be removed.
|
||||
text += "<font color='red'><b>Teleport Other</b></font><br>The Rite of Forced Translocation, like the Rite of Translocation, works by teleporting the person on the rune to one of the \
|
||||
same keyword. However, this rune will only work on people other than the user, allowing the user to send any living creature somewhere else.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Summon Tome</b></font><br>The Rite of Knowledge is a simplistic rune. When invoked, it will summon a single arcane tome to the rune's location before vanishing. \
|
||||
<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Convert</b></font><br>The Rite of Enlightment is paramount to the success of the cult. It will allow you to convert normal crew members into cultists. \
|
||||
To do this, simply place the crew member upon the rune and invoke it. This rune requires two acolytes to use. If the target to be converted is loyalty-implanted or a certain assignment, they will \
|
||||
be unable to be converted. People the Geometer wishes sacrificed will also be ineligible for conversion, and anyone with a shielding presence like the null rod will not be converted.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Sacrifice</b></font><br>The Rite of Tribute is used to offer sacrifice to the Geometer. Simply place any living creature upon the rune and invoke it (this will not \
|
||||
target cultists!). If this creature has a mind, a soul shard will be created and the creature's soul transported to it. This rune is required if the cult's objectives include the sacrifice of a crew \
|
||||
member.<br><br>"
|
||||
@@ -157,14 +110,7 @@ It also contains rune words, which are soon to be removed.
|
||||
within a few seconds, they will be brought back to life, healed of all ailments.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Veil Runes</b></font><br>The Rite of Obscurity is a rite that will cause all nearby runes to become invisible. The runes will still be considered by other rites \
|
||||
(such as the Rite of Translocation) but will be unusuable directly.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Reveal Runes</b></font><br>The Rite of True Sight is the foil of the Rite of Obscurity. It will turn all invisible runes visible once more, in addition to causing \
|
||||
all spirits nearby to become visible.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Disguise Runes</b></font><br>Many crewmen enjoy drawing runes in crayon that resemble spell circles in order to play pranks on their fellow crewmen. The Rite of \
|
||||
False Truths takes advantage of this very joke. When invoked, all nearby runes will appear dull, precisely resembling those drawn in crayon. They still cannot be cleaned by conventional means, so \
|
||||
anyone trying to clean up the rune may become suspicious as it does not respond.<br><br>"
|
||||
(such as the Rite of Translocation) but will be unusuable directly. Use the same rite once more to reveal these runes once more.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Electromagnetic Disruption</b></font><br>Robotic lifeforms have time and time again been the downfall of fledgling cults. The Rite of Disruption may allow you to gain the upper \
|
||||
hand against these pests. By using the rune, a large electromagnetic pulse will be emitted from the rune's location.<br><br>"
|
||||
@@ -178,14 +124,11 @@ It also contains rune words, which are soon to be removed.
|
||||
rune will draw a small amount of life force from the user and make the space above the rune completely dense, rendering it impassable to all but the most complex means. The rune may be invoked again to \
|
||||
undo this effect and allow passage again.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Deafen</b></font><br>The Rite of the Unheard Whisper is simple. When invoked, it will cause all non-cultists within a radius of seven tiles to become \
|
||||
completely deaf for a large amount of time.<br><br>"
|
||||
text += "<font color='red'><b>Debilitate</b></font><br>The Rite of the Shadowed Mind is simple. When invoked, it will cause all non-cultists that can see its rune to become deaf, blind and mute for a \
|
||||
considerable amount of time.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Blind</b></font><br>Much like the Rite of the Unheard Whisper, the Rite of the Unseen Glance serves a single purpose. Any non-cultists who can see \
|
||||
the rune will instantly be blinded for a substantial amount of time.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Stun</b></font><br>Though the Rite of Blazing Light is weak when invoked normally, using it in conjuction with the Rite of Binding makes it much more useful. \
|
||||
This rune will cause any non-cultists that can see the rune to become disoriented, disabling them for a short time.<br><br>"
|
||||
text += "<font color='red'><b>Stun</b></font><br>Though the Rite of Blazing Light is weak when invoked normally, merely disorienting and disabling nearby non-cultists, non-cultists that step on the rune \
|
||||
will be stunned without expending its power. However, the disorientation caused by this rune is quite brief, and when invoked directly, it will not remain for further invocation.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Summon Cultist</b></font><br>The Rite of Joined Souls requires two acolytes to use. When invoked, it will allow the user to summon a single cultist to the rune from \
|
||||
any location. This will deal a moderate amount of damage to all invokers.<br><br>"
|
||||
@@ -204,15 +147,18 @@ It also contains rune words, which are soon to be removed.
|
||||
text += "<font color='red'><b>Blood Boil</b></font><br>The Rite of Boiling Blood may be considered one of the most dangerous rites composed by the cult of Nar-Sie. When invoked, it will do a \
|
||||
massive amount of damage to all non-cultist viewers, but it will also emit an explosion upon invocation. Use with caution<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Immolate</b></font><br>The Rite of the Cleansing Flame is a weaker offensive rite, fit to be used by a lone cultist. When its rune is invoked, it will set any non-cultists \
|
||||
that can see it on fire. However, it will also burn its user.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Time Stop</b></font><br>The Rite of Dimensional Corruption is a versatile rite that can be very strong when protecting our cult from the enemies of the Geometer. \
|
||||
As it is invoked, it will rend and reshape reality around itself, stopping time for all those who don't follow the teachings of the Geometer. However, it requires more than one ritual soul as a \
|
||||
catalyst, and its power is bound to overflow and hurt its casters.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Manifest Spirit</b></font><br>If you wish to bring a spirit back from the dead with a wish for vengeance and desire to serve, the Rite of Spectral \
|
||||
Manifestation can do just that. When invoked, any spirits above the rune will be brought to life as a human wearing nothing that seeks only to serve you and the Geometer. However, the spirit's link \
|
||||
to reality is fragile - you must remain on top of the rune, and you will slowly take damage. Upon stepping off the rune, the spirits will dissipate, dropping their items to the ground. You may manifest \
|
||||
multiple spirits with one rune, but you will rapidly take damage in doing so.<br><br>"
|
||||
|
||||
text += "<font color='red'><b><i>Call Forth The Geometer</i></b></font><br>There is only one way to summon the avatar of Nar-Sie, and that is the Ritual of Dimensional Rending. This ritual, in \
|
||||
comparison to other runes, is very large, requiring a 3x3 space of empty tiles to create. To invoke the rune, nine cultists must stand on the rune, so that all of them are within its circle. Then, \
|
||||
simply invoke it. A brief tearing will be heard as the barrier between dimensions is torn open, and the avatar will come forth.<br><br><br>"
|
||||
|
||||
text += "While runes are excellent for many tasks, they lack portability. The advent of <b>talismans</b> has, to a degree, solved this inconvenience. Simply put, a talisman is a piece of paper with a \
|
||||
rune inlaid within it. The words of the rune can be whispered in order to invoke its effects, although usually to a lesser extent. To create a talisman, simply use a Rite of Binding as described above. \
|
||||
Unless stated otherwise, talismans are invoked by activating them in your hand. A list of valid rites, as well as the effects of their talisman form, can be found below.<br><br><br>"
|
||||
@@ -220,17 +166,11 @@ It also contains rune words, which are soon to be removed.
|
||||
text += "<font color='red'><b>Talisman of Teleportation</b></font><br>The talisman form of the Rite of Translocation will transport the invoker to a randomly chosen rune of the same keyword, then \
|
||||
disappear.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Talisman of Tome Summoning</b></font><br>This talisman functions nearly identically to the rune. The talisman will attempt to place the tome in your hand \
|
||||
instead of on the ground, though this is the only advantage it has over the rune. It can be used once, then disappears.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Talismans of Veiling, Revealing, and Disguising</b></font><br>These talismans all function identically to their rune counterparts, but with less range. In addition, \
|
||||
the Talisman of True Sight will not reveal spirits. They will disappear after one use.<br><br>"
|
||||
text += "<font color='red'><b>Talismans of Veiling</b></font><br>This talisman functions identically to its rune counterpart.It will disappear after one use.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Talisman of Electromagnetic Pulse</b></font><br>This talisman functions like the Rite of Disruption. It disappears after one use.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Talisman of Stunning</b></font><br>Without this talisman, the cult would have no way of easily acquiring targets to convert. Commonly called \"stunpapers\", this \
|
||||
talisman functions differently from others. Rather than simply reading the words, the target must be attacked directly with the talisman. The talisman will then knock down the target for a long \
|
||||
duration in addition to rendering them incapable of speech. Robotic lifeforms will suffer the effects of a heavy electromagnetic pulse instead."
|
||||
text += "<font color='red'><b>Talisman of Immolation</b></font><br>This talisman functions exactly like the Rite of Cleansing Flame. It can only be used once.<br><br>"
|
||||
|
||||
var/datum/browser/popup = new(user, "tome", "", 800, 600)
|
||||
popup.set_content(text)
|
||||
@@ -242,10 +182,10 @@ It also contains rune words, which are soon to be removed.
|
||||
var/rune_to_scribe
|
||||
var/entered_rune_name
|
||||
var/list/possible_runes = list()
|
||||
for(var/T in subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed)
|
||||
for(var/T in known_runes)
|
||||
var/obj/effect/rune/R = T
|
||||
if(initial(R.cultist_name))
|
||||
possible_runes.Add(initial(R.cultist_name)) //This is to allow the menu to let cultists select runes by name rather than by object path. I don't know a better way to do this
|
||||
possible_runes += initial(R.cultist_name) //This is to allow the menu to let cultists select runes by name rather than by object path. I don't know a better way to do this
|
||||
if(!possible_runes.len)
|
||||
return
|
||||
entered_rune_name = input(user, "Choose a rite to scribe.", "Sigils of Power") as null|anything in possible_runes
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
var/list/sacrificed = list()
|
||||
var/list/non_revealed_runes = (subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed)
|
||||
|
||||
/*
|
||||
|
||||
This file contains runes.
|
||||
@@ -9,18 +6,7 @@ They are drawn with an arcane tome in blood, and are distinguishable to cultists
|
||||
Fake runes can be drawn in crayon to fool people.
|
||||
Runes can either be invoked by one's self or with many different cultists. Each rune has a specific incantation that the cultists will say when invoking it.
|
||||
|
||||
To draw a rune, use an arcane tome and enter the words required. These words are in the tongue of the Geometer and must be entered as such.
|
||||
Word definitions:
|
||||
"ire" is Travel
|
||||
"ego" is Self
|
||||
"nahlizet" is Blood
|
||||
"certum" is Join
|
||||
"veri" is Hell
|
||||
"jatkaa" is Other
|
||||
"mgar" is Destroy
|
||||
"balaq" is Technology
|
||||
"karazet" is See
|
||||
"geeri" is Hide
|
||||
To draw a rune, use an arcane tome.
|
||||
|
||||
*/
|
||||
|
||||
@@ -38,7 +24,6 @@ Word definitions:
|
||||
mouse_opacity = 2
|
||||
|
||||
var/invocation = "Aiy ele-mayo!" //This is said by cultists when the rune is invoked.
|
||||
var/grammar //This is only framework at the moment, but may be required to draw runes in the future
|
||||
var/req_cultists = 1 //The amount of cultists required around the rune to invoke it. If only 1, any cultist can invoke it.
|
||||
var/rune_in_use = 0 // Used for some runes, this is for when you want a rune to not be usable when in use.
|
||||
|
||||
@@ -55,7 +40,6 @@ Word definitions:
|
||||
if(iscultist(user) || user.stat == DEAD) //If they're a cultist or a ghost, tell them the effects
|
||||
user << "<b>Name:</b> [cultist_name]"
|
||||
user << "<b>Effects:</b> [cultist_desc]"
|
||||
//user << "<b>Words:</b> [grammar]"
|
||||
user << "<b>Required Acolytes:</b> [req_cultists]"
|
||||
if(req_keyword && keyword)
|
||||
user << "<b>Keyword:</b> [keyword]"
|
||||
@@ -77,6 +61,9 @@ Word definitions:
|
||||
return
|
||||
if(can_invoke(user))
|
||||
invoke(user)
|
||||
var/oldtransform = transform
|
||||
animate(src, transform = matrix()*2, alpha = 0, time = 5) //fade out
|
||||
animate(transform = oldtransform, alpha = 255, time = 0)
|
||||
else
|
||||
fail_invoke(user)
|
||||
|
||||
@@ -151,7 +138,6 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
cultist_name = "malformed rune"
|
||||
cultist_desc = "A senseless rune written in gibberish. No good can come from invoking this."
|
||||
invocation = "Ra'sha yoka!"
|
||||
grammar = "N/A"
|
||||
|
||||
/obj/effect/rune/malformed/New()
|
||||
..()
|
||||
@@ -177,7 +163,6 @@ var/list/teleport_runes = list()
|
||||
invocation = "Sas'so c'arta forbici!"
|
||||
icon_state = "2"
|
||||
color = rgb(0, 0, 255)
|
||||
grammar = "ire ego"
|
||||
req_keyword = 1
|
||||
|
||||
/obj/effect/rune/teleport/New()
|
||||
@@ -216,7 +201,6 @@ var/list/teleport_other_runes = list()
|
||||
invocation = "Sas'so c'arta forbica!"
|
||||
icon_state = "1"
|
||||
color = rgb(200, 0, 0)
|
||||
grammar = "ire jatkaa"
|
||||
req_keyword = 1
|
||||
|
||||
/obj/effect/rune/teleport_other/New()
|
||||
@@ -264,62 +248,6 @@ var/list/teleport_other_runes = list()
|
||||
"<span class='cult'>Your vision blurs, and you suddenly appear somewhere else.</span>")
|
||||
target.forceMove(get_turf(selected_rune))
|
||||
|
||||
|
||||
//Rite of Knowledge: Creates an arcane tome at the rune's location and destroys the rune.
|
||||
/obj/effect/rune/summon_tome
|
||||
cultist_name = "Summon Tome"
|
||||
cultist_desc = "Pulls an arcane tome from the archives of the Geometer."
|
||||
invocation = "N'ath reth sh'yro eth d'raggathnor!"
|
||||
icon_state = "5"
|
||||
color = rgb(0, 0, 255)
|
||||
grammar = "karazet nahlizet ego"
|
||||
|
||||
/obj/effect/rune/summon_tome/invoke(mob/living/user)
|
||||
visible_message("<span class='warning'>A frayed tome materializes on the surface of [src], which dissolves into nothing.</span>")
|
||||
new /obj/item/weapon/tome(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
|
||||
//Rite of Enlightenment: Converts a normal crewmember to the cult. Faster for every cultist nearby.
|
||||
/obj/effect/rune/convert
|
||||
cultist_name = "Convert"
|
||||
cultist_desc = "Converts a normal crewmember on top of it to the cult. Does not work on loyalty-implanted crew."
|
||||
invocation = "Mah'weyh pleggh at e'ntrath!"
|
||||
icon_state = "3"
|
||||
color = rgb(255, 0, 0)
|
||||
grammar = "certum nahlizet ego"
|
||||
req_cultists = 2
|
||||
|
||||
/obj/effect/rune/convert/invoke(mob/living/user)
|
||||
var/list/convertees = list()
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/mob/living/M in T.contents)
|
||||
if(!iscultist(M) && !isloyal(M))
|
||||
convertees.Add(M)
|
||||
if(!convertees.len)
|
||||
fail_invoke()
|
||||
log_game("Convert rune failed - no eligible convertees")
|
||||
return
|
||||
var/mob/living/new_cultist = pick(convertees)
|
||||
if(!is_convertable_to_cult(new_cultist.mind) || new_cultist.null_rod_check())
|
||||
user << "<span class='warning'>Something is shielding [new_cultist]'s mind!</span>"
|
||||
fail_invoke()
|
||||
log_game("Convert rune failed - convertee could not be converted")
|
||||
if(is_sacrifice_target(new_cultist.mind))
|
||||
for(var/mob/living/M in orange(1,src))
|
||||
if(iscultist(M))
|
||||
M << "<span class='cultlarge'>\"I desire this one for myself. <i>SACRIFICE THEM!</i>\"</span>"
|
||||
return
|
||||
new_cultist.visible_message("<span class='warning'>[new_cultist] writhes in pain as the markings below them glow a bloody red!</span>", \
|
||||
"<span class='cultlarge'><i>AAAAAAAAAAAAAA-</i></span>")
|
||||
ticker.mode.add_cultist(new_cultist.mind)
|
||||
new_cultist.mind.special_role = "Cultist"
|
||||
new_cultist << "<span class='cultitalic'><b>Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \
|
||||
and something evil takes root.</b></span>"
|
||||
new_cultist << "<span class='cultitalic'><b>Assist your new compatriots in their dark dealings. Your goal is theirs, and theirs is yours. You serve the Geometer above all else. Bring it back.\
|
||||
</b></span>"
|
||||
|
||||
|
||||
//Rite of Tribute: Sacrifices a crew member to Nar-Sie. Places them into a soul shard if they're in their body.
|
||||
/obj/effect/rune/sacrifice
|
||||
cultist_name = "Sacrifice"
|
||||
@@ -327,7 +255,6 @@ var/list/teleport_other_runes = list()
|
||||
icon_state = "3"
|
||||
invocation = "Barhah hra zar'garis!"
|
||||
color = rgb(255, 255, 255)
|
||||
grammar = "veri nahlizet certum"
|
||||
rune_in_use = 0
|
||||
|
||||
/obj/effect/rune/sacrifice/New()
|
||||
@@ -357,13 +284,13 @@ var/list/teleport_other_runes = list()
|
||||
fail_invoke()
|
||||
rune_in_use = 0
|
||||
return
|
||||
if(((ishuman(offering) || isrobot(offering)) && offering.stat != DEAD) || is_sacrifice_target(offering.mind)) //Requires three people to sacrifice living targets or the round's target
|
||||
if(((ishuman(offering) || isrobot(offering)) && offering.stat != DEAD)) //Requires two people to sacrifice living targets
|
||||
var/cultists_nearby = 1
|
||||
for(var/mob/living/M in orange(1,src))
|
||||
for(var/mob/living/M in range(1,src))
|
||||
if(iscultist(M) && M != user)
|
||||
cultists_nearby++
|
||||
M.say(invocation)
|
||||
if(cultists_nearby < 3)
|
||||
if(cultists_nearby < 2)
|
||||
user << "<span class='cultitalic'>[offering] is too greatly linked to the world! You need more acolytes!</span>"
|
||||
fail_invoke()
|
||||
log_game("Sacrifice rune failed - not enough acolytes and target is living")
|
||||
@@ -376,29 +303,17 @@ var/list/teleport_other_runes = list()
|
||||
sac(offering)
|
||||
|
||||
/obj/effect/rune/sacrifice/proc/sac(mob/living/T)
|
||||
var/sacrifice_fulfilled
|
||||
if(T)
|
||||
if(istype(T, /mob/living/simple_animal/pet/dog))
|
||||
for(var/mob/living/carbon/C in range(3,src))
|
||||
if(iscultist(C))
|
||||
C << "<span class='cultlarge'>\"Even I have standards, such as they are!\"</span>"
|
||||
if(C.reagents)
|
||||
C.reagents.add_reagent("hell_water", 2)
|
||||
if(T.mind)
|
||||
sacrificed.Add(T.mind)
|
||||
if(is_sacrifice_target(T.mind))
|
||||
sacrifice_fulfilled = 1
|
||||
PoolOrNew(/obj/effect/overlay/temp/cult/sac, src.loc)
|
||||
for(var/mob/living/M in range(3,src))
|
||||
if(iscultist(M))
|
||||
if(sacrifice_fulfilled)
|
||||
M << "<span class='cultlarge'>\"Yes! This is the one I desire! You have done well.\"</span>"
|
||||
if(ishuman(T) || isrobot(T))
|
||||
M << "<span class='cultlarge'>\"I accept this sacrifice.\"</span>"
|
||||
else
|
||||
if(ishuman(T) || isrobot(T))
|
||||
M << "<span class='cultlarge'>\"I accept this sacrifice.\"</span>"
|
||||
else
|
||||
M << "<span class='cultlarge'>\"I accept this meager sacrifice.\"</span>"
|
||||
M << "<span class='cultlarge'>\"I accept this meager sacrifice.\"</span>"
|
||||
if(T.mind)
|
||||
if(ishuman(T) || isrobot(T))
|
||||
new /obj/item/summoning_orb(get_turf(src))
|
||||
var/obj/item/device/soulstone/stone = new /obj/item/device/soulstone(get_turf(src))
|
||||
stone.invisibility = INVISIBILITY_MAXIMUM //so it's not picked up during transfer_soul()
|
||||
if(!stone.transfer_soul("FORCE", T, usr)) //If it cannot be added
|
||||
@@ -417,65 +332,6 @@ var/list/teleport_other_runes = list()
|
||||
rune_in_use = 0
|
||||
|
||||
|
||||
//Ritual of Dimensional Rending: Calls forth the avatar of Nar-Sie upon the station.
|
||||
/obj/effect/rune/narsie
|
||||
cultist_name = "Call Forth The Geometer"
|
||||
cultist_desc = "Tears apart dimensional barriers, calling forth the avatar of the Geometer."
|
||||
invocation = null
|
||||
req_cultists = 9
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "rune_large"
|
||||
pixel_x = -32 //So the big ol' 96x96 sprite shows up right
|
||||
pixel_y = -32
|
||||
grammar = "veri certum ego"
|
||||
var/used
|
||||
|
||||
/obj/effect/rune/narsie/invoke(mob/living/user)
|
||||
if(used)
|
||||
return
|
||||
if(ticker.mode.name == "cult")
|
||||
var/datum/game_mode/cult/cult_mode = ticker.mode
|
||||
if(!("eldergod" in cult_mode.cult_objectives))
|
||||
message_admins("[usr.real_name]([user.ckey]) tried to summon Nar-Sie when the objective was wrong")
|
||||
for(var/mob/living/M in range(1,src))
|
||||
if(iscultist(M))
|
||||
M << "<span class='cultlarge'><i>\"YOUR SOUL BURNS WITH YOUR ARROGANCE!!!\"</i></span>"
|
||||
if(M.reagents)
|
||||
M.reagents.add_reagent("hell_water", 10)
|
||||
M.Weaken(5)
|
||||
fail_invoke()
|
||||
log_game("Summon Nar-Sie rune failed - improper objective")
|
||||
return
|
||||
else
|
||||
if(cult_mode.sacrifice_target && !(cult_mode.sacrifice_target in sacrificed))
|
||||
for(var/mob/living/M in orange(1,src))
|
||||
if(iscultist(M))
|
||||
M << "<span class='warning'>The sacrifice is not complete. The portal lacks the power to open!</span>"
|
||||
fail_invoke()
|
||||
log_game("Summon Nar-Sie rune failed - sacrifice not complete")
|
||||
return
|
||||
if(!cult_mode.eldergod)
|
||||
for(var/mob/living/M in range(1,src))
|
||||
if(iscultist(M))
|
||||
M << "<span class='warning'>The avatar of Nar-Sie is already on this plane!</span>"
|
||||
log_game("Summon Nar-Sie rune failed - already summoned")
|
||||
return
|
||||
//BEGIN THE SUMMONING
|
||||
used = 1
|
||||
for(var/mob/living/M in range(1,src))
|
||||
if(iscultist(M))
|
||||
M.say("TOK-LYR RQA-NAP G'OLT-ULOFT!!")
|
||||
world << 'sound/effects/dimensional_rend.ogg'
|
||||
world << "<span class='cultitalic'><b>Rip... <span class='big'>Rrrip...</span> <span class='reallybig'>RRRRRRRRRR--</span></b></span>"
|
||||
sleep(40)
|
||||
new /obj/singularity/narsie/large(get_turf(user)) //Causes Nar-Sie to spawn even if the rune has been removed
|
||||
cult_mode.eldergod = 0
|
||||
else
|
||||
fail_invoke()
|
||||
log_game("Summon Nar-Sie rune failed - gametype is not cult")
|
||||
return
|
||||
|
||||
|
||||
//Rite of Resurrection: Requires two corpses. Revives one and gibs the other.
|
||||
/obj/effect/rune/raise_dead
|
||||
cultist_name = "Raise Dead"
|
||||
@@ -483,7 +339,6 @@ var/list/teleport_other_runes = list()
|
||||
invocation = null //Depends on the name of the user - see below
|
||||
icon_state = "1"
|
||||
color = rgb(255, 0, 0)
|
||||
grammar = "nahlizet certum veri"
|
||||
|
||||
/obj/effect/rune/raise_dead/invoke(mob/living/user)
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -540,9 +395,9 @@ var/list/teleport_other_runes = list()
|
||||
mob_to_sacrifice.visible_message("<span class='warning'><b>[mob_to_sacrifice]'s body rises into the air, connected to [mob_to_revive] by a glowing tendril!</span>")
|
||||
mob_to_revive.Beam(mob_to_sacrifice,icon_state="sendbeam",icon='icons/effects/effects.dmi',time=20)
|
||||
sleep(20)
|
||||
if(mob_to_sacrifice) //sighing noise
|
||||
mob_to_sacrifice.visible_message("<span class='warning'><b>[mob_to_sacrifice] disintegrates into a pile of bones[mob_to_revive ? ", the glowing tendril sinking into [mob_to_revive]'s body":""].</span>")
|
||||
if(!mob_to_sacrifice || !in_range(mob_to_sacrifice, src))
|
||||
return
|
||||
mob_to_sacrifice.visible_message("<span class='warning'><b>[mob_to_sacrifice] disintegrates into a pile of bones[mob_to_revive ? ", the glowing tendril sinking into [mob_to_revive]'s body":""].</span>")
|
||||
mob_to_sacrifice.dust()
|
||||
if(!mob_to_revive || mob_to_revive.stat != DEAD)
|
||||
visible_message("<span class='warning'>The glowing tendril snaps against the rune with a shocking crack.</span>")
|
||||
@@ -561,63 +416,27 @@ var/list/teleport_other_runes = list()
|
||||
M.visible_message("<span class='warning'>[M] twitches.</span>")
|
||||
|
||||
|
||||
//Rite of Obscurity: Turns all runes within a 3-tile radius invisible.
|
||||
//Rite of Obscurity: Turns all runes within a 3-tile radius invisible or reveals them again.
|
||||
/obj/effect/rune/hide_runes
|
||||
cultist_name = "Veil Runes"
|
||||
cultist_desc = "Turns nearby runes invisible. They can be revealed by using the Reveal Runes rune."
|
||||
cultist_desc = "Turns nearby runes invisible. They can be revealed by using this rune again."
|
||||
invocation = "Kla'atu barada nikt'o!"
|
||||
icon_state = "1"
|
||||
color = rgb(0,0,255)
|
||||
grammar = "geeri karazet nahlizet"
|
||||
|
||||
/obj/effect/rune/hide_runes/invoke(mob/living/user)
|
||||
visible_message("<span class='warning'>[src] darkens to black and vanishes.</span>")
|
||||
for(var/obj/effect/rune/R in orange(3,src))
|
||||
R.visible_message("<span class='danger'>[R] fades away.</span>")
|
||||
R.invisibility = INVISIBILITY_OBSERVER
|
||||
R.alpha = 100 //To help ghosts distinguish hidden runes
|
||||
for(var/mob/dead/observer/O in orange(3,src))
|
||||
if(!O.invisibility)
|
||||
O << "<span class='cultitalic'>You suddenly feel as if you've vanished...</span>"
|
||||
O.invisibility = INVISIBILITY_OBSERVER
|
||||
if(R.invisibility == INVISIBILITY_OBSERVER)
|
||||
R.invisibility = 0
|
||||
R.alpha = initial(R.alpha)
|
||||
else
|
||||
R.visible_message("<span class='danger'>[R] fades away.</span>")
|
||||
R.invisibility = INVISIBILITY_OBSERVER
|
||||
R.alpha = 100 //To help ghosts distinguish hidden runes
|
||||
qdel(src)
|
||||
|
||||
|
||||
//Rite of True Sight: Turns ghosts and obscured runes visible
|
||||
/obj/effect/rune/true_sight
|
||||
cultist_name = "Reveal Runes"
|
||||
cultist_desc = "Reveals all invisible objects nearby, from spirits to runes."
|
||||
invocation = "Nikt'o barada kla'atu!"
|
||||
icon_state = "4"
|
||||
color = rgb(255, 255, 255)
|
||||
grammar = "karazet geeri nahlizet"
|
||||
|
||||
/obj/effect/rune/true_sight/invoke()
|
||||
visible_message("<span class='warning'>[src] explodes in a flash of blinding light!</span>")
|
||||
for(var/mob/dead/observer/O in orange(3,src))
|
||||
O << "<span class='cultitalic'>You suddenly feel very obvious...</span>"
|
||||
O.invisibility = 0
|
||||
for(var/obj/effect/rune/R in orange(3,src))
|
||||
R.invisibility = 0
|
||||
R.alpha = initial(R.alpha)
|
||||
qdel(src)
|
||||
|
||||
|
||||
//Rite of False Truths: Makes runes appear like crayon ones
|
||||
/obj/effect/rune/make_runes_fake
|
||||
cultist_name = "Disguise Runes"
|
||||
cultist_desc = "Causes all nearby runes (including itself) to resemble those drawn in crayon."
|
||||
invocation = "By'o isit!"
|
||||
icon_state = "4"
|
||||
color = rgb(0, 150, 0)
|
||||
grammar = "geeri nahlizet jatkaa"
|
||||
|
||||
/obj/effect/rune/make_runes_fake/invoke(mob/living/user)
|
||||
visible_message("<span class='warning'>[src] flares brightly, then slowly dulls and appears mundane.</span>")
|
||||
for(var/obj/effect/rune/R in range(3,src))
|
||||
R.desc = "A rune drawn in crayon."
|
||||
|
||||
|
||||
//Rite of Disruption: Emits an EMP blast.
|
||||
/obj/effect/rune/emp
|
||||
cultist_name = "Electromagnetic Disruption"
|
||||
@@ -625,7 +444,6 @@ var/list/teleport_other_runes = list()
|
||||
invocation = "Ta'gh fara'qha fel d'amar det!"
|
||||
icon_state = "5"
|
||||
color = rgb(255, 0, 0)
|
||||
grammar = "mgar karazet balaq"
|
||||
|
||||
/obj/effect/rune/emp/invoke(mob/living/user)
|
||||
visible_message("<span class='warning'>[src] glows blue for a moment before vanishing.</span>")
|
||||
@@ -645,7 +463,6 @@ var/list/teleport_other_runes = list()
|
||||
color = rgb(126, 23, 23)
|
||||
rune_in_use = 0 //One at a time, please!
|
||||
var/mob/living/affecting = null
|
||||
grammar = "veri ire ego"
|
||||
|
||||
/obj/effect/rune/astral/examine(mob/user)
|
||||
..()
|
||||
@@ -713,7 +530,6 @@ var/list/teleport_other_runes = list()
|
||||
invocation = "Khari'd! Eske'te tannin!"
|
||||
icon_state = "1"
|
||||
color = rgb(255, 0, 0)
|
||||
grammar = "mgar ire ego"
|
||||
|
||||
/obj/effect/rune/wall/examine(mob/user)
|
||||
..()
|
||||
@@ -729,73 +545,62 @@ var/list/teleport_other_runes = list()
|
||||
C.apply_damage(2, BRUTE, pick("l_arm", "r_arm"))
|
||||
|
||||
|
||||
//Rite of the Unheard Whisper: Deafens all non-cultists nearby.
|
||||
//Rite of the Shadowed Mind: Deafens, blinds and mutes all non-cultists nearby.
|
||||
/obj/effect/rune/deafen
|
||||
cultist_name = "Deafen"
|
||||
cultist_desc = "Causes all non-followers nearby to lose their hearing."
|
||||
cultist_name = "Debilitate"
|
||||
cultist_desc = "Causes all non-followers nearby to lose their hearing, sight and voice."
|
||||
invocation = "Sti kaliedir!"
|
||||
grammar = "geeri jatkaa karazet"
|
||||
color = rgb(0, 255, 0)
|
||||
icon_state = "4"
|
||||
|
||||
/obj/effect/rune/deafen/invoke(mob/living/user)
|
||||
visible_message("<span class='warning'>[src] blurs for a moment before fading away.</span>")
|
||||
for(var/mob/living/carbon/C in range(7,src))
|
||||
if(!iscultist(C) && !C.null_rod_check())
|
||||
C << "<span class='warning'>The world around you goes quiet.</span>"
|
||||
C.adjustEarDamage(0,50)
|
||||
qdel(src)
|
||||
|
||||
|
||||
//Rite of the Unseen Glance: Blinds all non-cultists nearby.
|
||||
/obj/effect/rune/blind
|
||||
cultist_name = "Blind"
|
||||
cultist_desc = "Causes all non-followers nearby to lose their sight."
|
||||
invocation = "Sti kaliesin!"
|
||||
icon_state = "4"
|
||||
color = rgb(0, 0, 255)
|
||||
grammar = "mgar jatkaa karazet"
|
||||
|
||||
/obj/effect/rune/blind/invoke(mob/living/user)
|
||||
visible_message("<span class='warning'>[src] emits a blinding red flash!</span>")
|
||||
for(var/mob/living/carbon/C in viewers(src))
|
||||
if(!iscultist(C) && !C.null_rod_check())
|
||||
C << "<span class='cultitalic'><b>You can't see!</b></span>"
|
||||
C << "<span class='cultlarge'>You feel oily shadows cover your senses.</span>"
|
||||
C.adjustEarDamage(0,50)
|
||||
C.flash_eyes(1, 1)
|
||||
C.eye_blurry += 50
|
||||
C.eye_blind += 20
|
||||
C.silent += 10
|
||||
qdel(src)
|
||||
|
||||
|
||||
//Rite of Disorientation: Stuns all non-cultists nearby for a brief time
|
||||
//Rite of Disorientation: Stuns and mutes all non-cultists nearby for a brief time
|
||||
/obj/effect/rune/stun
|
||||
cultist_name = "Stun"
|
||||
cultist_desc = "Stuns all nearby non-followers for a brief time."
|
||||
cultist_desc = "Stuns and mutes all nearby non-followers for a brief time."
|
||||
invocation = "Fuu ma'jin!"
|
||||
icon_state = "2"
|
||||
color = rgb(100, 0, 100)
|
||||
grammar = "certum geeri balaq"
|
||||
|
||||
/obj/effect/rune/stun/invoke(mob/living/user)
|
||||
visible_message("<span class='warning'>[src] explodes in a bright flash!</span>")
|
||||
for(var/mob/living/M in viewers(src))
|
||||
if(!iscultist(M) && !M.null_rod_check())
|
||||
M << "<span class='cultitalic'><b>You are disoriented by [src]!</b></span>"
|
||||
M.Weaken(3)
|
||||
M.Stun(3)
|
||||
M.flash_eyes(1,1)
|
||||
stun_he(M)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/rune/stun/Crossed(atom/movable/AM)
|
||||
..()
|
||||
if(isliving(AM))
|
||||
stun_he(AM)
|
||||
|
||||
//Rite of Joined Souls: Summons a single cultist. Requires 2 cultists.
|
||||
/obj/effect/rune/stun/proc/stun_he(mob/living/M)
|
||||
if(!iscultist(M) && !M.null_rod_check())
|
||||
M << "<span class='cultitalic'><b>You are disoriented by [src]!</b></span>"
|
||||
M.Weaken(3)
|
||||
M.Stun(3)
|
||||
M.flash_eyes(1,1)
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
C.silent += 3
|
||||
|
||||
//Rite of Joined Souls: Summons a single cultist.
|
||||
/obj/effect/rune/summon
|
||||
cultist_name = "Summon Cultist"
|
||||
cultist_desc = "Summons a single cultist to the rune."
|
||||
invocation = "N'ath reth sh'yro eth d'rekkathnor!"
|
||||
req_cultists = 2
|
||||
icon_state = "5"
|
||||
color = rgb(0, 255, 0)
|
||||
grammar = "certum jatkaa ego"
|
||||
|
||||
/obj/effect/rune/summon/invoke(mob/living/user)
|
||||
var/list/cultists = list()
|
||||
@@ -817,9 +622,7 @@ var/list/teleport_other_runes = list()
|
||||
cultist_to_summon.visible_message("<span class='warning'>[cultist_to_summon] suddenly disappears in a flash of red light!</span>", \
|
||||
"<span class='cultitalic'><b>Overwhelming vertigo consumes you as you are hurled through the air!</b></span>")
|
||||
visible_message("<span class='warning'>A foggy shape materializes atop [src] and solidifes into [cultist_to_summon]!</span>")
|
||||
for(var/mob/living/carbon/C in orange(1,src))
|
||||
if(iscultist(C))
|
||||
C.apply_damage(10, BRUTE, "head")
|
||||
user.apply_damage(10, BRUTE, "head")
|
||||
cultist_to_summon.loc = get_turf(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -831,7 +634,6 @@ var/list/teleport_other_runes = list()
|
||||
invocation = null //no talisman made, no invocation.
|
||||
icon_state = "3"
|
||||
color = rgb(0, 0, 255)
|
||||
grammar = "veri balaq certum"
|
||||
|
||||
/obj/effect/rune/imbue/invoke(mob/living/user)
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -881,7 +683,6 @@ var/list/teleport_other_runes = list()
|
||||
invocation = null //see below; doesn't say the invocation unless there's enough sheets.
|
||||
icon_state = "5"
|
||||
color = rgb(150, 150, 150)
|
||||
grammar = "ire veri balaq"
|
||||
|
||||
/obj/effect/rune/construct_shell/invoke(mob/living/user)
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -911,7 +712,6 @@ var/list/teleport_other_runes = list()
|
||||
invocation = "N'ath reth sh'yro eth draggathnor!"
|
||||
icon_state = "4"
|
||||
color = rgb(255, 0, 0)
|
||||
grammar = "veri mgar jatkaa"
|
||||
|
||||
/obj/effect/rune/armor/invoke(mob/living/user)
|
||||
visible_message("<span class='warning'>With the sound of clanging metal, [src] crumbles to dust!</span>")
|
||||
@@ -930,7 +730,6 @@ var/list/teleport_other_runes = list()
|
||||
invocation = null //see below; doesn't say the invocation if it has no targets.
|
||||
icon_state = "2"
|
||||
color = rgb(255, 0, 0)
|
||||
grammar = "ire nahlizet ego"
|
||||
|
||||
/obj/effect/rune/leeching/invoke(mob/living/user)
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -961,8 +760,7 @@ var/list/teleport_other_runes = list()
|
||||
invocation = "Dedo ol'btoh!"
|
||||
icon_state = "4"
|
||||
color = rgb(255, 0, 0)
|
||||
req_cultists = 3
|
||||
grammar = "mgar karazet nahlizet"
|
||||
req_cultists = 2
|
||||
|
||||
/obj/effect/rune/blood_boil/invoke(mob/living/user)
|
||||
visible_message("<span class='warning'>[src] briefly bubbles before exploding!</span>")
|
||||
@@ -973,7 +771,7 @@ var/list/teleport_other_runes = list()
|
||||
continue
|
||||
C << "<span class='cultlarge'>Your blood boils in your veins!</span>"
|
||||
C.take_overall_damage(51,51)
|
||||
for(var/mob/living/carbon/M in orange(1,src))
|
||||
for(var/mob/living/carbon/M in range(1,src))
|
||||
if(iscultist(M))
|
||||
M.apply_damage(15, BRUTE, pick("l_arm", "r_arm"))
|
||||
M << "<span class='cultitalic'>[src] saps your strength!</span>"
|
||||
@@ -981,6 +779,27 @@ var/list/teleport_other_runes = list()
|
||||
qdel(src)
|
||||
|
||||
|
||||
//Rite of the Cleansing Flame: Sets all non-cultists on fire.
|
||||
/obj/effect/rune/flame
|
||||
cultist_name = "Immolate"
|
||||
cultist_desc = "Sets any non-believers who can see the rune on fire."
|
||||
invocation = "Dedo va'batoh!"
|
||||
icon_state = "2"
|
||||
color = rgb(255, 0, 0)
|
||||
|
||||
/obj/effect/rune/flame/invoke(mob/living/user)
|
||||
visible_message("<span class='warning'>[src] burns away, scorching the floor below!</span>")
|
||||
for(var/mob/living/carbon/C in viewers(src))
|
||||
if(!iscultist(C) && !C.null_rod_check())
|
||||
C << "<span class='cultlarge'>You feel your skin crisp as you burst into flames!</span>"
|
||||
C.fire_act()
|
||||
user.apply_damage(15, BURN, pick("l_arm", "r_arm"))
|
||||
user << "<span class='cultitalic'>[src] burns your arms!</span>"
|
||||
var/turf/simulated/T = get_turf(src)
|
||||
T.burn_tile()
|
||||
qdel(src)
|
||||
|
||||
|
||||
//Rite of Spectral Manifestation: Summons a ghost on top of the rune as a cultist human with no items. User must stand on the rune at all times, and takes damage for each summoned ghost.
|
||||
/obj/effect/rune/manifest
|
||||
cultist_name = "Manifest Spirit"
|
||||
@@ -988,7 +807,6 @@ var/list/teleport_other_runes = list()
|
||||
invocation = "Gal'h'rfikk harfrandid mud'gib!" //how the fuck do you pronounce this
|
||||
icon_state = "6"
|
||||
color = rgb(255, 0, 0)
|
||||
grammar = "nahlizet karazet ire"
|
||||
|
||||
/obj/effect/rune/manifest/invoke(mob/living/user)
|
||||
if(!(user in get_turf(src)))
|
||||
@@ -1027,3 +845,40 @@ var/list/teleport_other_runes = list()
|
||||
for(var/obj/I in new_human)
|
||||
new_human.unEquip(I)
|
||||
new_human.dust()
|
||||
|
||||
//Rite of Dimensional Corruption: Stops time around the rune for all non-cultists.
|
||||
/obj/effect/rune/timestop
|
||||
cultist_name = "Time Stop"
|
||||
cultist_desc = "Stops time around the rune for all non-cultists."
|
||||
invocation = "T'ak ot'marzah oahr'du!"
|
||||
icon_state = "2"
|
||||
color = rgb(0, 0, 255)
|
||||
req_cultists = 2
|
||||
|
||||
/obj/effect/rune/timestop/invoke(mob/living/user)
|
||||
visible_message("<span class='warning'>[src] flares up for a moment, and then disappears into itself!</span>")
|
||||
new /obj/effect/timestop/cult(get_turf(src))
|
||||
for(var/mob/living/carbon/M in range(1,src))
|
||||
if(iscultist(M))
|
||||
M.apply_damage(20, BRUTE, "chest")
|
||||
M << "<span class='cultitalic'>[src] temporarily stops your heart from beating!</span>"
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/timestop/cult
|
||||
name = "Dimensional Corruption"
|
||||
desc = "Something not from this world has corrupted the spacetime continuum in this exact spot."
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "rune_large"
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
duration = 50
|
||||
alpha = 0
|
||||
color = rgb(255, 0, 0)
|
||||
|
||||
/obj/effect/timestop/cult/timestop()
|
||||
animate(src, alpha = 255, time = 5, loop = -1)
|
||||
SpinAnimation(speed = 5)
|
||||
for(var/mob/living/M in player_list)
|
||||
if(iscultist(M) || M.null_rod_check())
|
||||
immune |= M
|
||||
..()
|
||||
|
||||
@@ -26,8 +26,8 @@ Rite of Disorientation
|
||||
user << "<b>Name:</b> [cultist_name]"
|
||||
user << "<b>Effect:</b> [cultist_desc]"
|
||||
user << "<b>Uses Remaining:</b> [uses]"
|
||||
return
|
||||
..()
|
||||
else
|
||||
user << "<span class='danger'>There are indecipherable images scrawled on the paper in what looks to be... <i>blood?</i></span>"
|
||||
|
||||
/obj/item/weapon/paper/talisman/attack_self(mob/living/user)
|
||||
if(!iscultist(user))
|
||||
@@ -70,12 +70,11 @@ Rite of Disorientation
|
||||
var/dat = "<B>There are [uses] bloody runes on the parchment.</B><BR>"
|
||||
dat += "Please choose the chant to be imbued into the fabric of reality.<BR>"
|
||||
dat += "<HR>"
|
||||
dat += "<A href='?src=\ref[src];rune=newtome'>N'ath reth sh'yro eth d'raggathnor!</A> - Allows you to summon an arcane tome.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=teleport'>Sas'so c'arta forbici!</A> - Allows you to move to a Rite of Dislocation with the keyword of \"veri\".<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=emp'>Ta'gh fara'qha fel d'amar det!</A> - Allows you to destroy technology in a short range.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=conceal'>Kla'atu barada nikt'o!</A> - Allows you to conceal nearby runes.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=reveal'>Nikt'o barada kla'atu!</A> - Allows you to reveal nearby runes.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=runestun'>Fuu ma'jin!</A> - Allows you to stun a person by attacking them with the talisman.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=conceal'>Kla'atu barada nikt'o!</A> - Allows you to conceal nearby runes, or reveal previously concealed runes.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=flame'>Dedo va'batoh!</A> - Allows you to set nearby non-believers on fire.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=sacrune'>Barhah hra zar'garis!</A> - A sacrifice rune appears under your feet, ready to be invoked in the name of Nar-sie.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=soulstone'>Kal'om neth!</A> - Summons a soul stone, used to capure the spirits of dead or dying humans.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=construct'>Daa'ig osk!</A> - Summons a construct shell for use with captured souls. It is too large to carry on your person.<BR>"
|
||||
var/datum/browser/popup = new(user, "talisman", "", 400, 400)
|
||||
@@ -85,46 +84,37 @@ Rite of Disorientation
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/paper/talisman/supply/Topic(href, href_list)
|
||||
if(src)
|
||||
if(usr.stat || usr.restrained() || !in_range(src, usr))
|
||||
return
|
||||
if(href_list["rune"])
|
||||
switch(href_list["rune"])
|
||||
if("newtome")
|
||||
var/obj/item/weapon/paper/talisman/summon_tome/T = new(usr)
|
||||
usr.put_in_hands(T)
|
||||
if("teleport")
|
||||
var/obj/item/weapon/paper/talisman/teleport/T = new(usr)
|
||||
T.keyword = "veri"
|
||||
usr.put_in_hands(T)
|
||||
if("emp")
|
||||
var/obj/item/weapon/paper/talisman/emp/T = new(usr)
|
||||
usr.put_in_hands(T)
|
||||
if("conceal")
|
||||
var/obj/item/weapon/paper/talisman/hide_runes/T = new(usr)
|
||||
usr.put_in_hands(T)
|
||||
if("reveal")
|
||||
var/obj/item/weapon/paper/talisman/true_sight/T = new(usr)
|
||||
usr.put_in_hands(T)
|
||||
if("runestun")
|
||||
var/obj/item/weapon/paper/talisman/stun/T = new(usr)
|
||||
usr.put_in_hands(T)
|
||||
if("soulstone")
|
||||
var/obj/item/device/soulstone/T = new(usr)
|
||||
usr.put_in_hands(T)
|
||||
if("construct")
|
||||
new /obj/structure/constructshell(get_turf(usr))
|
||||
src.uses--
|
||||
if(src.uses <= 0)
|
||||
if(iscarbon(usr))
|
||||
var/mob/living/carbon/C = usr
|
||||
C.drop_item()
|
||||
visible_message("<span class='warning'>[src] crumbles to dust.</span>")
|
||||
qdel(src)
|
||||
if(!src || usr.stat || usr.restrained() || !in_range(src, usr))
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
if(href_list["rune"])
|
||||
switch(href_list["rune"])
|
||||
if("teleport")
|
||||
var/obj/item/weapon/paper/talisman/teleport/T = new(usr)
|
||||
T.keyword = "veri"
|
||||
usr.put_in_hands(T)
|
||||
if("emp")
|
||||
var/obj/item/weapon/paper/talisman/emp/T = new(usr)
|
||||
usr.put_in_hands(T)
|
||||
if("conceal")
|
||||
var/obj/item/weapon/paper/talisman/hide_runes/T = new(usr)
|
||||
usr.put_in_hands(T)
|
||||
if("flame")
|
||||
var/obj/item/weapon/paper/talisman/flame/T = new(usr)
|
||||
usr.put_in_hands(T)
|
||||
if("sacrune")
|
||||
new /obj/effect/rune/sacrifice(get_turf(usr))
|
||||
if("soulstone")
|
||||
var/obj/item/device/soulstone/T = new(usr)
|
||||
usr.put_in_hands(T)
|
||||
if("construct")
|
||||
new /obj/structure/constructshell(get_turf(usr))
|
||||
src.uses--
|
||||
if(src.uses <= 0)
|
||||
if(iscarbon(usr))
|
||||
var/mob/living/carbon/C = usr
|
||||
C.drop_item()
|
||||
visible_message("<span class='warning'>[src] crumbles to dust.</span>")
|
||||
qdel(src)
|
||||
|
||||
//Rite of Translocation: Same as rune
|
||||
/obj/item/weapon/paper/talisman/teleport
|
||||
@@ -162,65 +152,24 @@ Rite of Disorientation
|
||||
user << "<b>Keyword:</b> [keyword]"
|
||||
|
||||
|
||||
//Rite of Knowledge: Same as rune, but has two uses
|
||||
/obj/item/weapon/paper/talisman/summon_tome
|
||||
cultist_name = "Talisman of Tome Summoning"
|
||||
cultist_desc = "A one-use talisman that will call an untranslated tome from the archives of the Geometer."
|
||||
invocation = "N'ath reth sh'yro eth d'raggathnor!"
|
||||
health_cost = 1
|
||||
|
||||
/obj/item/weapon/paper/talisman/summon_tome/invoke(mob/living/user)
|
||||
user.visible_message("<span class='warning'>[user]'s hand glows red for a moment.</span>", \
|
||||
"<span class='cultitalic'>You speak the words of the talisman!</span>")
|
||||
var/obj/item/weapon/tome/T = new(get_turf(user))
|
||||
if(user.put_in_hands(T))
|
||||
user.visible_message("<span class='warning'>A tome appears in [user]'s hand!</span>", \
|
||||
"<span class='cultitalic'>An arcane tome materializes in your free hand.</span>")
|
||||
else
|
||||
user.visible_message("<span class='warning'>A tome appears at [user]'s feet!</span>", \
|
||||
"<span class='cultitalic'>An arcane tome materialzies at your feet.</span>")
|
||||
|
||||
//Rite of Obscurity: Same as rune, but less range
|
||||
//Talisman of Obscurity: Same as rune
|
||||
/obj/item/weapon/paper/talisman/hide_runes
|
||||
cultist_name = "Talisman of Veiling"
|
||||
cultist_desc = "A talisman that will make all runes within a small radius invisible."
|
||||
cultist_desc = "A talisman that will make all runes within a small radius invisible, or make invisible runes visible again."
|
||||
invocation = "Kla'atu barada nikt'o!"
|
||||
health_cost = 1
|
||||
|
||||
/obj/item/weapon/paper/talisman/hide_runes/invoke(mob/living/user)
|
||||
user.visible_message("<span class='warning'>Dust flows from [user]'s hand.</span>", \
|
||||
"<span class='cultitalic'>You speak the words of the talisman, veiling nearby runes.</span>")
|
||||
for(var/obj/effect/rune/R in orange(3,user))
|
||||
R.visible_message("<span class='danger'>[R] fades away.</span>")
|
||||
R.invisibility = INVISIBILITY_OBSERVER
|
||||
|
||||
|
||||
//Rite of True Sight: Same as rune, but doesn't work on ghosts
|
||||
/obj/item/weapon/paper/talisman/true_sight
|
||||
cultist_name = "Talisman of Revealing"
|
||||
cultist_desc = "A talisman that reveals nearby invisible runes."
|
||||
invocation = "Nikt'o barada kla'atu!"
|
||||
health_cost = 1
|
||||
|
||||
/obj/item/weapon/paper/talisman/true_sight/invoke(mob/living/user)
|
||||
user.visible_message("<span class='warning'>A flash of light shines from [user]'s hand!</span>", \
|
||||
"<span class='cultitalic'>You speak the words of the talisman, revealing nearby runes.</span>")
|
||||
for(var/obj/effect/rune/R in orange(3,user))
|
||||
R.invisibility = 0
|
||||
|
||||
|
||||
//Rite of False Truths: Same as rune
|
||||
/obj/item/weapon/paper/talisman/make_runes_fake
|
||||
cultist_name = "Talisman of Disguising"
|
||||
cultist_desc = "A talisman that will make nearby runes appear fake."
|
||||
invocation = "By'o isit!"
|
||||
health_cost = 3
|
||||
|
||||
/obj/item/weapon/paper/talisman/make_runes_fake/invoke(mob/living/user)
|
||||
user.visible_message("<span class='warning'>Dust flows from [user]s hand.</span>", \
|
||||
"<span class='cultitalic'>You speak the words of the talisman, making nearby runes appear fake.</span>")
|
||||
for(var/obj/effect/rune/R in orange(3,user))
|
||||
R.desc = "A rune drawn in crayon."
|
||||
for(var/obj/effect/rune/R in orange(3,src))
|
||||
if(R.invisibility == INVISIBILITY_OBSERVER)
|
||||
R.invisibility = 0
|
||||
R.alpha = initial(R.alpha)
|
||||
else
|
||||
R.visible_message("<span class='danger'>[R] fades away.</span>")
|
||||
R.invisibility = INVISIBILITY_OBSERVER
|
||||
R.alpha = 100 //To help ghosts distinguish hidden runes
|
||||
|
||||
|
||||
//Rite of Disruption: Same as rune
|
||||
@@ -236,42 +185,20 @@ Rite of Disorientation
|
||||
empulse(src, 4, 8)
|
||||
|
||||
|
||||
//Rite of Disorientation: Stuns and mutes a single target for quite some time
|
||||
/obj/item/weapon/paper/talisman/stun
|
||||
cultist_name = "Talisman of Stunning"
|
||||
cultist_desc = "A talisman that will stun and mute a single target. To use, attack target directly."
|
||||
invocation = "Fuu ma'jin!"
|
||||
health_cost = 10 //A lot of health because of how powerful this is
|
||||
//Rite of the Cleansing Flame: Same as rune
|
||||
/obj/item/weapon/paper/talisman/flame
|
||||
cultist_name = "Talisman of Immolation"
|
||||
cultist_desc = "A talisman that sets any non-believers who can see you on fire."
|
||||
invocation = "Dedo va'batoh!"
|
||||
health_cost = 10
|
||||
|
||||
/obj/item/weapon/paper/talisman/stun/attack_self(mob/living/user)
|
||||
if(iscultist(user))
|
||||
user << "<span class='warning'>To use this talisman, attack the target directly.</span>"
|
||||
else
|
||||
user << "<span class='danger'>There are indecipherable images scrawled on the paper in what looks to be... <i>blood?</i></span>"
|
||||
|
||||
/obj/item/weapon/paper/talisman/stun/attack(mob/living/target, mob/living/user)
|
||||
if(iscultist(user))
|
||||
user.whisper(invocation)
|
||||
user.visible_message("<span class='warning'>[user] holds up [src], which explodes in a flash of red light!</span>", \
|
||||
"<span class='cultitalic'>You stun [target] with the talisman!</span>")
|
||||
var/obj/item/weapon/nullrod/N = locate() in target
|
||||
if(N)
|
||||
target.visible_message("<span class='warning'>[target]'s null rod absorbs the talisman's light!</span>", \
|
||||
"<span class='userdanger'>Your null rod absorbs the blinding light!</span>")
|
||||
else
|
||||
target.Weaken(10)
|
||||
target.Stun(10)
|
||||
target.flash_eyes(1,1)
|
||||
if(issilicon(target))
|
||||
var/mob/living/silicon/S = target
|
||||
S.emp_act(1)
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
C.silent += 10
|
||||
user.drop_item()
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
/obj/item/weapon/paper/talisman/flame/invoke(mob/living/user)
|
||||
user.visible_message("<span class='warning'>\The [src] in [user]'s hand suddenly burns away in a red flash!</span>", \
|
||||
"<span class='cultitalic'>You speak the words of the talisman, setting your enemies on fire.</span>")
|
||||
for(var/mob/living/carbon/C in viewers(user))
|
||||
if(!iscultist(C) && !C.null_rod_check())
|
||||
C << "<span class='cultlarge'>You feel your skin crisp as you burst into flames!</span>"
|
||||
C.fire_act()
|
||||
|
||||
|
||||
//Rite of Arming: Equips cultist armor on the user, where available
|
||||
|
||||
@@ -113,6 +113,10 @@
|
||||
synd_mind.current.real_name = "[syndicate_name()] [leader_title]"
|
||||
synd_mind.current << "<B>You are the Syndicate [leader_title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.</B>"
|
||||
synd_mind.current << "<B>If you feel you are not up to this task, give your ID to another operative.</B>"
|
||||
synd_mind.current << "<B>In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.</B>"
|
||||
|
||||
var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge
|
||||
synd_mind.current.equip_to_slot_or_del(challenge, slot_r_hand)
|
||||
|
||||
var/list/foundIDs = synd_mind.current.search_contents_for(/obj/item/weapon/card/id)
|
||||
if(foundIDs.len)
|
||||
@@ -135,6 +139,7 @@
|
||||
return
|
||||
|
||||
|
||||
|
||||
/datum/game_mode/proc/forge_syndicate_objectives(datum/mind/syndicate)
|
||||
var/datum/objective/nuclear/syndobj = new
|
||||
syndobj.owner = syndicate
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#define CHALLENGE_TIME_LIMIT 3000
|
||||
#define MIN_CHALLENGE_PLAYERS 50
|
||||
|
||||
/obj/item/device/nuclear_challenge
|
||||
name = "Declaration of War (Challenge Mode)"
|
||||
icon_state = "gangtool-red"
|
||||
item_state = "walkietalkie"
|
||||
desc = "Use to send a declaration of hostilities to the target, delaying your shuttle departure for 20 minutes while they prepare for your assault. \
|
||||
Such a brazen move will attract the attention of powerful benefactors within the Syndicate, who will supply your team with a massive amount of bonus telecrystals. \
|
||||
Must be used within five minutes, or your benefactors will lose interest."
|
||||
|
||||
|
||||
|
||||
/obj/item/device/nuclear_challenge/attack_self(mob/living/user)
|
||||
if(player_list.len < MIN_CHALLENGE_PLAYERS)
|
||||
user << "The enemy crew is too small to be worth declaring war on."
|
||||
return
|
||||
if(user.z != ZLEVEL_CENTCOM)
|
||||
user << "You have to be at your base to use this."
|
||||
return
|
||||
|
||||
if(world.time > CHALLENGE_TIME_LIMIT)
|
||||
user << "It's too late to declare hostilities. Your benefactors are already busy with other schemes. You'll have to make do with what you have on hand."
|
||||
return
|
||||
|
||||
var/are_you_sure = alert(user, "Consult your team carefully before you declare war on [station_name()]]. Are you sure you want to alert the enemy crew?", "Declare war?", "Yes", "No")
|
||||
if(are_you_sure == "No")
|
||||
user << "On second thought, the element of surprise isn't so bad after all."
|
||||
return
|
||||
|
||||
var/war_declaration = "[user.real_name] has declared his intent to utterly destroy [station_name()] with a nuclear device, and dares the crew to try and stop them."
|
||||
priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/Alarm.ogg')
|
||||
user << "You've attracted the attention of powerful forces within the syndicate. A bonus bundle of telecrystals has been granted to your team. Great things await you if you complete the mission."
|
||||
|
||||
for(var/obj/machinery/computer/shuttle/syndicate/S in machines)
|
||||
S.challenge = TRUE
|
||||
|
||||
var/obj/item/device/radio/uplink/U = new /obj/item/device/radio/uplink(get_turf(user))
|
||||
U.hidden_uplink.uplink_owner= "[user.key]"
|
||||
U.hidden_uplink.uses = 280
|
||||
U.hidden_uplink.mode_override = /datum/game_mode/nuclear //Maybe we can have a special set of items for the challenge uplink eventually
|
||||
qdel(src)
|
||||
|
||||
|
||||
#undef CHALLENGE_TIME_LIMIT
|
||||
#undef MIN_CHALLENGE_PLAYERS
|
||||
@@ -192,7 +192,7 @@
|
||||
if(khrushchev.current && khrushchev.current.client && khrushchev.current.stat != DEAD)
|
||||
if(ROLE_REV in khrushchev.current.client.prefs.be_special)
|
||||
promotable_revs += khrushchev
|
||||
if(promotable_revs)
|
||||
if(promotable_revs.len)
|
||||
var/datum/mind/stalin = pick(promotable_revs)
|
||||
revolutionaries -= stalin
|
||||
head_revolutionaries += stalin
|
||||
|
||||
@@ -28,9 +28,12 @@
|
||||
if(!istype(M, /mob/living/carbon/human))//If target is not a human.
|
||||
return ..()
|
||||
if(istype(M, /mob/living/carbon/human/dummy))
|
||||
return..()
|
||||
return ..()
|
||||
add_logs(user, M, "captured [M.name]'s soul", src)
|
||||
|
||||
if(iscultist(user) && M && M.mind)
|
||||
new /obj/item/summoning_orb(get_turf(M))
|
||||
|
||||
transfer_soul("VICTIM", M, user)
|
||||
return
|
||||
|
||||
@@ -104,7 +107,7 @@
|
||||
/obj/item/device/soulstone/proc/transfer_soul(choice as text, target, mob/user).
|
||||
switch(choice)
|
||||
if("FORCE")
|
||||
if(!iscarbon(target)) //TO-DO: Add sacrifice stoning for non-organics, just because you have no body doesnt mean you dont have a soul
|
||||
if(!iscarbon(target)) //TODO: Add sacrifice stoning for non-organics, just because you have no body doesnt mean you dont have a soul
|
||||
return 0
|
||||
if(contents.len)
|
||||
return 0
|
||||
@@ -120,12 +123,6 @@
|
||||
|
||||
if("VICTIM")
|
||||
var/mob/living/carbon/human/T = target
|
||||
if(ticker.mode.name == "cult" && T.mind == ticker.mode:sacrifice_target)
|
||||
if(iscultist(user))
|
||||
user << "<span class='danger'>The Geometer of blood wants this mortal sacrificed with the rune.</span>"
|
||||
else
|
||||
user << "<span class='danger'>The soul stone doesn't work for no apparent reason.</span>"
|
||||
return 0
|
||||
if(imprinted != "empty")
|
||||
user << "<span class='userdanger'>Capture failed!</span>: The soul stone has already been imprinted with [imprinted]'s mind!"
|
||||
else
|
||||
@@ -200,7 +197,7 @@
|
||||
if(stoner && iswizard(stoner))
|
||||
newstruct << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
|
||||
else if(stoner && iscultist(stoner))
|
||||
newstruct << "<B>You are still bound to serve the cult, follow their orders and help them complete their goals at all costs.</B>"
|
||||
newstruct << "<B>You are still bound to serve the cult, follow their orders and help them summon the Geometer at all costs.</B>"
|
||||
else newstruct << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
|
||||
newstruct.cancel_camera()
|
||||
|
||||
|
||||
@@ -80,12 +80,13 @@
|
||||
|
||||
// breathable air according to human/Life()
|
||||
var/list/TLV = list(
|
||||
"oxygen" = new/datum/tlv( 16, 19, 135, 140), // Partial pressure, kpa
|
||||
"carbon dioxide" = new/datum/tlv(-1, -1, 5, 10), // Partial pressure, kpa
|
||||
"plasma" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
|
||||
"other" = new/datum/tlv(-1, -1, 0.5, 1), // Partial pressure, kpa
|
||||
"pressure" = new/datum/tlv(ONE_ATMOSPHERE*0.80,ONE_ATMOSPHERE*0.90,ONE_ATMOSPHERE*1.10,ONE_ATMOSPHERE*1.20), /* kpa */
|
||||
"temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), // K
|
||||
"oxygen" = new/datum/tlv(16,19,135,140), // Partial pressure, kpa
|
||||
"nitrogen" = new/datum/tlv(-1,-1,1000,1000), // Partial pressure, kpa
|
||||
"carbon dioxide" = new/datum/tlv(-1,-1,5,10), // Partial pressure, kpa
|
||||
"plasma" = new/datum/tlv(-1,-1,0.2,0.5), // Partial pressure, kpa
|
||||
"other" = new/datum/tlv(-1,-1,0.5,1), // Partial pressure, kpa
|
||||
"pressure" = new/datum/tlv(ONE_ATMOSPHERE*0.80,ONE_ATMOSPHERE*0.90,ONE_ATMOSPHERE*1.10,ONE_ATMOSPHERE*1.20), // kPa
|
||||
"temperature" = new/datum/tlv(T0C,T0C+10,T0C+40,T0C+66), // K
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -96,22 +97,24 @@
|
||||
/obj/machinery/alarm/server
|
||||
//req_access = list(access_rd) //no, let departaments to work together
|
||||
TLV = list(
|
||||
"oxygen" = new/datum/tlv(-1, -1,-1,-1), // Partial pressure, kpa
|
||||
"carbon dioxide" = new/datum/tlv(-1, -1,-1,-1), // Partial pressure, kpa
|
||||
"plasma" = new/datum/tlv(-1, -1,-1,-1), // Partial pressure, kpa
|
||||
"other" = new/datum/tlv(-1, -1,-1,-1), // Partial pressure, kpa
|
||||
"pressure" = new/datum/tlv(-1, -1,-1,-1), /* kpa */
|
||||
"temperature" = new/datum/tlv(-1, -1,-1,-1), // K
|
||||
"oxygen" = new/datum/tlv(-1,-1,-1,-1), // Partial pressure, kpa
|
||||
"nitrogen" = new/datum/tlv(-1,-1,-1,-1), // Partial pressure, kpa
|
||||
"carbon dioxide" = new/datum/tlv(-1,-1,-1,-1), // Partial pressure, kpa
|
||||
"plasma" = new/datum/tlv(-1,-1,-1,-1), // Partial pressure, kpa
|
||||
"other" = new/datum/tlv(-1,-1,-1,-1), // Partial pressure, kpa
|
||||
"pressure" = new/datum/tlv(-1,-1,-1,-1), /* kpa */
|
||||
"temperature" = new/datum/tlv(-1,-1,-1,-1), // K
|
||||
)
|
||||
|
||||
/obj/machinery/alarm/kitchen_cold_room
|
||||
TLV = list(
|
||||
"oxygen" = new/datum/tlv( 16, 19, 135, 140), // Partial pressure, kpa
|
||||
"carbon dioxide" = new/datum/tlv(-1, -1, 5, 10), // Partial pressure, kpa
|
||||
"plasma" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
|
||||
"other" = new/datum/tlv(-1, -1, 0.5, 1), // Partial pressure, kpa
|
||||
"pressure" = new/datum/tlv(ONE_ATMOSPHERE*0.80,ONE_ATMOSPHERE*0.90,ONE_ATMOSPHERE*1.50,ONE_ATMOSPHERE*1.60), /* kpa */
|
||||
"temperature" = new/datum/tlv(200, 210, 273.15, 283.15), // K
|
||||
"oxygen" = new/datum/tlv(16,19,135,140), // Partial pressure, kpa
|
||||
"nitrogen" = new/datum/tlv(-1,-1,1000,1000), // Partial pressure, kpa
|
||||
"carbon dioxide" = new/datum/tlv(-1,-1,5,10), // Partial pressure, kpa
|
||||
"plasma" = new/datum/tlv(-1,-1,0.2,0.5), // Partial pressure, kpa
|
||||
"other" = new/datum/tlv(-1,-1,0.5,1), // Partial pressure, kpa
|
||||
"pressure" = new/datum/tlv(ONE_ATMOSPHERE*0.80,ONE_ATMOSPHERE*0.90,ONE_ATMOSPHERE*1.10,ONE_ATMOSPHERE*1.20), // kPa
|
||||
"temperature" = new/datum/tlv(200,210,273.15,283.15), // K
|
||||
)
|
||||
|
||||
//all air alarms in area are connected via magic
|
||||
@@ -187,7 +190,7 @@
|
||||
/obj/machinery/alarm/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "air_alarm.tmpl", name, 480, 625)
|
||||
ui = new(user, src, ui_key, "air_alarm", name, 480, 660)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/alarm/get_ui_data(mob/user)
|
||||
@@ -253,7 +256,7 @@
|
||||
if(!location)
|
||||
return
|
||||
var/datum/gas_mixture/environment = location.return_air()
|
||||
var/total = environment.oxygen + environment.carbon_dioxide + environment.toxins + environment.nitrogen
|
||||
var/total = environment.oxygen + environment.nitrogen + environment.carbon_dioxide + environment.toxins
|
||||
|
||||
var/list/environment_data = list()
|
||||
data["atmos_alarm"] = alarm_area.atmosalm
|
||||
@@ -272,9 +275,13 @@
|
||||
var/oxygen_danger = cur_tlv.get_danger_level(environment.oxygen*partial_pressure)
|
||||
environment_data += list(list("name" = "Oxygen", "value" = environment.oxygen / total * 100, "unit" = "%", "danger_level" = oxygen_danger))
|
||||
|
||||
cur_tlv = TLV["nitrogen"]
|
||||
var/nitrogen_danger = cur_tlv.get_danger_level(environment.nitrogen*partial_pressure)
|
||||
environment_data += list(list("name" = "Nitrogen", "value" = environment.nitrogen / total * 100, "unit" = "%", "danger_level" = nitrogen_danger))
|
||||
|
||||
cur_tlv = TLV["carbon dioxide"]
|
||||
var/carbon_dioxide_danger = cur_tlv.get_danger_level(environment.carbon_dioxide*partial_pressure)
|
||||
environment_data += list(list("name" = "Carbon dioxide", "value" = environment.carbon_dioxide / total * 100, "unit" = "%", "danger_level" = carbon_dioxide_danger))
|
||||
environment_data += list(list("name" = "Carbon Dioxide", "value" = environment.carbon_dioxide / total * 100, "unit" = "%", "danger_level" = carbon_dioxide_danger))
|
||||
|
||||
cur_tlv = TLV["plasma"]
|
||||
var/plasma_danger = cur_tlv.get_danger_level(environment.toxins*partial_pressure)
|
||||
@@ -290,6 +297,7 @@
|
||||
cur_tlv = TLV["temperature"]
|
||||
var/temperature_danger = cur_tlv.get_danger_level(environment.temperature)
|
||||
environment_data += list(list("name" = "Temperature", "value" = environment.temperature, "unit" = "K ([round(environment.temperature - T0C, 0.1)]C)", "danger_level" = temperature_danger))
|
||||
|
||||
data["environment_data"] = environment_data
|
||||
|
||||
/obj/machinery/alarm/proc/populate_controls(list/data)
|
||||
@@ -311,7 +319,8 @@
|
||||
"excheck" = info["checks"]&1,
|
||||
"incheck" = info["checks"]&2,
|
||||
"direction" = info["direction"],
|
||||
"external" = info["external"]
|
||||
"external" = info["external"],
|
||||
"extdefault"= (info["external"] == ONE_ATMOSPHERE)
|
||||
))
|
||||
if(AALARM_SCREEN_SCRUB)
|
||||
data["scrubbers"] = list()
|
||||
@@ -348,10 +357,11 @@
|
||||
var/list/thresholds = list()
|
||||
|
||||
var/list/gas_names = list(
|
||||
"oxygen" = "O<sub>2</sub>",
|
||||
"carbon dioxide" = "CO<sub>2</sub>",
|
||||
"plasma" = "Toxin",
|
||||
"other" = "Other")
|
||||
"oxygen" = "O<sub>2</sub>",
|
||||
"nitrogen" = "N<sub>2</sub>",
|
||||
"carbon dioxide" = "CO<sub>2</sub>",
|
||||
"plasma" = "Toxin",
|
||||
"other" = "Other")
|
||||
for (var/g in gas_names)
|
||||
thresholds += list(list("name" = gas_names[g], "settings" = list()))
|
||||
selected = TLV[g]
|
||||
@@ -377,7 +387,7 @@
|
||||
|
||||
data["thresholds"] = thresholds
|
||||
|
||||
/obj/machinery/alarm/Topic(href, href_list)
|
||||
/obj/machinery/alarm/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
@@ -390,78 +400,65 @@
|
||||
if (usr.has_unlimited_silicon_privilege && src.aidisabled)
|
||||
return
|
||||
|
||||
if(href_list["toggleaccess"])
|
||||
if(usr.has_unlimited_silicon_privilege && !wires.IsIndexCut(AALARM_WIRE_IDSCAN))
|
||||
locked = !locked
|
||||
|
||||
if(href_list["command"])
|
||||
var/device_id = href_list["id_tag"]
|
||||
switch(href_list["command"])
|
||||
if("set_external_pressure")
|
||||
var/input_pressure = input("What pressure you like the system to mantain?", "Pressure Controls") as num|null
|
||||
if(isnum(input_pressure))
|
||||
send_signal(device_id, list(href_list["command"] = input_pressure))
|
||||
return 1
|
||||
|
||||
if("reset_external_pressure")
|
||||
send_signal(device_id, list("set_external_pressure" = ONE_ATMOSPHERE))
|
||||
return 1
|
||||
if(
|
||||
"power",
|
||||
"adjust_external_pressure",
|
||||
"co2_scrub",
|
||||
"tox_scrub",
|
||||
"n2o_scrub",
|
||||
"widenet",
|
||||
"scrubbing"
|
||||
)
|
||||
send_signal(device_id, list (href_list["command"] = text2num(href_list["val"])))
|
||||
spawn(3)
|
||||
src.updateUsrDialog()
|
||||
|
||||
if ("excheck")
|
||||
send_signal(device_id, list ("checks" = text2num(href_list["val"])^1))
|
||||
|
||||
if ("incheck")
|
||||
send_signal(device_id, list ("checks" = text2num(href_list["val"])^2))
|
||||
|
||||
//if("adjust_threshold") //was a good idea but required very wide window
|
||||
if("set_threshold")
|
||||
var/env = href_list["env"]
|
||||
var/varname = href_list["var"]
|
||||
var/datum/tlv/tlv = TLV[env]
|
||||
var/newval = input("Enter [varname] for [env]", "Alarm triggers", tlv.vars[varname]) as num|null
|
||||
|
||||
if (isnull(newval) || ..() || (locked && !(usr.has_unlimited_silicon_privilege)))
|
||||
return
|
||||
if (newval<0)
|
||||
tlv.vars[varname] = -1
|
||||
else if (env=="temperature" && newval>5000)
|
||||
tlv.vars[varname] = 5000
|
||||
else if (env=="pressure" && newval>50*ONE_ATMOSPHERE)
|
||||
tlv.vars[varname] = 50*ONE_ATMOSPHERE
|
||||
else if (env!="temperature" && env!="pressure" && newval>200)
|
||||
tlv.vars[varname] = 200
|
||||
else
|
||||
newval = round(newval,0.01)
|
||||
tlv.vars[varname] = newval
|
||||
|
||||
if(href_list["screen"])
|
||||
screen = text2num(href_list["screen"])
|
||||
|
||||
if(href_list["atmos_alarm"])
|
||||
if (alarm_area.atmosalert(2,src))
|
||||
post_alert(2)
|
||||
update_icon()
|
||||
|
||||
if(href_list["atmos_reset"])
|
||||
if (alarm_area.atmosalert(0,src))
|
||||
post_alert(0)
|
||||
update_icon()
|
||||
|
||||
if(href_list["mode"])
|
||||
mode = text2num(href_list["mode"])
|
||||
apply_mode()
|
||||
switch(action)
|
||||
if("toggleaccess")
|
||||
if(usr.has_unlimited_silicon_privilege && !wires.IsIndexCut(AALARM_WIRE_IDSCAN))
|
||||
locked = !locked
|
||||
if("adjust")
|
||||
var/device_id = params["id_tag"]
|
||||
switch(params["command"])
|
||||
if("set_external_pressure")
|
||||
var/input_pressure = input("Enter target pressure:", "Pressure Controls") as num|null
|
||||
if(isnum(input_pressure))
|
||||
send_signal(device_id, list(params["command"] = input_pressure))
|
||||
if("reset_external_pressure")
|
||||
send_signal(device_id, list("set_external_pressure" = ONE_ATMOSPHERE))
|
||||
if(
|
||||
"power",
|
||||
"adjust_external_pressure",
|
||||
"co2_scrub",
|
||||
"tox_scrub",
|
||||
"n2o_scrub",
|
||||
"widenet",
|
||||
"scrubbing"
|
||||
)
|
||||
send_signal(device_id, list (params["command"] = text2num(params["val"])))
|
||||
if ("excheck")
|
||||
send_signal(device_id, list ("checks" = text2num(params["val"])^1))
|
||||
if ("incheck")
|
||||
send_signal(device_id, list ("checks" = text2num(params["val"])^2))
|
||||
if("set_threshold")
|
||||
var/env = params["env"]
|
||||
var/varname = params["var"]
|
||||
var/datum/tlv/tlv = TLV[env]
|
||||
var/newval = input("Enter [varname] for [env]:", "Alarm Triggers", tlv.vars[varname]) as num|null
|
||||
if (isnull(newval))
|
||||
return
|
||||
if (newval<0)
|
||||
tlv.vars[varname] = -1
|
||||
else if (env=="temperature" && newval>5000)
|
||||
tlv.vars[varname] = 5000
|
||||
else if (env=="pressure" && newval>50*ONE_ATMOSPHERE)
|
||||
tlv.vars[varname] = 50*ONE_ATMOSPHERE
|
||||
else if (env!="temperature" && env!="pressure" && newval>200)
|
||||
tlv.vars[varname] = 200
|
||||
else
|
||||
newval = round(newval,0.01)
|
||||
tlv.vars[varname] = newval
|
||||
if("screen")
|
||||
screen = text2num(params["screen"])
|
||||
if("mode")
|
||||
mode = text2num(params["mode"])
|
||||
apply_mode()
|
||||
if("alarm")
|
||||
if(alarm_area.atmosalert(2, src))
|
||||
post_alert(2)
|
||||
update_icon()
|
||||
if("reset")
|
||||
if(alarm_area.atmosalert(0, src))
|
||||
post_alert(0)
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/machinery/alarm/proc/apply_mode()
|
||||
switch(mode)
|
||||
|
||||
@@ -271,13 +271,12 @@ update_flag
|
||||
/obj/machinery/portable_atmospherics/canister/interact(mob/user)
|
||||
if (src.destroyed)
|
||||
return
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "canister.tmpl", name, 470, 400, state = physical_state)
|
||||
ui = new(user, src, ui_key, "canister", name, 470, 470, state = physical_state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/get_ui_data()
|
||||
@@ -299,71 +298,71 @@ update_flag
|
||||
data["holdingTank"]["tankPressure"] = round(holding.air_contents.return_pressure())
|
||||
return data
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/Topic(href, href_list)
|
||||
/obj/machinery/portable_atmospherics/canister/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
if(href_list["toggle"])
|
||||
var/logmsg
|
||||
if (valve_open)
|
||||
if (holding)
|
||||
logmsg = "Valve was <b>closed</b> by [key_name(usr)], stopping the transfer into the [holding]<br>"
|
||||
else
|
||||
logmsg = "Valve was <b>closed</b> by [key_name(usr)], stopping the transfer into the <span class='boldannounce'>air</span><br>"
|
||||
else
|
||||
if (holding)
|
||||
logmsg = "Valve was <b>opened</b> by [key_name(usr)], starting the transfer into the [holding]<br>"
|
||||
else
|
||||
logmsg = "Valve was <b>opened</b> by [key_name(usr)], starting the transfer into the <span class='boldannounce'>air</span><br>"
|
||||
if(air_contents.toxins > 0)
|
||||
message_admins("[key_name_admin(usr)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[usr]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) opened a canister that contains plasma! (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_admin("[key_name(usr)] opened a canister that contains plasma at [x], [y], [z]")
|
||||
var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in air_contents.trace_gases
|
||||
if(sleeping_agent && (sleeping_agent.moles > 1))
|
||||
message_admins("[key_name_admin(usr)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[usr]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) opened a canister that contains N2O! (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_admin("[key_name(usr)] opened a canister that contains N2O at [x], [y], [z]")
|
||||
investigate_log(logmsg, "atmos")
|
||||
release_log += logmsg
|
||||
valve_open = !valve_open
|
||||
|
||||
if (href_list["remove_tank"])
|
||||
if(holding)
|
||||
switch(action)
|
||||
if("relabel")
|
||||
if (can_label)
|
||||
var/list/colors = list(\
|
||||
"\[N2O\]" = "redws", \
|
||||
"\[N2\]" = "red", \
|
||||
"\[O2\]" = "blue", \
|
||||
"\[Plasma\]" = "orange", \
|
||||
"\[CO2\]" = "black", \
|
||||
"\[Air\]" = "grey", \
|
||||
"\[CAUTION\]" = "yellow", \
|
||||
)
|
||||
var/label = input("Label canister:", "Gas Canister") as null|anything in colors
|
||||
if(label)
|
||||
src.canister_color = colors[label]
|
||||
src.icon_state = colors[label]
|
||||
src.name = "canister: [label]"
|
||||
if("pressure")
|
||||
switch(params["set"])
|
||||
if("custom")
|
||||
var/custom = input(usr, "What rate do you set the regulator to? The dial reads from [CAN_MIN_RELEASE_PRESSURE] to [CAN_MAX_RELEASE_PRESSURE].") as null|num
|
||||
if(custom)
|
||||
release_pressure = custom
|
||||
if("reset")
|
||||
release_pressure = CAN_DEFAULT_RELEASE_PRESSURE
|
||||
if("min")
|
||||
release_pressure = CAN_MIN_RELEASE_PRESSURE
|
||||
if("max")
|
||||
release_pressure = CAN_MAX_RELEASE_PRESSURE
|
||||
release_pressure = Clamp(round(release_pressure), CAN_MIN_RELEASE_PRESSURE, CAN_MAX_RELEASE_PRESSURE)
|
||||
if("valve")
|
||||
var/logmsg
|
||||
if (valve_open)
|
||||
investigate_log("[key_name(usr)] removed the [holding], leaving the valve open and transfering into the <span class='boldannounce'>air</span><br>", "atmos")
|
||||
holding.loc = loc
|
||||
holding = null
|
||||
if (href_list["release_p"])
|
||||
if (href_list["release_p"] == "custom")
|
||||
var/custom = input(usr, "What rate do you set the regulator to? The dial reads from [CAN_MIN_RELEASE_PRESSURE] to [CAN_MAX_RELEASE_PRESSURE].") as null|num
|
||||
if(isnum(custom))
|
||||
href_list["release_p"] = custom
|
||||
.()
|
||||
else if (href_list["release_p"] == "reset")
|
||||
release_pressure = CAN_DEFAULT_RELEASE_PRESSURE
|
||||
else if (href_list["release_p"] == "min")
|
||||
release_pressure = CAN_MIN_RELEASE_PRESSURE
|
||||
else if (href_list["release_p"] == "max")
|
||||
release_pressure = CAN_MAX_RELEASE_PRESSURE
|
||||
else
|
||||
release_pressure = text2num(href_list["release_p"])
|
||||
release_pressure = min(max(round(release_pressure), CAN_MIN_RELEASE_PRESSURE), CAN_MAX_RELEASE_PRESSURE)
|
||||
if (href_list["relabel"])
|
||||
if (can_label)
|
||||
var/list/colors = list(\
|
||||
"\[N2O\]" = "redws", \
|
||||
"\[N2\]" = "red", \
|
||||
"\[O2\]" = "blue", \
|
||||
"\[Plasma\]" = "orange", \
|
||||
"\[CO2\]" = "black", \
|
||||
"\[Air\]" = "grey", \
|
||||
"\[CAUTION\]" = "yellow", \
|
||||
)
|
||||
var/label = input("Choose canister label", "Gas canister") as null|anything in colors
|
||||
if (label)
|
||||
src.canister_color = colors[label]
|
||||
src.icon_state = colors[label]
|
||||
src.name = "canister: [label]"
|
||||
|
||||
if (holding)
|
||||
logmsg = "Valve was <b>closed</b> by [key_name(usr)], stopping the transfer into the [holding]<br>"
|
||||
else
|
||||
logmsg = "Valve was <b>closed</b> by [key_name(usr)], stopping the transfer into the <span class='boldannounce'>air</span><br>"
|
||||
else
|
||||
if (holding)
|
||||
logmsg = "Valve was <b>opened</b> by [key_name(usr)], starting the transfer into the [holding]<br>"
|
||||
else
|
||||
logmsg = "Valve was <b>opened</b> by [key_name(usr)], starting the transfer into the <span class='boldannounce'>air</span><br>"
|
||||
if(air_contents.toxins > 0)
|
||||
message_admins("[key_name_admin(usr)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[usr]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) opened a canister that contains plasma! (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_admin("[key_name(usr)] opened a canister that contains plasma at [x], [y], [z]")
|
||||
var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in air_contents.trace_gases
|
||||
if(sleeping_agent && (sleeping_agent.moles > 1))
|
||||
message_admins("[key_name_admin(usr)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[usr]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) opened a canister that contains N2O! (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_admin("[key_name(usr)] opened a canister that contains N2O at [x], [y], [z]")
|
||||
investigate_log(logmsg, "atmos")
|
||||
release_log += logmsg
|
||||
valve_open = !valve_open
|
||||
if("eject")
|
||||
if(holding)
|
||||
if (valve_open)
|
||||
investigate_log("[key_name(usr)] removed the [holding], leaving the valve open and transfering into the <span class='boldannounce'>air</span><br>", "atmos")
|
||||
holding.loc = loc
|
||||
holding = null
|
||||
add_fingerprint(usr)
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/toxins/New()
|
||||
..()
|
||||
|
||||
@@ -203,6 +203,8 @@
|
||||
for(var/mob/O in player_list)
|
||||
if(istype(O, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/AI = O
|
||||
if(AI.control_disabled || (AI.stat == DEAD))
|
||||
return
|
||||
if(U.name == "Unknown")
|
||||
AI << "<b>[U]</b> holds <a href='?_src_=usr;show_paper=1;'>\a [itemname]</a> up to one of your cameras ..."
|
||||
else
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define SYNDICATE_CHALLENGE_TIMER 12000 //20 minutes
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate
|
||||
name = "syndicate shuttle terminal"
|
||||
icon_screen = "syndishuttle"
|
||||
@@ -5,7 +7,18 @@
|
||||
req_access = list(access_syndicate)
|
||||
shuttleId = "syndicate"
|
||||
possible_destinations = "syndicate_away;syndicate_z5;syndicate_ne;syndicate_nw;syndicate_n;syndicate_se;syndicate_sw;syndicate_s"
|
||||
var/challenge = FALSE
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate/recall
|
||||
name = "syndicate shuttle recall terminal"
|
||||
possible_destinations = "syndicate_away"
|
||||
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate/Topic(href, href_list)
|
||||
if(href_list["move"])
|
||||
if(challenge && world.time < SYNDICATE_CHALLENGE_TIMER)
|
||||
usr << "<span class='warning'>You've issued a combat challenge to the station! You've got to give them at least [round(((SYNDICATE_CHALLENGE_TIMER - world.time) / 10) / 60)] more minutes to allow them to prepare.</span>"
|
||||
return 0
|
||||
..()
|
||||
|
||||
#undef SYNDICATE_CHALLENGE_TIMER
|
||||
@@ -16,7 +16,7 @@
|
||||
/obj/item/weapon/electronics/airlock/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0)
|
||||
SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "airlock_electronics.tmpl", name, 975, 415, state = hands_state)
|
||||
ui = new(user, src, ui_key, "airlock_electronics", name, 975, 415, state = hands_state)
|
||||
ui.open()
|
||||
|
||||
/obj/item/weapon/electronics/airlock/get_ui_data()
|
||||
@@ -40,19 +40,20 @@
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/weapon/electronics/airlock/Topic(href, href_list)
|
||||
/obj/item/weapon/electronics/airlock/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(href_list["access"])
|
||||
if(href_list["access"] == "clear")
|
||||
switch(action)
|
||||
if("clear")
|
||||
accesses = list()
|
||||
one_access = 0
|
||||
else if(href_list["access"] == "one")
|
||||
if("one_access")
|
||||
one_access = !one_access
|
||||
else
|
||||
var/access = text2num(href_list["access"])
|
||||
if("set")
|
||||
var/access = text2num(params["access"])
|
||||
if (!(access in accesses))
|
||||
accesses += access
|
||||
else
|
||||
accesses -= access
|
||||
return 1
|
||||
|
||||
@@ -108,6 +108,12 @@
|
||||
doortype = /obj/structure/door_assembly/door_assembly_viro/glass
|
||||
glass = 1
|
||||
|
||||
/obj/machinery/door/airlock/glass_maintenance
|
||||
icon = 'icons/obj/doors/airlocks/station/maintenance.dmi'
|
||||
opacity = 0
|
||||
doortype = /obj/structure/door_assembly/door_assembly_mai/glass
|
||||
glass = 1
|
||||
|
||||
//////////////////////////////////
|
||||
/*
|
||||
Station Airlocks Mineral
|
||||
@@ -216,6 +222,14 @@
|
||||
overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi'
|
||||
doortype = /obj/structure/door_assembly/door_assembly_ext
|
||||
|
||||
/obj/machinery/door/airlock/glass_external
|
||||
name = "external airlock"
|
||||
icon = 'icons/obj/doors/airlocks/external/external.dmi'
|
||||
overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi'
|
||||
doortype = /obj/structure/door_assembly/door_assembly_ext/glass
|
||||
opacity = 0
|
||||
glass = 1
|
||||
|
||||
//////////////////////////////////
|
||||
/*
|
||||
Centcom Airlocks
|
||||
|
||||
@@ -209,6 +209,13 @@ Class Procs:
|
||||
add_fingerprint(usr)
|
||||
return 0
|
||||
|
||||
/obj/machinery/ui_act(action, params)
|
||||
..()
|
||||
if(!can_be_used_by(usr))
|
||||
return 1
|
||||
add_fingerprint(usr)
|
||||
return 0
|
||||
|
||||
/obj/machinery/proc/can_be_used_by(mob/user)
|
||||
if(!interact_offline && stat & (NOPOWER|BROKEN))
|
||||
return 0
|
||||
|
||||
@@ -159,65 +159,57 @@
|
||||
/obj/machinery/space_heater/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "space_heater.tmpl", name, 490, 350, state = physical_state)
|
||||
ui = new(user, src, ui_key, "space_heater", name, 490, 340, state = physical_state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/space_heater/Topic(href, href_list)
|
||||
if((stat & BROKEN) || ..())
|
||||
/obj/machinery/space_heater/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
mode = HEATER_MODE_STANDBY
|
||||
usr.visible_message("[usr] switches [on ? "on" : "off"] \the [src].", "<span class='notice'>You switch [on ? "on" : "off"] \the [src].</span>")
|
||||
update_icon()
|
||||
if("mode")
|
||||
setMode = params["mode"]
|
||||
if("temp")
|
||||
if(panel_open)
|
||||
var/value
|
||||
if(params["set"] == "custom")
|
||||
value = input("Please input the target temperature", name) as num|null
|
||||
if(isnull(value))
|
||||
return
|
||||
value += T0C
|
||||
else
|
||||
value = targetTemperature + text2num(params["set"])
|
||||
|
||||
if(href_list["power"])
|
||||
on = !!text2num(href_list["power"])
|
||||
mode = HEATER_MODE_STANDBY
|
||||
usr.visible_message("[usr] switches [on ? "on" : "off"] \the [src].", "<span class='notice'>You switch [on ? "on" : "off"] \the [src].</span>")
|
||||
update_icon()
|
||||
SSnano.update_uis(src)
|
||||
|
||||
else if(href_list["mode"])
|
||||
setMode = href_list["mode"]
|
||||
SSnano.update_uis(src)
|
||||
|
||||
else if(href_list["temp"] && panel_open)
|
||||
var/value
|
||||
if(href_list["temp"] == "custom")
|
||||
value = input("Please input the target temperature", name) as num|null
|
||||
if(isnull(value))
|
||||
return
|
||||
value += T0C
|
||||
else
|
||||
value = targetTemperature + text2num(href_list["temp"])
|
||||
|
||||
var/minTemp = max(settableTemperatureMedian - settableTemperatureRange, TCMB)
|
||||
var/maxTemp = settableTemperatureMedian + settableTemperatureRange
|
||||
targetTemperature = dd_range(minTemp, maxTemp, round(value, 1))
|
||||
SSnano.update_uis(src)
|
||||
|
||||
else if(href_list["cellremove"] && panel_open)
|
||||
if(cell)
|
||||
if(usr.get_active_hand())
|
||||
usr << "<span class='warning'>You need an empty hand to remove \the [cell]!</span>"
|
||||
return
|
||||
cell.updateicon()
|
||||
usr.put_in_hands(cell)
|
||||
cell.add_fingerprint(usr)
|
||||
usr.visible_message("\The [usr] removes \the [cell] from \the [src].", "<span class='notice'>You remove \the [cell] from \the [src].</span>")
|
||||
cell = null
|
||||
SSnano.update_uis(src)
|
||||
|
||||
else if(href_list["cellinstall"] && panel_open)
|
||||
if(!cell)
|
||||
var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand()
|
||||
if(istype(C))
|
||||
if(!usr.drop_item())
|
||||
var/minTemp = max(settableTemperatureMedian - settableTemperatureRange, TCMB)
|
||||
var/maxTemp = settableTemperatureMedian + settableTemperatureRange
|
||||
targetTemperature = dd_range(minTemp, maxTemp, round(value, 1))
|
||||
if("ejectcell")
|
||||
if(panel_open && cell)
|
||||
if(usr.get_active_hand())
|
||||
usr << "<span class='warning'>You need an empty hand to remove \the [cell]!</span>"
|
||||
return
|
||||
cell = C
|
||||
C.loc = src
|
||||
C.add_fingerprint(usr)
|
||||
|
||||
usr.visible_message("\The [usr] inserts \a [C] into \the [src].", "<span class='notice'>You insert \the [C] into \the [src].</span>")
|
||||
SSnano.update_uis(src)
|
||||
cell.updateicon()
|
||||
usr.put_in_hands(cell)
|
||||
cell.add_fingerprint(usr)
|
||||
usr.visible_message("\The [usr] removes \the [cell] from \the [src].", "<span class='notice'>You remove \the [cell] from \the [src].</span>")
|
||||
cell = null
|
||||
if("installcell")
|
||||
if(panel_open && !cell)
|
||||
var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand()
|
||||
if(istype(C))
|
||||
if(!usr.drop_item())
|
||||
return
|
||||
cell = C
|
||||
C.loc = src
|
||||
C.add_fingerprint(usr)
|
||||
usr.visible_message("\The [usr] inserts \a [C] into \the [src].", "<span class='notice'>You insert \the [C] into \the [src].</span>")
|
||||
add_fingerprint(usr)
|
||||
return 1
|
||||
|
||||
/obj/machinery/space_heater/process()
|
||||
if(!on || (stat & BROKEN))
|
||||
|
||||
@@ -254,9 +254,12 @@
|
||||
if(newfreq && canAccess(usr))
|
||||
if(findtext(num2text(newfreq), "."))
|
||||
newfreq *= 10 // shift the decimal one place
|
||||
if(!(newfreq in freq_listening) && newfreq < 10000)
|
||||
freq_listening.Add(newfreq)
|
||||
temp = "<font color = #666633>-% New frequency filter assigned: \"[newfreq] GHz\" %-</font color>"
|
||||
if(newfreq == SYND_FREQ)
|
||||
temp = "<font color = #FF0000>-% Error: Interference preventing filtering frequency: \"[newfreq] GHz\" %-</font color>"
|
||||
else
|
||||
if(!(newfreq in freq_listening) && newfreq < 10000)
|
||||
freq_listening.Add(newfreq)
|
||||
temp = "<font color = #666633>-% New frequency filter assigned: \"[newfreq] GHz\" %-</font color>"
|
||||
|
||||
if(href_list["delete"])
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
|
||||
if(is_freq_listening(signal))
|
||||
if(change_frequency)
|
||||
signal.frequency = change_frequency
|
||||
if(signal.frequency != SYND_FREQ)
|
||||
signal.frequency = change_frequency
|
||||
|
||||
if(!istype(machine_from, /obj/machinery/telecomms/processor) && machine_from != src) // Signal must be ready (stupid assuming machine), let's send it
|
||||
// send to one linked processor unit
|
||||
|
||||
@@ -287,6 +287,8 @@
|
||||
return power_station
|
||||
|
||||
/obj/machinery/teleport/hub/Bumped(M as mob|obj)
|
||||
if(z == ZLEVEL_CENTCOM)
|
||||
M << "You can't use this here."
|
||||
if(power_station && power_station.engaged && !panel_open)
|
||||
teleport(M)
|
||||
use_power(5000)
|
||||
|
||||
@@ -118,12 +118,13 @@
|
||||
var/obj/mecha/working/mecha = loc
|
||||
if(!mecha.occupant)
|
||||
return
|
||||
var/mob/pilot = mecha.occupant
|
||||
var/list/occupant = list()
|
||||
occupant |= mecha.occupant
|
||||
mecha.occupant.sight |= SEE_TURFS
|
||||
occupant |= pilot
|
||||
pilot.sight |= SEE_TURFS
|
||||
scanning = 1
|
||||
mineral_scan_pulse(occupant,get_turf(loc))
|
||||
spawn(equip_cooldown)
|
||||
scanning = 0
|
||||
mecha.occupant.sight -= SEE_TURFS
|
||||
pilot.sight -= SEE_TURFS
|
||||
|
||||
|
||||
@@ -1255,6 +1255,7 @@
|
||||
icon_state = "nuketoy"
|
||||
var/cooldown = 0
|
||||
var/toysay = "What the fuck did you do?"
|
||||
var/toysound = 'sound/machines/click.ogg'
|
||||
|
||||
/obj/item/toy/figure/New()
|
||||
desc = "A \"Space Life\" brand [src]."
|
||||
@@ -1263,7 +1264,7 @@
|
||||
if(cooldown <= world.time)
|
||||
cooldown = world.time + 50
|
||||
user << "<span class='notice'>The [src] says \"[toysay]\"</span>"
|
||||
playsound(user, 'sound/machines/click.ogg', 20, 1)
|
||||
playsound(user, toysound, 20, 1)
|
||||
|
||||
/obj/item/toy/figure/cmo
|
||||
name = "Chief Medical Officer action figure"
|
||||
@@ -1289,6 +1290,7 @@
|
||||
name = "Cyborg action figure"
|
||||
icon_state = "borg"
|
||||
toysay = "I. LIVE. AGAIN."
|
||||
toysound = 'sound/voice/liveagain.ogg'
|
||||
|
||||
/obj/item/toy/figure/botanist
|
||||
name = "Botanist action figure"
|
||||
@@ -1329,6 +1331,7 @@
|
||||
name = "Clown action figure"
|
||||
icon_state = "clown"
|
||||
toysay = "Honk!"
|
||||
toysound = 'sound/items/bikehorn.ogg'
|
||||
|
||||
/obj/item/toy/figure/ian
|
||||
name = "Ian action figure"
|
||||
@@ -1394,6 +1397,7 @@
|
||||
name = "Mime action figure"
|
||||
icon_state = "mime"
|
||||
toysay = "..."
|
||||
toysound = null
|
||||
|
||||
/obj/item/toy/figure/miner
|
||||
name = "Shaft Miner action figure"
|
||||
@@ -1409,6 +1413,7 @@
|
||||
name = "Wizard action figure"
|
||||
icon_state = "wizard"
|
||||
toysay = "Ei Nath!"
|
||||
toysound = 'sound/magic/Disintegrate.ogg'
|
||||
|
||||
/obj/item/toy/figure/rd
|
||||
name = "Research Director action figure"
|
||||
@@ -1419,11 +1424,13 @@
|
||||
name = "Roboticist action figure"
|
||||
icon_state = "roboticist"
|
||||
toysay = "Big stompy mechs!"
|
||||
toysound = 'sound/mecha/mechstep.ogg'
|
||||
|
||||
/obj/item/toy/figure/scientist
|
||||
name = "Scientist action figure"
|
||||
icon_state = "scientist"
|
||||
toysay = "For science!"
|
||||
toysound = 'sound/effects/explosionfar.ogg'
|
||||
|
||||
/obj/item/toy/figure/syndie
|
||||
name = "Nuclear Operative action figure"
|
||||
@@ -1434,6 +1441,7 @@
|
||||
name = "Security Officer action figure"
|
||||
icon_state = "secofficer"
|
||||
toysay = "I am the law!"
|
||||
toysound = 'sound/voice/complionator/dredd.ogg'
|
||||
|
||||
/obj/item/toy/figure/virologist
|
||||
name = "Virologist action figure"
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
/obj/item/clothing/head/snowman)
|
||||
|
||||
gift_type_list += subtypesof(/obj/item/clothing/head/collectable)
|
||||
gift_type_list += subtypesof(/obj/item/toy) - (((typesof(/obj/item/toy/cards) - /obj/item/toy/cards/deck) + /obj/item/toy/ammo)) //All toys, except for abstract types and syndicate cards.
|
||||
gift_type_list += subtypesof(/obj/item/toy) - (((typesof(/obj/item/toy/cards) - /obj/item/toy/cards/deck) + /obj/item/toy/figure + /obj/item/toy/ammo)) //All toys, except for abstract types and syndicate cards.
|
||||
|
||||
var/gift_type = pick(gift_type_list)
|
||||
|
||||
|
||||
@@ -146,17 +146,10 @@ var/global/list/bibleitemstates = list("bible", "koran", "scrapbook", "bible", "
|
||||
user.Paralyse(20)
|
||||
return
|
||||
|
||||
// if(..() == BLOCKED)
|
||||
// return
|
||||
|
||||
if (M.stat !=2)
|
||||
if(M.mind && (M.mind.assigned_role == "Chaplain"))
|
||||
user << "<span class='warning'>You can't heal yourself!</span>"
|
||||
return
|
||||
/*if((M.mind in ticker.mode.cult) && (prob(20)))
|
||||
M << "\red The power of [src.deity_name] clears your mind of heresy!"
|
||||
user << "\red You see how [M]'s eyes become clear, the cult no longer holds control over him!"
|
||||
ticker.mode.remove_cultist(M.mind)*/
|
||||
if ((istype(M, /mob/living/carbon/human) && prob(60)))
|
||||
bless(M)
|
||||
if(ishuman(M))
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
/obj/item/weapon/tank/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "tanks.tmpl", name, 525, 175, state = inventory_state)
|
||||
ui = new(user, src, ui_key, "tanks", name, 525, 210, state = inventory_state)
|
||||
ui.open()
|
||||
|
||||
/obj/item/weapon/tank/get_ui_data()
|
||||
@@ -157,42 +157,43 @@
|
||||
data["maskConnected"] = 1
|
||||
return data
|
||||
|
||||
/obj/item/weapon/tank/Topic(href, href_list)
|
||||
/obj/item/weapon/tank/ui_act(action, params)
|
||||
if (..())
|
||||
return
|
||||
|
||||
if (href_list["dist_p"])
|
||||
if (href_list["dist_p"] == "custom")
|
||||
var/custom = input(usr, "What rate do you set the regulator to? The dial reads from 0 to [TANK_MAX_RELEASE_PRESSURE].") as null|num
|
||||
if(isnum(custom))
|
||||
href_list["dist_p"] = custom
|
||||
.()
|
||||
else if (href_list["dist_p"] == "reset")
|
||||
distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE
|
||||
else if (href_list["dist_p"] == "min")
|
||||
distribute_pressure = TANK_MIN_RELEASE_PRESSURE
|
||||
else if (href_list["dist_p"] == "max")
|
||||
distribute_pressure = TANK_MAX_RELEASE_PRESSURE
|
||||
else
|
||||
distribute_pressure = text2num(href_list["dist_p"])
|
||||
distribute_pressure = min(max(round(distribute_pressure), TANK_MIN_RELEASE_PRESSURE), TANK_MAX_RELEASE_PRESSURE)
|
||||
if (href_list["stat"])
|
||||
if(istype(loc,/mob/living/carbon))
|
||||
var/mob/living/carbon/location = loc
|
||||
if(location.internal == src)
|
||||
location.internal = null
|
||||
location.internals.icon_state = "internal0"
|
||||
usr << "<span class='notice'>You close the tank release valve.</span>"
|
||||
if (location.internals)
|
||||
switch(action)
|
||||
if("pressure")
|
||||
switch(params["set"])
|
||||
if("custom")
|
||||
var/custom = input(usr, "What rate do you set the regulator to? The dial reads from 0 to [TANK_MAX_RELEASE_PRESSURE].") as null|num
|
||||
if(isnum(custom))
|
||||
distribute_pressure = custom
|
||||
if("reset")
|
||||
distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE
|
||||
if("min")
|
||||
distribute_pressure = TANK_MIN_RELEASE_PRESSURE
|
||||
if("max")
|
||||
distribute_pressure = TANK_MAX_RELEASE_PRESSURE
|
||||
distribute_pressure = Clamp(round(distribute_pressure), TANK_MIN_RELEASE_PRESSURE, TANK_MAX_RELEASE_PRESSURE)
|
||||
if("valve")
|
||||
if(istype(loc,/mob/living/carbon))
|
||||
var/mob/living/carbon/location = loc
|
||||
if(location.internal == src)
|
||||
location.internal = null
|
||||
location.internals.icon_state = "internal0"
|
||||
else
|
||||
if(location.wear_mask && (location.wear_mask.flags & MASKINTERNALS))
|
||||
location.internal = src
|
||||
usr << "<span class='notice'>You open \the [src] valve.</span>"
|
||||
usr << "<span class='notice'>You close the tank release valve.</span>"
|
||||
if (location.internals)
|
||||
location.internals.icon_state = "internal1"
|
||||
location.internals.icon_state = "internal0"
|
||||
else
|
||||
usr << "<span class='warning'>You need something to connect to \the [src]!</span>"
|
||||
if(location.wear_mask && (location.wear_mask.flags & MASKINTERNALS))
|
||||
location.internal = src
|
||||
usr << "<span class='notice'>You open \the [src] valve.</span>"
|
||||
if (location.internals)
|
||||
location.internals.icon_state = "internal1"
|
||||
else
|
||||
usr << "<span class='warning'>You need something to connect to \the [src]!</span>"
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/weapon/tank/remove_air(amount)
|
||||
return air_contents.remove(amount)
|
||||
|
||||
@@ -235,7 +235,7 @@
|
||||
spawn(0)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
user.dir = i
|
||||
if(prob(20))
|
||||
if(i == 8)
|
||||
user.emote("flip")
|
||||
sleep(1)
|
||||
|
||||
|
||||
@@ -142,20 +142,30 @@
|
||||
icon = 'icons/obj/doors/airlocks/station/maintenance.dmi'
|
||||
typetext = "maintenance"
|
||||
icontext = "mai"
|
||||
glass_type = /obj/machinery/door/airlock/glass_maintenance
|
||||
airlock_type = /obj/machinery/door/airlock/maintenance
|
||||
anchored = 1
|
||||
state = 1
|
||||
|
||||
/obj/structure/door_assembly/door_assembly_mai/glass
|
||||
mineral = "glass"
|
||||
material = "glass"
|
||||
|
||||
/obj/structure/door_assembly/door_assembly_ext
|
||||
name = "external airlock assembly"
|
||||
icon = 'icons/obj/doors/airlocks/external/external.dmi'
|
||||
overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi'
|
||||
typetext = "external"
|
||||
icontext = "ext"
|
||||
glass_type = /obj/machinery/door/airlock/glass_external
|
||||
airlock_type = /obj/machinery/door/airlock/external
|
||||
anchored = 1
|
||||
state = 1
|
||||
|
||||
/obj/structure/door_assembly/door_assembly_ext/glass
|
||||
mineral = "glass"
|
||||
material = "glass"
|
||||
|
||||
/obj/structure/door_assembly/door_assembly_fre
|
||||
name = "freezer airlock assembly"
|
||||
icon = 'icons/obj/doors/airlocks/station/freezer.dmi'
|
||||
|
||||
@@ -214,8 +214,9 @@
|
||||
else if (istype(AM, /mob/living))
|
||||
var/mob/living/L = AM
|
||||
L.adjustFireLoss(20)
|
||||
L.adjust_fire_stacks(20)
|
||||
L.IgniteMob()
|
||||
if(L) //mobs turning into object corpses could get deleted here.
|
||||
L.adjust_fire_stacks(20)
|
||||
L.IgniteMob()
|
||||
|
||||
/turf/simulated/floor/plating/lava/attackby(obj/item/C, mob/user, params) //Lava isn't a good foundation to build on
|
||||
return
|
||||
|
||||
@@ -272,8 +272,7 @@ var/list/admin_verbs_hideable = list(
|
||||
/client/proc/fps,
|
||||
/client/proc/cmd_admin_grantfullaccess,
|
||||
/client/proc/cmd_admin_areatest,
|
||||
/client/proc/readmin,
|
||||
/client/proc/reload_nanoui_resources
|
||||
/client/proc/readmin
|
||||
)
|
||||
if(holder)
|
||||
verbs.Remove(holder.rank.adds)
|
||||
|
||||
@@ -310,97 +310,6 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
else
|
||||
alert("Invalid mob")
|
||||
|
||||
/*
|
||||
/client/proc/cmd_admin_monkeyize(var/mob/M in world)
|
||||
set category = "Fun"
|
||||
set name = "Make Monkey"
|
||||
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts")
|
||||
return
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/target = M
|
||||
log_admin("[key_name(src)] is attempting to monkeyize [M.key].")
|
||||
spawn(10)
|
||||
target.monkeyize()
|
||||
else
|
||||
alert("Invalid mob")
|
||||
|
||||
/client/proc/cmd_admin_changelinginize(var/mob/M in world)
|
||||
set category = "Fun"
|
||||
set name = "Make Changeling"
|
||||
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts")
|
||||
return
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
log_admin("[key_name(src)] has made [M.key] a changeling.")
|
||||
spawn(10)
|
||||
M.absorbed_dna[M.real_name] = M.dna
|
||||
M.make_changeling()
|
||||
if(M.mind)
|
||||
M.mind.special_role = "Changeling"
|
||||
else
|
||||
alert("Invalid mob")
|
||||
*/
|
||||
/*
|
||||
/client/proc/cmd_admin_abominize(var/mob/M in world)
|
||||
set category = null
|
||||
set name = "Make Abomination"
|
||||
|
||||
usr << "Ruby Mode disabled. Command aborted."
|
||||
return
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts.")
|
||||
return
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
log_admin("[key_name(src)] has made [M.key] an abomination.")
|
||||
|
||||
// spawn(10)
|
||||
// M.make_abomination()
|
||||
|
||||
*/
|
||||
/*
|
||||
/client/proc/make_cultist(var/mob/M in world)
|
||||
set category = "Fun"
|
||||
set name = "Make Cultist"
|
||||
set desc = "Makes target a cultist"
|
||||
if(!wordtravel)
|
||||
runerandom()
|
||||
if(M)
|
||||
if(M.mind in ticker.mode.cult)
|
||||
return
|
||||
else
|
||||
if(alert("Spawn that person a tome?",,"Yes","No")=="Yes")
|
||||
M << "\red You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie. A tome, a message from your new master, appears on the ground."
|
||||
new /obj/item/weapon/tome(M.loc)
|
||||
else
|
||||
M << "\red You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie."
|
||||
var/glimpse=pick("1","2","3","4","5","6","7","8")
|
||||
switch(glimpse)
|
||||
if("1")
|
||||
M << "\red You remembered one thing from the glimpse... [wordtravel] is travel..."
|
||||
if("2")
|
||||
M << "\red You remembered one thing from the glimpse... [wordblood] is blood..."
|
||||
if("3")
|
||||
M << "\red You remembered one thing from the glimpse... [wordjoin] is join..."
|
||||
if("4")
|
||||
M << "\red You remembered one thing from the glimpse... [wordhell] is Hell..."
|
||||
if("5")
|
||||
M << "\red You remembered one thing from the glimpse... [worddestr] is destroy..."
|
||||
if("6")
|
||||
M << "\red You remembered one thing from the glimpse... [wordtech] is technology..."
|
||||
if("7")
|
||||
M << "\red You remembered one thing from the glimpse... [wordself] is self..."
|
||||
if("8")
|
||||
M << "\red You remembered one thing from the glimpse... [wordsee] is see..."
|
||||
|
||||
if(M.mind)
|
||||
M.mind.special_role = "Cultist"
|
||||
ticker.mode.cult += M.mind
|
||||
src << "Made [M] a cultist."
|
||||
*/
|
||||
|
||||
var/list/TYPES_SHORTCUTS = list(
|
||||
/obj/effect/decal/cleanable = "CLEANABLE",
|
||||
/obj/item/device/radio/headset = "HEADSET",
|
||||
@@ -776,18 +685,3 @@ var/global/list/g_fancy_list_of_types = null
|
||||
|
||||
if(!holder) return
|
||||
debug_variables(huds[i])
|
||||
|
||||
/client/proc/reload_nanoui_resources()
|
||||
set category = "Debug"
|
||||
set name = "Reload NanoUI Resources"
|
||||
set desc = "Force the client to redownload NanoUI Resources"
|
||||
|
||||
// Close open NanoUIs.
|
||||
SSnano.close_user_uis(usr)
|
||||
|
||||
// Re-load the assets.
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/nanoui)
|
||||
assets.register()
|
||||
|
||||
// Clear the user's cache so they get resent.
|
||||
usr.client.cache = list()
|
||||
|
||||
@@ -159,7 +159,6 @@ var/intercom_range_display_status = 0
|
||||
src.verbs += /client/proc/cmd_show_at_list
|
||||
src.verbs += /client/proc/cmd_show_at_list
|
||||
src.verbs += /client/proc/manipulate_organs
|
||||
src.verbs += /client/proc/reload_nanoui_resources
|
||||
|
||||
feedback_add_details("admin_verb","mDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
@@ -194,7 +194,6 @@
|
||||
|
||||
|
||||
/datum/admins/proc/makeCult()
|
||||
|
||||
var/datum/game_mode/cult/temp = new
|
||||
if(config.protect_roles_from_antagonist)
|
||||
temp.restricted_jobs += temp.protected_jobs
|
||||
@@ -216,7 +215,7 @@
|
||||
candidates += applicant
|
||||
|
||||
if(candidates.len)
|
||||
var/numCultists = min(candidates.len, 4)
|
||||
var/numCultists = min(candidates.len, 5)
|
||||
|
||||
for(var/i = 0, i<numCultists, i++)
|
||||
H = pick(candidates)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
name = "Unknown"
|
||||
var/mobname = "default" //Use for the ghost spawner variant, so they don't come out named "sleeper"
|
||||
var/mobgender = MALE //Set to male by default due to the patriarchy. Other options include FEMALE and NEUTER
|
||||
var/mob_species = null //Set to make them a mutant race such as lizard or skeleton
|
||||
var/mob_species = null //Set to make them a mutant race such as lizard or skeleton. Uses the datum typepath instead of the ID.
|
||||
var/corpseuniform = null //Set this to an object path to have the slot filled with said object on the corpse.
|
||||
var/corpsesuit = null
|
||||
var/corpseshoes = null
|
||||
@@ -262,7 +262,7 @@
|
||||
|
||||
|
||||
/obj/effect/landmark/corpse/plasmaman
|
||||
mob_species = "plasmaman"
|
||||
mob_species = /datum/species/plasmaman
|
||||
corpsehelmet = /obj/item/clothing/head/helmet/space/plasmaman
|
||||
corpseuniform = /obj/item/clothing/under/plasmaman
|
||||
corpseback = /obj/item/weapon/tank/internals/plasmaman/full
|
||||
@@ -320,7 +320,7 @@
|
||||
/obj/effect/landmark/corpse/skeleton
|
||||
name = "skeletal remains"
|
||||
mobname = "skeleton"
|
||||
mob_species = "skeleton"
|
||||
mob_species = /datum/species/skeleton
|
||||
mobgender = NEUTER
|
||||
|
||||
|
||||
@@ -335,7 +335,7 @@
|
||||
/obj/effect/landmark/corpse/zombie
|
||||
name = "rotting corpse"
|
||||
mobname = "zombie"
|
||||
mob_species = "zombie"
|
||||
mob_species = /datum/species/zombie
|
||||
|
||||
/obj/effect/landmark/corpse/zombie/alive
|
||||
death = FALSE
|
||||
|
||||
@@ -1,262 +1,240 @@
|
||||
/*
|
||||
Asset cache quick users guide:
|
||||
|
||||
Make a datum at the bottom of this file with your assets for your thing.
|
||||
The simple subsystem will most like be of use for most cases.
|
||||
Then call get_asset_datum() with the type of the datum you created and store the return
|
||||
Then call .send(client) on that stored return value.
|
||||
|
||||
You can set verify to TRUE if you want send() to sleep until the client has the assets.
|
||||
*/
|
||||
|
||||
|
||||
// Amount of time(ds) MAX to send per asset, if this get exceeded we cancel the sleeping.
|
||||
// This is doubled for the first asset, then added per asset after
|
||||
#define ASSET_CACHE_SEND_TIMEOUT 7
|
||||
|
||||
//When sending mutiple assets, how many before we give the client a quaint little sending resources message
|
||||
#define ASSET_CACHE_TELL_CLIENT_AMOUNT 8
|
||||
|
||||
/client
|
||||
var/list/cache = list() // List of all assets sent to this client by the asset cache.
|
||||
var/list/completed_asset_jobs = list() // List of all completed jobs, awaiting acknowledgement.
|
||||
var/list/sending = list()
|
||||
var/last_asset_job = 0 // Last job done.
|
||||
|
||||
//This proc sends the asset to the client, but only if it needs it.
|
||||
//This proc blocks(sleeps) unless verify is set to false
|
||||
/proc/send_asset(var/client/client, var/asset_name, var/verify = TRUE)
|
||||
if(!istype(client))
|
||||
if(ismob(client))
|
||||
var/mob/M = client
|
||||
if(M.client)
|
||||
client = M.client
|
||||
|
||||
else
|
||||
return 0
|
||||
|
||||
else
|
||||
return 0
|
||||
|
||||
if(client.cache.Find(asset_name) || client.sending.Find(asset_name))
|
||||
return 0
|
||||
|
||||
client << browse_rsc(SSasset.cache[asset_name], asset_name)
|
||||
if(!verify || !winexists(client, "asset_cache_browser")) // Can't access the asset cache browser, rip.
|
||||
if (client)
|
||||
client.cache += asset_name
|
||||
return 1
|
||||
if (!client)
|
||||
return 0
|
||||
|
||||
client.sending |= asset_name
|
||||
var/job = ++client.last_asset_job
|
||||
|
||||
client << browse({"
|
||||
<script>
|
||||
window.location.href="?asset_cache_confirm_arrival=[job]"
|
||||
</script>
|
||||
"}, "window=asset_cache_browser")
|
||||
|
||||
var/t = 0
|
||||
var/timeout_time = (ASSET_CACHE_SEND_TIMEOUT * client.sending.len) + ASSET_CACHE_SEND_TIMEOUT
|
||||
while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
|
||||
sleep(1) // Lock up the caller until this is received.
|
||||
t++
|
||||
|
||||
if(client)
|
||||
client.sending -= asset_name
|
||||
client.cache |= asset_name
|
||||
client.completed_asset_jobs -= job
|
||||
|
||||
return 1
|
||||
|
||||
//This proc blocks(sleeps) unless verify is set to false
|
||||
/proc/send_asset_list(var/client/client, var/list/asset_list, var/verify = TRUE)
|
||||
if(!istype(client))
|
||||
if(ismob(client))
|
||||
var/mob/M = client
|
||||
if(M.client)
|
||||
client = M.client
|
||||
|
||||
else
|
||||
return 0
|
||||
|
||||
else
|
||||
return 0
|
||||
|
||||
var/list/unreceived = asset_list - (client.cache + client.sending)
|
||||
if(!unreceived || !unreceived.len)
|
||||
return 0
|
||||
if (unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT)
|
||||
client << "Sending Resources..."
|
||||
for(var/asset in unreceived)
|
||||
if (asset in SSasset.cache)
|
||||
client << browse_rsc(SSasset.cache[asset], asset)
|
||||
|
||||
if(!verify || !winexists(client, "asset_cache_browser")) // Can't access the asset cache browser, rip.
|
||||
if (client)
|
||||
client.cache += unreceived
|
||||
return 1
|
||||
if (!client)
|
||||
return 0
|
||||
client.sending |= unreceived
|
||||
var/job = ++client.last_asset_job
|
||||
|
||||
client << browse({"
|
||||
<script>
|
||||
window.location.href="?asset_cache_confirm_arrival=[job]"
|
||||
</script>
|
||||
"}, "window=asset_cache_browser")
|
||||
|
||||
var/t = 0
|
||||
var/timeout_time = ASSET_CACHE_SEND_TIMEOUT * client.sending.len
|
||||
while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
|
||||
sleep(1) // Lock up the caller until this is received.
|
||||
t++
|
||||
|
||||
if(client)
|
||||
client.sending -= unreceived
|
||||
client.cache |= unreceived
|
||||
client.completed_asset_jobs -= job
|
||||
|
||||
return 1
|
||||
|
||||
//This proc will download the files without clogging up the browse() queue, used for passively sending files on connection start.
|
||||
//The proc calls procs that sleep for long times.
|
||||
/proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE)
|
||||
for(var/file in files)
|
||||
if (!client)
|
||||
break
|
||||
if (register_asset)
|
||||
register_asset(file,files[file])
|
||||
send_asset(client,file)
|
||||
sleep(-1) //queuing calls like this too quickly can cause issues in some client versions
|
||||
|
||||
//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up.
|
||||
//if it's an icon or something be careful, you'll have to copy it before further use.
|
||||
/proc/register_asset(var/asset_name, var/asset)
|
||||
SSasset.cache[asset_name] = asset
|
||||
|
||||
//These datums are used to populate the asset cache, the proc "register()" does this.
|
||||
|
||||
//all of our asset datums, used for referring to these later
|
||||
/var/global/list/asset_datums = list()
|
||||
|
||||
//get a assetdatum or make a new one
|
||||
/proc/get_asset_datum(var/type)
|
||||
if (!(type in asset_datums))
|
||||
return new type()
|
||||
return asset_datums[type]
|
||||
|
||||
/datum/asset/New()
|
||||
asset_datums[type] = src
|
||||
|
||||
/datum/asset/proc/register()
|
||||
return
|
||||
|
||||
/datum/asset/proc/send(client)
|
||||
return
|
||||
|
||||
//If you don't need anything complicated.
|
||||
/datum/asset/simple
|
||||
var/assets = list()
|
||||
var/verify = FALSE
|
||||
|
||||
/datum/asset/simple/register()
|
||||
for(var/asset_name in assets)
|
||||
register_asset(asset_name, assets[asset_name])
|
||||
/datum/asset/simple/send(client)
|
||||
send_asset_list(client,assets,verify)
|
||||
|
||||
|
||||
//DEFINITIONS FOR ASSET DATUMS START HERE.
|
||||
|
||||
|
||||
/datum/asset/simple/pda
|
||||
assets = list(
|
||||
"pda_atmos.png" = 'icons/pda_icons/pda_atmos.png',
|
||||
"pda_back.png" = 'icons/pda_icons/pda_back.png',
|
||||
"pda_bell.png" = 'icons/pda_icons/pda_bell.png',
|
||||
"pda_blank.png" = 'icons/pda_icons/pda_blank.png',
|
||||
"pda_boom.png" = 'icons/pda_icons/pda_boom.png',
|
||||
"pda_bucket.png" = 'icons/pda_icons/pda_bucket.png',
|
||||
"pda_medbot.png" = 'icons/pda_icons/pda_medbot.png',
|
||||
"pda_floorbot.png" = 'icons/pda_icons/pda_floorbot.png',
|
||||
"pda_cleanbot.png" = 'icons/pda_icons/pda_cleanbot.png',
|
||||
"pda_crate.png" = 'icons/pda_icons/pda_crate.png',
|
||||
"pda_cuffs.png" = 'icons/pda_icons/pda_cuffs.png',
|
||||
"pda_eject.png" = 'icons/pda_icons/pda_eject.png',
|
||||
"pda_exit.png" = 'icons/pda_icons/pda_exit.png',
|
||||
"pda_flashlight.png" = 'icons/pda_icons/pda_flashlight.png',
|
||||
"pda_honk.png" = 'icons/pda_icons/pda_honk.png',
|
||||
"pda_mail.png" = 'icons/pda_icons/pda_mail.png',
|
||||
"pda_medical.png" = 'icons/pda_icons/pda_medical.png',
|
||||
"pda_menu.png" = 'icons/pda_icons/pda_menu.png',
|
||||
"pda_mule.png" = 'icons/pda_icons/pda_mule.png',
|
||||
"pda_notes.png" = 'icons/pda_icons/pda_notes.png',
|
||||
"pda_power.png" = 'icons/pda_icons/pda_power.png',
|
||||
"pda_rdoor.png" = 'icons/pda_icons/pda_rdoor.png',
|
||||
"pda_reagent.png" = 'icons/pda_icons/pda_reagent.png',
|
||||
"pda_refresh.png" = 'icons/pda_icons/pda_refresh.png',
|
||||
"pda_scanner.png" = 'icons/pda_icons/pda_scanner.png',
|
||||
"pda_signaler.png" = 'icons/pda_icons/pda_signaler.png',
|
||||
"pda_status.png" = 'icons/pda_icons/pda_status.png'
|
||||
)
|
||||
|
||||
/datum/asset/simple/paper
|
||||
assets = list(
|
||||
"large_stamp-clown.png" = 'icons/stamp_icons/large_stamp-clown.png',
|
||||
"large_stamp-deny.png" = 'icons/stamp_icons/large_stamp-deny.png',
|
||||
"large_stamp-ok.png" = 'icons/stamp_icons/large_stamp-ok.png',
|
||||
"large_stamp-hop.png" = 'icons/stamp_icons/large_stamp-hop.png',
|
||||
"large_stamp-cmo.png" = 'icons/stamp_icons/large_stamp-cmo.png',
|
||||
"large_stamp-ce.png" = 'icons/stamp_icons/large_stamp-ce.png',
|
||||
"large_stamp-hos.png" = 'icons/stamp_icons/large_stamp-hos.png',
|
||||
"large_stamp-rd.png" = 'icons/stamp_icons/large_stamp-rd.png',
|
||||
"large_stamp-cap.png" = 'icons/stamp_icons/large_stamp-cap.png',
|
||||
"large_stamp-qm.png" = 'icons/stamp_icons/large_stamp-qm.png',
|
||||
"large_stamp-law.png" = 'icons/stamp_icons/large_stamp-law.png'
|
||||
)
|
||||
|
||||
//Registers HTML Interface assets.
|
||||
/datum/asset/HTML_interface/register()
|
||||
for(var/path in typesof(/datum/html_interface))
|
||||
var/datum/html_interface/hi = new path()
|
||||
hi.registerResources()
|
||||
|
||||
/datum/asset/nanoui
|
||||
var/list/common = list()
|
||||
|
||||
var/list/common_dirs = list(
|
||||
"nano/styles/",
|
||||
"nano/scripts/",
|
||||
"nano/images/",
|
||||
"nano/layouts/"
|
||||
)
|
||||
var/list/uncommon_dirs = list(
|
||||
"nano/interfaces/"
|
||||
)
|
||||
|
||||
/datum/asset/nanoui/register()
|
||||
// Crawl the directories to find files.
|
||||
for (var/path in common_dirs)
|
||||
var/list/filenames = flist(path)
|
||||
for(var/filename in filenames)
|
||||
if(copytext(filename, length(filename)) != "/") // Ignore directories.
|
||||
if(fexists(path + filename))
|
||||
common[filename] = fcopy_rsc(path + filename)
|
||||
register_asset(filename, common[filename])
|
||||
for (var/path in uncommon_dirs)
|
||||
var/list/filenames = flist(path)
|
||||
for(var/filename in filenames)
|
||||
if(copytext(filename, length(filename)) != "/") // Ignore directories.
|
||||
if(fexists(path + filename))
|
||||
register_asset(filename, fcopy_rsc(path + filename))
|
||||
|
||||
/datum/asset/nanoui/send(client, uncommon)
|
||||
if(!islist(uncommon))
|
||||
uncommon = list(uncommon)
|
||||
|
||||
send_asset_list(client, uncommon)
|
||||
send_asset_list(client, common)
|
||||
/*
|
||||
Asset cache quick users guide:
|
||||
|
||||
Make a datum at the bottom of this file with your assets for your thing.
|
||||
The simple subsystem will most like be of use for most cases.
|
||||
Then call get_asset_datum() with the type of the datum you created and store the return
|
||||
Then call .send(client) on that stored return value.
|
||||
|
||||
You can set verify to TRUE if you want send() to sleep until the client has the assets.
|
||||
*/
|
||||
|
||||
|
||||
// Amount of time(ds) MAX to send per asset, if this get exceeded we cancel the sleeping.
|
||||
// This is doubled for the first asset, then added per asset after
|
||||
#define ASSET_CACHE_SEND_TIMEOUT 7
|
||||
|
||||
//When sending mutiple assets, how many before we give the client a quaint little sending resources message
|
||||
#define ASSET_CACHE_TELL_CLIENT_AMOUNT 8
|
||||
|
||||
/client
|
||||
var/list/cache = list() // List of all assets sent to this client by the asset cache.
|
||||
var/list/completed_asset_jobs = list() // List of all completed jobs, awaiting acknowledgement.
|
||||
var/list/sending = list()
|
||||
var/last_asset_job = 0 // Last job done.
|
||||
|
||||
//This proc sends the asset to the client, but only if it needs it.
|
||||
//This proc blocks(sleeps) unless verify is set to false
|
||||
/proc/send_asset(var/client/client, var/asset_name, var/verify = TRUE)
|
||||
if(!istype(client))
|
||||
if(ismob(client))
|
||||
var/mob/M = client
|
||||
if(M.client)
|
||||
client = M.client
|
||||
|
||||
else
|
||||
return 0
|
||||
|
||||
else
|
||||
return 0
|
||||
|
||||
if(client.cache.Find(asset_name) || client.sending.Find(asset_name))
|
||||
return 0
|
||||
|
||||
client << browse_rsc(SSasset.cache[asset_name], asset_name)
|
||||
if(!verify || !winexists(client, "asset_cache_browser")) // Can't access the asset cache browser, rip.
|
||||
if (client)
|
||||
client.cache += asset_name
|
||||
return 1
|
||||
if (!client)
|
||||
return 0
|
||||
|
||||
client.sending |= asset_name
|
||||
var/job = ++client.last_asset_job
|
||||
|
||||
client << browse({"
|
||||
<script>
|
||||
window.location.href="?asset_cache_confirm_arrival=[job]"
|
||||
</script>
|
||||
"}, "window=asset_cache_browser")
|
||||
|
||||
var/t = 0
|
||||
var/timeout_time = (ASSET_CACHE_SEND_TIMEOUT * client.sending.len) + ASSET_CACHE_SEND_TIMEOUT
|
||||
while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
|
||||
sleep(1) // Lock up the caller until this is received.
|
||||
t++
|
||||
|
||||
if(client)
|
||||
client.sending -= asset_name
|
||||
client.cache |= asset_name
|
||||
client.completed_asset_jobs -= job
|
||||
|
||||
return 1
|
||||
|
||||
//This proc blocks(sleeps) unless verify is set to false
|
||||
/proc/send_asset_list(var/client/client, var/list/asset_list, var/verify = TRUE)
|
||||
if(!istype(client))
|
||||
if(ismob(client))
|
||||
var/mob/M = client
|
||||
if(M.client)
|
||||
client = M.client
|
||||
|
||||
else
|
||||
return 0
|
||||
|
||||
else
|
||||
return 0
|
||||
|
||||
var/list/unreceived = asset_list - (client.cache + client.sending)
|
||||
if(!unreceived || !unreceived.len)
|
||||
return 0
|
||||
if (unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT)
|
||||
client << "Sending Resources..."
|
||||
for(var/asset in unreceived)
|
||||
if (asset in SSasset.cache)
|
||||
client << browse_rsc(SSasset.cache[asset], asset)
|
||||
|
||||
if(!verify || !winexists(client, "asset_cache_browser")) // Can't access the asset cache browser, rip.
|
||||
if (client)
|
||||
client.cache += unreceived
|
||||
return 1
|
||||
if (!client)
|
||||
return 0
|
||||
client.sending |= unreceived
|
||||
var/job = ++client.last_asset_job
|
||||
|
||||
client << browse({"
|
||||
<script>
|
||||
window.location.href="?asset_cache_confirm_arrival=[job]"
|
||||
</script>
|
||||
"}, "window=asset_cache_browser")
|
||||
|
||||
var/t = 0
|
||||
var/timeout_time = ASSET_CACHE_SEND_TIMEOUT * client.sending.len
|
||||
while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
|
||||
sleep(1) // Lock up the caller until this is received.
|
||||
t++
|
||||
|
||||
if(client)
|
||||
client.sending -= unreceived
|
||||
client.cache |= unreceived
|
||||
client.completed_asset_jobs -= job
|
||||
|
||||
return 1
|
||||
|
||||
//This proc will download the files without clogging up the browse() queue, used for passively sending files on connection start.
|
||||
//The proc calls procs that sleep for long times.
|
||||
/proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE)
|
||||
for(var/file in files)
|
||||
if (!client)
|
||||
break
|
||||
if (register_asset)
|
||||
register_asset(file,files[file])
|
||||
send_asset(client,file)
|
||||
sleep(-1) //queuing calls like this too quickly can cause issues in some client versions
|
||||
|
||||
//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up.
|
||||
//if it's an icon or something be careful, you'll have to copy it before further use.
|
||||
/proc/register_asset(var/asset_name, var/asset)
|
||||
SSasset.cache[asset_name] = asset
|
||||
|
||||
//These datums are used to populate the asset cache, the proc "register()" does this.
|
||||
|
||||
//all of our asset datums, used for referring to these later
|
||||
/var/global/list/asset_datums = list()
|
||||
|
||||
//get a assetdatum or make a new one
|
||||
/proc/get_asset_datum(var/type)
|
||||
if (!(type in asset_datums))
|
||||
return new type()
|
||||
return asset_datums[type]
|
||||
|
||||
/datum/asset/New()
|
||||
asset_datums[type] = src
|
||||
|
||||
/datum/asset/proc/register()
|
||||
return
|
||||
|
||||
/datum/asset/proc/send(client)
|
||||
return
|
||||
|
||||
//If you don't need anything complicated.
|
||||
/datum/asset/simple
|
||||
var/assets = list()
|
||||
var/verify = FALSE
|
||||
|
||||
/datum/asset/simple/register()
|
||||
for(var/asset_name in assets)
|
||||
register_asset(asset_name, assets[asset_name])
|
||||
/datum/asset/simple/send(client)
|
||||
send_asset_list(client,assets,verify)
|
||||
|
||||
|
||||
//DEFINITIONS FOR ASSET DATUMS START HERE.
|
||||
|
||||
|
||||
/datum/asset/simple/nanoui
|
||||
assets = list(
|
||||
"nanoui.lib.js" = 'nano/assets/nanoui.lib.js',
|
||||
"nanoui.main.js" = 'nano/assets/nanoui.main.js',
|
||||
"nanoui.templates.js" = 'nano/assets/nanoui.templates.js',
|
||||
"nanoui.lib.css" = 'nano/assets/nanoui.lib.css',
|
||||
"nanoui.common.css" = 'nano/assets/nanoui.common.css',
|
||||
"nanoui.generic.css" = 'nano/assets/nanoui.generic.css',
|
||||
"nanoui.nanotrasen.css" = 'nano/assets/nanoui.nanotrasen.css',
|
||||
"fontawesome-webfont.eot" = 'nano/assets/fontawesome-webfont.eot',
|
||||
"fontawesome-webfont.woff2" = 'nano/assets/fontawesome-webfont.woff2'
|
||||
)
|
||||
|
||||
/datum/asset/simple/pda
|
||||
assets = list(
|
||||
"pda_atmos.png" = 'icons/pda_icons/pda_atmos.png',
|
||||
"pda_back.png" = 'icons/pda_icons/pda_back.png',
|
||||
"pda_bell.png" = 'icons/pda_icons/pda_bell.png',
|
||||
"pda_blank.png" = 'icons/pda_icons/pda_blank.png',
|
||||
"pda_boom.png" = 'icons/pda_icons/pda_boom.png',
|
||||
"pda_bucket.png" = 'icons/pda_icons/pda_bucket.png',
|
||||
"pda_medbot.png" = 'icons/pda_icons/pda_medbot.png',
|
||||
"pda_floorbot.png" = 'icons/pda_icons/pda_floorbot.png',
|
||||
"pda_cleanbot.png" = 'icons/pda_icons/pda_cleanbot.png',
|
||||
"pda_crate.png" = 'icons/pda_icons/pda_crate.png',
|
||||
"pda_cuffs.png" = 'icons/pda_icons/pda_cuffs.png',
|
||||
"pda_eject.png" = 'icons/pda_icons/pda_eject.png',
|
||||
"pda_exit.png" = 'icons/pda_icons/pda_exit.png',
|
||||
"pda_flashlight.png" = 'icons/pda_icons/pda_flashlight.png',
|
||||
"pda_honk.png" = 'icons/pda_icons/pda_honk.png',
|
||||
"pda_mail.png" = 'icons/pda_icons/pda_mail.png',
|
||||
"pda_medical.png" = 'icons/pda_icons/pda_medical.png',
|
||||
"pda_menu.png" = 'icons/pda_icons/pda_menu.png',
|
||||
"pda_mule.png" = 'icons/pda_icons/pda_mule.png',
|
||||
"pda_notes.png" = 'icons/pda_icons/pda_notes.png',
|
||||
"pda_power.png" = 'icons/pda_icons/pda_power.png',
|
||||
"pda_rdoor.png" = 'icons/pda_icons/pda_rdoor.png',
|
||||
"pda_reagent.png" = 'icons/pda_icons/pda_reagent.png',
|
||||
"pda_refresh.png" = 'icons/pda_icons/pda_refresh.png',
|
||||
"pda_scanner.png" = 'icons/pda_icons/pda_scanner.png',
|
||||
"pda_signaler.png" = 'icons/pda_icons/pda_signaler.png',
|
||||
"pda_status.png" = 'icons/pda_icons/pda_status.png'
|
||||
)
|
||||
|
||||
/datum/asset/simple/paper
|
||||
assets = list(
|
||||
"large_stamp-clown.png" = 'icons/stamp_icons/large_stamp-clown.png',
|
||||
"large_stamp-deny.png" = 'icons/stamp_icons/large_stamp-deny.png',
|
||||
"large_stamp-ok.png" = 'icons/stamp_icons/large_stamp-ok.png',
|
||||
"large_stamp-hop.png" = 'icons/stamp_icons/large_stamp-hop.png',
|
||||
"large_stamp-cmo.png" = 'icons/stamp_icons/large_stamp-cmo.png',
|
||||
"large_stamp-ce.png" = 'icons/stamp_icons/large_stamp-ce.png',
|
||||
"large_stamp-hos.png" = 'icons/stamp_icons/large_stamp-hos.png',
|
||||
"large_stamp-rd.png" = 'icons/stamp_icons/large_stamp-rd.png',
|
||||
"large_stamp-cap.png" = 'icons/stamp_icons/large_stamp-cap.png',
|
||||
"large_stamp-qm.png" = 'icons/stamp_icons/large_stamp-qm.png',
|
||||
"large_stamp-law.png" = 'icons/stamp_icons/large_stamp-law.png'
|
||||
)
|
||||
|
||||
|
||||
//Registers HTML Interface assets.
|
||||
/datum/asset/HTML_interface/register()
|
||||
for(var/path in typesof(/datum/html_interface))
|
||||
var/datum/html_interface/hi = new path()
|
||||
hi.registerResources()
|
||||
|
||||
@@ -22,6 +22,14 @@
|
||||
/client/Topic(href, href_list, hsrc)
|
||||
if(!usr || usr != mob) //stops us calling Topic for somebody else's client. Also helps prevent usr=null
|
||||
return
|
||||
// NanoUI
|
||||
if(href_list["nano_error"])
|
||||
src << href_list["nano_error"]
|
||||
throw EXCEPTION("NanoUI: [href_list["nano_error"]]")
|
||||
if(href_list["nano_log"])
|
||||
src << href_list["nano_log"]
|
||||
return
|
||||
// asset_cache
|
||||
if(href_list["asset_cache_confirm_arrival"])
|
||||
//src << "ASSET JOB [href_list["asset_cache_confirm_arrival"]] ARRIVED."
|
||||
var/job = text2num(href_list["asset_cache_confirm_arrival"])
|
||||
|
||||
@@ -27,6 +27,7 @@ var/list/preferences_datums = list()
|
||||
|
||||
|
||||
var/UI_style = "Midnight"
|
||||
var/nanoui_fancy = TRUE
|
||||
var/toggles = TOGGLES_DEFAULT
|
||||
var/chat_toggles = TOGGLES_DEFAULT_CHAT
|
||||
var/ghost_form = "ghost"
|
||||
@@ -321,6 +322,7 @@ var/list/preferences_datums = list()
|
||||
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
||||
dat += "<h2>General Settings</h2>"
|
||||
dat += "<b>UI Style:</b> <a href='?_src_=prefs;preference=ui'>[UI_style]</a><br>"
|
||||
dat += "<b>Fancy NanoUI:</b> <a href='?_src_=prefs;preference=nanoui'>[(nanoui_fancy) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Play admin midis:</b> <a href='?_src_=prefs;preference=hear_midis'>[(toggles & SOUND_MIDI) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Play lobby music:</b> <a href='?_src_=prefs;preference=lobby_music'>[(toggles & SOUND_LOBBY) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Ghost ears:</b> <a href='?_src_=prefs;preference=ghost_ears'>[(chat_toggles & CHAT_GHOSTEARS) ? "Nearest Creatures" : "All Speech"]</a><br>"
|
||||
@@ -1002,6 +1004,9 @@ var/list/preferences_datums = list()
|
||||
else
|
||||
UI_style = "Midnight"
|
||||
|
||||
if("nanoui")
|
||||
nanoui_fancy = !nanoui_fancy
|
||||
|
||||
if("hear_adminhelps")
|
||||
toggles ^= SOUND_ADMINHELP
|
||||
if("announce_login")
|
||||
|
||||
@@ -165,6 +165,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["ooccolor"] >> ooccolor
|
||||
S["lastchangelog"] >> lastchangelog
|
||||
S["UI_style"] >> UI_style
|
||||
S["nanoui_fancy"] >> nanoui_fancy
|
||||
S["be_special"] >> be_special
|
||||
|
||||
if(islist(S["be_special"]))
|
||||
@@ -189,6 +190,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor)))
|
||||
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
|
||||
UI_style = sanitize_inlist(UI_style, list("Midnight", "Plasmafire", "Retro"), initial(UI_style))
|
||||
nanoui_fancy = sanitize_integer(nanoui_fancy, 0, 1, initial(nanoui_fancy))
|
||||
default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot))
|
||||
toggles = sanitize_integer(toggles, 0, 65535, initial(toggles))
|
||||
ghost_form = sanitize_inlist(ghost_form, ghost_forms, initial(ghost_form))
|
||||
@@ -207,6 +209,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["ooccolor"] << ooccolor
|
||||
S["lastchangelog"] << lastchangelog
|
||||
S["UI_style"] << UI_style
|
||||
S["nanoui_fancy"] << nanoui_fancy
|
||||
S["be_special"] << be_special
|
||||
S["default_slot"] << default_slot
|
||||
S["toggles"] << toggles
|
||||
|
||||
@@ -104,7 +104,8 @@
|
||||
/obj/item/weapon/melee/baton/loaded=1,\
|
||||
/obj/item/clothing/mask/gas/sechailer=1,\
|
||||
/obj/item/weapon/gun/energy/gun=1,\
|
||||
/obj/item/weapon/reagent_containers/hypospray/combat=1)
|
||||
/obj/item/weapon/reagent_containers/hypospray/combat=1,\
|
||||
/obj/item/weapon/gun/medbeam=1)
|
||||
|
||||
/datum/outfit/ert/medic/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
..()
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
put_on_delay = 50
|
||||
|
||||
/obj/item/clothing/suit/armor/laserproof
|
||||
name = "ablative armor vest"
|
||||
name = "reflector vest"
|
||||
desc = "A vest that excels in protecting the wearer against energy projectiles, as well as occasionally reflecting them."
|
||||
icon_state = "armor_reflec"
|
||||
item_state = "armor_reflec"
|
||||
@@ -172,13 +172,13 @@
|
||||
continue
|
||||
turfs += T
|
||||
if(!turfs.len)
|
||||
turfs += pick(/turf in orange(6, src))
|
||||
var/turf/picked = pick(turfs)
|
||||
if(!isturf(picked))
|
||||
return
|
||||
if(H.buckled)
|
||||
H.buckled.unbuckle_mob()
|
||||
H.forceMove(picked)
|
||||
turfs += pick(/turf in orange(6, H))
|
||||
var/turf/picked = pick(turfs)
|
||||
if(!isturf(picked))
|
||||
return
|
||||
if(H.buckled)
|
||||
H.buckled.unbuckle_mob()
|
||||
H.forceMove(picked)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 611 B After Width: | Height: | Size: 610 B |
@@ -18,7 +18,7 @@ The client is optional and may be a /mob, /client or /html_interface_client obje
|
||||
. = ..()
|
||||
|
||||
// Add appropriate CSS and set the default layout.
|
||||
src.head = src.head + "<link rel=\"stylesheet\" type=\"text/css\" href=\"nanotrasen.css\" />"
|
||||
src.head = src.head + "<link rel=\"stylesheet\" type=\"text/css\" href=\"hi-nanotrasen.css\" />"
|
||||
src.updateLayout("")
|
||||
|
||||
/datum/html_interface/nanotrasen/updateLayout(layout)
|
||||
@@ -32,7 +32,7 @@ The client is optional and may be a /mob, /client or /html_interface_client obje
|
||||
/datum/html_interface/nanotrasen/registerResources(var/list/resources = list())
|
||||
resources["uiBg.png"] = 'uiBg.png'
|
||||
resources["uiBgcenter.png"] = 'uiBgcenter.png'
|
||||
resources["nanotrasen.css"] = 'nanotrasen.css'
|
||||
resources["hi-nanotrasen.css"] = 'hi-nanotrasen.css'
|
||||
..(resources)
|
||||
|
||||
/datum/html_interface/nanotrasen/createWindow(datum/html_interface_client/hclient)
|
||||
|
||||
@@ -1,12 +1,284 @@
|
||||
proc/json2list(json)
|
||||
var/static/json_reader/_jsonr = new()
|
||||
return _jsonr.ReadObject(_jsonr.ScanJson(json))
|
||||
/* Usage:
|
||||
JSON.stringify(obj) - Converts lists and values into a JSON string.
|
||||
JSON.parse(json) - Converts a JSON string into lists and values.
|
||||
*/
|
||||
|
||||
proc/list2json(list/L)
|
||||
var/static/json_writer/_jsonw = new()
|
||||
return _jsonw.write(L)
|
||||
/var/datum/jsonHelper/JSON = new // A namespace for procs.
|
||||
|
||||
proc/list2json_usecache(list/L)
|
||||
var/static/json_writer/_jsonw = new()
|
||||
_jsonw.use_cache = 1
|
||||
return _jsonw.write(L)
|
||||
// ************************************ WRITER ************************************
|
||||
/datum/jsonHelper/proc/stringify(value)
|
||||
return list2text(WriteValue(list(), value))
|
||||
|
||||
/datum/jsonHelper/proc/WriteValue(list/json, value)
|
||||
. = json
|
||||
if(isnum(value))
|
||||
json += value // Consider num2text(value, 20) for maximum accuracy.
|
||||
else if(isnull(value))
|
||||
json += "null"
|
||||
else if(istext(value))
|
||||
WriteString(json, value)
|
||||
else if(istype(value, /list))
|
||||
WriteList(json, value)
|
||||
else
|
||||
throw EXCEPTION("Datums cannot be converted to JSON.")
|
||||
|
||||
/datum/jsonHelper/proc/WriteString(list/json, str)
|
||||
. = json
|
||||
var/quotePos = findtextEx(str, "\"")
|
||||
var/bsPos = findtextEx(str, "\\")
|
||||
if (quotePos == 0 && bsPos == 0)
|
||||
json.Add("\"", str, "\"")
|
||||
else
|
||||
json += "\""
|
||||
var/lastStop = 1
|
||||
while(quotePos != 0 || bsPos != 0)
|
||||
var/escPos
|
||||
if(quotePos < bsPos && quotePos != 0 || bsPos == 0)
|
||||
escPos = quotePos
|
||||
else
|
||||
escPos = bsPos
|
||||
json.Add(copytext(str, lastStop, escPos), "\\")
|
||||
lastStop = escPos
|
||||
if(escPos == quotePos)
|
||||
quotePos = findtextEx(str, "\"", escPos + 1)
|
||||
else if(escPos == bsPos)
|
||||
bsPos = findtextEx(str, "\\", escPos + 1)
|
||||
json.Add(copytext(str, lastStop), "\"")
|
||||
|
||||
/datum/jsonHelper/proc/WriteList(list/json, list/listVal)
|
||||
. = json
|
||||
#define Either 0
|
||||
#define CannotBeArray 1
|
||||
#define CannotBeObject 2
|
||||
#define BadList (CannotBeArray | CannotBeObject)
|
||||
var/listType = Either
|
||||
for(var/key in listVal)
|
||||
if(istext(key))
|
||||
if(!isnull(listVal[key]))
|
||||
listType |= CannotBeArray
|
||||
else
|
||||
if(!isnum(key) && !isnull(listVal[key]))
|
||||
listType = BadList
|
||||
else
|
||||
listType |= CannotBeObject
|
||||
|
||||
if(listType == BadList)
|
||||
throw EXCEPTION("The given list cannot be converted to JSON.")
|
||||
|
||||
if(listType == CannotBeArray)
|
||||
json += "{"
|
||||
var/addComma
|
||||
for(var/key in listVal)
|
||||
if(addComma)
|
||||
json += ","
|
||||
else
|
||||
addComma = TRUE
|
||||
WriteString(json, key)
|
||||
json += ":"
|
||||
WriteValue(json, listVal[key])
|
||||
json += "}"
|
||||
else
|
||||
json += "\["
|
||||
var/addComma
|
||||
for(var/key in listVal)
|
||||
if(addComma)
|
||||
json += ","
|
||||
else
|
||||
addComma = TRUE
|
||||
WriteValue(json, key)
|
||||
json += "]"
|
||||
#undef Either
|
||||
#undef CannotBeFlat
|
||||
#undef CannotBeAssoc
|
||||
#undef BadList
|
||||
|
||||
// ************************************ READER ************************************
|
||||
#define aBackspace 0x08
|
||||
#define aTab 0x09
|
||||
#define aLineBreak 0x0A
|
||||
#define aVertTab 0x0B
|
||||
#define aFormFeed 0x0C
|
||||
#define aCarriageReturn 0x0D
|
||||
#define aSpace 0x20
|
||||
#define aZero 0x30
|
||||
#define aNonBreakSpace 0xA0
|
||||
|
||||
#define Advance if(++readPos > jsonLen) { curAscii = 0; curChar = "" } else { curAscii = text2ascii(json, readPos); curChar = ascii2text(curAscii) } // Deal with it.
|
||||
#define SkipWhitespace while(curAscii in whitespace) Advance
|
||||
#define AdvanceWS Advance; SkipWhitespace
|
||||
|
||||
/datum/jsonHelper/var
|
||||
readPos
|
||||
jsonLen
|
||||
json
|
||||
curAscii
|
||||
curChar
|
||||
static/list/whitespace = list(aTab, aLineBreak, aVertTab, aFormFeed, aCarriageReturn, aSpace, aNonBreakSpace)
|
||||
|
||||
/datum/jsonHelper/proc/parse(json)
|
||||
readPos = 0
|
||||
jsonLen = length(json)
|
||||
src.json = json
|
||||
curAscii = 0
|
||||
curChar = ""
|
||||
AdvanceWS
|
||||
var/value = ParseValue()
|
||||
if(readPos < jsonLen)
|
||||
throw EXCEPTION("Expected: End of JSON")
|
||||
return value
|
||||
|
||||
/datum/jsonHelper/proc/ParseValue()
|
||||
if(curChar == "\"")
|
||||
return ParseString()
|
||||
else if(curChar == "-" || (curAscii >= aZero && curAscii <= aZero + 9))
|
||||
return ParseNumber()
|
||||
else if(curChar == "{")
|
||||
return ParseObject()
|
||||
else if(curChar == "\[")
|
||||
return ParseArray()
|
||||
else if(curChar == "t")
|
||||
if(copytext(json, readPos, readPos+4) == "true")
|
||||
readPos += 3
|
||||
AdvanceWS
|
||||
return TRUE
|
||||
else
|
||||
throw EXCEPTION("Expected: 'true'")
|
||||
else if(curChar == "f")
|
||||
if(copytext(json, readPos, readPos+5) == "false")
|
||||
readPos += 4
|
||||
AdvanceWS
|
||||
return FALSE
|
||||
else
|
||||
throw EXCEPTION("Expected: 'false'")
|
||||
else if(curChar == "n")
|
||||
if(copytext(json, readPos, readPos+4) == "null")
|
||||
readPos += 3
|
||||
AdvanceWS
|
||||
return null
|
||||
else
|
||||
throw EXCEPTION("Expected: 'null'")
|
||||
else if(curChar == "")
|
||||
throw EXCEPTION("Unexpected: End of JSON")
|
||||
else
|
||||
throw EXCEPTION("Unexpected: '[curChar]'")
|
||||
|
||||
|
||||
|
||||
/datum/jsonHelper/proc/ParseString()
|
||||
ASSERT(curChar == "\"")
|
||||
Advance
|
||||
var/list/chars = list()
|
||||
while(readPos <= jsonLen)
|
||||
if(curChar == "\"")
|
||||
AdvanceWS
|
||||
return list2text(chars)
|
||||
else if(curChar == "\\")
|
||||
Advance
|
||||
switch(curChar)
|
||||
if("\"", "\\", "/")
|
||||
chars += ascii2text(curAscii)
|
||||
if("b")
|
||||
chars += ascii2text(aBackspace)
|
||||
if("f")
|
||||
chars += ascii2text(aFormFeed)
|
||||
if("n")
|
||||
chars += "\n"
|
||||
if("r")
|
||||
chars += ascii2text(aCarriageReturn) // Should we ignore these?
|
||||
if("t")
|
||||
chars += "\t"
|
||||
if("u")
|
||||
throw EXCEPTION("JSON \\uXXXX escape sequence not supported")
|
||||
else
|
||||
throw EXCEPTION("Invalid escape sequence")
|
||||
Advance
|
||||
else
|
||||
chars += ascii2text(curAscii)
|
||||
Advance
|
||||
throw EXCEPTION("Unterminated string")
|
||||
|
||||
/datum/jsonHelper/proc/ParseNumber()
|
||||
var/firstPos = readPos
|
||||
if(curChar == "-")
|
||||
Advance
|
||||
if(curAscii >= aZero + 1 && curAscii <= aZero + 9)
|
||||
do
|
||||
Advance
|
||||
while(curAscii >= aZero && curAscii <= aZero + 9)
|
||||
else if(curAscii == aZero)
|
||||
Advance
|
||||
else
|
||||
throw EXCEPTION("Expected: digit")
|
||||
|
||||
if(curChar == ".")
|
||||
Advance
|
||||
var/found = FALSE
|
||||
while(curAscii >= aZero && curAscii <= aZero + 9)
|
||||
found = TRUE
|
||||
Advance
|
||||
if(!found)
|
||||
throw EXCEPTION("Expected: digit")
|
||||
|
||||
if(curChar == "E" || curChar == "e")
|
||||
Advance
|
||||
var/found = FALSE
|
||||
if(curChar == "-")
|
||||
Advance
|
||||
else if(curChar == "+")
|
||||
Advance
|
||||
while(curAscii >= aZero && curAscii <= aZero + 9)
|
||||
found = TRUE
|
||||
Advance
|
||||
if(!found)
|
||||
throw EXCEPTION("Expected: digit")
|
||||
|
||||
SkipWhitespace
|
||||
return text2num(copytext(json, firstPos, readPos))
|
||||
|
||||
/datum/jsonHelper/proc/ParseObject()
|
||||
ASSERT(curChar == "{")
|
||||
var/list/object = list()
|
||||
AdvanceWS
|
||||
while(curChar == "\"")
|
||||
var/key = ParseString()
|
||||
if(curChar != ":")
|
||||
throw EXCEPTION("Expected: ':'")
|
||||
AdvanceWS
|
||||
object[key] = ParseValue()
|
||||
if(curChar == ",")
|
||||
AdvanceWS
|
||||
else
|
||||
break
|
||||
if(curChar != "}")
|
||||
throw EXCEPTION("Expected: string or '}'")
|
||||
AdvanceWS
|
||||
return object
|
||||
|
||||
/datum/jsonHelper/proc/ParseArray()
|
||||
ASSERT(curChar == "\[")
|
||||
var/list/array = list()
|
||||
AdvanceWS
|
||||
while(curChar != "]")
|
||||
array += list(ParseValue()) // Wrapped in a list in case ParseValue() returns a list.
|
||||
if(curChar == ",")
|
||||
AdvanceWS
|
||||
else
|
||||
break
|
||||
if(curChar != "]")
|
||||
throw EXCEPTION("Expected: ']'")
|
||||
AdvanceWS
|
||||
return array
|
||||
|
||||
#undef aBackspace
|
||||
#undef aTab
|
||||
#undef aLineBreak
|
||||
#undef aVertTab
|
||||
#undef aFormFeed
|
||||
#undef aCarriageReturn
|
||||
#undef aSpace
|
||||
#undef aZero
|
||||
#undef aNonBreakSpace
|
||||
|
||||
#undef Advance
|
||||
#undef SkipWhitespace
|
||||
#undef AdvanceWS
|
||||
@@ -1,187 +0,0 @@
|
||||
json_reader/var/list/string = list("'", "\"")
|
||||
json_reader/var/list/symbols = list("{", "}", "\[", "]", ":", "\"", "'", ",")
|
||||
json_reader/var/list/sequences = list("b" = 8, "t" = 9, "n" = 10, "f" = 12, "r" = 13)
|
||||
json_reader/var/list/tokens
|
||||
json_reader/var/json
|
||||
json_reader/var/i = 1
|
||||
|
||||
|
||||
json_reader/proc/ScanJson(json)
|
||||
src.json = json
|
||||
. = new/list()
|
||||
src.i = 1
|
||||
while(src.i <= lentext(json))
|
||||
var/char = get_char()
|
||||
if(is_whitespace(char))
|
||||
i++
|
||||
continue
|
||||
if(string.Find(char))
|
||||
. += read_string(char)
|
||||
else if(symbols.Find(char))
|
||||
. += new/json_token/symbol(char)
|
||||
else if(is_digit(char))
|
||||
. += read_number()
|
||||
else
|
||||
. += read_word()
|
||||
i++
|
||||
. += new/json_token/eof()
|
||||
|
||||
json_reader/proc/read_word()
|
||||
var/val = ""
|
||||
while(i <= lentext(json))
|
||||
var/char = get_char()
|
||||
if(is_whitespace(char) || symbols.Find(char))
|
||||
i-- // let scanner handle this character
|
||||
return new/json_token/word(val)
|
||||
val += char
|
||||
i++
|
||||
|
||||
json_reader/proc/read_string(delim)
|
||||
var/escape = FALSE
|
||||
var/val = ""
|
||||
while(++i <= lentext(json))
|
||||
var/char = get_char()
|
||||
if(escape)
|
||||
switch(char)
|
||||
if("\\", "'", "\"", "/", "u")
|
||||
val += char
|
||||
else
|
||||
// TODO: support octal, hex, unicode sequences
|
||||
ASSERT(sequences.Find(char))
|
||||
val += ascii2text(sequences[char])
|
||||
else
|
||||
if(char == delim)
|
||||
return new/json_token/text(val)
|
||||
else if(char == "\\")
|
||||
escape = TRUE
|
||||
else
|
||||
val += char
|
||||
CRASH("Unterminated string.")
|
||||
|
||||
json_reader/proc/read_number()
|
||||
var/val = ""
|
||||
var/char = get_char()
|
||||
while(is_digit(char) || char == "." || lowertext(char) == "e")
|
||||
val += char
|
||||
i++
|
||||
char = get_char()
|
||||
i-- // allow scanner to read the first non-number character
|
||||
return new/json_token/number(text2num(val))
|
||||
|
||||
json_reader/proc/check_char()
|
||||
ASSERT(args.Find(get_char()))
|
||||
|
||||
json_reader/proc/get_char()
|
||||
return copytext(json, i, i+1)
|
||||
|
||||
json_reader/proc/is_whitespace(char)
|
||||
return char == " " || char == "\t" || char == "\n" || text2ascii(char) == 13
|
||||
|
||||
json_reader/proc/is_digit(char)
|
||||
var/c = text2ascii(char)
|
||||
return 48 <= c && c <= 57 || char == "+" || char == "-"
|
||||
|
||||
|
||||
json_reader/proc/ReadObject(list/tokens)
|
||||
src.tokens = tokens
|
||||
. = new/list()
|
||||
i = 1
|
||||
read_token("{", /json_token/symbol)
|
||||
while(i <= tokens.len)
|
||||
var/json_token/K = get_token()
|
||||
check_type(/json_token/word, /json_token/text)
|
||||
next_token()
|
||||
read_token(":", /json_token/symbol)
|
||||
|
||||
.[K.value] = read_value()
|
||||
|
||||
var/json_token/S = get_token()
|
||||
check_type(/json_token/symbol)
|
||||
switch(S.value)
|
||||
if(",")
|
||||
next_token()
|
||||
continue
|
||||
if("}")
|
||||
next_token()
|
||||
return
|
||||
else
|
||||
die()
|
||||
|
||||
json_reader/proc/get_token()
|
||||
return tokens[i]
|
||||
|
||||
json_reader/proc/next_token()
|
||||
return tokens[++i]
|
||||
|
||||
json_reader/proc/read_token(val, type)
|
||||
var/json_token/T = get_token()
|
||||
if(!(T.value == val && istype(T, type)))
|
||||
CRASH("Expected '[val]', found '[T.value]'.")
|
||||
next_token()
|
||||
return T
|
||||
|
||||
json_reader/proc/check_type(...)
|
||||
var/json_token/T = get_token()
|
||||
for(var/type in args)
|
||||
if(istype(T, type))
|
||||
return
|
||||
CRASH("Bad token type: [T.type].")
|
||||
|
||||
json_reader/proc/check_value(...)
|
||||
var/json_token/T = get_token()
|
||||
ASSERT(args.Find(T.value))
|
||||
|
||||
json_reader/proc/read_key()
|
||||
var/char = get_char()
|
||||
if(char == "\"" || char == "'")
|
||||
return read_string(char)
|
||||
|
||||
json_reader/proc/read_value()
|
||||
var/json_token/T = get_token()
|
||||
switch(T.type)
|
||||
if(/json_token/text, /json_token/number)
|
||||
next_token()
|
||||
return T.value
|
||||
if(/json_token/word)
|
||||
next_token()
|
||||
switch(T.value)
|
||||
if("true")
|
||||
return TRUE
|
||||
if("false")
|
||||
return FALSE
|
||||
if("null")
|
||||
return null
|
||||
if(/json_token/symbol)
|
||||
switch(T.value)
|
||||
if("\[")
|
||||
return read_array()
|
||||
if("{")
|
||||
return ReadObject(tokens.Copy(i))
|
||||
die()
|
||||
|
||||
json_reader/proc/read_array()
|
||||
read_token("\[", /json_token/symbol)
|
||||
. = new/list()
|
||||
var/list/L = .
|
||||
while(i <= tokens.len)
|
||||
// Avoid using Add() or += in case a list is returned.
|
||||
L.len++
|
||||
L[L.len] = read_value()
|
||||
var/json_token/T = get_token()
|
||||
check_type(/json_token/symbol)
|
||||
switch(T.value)
|
||||
if(",")
|
||||
next_token()
|
||||
continue
|
||||
if("]")
|
||||
next_token()
|
||||
return
|
||||
else
|
||||
die()
|
||||
next_token()
|
||||
CRASH("Unterminated array.")
|
||||
|
||||
|
||||
json_reader/proc/die(json_token/T)
|
||||
if(!T) T = get_token()
|
||||
CRASH("Unexpected token: [T.value].")
|
||||
@@ -1,9 +0,0 @@
|
||||
json_token/var/value
|
||||
json_token/New(v)
|
||||
src.value = v
|
||||
|
||||
json_token/text
|
||||
json_token/number
|
||||
json_token/word
|
||||
json_token/symbol
|
||||
json_token/eof
|
||||
@@ -1,67 +0,0 @@
|
||||
#define LIST_FLAT 0
|
||||
#define LIST_NESTED 1
|
||||
#define LIST_OBJECT 2 // Object in this case means json object, ortherwise known as an associative list or array.
|
||||
|
||||
json_writer/var/use_cache = 0
|
||||
|
||||
json_writer/proc/write(val)
|
||||
if(isnum(val))
|
||||
. = num2text(val)
|
||||
else if(isnull(val))
|
||||
. = "null"
|
||||
else if(istype(val, /list))
|
||||
switch (listtype(val))
|
||||
if (LIST_FLAT)
|
||||
. = write_array(val)
|
||||
if (LIST_NESTED)
|
||||
. = write_array(val)
|
||||
if (LIST_OBJECT)
|
||||
. = write_object(val)
|
||||
else
|
||||
. = write_string("[val]")
|
||||
|
||||
json_writer/proc/write_object(list/L)
|
||||
if(use_cache && L["__json_cache"])
|
||||
return L["__json_cache"]
|
||||
. = list()
|
||||
for(var/k in L)
|
||||
. += "\"[k]\":[write(L[k])]"
|
||||
|
||||
. = "{[list2text(., ",")]}"
|
||||
|
||||
json_writer/proc/write_flat_array(list/L)
|
||||
. = "\[[list2text(L, ",")]]"
|
||||
|
||||
json_writer/proc/write_array(list/L)
|
||||
. = list()
|
||||
for(var/item in L)
|
||||
. += write(item)
|
||||
. = "\[[list2text(., ",")]]"
|
||||
|
||||
json_writer/proc/write_string(txt)
|
||||
var/static/list/json_escape = list("\\" = "\\\\", "\"" = "\\\"", "\n" = "\\n")
|
||||
for(var/targ in json_escape)
|
||||
var/start = 1
|
||||
while(start <= lentext(txt))
|
||||
var/i = findtext(txt, targ, start)
|
||||
if(!i)
|
||||
break
|
||||
var/lrep = length(json_escape[targ])
|
||||
txt = "[copytext(txt, 1, i)][json_escape[targ]][copytext(txt, i + length(targ))]"
|
||||
start = i + lrep
|
||||
|
||||
return {""[txt]""}
|
||||
|
||||
json_writer/proc/listtype(list/L)
|
||||
. = LIST_FLAT
|
||||
for(var/key in L)
|
||||
if (. == LIST_FLAT && istype(key, /list))
|
||||
. = LIST_NESTED
|
||||
if (!isnum(key) && !istype(key, /list))
|
||||
. = LIST_OBJECT
|
||||
break // If it's an object, we can just stop now.
|
||||
|
||||
|
||||
#undef LIST_FLAT
|
||||
#undef LIST_NESTED
|
||||
#undef LIST_OBJECT
|
||||
@@ -18,12 +18,12 @@ obj/effect/dummy/slaughter/relaymove(mob/user, direction)
|
||||
spawn(1)
|
||||
src.canmove = 1
|
||||
|
||||
/obj/effect/dummy/slaughter/ex_act(blah)
|
||||
/obj/effect/dummy/slaughter/ex_act()
|
||||
return
|
||||
/obj/effect/dummy/slaughter/bullet_act(blah)
|
||||
/obj/effect/dummy/slaughter/bullet_act()
|
||||
return
|
||||
|
||||
/obj/effect/dummy/slaughter/singularity_act(blah)
|
||||
/obj/effect/dummy/slaughter/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/dummy/slaughter/Destroy()
|
||||
|
||||
@@ -684,9 +684,6 @@
|
||||
var/see_temp = H.see_invisible
|
||||
H.see_invisible = invis_sight
|
||||
|
||||
if(H.seer)
|
||||
H.see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
|
||||
if(H.glasses)
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses))
|
||||
var/obj/item/clothing/glasses/G = H.glasses
|
||||
|
||||
@@ -82,9 +82,12 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
return 1
|
||||
|
||||
/datum/species/lizard/handle_speech(message)
|
||||
// jesus christ why
|
||||
|
||||
if(copytext(message, 1, 2) != "*")
|
||||
message = replacetext(message, "s", "sss")
|
||||
message = regEx_replaceall(message, "(?<!s)s(?!s)", "sss") //(?<!s) Not s before. (?!s) not s after. That way it only triples a single s instead of double ss.
|
||||
message = regEx_replaceall(message, "(?<!s)ss(?!s)", "ssss")
|
||||
message = regEx_replaceall(message, "(?<!S)S(?!S)", "SSS")
|
||||
message = regEx_replaceall(message, "(?<!S)SS(?!S)", "SSSS")
|
||||
|
||||
return message
|
||||
|
||||
@@ -163,6 +166,7 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
name = "???"
|
||||
id = "shadow"
|
||||
darksight = 8
|
||||
invis_sight = SEE_INVISIBLE_MINIMUM
|
||||
sexes = 0
|
||||
ignored_by = list(/mob/living/simple_animal/hostile/faithless)
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/shadow
|
||||
|
||||
@@ -216,3 +216,7 @@
|
||||
else
|
||||
target.see_invisible = SEE_INVISIBLE_LIVING
|
||||
name = "Toggle Nightvision \[OFF]"
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/statue/sentience_act()
|
||||
faction -= "neutral"
|
||||
@@ -24,7 +24,7 @@
|
||||
see_in_dark = 8
|
||||
languages = ALL
|
||||
response_help = "passes through"
|
||||
response_disarm = "swings at"
|
||||
response_disarm = "swings through"
|
||||
response_harm = "punches through"
|
||||
unsuitable_atmos_damage = 0
|
||||
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) //I don't know how you'd apply those, but revenants no-sell them anyway.
|
||||
|
||||
@@ -89,10 +89,9 @@
|
||||
charge_max = 200
|
||||
range = 5
|
||||
stun = 30
|
||||
reveal = 100
|
||||
cast_amount = 40
|
||||
var/shock_range = 2
|
||||
var/shock_damage = 18
|
||||
var/shock_damage = 20
|
||||
action_icon_state = "overload_lights"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/revenant/overload/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
@@ -217,7 +216,7 @@
|
||||
desc = "Causes nearby living things to waste away."
|
||||
charge_max = 200
|
||||
range = 3
|
||||
reveal = 60
|
||||
reveal = 50
|
||||
cast_amount = 50
|
||||
unlock_amount = 200
|
||||
action_icon_state = "blight"
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
stagedamage++
|
||||
affected_mob.adjustToxLoss(stage*3) //should, normally, do about 45 toxin damage.
|
||||
PoolOrNew(/obj/effect/overlay/temp/revenant, affected_mob.loc)
|
||||
if(prob(45))
|
||||
if(!finalstage && prob(45))
|
||||
affected_mob.adjustStaminaLoss(stage*2)
|
||||
..() //So we don't increase a stage before applying the stage damage.
|
||||
switch(stage)
|
||||
|
||||
@@ -513,3 +513,7 @@
|
||||
nest.spawned_mobs -= src
|
||||
nest = null
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion
|
||||
return
|
||||
@@ -87,7 +87,6 @@
|
||||
var/obj/item/r_hand = null//Living
|
||||
var/obj/item/weapon/storage/s_active = null//Carbon
|
||||
|
||||
var/seer = 0 //for cult//Carbon, probably Human
|
||||
var/see_override = 0 //0 for no override, sets see_invisible = see_override in mob life process
|
||||
|
||||
var/datum/hud/hud_used = null
|
||||
|
||||
@@ -27,6 +27,20 @@
|
||||
datum/topic_state/state = default_state)
|
||||
return -1 // Sorta implemented.
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Called on a NanoUI when the UI receieves a href.
|
||||
* Think of this as Topic().
|
||||
*
|
||||
* required action string The action/button that has been invoked by the user.
|
||||
* required params list A list of parameters attached to the button.
|
||||
*
|
||||
* return bool If the UI should be updated or not.
|
||||
**/
|
||||
/atom/movable/proc/ui_act(action, list/params)
|
||||
return // Not implemented.
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
@@ -81,6 +95,5 @@
|
||||
var/href = "close=1"
|
||||
src.Topic(href, params2list(href), ui.ref)
|
||||
// Otherwise, if we use the legacy logic, unset the mob's machine.
|
||||
else if (ui.on_close_logic)
|
||||
if(src && src.mob)
|
||||
src.mob.unset_machine()
|
||||
else if(src && src.mob)
|
||||
src.mob.unset_machine()
|
||||
@@ -22,19 +22,19 @@
|
||||
var/window_id // The window_id for browse() and onclose().
|
||||
var/width = 0 // The window width.
|
||||
var/height = 0 // The window height
|
||||
var/on_close_logic = 1 // Enable legacy onclose() logic.
|
||||
var/atom/ref = null // An extra ref to use when the window is closed.
|
||||
var/window_options = "focus=0;can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // Extra options to winset().
|
||||
var/list/stylesheets = list() // The list of CSS stylesheets to apply to the NanoUI..
|
||||
var/list/scripts = list() // The list of Javascript scripts to apply to the NanoUI.
|
||||
var/templates[0] // The list of NanoUI templates available to the NanoUI.
|
||||
var/layout_key = "default" // The layout_key used to load alternate layouts and CSS.
|
||||
var/state_key = "default" // The state of the frontend.
|
||||
var/window_options = list( // Extra options to winset().
|
||||
"focus" = 0,
|
||||
"titlebar" = 1,
|
||||
"can_resize" = 1,
|
||||
"can_minimize" = 1,
|
||||
"can_maximize" = 0,
|
||||
"can_close" = 1,
|
||||
"auto_format" = 0
|
||||
)
|
||||
var/atom/ref = null // An extra ref to call when the window is closed.
|
||||
var/layout = "nanotrasen" // The layout to be used for this UI.
|
||||
var/template // The template to be used for this UI.
|
||||
var/auto_update = 1 // Update the NanoUI every MC tick.
|
||||
var/auto_update_layout = 0 // Re-render the layout every update.
|
||||
var/auto_update_content = 1 // Re-render the content every update.
|
||||
var/show_map = 0 // Show the Map UI.
|
||||
var/map_z_level = 1 // Map Z-level.
|
||||
var/list/initial_data // The data (and datastructure) used to initialize the NanoUI
|
||||
var/status = NANO_INTERACTIVE // The status/visibility of the NanoUI.
|
||||
var/datum/topic_state/state = null // Topic state used to determine status. Topic states are in interactions/.
|
||||
@@ -66,9 +66,9 @@
|
||||
src.user = user
|
||||
src.src_object = src_object
|
||||
src.ui_key = ui_key
|
||||
src.window_id = "[ui_key]\ref[src_object]"
|
||||
src.window_id = "\ref[src_object]-[ui_key]"
|
||||
|
||||
add_template("main", template)
|
||||
set_template(template)
|
||||
|
||||
if (title)
|
||||
src.title = sanitize(title)
|
||||
@@ -85,76 +85,9 @@
|
||||
master_ui.children += src
|
||||
src.state = state
|
||||
|
||||
add_common_assets()
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/nanoui)
|
||||
assets.send(user)
|
||||
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/nanoui)
|
||||
assets.send(user, template)
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Add the assets required by all NanoUIs.
|
||||
**/
|
||||
/datum/nanoui/proc/add_common_assets()
|
||||
// Libraries: jQuery, jQuery-UI, and doT.
|
||||
add_script("jquery.js")
|
||||
add_script("jquery-ui.js")
|
||||
add_script("doT.js")
|
||||
// Nano Utility: Utility functions and sanity checks.
|
||||
add_script("nano_utility.js") // The NanoUtility JS, this is used to store utility functions.
|
||||
// Nano Template: Renders templates using doT.
|
||||
add_script("nano_template.js")
|
||||
// Nano State Manager: Handles server updates and passes them to the current state.
|
||||
add_script("nano_state_manager.js")
|
||||
// Nano State: Base state.
|
||||
add_script("nano_state.js")
|
||||
// Nano State/Default: State used by all NanoUIs by default.
|
||||
add_script("nano_state_default.js")
|
||||
// Nano Base Callbacks: Used to set up callbacks across all NanoUIs.
|
||||
add_script("nano_base_callbacks.js")
|
||||
// Nano Base Helpers: Template helpers common across all NanoUIs.
|
||||
add_script("nano_base_helpers.js")
|
||||
// CSS reset.
|
||||
add_stylesheet("normalize.css")
|
||||
// Common style elements.
|
||||
add_stylesheet("shared.css")
|
||||
// Icons.
|
||||
add_stylesheet("icons.css")
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Set the status/visibility of the NanoUI.
|
||||
*
|
||||
* required state int The status to set (NANO_CLOSE/NANO_DISABLED/NANO_UPDATE/NANO_INTERACTIVE).
|
||||
* optional push_update bool Push an update to the UI (an update is always sent for NANO_DISABLED).
|
||||
**/
|
||||
/datum/nanoui/proc/set_status(state, push_update = 0)
|
||||
if (state != status) // Only update if status has changed.
|
||||
if (status == NANO_DISABLED)
|
||||
status = state
|
||||
if (push_update)
|
||||
update()
|
||||
else
|
||||
status = state
|
||||
if (push_update || status == 0) // Force an update if NANO_DISABLED.
|
||||
push_data(null, 1)
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Update the status/visibility of the NanoUI for its user.
|
||||
*
|
||||
* optional push_update bool Push an update to the UI (an update is always sent for NANO_DISABLED).
|
||||
**/
|
||||
/datum/nanoui/proc/update_status(push_update = 0)
|
||||
var/new_status = src_object.CanUseTopic(user, state)
|
||||
if(master_ui)
|
||||
new_status = min(new_status, master_ui.status)
|
||||
|
||||
set_status(new_status, push_update)
|
||||
if(new_status == NANO_CLOSE)
|
||||
close()
|
||||
|
||||
/**
|
||||
* public
|
||||
@@ -187,17 +120,25 @@
|
||||
/datum/nanoui/proc/get_config_data()
|
||||
var/list/config_data = list(
|
||||
"title" = title,
|
||||
"srcObject" = list(
|
||||
"name" = src_object.name
|
||||
),
|
||||
"stateKey" = state_key,
|
||||
"status" = status,
|
||||
"autoUpdateLayout" = auto_update_layout,
|
||||
"autoUpdateContent" = auto_update_content,
|
||||
"showMap" = show_map,
|
||||
"mapZLevel" = map_z_level,
|
||||
"ref" = "\ref[src]",
|
||||
"window" = list(
|
||||
"width" = width,
|
||||
"height" = height,
|
||||
"ref" = window_id
|
||||
),
|
||||
"user" = list(
|
||||
"name" = user.name
|
||||
"name" = user.name,
|
||||
"fancy" = user.client.prefs.nanoui_fancy,
|
||||
"ref" = "\ref[user]"
|
||||
),
|
||||
"srcObject" = list(
|
||||
"name" = src_object.name,
|
||||
"ref" = "\ref[src_object]"
|
||||
),
|
||||
"templates" = list(
|
||||
"layout" = "_[layout]",
|
||||
"content" = "[template]"
|
||||
)
|
||||
)
|
||||
return config_data
|
||||
@@ -224,115 +165,31 @@
|
||||
*
|
||||
* Sets the browse() window options for this NanoUI.
|
||||
*
|
||||
* required window_options string The window options to set.
|
||||
* required window_options list The window options to set.
|
||||
**/
|
||||
/datum/nanoui/proc/set_window_options(window_options)
|
||||
/datum/nanoui/proc/set_window_options(list/window_options)
|
||||
src.window_options = window_options
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Add a stylesheet to the NanoUI.
|
||||
* This must be called before the NanoUI is opened.
|
||||
* Set the layout for this NanoUI.
|
||||
* This loads custom layout styles and templates for this NanoUI.
|
||||
*
|
||||
* required file string The path of the stylesheet file to add.
|
||||
* required layout string The new UI layout.
|
||||
**/
|
||||
/datum/nanoui/proc/add_stylesheet(file)
|
||||
stylesheets.Add(file)
|
||||
/datum/nanoui/proc/set_layout(layout)
|
||||
src.layout = lowertext(layout)
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Add a script to the NanoUI.
|
||||
* This must be called before the NanoUI is opened.
|
||||
* Set the template for this NanoUI.
|
||||
*
|
||||
* required file string The path of the script file to add.
|
||||
* required template string The new UI template.
|
||||
**/
|
||||
/datum/nanoui/proc/add_script(file)
|
||||
scripts.Add(file)
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Add a template to the NanoUI.
|
||||
* This must be called before the NanoUI is opened.
|
||||
*
|
||||
* required key string The key used to reference this file in the frontend.
|
||||
* required file string The path of the template file to add.
|
||||
**/
|
||||
/datum/nanoui/proc/add_template(key, filename)
|
||||
templates[key] = filename
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Set the layout key for this NanoUI.
|
||||
* This loads two files during get_html(): 'layout_[layout_key].tmpl' and 'layout_[layout_key].css'.
|
||||
*
|
||||
* required layout_key string The new layout key.
|
||||
**/
|
||||
/datum/nanoui/proc/set_layout_key(layout_key)
|
||||
src.layout_key = lowertext(layout_key)
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Enable/disable auto-updating of the NanoUI layout.
|
||||
*
|
||||
* required state bool Enable/disable auto-updating of the layout.
|
||||
**/
|
||||
/datum/nanoui/proc/set_auto_update_layout(state)
|
||||
auto_update_layout = state
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Enable/disable auto-updating of the NanoUI content.
|
||||
*
|
||||
* required state bool Enable/disable auto-updating of the content.
|
||||
**/
|
||||
/datum/nanoui/proc/set_auto_update_content(state)
|
||||
auto_update_content = state
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Set the state key used in the frontend.
|
||||
*
|
||||
* required state_key string The new state key..
|
||||
**/
|
||||
/datum/nanoui/proc/set_state_key(state_key)
|
||||
src.state_key = state_key
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Toggle showing the Map UI.
|
||||
*
|
||||
* required state bool Enable/disable the Map UI.
|
||||
**/
|
||||
/datum/nanoui/proc/set_show_map(state)
|
||||
show_map = state
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Set the map Z-level.
|
||||
*
|
||||
* required z int The new Z-level.
|
||||
**/
|
||||
/datum/nanoui/proc/set_map_z_level(z)
|
||||
map_z_level = z
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Enable/disable legacy on_close logic.
|
||||
*
|
||||
* required state bool Enable/disable the logic.
|
||||
**/
|
||||
/datum/nanoui/proc/use_on_close_logic(state)
|
||||
on_close_logic = state
|
||||
/datum/nanoui/proc/set_template(template)
|
||||
src.template = lowertext(template)
|
||||
|
||||
/**
|
||||
* private
|
||||
@@ -342,56 +199,50 @@
|
||||
* return string NanoUI HTML output.
|
||||
**/
|
||||
/datum/nanoui/proc/get_html()
|
||||
// Add files based on the layout key.
|
||||
add_stylesheet("layout_[layout_key].css")
|
||||
add_template("layout", "layout_[layout_key].tmpl")
|
||||
|
||||
// Generate <script> and <link> tags.
|
||||
var/script_html = ""
|
||||
for (var/script in scripts)
|
||||
script_html += "<script type='text/javascript' src='[script]'></script>"
|
||||
var/stylesheet_html = ""
|
||||
for (var/stylesheet in stylesheets)
|
||||
stylesheet_html += "<link rel='stylesheet' type='text/css' href='[stylesheet]' />"
|
||||
var/script_html = {"
|
||||
<script type='text/javascript' src='nanoui.lib.js'></script>
|
||||
<script type='text/javascript' src='nanoui.main.js'></script>
|
||||
<script type='text/javascript' src='nanoui.templates.js'></script>
|
||||
"}
|
||||
var/stylesheet_html = {"
|
||||
<link rel="stylesheet" type='text/css' href='http://css-spinners.com/css/spinner/hexdots.css'>
|
||||
<link rel='stylesheet' type='text/css' href='nanoui.lib.css' />
|
||||
<link rel='stylesheet' type='text/css' href='nanoui.common.css' />
|
||||
<link rel='stylesheet' type='text/css' href='nanoui.[layout].css' />
|
||||
"}
|
||||
|
||||
// Generate template JSON.
|
||||
var/template_data_json = "{}"
|
||||
if (templates.len > 0)
|
||||
template_data_json = list2json(templates)
|
||||
|
||||
// Generate data JSON.
|
||||
// Generate JSON.
|
||||
var/list/send_data = get_send_data(initial_data)
|
||||
var/initial_data_json = replacetext(replacetext(list2json_usecache(send_data), """, "&#34;"), "'", "'")
|
||||
|
||||
// Generate URL parameters JSON.
|
||||
var/url_parameters_json = list2json(list("src" = "\ref[src]"))
|
||||
var/initial_data_json = replacetext(JSON.stringify(send_data), "'", "\\'")
|
||||
|
||||
// Generate the HTML document.
|
||||
return {"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="x-ua-compatible" content="IE=edge">
|
||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||
<script type='text/javascript'>
|
||||
function receiveUpdateData(jsonString)
|
||||
{
|
||||
if (typeof NanoStateManager != 'undefined' && typeof jQuery != 'undefined')
|
||||
{
|
||||
NanoStateManager.receiveUpdateData(jsonString);
|
||||
function receiveUpdate(dataString) {
|
||||
if (typeof NanoBus !== 'undefined') {
|
||||
NanoBus.emit('serverUpdate', dataString);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
[script_html]
|
||||
[stylesheet_html]
|
||||
[script_html]
|
||||
</head>
|
||||
<body scroll=auto data-template-data='[template_data_json]' data-initial-data='[initial_data_json]' data-url-parameters='[url_parameters_json]'>
|
||||
<div id="uiLayout"></div>
|
||||
<noscript>
|
||||
<div id="uiNoScript">
|
||||
<h1>Javascript Required</h1>
|
||||
<hr />
|
||||
<p>Javascript is required in order to use this NanoUI interface.</p>
|
||||
<p>Please enable Javascript in Internet Explorer, and restart your game.</p>
|
||||
<body>
|
||||
<div id='data' data-initial='[initial_data_json]'></div>
|
||||
<div id='layout'>
|
||||
<div class='hexdots-loader' style='position:fixed;top:50%;left:50%;transform:translate(-50%, -50%);-ms-transform:translate(-50%, -50%);'>
|
||||
Sending Resources...
|
||||
</div>
|
||||
</div>
|
||||
<noscript>
|
||||
<h1>Javascript Required</h1>
|
||||
<p>Javascript is required in order to use this NanoUI interface.</p>
|
||||
<p>Please enable Javascript in Internet Explorer, and restart your game.</p>
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
||||
@@ -415,12 +266,11 @@
|
||||
var/window_size = ""
|
||||
if (width && height) // If we have a width and height, use them.
|
||||
window_size = "size=[width]x[height];"
|
||||
update_status(push_update = 0) // Update the window state.
|
||||
update_status(push = 0) // Update the window state.
|
||||
if (status == NANO_CLOSE)
|
||||
return // Bail if we should close.
|
||||
|
||||
user << browse(get_html(), "window=[window_id];[window_size][window_options]") // Open the window.
|
||||
winset(user, "mapwindow.map", "focus=true") // Return keyboard focus to map.
|
||||
user << browse(get_html(), "window=[window_id];[window_size][list2params(window_options)]") // Open the window.
|
||||
winset(user, window_id, "on-close=\"nanoclose \ref[src]\"") // Instruct the client to signal NanoUI when the window is closed.
|
||||
SSnano.ui_opened(src) // Call the opened handler.
|
||||
|
||||
@@ -435,7 +285,7 @@
|
||||
**/
|
||||
/datum/nanoui/proc/reinitialize(template, list/data)
|
||||
if(template)
|
||||
add_template("main", template) // Replace the 'main' template.
|
||||
src.template = template // Set a new template.
|
||||
if(data)
|
||||
set_initial_data(data) // Replace the initial_data.
|
||||
open()
|
||||
@@ -458,17 +308,17 @@
|
||||
* Push data to an already open NanoUI.
|
||||
*
|
||||
* required data list The data to send.
|
||||
* optional force_push bool If the update should be sent regardless of state.
|
||||
* optional force bool If the update should be sent regardless of state.
|
||||
**/
|
||||
/datum/nanoui/proc/push_data(data, force_push = 0)
|
||||
update_status(push_update = 0) // Update the window state.
|
||||
if (status == NANO_DISABLED && !force_push)
|
||||
/datum/nanoui/proc/push_data(data, force = 0)
|
||||
update_status(push = 0) // Update the window state.
|
||||
if (status == NANO_DISABLED && !force)
|
||||
return // Cannot update UI, we have no visibility.
|
||||
|
||||
var/list/send_data = get_send_data(data) // Get the data to send.
|
||||
|
||||
// Send the new data to the recieveUpdateData() Javascript function.
|
||||
user << output(list2params(list(list2json_usecache(send_data))),"[window_id].browser:receiveUpdateData")
|
||||
// Send the new data to the recieveUpdate() Javascript function.
|
||||
user << output(list2params(list(JSON.stringify(send_data))), "[window_id].browser:receiveUpdate")
|
||||
|
||||
/**
|
||||
* private
|
||||
@@ -478,22 +328,16 @@
|
||||
* If the src_object's Topic() returns 1, update all UIs attacked to it.
|
||||
**/
|
||||
/datum/nanoui/Topic(href, href_list)
|
||||
update_status(push_update = 0) // Update the window state.
|
||||
update_status(push = 0) // Update the window state.
|
||||
if (status != NANO_INTERACTIVE || user != usr)
|
||||
return // If UI is not interactive or usr calling Topic is not the UI user.
|
||||
|
||||
var/update = src_object.Topic(href, href_list, 0, state) // Call Topic() on the src_object.
|
||||
var/action = href_list["nano"] // Pull the action out.
|
||||
href_list -= "nano"
|
||||
|
||||
// Code to toggle/update the Map UI.
|
||||
var/map_update = 0
|
||||
if(href_list["showMap"])
|
||||
set_show_map(text2num(href_list["showMap"]))
|
||||
map_update = 1
|
||||
if(href_list["mapZLevel"])
|
||||
set_map_z_level(text2num(href_list["mapZLevel"]))
|
||||
map_update = 1
|
||||
var/update = src_object.ui_act(action, href_list, state) // Call Topic() on the src_object.
|
||||
|
||||
if ((src_object && update) || map_update)
|
||||
if (src_object && update)
|
||||
SSnano.update_uis(src_object) // If we have a src_object and its Topic() told us to update.
|
||||
|
||||
/**
|
||||
@@ -502,17 +346,17 @@
|
||||
* Update the NanoUI. Only updates the contents/layout if update is true,
|
||||
* otherwise only updates the status.
|
||||
*
|
||||
* optional update bool If the UI should be updated (or just the status).
|
||||
* optional force bool If the UI should be forced to update.
|
||||
**/
|
||||
/datum/nanoui/process(update = 0)
|
||||
/datum/nanoui/process(force = 0)
|
||||
if (!src_object || !user) // If the object or user died (or something else), abort.
|
||||
close()
|
||||
return
|
||||
|
||||
if (status && (update || auto_update))
|
||||
if (status && (force || auto_update))
|
||||
update() // Update the UI if the status and update settings allow it.
|
||||
else
|
||||
update_status(push_update = 1) // Otherwise only update status.
|
||||
update_status(push = 1) // Otherwise only update status.
|
||||
|
||||
/**
|
||||
* private
|
||||
@@ -524,3 +368,38 @@
|
||||
**/
|
||||
/datum/nanoui/proc/update(force_open = 0)
|
||||
src_object.ui_interact(user, ui_key, src, force_open, master_ui, state)
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Set the status/visibility of the NanoUI.
|
||||
*
|
||||
* required state int The status to set (NANO_CLOSE/NANO_DISABLED/NANO_UPDATE/NANO_INTERACTIVE).
|
||||
* optional push bool Push an update to the UI (an update is always sent for NANO_DISABLED).
|
||||
**/
|
||||
/datum/nanoui/proc/set_status(state, push = 0)
|
||||
if (state != status) // Only update if status has changed.
|
||||
if (status == NANO_DISABLED)
|
||||
status = state
|
||||
if (push)
|
||||
update()
|
||||
else
|
||||
status = state
|
||||
if (push || status == 0) // Force an update if NANO_DISABLED.
|
||||
push_data(null, 1)
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Update the status/visibility of the NanoUI for its user.
|
||||
*
|
||||
* optional push bool Push an update to the UI (an update is always sent for NANO_DISABLED).
|
||||
**/
|
||||
/datum/nanoui/proc/update_status(push = 0)
|
||||
var/new_status = src_object.CanUseTopic(user, state)
|
||||
if(master_ui)
|
||||
new_status = min(new_status, master_ui.status)
|
||||
|
||||
set_status(new_status, push)
|
||||
if(new_status == NANO_CLOSE)
|
||||
close()
|
||||
@@ -81,7 +81,7 @@
|
||||
for (var/ui_key in open_uis[src_object_key])
|
||||
for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.nano_host()) // Check the UI is valid.
|
||||
ui.process(update = 1) // Update the UI.
|
||||
ui.process(force = 1) // Update the UI.
|
||||
update_count++ // Count each UI we update.
|
||||
return update_count
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
var/update_count = 0
|
||||
for (var/datum/nanoui/ui in user.open_uis)
|
||||
if ((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
|
||||
ui.process(update = 1) // Update the UI.
|
||||
ui.process(force = 1) // Update the UI.
|
||||
update_count++ // Count each UI we upadte.
|
||||
return update_count
|
||||
|
||||
|
||||
@@ -54,10 +54,6 @@
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/paper)
|
||||
assets.send(user)
|
||||
|
||||
if(istype(src, /obj/item/weapon/paper/talisman)) //Talismans cannot be read
|
||||
if(!iscultist(user) && !user.stat)
|
||||
user << "<span class='danger'>There are indecipherable images scrawled on the paper in what looks to be... <i>blood?</i></span>"
|
||||
return
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
if( !(ishuman(user) || isobserver(user) || issilicon(user)) )
|
||||
user << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[stars(info)]<HR>[stamps]</BODY></HTML>", "window=[name]")
|
||||
@@ -202,6 +198,7 @@
|
||||
|
||||
t = "<font face=\"[PEN_FONT]\" color=[P.colour]>[t]</font>"
|
||||
else // If it is a crayon, and he still tries to use these, make them empty!
|
||||
var/obj/item/toy/crayon/C = P
|
||||
t = replacetext(t, "\[*\]", "")
|
||||
t = replacetext(t, "\[hr\]", "")
|
||||
t = replacetext(t, "\[small\]", "")
|
||||
@@ -209,7 +206,7 @@
|
||||
t = replacetext(t, "\[list\]", "")
|
||||
t = replacetext(t, "\[/list\]", "")
|
||||
|
||||
t = "<font face=\"[CRAYON_FONT]\" color=[P.colour]><b>[t]</b></font>"
|
||||
t = "<font face=\"[CRAYON_FONT]\" color=[C.paint_color]><b>[t]</b></font>"
|
||||
|
||||
// t = replacetext(t, "#", "") // Junk converted to nothing!
|
||||
|
||||
|
||||
@@ -631,7 +631,7 @@
|
||||
/obj/machinery/power/apc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "apc.tmpl", name, 550, 550)
|
||||
ui = new(user, src, ui_key, "apc", name, 550, 550)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/apc/get_ui_data(mob/user)
|
||||
@@ -721,22 +721,8 @@
|
||||
|
||||
|
||||
/obj/machinery/power/apc/proc/can_use(mob/user, loud = 0) //used by attack_hand() and Topic()
|
||||
if (IsAdminGhost(user))
|
||||
if(IsAdminGhost(user))
|
||||
return 1
|
||||
if (user.stat)
|
||||
user << "<span class='warning'>You must be conscious to use [src]!</span>"
|
||||
return 0
|
||||
if(!user.client)
|
||||
return 0
|
||||
if(!user.IsAdvancedToolUser())
|
||||
user << "<span class='warning'>You don't have the dexterity to use [src]!</span>"
|
||||
return 0
|
||||
if(user.restrained())
|
||||
user << "<span class='warning'>You must have free hands to use [src].</span>"
|
||||
return 0
|
||||
if(user.lying)
|
||||
user << "<span class='warning'>You must stand to use [src]!</span>"
|
||||
return 0
|
||||
if(user.has_unlimited_silicon_privilege)
|
||||
var/mob/living/silicon/ai/AI = user
|
||||
var/mob/living/silicon/robot/robot = user
|
||||
@@ -754,98 +740,81 @@
|
||||
else
|
||||
if ((!in_range(src, user) || !istype(src.loc, /turf)))
|
||||
return 0
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
if (istype(H))
|
||||
if(H.getBrainLoss() >= 60)
|
||||
H.visible_message("[H] stares cluelessly at [src] and drools.")
|
||||
return 0
|
||||
else if(prob(H.getBrainLoss()))
|
||||
user << "<span class='danger'>You momentarily forget how to use [src].</span>"
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/power/apc/Topic(href, href_list)
|
||||
/obj/machinery/power/apc/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(!can_use(usr, 1))
|
||||
return
|
||||
|
||||
if (href_list["lock"])
|
||||
coverlocked = !coverlocked
|
||||
|
||||
else if (href_list["breaker"])
|
||||
toggle_breaker()
|
||||
|
||||
else if (href_list["cmode"])
|
||||
chargemode = !chargemode
|
||||
if(!chargemode)
|
||||
charging = 0
|
||||
update_icon()
|
||||
|
||||
else if (href_list["eqp"])
|
||||
var/val = text2num(href_list["eqp"])
|
||||
equipment = setsubsystem(val)
|
||||
update_icon()
|
||||
update()
|
||||
|
||||
else if (href_list["lgt"])
|
||||
var/val = text2num(href_list["lgt"])
|
||||
lighting = setsubsystem(val)
|
||||
update_icon()
|
||||
update()
|
||||
|
||||
else if (href_list["env"])
|
||||
var/val = text2num(href_list["env"])
|
||||
environ = setsubsystem(val)
|
||||
update_icon()
|
||||
update()
|
||||
|
||||
else if (href_list["overload"])
|
||||
if(usr.has_unlimited_silicon_privilege)
|
||||
src.overload_lighting()
|
||||
|
||||
else if (href_list["malfhack"])
|
||||
var/mob/living/silicon/ai/malfai = usr
|
||||
if(get_malf_status(malfai)==1)
|
||||
if (malfai.malfhacking)
|
||||
malfai << "You are already hacking an APC."
|
||||
return 1
|
||||
malfai << "Beginning override of APC systems. This takes some time, and you cannot perform other actions during the process."
|
||||
malfai.malfhack = src
|
||||
malfai.malfhacking = 1
|
||||
sleep(600)
|
||||
if(src)
|
||||
if (!src.aidisabled)
|
||||
malfai.malfhack = null
|
||||
malfai.malfhacking = 0
|
||||
locked = 1
|
||||
if (ticker.mode.config_tag == "malfunction")
|
||||
if (src.z == ZLEVEL_STATION) //if (is_type_in_list(get_area(src), the_station_areas))
|
||||
ticker.mode:apcs++
|
||||
if(usr:parent)
|
||||
src.malfai = usr:parent
|
||||
else
|
||||
src.malfai = usr
|
||||
malfai << "Hack complete. The APC is now under your exclusive control."
|
||||
update_icon()
|
||||
|
||||
else if (href_list["occupyapc"])
|
||||
if(get_malf_status(usr))
|
||||
malfoccupy(usr)
|
||||
|
||||
else if (href_list["deoccupyapc"])
|
||||
if(get_malf_status(usr))
|
||||
malfvacate()
|
||||
|
||||
else if (href_list["toggleaccess"])
|
||||
if(usr.has_unlimited_silicon_privilege)
|
||||
if(emagged || (stat & (BROKEN|MAINT)))
|
||||
usr << "The APC does not respond to the command."
|
||||
else
|
||||
locked = !locked
|
||||
switch(action)
|
||||
if("lock")
|
||||
coverlocked = !coverlocked
|
||||
if ("breaker")
|
||||
toggle_breaker()
|
||||
if("chargemode")
|
||||
chargemode = !chargemode
|
||||
if(!chargemode)
|
||||
charging = 0
|
||||
update_icon()
|
||||
|
||||
if("channel")
|
||||
if (params["eqp"])
|
||||
var/val = text2num(params["eqp"])
|
||||
equipment = setsubsystem(val)
|
||||
update_icon()
|
||||
update()
|
||||
else if (params["lgt"])
|
||||
var/val = text2num(params["lgt"])
|
||||
lighting = setsubsystem(val)
|
||||
update_icon()
|
||||
update()
|
||||
else if (params["env"])
|
||||
var/val = text2num(params["env"])
|
||||
environ = setsubsystem(val)
|
||||
update_icon()
|
||||
update()
|
||||
if("toggleaccess")
|
||||
if(usr.has_unlimited_silicon_privilege)
|
||||
if(emagged || (stat & (BROKEN|MAINT)))
|
||||
usr << "The APC does not respond to the command."
|
||||
else
|
||||
locked = !locked
|
||||
update_icon()
|
||||
if("overload")
|
||||
if(usr.has_unlimited_silicon_privilege)
|
||||
src.overload_lighting()
|
||||
if("hack")
|
||||
var/mob/living/silicon/ai/malfai = usr
|
||||
if(get_malf_status(malfai)==1)
|
||||
if (malfai.malfhacking)
|
||||
malfai << "You are already hacking an APC."
|
||||
return 1
|
||||
malfai << "Beginning override of APC systems. This takes some time, and you cannot perform other actions during the process."
|
||||
malfai.malfhack = src
|
||||
malfai.malfhacking = 1
|
||||
sleep(600)
|
||||
if(src)
|
||||
if (!src.aidisabled)
|
||||
malfai.malfhack = null
|
||||
malfai.malfhacking = 0
|
||||
locked = 1
|
||||
if (ticker.mode.config_tag == "malfunction")
|
||||
if (src.z == ZLEVEL_STATION) //if (is_type_in_list(get_area(src), the_station_areas))
|
||||
ticker.mode:apcs++
|
||||
if(usr:parent)
|
||||
src.malfai = usr:parent
|
||||
else
|
||||
src.malfai = usr
|
||||
malfai << "Hack complete. The APC is now under your exclusive control."
|
||||
update_icon()
|
||||
if("occupy")
|
||||
if(get_malf_status(usr))
|
||||
malfoccupy(usr)
|
||||
if("deoccupy")
|
||||
if(get_malf_status(usr))
|
||||
malfvacate()
|
||||
return 1
|
||||
|
||||
/obj/machinery/power/apc/proc/toggle_breaker()
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
return
|
||||
|
||||
/obj/singularity/narsie/proc/godsmack(atom/A)
|
||||
if(istype(A,/obj/))
|
||||
if(isobj(A))
|
||||
var/obj/O = A
|
||||
O.ex_act(1)
|
||||
if(O) qdel(O)
|
||||
|
||||
@@ -246,7 +246,7 @@
|
||||
|
||||
|
||||
/obj/singularity/proc/consume(atom/A)
|
||||
var/gain = A.singularity_act(current_size)
|
||||
var/gain = A.singularity_act(current_size, src)
|
||||
src.energy += gain
|
||||
if(istype(A, /obj/machinery/power/supermatter_shard) && !consumedSupermatter)
|
||||
desc = "[initial(desc)] It glows fiercely with inner fire."
|
||||
|
||||
@@ -327,7 +327,7 @@
|
||||
/obj/machinery/power/smes/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "smes.tmpl", name, 500, 400)
|
||||
ui = new(user, src, ui_key, "smes", name, 500, 455)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/smes/get_ui_data()
|
||||
@@ -350,65 +350,52 @@
|
||||
)
|
||||
return data
|
||||
|
||||
/obj/machinery/power/smes/Topic(href, href_list)
|
||||
/obj/machinery/power/smes/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if( href_list["input_attempt"] )
|
||||
input_attempt = text2num(href_list["input_attempt"])
|
||||
if(!input_attempt)
|
||||
inputting = 0
|
||||
log_smes(usr.ckey)
|
||||
update_icon()
|
||||
|
||||
else if( href_list["output_attempt"] )
|
||||
output_attempt = text2num(href_list["output_attempt"])
|
||||
if(!output_attempt)
|
||||
outputting = 0
|
||||
log_smes(usr.ckey)
|
||||
update_icon()
|
||||
|
||||
else if( href_list["set_input_level"] )
|
||||
switch(href_list["set_input_level"])
|
||||
if("max")
|
||||
input_level = input_level_max
|
||||
if("custom")
|
||||
var/custom = input(usr, "What rate would you like this SMES to attempt to charge at? Max is [input_level_max].") as null|num
|
||||
if(isnum(custom))
|
||||
href_list["set_input_level"] = custom
|
||||
.()
|
||||
if("plus")
|
||||
input_level += 10000
|
||||
if("minus")
|
||||
input_level -= 10000
|
||||
else
|
||||
var/n = text2num(href_list["set_input_level"])
|
||||
if(isnum(n))
|
||||
input_level = n
|
||||
|
||||
input_level = Clamp(input_level, 0, input_level_max)
|
||||
log_smes(usr.ckey)
|
||||
|
||||
else if(href_list["set_output_level"])
|
||||
switch(href_list["set_output_level"])
|
||||
if("max")
|
||||
output_level = output_level_max
|
||||
if("custom")
|
||||
var/custom = input(usr, "What rate would you like this SMES to attempt to output at? Max is [output_level_max].") as null|num
|
||||
if(isnum(custom))
|
||||
href_list["set_output_level"] = custom
|
||||
.()
|
||||
if("plus")
|
||||
output_level += 10000
|
||||
if("minus")
|
||||
output_level -= 10000
|
||||
else
|
||||
var/n = text2num(href_list["set_output_level"])
|
||||
if(isnum(n))
|
||||
output_level = n
|
||||
|
||||
output_level = Clamp(output_level, 0, output_level_max)
|
||||
log_smes(usr.ckey)
|
||||
switch(action)
|
||||
if("tryinput")
|
||||
input_attempt = !input_attempt
|
||||
log_smes(usr.ckey)
|
||||
update_icon()
|
||||
if("tryoutput")
|
||||
output_attempt = !output_attempt
|
||||
log_smes(usr.ckey)
|
||||
update_icon()
|
||||
if("input")
|
||||
switch(params["set"])
|
||||
if("custom")
|
||||
var/custom = input(usr, "What rate would you like this SMES to attempt to charge at? Max is [input_level_max].") as null|num
|
||||
if(custom)
|
||||
input_level = custom
|
||||
if("min")
|
||||
input_level = 0
|
||||
if("max")
|
||||
input_level = input_level_max
|
||||
if("plus")
|
||||
input_level += 10000
|
||||
if("minus")
|
||||
input_level -= 10000
|
||||
input_level = Clamp(input_level, 0, input_level_max)
|
||||
log_smes(usr.ckey)
|
||||
if("output")
|
||||
switch(params["set"])
|
||||
if("custom")
|
||||
var/custom = input(usr, "What rate would you like this SMES to attempt to output at? Max is [output_level_max].") as null|num
|
||||
if(custom)
|
||||
output_level = custom
|
||||
if("min")
|
||||
output_level = 0
|
||||
if("max")
|
||||
output_level = output_level_max
|
||||
if("plus")
|
||||
output_level += 10000
|
||||
if("minus")
|
||||
output_level -= 10000
|
||||
output_level = Clamp(output_level, 0, output_level_max)
|
||||
log_smes(usr.ckey)
|
||||
return 1
|
||||
|
||||
/obj/machinery/power/smes/proc/log_smes(user = "")
|
||||
investigate_log("input/output; [input_level>output_level?"<font color='green'>":"<font color='red'>"][input_level]/[output_level]</font> | Charge: [charge] | Output-mode: [output_attempt?"<font color='green'>on</font>":"<font color='red'>off</font>"] | Input-mode: [input_attempt?"<font color='green'>auto</font>":"<font color='red'>off</font>"] by [user]","singulo")
|
||||
|
||||
@@ -372,7 +372,7 @@
|
||||
/obj/machinery/power/solar_control/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "solar_control.tmpl", name, 490, 395)
|
||||
ui = new(user, src, ui_key, "solar_control", name, 515, 425)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/solar_control/get_ui_data()
|
||||
@@ -437,38 +437,39 @@
|
||||
targetdir = (targetdir + trackrate/abs(trackrate) + 360) % 360 //... do it
|
||||
nexttime += 36000/abs(trackrate) //reset the counter for the next 1°
|
||||
|
||||
/obj/machinery/power/solar_control/Topic(href, href_list)
|
||||
/obj/machinery/power/solar_control/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(href_list["rate_control"])
|
||||
if(href_list["cdir"])
|
||||
src.cdir = dd_range(0,359,(360+src.cdir+text2num(href_list["cdir"]))%360)
|
||||
src.targetdir = src.cdir
|
||||
if(track == 2) //manual update, so losing auto-tracking
|
||||
track = 0
|
||||
spawn(1)
|
||||
set_panels(cdir)
|
||||
if(href_list["tdir"])
|
||||
src.trackrate = dd_range(-7200,7200,src.trackrate+text2num(href_list["tdir"]))
|
||||
if(src.trackrate) nexttime = world.time + 36000/abs(trackrate)
|
||||
|
||||
if(href_list["track"])
|
||||
track = text2num(href_list["track"])
|
||||
if(track == 2)
|
||||
if(connected_tracker)
|
||||
switch(action)
|
||||
if("control")
|
||||
if(params["cdir"])
|
||||
src.cdir = dd_range(0,359,(360+src.cdir+text2num(params["cdir"]))%360)
|
||||
src.targetdir = src.cdir
|
||||
if(track == 2) //manual update, so losing auto-tracking
|
||||
track = 0
|
||||
spawn(1)
|
||||
set_panels(cdir)
|
||||
if(params["tdir"])
|
||||
src.trackrate = dd_range(-7200,7200,src.trackrate+text2num(params["tdir"]))
|
||||
if(src.trackrate) nexttime = world.time + 36000/abs(trackrate)
|
||||
if("tracking")
|
||||
track = text2num(params["mode"])
|
||||
if(track == 2)
|
||||
if(connected_tracker)
|
||||
connected_tracker.set_angle(SSsun.angle)
|
||||
set_panels(cdir)
|
||||
else if (track == 1) //begin manual tracking
|
||||
src.targetdir = src.cdir
|
||||
if(src.trackrate) nexttime = world.time + 36000/abs(trackrate)
|
||||
set_panels(targetdir)
|
||||
if("refresh")
|
||||
search_for_connected()
|
||||
if(connected_tracker && track == 2)
|
||||
connected_tracker.set_angle(SSsun.angle)
|
||||
set_panels(cdir)
|
||||
else if (track == 1) //begin manual tracking
|
||||
src.targetdir = src.cdir
|
||||
if(src.trackrate) nexttime = world.time + 36000/abs(trackrate)
|
||||
set_panels(targetdir)
|
||||
set_panels(cdir)
|
||||
return 1
|
||||
|
||||
if(href_list["search_connected"])
|
||||
search_for_connected()
|
||||
if(connected_tracker && track == 2)
|
||||
connected_tracker.set_angle(SSsun.angle)
|
||||
set_panels(cdir)
|
||||
|
||||
//rotates the panel to the passed angle
|
||||
/obj/machinery/power/solar_control/proc/set_panels(cdir)
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/obj/item/weapon/gun/medbeam
|
||||
name = "Medical Beamgun"
|
||||
desc = "Delivers medical nanites in a focused beam."
|
||||
icon = 'icons/obj/chronos.dmi'
|
||||
icon_state = "chronogun"
|
||||
item_state = "chronogun"
|
||||
w_class = 3.0
|
||||
|
||||
var/mob/living/current_target
|
||||
var/last_check = 0
|
||||
var/check_delay = 10 //Check los as often as possible, max resolution is SSobj tick though
|
||||
var/max_range = 8
|
||||
var/active = 0
|
||||
var/datum/beam/current_beam = null
|
||||
|
||||
heavy_weapon = 1
|
||||
|
||||
/obj/item/weapon/gun/medbeam/New()
|
||||
..()
|
||||
SSobj.processing |= src
|
||||
|
||||
/obj/item/weapon/gun/medbeam/dropped(mob/user)
|
||||
..()
|
||||
LoseTarget()
|
||||
|
||||
/obj/item/weapon/gun/medbeam/proc/LoseTarget()
|
||||
if(active)
|
||||
qdel(current_beam)
|
||||
active = 0
|
||||
on_beam_release(current_target)
|
||||
current_target = null
|
||||
|
||||
/obj/item/weapon/gun/medbeam/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override)
|
||||
add_fingerprint(user)
|
||||
|
||||
if(!isliving(target))
|
||||
return
|
||||
if(current_target)
|
||||
LoseTarget()
|
||||
|
||||
current_target = target
|
||||
active = 1
|
||||
current_beam = new(user,current_target,time=6000)
|
||||
spawn(0)
|
||||
current_beam.Start()
|
||||
|
||||
feedback_add_details("gun_fired","[src.type]")
|
||||
|
||||
/obj/item/weapon/gun/medbeam/afterattack(obj/target, mob/user, proximity)
|
||||
if(target.loc == loc || target == user)
|
||||
return
|
||||
|
||||
if(!current_target && isliving(target))
|
||||
current_target = target
|
||||
active = 1
|
||||
current_beam = new(user,current_target,time=6000)
|
||||
spawn(0)
|
||||
current_beam.Start()
|
||||
|
||||
/obj/item/weapon/gun/medbeam/process()
|
||||
var/mob/living/carbon/human/H = loc
|
||||
if(!istype(H))
|
||||
LoseTarget()
|
||||
return
|
||||
|
||||
if(!current_target)
|
||||
LoseTarget()
|
||||
return
|
||||
|
||||
if(world.time <= last_check+check_delay)
|
||||
return
|
||||
|
||||
last_check = world.time
|
||||
|
||||
if(get_dist(H,current_target)>max_range || !los_check(H,current_target))
|
||||
LoseTarget()
|
||||
H << "<span class='warning'>You lose control of the beam!</span>"
|
||||
return
|
||||
|
||||
if(current_target)
|
||||
on_beam_tick(current_target)
|
||||
|
||||
/obj/item/weapon/gun/medbeam/proc/los_check(mob/user,mob/target)
|
||||
var/turf/user_turf = user.loc
|
||||
if(!istype(user_turf))
|
||||
return 0
|
||||
var/obj/dummy = new(user_turf)
|
||||
dummy.pass_flags |= PASSTABLE & PASSGLASS & PASSGRILLE //Grille/Glass so it can be used through common windows
|
||||
for(var/turf/turf in getline(user_turf,target))
|
||||
if(turf.density)
|
||||
qdel(dummy)
|
||||
return 0
|
||||
for(var/atom/movable/AM in turf)
|
||||
if(!AM.CanPass(dummy,turf,1))
|
||||
qdel(dummy)
|
||||
return 0
|
||||
for(var/obj/effect/ebeam/medical/B in turf)// Don't cross the str-beams!
|
||||
if(B.owner != current_beam)
|
||||
explosion(B.loc,0,3,5,8)
|
||||
qdel(dummy)
|
||||
return 0
|
||||
qdel(dummy)
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/medbeam/proc/on_beam_hit(var/mob/living/target)
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/medbeam/proc/on_beam_tick(var/mob/living/target)
|
||||
target.adjustBruteLoss(-4)
|
||||
target.adjustFireLoss(-4)
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/medbeam/proc/on_beam_release(var/mob/living/target)
|
||||
return
|
||||
|
||||
/obj/effect/ebeam/medical
|
||||
name = "medical beam"
|
||||
@@ -1,356 +1,354 @@
|
||||
/obj/machinery/chem_dispenser
|
||||
name = "chem dispenser"
|
||||
desc = "Creates and dispenses chemicals."
|
||||
density = 1
|
||||
anchored = 1
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "dispenser"
|
||||
use_power = 1
|
||||
idle_power_usage = 40
|
||||
var/energy = 100
|
||||
var/max_energy = 100
|
||||
var/amount = 30
|
||||
var/recharged = 0
|
||||
var/recharge_delay = 5
|
||||
var/image/icon_beaker = null
|
||||
var/obj/item/weapon/reagent_containers/beaker = null
|
||||
var/list/dispensable_reagents = list(
|
||||
"hydrogen",
|
||||
"lithium",
|
||||
"carbon",
|
||||
"nitrogen",
|
||||
"oxygen",
|
||||
"fluorine",
|
||||
"sodium",
|
||||
"aluminium",
|
||||
"silicon",
|
||||
"phosphorus",
|
||||
"sulfur",
|
||||
"chlorine",
|
||||
"potassium",
|
||||
"iron",
|
||||
"copper",
|
||||
"mercury",
|
||||
"radium",
|
||||
"water",
|
||||
"ethanol",
|
||||
"sugar",
|
||||
"sacid",
|
||||
"welding_fuel",
|
||||
"silver",
|
||||
"iodine",
|
||||
"bromine",
|
||||
"stable_plasma"
|
||||
)
|
||||
|
||||
/obj/machinery/chem_dispenser/New()
|
||||
..()
|
||||
recharge()
|
||||
dispensable_reagents = sortList(dispensable_reagents)
|
||||
|
||||
/obj/machinery/chem_dispenser/power_change()
|
||||
if(powered())
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
stat |= NOPOWER
|
||||
|
||||
/obj/machinery/chem_dispenser/process()
|
||||
|
||||
if(recharged < 0)
|
||||
recharge()
|
||||
recharged = recharge_delay
|
||||
else
|
||||
recharged -= 1
|
||||
|
||||
/obj/machinery/chem_dispenser/proc/recharge()
|
||||
if(stat & (BROKEN|NOPOWER)) return
|
||||
var/addenergy = 1
|
||||
var/oldenergy = energy
|
||||
energy = min(energy + addenergy, max_energy)
|
||||
if(energy != oldenergy)
|
||||
use_power(2500)
|
||||
|
||||
/obj/machinery/chem_dispenser/ex_act(severity, target)
|
||||
if(severity < 3)
|
||||
..()
|
||||
|
||||
/obj/machinery/chem_dispenser/blob_act()
|
||||
if(prob(50))
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/chem_dispenser/interact(mob/user)
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/chem_dispenser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "chem_dispenser.tmpl", name, 500, 650)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/chem_dispenser/get_ui_data()
|
||||
var/data = list()
|
||||
data["amount"] = amount
|
||||
data["energy"] = energy
|
||||
data["maxEnergy"] = max_energy
|
||||
data["isBeakerLoaded"] = beaker ? 1 : 0
|
||||
|
||||
var beakerContents[0]
|
||||
var beakerCurrentVolume = 0
|
||||
if(beaker && beaker.reagents && beaker.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
||||
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list...
|
||||
beakerCurrentVolume += R.volume
|
||||
data["beakerContents"] = beakerContents
|
||||
|
||||
if (beaker)
|
||||
data["beakerCurrentVolume"] = beakerCurrentVolume
|
||||
data["beakerMaxVolume"] = beaker.volume
|
||||
data["beakerTransferAmounts"] = beaker.possible_transfer_amounts
|
||||
else
|
||||
data["beakerCurrentVolume"] = null
|
||||
data["beakerMaxVolume"] = null
|
||||
data["beakerTransferAmounts"] = null
|
||||
|
||||
var chemicals[0]
|
||||
for(var/re in dispensable_reagents)
|
||||
var/datum/reagent/temp = chemical_reagents_list[re]
|
||||
if(temp)
|
||||
chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("dispense" = temp.id)))) // list in a list because Byond merges the first list...
|
||||
data["chemicals"] = chemicals
|
||||
return data
|
||||
|
||||
/obj/machinery/chem_dispenser/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(href_list["amount"])
|
||||
amount = round(text2num(href_list["amount"]), 5) // round to nearest 5
|
||||
if (amount < 0) // Since the user can actually type the commands himself, some sanity checking
|
||||
amount = 0
|
||||
if (amount > 100)
|
||||
amount = 100
|
||||
|
||||
if(href_list["dispense"])
|
||||
if(beaker && dispensable_reagents.Find(href_list["dispense"]))
|
||||
var/datum/reagents/R = beaker.reagents
|
||||
var/space = R.maximum_volume - R.total_volume
|
||||
|
||||
R.add_reagent(href_list["dispense"], min(amount, energy * 10, space))
|
||||
energy = max(energy - min(amount, energy * 10, space) / 10, 0)
|
||||
|
||||
if(href_list["remove"])
|
||||
if(beaker)
|
||||
var/amount = text2num(href_list["remove"])
|
||||
if(isnum(amount) && (amount > 0) && (amount in beaker.possible_transfer_amounts))
|
||||
beaker.reagents.remove_all(amount)
|
||||
|
||||
if(href_list["ejectBeaker"])
|
||||
if(beaker)
|
||||
beaker.loc = loc
|
||||
beaker = null
|
||||
overlays.Cut()
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/machinery/chem_dispenser/attackby(obj/item/I, mob/user, params)
|
||||
if(default_unfasten_wrench(user, I))
|
||||
return
|
||||
|
||||
if(isrobot(user))
|
||||
return
|
||||
|
||||
var/obj/item/weapon/reagent_containers/B = I // Get a beaker from it?
|
||||
if(!istype(B))
|
||||
return // Not a beaker?
|
||||
|
||||
if(beaker)
|
||||
user << "<span class='warning'>A beaker is already loaded into the machine!</span>"
|
||||
return
|
||||
|
||||
if(!user.drop_item()) // Can't let go?
|
||||
return
|
||||
|
||||
beaker = B
|
||||
beaker.loc = src
|
||||
user << "<span class='notice'>You add the beaker to the machine.</span>"
|
||||
|
||||
if(!icon_beaker)
|
||||
icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position.
|
||||
icon_beaker.pixel_x = rand(-10,5)
|
||||
overlays += icon_beaker
|
||||
|
||||
/obj/machinery/chem_dispenser/attack_hand(mob/user)
|
||||
if (!user)
|
||||
return
|
||||
interact(user)
|
||||
|
||||
|
||||
/obj/machinery/chem_dispenser/constructable
|
||||
name = "portable chem dispenser"
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "minidispenser"
|
||||
energy = 10
|
||||
max_energy = 10
|
||||
amount = 5
|
||||
recharge_delay = 30
|
||||
dispensable_reagents = list()
|
||||
var/list/dispensable_reagent_tiers = list(
|
||||
list(
|
||||
"hydrogen",
|
||||
"oxygen",
|
||||
"silicon",
|
||||
"phosphorus",
|
||||
"sulfur",
|
||||
"carbon",
|
||||
"nitrogen",
|
||||
"water"
|
||||
),
|
||||
list(
|
||||
"lithium",
|
||||
"sugar",
|
||||
"sacid",
|
||||
"copper",
|
||||
"mercury",
|
||||
"sodium",
|
||||
"iodine",
|
||||
"bromine"
|
||||
),
|
||||
list(
|
||||
"ethanol",
|
||||
"chlorine",
|
||||
"potassium",
|
||||
"aluminium",
|
||||
"radium",
|
||||
"fluorine",
|
||||
"iron",
|
||||
"welding_fuel",
|
||||
"silver",
|
||||
"stable_plasma"
|
||||
),
|
||||
list(
|
||||
"oil",
|
||||
"ash",
|
||||
"acetone",
|
||||
"saltpetre",
|
||||
"ammonia",
|
||||
"diethylamine"
|
||||
)
|
||||
)
|
||||
|
||||
/obj/machinery/chem_dispenser/constructable/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/chem_dispenser(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/cell/high(null)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/chem_dispenser/constructable/RefreshParts()
|
||||
var/time = 0
|
||||
var/temp_energy = 0
|
||||
var/i
|
||||
for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
|
||||
temp_energy += M.rating
|
||||
temp_energy--
|
||||
max_energy = temp_energy * 5 //max energy = (bin1.rating + bin2.rating - 1) * 5, 5 on lowest 25 on highest
|
||||
for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
|
||||
time += C.rating
|
||||
for(var/obj/item/weapon/stock_parts/cell/P in component_parts)
|
||||
time += round(P.maxcharge, 10000) / 10000
|
||||
recharge_delay /= time/2 //delay between recharges, double the usual time on lowest 50% less than usual on highest
|
||||
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
|
||||
for(i=1, i<=M.rating, i++)
|
||||
dispensable_reagents |= dispensable_reagent_tiers[i]
|
||||
dispensable_reagents = sortList(dispensable_reagents)
|
||||
|
||||
/obj/machinery/chem_dispenser/constructable/attackby(var/obj/item/I, var/mob/user, params)
|
||||
..()
|
||||
if(default_deconstruction_screwdriver(user, "minidispenser-o", "minidispenser", I))
|
||||
return
|
||||
|
||||
if(exchange_parts(user, I))
|
||||
return
|
||||
|
||||
if(panel_open)
|
||||
if(istype(I, /obj/item/weapon/crowbar))
|
||||
if(beaker)
|
||||
beaker.loc = loc
|
||||
beaker = null
|
||||
default_deconstruction_crowbar(I)
|
||||
return 1
|
||||
|
||||
/obj/machinery/chem_dispenser/drinks
|
||||
name = "soda dispenser"
|
||||
anchored = 1
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "soda_dispenser"
|
||||
amount = 10
|
||||
dispensable_reagents = list(
|
||||
"water",
|
||||
"ice",
|
||||
"coffee",
|
||||
"cream",
|
||||
"tea",
|
||||
"icetea",
|
||||
"cola",
|
||||
"spacemountainwind",
|
||||
"dr_gibb",
|
||||
"space_up",
|
||||
"tonic",
|
||||
"sodawater",
|
||||
"lemon_lime",
|
||||
"sugar",
|
||||
"orangejuice",
|
||||
"limejuice",
|
||||
"tomatojuice"
|
||||
)
|
||||
|
||||
/obj/machinery/chem_dispenser/drinks/attackby(obj/item/I, mob/user)
|
||||
if(default_unfasten_wrench(user, I))
|
||||
return
|
||||
|
||||
if (istype(I, /obj/item/weapon/reagent_containers/glass) || \
|
||||
istype(I, /obj/item/weapon/reagent_containers/food/drinks/drinkingglass) || \
|
||||
istype(I, /obj/item/weapon/reagent_containers/food/drinks/shaker))
|
||||
|
||||
if (beaker)
|
||||
return 1
|
||||
else
|
||||
if(!user.drop_item())
|
||||
return 1
|
||||
src.beaker = I
|
||||
beaker.loc = src
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/chem_dispenser/drinks/beer
|
||||
name = "booze dispenser"
|
||||
anchored = 1
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "booze_dispenser"
|
||||
dispensable_reagents = list(
|
||||
"lemon_lime",
|
||||
"sugar",
|
||||
"orangejuice",
|
||||
"limejuice",
|
||||
"sodawater",
|
||||
"tonic",
|
||||
"beer",
|
||||
"kahlua",
|
||||
"whiskey",
|
||||
"wine",
|
||||
"vodka",
|
||||
"gin",
|
||||
"rum",
|
||||
"tequila",
|
||||
"vermouth",
|
||||
"cognac",
|
||||
"ale"
|
||||
)
|
||||
/obj/machinery/chem_dispenser
|
||||
name = "chem dispenser"
|
||||
desc = "Creates and dispenses chemicals."
|
||||
density = 1
|
||||
anchored = 1
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "dispenser"
|
||||
use_power = 1
|
||||
idle_power_usage = 40
|
||||
interact_offline = 1
|
||||
var/energy = 100
|
||||
var/max_energy = 100
|
||||
var/amount = 30
|
||||
var/recharged = 0
|
||||
var/recharge_delay = 5
|
||||
var/image/icon_beaker = null
|
||||
var/obj/item/weapon/reagent_containers/beaker = null
|
||||
var/list/dispensable_reagents = list(
|
||||
"hydrogen",
|
||||
"lithium",
|
||||
"carbon",
|
||||
"nitrogen",
|
||||
"oxygen",
|
||||
"fluorine",
|
||||
"sodium",
|
||||
"aluminium",
|
||||
"silicon",
|
||||
"phosphorus",
|
||||
"sulfur",
|
||||
"chlorine",
|
||||
"potassium",
|
||||
"iron",
|
||||
"copper",
|
||||
"mercury",
|
||||
"radium",
|
||||
"water",
|
||||
"ethanol",
|
||||
"sugar",
|
||||
"sacid",
|
||||
"welding_fuel",
|
||||
"silver",
|
||||
"iodine",
|
||||
"bromine",
|
||||
"stable_plasma"
|
||||
)
|
||||
|
||||
/obj/machinery/chem_dispenser/New()
|
||||
..()
|
||||
recharge()
|
||||
dispensable_reagents = sortList(dispensable_reagents)
|
||||
|
||||
/obj/machinery/chem_dispenser/power_change()
|
||||
if(powered())
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
stat |= NOPOWER
|
||||
|
||||
/obj/machinery/chem_dispenser/process()
|
||||
|
||||
if(recharged < 0)
|
||||
recharge()
|
||||
recharged = recharge_delay
|
||||
else
|
||||
recharged -= 1
|
||||
|
||||
/obj/machinery/chem_dispenser/proc/recharge()
|
||||
if(stat & (BROKEN|NOPOWER)) return
|
||||
var/addenergy = 1
|
||||
var/oldenergy = energy
|
||||
energy = min(energy + addenergy, max_energy)
|
||||
if(energy != oldenergy)
|
||||
use_power(2500)
|
||||
|
||||
/obj/machinery/chem_dispenser/ex_act(severity, target)
|
||||
if(severity < 3)
|
||||
..()
|
||||
|
||||
/obj/machinery/chem_dispenser/blob_act()
|
||||
if(prob(50))
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/chem_dispenser/interact(mob/user)
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/chem_dispenser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "chem_dispenser", name, 530, 700)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/chem_dispenser/get_ui_data()
|
||||
var/data = list()
|
||||
data["amount"] = amount
|
||||
data["energy"] = energy
|
||||
data["maxEnergy"] = max_energy
|
||||
data["isBeakerLoaded"] = beaker ? 1 : 0
|
||||
|
||||
var beakerContents[0]
|
||||
var beakerCurrentVolume = 0
|
||||
if(beaker && beaker.reagents && beaker.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
||||
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list...
|
||||
beakerCurrentVolume += R.volume
|
||||
data["beakerContents"] = beakerContents
|
||||
|
||||
if (beaker)
|
||||
data["beakerCurrentVolume"] = beakerCurrentVolume
|
||||
data["beakerMaxVolume"] = beaker.volume
|
||||
data["beakerTransferAmounts"] = beaker.possible_transfer_amounts
|
||||
else
|
||||
data["beakerCurrentVolume"] = null
|
||||
data["beakerMaxVolume"] = null
|
||||
data["beakerTransferAmounts"] = null
|
||||
|
||||
var chemicals[0]
|
||||
for(var/re in dispensable_reagents)
|
||||
var/datum/reagent/temp = chemical_reagents_list[re]
|
||||
if(temp)
|
||||
chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("reagent" = temp.id))))
|
||||
data["chemicals"] = chemicals
|
||||
return data
|
||||
|
||||
/obj/machinery/chem_dispenser/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("amount")
|
||||
amount = round(text2num(params["set"]), 5) // round to nearest 5
|
||||
if (amount < 0) // Since the user can actually type the commands himself, some sanity checking
|
||||
amount = 0
|
||||
if (amount > 100)
|
||||
amount = 100
|
||||
if("dispense")
|
||||
if(beaker && dispensable_reagents.Find(params["reagent"]))
|
||||
var/datum/reagents/R = beaker.reagents
|
||||
var/space = R.maximum_volume - R.total_volume
|
||||
|
||||
R.add_reagent(params["reagent"], min(amount, energy * 10, space))
|
||||
energy = max(energy - min(amount, energy * 10, space) / 10, 0)
|
||||
if("remove")
|
||||
if(beaker)
|
||||
var/amount = text2num(params["amount"])
|
||||
if(isnum(amount) && (amount > 0) && (amount in beaker.possible_transfer_amounts))
|
||||
beaker.reagents.remove_all(amount)
|
||||
if("eject")
|
||||
if(beaker)
|
||||
beaker.loc = loc
|
||||
beaker = null
|
||||
overlays.Cut()
|
||||
return 1
|
||||
|
||||
/obj/machinery/chem_dispenser/attackby(obj/item/I, mob/user, params)
|
||||
if(default_unfasten_wrench(user, I))
|
||||
return
|
||||
|
||||
if(isrobot(user))
|
||||
return
|
||||
|
||||
var/obj/item/weapon/reagent_containers/B = I // Get a beaker from it?
|
||||
if(!istype(B))
|
||||
return // Not a beaker?
|
||||
|
||||
if(beaker)
|
||||
user << "<span class='warning'>A beaker is already loaded into the machine!</span>"
|
||||
return
|
||||
|
||||
if(!user.drop_item()) // Can't let go?
|
||||
return
|
||||
|
||||
beaker = B
|
||||
beaker.loc = src
|
||||
user << "<span class='notice'>You add the beaker to the machine.</span>"
|
||||
|
||||
if(!icon_beaker)
|
||||
icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position.
|
||||
icon_beaker.pixel_x = rand(-10,5)
|
||||
overlays += icon_beaker
|
||||
|
||||
/obj/machinery/chem_dispenser/attack_hand(mob/user)
|
||||
if (!user)
|
||||
return
|
||||
interact(user)
|
||||
|
||||
|
||||
/obj/machinery/chem_dispenser/constructable
|
||||
name = "portable chem dispenser"
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "minidispenser"
|
||||
energy = 10
|
||||
max_energy = 10
|
||||
amount = 5
|
||||
recharge_delay = 30
|
||||
dispensable_reagents = list()
|
||||
var/list/dispensable_reagent_tiers = list(
|
||||
list(
|
||||
"hydrogen",
|
||||
"oxygen",
|
||||
"silicon",
|
||||
"phosphorus",
|
||||
"sulfur",
|
||||
"carbon",
|
||||
"nitrogen",
|
||||
"water"
|
||||
),
|
||||
list(
|
||||
"lithium",
|
||||
"sugar",
|
||||
"sacid",
|
||||
"copper",
|
||||
"mercury",
|
||||
"sodium",
|
||||
"iodine",
|
||||
"bromine"
|
||||
),
|
||||
list(
|
||||
"ethanol",
|
||||
"chlorine",
|
||||
"potassium",
|
||||
"aluminium",
|
||||
"radium",
|
||||
"fluorine",
|
||||
"iron",
|
||||
"welding_fuel",
|
||||
"silver",
|
||||
"stable_plasma"
|
||||
),
|
||||
list(
|
||||
"oil",
|
||||
"ash",
|
||||
"acetone",
|
||||
"saltpetre",
|
||||
"ammonia",
|
||||
"diethylamine"
|
||||
)
|
||||
)
|
||||
|
||||
/obj/machinery/chem_dispenser/constructable/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/chem_dispenser(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/cell/high(null)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/chem_dispenser/constructable/RefreshParts()
|
||||
var/time = 0
|
||||
var/temp_energy = 0
|
||||
var/i
|
||||
for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
|
||||
temp_energy += M.rating
|
||||
temp_energy--
|
||||
max_energy = temp_energy * 5 //max energy = (bin1.rating + bin2.rating - 1) * 5, 5 on lowest 25 on highest
|
||||
for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
|
||||
time += C.rating
|
||||
for(var/obj/item/weapon/stock_parts/cell/P in component_parts)
|
||||
time += round(P.maxcharge, 10000) / 10000
|
||||
recharge_delay /= time/2 //delay between recharges, double the usual time on lowest 50% less than usual on highest
|
||||
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
|
||||
for(i=1, i<=M.rating, i++)
|
||||
dispensable_reagents |= dispensable_reagent_tiers[i]
|
||||
dispensable_reagents = sortList(dispensable_reagents)
|
||||
|
||||
/obj/machinery/chem_dispenser/constructable/attackby(var/obj/item/I, var/mob/user, params)
|
||||
..()
|
||||
if(default_deconstruction_screwdriver(user, "minidispenser-o", "minidispenser", I))
|
||||
return
|
||||
|
||||
if(exchange_parts(user, I))
|
||||
return
|
||||
|
||||
if(panel_open)
|
||||
if(istype(I, /obj/item/weapon/crowbar))
|
||||
if(beaker)
|
||||
beaker.loc = loc
|
||||
beaker = null
|
||||
default_deconstruction_crowbar(I)
|
||||
return 1
|
||||
|
||||
/obj/machinery/chem_dispenser/drinks
|
||||
name = "soda dispenser"
|
||||
anchored = 1
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "soda_dispenser"
|
||||
amount = 10
|
||||
dispensable_reagents = list(
|
||||
"water",
|
||||
"ice",
|
||||
"coffee",
|
||||
"cream",
|
||||
"tea",
|
||||
"icetea",
|
||||
"cola",
|
||||
"spacemountainwind",
|
||||
"dr_gibb",
|
||||
"space_up",
|
||||
"tonic",
|
||||
"sodawater",
|
||||
"lemon_lime",
|
||||
"sugar",
|
||||
"orangejuice",
|
||||
"limejuice",
|
||||
"tomatojuice"
|
||||
)
|
||||
|
||||
/obj/machinery/chem_dispenser/drinks/attackby(obj/item/I, mob/user)
|
||||
if(default_unfasten_wrench(user, I))
|
||||
return
|
||||
|
||||
if (istype(I, /obj/item/weapon/reagent_containers/glass) || \
|
||||
istype(I, /obj/item/weapon/reagent_containers/food/drinks/drinkingglass) || \
|
||||
istype(I, /obj/item/weapon/reagent_containers/food/drinks/shaker))
|
||||
|
||||
if (beaker)
|
||||
return 1
|
||||
else
|
||||
if(!user.drop_item())
|
||||
return 1
|
||||
src.beaker = I
|
||||
beaker.loc = src
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/chem_dispenser/drinks/beer
|
||||
name = "booze dispenser"
|
||||
anchored = 1
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "booze_dispenser"
|
||||
dispensable_reagents = list(
|
||||
"lemon_lime",
|
||||
"sugar",
|
||||
"orangejuice",
|
||||
"limejuice",
|
||||
"sodawater",
|
||||
"tonic",
|
||||
"beer",
|
||||
"kahlua",
|
||||
"whiskey",
|
||||
"wine",
|
||||
"vodka",
|
||||
"gin",
|
||||
"rum",
|
||||
"tequila",
|
||||
"vermouth",
|
||||
"cognac",
|
||||
"ale"
|
||||
)
|
||||
|
||||
@@ -1,134 +1,126 @@
|
||||
/obj/machinery/chem_heater
|
||||
name = "chemical heater"
|
||||
density = 1
|
||||
anchored = 1
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "mixer0b"
|
||||
use_power = 1
|
||||
idle_power_usage = 40
|
||||
var/obj/item/weapon/reagent_containers/beaker = null
|
||||
var/desired_temp = 300
|
||||
var/heater_coefficient = 0.10
|
||||
var/on = FALSE
|
||||
|
||||
/obj/machinery/chem_heater/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/chem_heater(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/chem_heater/RefreshParts()
|
||||
heater_coefficient = 0.10
|
||||
for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts)
|
||||
heater_coefficient *= M.rating
|
||||
|
||||
/obj/machinery/chem_heater/process()
|
||||
..()
|
||||
if(stat & NOPOWER)
|
||||
return
|
||||
if(on)
|
||||
if(beaker)
|
||||
if(beaker.reagents.chem_temp > desired_temp)
|
||||
beaker.reagents.chem_temp += min(-1, (desired_temp - beaker.reagents.chem_temp) * heater_coefficient)
|
||||
if(beaker.reagents.chem_temp < desired_temp)
|
||||
beaker.reagents.chem_temp += max(1, (desired_temp - beaker.reagents.chem_temp) * heater_coefficient)
|
||||
beaker.reagents.chem_temp = round(beaker.reagents.chem_temp) //stops stuff like 456.12312312302
|
||||
|
||||
beaker.reagents.handle_reactions()
|
||||
|
||||
/obj/machinery/chem_heater/power_change()
|
||||
if(powered())
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
stat |= NOPOWER
|
||||
|
||||
/obj/machinery/chem_heater/attackby(obj/item/I, mob/user, params)
|
||||
if(isrobot(user))
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/glass))
|
||||
if(beaker)
|
||||
user << "<span class='warning'>A beaker is already loaded into the machine!</span>"
|
||||
return
|
||||
|
||||
if(user.drop_item())
|
||||
beaker = I
|
||||
I.loc = src
|
||||
user << "<span class='notice'>You add the beaker to the machine.</span>"
|
||||
icon_state = "mixer1b"
|
||||
|
||||
if(default_deconstruction_screwdriver(user, "mixer0b", "mixer0b", I))
|
||||
return
|
||||
|
||||
if(exchange_parts(user, I))
|
||||
return
|
||||
|
||||
if(panel_open)
|
||||
if(istype(I, /obj/item/weapon/crowbar))
|
||||
eject_beaker()
|
||||
default_deconstruction_crowbar(I)
|
||||
return 1
|
||||
|
||||
/obj/machinery/chem_heater/attack_hand(mob/user)
|
||||
if (!user)
|
||||
return
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/chem_heater/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(href_list["toggle_on"])
|
||||
on = !on
|
||||
|
||||
if(href_list["adjust_temperature"])
|
||||
var/val = href_list["adjust_temperature"]
|
||||
if(isnum(val))
|
||||
desired_temp = Clamp(desired_temp+val, 0, 1000)
|
||||
else if(val == "input")
|
||||
desired_temp = Clamp(input("Please input the target temperature", name) as num, 0, 1000)
|
||||
else
|
||||
return
|
||||
|
||||
if(href_list["eject_beaker"])
|
||||
eject_beaker()
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/machinery/chem_heater/interact(mob/user)
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "chem_heater.tmpl", name, 350, 400)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/chem_heater/get_ui_data()
|
||||
var/data = list()
|
||||
data["targetTemp"] = desired_temp
|
||||
data["isActive"] = on
|
||||
data["isBeakerLoaded"] = beaker ? 1 : 0
|
||||
|
||||
data["currentTemp"] = beaker ? beaker.reagents.chem_temp : null
|
||||
data["beakerCurrentVolume"] = beaker ? beaker.reagents.total_volume : null
|
||||
data["beakerMaxVolume"] = beaker ? beaker.volume : null
|
||||
|
||||
var beakerContents[0]
|
||||
if(beaker)
|
||||
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
||||
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list...
|
||||
data["beakerContents"] = beakerContents
|
||||
return data
|
||||
|
||||
/obj/machinery/chem_heater/proc/eject_beaker()
|
||||
if(beaker)
|
||||
beaker.loc = get_turf(src)
|
||||
beaker.reagents.handle_reactions()
|
||||
beaker = null
|
||||
/obj/machinery/chem_heater
|
||||
name = "chemical heater"
|
||||
density = 1
|
||||
anchored = 1
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "mixer0b"
|
||||
use_power = 1
|
||||
idle_power_usage = 40
|
||||
var/obj/item/weapon/reagent_containers/beaker = null
|
||||
var/desired_temp = 300
|
||||
var/heater_coefficient = 0.10
|
||||
var/on = FALSE
|
||||
|
||||
/obj/machinery/chem_heater/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/chem_heater(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/chem_heater/RefreshParts()
|
||||
heater_coefficient = 0.10
|
||||
for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts)
|
||||
heater_coefficient *= M.rating
|
||||
|
||||
/obj/machinery/chem_heater/process()
|
||||
..()
|
||||
if(stat & NOPOWER)
|
||||
return
|
||||
if(on)
|
||||
if(beaker)
|
||||
if(beaker.reagents.chem_temp > desired_temp)
|
||||
beaker.reagents.chem_temp += min(-1, (desired_temp - beaker.reagents.chem_temp) * heater_coefficient)
|
||||
if(beaker.reagents.chem_temp < desired_temp)
|
||||
beaker.reagents.chem_temp += max(1, (desired_temp - beaker.reagents.chem_temp) * heater_coefficient)
|
||||
beaker.reagents.chem_temp = round(beaker.reagents.chem_temp) //stops stuff like 456.12312312302
|
||||
|
||||
beaker.reagents.handle_reactions()
|
||||
|
||||
/obj/machinery/chem_heater/power_change()
|
||||
if(powered())
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
stat |= NOPOWER
|
||||
|
||||
/obj/machinery/chem_heater/attackby(obj/item/I, mob/user, params)
|
||||
if(isrobot(user))
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/glass))
|
||||
if(beaker)
|
||||
user << "<span class='warning'>A beaker is already loaded into the machine!</span>"
|
||||
return
|
||||
|
||||
if(user.drop_item())
|
||||
beaker = I
|
||||
I.loc = src
|
||||
user << "<span class='notice'>You add the beaker to the machine.</span>"
|
||||
icon_state = "mixer1b"
|
||||
|
||||
if(default_deconstruction_screwdriver(user, "mixer0b", "mixer0b", I))
|
||||
return
|
||||
|
||||
if(exchange_parts(user, I))
|
||||
return
|
||||
|
||||
if(panel_open)
|
||||
if(istype(I, /obj/item/weapon/crowbar))
|
||||
eject_beaker()
|
||||
default_deconstruction_crowbar(I)
|
||||
return 1
|
||||
|
||||
/obj/machinery/chem_heater/attack_hand(mob/user)
|
||||
if (!user)
|
||||
return
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/chem_heater/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
if("temperature")
|
||||
desired_temp = Clamp(input("Please input the target temperature", name) as num, 0, 1000)
|
||||
if("eject")
|
||||
eject_beaker()
|
||||
return 1
|
||||
|
||||
/obj/machinery/chem_heater/interact(mob/user)
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "chem_heater", name, 350, 400)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/chem_heater/get_ui_data()
|
||||
var/data = list()
|
||||
data["targetTemp"] = desired_temp
|
||||
data["isActive"] = on
|
||||
data["isBeakerLoaded"] = beaker ? 1 : 0
|
||||
|
||||
data["currentTemp"] = beaker ? beaker.reagents.chem_temp : null
|
||||
data["beakerCurrentVolume"] = beaker ? beaker.reagents.total_volume : null
|
||||
data["beakerMaxVolume"] = beaker ? beaker.volume : null
|
||||
|
||||
var beakerContents[0]
|
||||
if(beaker)
|
||||
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
||||
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list...
|
||||
data["beakerContents"] = beakerContents
|
||||
return data
|
||||
|
||||
/obj/machinery/chem_heater/proc/eject_beaker()
|
||||
if(beaker)
|
||||
beaker.loc = get_turf(src)
|
||||
beaker.reagents.handle_reactions()
|
||||
beaker = null
|
||||
icon_state = "mixer0b"
|
||||
@@ -183,13 +183,10 @@
|
||||
if (!M.stuttering) M.stuttering = 1
|
||||
M.stuttering += 4
|
||||
M.Dizzy(5)
|
||||
if(iscultist(M) && prob(5))
|
||||
M.say(pick("Av'te Nar'sie","Pa'lid Mors","INO INO ORA ANA","SAT ANA!","Daim'niodeis Arc'iai Le'eones","Egkau'haom'nai en Chaous","Ho Diak'nos tou Ap'iron","R'ge Na'sie","Diabo us Vo'iscum","Si gn'um Co'nu"))
|
||||
if(data >= 75 && prob(33)) // 30 units, 135 seconds
|
||||
if (!M.confused) M.confused = 1
|
||||
M.confused += 3
|
||||
if(iscultist(M) || (is_handofgod_cultist(M) && !is_handofgod_prophet(M)))
|
||||
ticker.mode.remove_cultist(M.mind)
|
||||
if((is_handofgod_cultist(M) && !is_handofgod_prophet(M)))
|
||||
ticker.mode.remove_hog_follower(M.mind)
|
||||
holder.remove_reagent(src.id, src.volume) // maybe this is a little too perfect and a max() cap on the statuses would be better??
|
||||
M.jitteriness = 0
|
||||
|
||||
@@ -175,56 +175,28 @@
|
||||
return..()
|
||||
var/mob/living/simple_animal/SM = M
|
||||
if(SM.sentience_type != sentience_type)
|
||||
user << "<span class='warning'>The potion won't work on [M].</span>"
|
||||
user << "<span class='warning'>The potion won't work on [SM].</span>"
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
user << "<span class='notice'>You offer the sentience potion to [M]...</span>"
|
||||
user << "<span class='notice'>You offer the sentience potion to [SM]...</span>"
|
||||
being_used = 1
|
||||
|
||||
var/list/candidates = get_candidates(ROLE_ALIEN, ALIEN_AFK_BRACKET)
|
||||
|
||||
shuffle(candidates)
|
||||
|
||||
var/time_passed = world.time
|
||||
var/list/consenting_candidates = list()
|
||||
|
||||
for(var/candidate in candidates)
|
||||
|
||||
if(candidate in not_interested)
|
||||
continue
|
||||
|
||||
spawn(0)
|
||||
switch(alert(candidate, "Would you like to play as [M.name]? Please choose quickly!","Confirmation","Yes","No"))
|
||||
if("Yes")
|
||||
if((world.time-time_passed)>=50 || !src)
|
||||
return
|
||||
consenting_candidates += candidate
|
||||
if("No")
|
||||
if(!src)
|
||||
return
|
||||
not_interested += candidate
|
||||
|
||||
sleep(50)
|
||||
|
||||
if(!src)
|
||||
return
|
||||
|
||||
listclearnulls(consenting_candidates) //some candidates might have left during sleep(50)
|
||||
|
||||
if(consenting_candidates.len)
|
||||
var/client/C = null
|
||||
C = pick(consenting_candidates)
|
||||
M.key = C.key
|
||||
M.languages |= HUMAN
|
||||
M.faction -= "neutral"
|
||||
M << "<span class='warning'>All at once it makes sense: you know what you are and who you are! Self awareness is yours!</span>"
|
||||
M << "<span class='userdanger'>You are grateful to be self aware and owe [user] a great debt. Serve [user], and assist them in completing their goals at any cost.</span>"
|
||||
user << "<span class='notice'>[M] accepts the potion and suddenly becomes attentive and aware. It worked!</span>"
|
||||
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [SM.name]?", ROLE_ALIEN, null, ROLE_ALIEN, 50)
|
||||
var/mob/dead/observer/theghost = null
|
||||
if(candidates.len)
|
||||
theghost = pick(candidates)
|
||||
SM.key = theghost.key
|
||||
SM.languages |= HUMAN
|
||||
SM.faction = user.faction
|
||||
SM.sentience_act()
|
||||
SM << "<span class='warning'>All at once it makes sense: you know what you are and who you are! Self awareness is yours!</span>"
|
||||
SM << "<span class='userdanger'>You are grateful to be self aware and owe [user] a great debt. Serve [user], and assist them in completing their goals at any cost.</span>"
|
||||
user << "<span class='notice'>[SM] accepts the potion and suddenly becomes attentive and aware. It worked!</span>"
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='notice'>[M] looks interested for a moment, but then looks back down. Maybe you should try again later.</span>"
|
||||
user << "<span class='notice'>[SM] looks interested for a moment, but then looks back down. Maybe you should try again later.</span>"
|
||||
being_used = 0
|
||||
..()
|
||||
|
||||
|
||||
@@ -55,6 +55,52 @@
|
||||
|
||||
-->
|
||||
<div class="commit sansserif">
|
||||
<h2 class="date">16 December 2015</h2>
|
||||
<h3 class="author">AnturK updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Medical Beam Gun now available for Nuclear Operatives and ERT Medics.</li>
|
||||
</ul>
|
||||
<h3 class="author">Joan updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Revenant Overload Lights reveal time lowered from 10 seconds to 8 seconds, shock damage increased from 18 to 20.</li>
|
||||
<li class="tweak">Revenant Blight reveal time lowered from 6 seconds to 5 seconds.</li>
|
||||
</ul>
|
||||
<h3 class="author">Kor updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Styptic once again works in patches.</li>
|
||||
<li class="rscadd">Nuke Op team leaders can now activate challenge mode if more than 50 players are online.</li>
|
||||
<li class="rscadd">Xenobio mobs will no longer spontaneously murder their friends if you give them sentience</li>
|
||||
</ul>
|
||||
<h3 class="author">The-Albinobigfoot updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">The Wishgranter now displays its faith in humans with curbed enthusiasm.</li>
|
||||
</ul>
|
||||
<h3 class="author">Tkdrg updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="experiment">Cult has been overhauled in an attempt to make the gamemode more fun.</li>
|
||||
<li class="rscdel">Cult onversion and stunpapers have been removed. So have most cult objectives.</li>
|
||||
<li class="tweak">The cult's single objective is now defend and feed a large construct shell in order to summon the Geometer.</li>
|
||||
<li class="tweak">The cult must sacrifice souls in order to acquire summoning orbs, which must be inserted inside said shell.</li>
|
||||
<li class="tweak">The large construct shell can be procured by using a summoning orb in hand, but it is vulnerable to attack.</li>
|
||||
<li class="tweak">Once enough orbs are inserted, the station will go Delta. After three minutes, the cult will have won.</li>
|
||||
<li class="rscadd">Cult communications now no longer damage you when done without a tome.</li>
|
||||
<li class="rscadd">Cultists now start with a sacrificial dagger, with bleeding effects and high throwing damage.</li>
|
||||
<li class="rscadd">Most existing runes were buffed, merged, or removed. A Immolate rune and a Time Stop rune were added. Experiment!</li>
|
||||
<li class="experiment">Each cultist now gets a random set of runes in their tomes. Pool together your knowledge in order to thrive.</li>
|
||||
</ul>
|
||||
<h3 class="author">neersighted updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="experiment">NanoUI 3.0</li>
|
||||
<li class="experiment">Completely rewrite NanoUI frontend; rework backend.</li>
|
||||
<li class="tweak">Re-design NanoUI interface to be much more attractive.</li>
|
||||
<li class="tweak">Reduce NanoUI LOC count/resource size.</li>
|
||||
<li class="tweak">Reduce NanoUI tickrate; make UIs update properly.</li>
|
||||
<li class="rscadd">Add chromeless NanoUI mode.</li>
|
||||
<li class="rscadd">NanoUI's chromeless mode can be toggled with the 'Fancy NanoUI' preference.</li>
|
||||
<li class="bugfix">Allow NanoUI to work on IE8-IE11, and Edge.</li>
|
||||
<li class="bugfix">Close holes that allow NanoUI href spoofing.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">15 December 2015</h2>
|
||||
<h3 class="author">Incoming5643 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
|
||||
@@ -2834,3 +2834,46 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
|
||||
oranges:
|
||||
- tweak: hulk no longer stuns
|
||||
- tweak: John Cena
|
||||
2015-12-16:
|
||||
AnturK:
|
||||
- rscadd: Medical Beam Gun now available for Nuclear Operatives and ERT Medics.
|
||||
Joan:
|
||||
- tweak: Revenant Overload Lights reveal time lowered from 10 seconds to 8 seconds,
|
||||
shock damage increased from 18 to 20.
|
||||
- tweak: Revenant Blight reveal time lowered from 6 seconds to 5 seconds.
|
||||
Kor:
|
||||
- rscadd: Styptic once again works in patches.
|
||||
- rscadd: Nuke Op team leaders can now activate challenge mode if more than 50 players
|
||||
are online.
|
||||
- rscadd: Xenobio mobs will no longer spontaneously murder their friends if you
|
||||
give them sentience
|
||||
The-Albinobigfoot:
|
||||
- bugfix: The Wishgranter now displays its faith in humans with curbed enthusiasm.
|
||||
Tkdrg:
|
||||
- experiment: Cult has been overhauled in an attempt to make the gamemode more fun.
|
||||
- rscdel: Cult onversion and stunpapers have been removed. So have most cult objectives.
|
||||
- tweak: The cult's single objective is now defend and feed a large construct shell
|
||||
in order to summon the Geometer.
|
||||
- tweak: The cult must sacrifice souls in order to acquire summoning orbs, which
|
||||
must be inserted inside said shell.
|
||||
- tweak: The large construct shell can be procured by using a summoning orb in hand,
|
||||
but it is vulnerable to attack.
|
||||
- tweak: Once enough orbs are inserted, the station will go Delta. After three minutes,
|
||||
the cult will have won.
|
||||
- rscadd: Cult communications now no longer damage you when done without a tome.
|
||||
- rscadd: Cultists now start with a sacrificial dagger, with bleeding effects and
|
||||
high throwing damage.
|
||||
- rscadd: Most existing runes were buffed, merged, or removed. A Immolate rune and
|
||||
a Time Stop rune were added. Experiment!
|
||||
- experiment: Each cultist now gets a random set of runes in their tomes. Pool together
|
||||
your knowledge in order to thrive.
|
||||
neersighted:
|
||||
- experiment: NanoUI 3.0
|
||||
- experiment: Completely rewrite NanoUI frontend; rework backend.
|
||||
- tweak: Re-design NanoUI interface to be much more attractive.
|
||||
- tweak: Reduce NanoUI LOC count/resource size.
|
||||
- tweak: Reduce NanoUI tickrate; make UIs update properly.
|
||||
- rscadd: Add chromeless NanoUI mode.
|
||||
- rscadd: NanoUI's chromeless mode can be toggled with the 'Fancy NanoUI' preference.
|
||||
- bugfix: Allow NanoUI to work on IE8-IE11, and Edge.
|
||||
- bugfix: Close holes that allow NanoUI href spoofing.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
author: Kor
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Styptic once again works in patches."
|
||||
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.4 KiB |