diff --git a/_maps/map_files/MetaStation/MetaStation.v41G.dmm b/_maps/map_files/MetaStation/MetaStation.v41G.dmm index 6b8a848d759..51cf098c9f5 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41G.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41G.dmm @@ -3570,7 +3570,7 @@ "bqx" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bqy" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel{dir = 4; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) "bqz" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/item/weapon/storage/fancy/donut_box,/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"bqA" = (/obj/structure/displaycase{pixel_y = 5},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) +"bqA" = (/obj/structure/displaycase/captain{pixel_y = 5},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bqB" = (/obj/structure/sign/map/left{desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-left-MS"; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bqC" = (/obj/structure/sign/map/right{desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-right-MS"; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bqD" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) @@ -6526,7 +6526,7 @@ "cvm" = (/obj/item/weapon/folder/white,/obj/item/weapon/stamp/rd{pixel_x = 3; pixel_y = -2},/obj/structure/table/reinforced,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) "cvn" = (/obj/machinery/computer/aifixer,/obj/structure/window/reinforced{dir = 4},/obj/machinery/requests_console{announcementConsole = 1; department = "Research Director's Desk"; departmentType = 5; name = "Research Director RC"; pixel_x = 0; pixel_y = 30},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) "cvo" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/crew_quarters/hor) -"cvp" = (/obj/structure/lamarr,/obj/machinery/light/small{dir = 1},/obj/structure/sign/biohazard{pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/hor) +"cvp" = (/obj/structure/displaycase/labcage,/obj/machinery/light/small{dir = 1},/obj/structure/sign/biohazard{pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/hor) "cvq" = (/obj/item/weapon/storage/secure/safe{pixel_x = 32; pixel_y = 0},/obj/machinery/ai_status_display{pixel_y = 32},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/crew_quarters/hor) "cvr" = (/obj/machinery/portable_atmospherics/scrubber/huge,/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/toxins/storage) "cvs" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/toxins/storage) diff --git a/_maps/map_files/MiniStation/MiniStation.dmm b/_maps/map_files/MiniStation/MiniStation.dmm index 702ab5ca619..1be7ce132eb 100644 --- a/_maps/map_files/MiniStation/MiniStation.dmm +++ b/_maps/map_files/MiniStation/MiniStation.dmm @@ -20,7 +20,7 @@ "at" = (/obj/machinery/computer/med_data,/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 2},/area/bridge) "au" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/PDAs{pixel_x = 4; pixel_y = 4},/obj/item/weapon/storage/box/ids,/turf/simulated/floor/plasteel,/area/bridge) "av" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/lockbox/medal,/turf/simulated/floor/plasteel,/area/bridge) -"aw" = (/obj/structure/lamarr,/turf/simulated/floor/plasteel,/area/bridge) +"aw" = (/obj/structure/displaycase/labcage,/turf/simulated/floor/plasteel,/area/bridge) "ax" = (/obj/structure/table/reinforced,/obj/machinery/recharger,/obj/item/weapon/hand_tele,/turf/simulated/floor/plasteel,/area/bridge) "ay" = (/turf/simulated/floor/plasteel,/area/bridge) "az" = (/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/bridge) @@ -29,7 +29,7 @@ "aC" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 1},/area/bridge) "aD" = (/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 1},/area/bridge) "aE" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/toolbox/emergency,/turf/simulated/floor/plasteel,/area/bridge) -"aF" = (/obj/structure/displaycase,/turf/simulated/floor/plasteel,/area/bridge) +"aF" = (/obj/structure/displaycase/captain,/turf/simulated/floor/plasteel,/area/bridge) "aG" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel,/area/bridge) "aH" = (/obj/machinery/atmospherics/components/unary/vent_pump{dir = 2; on = 1},/turf/simulated/floor/plasteel,/area/bridge) "aI" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/turf/simulated/floor/plasteel,/area/bridge) @@ -227,7 +227,7 @@ "es" = (/obj/structure/closet/crate/bin,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) "et" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/effect/spawner/structure/window/reinforced,/turf/simulated/floor/plating,/area/security/brig) "eu" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall,/area/space) -"ev" = (/obj/structure/rack,/obj/item/clothing/suit/space/hardsuit/mining,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/hardsuit/mining,/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/quartermaster/storage) +"ev" = (/obj/machinery/suit_storage_unit/mining,/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/quartermaster/storage) "ew" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/turf/simulated/floor/plasteel,/area/quartermaster/storage) "ex" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/floor/plasteel,/area/quartermaster/storage) "ey" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 6},/turf/simulated/floor/plasteel,/area/quartermaster/storage) @@ -1141,7 +1141,7 @@ "vW" = (/obj/structure/closet/wardrobe/black,/turf/simulated/floor/plasteel/shuttle,/area/shuttle/arrival) "vX" = (/obj/structure/closet/wardrobe/grey,/turf/simulated/floor/plasteel/shuttle,/area/shuttle/arrival) "vY" = (/turf/simulated/wall/shuttle{icon_state = "swall7"; dir = 2},/area/shuttle/arrival) -"vZ" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 8},/turf/simulated/floor/plating,/area/shuttle/arrival) +"vZ" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 8},/turf/simulated/floor/plating/airless,/area/shuttle/arrival) "wa" = (/turf/simulated/floor/plasteel/shuttle,/turf/simulated/wall/shuttle{icon_state = "swall_f9"; dir = 2},/area/shuttle/arrival) "wb" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/tank/internals/emergency_oxygen,/turf/simulated/floor/plating,/area/hallway/primary/central) "wc" = (/turf/simulated/wall,/area/crew_quarters/heads{name = "\improper Job Assignment"}) @@ -1165,7 +1165,7 @@ "wu" = (/turf/simulated/wall/shuttle{icon_state = "swall3"; dir = 2},/area/shuttle/arrival) "wv" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plasteel/shuttle,/area/shuttle/arrival) "ww" = (/obj/structure/stool/bed/chair{dir = 8},/obj/effect/landmark{name = "JoinLate"},/turf/simulated/floor/plasteel/shuttle,/area/shuttle/arrival) -"wx" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/shuttle/arrival) +"wx" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/shuttle/arrival) "wy" = (/obj/machinery/atmospherics/components/unary/vent_pump{dir = 8; external_pressure_bound = 0; frequency = 1441; id_tag = "o2_out"; initialize_directions = 1; internal_pressure_bound = 4000; on = 1; pressure_checks = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/engine/engineering) "wz" = (/obj/effect/landmark{name = "Observer-Start"},/turf/simulated/floor/plasteel/shuttle,/area/shuttle/arrival) "wA" = (/obj/machinery/power/apc{auto_name = 1; dir = 1; name = "_North APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/crew_quarters/heads{name = "\improper Job Assignment"}) @@ -1642,7 +1642,7 @@ "GP" = (/obj/machinery/telecomms/processor/preset_one,/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Mainframe Floor"; nitrogen = 100; oxygen = 0; temperature = 80},/area/tcommsat/computer) "GQ" = (/obj/machinery/telecomms/broadcaster/preset_left/ministation,/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Mainframe Floor"; nitrogen = 100; oxygen = 0; temperature = 80},/area/tcommsat/computer) "GR" = (/obj/docking_port/stationary{dheight = 9; dir = 2; dwidth = 5; height = 22; id = "syndicate_s"; name = "south of station"; turf_type = /turf/simulated/floor/plating/snow; width = 18},/turf/space,/area/space) - + (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/MiniStation/z2.dmm b/_maps/map_files/MiniStation/z2.dmm index e3dbfe6a3ef..ac11b27332e 100644 --- a/_maps/map_files/MiniStation/z2.dmm +++ b/_maps/map_files/MiniStation/z2.dmm @@ -112,11 +112,11 @@ "ch" = (/turf/indestructible/riveted,/area/start) "ci" = (/obj/effect/landmark/start,/turf/simulated/floor/plating,/area/start) "cj" = (/turf/indestructible/splashscreen,/area/start) -"ck" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 1},/turf/simulated/floor/plating,/area/shuttle/supply) +"ck" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 1},/turf/simulated/floor/plating/airless,/area/shuttle/supply) "cl" = (/turf/space,/turf/simulated/wall/shuttle{icon_state = "swall_f6"; dir = 2},/area/shuttle/supply) "cm" = (/obj/machinery/flasher{id = "tdomeflash"; name = "Thunderdome Flash"},/turf/simulated/floor/bluegrid,/area/tdome/arena_source) "cn" = (/turf/simulated/floor/bluegrid,/area/tdome/arena_source) -"co" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/shuttle/supply) +"co" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/shuttle/supply) "cp" = (/turf/simulated/wall/shuttle{icon_state = "swall13"; dir = 2},/area/shuttle/supply) "cq" = (/turf/space,/turf/simulated/wall/shuttle{icon_state = "swall_f10"; dir = 2},/area/shuttle/supply) "cr" = (/turf/indestructible/abductor{icon_state = "alien21"},/area/abductor_ship) @@ -277,8 +277,8 @@ "fq" = (/obj/machinery/door/airlock/shuttle{name = "Emergency Shuttle Airlock"},/obj/docking_port/mobile/emergency{dir = 8; dwidth = 12; height = 9; width = 21},/obj/docking_port/stationary{dir = 8; dwidth = 12; height = 9; id = "emergency_away"; name = "Centcom"; width = 21},/turf/simulated/floor/plating,/area/space) "fr" = (/turf/simulated/floor/plating,/area/centcom/evac) "fs" = (/turf/indestructible/fakeglass{color = "#008000"; dir = 4; icon_state = "fakewindows"},/area/wizard_station) -"ft" = (/turf/indestructible/fakeglass{color = "#008000"; dir = 8; icon_state = "fakewindows"},/area/wizard_station) -"fu" = (/turf/indestructible/riveted{tag = "icon-uranium2"; icon_state = "uranium2"},/area/wizard_station) +"ft" = (/turf/indestructible/fakeglass{color = "#008000"; dir = 8; icon_state = "fakewindows2"},/area/wizard_station) +"fu" = (/turf/indestructible/riveted/uranium,/area/wizard_station) "fv" = (/turf/indestructible/riveted,/area/syndicate_mothership) "fw" = (/turf/simulated/floor/plating,/turf/simulated/wall/shuttle{icon_state = "swall_f6"; dir = 2},/area/shuttle/transport) "fx" = (/turf/simulated/wall/shuttle{icon_state = "swall12"; dir = 2},/area/shuttle/transport) @@ -287,11 +287,11 @@ "fA" = (/turf/simulated/floor/plating,/turf/simulated/wall/shuttle{icon_state = "swall_f10"; dir = 2},/area/shuttle/transport) "fB" = (/turf/indestructible/fakeglass{icon_state = "fakewindows2"; dir = 1},/area/centcom/ferry) "fC" = (/turf/indestructible/fakeglass,/area/centcom/control) -"fD" = (/obj/item/weapon/shard{color = "#008000"},/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage5"; icon_state = "cultdamage5"},/area/wizard_station) +"fD" = (/obj/item/weapon/shard{color = "#008000"},/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage5"},/area/wizard_station) "fE" = (/turf/simulated/floor/plasteel/cult,/area/wizard_station) -"fF" = (/obj/machinery/computer/shuttle,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) -"fG" = (/turf/indestructible/riveted{tag = "icon-uranium10"; icon_state = "uranium10"},/area/wizard_station) -"fH" = (/turf/indestructible/riveted{tag = "icon-uranium5"; icon_state = "uranium5"},/area/wizard_station) +"fF" = (/turf/simulated/floor/plasteel/cult/airless,/area/wizard_station) +"fG" = (/obj/machinery/computer/shuttle,/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage"},/area/wizard_station) +"fH" = (/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage2"},/area/wizard_station) "fI" = (/turf/simulated/floor/plating/snow,/area/syndicate_mothership) "fJ" = (/obj/structure/flora/grass/brown,/turf/simulated/floor/plating/snow,/area/syndicate_mothership) "fK" = (/obj/structure/flora/grass/both,/turf/simulated/floor/plating/snow,/area/syndicate_mothership) @@ -308,10 +308,10 @@ "fV" = (/obj/structure/grille,/obj/structure/window/shuttle,/turf/simulated/floor/plating,/area/space) "fW" = (/obj/machinery/vending/wallmed{name = "Emergency NanoMed"; req_access_txt = "0"},/turf/simulated/wall/shuttle{icon_state = "swall3"; dir = 2},/area/space) "fX" = (/obj/structure/stool/bed/chair{dir = 8},/obj/item/device/radio/intercom{pixel_x = 25},/turf/simulated/floor/plasteel/shuttle{icon_state = "shuttlefloor3"},/area/space) -"fY" = (/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage2"; icon_state = "cultdamage2"},/area/wizard_station) -"fZ" = (/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage3"; icon_state = "cultdamage3"},/area/wizard_station) -"ga" = (/turf/indestructible/riveted{tag = "icon-uranium3"; icon_state = "uranium3"},/area/wizard_station) -"gb" = (/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel/cult,/area/wizard_station) +"fY" = (/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage3"},/area/wizard_station) +"fZ" = (/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel/cult/airless,/area/wizard_station) +"ga" = (/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage"},/area/wizard_station) +"gb" = (/obj/structure/showcase{desc = "A strange machine supposedly from another world. The Wizard Federation has been meddling with it for years."; icon_state = "processor"; name = "byond random number generator"},/turf/simulated/floor/plasteel/cult/airless,/area/wizard_station) "gc" = (/obj/structure/shuttle/engine/heater{tag = "icon-heater (WEST)"; icon_state = "heater"; dir = 8},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel/shuttle,/area/shuttle/transport) "gd" = (/turf/simulated/floor/plasteel/shuttle,/area/shuttle/transport) "ge" = (/obj/machinery/door/airlock/shuttle,/obj/docking_port/mobile{dir = 8; dwidth = 2; height = 12; id = "ferry"; name = "ferry shuttle"; travelDir = 180; width = 5},/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 12; id = "ferry_away"; name = "unknown"; turf_type = /turf/simulated/floor; width = 5},/turf/simulated/floor/plasteel/shuttle,/area/shuttle/transport) @@ -320,36 +320,36 @@ "gh" = (/turf/indestructible/fakeglass{icon_state = "fakewindows2"; dir = 6},/area/centcom/ferry) "gi" = (/turf/indestructible/fakeglass{icon_state = "fakewindows2"; dir = 1},/area/centcom/evac) "gj" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/turf/indestructible/riveted,/area/centcom/evac) -"gk" = (/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) -"gl" = (/obj/structure/showcase{desc = "A strange machine supposedly from another world. The Wizard Federation has been meddling with it for years."; icon_state = "processor"; name = "byond random number generator"},/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage7"; icon_state = "cultdamage7"},/area/wizard_station) -"gm" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/plasteel/cult,/area/wizard_station) -"gn" = (/obj/structure/showcase{desc = "A historical figure of great importance to the wizard federation. He spent his long life learning magic, stealing artifacts, and harassing idiots with swords. May he rest forever, Rodney."; icon = 'icons/mob/mob.dmi'; icon_state = "nim"; name = "wizard of yendor showcase"},/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage4"; icon_state = "cultdamage4"},/area/wizard_station) +"gk" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/plasteel/cult/airless,/area/wizard_station) +"gl" = (/obj/structure/showcase{desc = "A historical figure of great importance to the wizard federation. He spent his long life learning magic, stealing artifacts, and harassing idiots with swords. May he rest forever, Rodney."; icon = 'icons/mob/mob.dmi'; icon_state = "nim"; name = "wizard of yendor showcase"},/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage4"},/area/wizard_station) +"gm" = (/obj/effect/forcefield,/obj/structure/door_assembly/door_assembly_uranium{anchored = 1; name = "Bridge"},/turf/simulated/floor/plasteel/cult,/area/wizard_station) +"gn" = (/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood,/turf/simulated/floor/plasteel/cult{icon_state = "cultdamage6"},/area/wizard_station) "go" = (/obj/structure/flora/bush,/turf/simulated/floor/plating/snow,/area/syndicate_mothership) "gp" = (/turf/simulated/wall/shuttle{icon_state = "swallc1"; dir = 2},/area/shuttle/transport) "gq" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plasteel/shuttle,/area/shuttle/transport) "gr" = (/obj/machinery/door/airlock/centcom{name = "Transport Shuttle"; opacity = 1; req_access_txt = "101"},/turf/simulated/floor/plasteel,/area/centcom/ferry) "gs" = (/turf/indestructible/fakeglass,/area/centcom/evac) "gt" = (/turf/indestructible/fakeglass{color = "#008000"; dir = 6; icon_state = "fakewindows2"},/area/wizard_station) -"gu" = (/obj/effect/forcefield,/obj/structure/door_assembly{anchored = 1; icon_state = "door_as_uranium1"; name = "Bridge"},/turf/simulated/floor/plasteel/cult,/area/wizard_station) -"gv" = (/turf/indestructible/riveted{tag = "icon-uranium9"; icon_state = "uranium9"},/area/wizard_station) -"gw" = (/turf/indestructible/riveted{tag = "icon-uranium6"; icon_state = "uranium6"},/area/wizard_station) +"gu" = (/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel/cult{icon_state = "cultdamage"},/area/wizard_station) +"gv" = (/turf/simulated/floor/plasteel/cult{icon_state = "cultdamage7"},/area/wizard_station) +"gw" = (/obj/effect/forcefield,/turf/simulated/floor/plasteel/cult{icon_state = "cultdamage"},/area/wizard_station) "gx" = (/turf/simulated/floor/plating,/turf/simulated/wall/shuttle{icon_state = "swall_f5"; dir = 2},/area/shuttle/transport) "gy" = (/turf/simulated/floor/plating,/turf/simulated/wall/shuttle{icon_state = "swall_f9"; dir = 2},/area/shuttle/transport) "gz" = (/turf/simulated/floor/plasteel{icon_state = "greencorner"},/area/centcom/ferry) "gA" = (/turf/simulated/floor/plasteel{icon_state = "greencorner"; dir = 8},/area/centcom/evac) "gB" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel/shuttle{icon_state = "shuttlefloor3"},/area/space) -"gC" = (/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage6"; icon_state = "cultdamage6"},/area/wizard_station) -"gD" = (/turf/indestructible/riveted{tag = "icon-uranium1"; icon_state = "uranium1"},/area/wizard_station) -"gE" = (/obj/structure/mirror{pixel_x = 28},/turf/simulated/floor/plasteel/cult,/area/wizard_station) -"gF" = (/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) +"gC" = (/turf/simulated/floor/plasteel/airless,/area/wizard_station) +"gD" = (/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel/airless,/area/wizard_station) +"gE" = (/turf/simulated/floor/plasteel/cult{icon_state = "cultdamage"},/area/wizard_station) +"gF" = (/obj/effect/forcefield,/turf/simulated/floor/plasteel/cult{icon_state = "cultdamage5"},/area/wizard_station) "gG" = (/obj/machinery/door/airlock/shuttle{name = "Emergency Shuttle Airlock"},/turf/simulated/floor/plasteel/shuttle,/area/space) "gH" = (/turf/simulated/wall/shuttle{icon_state = "swall0"; dir = 2},/area/wizard_station) "gI" = (/turf/simulated/wall/shuttle{icon_state = "swall4"; dir = 2},/area/wizard_station) "gJ" = (/turf/indestructible/fakedoor{name = "Squad 4 Pod"},/area/wizard_station) "gK" = (/obj/effect/forcefield,/turf/simulated/floor/plasteel/cult,/area/wizard_station) "gL" = (/turf/simulated/floor/plasteel/cult,/turf/simulated/wall/shuttle{icon_state = "swall_f10"; dir = 2},/area/wizard_station) -"gM" = (/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage7"; icon_state = "cultdamage7"},/area/wizard_station) -"gN" = (/obj/effect/forcefield,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) +"gM" = (/obj/effect/forcefield,/turf/simulated/floor/plasteel/cult{icon_state = "cultdamage7"},/area/wizard_station) +"gN" = (/turf/simulated/floor/plasteel/cult{icon_state = "cultdamage5"},/area/wizard_station) "gO" = (/turf/simulated/floor/plating/snow,/turf/simulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"},/area/syndicate_mothership) "gP" = (/turf/indestructible/riveted,/area/centcom/holding) "gQ" = (/obj/structure/shuttle/engine/heater{tag = "icon-heater (WEST)"; icon_state = "heater"; dir = 8},/turf/simulated/floor/plating/airless,/area/wizard_station) @@ -360,11 +360,11 @@ "gV" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion (EAST)"; icon_state = "propulsion"; dir = 4},/turf/space/transit,/area/wizard_station) "gW" = (/obj/machinery/status_display,/turf/simulated/wall/shuttle{icon_state = "swall11"; dir = 2},/area/space) "gX" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plasteel/shuttle{icon_state = "shuttlefloor3"},/area/space) -"gY" = (/turf/simulated/floor/plasteel,/area/wizard_station) -"gZ" = (/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel,/area/wizard_station) +"gY" = (/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage2"},/area/wizard_station) +"gZ" = (/obj/structure/table/wood/poker,/obj/item/toy/cards/cardhand,/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage2"},/area/wizard_station) "ha" = (/obj/machinery/door/poddoor/preopen,/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plating/airless,/area/wizard_station) -"hb" = (/obj/effect/forcefield,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage5"; icon_state = "cultdamage5"},/area/wizard_station) -"hc" = (/obj/effect/forcefield,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage7"; icon_state = "cultdamage7"},/area/wizard_station) +"hb" = (/obj/machinery/vending/snack,/turf/simulated/floor/plasteel/cult{icon_state = "cultdamage"},/area/wizard_station) +"hc" = (/turf/simulated/floor/plasteel/cult{icon_state = "cultdamage3"},/area/wizard_station) "hd" = (/turf/simulated/wall/shuttle{icon_state = "wall3"},/area/shuttle/syndicate) "he" = (/turf/simulated/floor/plating/snow,/turf/simulated/wall/shuttle{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/syndicate) "hf" = (/obj/structure/grille,/obj/machinery/door/poddoor/shutters{id = "syndieshutters"; name = "blast shutters"},/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/plating,/area/shuttle/syndicate) @@ -375,9 +375,9 @@ "hk" = (/obj/machinery/door/airlock/glass_security{name = "Escape Shuttle Cell"; req_access_txt = "2"},/turf/simulated/floor/plasteel/shuttle,/area/space) "hl" = (/turf/simulated/wall/shuttle{icon_state = "swall12"; dir = 2},/area/wizard_station) "hm" = (/turf/simulated/floor/plasteel/cult,/turf/simulated/wall/shuttle{icon_state = "swall_f9"; dir = 2},/area/wizard_station) -"hn" = (/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage5"; icon_state = "cultdamage5"},/area/wizard_station) -"ho" = (/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage2"; icon_state = "cultdamage2"},/area/wizard_station) -"hp" = (/obj/structure/table/wood/poker,/obj/item/toy/cards/cardhand,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage2"; icon_state = "cultdamage2"},/area/wizard_station) +"hn" = (/obj/structure/door_assembly/door_assembly_uranium{anchored = 1; name = "Break Room"},/turf/simulated/floor/plasteel/cult,/area/wizard_station) +"ho" = (/obj/structure/table/wood,/obj/item/clothing/suit/wizrobe/magusblue,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/obj/structure/mirror/magic{pixel_y = 28},/turf/simulated/floor/plasteel/cult,/area/wizard_station) +"hp" = (/obj/structure/rack,/obj/item/clothing/head/helmet/space/hardsuit/wizard,/turf/simulated/floor/plasteel/cult/airless,/area/wizard_station) "hq" = (/obj/structure/table,/obj/machinery/microwave,/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "hr" = (/obj/structure/table,/obj/item/device/flashlight/lamp{pixel_x = 4; pixel_y = 1},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "hs" = (/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) @@ -401,7 +401,7 @@ "hK" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plasteel/shuttle/red,/area/space) "hL" = (/turf/simulated/floor/plasteel/shuttle/red,/area/space) "hM" = (/obj/machinery/vending/magivend,/turf/simulated/floor/plasteel/cult,/area/wizard_station) -"hN" = (/obj/machinery/vending/snack,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) +"hN" = (/obj/effect/forcefield,/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage"},/area/wizard_station) "hO" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "hP" = (/obj/structure/stool/bed/chair/comfy/black{dir = 1; icon_state = "comfychair"; name = "pilot's chair"; tag = "icon-comfychair (NORTH)"},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "hQ" = (/turf/simulated/floor/plating/snow,/turf/simulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 4},/area/syndicate_mothership) @@ -419,11 +419,11 @@ "ic" = (/obj/structure/table/reinforced,/obj/item/weapon/pen,/turf/simulated/floor/plasteel/black,/area/centcom/evac) "id" = (/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 6},/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/turf/simulated/floor/plasteel/shuttle{icon_state = "shuttlefloor3"},/area/space) "ie" = (/turf/simulated/wall/shuttle{icon_state = "swall1"; dir = 2},/area/space) -"if" = (/obj/structure/door_assembly{anchored = 1; icon_state = "door_as_uranium1"; name = "Break Room"},/turf/simulated/floor/plasteel/cult,/area/wizard_station) -"ig" = (/turf/indestructible/riveted{tag = "icon-uranium8"; icon_state = "uranium8"},/area/wizard_station) -"ih" = (/turf/indestructible/riveted{tag = "icon-uranium12"; icon_state = "uranium12"},/area/wizard_station) -"ii" = (/turf/indestructible/riveted{tag = "icon-uranium4"; icon_state = "uranium4"},/area/wizard_station) -"ij" = (/turf/indestructible/riveted{tag = "icon-uranium14"; icon_state = "uranium14"},/area/wizard_station) +"if" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage"},/area/wizard_station) +"ig" = (/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel/cult/airless,/area/wizard_station) +"ih" = (/obj/effect/decal/cleanable/blood/splatter,/obj/structure/rack{health = 9999},/obj/item/clothing/suit/space/hardsuit/wizard,/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage"},/area/wizard_station) +"ii" = (/obj/effect/decal/cleanable/blood/splatter,/mob/living/simple_animal/hostile/creature{name = "Experiment 35b"},/turf/simulated/floor/plasteel/cult/airless,/area/wizard_station) +"ij" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/remains/human,/turf/simulated/floor/plasteel/airless,/area/wizard_station) "ik" = (/obj/machinery/door/airlock{icon = 'icons/obj/doors/airlocks/station/uranium.dmi'; name = "Break Room"},/turf/simulated/floor/plasteel/cult,/area/wizard_station) "il" = (/obj/structure/table,/obj/item/stack/sheet/glass{amount = 10},/obj/item/device/multitool,/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "im" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; freerange = 1; frequency = 1213; name = "Syndicate Intercom"; pixel_y = -32; subspace_transmission = 1; syndie = 1},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) @@ -450,9 +450,9 @@ "iH" = (/obj/structure/table/wood,/obj/item/stack/medical/bruise_pack,/obj/item/stack/medical/ointment,/turf/simulated/floor/plasteel/cult,/area/wizard_station) "iI" = (/obj/structure/table/wood,/obj/item/weapon/retractor,/turf/simulated/floor/plasteel/cult,/area/wizard_station) "iJ" = (/obj/structure/table/wood,/obj/item/clothing/suit/wizrobe/magusred,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/turf/simulated/floor/plasteel/cult,/area/wizard_station) -"iK" = (/obj/structure/table/wood,/obj/item/clothing/suit/wizrobe/magusblue,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/turf/simulated/floor/plasteel/cult,/area/wizard_station) -"iL" = (/obj/structure/rack,/obj/item/clothing/head/helmet/space/hardsuit/wizard,/turf/simulated/floor/plasteel/cult,/area/wizard_station) -"iM" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) +"iK" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel/airless,/area/wizard_station) +"iL" = (/obj/effect/landmark/start{name = "wizard"},/turf/simulated/floor/plasteel/cult{icon_state = "cultdamage5"},/area/wizard_station) +"iM" = (/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel/cult/airless,/area/wizard_station) "iN" = (/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel/cult,/area/wizard_station) "iO" = (/turf/simulated/floor/plating/snow,/turf/simulated/wall/shuttle{icon_state = "diagonalWall3"},/area/shuttle/syndicate) "iP" = (/obj/machinery/door/window{name = "Cockpit"; req_access_txt = "150"},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) @@ -468,7 +468,7 @@ "iZ" = (/turf/indestructible/fakeglass{color = "#008000"; dir = 1; icon_state = "fakewindows"},/area/wizard_station) "ja" = (/obj/structure/cult/tome,/turf/simulated/floor/plasteel/cult,/area/wizard_station) "jb" = (/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) -"jc" = (/obj/effect/decal/cleanable/blood/splatter,/obj/structure/rack{health = 9999},/obj/item/clothing/suit/space/hardsuit/wizard,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) +"jc" = (/obj/effect/decal/cleanable/blood/splatter,/obj/structure/rack,/obj/item/weapon/staff,/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage"},/area/wizard_station) "jd" = (/turf/simulated/floor/plasteel/cult,/turf/simulated/wall/shuttle{icon_state = "swall_f6"; dir = 2},/area/wizard_station) "je" = (/turf/simulated/wall/shuttle{icon_state = "swall8"; dir = 2},/area/wizard_station) "jf" = (/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/weapon/crowbar/red,/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) @@ -488,9 +488,9 @@ "jt" = (/obj/structure/bookcase,/turf/simulated/floor/plasteel/cult,/area/wizard_station) "ju" = (/obj/structure/cult/talisman{desc = "A altar dedicated to the Wizard's Federation"},/obj/item/weapon/kitchen/knife/ritual,/turf/simulated/floor/plasteel/cult,/area/wizard_station) "jv" = (/obj/item/clothing/shoes/sandal/marisa,/obj/item/clothing/suit/wizrobe/marisa,/obj/item/clothing/head/wizard/marisa,/obj/item/weapon/staff/broom,/turf/simulated/floor/plasteel/cult,/area/wizard_station) -"jw" = (/obj/effect/decal/cleanable/blood/splatter,/mob/living/simple_animal/hostile/creature{name = "Experiment 35b"},/turf/simulated/floor/plasteel/cult,/area/wizard_station) -"jx" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/remains/human,/turf/simulated/floor/plasteel,/area/wizard_station) -"jy" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel,/area/wizard_station) +"jw" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/forcefield,/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage"},/area/wizard_station) +"jx" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage4"},/area/wizard_station) +"jy" = (/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage4"},/area/wizard_station) "jz" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "jA" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "jB" = (/turf/indestructible/fakeglass{icon_state = "fakewindows"; dir = 9},/area/syndicate_mothership) @@ -504,8 +504,8 @@ "jJ" = (/turf/simulated/floor/plasteel{icon_state = "green"; dir = 6},/area/tdome/tdomeobserve) "jK" = (/turf/indestructible/fakedoor{name = "Centcom Security"},/area/centcom/evac) "jL" = (/turf/indestructible/fakeglass{color = "#008000"},/area/wizard_station) -"jM" = (/obj/effect/landmark/start{name = "wizard"},/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage5"; icon_state = "cultdamage5"},/area/wizard_station) -"jN" = (/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel/cult,/area/wizard_station) +"jM" = (/obj/structure/door_assembly/door_assembly_uranium{anchored = 1; name = "Corridor A"},/turf/simulated/floor/plasteel/cult,/area/wizard_station) +"jN" = (/obj/effect/forcefield,/turf/simulated/floor/plasteel/cult{icon_state = "cultdamage3"},/area/wizard_station) "jO" = (/turf/simulated/floor/plasteel/cult,/turf/simulated/wall/shuttle{icon_state = "swall_f5"; dir = 2},/area/wizard_station) "jP" = (/turf/indestructible/fakedoor{name = "Squad 3 Pod"},/area/wizard_station) "jQ" = (/turf/indestructible/fakeglass{icon_state = "fakewindows2"; dir = 1},/area/syndicate_mothership) @@ -513,10 +513,10 @@ "jS" = (/obj/machinery/door/poddoor/shutters{id = "nukeop_ready"; name = "shuttle dock"},/turf/simulated/floor/plating,/area/syndicate_mothership) "jT" = (/obj/structure/stool/bed/chair/wood/wings{tag = "icon-wooden_chair_wings (NORTH)"; icon_state = "wooden_chair_wings"; dir = 1},/turf/simulated/floor/plasteel/cult,/area/wizard_station) "jU" = (/obj/structure/cult/pylon,/turf/simulated/floor/plasteel/cult,/area/wizard_station) -"jV" = (/obj/effect/decal/cleanable/blood/splatter,/obj/structure/rack,/obj/item/weapon/staff,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) -"jW" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/forcefield,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) -"jX" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage4"; icon_state = "cultdamage4"},/area/wizard_station) -"jY" = (/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage4"; icon_state = "cultdamage4"},/area/wizard_station) +"jV" = (/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage2"},/area/wizard_station) +"jW" = (/obj/effect/decal/remains/human,/turf/simulated/floor/plasteel/cult{icon_state = "cultdamage"},/area/wizard_station) +"jX" = (/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage5"},/area/wizard_station) +"jY" = (/obj/structure/table/wood,/obj/effect/landmark{name = "Teleport-Scroll"},/obj/item/weapon/dice/d20,/obj/item/weapon/dice,/turf/simulated/floor/carpet,/area/wizard_station) "jZ" = (/obj/machinery/suit_storage_unit/syndicate,/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "ka" = (/obj/effect/landmark{name = "Syndicate-Uplink"},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "kb" = (/turf/indestructible/fakeglass,/area/syndicate_mothership) @@ -525,8 +525,8 @@ "ke" = (/obj/machinery/computer/telecrystals/uplinker,/turf/simulated/floor/plasteel/cult{tag = "icon-podhatch (SOUTHWEST)"; icon_state = "podhatch"; dir = 10},/area/syndicate_mothership) "kf" = (/obj/structure/toilet{pixel_y = 8},/obj/structure/window/reinforced/tinted{dir = 8; icon_state = "twindow"},/obj/machinery/door/window{name = "Tactical Toilet"; opacity = 1},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "kg" = (/obj/structure/urinal{pixel_y = 28},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) -"kh" = (/obj/structure/door_assembly{anchored = 1; icon_state = "door_as_uranium1"; name = "Corridor A"},/turf/simulated/floor/plasteel/cult,/area/wizard_station) -"ki" = (/turf/indestructible/riveted{tag = "icon-uranium13"; icon_state = "uranium13"},/area/wizard_station) +"kh" = (/turf/simulated/floor/carpet,/area/wizard_station) +"ki" = (/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage6"},/area/wizard_station) "kj" = (/obj/machinery/door/airlock{icon = 'icons/obj/doors/airlocks/station/uranium.dmi'; name = "Corridor A"},/turf/simulated/floor/plasteel/cult,/area/wizard_station) "kk" = (/obj/structure/table,/obj/item/device/aicard,/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "kl" = (/obj/structure/stool,/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) @@ -543,7 +543,7 @@ "kw" = (/turf/simulated/floor/plasteel{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "kx" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 8},/turf/space/transit,/area/wizard_station) "ky" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/structure/mirror{pixel_x = 28},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) -"kz" = (/obj/effect/forcefield,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage3"; icon_state = "cultdamage3"},/area/wizard_station) +"kz" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/wiz,/turf/simulated/floor/carpet,/area/wizard_station) "kA" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'FOURTH WALL'."; name = "\improper FOURTH WALL"; pixel_x = -32},/turf/simulated/floor/plating/snow,/area/syndicate_mothership) "kB" = (/obj/structure/table,/obj/item/weapon/c4{pixel_x = 2; pixel_y = 1},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "kC" = (/turf/simulated/floor{dir = 8; icon_state = "wood"},/area/syndicate_mothership) @@ -554,8 +554,8 @@ "kH" = (/obj/item/weapon/soap/syndie,/obj/structure/mopbucket,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "kI" = (/turf/simulated/floor/plasteel{icon_state = "redbluefull"; dir = 2},/area/tdome/tdomeobserve) "kJ" = (/obj/structure/stool/bed/chair,/obj/effect/landmark{name = "tdomeobserve"},/turf/simulated/floor/plasteel{icon_state = "redbluefull"; dir = 2},/area/tdome/tdomeobserve) -"kK" = (/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage2"; icon_state = "cultdamage2"},/area/wizard_station) -"kL" = (/obj/effect/decal/remains/human,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) +"kK" = (/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage"},/area/wizard_station) +"kL" = (/turf/simulated/floor/plasteel/cult/airless{icon_state = "cultdamage7"},/area/wizard_station) "kM" = (/obj/machinery/door/window{dir = 4; name = "EVA Storage"; req_access_txt = "150"},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "kN" = (/obj/machinery/door/airlock/external{req_access_txt = "150"},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "kO" = (/obj/machinery/computer/telecrystals/boss,/turf/simulated/floor/plasteel/cult{tag = "icon-podhatch (NORTHEAST)"; icon_state = "podhatch"; dir = 5},/area/syndicate_mothership) @@ -565,7 +565,7 @@ "kS" = (/turf/indestructible/fakedoor{name = "Thunderdome"},/area/tdome/tdomeobserve) "kT" = (/obj/machinery/computer/security/telescreen,/turf/simulated/floor/plasteel{icon_state = "redbluefull"; dir = 2},/area/tdome/tdomeobserve) "kU" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "EVA Storage"; req_access_txt = "150"},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) -"kV" = (/obj/structure/table/wood,/obj/effect/landmark{name = "Teleport-Scroll"},/obj/item/weapon/dice/d20,/obj/item/weapon/dice,/turf/simulated/floor/carpet{dir = 9; icon_state = "carpetside"},/area/wizard_station) +"kV" = (/obj/structure/dresser,/obj/item/weapon/storage/backpack/satchel,/turf/simulated/floor/carpet,/area/wizard_station) "kW" = (/obj/structure/rack,/obj/item/clothing/suit/space/syndicate/black/red,/obj/item/clothing/head/helmet/space/syndicate/black/red,/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "kX" = (/turf/simulated/floor/plating/snow,/turf/simulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 10},/area/syndicate_mothership) "kY" = (/turf/simulated/floor/plasteel/black,/area/syndicate_mothership) @@ -578,11 +578,11 @@ "lf" = (/turf/simulated/floor/plating/snow,/turf/simulated/floor/plasteel/cult{tag = "icon-gravsnow_corner (NORTH)"; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 1},/area/syndicate_mothership) "lg" = (/turf/simulated/floor/plating/snow,/obj/structure/flora/bush,/turf/simulated/floor/plasteel/cult{tag = "icon-gravsnow_corner (NORTH)"; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 1},/area/syndicate_mothership) "lh" = (/turf/indestructible/fakeglass{icon_state = "fakewindows2"; dir = 8},/area/tdome/tdomeobserve) -"li" = (/turf/simulated/floor/carpet{dir = 5; icon_state = "carpetside"},/area/wizard_station) -"lj" = (/turf/simulated/floor/carpet{dir = 1; icon_state = "carpetside"},/area/wizard_station) -"lk" = (/obj/structure/dresser,/obj/item/weapon/storage/backpack/satchel,/turf/simulated/floor/carpet{dir = 10; icon_state = "carpetside"},/area/wizard_station) +"li" = (/obj/structure/table/wood,/obj/item/weapon/storage/bag/tray,/obj/item/weapon/reagent_containers/food/snacks/burger/spell,/turf/simulated/floor/carpet,/area/wizard_station) +"lj" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/wizard_station) +"lk" = (/obj/structure/window/reinforced{color = "#008000"; dir = 1},/turf/simulated/floor/plating/lava/airless,/area/wizard_station) "ll" = (/obj/effect/forcefield,/turf/space,/area/wizard_station) -"lm" = (/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage6"; icon_state = "cultdamage6"},/area/wizard_station) +"lm" = (/obj/structure/shuttle/engine/heater,/turf/simulated/floor/plating/lava/airless,/area/wizard_station) "ln" = (/turf/simulated/floor/plasteel/cult,/turf/simulated/wall/shuttle{dir = 2; icon_state = "swall_f10"; layer = 2},/area/wizard_station) "lo" = (/obj/machinery/recharge_station,/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "lp" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) @@ -597,10 +597,6 @@ "ly" = (/obj/structure/table,/obj/item/device/assembly/signaler,/obj/item/device/assembly/signaler,/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "lz" = (/obj/structure/stool,/turf/simulated/floor/plasteel/black,/area/syndicate_mothership) "lA" = (/turf/indestructible/riveted,/area/tdome/arena) -"lB" = (/turf/simulated/floor{dir = 8; icon_state = "carpetside"},/area/wizard_station) -"lC" = (/turf/simulated/floor{dir = 4; icon_state = "carpetside"},/area/wizard_station) -"lD" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/wiz,/turf/simulated/floor/plasteel{icon_state = "carpet"; dir = 2},/area/wizard_station) -"lE" = (/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plasteel/cult{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) "lF" = (/turf/simulated/wall/shuttle{icon_state = "swall1"; dir = 2},/area/wizard_station) "lG" = (/turf/simulated/wall/shuttle{icon_state = "swall3"; dir = 2},/area/wizard_station) "lH" = (/obj/machinery/door/window{dir = 4; name = "Infirmary"; req_access_txt = "150"},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) @@ -614,15 +610,12 @@ "lP" = (/obj/machinery/door/poddoor{id = "thunderdome"; name = "Thunderdome Blast Door"},/turf/simulated/floor/plating,/area/tdome/arena) "lQ" = (/obj/effect/landmark{name = "tdome1"},/turf/simulated/floor/plating,/area/tdome/tdome1) "lR" = (/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) -"lS" = (/obj/structure/table/wood,/obj/item/weapon/storage/bag/tray,/obj/item/weapon/reagent_containers/food/snacks/burger/spell,/turf/simulated/floor/carpet{dir = 6; icon_state = "carpetside"},/area/wizard_station) -"lU" = (/turf/simulated/floor{dir = 2; icon_state = "carpetside"},/area/wizard_station) "lV" = (/turf/indestructible/fakedoor{name = "Squad 2 Pod"},/area/wizard_station) "lW" = (/obj/machinery/sleeper{icon_state = "sleeper-open"; dir = 4},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "lX" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Infirmary"; req_access_txt = "150"},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "lY" = (/obj/machinery/door/window{dir = 8; name = "Tool Storage"; req_access_txt = "150"},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "lZ" = (/obj/machinery/recharger{pixel_y = 4},/obj/effect/landmark{name = "tdome2"},/turf/simulated/floor/plating,/area/tdome/tdome2) "ma" = (/obj/machinery/recharger{pixel_y = 4},/obj/effect/landmark{name = "tdome1"},/turf/simulated/floor/plating,/area/tdome/tdome1) -"mb" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/wizard_station) "mc" = (/turf/simulated/wall/shuttle,/area/wizard_station) "md" = (/obj/structure/table,/obj/item/weapon/reagent_containers/syringe/charcoal,/obj/item/weapon/reagent_containers/syringe/charcoal{pixel_y = 2},/obj/item/weapon/reagent_containers/syringe/charcoal{pixel_y = 4},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) "me" = (/obj/structure/table,/obj/item/weapon/gun/syringe{pixel_x = 1; pixel_y = 2},/turf/simulated/floor/plasteel/shuttle/red,/area/shuttle/syndicate) @@ -650,10 +643,7 @@ "mA" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"},/turf/simulated/floor/plating,/area/shuttle/syndicate) "mB" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"},/turf/simulated/floor/plating,/area/shuttle/syndicate) "mC" = (/obj/structure/shuttle/engine/propulsion,/turf/simulated/floor/plating,/area/shuttle/syndicate) -"mD" = (/turf/indestructible/riveted{tag = "icon-uranium11"; icon_state = "uranium11"},/area/wizard_station) -"mE" = (/obj/structure/window/reinforced{color = "#008000"; dir = 1},/turf/simulated/floor/plasteel/cult{tag = "icon-lava"; icon_state = "lava"},/area/wizard_station) "mF" = (/obj/machinery/door/poddoor{id = "thunderdomehea"; name = "Heavy Supply"},/turf/simulated/floor/plasteel/black,/area/tdome/arena) -"mG" = (/obj/structure/shuttle/engine/heater,/turf/simulated/floor/plasteel/cult{tag = "icon-lava"; icon_state = "lava"},/area/wizard_station) "mH" = (/obj/structure/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/sneakers/brown,/obj/item/clothing/suit/armor/vest,/obj/item/clothing/head/helmet/swat,/obj/item/weapon/gun/energy/laser,/turf/simulated/floor/plasteel/black,/area/tdome/arena) "mI" = (/turf/indestructible/fakeglass{icon_state = "fakewindows"; dir = 8},/area/tdome/tdomeadmin) "mJ" = (/turf/indestructible/fakeglass{icon_state = "fakewindows2"; dir = 8},/area/tdome/tdomeadmin) @@ -869,35 +859,35 @@ aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaMaM aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMeueueueueueueueueueueueueueueueueWeueueReXdJeYfaeZeQeXeReJfcfbfbfbfdeJeJeJejeTekeUfeeTekeUejfcfbfdeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMeufffffffffffffffffffffffffffgfjfhfkeueReXfldJdJdJfmeXeReJfneVeVfoeVeVeVeJejekekeUdVeTekekfqfpfrfpeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaevftfsfuaaaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMeufffwfxfxfyfxfxfxfzfxfxfAfffBfjfhfkeueReXdSdJdJdJdTfCeReJfneVeVfoeVeVeVeJejeTekeUdVeTekeUejfcfbfdeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaeBaafDfFfEfHfGaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIfIfIfJfIfIfIfLfKfIfIfIfLfIfIfIfIfIfIfLfIfIfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMeufNfMfPfOfQfQfQfQfQfQfQfyfSfRfjfhfkeueRfCdSdJdJdJdNdFeheJfTeVeVfoeVeVeVfUfVeTekeUfWeTekfXejaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaeBfifYfZfEgbgaaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfJfIfIfIfIfIfIfIfIfIfIfIfLfIfIfIfIfIfLfIfIfIfIfIfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMeufNgcgdgdgdgdgdgdgdgdgdgegffffhfhggeugheudLdJdJdJdJdJdJeVeVeVeVfoeVeVeVgifVeTekeUdVeTekeUfVaMaMgjeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaafuglgkgbgmgngaaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIgofIfIfIfIfIfJfIfIfKfLfIfIfLfIfIfLfKfIfLfIfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMeufNgpgqgqgqgqgqgqgqgqgqfyfSfgfjfhfhgrfhfhdJdJdJdJdJdJdJeVeVeVeVfoeVeVeVgsfVeTekeUdVeTekeUejaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaafHfGgtgugtgwgvaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfJfIfIfLfKfIfIfLfIfKfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMeuffgxfxfxfyfxfxfxfzfxfxgyfffBfjfhgzeugheufldJdJdJfmdFeheJgAeVeVfoeVeVeVeJejeTekeUgBeTekeUejfcfbfdeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaeBeBgDgCgFgEgDaaaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfJfIfIfIfIfIfKfIfLfKfIfLfIfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMeufffffffffffffffffffffffffffRfjfhfkeueReOdQdJdJdJdReOeReJfneVeVfoeVeVeVeJejekekekekekekekgGfpfrfpeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaagHgJgIgLgKgMfEgNeBaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIgOgOgOgOgOgOgOfIfIfIfIfIfIfIfLfIfIgofKfIfIfIfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgRgPgPeReXdQdJdJdJdReXeReJfcfdgTgSeJeVeVeJejgUdVdVgWeLekgXejfcfbfdeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaagVgQgZgYhagKfEgkhchbeBeBaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIhehdhfhfhfhfhfhdhgfIfIfIfIgofIgOfJgOfJfIfLfIfLfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPeRfCdQdJdJdJdRfCeReJhhhhhhhheJeVeVeJejeLeLhiejdVhkdVejaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaeBaagIhlhlhmgKfEhngkhbaahohpaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIhdhqhshrhuhthvhvhdhwfIfIgOfvfvhxhyfvfvgOhAhzgOfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPhBhBhDhChGhEhHhBhBeJhhhhhhhheJeVeVeJejeLeLhIejhJhLhKejaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaagNeBaaaaeBhFhMfZhNfZgNeBeBaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIhdhOhshshPhshshshdhwfIhQfvfvhShRhRhSfvfvfvfvfvfvfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPhUhThWhVhYhXhWhThUeJiahZicibeJeVeVeJejideLhiiehJhLhKejaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaagwigifiiihijihihigikiiihihijihigaaeBaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIhdilhshshsimhsinhdhwgohQfvioipipipipiriqitisiviuiwfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPhTixiyhVhYhXiyizhTeJhhiAiBhheJeVeVeJiDiCiEiEiEiEiEiCiFaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaagDiGfEfEiGgDiHiIfEfEfEiKiJgDiLiMgNiNeBeBaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIiOhdhdhdiPhdhdhdiQfIfIiRfviSipiTiTiUipipipiViWiWiWfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPiXhTiXhVhYhXiXhTiXeJhhhhhhhheJeVeVeJaMiDiYiYiYiYiYiFaMaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaiZjafEfEjagtiNiNfEfEfEfEjbiZjcjdhlhljeaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIhdjfhsjghdjhgOgOgOjifvipiTjjjkiTipjljmisjojnfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPjphThThVhYhXhThTjqeJhhhhhhjreJeVeVeJeJeJeJeJeJeJeJeJeJeJeJeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaajsjtfEgkfEkphngkfEjufEfEjvjsjwkujxjykvkxaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIhdjzhsjAhdjBjCjCjChyfvipiTjDjEiTipjljFfvfvfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPjHjGjGhVhYhXjIjIjJeJeJjKeJeJeJeVeVeVeVeVeVeVeVeVeVeVeVeVeVeVeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaajLjafEfZhnkDfZfEfEjMfEfEfEjLjNjOjejPgHaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIhehdhdhdhdhdjzhsjAhdjQjRjRjRjRjSipipipipipipjljFfvfvfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPhBhBhBhBhYhBhBhBhBhBaMaMaMaMeJeVeVeVeVeVeVeVeVeVeVeVeVeVeVeVeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaafujTfEfEjTfujUfEgkfZfEfEjUfujVjXjWjYaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIhdjZhshskahdjzhsjAhdkbkchxjChyfvkdiTiTiTipipjlkefvkgkffvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhBhYhBaMaMaMaMaMaMaMaMeJeJeJeJeJeJeJeJeJeJeJeJeJeJeJeJeJeJeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaafHigkhiiihkiihiggtkjgtiiihkiihigeBeBeBaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIhdjZhsklkkhdjzhsjAhdhdknkmhgkofvkqkskrksksipipipktkwkwkyfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhBhBhBhBhBhBhBhBhGhBhBhBhBhBhBhBhBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaahFgkaaeBaaeBkzgMhFaaaaeBaaaaaaaaeBaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvkAfIhdjZhshskBhdhshshshdhshshshdiRfvkCkEkCkCkFipipipfvkHkGkyfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhBkIkJkJkJkJkJkIkIkIkJkJkJkJkJkIhBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaeBeBaakKgkaallkLhFeBaahnaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIhdjZhshshskMhshshskNhshshshdhQfvfvjmkOkQkPfvkRfvfvfvfvfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMkSkIkIkIkTkIkIkIkIkIkIkIkTkIkIkIkSaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaeBeBaalrgklsaaaaaaeBaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIhdjZhshshskUhshshshjhshskWhdkXkXkofvfvfvfvfvkYkYkZlblalcfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhBkIkJkJkJkJkJkIkIkIkJkJkJkJkJkIhBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaeBgwigldiifGeBaaeBeBaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhehdhdhdhdhdhdlehshshdhdhdhdhdhdhglflflflgkofvkYkYkYkYkYkYfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhBhElhlhlhlhlhlhlhlhlhlhlhlhlhhChBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaaagDkVljligDkKjdhalnlmeBaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdlololpltlqhdhshshshdlulwlvlylxhdfIfJfIfIfKiskYkYkYkYkYlzfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlAlAlAlAlAlAlAlAmgmhmhmhmhmhmhmhmhmhmhmhmhmhmglAlAlAlAlAlAlAlAlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaaagtlBlDlCgtlElFgYlGfEgaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdhshshsklhslHhshshslIhsklhskllJhdfIgofLfJgofvlKlKlKlKlKlLfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlMlOlNlNlNlNlNlPnemhmhmhmhmhmhmhmhmhmhmhmhmhnglPlQlQlQlQlQlOlRlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaagMeBfulklUlSfufZlVgYlGaaeBaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdlWhshshshslXhshshslYhshshshshshdfIfIfIfLhQfvfvfvfvfvfvfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlMlOlNlZlNlZlNlPnemhmhmhmhmhmhmhmhmhmhmhmhmhnglPlQmalQmalQlOlRlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaeBgwkiiggtiikifGmcmblGaaeBaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdlWhshsmemdhdmfmimfhdmjmkhshshshdfIfLfIgohQfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlMlOlNlNmllNlNlPnemhmhmhmhmhnxnynxmhmhmhmhmhnglPlQlQmmlQlQlOlRlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaeBgDfEmnmomnfEgDaanqaaaaeBaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdhshsmphdhdhdmqmrhshdhdhdhshshshdfIfIfJfIhQfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlMlOlNlNlNlNlNlPnemhmhmhmhmhnxnDnxmhmhmhmhmhnglPlQlQlQlQlQlOlRlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaeBgknzfEfEfEfEfEnzaaaaaaaagkaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdmsmumthdfIhdmvmvmvhdfIhdmwmymxhdfIfIfIfIhQfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlMlOlNlZlNlZlNlPnemhmhmhmhmhmhmhmhmhmhmhmhmhnglPlQmalQmalQlOlRlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaeBeBgMfEfumzfEfEfEmzfuaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdmvmvmvhdfIiOmAmCmBiQfIhdmvmvmvhdfIfIfIfIhQfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlMlOlNlNlNlNlNlPnemhmhmhmhmhmhmhmhmhmhmhmhmhnglPlQlQlQlQlQlOlRlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaeBiiihmDmEmEmEmEmEgaaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIiOmAmCmBiQfIfIfIfIfIfIfIiOmAmCmBiQfIfIfIfIhQfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlAlAmFmFmFmFmFlAmgmhmhmhmhmhmhmhmhmhmhmhmhmhmglAmFmFmFmFmFlAlAlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaafHigmGmGmGiigvaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIhQfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAmHmHmHmHmHlAmImJmJmJmJmJmJmJmJmJmJmJmJmJmKlAmLmLmLmLmLlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaeBaafDfGfFfufuaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIfIfIfJfIfIfIfLfKfIfIfIfLfIfIfIfIfIfIfLfIfIfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMeufNfMfPfOfQfQfQfQfQfQfQfyfSfRfjfhfkeueRfCdSdJdJdJdNdFeheJfTeVeVfoeVeVeVfUfVeTekeUfWeTekfXejaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaeBfifHfYfFfZfuaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfJfIfIfIfIfIfIfIfIfIfIfIfLfIfIfIfIfIfLfIfIfIfIfIfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMeufNgcgdgdgdgdgdgdgdgdgdgegffffhfhggeugheudLdJdJdJdJdJdJeVeVeVeVfoeVeVeVgifVeTekeUdVeTekeUfVaMaMgjeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaafugbgafZgkglfuaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIgofIfIfIfIfIfJfIfIfKfLfIfIfLfIfIfLfKfIfLfIfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMeufNgpgqgqgqgqgqgqgqgqgqfyfSfgfjfhfhgrfhfhdJdJdJdJdJdJdJeVeVeVeVfoeVeVeVgsfVeTekeUdVeTekeUejaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaafufugtgmgtfufuaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfJfIfIfLfKfIfIfLfIfKfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMeuffgxfxfxfyfxfxfxfzfxfxgyfffBfjfhgzeugheufldJdJdJfmdFeheJgAeVeVfoeVeVeVeJejeTekeUgBeTekeUejfcfbfdeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaeBeBfugngufEfuaaaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfJfIfIfIfIfIfKfIfLfKfIfLfIfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMeufffffffffffffffffffffffffffRfjfhfkeueReOdQdJdJdJdReOeReJfneVeVfoeVeVeVeJejekekekekekekekgGfpfrfpeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaagHgJgIgLgKgvfEgweBaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIgOgOgOgOgOgOgOfIfIfIfIfIfIfIfLfIfIgofKfIfIfIfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgPgRgPgPeReXdQdJdJdJdReXeReJfcfdgTgSeJeVeVeJejgUdVdVgWeLekgXejfcfbfdeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaagVgQgDgChagKfEgEgMgFeBeBaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIhehdhfhfhfhfhfhdhgfIfIfIfIgofIgOfJgOfJfIfLfIfLfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPeRfCdQdJdJdJdRfCeReJhhhhhhhheJeVeVeJejeLeLhiejdVhkdVejaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaeBaagIhlhlhmgKfEgNgEgFaagYgZaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIhdhqhshrhuhthvhvhdhwfIfIgOfvfvhxhyfvfvgOhAhzgOfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPhBhBhDhChGhEhHhBhBeJhhhhhhhheJeVeVeJejeLeLhIejhJhLhKejaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaagweBaaaaeBhFhMhchbhcgweBeBaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIhdhOhshshPhshshshdhwfIhQfvfvhShRhRhSfvfvfvfvfvfvfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPhUhThWhVhYhXhWhThUeJiahZicibeJeVeVeJejideLhiiehJhLhKejaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaafufuhnfufufufufufuikfufufufufufuaaeBaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIhdilhshshsimhsinhdhwgohQfvioipipipipiriqitisiviuiwfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPhTixiyhVhYhXiyizhTeJhhiAiBhheJeVeVeJiDiCiEiEiEiEiEiCiFaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaafuiGfEfEiGfuiHiIfEfEfEhoiJfuhpifhNigeBeBaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIiOhdhdhdiPhdhdhdiQfIfIiRfviSipiTiTiUipipipiViWiWiWfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPiXhTiXhVhYhXiXhTiXeJhhhhhhhheJeVeVeJaMiDiYiYiYiYiYiFaMaMaMeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaiZjafEfEjaiZiNiNfEfEfEfEjbiZihjdhlhljeaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIhdjfhsjghdjhgOgOgOjifvipiTjjjkiTipjljmisjojnfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPjphThThVhYhXhThTjqeJhhhhhhjreJeVeVeJeJeJeJeJeJeJeJeJeJeJeJeJeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaajsjtfEgEfEkpgNgEfEjufEfEjvjsiikuijiKkvkxaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIhdjzhsjAhdjBjCjCjChyfvipiTjDjEiTipjljFfvfvfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPjHjGjGhVhYhXjIjIjJeJeJjKeJeJeJeVeVeVeVeVeVeVeVeVeVeVeVeVeVeVeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaajLjafEhcgNkDhcfEfEiLfEfEfEjLiMjOjejPgHaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIhehdhdhdhdhdjzhsjAhdjQjRjRjRjRjSipipipipipipjljFfvfvfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMgPhBhBhBhBhYhBhBhBhBhBaMaMaMaMeJeVeVeVeVeVeVeVeVeVeVeVeVeVeVeVeVeVeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaafujTfEfEjTfujUfEgEhcfEfEjUfujcjxjwjyaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIhdjZhshskahdjzhsjAhdkbkchxjChyfvkdiTiTiTipipjlkefvkgkffvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhBhYhBaMaMaMaMaMaMaMaMeJeJeJeJeJeJeJeJeJeJeJeJeJeJeJeJeJeJeJaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaafufujMfufufufufugtkjgtfufufufufueBeBeBaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIhdjZhsklkkhdjzhsjAhdhdknkmhgkofvkqkskrksksipipipktkwkwkyfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhBhBhBhBhBhBhBhBhGhBhBhBhBhBhBhBhBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaahFgaaaeBaaeBjNgvhFaaaaeBaaaaaaaaeBaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvkAfIhdjZhshskBhdhshshshdhshshshdiRfvkCkEkCkCkFipipipfvkHkGkyfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhBkIkJkJkJkJkJkIkIkIkJkJkJkJkJkIhBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaeBeBaajVgaaalljWhFeBaajXaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIhdjZhshshskMhshshskNhshshshdhQfvfvjmkOkQkPfvkRfvfvfvfvfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMkSkIkIkIkTkIkIkIkIkIkIkIkTkIkIkIkSaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaeBeBaalrgElsaaaaaaeBaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIhdjZhshshskUhshshshjhshskWhdkXkXkofvfvfvfvfvkYkYkZlblalcfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhBkIkJkJkJkJkJkIkIkIkJkJkJkJkJkIhBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaeBfufuldfufueBaaeBeBaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhehdhdhdhdhdhdlehshshdhdhdhdhdhdhglflflflgkofvkYkYkYkYkYkYfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhBhElhlhlhlhlhlhlhlhlhlhlhlhlhhChBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaaafujYkhkhfujVjdhalnkieBaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdlololpltlqhdhshshshdlulwlvlylxhdfIfJfIfIfKiskYkYkYkYkYlzfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlAlAlAlAlAlAlAlAmgmhmhmhmhmhmhmhmhmhmhmhmhmhmglAlAlAlAlAlAlAlAlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaaagtkhkzkhgtkKlFgClGfFfuaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdhshshsklhslHhshshslIhsklhskllJhdfIgofLfJgofvlKlKlKlKlKlLfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlMlOlNlNlNlNlNlPnemhmhmhmhmhmhmhmhmhmhmhmhmhnglPlQlQlQlQlQlOlRlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaakLeBfukVkhlifufYlVgClGaaeBaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdlWhshshshslXhshshslYhshshshshshdfIfIfIfLhQfvfvfvfvfvfvfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlMlOlNlZlNlZlNlPnemhmhmhmhmhmhmhmhmhmhmhmhmhnglPlQmalQmalQlOlRlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaeBfufufugtfufufumcljlGaaeBaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdlWhshsmemdhdmfmimfhdmjmkhshshshdfIfLfIgohQfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlMlOlNlNmllNlNlPnemhmhmhmhmhnxnynxmhmhmhmhmhnglPlQlQmmlQlQlOlRlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaeBfufEmnmomnfEfuaanqaaaaeBaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdhshsmphdhdhdmqmrhshdhdhdhshshshdfIfIfJfIhQfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlMlOlNlNlNlNlNlPnemhmhmhmhmhnxnDnxmhmhmhmhmhnglPlQlQlQlQlQlOlRlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaeBganzfEfEfEfEfEnzaaaaaaaagaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdmsmumthdfIhdmvmvmvhdfIhdmwmymxhdfIfIfIfIhQfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlMlOlNlZlNlZlNlPnemhmhmhmhmhmhmhmhmhmhmhmhmhnglPlQmalQmalQlOlRlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaeBeBkLfFfumzfEfEfEmzfuaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIhdmvmvmvhdfIiOmAmCmBiQfIhdmvmvmvhdfIfIfIfIhQfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlMlOlNlNlNlNlNlPnemhmhmhmhmhmhmhmhmhmhmhmhmhnglPlQlQlQlQlQlOlRlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaeBfufufulklklklklkfuaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIiOmAmCmBiQfIfIfIfIfIfIfIiOmAmCmBiQfIfIfIfIhQfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlAlAmFmFmFmFmFlAmgmhmhmhmhmhmhmhmhmhmhmhmhmhmglAmFmFmFmFmFlAlAlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaafufulmlmlmfufuaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIfIhQfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAmHmHmHmHmHlAmImJmJmJmJmJmJmJmJmJmJmJmJmJmKlAmLmLmLmLmLlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanUnUnUaaaaaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvfvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMlAlAlAlAlAlAlAmMmNmNmNmNmNmOmQmPmNmNmNmNmNmMlAlAlAlAlAlAlAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmRmMmMmMmSmMmTmTmTmTmTmMmSmMmMmMmRaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmRmRmUmRmRmRmRmVmXmWmRmRmRmRmUmRmRaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM diff --git a/_maps/map_files/TgStation/tgstation.2.1.3.dmm b/_maps/map_files/TgStation/tgstation.2.1.3.dmm index 03d97f3faec..1fd94197430 100644 --- a/_maps/map_files/TgStation/tgstation.2.1.3.dmm +++ b/_maps/map_files/TgStation/tgstation.2.1.3.dmm @@ -2819,7 +2819,7 @@ "bck" = (/obj/structure/table/wood,/obj/item/weapon/storage/fancy/donut_box,/obj/machinery/atmospherics/components/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "bcl" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "bcm" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/carpet,/area/crew_quarters/captain) -"bcn" = (/obj/structure/displaycase,/turf/simulated/floor/wood,/area/crew_quarters/captain) +"bcn" = (/obj/structure/displaycase/captain,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bco" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=Dorm"; location = "HOP2"},/turf/simulated/floor/plasteel,/area/hallway/primary/central) "bcp" = (/obj/structure/sign/directions/evac{dir = 4; icon_state = "direction_evac"; pixel_x = 32; pixel_y = 28; tag = "icon-direction_evac (EAST)"},/obj/structure/sign/directions/security{dir = 1; icon_state = "direction_sec"; pixel_x = 32; pixel_y = 36; tag = "icon-direction_sec (NORTH)"},/turf/simulated/floor/plasteel,/area/hallway/primary/central) "bcq" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/hallway/primary/starboard) @@ -3970,7 +3970,7 @@ "byr" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/hor) "bys" = (/obj/structure/rack,/obj/item/device/aicard,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warnwhite"},/area/crew_quarters/hor) "byt" = (/turf/simulated/wall/r_wall,/area/crew_quarters/hor) -"byu" = (/obj/structure/lamarr,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"},/area/crew_quarters/hor) +"byu" = (/obj/structure/displaycase/labcage,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"},/area/crew_quarters/hor) "byv" = (/obj/structure/grille,/obj/machinery/door/poddoor/preopen{id = "telelab"; name = "test chamber blast door"},/obj/structure/window/reinforced/fulltile,/obj/machinery/door/firedoor/heavy,/turf/simulated/floor/engine,/area/toxins/explab) "byw" = (/obj/machinery/door/poddoor/preopen{id = "telelab"; name = "test chamber blast door"},/obj/machinery/door/firedoor/heavy,/turf/simulated/floor/engine,/area/toxins/explab) "byx" = (/obj/machinery/atmospherics/components/unary/heat_reservoir/heater{dir = 8},/turf/simulated/floor/plating,/area/maintenance/asmaint2) @@ -6581,7 +6581,7 @@ "cwC" = (/obj/machinery/power/port_gen/pacman,/obj/structure/cable,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/ai_monitored/storage/secure) "cwD" = (/obj/structure/table,/obj/item/stack/sheet/mineral/plasma{layer = 2.9},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/ai_monitored/storage/secure) "cwE" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/plating,/area/ai_monitored/storage/secure) - + (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index b03c73b01c0..9c9d1da8b9d 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -23,12 +23,13 @@ #define FRIDAY_13TH "Friday the 13th" //Human Overlays Indexes///////// -#define SPECIES_LAYER 26 // mutantrace colors... these are on a seperate layer in order to prvent +#define SPECIES_LAYER 27 // mutantrace colors... these are on a seperate layer in order to prvent +#define MUTATIONS_LAYER 26 //mutations. Hulk, Tk headglows, etc #define BODY_BEHIND_LAYER 25 #define BODY_LAYER 24 //underwear, undershirts, socks, eyes, lips(makeup) #define BODY_ADJ_LAYER 23 -#define MUTATIONS_LAYER 22 //Tk headglows etc. -#define AUGMENTS_LAYER 21 +#define AUGMENTS_LAYER 22 +#define FRONT_MUTATIONS_LAYER 21 //mutations that should appear above body and augments layer (e.g. laser eyes) #define DAMAGE_LAYER 20 //damage indicators (cuts and burns) #define UNIFORM_LAYER 19 #define ID_LAYER 18 @@ -49,7 +50,7 @@ #define R_HAND_LAYER 3 //Having the two hands seperate seems rather silly, merge them together? It'll allow for code to be reused on mobs with arbitarily many hands #define BODY_FRONT_LAYER 2 #define FIRE_LAYER 1 //If you're on fire -#define TOTAL_LAYERS 26 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_; +#define TOTAL_LAYERS 27 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_; //Human Overlay Index Shortcuts for alternate_worn_layer, layers //Because I *KNOW* somebody will think layer+1 means "above" diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 87a605ceb25..1d7c5cfdd24 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -380,7 +380,7 @@ return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y) -/proc/pollCandidates(var/Question, var/jobbanType, var/datum/game_mode/gametypeCheck, var/be_special_flag = 0) +/proc/pollCandidates(var/Question, var/jobbanType, var/datum/game_mode/gametypeCheck, var/be_special_flag = 0, var/poll_time = 300) var/list/mob/dead/observer/candidates = list() var/time_passed = world.time if (!Question) @@ -400,10 +400,10 @@ continue spawn(0) G << 'sound/misc/notice2.ogg' //Alerting them to their consideration - switch(alert(G,Question,"Please answer in 30 seconds!","Yes","No")) + switch(alert(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No")) if("Yes") G << "Choice registered: Yes." - if((world.time-time_passed)>300)//If more than 30 game seconds passed. + if((world.time-time_passed)>poll_time)//If more than 30 game seconds passed. G << "Sorry, you were too late for the consideration!" G << 'sound/machines/buzz-sigh.ogg' return @@ -413,7 +413,7 @@ return else return - sleep(300) + sleep(poll_time) //Check all our candidates, to make sure they didn't log off during the 30 second wait period. for(var/mob/dead/observer/G in candidates) @@ -429,7 +429,7 @@ var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned. G_found.client.prefs.copy_to(new_character) - ready_dna(new_character) + new_character.dna.update_dna_identity() new_character.key = G_found.key - return new_character \ No newline at end of file + return new_character diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index aa1082cdf82..25454eefcff 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -14,4 +14,5 @@ var/global/list/chemical_reagents_list //list of all /datum/reagent datums in var/global/list/surgeries_list = list() //list of all surgeries by name, associated with their path. var/global/list/table_recipes = list() //list of all table craft recipes var/global/list/rcd_list = list() //list of Rapid Construction Devices. -var/global/list/apcs_list = list() //list of all Area Power Controller machines, seperate from machines for powernet speeeeeeed. \ No newline at end of file +var/global/list/apcs_list = list() //list of all Area Power Controller machines, seperate from machines for powernet speeeeeeed. +var/global/list/tracking_implants = list() //list of all tracking implants to work out what treks everyone are on. Sadly not on lavaworld not implemented... \ No newline at end of file diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm index ccd6ccaf7f2..b3b0d91fbd1 100644 --- a/code/_onclick/drag_drop.dm +++ b/code/_onclick/drag_drop.dm @@ -5,8 +5,10 @@ recieving object instead, so that's the default action. This allows you to drag almost anything into a trash can. */ -/atom/MouseDrop(atom/over) +/atom/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) if(!usr || !over) return + if(over == src) + return usr.client.Click(src, src_location, src_control, params) if(!Adjacent(usr) || !over.Adjacent(usr)) return // should stop you from dragging through windows over.MouseDrop_T(src,usr) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index eb5b6b5db80..e843e61a035 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -83,6 +83,8 @@ var/datum/subsystem/events/SSevent for(var/datum/round_event_control/E in control) if(E.occurrences >= E.max_occurrences) continue if(E.earliest_start >= world.time) continue + if(ticker.mode.config_tag in E.gamemode_blacklist) continue + if(E.gamemode_whitelist && !(ticker.mode.config_tag in E.gamemode_whitelist)) continue if(E.holidayID) if(!holidays || !holidays[E.holidayID]) continue sum_of_weights -= E.weight diff --git a/code/controllers/subsystem/objects.dm b/code/controllers/subsystem/objects.dm index 61c7b804aea..24e206139b7 100644 --- a/code/controllers/subsystem/objects.dm +++ b/code/controllers/subsystem/objects.dm @@ -15,6 +15,7 @@ var/datum/subsystem/objects/SSobj NEW_SS_GLOBAL(SSobj) /datum/subsystem/objects/Initialize(timeofday, zlevel) + setupGenetics() for(var/atom/movable/AM in world) if (zlevel && AM.z != zlevel) continue diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index f351bd6d9cb..46f76fb41cd 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -59,7 +59,6 @@ var/datum/subsystem/ticker/ticker return ..() if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase() if(!syndicate_code_response) syndicate_code_response = generate_code_phrase() - setupGenetics() setupFactions() ..() diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 45f8ddab2f6..cd4363d9dff 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -252,6 +252,7 @@ body += "" body += "" body += "" + body += "" if(iscarbon(D)) body += "" body += "" @@ -592,6 +593,29 @@ body if(usr.client) usr.client.cmd_assume_direct_control(M) + else if(href_list["offer_control"]) + if(!check_rights(0)) return + + var/mob/M = locate(href_list["offer_control"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + M << "Control of your mob has been offered to dead players." + log_admin("[key_name(usr)] has offered control of ([key_name(M)]) to ghosts.") + message_admins("[key_name_admin(usr)] has offered control of ([key_name_admin(M)]) to ghosts") + var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [M.real_name]?", "pAI", null, FALSE, 100) + var/mob/dead/observer/theghost = null + + if(candidates.len) + theghost = pick(candidates) + M << "Your mob has been taken over by a ghost!" + message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(M)])") + M.ghostize() + M.key = theghost.key + else + M << "There were no ghosts willing to take control." + message_admins("No ghosts were willing to take control of [key_name_admin(M)])") + else if(href_list["delall"]) if(!check_rights(R_DEBUG|R_SERVER)) return @@ -813,8 +837,7 @@ body if(result) var/newtype = species_list[result] - hardset_dna(H, null, null, null, null, newtype) - H.regenerate_icons() + H.set_species(newtype) else if(href_list["purrbation"]) if(!check_rights(R_SPAWN)) return @@ -828,7 +851,7 @@ body usr << "Mob doesn't exist anymore" return - if(H.dna && H.dna.species.id == "human") + if(H.dna.species.id == "human") if(H.dna.features["tail_human"] == "None" || H.dna.features["ears"] == "None") usr << "Put [H] on purrbation." H << "You suddenly feel valid." diff --git a/code/datums/diseases/advance/symptoms/genetics.dm b/code/datums/diseases/advance/symptoms/genetics.dm index cb730215ee9..68875694060 100644 --- a/code/datums/diseases/advance/symptoms/genetics.dm +++ b/code/datums/diseases/advance/symptoms/genetics.dm @@ -31,7 +31,8 @@ Bonus ..() if(prob(SYMPTOM_ACTIVATION_PROB * 5)) // 15% chance var/mob/living/carbon/M = A.affected_mob - if(!check_dna_integrity(M)) return + if(!M.has_dna()) + return switch(A.stage) if(4, 5) M << "[pick("Your skin feels itchy.", "You feel light headed.")]" @@ -44,7 +45,7 @@ Bonus possible_mutations = (bad_mutations | not_good_mutations) - mutations_list[RACEMUT] var/mob/living/carbon/M = A.affected_mob if(M) - if(!check_dna_integrity(M)) + if(!M.has_dna()) return archived_dna = M.dna.struc_enzymes @@ -52,10 +53,10 @@ Bonus /datum/symptom/genetic_mutation/End(datum/disease/advance/A) var/mob/living/carbon/M = A.affected_mob if(M && archived_dna) - if(!check_dna_integrity(M)) + if(!M.has_dna()) return - hardset_dna(M, se = archived_dna) - domutcheck(M) + M.dna.struc_enzymes = archived_dna + M.domutcheck() /* ////////////////////////////////////// diff --git a/code/datums/diseases/dna_spread.dm b/code/datums/diseases/dna_spread.dm index eb38e8689af..1ee18603a61 100644 --- a/code/datums/diseases/dna_spread.dm +++ b/code/datums/diseases/dna_spread.dm @@ -43,7 +43,7 @@ affected_mob.adjustToxLoss(2) affected_mob.updatehealth() if(4) - if(!src.transformed && !src.carrier) + if(!transformed && !carrier) //Save original dna for when the disease is cured. original_dna = new affected_mob.dna.type affected_mob.dna.copy_dna(original_dna) @@ -51,24 +51,22 @@ affected_mob << "You don't feel like yourself.." var/datum/dna/transform_dna = strain_data["dna"] - transform_dna.transfer_identity(affected_mob) + transform_dna.transfer_identity(affected_mob, transfer_SE = 1) affected_mob.real_name = affected_mob.dna.real_name + affected_mob.updateappearance(mutcolor_update=1) + affected_mob.domutcheck() - updateappearance(affected_mob) - domutcheck(affected_mob) - - src.transformed = 1 - src.carrier = 1 //Just chill out at stage 4 + transformed = 1 + carrier = 1 //Just chill out at stage 4 return /datum/disease/dnaspread/Del() if (original_dna && transformed && affected_mob) - original_dna.transfer_identity(affected_mob) + original_dna.transfer_identity(affected_mob, transfer_SE = 1) affected_mob.real_name = affected_mob.dna.real_name - - updateappearance(affected_mob) - domutcheck(affected_mob) + affected_mob.updateappearance(mutcolor_update=1) + affected_mob.domutcheck() affected_mob << "You feel more like yourself." ..() \ No newline at end of file diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index 1b83792a13c..b5913c3e71a 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -201,9 +201,8 @@ if(3) if(ishuman(affected_mob)) var/mob/living/carbon/human/human = affected_mob - if(human.dna && human.dna.species.id != "slime") - hardset_dna(human, null, null, null, null, /datum/species/slime) - human.regenerate_icons() + if(human.dna.species.id != "slime") + human.set_species(/datum/species/slime) /datum/disease/transformation/corgi name = "The Barkening" diff --git a/code/datums/martial.dm b/code/datums/martial.dm index 96d8726d596..2929c4b0a2e 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -27,34 +27,22 @@ /datum/martial_art/proc/basic_hit(mob/living/carbon/human/A,mob/living/carbon/human/D) A.do_attack_animation(D) - var/damage = rand(0,9) + var/damage = rand(0,9) + A.dna.species.punchmod - var/atk_verb = "punch" + var/atk_verb = A.dna.species.attack_verb if(D.lying) atk_verb = "kick" - else if(A.dna) - atk_verb = A.dna.species.attack_verb - - if(A.dna) - damage += A.dna.species.punchmod if(!damage) - if(A.dna) - playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1) - else - playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - D.visible_message("[A] has attempted to [atk_verb] [D]!") - add_logs(A, D, "attempted to [atk_verb]") - return 0 + playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1) + D.visible_message("[A] has attempted to [atk_verb] [D]!") + add_logs(A, D, "attempted to [atk_verb]") + return 0 var/obj/item/organ/limb/affecting = D.get_organ(ran_zone(A.zone_sel.selecting)) var/armor_block = D.run_armor_check(affecting, "melee") - if(A.dna) - playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1) - else - playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1) - + playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1) D.visible_message("[A] has [atk_verb]ed [D]!", \ "[A] has [atk_verb]ed [D]!") @@ -104,24 +92,18 @@ var/atk_verb = pick("left hook","right hook","straight punch") - var/damage = rand(5,8) - if(A.dna) - damage += A.dna.species.punchmod + var/damage = rand(5,8) + A.dna.species.punchmod if(!damage) - if(A.dna) - playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1) - else - playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - D.visible_message("[A] has attempted to hit [D] with a [atk_verb]!") - add_logs(A, D, "attempted to hit", atk_verb) - return 0 + playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1) + D.visible_message("[A] has attempted to hit [D] with a [atk_verb]!") + add_logs(A, D, "attempted to hit", atk_verb) + return 0 var/obj/item/organ/limb/affecting = D.get_organ(ran_zone(A.zone_sel.selecting)) var/armor_block = D.run_armor_check(affecting, "melee") - playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1) - + playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1) D.visible_message("[A] has hit [D] with a [atk_verb]!", \ "[A] has hit [D] with a [atk_verb]!") diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 116bc8ac19c..f84c04f531a 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -976,10 +976,10 @@ usr << "Resetting DNA failed!" else var/mob/living/carbon/C = current - C.dna = changeling.first_prof.dna + changeling.first_prof.dna.transfer_identity(C, transfer_SE=1) C.real_name = changeling.first_prof.name - updateappearance(C) - domutcheck(C) + C.updateappearance(mutcolor_update=1) + C.domutcheck() else if (href_list["nuclear"]) switch(href_list["nuclear"]) @@ -1409,7 +1409,7 @@ var/mob/living/carbon/human/H = current - hardset_dna(H,null,null,null,null,/datum/species/abductor,null) + H.set_species(/datum/species/abductor) var/datum/species/abductor/S = H.dna.species switch(role) diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index 83455d194f7..64ff70e3eef 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -16,6 +16,9 @@ var/text_gain_indication = "" var/text_lose_indication = "" var/list/visual_indicators = list() + var/layer_used = MUTATIONS_LAYER //which mutation layer to use + var/list/species_allowed = list() //to restrict mutation to only certain species + var/health_req //minimum health required to acquire the mutation /datum/mutation/human/proc/force_give(mob/living/carbon/human/owner) set_block(owner) @@ -33,7 +36,7 @@ return before + injection + after /datum/mutation/human/proc/set_block(mob/living/carbon/owner, on = 1) - if(owner && istype(owner) && owner.dna) + if(owner && owner.has_dna()) owner.dna.struc_enzymes = set_se(owner.dna.struc_enzymes, on) /datum/mutation/human/proc/check_block_string(se_string) @@ -51,17 +54,25 @@ /datum/mutation/human/proc/on_acquiring(mob/living/carbon/human/owner) if(!owner || !istype(owner) || (src in owner.dna.mutations)) return 1 + if(species_allowed.len && !species_allowed.Find(owner.dna.species.id)) + return 1 + if(health_req && owner.health < health_req) + return 1 owner.dna.mutations.Add(src) - owner << text_gain_indication + if(text_gain_indication) + owner << text_gain_indication if(visual_indicators.len) - owner.update_mutation_overlays() + var/list/mut_overlay = list(get_visual_indicator(owner)) + if(owner.overlays_standing[layer_used]) + mut_overlay = owner.overlays_standing[layer_used] + mut_overlay |= get_visual_indicator(owner) + owner.remove_overlay(layer_used) + owner.overlays_standing[layer_used] = mut_overlay + owner.apply_overlay(layer_used) /datum/mutation/human/proc/get_visual_indicator(mob/living/carbon/human/owner) return -/datum/mutation/human/proc/lose_indication(mob/living/carbon/human/owner) - owner.overlays.Remove(visual_indicators) - /datum/mutation/human/proc/on_attack_hand(mob/living/carbon/human/owner, atom/target) return @@ -76,9 +87,16 @@ /datum/mutation/human/proc/on_losing(mob/living/carbon/human/owner) if(owner && istype(owner) && (owner.dna.mutations.Remove(src))) - owner << text_lose_indication + if(text_lose_indication) + owner << text_lose_indication if(visual_indicators.len) - owner.update_mutation_overlays() + var/list/mut_overlay = list() + if(owner.overlays_standing[layer_used]) + mut_overlay = owner.overlays_standing[layer_used] + owner.remove_overlay(layer_used) + mut_overlay.Remove(get_visual_indicator(owner)) + owner.overlays_standing[layer_used] = mut_overlay + owner.apply_overlay(layer_used) return 0 return 1 @@ -96,6 +114,8 @@ get_chance = 15 lowest_value = 256 * 12 text_gain_indication = "Your muscles hurt!" + species_allowed = list("human") //no skeleton/lizard hulk + health_req = 25 /datum/mutation/human/hulk/New() ..() @@ -583,32 +603,42 @@ message = replacetext(message," muh valids "," getting my kicks ") return trim(message) - /datum/mutation/human/laser_eyes - name = "Laser Eyes" quality = POSITIVE dna_block = NON_SCANNABLE text_gain_indication = "You feel pressure building up behind your eyes." + layer_used = FRONT_MUTATIONS_LAYER + +/datum/mutation/human/laser_eyes/New() + ..() + visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="lasereyes_s", "layer"=-FRONT_MUTATIONS_LAYER) + +/datum/mutation/human/laser_eyes/get_visual_indicator(mob/living/carbon/human/owner) + return visual_indicators[1] /datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target) if(owner.a_intent == "harm") owner.LaserEyes(target) -/mob/living/carbon/human/proc/update_mutation_overlays() - remove_overlay(MUTATIONS_LAYER) - var/image/standing +/mob/living/carbon/proc/update_mutations_overlay() + return +/mob/living/carbon/human/update_mutations_overlay() for(var/datum/mutation/human/CM in dna.mutations) + if(CM.species_allowed.len && !CM.species_allowed.Find(dna.species.id)) + CM.force_lose(src) //shouldn't have that mutation at all + continue if(CM.visual_indicators.len) + var/list/mut_overlay = list() + if(overlays_standing[CM.layer_used]) + mut_overlay = overlays_standing[CM.layer_used] var/image/V = CM.get_visual_indicator(src) - if(!standing) - standing = V - else - standing.overlays += V - - if(standing) - overlays_standing[MUTATIONS_LAYER] = standing - apply_overlay(MUTATIONS_LAYER) - + if(!mut_overlay.Find(V)) //either we lack the visual indicator or we have the wrong one + remove_overlay(CM.layer_used) + for(var/image/I in CM.visual_indicators) + mut_overlay.Remove(I) + mut_overlay |= V + overlays_standing[CM.layer_used] = mut_overlay + apply_overlay(CM.layer_used) diff --git a/code/datums/spells/bloodcrawl.dm b/code/datums/spells/bloodcrawl.dm index 0216a494c35..495a2335baa 100644 --- a/code/datums/spells/bloodcrawl.dm +++ b/code/datums/spells/bloodcrawl.dm @@ -1,13 +1,14 @@ /obj/effect/proc_holder/spell/bloodcrawl - name = "Blood crawl" - desc = "Use blood to travel." - charge_max = 10 + name = "Blood Crawl" + desc = "Use pools of blood to phase out of existence." + charge_max = 0 clothes_req = 0 selection_type = "range" range = 1 cooldown_min = 0 overlay = null action_icon_state = "bloodcrawl" + action_background_icon_state = "bg_demon" var/phased = 0 /obj/effect/proc_holder/spell/bloodcrawl/choose_targets(mob/user = usr) @@ -16,7 +17,7 @@ perform(target) return revert_cast() - user << "You need blood to blood crawl." + user << "There must be a nearby source of blood!" /obj/effect/proc_holder/spell/bloodcrawl/perform(obj/effect/decal/cleanable/target, recharge = 1, mob/living/user = usr) if(istype(user)) @@ -24,9 +25,9 @@ if(user.phasein(target)) phased = 0 else - user.phaseout(target) - phased = 1 + if(user.phaseout(target)) + phased = 1 start_recharge() return revert_cast() - user << "You cannot blood crawl." \ No newline at end of file + user << "You are unable to blood crawl!" diff --git a/code/datums/spells/lichdom.dm b/code/datums/spells/lichdom.dm index ee2189c36f4..f199a06048f 100644 --- a/code/datums/spells/lichdom.dm +++ b/code/datums/spells/lichdom.dm @@ -55,7 +55,7 @@ lich.real_name = user.mind.name user.mind.transfer_to(lich) - hardset_dna(lich,null,null,lich.real_name,null,/datum/species/skeleton) + lich.hardset_dna(null,null,lich.real_name,null,/datum/species/skeleton) lich << "Your bones clatter and shutter as they're pulled back into this world!" charge_max += 600 var/mob/old_body = current_body @@ -98,7 +98,7 @@ marked_item.desc = "A terrible aura surrounds this item, its very existence is offensive to life itself..." marked_item.color = "#003300" user << "With a hideous feeling of emptiness you watch in horrified fascination as skin sloughs off bone! Blood boils, nerves disintegrate, eyes boil in their sockets! As your organs crumble to dust in your fleshless chest you come to terms with your choice. You're a lich!" - hardset_dna(user, null, null, null, null, /datum/species/skeleton) + user.set_species(/datum/species/skeleton) current_body = user.mind.current if(ishuman(user)) var/mob/living/carbon/human/H = user diff --git a/code/datums/spells/wizard.dm b/code/datums/spells/wizard.dm index a32bae29911..75d971cced4 100644 --- a/code/datums/spells/wizard.dm +++ b/code/datums/spells/wizard.dm @@ -41,7 +41,6 @@ clothes_req = 1 invocation = "BIRUZ BENNAR" invocation_type = "shout" - message = "You feel strong! You feel a pressure building behind your eyes!" range = -1 include_user = 1 centcom_cancast = 0 @@ -248,7 +247,7 @@ sound="sound/magic/Blind.ogg" /obj/effect/proc_holder/spell/targeted/genetic/blind - disabilities = 1 + disabilities = BLIND duration = 300 sound="sound/magic/Blind.ogg" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index a59c0d7c867..373d98c3b36 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -280,11 +280,11 @@ var/list/blood_splatter_icons = list() //returns 1 if made bloody, returns 0 otherwise /atom/proc/add_blood(mob/living/carbon/M) - if(ishuman(M) && M.dna) + if(ishuman(M)) var/mob/living/carbon/human/H = M if(NOBLOOD in H.dna.species.specflags) return 0 - if(rejects_blood() || !istype(M) || !check_dna_integrity(M)) + if(rejects_blood() || !M.has_dna()) return 0 return 1 @@ -358,7 +358,7 @@ var/list/blood_splatter_icons = list() // Only adds blood on the floor -- Skie /atom/proc/add_blood_floor(mob/living/carbon/M) if(istype(src, /turf/simulated)) - if(check_dna_integrity(M)) //mobs with dna = (monkeys + humans at time of writing) + if(M.has_dna()) //mobs with dna = (monkeys + humans at time of writing) var/obj/effect/decal/cleanable/blood/B = locate() in contents if(!B) blood_splatter(src,M,1) diff --git a/code/game/dna.dm b/code/game/dna.dm index b402edbda36..33615f83cfb 100644 --- a/code/game/dna.dm +++ b/code/game/dna.dm @@ -1,19 +1,4 @@ -#define INJECTOR_TIMEOUT 300 -#define REJUVENATORS_INJECT 15 -#define REJUVENATORS_MAX 90 -#define NUMBER_OF_BUFFERS 3 -#define RADIATION_STRENGTH_MAX 15 -#define RADIATION_STRENGTH_MULTIPLIER 1 //larger has a more range - -#define RADIATION_DURATION_MAX 30 -#define RADIATION_ACCURACY_MULTIPLIER 3 //larger is less accurate - -#define RADIATION_IRRADIATION_MULTIPLIER 0.2 //multiplier for how much radiation a test subject recieves - -#define BAD_MUTATION_DIFFICULTY 2 -#define GOOD_MUTATION_DIFFICULTY 4 -#define OP_MUTATION_DIFFICULTY 5 /////////////////////////// DNA DATUM /datum/dna var/unique_enzymes @@ -27,26 +12,26 @@ var/mob/living/carbon/holder /datum/dna/New(mob/living/carbon/new_holder) - if(new_holder && istype(new_holder)) + if(new_holder) holder = new_holder -/datum/dna/proc/transfer_identity(mob/living/carbon/destination) - if(check_dna_integrity(destination)) - destination.dna.unique_enzymes = unique_enzymes - destination.dna.uni_identity = uni_identity - destination.dna.blood_type = blood_type - hardset_dna(destination, null, null, null, null, species.type) - destination.dna.features = features - destination.dna.real_name = real_name - destination.dna.mutations = mutations +/datum/dna/proc/transfer_identity(mob/living/carbon/destination, transfer_SE = 0) + destination.dna.unique_enzymes = unique_enzymes + destination.dna.uni_identity = uni_identity + destination.dna.blood_type = blood_type + destination.set_species(species.type, icon_update=0) + destination.dna.features = features + destination.dna.real_name = real_name + if(transfer_SE) + destination.dna.struc_enzymes = struc_enzymes /datum/dna/proc/copy_dna(datum/dna/new_dna) new_dna.unique_enzymes = unique_enzymes new_dna.struc_enzymes = struc_enzymes new_dna.uni_identity = uni_identity new_dna.blood_type = blood_type - new_dna.species = new species.type new_dna.features = features + new_dna.species = new species.type new_dna.real_name = real_name new_dna.mutations = mutations @@ -70,55 +55,72 @@ for(var/datum/mutation/human/HM in group) HM.force_lose(holder) -/datum/dna/proc/generate_uni_identity(mob/living/carbon/character) +/datum/dna/proc/generate_uni_identity() . = "" var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS) - if(istype(character)) - L[DNA_GENDER_BLOCK] = construct_block((character.gender!=MALE)+1, 2) - if(istype(character, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = character - if(!H.dna.species) - hardset_dna(H, null, null, null, null, /datum/species/human) - if(!hair_styles_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, hair_styles_list, hair_styles_male_list, hair_styles_female_list) - L[DNA_HAIR_STYLE_BLOCK] = construct_block(hair_styles_list.Find(H.hair_style), hair_styles_list.len) - L[DNA_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.hair_color) - if(!facial_hair_styles_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, facial_hair_styles_list, facial_hair_styles_male_list, facial_hair_styles_female_list) - L[DNA_FACIAL_HAIR_STYLE_BLOCK] = construct_block(facial_hair_styles_list.Find(H.facial_hair_style), facial_hair_styles_list.len) - L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color) - L[DNA_SKIN_TONE_BLOCK] = construct_block(skin_tones.Find(H.skin_tone), skin_tones.len) - L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color) + + L[DNA_GENDER_BLOCK] = construct_block((holder.gender!=MALE)+1, 2) + if(ishuman(holder)) + var/mob/living/carbon/human/H = holder + if(!hair_styles_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, hair_styles_list, hair_styles_male_list, hair_styles_female_list) + L[DNA_HAIR_STYLE_BLOCK] = construct_block(hair_styles_list.Find(H.hair_style), hair_styles_list.len) + L[DNA_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.hair_color) + if(!facial_hair_styles_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, facial_hair_styles_list, facial_hair_styles_male_list, facial_hair_styles_female_list) + L[DNA_FACIAL_HAIR_STYLE_BLOCK] = construct_block(facial_hair_styles_list.Find(H.facial_hair_style), facial_hair_styles_list.len) + L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color) + L[DNA_SKIN_TONE_BLOCK] = construct_block(skin_tones.Find(H.skin_tone), skin_tones.len) + L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color) for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) if(L[i]) . += L[i] else . += random_string(DNA_BLOCK_SIZE,hex_characters) return . -/datum/dna/proc/generate_struc_enzymes(mob/living/carbon/character) - var/list/L = list("0","1","2","3","4","5","6") +/datum/dna/proc/generate_struc_enzymes() var/list/sorting = new /list(DNA_STRUC_ENZYMES_BLOCKS) var/result = "" for(var/datum/mutation/human/A in good_mutations + bad_mutations + not_good_mutations) - if(A.name == RACEMUT && istype(character,/mob/living/carbon/monkey)) + if(A.name == RACEMUT && ismonkey(holder)) sorting[A.dna_block] = num2hex(A.lowest_value + rand(0, 256 * 6), DNA_BLOCK_SIZE) - character.dna.mutations.Add(A) + mutations |= A else - sorting[A.dna_block] = random_string(DNA_BLOCK_SIZE, L) + sorting[A.dna_block] = random_string(DNA_BLOCK_SIZE, list("0","1","2","3","4","5","6")) for(var/B in sorting) result += B return result -/datum/dna/proc/generate_unique_enzymes(mob/living/carbon/character) +/datum/dna/proc/generate_unique_enzymes() . = "" - if(istype(character)) - real_name = character.real_name - . += md5(character.real_name) + if(istype(holder)) + real_name = holder.real_name + . += md5(holder.real_name) else - . += repeat_string(DNA_UNIQUE_ENZYMES_LEN, "0") + . += random_string(DNA_UNIQUE_ENZYMES_LEN, hex_characters) return . +/datum/dna/proc/update_ui_block(blocknumber) + if(!blocknumber || !ishuman(holder)) + return + var/mob/living/carbon/human/H = holder + switch(blocknumber) + if(DNA_HAIR_COLOR_BLOCK) + setblock(uni_identity, blocknumber, sanitize_hexcolor(H.hair_color)) + if(DNA_FACIAL_HAIR_COLOR_BLOCK) + setblock(uni_identity, blocknumber, sanitize_hexcolor(H.facial_hair_color)) + if(DNA_SKIN_TONE_BLOCK) + setblock(uni_identity, blocknumber, construct_block(skin_tones.Find(H.skin_tone), skin_tones.len)) + if(DNA_EYE_COLOR_BLOCK) + setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color)) + if(DNA_GENDER_BLOCK) + setblock(uni_identity, blocknumber, construct_block((H.gender!=MALE)+1, 2)) + if(DNA_FACIAL_HAIR_STYLE_BLOCK) + setblock(uni_identity, blocknumber, construct_block(facial_hair_styles_list.Find(H.facial_hair_style), facial_hair_styles_list.len)) + if(DNA_HAIR_STYLE_BLOCK) + setblock(uni_identity, blocknumber, construct_block(hair_styles_list.Find(H.hair_style), hair_styles_list.len)) + /datum/dna/proc/mutations_say_mods(message) if(message) for(var/datum/mutation/human/M in mutations) @@ -131,79 +133,130 @@ spans |= M.get_spans() return spans -/proc/hardset_dna(mob/living/carbon/owner, ui, se, real_name, blood_type, datum/species/mrace, features) - if(!ismonkey(owner) && !ishuman(owner)) - return - if(!owner.dna) - create_dna(owner, mrace) +/datum/dna/proc/is_same_as(datum/dna/D) + if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name) + if(species.type == D.species.type && features == D.features && blood_type == D.blood_type) + return 1 + return 0 - if(mrace && !ismonkey(owner)) - if(owner.dna.species.exotic_blood) - var/datum/reagent/exotic_blood = new owner.dna.species.exotic_blood - owner.reagents.del_reagent(exotic_blood.id) - owner.dna.species = new mrace() +//used to update dna UI, UE, and dna.real_name. +/datum/dna/proc/update_dna_identity() + uni_identity = generate_uni_identity() + unique_enzymes = generate_unique_enzymes() - if(features) - owner.dna.features = features +/datum/dna/proc/initialize_dna(newblood_type) + if(newblood_type) + blood_type = newblood_type + unique_enzymes = generate_unique_enzymes() + uni_identity = generate_uni_identity() + struc_enzymes = generate_struc_enzymes() + features = list("mcolor" = "FFF", "tail" = "Smooth", "snout" = "Round", "horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None") - if(real_name) - owner.real_name = real_name - owner.dna.generate_unique_enzymes(owner) - if(blood_type) - owner.dna.blood_type = blood_type - if(ui) - owner.dna.uni_identity = ui - updateappearance(owner) +/////////////////////////// DNA MOB-PROCS ////////////////////// - if(se) - owner.dna.struc_enzymes = se - domutcheck(owner) - - check_dna_integrity(owner) - - owner.regenerate_icons() +/mob/proc/set_species(datum/species/mrace, icon_update = 1) return -/proc/check_dna_integrity(mob/living/carbon/character) - if(!character || !(istype(character, /mob/living/carbon/human) || istype(character, /mob/living/carbon/monkey))) //Evict xenos from carbon 2012 +/mob/living/carbon/set_species(datum/species/mrace, icon_update = 1) + if(has_dna()) + if(dna.species.exotic_blood) + var/datum/reagent/EB = dna.species.exotic_blood + reagents.del_reagent(initial(EB.id)) + dna.species = new mrace() + +/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = 1) + ..() + if(icon_update) + update_body() + update_hair() + update_mutcolor() + update_mutations_overlay()// no lizard with human hulk overlay please. + + +/mob/proc/has_dna() + return + +/mob/living/carbon/has_dna() + return dna + + +/mob/living/carbon/human/proc/hardset_dna(ui, se, newreal_name, newblood_type, datum/species/mrace, newfeatures) + + if(newfeatures) + dna.features = newfeatures + + if(mrace) + set_species(mrace, icon_update=0) + + if(newreal_name) + real_name = newreal_name + dna.generate_unique_enzymes() + + if(newblood_type) + dna.blood_type = newblood_type + + if(ui) + dna.uni_identity = ui + updateappearance(icon_update=0) + + if(se) + dna.struc_enzymes = se + domutcheck() + + if(mrace || newfeatures || ui) + update_body() + update_hair() + update_mutcolor() + update_mutations_overlay() + + +/mob/living/carbon/proc/create_dna() + dna = new /datum/dna(src) + if(!dna.species) + dna.species = new /datum/species/human() + +//proc used to update the mob's appearance after its dna UI has been changed +/mob/living/carbon/proc/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0) + if(!has_dna()) return - if(!character.dna) - if(ready_dna(character)) - return character.dna + gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE + +mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0) + ..() + var/structure = dna.uni_identity + hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK)) + facial_hair_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK)) + skin_tone = skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), skin_tones.len)] + eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK)) + facial_hair_style = facial_hair_styles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIR_STYLE_BLOCK), facial_hair_styles_list.len)] + hair_style = hair_styles_list[deconstruct_block(getblock(structure, DNA_HAIR_STYLE_BLOCK), hair_styles_list.len)] + if(icon_update) + update_body() + update_hair() + if(mutcolor_update) + update_mutcolor() + if(mutations_overlay_update) + update_mutations_overlay() + + +/mob/proc/domutcheck() + return + +/mob/living/carbon/domutcheck() + if(!has_dna()) return - if(length(character.dna.uni_identity) != DNA_UNI_IDENTITY_BLOCKS*DNA_BLOCK_SIZE) - character.dna.uni_identity = character.dna.generate_uni_identity(character) - if(length(character.dna.struc_enzymes)!= DNA_STRUC_ENZYMES_BLOCKS*DNA_BLOCK_SIZE) - character.dna.struc_enzymes = character.dna.generate_struc_enzymes() - if(!character.dna.real_name || length(character.dna.unique_enzymes) != DNA_UNIQUE_ENZYMES_LEN) - character.dna.unique_enzymes = character.dna.generate_unique_enzymes(character) - return character.dna + for(var/datum/mutation/human/A in good_mutations | bad_mutations | not_good_mutations) + if(ismob(A.check_block(src))) + return //we got monkeyized/humanized, this mob will be deleted, no need to continue. -/proc/ready_dna(mob/living/carbon/character, blood_type) - if(!istype(character, /mob/living/carbon/monkey) && !istype(character, /mob/living/carbon/human)) - return - if(!character.dna) - create_dna(character) - if(blood_type) - character.dna.blood_type = blood_type - character.dna.real_name = character.real_name - character.dna.uni_identity = character.dna.generate_uni_identity(character) - character.dna.struc_enzymes = character.dna.generate_struc_enzymes(character) - character.dna.unique_enzymes = character.dna.generate_unique_enzymes(character) - character.dna.features = character.features - return character.dna + update_mutations_overlay() -/proc/create_dna(mob/living/carbon/C, datum/species/S) //don't use this unless you're about to use hardset_dna or ready_dna - C.dna = new /datum/dna(C) - C.dna.holder = C - if(S) C.dna.species = new S() // do not remove; this is here to prevent runtimes -/////////////////////////// DNA DATUM -/////////////////////////// DNA HELPER-PROCS +/////////////////////////// DNA HELPER-PROCS ////////////////////////////// /proc/getleftblocks(input,blocknumber,blocksize) if(blocknumber > 1) return copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) @@ -219,45 +272,35 @@ if(!istring || !blocknumber || !replacement || !blocksize) return 0 return getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) -/proc/scramble(input,rs,rd) - var/length = length(input) - var/ran = gaussian(0, rs*RADIATION_STRENGTH_MULTIPLIER) - if(ran == 0) ran = pick(-1,1) //hacky, statistically should almost never happen. 0-change makes people mad though - else if(ran < 0) ran = round(ran) //negative, so floor it - else ran = -round(-ran) //positive, so ceiling it - return num2hex(Wrap(hex2num(input)+ran, 0, 16**length), length) - -/proc/randomize_radiation_accuracy(position_we_were_supposed_to_hit, radduration, number_of_blocks) - return Wrap(round(position_we_were_supposed_to_hit + gaussian(0, RADIATION_ACCURACY_MULTIPLIER/radduration), 1), 1, number_of_blocks+1) - /proc/randmut(mob/living/carbon/M, list/candidates, difficulty = 2) - if(!check_dna_integrity(M)) + if(!M.has_dna()) return var/datum/mutation/human/num = pick(candidates) . = num.force_give(M) return /proc/randmutb(mob/living/carbon/M) - if(!check_dna_integrity(M)) + if(!M.has_dna()) return var/datum/mutation/human/HM = pick((bad_mutations | not_good_mutations) - mutations_list[RACEMUT]) . = HM.force_give(M) /proc/randmutg(mob/living/carbon/M) - if(!check_dna_integrity(M)) + if(!M.has_dna()) return var/datum/mutation/human/HM = pick(good_mutations) . = HM.force_give(M) /proc/randmuti(mob/living/carbon/M) - if(!check_dna_integrity(M)) return - var/num = rand(1, DNA_STRUC_ENZYMES_BLOCKS) + if(!M.has_dna()) + return + var/num = rand(1, DNA_UNI_IDENTITY_BLOCKS) var/newdna = setblock(M.dna.uni_identity, num, random_string(DNA_BLOCK_SIZE, hex_characters)) M.dna.uni_identity = newdna return /proc/clean_dna(mob/living/carbon/M) - if(!check_dna_integrity(M)) + if(!M.has_dna()) return M.dna.remove_all_mutations() @@ -266,691 +309,20 @@ randmut(M, candidates, difficulty) /proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, probability) - if(!check_dna_integrity(M)) + if(!M.has_dna()) return 0 if(se) for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++) if(prob(probability)) M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, random_string(DNA_BLOCK_SIZE, hex_characters)) - domutcheck(M) + M.domutcheck() if(ui) for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) if(prob(probability)) M.dna.uni_identity = setblock(M.dna.uni_identity, i, random_string(DNA_BLOCK_SIZE, hex_characters)) - updateappearance(M) + M.updateappearance(mutations_overlay_update=1) return 1 -/////////////////////////// DNA HELPER-PROCS - -/////////////////////////// DNA MISC-PROCS -/proc/updateappearance(mob/living/carbon/C) - if(!check_dna_integrity(C)) - return 0 - - var/structure = C.dna.uni_identity - C.gender = (deconstruct_block(getblock(structure, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE - if(istype(C, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = C - H.hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK)) - H.facial_hair_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK)) - H.skin_tone = skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), skin_tones.len)] - H.eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK)) - H.facial_hair_style = facial_hair_styles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIR_STYLE_BLOCK), facial_hair_styles_list.len)] - H.hair_style = hair_styles_list[deconstruct_block(getblock(structure, DNA_HAIR_STYLE_BLOCK), hair_styles_list.len)] - - H.update_body() - H.update_hair() - return 1 - -/proc/domutcheck(mob/living/carbon/M) - if(!check_dna_integrity(M)) - return 0 - - var/mob/living/carbon/C = M - var/mob/living/carbon/temp - - for(var/datum/mutation/human/A in good_mutations | bad_mutations | not_good_mutations) - temp = A.check_block(C) - if(ismob(temp)) - C = temp - -//////////////////////////////////////////////////////////// Monkey Block - if(M) - M.regenerate_icons() - return 1 -/////////////////////////// DNA MISC-PROCS - - -/////////////////////////// DNA MACHINES -/obj/machinery/dna_scannernew - name = "\improper DNA scanner" - desc = "It scans DNA structures." - icon = 'icons/obj/Cryogenic2.dmi' - icon_state = "scanner" - density = 1 - var/locked = 0 - anchored = 1 - use_power = 1 - idle_power_usage = 50 - active_power_usage = 300 - var/damage_coeff - var/scan_level - var/precision_coeff - -/obj/machinery/dna_scannernew/New() - ..() - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/clonescanner(null) - component_parts += new /obj/item/weapon/stock_parts/scanning_module(null) - component_parts += new /obj/item/weapon/stock_parts/manipulator(null) - component_parts += new /obj/item/weapon/stock_parts/micro_laser(null) - component_parts += new /obj/item/weapon/stock_parts/console_screen(null) - component_parts += new /obj/item/stack/cable_coil(null, 1) - component_parts += new /obj/item/stack/cable_coil(null, 1) - RefreshParts() - - -/obj/machinery/dna_scannernew/RefreshParts() - scan_level = 0 - damage_coeff = 0 - precision_coeff = 0 - for(var/obj/item/weapon/stock_parts/scanning_module/P in component_parts) - scan_level += P.rating - for(var/obj/item/weapon/stock_parts/manipulator/P in component_parts) - precision_coeff = P.rating - for(var/obj/item/weapon/stock_parts/micro_laser/P in component_parts) - damage_coeff = P.rating - -/obj/machinery/dna_scannernew/update_icon() - - //no power or maintenance - if(stat & (NOPOWER|BROKEN)) - icon_state = initial(icon_state)+ (state_open ? "_open" : "") + "_unpowered" - return - - if((stat & MAINT) || panel_open) - icon_state = initial(icon_state)+ (state_open ? "_open" : "") + "_maintenance" - return - - //running and someone in there - if(occupant) - icon_state = initial(icon_state)+ "_occupied" - return - - //running - icon_state = initial(icon_state)+ (state_open ? "_open" : "") - -/obj/machinery/dna_scannernew/power_change() - ..() - update_icon() - -/obj/machinery/dna_scannernew/proc/toggle_open(mob/user) - if(panel_open) - user << "Close the maintenance panel first." - return - - if(state_open) - close_machine() - return - - else if(locked) - user << "The bolts are locked down, securing the door shut." - return - - open_machine() - -/obj/machinery/dna_scannernew/container_resist() - var/mob/living/user = usr - var/breakout_time = 2 - if(state_open || !locked) //Open and unlocked, no need to escape - state_open = 1 - return - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT - user << "You lean on the back of [src] and start pushing the door open... (this will take about [breakout_time] minutes.)" - user.visible_message("You hear a metallic creaking from [src]!") - - if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds - if(!user || user.stat != CONSCIOUS || user.loc != src || state_open || !locked) - return - - locked = 0 - visible_message("[user] successfully broke out of [src]!") - user << "You successfully break out of [src]!" - - open_machine() - -/obj/machinery/dna_scannernew/close_machine() - if(!state_open) - return 0 - - ..() - - // search for ghosts, if the corpse is empty and the scanner is connected to a cloner - if(occupant) - if(locate(/obj/machinery/computer/cloning, get_step(src, NORTH)) \ - || locate(/obj/machinery/computer/cloning, get_step(src, SOUTH)) \ - || locate(/obj/machinery/computer/cloning, get_step(src, EAST)) \ - || locate(/obj/machinery/computer/cloning, get_step(src, WEST))) - - occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!") - return 1 - -/obj/machinery/dna_scannernew/open_machine() - if(state_open) - return 0 - - ..() - - return 1 - -/obj/machinery/dna_scannernew/relaymove(mob/user as mob) - if(user.stat || locked) - return - - open_machine() - return - -/obj/machinery/dna_scannernew/attackby(obj/item/I, mob/user, params) - - if(!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, I))//sent icon_state is irrelevant... - update_icon()//..since we're updating the icon here, since the scanner can be unpowered when opened/closed - return - - if(exchange_parts(user, I)) - return - - if(default_pry_open(I)) - return - - if(default_deconstruction_crowbar(I)) - return - - if(istype(I, /obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = I - if(!ismob(G.affecting)) - return - - if(!state_open) - user << "Open the scanner first." - return - - var/mob/M = G.affecting - M.loc = loc - user.stop_pulling() - qdel(G) - -/obj/machinery/dna_scannernew/attack_hand(mob/user) - if(..(user,1,0)) //don't set the machine, since there's no dialog - return - - toggle_open(user) - -/obj/machinery/dna_scannernew/blob_act() - if(prob(75)) - qdel(src) - - -//DNA COMPUTER -/obj/machinery/computer/scan_consolenew - name = "\improper DNA scanner access console" - desc = "Scan DNA." - icon_screen = "dna" - icon_keyboard = "med_key" - density = 1 - circuit = /obj/item/weapon/circuitboard/scan_consolenew - var/radduration = 2 - var/radstrength = 1 - - var/list/buffer[NUMBER_OF_BUFFERS] - - var/injectorready = 0 //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete - var/current_screen = "mainmenu" - var/obj/machinery/dna_scannernew/connected = null - var/obj/item/weapon/disk/data/diskette = null - anchored = 1 - use_power = 1 - idle_power_usage = 10 - active_power_usage = 400 - -/obj/machinery/computer/scan_consolenew/attackby(obj/item/I, mob/user, params) - if (istype(I, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES - if (!src.diskette) - if(!user.drop_item()) - return - I.loc = src - src.diskette = I - user << "You insert [I]." - src.updateUsrDialog() - return - else - ..() - return - -/obj/machinery/computer/scan_consolenew/New() - ..() - - spawn(5) - for(dir in list(NORTH,EAST,SOUTH,WEST)) - connected = locate(/obj/machinery/dna_scannernew, get_step(src, dir)) - if(!isnull(connected)) - break - spawn(250) - injectorready = 1 - return - return - -/obj/machinery/computer/scan_consolenew/attack_hand(mob/user) - if(..()) - return - ShowInterface(user) - -/obj/machinery/computer/scan_consolenew/proc/ShowInterface(mob/user, last_change) - if(!user) return - var/datum/browser/popup = new(user, "scannernew", "DNA Modifier Console", 800, 630) // Set up the popup browser window - if(!( in_range(src, user) || istype(user, /mob/living/silicon) )) - popup.close() - return - popup.add_stylesheet("scannernew", 'html/browser/scannernew.css') - - var/mob/living/carbon/viable_occupant - var/occupant_status = "
Subject Status:
" - var/scanner_status - var/temp_html - if(connected && connected.is_operational()) - if(connected.occupant) //set occupant_status message - viable_occupant = connected.occupant - if(check_dna_integrity(viable_occupant) && (!(viable_occupant.disabilities & NOCLONE) || (connected.scan_level == 3))) //occupent is viable for dna modification - occupant_status += "[viable_occupant.name] => " - switch(viable_occupant.stat) - if(CONSCIOUS) occupant_status += "Conscious" - if(UNCONSCIOUS) occupant_status += "Unconscious" - else occupant_status += "DEAD - Cannot Operate" - occupant_status += "
" - occupant_status += "
Health:
[viable_occupant.health] %
" - occupant_status += "
Radiation Level:
[viable_occupant.radiation] %
" - var/rejuvenators = viable_occupant.reagents.get_reagent_amount("epinephrine") - occupant_status += "
Rejuvenators:
[rejuvenators] units
" - occupant_status += "
Unique Enzymes :
[viable_occupant.dna.unique_enzymes]
" - occupant_status += "
Last Operation:
[last_change ? last_change : "----"]
" - else - viable_occupant = null - occupant_status += "Invalid DNA structure" - if (viable_occupant && viable_occupant.stat == DEAD) - viable_occupant = null // No editing the dead. - else - occupant_status += "No subject detected" - - if(connected.state_open) - scanner_status = "Open" - else - scanner_status = "Closed" - if(connected.locked) - scanner_status += " (Locked)" - else - scanner_status += " (Unlocked)" - - - else - occupant_status += "----" - scanner_status += "Error: No scanner detected" - - var/status = "
" - status += "
Scanner:
[scanner_status]
" - status += "[occupant_status]" - - - status += "

Radiation Emitter Status

" - var/stddev = radstrength*RADIATION_STRENGTH_MULTIPLIER - status += "
Output Level:
[radstrength]
" - status += "
  \> Mutation:
(-[stddev] to +[stddev] = 68 %) (-[2*stddev] to +[2*stddev] = 95 %)
" - if(connected) - stddev = RADIATION_ACCURACY_MULTIPLIER/(radduration + (connected.precision_coeff ** 2)) - else - stddev = RADIATION_ACCURACY_MULTIPLIER/radduration - var/chance_to_hit - switch(stddev) //hardcoded values from a z-table for a normal distribution - if(0 to 0.25) chance_to_hit = ">95 %" - if(0.25 to 0.5) chance_to_hit = "68-95 %" - if(0.5 to 0.75) chance_to_hit = "55-68 %" - else chance_to_hit = "<38 %" - status += "
Pulse Duration:
[radduration]
" - status += "
  \> Accuracy:
[chance_to_hit]
" - status += "
" // Close statusDisplay div - var/buttons = "Scan " - if(connected) - buttons += " [connected.state_open ? "Close" : "Open"] Scanner " - if (connected.state_open) - buttons += "[connected.locked ? "Unlock" : "Lock"] Scanner " - else - buttons += "[connected.locked ? "Unlock" : "Lock"] Scanner " - else buttons += "Open Scanner Lock Scanner " - if(viable_occupant) buttons += "Inject Rejuvenators " - else buttons += "Inject Rejuvenators " - if(diskette) buttons += "Eject Disk " - else buttons += "Eject Disk " - if(current_screen == "buffer") buttons += "Radiation Emitter Menu " - else buttons += "Buffer Menu " - - switch(current_screen) - if("working") - temp_html += status - temp_html += "

System Busy

" - temp_html += "Working ... Please wait ([radduration] Seconds)" - if("buffer") - temp_html += status - temp_html += buttons - temp_html += "

Buffer Menu

" - - if(istype(buffer)) - for(var/i=1, i<=buffer.len, i++) - temp_html += "
Slot [i]: " - var/list/buffer_slot = buffer[i] - if( !buffer_slot || !buffer_slot.len || !buffer_slot["name"] || !((buffer_slot["UI"] && buffer_slot["UE"]) || buffer_slot["SE"]) ) - temp_html += "
\tNo Data" - if(viable_occupant) temp_html += "
Save to Buffer " - else temp_html += "
Save to Buffer " - temp_html += "Clear Buffer " - if(diskette) temp_html += "Load from Disk " - else temp_html += "Load from Disk " - temp_html += "Save to Disk " - else - var/ui = buffer_slot["UI"] - var/se = buffer_slot["SE"] - var/ue = buffer_slot["UE"] - var/name = buffer_slot["name"] - var/label = buffer_slot["label"] - var/blood_type = buffer_slot["blood_type"] - temp_html += "
\tLabel: [label ? label : name]" - temp_html += "
\tSubject: [name]" - if(ue && name && blood_type) - temp_html += "
\tBlood Type: [blood_type]" - temp_html += "
\tUE: [ue] " - if(viable_occupant) temp_html += "Occupant " - else temp_html += "Occupant" - if(injectorready) temp_html += "Injector" - else temp_html += "Injector" - else - temp_html += "
\tBlood Type: No Data" - temp_html += "
\tUE: No Data" - if(ui) - temp_html += "
\tUI: [ui] " - if(viable_occupant) temp_html += "Occupant " - else temp_html += "Occupant" - if(injectorready) temp_html += "Injector" - else temp_html += "Injector" - else - temp_html += "
\tUI: No Data" - if(se) - temp_html += "
\tSE: [se] " - if(viable_occupant && viable_occupant.stat != DEAD) temp_html += "Occupant " - else temp_html += "Occupant " - if(injectorready) temp_html += "Injector" - else temp_html += "Injector" - else - temp_html += "
\tSE: No Data" - if(viable_occupant) temp_html += "
Save to Buffer " - else temp_html += "
Save to Buffer " - temp_html += "Clear Buffer " - if(diskette) temp_html += "Load from Disk " - else temp_html += "Load from Disk " - if(diskette && !diskette.read_only) temp_html += "Save to Disk " - else temp_html += "Save to Disk " - else - temp_html += status - temp_html += buttons - temp_html += "

Radiation Emitter Menu

" - - temp_html += "-- Output Level ++" - temp_html += "
-- Pulse Duration ++" - - temp_html += "

Irradiate Subject

" - temp_html += "
Unique Identifier:
" - - var/max_line_len = 7*DNA_BLOCK_SIZE - if(viable_occupant) - temp_html += "
1
" - var/len = length(viable_occupant.dna.uni_identity) - for(var/i=1, i<=len, i++) - temp_html += "[copytext(viable_occupant.dna.uni_identity,i,i+1)]" - if ((i % max_line_len) == 0) - temp_html += "
" - if((i % DNA_BLOCK_SIZE) == 0 && i < len) - temp_html += "
[(i / DNA_BLOCK_SIZE) + 1]
" - else - temp_html += "----" - temp_html += "

" - - temp_html += "
Structural Enzymes:
" - if(viable_occupant) - temp_html += "
1
" - var/len = length(viable_occupant.dna.struc_enzymes) - for(var/i=1, i<=len, i++) - temp_html += "[copytext(viable_occupant.dna.struc_enzymes,i,i+1)]" - if ((i % max_line_len) == 0) - temp_html += "
" - if((i % DNA_BLOCK_SIZE) == 0 && i < len) - temp_html += "
[(i / DNA_BLOCK_SIZE) + 1]
" - else - temp_html += "----" - temp_html += "
" - - popup.set_content(temp_html) - popup.open() - - -/obj/machinery/computer/scan_consolenew/Topic(href, href_list) - if(..()) - return - if(!isturf(usr.loc)) - return - if(!( (isturf(loc) && in_range(src, usr)) || istype(usr, /mob/living/silicon) )) - return - if(current_screen == "working") - return - - add_fingerprint(usr) - usr.set_machine(src) - - var/mob/living/carbon/viable_occupant - if(connected) - viable_occupant = connected.occupant - if(!istype(viable_occupant) || !viable_occupant.dna || (viable_occupant.disabilities & NOCLONE)) - viable_occupant = null - - //Basic Tasks/////////////////////////////////////////// - var/num = round(text2num(href_list["num"])) - var/last_change - switch(href_list["task"]) - if("togglelock") - if(connected) connected.locked = !connected.locked - if("toggleopen") - if(connected) connected.toggle_open(usr) - if("setduration") - if(!num) - num = round(input(usr, "Choose pulse duration:", "Input an Integer", null) as num|null) - if(num) - radduration = Wrap(num, 1, RADIATION_DURATION_MAX+1) - if("setstrength") - if(!num) - num = round(input(usr, "Choose pulse strength:", "Input an Integer", null) as num|null) - if(num) - radstrength = Wrap(num, 1, RADIATION_STRENGTH_MAX+1) - if("screen") - current_screen = href_list["text"] - if("rejuv") - if(viable_occupant && viable_occupant.reagents) - var/epinephrine_amount = viable_occupant.reagents.get_reagent_amount("epinephrine") - var/can_add = max(min(REJUVENATORS_MAX - epinephrine_amount, REJUVENATORS_INJECT), 0) - viable_occupant.reagents.add_reagent("epinephrine", can_add) - if("setbufferlabel") - var/text = sanitize(input(usr, "Input a new label:", "Input an Text", null) as text|null) - if(num && text) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) - var/list/buffer_slot = buffer[num] - if(istype(buffer_slot)) - buffer_slot["label"] = text - if("setbuffer") - if(num && viable_occupant) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) - buffer[num] = list( - "label"="Buffer[num]:[viable_occupant.real_name]", - "UI"=viable_occupant.dna.uni_identity, - "SE"=viable_occupant.dna.struc_enzymes, - "UE"=viable_occupant.dna.unique_enzymes, - "name"=viable_occupant.real_name, - "blood_type"=viable_occupant.dna.blood_type - ) - if("clearbuffer") - if(num) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) - var/list/buffer_slot = buffer[num] - if(istype(buffer_slot)) - buffer_slot.Cut() - if("transferbuffer") - if(num && viable_occupant && viable_occupant.stat != DEAD) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) - var/list/buffer_slot = buffer[num] - if(istype(buffer_slot)) //15 and 40 are just magic numbers that were here before so i didnt touch them, they are initial boundaries of damage - viable_occupant.radiation += rand(15/(connected.damage_coeff ** 2),40/(connected.damage_coeff ** 2)) //Each laser level reduces damage by lvl^2, so no effect on 1 lvl, 4 times less damage on 2 and 9 times less damage on 3 - switch(href_list["text"]) //Numbers are this high because other way upgrading laser is just not worth the hassle, and i cant think of anything better to inmrove - if("se") - if(buffer_slot["SE"]) - viable_occupant.dna.struc_enzymes = buffer_slot["SE"] - domutcheck(viable_occupant) - if("ui") - if(buffer_slot["UI"]) - viable_occupant.dna.uni_identity = buffer_slot["UI"] - updateappearance(viable_occupant) - else - if(buffer_slot["name"] && buffer_slot["UE"] && buffer_slot["blood_type"]) - viable_occupant.real_name = buffer_slot["name"] - viable_occupant.name = buffer_slot["name"] - viable_occupant.dna.unique_enzymes = buffer_slot["UE"] - viable_occupant.dna.blood_type = buffer_slot["blood_type"] - updateappearance(viable_occupant) - if("injector") - if(num && injectorready) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) - var/list/buffer_slot = buffer[num] - if(istype(buffer_slot)) - var/obj/item/weapon/dnainjector/I - switch(href_list["text"]) - if("se") - if(buffer_slot["SE"]) - I = new /obj/item/weapon/dnainjector(loc) - for(var/datum/mutation/human/HM in good_mutations + bad_mutations + not_good_mutations) - if(HM.check_block_string(buffer_slot["SE"])) - if(prob(HM.get_chance)) - I.add_mutations.Add(HM) - else - I.remove_mutations.Add(HM) - I.damage_coeff = connected.damage_coeff - if("ui") - if(buffer_slot["UI"]) - I = new /obj/item/weapon/dnainjector(loc) - I.fields = list("UI"=buffer_slot["UI"]) - I.damage_coeff = connected.damage_coeff - else - if(buffer_slot["name"] && buffer_slot["UE"] && buffer_slot["blood_type"]) - I = new /obj/item/weapon/dnainjector(loc) - I.fields = list("name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "blood_type"=buffer_slot["blood_type"]) - I.damage_coeff = connected.damage_coeff - if(I) - injectorready = 0 - spawn(INJECTOR_TIMEOUT) - injectorready = 1 - if("loaddisk") - if(num && diskette && diskette.fields) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) - buffer[num] = diskette.fields.Copy() - if("savedisk") - if(num && diskette && !diskette.read_only) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) - var/list/buffer_slot = buffer[num] - if(istype(buffer_slot)) - diskette.name = "data disk \[[buffer_slot["label"]]\]" - diskette.fields = buffer_slot.Copy() - if("ejectdisk") - if(diskette) - diskette.loc = get_turf(src) - diskette = null - if("pulseui","pulsese") - if(num && viable_occupant && connected && viable_occupant.stat != DEAD) - radduration = Wrap(radduration, 1, RADIATION_DURATION_MAX+1) - radstrength = Wrap(radstrength, 1, RADIATION_STRENGTH_MAX+1) - - var/locked_state = connected.locked - connected.locked = 1 - - current_screen = "working" - ShowInterface(usr) - - sleep(radduration*10) - current_screen = "mainmenu" - - if(viable_occupant && connected && connected.occupant==viable_occupant) - viable_occupant.radiation += (RADIATION_IRRADIATION_MULTIPLIER*radduration*radstrength)/(connected.damage_coeff ** 2) //Read comment in "transferbuffer" section above for explanation - switch(href_list["task"]) //Same thing as there but values are even lower, on best part they are about 0.0*, effectively no damage - if("pulseui") - var/len = length(viable_occupant.dna.uni_identity) - num = Wrap(num, 1, len+1) - num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len) //Each manipulator level above 1 makes randomization as accurate as selected time + manipulator lvl^2 - //Value is this high for the same reason as with laser - not worth the hassle of upgrading if the bonus is low - var/block = round((num-1)/DNA_BLOCK_SIZE)+1 - var/subblock = num - block*DNA_BLOCK_SIZE - last_change = "UI #[block]-[subblock]; " - - var/hex = copytext(viable_occupant.dna.uni_identity, num, num+1) - last_change += "[hex]" - hex = scramble(hex, radstrength, radduration) - last_change += "->[hex]" - - viable_occupant.dna.uni_identity = copytext(viable_occupant.dna.uni_identity, 1, num) + hex + copytext(viable_occupant.dna.uni_identity, num+1, 0) - updateappearance(viable_occupant) - if("pulsese") - var/len = length(viable_occupant.dna.struc_enzymes) - num = Wrap(num, 1, len+1) - num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len) - - var/block = round((num-1)/DNA_BLOCK_SIZE)+1 - var/subblock = num - block*DNA_BLOCK_SIZE - last_change = "SE #[block]-[subblock]; " - - var/hex = copytext(viable_occupant.dna.struc_enzymes, num, num+1) - last_change += "[hex]" - hex = scramble(hex, radstrength, radduration) - last_change += "->[hex]" - - viable_occupant.dna.struc_enzymes = copytext(viable_occupant.dna.struc_enzymes, 1, num) + hex + copytext(viable_occupant.dna.struc_enzymes, num+1, 0) - domutcheck(viable_occupant) - else - current_screen = "mainmenu" - - if(connected) - connected.locked = locked_state - - ShowInterface(usr,last_change) - - -/////////////////////////// DNA MACHINES -#undef INJECTOR_TIMEOUT -#undef REJUVENATORS_INJECT -#undef REJUVENATORS_MAX -#undef NUMBER_OF_BUFFERS - -#undef RADIATION_STRENGTH_MAX -#undef RADIATION_STRENGTH_MULTIPLIER - -#undef RADIATION_DURATION_MAX -#undef RADIATION_ACCURACY_MULTIPLIER - -#undef RADIATION_IRRADIATION_MULTIPLIER - -//#undef BAD_MUTATION_DIFFICULTY -//#undef GOOD_MUTATION_DIFFICULTY -//#undef OP_MUTATION_DIFFICULTY - //value in range 1 to values. values must be greater than 0 //all arguments assumed to be positive integers /proc/construct_block(value, values, blocksize=DNA_BLOCK_SIZE) @@ -968,10 +340,4 @@ value = values return value - -/datum/dna/proc/is_same_as(datum/dna/D) - if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name) - if(species == D.species && features == D.features && blood_type == D.blood_type) - return 1 - return 0 - +/////////////////////////// DNA HELPER-PROCS \ No newline at end of file diff --git a/code/game/gamemodes/abduction/abduction.dm b/code/game/gamemodes/abduction/abduction.dm index 0b710001f38..1151de4f55f 100644 --- a/code/game/gamemodes/abduction/abduction.dm +++ b/code/game/gamemodes/abduction/abduction.dm @@ -107,7 +107,7 @@ H = agent.current L = agent_landmarks[team_number] H.loc = L.loc - hardset_dna(H, null, null, null, null, /datum/species/abductor) + H.set_species(/datum/species/abductor) S = H.dna.species S.agent = 1 S.team = team_number @@ -115,13 +115,12 @@ equip_common(H,team_number) equip_agent(H,team_number) greet_agent(agent,team_number) - H.regenerate_icons() scientist = scientists[team_number] H = scientist.current L = scientist_landmarks[team_number] H.loc = L.loc - hardset_dna(H, null, null, null, null, /datum/species/abductor) + H.set_species(/datum/species/abductor) S = H.dna.species S.scientist = 1 S.team = team_number @@ -129,7 +128,6 @@ equip_common(H,team_number) equip_scientist(H,team_number) greet_scientist(scientist,team_number) - H.regenerate_icons() return ..() //Used for create antag buttons @@ -156,7 +154,7 @@ H = agent.current L = agent_landmarks[team_number] H.loc = L.loc - hardset_dna(H, null, null, null, null, /datum/species/abductor) + H.set_species(/datum/species/abductor) S = H.dna.species S.agent = 1 S.team = team_number @@ -164,13 +162,13 @@ equip_common(H,team_number) equip_agent(H,team_number) greet_agent(agent,team_number) - H.regenerate_icons() + scientist = scientists[team_number] H = scientist.current L = scientist_landmarks[team_number] H.loc = L.loc - hardset_dna(H, null, null, null, null, /datum/species/abductor) + H.set_species(/datum/species/abductor) S = H.dna.species S.scientist = 1 S.team = team_number @@ -178,7 +176,7 @@ equip_common(H,team_number) equip_scientist(H,team_number) greet_scientist(scientist,team_number) - H.regenerate_icons() + /datum/game_mode/abduction/proc/greet_agent(datum/mind/abductor,team_number) @@ -332,7 +330,7 @@ if(!owner.current || !ishuman(owner.current)) return 0 var/mob/living/carbon/human/H = owner.current - if(!H.dna || !H.dna.species || !(H.dna.species.id == "abductor")) + if(H.dna.species.id != "abductor") return 0 var/datum/species/abductor/S = H.dna.species ab_team = S.team diff --git a/code/game/gamemodes/abduction/abduction_gear.dm b/code/game/gamemodes/abduction/abduction_gear.dm index 0793989952f..94966530738 100644 --- a/code/game/gamemodes/abduction/abduction_gear.dm +++ b/code/game/gamemodes/abduction/abduction_gear.dm @@ -288,7 +288,7 @@ var/obj/machinery/abductor/console/console if(ishuman(source)) var/mob/living/carbon/human/H = source - if(H.dna && istype(H.dna.species, /datum/species/abductor)) + if(H.dna.species.id == "abductor") var/datum/species/abductor/S = H.dna.species console = get_team_console(S.team) home = console.pad @@ -405,8 +405,6 @@ Congratulations! You are now trained for xenobiology research!"} if(!ishuman(user)) return 0 var/mob/living/carbon/human/H = user - if(!H.dna) - return 0 if(H.dna.species.id != "abductor") return 0 return 1 @@ -499,8 +497,7 @@ Congratulations! You are now trained for xenobiology research!"} if(ishuman(L)) var/mob/living/carbon/human/H = L - if(H.dna && H.dna.species) - species = "[H.dna.species.name]" + species = "[H.dna.species.name]" if(L.mind && L.mind.changeling) species = "Changeling lifeform" var/obj/item/organ/internal/gland/temp = locate() in H.internal_organs diff --git a/code/game/gamemodes/abduction/abduction_surgery.dm b/code/game/gamemodes/abduction/abduction_surgery.dm index f22f188945b..a97011d53db 100644 --- a/code/game/gamemodes/abduction/abduction_surgery.dm +++ b/code/game/gamemodes/abduction/abduction_surgery.dm @@ -8,7 +8,7 @@ if(!ishuman(user)) return 0 var/mob/living/carbon/human/H = user - if(H.dna && istype(H.dna.species, /datum/species/abductor)) + if(H.dna.species.id == "abductor") return 1 if((locate(/obj/item/weapon/implant/abductor) in H)) return 1 diff --git a/code/game/gamemodes/abduction/gland.dm b/code/game/gamemodes/abduction/gland.dm index fd2ecdcce4c..db0aa0c32dc 100644 --- a/code/game/gamemodes/abduction/gland.dm +++ b/code/game/gamemodes/abduction/gland.dm @@ -120,9 +120,7 @@ /obj/item/organ/internal/gland/pop/activate() owner << "You feel unlike yourself." var/species = pick(list(/datum/species/lizard,/datum/species/slime,/datum/species/plant/pod,/datum/species/fly)) - hardset_dna(owner, null, null, null, null, species) - owner.regenerate_icons() - return + owner.set_species(species) /obj/item/organ/internal/gland/ventcrawling origin_tech = "materials=4;biotech=5;bluespace=3" @@ -241,7 +239,7 @@ /obj/effect/cocoon/abductor/proc/Copy(mob/living/carbon/human/H) var/mob/living/carbon/human/interactive/greytide/clone = new(src) - hardset_dna(clone,H.dna.uni_identity,H.dna.struc_enzymes,H.real_name, H.dna.blood_type, H.dna.species.type, H.dna.features) + clone.hardset_dna(H.dna.uni_identity,H.dna.struc_enzymes,H.real_name, H.dna.blood_type, H.dna.species.type, H.dna.features) //There's no define for this / get all items ? var/list/slots = list(slot_back,slot_w_uniform,slot_wear_suit,\ diff --git a/code/game/gamemodes/abduction/machinery/console.dm b/code/game/gamemodes/abduction/machinery/console.dm index 725ebf46091..24f17a5ce92 100644 --- a/code/game/gamemodes/abduction/machinery/console.dm +++ b/code/game/gamemodes/abduction/machinery/console.dm @@ -4,8 +4,6 @@ var/team = 0 /obj/machinery/abductor/proc/IsAbductor(mob/living/carbon/human/H) - if(!H.dna) - return 0 return H.dna.species.id == "abductor" /obj/machinery/abductor/proc/IsAgent(mob/living/carbon/human/H) diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index 78e195f331c..722f1bce2af 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -98,6 +98,7 @@ M.mind.name = newname M.real_name = newname M.name = newname + M.dna.update_dna_identity() var/datum/objective/protect/new_objective = new /datum/objective/protect new_objective.owner = M:mind new_objective:target = usr:mind diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index a88707f19cc..119d38f0645 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -346,7 +346,8 @@ var/list/slot2type = list("head" = /obj/item/clothing/head/changeling, "wear_mas return if(has_dna(target.dna)) user << "We already have this DNA in storage!" - if(!check_dna_integrity(target)) + return + if(!target.has_dna()) user << "[target] is not compatible with our biology." return return 1 @@ -405,10 +406,9 @@ var/list/slot2type = list("head" = /obj/item/clothing/head/changeling, "wear_mas /proc/changeling_transform(var/mob/living/carbon/human/user, var/datum/changelingprofile/chosen_prof) var/datum/dna/chosen_dna = chosen_prof.dna user.real_name = chosen_prof.name - user.dna = chosen_dna - hardset_dna(user, null, null, null, null, chosen_dna.species.type, chosen_dna.features) - domutcheck(user) - updateappearance(user) + chosen_dna.transfer_identity(user, 1) + user.updateappearance(mutcolor_update=1) + user.domutcheck() //vars hackery. not pretty, but better than the alternative. for(var/slot in slots) diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm index e42e1fad641..d9f6faa9457 100644 --- a/code/game/gamemodes/changeling/evolution_menu.dm +++ b/code/game/gamemodes/changeling/evolution_menu.dm @@ -388,8 +388,6 @@ var/list/sting_paths /mob/proc/remove_changeling_powers(keep_free_powers=0) if(ishuman(src) || ismonkey(src)) if(mind && mind.changeling) - digitalcamo = 0 - digitalinvis = 0 mind.changeling.changeling_speak = 0 mind.changeling.reset() for(var/obj/effect/proc_holder/changeling/p in mind.changeling.purchasedpowers) diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 054035f2e14..2d8316edfa5 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -130,7 +130,7 @@ if((target.disabilities & NOCLONE) || (target.disabilities & HUSK)) user << "DNA of [target] is ruined beyond usability!" return - if(!check_dna_integrity(target) || !ishuman(target)) + if(!ishuman(target)) user << "[target] is not compatible with this ability." return return 1 diff --git a/code/game/gamemodes/changeling/powers/chameleon_skin.dm b/code/game/gamemodes/changeling/powers/chameleon_skin.dm index 36b7ba87339..f39505fa712 100644 --- a/code/game/gamemodes/changeling/powers/chameleon_skin.dm +++ b/code/game/gamemodes/changeling/powers/chameleon_skin.dm @@ -10,17 +10,21 @@ /obj/effect/proc_holder/changeling/chameleon_skin/sting_action(mob/user) - var/mob/living/carbon/human/H = user //SHOULD always be human, because req_human = 1 - if(!istype(H)) + var/mob/living/carbon/human/H = user //SHOULD always be human, because req_human = 1 //phil235 so why is it needd? + if(!istype(H)) // req_human could be done in can_sting stuff. return var/datum/mutation/human/HM = mutations_list[CHAMELEON] - if(H.dna && H.dna.mutations) - if(HM in H.dna.mutations) - HM.force_lose(H) - else - HM.force_give(H) + if(HM in H.dna.mutations) + HM.force_lose(H) + else + HM.force_give(H) feedback_add_details("changeling_powers","CS") return 1 - +/obj/effect/proc_holder/changeling/chameleon_skin/on_refund(mob/user) + if(user.has_dna()) + var/mob/living/carbon/C = user + var/datum/mutation/human/HM = mutations_list[CHAMELEON] + if(HM in C.dna.mutations) + HM.force_lose(C) \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/digitalcamo.dm b/code/game/gamemodes/changeling/powers/digitalcamo.dm index 13bf62bdbc4..79651c98a97 100644 --- a/code/game/gamemodes/changeling/powers/digitalcamo.dm +++ b/code/game/gamemodes/changeling/powers/digitalcamo.dm @@ -18,3 +18,7 @@ feedback_add_details("changeling_powers","CAM") return 1 + +/obj/effect/proc_holder/changeling/digitalcamo/on_refund(mob/user) + user.digitalcamo = 0 + user.digitalinvis = 0 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/humanform.dm b/code/game/gamemodes/changeling/powers/humanform.dm index 04d36c169ac..5fde1238159 100644 --- a/code/game/gamemodes/changeling/powers/humanform.dm +++ b/code/game/gamemodes/changeling/powers/humanform.dm @@ -24,12 +24,11 @@ if(!user || user.notransform) return 0 user << "We transform our appearance." - - user.humanize((TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPSRC), chosen_prof.name) - - changeling_transform(user, chosen_prof) changeling.purchasedpowers -= src + + var/newmob = user.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS) + + changeling_transform(newmob, chosen_prof) feedback_add_details("changeling_powers","LFT") - qdel(user) return 1 diff --git a/code/game/gamemodes/changeling/powers/lesserform.dm b/code/game/gamemodes/changeling/powers/lesserform.dm index 2ce8470c19c..05406b02bdf 100644 --- a/code/game/gamemodes/changeling/powers/lesserform.dm +++ b/code/game/gamemodes/changeling/powers/lesserform.dm @@ -12,9 +12,7 @@ return 0 user << "Our genes cry out!" - user.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPSE | TR_KEEPSRC) + user.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) - // Human-form power now handled in monkeyize() feedback_add_details("changeling_powers","LF") - .=1 - qdel(user) \ No newline at end of file + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index 71e6512b68b..1efb76bef3c 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -21,20 +21,23 @@ var/weapon_name_simple /obj/effect/proc_holder/changeling/weapon/try_to_sting(mob/user, mob/target) - if(istype(user.l_hand, weapon_type)) //Not the nicest way to do it, but eh - playsound(user, 'sound/effects/blobattack.ogg', 30, 1) - qdel(user.l_hand) - user.visible_message("With a sickening crunch, [user] reforms their [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "With a sickening crunch, [user] reforms their [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "With a sickening crunch, [user] reforms their [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "The [user.get_active_hand()] is stuck to your hand, you cannot grow a [weapon_name_simple] over it!" @@ -44,6 +47,10 @@ playsound(user, 'sound/effects/blobattack.ogg', 30, 1) return W +/obj/effect/proc_holder/changeling/weapon/on_refund(mob/user) + check_weapon(user, user.r_hand, 1) + check_weapon(user, user.l_hand, 0) + //Parent to space suits and armor. /obj/effect/proc_holder/changeling/suit name = "Organic Suit" @@ -61,10 +68,16 @@ var/blood_on_castoff = 0 /obj/effect/proc_holder/changeling/suit/try_to_sting(mob/user, mob/target) + if(check_suit(user)) + return + var/mob/living/carbon/human/H = user + ..(H, target) + +//checks if we already have an organic suit and casts it off. +/obj/effect/proc_holder/changeling/suit/proc/check_suit(mob/user) var/datum/changeling/changeling = user.mind.changeling if(!ishuman(user) || !changeling) - return - + return 1 var/mob/living/carbon/human/H = user if(istype(H.wear_suit, suit_type) || istype(H.head, helmet_type)) H.visible_message("[H] casts off their [suit_name_simple]!", "We cast off our [suit_name_simple][genetic_damage > 0 ? ", temporarily weakening our genomes." : "."]", "You hear the organic matter ripping and tearing!") @@ -82,8 +95,13 @@ changeling.geneticdamage += genetic_damage //Casting off a space suit leaves you weak for a few seconds. changeling.chem_recharge_slowdown -= recharge_slowdown + return 1 + +/obj/effect/proc_holder/changeling/suit/on_refund(mob/user) + if(!ishuman(user)) return - ..(H, target) + var/mob/living/carbon/human/H = user + check_suit(H) /obj/effect/proc_holder/changeling/suit/sting_action(mob/living/carbon/human/user) if(!user.canUnEquip(user.wear_suit)) diff --git a/code/game/gamemodes/changeling/powers/panacea.dm b/code/game/gamemodes/changeling/powers/panacea.dm index 672d3b5f594..14f751ec5b4 100644 --- a/code/game/gamemodes/changeling/powers/panacea.dm +++ b/code/game/gamemodes/changeling/powers/panacea.dm @@ -15,6 +15,9 @@ for(var/datum/disease/D in user.viruses) D.cure() - + for(var/obj/item/organ/internal/I in user) + if(istype(I,/obj/item/organ/internal/body_egg/alien_embryo)) + I.Remove(user) + I.loc = get_turf(user) feedback_add_details("changeling_powers","AP") return 1 diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm index 5cd021fff74..a94ff6fc68e 100644 --- a/code/game/gamemodes/changeling/powers/tiny_prick.dm +++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm @@ -81,7 +81,7 @@ /obj/effect/proc_holder/changeling/sting/transformation/can_sting(mob/user, mob/target) if(!..()) return - if((target.disabilities & HUSK) || !check_dna_integrity(target)) + if((target.disabilities & HUSK) || !target.has_dna()) user << "Our sting appears ineffective against its DNA." return 0 return 1 @@ -92,15 +92,17 @@ if(ismonkey(target)) user << "Our genes cry out as we sting [target.name]!" - if(iscarbon(target) && (target.status_flags & CANWEAKEN)) + if(iscarbon(target)) var/mob/living/carbon/C = target - C.do_jitter_animation(500) - C.take_organ_damage(20, 0) //The process is extremely painful + if(C.status_flags & CANWEAKEN) + C.do_jitter_animation(500) + C.take_organ_damage(20, 0) //The process is extremely painful - target.visible_message("[target] begins to violenty convulse!","You feel a tiny prick and a begin to uncontrollably convulse!") - spawn(10) - hardset_dna(target, NewDNA.uni_identity, NewDNA.struc_enzymes, NewDNA.real_name, NewDNA.blood_type, NewDNA.species.type, NewDNA.features) - updateappearance(target) + target.visible_message("[target] begins to violenty convulse!","You feel a tiny prick and a begin to uncontrollably convulse!") + spawn(10) + NewDNA.transfer_identity(C, transfer_SE=1) + C.updateappearance(mutcolor_update=1) + C.domutcheck() feedback_add_details("changeling_powers","TS") return 1 @@ -125,7 +127,7 @@ /obj/effect/proc_holder/changeling/sting/false_armblade/can_sting(mob/user, mob/target) if(!..()) return - if((target.disabilities & HUSK) || !check_dna_integrity(target)) + if((target.disabilities & HUSK) || !target.has_dna()) user << "Our sting appears ineffective against its DNA." return 0 return 1 diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 9c3bf83d20c..eb56a644fb6 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -92,7 +92,8 @@ if(config.protect_assistant_from_antagonist) restricted_jobs += "Assistant" - acolytes_needed = max(2, round(num_players()/5)) //Scales the escape requirement with the amount of people in the round + 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 for(var/cultists_number = 1 to recommended_enemies) if(!antag_candidates.len) @@ -141,11 +142,11 @@ 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 Rite of Tribute and three acolytes to do so." + 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 use of the Ritual of Dimensional Rending. It will only work if nine cultists stand on and around it." + 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 << "Objective #[obj_count]: [explanation]" cult_mind.memory += "Objective #[obj_count]: [explanation]
" @@ -171,7 +172,7 @@ if(!where) mob << "Unfortunately, you weren't able to get a talisman. This is very bad and you should adminhelp immediately." else - mob << "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." + mob << "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." mob.update_icons() if(where == "backpack") var/obj/item/weapon/storage/B = mob.back @@ -203,13 +204,13 @@ cult -= cult_mind cult_mind.current.verbs -= /mob/living/proc/cult_innate_comm cult_mind.current.Paralyse(5) - cult_mind.current << "An unfamiliar white light flashes through your mind, cleansing the taint of the dark-one and the memories of your time as his servant with it." + cult_mind.current << "An unfamiliar white light flashes through your mind, cleansing the taint of the Dark One and all your memories as its servant." cult_mind.memory = "" update_cult_icons_removed(cult_mind) cult_mind.current.attack_log += "\[[time_stamp()]\] Has renounced the cult!" if(show_message) for(var/mob/M in viewers(cult_mind.current)) - M << "[cult_mind.current] looks like they just reverted to their old faith!" + M << "[cult_mind.current] looks like they just reverted to their old faith!" /datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind) var/datum/atom_hud/antag/culthud = huds[ANTAG_HUD_CULT] @@ -259,7 +260,7 @@ if(!check_cult_victory()) feedback_set_details("round_end_result","win - cult win") feedback_set("round_end_result",acolytes_survived) - world << "The cult wins! It has succeeded in serving its dark masters!" + world << "The cult wins! It has succeeded in serving its dark master!" else feedback_set_details("round_end_result","loss - staff stopped the cult") feedback_set("round_end_result",acolytes_survived) diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 000120ef61a..33c36715fc3 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -138,83 +138,82 @@ It also contains rune words, which are soon to be removed. Rite of Knowledge: \"karazet nahlizet ego\"
\


"*/ - text += "Rite of Translocation
The Rite of Translocation is a unique rite in that it requires a keyword before the scribing can begin. When invoked, the rune will \ + text += "Teleport
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 \ with the same keyword, it will choose randomly between all eligible runes and send the invoker to one of them.

" - text += "Rite of Forced Translocation
The Rite of Forced Translocation, like the Rite of Translocation, works by teleporting the person on the rune to one of the \ + text += "Teleport Other
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.

" - text += "Rite of Knowledge
The Rite of Knowledge is a simplistic rune. When invoked, it will summon a single arcane tome to the rune's location before vanishing. \ + text += "Summon Tome
The Rite of Knowledge is a simplistic rune. When invoked, it will summon a single arcane tome to the rune's location before vanishing. \

" - text += "Rite of Enlightenment
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 may take some time, depending on the amount of cultists nearby. It takes twenty seconds, with each additional cultist shaving \ - off ten seconds of the conversion. With three or more cultists, conversion is instantaneous. Once invoked, only the original user must remain. If the target is loyalty-implanted or has a null rod in \ - their possession, this will not work.

" + text += "Convert
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 a null rod will not be converted.

" - text += "Rite of Tribute
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 \ + text += "Sacrifice
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.

" - text += "Rite of Resurrection
The Rite of Resurrection is a delicate rite that requires two corpses. To perform the ritual, place the corpse you wish to revive onto \ + text += "Raise Dead
The Rite of Resurrection is a delicate rite that requires two corpses. To perform the ritual, place the corpse you wish to revive onto \ the rune and the offering body adjacent to it. When the rune is invoked, the body to be sacrificed will turn to ashes, the life force flowing into the revival target. Assuming the target is not moved \ within a few seconds, they will be brought back to life, healed of all ailments.

" - text += "Rite of Obscurity
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 \ + text += "Veil Runes
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 is unusuable directly.

" - text += "Rite of True Sight
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 \ + text += "Reveal Runes
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 partially corporeal.

" - text += "Rite of False Truths
Many crew men enjoy drawing runes in crayon that resemble spell circles in order to play pranks on their fellow crewmen. The Rite of \ + text += "Disguise Runes
Many crew men 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.

" - text += "Rite of Disruption
Robotic lifeforms have time and time again been the downfall of fledgling cults. The Rite of Disruption may allow you to gain the upper \ + text += "Electromagnetic Disruption
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.

" - text += "Rite of Astral Communion
The Rite of Astral Communion is perhaps the most ingenious rune that is usable by a single person. Upon invoking the rune, the \ + text += "Astral Communion
The Rite of Astral Communion is perhaps the most ingenious rune that is usable by a single person. Upon invoking the rune, the \ user's spirit will be ripped from their body. In this state, the user's physical body will be locked in place to the rune itself - any attempts to move it will result in the rune pulling it back. \ The body will also take constant damage while in this form, and may even die. The user's spirit will contain their consciousness, and will allow them to freely wander the station as a ghost. This may \ also be used to commune with the dead.

" - text += "Rite of the Corporeal Shield
While simple, the Rite of the Corporeal Shield serves an important purpose in defense and hindering passage. When invoked, the \ + text += "Form Shield
While simple, the Rite of the Corporeal Shield serves an important purpose in defense and hindering passage. When invoked, the \ 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.

" - text += "Rite of the Unheard Whisper
The Rite of the Unheard Whisper is simple. When invoked, it will cause all non-cultists within a radius of seven tiles to become \ + text += "Deafen
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.

" - text += "Rite of the Unseen Glance
Much like the Rite of the Unheard Whisper, the Rite of the Unseen Glance serves a single purpose. Any non-cultists who can see \ + text += "Blind
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.

" - text += "Rite of Disorientation
A somewhat empowered version of the Rite of the Unseen Glance, this rune will cause any non-cultists that can see the rune to become \ + text += "Stun
A somewhat empowered version of the Rite of the Unseen Glance, this rune will cause any non-cultists that can see the rune to become \ disoriented, disabling them for a short time.

" - text += "Rite of Joined Souls
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 \ + text += "Summon Cultist
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.

" - text += "Rite of Binding
The Rite of Binding is the only way to create talismans. A blank sheet of paper must be on top of the rune, with a valid rune nearby. After \ + text += "Imbue Talisman
The Rite of Binding is the only way to create talismans. A blank sheet of paper must be on top of the rune, with a valid rune nearby. After \ invoking it, the paper will be converted into a talisman, and the rune inlaid upon it.

" - text += "Rite of Fabrication
The Rite of Fabrication is the main way of creating construct shells. To use it, one must place five sheets of plasteel on top of the rune \ + text += "Fabricate Shell
The Rite of Fabrication is the main way of creating construct shells. To use it, one must place five sheets of plasteel on top of the rune \ and invoke it. The sheets will them be twisted into a construct shell, ready to recieve a soul to occupy it.

" - text += "Rite of Arming
The Rite of Arming will equip the user with invoker's robes, a backpack, a Nar-Sian longsword, and a pair of boots. Any items that cannot \ + text += "Summon Arnaments
The Rite of Arming will equip the user with invoker's robes, a backpack, a Nar-Sian longsword, and a pair of boots. Any items that cannot \ be equipped will instead not be summoned regardless.

" - text += "Rite of Leeching
The Rite of Leeching will drain the life of any non-cultist above the rune and heal the invoker for the same amount.

" + text += "Drain Life
The Rite of Leeching will drain the life of any non-cultist above the rune and heal the invoker for the same amount.

" - text += "Rite of Boiling Blood
The Rite of Boiling Blood may be considered one of the most dangerous rites composed by the Nar-Sian cult. When invoked, it will do a \ + text += "Boil Blood
The Rite of Boiling Blood may be considered one of the most dangerous rites composed by the Nar-Sian cult. 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

" - text += "Rite of Spectral Manifestation
If you wish to bring a spirit back from the dead with a wish for vengeance and desire to serve, the Rite of Spectral \ + text += "Manifest Spirit
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.

" - text += "Ritual of Dimensional Rending
There is only one way to summon the avatar of Nar-Sie, and that is the Ritual of Dimensional Rending. This ritual, in \ + text += "Call Forth The Geometer
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.


" @@ -222,17 +221,17 @@ It also contains rune words, which are soon to be removed. 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.


" - text += "Talisman of Translocation
The talisman form of the Rite of Translocation will transport the invoker to a randomly chosen rune of the same keyword, then \ + text += "Talisman of Teleportation
The talisman form of the Rite of Translocation will transport the invoker to a randomly chosen rune of the same keyword, then \ disappear.

" - text += "Talisman of Knowledge
This talisman functions identically to the rune. It can be used once, then disappears.

" + text += "Talisman of Tome summoning
This talisman functions identically to the rune. It can be used once, then disappears.

" - text += "Talismans of Obscurity, True Sight, and False Truths
These talismans all function identically to their rune counterparts, but with less range. In addition, \ + text += "Talismans of Veiling, Revealing, and Disguising
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.

" - text += "Talisman of Disruption
This talisman functions like the Rite of Disruption, but with halved range. It disappears after one use.

" + text += "Talisman of Electromagnets
This talisman functions like the Rite of Disruption. It disappears after one use.

" - text += "Talisman of Disorientation
Without this talisman, the cult would have no way of easily acquiring targets to convert. Commonly called \"stunpapers\", this \ + text += "Talisman of Stunning
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." @@ -269,7 +268,7 @@ It also contains rune words, which are soon to be removed. "You slice open your arm and begin drawing a sigil of the Geometer.") if(iscarbon(user)) var/mob/living/carbon/C = user - C.apply_damage(1, BRUTE, pick("l_arm", "r_arm")) + C.apply_damage(0.1, BRUTE, pick("l_arm", "r_arm")) if(!do_after(user, 50, target = get_turf(user))) return user.visible_message("[user] creates a strange circle in their own blood.", \ diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 7ee742718c1..d9ce858c153 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -171,7 +171,7 @@ structure_check() searches for nearby cultist structures required for the invoca var/list/teleport_runes = list() //Rite of Translocation: Warps the user to a random teleport rune with the same keyword. /obj/effect/rune/teleport - cultist_name = "Rite of Translocation" + cultist_name = "Teleport" cultist_desc = "Warps the user to a random rune of the same keyword." invocation = "Sas'so c'arta forbici!" icon_state = "2" @@ -210,7 +210,7 @@ var/list/teleport_runes = list() var/list/teleport_other_runes = list() //Rite of Forced Translocation: Warps the target to a random teleport rune with the same keyword. /obj/effect/rune/teleport_other - cultist_name = "Rite of Forced Translocation" + cultist_name = "Teleport Other" cultist_desc = "Warps the target to a random rune of the same keyword." invocation = "Sas'so c'arta forbica!" icon_state = "1" @@ -266,8 +266,8 @@ var/list/teleport_other_runes = list() //Rite of Knowledge: Creates an arcane tome at the rune's location and destroys the rune. /obj/effect/rune/summon_tome - cultist_name = "Rite of Knowledge" - cultist_desc = "Pulls an unstranslated arcane tome from the archives of the Geometer." + 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) @@ -281,12 +281,13 @@ var/list/teleport_other_runes = list() //Rite of Enlightenment: Converts a normal crewmember to the cult. Faster for every cultist nearby. /obj/effect/rune/convert - cultist_name = "Rite of Enlightenment" + 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() @@ -308,31 +309,6 @@ var/list/teleport_other_runes = list() if(iscultist(M)) M << "\"I desire this one for myself. SACRIFICE THEM!\"" return - var/time = 300 - for(var/mob/living/M in orange(1,src)) - if(iscultist(M)) - time -= 100 - time = Clamp(time, 0, 300) - if(time) - visible_message("[src] begins to glow with a sinister light...") - for(var/mob/living/M in orange(1,src)) - if(iscultist(M)) - if(M != user) - M << "You have aided [user] in invoking the [cultist_name]. You may now safely depart." - else - M << "You begin the enlightenment of [new_cultist]. This will take [time / 10] seconds and you must stand still." - new_cultist << "Your head begins to ache..." - if(!do_mob(user, new_cultist, time)) - visible_message("[src] reluctantly falls dark.") - new_cultist << "Your headache fades." - return - if(is_sacrifice_target(new_cultist.mind)) - for(var/mob/living/M in orange(1,src)) - if(iscultist(M)) - M << "\"I desire this one for myself. SACRIFICE THEM!\"" - fail_invoke() - log_game("Convert rune failed - convertee is sacrifice target") - return new_cultist.visible_message("[new_cultist] writhes in pain as the markings below them glow a bloody red!", \ "AAAAAAAAAAAAAA-") ticker.mode.add_cultist(new_cultist.mind) @@ -345,14 +321,18 @@ var/list/teleport_other_runes = list() //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 = "Rite of Tribute" + cultist_name = "Sacrifice" cultist_desc = "Sacrifices a crew member to the Geometer. May place them into a soul shard if their spirit remains in their body." icon_state = "3" - invocation = "Barhah hra zar'garis!" + invocation = "Ih wah'kd in teh'tin!" color = rgb(255, 255, 255) grammar = "veri nahlizet certum" var/rune_in_use = 0 +/obj/effect/rune/sacrifice/New() + ..() + icon_state = "[rand(1,6)]" + /obj/effect/rune/sacrifice/invoke(mob/living/user) if(rune_in_use) return @@ -397,28 +377,16 @@ var/list/teleport_other_runes = list() /obj/effect/rune/sacrifice/proc/sac(mob/living/T) var/sacrifice_fulfilled if(T) - if(T.mind) - var/obj/item/device/soulstone/stone = new /obj/item/device/soulstone(get_turf(src)) - if(!stone.transfer_soul("FORCE", T, usr)) //If it cannot be added - qdel(stone) - if(!T) - rune_in_use = 0 - return if(istype(T, /mob/living/simple_animal/pet/dog/corgi)) for(var/mob/living/carbon/C in orange(1,src)) if(iscultist(C)) C << "Even dark gods from another plane have standards, sicko." if(C.reagents) C.reagents.add_reagent("hell_water", 2) - sacrificed.Add(T.mind) - if(is_sacrifice_target(T.mind)) - sacrifice_fulfilled = 1 - if(isrobot(T)) - playsound(T, 'sound/magic/Disable_Tech.ogg', 100, 1) - T.dust() //To prevent the MMI from remaining - else - playsound(T, 'sound/magic/Disintegrate.ogg', 100, 1) - T.gib() + if(T.mind) + sacrificed.Add(T.mind) + if(is_sacrifice_target(T.mind)) + sacrifice_fulfilled = 1 for(var/mob/living/M in orange(1,src)) if(iscultist(M)) if(sacrifice_fulfilled) @@ -428,12 +396,25 @@ var/list/teleport_other_runes = list() M << "\"I accept this sacrifice.\"" else M << "\"I accept this meager sacrifice.\"" + if(T.mind) + var/obj/item/device/soulstone/stone = new /obj/item/device/soulstone(get_turf(src)) + if(!stone.transfer_soul("FORCE", T, usr)) //If it cannot be added + qdel(stone) + if(!T) + rune_in_use = 0 + return + if(isrobot(T)) + playsound(T, 'sound/magic/Disable_Tech.ogg', 100, 1) + T.dust() //To prevent the MMI from remaining + else + playsound(T, 'sound/magic/Disintegrate.ogg', 100, 1) + T.gib() rune_in_use = 0 //Ritual of Dimensional Rending: Calls forth the avatar of Nar-Sie upon the station. /obj/effect/rune/narsie - cultist_name = "Ritual of Dimensional Rending" + cultist_name = "Call Forth The Geometer" cultist_desc = "Tears apart dimensional barriers, calling forth the avatar of the Geometer." invocation = "Tok-lyr rqa'nap g'olt-ulotf!" req_cultists = 9 @@ -489,10 +470,11 @@ var/list/teleport_other_runes = list() //Rite of Resurrection: Requires two corpses. Revives one and gibs the other. /obj/effect/rune/raise_dead - cultist_name = "Rite of Resurrection" + cultist_name = "Raise Dead" cultist_desc = "Requires two corpses. The one placed upon the rune is brought to life, the other is turned to ash." invocation = null //Depends on the name of the user - see below - color = rgb(150, 0, 0) + icon_state = "1" + color = rgb(255, 0, 0) grammar = "nahlizet certum veri" /obj/effect/rune/raise_dead/invoke(mob/living/user) @@ -557,11 +539,11 @@ var/list/teleport_other_runes = list() //Rite of Obscurity: Turns all runes within a 3-tile radius invisible. /obj/effect/rune/hide_runes - cultist_name = "Rite of Obscurity" - cultist_desc = "Turns nearby runes invisible. They can be revealed by using the Rite of True Sight." + cultist_name = "Veil Runes" + cultist_desc = "Turns nearby runes invisible. They can be revealed by using the Reveal Runes rune." invocation = "Kla'atu barada nikt'o!" - icon_state = "3" - color = rgb(255,255,255) + icon_state = "1" + color = rgb(0,0,255) grammar = "geeri karazet nahlizet" /obj/effect/rune/hide_runes/invoke(mob/living/user) @@ -579,11 +561,11 @@ var/list/teleport_other_runes = list() //Rite of True Sight: Turns ghosts and obscured runes visible /obj/effect/rune/true_sight - cultist_name = "Rite of 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 = "6" - color = rgb(255, 162, 33) + icon_state = "4" + color = rgb(255, 255, 255) grammar = "karazet geeri nahlizet" /obj/effect/rune/true_sight/invoke() @@ -599,7 +581,7 @@ var/list/teleport_other_runes = list() //Rite of False Truths: Makes runes appear like crayon ones /obj/effect/rune/make_runes_fake - cultist_name = "Rite of False Truths" + 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" @@ -614,11 +596,11 @@ var/list/teleport_other_runes = list() //Rite of Disruption: Emits an EMP blast. /obj/effect/rune/emp - cultist_name = "Rite of Disruption" + cultist_name = "Electromagnetic Disruption" cultist_desc = "Emits a large electromagnetic pulse, hindering electronics and disabling silicons." invocation = "Ta'gh fara'qha fel d'amar det!" - icon_state = "1" - color = rgb(0, 0, 255) + icon_state = "5" + color = rgb(255, 0, 0) grammar = "mgar karazet balaq" /obj/effect/rune/emp/invoke(mob/living/user) @@ -632,11 +614,11 @@ var/list/teleport_other_runes = list() //Rite of Astral Communion: Separates one's spirit from their body. They will take damage while it is active. /obj/effect/rune/astral - cultist_name = "Rite of Astral Communion" + cultist_name = "Astral Communion" cultist_desc = "Severs the link between one's spirit and body. This effect is taxing and one's physical body will take damage while this is active." invocation = "Fwe'sh mah erl nyag r'ya!" - icon_state = "1" - color = rgb(68, 47, 255) + icon_state = "6" + color = rgb(0, 0, 255) var/rune_in_use = 0 //One at a time, please! var/mob/living/affecting = null grammar = "veri ire ego" @@ -702,10 +684,11 @@ var/list/teleport_other_runes = list() //Rite of the Corporeal Shield: When invoked, becomes solid and cannot be passed. Invoke again to undo. /obj/effect/rune/wall - cultist_name = "Rite of the Corporeal Shield" + cultist_name = "Form Shield" cultist_desc = "When invoked, makes the rune block passage. Can be invoked again to reverse this." 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) @@ -724,10 +707,12 @@ var/list/teleport_other_runes = list() //Rite of the Unheard Whisper: Deafens all non-cultists nearby. /obj/effect/rune/deafen - cultist_name = "Rite of the Unheard Whisper" + cultist_name = "Deafen" cultist_desc = "Causes all non-followers nearby to lose their hearing." 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("[src] blurs for a moment before fading away.") @@ -740,11 +725,11 @@ var/list/teleport_other_runes = list() //Rite of the Unseen Glance: Blinds all non-cultists nearby. /obj/effect/rune/blind - cultist_name = "Rite of the Unseen Glance" + cultist_name = "Blind" cultist_desc = "Causes all non-followers nearby to lose their sight." invocation = "Sti kaliesin!" - icon_state = "1" - color = rgb(0, 255, 0) + icon_state = "4" + color = rgb(0, 0, 255) grammar = "mgar jatkaa karazet" /obj/effect/rune/blind/invoke(mob/living/user) @@ -760,11 +745,11 @@ var/list/teleport_other_runes = list() //Rite of Disorientation: Stuns all non-cultists nearby for a brief time /obj/effect/rune/stun - cultist_name = "Rite of Disorientation" + cultist_name = "Stun" cultist_desc = "Stuns all nearby non-followers for a brief time." invocation = "Fuu ma'jin!" icon_state = "2" - color = rgb(150, 0, 255) + color = rgb(100, 0, 100) grammar = "certum geeri balaq" /obj/effect/rune/stun/invoke(mob/living/user) @@ -780,7 +765,7 @@ var/list/teleport_other_runes = list() //Rite of Joined Souls: Summons a single cultist. Requires 2 cultists. /obj/effect/rune/summon - cultist_name = "Rite of Joined Souls" + 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 @@ -817,11 +802,11 @@ var/list/teleport_other_runes = list() //Rite of Binding: Turns a nearby rune and a paper on top of the rune to a talisman, if both are valid. /obj/effect/rune/imbue - cultist_name = "Rite of Binding" + cultist_name = "Bind Talisman" cultist_desc = "Transforms papers and valid runes into talismans." invocation = "H'drak v'loso, mir'kanas verbot!" icon_state = "3" - color = rgb(150, 0, 255) + color = rgb(0, 0, 255) grammar = "veri balaq certum" /obj/effect/rune/imbue/invoke(mob/living/user) @@ -860,18 +845,13 @@ var/list/teleport_other_runes = list() log_game("Talisman Imbue rune failed - chosen rune invalid") return visible_message("[picked_rune] crumbles to dust, and bloody images form themselves on [paper_to_imbue].") - if(iscarbon(user)) - var/mob/living/carbon/C = user - C.apply_damage(5, BRUTE, pick("l_arm", "r_arm")) - else - user.adjustBruteLoss(5) qdel(paper_to_imbue) qdel(picked_rune) //Rite of Fabrication: Creates a construct shell out of 5 metal sheets. /obj/effect/rune/construct_shell - cultist_name = "Rite of Fabrication" + cultist_name = "Fabricate Shell" cultist_desc = "Turns five plasteel sheets into an empty construct shell, suitable for containing a soul shard." invocation = "Ethra p'ni dedol!" icon_state = "5" @@ -900,7 +880,7 @@ var/list/teleport_other_runes = list() //Rite of Arming: Creates cult robes, a trophy rack, and a cult sword on the rune. /obj/effect/rune/armor - cultist_name = "Rite of Arming" + cultist_name = "Summon Arnaments" cultist_desc = "Equips the user with robes, shoes, a backpack, and a longsword. Items that cannot be equipped will not be summoned." invocation = "N'ath reth sh'yro eth draggathnor!" icon_state = "4" @@ -919,7 +899,7 @@ var/list/teleport_other_runes = list() //Rite of Leeching: Deals brute damage to the target and heals the same amount to the invoker. /obj/effect/rune/leeching - cultist_name = "Rite of Leeching" + cultist_name = "Drain Life" cultist_desc = "Drains the life of the target on the rune, restoring it to the user." invocation = "Yu'gular faras desdae. Havas mithum javara. Umathar uf'kal thenar!" //that's a mouthful icon_state = "2" @@ -948,7 +928,7 @@ var/list/teleport_other_runes = list() //Rite of Boiling Blood: Deals extremely high amounts of damage to non-cultists nearby /obj/effect/rune/blood_boil - cultist_name = "Rite of Boiling Blood" + cultist_name = "Boil Blood" cultist_desc = "Boils the blood of non-believers who can see the rune, dealing extreme amounts of damage." invocation = "Dedo ol'btoh!" icon_state = "4" @@ -975,7 +955,7 @@ var/list/teleport_other_runes = list() //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 = "Rite of Spectral Manifestation" + cultist_name = "Manifest Spirit" cultist_desc = "Manifests a spirit as a servant of the Geometer. The invoker must not move from atop the rune, and will take damage for each summoned spirit." invocation = "Gal'h'rfikk harfrandid mud'gib!" //how the fuck do you pronounce this icon_state = "6" diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 2a63281e1fb..bebcf0f2bdc 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -19,6 +19,7 @@ Rite of Disorientation var/cultist_desc = "A basic talisman. It serves no purpose." var/invocation = "Naise meam!" var/uses = 1 + var/health_cost = 0 //The amount of health taken from the user when invoking the talisman /obj/item/weapon/paper/talisman/examine(mob/user) ..() @@ -40,7 +41,9 @@ Rite of Disorientation qdel(src) /obj/item/weapon/paper/talisman/proc/invoke(mob/living/user) - + if(health_cost && iscarbon(user)) + var/mob/living/carbon/C = user + C.apply_damage(health_cost, BRUTE, pick("l_arm", "r_arm")) //Malformed Talisman: If something goes wrong. /obj/item/weapon/paper/talisman/malformed @@ -124,9 +127,10 @@ Rite of Disorientation //Rite of Translocation: Same as rune /obj/item/weapon/paper/talisman/teleport - cultist_name = "Rite of Translocation" + cultist_name = "Talisman of Teleportation" cultist_desc = "A single-use talisman that will teleport a user to a random rune of the same keyword." invocation = "Sas'so c'arta forbici!" + health_cost = 5 var/keyword = "ire" /obj/item/weapon/paper/talisman/teleport/invoke(mob/living/user) @@ -135,7 +139,7 @@ Rite of Disorientation if(R.keyword == src.keyword) possible_runes.Add(R) if(!possible_runes.len) - user << "There are no Rites of Translocation with the same keyword!" + user << "There are no Teleport runes with the same keyword!" log_game("Teleportation talisman failed - no teleport runes of the same keyword") uses++ //To prevent deletion return @@ -151,12 +155,18 @@ Rite of Disorientation spawn(1) //To give the keyword time to change from the imbue rune info += keyword +/obj/item/weapon/paper/talisman/teleport/examine(mob/user) + ..() + if(iscultist(user) && keyword) + user << "Keyword: [keyword]" + //Rite of Knowledge: Same as rune, but has two uses /obj/item/weapon/paper/talisman/summon_tome - cultist_name = "Rite of Knowledge" + cultist_name = "Talisman of Tome Summoning" cultist_desc = "A two-use talisman that will call untranslated tomes 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("Dust flows from [user]'s hand for a moment.", \ @@ -171,9 +181,10 @@ Rite of Disorientation //Rite of Obscurity: Same as rune, but less range /obj/item/weapon/paper/talisman/hide_runes - cultist_name = "Rite of Obscurity" + cultist_name = "Talisman of Veiling" cultist_desc = "A talisman that will make all runes within a small radius invisible." invocation = "Kla'atu barada nikt'o!" + health_cost = 1 /obj/item/weapon/paper/talisman/hide_runes/invoke(mob/living/user) user.visible_message("Dust flows from [user]'s hand.", \ @@ -185,9 +196,10 @@ Rite of Disorientation //Rite of True Sight: Same as rune, but doesn't work on ghosts /obj/item/weapon/paper/talisman/true_sight - cultist_name = "Rite of 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("A flash of light shines from [user]'s hand!", \ @@ -198,9 +210,10 @@ Rite of Disorientation //Rite of False Truths: Same as rune /obj/item/weapon/paper/talisman/make_runes_fake - cultist_name = "Rite of False Truths" + 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("Dust flows from [user]s hand.", \ @@ -211,21 +224,23 @@ Rite of Disorientation //Rite of Disruption: Same as rune, halved radius /obj/item/weapon/paper/talisman/emp - cultist_name = "Rite of Disruption" + cultist_name = "Talisman of Electromagnets" cultist_desc = "A talisman that will cause a moderately-sized electromagnetic pulse." invocation = "Ta'gh fara'qha fel d'amar det!" + health_cost = 5 /obj/item/weapon/paper/talisman/emp/invoke(mob/living/user) - user.visible_message("[user]'s hand glows a bright blue!", \ + user.visible_message("[user]'s hand flashes a bright blue!", \ "You speak the words of the talisman, emitting an EMP blast.") - empulse(src, 2, 4) + 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 = "Rite of Disorientation" + 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 /obj/item/weapon/paper/talisman/stun/attack_self(mob/living/user) user << "To use this talisman, attack the target directly." @@ -254,3 +269,20 @@ Rite of Disorientation qdel(src) return ..() + + +//Rite of Arming: Equips cultist armor on the user, where available +/obj/item/weapon/paper/talisman/armor + cultist_name = "Talisman of Arming" + cultist_desc = "A talisman that will equip the invoker with cultist equipment where available." + invocation = "N'ath reth sh'yro eth draggathnor!" + health_cost = 3 + +/obj/item/weapon/paper/talisman/armor/invoke(mob/living/user) + user.visible_message("Otherworldy objects suddenly appear on [user]!", \ + "You speak the words of the talisman, arming yourself!") + user.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(user), slot_head) + user.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), slot_wear_suit) + user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult/alt(user), slot_shoes) + user.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back) + user.put_in_hands(new /obj/item/weapon/melee/cultblade(user)) diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index a16b2946415..e3ce3bf5ea1 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -147,11 +147,11 @@ var/DNAstring = input("Input DNA string to search for." , "Please Enter String." , "") if(!DNAstring) return - for(var/mob/living/carbon/M in mob_list) - if(!M.dna) + for(var/mob/living/carbon/C in mob_list) + if(!C.dna) continue - if(M.dna.unique_enzymes == DNAstring) - target = M + if(C.dna.unique_enzymes == DNAstring) + target = C break return attack_self() diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index e485a62657d..cb4d5ace22f 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -807,7 +807,7 @@ var/global/list/possible_items_special = list() var/turf/cloc = get_turf(changeling.current) if(cloc && cloc.onCentcom() && (changeling.current.stat != DEAD)) //Living changeling on centcomm.... for(var/name in check_names) //Is he (disguised as) one of the staff? - if(H.dna && H.dna.real_name == name) + if(H.dna.real_name == name) check_names -= name //This staff member is accounted for, remove them, so the team don't succeed by escape as 7 of the same engineer success++ //A living changeling staff member made it to centcomm continue changelings diff --git a/code/game/gamemodes/setupgame.dm b/code/game/gamemodes/setupgame.dm index 2e5721b5fe7..e2a6af4e114 100644 --- a/code/game/gamemodes/setupgame.dm +++ b/code/game/gamemodes/setupgame.dm @@ -1,4 +1,4 @@ -/datum/subsystem/ticker/proc/setupGenetics() +/datum/subsystem/objects/proc/setupGenetics() var/list/avnums = new /list(DNA_STRUC_ENZYMES_BLOCKS) for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++) avnums[i] = i diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index 01cae7b3b94..fbcc07e8296 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -297,7 +297,7 @@ user.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(usr), slot_gloves) user.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(usr), slot_wear_mask) user.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/shadowling(usr), slot_glasses) - hardset_dna(user, null, null, null, null, /datum/species/shadow/ling) + user.set_species(/datum/species/shadow/ling) /obj/effect/proc_holder/spell/targeted/collective_mind //Lets a shadowling bring together their thralls' strength, granting new abilities and a headcount @@ -569,7 +569,7 @@ datum/reagent/shadowling_blindness_smoke //Reagent used for above spell thrallToRevive.visible_message("[thrallToRevive] slowly rises, no longer recognizable as human.", \ "You feel new power flow into you. You have been gifted by your masters. You now closely resemble them. You are empowered in \ darkness but wither slowly in light. In addition, Lesser Glare and Guise have been upgraded into their true forms.") - hardset_dna(thrallToRevive, null, null, null, null, /datum/species/shadow/ling/lesser) + thrallToRevive.set_species(/datum/species/shadow/ling/lesser) thrallToRevive.mind.remove_spell(/obj/effect/proc_holder/spell/targeted/lesser_glare) thrallToRevive.mind.remove_spell(/obj/effect/proc_holder/spell/targeted/lesser_shadow_walk) thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/glare(null)) diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm index 8cbba92304a..3ab3d435b03 100644 --- a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm @@ -84,7 +84,7 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N H.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(H), slot_gloves) H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(H), slot_wear_mask) H.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/shadowling(H), slot_glasses) - hardset_dna(H, null, null, null, null, /datum/species/shadow/ling) //can't be a shadowling without being a shadowling + H.set_species(/datum/species/shadow/ling) //can't be a shadowling without being a shadowling sleep(10) H << "Your powers are awoken. You may now live to your fullest extent. Remember your goal. Cooperate with your thralls and allies." diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 06a94232ece..582eb0ebceb 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -22,9 +22,9 @@ /obj/item/weapon/veilrender/attack_self(mob/user) if(charges > 0) - new /obj/effect/rend(get_turf(usr), spawn_type, spawn_amt, rend_desc, spawn_fast) + new /obj/effect/rend(get_turf(user), spawn_type, spawn_amt, rend_desc, spawn_fast) charges-- - user.visible_message("[src] hums with power as [usr] deals a blow to [activate_descriptor] itself!") + user.visible_message("[src] hums with power as [user] deals a blow to [activate_descriptor] itself!") else user << "The unearthly energies that powered the blade are now dormant." @@ -59,7 +59,7 @@ /obj/effect/rend/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/weapon/nullrod)) - user.visible_message("[usr] seals \the [src] with \the [I].") + user.visible_message("[user] seals \the [src] with \the [I].") qdel(src) return ..() @@ -97,7 +97,7 @@ /obj/item/weapon/scrying/attack_self(mob/user) user << "You can see...everything!" - visible_message("[usr] stares into [src], their eyes glazing over.") + visible_message("[user] stares into [src], their eyes glazing over.") user.ghostize(1) return @@ -118,7 +118,7 @@ unlimited = 1 /obj/item/device/necromantic_stone/attack(mob/living/carbon/human/M, mob/living/carbon/human/user) - if(!istype(M, /mob/living/carbon/human)) + if(!istype(M)) return ..() if(!istype(user) || !user.canUseTopic(M,1)) @@ -137,7 +137,7 @@ user << "This artifact can only affect three undead at a time!" return - hardset_dna(M, null, null, null, null, /datum/species/skeleton) + M.set_species(/datum/species/skeleton, icon_update=0) M.revive() spooky_scaries |= M M << "You have been revived by [user.real_name]!" @@ -261,13 +261,24 @@ var/global/list/multiverse = list() /obj/item/weapon/multisword/proc/spawn_copy(var/client/C, var/turf/T) var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) - C.prefs.copy_to(M) + C.prefs.copy_to(M, icon_updates=0) M.key = C.key M.mind.name = usr.real_name M << "You are an alternate version of [usr.real_name] from another universe! Help them accomplish their goals at all costs." M.real_name = usr.real_name M.name = usr.real_name M.faction = list("[usr.real_name]") + if(prob(50)) + var/list/all_species = list() + for(var/speciestype in typesof(/datum/species) - /datum/species) + var/datum/species/S = new speciestype() + if(!S.dangerous_existence) + all_species += speciestype + M.set_species(pick(all_species), icon_update=0) + M.update_body() + M.update_hair() + M.update_mutcolor() + M.dna.update_dna_identity() equip_copy(M) if(evil) @@ -440,14 +451,6 @@ var/global/list/multiverse = list() else return - ready_dna(M) - if(M.dna && prob(50)) - var/list/all_species = list() - for(var/speciestype in typesof(/datum/species) - /datum/species) - var/datum/species/S = new speciestype() - if(!S.dangerous_existence) - all_species += speciestype - hardset_dna(M, null, null, null, null, pick(all_species)) M.update_icons() M.update_augments() diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm index d59f47796b5..d53f5fa2dba 100644 --- a/code/game/gamemodes/wizard/raginmages.dm +++ b/code/game/gamemodes/wizard/raginmages.dm @@ -130,7 +130,7 @@ var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned. G_found.client.prefs.copy_to(new_character) - ready_dna(new_character) + new_character.dna.update_dna_identity() new_character.key = G_found.key return new_character diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index a7b0ab3ca3b..ca5fb09823c 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -50,14 +50,12 @@ return 0 //Equip the rest of the gear - if(H.dna) - H.dna.species.before_equip_job(src, H) + H.dna.species.before_equip_job(src, H) if(outfit) H.equipOutfit(outfit) - if(H.dna) - H.dna.species.after_equip_job(src, H) + H.dna.species.after_equip_job(src, H) /datum/job/proc/apply_fingerprints(mob/living/carbon/human/H) if(!istype(H)) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index e11ebd25a9e..221d898227c 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -185,7 +185,7 @@ H.ckey = ckey H << "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?
" - hardset_dna(H, ui, se, null, null, mrace, features) + H.hardset_dna(ui, se, H.real_name, null, mrace, features) H.faction |= factions H.set_cloned_appearance() @@ -301,13 +301,13 @@ return /obj/machinery/clonepod/proc/go_out() - if (src.locked) + if (locked) return - if (src.mess) //Clean that mess and dump those gibs! - src.mess = 0 - gibs(src.loc) - src.icon_state = "pod_0" + if (mess) //Clean that mess and dump those gibs! + mess = 0 + gibs(loc) + icon_state = "pod_0" /* for(var/obj/O in src) @@ -315,22 +315,22 @@ */ return - if (!(src.occupant)) + if (!occupant) return /* for(var/obj/O in src) O.loc = src.loc */ - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE + if (occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE if(occupant.loc == src) - src.occupant.loc = src.loc - src.icon_state = "pod_0" - src.eject_wait = 0 //If it's still set somehow. - domutcheck(src.occupant) //Waiting until they're out before possible monkeyizing. - src.occupant = null + occupant.loc = loc + icon_state = "pod_0" + eject_wait = 0 //If it's still set somehow. + occupant.domutcheck() //Waiting until they're out before possible monkeyizing. + occupant = null return /obj/machinery/clonepod/proc/malfunction() diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 65f0690047d..8cfd51a294f 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -350,7 +350,7 @@ return /obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject) - if (!check_dna_integrity(subject) || !istype(subject)) + if (!istype(subject)) scantemp = "Unable to locate valid genetic data." return if (!subject.getorgan(/obj/item/organ/internal/brain)) diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm new file mode 100644 index 00000000000..5de7d5b4adb --- /dev/null +++ b/code/game/machinery/computer/dna_console.dm @@ -0,0 +1,482 @@ +#define INJECTOR_TIMEOUT 300 +#define REJUVENATORS_INJECT 15 +#define REJUVENATORS_MAX 90 +#define NUMBER_OF_BUFFERS 3 + +#define RADIATION_STRENGTH_MAX 15 +#define RADIATION_STRENGTH_MULTIPLIER 1 //larger has a more range + +#define RADIATION_DURATION_MAX 30 +#define RADIATION_ACCURACY_MULTIPLIER 3 //larger is less accurate + +#define RADIATION_IRRADIATION_MULTIPLIER 0.2 //multiplier for how much radiation a test subject recieves + +/obj/machinery/computer/scan_consolenew + name = "\improper DNA scanner access console" + desc = "Scan DNA." + icon_screen = "dna" + icon_keyboard = "med_key" + density = 1 + circuit = /obj/item/weapon/circuitboard/scan_consolenew + var/radduration = 2 + var/radstrength = 1 + + var/list/buffer[NUMBER_OF_BUFFERS] + + var/injectorready = 0 //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete + var/current_screen = "mainmenu" + var/obj/machinery/dna_scannernew/connected = null + var/obj/item/weapon/disk/data/diskette = null + anchored = 1 + use_power = 1 + idle_power_usage = 10 + active_power_usage = 400 + +/obj/machinery/computer/scan_consolenew/attackby(obj/item/I, mob/user, params) + if (istype(I, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES + if (!src.diskette) + if(!user.drop_item()) + return + I.loc = src + src.diskette = I + user << "You insert [I]." + src.updateUsrDialog() + return + else + ..() + return + +/obj/machinery/computer/scan_consolenew/New() + ..() + + spawn(5) + for(dir in list(NORTH,EAST,SOUTH,WEST)) + connected = locate(/obj/machinery/dna_scannernew, get_step(src, dir)) + if(!isnull(connected)) + break + spawn(250) + injectorready = 1 + return + return + +/obj/machinery/computer/scan_consolenew/attack_hand(mob/user) + if(..()) + return + ShowInterface(user) + +/obj/machinery/computer/scan_consolenew/proc/ShowInterface(mob/user, last_change) + if(!user) return + var/datum/browser/popup = new(user, "scannernew", "DNA Modifier Console", 800, 630) // Set up the popup browser window + if(!( in_range(src, user) || istype(user, /mob/living/silicon) )) + popup.close() + return + popup.add_stylesheet("scannernew", 'html/browser/scannernew.css') + + var/mob/living/carbon/viable_occupant + var/occupant_status = "
Subject Status:
" + var/scanner_status + var/temp_html + if(connected && connected.is_operational()) + if(connected.occupant) //set occupant_status message + viable_occupant = connected.occupant + if(viable_occupant.has_dna() && (!(viable_occupant.disabilities & NOCLONE) || (connected.scan_level == 3))) //occupent is viable for dna modification + occupant_status += "[viable_occupant.name] => " + switch(viable_occupant.stat) + if(CONSCIOUS) occupant_status += "Conscious" + if(UNCONSCIOUS) occupant_status += "Unconscious" + else occupant_status += "DEAD - Cannot Operate" + occupant_status += "
" + occupant_status += "
Health:
[viable_occupant.health] %
" + occupant_status += "
Radiation Level:
[viable_occupant.radiation] %
" + var/rejuvenators = viable_occupant.reagents.get_reagent_amount("epinephrine") + occupant_status += "
Rejuvenators:
[rejuvenators] units
" + occupant_status += "
Unique Enzymes :
[viable_occupant.dna.unique_enzymes]
" + occupant_status += "
Last Operation:
[last_change ? last_change : "----"]
" + else + viable_occupant = null + occupant_status += "Invalid DNA structure" + if (viable_occupant && viable_occupant.stat == DEAD) + viable_occupant = null // No editing the dead. + else + occupant_status += "No subject detected" + + if(connected.state_open) + scanner_status = "Open" + else + scanner_status = "Closed" + if(connected.locked) + scanner_status += " (Locked)" + else + scanner_status += " (Unlocked)" + + + else + occupant_status += "----" + scanner_status += "Error: No scanner detected" + + var/status = "
" + status += "
Scanner:
[scanner_status]
" + status += "[occupant_status]" + + + status += "

Radiation Emitter Status

" + var/stddev = radstrength*RADIATION_STRENGTH_MULTIPLIER + status += "
Output Level:
[radstrength]
" + status += "
  \> Mutation:
(-[stddev] to +[stddev] = 68 %) (-[2*stddev] to +[2*stddev] = 95 %)
" + if(connected) + stddev = RADIATION_ACCURACY_MULTIPLIER/(radduration + (connected.precision_coeff ** 2)) + else + stddev = RADIATION_ACCURACY_MULTIPLIER/radduration + var/chance_to_hit + switch(stddev) //hardcoded values from a z-table for a normal distribution + if(0 to 0.25) chance_to_hit = ">95 %" + if(0.25 to 0.5) chance_to_hit = "68-95 %" + if(0.5 to 0.75) chance_to_hit = "55-68 %" + else chance_to_hit = "<38 %" + status += "
Pulse Duration:
[radduration]
" + status += "
  \> Accuracy:
[chance_to_hit]
" + status += "
" // Close statusDisplay div + var/buttons = "Scan " + if(connected) + buttons += " [connected.state_open ? "Close" : "Open"] Scanner " + if (connected.state_open) + buttons += "[connected.locked ? "Unlock" : "Lock"] Scanner " + else + buttons += "[connected.locked ? "Unlock" : "Lock"] Scanner " + else buttons += "Open Scanner Lock Scanner " + if(viable_occupant) buttons += "Inject Rejuvenators " + else buttons += "Inject Rejuvenators " + if(diskette) buttons += "Eject Disk " + else buttons += "Eject Disk " + if(current_screen == "buffer") buttons += "Radiation Emitter Menu " + else buttons += "Buffer Menu " + + switch(current_screen) + if("working") + temp_html += status + temp_html += "

System Busy

" + temp_html += "Working ... Please wait ([radduration] Seconds)" + if("buffer") + temp_html += status + temp_html += buttons + temp_html += "

Buffer Menu

" + + if(istype(buffer)) + for(var/i=1, i<=buffer.len, i++) + temp_html += "
Slot [i]: " + var/list/buffer_slot = buffer[i] + if( !buffer_slot || !buffer_slot.len || !buffer_slot["name"] || !((buffer_slot["UI"] && buffer_slot["UE"]) || buffer_slot["SE"]) ) + temp_html += "
\tNo Data" + if(viable_occupant) temp_html += "
Save to Buffer " + else temp_html += "
Save to Buffer " + temp_html += "Clear Buffer " + if(diskette) temp_html += "Load from Disk " + else temp_html += "Load from Disk " + temp_html += "Save to Disk " + else + var/ui = buffer_slot["UI"] + var/se = buffer_slot["SE"] + var/ue = buffer_slot["UE"] + var/name = buffer_slot["name"] + var/label = buffer_slot["label"] + var/blood_type = buffer_slot["blood_type"] + temp_html += "
\tLabel: [label ? label : name]" + temp_html += "
\tSubject: [name]" + if(ue && name && blood_type) + temp_html += "
\tBlood Type: [blood_type]" + temp_html += "
\tUE: [ue] " + if(viable_occupant) temp_html += "Occupant " + else temp_html += "Occupant" + if(injectorready) temp_html += "Injector" + else temp_html += "Injector" + else + temp_html += "
\tBlood Type: No Data" + temp_html += "
\tUE: No Data" + if(ui) + temp_html += "
\tUI: [ui] " + if(viable_occupant) temp_html += "Occupant " + else temp_html += "Occupant" + if(injectorready) temp_html += "Injector" + else temp_html += "Injector" + else + temp_html += "
\tUI: No Data" + if(se) + temp_html += "
\tSE: [se] " + if(viable_occupant && viable_occupant.stat != DEAD) temp_html += "Occupant " + else temp_html += "Occupant " + if(injectorready) temp_html += "Injector" + else temp_html += "Injector" + else + temp_html += "
\tSE: No Data" + if(viable_occupant) temp_html += "
Save to Buffer " + else temp_html += "
Save to Buffer " + temp_html += "Clear Buffer " + if(diskette) temp_html += "Load from Disk " + else temp_html += "Load from Disk " + if(diskette && !diskette.read_only) temp_html += "Save to Disk " + else temp_html += "Save to Disk " + else + temp_html += status + temp_html += buttons + temp_html += "

Radiation Emitter Menu

" + + temp_html += "-- Output Level ++" + temp_html += "
-- Pulse Duration ++" + + temp_html += "

Irradiate Subject

" + temp_html += "
Unique Identifier:
" + + var/max_line_len = 7*DNA_BLOCK_SIZE + if(viable_occupant) + temp_html += "
1
" + var/len = length(viable_occupant.dna.uni_identity) + for(var/i=1, i<=len, i++) + temp_html += "[copytext(viable_occupant.dna.uni_identity,i,i+1)]" + if ((i % max_line_len) == 0) + temp_html += "
" + if((i % DNA_BLOCK_SIZE) == 0 && i < len) + temp_html += "
[(i / DNA_BLOCK_SIZE) + 1]
" + else + temp_html += "----" + temp_html += "

" + + temp_html += "
Structural Enzymes:
" + if(viable_occupant) + temp_html += "
1
" + var/len = length(viable_occupant.dna.struc_enzymes) + for(var/i=1, i<=len, i++) + temp_html += "[copytext(viable_occupant.dna.struc_enzymes,i,i+1)]" + if ((i % max_line_len) == 0) + temp_html += "
" + if((i % DNA_BLOCK_SIZE) == 0 && i < len) + temp_html += "
[(i / DNA_BLOCK_SIZE) + 1]
" + else + temp_html += "----" + temp_html += "
" + + popup.set_content(temp_html) + popup.open() + + +/obj/machinery/computer/scan_consolenew/Topic(href, href_list) + if(..()) + return + if(!isturf(usr.loc)) + return + if(!( (isturf(loc) && in_range(src, usr)) || istype(usr, /mob/living/silicon) )) + return + if(current_screen == "working") + return + + add_fingerprint(usr) + usr.set_machine(src) + + var/mob/living/carbon/viable_occupant + if(connected) + viable_occupant = connected.occupant + if(!istype(viable_occupant) || !viable_occupant.dna || (viable_occupant.disabilities & NOCLONE)) + viable_occupant = null + + //Basic Tasks/////////////////////////////////////////// + var/num = round(text2num(href_list["num"])) + var/last_change + switch(href_list["task"]) + if("togglelock") + if(connected) connected.locked = !connected.locked + if("toggleopen") + if(connected) connected.toggle_open(usr) + if("setduration") + if(!num) + num = round(input(usr, "Choose pulse duration:", "Input an Integer", null) as num|null) + if(num) + radduration = Wrap(num, 1, RADIATION_DURATION_MAX+1) + if("setstrength") + if(!num) + num = round(input(usr, "Choose pulse strength:", "Input an Integer", null) as num|null) + if(num) + radstrength = Wrap(num, 1, RADIATION_STRENGTH_MAX+1) + if("screen") + current_screen = href_list["text"] + if("rejuv") + if(viable_occupant && viable_occupant.reagents) + var/epinephrine_amount = viable_occupant.reagents.get_reagent_amount("epinephrine") + var/can_add = max(min(REJUVENATORS_MAX - epinephrine_amount, REJUVENATORS_INJECT), 0) + viable_occupant.reagents.add_reagent("epinephrine", can_add) + if("setbufferlabel") + var/text = sanitize(input(usr, "Input a new label:", "Input an Text", null) as text|null) + if(num && text) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = buffer[num] + if(istype(buffer_slot)) + buffer_slot["label"] = text + if("setbuffer") + if(num && viable_occupant) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + buffer[num] = list( + "label"="Buffer[num]:[viable_occupant.real_name]", + "UI"=viable_occupant.dna.uni_identity, + "SE"=viable_occupant.dna.struc_enzymes, + "UE"=viable_occupant.dna.unique_enzymes, + "name"=viable_occupant.real_name, + "blood_type"=viable_occupant.dna.blood_type + ) + if("clearbuffer") + if(num) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = buffer[num] + if(istype(buffer_slot)) + buffer_slot.Cut() + if("transferbuffer") + if(num && viable_occupant && viable_occupant.stat != DEAD) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = buffer[num] + if(istype(buffer_slot)) //15 and 40 are just magic numbers that were here before so i didnt touch them, they are initial boundaries of damage + viable_occupant.radiation += rand(15/(connected.damage_coeff ** 2),40/(connected.damage_coeff ** 2)) //Each laser level reduces damage by lvl^2, so no effect on 1 lvl, 4 times less damage on 2 and 9 times less damage on 3 + switch(href_list["text"]) //Numbers are this high because other way upgrading laser is just not worth the hassle, and i cant think of anything better to inmrove + if("se") + if(buffer_slot["SE"]) + viable_occupant.dna.struc_enzymes = buffer_slot["SE"] + viable_occupant.domutcheck() + if("ui") + if(buffer_slot["UI"]) + viable_occupant.dna.uni_identity = buffer_slot["UI"] + viable_occupant.updateappearance(mutations_overlay_update=1) + else + if(buffer_slot["name"] && buffer_slot["UE"] && buffer_slot["blood_type"]) + viable_occupant.real_name = buffer_slot["name"] + viable_occupant.name = buffer_slot["name"] + viable_occupant.dna.unique_enzymes = buffer_slot["UE"] + viable_occupant.dna.blood_type = buffer_slot["blood_type"] + if("injector") + if(num && injectorready) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = buffer[num] + if(istype(buffer_slot)) + var/obj/item/weapon/dnainjector/I + switch(href_list["text"]) + if("se") + if(buffer_slot["SE"]) + I = new /obj/item/weapon/dnainjector(loc) + for(var/datum/mutation/human/HM in good_mutations + bad_mutations + not_good_mutations) + if(HM.check_block_string(buffer_slot["SE"])) + if(prob(HM.get_chance)) + I.add_mutations.Add(HM) + else + I.remove_mutations.Add(HM) + I.damage_coeff = connected.damage_coeff + if("ui") + if(buffer_slot["UI"]) + I = new /obj/item/weapon/dnainjector(loc) + I.fields = list("UI"=buffer_slot["UI"]) + I.damage_coeff = connected.damage_coeff + else + if(buffer_slot["name"] && buffer_slot["UE"] && buffer_slot["blood_type"]) + I = new /obj/item/weapon/dnainjector(loc) + I.fields = list("name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "blood_type"=buffer_slot["blood_type"]) + I.damage_coeff = connected.damage_coeff + if(I) + injectorready = 0 + spawn(INJECTOR_TIMEOUT) + injectorready = 1 + if("loaddisk") + if(num && diskette && diskette.fields) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + buffer[num] = diskette.fields.Copy() + if("savedisk") + if(num && diskette && !diskette.read_only) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = buffer[num] + if(istype(buffer_slot)) + diskette.name = "data disk \[[buffer_slot["label"]]\]" + diskette.fields = buffer_slot.Copy() + if("ejectdisk") + if(diskette) + diskette.loc = get_turf(src) + diskette = null + if("pulseui","pulsese") + if(num && viable_occupant && connected && viable_occupant.stat != DEAD) + radduration = Wrap(radduration, 1, RADIATION_DURATION_MAX+1) + radstrength = Wrap(radstrength, 1, RADIATION_STRENGTH_MAX+1) + + var/locked_state = connected.locked + connected.locked = 1 + + current_screen = "working" + ShowInterface(usr) + + sleep(radduration*10) + current_screen = "mainmenu" + + if(viable_occupant && connected && connected.occupant==viable_occupant) + viable_occupant.radiation += (RADIATION_IRRADIATION_MULTIPLIER*radduration*radstrength)/(connected.damage_coeff ** 2) //Read comment in "transferbuffer" section above for explanation + switch(href_list["task"]) //Same thing as there but values are even lower, on best part they are about 0.0*, effectively no damage + if("pulseui") + var/len = length(viable_occupant.dna.uni_identity) + num = Wrap(num, 1, len+1) + num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len) //Each manipulator level above 1 makes randomization as accurate as selected time + manipulator lvl^2 + //Value is this high for the same reason as with laser - not worth the hassle of upgrading if the bonus is low + var/block = round((num-1)/DNA_BLOCK_SIZE)+1 + var/subblock = num - block*DNA_BLOCK_SIZE + last_change = "UI #[block]-[subblock]; " + + var/hex = copytext(viable_occupant.dna.uni_identity, num, num+1) + last_change += "[hex]" + hex = scramble(hex, radstrength, radduration) + last_change += "->[hex]" + + viable_occupant.dna.uni_identity = copytext(viable_occupant.dna.uni_identity, 1, num) + hex + copytext(viable_occupant.dna.uni_identity, num+1, 0) + viable_occupant.updateappearance(mutations_overlay_update=1) + if("pulsese") + var/len = length(viable_occupant.dna.struc_enzymes) + num = Wrap(num, 1, len+1) + num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len) + + var/block = round((num-1)/DNA_BLOCK_SIZE)+1 + var/subblock = num - block*DNA_BLOCK_SIZE + last_change = "SE #[block]-[subblock]; " + + var/hex = copytext(viable_occupant.dna.struc_enzymes, num, num+1) + last_change += "[hex]" + hex = scramble(hex, radstrength, radduration) + last_change += "->[hex]" + + viable_occupant.dna.struc_enzymes = copytext(viable_occupant.dna.struc_enzymes, 1, num) + hex + copytext(viable_occupant.dna.struc_enzymes, num+1, 0) + viable_occupant.domutcheck() + else + current_screen = "mainmenu" + + if(connected) + connected.locked = locked_state + + ShowInterface(usr,last_change) + +/obj/machinery/computer/scan_consolenew/proc/scramble(input,rs,rd) + var/length = length(input) + var/ran = gaussian(0, rs*RADIATION_STRENGTH_MULTIPLIER) + if(ran == 0) ran = pick(-1,1) //hacky, statistically should almost never happen. 0-change makes people mad though + else if(ran < 0) ran = round(ran) //negative, so floor it + else ran = -round(-ran) //positive, so ceiling it + return num2hex(Wrap(hex2num(input)+ran, 0, 16**length), length) + +/obj/machinery/computer/scan_consolenew/proc/randomize_radiation_accuracy(position_we_were_supposed_to_hit, radduration, number_of_blocks) + return Wrap(round(position_we_were_supposed_to_hit + gaussian(0, RADIATION_ACCURACY_MULTIPLIER/radduration), 1), 1, number_of_blocks+1) + + + +/////////////////////////// DNA MACHINES +#undef INJECTOR_TIMEOUT +#undef REJUVENATORS_INJECT +#undef REJUVENATORS_MAX +#undef NUMBER_OF_BUFFERS + +#undef RADIATION_STRENGTH_MAX +#undef RADIATION_STRENGTH_MULTIPLIER + +#undef RADIATION_DURATION_MAX +#undef RADIATION_ACCURACY_MULTIPLIER + +#undef RADIATION_IRRADIATION_MULTIPLIER + +//#undef BAD_MUTATION_DIFFICULTY +//#undef GOOD_MUTATION_DIFFICULTY +//#undef OP_MUTATION_DIFFICULTY \ No newline at end of file diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index ed568709958..679d9282e31 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -33,7 +33,7 @@ dat += "

Prisoner Implant Management

" dat += "
Chemical Implants
" var/turf/Tr = null - for(var/obj/item/weapon/implant/chem/C in world) + for(var/obj/item/weapon/implant/chem/C in tracking_implants) Tr = get_turf(C) if((Tr) && (Tr.z != src.z)) continue//Out of range if(!C.implanted) continue @@ -43,7 +43,7 @@ dat += "((10))
" dat += "********************************
" dat += "
Tracking Implants
" - for(var/obj/item/weapon/implant/tracking/T in world) + for(var/obj/item/weapon/implant/tracking/T in tracking_implants) if(!iscarbon(T.imp_in)) continue if(!T.implanted) diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm new file mode 100644 index 00000000000..ac18b3fe445 --- /dev/null +++ b/code/game/machinery/dna_scanner.dm @@ -0,0 +1,167 @@ +/obj/machinery/dna_scannernew + name = "\improper DNA scanner" + desc = "It scans DNA structures." + icon = 'icons/obj/Cryogenic2.dmi' + icon_state = "scanner" + density = 1 + var/locked = 0 + anchored = 1 + use_power = 1 + idle_power_usage = 50 + active_power_usage = 300 + var/damage_coeff + var/scan_level + var/precision_coeff + +/obj/machinery/dna_scannernew/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/clonescanner(null) + component_parts += new /obj/item/weapon/stock_parts/scanning_module(null) + component_parts += new /obj/item/weapon/stock_parts/manipulator(null) + component_parts += new /obj/item/weapon/stock_parts/micro_laser(null) + component_parts += new /obj/item/weapon/stock_parts/console_screen(null) + component_parts += new /obj/item/stack/cable_coil(null, 1) + component_parts += new /obj/item/stack/cable_coil(null, 1) + RefreshParts() + + +/obj/machinery/dna_scannernew/RefreshParts() + scan_level = 0 + damage_coeff = 0 + precision_coeff = 0 + for(var/obj/item/weapon/stock_parts/scanning_module/P in component_parts) + scan_level += P.rating + for(var/obj/item/weapon/stock_parts/manipulator/P in component_parts) + precision_coeff = P.rating + for(var/obj/item/weapon/stock_parts/micro_laser/P in component_parts) + damage_coeff = P.rating + +/obj/machinery/dna_scannernew/update_icon() + + //no power or maintenance + if(stat & (NOPOWER|BROKEN)) + icon_state = initial(icon_state)+ (state_open ? "_open" : "") + "_unpowered" + return + + if((stat & MAINT) || panel_open) + icon_state = initial(icon_state)+ (state_open ? "_open" : "") + "_maintenance" + return + + //running and someone in there + if(occupant) + icon_state = initial(icon_state)+ "_occupied" + return + + //running + icon_state = initial(icon_state)+ (state_open ? "_open" : "") + +/obj/machinery/dna_scannernew/power_change() + ..() + update_icon() + +/obj/machinery/dna_scannernew/proc/toggle_open(mob/user) + if(panel_open) + user << "Close the maintenance panel first." + return + + if(state_open) + close_machine() + return + + else if(locked) + user << "The bolts are locked down, securing the door shut." + return + + open_machine() + +/obj/machinery/dna_scannernew/container_resist() + var/mob/living/user = usr + var/breakout_time = 2 + if(state_open || !locked) //Open and unlocked, no need to escape + state_open = 1 + return + user.changeNext_move(CLICK_CD_BREAKOUT) + user.last_special = world.time + CLICK_CD_BREAKOUT + user << "You lean on the back of [src] and start pushing the door open... (this will take about [breakout_time] minutes.)" + user.visible_message("You hear a metallic creaking from [src]!") + + if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds + if(!user || user.stat != CONSCIOUS || user.loc != src || state_open || !locked) + return + + locked = 0 + visible_message("[user] successfully broke out of [src]!") + user << "You successfully break out of [src]!" + + open_machine() + +/obj/machinery/dna_scannernew/close_machine() + if(!state_open) + return 0 + + ..() + + // search for ghosts, if the corpse is empty and the scanner is connected to a cloner + if(occupant) + if(locate(/obj/machinery/computer/cloning, get_step(src, NORTH)) \ + || locate(/obj/machinery/computer/cloning, get_step(src, SOUTH)) \ + || locate(/obj/machinery/computer/cloning, get_step(src, EAST)) \ + || locate(/obj/machinery/computer/cloning, get_step(src, WEST))) + + occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!") + return 1 + +/obj/machinery/dna_scannernew/open_machine() + if(state_open) + return 0 + + ..() + + return 1 + +/obj/machinery/dna_scannernew/relaymove(mob/user as mob) + if(user.stat || locked) + return + + open_machine() + return + +/obj/machinery/dna_scannernew/attackby(obj/item/I, mob/user, params) + + if(!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, I))//sent icon_state is irrelevant... + update_icon()//..since we're updating the icon here, since the scanner can be unpowered when opened/closed + return + + if(exchange_parts(user, I)) + return + + if(default_pry_open(I)) + return + + if(default_deconstruction_crowbar(I)) + return + + if(istype(I, /obj/item/weapon/grab)) + var/obj/item/weapon/grab/G = I + if(!ismob(G.affecting)) + return + + if(!state_open) + user << "Open the scanner first." + return + + var/mob/M = G.affecting + M.loc = loc + user.stop_pulling() + qdel(G) + +/obj/machinery/dna_scannernew/attack_hand(mob/user) + if(..(user,1,0)) //don't set the machine, since there's no dialog + return + + toggle_open(user) + +/obj/machinery/dna_scannernew/blob_act() + if(prob(75)) + qdel(src) \ No newline at end of file diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 6c073ceb95e..143d5d30029 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -124,9 +124,9 @@ var/mob/living/carbon/human/T = attached - if(!istype(T)) return - if(!T.dna) + if(!istype(T)) return + if(T.disabilities & NOCLONE) return diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 1cbf53376ea..4394c1f4140 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -180,7 +180,7 @@ areaindex[tmpname] = 1 L[tmpname] = R - for (var/obj/item/weapon/implant/tracking/I in world) + for (var/obj/item/weapon/implant/tracking/I in tracking_implants) if (!I.implanted || !ismob(I.loc)) continue else @@ -315,8 +315,8 @@ var/mob/living/carbon/human/human = M if(human.dna && human.dna.species.id == "human") M << "You hear a buzzing in your ears." - hardset_dna(human, null, null, null, null, /datum/species/fly) - human.regenerate_icons() + human.set_species(/datum/species/fly) + human.apply_effect((rand(120 - accurate * 40, 180 - accurate * 60)), IRRADIATE, 0) calibrated = 0 return diff --git a/code/game/mecha/combat/honker.dm b/code/game/mecha/combat/honker.dm index 55b9d068630..c6a3a347726 100644 --- a/code/game/mecha/combat/honker.dm +++ b/code/game/mecha/combat/honker.dm @@ -45,7 +45,7 @@ HONK pressure: [cabin_pressure>WARNING_HIGH_PRESSURE ? "[cabin_pressure]": cabin_pressure]kPa
HONK temperature: [return_temperature()]°K|[return_temperature() - T0C]°C
Lights: [lights?"on":"off"]
- [src.dna?"DNA-locked:
[src.dna] \[Reset\]
":null] + [dna_lock?"DNA-locked:
[dna_lock] \[Reset\]
":null] "} return output diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 0225ac4ee3b..17d095f2911 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -34,7 +34,7 @@ var/last_message = 0 var/add_req_access = 1 var/maint_access = 0 - var/dna //dna-locking the mech + var/dna_lock//dna-locking the mech var/list/proc_res = list() //stores proc owners, like proc_res["functionname"] = owner reference var/datum/effect/effect/system/spark_spread/spark_system = new var/lights = 0 @@ -557,7 +557,7 @@ else if(AI.stat || !AI.client) user << "[AI.name] is currently unresponsive, and cannot be uploaded." return - else if(occupant || dna) //Normal AIs cannot steal mechs! + else if(occupant || dna_lock) //Normal AIs cannot steal mechs! user << "Access denied. [name] is [occupant ? "currently occupied" : "secured with a DNA lock"]." return AI.control_disabled = 0 @@ -653,10 +653,10 @@ log_append_to_last("Permission denied.") return var/passed - if(dna) - if(check_dna_integrity(user)) + if(dna_lock) + if(user.has_dna()) var/mob/living/carbon/C = user - if(C.dna.unique_enzymes==src.dna) + if(C.dna.unique_enzymes==dna_lock) passed = 1 else if(operation_allowed(user)) passed = 1 @@ -711,8 +711,8 @@ else if(occupant) user << "Occupant detected!" return 0 - else if(dna && dna!=mmi_as_oc.brainmob.dna.unique_enzymes) - user << "Stop it!" + else if(dna_lock && (!mmi_as_oc.brainmob.dna || dna_lock!=mmi_as_oc.brainmob.dna.unique_enzymes)) + user << "Access denied. [name] is secured with a DNA lock." return 0 visible_message("[user] starts to insert an MMI into [src.name].") diff --git a/code/game/mecha/mecha_topic.dm b/code/game/mecha/mecha_topic.dm index 25ba30fde4a..8dc4dfde8c6 100644 --- a/code/game/mecha/mecha_topic.dm +++ b/code/game/mecha/mecha_topic.dm @@ -83,7 +83,7 @@ Airtank temperature: [tank_temperature]°K|[tank_temperature - T0C]°C
Cabin pressure: [cabin_pressure>WARNING_HIGH_PRESSURE ? "[cabin_pressure]": cabin_pressure]kPa
Cabin temperature: [return_temperature()]°K|[return_temperature() - T0C]°C
- [src.dna?"DNA-locked:
[src.dna] \[Reset\]
":null] + [dna_lock?"DNA-locked:
[dna_lock] \[Reset\]
":null] "} return output @@ -300,11 +300,11 @@ if(occupant && !iscarbon(occupant)) occupant << " You do not have any DNA!" return - dna = src.occupant.dna.unique_enzymes + dna_lock = occupant.dna.unique_enzymes occupant_message("You feel a prick as the needle takes your DNA sample.") if(href_list["reset_dna"]) - dna = null + dna_lock = null if(href_list["repair_int_control_lost"]) occupant_message("Recalibrating coordination system...") diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index ad8574211f8..6f90e2d9f92 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -80,7 +80,7 @@ return if(ishuman(user)) var/mob/living/carbon/human/H = user - if(H.dna && (H.dna.check_mutation(HULK) || NOGUNS in H.dna.species.specflags)) + if(H.dna.check_mutation(HULK) || NOGUNS in H.dna.species.specflags) user << "Your fingers can't press the button!" return diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index a80e0d4eb31..c9311f53a64 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -162,8 +162,7 @@ MASS SPECTROMETER // Species and body temperature if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.dna) - user << "Species: [H.dna.species.name]" + user << "Species: [H.dna.species.name]" user << "Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)" // Time of death diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index e8e91caf7ac..66cbfef59cb 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -16,7 +16,6 @@ return 1 return 0 - /obj/item/borg/upgrade/reset name = "cyborg module reset board" desc = "Used to reset a cyborg's module. Destroys any other upgrades applied to the cyborg." @@ -197,7 +196,7 @@ R.module.rebuild() return 1 -/obj/item/borg/upgrade/syndicate/ +/obj/item/borg/upgrade/syndicate name = "illegal equipment module" desc = "Unlocks the hidden, deadlier functions of a cyborg" icon_state = "cyborg_upgrade3" @@ -211,3 +210,85 @@ R.SetEmagged(1) return 1 + +/obj/item/borg/upgrade/selfrepair + name = "self-repair module" + desc = "This module will repair the cyborg over time." + icon_state = "cyborg_upgrade5" + require_module = 1 + var/repair_amount = -1 + var/repair_tick = 1 + var/msg_cooldown = 0 + var/on = 0 + var/powercost = 10 + var/mob/living/silicon/robot/cyborg + +/obj/item/borg/upgrade/selfrepair/action(mob/living/silicon/robot/R) + if(..()) + return 0 + var/obj/item/borg/upgrade/selfrepair/U = locate() in R + if(U) + usr << "This unit is already equipped with a self-repair module." + return 0 + cyborg = R + icon_state = "selfrepair_off" + action_button_name = "Toggle Self-Repair" + return 1 + +/obj/item/borg/upgrade/selfrepair/ui_action_click() + on = !on + if(on) + cyborg << "You activate the self-repair module." + SSobj.processing |= src + else + cyborg << "You deactivate the self-repair module." + SSobj.processing -= src + update_icon() + +/obj/item/borg/upgrade/selfrepair/update_icon() + if(cyborg) + icon_state = "selfrepair_[on ? "on" : "off"]" + else + icon_state = "cyborg_upgrade5" + +/obj/item/borg/upgrade/selfrepair/proc/deactivate() + SSobj.processing -= src + on = 0 + update_icon() + +/obj/item/borg/upgrade/selfrepair/process() + if(!repair_tick) + repair_tick = 1 + return + + if( cyborg && (cyborg.stat != DEAD) && on) + if(cyborg.cell.charge < powercost*2) + cyborg << "Self-repair module deactivated. Please recharge." + deactivate() + return + + if(cyborg.health < cyborg.maxHealth) + if(cyborg.health < 0) + repair_amount = -2.5 + powercost = 30 + else + repair_amount = -1 + powercost = 10 + cyborg.adjustBruteLoss(repair_amount) + cyborg.adjustFireLoss(repair_amount) + cyborg.updatehealth() + cyborg.cell.use(powercost) + else + cyborg.cell.use(5) + repair_tick = 0 + + if( (world.time - 2000) > msg_cooldown ) + var/msgmode = "standby" + if(cyborg.health < 0) + msgmode = "critical" + else if(cyborg.health < cyborg.maxHealth) + msgmode = "normal" + cyborg << "Self-repair is active in [msgmode] mode." + msg_cooldown = world.time + else + deactivate() diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 496654df1ae..4f3d9f59eb5 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -103,6 +103,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ new/datum/stack_recipe("book case", /obj/structure/bookcase, 4, time = 15, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("drying rack", /obj/machinery/smartfridge/drying_rack, 10, time = 15, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("dog bed", /obj/structure/stool/bed/dogbed, 10, time = 10, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("display case chassis", /obj/structure/displaycase_chassis, 5, one_per_turf = 1, on_floor = 1), \ ) /obj/item/stack/sheet/mineral/wood diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index 9276fce55bc..28afa0a7bb8 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -17,7 +17,7 @@ /obj/item/weapon/dnainjector/proc/inject(mob/living/carbon/M, mob/user) - if(check_dna_integrity(M) && !(M.disabilities & NOCLONE)) + if(M.has_dna() && !(M.disabilities & NOCLONE)) if(M.stat == DEAD) //prevents dead people from having their DNA changed user << "You can't modify [M]'s DNA while \he's dead." return @@ -38,7 +38,7 @@ M.dna.blood_type = fields["blood_type"] if(fields["UI"]) //UI+UE M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"]) - updateappearance(M) + M.updateappearance(mutations_overlay_update=1) log_attack(log_msg) else user << "It appears that [M] does not have compatible DNA." diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index 1522d73b8f5..a01bfb82ca1 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -87,6 +87,15 @@ origin_tech = "materials=2;magnets=2;programming=2;biotech=2" var/id = 1 + +/obj/item/weapon/implant/tracking/New() + ..() + tracking_implants += src + +/obj/item/weapon/implant/tracking/Destroy() + ..() + tracking_implants -= src + /obj/item/weapon/implant/tracking/get_data() var/dat = {"Implant Specifications:
Name: Tracking Beacon
diff --git a/code/game/objects/items/weapons/implants/implant_chem.dm b/code/game/objects/items/weapons/implants/implant_chem.dm index 6f85742039b..312363d6713 100644 --- a/code/game/objects/items/weapons/implants/implant_chem.dm +++ b/code/game/objects/items/weapons/implants/implant_chem.dm @@ -24,6 +24,14 @@ /obj/item/weapon/implant/chem/New() ..() create_reagents(50) + tracking_implants += src + +/obj/item/weapon/implant/chem/Destroy() + ..() + tracking_implants -= src + + + /obj/item/weapon/implant/chem/trigger(emote, mob/source) if(emote == "deathgasp") diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm index 0bf17d4be30..da8ffa7cef0 100644 --- a/code/game/objects/items/weapons/teleportation.dm +++ b/code/game/objects/items/weapons/teleportation.dm @@ -78,7 +78,7 @@ Frequency: src.temp += "[W.code]-[dir2text(get_dir(sr, tr))]-[direct]
" src.temp += "Extranneous Signals:
" - for (var/obj/item/weapon/implant/tracking/W in world) + for (var/obj/item/weapon/implant/tracking/W in tracking_implants) if (!W.implanted || !ismob(W.loc)) continue else diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 3fd5b7cf096..e342de7ac9a 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -244,7 +244,7 @@ return 1 /obj/item/weapon/twohanded/dualsaber/wield(mob/living/carbon/M) //Specific wield () hulk checks due to reflection chance for balance issues and switches hitsounds. - if(istype(M)) + if(M.has_dna()) if(M.dna.check_mutation(HULK)) M << "You lack the grace to wield this!" return diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 148202d59e6..37f136b4618 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -1,22 +1,23 @@ /obj/structure/displaycase name = "display case" icon = 'icons/obj/stationobjs.dmi' - icon_state = "glassbox1" - desc = "A display case for prized possessions. Hooked up with an anti-theft system." + icon_state = "glassbox0" + desc = "A display case for prized possessions." density = 1 anchored = 1 unacidable = 1//Dissolving the case would also delete the gun. var/health = 30 - var/occupied = 1 var/destroyed = 0 + var/obj/item/showpiece = null + var/alert = 0 + var/open = 0 + var/obj/item/weapon/electronics/airlock/electronics /obj/structure/displaycase/ex_act(severity, target) switch(severity) if (1) new /obj/item/weapon/shard( src.loc ) - if (occupied) - new /obj/item/weapon/gun/energy/laser/captain( src.loc ) - occupied = 0 + dump() qdel(src) if (2) if (prob(50)) @@ -27,6 +28,13 @@ src.health -= 5 src.healthcheck() +/obj/structure/displaycase/examine(mob/user) + ..() + if(showpiece) + user << "There's [showpiece] inside." + if(alert) + user << "Hooked up with an anti-theft system." + /obj/structure/displaycase/bullet_act(obj/item/projectile/Proj) if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) @@ -35,16 +43,17 @@ src.healthcheck() return +/obj/structure/displaycase/proc/dump() + if (showpiece) + showpiece.loc = src.loc + showpiece = null /obj/structure/displaycase/blob_act() if (prob(75)) new /obj/item/weapon/shard( src.loc ) - if (occupied) - new /obj/item/weapon/gun/energy/laser/captain( src.loc ) - occupied = 0 + dump() qdel(src) - /obj/structure/displaycase/proc/healthcheck() if (src.health <= 0) if (!( src.destroyed )) @@ -55,27 +64,76 @@ update_icon() //Activate Anti-theft - var/area/alarmed = get_area(src) - alarmed.burglaralert(src) - playsound(src, "sound/effects/alert.ogg", 50, 1) + if(alert) + var/area/alarmed = get_area(src) + alarmed.burglaralert(src) + playsound(src, "sound/effects/alert.ogg", 50, 1) else playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) return -/obj/structure/displaycase/update_icon() - if(src.destroyed) - src.icon_state = "glassboxb[src.occupied]" +/obj/structure/displaycase/proc/is_directional(atom/A) + try + getFlatIcon(A,defdir=4) + catch + return 0 + return 1 +/obj/structure/displaycase/proc/get_flat_icon_directional(atom/A) + //Get flatIcon even if dir is mismatched for directionless icons + //SLOW + var/icon/I + if(is_directional(A)) + I = getFlatIcon(A) else - src.icon_state = "glassbox[src.occupied]" + var/old_dir = A.dir + A.dir = 2 + I = getFlatIcon(A) + A.dir = old_dir + return I + +/obj/structure/displaycase/update_icon() + var/icon/I + if(open) + I = icon('icons/obj/stationobjs.dmi',"glassbox_open") + else + I = icon('icons/obj/stationobjs.dmi',"glassbox0") + if(destroyed) + I = icon('icons/obj/stationobjs.dmi',"glassboxb0") + if(showpiece) + var/icon/S = get_flat_icon_directional(showpiece) + S.Scale(17,17) + I.Blend(S,ICON_UNDERLAY,8,8) + src.icon = I return - /obj/structure/displaycase/attackby(obj/item/weapon/W, mob/user, params) - user.changeNext_move(CLICK_CD_MELEE) - src.health -= W.force - src.healthcheck() - ..() + if(istype(W, /obj/item/weapon/card) && electronics && !destroyed && allowed(user)) + user << "You [open ? "close":"open"] the [src]" + open = !open + update_icon() + return + if(!alert && istype(W,/obj/item/weapon/crowbar)) + if(destroyed && !showpiece) + user << "You remove the destroyed case" + qdel(src) + return + user << "You start to [open ? "close":"open"] the [src]" + if(do_after(user, 20, target = src)) + user << "You [open ? "close":"open"] the [src]" + open = !open + update_icon() + else if(open) + if(user.unEquip(W)) + W.loc = src + showpiece = W + user << "You put [W] on display" + update_icon() + else + user.changeNext_move(CLICK_CD_MELEE) + src.health -= W.force + src.healthcheck() + ..() return /obj/structure/displaycase/attack_paw(mob/user) @@ -83,10 +141,9 @@ /obj/structure/displaycase/attack_hand(mob/user) user.changeNext_move(CLICK_CD_MELEE) - if (src.destroyed && src.occupied) - new /obj/item/weapon/gun/energy/laser/captain( src.loc ) + if (showpiece && (destroyed || open)) + dump() user << "You deactivate the hover field built into the case." - src.occupied = 0 src.add_fingerprint(user) update_icon() return @@ -98,3 +155,71 @@ return +/obj/structure/displaycase_chassis + anchored = 1 + density = 0 + name = "display case chassis" + desc = "wooden base of display case" + icon = 'icons/obj/stationobjs.dmi' + icon_state = "glassbox_chassis" + var/obj/item/weapon/electronics/airlock/electronics + + +/obj/structure/displaycase_chassis/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/wrench)) + user << "You start disassembling [src]..." + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + if(do_after(user, 30, target = src)) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + new /obj/item/stack/sheet/mineral/wood(get_turf(src)) + qdel(src) + return + if(istype(I, /obj/item/weapon/electronics/airlock)) + user << "You start installing the electronics into [src]..." + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + if(user.unEquip(I) && do_after(user, 30, target = src)) + I.loc = src + electronics = I + user << "You install the airlock electronics." + return + if(istype(I, /obj/item/stack/sheet/glass)) + var/obj/item/stack/sheet/glass/G = I + if(G.get_amount() < 10) + user << "You need ten glass sheets to do this!" + return + user << "You start adding [G] to [src]..." + if(do_after(user, 20, target = src)) + G.use(10) + var/obj/structure/displaycase/display = new(src.loc) + if(electronics) + electronics.loc = display + display.electronics = electronics + if(electronics.use_one_access) + display.req_one_access = electronics.conf_access + else + display.req_access = electronics.conf_access + qdel(src) + return + return + + +/obj/structure/displaycase/captain + alert = 1 + +/obj/structure/displaycase/captain/New() + ..() + showpiece = new /obj/item/weapon/gun/energy/laser/captain (src) + update_icon() + +/obj/structure/displaycase/labcage + name = "lab cage" + desc = "A glass lab container for storing interesting creatures." + +/obj/structure/displaycase/labcage/New() + ..() + var/obj/item/clothing/mask/facehugger/A = new /obj/item/clothing/mask/facehugger(src) + A.sterile = 1 + A.name = "Lamarr" + showpiece = A + update_icon() + diff --git a/code/game/objects/structures/lamarr_cage.dm b/code/game/objects/structures/lamarr_cage.dm deleted file mode 100644 index e1944e4d6bc..00000000000 --- a/code/game/objects/structures/lamarr_cage.dm +++ /dev/null @@ -1,91 +0,0 @@ -/obj/structure/lamarr - name = "lab cage" - icon = 'icons/obj/stationobjs.dmi' - icon_state = "labcage1" - desc = "A glass lab container for storing interesting creatures." - density = 1 - anchored = 1 - unacidable = 1//Dissolving the case would also delete Lamarr - var/health = 30 - var/occupied = 1 - var/destroyed = 0 - -/obj/structure/lamarr/ex_act(severity, target) - switch(severity) - if (1) - new /obj/item/weapon/shard( src.loc ) - Break() - qdel(src) - if (2) - if (prob(50)) - src.health -= 15 - src.healthcheck() - if (3) - if (prob(50)) - src.health -= 5 - src.healthcheck() - - -/obj/structure/lamarr/bullet_act(obj/item/projectile/Proj) - health -= Proj.damage - ..() - src.healthcheck() - return - - -/obj/structure/lamarr/blob_act() - if (prob(75)) - new /obj/item/weapon/shard( src.loc ) - Break() - qdel(src) - - -/obj/structure/lamarr/proc/healthcheck() - if (src.health <= 0) - if (!( src.destroyed )) - src.density = 0 - src.destroyed = 1 - new /obj/item/weapon/shard( src.loc ) - playsound(src, "shatter", 70, 1) - Break() - else - playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) - return - -/obj/structure/lamarr/update_icon() - if(src.destroyed) - src.icon_state = "labcageb[src.occupied]" - else - src.icon_state = "labcage[src.occupied]" - return - - -/obj/structure/lamarr/attackby(obj/item/weapon/W, mob/user, params) - user.changeNext_move(CLICK_CD_MELEE) - src.health -= W.force - src.healthcheck() - ..() - return - -/obj/structure/lamarr/attack_paw(mob/user) - return src.attack_hand(user) - -/obj/structure/lamarr/attack_hand(mob/user) - user.changeNext_move(CLICK_CD_MELEE) - if (src.destroyed) - return - else - user.visible_message("[user] kicks the lab cage.", \ - "You kick the lab cage.") - src.health -= 2 - healthcheck() - return - -/obj/structure/lamarr/proc/Break() - if(occupied) - var/obj/item/clothing/mask/facehugger/A = new /obj/item/clothing/mask/facehugger( src.loc ) - A.sterile = 1 - A.name = "Lamarr" - occupied = 0 - update_icon() - return \ No newline at end of file diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index b0c939443c1..9c3f73faf40 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -148,16 +148,17 @@ var/racechoice = input(H, "What are we again?", "Race change") as null|anything in choosable_races newrace = species_list[racechoice] - if(!newrace || !H.dna) + if(!newrace) return - hardset_dna(H, null, null, null, null, newrace) + H.set_species(newrace, icon_update=0) if(H.dna.species.use_skintones) var/new_s_tone = input(user, "Choose your skin tone:", "Race change") as null|anything in skin_tones if(new_s_tone) H.skin_tone = new_s_tone + H.dna.update_ui_block(DNA_SKIN_TONE_BLOCK) if(MUTCOLORS in H.dna.species.specflags) var/new_mutantcolor = input(user, "Choose your skin color:", "Race change") as color|null @@ -170,7 +171,10 @@ else H << "Invalid color. Your color is not bright enough." - H.regenerate_icons() + H.update_body() + H.update_hair() + H.update_mutcolor() + H.update_mutations_overlay() // no hulk lizard if("gender") if(!(H.gender in list("male", "female"))) //blame the patriarchy @@ -180,12 +184,19 @@ if(alert(H, "Become a Witch?", "Confirmation", "Yes", "No") == "Yes") H.gender = "female" H << "Man, you feel like a woman!" - H.regenerate_icons() + else + return + else if(alert(H, "Become a Warlock?", "Confirmation", "Yes", "No") == "Yes") H.gender = "male" H << "Whoa man, you feel like a man!" - H.regenerate_icons() + else + return + H.dna.update_ui_block(DNA_GENDER_BLOCK) + H.update_body() + H.update_mutations_overlay() //(hulk male/female) + if("hair") var/hairchoice = alert(H, "Hair style or hair color?", "Change Hair", "Style", "Color") @@ -196,15 +207,17 @@ var/new_hair_color = input(H, "Choose your hair color", "Hair Color") as null|color if(new_hair_color) H.hair_color = sanitize_hexcolor(new_hair_color) + H.dna.update_ui_block(DNA_HAIR_COLOR_BLOCK) if(H.gender == "male") var/new_face_color = input(H, "Choose your facial hair color", "Hair Color") as null|color if(new_face_color) H.facial_hair_color = sanitize_hexcolor(new_face_color) - + H.dna.update_ui_block(DNA_FACIAL_HAIR_COLOR_BLOCK) H.update_hair() if("eyes") var/new_eye_color = input(H, "Choose your eye color", "Eye Color") as null|color if(new_eye_color) H.eye_color = sanitize_hexcolor(new_eye_color) + H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK) H.update_body() \ No newline at end of file diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 0e4b1608506..f3d04c5626b 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -198,6 +198,10 @@ flags |= NOJAUNT /turf/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user) + if(src_object.contents.len) + usr << "You start dumping out the contents..." + if(!do_after(usr,20,target=src_object)) + return 0 for(var/obj/item/I in src_object) if(user.s_active != src_object) if(I.on_found(user)) diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index 2861e298a53..86eb11de26f 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -220,7 +220,7 @@ var/dat = "Showing DNA from blood.
" dat += "" for(var/mob/living/carbon/human/H in mob_list) - if(H.dna && H.ckey) + if(H.ckey) dat += "" dat += "
NameDNABlood Type
[H][H.dna.unique_enzymes][H.dna.blood_type]
" usr << browse(dat, "window=DNA;size=440x410") @@ -231,12 +231,7 @@ dat += "" for(var/mob/living/carbon/human/H in mob_list) if(H.ckey) - if(H.dna && H.dna.uni_identity) - dat += "" - else if(H.dna && !H.dna.uni_identity) - dat += "" - else if(!H.dna) - dat += "" + dat += "" dat += "
NameFingerprints
[H][md5(H.dna.uni_identity)]
[H]H.dna.uni_identity = null
[H]H.dna = null
[H][md5(H.dna.uni_identity)]
" usr << browse(dat, "window=fingerprints;size=440x410") @@ -259,8 +254,7 @@ message_admins("\blue [key_name_admin(usr)] turned all humans into [result]") var/newtype = species_list[result] for(var/mob/living/carbon/human/H in mob_list) - hardset_dna(H, null, null, null, null, newtype) - H.regenerate_icons() + H.set_species(newtype) if("corgi") if(!check_rights(R_FUN)) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index d1275930c8c..d832c960d13 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1527,7 +1527,6 @@ var/client/C = usr.client if(!isobserver(usr)) C.admin_ghost() var/mob/dead/observer/A = C.mob - sleep(2) A.ManualFollow(M) log_admin("[key_name(usr)] followed [key_name(M)]") message_admins("[key_name_admin(usr)] followed [key_name_admin(M)]") diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm index 19cc6dd5667..00a51054c80 100644 --- a/code/modules/admin/verbs/deadsay.dm +++ b/code/modules/admin/verbs/deadsay.dm @@ -26,7 +26,7 @@ for (var/mob/M in player_list) if (istype(M, /mob/new_player)) continue - if (M.stat == DEAD || (M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above + if (M.stat == DEAD || istype(M, /mob/living/simple_animal/revenant) || (M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above M.show_message(rendered, 2) feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! \ No newline at end of file diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 2ba4e19149b..198dbff5c2e 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -326,13 +326,13 @@ //Spawn and equip the commando var/mob/living/carbon/human/Commando = new(spawnloc) chosen_candidate.client.prefs.copy_to(Commando) - ready_dna(Commando) if(numagents == 1) //If Squad Leader Commando.real_name = "Officer [pick(commando_names)]" Commando.equipOutfit(/datum/outfit/death_commando/officer) else Commando.real_name = "Trooper [pick(commando_names)]" Commando.equipOutfit(/datum/outfit/death_commando) + Commando.dna.update_dna_identity() Commando.key = chosen_candidate.key Commando.mind.assigned_role = "Death Commando" for(var/obj/machinery/door/poddoor/ert/door in airlocks) @@ -420,8 +420,8 @@ //Create the official var/mob/living/carbon/human/newmob = new (pick(emergencyresponseteamspawn)) chosen_candidate.client.prefs.copy_to(newmob) - ready_dna(newmob) newmob.real_name = newmob.dna.species.random_name(newmob.gender,1) + newmob.dna.update_dna_identity() newmob.key = chosen_candidate.key newmob.mind.assigned_role = "Centcom Official" newmob.equipOutfit(/datum/outfit/centcom_official) @@ -490,7 +490,6 @@ var/mob/living/carbon/human/ERTOperative = new(spawnloc) var/list/lastname = last_names chosen_candidate.client.prefs.copy_to(ERTOperative) - ready_dna(ERTOperative) var/ertname = pick(lastname) switch(numagents) if(1) @@ -514,6 +513,7 @@ if(7) ERTOperative.real_name = "Engineer [ertname]" ERTOperative.equipOutfit(redalert ? /datum/outfit/ert/engineer/alert : /datum/outfit/ert/engineer) + ERTOperative.dna.update_dna_identity() ERTOperative.key = chosen_candidate.key ERTOperative.mind.assigned_role = "ERT" diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 7cb4c9f4994..6e314d19ee0 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -300,15 +300,13 @@ Traitors and the like can also be revived with the previous role mostly intact. new_character.real_name = record_found.fields["name"] new_character.gender = record_found.fields["sex"] new_character.age = record_found.fields["age"] - new_character.dna.blood_type = record_found.fields["blood_type"] + new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], record_found.fields["species"], record_found.fields["features"]) else - new_character.gender = pick(MALE,FEMALE) var/datum/preferences/A = new() - A.real_name = G_found.real_name A.copy_to(new_character) + A.real_name = G_found.real_name + new_character.dna.update_dna_identity() - if(!new_character.real_name) - new_character.real_name = new_character.dna.species.random_name(new_character.gender,1) new_character.name = new_character.real_name if(G_found.mind && !G_found.mind.active) @@ -316,13 +314,8 @@ Traitors and the like can also be revived with the previous role mostly intact. new_character.mind.special_verbs = list() else new_character.mind_initialize() - if(!new_character.mind.assigned_role) new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role. - - //DNA - if(record_found)//Pull up their name from database records if they did have a mind. - hardset_dna(new_character, record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], record_found.fields["species"], record_found.fields["features"]) - else//If they have no records, we just do a random DNA for them, based on their random appearance/savefile. - ready_dna(new_character) + if(!new_character.mind.assigned_role) + new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role. new_character.key = G_found.key @@ -822,7 +815,7 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits id_select += "" id_select += "" - var/dat = {" + var/dat = {" Create Outfit
diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 89e24aa3672..af2f1680f6c 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -1,3 +1,5 @@ +var/obj/machinery/gateway/centerstation/the_gateway = null + /obj/machinery/gateway name = "gateway" desc = "A mysterious gateway built by unknown hands, it allows for faster than light travel to far-flung locations." @@ -9,6 +11,18 @@ var/active = 0 +/obj/machinery/gateway/centerstation/New() + ..() + if(!the_gateway) + the_gateway = src + + +/obj/machinery/gateway/centerstation/Destroy() + if(the_gateway == src) + the_gateway = null + ..() + + /obj/machinery/gateway/initialize() update_icon() if(dir == 2) diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index 450d153a94f..54b0a0953c2 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -80,20 +80,17 @@ user.dna.add_mutation(LASEREYES) user.dna.add_mutation(COLDRES) user.dna.add_mutation(XRAY) - hardset_dna(user, null, null, null, null, /datum/species/shadow) - user.regenerate_icons() + user.set_species(/datum/species/shadow) if("Wealth") user << "Your wish is granted, but at a terrible cost..." user << "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart." new /obj/structure/closet/syndicate/resources/everything(loc) - hardset_dna(user, null, null, null, null, /datum/species/shadow) - user.regenerate_icons() + user.set_species(/datum/species/shadow) if("Immortality") user << "Your wish is granted, but at a terrible cost..." user << "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart." user.verbs += /mob/living/carbon/proc/immortality - hardset_dna(user, null, null, null, null, /datum/species/shadow) - user.regenerate_icons() + user.set_species(/datum/species/shadow) if("To Kill") user << "Your wish is granted, but at a terrible cost..." user << "The Wish Granter punishes you for your wickedness, claiming your soul and warping your body to match the darkness in your heart." @@ -107,8 +104,7 @@ for(var/datum/objective/OBJ in user.mind.objectives) user << "Objective #[obj_count]: [OBJ.explanation_text]" obj_count++ - hardset_dna(user, null, null, null, null, /datum/species/shadow) - user.regenerate_icons() + user.set_species(/datum/species/shadow) if("Peace") user << "Whatever alien sentience that the Wish Granter possesses is satisfied with your wish. There is a distant wailing as the last of the Faithless begin to die, then silence." user << "You feel as if you just narrowly avoided a terrible fate..." diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 24fe636eeff..95cd0a176d4 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1049,7 +1049,7 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set ShowChoices(user) return 1 -/datum/preferences/proc/copy_to(mob/living/carbon/human/character) +/datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1) if(be_random_name) real_name = pref_species.random_name(gender) @@ -1081,19 +1081,19 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set character.undershirt = undershirt character.socks = socks - character.features = features - character.backbag = backbag - if(character.dna) - var/datum/species/chosen_species - - character.dna.real_name = character.real_name - if(pref_species != /datum/species/human && config.mutant_races) - chosen_species = pref_species.type - else - chosen_species = /datum/species/human - hardset_dna(character, null, null, null, blood_type, chosen_species, features) + character.dna.blood_type = blood_type + character.dna.features = features + character.dna.real_name = character.real_name + var/datum/species/chosen_species + if(pref_species != /datum/species/human && config.mutant_races) + chosen_species = pref_species.type else + chosen_species = /datum/species/human + character.set_species(chosen_species, icon_update=0) + + if(icon_updates) character.update_body() - character.update_hair() \ No newline at end of file + character.update_hair() + character.update_mutcolor() \ No newline at end of file diff --git a/code/modules/detectivework/detective_work.dm b/code/modules/detectivework/detective_work.dm index 9d4981c9e80..fa324c1886c 100644 --- a/code/modules/detectivework/detective_work.dm +++ b/code/modules/detectivework/detective_work.dm @@ -52,21 +52,19 @@ if(isnull(M.key)) return if(ishuman(M)) var/mob/living/carbon/human/H = M - if(!istype(H.dna, /datum/dna)) - return 0 if(H.gloves) if(fingerprintslast != H.ckey) - fingerprintshidden += text("\[[time_stamp()]\] (Wearing gloves). Real name: [], Key: []",H.real_name, H.key) + fingerprintshidden += "\[[time_stamp()]\] (Wearing gloves). Real name: [H.real_name], Key: [H.key]" fingerprintslast = H.ckey return 0 - if(!( fingerprints )) + if(!fingerprints) if(fingerprintslast != H.ckey) - fingerprintshidden += text("\[[time_stamp()]\] Real name: [], Key: []",H.real_name, H.key) + fingerprintshidden += "\[[time_stamp()]\] Real name: [H.real_name], Key: [H.key]" fingerprintslast = H.ckey return 1 else if(fingerprintslast != M.ckey) - fingerprintshidden += text("\[[time_stamp()]\] Real name: [], Key: []",M.real_name, M.key) + fingerprintshidden += "\[[time_stamp()]\] Real name: [M.real_name], Key: [M.key]" fingerprintslast = M.ckey return @@ -75,17 +73,15 @@ if(isnull(M)) return if(isnull(M.key)) return if(ishuman(M)) + var/mob/living/carbon/human/H = M //Add the list if it does not exist. if(!fingerprintshidden) fingerprintshidden = list() //Fibers~ - add_fibers(M) + add_fibers(H) //Now, lets get to the dirty work. - //First, make sure their DNA makes sense. - var/mob/living/carbon/human/H = M - check_dna_integrity(H) //sets up dna and its variables if it was missing somehow //Check if the gloves (if any) hide fingerprints if(H.gloves) diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm index 5651ca8825e..01a41abc9fd 100644 --- a/code/modules/detectivework/scanner.dm +++ b/code/modules/detectivework/scanner.dm @@ -83,7 +83,7 @@ if(ishuman(A)) var/mob/living/carbon/human/H = A - if (istype(H.dna, /datum/dna) && !H.gloves) + if(!H.gloves) fingerprints += md5(H.dna.uni_identity) else if(!ismob(A)) diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm index a08a507a907..107c8f10920 100644 --- a/code/modules/events/holiday/halloween.dm +++ b/code/modules/events/holiday/halloween.dm @@ -11,11 +11,10 @@ for(var/mob/living/carbon/human/H in mob_list) var/obj/item/weapon/storage/backpack/b = locate() in H.contents new /obj/item/weapon/storage/spooky(b) - if(H.dna) - if(prob(50)) - hardset_dna(H, null, null, null, null, /datum/species/skeleton) - else - hardset_dna(H, null, null, null, null, /datum/species/zombie) + if(prob(50)) + H.set_species(/datum/species/skeleton) + else + H.set_species(/datum/species/zombie) for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in mob_list) Ian.place_on_head(new /obj/item/weapon/bedsheet(Ian)) diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index f86ecdb5c42..c83ea419df4 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -43,10 +43,9 @@ if(prob(25)) if(prob(75)) randmutb(H) - domutcheck(H, null, 1) else randmutg(H) - domutcheck(H, null, 1) + H.domutcheck() else if(istype(C, /mob/living/carbon/monkey)) var/mob/living/carbon/monkey/M = C diff --git a/code/modules/events/wizard/imposter.dm b/code/modules/events/wizard/imposter.dm index cda6dc2d41f..9a155830455 100644 --- a/code/modules/events/wizard/imposter.dm +++ b/code/modules/events/wizard/imposter.dm @@ -17,13 +17,11 @@ PoolOrNew(/obj/effect/effect/smoke, W.loc) var/mob/living/carbon/human/I = new /mob/living/carbon/human(W.loc) - I.real_name = W.real_name - I.dna.unique_enzymes = W.dna.unique_enzymes - I.name = W.real_name - I.dna.blood_type = W.dna.blood_type - I.dna.uni_identity = W.dna.uni_identity - I.dna.struc_enzymes = W.dna.struc_enzymes - updateappearance(I) + W.dna.transfer_identity(I, transfer_SE=1) + I.real_name = I.dna.real_name + I.name = I.dna.real_name + I.updateappearance(mutcolor_update=1) + I.domutcheck() if(W.ears) I.equip_to_slot_or_del(new W.ears.type, slot_ears) if(W.w_uniform) I.equip_to_slot_or_del(new W.w_uniform.type , slot_w_uniform) if(W.shoes) I.equip_to_slot_or_del(new W.shoes.type, slot_shoes) diff --git a/code/modules/events/wizard/race.dm b/code/modules/events/wizard/race.dm index 54c3cbf6877..7bbee2ba98c 100644 --- a/code/modules/events/wizard/race.dm +++ b/code/modules/events/wizard/race.dm @@ -21,10 +21,9 @@ all_the_same = 1 for(var/mob/living/carbon/human/H in mob_list) //yes, even the dead - if(H.dna) - hardset_dna(H, null, null, null, null, new_species) - H.real_name = new_species.random_name(H.gender,1) - H.regenerate_icons() - H << "You feel somehow... different?" + H.set_species(new_species) + H.real_name = new_species.random_name(H.gender,1) + H.dna.unique_enzymes = H.dna.generate_unique_enzymes() + H << "You feel somehow... different?" if(!all_the_same) new_species = pick(all_species) diff --git a/code/modules/food&drinks/kitchen machinery/processor.dm b/code/modules/food&drinks/kitchen machinery/processor.dm index 431dee34309..5db38bbc970 100644 --- a/code/modules/food&drinks/kitchen machinery/processor.dm +++ b/code/modules/food&drinks/kitchen machinery/processor.dm @@ -112,8 +112,8 @@ for(var/datum/disease/D in O.viruses) if(!(D.spread_flags & SPECIAL)) B.data["viruses"] += D.Copy() - if(check_dna_integrity(O)) - B.data["blood_DNA"] = copytext(O.dna.unique_enzymes,1,0) + if(O.has_dna()) + B.data["blood_DNA"] = O.dna.unique_enzymes if(O.resistances&&O.resistances.len) B.data["resistances"] = O.resistances.Copy() diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 7155b547781..082ed238267 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -897,7 +897,7 @@ podman.faction |= factions if(!features["mcolor"]) features["mcolor"] = "#59CE00" - hardset_dna(podman,null,null,podman.real_name,blood_type,/datum/species/plant/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman + podman.hardset_dna(null,null,podman.real_name,blood_type,/datum/species/plant/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman podman.set_cloned_appearance() else //else, one packet of seeds. maybe two diff --git a/code/modules/mob/interactive.dm b/code/modules/mob/interactive.dm index 0660e8e4f99..3c24e017066 100644 --- a/code/modules/mob/interactive.dm +++ b/code/modules/mob/interactive.dm @@ -86,22 +86,14 @@ /mob/living/carbon/human/interactive/proc/random() //this is here because this has no client/prefs/brain whatever. - underwear = random_underwear(gender) - skin_tone = random_skin_tone() - hair_style = random_hair_style(gender) - facial_hair_style = random_facial_hair_style(gender) - hair_color = random_short_color() - facial_hair_color = hair_color - eye_color = "blue" age = rand(AGE_MIN,AGE_MAX) - ready_dna(src,random_blood_type()) //job handling var/list/jobs = SSjob.occupations for(var/datum/job/J in jobs) if(J.title == "Cyborg" || J.title == "AI" || J.title == "Chaplain" || J.title == "Mime") jobs -= J myjob = pick(jobs) - src.job = myjob.title + job = myjob.title if(!graytide) myjob.equip(src) myjob.apply_fingerprints(src) @@ -120,25 +112,18 @@ /mob/living/carbon/human/interactive/New() ..() - gender = pick(MALE,FEMALE) - if(gender == MALE) - name = "[pick(first_names_male)] [pick(last_names)]" - real_name = name - else - name = "[pick(first_names_female)] [pick(last_names)]" - real_name = name random() MYID = new(src) MYID.name = "[src.real_name]'s ID Card ([myjob.title])" MYID.assignment = "[myjob.title]" MYID.registered_name = src.real_name MYID.access = myjob.access - src.equip_to_slot_or_del(MYID, slot_wear_id) + equip_to_slot_or_del(MYID, slot_wear_id) MYPDA = new(src) - MYPDA.owner = src.real_name + MYPDA.owner = real_name MYPDA.ownjob = "Crew" - MYPDA.name = "PDA-[src.real_name] ([myjob.title])" - src.equip_to_slot_or_del(MYPDA, slot_belt) + MYPDA.name = "PDA-[real_name] ([myjob.title])" + equip_to_slot_or_del(MYPDA, slot_belt) zone_sel = new /obj/screen/zone_sel() zone_sel.selecting = "chest" if(prob(10)) //my x is augmented @@ -371,9 +356,7 @@ if(!l_hand || !r_hand) var/obj/item/clothing/C = TARGET take_to_slot(C) - if(equip_to_appropriate_slot(C)) - C.update_icon() - else + if(!equip_to_appropriate_slot(C)) var/obj/item/I = get_item_by_slot(C) unEquip(I) equip_to_appropriate_slot(C) @@ -384,7 +367,6 @@ equip_to_appropriate_slot(MYPDA) if(MYID in src.loc) equip_to_appropriate_slot(MYID) - update_icons() //THIEVING SKILLS END //-------------TOUCH ME if(istype(TARGET,/obj/structure)) diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm index 3f7bfba90cf..38c89f9a3c9 100644 --- a/code/modules/mob/living/bloodcrawl.dm +++ b/code/modules/mob/living/bloodcrawl.dm @@ -31,11 +31,23 @@ obj/effect/dummy/slaughter/relaymove(mob/user, direction) /mob/living/proc/phaseout(obj/effect/decal/cleanable/B) + if(iscarbon(src)) + var/mob/living/carbon/C = src + if(C.l_hand || C.r_hand) + C << "You may not hold items while blood crawling!" + return 0 + var/obj/item/weapon/bloodcrawl/B1 = new(C) + var/obj/item/weapon/bloodcrawl/B2 = new(C) + B1.icon_state = "bloodhand_left" + B2.icon_state = "bloodhand_right" + C.put_in_hands(B1) + C.put_in_hands(B2) + C.regenerate_icons() var/mob/living/kidnapped = null var/turf/mobloc = get_turf(src.loc) src.notransform = TRUE spawn(0) - src.visible_message("[src] sinks into the pool of blood.") + src.visible_message("[src] sinks into the pool of blood!") playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, 1, -1) var/obj/effect/dummy/slaughter/holder = PoolOrNew(/obj/effect/dummy/slaughter,mobloc) src.ExtinguishMob() @@ -45,42 +57,71 @@ obj/effect/dummy/slaughter/relaymove(mob/user, direction) if(istype(src.pulling, /mob/living)) var/mob/living/victim = src.pulling if(victim.stat == CONSCIOUS) - src.visible_message("[victim] kicks free of the [src] at the last second!") + src.visible_message("[victim] kicks free of the blood pool just before entering it!") else victim.loc = holder - src.visible_message("The [src] drags [victim] into the pool of blood!") + victim.emote("scream") + src.visible_message("[src] drags [victim] into the pool of blood!") kidnapped = victim src.loc = holder src.holder = holder if(kidnapped) - src << "You begin to feast on [kidnapped]. You can not move while you are doing this." - playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1) - sleep(30) - playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1) - sleep(30) - playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1) - sleep(30) + src << "You begin to feast on [kidnapped]. You can not move while you are doing this." + for(var/i = 3; i > 0; i--) + playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1) + sleep(30) if(kidnapped) - src << "You devour [kidnapped]. Your health is fully restored." + src << "You devour [kidnapped]. Your health is fully restored." src.adjustBruteLoss(-1000) src.adjustFireLoss(-1000) src.adjustOxyLoss(-1000) src.adjustToxLoss(-1000) - kidnapped.ghostize() - qdel(kidnapped) + if(istype(src, /mob/living/simple_animal/slaughter)) + var/mob/living/simple_animal/slaughter/S = src + kidnapped << "You feel teeth sink into your flesh, and the--" + kidnapped.adjustBruteLoss(1000) + kidnapped.loc = src + S.consumed_mobs.Add(kidnapped) + else + kidnapped.ghostize() + qdel(kidnapped) else - src << "You happily devour...nothing? Your meal vanished at some point!" + src << "You happily devour... nothing? Your meal vanished at some point!" src.notransform = 0 + return 1 + +/obj/item/weapon/bloodcrawl + name = "blood crawl" + desc = "You are unable to hold anything while in this form." + icon = 'icons/effects/blood.dmi' + flags = NODROP /mob/living/proc/phasein(obj/effect/decal/cleanable/B) if(src.notransform) - src << "Finish eating first!" + src << "Finish eating first!" return 0 - + B.visible_message("[B] starts to bubble...") + if(!do_after(src, 20, target = B)) + return + if(!B) + return src.loc = B.loc src.client.eye = src - src.visible_message("The [src] rises out of the pool of blood!") + src.visible_message("[src] rises out of the pool of blood!") playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1) + if(iscarbon(src)) + var/mob/living/carbon/C = src + for(var/obj/item/weapon/bloodcrawl/BC in C) + C.flags = null + C.unEquip(BC) + qdel(BC) + var/oldcolor = src.color + if(istype(B, /obj/effect/decal/cleanable/xenoblood)) //Makes the mob have the color of the blood pool it came out of for a few seconds + src.color = rgb(43, 186, 0) + else + src.color = rgb(149, 10, 10) qdel(src.holder) src.holder = null - return 1 \ No newline at end of file + spawn(30) + src.color = oldcolor + return 1 diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 248d147de43..f615908affe 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -85,15 +85,18 @@ update_icon() name = "Man-Machine Interface" -/obj/item/device/mmi/proc/transfer_identity(mob/living/carbon/human/H) //Same deal as the regular brain proc. Used for human-->robot people. +/obj/item/device/mmi/proc/transfer_identity(mob/living/L) //Same deal as the regular brain proc. Used for human-->robot people. brainmob = new(src) - brainmob.name = H.real_name - brainmob.real_name = H.real_name - if(check_dna_integrity(H)) - brainmob.dna = H.dna + brainmob.name = L.real_name + brainmob.real_name = L.real_name + if(L.has_dna()) + var/mob/living/carbon/C = L + brainmob.dna = C.dna + brainmob.dna.holder = brainmob brainmob.container = src - if(istype(H)) + if(ishuman(L)) + var/mob/living/carbon/human/H = L var/obj/item/organ/internal/brain/newbrain = H.getorgan(/obj/item/organ/internal/brain) newbrain.loc = src brain = newbrain diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 981facfcc9b..81c7deec716 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -26,10 +26,10 @@ qdel(brainmob) - //Update the body's icon so it doesnt appear debrained anymore - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.update_hair(0) + //Update the body's icon so it doesnt appear debrained anymore + if(ishuman(M)) + var/mob/living/carbon/human/H = M + H.update_hair(0) /obj/item/organ/internal/brain/Remove(mob/living/carbon/M, special = 0) ..() @@ -56,9 +56,10 @@ brainmob.name = L.real_name brainmob.real_name = L.real_name brainmob.timeofhostdeath = L.timeofdeath - if(iscarbon(L)) + if(L.has_dna()) var/mob/living/carbon/C = L brainmob.dna = C.dna + brainmob.dna.holder = brainmob if(L.mind) L.mind.transfer_to(brainmob) brainmob << "You feel slightly disoriented. That's normal when you're just a brain." diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm index 7f8445b95fc..ae7508be604 100644 --- a/code/modules/mob/living/carbon/brain/posibrain.dm +++ b/code/modules/mob/living/carbon/brain/posibrain.dm @@ -55,17 +55,20 @@ var/global/posibrain_notif_cooldown = 0 return transfer_personality(user) -/obj/item/device/mmi/posibrain/transfer_identity(mob/living/carbon/H) - name = "positronic brain ([H])" - brainmob.name = H.real_name - brainmob.real_name = H.real_name - brainmob.dna = H.dna - brainmob.timeofhostdeath = H.timeofdeath +/obj/item/device/mmi/posibrain/transfer_identity(mob/living/carbon/C) + name = "positronic brain ([C])" + brainmob.name = C.real_name + brainmob.real_name = C.real_name + brainmob.dna = C.dna + if(C.has_dna()) + brainmob.dna = C.dna + brainmob.dna.holder = brainmob + brainmob.timeofhostdeath = C.timeofdeath brainmob.stat = 0 if(brainmob.mind) brainmob.mind.assigned_role = "Positronic Brain" - if(H.mind) - H.mind.transfer_to(brainmob) + if(C.mind) + C.mind.transfer_to(brainmob) brainmob.mind.remove_all_antag() brainmob.mind.wipe_memory() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 6a001457d30..ff959f6c940 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -22,6 +22,8 @@ for(var/atom/movable/food in stomach_contents) qdel(food) remove_from_all_data_huds() + if(dna) + qdel(dna) return ..() /mob/living/carbon/Move(NewLoc, direct) diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 580b0b5919d..89af6c2f4ca 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -9,9 +9,6 @@ var/obj/item/handcuffed = null //Whether or not the mob is handcuffed var/obj/item/legcuffed = null //Same as handcuffs but for legs. Bear traps use this. - var/list/features = list("mcolor" = "FFF", "tail" = "Smooth", "snout" = "Round", "horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None") - - //inventory slots var/obj/item/back = null var/obj/item/clothing/mask/wear_mask = null diff --git a/code/modules/mob/living/carbon/human/blood.dm b/code/modules/mob/living/carbon/human/blood.dm index e91eca45fb3..86ab99bf505 100644 --- a/code/modules/mob/living/carbon/human/blood.dm +++ b/code/modules/mob/living/carbon/human/blood.dm @@ -272,10 +272,9 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 source = M.get_blood(M.vessel) else if(istype(source,/mob/living/carbon/monkey)) var/mob/living/carbon/monkey/donor = source - if(donor.dna) - source = new() - source.data["blood_DNA"] = donor.dna.unique_enzymes - source.data["blood_type"] = donor.dna.blood_type + source = new() + source.data["blood_DNA"] = donor.dna.unique_enzymes + source.data["blood_type"] = donor.dna.blood_type // Are we dripping or splattering? var/list/drips = list() diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 147a0a7f016..a24e880ed7a 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -8,10 +8,7 @@ ..() /mob/living/carbon/human/spawn_gibs() - if(dna) - hgibs(loc, viruses, dna) - else - hgibs(loc, viruses, null) + hgibs(loc, viruses, dna) /mob/living/carbon/human/spawn_dust() new /obj/effect/decal/remains/human(loc) @@ -35,8 +32,7 @@ update_canmove() if(client) blind.layer = 0 - if(dna) - dna.species.spec_death(gibbed,src) + dna.species.spec_death(gibbed,src) tod = worldtime2text() //weasellos time of death patch if(mind) mind.store_memory("Time of death: [tod]", 0) @@ -47,9 +43,8 @@ return ..(gibbed) /mob/living/carbon/human/proc/makeSkeleton() - if(!check_dna_integrity(src)) return status_flags |= DISFIGURED - hardset_dna(src, null, null, null, null, /datum/species/skeleton) + set_species(/datum/species/skeleton) return 1 /mob/living/carbon/proc/ChangeToHusk() diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index c90c5171808..2ab52c617ef 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -308,7 +308,7 @@ m_type = 2 if("wag","wags") - if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || (features["tail_human"] != "None"))) + if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || (dna.features["tail_human"] != "None"))) message = "[src] wags \his tail." startTailWag() else diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b2e031465b2..2b585fa1f89 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -16,6 +16,12 @@ /mob/living/carbon/human/New() verbs += /mob/living/proc/mob_sleep verbs += /mob/living/proc/lay_down + + //initialize dna. for spawned humans; overwritten by other code + create_dna(src) + randomize_human(src) + dna.initialize_dna() + //initialise organs organs = newlist(/obj/item/organ/limb/chest, /obj/item/organ/limb/head, /obj/item/organ/limb/l_arm, /obj/item/organ/limb/r_arm, /obj/item/organ/limb/r_leg, /obj/item/organ/limb/l_leg) @@ -28,11 +34,6 @@ for(var/obj/item/organ/internal/I in internal_organs) I.Insert(src) - // for spawned humans; overwritten by other code - create_dna(src) - randomize_human(src) - ready_dna(src) - make_blood() ..() @@ -90,9 +91,8 @@ stat("Energy Charge:", "[round(SN.cell.charge/100)]%") stat("Smoke Bombs:", "\Roman [SN.s_bombs]") //Ninja status - if(dna) - stat("Fingerprints:", "[md5(dna.uni_identity)]") - stat("Unique Identity:", "[dna.unique_enzymes]") + stat("Fingerprints:", "[md5(dna.uni_identity)]") + stat("Unique Identity:", "[dna.unique_enzymes]") stat("Overall Status:", "[stat > 1 ? "dead" : "[health]% healthy"]") stat("Nutrition Status:", "[nutrition]") stat("Oxygen Loss:", "[getOxyLoss()]") @@ -663,7 +663,8 @@ facial_hair_style = "Shaved" hair_style = pick("Bedhead", "Bedhead 2", "Bedhead 3") underwear = "Nude" - regenerate_icons() + update_body() + update_hair() /mob/living/carbon/human/singularity_act() var/gain = 20 diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 39ba01934e5..b1502b73eef 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -7,11 +7,7 @@ /mob/living/carbon/human/attack_hand(mob/living/carbon/human/M) if(..()) //to allow surgery to return properly. return - - if(dna) - dna.species.spec_attack_hand(M, src) - - return + dna.species.spec_attack_hand(M, src) /mob/living/carbon/human/proc/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, inrange, params) return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 4cd0b1b833a..37f501760a5 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -160,38 +160,5 @@ /mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0) - if(dna) // if you have a species, it will run the apply_damage code there instead - dna.species.apply_damage(damage, damagetype, def_zone, blocked, src) - else - if((damagetype != BRUTE) && (damagetype != BURN)) - ..(damage, damagetype, def_zone, blocked) - return 1 - - else - blocked = (100-blocked)/100 - if(blocked <= 0) return 0 - - var/obj/item/organ/limb/organ = null - if(islimb(def_zone)) - organ = def_zone - else - if(!def_zone) def_zone = ran_zone(def_zone) - organ = get_organ(check_zone(def_zone)) - if(!organ) return 0 - - damage = (damage * blocked) - - switch(damagetype) - if(BRUTE) - damageoverlaytemp = 20 - if(organ.take_damage(damage, 0)) - update_damage_overlays(0) - if(BURN) - damageoverlaytemp = 20 - if(organ.take_damage(0, damage)) - update_damage_overlays(0) - - // Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life(). - - updatehealth() - return 1 + // depending on the species, it will run the corresponding apply_damage code there + return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index b06507cff74..d11d0e389e2 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -37,9 +37,7 @@ emp_act return protection /mob/living/carbon/human/on_hit(proj_type) - if(dna) - dna.species.on_hit(proj_type, src) - return + dna.species.on_hit(proj_type, src) /mob/living/carbon/human/bullet_act(obj/item/projectile/P, def_zone) if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam)) @@ -128,91 +126,8 @@ emp_act feedback_add_details("item_used_for_combat","[I.type]|[I.force]") feedback_add_details("zone_targeted","[target_area]") - if(dna) // allows your species to affect the attacked_by code - return dna.species.spec_attacked_by(I,user,def_zone,affecting,hit_area,src.a_intent,target_limb,target_area,src) - - else - if(user != src) - user.do_attack_animation(src) - if(check_shields(I.force, "the [I.name]", I)) - return 0 - - if(I.attack_verb && I.attack_verb.len) - visible_message("[user] has [pick(I.attack_verb)] [src] in the [hit_area] with [I]!", \ - "[user] has [pick(I.attack_verb)] [src] in the [hit_area] with [I]!") - else if(I.force) - visible_message("[user] has attacked [src] in the [hit_area] with [I]!", \ - "[user] has attacked [src] in the [hit_area] with [I]!") - else - return 0 - - var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened a hit to your [hit_area].", I.armour_penetration) - armor = min(90,armor) //cap damage reduction at 90% - - var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) - - apply_damage(I.force, I.damtype, affecting, armor , I) - var/bloody = 0 - if(((I.damtype == BRUTE) && I.force && prob(25 + (I.force * 2)))) - if(affecting.status == ORGAN_ORGANIC) - I.add_blood(src) //Make the weapon bloody, not the person. - if(prob(I.force * 2)) //blood spatter! - bloody = 1 - var/turf/location = loc - if(istype(location, /turf/simulated)) - location.add_blood(src) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(get_dist(H, src) <= 1) //people with TK won't get smeared with blood - if(H.wear_suit) - H.wear_suit.add_blood(src) - H.update_inv_wear_suit() //updates mob overlays to show the new blood (no refresh) - else if(H.w_uniform) - H.w_uniform.add_blood(src) - H.update_inv_w_uniform() //updates mob overlays to show the new blood (no refresh) - if (H.gloves) - var/obj/item/clothing/gloves/G = H.gloves - G.add_blood(H) - else - H.add_blood(H) - H.update_inv_gloves() //updates on-mob overlays for bloody hands and/or bloody gloves - - switch(hit_area) - if("head") //Harder to score a stun but if you do it lasts a bit longer - if(stat == CONSCIOUS) - if(prob(I.force)) - visible_message("[src] has been knocked unconscious!", \ - "[src] has been knocked unconscious!") - apply_effect(20, PARALYZE, armor) - if(prob(I.force + min(100,100 - src.health)) && src != user && I.damtype == BRUTE) - ticker.mode.remove_revolutionary(mind) - if(bloody) //Apply blood - if(wear_mask) - wear_mask.add_blood(src) - update_inv_wear_mask() - if(head) - head.add_blood(src) - update_inv_head() - if(glasses && prob(33)) - glasses.add_blood(src) - update_inv_glasses() - - if("chest") //Easier to score a stun but lasts less time - if(stat == CONSCIOUS && I.force && prob(I.force + 10)) - visible_message("[src] has been knocked down!", \ - "[src] has been knocked down!") - apply_effect(5, WEAKEN, armor) - - if(bloody) - if(wear_suit) - wear_suit.add_blood(src) - update_inv_wear_suit() - if(w_uniform) - w_uniform.add_blood(src) - update_inv_w_uniform() - - if(Iforce > 10 || Iforce >= 5 && prob(33)) - forcesay(hit_appends) //forcesay checks stat already + // the attacked_by code varies among species + return dna.species.spec_attacked_by(I,user,def_zone,affecting,hit_area,src.a_intent,target_limb,target_area,src) /mob/living/carbon/human/emp_act(severity) var/informed = 0 diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index f63e04ad3cf..ed0add4de62 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -128,11 +128,9 @@ return (health <= config.health_threshold_crit && stat == UNCONSCIOUS) /mob/living/carbon/human/reagent_check(datum/reagent/R) - if(dna) - var/bypass = dna.species.handle_chemicals(R,src) - return bypass // if it returns 0, it will run the usual on_mob_life for that reagent. otherwise, it will stop after running handle_chemicals for the species. - else - return 0 + return dna.species.handle_chemicals(R,src) + // if it returns 0, it will run the usual on_mob_life for that reagent. otherwise, it will stop after running handle_chemicals for the species. + /mob/living/carbon/human/can_track(mob/living/user) if(wear_id && istype(wear_id.GetID(), /obj/item/weapon/card/id/syndicate)) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 69412112239..ca451659a7e 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -1,6 +1,6 @@ /mob/living/carbon/human/movement_delay() - if(dna) - . += dna.species.movement_delay(src) + + . += dna.species.movement_delay(src) . += ..() . += config.human_delay @@ -46,9 +46,8 @@ /mob/living/carbon/human/Move(NewLoc, direct) . = ..() - if(dna) - for(var/datum/mutation/human/HM in dna.mutations) - HM.on_move(src, NewLoc) + for(var/datum/mutation/human/HM in dna.mutations) + HM.on_move(src, NewLoc) if(shoes) if(!lying) if(loc == NewLoc) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index db4591a230d..5968b88647e 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -1,158 +1,5 @@ /mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = 0) - if(dna) - return dna.species.can_equip(I, slot, disable_warning, src) - else - switch(slot) - if(slot_l_hand) - if(l_hand) - return 0 - return 1 - if(slot_r_hand) - if(r_hand) - return 0 - return 1 - if(slot_wear_mask) - if(wear_mask) - return 0 - if( !(I.slot_flags & SLOT_MASK) ) - return 0 - return 1 - if(slot_back) - if(back) - return 0 - if( !(I.slot_flags & SLOT_BACK) ) - return 0 - return 1 - if(slot_wear_suit) - if(wear_suit) - return 0 - if( !(I.slot_flags & SLOT_OCLOTHING) ) - return 0 - return 1 - if(slot_gloves) - if(gloves) - return 0 - if( !(I.slot_flags & SLOT_GLOVES) ) - return 0 - return 1 - if(slot_shoes) - if(shoes) - return 0 - if( !(I.slot_flags & SLOT_FEET) ) - return 0 - return 1 - if(slot_belt) - if(belt) - return 0 - if(!w_uniform) - if(!disable_warning) - src << "You need a jumpsuit before you can attach this [I.name]!" - return 0 - if( !(I.slot_flags & SLOT_BELT) ) - return - return 1 - if(slot_glasses) - if(glasses) - return 0 - if( !(I.slot_flags & SLOT_EYES) ) - return 0 - return 1 - if(slot_head) - if(head) - return 0 - if( !(I.slot_flags & SLOT_HEAD) ) - return 0 - return 1 - if(slot_ears) - if(ears) - return 0 - if( !(I.slot_flags & SLOT_EARS) ) - return 0 - return 1 - if(slot_w_uniform) - if(w_uniform) - return 0 - if( !(I.slot_flags & SLOT_ICLOTHING) ) - return 0 - return 1 - if(slot_wear_id) - if(wear_id) - return 0 - if(!w_uniform) - if(!disable_warning) - src << "You need a jumpsuit before you can attach this [I.name]!" - return 0 - if( !(I.slot_flags & SLOT_ID) ) - return 0 - return 1 - if(slot_l_store) - if(I.flags & NODROP) //Pockets aren't visible, so you can't move NODROP items into them. - return 0 - if(l_store) - return 0 - if(!w_uniform) - if(!disable_warning) - src << "You need a jumpsuit before you can attach this [I.name]!" - return 0 - if(I.slot_flags & SLOT_DENYPOCKET) - return - if( I.w_class <= 2 || (I.slot_flags & SLOT_POCKET) ) - return 1 - if(slot_r_store) - if(I.flags & NODROP) - return 0 - if(r_store) - return 0 - if(!w_uniform) - if(!disable_warning) - src << "You need a jumpsuit before you can attach this [I.name]!" - return 0 - if(I.slot_flags & SLOT_DENYPOCKET) - return 0 - if( I.w_class <= 2 || (I.slot_flags & SLOT_POCKET) ) - return 1 - return 0 - if(slot_s_store) - if(I.flags & NODROP) //Suit storage NODROP items drop if you take a suit off, this is to prevent people exploiting this. - return 0 - if(s_store) - return 0 - if(!wear_suit) - if(!disable_warning) - src << "You need a suit before you can attach this [I.name]!" - return 0 - if(!wear_suit.allowed) - if(!disable_warning) - usr << "You somehow have a suit with no defined allowed items for suit storage, stop that!" //should be src? - return 0 - if(I.w_class > 4) - if(!disable_warning) - usr << "The [I.name] is too big to attach!" //should be src? - return 0 - if( istype(I, /obj/item/device/pda) || istype(I, /obj/item/weapon/pen) || is_type_in_list(I, wear_suit.allowed) ) //ugly and un-polymorphic. - return 1 - return 0 - if(slot_handcuffed) - if(handcuffed) - return 0 - if(!istype(I, /obj/item/weapon/restraints/handcuffs)) - return 0 - return 1 - if(slot_legcuffed) - if(legcuffed) - return 0 - if(!istype(I, /obj/item/weapon/restraints/legcuffs)) - return 0 - return 1 - if(slot_in_backpack) - if (back && istype(back, /obj/item/weapon/storage/backpack)) - var/obj/item/weapon/storage/backpack/B = back - if(B.contents.len < B.storage_slots && I.w_class <= B.max_w_class) - return 1 - return 0 - return 0 //Unsupported slot - - + return dna.species.can_equip(I, slot, disable_warning, src) /mob/living/carbon/human/verb/quick_equip() set name = "quick-equip" @@ -477,7 +324,7 @@ /mob/living/carbon/human/proc/equipOutfit(outfit) var/datum/outfit/O = null - + if(ispath(outfit)) O = new outfit else @@ -486,5 +333,5 @@ return 0 if(!O) return 0 - + return O.equip(src) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 0d51f2f5d0d..b4f66fe3ccc 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -38,9 +38,8 @@ tinttotal = tintcheck() //here as both hud updates and status updates call it if(..()) - if(dna) - for(var/datum/mutation/human/HM in dna.mutations) - HM.on_life(src) + for(var/datum/mutation/human/HM in dna.mutations) + HM.on_life(src) //heart attack stuff handle_heart() @@ -50,8 +49,7 @@ //Update our name based on whether our face is obscured/disfigured name = get_visible_name() - if(dna) - dna.species.spec_life(src) // for mutantraces + dna.species.spec_life(src) // for mutantraces /mob/living/carbon/human/calculate_affecting_pressure(pressure) @@ -98,16 +96,15 @@ reagents.metabolize(src, can_overdose=1) /mob/living/carbon/human/breathe() - if(!dna || !dna.species.breathe(src)) + if(!dna.species.breathe(src)) ..() /mob/living/carbon/human/check_breath(datum/gas_mixture/breath) - if(!dna || !dna.species.check_breath(breath, src)) + if(!dna.species.check_breath(breath, src)) ..() /mob/living/carbon/human/handle_environment(datum/gas_mixture/environment) - if(dna) - dna.species.handle_environment(environment, src) + dna.species.handle_environment(environment, src) ///FIRE CODE /mob/living/carbon/human/handle_fire() @@ -263,10 +260,7 @@ /mob/living/carbon/human/handle_chemicals_in_body() ..() - if(dna) - dna.species.handle_chemicals_in_body(src) - - return //TODO: DEFERRED + dna.species.handle_chemicals_in_body(src) /mob/living/carbon/human/handle_vision() client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask) @@ -275,12 +269,10 @@ else if(!client.adminobs) reset_view(null) - if(dna) - dna.species.handle_vision(src) + dna.species.handle_vision(src) /mob/living/carbon/human/handle_hud_icons() - if(dna) - dna.species.handle_hud_icons(src) + dna.species.handle_hud_icons(src) /mob/living/carbon/human/handle_random_events() // Puke if toxloss is too high diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 8b0fdbe16d5..4720ac6a5cf 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -9,8 +9,7 @@ return ..() /mob/living/carbon/human/treat_message(message) - if(dna) - message = dna.species.handle_speech(message,src) + message = dna.species.handle_speech(message,src) if(viruses.len) for(var/datum/disease/pierrot_throat/D in viruses) var/list/temp_message = text2list(message, " ") //List each word in the message @@ -25,8 +24,7 @@ pick_list -= H //Make sure that you dont HONK the same word twice message = list2text(temp_message, " ") message = ..(message) - if(dna) - message = dna.mutations_say_mods(message) + message = dna.mutations_say_mods(message) return message /mob/living/carbon/human/get_spans() diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 5ffd1419253..f9973ea991d 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -247,7 +247,7 @@ if(H.undershirt) var/datum/sprite_accessory/undershirt/U2 = undershirt_list[H.undershirt] if(U2) - if(H.dna && H.dna.species.sexes && H.gender == FEMALE) + if(H.dna.species.sexes && H.gender == FEMALE) standing += H.wear_female_version(U2.icon_state, U2.icon, BODY_LAYER) else standing += image("icon"=U2.icon, "icon_state"="[U2.icon_state]_s", "layer"=-BODY_LAYER) @@ -804,8 +804,8 @@ if(prob(1)) H << "You mutate!" randmutb(H) - domutcheck(H,null) H.emote("gasp") + H.domutcheck() return 0 return 1 @@ -907,22 +907,14 @@ else M.do_attack_animation(H) - var/atk_verb = "punch" + var/atk_verb = M.dna.species.attack_verb if(H.lying) atk_verb = "kick" - else if(M.dna) - atk_verb = M.dna.species.attack_verb - var/damage = rand(0, 9) - if(M.dna) - damage += M.dna.species.punchmod + var/damage = rand(0, 9) + M.dna.species.punchmod if(!damage) - if(M.dna) - playsound(H.loc, M.dna.species.miss_sound, 25, 1, -1) - else - playsound(H.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - + playsound(H.loc, M.dna.species.miss_sound, 25, 1, -1) H.visible_message("[M] has attempted to [atk_verb] [H]!") return 0 @@ -930,11 +922,7 @@ var/obj/item/organ/limb/affecting = H.get_organ(ran_zone(M.zone_sel.selecting)) var/armor_block = H.run_armor_check(affecting, "melee") - if(M.dna) - playsound(H.loc, M.dna.species.attack_sound, 25, 1, -1) - else - playsound(H.loc, 'sound/weapons/punch1.ogg', 25, 1, -1) - + playsound(H.loc, M.dna.species.attack_sound, 25, 1, -1) H.visible_message("[M] has [atk_verb]ed [H]!", \ "[M] has [atk_verb]ed [H]!") @@ -1008,9 +996,9 @@ /datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, def_zone, obj/item/organ/limb/affecting, hit_area, intent, obj/item/organ/limb/target_limb, target_area, mob/living/carbon/human/H) // Allows you to put in item-specific reactions based on species - if(user != src) + if(user != H) user.do_attack_animation(H) - if((user != H) && H.check_shields(I.force, "the [I.name]", I)) + if(H.check_shields(I.force, "the [I.name]", I)) return 0 if(I.attack_verb && I.attack_verb.len) @@ -1022,11 +1010,11 @@ else return 0 - var/armor = H.run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened a hit to your [hit_area].",I.armour_penetration) - armor = min(90,armor) //cap damage reduction at 90% + var/armor_block = H.run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened a hit to your [hit_area].",I.armour_penetration) + armor_block = min(90,armor_block) //cap damage reduction at 90% var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) - apply_damage(I.force, I.damtype, affecting, armor, H) + apply_damage(I.force, I.damtype, affecting, armor_block, H) var/bloody = 0 if(((I.damtype == BRUTE) && I.force && prob(25 + (I.force * 2)))) @@ -1037,28 +1025,30 @@ var/turf/location = H.loc if(istype(location, /turf/simulated)) location.add_blood(H) - if(get_dist(H, H) <= 1) //people with TK won't get smeared with blood - if(H.wear_suit) - H.wear_suit.add_blood(H) - H.update_inv_wear_suit() //updates mob overlays to show the new blood (no refresh) - else if(H.w_uniform) - H.w_uniform.add_blood(H) - H.update_inv_w_uniform() //updates mob overlays to show the new blood (no refresh) - if (H.gloves) - var/obj/item/clothing/gloves/G = H.gloves - G.add_blood(H) - else - H.add_blood(H) - H.update_inv_gloves() //updates on-mob overlays for bloody hands and/or bloody gloves + if(ishuman(user)) + var/mob/living/carbon/human/M = user + if(get_dist(M, H) <= 1) //people with TK won't get smeared with blood + if(M.wear_suit) + M.wear_suit.add_blood(H) + M.update_inv_wear_suit() //updates mob overlays to show the new blood (no refresh) + else if(M.w_uniform) + M.w_uniform.add_blood(H) + M.update_inv_w_uniform() //updates mob overlays to show the new blood (no refresh) + if (M.gloves) + var/obj/item/clothing/gloves/G = M.gloves + G.add_blood(H) + else + M.add_blood(H) + M.update_inv_gloves() //updates on-mob overlays for bloody hands and/or bloody gloves switch(hit_area) if("head") //Harder to score a stun but if you do it lasts a bit longer - if(H.stat == CONSCIOUS && armor < 50) + if(H.stat == CONSCIOUS && armor_block < 50) if(prob(I.force)) H.visible_message("[H] has been knocked unconscious!", \ "[H] has been knocked unconscious!") - H.apply_effect(20, PARALYZE, armor) + H.apply_effect(20, PARALYZE, armor_block) if(prob(I.force + ((100 - H.health)/2)) && H != user && I.damtype == BRUTE) ticker.mode.remove_revolutionary(H.mind) @@ -1077,7 +1067,7 @@ if(H.stat == CONSCIOUS && I.force && prob(I.force + 10)) H.visible_message("[H] has been knocked down!", \ "[H] has been knocked down!") - H.apply_effect(5, WEAKEN, armor) + H.apply_effect(5, WEAKEN, armor_block) if(bloody) if(H.wear_suit) @@ -1091,34 +1081,9 @@ H.forcesay(hit_appends) //forcesay checks stat already. return -/datum/species/proc/attacked_by(obj/item/I, mob/living/user, def_zone, mob/living/carbon/human/H) - H.apply_damage(I.force, I.damtype) - if(I.damtype == "brute") - if(prob(33) && I.force && !(NOBLOOD in specflags)) - var/turf/location = H.loc - if(istype(location, /turf/simulated)) - location.add_blood_floor(H) - - var/message_verb = "" - if(I.attack_verb && I.attack_verb.len) - message_verb = "[pick(I.attack_verb)]" - else if(I.force) - message_verb = "attacked" - - var/attack_message = "[H] has been [message_verb] with [I]." - if(user) - user.do_attack_animation(src) - if(user in viewers(src, null)) - attack_message = "[user] has [message_verb] [H] with [I]!" - if(message_verb) - H.visible_message("[attack_message]", - "[attack_message]") - - return - /datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H) blocked = (100-(blocked+armor))/100 - if(blocked <= 0) return 0 + if(!damage || blocked <= 0) return 0 var/obj/item/organ/limb/organ = null if(islimb(def_zone)) @@ -1147,6 +1112,7 @@ H.adjustCloneLoss(damage * blocked) if(STAMINA) H.adjustStaminaLoss(damage * blocked) + return 1 /datum/species/proc/on_hit(obj/item/projectile/proj_type, mob/living/carbon/human/H) // called when hit by a projectile diff --git a/code/modules/mob/living/carbon/human/species_types.dm b/code/modules/mob/living/carbon/human/species_types.dm index 2549b1635bf..cd5c473014b 100644 --- a/code/modules/mob/living/carbon/human/species_types.dm +++ b/code/modules/mob/living/carbon/human/species_types.dm @@ -38,8 +38,7 @@ /datum/species/human/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) if(chem.id == "mutationtoxin") H << "Your flesh rapidly mutates!" - hardset_dna(H, null, null, null, null, /datum/species/slime) - H.regenerate_icons() + H.set_species(/datum/species/slime) H.reagents.del_reagent(chem.type) H.faction |= "slime" return 1 @@ -128,10 +127,9 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H) H.visible_message("[H] writhes in pain as \his vacuoles boil.", "You writhe in pain as your vacuoles boil!", "You hear the crunching of leaves.") if(prob(80)) randmutb(H) - domutcheck(H,null) else randmutg(H) - domutcheck(H,null) + H.domutcheck() else H.adjustFireLoss(rand(5,15)) H.show_message("The radiation beam singes you!") diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 0ec31fdd1a3..1b3da71d25d 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -53,30 +53,10 @@ Please contact me on #coderbus IRC. ~Carnie x */ /mob/living/carbon/human/proc/update_base_icon_state() - if(dna) - base_icon_state = dna.species.update_base_icon_state(src) - else - if(disabilities & HUSK) - base_icon_state = "husk" - else - base_icon_state = "[skin_tone]_[(gender == FEMALE) ? "f" : "m"]" - + base_icon_state = dna.species.update_base_icon_state(src) icon_state = "[base_icon_state]_s" -//UPDATES OVERLAYS FROM OVERLAYS_STANDING -//TODO: Remove all instances where this proc is called. It used to be the fastest way to swap between standing/lying. -/mob/living/carbon/human/update_icons() - update_hud() //TODO: remove the need for this - - if(overlays.len != overlays_standing.len) - overlays.Cut() - - for(var/thing in overlays_standing) - if(thing) overlays += thing - - update_transform() - //DAMAGE OVERLAYS //constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists /mob/living/carbon/human/update_damage_overlays() @@ -105,25 +85,21 @@ Please contact me on #coderbus IRC. ~Carnie x if((wear_suit) && (wear_suit.hooded) && (wear_suit.suittoggled == 1)) return - if(dna) - dna.species.handle_hair(src) + dna.species.handle_hair(src) /mob/living/carbon/human/proc/update_mutcolor() - if(dna && !(disabilities & HUSK)) + if(!(disabilities & HUSK)) dna.species.update_color(src) +//used when putting/removing clothes that hide certain mutant body parts to just update those and not update the whole body. /mob/living/carbon/human/proc/update_mutant_bodyparts() - if(dna) - dna.species.handle_mutant_bodyparts(src) + dna.species.handle_mutant_bodyparts(src) /mob/living/carbon/human/proc/update_body() remove_overlay(BODY_LAYER) - update_base_icon_state() - - if(dna) - dna.species.handle_body(src) + dna.species.handle_body(src) /mob/living/carbon/human/update_fire() ..("Standing") @@ -181,6 +157,8 @@ Please contact me on #coderbus IRC. ~Carnie x update_hud() // Mutantrace colors update_mutcolor() + //mutations + update_mutations_overlay() /* --------------------------------------- */ //vvvvvv UPDATE_INV PROCS vvvvvv diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index fc9f30829cd..909d769ac74 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -38,8 +38,8 @@ if(prob(1)) src << "You mutate!" randmutb(src) - domutcheck(src,null) emote("gasp") + domutcheck() ..() /mob/living/carbon/monkey/handle_chemicals_in_body() diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index a1f11e9167f..64f73ca3980 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -16,16 +16,24 @@ verbs += /mob/living/proc/mob_sleep verbs += /mob/living/proc/lay_down + gender = pick(MALE, FEMALE) + real_name = name + if(good_mutations.len) //genetic mutations have been set up. + initialize() + internal_organs += new /obj/item/organ/internal/appendix internal_organs += new /obj/item/organ/internal/heart internal_organs += new /obj/item/organ/internal/brain for(var/obj/item/organ/internal/I in internal_organs) I.Insert(src) - gender = pick(MALE, FEMALE) ..() +/mob/living/carbon/monkey/initialize() + create_dna(src) + dna.initialize_dna(random_blood_type()) + /mob/living/carbon/monkey/prepare_data_huds() //Prepare our med HUD... ..() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 05fed0bff86..7d7b67a5d69 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -605,8 +605,8 @@ Sorry Giacom. Please don't be mad :( if((!(newdir in H.existing_dirs) || trail_type == "trails_1" || trail_type == "trails_2") && H.existing_dirs.len <= 16) //maximum amount of overlays is 16 (all light & heavy directions filled) H.existing_dirs += newdir H.overlays.Add(image('icons/effects/blood.dmi',trail_type,dir = newdir)) - if(check_dna_integrity(M)) //blood DNA - var/mob/living/carbon/DNA_helper = pulling + if(M.has_dna()) //blood DNA + var/mob/living/carbon/DNA_helper = M H.blood_DNA[DNA_helper.dna.unique_enzymes] = DNA_helper.dna.blood_type /mob/living/proc/getTrail() //silicon and simple_animals don't get blood trails diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 67e827da796..ccabb8a7ece 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -375,7 +375,7 @@ M.visible_message("[M] presses \his thumb against [P].",\ "You press your thumb against [P].",\ "[P] makes a sharp clicking sound as it extracts DNA material from [M].") - if(!check_dna_integrity(M)) + if(!M.has_dna()) P << "No DNA detected" return P << "

[M]'s UE string : [M.dna.unique_enzymes]

" diff --git a/code/modules/mob/living/simple_animal/bot_swarm/swarmer.dm b/code/modules/mob/living/simple_animal/bot_swarm/swarmer.dm index 169e705481f..92d395b2615 100644 --- a/code/modules/mob/living/simple_animal/bot_swarm/swarmer.dm +++ b/code/modules/mob/living/simple_animal/bot_swarm/swarmer.dm @@ -229,6 +229,9 @@ /mob/living/simple_animal/slime/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) S << "This biological resource is somehow resisting our bluespace transceiver. Aborting." +/obj/machinery/droneDispenser/swarmer/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + S << "This object is receiving unactivated swarmer shells to help us. Aborting." + ////END CTRL CLICK FOR SWARMERS//// diff --git a/code/modules/mob/living/simple_animal/bot_swarm/swarmer_event.dm b/code/modules/mob/living/simple_animal/bot_swarm/swarmer_event.dm new file mode 100644 index 00000000000..a95a3d17d16 --- /dev/null +++ b/code/modules/mob/living/simple_animal/bot_swarm/swarmer_event.dm @@ -0,0 +1,30 @@ +/datum/round_event_control/spawn_swarmer + name = "Spawn Swarmer Shell" + typepath = /datum/round_event/spawn_swarmer + weight = 7 + max_occurrences = 1 //Only once okay fam + earliest_start = 18000 //30 minutes + + +/datum/round_event/spawn_swarmer + + +/datum/round_event/spawn_swarmer/start() + if(find_swarmer()) + return 0 + if(!the_gateway) + return 0 + new /obj/item/unactivated_swarmer(get_turf(the_gateway)) + if(prob(25)) //25% chance to announce it to the crew + var/swarmer_report = "[command_name()] High-Priority Update
" + swarmer_report += "

Our long-range sensors have detected an odd signal emanating from your station's gateway. We recommend immediate investigation of your gateway, as something may have come \ + through." + print_command_report(swarmer_report,"Classified [command_name()] Update") + priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg') + + +/datum/round_event/spawn_swarmer/proc/find_swarmer() + for(var/mob/living/M in mob_list) + if(istype(M, /mob/living/simple_animal/hostile/swarmer) && M.client) //If there is a swarmer with an active client, we've found our swarmer + return 1 + return 0 diff --git a/code/modules/mob/living/simple_animal/morph/morph.dm b/code/modules/mob/living/simple_animal/morph/morph.dm index b8d9d8e3230..c815f567578 100644 --- a/code/modules/mob/living/simple_animal/morph/morph.dm +++ b/code/modules/mob/living/simple_animal/morph/morph.dm @@ -1,9 +1,9 @@ #define MORPH_COOLDOWN 50 /mob/living/simple_animal/hostile/morph - name = "Morph" - real_name = "Morph" - desc = "some amorphous blob" + name = "morph" + real_name = "morph" + desc = "A revolting, pulsating pile of flesh." speak_emote = list("gurgles") emote_hear = list("gurgles") icon = 'icons/mob/animal.dmi' @@ -28,16 +28,25 @@ see_invisible = SEE_INVISIBLE_MINIMUM idle_vision_range = 1 // Only attack when target is close wander = 0 + attacktext = "glomps" + attack_sound = 'sound/effects/blobattack.ogg' var/morphed = 0 var/atom/movable/form = null var/morph_time = 0 + var/playstyle_string = "You are a morph, an abomination of science created primarily with changeling cells. \ + You may take the form of anything nearby by middle-clicking it. This process will alert any nearby \ + observers, and can only be performed once every five seconds. While morphed, you move faster, but do \ + less damage. In addition, anyone within three tiles will note an uncanny wrongness if examining you. \ + You can attack any item or dead creature to consume it - creatures will fully restore your health. \ + Finally, you can restore yourself to your original form while morphed by middle-clicking yourself." + /mob/living/simple_animal/hostile/morph/examine(mob/user) if(morphed) form.examine(user) // Refactor examine to return desc so it's static? Not sure if worth it if(get_dist(user,src)<=3) - user << "Looks odd!" + user << "It doesn't look quite right..." else ..() return @@ -57,6 +66,7 @@ if(istype(A) && allowed(A)) assume(A) else + src << "Your chameleon skin is still repairing itself!" ..() /mob/living/simple_animal/hostile/morph/proc/assume(atom/movable/target) @@ -72,11 +82,15 @@ else overlays = target.overlays.Copy() + visible_message("[src] suddenly twists and changes shape, becoming a copy of [target]!", \ + "You twist your body and assume the form of [target].") + name = target.name icon = target.icon icon_state = target.icon_state overlays = target.overlays + //Morphed is weaker melee_damage_lower = 5 melee_damage_upper = 5 @@ -93,6 +107,8 @@ //anim(loc,src,'icons/mob/mob.dmi',,"morph",,src.dir) + visible_message("[src] suddenly collapses in on itself, dissolving into a pile of green flesh!", \ + "You reform to your normal body.") name = initial(name) icon = initial(icon) icon_state = initial(icon_state) @@ -108,7 +124,8 @@ /mob/living/simple_animal/hostile/morph/death() if(morphed) - visible_message("The [src] dissolves!") + visible_message("[src] twists and dissolves into a pile of green flesh!", \ + "Your skin ruptures! Your flesh breaks apart! No disguise can ward off de--") restore() //Dump eaten stuff @@ -148,7 +165,7 @@ var/mob/living/L = target if(L.stat == DEAD) if(do_after(src, 30, target = L)) - visible_message("[src] swallows the [target] whole!") + visible_message("[src] swallows [target] whole!") L.loc = src adjustBruteLoss(-50) return @@ -156,7 +173,7 @@ var/obj/item/I = target if(!I.anchored) if(do_after(src,20, target = I)) - visible_message("[src] swallows the [target] whole!") + visible_message("[src] swallows [target] whole!") I.loc = src return target.attack_animal(src) @@ -198,15 +215,10 @@ player_mind.assigned_role = "Morph" player_mind.special_role = "Morph" ticker.mode.traitors |= player_mind - var/info = {"You are a Morph, a shapeshifting alien creature. - You can assume the shape of anything in sight by Shift-Clicking it. - You can only transform every 5 seconds. - To return to your basic form Shift-Click on yourself. - Base form is slow but strong, you're much weaker and faster when disguised. - You can eat items and corpses by clicking on them,eating corpses will heal you."} - S << info - message_admins("[key_of_morph] has been made into Morph by an event.") - log_game("[key_of_morph] was spawned as a Morph by an event.") + S << S.playstyle_string + S << 'sound/magic/Mutate.ogg' + message_admins("[key_of_morph] has been made into morph by an event.") + log_game("[key_of_morph] was spawned as a morph by an event.") return 1 /datum/round_event/morph/start() @@ -214,11 +226,11 @@ /datum/round_event/morph/proc/find_morph() - message_admins("Attempted to spawn a Morph but there was no players available. Will try again momentarily.") + message_admins("Attempted to spawn a morph but there was no players available. Will try again momentarily.") spawn(50) if(get_morph(1)) - message_admins("Situation has been resolved, [key_of_morph] has been spawned as a Morph.") - log_game("[key_of_morph] was spawned as a Morph by an event.") + message_admins("Situation has been resolved, [key_of_morph] has been spawned as a morph.") + log_game("[key_of_morph] was spawned as a morph by an event.") return 0 - message_admins("Unfortunately, no candidates were available for becoming a Morph. Shutting down.") + message_admins("Unfortunately, no candidates were available for becoming a morph. Shutting down.") return kill() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm index 1bb8c995e60..c90283d76ba 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm @@ -3,17 +3,19 @@ //Don't hear deadchat and are NOT normal ghosts //Admin-spawn or random event +#define INVISIBILITY_REVENANT 30 + /mob/living/simple_animal/revenant name = "revenant" desc = "A malevolent spirit." icon = 'icons/mob/mob.dmi' icon_state = "revenant_idle" incorporeal_move = 3 - invisibility = INVISIBILITY_OBSERVER + invisibility = INVISIBILITY_REVENANT health = 25 maxHealth = 25 healable = 0 - see_invisible = SEE_INVISIBLE_OBSERVER + see_invisible = INVISIBILITY_REVENANT languages = ALL response_help = "passes through" response_disarm = "swings at" @@ -137,7 +139,8 @@ if(target) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining. change_essence_amount(essence_drained * 5, 0, target) src << "[target]'s soul has been considerably weakened and will yield no more essence for the time being." - target.visible_message("[target] gently slumps back onto the ground.") + target.visible_message("[target] slumps onto the ground.", \ + "Violets lights, dancing in your vision, getting clo--") drained_mobs.Add(target) target.death(0) icon_state = "revenant_idle" @@ -150,7 +153,10 @@ /mob/living/simple_animal/revenant/say(message) - return 0 //Revenants cannot speak out loud. + for(var/mob/M in mob_list) + if(istype(M, /mob/living/simple_animal/revenant) || M.stat == DEAD) + M << "REVENANT: [src] says, \"[message]\"" //Can commune with the dead + return /mob/living/simple_animal/revenant/Stat() ..() @@ -182,14 +188,16 @@ src.mind.objectives += objective2 src << "Objective #2: [objective2.explanation_text]" ticker.mode.traitors |= src.mind //Necessary for announcing - mob_spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_transmit - mob_spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_light - mob_spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile - mob_spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf + AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null)) + AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_light(null)) + AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile(null)) + AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf(null)) /mob/living/simple_animal/revenant/death() + if(!revealed) //Revenants cannot die if they aren't revealed + return 0 ..(1) - src << "NO! No... it's too late, you can feel yourself fading..." + src << "NO! No... it's too late, you can feel yourself fading..." notransform = 1 revealed = 1 invisibility = 0 @@ -199,8 +207,9 @@ for(var/i = alpha, i > 0, i -= 10) sleep(0.1) alpha = i - visible_message("[src]'s body breaks apart into blue dust.") - new /obj/item/weapon/ectoplasm/revenant(get_turf(src)) + visible_message("[src]'s body breaks apart into a fine pile of blue dust.") + var/obj/item/weapon/ectoplasm/revenant/R = new (get_turf(src)) + R.client_to_revive = src.client //If the essence reforms, the old revenant is put back in the body ghostize() qdel(src) return @@ -209,7 +218,7 @@ /mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/weapon/nullrod)) visible_message("[src] violently flinches!", \ - "As the null rod passes through you, you feel your essence draining away!") + "As the null rod passes through you, you feel your essence draining away!") essence -= 25 //hella effective inhibited = 1 spawn(30) @@ -263,7 +272,7 @@ src << "You have been revealed." spawn(time) revealed = 0 - invisibility = INVISIBILITY_OBSERVER + invisibility = INVISIBILITY_REVENANT src << "You are once more concealed." /mob/living/simple_animal/revenant/proc/stun(time) @@ -323,7 +332,8 @@ icon_state = "revenantEctoplasm" w_class = 2 var/reforming = 0 - var/reformed = 0 + var/inert = 0 + var/client/client_to_revive /obj/item/weapon/ectoplasm/revenant/New() ..() @@ -332,17 +342,12 @@ if(src && reforming) return reform() if(src && !reforming) + reforming = 1 visible_message("[src] settles down and seems lifeless.") return -/obj/item/weapon/ectoplasm/revenant/attack_hand(mob/user) - if(reformed) - user << "[src] keeps slipping out of your hands, you can't get a hold on it!" - return - ..() - /obj/item/weapon/ectoplasm/revenant/attack_self(mob/user) - if(!reforming) + if(!reforming || inert) return ..() user.visible_message("[user] scatters [src] in all directions.", \ "You scatter [src] across the area. The particles slowly fade away.") @@ -351,6 +356,8 @@ /obj/item/weapon/ectoplasm/revenant/throw_impact(atom/hit_atom) ..() + if(inert) + return visible_message("[src] breaks into particles upon impact, which fade away to nothingness.") qdel(src) @@ -364,20 +371,29 @@ /obj/item/weapon/ectoplasm/revenant/proc/reform() if(!reforming || !src) return + var/key_of_revenant message_admins("Revenant ectoplasm was left undestroyed for 1 minute and has reformed into a new revenant.") loc = get_turf(src) //In case it's in a backpack or someone's hand visible_message("[src] suddenly rises into the air before fading away.") var/mob/living/simple_animal/revenant/R = new(get_turf(src)) - qdel(src) - var/list/candidates = get_candidates(BE_REVENANT) - if(!candidates.len) - message_admins("No candidates were found for the new revenant. Oh well!") - return 0 - var/client/C = pick(candidates) - var/key_of_revenant = C.key - if(!key_of_revenant) - message_admins("No ckey was found for the new revenant. Oh well!") - return 0 + if(client_to_revive) + for(var/mob/M in mob_list) + if(M.client == client_to_revive && M.stat == DEAD) //Only recreates the mob if the mob the client is in is dead + message_admins("[R.client] was a revenant and died. Re-making them into the new revenant formed by ectoplasm.") + R.client = client_to_revive + key_of_revenant = client_to_revive.key + break + message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...") + else + var/list/candidates = get_candidates(BE_REVENANT) + if(!candidates.len) + message_admins("No candidates were found for the new revenant. Oh well!") + return 0 + var/client/C = pick(candidates) + key_of_revenant = C.key + if(!key_of_revenant) + message_admins("No ckey was found for the new revenant. Oh well!") + return 0 var/datum/mind/player_mind = new /datum/mind(key_of_revenant) player_mind.active = 1 player_mind.transfer_to(R) @@ -386,4 +402,7 @@ ticker.mode.traitors |= player_mind message_admins("[key_of_revenant] has been made into a revenant by reforming ectoplasm.") log_game("[key_of_revenant] was spawned as a revenant by reforming ectoplasm.") + qdel(src) + if(src) //Should never happen, but just in case + inert = 1 return 1 diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm index 6de716e3180..a8d198286b8 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm @@ -7,6 +7,8 @@ clothes_req = 0 range = 7 include_user = 0 + action_icon_state = "r_transmit" + action_background_icon_state = "bg_revenant" /obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr) for(var/mob/living/M in targets) @@ -16,7 +18,7 @@ charge_counter = charge_max return usr << "You transmit to [M]: [msg]" - M << "A strange voice resonates in your head... [msg]" + M << "An alien voice resonates from all around... [msg]" //Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people. @@ -30,6 +32,8 @@ var/reveal = 80 var/stun = 20 var/locked = 1 + action_icon_state = "overload_lights" + action_background_icon_state = "bg_revenant" /obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, mob/living/simple_animal/revenant/user = usr) if(locked) @@ -40,7 +44,7 @@ name = "Overload Lights (20E)" panel = "Revenant Abilities" locked = 0 - range = 6 + range = 2 charge_counter = charge_max return if(!user.castcheck(-20)) @@ -58,7 +62,7 @@ s.set_up(4, 1, L) s.start() sleep(10) - for(var/mob/living/M in orange(4, L)) + for(var/mob/living/M in range(4, L)) if(M == user) return M.Beam(L,icon_state="lightning",icon='icons/effects/effects.dmi',time=5) @@ -73,8 +77,8 @@ //Defile: Corrupts nearby stuff, unblesses floor tiles. /obj/effect/proc_holder/spell/aoe_turf/revenant_defile - name = "Defile (35E)" - desc = "Twists and corrupts the nearby area. Also dispels holy auras on floors, but not salt lines." + name = "Defile (20E)" + desc = "Twists and corrupts the nearby area. Also dispels holy auras on floors." panel = "Revenant Abilities (Locked)" charge_max = 200 clothes_req = 0 @@ -82,6 +86,8 @@ var/reveal = 100 var/stun = 20 var/locked = 1 + action_icon_state = "defile" + action_background_icon_state = "bg_revenant" /obj/effect/proc_holder/spell/aoe_turf/revenant_defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr) if(locked) @@ -89,7 +95,7 @@ charge_counter = charge_max return user << "You have unlocked Defile!" - name = "Defile (20E)" + name = "Defile (10E)" panel = "Revenant Abilities" locked = 0 range = 3 @@ -102,10 +108,6 @@ spawn(0) if(T.flags & NOJAUNT) T.flags -= NOJAUNT - if(!istype(T, /turf/simulated/wall/cult) && istype(T, /turf/simulated/wall) && prob(40)) - T.ChangeTurf(/turf/simulated/wall/cult) - if(!istype(T, /turf/simulated/floor/engine/cult) && istype(T, /turf/simulated/floor) && prob(40)) - T.ChangeTurf(/turf/simulated/floor/engine/cult) for(var/mob/living/carbon/human/human in T.contents) human << "You suddenly feel tired." human.adjustStaminaLoss(35) @@ -128,6 +130,8 @@ var/reveal = 60 var/stun = 30 var/locked = 1 + action_icon_state = "malfunction" + action_background_icon_state = "bg_revenant" /obj/effect/proc_holder/spell/aoe_turf/revenant_malf/cast(list/targets, mob/living/simple_animal/revenant/user = usr) if(locked) @@ -152,8 +156,19 @@ bot.open = 1 bot.Emag(null) for(var/obj/machinery/mach in T.contents) + if(istype(mach, /obj/machinery/dominator) || istype(mach, /obj/machinery/power/apc)) //Doesn't work on dominators and APCs, to prevent kekkery + continue if(prob(10)) mach.emag_act(null) - empulse(user.loc, 3, 5) + else + mach.emp_act(1) + for(var/mob/living/silicon/robot/S in T.contents) //Only works on cyborgs, not AI + S << "ERROR $!(@ ERROR )#^! SENSORY OVERLOAD \[$(!@#" + S << 'sound/misc/interference.ogg' + playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1) + var/datum/effect/effect/system/spark_spread/sp = new /datum/effect/effect/system/spark_spread + sp.set_up(5, 1, S) + sp.start() + S.Weaken(6) user.reveal(reveal) user.stun(stun) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/slaughter/slaughter.dm b/code/modules/mob/living/simple_animal/slaughter/slaughter.dm index 5f39ad01d46..e616aa4fb42 100644 --- a/code/modules/mob/living/simple_animal/slaughter/slaughter.dm +++ b/code/modules/mob/living/simple_animal/slaughter/slaughter.dm @@ -1,9 +1,9 @@ //////////////////The Monster /mob/living/simple_animal/slaughter - name = "Slaughter Demon" - real_name = "Slaughter Demon" - desc = "You should run." + name = "slaughter demon" + real_name = "slaughter demon" + desc = "A large, menacing creature covered in armored black scales." speak_emote = list("gurgles") emote_hear = list("wails","screeches") response_help = "thinks better of touching" @@ -31,10 +31,11 @@ var/boost = 0 bloodcrawl = BLOODCRAWL_EAT see_invisible = SEE_INVISIBLE_MINIMUM - var/playstyle_string = "You are the Slaughter Demon, a terible creature from another existence. You have a single desire: To kill. \ - You may Ctrl+Click on blood pools to travel through them, appearing and dissaapearing from the station at will. \ - Pulling a dead or critical mob while you enter a pool will pull them in with you, allowing you to feast. \ - You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. " + var/list/consumed_mobs = list() + var/playstyle_string = "You are a slaughter demon, a terrible creature from another realm. You have a single desire: To kill. \ + You may use the \"Blood Crawl\" ability near blood pools to travel through them, appearing and dissaapearing from the station at will. \ + Pulling a dead or unconscious mob while you enter a pool will pull them in with you, allowing you to feast and regain your health. \ + You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. " /mob/living/simple_animal/slaughter/New() ..() @@ -52,10 +53,17 @@ /mob/living/simple_animal/slaughter/death() ..(1) - new /obj/effect/decal/cleanable/blood (src.loc) - new /obj/item/weapon/demonheart (src.loc) + new /obj/effect/decal/cleanable/blood (get_turf(src)) + var/obj/effect/decal/cleanable/blood/innards = new (get_turf(src)) + innards.icon = 'icons/obj/surgery.dmi' + innards.icon_state = "innards" + innards.name = "pile of viscera" + innards.desc = "A repulsive pile of guts and gore." + new /obj/item/organ/internal/heart/demon (src.loc) playsound(get_turf(src),'sound/magic/demon_dies.ogg', 200, 1) - visible_message("The [src] screams in anger as its form collapes into a pool of viscera.") + visible_message("[src] screams in anger as it collapses into a puddle of viscera, its most recent meals spilling out of it.") + for(var/mob/living/M in consumed_mobs) + M.loc = get_turf(src) ghostize() qdel(src) return @@ -64,26 +72,44 @@ /mob/living/simple_animal/slaughter/phasein() . = ..() speed = 0 - boost = world.time + 30 + boost = world.time + 60 -//////////The Loot - -/obj/item/weapon/demonheart - name = "demon's heart" - desc = "It's still faintly beating with rage" +//The loot from killing a slaughter demon - can be consumed to allow the user to blood crawl +/obj/item/organ/internal/heart/demon + name = "demon heart" + desc = "Still it beats furiously, emanating an aura of utter hate." icon = 'icons/obj/surgery.dmi' - icon_state = "heart-on" + icon_state = "demon_heart" origin_tech = "combat=5;biotech=8" -/obj/item/weapon/demonheart/attack_self(mob/living/user) - visible_message("[user] feasts upon the [src].") +/obj/item/organ/internal/heart/demon/attack(mob/M, mob/living/carbon/user, obj/target) + if(M != user) + return ..() + user.visible_message("[user] raises [src] to their mouth and tears into it with their teeth!", \ + "An unnatural hunger consumes you. You raise [src] your mouth and devour it!") + playsound(user, 'sound/magic/Demon_consume.ogg', 50, 1) for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list) if(knownspell.type == /obj/effect/proc_holder/spell/bloodcrawl) - user <<"You already know how to blood crawl." + user <<"...and you don't feel any different." qdel(src) return - user << "You absorb some of the demon's power!" - user.mind.AddSpell(new /obj/effect/proc_holder/spell/bloodcrawl) - qdel(src) + user.visible_message("[user]'s eyes flare a deep crimson!", \ + "You feel a strange power seep into your body... you have absorbed the demon's blood-travelling powers!") + /*for(var/obj/item/organ/internal/O in user.internal_organs) + if(istype(O, /obj/item/organ/internal/heart)) + O.Remove(user, 1) + O.loc = get_turf(user) + qdel(O)*/ + user.drop_item() + src.Insert(user) //Consuming the heart literally replaces your heart with a demon heart. H A R D C O R E +/obj/item/organ/internal/heart/demon/Insert(mob/living/carbon/M, special = 0) + ..() + if(M.mind) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/bloodcrawl(null)) + +/obj/item/organ/internal/heart/demon/Remove(mob/living/carbon/M, special = 0) + ..() + if(M.mind) + M.mind.remove_spell(/obj/effect/proc_holder/spell/bloodcrawl) diff --git a/code/modules/mob/living/simple_animal/slaughter/slaughterevent.dm b/code/modules/mob/living/simple_animal/slaughter/slaughterevent.dm index de3e477ab6d..cbc845bc69d 100644 --- a/code/modules/mob/living/simple_animal/slaughter/slaughterevent.dm +++ b/code/modules/mob/living/simple_animal/slaughter/slaughterevent.dm @@ -44,9 +44,10 @@ player_mind.special_role = "Slaughter Demon" ticker.mode.traitors |= player_mind S << S.playstyle_string - S << "You are currently not currently in the same plane of existence as the station. Ctrl+Click a blood pool to manifest." - message_admins("[key_of_slaughter] has been made into a Slaughter Demon by an event.") - log_game("[key_of_slaughter] was spawned as a Slaughter Demon by an event.") + S << "You are currently not currently in the same plane of existence as the station. Blood Crawl near a blood pool to manifest." + S << 'sound/magic/demon_dies.ogg' + message_admins("[key_of_slaughter] has been made into a slaughter demon by an event.") + log_game("[key_of_slaughter] was spawned as a slaughter demon by an event.") return 1 @@ -57,11 +58,11 @@ /datum/round_event/slaughter/proc/find_slaughter() - message_admins("Attempted to spawn a Slaughter Demon but there was no players available. Will try again momentarily.") + message_admins("Attempted to spawn a slaughter demon but there was no players available. Will try again momentarily.") spawn(50) if(get_slaughter(1)) - message_admins("Situation has been resolved, [key_of_slaughter] has been spawned as a Slaughter Demon.") - log_game("[key_of_slaughter] was spawned as a Slaughter Demon by an event.") + message_admins("Situation has been resolved, [key_of_slaughter] has been spawned as a slaughter demon.") + log_game("[key_of_slaughter] was spawned as a slaughter demon by an event.") return 0 - message_admins("Unfortunately, no candidates were available for becoming a Slaugter Demon. Shutting down.") + message_admins("Unfortunately, no candidates were available for becoming a slaughter demon. Shutting down.") return kill() diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index 5531fcd6a85..c0756da1c8b 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -251,9 +251,8 @@ if(istype(L, /mob/living/carbon/human)) //Ignore slime(wo)men var/mob/living/carbon/human/H = L - if(H.dna) - if(src.type in H.dna.species.ignored_by) - continue + if(src.type in H.dna.species.ignored_by) + continue if(!L.canmove) // Only one slime can latch on at a time. var/notarget = 0 diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm index 2608561867d..4d1e46f595a 100644 --- a/code/modules/mob/mob_transformation_simple.dm +++ b/code/modules/mob/mob_transformation_simple.dm @@ -40,15 +40,11 @@ M.name = src.name M.real_name = src.real_name - if(check_dna_integrity(src)) + if(has_dna() && M.has_dna()) var/mob/living/carbon/C = src var/mob/living/carbon/D = M - D.dna = C.dna - updateappearance(D) - else - if(istype(M, /mob/living/carbon/human)) - src.client.prefs.copy_to(M) - ready_dna(M) + C.dna.transfer_identity(D) + D.updateappearance(mutcolor_update=1, mutations_overlay_update=1) if(mind && istype(M, /mob/living)) mind.transfer_to(M) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index f8f6eea2413..a274a75ccde 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -362,21 +362,17 @@ var/mob/living/carbon/human/new_character = new(loc) new_character.lastarea = get_area(loc) - create_dna(new_character) - if(config.force_random_names || appearance_isbanned(src)) client.prefs.random_character() client.prefs.real_name = client.prefs.pref_species.random_name(gender,1) client.prefs.copy_to(new_character) - + new_character.dna.update_dna_identity() if(mind) mind.active = 0 //we wish to transfer the key manually mind.transfer_to(new_character) //won't transfer key since the mind is not active new_character.name = real_name - ready_dna(new_character, client.prefs.blood_type) - new_character.key = key //Manually transfer the key to log them in new_character.stopLobbySound() diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 4bbc1b2a8ee..ff7b09b6632 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -1,4 +1,4 @@ -/mob/living/carbon/proc/monkeyize(tr_flags = (TR_KEEPITEMS | TR_KEEPVIRUS | TR_DEFAULTMSG), newname = null) +/mob/living/carbon/proc/monkeyize(tr_flags = (TR_KEEPITEMS | TR_KEEPVIRUS | TR_DEFAULTMSG)) if (notransform) return //Handle items on mob @@ -16,8 +16,11 @@ int_organs += I I.Remove(src, 1) + if(tr_flags & TR_KEEPITEMS) + for(var/obj/item/W in (src.contents-implants-int_organs)) + unEquip(W) + //Make mob invisible and spawn animation - regenerate_icons() notransform = 1 canmove = 0 stunned = 1 @@ -35,18 +38,18 @@ qdel(animation) // hash the original name? - if (tr_flags & TR_HASHNAME) + if(tr_flags & TR_HASHNAME) O.name = "monkey ([copytext(md5(real_name), 2, 6)])" O.real_name = "monkey ([copytext(md5(real_name), 2, 6)])" - if (newname) //if there's a name as an argument, always take that one over the current name - O.name = newname - O.real_name = newname //handle DNA and other attributes - if(dna) - dna.transfer_identity(O) - if(tr_flags & TR_KEEPSE) - O.dna.struc_enzymes = dna.struc_enzymes + dna.transfer_identity(O) + O.updateappearance(icon_update=0) + + if(tr_flags & TR_KEEPSE) + O.dna.struc_enzymes = dna.struc_enzymes + var/datum/mutation/human/race/R = mutations_list[RACEMUT] + O.dna.struc_enzymes = R.set_se(O.dna.struc_enzymes, on=1)//we don't want to keep the race block inactive if(suiciding) O.suiciding = suiciding @@ -70,9 +73,10 @@ O.radiation = radiation //re-add implants to new mob - for(var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O + if (tr_flags & TR_KEEPIMPLANTS) + for(var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O //re-add organs to new mob if(tr_flags & TR_KEEPORGANS) @@ -96,16 +100,14 @@ if(loc.vars[A] == src) loc.vars[A] = O - updateappearance(O) . = O - if ( !(tr_flags & TR_KEEPSRC) ) //flag should be used if monkeyize() is called inside another proc of src so that one does not crash - qdel(src) + qdel(src) ////////////////////////// Humanize ////////////////////////////// //Could probably be merged with monkeyize but other transformations got their own procs, too -/mob/living/carbon/proc/humanize(tr_flags = (TR_KEEPITEMS | TR_KEEPVIRUS | TR_DEFAULTMSG), newname = null) +/mob/living/carbon/proc/humanize(tr_flags = (TR_KEEPITEMS | TR_KEEPVIRUS | TR_DEFAULTMSG)) if (notransform) return //Handle items on mob @@ -125,7 +127,7 @@ //now the rest if (tr_flags & TR_KEEPITEMS) - for(var/obj/item/W in (src.contents-implants)) + for(var/obj/item/W in (src.contents-implants-int_organs)) unEquip(W) if (client) client.screen -= W @@ -134,11 +136,7 @@ W.dropped(src) W.layer = initial(W.layer) - // for(var/obj/item/W in src) - // unEquip(W) - //Make mob invisible and spawn animation - regenerate_icons() notransform = 1 canmove = 0 stunned = 1 @@ -156,27 +154,21 @@ O.equip_to_appropriate_slot(C) qdel(animation) - O.gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE + dna.transfer_identity(O) + O.updateappearance(mutcolor_update=1) - if(dna) - dna.transfer_identity(O) - O.update_icons() - if(tr_flags & TR_KEEPSE) - O.dna.struc_enzymes = dna.struc_enzymes - domutcheck(O) - - if(!dna.species) - hardset_dna(O, null, null, null, null, /datum/species/human) + if(cmptext("monkey",copytext(O.dna.real_name,1,7))) + O.real_name = random_unique_name(O.gender) + O.dna.generate_unique_enzymes(O) else - hardset_dna(O, null, null, null, null, dna.species.type) - - if(newname) //if there's a name as an argument, always take that one over the current name - O.real_name = newname - else - if(cmptext("monkey",copytext(O.dna.real_name,1,7))) - O.dna.real_name = random_unique_name(O.gender) O.real_name = O.dna.real_name - O.name = O.real_name + O.name = O.real_name + + if(tr_flags & TR_KEEPSE) + O.dna.struc_enzymes = dna.struc_enzymes + var/datum/mutation/human/race/R = mutations_list[RACEMUT] + O.dna.struc_enzymes = R.set_se(O.dna.struc_enzymes, on=0)//we don't want to keep the race block active + O.domutcheck() if(suiciding) O.suiciding = suiciding @@ -201,10 +193,11 @@ O.radiation = radiation //re-add implants to new mob - for(var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O - O.sec_hud_set_implants() + if (tr_flags & TR_KEEPIMPLANTS) + for(var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O + O.sec_hud_set_implants() if(tr_flags & TR_KEEPORGANS) for(var/obj/item/organ/internal/I in O.internal_organs) @@ -215,21 +208,23 @@ if(mind) mind.transfer_to(O) + if(O.mind.changeling) + for(var/obj/effect/proc_holder/changeling/humanform/HF in O.mind.changeling.purchasedpowers) + mind.changeling.purchasedpowers -= HF + O.a_intent = "help" if (tr_flags & TR_DEFAULTMSG) O << "You are now a human." O.update_pipe_vision() - updateappearance(O) . = O for(var/A in loc.vars) if(loc.vars[A] == src) loc.vars[A] = O - if ( !(tr_flags & TR_KEEPSRC) ) //don't delete src yet if it's needed to finish calling proc - qdel(src) + qdel(src) /mob/new_player/AIize() diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm index 4146165206b..2e1e6528256 100644 --- a/code/modules/ninja/ninja_event.dm +++ b/code/modules/ninja/ninja_event.dm @@ -170,7 +170,7 @@ Contents: var/datum/preferences/A = new()//Randomize appearance for the ninja. A.real_name = "[pick(ninja_titles)] [pick(ninja_names)]" A.copy_to(new_ninja) - ready_dna(new_ninja) + new_ninja.dna.update_dna_identity() new_ninja.equip_space_ninja() return new_ninja diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 134eb2542ee..280c90b7e00 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -51,6 +51,10 @@ /obj/item/weapon/paper/examine(mob/user) ..() + if(istype(src, /obj/item/weapon/paper/talisman)) //Talismans cannot be read + if(!iscultist(user) && !user.stat) + user << "There are indecipherable images scrawled on the paper in what looks to be... blood?" + return if(in_range(user, src) || isobserver(user)) if( !(ishuman(user) || isobserver(user) || issilicon(user)) ) user << browse("[name][stars(info)]
[stamps]", "window=[name]") diff --git a/code/modules/projectiles/firing.dm b/code/modules/projectiles/firing.dm index 1890309581f..80afb0f065c 100644 --- a/code/modules/projectiles/firing.dm +++ b/code/modules/projectiles/firing.dm @@ -1,9 +1,9 @@ -/obj/item/ammo_casing/proc/fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, params, distro, quiet) +/obj/item/ammo_casing/proc/fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, params, distro, quiet, zone_override = "") distro += variance for (var/i = max(1, pellets), i > 0, i--) var/curloc = user.loc var/targloc = get_turf(target) - ready_proj(target, user, quiet) + ready_proj(target, user, quiet, zone_override) if(distro) targloc = spread(targloc, curloc, distro) if(!throw_proj(targloc, user, params)) @@ -15,12 +15,15 @@ update_icon() return 1 -/obj/item/ammo_casing/proc/ready_proj(atom/target as mob|obj|turf, mob/living/user, quiet) +/obj/item/ammo_casing/proc/ready_proj(atom/target as mob|obj|turf, mob/living/user, quiet, zone_override = "") if (!BB) return BB.original = target BB.firer = user - BB.def_zone = user.zone_sel.selecting + if (zone_override) + BB.def_zone = zone_override + else + BB.def_zone = user.zone_sel.selecting BB.suppressed = quiet if(reagents && BB.reagents) @@ -33,7 +36,7 @@ return 0 if(targloc == curloc) if(BB.original == user) //if we target ourselves we go straight to bullet_act() - user.bullet_act(BB) + user.bullet_act(BB, BB.def_zone) qdel(BB) return 1 BB.loc = get_turf(user) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 3f64abf3237..b9749cc3e98 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -133,7 +133,8 @@ var/mob/living/M = user if (M.disabilities & CLUMSY && prob(40)) user << "You shoot yourself in the foot with \the [src]!" - process_fire(user,user,0,params) + var/shot_leg = pick("l_leg", "r_leg") + process_fire(user,user,0,params, zone_override = shot_leg) M.drop_item() return @@ -155,7 +156,7 @@ return 0 if(trigger_guard) - if(istype(user) && user.dna) + if(user.has_dna()) if(user.dna.check_mutation(HULK)) user << "Your meaty finger is much too large for the trigger guard!" return 0 @@ -177,7 +178,7 @@ return 0 -/obj/item/weapon/gun/proc/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params) +/obj/item/weapon/gun/proc/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override) add_fingerprint(user) if(semicd) @@ -195,7 +196,7 @@ if( i>1 && !(src in get_both_hands(user))) //for burst firing break if(chambered) - if(!chambered.fire(target, user, params, , suppressed)) + if(!chambered.fire(target, user, params, , suppressed, zone_override)) shoot_with_empty_chamber(user) break else @@ -211,7 +212,7 @@ sleep(fire_delay) else if(chambered) - if(!chambered.fire(target, user, params, , suppressed)) + if(!chambered.fire(target, user, params, , suppressed, zone_override)) shoot_with_empty_chamber(user) return else @@ -359,4 +360,4 @@ if(src && input && !M.stat && in_range(M,src) && !M.restrained() && M.canmove) name = input M << "You name the gun [input]. Say hello to your new friend." - return \ No newline at end of file + return diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index 40b6843c936..c61fdfd9de9 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -98,13 +98,14 @@ M << "You feel a wave of heat wash over you." M.irradiate(300) fail_state = 2 //break the gun so it stops recharging + crit_fail = 1 //So that it may be properly perfected in this state. SSobj.processing.Remove(src) update_icon() return 0 /obj/item/weapon/gun/energy/gun/nuclear/emp_act(severity) ..() - reliability -= round(15/severity) + reliability = max(reliability - round(15/severity), 0) //Do not allow it to go negative! /obj/item/weapon/gun/energy/gun/nuclear/update_icon() ..() diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index 3de838042f6..028cf8f7f68 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -139,7 +139,7 @@ user.visible_message("[user] is putting the barrel of the [src.name] in \his mouth. It looks like \he's trying to commit suicide.") sleep(25) if(user.l_hand == src || user.r_hand == src) - process_fire(user, user, 0) + process_fire(user, user, 0, zone_override = "head") user.visible_message("[user] blows \his brains out with the [src.name]!") return(BRUTELOSS) else @@ -157,4 +157,4 @@ icon_state = "suppressor" w_class = 2 var/oldsound = null - var/initial_w_class = null \ No newline at end of file + var/initial_w_class = null diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index b76da0d0558..9dc38fe5ba6 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -119,6 +119,9 @@ can_suppress = 0 burst_size = 0 +/obj/item/weapon/gun/projectile/automatic/wt550/ui_action_click() + return + /obj/item/weapon/gun/projectile/automatic/wt550/update_icon() ..() icon_state = "wt550[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""]" diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 86df409121b..dc685593d08 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -74,7 +74,7 @@ options["The Peacemaker"] = "detective_peacemaker" options["Cancel"] = null -/obj/item/weapon/gun/projectile/revolver/detective/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params) +/obj/item/weapon/gun/projectile/revolver/detective/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override = "") if(magazine.caliber != initial(magazine.caliber)) if(prob(70 - (magazine.ammo_count() * 10))) //minimum probability of 10, maximum of 60 playsound(user, fire_sound, 50, 1) diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 3fb86384fbb..3238db399ec 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -216,19 +216,21 @@ new_mob = new /mob/living/carbon/human(M.loc) var/datum/preferences/A = new() //Randomize appearance for the human - A.copy_to(new_mob) + A.copy_to(new_mob, icon_updates=0) var/mob/living/carbon/human/H = new_mob - ready_dna(H) - if(H.dna && prob(50)) + if(prob(50)) var/list/all_species = list() for(var/speciestype in typesof(/datum/species) - /datum/species) var/datum/species/S = new speciestype() if(!S.dangerous_existence) all_species += speciestype - hardset_dna(H, null, null, null, null, pick(all_species)) + H.set_species(pick(all_species), icon_update=0) H.real_name = H.dna.species.random_name(H.gender,1) - H.update_icons() + H.update_body() + H.update_hair() + H.update_mutcolor() + H.dna.update_dna_identity() else return diff --git a/code/modules/reagents/Chemistry-Reagents/Drug-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Drug-Reagents.dm index da54674aba5..df33fc5c594 100644 --- a/code/modules/reagents/Chemistry-Reagents/Drug-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Drug-Reagents.dm @@ -132,10 +132,10 @@ return /datum/reagent/drug/krokodil/addiction_act_stage4(mob/living/carbon/human/M) - if(M.dna && !istype(M.dna.species, /datum/species/cosmetic_zombie)) + if(M.has_dna() && M.dna.species.id != "zombie") M << "Your skin falls off easily!" M.adjustBruteLoss(50*REM) // holy shit your skin just FELL THE FUCK OFF - hardset_dna(M, null, null, null, null, /datum/species/cosmetic_zombie) + M.set_species(/datum/species/cosmetic_zombie) else M.adjustBruteLoss(5*REM) ..() diff --git a/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm index 5d738957633..43a4c5c8a39 100644 --- a/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm @@ -724,7 +724,7 @@ /datum/reagent/medicine/mutadone/on_mob_life(mob/living/carbon/human/M) M.jitteriness = 0 - if(istype(M) && M.dna) + if(M.has_dna()) M.dna.remove_all_mutations() ..() return diff --git a/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm index 3b7b5066c1e..4e0b0fbeb02 100644 --- a/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm @@ -356,8 +356,7 @@ var/datum/species/mutation = pick(possible_morphs) if(prob(90) && mutation && H.dna.species != /datum/species/golem && H.dna.species != /datum/species/golem/adamantine) H << "The pain subsides. You feel... different." - hardset_dna(H, null, null, null, null, mutation) - H.regenerate_icons() + H.set_species(mutation) if(mutation == /datum/species/slime) H.faction |= "slime" else diff --git a/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm index 8b5fd49055a..aaaaf09c20e 100644 --- a/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm @@ -31,7 +31,7 @@ /datum/reagent/toxin/mutagen/reaction_mob(mob/living/carbon/M, method=TOUCH, reac_volume) if(!..()) return - if(!istype(M) || !M.dna) + if(!M.has_dna()) return //No robots, AIs, aliens, Ians or other mobs should be affected by this. if((method==VAPOR && prob(min(33, reac_volume))) || method==INGEST || method == PATCH) randmuti(M) @@ -39,8 +39,8 @@ randmutb(M) else randmutg(M) - domutcheck(M, null) - updateappearance(M) + M.updateappearance() + M.domutcheck() ..() /datum/reagent/toxin/mutagen/on_mob_life(mob/living/carbon/M) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 1095e93cbd2..7fdd33e9955 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -66,20 +66,16 @@ if(ismob(target)) //Blood! if(ishuman(target)) var/mob/living/carbon/human/H = target - if(H.dna) - if(NOBLOOD in H.dna.species.specflags && !H.dna.species.exotic_blood) - user << "You are unable to locate any blood!" - return + if(NOBLOOD in H.dna.species.specflags && !H.dna.species.exotic_blood) + user << "You are unable to locate any blood!" + return if(reagents.has_reagent("blood")) user << "There is already a blood sample in this syringe!" return if(istype(target, /mob/living/carbon)) //maybe just add a blood reagent to all mobs. Then you can suck them dry...With hundreds of syringes. Jolly good idea. var/amount = src.reagents.maximum_volume - src.reagents.total_volume var/mob/living/carbon/T = target - if(!check_dna_integrity(T)) - user << "You are unable to locate any blood!" - return - if(T.disabilities & NOCLONE) //target done been eat, no more blood in him + if(!T.has_dna() || (T.disabilities & NOCLONE)) //target done been eat, no more blood in him user << "You are unable to locate any blood!" return if(target != user) @@ -95,7 +91,7 @@ if(!B && ishuman(target)) var/mob/living/carbon/human/H = target - if(H.dna && H.dna.species.exotic_blood && H.reagents.total_volume) + if(H.dna.species.exotic_blood && H.reagents.total_volume) target.reagents.trans_to(src, amount) else user << "You are unable to locate any blood!" diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 6f349b66ad1..b480ed8ab8c 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -695,6 +695,16 @@ construction_time = 120 category = list("Cyborg Upgrade Modules") +/datum/design/borg_upgrade_selfrepair + name = "Cyborg Upgrade (Self-repair)" + id = "borg_upgrade_selfrepair" + build_type = MECHFAB + build_path = /obj/item/borg/upgrade/selfrepair + req_tech = list("materials" = 4, "engineering" = 4) + materials = list(MAT_METAL=15000, MAT_GLASS=15000) + construction_time = 120 + category = list("Cyborg Upgrade Modules") + //Misc /datum/design/mecha_tracking name = "Exosuit Tracking Beacon" diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index ab792260177..c2edf89e874 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -190,31 +190,31 @@ category = list("Ammo") /datum/design/mag_oldsmg/ap_mag - name = "Submachine Gun Armour Piercing Magazine (9mmAP)" + name = "WT-550 Auto Gun Armour Piercing Magazine (9mmAP)" desc = "A 20 round armour piercing magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg_ap" - materials = list(MAT_METAL = 6000, MAG_SILVER = 200) + materials = list(MAT_METAL = 6000, MAT_SILVER = 200) build_path = /obj/item/ammo_box/magazine/wt550m9/wtap /datum/design/mag_oldsmg/ic_mag - name = "Submachine Gun Incindiary Magazine (9mmIC)" + name = "WT-550 Auto Gun Incendiary Magazine (9mmIC)" desc = "A 20 round armour piercing magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg_ic" - materials = list(MAT_METAL = 6000, MAG_SILVER = 200, MAT_GLASS = 800) + materials = list(MAT_METAL = 6000, MAT_SILVER = 200, MAT_GLASS = 800) build_path = /obj/item/ammo_box/magazine/wt550m9/wtic /datum/design/mag_oldsmg/tx_mag - name = "Submachine Gun Urnaium Magazine (9mmTX)" + name = "WT-550 Auto Gun Urnaium Magazine (9mmTX)" desc = "A 20 round urnaium tipped magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg_tx" - materials = list(MAT_METAL = 6000, MAG_SILVER = 400, MAG_URNAIUM = 2000) + materials = list(MAT_METAL = 6000, MAT_SILVER = 400, MAT_URANIUM = 2000) build_path = /obj/item/ammo_box/magazine/wt550m9/wttx //SABR Mags /datum/design/mag_smg - name = "Submachine Gun Magazine (9mm)" - desc = "A 42-round magazine for the prototype submachine gun." + name = "SABR SMG Magazine (9mm)" + desc = "A 30-round magazine for the prototype submachine gun." id = "mag_smg" req_tech = list("combat" = 4, "materials" = 3) build_type = PROTOLATHE @@ -223,24 +223,24 @@ category = list("Ammo") /datum/design/mag_smg/ap_mag - name = "Submachine Gun Armour Piercing Magazine (9mmAP)" - desc = "A 42-round armour piercing magazine for the prototype submachine gun. Deals slightly less damage by bypasses most armour" + name = "SABR SMG Armour Piercing Magazine (9mmAP)" + desc = "A 30-round armour piercing magazine for the prototype submachine gun. Deals slightly less damage by bypasses most armour" id = "mag_smg_ap" - materials = list(MAT_METAL = 3000, MAG_SILVER = 100) + materials = list(MAT_METAL = 3000, MAT_SILVER = 100) build_path = /obj/item/ammo_box/magazine/smgm9mm/ap /datum/design/mag_smg/incin_mag - name = "Submachine Gun Incindiary Magazine (9mmIC)" - desc = "A 42-round incindiary round magazine for the prototype submachine gun. Deals significanlty less damage but sets the target on fire" + name = "SABR SMG Incendiary Magazine (9mmIC)" + desc = "A 30-round incindiary round magazine for the prototype submachine gun. Deals significanlty less damage but sets the target on fire" id = "mag_smg_ic" - materials = list(MAT_METAL = 3000, MAG_SILVER = 100, MAT_GLASS = 400) + materials = list(MAT_METAL = 3000, MAT_SILVER = 100, MAT_GLASS = 400) build_path = /obj/item/ammo_box/magazine/smgm9mm/fire /datum/design/mag_smg/incin_tox - name = "Submachine Gun Urnaium Magazine (9mmIC)" - desc = "A 42-round urnaium tipped round magazine for the prototype submachine gun. Deals toxin damage, but less overall damage." + name = "SABR SMG Urnaium Magazine (9mmTX)" + desc = "A 30-round urnaium tipped round magazine for the prototype submachine gun. Deals toxin damage, but less overall damage." id = "mag_smg_tx" - materials = list(MAT_METAL = 3000, MAT_GLASS = 200, MAG_URNAIUM = 1000) + materials = list(MAT_METAL = 3000, MAT_GLASS = 200, MAT_URANIUM = 1000) build_path = /obj/item/ammo_box/magazine/smgm9mm/toxin /datum/design/stunshell diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 4792688be1f..fb55059cbcf 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -394,11 +394,10 @@ user << "The rune fizzles uselessly! There is no spirit nearby." return var/mob/living/carbon/human/G = new /mob/living/carbon/human - if(prob(50)) G.gender = "female" - hardset_dna(G, null, null, null, null, /datum/species/golem/adamantine) - + G.set_species(/datum/species/golem/adamantine) G.set_cloned_appearance() - G.real_name = text("Adamantine Golem ([rand(1, 1000)])") + G.real_name = "Adamantine Golem ([rand(1, 1000)])" + G.dna.unique_enzymes = G.dna.generate_unique_enzymes() G.dna.species.auto_equip(G) G.loc = src.loc G.key = ghost.key diff --git a/html/changelog.html b/html/changelog.html index 92e133dc46a..ea4c8d14c32 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,73 @@ -->
+

22 September 2015

+

Kor updated:

+
    +
  • A new admin command, Offer Control to Ghosts, can be found in the view variables menu. It will randomly select a willing candidate from among dead players, providing a fair method of replacing antagonists.
  • +
+

Xhuis updated:

+
    +
  • When a morph changes form, a message is shown to nearby people. This also happens upon undisguising.
  • +
  • Morphs now have an attack sound and message.
  • +
  • The Spawn Morph event now plays a sound to the chosen candidate.
  • +
  • Slaughter demons (and other creatures with blood crawl) now take two seconds to emerge from blood pools. Entering is still instantaneous.
  • +
  • The demon heart's sprite has been updated.
  • +
  • Eating a demon heart now surgically implants the heart into your chest. If the heart is removed from you, you lose the ability. Someone else can eat the heart to gain the ability.
  • +
  • Blood Crawl no longer has a 1-second cooldown, instead having none.
  • +
  • You can no longer hold items when attempting to Blood Crawl, nor can you use any items while Blood Crawling.
  • +
  • Creatures that can Blood Crawl now take two seconds to emerge from blood pools.
  • +
  • Slaughter demons now store devoured creatures, and will drop them upon death.
  • +
  • Revenants now have the ability to speak to the dead.
  • +
  • Revenant abilities now have icons.
  • +
  • Malfunction no longer EMPs a specific area - it will instead EMP nearby machines directly and stun cyborgs. Dominators are immune to this.
  • +
  • Revenants now have directional sprites.
  • +
  • Overload Lights now has a smaller radius.
  • +
  • Defile no longer corrupts tiles.
  • +
  • When glimmering residue reforms, the game will attempt to place the old revenant in control of the new one. If this cannot be done, it will find a random candidate.
  • +
  • Revenants can no longer see ghosts. They can see other revenants, however, and ghosts can still see revenants.
  • +
  • The Spawn Slaughter Demon event now plays a sound to the chosen candidate.
  • +
+

phil235 updated:

+
    +
  • Lizards and other non human species can no longer acquire the hulk mutation. Hulks no longer have red eyes
  • +
  • Monkeys now always have dna and a blood type (compatible with humans).
  • +
  • Monkey transformation no longer deletes the human's clothes.
  • +
  • Space Retrovirus now correctly transfers dna SE to the infected human.
  • +
  • Changeling's Anatomic Panacea removes alien embryo again.
  • +
  • Cloning someone now correctly sets up their dna UE.
  • +
  • Fixes the laser eyes mutation not giving glowing red eyes to the human.
  • +
  • Using changeling readaptation now properly removes all evolutions bought (arm blade, chameleon skin, organic suit).
  • +
+

xxalpha updated:

+
    +
  • Added a researchable cyborg self-repair module to the robotics fabricator.
  • +
+ +

20 September 2015

+

Xhuis updated:

+
    +
  • Rites have been renamed to their old runes, which reflect their functionality.
  • +
  • Examining a talisman no longer opens the paper GUI.
  • +
  • Armor talismans have been re-added.
  • +
  • EMP talismans now have the same range as their rune counterpart.
  • +
  • Some talismans now cost health to use, costing more or less depending on their effect.
  • +
  • Scribing runes now deals 0.1 brute damage instead of 1.
  • +
  • Bind Talisman runes no longer deal 5 brute damage when invoking.
  • +
  • Rune shapes and colors are now identical to their old versions.
  • +
  • Conversion runes can no longer be used by yourself, and require a static 2 cultists.
  • +
+ +

19 September 2015

+

Xhuis updated:

+
    +
  • Shadowlings are now able to sacrifice a thrall to extend the shuttle timer by 15 minutes. This will not stack.
  • +
  • Additional abilities granted by Collective Mind will now properly have icons.
  • +
  • Shadowlings now have their antagonism removed if turned into a silicon.
  • +
  • The order of abilities unlocked by Collective Mind has been changed. It now starts with Sonic Screech.
  • +
  • Veil now destroys glowshrooms in a much larger radius than before.
  • +
+

17 September 2015

bgobandit updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index be3e9459aaf..ac5873fa26a 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -1821,3 +1821,75 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. metal) to contain radiation.' - rscadd: New portable nuke, self-destruct terminal, syndie screwdriver sprites by WJohnston. +2015-09-19: + Xhuis: + - rscadd: Shadowlings are now able to sacrifice a thrall to extend the shuttle timer + by 15 minutes. This will not stack. + - bugfix: Additional abilities granted by Collective Mind will now properly have + icons. + - bugfix: Shadowlings now have their antagonism removed if turned into a silicon. + - tweak: The order of abilities unlocked by Collective Mind has been changed. It + now starts with Sonic Screech. + - tweak: Veil now destroys glowshrooms in a much larger radius than before. +2015-09-20: + Xhuis: + - tweak: Rites have been renamed to their old runes, which reflect their functionality. + - tweak: Examining a talisman no longer opens the paper GUI. + - tweak: Armor talismans have been re-added. + - tweak: EMP talismans now have the same range as their rune counterpart. + - tweak: Some talismans now cost health to use, costing more or less depending on + their effect. + - tweak: Scribing runes now deals 0.1 brute damage instead of 1. + - tweak: Bind Talisman runes no longer deal 5 brute damage when invoking. + - tweak: Rune shapes and colors are now identical to their old versions. + - tweak: Conversion runes can no longer be used by yourself, and require a static + 2 cultists. +2015-09-22: + Kor: + - rscadd: A new admin command, Offer Control to Ghosts, can be found in the view + variables menu. It will randomly select a willing candidate from among dead + players, providing a fair method of replacing antagonists. + Xhuis: + - tweak: When a morph changes form, a message is shown to nearby people. This also + happens upon undisguising. + - tweak: Morphs now have an attack sound and message. + - tweak: The Spawn Morph event now plays a sound to the chosen candidate. + - tweak: Slaughter demons (and other creatures with blood crawl) now take two seconds + to emerge from blood pools. Entering is still instantaneous. + - tweak: The demon heart's sprite has been updated. + - tweak: Eating a demon heart now surgically implants the heart into your chest. + If the heart is removed from you, you lose the ability. Someone else can eat + the heart to gain the ability. + - tweak: Blood Crawl no longer has a 1-second cooldown, instead having none. + - tweak: You can no longer hold items when attempting to Blood Crawl, nor can you + use any items while Blood Crawling. + - tweak: Creatures that can Blood Crawl now take two seconds to emerge from blood + pools. + - tweak: Slaughter demons now store devoured creatures, and will drop them upon + death. + - tweak: Revenants now have the ability to speak to the dead. + - tweak: Revenant abilities now have icons. + - tweak: Malfunction no longer EMPs a specific area - it will instead EMP nearby + machines directly and stun cyborgs. Dominators are immune to this. + - tweak: Revenants now have directional sprites. + - tweak: Overload Lights now has a smaller radius. + - tweak: Defile no longer corrupts tiles. + - tweak: When glimmering residue reforms, the game will attempt to place the old + revenant in control of the new one. If this cannot be done, it will find a random + candidate. + - tweak: Revenants can no longer see ghosts. They can see other revenants, however, + and ghosts can still see revenants. + - tweak: The Spawn Slaughter Demon event now plays a sound to the chosen candidate. + phil235: + - rscdel: Lizards and other non human species can no longer acquire the hulk mutation. + Hulks no longer have red eyes + - bugfix: Monkeys now always have dna and a blood type (compatible with humans). + - bugfix: Monkey transformation no longer deletes the human's clothes. + - bugfix: Space Retrovirus now correctly transfers dna SE to the infected human. + - bugfix: Changeling's Anatomic Panacea removes alien embryo again. + - bugfix: Cloning someone now correctly sets up their dna UE. + - bugfix: Fixes the laser eyes mutation not giving glowing red eyes to the human. + - bugfix: Using changeling readaptation now properly removes all evolutions bought + (arm blade, chameleon skin, organic suit). + xxalpha: + - rscadd: Added a researchable cyborg self-repair module to the robotics fabricator. diff --git a/html/changelogs/Xhuis-SlingStuff.yml b/html/changelogs/Xhuis-SlingStuff.yml deleted file mode 100644 index f40d2aa7002..00000000000 --- a/html/changelogs/Xhuis-SlingStuff.yml +++ /dev/null @@ -1,9 +0,0 @@ -author: Xhuis -delete-after: True - -changes: - - rscadd: "Shadowlings are now able to sacrifice a thrall to extend the shuttle timer by 15 minutes. This will not stack." - - bugfix: "Additional abilities granted by Collective Mind will now properly have icons." - - bugfix: "Shadowlings now have their antagonism removed if turned into a silicon." - - tweak: "The order of abilities unlocked by Collective Mind has been changed. It now starts with Sonic Screech." - - tweak: "Veil now destroys glowshrooms in a much larger radius than before." \ No newline at end of file diff --git a/icons/effects/blood.dmi b/icons/effects/blood.dmi index b81a0e94104..250ed8f3dc4 100644 Binary files a/icons/effects/blood.dmi and b/icons/effects/blood.dmi differ diff --git a/icons/effects/genetics.dmi b/icons/effects/genetics.dmi index ba81afe9d11..768be9b9231 100644 Binary files a/icons/effects/genetics.dmi and b/icons/effects/genetics.dmi differ diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index 343654c5810..c1ffea30969 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index 76d807e61d8..fb295a1cf5d 100644 Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index 7f29bc82e7a..c71e05f382a 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/doors/airlocks/hatch/overlays.dmi b/icons/obj/doors/airlocks/hatch/overlays.dmi index 738f7e8fce5..38f8b50f420 100644 Binary files a/icons/obj/doors/airlocks/hatch/overlays.dmi and b/icons/obj/doors/airlocks/hatch/overlays.dmi differ diff --git a/icons/obj/doors/airlocks/station/atmos.dmi b/icons/obj/doors/airlocks/station/atmos.dmi index 85e5f3c1094..21fe5d2aab8 100644 Binary files a/icons/obj/doors/airlocks/station/atmos.dmi and b/icons/obj/doors/airlocks/station/atmos.dmi differ diff --git a/icons/obj/doors/airlocks/station/command.dmi b/icons/obj/doors/airlocks/station/command.dmi index e473eb1cd10..90b3e4238d1 100644 Binary files a/icons/obj/doors/airlocks/station/command.dmi and b/icons/obj/doors/airlocks/station/command.dmi differ diff --git a/icons/obj/doors/airlocks/station/engineering.dmi b/icons/obj/doors/airlocks/station/engineering.dmi index 1f77793bce0..816a84538c1 100644 Binary files a/icons/obj/doors/airlocks/station/engineering.dmi and b/icons/obj/doors/airlocks/station/engineering.dmi differ diff --git a/icons/obj/doors/airlocks/station/medical.dmi b/icons/obj/doors/airlocks/station/medical.dmi index cb10aca0763..f7cb5be24ef 100644 Binary files a/icons/obj/doors/airlocks/station/medical.dmi and b/icons/obj/doors/airlocks/station/medical.dmi differ diff --git a/icons/obj/doors/airlocks/station/mining.dmi b/icons/obj/doors/airlocks/station/mining.dmi index a4628613568..23dee39ef6a 100644 Binary files a/icons/obj/doors/airlocks/station/mining.dmi and b/icons/obj/doors/airlocks/station/mining.dmi differ diff --git a/icons/obj/doors/airlocks/station/public.dmi b/icons/obj/doors/airlocks/station/public.dmi index 3c2bdbcaa93..0449817360e 100644 Binary files a/icons/obj/doors/airlocks/station/public.dmi and b/icons/obj/doors/airlocks/station/public.dmi differ diff --git a/icons/obj/doors/airlocks/station/research.dmi b/icons/obj/doors/airlocks/station/research.dmi index ba483f8d3cf..e2a834d133c 100644 Binary files a/icons/obj/doors/airlocks/station/research.dmi and b/icons/obj/doors/airlocks/station/research.dmi differ diff --git a/icons/obj/doors/airlocks/station/science.dmi b/icons/obj/doors/airlocks/station/science.dmi index 11290674546..a3aa87c5a6e 100644 Binary files a/icons/obj/doors/airlocks/station/science.dmi and b/icons/obj/doors/airlocks/station/science.dmi differ diff --git a/icons/obj/doors/airlocks/station/security.dmi b/icons/obj/doors/airlocks/station/security.dmi index 8f42fcb4b3b..c6f01195abb 100644 Binary files a/icons/obj/doors/airlocks/station/security.dmi and b/icons/obj/doors/airlocks/station/security.dmi differ diff --git a/icons/obj/doors/airlocks/station/virology.dmi b/icons/obj/doors/airlocks/station/virology.dmi index 12123fc71b5..79ac14dffc3 100644 Binary files a/icons/obj/doors/airlocks/station/virology.dmi and b/icons/obj/doors/airlocks/station/virology.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index 1c0e0a73d79..415ce62a797 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/module.dmi b/icons/obj/module.dmi index e7fc43e6109..fb68f0bcc65 100644 Binary files a/icons/obj/module.dmi and b/icons/obj/module.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index 72ef46c7163..a9efb0990f4 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/icons/obj/stationobjs.dmi b/icons/obj/stationobjs.dmi index a0ad4429129..6ea13bfc621 100644 Binary files a/icons/obj/stationobjs.dmi and b/icons/obj/stationobjs.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index e1f7fe92119..53e3b56f76c 100644 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/tgstation.dme b/tgstation.dme index b36f5a2073e..83af6872f1a 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -400,6 +400,7 @@ #include "code\game\machinery\cloning.dm" #include "code\game\machinery\constructable_frame.dm" #include "code\game\machinery\deployable.dm" +#include "code\game\machinery\dna_scanner.dm" #include "code\game\machinery\doppler_array.dm" #include "code\game\machinery\droneDispenser.dm" #include "code\game\machinery\flasher.dm" @@ -464,6 +465,7 @@ #include "code\game\machinery\computer\communications.dm" #include "code\game\machinery\computer\computer.dm" #include "code\game\machinery\computer\crew.dm" +#include "code\game\machinery\computer\dna_console.dm" #include "code\game\machinery\computer\HolodeckControl.dm" #include "code\game\machinery\computer\law.dm" #include "code\game\machinery\computer\medical.dm" @@ -735,7 +737,6 @@ #include "code\game\objects\structures\janicart.dm" #include "code\game\objects\structures\kitchen_spike.dm" #include "code\game\objects\structures\ladders.dm" -#include "code\game\objects\structures\lamarr_cage.dm" #include "code\game\objects\structures\lattice.dm" #include "code\game\objects\structures\mineral_doors.dm" #include "code\game\objects\structures\mirror.dm" @@ -1243,6 +1244,7 @@ #include "code\modules\mob\living\simple_animal\shade.dm" #include "code\modules\mob\living\simple_animal\simple_animal.dm" #include "code\modules\mob\living\simple_animal\bot_swarm\swarmer.dm" +#include "code\modules\mob\living\simple_animal\bot_swarm\swarmer_event.dm" #include "code\modules\mob\living\simple_animal\friendly\butterfly.dm" #include "code\modules\mob\living\simple_animal\friendly\cat.dm" #include "code\modules\mob\living\simple_animal\friendly\crab.dm"