diff --git a/Dockerfile b/Dockerfile index a0370935..ec3694c7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM tgstation/byond:512.1484 as base +FROM tgstation/byond:512.1488 as base FROM base as build_base diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 8a1ed98f..398b4828 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -208,15 +208,15 @@ "adZ" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden,/turf/closed/wall/r_wall,/area/security/execution/transfer) "aea" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 8},/turf/open/floor/plasteel,/area/security/prison) "aeb" = (/obj/machinery/button/door{id = "permacell3"; name = "Cell 3 Lockdown"; pixel_x = -4; pixel_y = 25; req_access_txt = "2"},/obj/machinery/button/flasher{id = "PCell 3"; pixel_x = 6; pixel_y = 24},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden,/obj/effect/turf_decal/tile/red{dir = 4},/turf/open/floor/plasteel,/area/security/prison) -"aec" = (/obj/machinery/light{dir = 1; pixel_y = 16},/obj/machinery/computer/security/telescreen/prison{pixel_y = 30},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/components/unary/vent_pump/on,/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 4},/turf/open/floor/plasteel,/area/security/prison) -"aed" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/effect/turf_decal/tile/red{dir = 1},/turf/open/floor/plasteel,/area/security/prison) +"aec" = (/obj/machinery/computer/security/telescreen/prison{pixel_y = 30},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/components/unary/vent_pump/on,/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 4},/turf/open/floor/plasteel,/area/security/prison) +"aed" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/effect/turf_decal/tile/red{dir = 1},/obj/machinery/light{dir = 1; pixel_y = 16},/turf/open/floor/plasteel,/area/security/prison) "aee" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden,/turf/open/floor/plasteel,/area/security/prison) "aef" = (/obj/machinery/button/door{id = "permacell2"; name = "Cell 2 Lockdown"; pixel_x = -4; pixel_y = 25; req_access_txt = "2"},/obj/machinery/button/flasher{id = "PCell 2"; pixel_x = 6; pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/effect/turf_decal/tile/red{dir = 4},/turf/open/floor/plasteel,/area/security/prison) "aeg" = (/obj/machinery/computer/security/telescreen/prison{pixel_y = 30},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/camera{c_tag = "Prison Hallway"; network = list("ss13","prison")},/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 4},/turf/open/floor/plasteel,/area/security/prison) -"aeh" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/effect/turf_decal/tile/red{dir = 1},/turf/open/floor/plasteel,/area/security/prison) +"aeh" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/effect/turf_decal/tile/red{dir = 1},/obj/machinery/light{dir = 1; pixel_y = 16},/turf/open/floor/plasteel,/area/security/prison) "aei" = (/obj/structure/cable{icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/open/floor/plasteel,/area/security/prison) "aej" = (/obj/machinery/button/door{id = "permacell1"; name = "Cell 1 Lockdown"; pixel_x = -4; pixel_y = 25; req_access_txt = "2"},/obj/machinery/button/flasher{id = "PCell 1"; pixel_x = 6; pixel_y = 24},/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden,/obj/effect/turf_decal/tile/red{dir = 4},/turf/open/floor/plasteel,/area/security/prison) -"aek" = (/obj/machinery/airalarm{pixel_y = 23},/obj/machinery/light{dir = 1; pixel_y = 16},/obj/structure/cable{icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 10},/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 4},/turf/open/floor/plasteel,/area/security/prison) +"aek" = (/obj/machinery/airalarm{pixel_y = 23},/obj/structure/cable{icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 10},/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 4},/turf/open/floor/plasteel,/area/security/prison) "ael" = (/obj/machinery/firealarm{pixel_y = 24},/obj/machinery/power/apc{areastring = "/area/security/prison"; dir = 4; name = "Prison Wing APC"; pixel_x = 24},/obj/structure/cable{icon_state = "0-8"},/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red,/obj/effect/turf_decal/tile/red{dir = 4},/turf/open/floor/plasteel,/area/security/prison) "aem" = (/obj/machinery/flasher/portable,/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/turf/open/floor/plasteel/dark,/area/ai_monitored/security/armory) "aen" = (/obj/effect/turf_decal/stripes/line{dir = 10},/turf/open/floor/plasteel,/area/ai_monitored/security/armory) @@ -1419,11 +1419,11 @@ "aBo" = (/obj/machinery/door/airlock/maintenance{name = "Tool Storage Maintenance"; req_access_txt = "12"},/obj/structure/cable{icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/open/floor/plating,/area/maintenance/port/fore) "aBp" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/closed/wall,/area/storage/primary) "aBq" = (/turf/closed/wall/r_wall,/area/storage/primary) -"aBr" = (/obj/machinery/computer/bank_machine,/obj/effect/turf_decal/bot_white,/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/turf/open/floor/plasteel/dark,/area/ai_monitored/nuke_storage) +"aBr" = (/obj/machinery/computer/bank_machine,/obj/effect/turf_decal/bot_white,/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/machinery/light{dir = 1; pixel_y = 16},/turf/open/floor/plasteel/dark,/area/ai_monitored/nuke_storage) "aBs" = (/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/open/floor/circuit,/area/ai_monitored/nuke_storage) -"aBt" = (/obj/machinery/airalarm{pixel_y = 23},/obj/machinery/light{dir = 1; pixel_y = 16},/turf/open/floor/circuit,/area/ai_monitored/nuke_storage) +"aBt" = (/obj/machinery/airalarm{pixel_y = 23},/turf/open/floor/circuit,/area/ai_monitored/nuke_storage) "aBu" = (/obj/machinery/power/apc{areastring = "/area/ai_monitored/nuke_storage"; dir = 1; name = "Vault APC"; pixel_y = 25},/obj/structure/cable{icon_state = "0-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/open/floor/circuit,/area/ai_monitored/nuke_storage) -"aBv" = (/obj/structure/filingcabinet,/obj/item/folder/documents,/obj/effect/turf_decal/bot_white,/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/turf/open/floor/plasteel/dark,/area/ai_monitored/nuke_storage) +"aBv" = (/obj/structure/filingcabinet,/obj/item/folder/documents,/obj/effect/turf_decal/bot_white,/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/machinery/light{dir = 1; pixel_y = 16},/turf/open/floor/plasteel/dark,/area/ai_monitored/nuke_storage) "aBw" = (/obj/machinery/gateway{dir = 10},/obj/effect/turf_decal/bot_white/left,/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/turf/open/floor/plasteel/dark,/area/gateway) "aBx" = (/obj/machinery/gateway,/obj/structure/cable{icon_state = "0-2"},/obj/effect/turf_decal/bot_white,/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/turf/open/floor/plasteel/dark,/area/gateway) "aBy" = (/obj/machinery/gateway{dir = 6},/obj/effect/turf_decal/bot_white/right,/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/turf/open/floor/plasteel/dark,/area/gateway) @@ -1736,7 +1736,7 @@ "aHt" = (/obj/machinery/atmospherics/components/unary/vent_pump/on{dir = 1},/obj/structure/sink{dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/obj/effect/landmark/start/assistant,/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/freezer,/area/crew_quarters/toilet) "aHu" = (/turf/open/floor/plasteel/freezer,/area/crew_quarters/toilet) "aHv" = (/obj/machinery/door/airlock{name = "Unit 1"},/turf/open/floor/plasteel/freezer,/area/crew_quarters/toilet) -"aHw" = (/obj/structure/lattice,/turf/closed/wall,/area/maintenance/starboard/fore) +"aHw" = (/turf/open/space/basic,/area/maintenance/starboard/fore) "aHx" = (/obj/machinery/door/airlock{name = "Unit B"},/turf/open/floor/plasteel/freezer,/area/crew_quarters/toilet) "aHy" = (/obj/structure/cable{icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 1},/turf/open/floor/plating,/area/maintenance/starboard/fore) "aHz" = (/obj/structure/cable{icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/cable{icon_state = "2-4"},/turf/open/floor/plating,/area/maintenance/starboard/fore) @@ -1815,7 +1815,7 @@ "aIU" = (/obj/machinery/vending/cola/random,/turf/open/floor/plasteel/dark,/area/hallway/primary/central) "aIV" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral{dir = 8},/turf/open/floor/plasteel,/area/hallway/primary/central) "aIW" = (/obj/structure/extinguisher_cabinet{pixel_x = 27},/obj/machinery/light{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/turf/open/floor/plasteel,/area/hallway/primary/central) -"aIX" = (/obj/machinery/camera{c_tag = "Dormitory Toilets"; dir = 1},/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/freezer,/area/crew_quarters/toilet) +"aIX" = (/obj/structure/lattice,/turf/open/space/basic,/area/maintenance/starboard/fore) "aIY" = (/obj/machinery/door/airlock{name = "Entertainment"; req_access_txt = "46"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/open/floor/plating,/area/maintenance/starboard/fore) "aIZ" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 1},/turf/closed/wall,/area/maintenance/starboard/fore) "aJa" = (/obj/structure/disposalpipe/segment,/turf/closed/wall,/area/crew_quarters/bar) @@ -4451,7 +4451,7 @@ "bHE" = (/obj/item/radio/intercom{frequency = 1485; name = "Station Intercom (Medbay)"; pixel_x = -30},/obj/machinery/camera{c_tag = "Medbay South"; dir = 4; network = list("ss13","medbay")},/turf/open/floor/plasteel/white,/area/medical/medbay/central) "bHF" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/components/unary/vent_scrubber/on,/turf/open/floor/plasteel/white,/area/medical/medbay/central) "bHG" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/public/glass{dir = 4; name = "Central Access"},/turf/open/floor/plasteel,/area/hallway/primary/starboard) -"bHH" = (/obj/machinery/door/airlock/public/glass{dir = 4; name = "Central Access"},/turf/open/floor/plasteel,/area/hallway/primary/starboard) +"bHH" = (/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "drain"; name = "drain"},/obj/machinery/camera{c_tag = "Vacant Office"; dir = 4},/turf/open/floor/plasteel/freezer,/area/crew_quarters/toilet) "bHI" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/structure/medscreen,/turf/open/floor/plasteel/white,/area/medical/virology) "bHJ" = (/obj/machinery/airalarm{dir = 4; pixel_x = -22},/obj/machinery/light/small{dir = 8},/turf/open/floor/plasteel,/area/science/storage) "bHK" = (/turf/open/floor/plasteel,/area/science/storage) @@ -4520,6 +4520,9 @@ "bIV" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/open/floor/plasteel/white,/area/medical/medbay/central) "bIW" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden,/turf/open/floor/plasteel/white,/area/medical/medbay/central) "bIX" = (/obj/machinery/door/airlock/command/glass{dir = 4; name = "Chief Medical Officer"; req_access_txt = "40"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/effect/turf_decal/tile/blue{dir = 4},/obj/effect/turf_decal/tile/blue{dir = 8},/turf/open/floor/plasteel/cafeteria,/area/crew_quarters/heads/cmo) +"bIY" = (/obj/machinery/door/airlock/public/glass{dir = 4; name = "Central Access"},/obj/machinery/door/firedoor,/turf/open/floor/plasteel,/area/hallway/primary/starboard) +"bIZ" = (/obj/machinery/atmospherics/pipe/manifold4w/general/visible,/turf/open/floor/plasteel,/area/engine/atmos) +"bJa" = (/obj/structure/lattice/catwalk,/obj/structure/cable{icon_state = "0-8"},/turf/open/space,/area/solar/starboard/aft) "bJb" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/closed/wall,/area/crew_quarters/heads/cmo) "bJc" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/open/floor/plating,/area/maintenance/aft) "bJd" = (/obj/structure/cable{icon_state = "1-2"},/obj/structure/disposalpipe/sorting/mail{sortType = 10},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/open/floor/plating,/area/maintenance/aft) @@ -4580,6 +4583,7 @@ "bKg" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/open/floor/plasteel/white/side{dir = 1},/area/medical/sleeper) "bKh" = (/obj/structure/closet/crate/freezer,/obj/item/reagent_containers/blood,/obj/item/reagent_containers/blood,/obj/item/reagent_containers/blood/AMinus,/obj/item/reagent_containers/blood/BMinus{pixel_x = -4; pixel_y = 4},/obj/item/reagent_containers/blood/BPlus{pixel_x = 1; pixel_y = 2},/obj/item/reagent_containers/blood/OMinus,/obj/item/reagent_containers/blood/OPlus{pixel_x = -2; pixel_y = -1},/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/APlus,/obj/item/reagent_containers/blood/random,/turf/open/floor/plasteel,/area/medical/sleeper) "bKi" = (/obj/structure/bed,/obj/item/bedsheet/medical,/turf/open/floor/plasteel/white,/area/medical/sleeper) +"bKj" = (/obj/structure/lattice/catwalk,/obj/structure/cable{icon_state = "0-4"},/turf/open/space,/area/solar/starboard/aft) "bKk" = (/obj/structure/closet/wardrobe/pjs,/turf/open/floor/plasteel/white,/area/medical/sleeper) "bKl" = (/obj/structure/table,/obj/machinery/light,/obj/item/reagent_containers/spray/cleaner,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/turf/open/floor/plasteel/white,/area/medical/sleeper) "bKm" = (/obj/structure/table,/obj/item/storage/firstaid/o2{pixel_x = 3; pixel_y = 3},/obj/item/storage/firstaid/o2,/obj/item/storage/firstaid/regular{pixel_x = -3; pixel_y = -3},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/open/floor/plasteel/white,/area/medical/sleeper) @@ -4593,6 +4597,7 @@ "bKu" = (/obj/structure/disposalpipe/junction/flip{dir = 2},/obj/machinery/atmospherics/pipe/manifold4w/scrubbers,/turf/open/floor/plasteel/white,/area/medical/medbay/central) "bKv" = (/obj/structure/disposalpipe/segment{dir = 9},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/open/floor/plasteel/white,/area/medical/medbay/central) "bKw" = (/obj/effect/spawner/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/open/floor/plating,/area/crew_quarters/heads/cmo) +"bKx" = (/obj/structure/lattice/catwalk,/obj/structure/cable{icon_state = "0-2"},/turf/open/space,/area/solar/starboard/aft) "bKB" = (/obj/structure/sign/warning/electricshock,/turf/closed/wall/r_wall,/area/science/xenobiology) "bKC" = (/obj/structure/disposaloutlet{dir = 1},/obj/structure/disposalpipe/trunk,/turf/open/floor/engine,/area/science/xenobiology) "bKD" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/obj/effect/turf_decal/bot,/turf/open/floor/plasteel,/area/science/storage) @@ -5296,7 +5301,6 @@ "bYa" = (/obj/structure/rack,/obj/item/clothing/suit/hazardvest,/obj/item/clothing/suit/hazardvest,/obj/item/clothing/suit/hazardvest,/obj/item/clothing/suit/hazardvest,/obj/item/clothing/gloves/color/black,/obj/item/clothing/gloves/color/black,/obj/item/clothing/gloves/color/black,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/turf/open/floor/plasteel,/area/engine/atmos) "bYb" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{dir = 8},/turf/open/floor/plasteel,/area/engine/atmos) "bYc" = (/obj/machinery/atmospherics/pipe/manifold/general/visible,/obj/machinery/meter,/turf/open/floor/plasteel,/area/engine/atmos) -"bYd" = (/obj/machinery/atmospherics/pipe/manifold{dir = 4},/turf/open/floor/plasteel,/area/engine/atmos) "bYe" = (/obj/machinery/atmospherics/components/trinary/filter/atmos/n2o{dir = 1},/turf/open/floor/plasteel,/area/engine/atmos) "bYf" = (/obj/machinery/atmospherics/pipe/simple/green/visible{dir = 4},/obj/effect/turf_decal/tile/red{dir = 4},/obj/effect/turf_decal/tile/red{dir = 8},/turf/open/floor/plasteel/white/corner,/area/engine/atmos) "bYg" = (/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/nitrous_input{dir = 8},/turf/open/floor/engine/n2o,/area/engine/atmos) @@ -5415,7 +5419,6 @@ "cap" = (/obj/machinery/atmospherics/components/unary/portables_connector/visible{dir = 4},/obj/machinery/portable_atmospherics/canister,/obj/effect/turf_decal/bot,/turf/open/floor/plasteel,/area/engine/atmos) "caq" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{dir = 4},/turf/open/floor/plasteel,/area/engine/atmos) "car" = (/obj/machinery/atmospherics/components/unary/portables_connector/visible{dir = 4},/turf/open/floor/plasteel,/area/engine/atmos) -"cas" = (/obj/machinery/atmospherics/pipe/manifold4w,/turf/open/floor/plasteel,/area/engine/atmos) "cat" = (/obj/effect/turf_decal/bot,/obj/machinery/atmospherics/pipe/simple/orange/visible{dir = 9},/turf/open/floor/plasteel,/area/engine/atmos) "cau" = (/obj/machinery/atmospherics/pipe/manifold/yellow/visible{dir = 8},/turf/open/floor/plasteel,/area/engine/atmos) "cav" = (/obj/machinery/camera{c_tag = "Atmospherics East"; dir = 8},/obj/machinery/atmospherics/components/binary/pump{dir = 8; name = "Plasma Outlet Pump"},/obj/effect/turf_decal/stripes/line{dir = 5},/turf/open/floor/plasteel,/area/engine/atmos) @@ -6711,7 +6714,6 @@ "czl" = (/obj/structure/sign/warning/vacuum/external{pixel_y = 32},/turf/open/floor/plating,/area/ai_monitored/turret_protected/aisat_interior) "czm" = (/obj/effect/mapping_helpers/airlock/cyclelink_helper{dir = 8},/obj/machinery/door/airlock/external{name = "MiniSat External Access"; req_access_txt = "65;13"},/turf/open/floor/plating,/area/ai_monitored/turret_protected/aisat_interior) "czn" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/open/floor/plating,/area/ai_monitored/turret_protected/aisat_interior) -"czo" = (/obj/structure/cable{icon_state = "0-2"},/obj/structure/lattice/catwalk,/turf/open/space,/area/solar/starboard/aft) "czp" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5},/turf/closed/wall/r_wall,/area/engine/engineering) "czq" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 10},/turf/closed/wall/r_wall,/area/engine/engineering) "czr" = (/obj/structure/closet/wardrobe/engineering_yellow,/obj/effect/turf_decal/stripes/line{dir = 10},/turf/open/floor/engine,/area/engine/engineering) @@ -6740,8 +6742,6 @@ "czO" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 8},/turf/closed/wall,/area/ai_monitored/turret_protected/aisat_interior) "czP" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/closed/wall,/area/ai_monitored/turret_protected/aisat_interior) "czQ" = (/obj/machinery/atmospherics/components/unary/outlet_injector/on{dir = 8},/turf/open/floor/plating/airless,/area/ai_monitored/turret_protected/aisat_interior) -"czR" = (/obj/structure/cable{icon_state = "4-8"},/obj/structure/lattice/catwalk,/turf/open/space,/area/solar/starboard/aft) -"czS" = (/obj/structure/cable{icon_state = "0-2"},/obj/structure/cable{icon_state = "0-4"},/obj/structure/cable{icon_state = "0-8"},/obj/structure/cable,/obj/structure/lattice/catwalk,/turf/open/space,/area/solar/starboard/aft) "czT" = (/obj/machinery/atmospherics/pipe/heat_exchanging/simple{dir = 5},/obj/structure/lattice,/turf/open/space,/area/space/nearstation) "czU" = (/obj/structure/table,/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = -7},/obj/item/stack/cable_coil,/turf/open/floor/plasteel/dark,/area/engine/engineering) "czV" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/open/floor/plasteel/dark,/area/engine/engineering) @@ -7061,12 +7061,12 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxvaaaaaaaaaaxwaXfaxyaxzaxAaxBaxAaxCaxDaxDaxEaxFaxDaxGaxHaxDaxDaxIaveaxJauWaxKamiamiaxLaxMalzaxNaxOatZatZatZatZatZaxPateaxQamialzarYarYateaxRalzaxSaxTaxUaxUaxVaxUaxWaxUaxUaxXaxYaxZayaayaayaayaayaayaayaaybaycaydayeayfaygayhayiayjaykaylaymaynayoaypayqayranbaysahfafmaqDaruarvaytarxayuayvawSawSawSawTaywayxayyayzauEayAayBayCayDayEayFayGayHayIaqKaqKaqKaqKaqKayJaqGaqGaqGamIamIaltaorayKayKayKayKaltarPaltaltayLaltaltapialtarPasLaltaltapialtamIasLaxnayMarSarUayNayOayPayQayRayOaySarUaadaoBaoBaoBaoBaoBaoBaoBaoBaoBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaweayTaweayUayVayUayWaxBaxBayXayUayVayUayYayZazaazbalzataauWalzalzalzalzazcazcazdazeazcazcazcazcazcaugawsaveaveaveaveaveazfaxRaoEaxSaaaaadaaaazgaaaazhaaaaadaaaaxYaxZayaaAAazjazkazlaCWayaaybaznazoazpazpazqazrazpazpazpazsaztaztazuazvayqazwanbazxahfafmaqDastasvasvazyasxazzazAazBazCazDazEazFazFazGazFaqGazHazIazJazKazLazMazNayJaqKaqKaqKaqKaqKayJaltapZamIamIamIaltaltayKazOazPayKapZarPaltazQamIaltazRamIaltazSazTaltazUamIaltapiapiaxnazVapiarUazWayOazXazYazXayOazZarUaadaadaadaoBaoBaoBaoBaoBaoBaoBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauSaAaauSaAbaxyayUaAcaAdaAeaAfayUaxyaAbayUauSaAgaAhalzaAiaAjaAkaAkaAkaAlazcaAmaAnaAoaApaAqaAraAmazcaAsaAtaAuaAvaAvaAvaAvaAvaAwarYaxSaadaAxaAxaAyaAxaAzaAxaAxaadaxYaxZayaaCXaABaACaADaCYayaaAEaAFaAGaAHaAIaAJaAKaALaAMaANaAOaAPayoayoayoaAQazwanbaARahfafmaASaASaASaASaASaATatuazFazFazFazFazFazFaAUaAVaAWazFaqGaqGaqGaqGaJgaJhaltayJaqKaqKaqKaqKaqKayJaltaltamIamIamIaltaAYayKaAZaBaayKamIarPaltamIasNaltamIamIaltarPasOaltamIamIaltaBbamIaxnayMaqTarUarUarUarUarUarUarUarUarUarVarVarVarVarVaadaoBaoBaoBaoBaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUaBcayUayUayUayUayUayUaBcayUaaaauSaBdazbaBeaBfaBgaBeaBeaBeaBhazcaAmaBiaBjaBkaBlaBmaAmazcaBnaBoaBnaBnaBnaBnaBnaBnaBpaBnaBqaaaaAxaBraBsaBtaBuaBvaAxaaaaxYaxZayaaCXaBwaBxaByaCYayaaqsaBzaydaBAaBBaBCaBDaBEaAPaBFaBGayoayoaBHayoaAQazwanbazxahfafmaASaBIaBJaBKaBLayuatuazFaBMaBNaBOaBOazFaBSaBPaAWazFaBQaZMaBRaqGaAXauJaltaBVaBWaBWaBWaBWaBWaBXaltaltaBYaBZaCaaltaltayKaCbaCcayKaCdaCealtaltaltaltaltaltaCfaCgaChaCiaCiaCiaCjaCkaClaCmaCnaCoaCpaCqaCraCsaCtaCuaCvaCwaCwaCwaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauSayWaCxaBeaCyaCzaCAaCBaCCaCDazcaAmaCEaCFaCGaCFaCFaAmazcaCHaCIaCJaCKaCLaCMaCNaCOaCPaCQaBqaadaAxaCRaCSaCTaCUaCVaAxaadaxYaxZayaaCZaDabiybizbiAayaaqsaDbaydaDcaDdaDeayoaDfaDgaDhaDiaDjaAQayqaDkayqazwanbazxahfafmaASaDlaDmaDnaDoasxaDpaDqaDraDsaDtaDtaDuaDvaDwaDBaDxaBUaDyaDzaDAaDCaDDaltaHwaltaHwaltaHwaltaHwaltaltaBYaDEaDFaDGaDHayKaDIaDJayKarPamIaltaaaaltaDKaDLaDLaDMaDNaDOaDOaDOaDOaDOaDPaDQaDRaDSaDTaDTaDTaDUaVqaDWaDXaDYaDZaEaaEbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUaBcayUayUayUayUayUayUaBcayUaaaauSaBdazbaBeaBfaBgaBeaBeaBeaBhazcaAmaBiaBjaBkaBlaBmaAmazcaBnaBoaBnaBnaBnaBnaBnaBnaBpaBnaBqaaaaAxaBraBsaBtaBuaBvaAxaaaaxYaxZayaaCXaBwaBxaByaCYayaaqsaBzaydaBAaBBaBCaBDaBEaAPaBFaBGayoayoaBHayoaAQazwanbazxahfafmaASaBIaBJaBKaBLayuatuazFaBMaBNaBOaBOazFaBSaBPaAWazFaBQaZMaBRaqGaAXauJaltaBVaBWaBWaBWaBWaBWaBXaHwaltaBYaBZaCaaltaltayKaCbaCcayKaCdaCealtaltaltaltaltaltaCfaCgaChaCiaCiaCiaCjaCkaClaCmaCnaCoaCpaCqaCraCsaCtaCuaCvaCwaCwaCwaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauSayWaCxaBeaCyaCzaCAaCBaCCaCDazcaAmaCEaCFaCGaCFaCFaAmazcaCHaCIaCJaCKaCLaCMaCNaCOaCPaCQaBqaadaAxaCRaCSaCTaCUaCVaAxaadaxYaxZayaaCZaDabiybizbiAayaaqsaDbaydaDcaDdaDeayoaDfaDgaDhaDiaDjaAQayqaDkayqazwanbazxahfafmaASaDlaDmaDnaDoasxaDpaDqaDraDsaDtaDtaDuaDvaDwaDBaDxaBUaDyaDzaDAaDCaDDaltaIXaHwaIXaHwaIXaHwaIXaHwaltaBYaDEaDFaDGaDHayKaDIaDJayKarPamIaltaaaaltaDKaDLaDLaDMaDNaDOaDOaDOaDOaDOaDPaDQaDRaDSaDTaDTaDTaDUaVqaDWaDXaDYaDZaEaaEbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayWaEcaBeaEdaEeaEfaEgaEhaEiazcaEjaCFaCFaCFaCFaCFaCFaEkaElaCIaElaEmaElaElaElaElaCPaElaBqaaaaAxaEnaEoaEoaEpaEqaAxaaaaxYaxZayaaEraEsaEtaEuaEvayaaqsaEwaydaydaDiaExaEyaEzaEAaydaydayoayoayqaEBayqazwanbazxahfafmaASaDlaECaEDalSaEFaEGaEHaEIaEJaEKaEKaEKaEKaEKaELazFaEMaEOaFHaqGaHCaHDaltaltaltaltaltaltaltaltaltaltaltaltaltaEPaltayKaEQaERaESaETaEUaEVaEWaEVaEXaEYaDOaEZaFaaFbaFbaFbaFbaFcaFdaFeaFcaFcaFcaFcaFcaFcaFcaFfaFgaFhaCwaCwaCwaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayWaFiaBeaFjaFkaFlaFmaFnaFoazcaFpaCFaCFaCFaCFaCFaFqazcaFraFsaFtaFuaElaElaElaFvaFwaFxaBqaadaAxaFyaFzaFAaFBaFCaAxaadaxYaFDayaaFEaFFaEtaFGaENayaaqsaFIayqaFJayoaFKaFLaFMayoaFNayqaFOaFPayqaFLayqaFQaoNaFRahfafmaASaDlaFSaFTaFUattatuazFaFVaFWazFaFXazFaFZazFaFYaZMaZMaWIaGbaGcaGeaGfaGgaHHaGiaGiaGjaGkaHyaHzaGkaGlaGmaGkaGkaGnaGiaGoaGpaCnaGqaGraGsaGtaGuaGtaGvaGwaFbaGxaGyaFbaGzaGAaGBaFcaGCaGDaFcaGEaGFaGGaGHaGIaGJaGKaGLaGMaGNaGOaGPaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoBaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGQayUayWaGRaBeaBeaGSaGTaGUaGTaBeazcazcazcazcaGVaCFaGWaGXazcaGYaCIaElaElaElaGZaElaElaCPaHaaBqaaaaAxaAxaHbaHcaHbaAxaAxaaaaxYaxZayaaHdaHeaHfaHgaHhayaaqsaHiayqaHjayoaHkaFLaHlayoaHmayqaAQaAQayqaHnayqaHoaHpaHqahfanDaASaASaASaASaASaHraHsazFaHtaHuazFaHvazFaHxazFaGdaGhaHJaGhaHAaHGbiBbiCaHEaHFaHIaHIaIYaIZaJcaKmaHIaHKaHLaHMaxpaxpaxpaHNaHOaHPaHQaHRamIaHSaHSaHSaHTaHUaFbaHVaHWaHXaHYaHZaIaaFcaIbaIcaFcaIdaIeaIfaIgaGIaIhaFfaFgaDYaIiaIjaGPaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayWaxBaIkaIlaImaIlaInaxBaIoaIpaIqaIrazcaIsaCFaCFaItazcaIuaCIaElaIvaIwaIxaIyaIzaIAaIBaBqaaaaadaaaaICaIDaICaaaaadaaaaxYaxZayaaIEaIFaIGaFGaIHayaaqsapyayqaIIayoaFLaFLaFLaIJaIKayqaaaaaaaILaIMaINaIOaIPaIQemiaISaILaaaaaaaITaIUaIVaIWazFaIXaHuaHuaHuaHuaHuazFaJaaJbaJdaJeaJdaJdaNtaPQbiDaBTaBTaJfaKhaKiaKjaKkaJiaJiaJjaJkaJlaJiaJmaHSaHSaJnaHTaHSaHSaHSaJoaJpaHTaHUaFbaJqaJraJsaJtaJuaJvaFcaJwaJxaJyaJzaJAaJBaJCaJDaIhaFfaJEaDYaGNaJFaGPaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayWaxBaIkaIlaImaIlaInaxBaIoaIpaIqaIrazcaIsaCFaCFaItazcaIuaCIaElaIvaIwaIxaIyaIzaIAaIBaBqaaaaadaaaaICaIDaICaaaaadaaaaxYaxZayaaIEaIFaIGaFGaIHayaaqsapyayqaIIayoaFLaFLaFLaIJaIKayqaaaaaaaILaIMaINaIOaIPaIQemiaISaILaaaaaaaITaIUaIVaIWazFbHHaHuaHuaHuaHuaHuazFaJaaJbaJdaJeaJdaJdaNtaPQbiDaBTaBTaJfaKhaKiaKjaKkaJiaJiaJjaJkaJlaJiaJmaHSaHSaJnaHTaHSaHSaHSaJoaJpaHTaHUaFbaJqaJraJsaJtaJuaJvaFcaJwaJxaJyaJzaJAaJBaJCaJDaIhaFfaJEaDYaGNaJFaGPaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayWaxBaJGaJHaJIaJHaJJaJHaJHaJHaJKaxBazcaJLaJMaJLazcazcaJNaJOaJNaBnaBnaBnaBnaJNaJPaJQaBqaJRaJSaJSaJTaJUaJVaJSaJSaJWaxYaJXayaaJYayaaJZaKaaKbayaarjaoJayqayqayqaAQaKcaAQayqayqayqaILaILaILaKdaIPaIPaIPaIPaIPaKeaILaILaILaITaKfaIVaKgazFaLMazFazFazFazFazFaJdaGaaKsbiEaKtbgUaKoaMcaLQaLcaLTaBTaKpaKraKraKjaLSaJiaLUaKuaKvaKwaJiaKxaKyaKzaKAaKBaKCaKDaKEaKFaKGaHTaHUaFbaKHaKIaKJaJtaJuaKKaFcaKLaKMaKNaKOaKPaKQaKRaFcaFcaKSaFgaDYaIiaIjaGPaaaaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauSaKTaxBaKUaKVaKWaKXaKYaKZaweaLaaLbaxBaLjaLdaLeaLeaLfaLeaLeaLgaLeaLeaLeaLeaLeaLeaLhaLiaLqaLkaLlaLmaLmaLnaLmaLmaLmaLmaLoaLpaLxaLraLmaLsaLmaLtaMWaLuaLvaLwaLRaEEaIRaIRaIRaLNaLPaLPbiFaLPaLPaLAaLBaLCaLDaLEaLFaLGaLPaLPbiFaLHaLIaLJaLKaPJbcXaNKbiGaLPbiHbiIaOCaLVaKsaLWaWHaLXaLYaOvaNjaNlaNnaBTaLZaMaaMbaNkaNmaJiaMdaKuaMeaMfaJiaJiaMgaMhaMiaMjaMkaMlaMmaMnaMoaHTaHUaFbaMpaMpaMqaMraMpaMpaFcaMsaMtaFcaMuaKRaKRaKRaFcaMvaMwaMxaDYaCwaCwaCwaMyaMyaMyaMzaMzaMzaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayVayUayUayUayUayUayUayVayUaaaauSaBdaMAaKUaMBaMCaMDaMEaMFaweaMGaLbaMHaIkaLdaMIaMJaMKaMLaMLaMMaLeaLeaLeaLeaLeaLeaLeaLiaLeaLdaMNaLeaLeaMOaMPaMQaMQaMQaMRaMSaMQaMTaMQaMUaMQaMVaOnaMXaMYaMZaIPaIPaIPaIPaIPaIPaIPaIPaLzaIPaIPaNaaNbaNcaNdaNeaNfaNgaIPaIPaLzaIPaNhaIPaIPaIPaIPaIPaIPaIPaNiaIPaOCaNoaNpaNqaNraStaNsbiJaOwaOxaOyaBTaNuaOuaOuaHBaOzaJiaNvaKuaNwaNxaNyaJiaHSaHSaNzaHSaHSaHSaNAaNBaNAaHTaHUaFbaNCaMpaMpaNDaMpaNEaFcaFcaFcaFcaFcaFcaFcaNFaFcaFfaFfaFgaDYaNGaNHaCwaNIaNJaRkaNLaNMaMzaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -7082,7 +7082,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUbanaPebaoaTcaUwaVFaUwaUubapaUwbaqaUwaTcbarbasbataXpaXpaXpbaubavaXpaZbbawaZbaPlaZdaZeaZfaZgaPlaZhaZibaxbayaZjbazaZmaZnaWdbaAaZpaZpaZGbaBaZpbaDbbxaIPaIPbbZaZvbaFbaGbaHbaIbaJbcebaLbaMbaNbaOaZAaZAbaPbaQbaPaZAaZAbaRbaSbaCbaTbaUbaXbaYbbzbaVbaWaZDbjoaIPaIPbgTbgTbjpbbXaJdaJdaJdbbbaSqbbbaJdbbcaJdaJdaJdaJibcbbdZbbdbbdbbdbbdbcfbdHaJiaZWbbgbbgaZWbaabaabaabaaaHTaZZbaababaFbaFbaFbbbhaFbbbhaFbbbhaFbaFbaCwaCwbbibbibbibbibbibbiaCwaCwbbjaQjbbkaQiaQjaQjbblaQlaQlaQlaQlaSZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadauSauSayUayUayUayUayUayUayUayUauSauSaweaxBaxBaTcaTcaTdaTcaTcaTcaTcaTeaTcaTcbbmbbnbboaXpaYWbbpbaubbqaXpbbrbbsbbraPlaZdaZeaZfaZgaPlbbtaZiaZjbbubbvbbwaZmaZnbjqaZsbbybaZbbabbAaZpbaDbbCaIPaIPaXNbbDbbEbaJbbFbbGbbGbbHbbIbbJbaNbbKaZAaZAbaPbbLbaPaZAaZAbbMbaSbbBbbNbpdbbRbbSbcWbaWbbOaZDbjobbUaIPaIPbaabaabaabecbGkbehbaabaabaabeibembembembembeobaabaabaabaabaabaabaabaabehbaabaabaabaabaabaabaabcabepbccbcdbaabesbembembaabembaabembaabembekbeobfObaabaabaabaabaabaabbWbcgaSXaQjbchbcibcjbckaMzaMzaMzaMzaMzaRIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUawhawiawiawiawiawiawiawiawiawhawibclaxDaxDbcmbcnbcobcpbcpbcpbcqbcrbcsaPjbctbcubcvaXpaXpaXpbcwbcxaXpaPlaPlaPlaPlaZdaZebcybczaPlaZhaZiaZjbcAbcBbcCbcDbcEbcFbcGbcGbcGbcHbcIaZsbcJaWdaQUaNhaXNbcKbcLbaJbcMbcNbcObcPbcQbcRbaNbcSbaPaZAbcTbcUbcTaZAbaPaZCbaSbbPbbNbpdbbRbdVbcWbaWbaWaZDbjraIPaIPaIPbaabaabaabaabHGbbWbaabaabaabaabcYbaabaabaabaabaabcZaYzaYzaYzaYzbdabaabbWbaabaabaabaabaabaabdbbdcbddbdebdfbdfbdfbdgbdfbdfbdfbdfbdfbdfbdfbdfbdfbdfbdfbdfbdfbdfbdfbdhbdibdjbdkbdkbdlaQibdmaQjbdnaQlaQlbdoaQlbdpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadayUaxAaxBaxAazaaxBaxBbdqaxAaxBaxAazaaxBaxBaxBbdrbdsbdrbdrbdrbdrbdtbduaPjaPjaPjbdvaVLaXpaYWbdwbdxbbqaXpbdybdzbdyaPlaPlaPlbdAbdBaPlaZhaZibdCbdDbdEbdFaZmaPjaWdaWdaWdaWdaWdaWdaWdbdGaWdbfPaIPaXNbcKbdIbaJbcMbdJbdKbcPbcQbaJbaNbdLbdMaZAbdNbdObdPaZAbdQbdRbaSbbQbbTbcVbdWbdXbjdbaWbdSaZDbjobeaaIPbedbgBbgBbgBbiibHHbjtbeebeebeebfAbefbeebeebjubgBbgBbgBbgBbgBbjvbjwbejbjxbjtbgBbgBbaabaafnsbelbjybenbjzbjAbeqbeqbeqbaabgBbgDbjBbgBbgBbaabaabaabaabaabaabaabaabaabaabaabbWbetbeubevbewaQiaQjaPbaMzaMzaMzaMzaMzaMzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadayUaxAaxBaxAazaaxBaxBbdqaxAaxBaxAazaaxBaxBaxBbdrbdsbdrbdrbdrbdrbdtbduaPjaPjaPjbdvaVLaXpaYWbdwbdxbbqaXpbdybdzbdyaPlaPlaPlbdAbdBaPlaZhaZibdCbdDbdEbdFaZmaPjaWdaWdaWdaWdaWdaWdaWdbdGaWdbfPaIPaXNbcKbdIbaJbcMbdJbdKbcPbcQbaJbaNbdLbdMaZAbdNbdObdPaZAbdQbdRbaSbbQbbTbcVbdWbdXbjdbaWbdSaZDbjobeaaIPbedbgBbgBbgBbiibIYbjtbeebeebeebfAbefbeebeebjubgBbgBbgBbgBbgBbjvbjwbejbjxbjtbgBbgBbaabaafnsbelbjybenbjzbjAbeqbeqbeqbaabgBbgDbjBbgBbgBbaabaabaabaabaabaabaabaabaabaabaabbWbetbeubevbewaQiaQjaPbaMzaMzaMzaMzaMzaMzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaweayUbexayUayWaxBaxBayXayUbeyayUayYbezbeAbeAbdrbeBbeCbeDbeEbeFbdtbeGbeHbeIbeIbeJbeKaXpaXpaXpbeLbeMaXpaPjaPjaPjaPjbeNbeObePbeQbeObeRaZibeSbeTaZjaZlaZmbeUbeVbeWbeXbeXbeXbeXbeYbeZbeVbjCaIPbbZaZvbaJbfbbfcbfdbfebffbcQbfgbfhaXYbfibfjbfkbfkbfkbflbfmaYdbfnbdTbdUbdYbpxbfobjdbaWbfpaZDbjoaIPbjDbfvbfvbfvbfvbfvbfvbfvbfwbfxbfxbfxbfybfzbfzbfwbjEbjEbjEberberberberberbfBbfBbfBbfCbfBbfBbfBbfBbfBbfGbfHbfIbfJbfJbfJbfKbfLbfLbfLbfLbfLbfMbfNbfNbjFbjGbfNbjHbjIbfNbfNbfRbfSbfSbfSbfSbfTbfUbfVbfWaMzaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaAaauSaAbaxyayUaAcaAdbfXbfYayUaxyaAbayUauSaAaawebdrbfZbgabgabgabgbbgcbgdbgebeObeObgfbggaXpaYWbghbeLbgiaXpbgjbgjaRTbgkbglbgmbgnbgmbgmbgobgpbgqaZkbgrbgsaZmaRTbgtbgubeVbgvbgwbgxbgyaPNbgAbjJbgCbjKaZvbgEaZybgFbgGbgHbgIbcQbgJaZvaadbgKbjLbjMbjMbjMbjNbgMaadaZDbfqbfrbfsbftbaWbfubaWbgNaZDbjoaIPbjObfvbjPbgVbgWbgXbgYbfvbhfbjQbjQbjQbhbbhcbhcbhdbhebjRaWYbfDbfEbfFbhhberbhlbhibhjbhkbhibhmbhnbfBbfBbhobhpbhqbhrbhsbhtbhubhvbhwbhxbjSbfLbhzbhAbhzbfLbhBbhCbhBbfSbhDbhEbhDbfSbhFbhGbfSbhHbhIaMzaMzaMzaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaadaadaadaadayUbhJayUayUayUayUayUayUbhKayUaadaadaadaaabdrbhLbdrbhMbgabhNbhObdraRTaTfbhPbhQbhRbhSbhSbhSbhSbhSbhSbhTbhUbhVbhWbhXbhYbhYbhYbhYbhYbhYaZmbhZaZiaZmbhYbhYbiabibbicbidbiebifbiebigbihbfaaIPbjTaZvbijaZyaZyaZyaZybgIbcQbikaZvaadbgKbjUbilbimbinbjVbgMaadaZDbgObbNbgPbgQbaWbjdbaWbaWaZDbjoaIPbjDbfvbirbisbitbitbiubivbhcbiwbhcbhcbhbbjWbhcbhcbhcbhcbixbfDbjXbjYbjZberbkabhibhibkbbkabkcbhibfBbkdbkebfHbkfbkgbkhbkibkjbkkbklbkmbknbkobkpbkqbkrbfLbksbktbkubfSbgRbgSbgRbiobgRbgRbfSbkzbhIaaaaadaaaaadaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -7116,10 +7116,10 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaebNFbUDbJIbJIbJIbUEbEybUFbEybUGbEybTvbJIbJIbUHbNEbEyaaaaadaaaaaabNFbIlbMsbEybEybMsbUIbPNbUJbUKbULbUMbUNbUObUPbUQbPNbURbUSbHbbOObUTbUUbUVbPdbPdbUWbOPbUXbUYbUZbVabPdbPdbOWbVbbVcbVdbVcbVdbVebVdbVfaadbQkbQkbQkbQkbQkaadbEEbCxbPebQtbVgbVhbVibVjbVkbVlbVmbVnbQtbQtbQtbQtbVobPebCxbFavIdbGlbGlbVpbVqbOnbVrbOnbVsbVtbGlbGliiObLRbVubThbThbThbVvbVwbVxbVybVzbVAbSbbVBbUAbVCbUAbVDbScbVEbNrbSebNraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabEybEybShbJIbJIbJIbVFbJIbTubVGbEybEybEybVHbEybEybEybNFbNFbNFbVIbVJbVKbVLbVMbGObVNbUIbPNbPNbPNbPNbPNbPNbPNbPNbPNbPNbVObVPbHbbVQbNSbVRbVSbTNbVTbTNbOPbPdbPdbPdbVabVUbQibQibVVbVWbVXbRrbVYbVZbWabRvbRwbRxbWbbWcbWcbQkaadbEEbCxbWdbWebWebWebWfbWgbQtbWhbVhbWibVhbVhbVhbVhbWjbPebCxbFabGlbGlbGlbWkbWlbUnbWmbOnbWnbWobUjbUjbWpbLRbWqbWrbThbThbWsbTkbWtbVzbVwbWubSbbWvbUAbWwbUAbUAbScbVEbNrbSebNraadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoBaoBaaeaadaadbWxaoBbEybEybEybEybEybEybEybEybEybEybJIbJIbJIbJIbJIbWybWzbWAbWAbWBbWCbWDbFnbFnbFnbFnbWEbWFbWFbWFbWFbWFbWGbWHbWHbWIbEybURbWJbHbbWKbWLbWMbWNbQibQibWObWPbQibQibWQbWRbWSbPdbWTbWUbWVbWWbPdbWXbWYbWZbSSaadbSTbXabXbbXcbQkaadbRBbXdbMPbMPbMPbXebPebXfbQtbXgbXhbXibXjbXkbXkbXkbXlbPebCxbFabLRbLRbLRbLRbXmbXnbVrbXobXmbLRbLRbLRbLRbLRbXpbXqbThbThbXrbXsbXsbXsbXsbXtbSbbXubXvbXwbXxbXybScbVEbNrbSebNraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabXzbXAbXAbXAbXAbXBbXCbXCbXDbXEbXFbXGbXHbXIbXJbXKbEybXLbEybEybEybEybEybXMbEybEybMsbNGbXNbXNbXNbXNbXNbXNbXNbXNbXObXObXObXObXObNEbXPbEybURbWJbHbbWKbXQbXRbXSbXTbTSbXUbXVbTSbTSbXWbXXbXYbXZbYabYbbYcbYdbPdbWXbYebYfbUabUbbRxbYgbWcbWcbQkaadbRBbYhbEEbEEbEEbCxbPebYibQtbQtbYjbYkbYlbQpbXkbQpbYmbPebCxbFabUibUjbUjbYnbUlbOnbYobUnbYpbYqbGlbGlbGlbLRbYrbYsbYtbThbYubThbThbThbYvbYwbYxbYybYzbYAbYBbYCbScbVEbNrbSebNraadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabXzbXAbXAbXAbXAbXBbXCbXCbXDbXEbXFbXGbXHbXIbXJbXKbEybXLbEybEybEybEybEybXMbEybEybMsbNGbXNbXNbXNbXNbXNbXNbXNbXNbXObXObXObXObXObNEbXPbEybURbWJbHbbWKbXQbXRbXSbXTbTSbXUbXVbTSbTSbXWbXXbXYbXZbYabYbbYccaqbPdbWXbYebYfbUabUbbRxbYgbWcbWcbQkaadbRBbYhbEEbEEbEEbCxbPebYibQtbQtbYjbYkbYlbQpbXkbQpbYmbPebCxbFabUibUjbUjbYnbUlbOnbYobUnbYpbYqbGlbGlbGlbLRbYrbYsbYtbThbYubThbThbThbYvbYwbYxbYybYzbYAbYBbYCbScbVEbNrbSebNraadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoBaadaaeaoBaadaoBaoBbNFbNFbNFbJIbYDbYEbYFbYGbYHbEybJIbEybYIbYJbYIbYKbYLbYIbYMbMsbNGbXNbYNbYObYPbYQbYRbYSbYNbYTbYUbYVbYWbXObXObXPbEybYXbWJbHbbYYbYZbZabZabZbbZcbZcbZcbZcbZcbZdbZebOPbOPbOPbZfbPdbWVbZgbZhbZibZjbZkbZlbQkbQkbQkbQkbQkaadbRBbYhbZmbCwbCwbCxbQlbZnbZobZpbZqbZrbZsbZtbXkbZtbZubPebCxbFavIdbZvbGlbZwbVqbOnbVrbOnbVsbZxbGlbZviiObLRbZybZzbZAbZBbZCbZDbZEbZEbZFbZGbZHbZIbYzbZJbZKbZLbScbVEbNrbSebNrbNrbNraaeaaeaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoBaadaaeaaeaaeaaeaaebZMbJIbZNbJIbZObZPbYEbZQbJIbZRbJIbEybYIbZSbYIbZTbZUbYIbZVbMsbNGbXNbYNbZWbZXbZYbZZcaabYNcabcaccadcaecafbXObXPbEybURbWJbHbcagcahbNScaicajbZccakcalcambZccanbVacaobOPcapcaqcarcascatcaubVZcavbRvcawbRxcaxcaycazbQkaadbEEbYhbEEcaAcaBbCxbPecaCcaDcaEcaFcaGcaDcaHbXkcaHbRHbRJbCxbFabGlbGlbGlcaIcaJbUnbWmbOnbWncaKbUjbUjbWpbFacaLcaMcaNcaOcaLcaLcaPcaQcaRcaScaTcaUcaVcaWcaXcaYbScbVEbNrcaZbNrcbabNraadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoBcbbaoBaoBaoBaadaadbNFbNFbNFcbccbdcbecbfcbgbJIbEybEycbhbYIcbicbjbYIcbkcblbYIbMsbNGbXNcbmcbncbobZYcbpcbmcbmcabcbqcbrcbscbtbXObXPbEybURbWJaYncbucbucbvcbwcbxcbycbzcbAcbBbZcbPdbVacbCcbDcapcbEcarcascbFcbGbVZcbHcbIcbJcbKcbLcbMcbNbQkaadbEEbYhbEEbJZbJZbCxbPebPfcbOcbPbPfcbQbPfbPfbPfbPfbPfbPebCxbFabLRbLRbLRbLRbXmcbRbVrcbSbXmbLRbLRbLRbLRbFabVwcbTbVwcbUbVwcaLcaPcaQcbVcbWcbXcbYcbZccabUAccbbScbVEbNrcccccdbQSbPIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoBaadaaeaaeaaeaaeaaebZMbJIbZNbJIbZObZPbYEbZQbJIbZRbJIbEybYIbZSbYIbZTbZUbYIbZVbMsbNGbXNbYNbZWbZXbZYbZZcaabYNcabcaccadcaecafbXObXPbEybURbWJbHbcagcahbNScaicajbZccakcalcambZccanbVacaobOPcapcaqcarbIZcatcaubVZcavbRvcawbRxcaxcaycazbQkaadbEEbYhbEEcaAcaBbCxbPecaCcaDcaEcaFcaGcaDcaHbXkcaHbRHbRJbCxbFabGlbGlbGlcaIcaJbUnbWmbOnbWncaKbUjbUjbWpbFacaLcaMcaNcaOcaLcaLcaPcaQcaRcaScaTcaUcaVcaWcaXcaYbScbVEbNrcaZbNrcbabNraadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoBcbbaoBaoBaoBaadaadbNFbNFbNFcbccbdcbecbfcbgbJIbEybEycbhbYIcbicbjbYIcbkcblbYIbMsbNGbXNcbmcbncbobZYcbpcbmcbmcabcbqcbrcbscbtbXObXPbEybURbWJaYncbucbucbvcbwcbxcbycbzcbAcbBbZcbPdbVacbCcbDcapcbEcarbIZcbFcbGbVZcbHcbIcbJcbKcbLcbMcbNbQkaadbEEbYhbEEbJZbJZbCxbPebPfcbOcbPbPfcbQbPfbPfbPfbPfbPfbPebCxbFabLRbLRbLRbLRbXmcbRbVrcbSbXmbLRbLRbLRbLRbFabVwcbTbVwcbUbVwcaLcaPcaQcbVcbWcbXcbYcbZccabUAccbbScbVEbNrcccccdbQSbPIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaadaadaadbNFcceccfccfccgbYHbNEbEycchccibYIccjcckcclccjccjccmbImbNGbXNcbmcbmccnccoccpccqccrccscctccuccvccwbXObXPbEyccxccycczcbuccAccBccCccDccEccFccGccHbZcccIccJcaobOPcapccKcarcbEccLbWXccMccNbUaccOccPccQcaycaybQkaadbRBbYhccRbEEccSbCxccTbWebWeccUbPfccVccWccXbEEccYccZbEZbCxbFabUibUjbUjcdabUlbOnbYobUncdbcdcbGlbGlbGlbFacddbVwbVwbVwbVwcaLcdecdecdfcdgbYxcdhbUAcdibUAbVDbScbVEbNrcdjbQTcdkbPIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaaQaaQaaQaaQaaQaaQaaQaaQaaYaaQaaQaaQaaQaaQaaaaaabEybEybEybEybEybEycdlbEybEybEybEycdmcdnbYIccjcbjcdoccjccjccmbImbNGbXNcdpcdqcdrcdsbYNbYNcdtcducdvcdwcdxcdybXOcdzcdAcdBcdCcdDcbucdEcdFcdGcdHcdIcdJcdKcdLcdMbRpcdNbOPbOPbOPcdObPdcdPcdQbWXbWYbPdbSScdRcdSbQkbQkbQkbQkaadbRBcdTcdUbEEcdVcdWcdXbMPcdYcdZbEEceacebcecbEEcedbOibOkceebFavIdbGlbGlcefbVqbOnbVrbOnbVscegbGlbGliiObFacehbVwceicejcekcelcemcenceocdgbSbcepceqbUzbUAcerbSccesbNrcetceubSebPIaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaaaaadaaaaadaaaaadaaaacfaaaaadaaaaadaaaaaQaadaadbEycevcewbJIcexbJIbJIbJIbJIbNEbEyceycezceAccjcbjbYIceBceCbYIbImbNGbXNceDceEbYNbYNbYNcbmceFceGceHceIceJceKbXObEybEyceLceMceNcbucbuceOcePceQceRceRceRceRbZcbPdceSceTceUceVceWceXceYceZcaubVZcfabRvcawccPcfbcfccfcbQkaadbRBbCwbYhbEEbEEcfdbBrbEEcfecffbEEbEEcfgbEEbEEcffcfhbJccfibFabGlbGlbJecfjcfkbUncflbOnbWncfmbUjbUjbWpbFabVwbVwcfnbVwbVwcaLcdecdecfocfpbSbcfqcfrcfsbUAcftbScbVEbNrbNrbNrbSebNraadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -7148,10 +7148,10 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabicxOabiaaaaaacwVcwWcwXcwWcwXcwWcwXcxPcxQcxRcuPcxScxTcxkcxUcxVcxWcxXcxYcxkcxZcyacuPcwgcwJcxJcybcfWcwxcyccmCaadaaacydaaaaadaaaaaaaaaaadaaaaaaaaaaadaaaaaaaaacocaaaaaaaaacyecyecyecyecyeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaadcwocwocwocwocwoaaacwpaaacwocwocwocwocwoaadaaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabicxOabiaaaaaacyfcygcyhcygcyhcygcyhcygcyicyjcykcylcwGcvAcvAcymcyncwecvAcvAcwAcyocypcyqcyrcyscybcsVaaeaaeaaeaadaaaaaacytcyucyvcyvcyvcyucyvcyvcyvcyucyvcyvcyvcywcyvcyvcyvcyxcyycyzcyAcyeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaaacwPcwQcwQcwQcwQcwRcwpcwScwTcwTcwTcwTcwUaaaaaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabicxOabiaadaadcyBcyCcyCcyCcyCcyCcyCcyCcxQcyDcuPcyEcyFcyGcyHcyIcyJcyKcyHcyLcyMcyNcuPcyOcyPcwJcyQcsVaaaaaaaaeaadaaaaaaaaaaadaaaaaaaaaaadaaaaaaaaaaadaaaaaaaaacocaaecyecyecyecyRcyScyRcyeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaadcxwcxwcxwcxwcxwaaacwpaaacxwcxwcxwcxwcxwaadaaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabicxOabiaaaaaacyfcyBcyfcyBcyfcyBcyfcyBcxQcyTcyUcyVcyWcyXcyYcyZczaczbcyYczcczdczeczfczgczhcziczjcsVaaaaaaaaeaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadcocaaeczkczlczmcyAczncyAcyeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaYaaaaaaaaaaadaaaaaaaaaczoaaaaaaaaaaadaaaaaaaaaaaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabicxOabiaaaaaacyfcyBcyfcyBcyfcyBcyfcyBczpczqczrczscztczuczuczvczaczwczuczuczxczyczzczAczBcfWcfWcfWaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeczCaaecyeczDczEczFcznczGczEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaadcwocwocwocwocwoaaactVaaacwocwocwocwocwoaadaaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabicxOabiaadaadcyBcyCcyCcyCcyCcyCcyCcyCaaaczpcsRczHczIcsVcfWcsVcsVcsVcfWcsVczIczJcirczKczLaaeaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacocaaeczMczMczMczMczNczOczPczQaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaaacwPcwQcwQcwQcwQczRczSczRcwTcwTcwTcwTcwUaaaaaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabicxOabiaaaaaaczTcxPczTcxPczTcxPczTcxPaaacfWczUczVczWcnIczXczYczZcwJczXcnIczWcAacAbcfWcAcaaeaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacocaaaaaaczMczMcAdcAecAfczMczMczMczMczMaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaadcxwcxwcxwcxwcxwaaactVaaacxwcxwcxwcxwcxwaadaaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabicxOabiaaaaaacyfcyBcyfcyBcyfcyBcyfcyBcxQcyTcyUcyVcyWcyXcyYcyZczaczbcyYczcczdczeczfczgczhcziczjcsVaaaaaaaaeaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadcocaaeczkczlczmcyAczncyAcyeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaYaaaaaaaaaaadaaaaaaaaacwpaaaaaaaaaaadaaaaaaaaaaaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabicxOabiaaaaaacyfcyBcyfcyBcyfcyBcyfcyBczpczqczrczscztczuczuczvczaczwczuczuczxczyczzczAczBcfWcfWcfWaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeczCaaecyeczDczEczFcznczGczEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaadcwocwocwocwocwoaaacwpaaacwocwocwocwocwoaadaaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabicxOabiaadaadcyBcyCcyCcyCcyCcyCcyCcyCaaaczpcsRczHczIcsVcfWcsVcsVcsVcfWcsVczIczJcirczKczLaaeaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacocaaeczMczMczMczMczNczOczPczQaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaaacwPcwQcwQcwQcwQbJacwpbKjcwTcwTcwTcwTcwUaaaaaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabicxOabiaaaaaaczTcxPczTcxPczTcxPczTcxPaaacfWczUczVczWcnIczXczYczZcwJczXcnIczWcAacAbcfWcAcaaeaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacocaaaaaaczMczMcAdcAecAfczMczMczMczMczMaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaadcxwcxwcxwcxwcxwaaabKxaaacxwcxwcxwcxwcxwaadaaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabiabiaaaaaaaaaaadaaaaadaaaaadaaaaadaaacfWcwJczVcAgcAhcwJcwJcwJcwJcwJcAicAjcAacwJcfWaaeaaeaadaadaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacocaaaaaaczMcAkcAlcAmcAncAocApcAqcArczMaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaaaaaaaadaaaaadaaaaaactVaaaaaaaadaaaaadaaaaaaaaQaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaadaaaaadaaaaadaaaaadaaacfWcAscAtcAucAvcwJcwJczZcwJcwJcAwcAjcAxaZJcfWaaaaadaaaaadcxOabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacocaaaaaaczMcAycAzcAAcABcACcADcAEcAFczMaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaQaaQaaQaaQaaQaadaadaaactVaaaaadaadaaQaaQaaQaaYaaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadabiabiabiabiabiabiabiabiabiaadcfWcwJcwJcAGcAvcwJcAHcAIcAJcwJcAicAKcwJcwJcfWaadaadaadaadcxOabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcrLcALaadczMcAMcANcAOcAPcAQcARcAScATczMaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaadcAUaadaaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm index da8aebb4..fd29e892 100644 --- a/code/__DEFINES/colors.dm +++ b/code/__DEFINES/colors.dm @@ -4,15 +4,15 @@ #define COLOR_INPUT_ENABLED "#D3B5B5" #define COLOR_DARKMODE_INFO_BUTTONS_BG "#40628A" -#define COLOR_DARKMODE_ISSUE_BUTTON_BG "#ce4242" -#define COLOR_DARKMODE_BACKGROUND "#202020" -#define COLOR_DARKMODE_DARKBACKGROUND "#171717" -#define COLOR_DARKMODE_TEXT "#f0f0f0" +#define COLOR_DARKMODE_ISSUE_BUTTON_BG "#A92C2C" +#define COLOR_DARKMODE_BACKGROUND "#272727" +#define COLOR_DARKMODE_DARKBACKGROUND "#242424" +#define COLOR_DARKMODE_TEXT "#E0E0E0" -#define COLOR_WHITEMODE_INFO_BUTTONS_BG "#90b3dd" -#define COLOR_WHITEMODE_ISSUE_BUTTON_BG "#ef7f7f" -#define COLOR_WHITEMODE_BACKGROUND "#eeeeee" -#define COLOR_WHITEMODE_DARKBACKGROUND "#dddddd" +#define COLOR_WHITEMODE_INFO_BUTTONS_BG "#90B3DD" +#define COLOR_WHITEMODE_ISSUE_BUTTON_BG "##EF7F7F" +#define COLOR_WHITEMODE_BACKGROUND "#F0F0F0" +#define COLOR_WHITEMODE_DARKBACKGROUND "#E6E6E6" #define COLOR_WHITEMODE_TEXT "#000000" #define COLOR_FLOORTILE_GRAY "#8D8B8B" diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index e1d54064..92808872 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -227,6 +227,8 @@ //Mood #define COMSIG_ADD_MOOD_EVENT "add_mood" //Called when you send a mood event from anywhere in the code. #define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code. +#define COMSIG_INCREASE_SANITY "decrease_sanity" //Called when you want to increase sanity from anywhere in the code. +#define COMSIG_DECREASE_SANITY "increase_sanity" //Same as above but to decrease sanity instead. //NTnet #define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive" //called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata)) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 5bcee19f..da56e4ef 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -56,7 +56,7 @@ #define isgolem(A) (is_species(A, /datum/species/golem)) #define islizard(A) (is_species(A, /datum/species/lizard)) #define isplasmaman(A) (is_species(A, /datum/species/plasmaman)) -#define ispodperson(A) (is_species(A, /datum/species/podperson)) +#define ispodperson(A) (is_species(A, /datum/species/pod)) #define isflyperson(A) (is_species(A, /datum/species/fly)) #define isjellyperson(A) (is_species(A, /datum/species/jelly)) #define isslimeperson(A) (is_species(A, /datum/species/jelly/slime)) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index bb6fab9f..935d71a3 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -496,3 +496,6 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S #define VOMIT_TOXIC 1 #define VOMIT_PURPLE 2 + +//Misc text define. Does 4 spaces. Used as a makeshift tabulator. +#define FOURSPACES "    " \ No newline at end of file diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index a9636b64..be0ac101 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -117,6 +117,8 @@ #define BIOWARE_GENERIC "generic" #define BIOWARE_NERVES "nerves" #define BIOWARE_CIRCULATION "circulation" +#define BIOWARE_LIGAMENTS "ligaments" +#define BIOWARE_DISSECTION "dissected" //Health hud screws for carbon mobs #define SCREWYHUD_NONE 0 diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index 174289d3..b8cdeef6 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -34,3 +34,17 @@ #define DEL_REAGENT 1 // reagent deleted (fully cleared) #define ADD_REAGENT 2 // reagent added #define REM_REAGENT 3 // reagent removed (may still exist) + +//reagent bitflags, used for altering how they works +#define REAGENT_DEAD_PROCESS (1<<0) //calls on_mob_dead() if present in a dead body +#define REAGENT_DONOTSPLIT (1<<1) //Do not split the chem at all during processing +#define REAGENT_ONLYINVERSE (1<<2) //Only invert chem, no splitting +#define REAGENT_ONMOBMERGE (1<<3) //Call on_mob_life proc when reagents are merging. +#define REAGENT_INVISIBLE (1<<4) //Doesn't appear on handheld health analyzers. +#define REAGENT_FORCEONNEW (1<<5) //Forces a on_new() call without a data overhead +#define REAGENT_SNEAKYNAME (1<<6) //When inverted, the inverted chem uses the name of the original chem +#define REAGENT_SPLITRETAINVOL (1<<7) //Retains initial volume of chem when splitting + +//Chemical reaction flags, for determining reaction specialties +#define REACTION_CLEAR_IMPURE (1<<0) //Convert into impure/pure on reaction completion +#define REACTION_CLEAR_INVERSE (1<<1) //Convert into inverse on reaction completion when purity is low enough \ No newline at end of file diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm index 0820d632..1faa87e9 100644 --- a/code/__DEFINES/robots.dm +++ b/code/__DEFINES/robots.dm @@ -36,6 +36,7 @@ #define MED_BOT (1<<4) // Medibots #define HONK_BOT (1<<5) // Honkbots & ED-Honks #define FIRE_BOT (1<<6) // Firebots +#define HUG_BOT (1<<7) // Hugbots //AI notification defines #define NEW_BORG 1 diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 3394fba9..3ec3650c 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -83,7 +83,8 @@ #define INIT_ORDER_SHUTTLE -21 #define INIT_ORDER_MINOR_MAPPING -40 #define INIT_ORDER_PATH -50 -#define INIT_ORDER_PERSISTENCE -100 +#define INIT_ORDER_PERSISTENCE -95 +#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init. // Subsystem fire priority, from lowest to highest priority // If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child) @@ -97,7 +98,7 @@ #define FIRE_PRIORITY_GARBAGE 15 #define FIRE_PRIORITY_WET_FLOORS 20 #define FIRE_PRIORITY_AIR 20 -#define FIRE_PRIORITY_NPC 20 +#define FIRE_PRIORITY_NPC 80 #define FIRE_PRIORITY_PROCESS 25 #define FIRE_PRIORITY_THROWING 25 #define FIRE_PRIORITY_SPACEDRIFT 30 @@ -114,6 +115,7 @@ #define FIRE_PRIORITY_MOBS 100 #define FIRE_PRIORITY_TGUI 110 #define FIRE_PRIORITY_TICKER 200 +#define FIRE_PRIORITY_CHAT 400 #define FIRE_PRIORITY_OVERLAYS 500 #define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost. diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index f56a5683..08b9b6c3 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -95,6 +95,8 @@ #define TRAIT_NOHUNGER "no_hunger" #define TRAIT_EASYDISMEMBER "easy_dismember" #define TRAIT_LIMBATTACHMENT "limb_attach" +#define TRAIT_NOLIMBDISABLE "no_limb_disable" +#define TRAIT_EASYLIMBDISABLE "easy_limb_disable" #define TRAIT_TOXINLOVER "toxinlover" #define TRAIT_NOBREATH "no_breath" #define TRAIT_ANTIMAGIC "anti_magic" diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 55d9e7a6..6a80f230 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -280,34 +280,34 @@ if(GLOB.round_id) var/statspage = CONFIG_GET(string/roundstatsurl) var/info = statspage ? "[GLOB.round_id]" : GLOB.round_id - parts += "[GLOB.TAB]Round ID: [info]" + parts += "[FOURSPACES]Round ID: [info]" var/list/voting_results = SSvote.stored_gamemode_votes if(length(voting_results)) - parts += "[GLOB.TAB]Voting: " + parts += "[FOURSPACES]Voting: " var/total_score = 0 for(var/choice in voting_results) var/score = voting_results[choice] total_score += score - parts += "[GLOB.TAB][GLOB.TAB][choice]: [score]" + parts += "[FOURSPACES][FOURSPACES][choice]: [score]" - parts += "[GLOB.TAB]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]" - parts += "[GLOB.TAB]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[popcount["station_integrity"]]%"]" + parts += "[FOURSPACES]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]" + parts += "[FOURSPACES]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[popcount["station_integrity"]]%"]" var/total_players = GLOB.joined_player_list.len if(total_players) - parts+= "[GLOB.TAB]Total Population: [total_players]" + parts+= "[FOURSPACES]Total Population: [total_players]" if(station_evacuated) - parts += "
[GLOB.TAB]Evacuation Rate: [popcount[POPCOUNT_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_ESCAPEES]/total_players)]%)" - parts += "[GLOB.TAB](on emergency shuttle): [popcount[POPCOUNT_SHUTTLE_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_SHUTTLE_ESCAPEES]/total_players)]%)" - parts += "[GLOB.TAB]Survival Rate: [popcount[POPCOUNT_SURVIVORS]] ([PERCENT(popcount[POPCOUNT_SURVIVORS]/total_players)]%)" + parts += "
[FOURSPACES]Evacuation Rate: [popcount[POPCOUNT_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_ESCAPEES]/total_players)]%)" + parts += "[FOURSPACES](on emergency shuttle): [popcount[POPCOUNT_SHUTTLE_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_SHUTTLE_ESCAPEES]/total_players)]%)" + parts += "[FOURSPACES]Survival Rate: [popcount[POPCOUNT_SURVIVORS]] ([PERCENT(popcount[POPCOUNT_SURVIVORS]/total_players)]%)" if(SSblackbox.first_death) var/list/ded = SSblackbox.first_death if(ded.len) - parts += "[GLOB.TAB]First Death: [ded["name"]], [ded["role"]], at [ded["area"]]. Damage taken: [ded["damage"]].[ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""]" + parts += "[FOURSPACES]First Death: [ded["name"]], [ded["role"]], at [ded["area"]]. Damage taken: [ded["damage"]].[ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""]" //ignore this comment, it fixes the broken sytax parsing caused by the " above else - parts += "[GLOB.TAB]Nobody died this shift!" + parts += "[FOURSPACES]Nobody died this shift!" return parts.Join("
") /client/proc/roundend_report_file() diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index b5cd75a5..5c3f3beb 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -171,12 +171,27 @@ GLOBAL_LIST_INIT(bitfields, list( "rad_flags" = list( "RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS, "RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE, - ), + ), "disease_flags" = list( "CURABLE" = CURABLE, "CAN_CARRY" = CAN_CARRY, "CAN_RESIST" = CAN_RESIST - ), + ), + + "chemical_flags" = list( + "REAGENT_DEAD_PROCESS" = REAGENT_DEAD_PROCESS, + "REAGENT_DONOTSPLIT" = REAGENT_DONOTSPLIT, + "REAGENT_ONLYINVERSE" = REAGENT_ONLYINVERSE, + "REAGENT_ONMOBMERGE" = REAGENT_ONMOBMERGE, + "REAGENT_INVISIBLE" = REAGENT_INVISIBLE, + "REAGENT_FORCEONNEW" = REAGENT_FORCEONNEW, + "REAGENT_SNEAKYNAME" = REAGENT_SNEAKYNAME, + "REAGENT_SPLITRETAINVOL" = REAGENT_SPLITRETAINVOL + ), + "clear_conversion" = list( + "REACTION_CLEAR_IMPURE" = REACTION_CLEAR_IMPURE, + "REACTION_CLEAR_INVERSE" = REACTION_CLEAR_INVERSE + ), "organ_flags" = list( "ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC, @@ -185,5 +200,5 @@ GLOBAL_LIST_INIT(bitfields, list( "ORGAN_EXTERNAL" = ORGAN_EXTERNAL, "ORGAN_VITAL" = ORGAN_VITAL, "ORGAN_NO_SPOIL" = ORGAN_NO_SPOIL - ), - )) \ No newline at end of file + ), + )) \ No newline at end of file diff --git a/code/_globalvars/lists/poll_ignore.dm b/code/_globalvars/lists/poll_ignore.dm index 94723cae..b28ee975 100644 --- a/code/_globalvars/lists/poll_ignore.dm +++ b/code/_globalvars/lists/poll_ignore.dm @@ -13,6 +13,8 @@ #define POLL_IGNORE_GOLEM "golem" #define POLL_IGNORE_SWARMER "swarmer" #define POLL_IGNORE_DRONE "drone" +#define POLL_IGNORE_DEMON "demon" +#define POLL_IGNORE_WIZARD "wizard" GLOBAL_LIST_INIT(poll_ignore_desc, list( POLL_IGNORE_SENTIENCE_POTION = "Sentience potion", @@ -28,6 +30,8 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list( POLL_IGNORE_GOLEM = "Golems", POLL_IGNORE_SWARMER = "Swarmer shells", POLL_IGNORE_DRONE = "Drone shells", + POLL_IGNORE_DEMON = "Demons", + POLL_IGNORE_WIZARD = "Wizards", )) GLOBAL_LIST_INIT(poll_ignore, init_poll_ignore()) diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index d8d22289..899ccbe7 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -6,8 +6,6 @@ GLOBAL_VAR_INIT(timezoneOffset, 0) // The difference betwen midnight (of the hos // However it'd be ok to use for accessing attack logs and such too, which are even laggier. GLOBAL_VAR_INIT(fileaccess_timer, 0) -GLOBAL_VAR_INIT(TAB, "    ") - GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) GLOBAL_VAR_INIT(CELLRATE, 0.002) // conversion ratio between a watt-tick and kilojoule diff --git a/code/controllers/subsystem/chat.dm b/code/controllers/subsystem/chat.dm new file mode 100644 index 00000000..a579752a --- /dev/null +++ b/code/controllers/subsystem/chat.dm @@ -0,0 +1,67 @@ +SUBSYSTEM_DEF(chat) + name = "Chat" + flags = SS_TICKER|SS_NO_INIT + wait = 1 + priority = FIRE_PRIORITY_CHAT + init_order = INIT_ORDER_CHAT + var/list/payload = list() + + +/datum/controller/subsystem/chat/fire() + for(var/i in payload) + var/client/C = i + C << output(payload[C], "browseroutput:output") + payload -= C + + if(MC_TICK_CHECK) + return + + +/datum/controller/subsystem/chat/proc/queue(target, message, handle_whitespace = TRUE) + if(!target || !message) + return + + if(!istext(message)) + stack_trace("to_chat called with invalid input type") + return + + if(target == world) + target = GLOB.clients + + //Some macros remain in the string even after parsing and fuck up the eventual output + message = replacetext(message, "\improper", "") + message = replacetext(message, "\proper", "") + if(handle_whitespace) + message = replacetext(message, "\n", "
") + message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]") + message += "
" + + + //url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript. + //Do the double-encoding here to save nanoseconds + var/twiceEncoded = url_encode(url_encode(message)) + + if(islist(target)) + for(var/I in target) + var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible + + if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file. + continue + + if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue + C.chatOutput.messageQueue += message + continue + + payload[C] += twiceEncoded + + else + var/client/C = CLIENT_FROM_VAR(target) //Grab us a client if possible + + if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file. + return + + if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue + C.chatOutput.messageQueue += message + return + + payload[C] += twiceEncoded \ No newline at end of file diff --git a/code/controllers/subsystem/npcpool.dm b/code/controllers/subsystem/npcpool.dm index c69154a1..7fd35124 100644 --- a/code/controllers/subsystem/npcpool.dm +++ b/code/controllers/subsystem/npcpool.dm @@ -1,6 +1,6 @@ SUBSYSTEM_DEF(npcpool) name = "NPC Pool" - flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND + flags = SS_KEEP_TIMING | SS_NO_INIT priority = FIRE_PRIORITY_NPC runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index 730ffa9f..eb381af5 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -21,6 +21,8 @@ RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT, .proc/add_event) RegisterSignal(parent, COMSIG_CLEAR_MOOD_EVENT, .proc/clear_event) + RegisterSignal(parent, COMSIG_INCREASE_SANITY, .proc/IncreaseSanity) + RegisterSignal(parent, COMSIG_DECREASE_SANITY, .proc/DecreaseSanity) RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud) var/mob/living/owner = parent @@ -129,23 +131,23 @@ switch(mood_level) if(1) - DecreaseSanity(0.2) + DecreaseSanity(src, 0.2) if(2) - DecreaseSanity(0.125, SANITY_CRAZY) + DecreaseSanity(src, 0.125, SANITY_CRAZY) if(3) - DecreaseSanity(0.075, SANITY_UNSTABLE) + DecreaseSanity(src, 0.075, SANITY_UNSTABLE) if(4) - DecreaseSanity(0.025, SANITY_DISTURBED) + DecreaseSanity(src, 0.025, SANITY_DISTURBED) if(5) - IncreaseSanity(0.1) + IncreaseSanity(src, 0.1) if(6) - IncreaseSanity(0.15) + IncreaseSanity(src, 0.15) if(7) - IncreaseSanity(0.20) + IncreaseSanity(src, 0.20) if(8) - IncreaseSanity(0.25, SANITY_GREAT) + IncreaseSanity(src, 0.25, SANITY_GREAT) if(9) - IncreaseSanity(0.4, SANITY_GREAT) + IncreaseSanity(src, 0.4, SANITY_GREAT) if(insanity_effect != holdmyinsanityeffect) if(insanity_effect > holdmyinsanityeffect) @@ -218,9 +220,9 @@ master.crit_threshold = (master.crit_threshold - insanity_effect) + newval insanity_effect = newval -/datum/component/mood/proc/DecreaseSanity(amount, minimum = SANITY_INSANE) +/datum/component/mood/proc/DecreaseSanity(datum/source, amount, minimum = SANITY_INSANE) if(sanity < minimum) //This might make KevinZ stop fucking pinging me. - IncreaseSanity(0.5) + IncreaseSanity(src, 0.5) else sanity = max(minimum, sanity - amount) if(sanity < SANITY_UNSTABLE) @@ -229,13 +231,13 @@ else insanity_effect = (MINOR_INSANITY_PEN) -/datum/component/mood/proc/IncreaseSanity(amount, maximum = SANITY_NEUTRAL) +/datum/component/mood/proc/IncreaseSanity(datum/source, amount, maximum = SANITY_NEUTRAL) // Disturbed stops you from getting any more sane - I'm just gonna bung this in here var/mob/living/owner = parent if(HAS_TRAIT(owner, TRAIT_UNSTABLE)) return if(sanity > maximum) - DecreaseSanity(0.5) //Removes some sanity to go back to our current limit. + DecreaseSanity(src, 0.5) //Removes some sanity to go back to our current limit. else sanity = min(maximum, sanity + amount) if(sanity > SANITY_CRAZY) @@ -262,6 +264,8 @@ if(the_event.timeout) addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE) + return the_event + /datum/component/mood/proc/clear_event(datum/source, category) var/datum/mood_event/event = mood_events[category] if(!event) diff --git a/code/datums/ert.dm b/code/datums/ert.dm index 8fc0a915..e18c6701 100644 --- a/code/datums/ert.dm +++ b/code/datums/ert.dm @@ -61,7 +61,7 @@ teamsize = 1 opendoors = FALSE enforce_human = FALSE - roles = /datum/antagonist/greybois + roles = list(/datum/antagonist/greybois) leader_role = /datum/antagonist/greybois/greygod rename_team = "Emergency Assistants" polldesc = "an Emergency Assistant" diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index 69f1a668..a278affa 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -169,3 +169,10 @@ /datum/mood_event/sad_empath/add_effects(mob/sadtarget) description = "[sadtarget.name] seems upset...\n" + +/datum/mood_event/revenant_blight + description = "Just give up, honk...\n" + mood_change = -5 + +/datum/mood_event/revenant_blight/add_effects() + description = "Just give up, [pick("no one will miss you", "there is nothing you can do to help", "even a clown would be more useful than you", "does it even matter in the end?")]...\n" \ No newline at end of file diff --git a/code/datums/ruins/space.dm b/code/datums/ruins/space.dm index 3d4f6ade..b89e9453 100644 --- a/code/datums/ruins/space.dm +++ b/code/datums/ruins/space.dm @@ -316,4 +316,4 @@ id = "advancedlab" suffix = "advancedlab.dmm" name = "Abductor Replication Lab" - description = "Some scientists tried and almost succeeded to recreate abductor tools. Somewhat slower and a bit less modern than their originals, these tools are the best you can get if you aren't an alien." + description = "Some scientists tried and almost succeeded to recreate abductor tools. Somewhat slower and a bit less modern than their originals, these tools are the best you can get if you aren't an alien." \ No newline at end of file diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 743126e4..420545cc 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -426,19 +426,20 @@ else new /obj/effect/temp_visual/bleed(get_turf(owner)) -/mob/living/proc/apply_necropolis_curse(set_curse) +/mob/living/proc/apply_necropolis_curse(set_curse, duration = 10 MINUTES) var/datum/status_effect/necropolis_curse/C = has_status_effect(STATUS_EFFECT_NECROPOLIS_CURSE) if(!set_curse) set_curse = pick(CURSE_BLINDING, CURSE_SPAWNING, CURSE_WASTING, CURSE_GRASPING) if(QDELETED(C)) - apply_status_effect(STATUS_EFFECT_NECROPOLIS_CURSE, set_curse) + apply_status_effect(STATUS_EFFECT_NECROPOLIS_CURSE, set_curse, duration) + else C.apply_curse(set_curse) - C.duration += 3000 //additional curses add 5 minutes + C.duration += duration * 0.5 //additional curses add half their duration /datum/status_effect/necropolis_curse id = "necrocurse" - duration = 6000 //you're cursed for 10 minutes have fun + duration = 10 MINUTES //you're cursed for 10 minutes have fun tick_interval = 50 alert_type = null var/curse_flags = NONE @@ -446,7 +447,9 @@ var/effect_cooldown = 100 var/obj/effect/temp_visual/curse/wasting_effect = new -/datum/status_effect/necropolis_curse/on_creation(mob/living/new_owner, set_curse) +/datum/status_effect/necropolis_curse/on_creation(mob/living/new_owner, set_curse, _duration) + if(_duration) + duration = _duration . = ..() if(.) apply_curse(set_curse) diff --git a/code/game/area/areas/ruins/space.dm b/code/game/area/areas/ruins/space.dm index d5ceb833..74b9e3a1 100644 --- a/code/game/area/areas/ruins/space.dm +++ b/code/game/area/areas/ruins/space.dm @@ -471,4 +471,4 @@ // Abductor Replication Lab /area/ruin/space/has_grav/powered/advancedlab name = "Abductor Replication Lab" - icon_state = "yellow" + icon_state = "yellow" \ No newline at end of file diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm index b9b95eec..e53e3cb4 100644 --- a/code/game/machinery/computer/teleporter.dm +++ b/code/game/machinery/computer/teleporter.dm @@ -124,12 +124,12 @@ L[avoid_assoc_duplicate_keys(A.name, areaindex)] = R for(var/obj/item/implant/tracking/I in GLOB.tracked_implants) - if(!I.imp_in || !isliving(I.loc)) + if(!I.imp_in || !I.allow_teleport || !isliving(I.imp_in)) continue else var/mob/living/M = I.loc if(M.stat == DEAD) - if(M.timeofdeath + 6000 < world.time) + if(M.timeofdeath + I.lifespan_postmortem < world.time) continue if(is_eligible(I)) L[avoid_assoc_duplicate_keys(M.real_name, areaindex)] = I diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 3051a72d..559d880f 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -210,13 +210,13 @@ add_fingerprint(user) /obj/machinery/suit_storage_unit/proc/cook() + var/mob/living/mob_occupant = occupant if(uv_cycles) uv_cycles-- uv = TRUE locked = TRUE update_icon() if(occupant) - var/mob/living/mob_occupant = occupant if(uv_super) mob_occupant.adjustFireLoss(rand(20, 36)) else @@ -245,6 +245,7 @@ visible_message("[src]'s door slides open. The glowing yellow lights dim to a gentle green.") else visible_message("[src]'s door slides open, barraging you with the nauseating smell of charred flesh.") + mob_occupant.radiation = 0 playsound(src, 'sound/machines/airlockclose.ogg', 25, 1) for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRONG) diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index c52a0334..1da89fb3 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -1,3 +1,7 @@ +GLOBAL_VAR_INIT(singularity_counter, 0) + +#define METEOR_DISASTER_MODIFIER 0.5 + //////////////////////////////////////// //Singularity beacon //////////////////////////////////////// @@ -14,38 +18,58 @@ verb_say = "states" var/cooldown = 0 - var/active = 0 + var/active = FALSE + var/meteor_buff = FALSE var/icontype = "beacon" - /obj/machinery/power/singularity_beacon/proc/Activate(mob/user = null) + if(active) + return FALSE if(surplus() < 1500) if(user) to_chat(user, "The connected wire doesn't have enough current.") - return + return FALSE + if(is_station_level(z)) + increment_meteor_waves() for(var/obj/singularity/singulo in GLOB.singularities) if(singulo.z == z) singulo.target = src icon_state = "[icontype]1" - active = 1 + active = TRUE if(user) to_chat(user, "You activate the beacon.") + return TRUE - -/obj/machinery/power/singularity_beacon/proc/Deactivate(mob/user = null) +/obj/machinery/power/singularity_beacon/proc/Deactivate(mob/user) + if(!active) + return FALSE for(var/obj/singularity/singulo in GLOB.singularities) if(singulo.target == src) singulo.target = null icon_state = "[icontype]0" - active = 0 + active = FALSE if(user) to_chat(user, "You deactivate the beacon.") + if(meteor_buff) + decrement_meteor_waves() + return TRUE + +/obj/machinery/power/singularity_beacon/proc/increment_meteor_waves() + meteor_buff = TRUE + GLOB.singularity_counter++ + for(var/datum/round_event_control/meteor_wave/W in SSevents.control) + W.weight += round(initial(W.weight) * METEOR_DISASTER_MODIFIER) + +/obj/machinery/power/singularity_beacon/proc/decrement_meteor_waves() + meteor_buff = FALSE + GLOB.singularity_counter-- + for(var/datum/round_event_control/meteor_wave/W in SSevents.control) + W.weight -= round(initial(W.weight) * METEOR_DISASTER_MODIFIER) /obj/machinery/power/singularity_beacon/attack_ai(mob/user) return - /obj/machinery/power/singularity_beacon/attack_hand(mob/user) . = ..() if(.) @@ -86,6 +110,12 @@ if(!active) return + var/is_on_station = is_station_level(z) + if(meteor_buff && !is_on_station) + decrement_meteor_waves() + else if(!meteor_buff && is_on_station) + increment_meteor_waves() + if(surplus() >= 1500) add_load(1500) if(cooldown <= world.time) @@ -133,3 +163,5 @@ /obj/item/sbeacondrop/clownbomb desc = "A label on it reads: Warning: Activating this device will send a silly explosive to your location." droptype = /obj/machinery/syndicatebomb/badmin/clown + +#undef METEOR_DISASTER_MODIFIER \ No newline at end of file diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 9c3df539..693d32e5 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -89,6 +89,7 @@ buckled_mob.clear_alert("buckled") buckled_mobs -= buckled_mob SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, buckled_mob, force) + SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, src, force) post_unbuckle_mob(.) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index e9fd4a06..779aef86 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -453,7 +453,7 @@ GENE SCANNER if(M.reagents.reagent_list.len) var/list/datum/reagent/reagents = list() for(var/datum/reagent/R in M.reagents.reagent_list) - if(R.invisible) + if(R.chemical_flags & REAGENT_INVISIBLE) continue reagents += R @@ -475,6 +475,20 @@ GENE SCANNER msg += "*---------*" to_chat(user, msg) + if(M.reagents.has_reagent("fermiTox")) + var/datum/reagent/fermiTox = M.reagents.has_reagent("fermiTox") + switch(fermiTox.volume) + if(5 to 10) + msg += "Subject contains a low amount of toxic isomers.\n" + if(10 to 25) + msg += "Subject contains toxic isomers.\n" + if(25 to 50) + msg += "Subject contains a substantial amount of toxic isomers.\n" + if(50 to 95) + msg += "Subject contains a high amount of toxic isomers.\n" + if(95 to INFINITY) + msg += "Subject contains a extremely dangerous amount of toxic isomers.\n" + /obj/item/healthanalyzer/verb/toggle_mode() set name = "Switch Verbosity" set category = "Object" diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index c567a6e7..849e14b4 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -1,5 +1,6 @@ /obj/item/restraints breakouttime = 600 + var/demoralize_criminals = TRUE // checked on carbon/carbon.dm to decide wheter to apply the handcuffed negative moodlet or not. /obj/item/restraints/suicide_act(mob/living/carbon/user) user.visible_message("[user] is strangling [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -220,6 +221,7 @@ name = "fake handcuffs" desc = "Fake handcuffs meant for gag purposes." breakouttime = 10 //Deciseconds = 1s + demoralize_criminals = FALSE /obj/item/restraints/handcuffs/fake/kinky name = "kinky handcuffs" diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index e67bb6bf..65478a84 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -249,7 +249,7 @@ return var/obj/item/nullrod/holy_weapon var/list/holy_weapons_list = typesof(/obj/item/nullrod) + list( - /obj/item/melee/transforming/energy/sword/cx/chaplain + /obj/item/twohanded/dualsaber/hypereutactic/chaplain ) var/list/display_names = list() for(var/V in holy_weapons_list) @@ -710,7 +710,7 @@ righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' w_class = WEIGHT_CLASS_NORMAL attack_verb = list("bashes", "smacks", "whacks") - + /obj/item/nullrod/hypertool icon = 'icons/obj/device.dmi' icon_state = "hypertool" diff --git a/code/game/objects/items/implants/implant_track.dm b/code/game/objects/items/implants/implant_track.dm index 913c577f..4398688c 100644 --- a/code/game/objects/items/implants/implant_track.dm +++ b/code/game/objects/items/implants/implant_track.dm @@ -1,7 +1,19 @@ /obj/item/implant/tracking name = "tracking implant" desc = "Track with this." - activated = 0 + activated = FALSE + var/lifespan_postmortem = 10 MINUTES //for how many deciseconds after user death will the implant work? + var/allow_teleport = TRUE //will people implanted with this act as teleporter beacons? + +/obj/item/implant/tracking/c38 + name = "TRAC implant" + desc = "A smaller tracking implant that supplies power for only a few minutes." + var/lifespan = 5 MINUTES //how many deciseconds does the implant last? + allow_teleport = FALSE + +/obj/item/implant/tracking/c38/Initialize() + . = ..() + QDEL_IN(src, lifespan) /obj/item/implant/tracking/New() ..() @@ -21,7 +33,7 @@ var/dat = {"Implant Specifications:
Name: Tracking Beacon
Life: 10 minutes after death of host
- Important Notes: None
+ Important Notes: Implant also works as a teleporter beacon.

Implant Details:
Function: Continuously transmits low power signal. Useful for tracking.
diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 5a4fc697..dd64c671 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -75,15 +75,14 @@ temp += "Implant Signals:
" for (var/obj/item/implant/tracking/W in GLOB.tracked_implants) - if (!W.imp_in || !isliving(W.loc)) + if (!isliving(W.imp_in)) continue - else - var/mob/living/M = W.loc - if (M.stat == DEAD) - if (M.timeofdeath + 6000 < world.time) - continue + var/mob/living/M = W.imp_in + if (M.stat == DEAD) + if (M.timeofdeath + W.lifespan_postmortem < world.time) + continue - var/turf/tr = get_turf(W) + var/turf/tr = get_turf(M) if (tr.z == sr.z && tr) var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y)) if (direct < 20) @@ -188,8 +187,13 @@ user.show_message("\The [src] is recharging!") return var/atom/T = L[t1] + var/implantcheckmate = FALSE + if(isliving(T)) + var/mob/living/M = T + if(!locate(/obj/item/implant/tracking) in M.implants) //The user was too slow and let the target mob's tracking implant expire or get removed. + implantcheckmate = TRUE var/area/A = get_area(T) - if(A.noteleport) + if(A.noteleport || implantcheckmate) to_chat(user, "\The [src] is malfunctioning.") return current_location = get_turf(user) //Recheck. @@ -233,4 +237,4 @@ itemUser.visible_message("The portal snaps closed taking [user]'s head with it!") else itemUser.visible_message("[user] looks even further depressed as they realize they do not have a head...and suddenly dies of shame!") - return (BRUTELOSS) + return (BRUTELOSS) \ No newline at end of file diff --git a/code/game/objects/items/theft_tools.dm b/code/game/objects/items/theft_tools.dm index 0c74f610..b99be7e9 100644 --- a/code/game/objects/items/theft_tools.dm +++ b/code/game/objects/items/theft_tools.dm @@ -232,7 +232,7 @@ . = ..() if(!sliver) return - if(ismovableatom(O) && O != sliver) + if(proximity && ismovableatom(O) && O != sliver) Consume(O, user) /obj/item/hemostat/supermatter/throw_impact(atom/hit_atom) // no instakill supermatter javelins diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm index 1ab28a33..1aaeb8a4 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -304,6 +304,16 @@ icon = "meow_mix" desc = "No, we don't serve catnip, officer!" +/datum/barsign/goose + name = "The Loose Goose" + icon = "goose" + desc = "Drink till you puke and/or break the laws of reality!" + +/datum/barsign/the_hive + name = "The Hive" + icon = "thehive" + desc = "Comb in for some sweet drinks! Not known for serving any sappy drink." + /datum/barsign/hiddensigns hidden = TRUE diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index aad68b21..645d1e5d 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -22,7 +22,9 @@ if(opened || move_delay || user.stat || user.IsStun() || user.IsKnockdown() || user.IsUnconscious() || !isturf(loc) || !has_gravity(loc)) return move_delay = TRUE - if(step(src, direction)) + var/oldloc = loc + step(src, direction) + if(oldloc != loc) addtimer(CALLBACK(src, .proc/ResetMoveDelay), (use_mob_movespeed ? user.movement_delay() : CONFIG_GET(number/movedelay/walk_delay)) * move_speed_multiplier) else ResetMoveDelay() diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 12827a0a..4a56272a 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -561,7 +561,7 @@ icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" mob_name = "a space pirate" - mob_species = /datum/species/skeleton/pirate + mob_species = /datum/species/skeleton/space outfit = /datum/outfit/pirate/space roundstart = FALSE death = FALSE diff --git a/code/game/sound.dm b/code/game/sound.dm index 5503c610..e7562476 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -182,6 +182,8 @@ soundin = pick('sound/voice/beepsky/god.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/beepsky/secureday.ogg', 'sound/voice/beepsky/radio.ogg', 'sound/voice/beepsky/insult.ogg', 'sound/voice/beepsky/creep.ogg') if("honkbot_e") soundin = pick('sound/items/bikehorn.ogg', 'sound/items/AirHorn2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/items/AirHorn.ogg', 'sound/effects/reee.ogg', 'sound/items/WEEOO1.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/beepsky/creep.ogg','sound/magic/Fireball.ogg' ,'sound/effects/pray.ogg', 'sound/voice/hiss1.ogg','sound/machines/buzz-sigh.ogg', 'sound/machines/ping.ogg', 'sound/weapons/flashbang.ogg', 'sound/weapons/bladeslice.ogg') + if("goose") + soundin = pick('sound/creatures/goose1.ogg', 'sound/creatures/goose2.ogg', 'sound/creatures/goose3.ogg', 'sound/creatures/goose4.ogg') //START OF CIT CHANGES - adds random vore sounds if ("struggle_sound") soundin = pick( 'sound/vore/pred/struggle_01.ogg','sound/vore/pred/struggle_02.ogg','sound/vore/pred/struggle_03.ogg', diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 7110ff44..19e6fc68 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -452,16 +452,21 @@ /turf/AllowDrop() return TRUE -/turf/proc/add_vomit_floor(mob/living/carbon/M, toxvomit = NONE) +/turf/proc/add_vomit_floor(mob/living/M, toxvomit = NONE) + var/obj/effect/decal/cleanable/vomit/V = new /obj/effect/decal/cleanable/vomit(src, M.get_static_viruses()) - // If the vomit combined, apply toxicity and reagents to the old vomit + //if the vomit combined, apply toxicity and reagents to the old vomit if (QDELETED(V)) V = locate() in src // Make toxins and blazaam vomit look different if(toxvomit == VOMIT_PURPLE) V.icon_state = "vomitpurp_[pick(1,4)]" - else if(toxvomit == VOMIT_TOXIC) + else if (toxvomit == VOMIT_TOXIC) V.icon_state = "vomittox_[pick(1,4)]" + if (iscarbon(M)) + var/mob/living/carbon/C = M + if(C.reagents) + clear_reagents_to_vomit_pool(C,V) /proc/clear_reagents_to_vomit_pool(mob/living/carbon/M, obj/effect/decal/cleanable/vomit/V) M.reagents.trans_to(V, M.reagents.total_volume / 10) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index d6727f78..d0ec5920 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -413,9 +413,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) dat += "CLOSED" else dat += "UNKNOWN" - dat += "[GLOB.TAB][TicketHref("Refresh", ref_src)][GLOB.TAB][TicketHref("Re-Title", ref_src, "retitle")]" + dat += "[FOURSPACES][TicketHref("Refresh", ref_src)][FOURSPACES][TicketHref("Re-Title", ref_src, "retitle")]" if(state != AHELP_ACTIVE) - dat += "[GLOB.TAB][TicketHref("Reopen", ref_src, "reopen")]" + dat += "[FOURSPACES][TicketHref("Reopen", ref_src, "reopen")]" dat += "

Opened at: [GAMETIMESTAMP("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)" if(closed_at) dat += "
Closed at: [GAMETIMESTAMP("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)" @@ -423,7 +423,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) if(initiator) dat += "Actions: [FullMonty(ref_src)]
" else - dat += "DISCONNECTED[GLOB.TAB][ClosureLinks(ref_src)]
" + dat += "DISCONNECTED[FOURSPACES][ClosureLinks(ref_src)]
" dat += "
Log:

" for(var/I in _interactions) dat += "[I]
" diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm index a22933be..3f1c437f 100644 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ b/code/modules/antagonists/_common/antag_spawner.dm @@ -56,7 +56,7 @@ if(used) to_chat(H, "You already used this contract!") return - var/list/candidates = pollCandidatesForMob("Do you want to play as a wizard's [href_list["school"]] apprentice?", ROLE_WIZARD, null, ROLE_WIZARD, 150, src) + var/list/candidates = pollCandidatesForMob("Do you want to play as a wizard's [href_list["school"]] apprentice?", ROLE_WIZARD, null, ROLE_WIZARD, 150, src, ignore_category = POLL_IGNORE_WIZARD) if(LAZYLEN(candidates)) if(QDELETED(src)) return @@ -235,7 +235,7 @@ return if(used) return - var/list/candidates = pollCandidatesForMob("Do you want to play as a [initial(demon_type.name)]?", ROLE_ALIEN, null, ROLE_ALIEN, 50, src) + var/list/candidates = pollCandidatesForMob("Do you want to play as a [initial(demon_type.name)]?", ROLE_ALIEN, null, ROLE_ALIEN, 50, src, ignore_category = POLL_IGNORE_DEMON) if(LAZYLEN(candidates)) if(used || QDELETED(src)) return diff --git a/code/modules/antagonists/abductor/equipment/abduction_surgery.dm b/code/modules/antagonists/abductor/equipment/abduction_surgery.dm index 819dbafd..98164de0 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_surgery.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_surgery.dm @@ -1,5 +1,5 @@ /datum/surgery/organ_extraction - name = "experimental dissection" + name = "experimental organ replacement" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, /datum/surgery_step/extract_organ, /datum/surgery_step/gland_insert) possible_locs = list(BODY_ZONE_CHEST) ignore_clothes = 1 diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index 1dbae4ca..a1bfc067 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -644,6 +644,11 @@ desc = "A spell that will absorb blood from anything you touch.
Touching cultists and constructs can heal them.
Clicking the hand will potentially let you focus the spell into something stronger." color = "#7D1717" +/obj/item/melee/blood_magic/manipulator/examine(mob/user) + . = ..() + if(iscultist(user)) + to_chat(user, "The [name] currently has [uses] blood charges left.") + /obj/item/melee/blood_magic/manipulator/afterattack(atom/target, mob/living/carbon/human/user, proximity) if(proximity) if(ishuman(target)) @@ -678,9 +683,9 @@ if(ratio>1) ratio = 1 uses -= round(overall_damage) - H.visible_message("[H] is fully healed by [H==user ? "[H.p_their()]":"[H]'s"]'s blood magic!") + H.visible_message("[H] is fully healed by [H==user ? "[H.p_their()]":"[user]'s"] blood magic!") else - H.visible_message("[H] is partially healed by [H==user ? "[H.p_their()]":"[H]'s"] blood magic.") + H.visible_message("[H] is partially healed by [H==user ? "[H.p_their()]":"[user]'s"] blood magic.") uses = 0 ratio *= -1 H.adjustOxyLoss((overall_damage*ratio) * (H.getOxyLoss() / overall_damage), 0) @@ -762,7 +767,7 @@ switch(choice) if("Blood Spear (150)") if(uses < 150) - to_chat(user, "You need 200 charges to perform this rite.") + to_chat(user, "You need 150 charges to perform this rite.") else uses -= 150 var/turf/T = get_turf(user) @@ -778,7 +783,7 @@ "A [rite.name] materializes at your feet.") if("Blood Bolt Barrage (300)") if(uses < 300) - to_chat(user, "You need 400 charges to perform this rite.") + to_chat(user, "You need 300 charges to perform this rite.") else var/obj/rite = new /obj/item/gun/ballistic/shotgun/boltaction/enchanted/arcane_barrage/blood() uses -= 300 @@ -790,7 +795,7 @@ qdel(rite) if("Blood Beam (500)") if(uses < 500) - to_chat(user, "You need 600 charges to perform this rite.") + to_chat(user, "You need 500 charges to perform this rite.") else var/obj/rite = new /obj/item/blood_beam() uses -= 500 diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 25e3663c..10759afc 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -666,6 +666,7 @@ righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi' slot_flags = 0 force = 17 + force_unwielded = 17 force_wielded = 24 throwforce = 40 throw_speed = 2 diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 541f8f9e..927d4c73 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -185,9 +185,6 @@ structure_check() searches for nearby cultist structures required for the invoca color = RUNE_COLOR_OFFER req_cultists = 1 rune_in_use = FALSE - var/mob/living/currentconversionman - var/conversiontimeout - var/conversionresult /obj/effect/rune/convert/do_invoke_glow() return @@ -236,34 +233,14 @@ structure_check() searches for nearby cultist structures required for the invoca /obj/effect/rune/convert/proc/do_convert(mob/living/convertee, list/invokers) if(invokers.len < 2) for(var/M in invokers) - to_chat(M, "You need at least two invokers to convert [convertee]!") + to_chat(M, "You need at least two invokers to convert [convertee]!") log_game("Offer rune failed - tried conversion with one invoker") return 0 - if(convertee.anti_magic_check(TRUE, TRUE)) + if(convertee.anti_magic_check(TRUE, TRUE, FALSE, 0)) //Not chargecost because it can be spammed for(var/M in invokers) to_chat(M, "Something is shielding [convertee]'s mind!") log_game("Offer rune failed - convertee had anti-magic") return 0 - to_chat(convertee, "The world goes red. All at once you are aware of an evil, eldritch truth taking roots into your mind.\n\ - Click here to become a follower of Nar'sie, or suffer a fate worse than death.") - INVOKE_ASYNC(src, .proc/optinalert, convertee) - currentconversionman = convertee - conversiontimeout = world.time + (14 SECONDS) - convertee.Stun(140) - ADD_TRAIT(convertee, TRAIT_MUTE, "conversionrune") - flash_color(convertee, list("#960000", "#960000", "#960000", rgb(0,0,0)), 50) - conversionresult = FALSE - while(world.time < conversiontimeout && convertee && !conversionresult) - stoplag(1) - currentconversionman = null - if(!convertee) - return FALSE - REMOVE_TRAIT(convertee, TRAIT_MUTE, "conversionrune") - if(get_turf(convertee) != get_turf(src)) - return FALSE - if(!conversionresult) - do_sacrifice(convertee, invokers, TRUE) - return FALSE var/brutedamage = convertee.getBruteLoss() var/burndamage = convertee.getFireLoss() if(brutedamage || burndamage) @@ -275,6 +252,8 @@ structure_check() searches for nearby cultist structures required for the invoca SSticker.mode.add_cultist(convertee.mind, 1) new /obj/item/melee/cultblade/dagger(get_turf(src)) convertee.mind.special_role = ROLE_CULTIST + to_chat(convertee, "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \ + and something evil takes root.") to_chat(convertee, "Assist your new compatriots in their dark dealings. Your goal is theirs, and theirs is yours. You serve the Geometer above all else. Bring it back.\ ") if(ishuman(convertee)) @@ -284,18 +263,7 @@ structure_check() searches for nearby cultist structures required for the invoca H.cultslurring = 0 return 1 -/obj/effect/rune/convert/proc/optinalert(mob/living/convertee) - var/alert = alert(convertee, "Will you embrace the Geometer of Blood or perish in futile resistance?", "Choose your own fate", "Join the Blood Cult", "Suffer a horrible demise") - if(alert == "Join the Blood Cult") - signmeup(convertee) - -/obj/effect/rune/convert/proc/signmeup(mob/living/convertee) - if(currentconversionman == usr) - conversionresult = TRUE - else - to_chat(usr, "Your fate has already been set in stone.") - -/obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers, force_a_sac) +/obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers) var/mob/living/first_invoker = invokers[1] if(!first_invoker) return FALSE @@ -305,7 +273,7 @@ structure_check() searches for nearby cultist structures required for the invoca var/big_sac = FALSE - if(!force_a_sac && (((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || C.cult_team.is_sacrifice_target(sacrificial.mind)) && invokers.len < 3) + if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || C.cult_team.is_sacrifice_target(sacrificial.mind)) && invokers.len < 3) for(var/M in invokers) to_chat(M, "[sacrificial] is too greatly linked to the world! You need three acolytes!") log_game("Offer rune failed - not enough acolytes and target is living or sac target") @@ -345,10 +313,6 @@ structure_check() searches for nearby cultist structures required for the invoca sacrificial.gib() return TRUE -/obj/effect/rune/convert/Topic(href, href_list) - if(href_list["signmeup"]) - signmeup(usr) - /obj/effect/rune/empower cultist_name = "Empower" cultist_desc = "allows cultists to prepare greater amounts of blood magic at far less of a cost." diff --git a/code/modules/antagonists/devil/devil.dm b/code/modules/antagonists/devil/devil.dm index 3f2bd003..dc649025 100644 --- a/code/modules/antagonists/devil/devil.dm +++ b/code/modules/antagonists/devil/devil.dm @@ -539,10 +539,10 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", var/list/parts = list() parts += "The devil's true name is: [truename]" parts += "The devil's bans were:" - parts += "[GLOB.TAB][GLOB.lawlorify[LORE][ban]]" - parts += "[GLOB.TAB][GLOB.lawlorify[LORE][bane]]" - parts += "[GLOB.TAB][GLOB.lawlorify[LORE][obligation]]" - parts += "[GLOB.TAB][GLOB.lawlorify[LORE][banish]]" + parts += "[FOURSPACES][GLOB.lawlorify[LORE][ban]]" + parts += "[FOURSPACES][GLOB.lawlorify[LORE][bane]]" + parts += "[FOURSPACES][GLOB.lawlorify[LORE][obligation]]" + parts += "[FOURSPACES][GLOB.lawlorify[LORE][banish]]" return parts.Join("
") /datum/antagonist/devil/roundend_report() diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm index edae8a42..daa38767 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm @@ -1,7 +1,8 @@ #define CHALLENGE_TELECRYSTALS 280 #define PLAYER_SCALING 1.5 #define CHALLENGE_TIME_LIMIT 3000 -#define CHALLENGE_MIN_PLAYERS 50 +#define CHALLENGE_PLAYERS_TARGET 50 //target players population. anything below is a malus to the challenge tc bonus. +#define TELECRYSTALS_MALUS_SCALING 1 //the higher the value, the bigger the malus. #define CHALLENGE_SHUTTLE_DELAY 15000 // 25 minutes, so the ops have at least 5 minutes before the shuttle is callable. GLOBAL_LIST_EMPTY(jam_on_wardec) @@ -62,12 +63,15 @@ GLOBAL_VAR_INIT(war_declared, FALSE) for(var/obj/machinery/computer/camera_advanced/shuttle_docker/D in GLOB.jam_on_wardec) D.jammed = TRUE - + GLOB.war_declared = TRUE var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop) var/actual_players = GLOB.joined_player_list.len - nukeops.len + var/tc_malus = 0 + if(actual_players < CHALLENGE_PLAYERS_TARGET) + tc_malus = FLOOR((CHALLENGE_TELECRYSTALS - actual_players * INVERSE(CHALLENGE_PLAYERS_TARGET)) * TELECRYSTALS_MALUS_SCALING, 1) - new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS + CEILING(PLAYER_SCALING * actual_players, 1)) + new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS - tc_malus + CEILING(PLAYER_SCALING * actual_players, 1)) CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY)) SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1) @@ -79,11 +83,6 @@ GLOBAL_VAR_INIT(war_declared, FALSE) to_chat(user, "You are already in the process of declaring war! Make your mind up.") return FALSE - var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop) - var/actual_players = GLOB.joined_player_list.len - nukeops.len - if(actual_players < CHALLENGE_MIN_PLAYERS) - to_chat(user, "The enemy crew is too small to be worth declaring war on.") - return FALSE if(!user.onSyndieBase()) to_chat(user, "You have to be at your base to use this.") return FALSE @@ -102,5 +101,6 @@ GLOBAL_VAR_INIT(war_declared, FALSE) #undef CHALLENGE_TELECRYSTALS #undef CHALLENGE_TIME_LIMIT -#undef CHALLENGE_MIN_PLAYERS +#undef CHALLENGE_PLAYERS_TARGET +#undef TELECRYSTALS_MALUS_SCALING #undef CHALLENGE_SHUTTLE_DELAY diff --git a/code/modules/antagonists/revenant/revenant_blight.dm b/code/modules/antagonists/revenant/revenant_blight.dm index 7037ecae..89d8de28 100644 --- a/code/modules/antagonists/revenant/revenant_blight.dm +++ b/code/modules/antagonists/revenant/revenant_blight.dm @@ -11,9 +11,9 @@ viable_mobtypes = list(/mob/living/carbon/human) disease_flags = CURABLE permeability_mod = 1 - severity = DISEASE_SEVERITY_HARMFUL - var/stagedamage = 0 //Highest stage reached. + severity = DISEASE_SEVERITY_DANGEROUS var/finalstage = 0 //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects. + var/datum/mood_event/revenant_blight/depression /datum/disease/revblight/cure() if(affected_mob) @@ -21,12 +21,13 @@ if(affected_mob.dna && affected_mob.dna.species) affected_mob.dna.species.handle_mutant_bodyparts(affected_mob) affected_mob.dna.species.handle_hair(affected_mob) - to_chat(affected_mob, "You feel better.") + SEND_SIGNAL(affected_mob, COMSIG_CLEAR_MOOD_EVENT, "rev_blight") ..() /datum/disease/revblight/stage_act() if(!finalstage) - if(affected_mob.lying && prob(stage*6)) + if(affected_mob.lying && prob(stage*4)) + to_chat(affected_mob, "You feel better.") cure() return if(prob(stage*3)) @@ -34,10 +35,6 @@ affected_mob.confused += 8 affected_mob.adjustStaminaLoss(8) new /obj/effect/temp_visual/revenant(affected_mob.loc) - if(stagedamage < stage) - stagedamage++ - affected_mob.adjustToxLoss(stage*2) //should, normally, do about 30 toxin damage. - new /obj/effect/temp_visual/revenant(affected_mob.loc) if(prob(45)) affected_mob.adjustStaminaLoss(stage) ..() //So we don't increase a stage before applying the stage damage. @@ -46,9 +43,13 @@ if(prob(5)) affected_mob.emote("pale") if(3) + if(!depression) + depression = SEND_SIGNAL(affected_mob, COMSIG_ADD_MOOD_EVENT, "rev_blight", /datum/mood_event/revenant_blight) + SEND_SIGNAL(affected_mob, COMSIG_DECREASE_SANITY, 0.12, SANITY_CRAZY) if(prob(10)) affected_mob.emote(pick("pale","shiver")) if(4) + SEND_SIGNAL(affected_mob, COMSIG_DECREASE_SANITY, 0.18, SANITY_CRAZY) if(prob(15)) affected_mob.emote(pick("pale","shiver","cries")) if(5) @@ -56,12 +57,18 @@ finalstage = TRUE to_chat(affected_mob, "You feel like [pick("nothing's worth it anymore", "nobody ever needed your help", "nothing you did mattered", "everything you tried to do was worthless")].") affected_mob.adjustStaminaLoss(45) - new /obj/effect/temp_visual/revenant(affected_mob.loc) - if(affected_mob.dna && affected_mob.dna.species) + if(affected_mob.dna?.species) affected_mob.dna.species.handle_mutant_bodyparts(affected_mob,"#1d2953") affected_mob.dna.species.handle_hair(affected_mob,"#1d2953") affected_mob.visible_message("[affected_mob] looks terrifyingly gaunt...", "You suddenly feel like your skin is wrong...") affected_mob.add_atom_colour("#1d2953", TEMPORARY_COLOUR_PRIORITY) - addtimer(CALLBACK(src, .proc/cure), 100) - else - return + new /obj/effect/temp_visual/revenant(affected_mob.loc) + addtimer(CALLBACK(src, .proc/curses), 150) + +/datum/disease/revblight/proc/curses() + if(QDELETED(affected_mob)) + return + affected_mob.playsound_local(affected_mob, 'sound/effects/curse5.ogg', 40, 1, -1) + to_chat(affected_mob, "You sense the terrific curse of a vengeful ghost befall upon you...") + affected_mob.apply_necropolis_curse(null, 7 MINUTES) //Once the blight has done its course without being cured beforehand, it will cast a necrocurse to compensate how underpowered it's. + cure() diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm index 562d6f25..7207adc4 100644 --- a/code/modules/antagonists/wizard/equipment/artefact.dm +++ b/code/modules/antagonists/wizard/equipment/artefact.dm @@ -198,7 +198,7 @@ to_chat(user, "This artifact can only affect three undead at a time!") return - M.set_species(/datum/species/skeleton, icon_update=0) + M.set_species(/datum/species/skeleton/space, icon_update=0) M.revive(full_heal = 1, admin_revive = 1) spooky_scaries |= M to_chat(M, "You have been revived by [user.real_name]!") diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 0b83304f..3ddcdf80 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -571,6 +571,8 @@ GLOBAL_LIST_EMPTY(asset_datums) "fontawesome-webfont.woff" = 'tgui/assets/fonts/fontawesome-webfont.woff', "font-awesome.css" = 'code/modules/goonchat/browserassets/css/font-awesome.css', "browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css', + "browserOutput_dark.css" = 'code/modules/goonchat/browserassets/css/browserOutput_dark.css', + "browserOutput_light.css" = 'code/modules/goonchat/browserassets/css/browserOutput_light.css' ) /datum/asset/spritesheet/goonchat diff --git a/code/modules/client/darkmode.dm b/code/modules/client/darkmode.dm index 8d586100..f806e5c9 100644 --- a/code/modules/client/darkmode.dm +++ b/code/modules/client/darkmode.dm @@ -16,7 +16,7 @@ Thanks to spacemaniac and mcdonald for help with the JS side of this. //Main windows winset(src, "infowindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]") winset(src, "info", "background-color = [COLOR_WHITEMODE_BACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]") - winset(src, "browseroutput", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];text-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "browseroutput", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]") winset(src, "outputwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]") winset(src, "mainwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND]") winset(src, "split", "background-color = [COLOR_WHITEMODE_BACKGROUND]") @@ -30,7 +30,9 @@ Thanks to spacemaniac and mcdonald for help with the JS side of this. //Status and verb tabs winset(src, "output", "background-color = [COLOR_WHITEMODE_BACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]") winset(src, "statwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]") - winset(src, "stat", "background-color = [COLOR_WHITEMODE_BACKGROUND];tab-background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT];tab-text-color = [COLOR_WHITEMODE_TEXT];prefix-color = [COLOR_WHITEMODE_TEXT];suffix-color = [COLOR_WHITEMODE_TEXT]") + winset(src, "stat", "background-color = [COLOR_WHITEMODE_BACKGROUND];tab-background-color = [COLOR_WHITEMODE_DARKBACKGROUND];\ + text-color = [COLOR_WHITEMODE_TEXT];tab-text-color = [COLOR_WHITEMODE_TEXT];\ + prefix-color = [COLOR_WHITEMODE_TEXT];suffix-color = [COLOR_WHITEMODE_TEXT]") //Etc. winset(src, "say", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]") winset(src, "asset_cache_browser", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]") @@ -54,24 +56,10 @@ Thanks to spacemaniac and mcdonald for help with the JS side of this. //Status and verb tabs winset(src, "output", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]") winset(src, "statwindow", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];text-color = [COLOR_DARKMODE_TEXT]") - winset(src, "stat", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];tab-background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT];tab-text-color = [COLOR_DARKMODE_TEXT];prefix-color = [COLOR_DARKMODE_TEXT];suffix-color = [COLOR_DARKMODE_TEXT]") + winset(src, "stat", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];tab-background-color = [COLOR_DARKMODE_BACKGROUND];\ + text-color = [COLOR_DARKMODE_TEXT];tab-text-color = [COLOR_DARKMODE_TEXT];\ + prefix-color = [COLOR_DARKMODE_TEXT];suffix-color = [COLOR_DARKMODE_TEXT]") //Etc. winset(src, "say", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]") winset(src, "asset_cache_browser", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]") - winset(src, "tooltip", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]") - - -/datum/asset/simple/goonchat - verify = FALSE - assets = list( - "json2.min.js" = 'code/modules/goonchat/browserassets/js/json2.min.js', - "errorHandler.js" = 'code/modules/goonchat/browserassets/js/errorHandler.js', - "browserOutput.js" = 'code/modules/goonchat/browserassets/js/browserOutput.js', - "fontawesome-webfont.eot" = 'tgui/assets/fonts/fontawesome-webfont.eot', - "fontawesome-webfont.svg" = 'tgui/assets/fonts/fontawesome-webfont.svg', - "fontawesome-webfont.ttf" = 'tgui/assets/fonts/fontawesome-webfont.ttf', - "fontawesome-webfont.woff" = 'tgui/assets/fonts/fontawesome-webfont.woff', - "font-awesome.css" = 'code/modules/goonchat/browserassets/css/font-awesome.css', - "browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css', - "browserOutput_white.css" = 'code/modules/goonchat/browserassets/css/browserOutput_white.css', - ) \ No newline at end of file + winset(src, "tooltip", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]") \ No newline at end of file diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 48673f47..fbc30413 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -777,6 +777,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Testicles Color:
" dat += "    Change
" dat += "Testicles showing:[features["balls_shape"]]" + dat += "Produces:[features["balls_fluid"]]" dat += APPEARANCE_CATEGORY_COLUMN dat += "

Vagina

" dat += "[features["has_vag"] == TRUE ? "Yes" : "No"]" @@ -807,7 +808,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Lactates:[features["breasts_producing"] == TRUE ? "Yes" : "No"]" if(features["breasts_producing"] == TRUE) dat += "Produces:[features["breasts_fluid"]]" - + dat += "" dat += "" dat += "" @@ -1996,6 +1997,12 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(new_shape) features["balls_shape"] = new_shape + if("balls_fluid") + var/new_shape + new_shape = input(user, "Balls Fluid", "Character Preference") as null|anything in GLOB.genital_fluids_list + if(new_shape) + features["balls_fluid"] = new_shape + if("egg_size") var/new_size var/list/egg_sizes = list(1,2,3) @@ -2023,7 +2030,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) new_shape = input(user, "Breast Shape", "Character Preference") as null|anything in GLOB.breasts_shapes_list if(new_shape) features["breasts_shape"] = new_shape - + if("breasts_fluid") var/new_shape new_shape = input(user, "Breast Fluid", "Character Preference") as null|anything in GLOB.genital_fluids_list diff --git a/code/modules/client/verbs/looc.dm b/code/modules/client/verbs/looc.dm index c365af2e..84d1c3af 100644 --- a/code/modules/client/verbs/looc.dm +++ b/code/modules/client/verbs/looc.dm @@ -1,3 +1,4 @@ + GLOBAL_VAR_INIT(LOOC_COLOR, null)//If this is null, use the CSS for OOC. Otherwise, use a custom colour. GLOBAL_VAR_INIT(normal_looc_colour, "#6699CC") diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm index 743f2edf..662053f8 100644 --- a/code/modules/events/meteor_wave.dm +++ b/code/modules/events/meteor_wave.dm @@ -1,5 +1,8 @@ // Normal strength +#define SINGULO_BEACON_DISTURBANCE 0.2 //singularity beacon also improve the odds of meteor waves and speed them up a little. +#define SINGULO_BEACON_MAX_DISTURBANCE 0.6 //maximum cap due to how meteor waves can be potentially round ending. + /datum/round_event_control/meteor_wave name = "Meteor Wave: Normal" typepath = /datum/round_event/meteor_wave @@ -18,6 +21,8 @@ /datum/round_event/meteor_wave/setup() announceWhen = 1 startWhen = rand(300, 600) //Yeah for SOME REASON this is measured in seconds and not deciseconds??? + if(GLOB.singularity_counter) + startWhen *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE) endWhen = startWhen + 60 @@ -52,7 +57,7 @@ kill() /datum/round_event/meteor_wave/announce(fake) - priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round(startWhen/60)] minutes.", "Meteor Alert", 'sound/ai/meteors.ogg') + priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round(startWhen/60)] minutes.[GLOB.singularity_counter ? " Warning: Anomalous gravity pulse detected, Syndicate technology interference likely." : ""]", "Meteor Alert", 'sound/ai/meteors.ogg') /datum/round_event/meteor_wave/tick() if(ISMULTIPLE(activeFor, 3)) @@ -79,3 +84,6 @@ /datum/round_event/meteor_wave/catastrophic wave_name = "catastrophic" + +#undef SINGULO_BEACON_DISTURBANCE +#undef SINGULO_BEACON_MAX_DISTURBANCE \ No newline at end of file diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 88f72d27..d035db82 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -771,7 +771,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( ..() var/turf/source = random_far_turf() if(!sound_type) - sound_type = pick("airlock","airlock pry","console","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack") + sound_type = pick("airlock","airlock pry","console","flash","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack") feedback_details += "Type: [sound_type]" //Strange audio switch(sound_type) @@ -788,6 +788,8 @@ GLOBAL_LIST_INIT(hallucination_list, list( target.playsound_local(source,'sound/effects/explosion1.ogg', 50, 1) else target.playsound_local(source, 'sound/effects/explosion2.ogg', 50, 1) + if("flash") + target.playsound_local(source, 'sound/weapons/flash.ogg', 50, 1) if("far explosion") target.playsound_local(source, 'sound/effects/explosionfar.ogg', 50, 1) if("glass") diff --git a/code/modules/food_and_drinks/recipes/drinks_recipes.dm b/code/modules/food_and_drinks/recipes/drinks_recipes.dm index ff9e9102..e66870dc 100644 --- a/code/modules/food_and_drinks/recipes/drinks_recipes.dm +++ b/code/modules/food_and_drinks/recipes/drinks_recipes.dm @@ -410,7 +410,9 @@ FermiChem = TRUE//If the chemical uses the Fermichem reaction mechanics FermiExplode = FALSE //If the chemical explodes in a special way PurityMin = 0 //The minimum purity something has to be above, otherwise it explodes. + clear_conversion = REACTION_CLEAR_INVERSE +/* /datum/chemical_reaction/neurotoxin/FermiFinish(datum/reagents/holder, var/atom/my_atom) var/datum/reagent/consumable/ethanol/neurotoxin/Nt = locate(/datum/reagent/consumable/ethanol/neurotoxin) in my_atom.reagents.reagent_list if(Nt) @@ -418,6 +420,7 @@ if(Nt.purity < 0.5) holder.remove_reagent(src.id, cached_volume) holder.add_reagent("neurosmash", cached_volume) +*/ /datum/chemical_reaction/snowwhite name = "Snow White" diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm index 7fe6b41b..ac3886b8 100644 --- a/code/modules/goonchat/browserOutput.dm +++ b/code/modules/goonchat/browserOutput.dm @@ -5,17 +5,9 @@ For the main html chat area //Precaching a bunch of shit GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of icons for the browser output -//Should match the value set in the browser js -#define MAX_COOKIE_LENGTH 5 - - //On client, created on login /datum/chatOutput var/client/owner //client ref - // How many times client data has been checked - var/total_checks = 0 - // When to next clear the client data checks counter - var/next_time_to_clear = 0 var/loaded = FALSE // Has the client loaded the browser output area? var/list/messageQueue //If they haven't loaded chat, this is where messages will go until they do var/cookieSent = FALSE // Has the client sent a cookie for analysis @@ -90,11 +82,13 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico if("setMusicVolume") data = setMusicVolume(arglist(params)) - if("swaptodarkmode") - swaptodarkmode() + if("colorPresetPost") //User just swapped color presets in their goonchat preferences. Do we do anything else? + switch(href_list["preset"]) + if("light") + owner.force_white_theme() + if("dark" || "normal") + owner.force_dark_theme() - if("swaptolightmode") - swaptolightmode() if(data) ehjax_send(data = data) @@ -156,19 +150,6 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico //Called by client, sent data to investigate (cookie history so far) /datum/chatOutput/proc/analyzeClientData(cookie = "") - //Spam check - if(world.time > next_time_to_clear) - next_time_to_clear = world.time + (3 SECONDS) - total_checks = 0 - - total_checks += 1 - - if(total_checks > SPAM_TRIGGER_AUTOMUTE) - message_admins("[key_name(owner)] kicked for goonchat topic spam") - qdel(owner) - return - - if(!cookie) return @@ -177,24 +158,13 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico if (connData && islist(connData) && connData.len > 0 && connData["connData"]) connectionHistory = connData["connData"] //lol fuck var/list/found = new() - - if(connectionHistory.len > MAX_COOKIE_LENGTH) - message_admins("[key_name(src.owner)] was kicked for an invalid ban cookie)") - qdel(owner) - return - - for(var/i in connectionHistory.len to 1 step -1) - if(QDELETED(owner)) - //he got cleaned up before we were done - return var/list/row = src.connectionHistory[i] if (!row || row.len < 3 || (!row["ckey"] || !row["compid"] || !row["ip"])) //Passed malformed history object return if (world.IsBanned(row["ckey"], row["ip"], row["compid"], real_bans_only=TRUE)) found = row break - CHECK_TICK //Uh oh this fucker has a history of playing on a banned account!! if (found.len > 0) @@ -213,8 +183,8 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico log_world("\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client: [(src.owner.key ? src.owner.key : src.owner)] triggered JS error: [error]") //Global chat procs -/proc/to_chat(target, message, handle_whitespace=TRUE) - if(!target) +/proc/to_chat_immediate(target, message, handle_whitespace=TRUE) + if(!target || !message) return //Ok so I did my best but I accept that some calls to this will be for shit like sound and images @@ -236,7 +206,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico message = replacetext(message, "\proper", "") if(handle_whitespace) message = replacetext(message, "\n", "
") - message = replacetext(message, "\t", "[GLOB.TAB][GLOB.TAB]") + message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]") if(islist(target)) // Do the double-encoding outside the loop to save nanoseconds @@ -279,12 +249,8 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico // url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript. C << output(url_encode(url_encode(message)), "browseroutput:output") - -/datum/chatOutput/proc/swaptolightmode() //Dark mode light mode stuff. Yell at KMC if this breaks! (See darkmode.dm for documentation) - owner.force_white_theme() - -/datum/chatOutput/proc/swaptodarkmode() - owner.force_dark_theme() - - -#undef MAX_COOKIE_LENGTH +/proc/to_chat(target, message, handle_whitespace = TRUE) + if(Master.current_runlevel == RUNLEVEL_INIT || !SSchat?.initialized) + to_chat_immediate(target, message, handle_whitespace) + return + SSchat.queue(target, message, handle_whitespace) \ No newline at end of file diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index d10b3359..cca54377 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -7,20 +7,16 @@ html, body { padding: 0; margin: 0; height: 100%; - color: #f0f0f0; + color: #000000; } body { - background: #171717; + background: #E0E0E0; /*CIT CHANGE - darkens chatbox a lil*/ font-family: Verdana, sans-serif; font-size: 9pt; - font-color: #f0f0f0; line-height: 1.2; overflow-x: hidden; overflow-y: scroll; - word-wrap: break-word; - scrollbar-face-color:#1A1A1A; - scrollbar-track-color:#171717; - scrollbar-highlight-color:#171717; + word-wrap: break-word; } em { @@ -60,9 +56,9 @@ img.icon { border-radius: 10px; } -a {color: #397ea5;} -a.visited {color: #7c00e6;} -a:visited {color: #7c00e6;} +a {color: #0000ff;} +a.visited {color: #ff00ff;} +a:visited {color: #ff00ff;} a.popt {text-decoration: none;} /***************************************** @@ -93,21 +89,21 @@ a.popt {text-decoration: none;} bottom: 0; right: 0; padding: 8px; - background: #202020; + background: #d0d0d0; text-decoration: none; font-variant: small-caps; font-size: 1.1em; font-weight: bold; - color: #a4bad6; + color: #333; } -#newMessages:hover {background: #171717;} +#newMessages:hover {background: #ccc;} #newMessages i {vertical-align: middle; padding-left: 3px;} #ping { position: fixed; top: 0; right: 115px; width: 45px; - background: #202020; + background: #d0d0d0; height: 30px; padding: 8px 0 2px 0; } @@ -124,19 +120,19 @@ a.popt {text-decoration: none;} right: 0; } #userBar .subCell { - background: #202020; + background: #d0d0d0; height: 30px; padding: 5px 0; display: block; - color: #a4bad6; + color: #333; text-decoration: none; line-height: 28px; - border-top: 1px solid #171717; + border-top: 1px solid #b4b4b4; } -#userBar .subCell:hover {background: #202020;} +#userBar .subCell:hover {background: #ccc;} #userBar .toggle { width: 40px; - background: #202020; + background: #ccc; border-top: 0; float: right; text-align: center; @@ -172,7 +168,7 @@ a.popt {text-decoration: none;} position: fixed; top: 50%; left: 50%; - background: #ddd; + background: #d0d0d0; } .popup .close { position: absolute; @@ -189,7 +185,7 @@ a.popt {text-decoration: none;} .popup .close:hover {background: #999;} .popup .head { background: #999; - color: #ddd; + color: #d0d0d0; padding: 0 10px; height: 30px; line-height: 30px; @@ -200,7 +196,7 @@ a.popt {text-decoration: none;} } .popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;} .popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;} -.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;} +.popup input[type=submit] {padding: 5px 10px; background: #999; color: #d0d0d0; text-transform: uppercase; font-size: 0.9em; font-weight: bold;} .popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;} .changeFont {padding: 10px;} @@ -214,7 +210,7 @@ a.popt {text-decoration: none;} /* ADMIN CONTEXT MENU */ .contextMenu { - background-color: #ddd; + background-color: #d0d0d0; position: fixed; margin: 2px; width: 150px; @@ -246,9 +242,9 @@ a.popt {text-decoration: none;} ******************************************/ /* MOTD */ -.motd {color: #a4bad6; font-family: Verdana, sans-serif;} -.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #a4bad6; text-decoration: underline;} -.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #a4bad6;} +.motd {color: #638500; font-family: Verdana, sans-serif;} +.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #638500; text-decoration: underline;} +.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;} /* ADD HERE FOR BOLD */ .bold, .name, .prefix, .ooc, .looc, .adminooc, .admin, .medal, .yell {font-weight: bold;} @@ -259,91 +255,91 @@ a.popt {text-decoration: none;} /* OUTPUT COLORS */ .highlight {background: yellow;} -h1, h2, h3, h4, h5, h6 {color: #a4bad6;font-family: Georgia, Verdana, sans-serif;} -h1.alert, h2.alert {color: #a4bad6;} +h1, h2, h3, h4, h5, h6 {color: #0000ff;font-family: Georgia, Verdana, sans-serif;} +h1.alert, h2.alert {color: #000000;} em {font-style: normal; font-weight: bold;} -.ooc {color: #cca300; font-weight: bold;} -.looc {color: #d8b555; font-weight: bold;} -.antagooc {color: #ce254f; font-weight: bold;} +.ooc {color: #002eb8; font-weight: bold;} +.looc {color: #6699CC; font-weight: bold;} +.antagooc {color: #b8002e; font-weight: bold;} .adminobserverooc {color: #0099cc; font-weight: bold;} -.adminooc {color: #3d5bc3; font-weight: bold;} +.adminooc {color: #700038; font-weight: bold;} -.adminsay {color: #ff4500; font-weight: bold;} -.admin {color: #5975da; font-weight: bold;} +.adminsay {color: #FF4500} +.admin {color: #386aff; font-weight: bold;} .name { font-weight: bold;} .say {} -.deadsay {color: #e2c1ff;} +.deadsay {color: #5c00e6;} .binarysay {color: #20c20e; background-color: #000000; display: block;} .binarysay a {color: #00ff00;} .binarysay a:active, .binarysay a:visited {color: #88ff88;} -.radio {color: #1ecc43;} -.sciradio {color: #c68cfa;} -.comradio {color: #5177ff;} -.secradio {color: #dd3535;} -.medradio {color: #57b8f0;} -.engradio {color: #f37746;} -.suppradio {color: #b88646;} -.servradio {color: #6ca729;} -.syndradio {color: #8f4a4b;} -.centcomradio {color: #2681a5;} -.aiprivradio {color: #d65d95;} -.redteamradio {color: #ff4444;} -.blueteamradio {color: #3434fd;} +.radio {color: #008000;} +.sciradio {color: #993399;} +.comradio {color: #948f02;} +.secradio {color: #a30000;} +.medradio {color: #337296;} +.engradio {color: #fb5613;} +.suppradio {color: #a8732b;} +.servradio {color: #6eaa2c;} +.syndradio {color: #6d3f40;} +.centcomradio {color: #686868;} +.aiprivradio {color: #ff00ff;} +.redteamradio {color: #ff0000;} +.blueteamradio {color: #0000ff;} .yell { font-weight: bold;} -.alert {color: #d82020;} -h1.alert, h2.alert {color: #99aab5;} +.alert {color: #ff0000;} +h1.alert, h2.alert {color: #000000;} .emote { font-style: italic;} .selecteddna {color: #ffffff; background-color: #001B1B} -.attack {color: #e01c1c;} -.disarm {color: #b42525;} -.passive {color: #a00f0f;} +.attack {color: #ff0000;} +.disarm {color: #990000;} +.passive {color: #660000;} -.userdanger {color: #c51e1e; font-weight: bold; font-size: 24px;} -.danger {color: #c51e1e;} -.warning {color: #c51e1e; font-style: italic;} +.userdanger {color: #ff0000; font-weight: bold; font-size: 24px;} +.danger {color: #ff0000;} +.warning {color: #ff0000; font-style: italic;} .alertwarning {color: #FF0000; font-weight: bold} -.boldwarning {color: #c51e1e; font-style: italic; font-weight: bold} -.announce {color: #c51e1e; font-weight: bold;} -.boldannounce {color: #c51e1e; font-weight: bold;} -.greenannounce {color: #059223; font-weight: bold;} +.boldwarning {color: #ff0000; font-style: italic; font-weight: bold} +.announce {color: #228b22; font-weight: bold;} +.boldannounce {color: #ff0000; font-weight: bold;} +.greenannounce {color: #00ff00; font-weight: bold;} .rose {color: #ff5050;} -.info {color: #6685f5;} -.notice {color: #6685f5;} -.boldnotice {color: #6685f5; font-weight: bold;} -.adminnotice {color: #6685f5;} +.info {color: #0000CC;} +.notice {color: #000099;} +.boldnotice {color: #000099; font-weight: bold;} +.adminnotice {color: #0000ff;} .adminhelp {color: #ff0000; font-weight: bold;} -.unconscious {color: #a4bad6; font-weight: bold;} +.unconscious {color: #0000ff; font-weight: bold;}} .suicide {color: #ff5050; font-style: italic;} -.red {color: #FF0000} -.pink {color: #ff70c1;} -.blue {color: #215cff} -.green {color: #059223;} -.nicegreen {color: #059223;} +.green {color: #03ff39;} +.red {color: #FF0000;} +.pink {color: #FF69Bf;} +.blue {color: #0000FF;} +.nicegreen {color: #14a833;} .userlove {color: #ff42a6; font-style: italic; font-weight: bold; text-shadow: 0 0 6px #82365e;} .love {color: #ff4591; font-style: italic; text-shadow: 0 0 6px #994449;} -.shadowling {color: #8e8a99;} -.cult {color: #aa1c1c;} +.shadowling {color: #3b2769;} +.cult {color: #960000;} -.cultitalic {color: #aa1c1c; font-style: italic;} -.cultbold {color: #aa1c1c; font-style: italic; font-weight: bold;} -.cultboldtalic {color: #aa1c1c; font-weight: bold; font-size: 24px;} +.cultitalic {color: #960000; font-style: italic;} +.cultbold {color: #960000; font-style: italic; font-weight: bold;} +.cultboldtalic {color: #960000; font-weight: bold; font-size: 24px;} -.cultlarge {color: #aa1c1c; font-weight: bold; font-size: 24px;} -.narsie {color: #aa1c1c; font-weight: bold; font-size: 120px;} -.narsiesmall {color: #aa1c1c; font-weight: bold; font-size: 48px;} +.cultlarge {color: #960000; font-weight: bold; font-size: 24px;} +.narsie {color: #960000; font-weight: bold; font-size: 120px;} +.narsiesmall {color: #960000; font-weight: bold; font-size: 48px;} .colossus {color: #7F282A; font-size: 40px;} -.hierophant {color: #b441ee; font-weight: bold; font-style: italic;} -.hierophant_warning {color: #c56bf1; font-style: italic;} -.purple {color: #9956d3;} -.holoparasite {color: #88809c;} +.hierophant {color: #660099; font-weight: bold; font-style: italic;} +.hierophant_warning {color: #660099; font-style: italic;} +.purple {color: #5e2d79;} +.holoparasite {color: #35333a;} .revennotice {color: #1d2953;} .revenboldnotice {color: #1d2953; font-weight: bold;} @@ -351,11 +347,11 @@ h1.alert, h2.alert {color: #99aab5;} .revenminor {color: #823abb} .revenwarning {color: #760fbb; font-style: italic;} .revendanger {color: #760fbb; font-weight: bold; font-size: 24px;} -.umbra {color: #7c00e6;} -.umbra_emphasis {color: #7c00e6; font-weight: bold; font-style: italic;} -.umbra_large {color: #7c00e6; font-size: 24px; font-weight: bold; font-style: italic;} +.umbra {color: #5000A0;} +.umbra_emphasis {color: #5000A0; font-weight: bold; font-style: italic;} +.umbra_large {color: #5000A0; font-size: 24px; font-weight: bold; font-style: italic;} -.deconversion_message {color: #a947ff; font-size: 24px; font-style: italic;} +.deconversion_message {color: #5000A0; font-size: 24px; font-style: italic;} .brass {color: #BE8700;} .heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;} @@ -380,17 +376,17 @@ h1.alert, h2.alert {color: #99aab5;} .neovgre {color: #6E001A; font-weight: bold; font-style: italic;} .neovgre_small {color: #6E001A;} -.newscaster {color: #c05d5d;} -.ghostalert {color: #6600ff; font-style: italic; font-weight: bold;} +.newscaster {color: #800000;} +.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;} -.alien {color: #855d85;} -.noticealien {color: #059223;} -.alertalien {color: #059223; font-weight: bold;} -.changeling {color: #059223; font-style: italic;} +.alien {color: #543354;} +.noticealien {color: #00c000;} +.alertalien {color: #00c000; font-weight: bold;} +.changeling {color: #800080; font-style: italic;} -.spider {color: #8800ff;} +.spider {color: #4d004d;} -.interface {color: #750e75;} +.interface {color: #330033;} .sans {font-family: "Comic Sans MS", cursive, sans-serif;} .papyrus {font-family: "Papyrus", cursive, sans-serif;} @@ -401,9 +397,9 @@ h1.alert, h2.alert {color: #99aab5;} .big {font-size: 24px;} .reallybig {font-size: 32px;} .extremelybig {font-size: 40px;} -.greentext {color: #059223; font-size: 24px;} -.redtext {color: #c51e1e; font-size: 24px;} -.clown {color: #ff70c1; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;} +.greentext {color: #00FF00; font-size: 24px;} +.redtext {color: #FF0000; font-size: 24px;} +.clown {color: #FF69Bf; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;} .his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;} .velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;} @keyframes velvet { @@ -435,20 +431,20 @@ h1.alert, h2.alert {color: #99aab5;} .memo {color: #638500; text-align: center;} .memoedit {text-align: center; font-size: 16px;} -.abductor {color: #c204c2; font-style: italic;} -.mind_control {color: #df3da9; font-size: 3; font-weight: bold; font-style: italic;} +.abductor {color: #800080; font-style: italic;} +.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;} .slime {color: #00CED1;} .drone {color: #848482;} .monkey {color: #975032;} .swarmer {color: #2C75FF;} .resonate {color: #298F85;} -.monkeyhive {color: #a56408;} -.monkeylead {color: #af6805; font-size: 2;} +.monkeyhive {color: #774704;} +.monkeylead {color: #774704; font-size: 2;} .connectionClosed, .fatalError {background: red; color: white; padding: 5px;} .connectionClosed.restored {background: green;} -.internal.boldnshit {color: #3d5bc3; font-weight: bold;} +.internal.boldnshit {color: #000099; font-weight: bold;} /* HELPER CLASSES */ .text-normal {font-weight: normal; font-style: normal;} diff --git a/code/modules/goonchat/browserassets/css/browserOutput_dark.css b/code/modules/goonchat/browserassets/css/browserOutput_dark.css new file mode 100644 index 00000000..d143dfc3 --- /dev/null +++ b/code/modules/goonchat/browserassets/css/browserOutput_dark.css @@ -0,0 +1,159 @@ +html, body {color: #E0E0E0;} +body { + background: #171717; + font-color: #E0E0E0; + scrollbar-face-color:#1A1A1A; + scrollbar-track-color:#171717; + scrollbar-highlight-color:#171717; +} + +a {color: #397ea5;} +a.visited {color: #7c00e6;} +a:visited {color: #7c00e6;} + +#newMessages { + background: #242424; + color: #E0E0E0; +} +#newMessages:hover {background: #272727;} + +#ping {background: #272727;} + +#userBar .subCell { + background: #272727; + color: #E0E0E0; + border-top: 1px solid #171717; +} +#userBar .subCell:hover {background: #272727;} +#userBar .toggle {background: #272727;} + +/* MOTD */ +.motd {color: #E0E0E0; font-family: Verdana, sans-serif;} +.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #E0E0E0; text-decoration: underline;} +.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #E0E0E0;} + +h1, h2, h3, h4, h5, h6 {color: #E0E0E0;font-family: Georgia, Verdana, sans-serif;} +h1.alert, h2.alert {color: #E0E0E0;} + +.ooc {color: #cca300; font-weight: bold;} +.looc {color: #d8b555; font-weight: bold;} +.antagooc {color: #ce254f; font-weight: bold;} +.adminobserverooc {color: #0099cc; font-weight: bold;} +.adminooc {color: #3d5bc3; font-weight: bold;} + +.admin {color: #5975da; font-weight: bold;} + +.deadsay {color: #e2c1ff;} +.radio {color: #1ecc43;} +.sciradio {color: #c68cfa;} +.comradio {color: #5177ff;} +.secradio {color: #dd3535;} +.medradio {color: #57b8f0;} +.engradio {color: #f37746;} +.suppradio {color: #b88646;} +.servradio {color: #6ca729;} +.syndradio {color: #8f4a4b;} +.centcomradio {color: #2681a5;} +.aiprivradio {color: #d65d95;} +.redteamradio {color: #ff4444;} +.blueteamradio {color: #3434fd;} + +.alert {color: #d82020;} +h1.alert, h2.alert {color: #99aab5;} + +.attack {color: #e01c1c;} +.disarm {color: #b42525;} +.passive {color: #a00f0f;} + +.userdanger {color: #c51e1e; font-weight: bold; font-size: 24px;} +.danger {color: #c51e1e;} +.warning {color: #c51e1e; font-style: italic;} +.alertwarning {color: #c51e1e; font-weight: bold} +.boldwarning {color: #c51e1e; font-style: italic; font-weight: bold} +.announce {color: #c51e1e; font-weight: bold;} +.boldannounce {color: #c51e1e; font-weight: bold;} +.greenannounce {color: #059223; font-weight: bold;} +.info {color: #6685f5;} +.notice {color: #6685f5;} +.boldnotice {color: #6685f5; font-weight: bold;} +.adminnotice {color: #6685f5;} +.adminhelp {color: #ff0000; font-weight: bold;} +.unconscious {color: #E0E0E0; font-weight: bold;} +.red {color: #FF0000} +.pink {color: #ff70c1;} +.blue {color: #215cff} +.green {color: #059223;} +.nicegreen {color: #059223;} +.userlove {color: #ff42a6; font-style: italic; font-weight: bold; text-shadow: 0 0 6px #82365e;} +.love {color: #ff4591; font-style: italic; text-shadow: 0 0 6px #994449;} +.shadowling {color: #8e8a99;} +.cult {color: #aa1c1c;} + +.cultitalic {color: #aa1c1c; font-style: italic;} +.cultbold {color: #aa1c1c; font-style: italic; font-weight: bold;} +.cultboldtalic {color: #aa1c1c; font-weight: bold; font-size: 24px;} + +.cultlarge {color: #aa1c1c; font-weight: bold; font-size: 24px;} +.narsie {color: #aa1c1c; font-weight: bold; font-size: 120px;} +.narsiesmall {color: #aa1c1c; font-weight: bold; font-size: 48px;} +.hierophant {color: #b441ee; font-weight: bold; font-style: italic;} +.hierophant_warning {color: #c56bf1; font-style: italic;} +.purple {color: #9956d3;} +.holoparasite {color: #88809c;} + +.revennotice {color: #3645aa;} +.revenboldnotice {color: #3645aa; font-weight: bold;} +.revenbignotice {color: #3645aa; font-weight: bold; font-size: 24px;} +.revenminor {color: #823ddd} +.revenwarning {color: #8911d9; font-style: italic;} +.revendanger {color: #8911d9; font-weight: bold; font-size: 24px;} +.umbra {color: #7c00e6;} +.umbra_emphasis {color: #7c00e6; font-weight: bold; font-style: italic;} +.umbra_large {color: #7c00e6; font-size: 24px; font-weight: bold; font-style: italic;} + +.deconversion_message {color: #a947ff; font-size: 24px; font-style: italic;} + +.alloy {color: #545b64;} +.heavy_alloy {color: #545b64; font-weight: bold; font-style: italic;} +.nezbere_large {color: #545b64; font-size: 24px; font-weight: bold; font-style: italic;} +.nezbere {color: #545b64; font-weight: bold; font-style: italic;} +.nezbere_small {color: #545b64;} +.inathneq_large {color: #1d7dc7; font-size: 24px; font-weight: bold; font-style: italic;} +.inathneq {color: #1d7dc7; font-weight: bold; font-style: italic;} +.inathneq_small {color: #1d7dc7;} +.neovgre_large {color: #7c0622; font-size: 24px; font-weight: bold; font-style: italic;} +.neovgre {color: #7c0622; font-weight: bold; font-style: italic;} +.neovgre_small {color: #7c0622;} + +.newscaster {color: #c05d5d;} +.ghostalert {color: #6600ff; font-style: italic; font-weight: bold;} + +.alien {color: #855d85;} +.noticealien {color: #059223;} +.alertalien {color: #059223; font-weight: bold;} +.changeling {color: #059223; font-style: italic;} + +.spider {color: #8800ff;} + +.interface {color: #750e75;} + +.greentext {color: #059223; font-size: 24px;} +.redtext {color: #c51e1e; font-size: 24px;} +.clown {color: #ff70c1; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;} +.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;} +@keyframes velvet { + 0% { color: #890020; } + 40% { color: #c51e1e; } + 50% { color: #FF8888; } + 60% { color: #c51e1e; } + 100% { color: #890020; } +} + +.abductor {color: #c204c2; font-style: italic;} +.mind_control {color: #df3da9; font-size: 3; font-weight: bold; font-style: italic;} +.drone {color: #979795;} + +.monkeyhive {color: #a56408;} +.monkeylead {color: #af6805; font-size: 2;} + +.internal.boldnshit {color: #3d5bc3; font-weight: bold;} \ No newline at end of file diff --git a/code/modules/goonchat/browserassets/css/browserOutput_white.css b/code/modules/goonchat/browserassets/css/browserOutput_light.css similarity index 58% rename from code/modules/goonchat/browserassets/css/browserOutput_white.css rename to code/modules/goonchat/browserassets/css/browserOutput_light.css index 91f00312..098bd253 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput_white.css +++ b/code/modules/goonchat/browserassets/css/browserOutput_light.css @@ -1,236 +1,18 @@ -/***************************************** -* -* GLOBAL STYLES -* -******************************************/ -html, body { - padding: 0; - margin: 0; - height: 100%; - color: #000000; -} -body { - background: #eeeeee; - font-family: Verdana, sans-serif; - font-size: 9pt; - line-height: 1.2; - overflow-x: hidden; - overflow-y: scroll; - word-wrap: break-word; -} +body {background: #F1F1F1;} -em { - font-style: normal; - font-weight: bold; -} +#newMessages {background: #ddd;} +#ping {background: #ddd;} -img { - margin: 0; - padding: 0; - line-height: 1; - -ms-interpolation-mode: nearest-neighbor; - image-rendering: pixelated; -} -img.icon { - height: 1em; - min-height: 16px; - width: auto; - vertical-align: bottom; -} - - -.r:before { /* "repeated" badge class for combined messages */ - content: 'x'; -} -.r { - display: inline-block; - min-width: 0.5em; - font-size: 0.7em; - padding: 0.2em 0.3em; - line-height: 1; - color: white; - text-align: center; - white-space: nowrap; - vertical-align: middle; - background-color: crimson; - border-radius: 10px; -} - -a {color: #0000ff;} -a.visited {color: #ff00ff;} -a:visited {color: #ff00ff;} -a.popt {text-decoration: none;} - -/***************************************** -* -* OUTPUT NOT RELATED TO ACTUAL MESSAGES -* -******************************************/ -#loading { - position: fixed; - width: 300px; - height: 150px; - text-align: center; - left: 50%; - top: 50%; - margin: -75px 0 0 -150px; -} -#loading i {display: block; padding-bottom: 3px;} - -#messages { - font-size: 13px; - padding: 3px; - margin: 0; - word-wrap: break-word; -} -#newMessages { - position: fixed; - display: block; - bottom: 0; - right: 0; - padding: 8px; - background: #ddd; - text-decoration: none; - font-variant: small-caps; - font-size: 1.1em; - font-weight: bold; - color: #333; -} -#newMessages:hover {background: #ccc;} -#newMessages i {vertical-align: middle; padding-left: 3px;} -#ping { - position: fixed; - top: 0; - right: 115px; - width: 45px; - background: #ddd; - height: 30px; - padding: 8px 0 2px 0; -} -#ping i {display: block; text-align: center;} -#ping .ms { - display: block; - text-align: center; - font-size: 8pt; - padding-top: 2px; -} -#userBar { - position: fixed; - top: 0; - right: 0; -} -#userBar .subCell { - background: #ddd; - height: 30px; - padding: 5px 0; - display: block; - color: #333; - text-decoration: none; - line-height: 28px; - border-top: 1px solid #b4b4b4; -} -#userBar .subCell:hover {background: #ccc;} -#userBar .toggle { - width: 40px; - background: #ccc; - border-top: 0; - float: right; - text-align: center; -} -#userBar .sub {clear: both; display: none; width: 160px;} -#userBar .sub.scroll {overflow-y: scroll;} -#userBar .sub.subCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;} -#userBar .sub span { - display: block; - line-height: 30px; - float: left; -} -#userBar .sub i { - display: block; - padding: 0 5px; - font-size: 1.1em; - width: 22px; - text-align: center; - line-height: 30px; - float: right; -} -#userBar .sub input { - position: absolute; - padding: 7px 5px; - width: 121px; - line-height: 30px; - float: left; -} -#userBar .topCell {border-top: 0;} +#userBar .subCell {background: #ddd;} /* POPUPS */ -.popup { - position: fixed; - top: 50%; - left: 50%; - background: #ddd; -} -.popup .close { - position: absolute; - background: #aaa; - top: 0; - right: 0; - color: #333; - text-decoration: none; - z-index: 2; - padding: 0 10px; - height: 30px; - line-height: 30px; -} -.popup .close:hover {background: #999;} -.popup .head { - background: #999; - color: #ddd; - padding: 0 10px; - height: 30px; - line-height: 30px; - text-transform: uppercase; - font-size: 0.9em; - font-weight: bold; - border-bottom: 2px solid green; -} -.popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;} -.popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;} -.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;} -.popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;} - -.changeFont {padding: 10px;} -.changeFont a {display: block; text-decoration: none; padding: 3px; color: #333;} -.changeFont a:hover {background: #ccc;} - -.highlightPopup {padding: 10px; text-align: center;} -.highlightPopup input[type=text] {display: block; width: 215px; text-align: left; margin-top: 5px;} -.highlightPopup input.highlightColor {background-color: #FFFF00;} -.highlightPopup input.highlightTermSubmit {margin-top: 5px;} +.popup {background: #ddd;} +.popup .head {color: #ddd;} +.popup input[type=submit] {color: #ddd;} /* ADMIN CONTEXT MENU */ -.contextMenu { - background-color: #ddd; - position: fixed; - margin: 2px; - width: 150px; -} -.contextMenu a { - display: block; - padding: 2px 5px; - text-decoration: none; - color: #333; -} +.contextMenu {background-color: #ddd;} -.contextMenu a:hover { - background-color: #ccc; -} - -/* ADMIN FILTER MESSAGES MENU */ -.filterMessages {padding: 5px;} -.filterMessages div {padding: 2px 0;} -.filterMessages input {} -.filterMessages label {} .icon-stack {height: 1em; line-height: 1em; width: 1em; vertical-align: middle; margin-top: -2px;} @@ -266,8 +48,8 @@ em {font-style: normal; font-weight: bold;} .adminobserverooc {color: #0099cc; font-weight: bold;} .adminooc {color: #700038; font-weight: bold;} -.adminsay {color: #ff4500; font-weight: bold;} -.admin {color: #4473ff; font-weight: bold;} +.adminsay {color: #FF4500} +.admin {color: #386aff; font-weight: bold;} .name { font-weight: bold;} @@ -305,7 +87,7 @@ h1.alert, h2.alert {color: #000000;} .userdanger {color: #ff0000; font-weight: bold; font-size: 24px;} .danger {color: #ff0000;} .warning {color: #ff0000; font-style: italic;} -.alertwarning {color: #FF0000; font-weight: bold} +.alertwarning {color: #FF0000; font-weight: bold} .boldwarning {color: #ff0000; font-style: italic; font-weight: bold} .announce {color: #228b22; font-weight: bold;} .boldannounce {color: #ff0000; font-weight: bold;} @@ -318,10 +100,10 @@ h1.alert, h2.alert {color: #000000;} .adminhelp {color: #ff0000; font-weight: bold;} .unconscious {color: #0000ff; font-weight: bold;} .suicide {color: #ff5050; font-style: italic;} -.green {color: #03ff39;} -.red {color: #FF0000} +.green {color: #03ff39;} +.red {color: #FF0000;} .pink {color: #FF69Bf;} -.blue {color: #0000FF} +.blue {color: #0000FF;} .nicegreen {color: #14a833;} .userlove {color: #FF1493; font-style: italic; font-weight: bold; text-shadow: 0 0 6px #ff6dbc;} .love {color: #ff006a; font-style: italic; text-shadow: 0 0 6px #ff6d6d;} @@ -330,7 +112,7 @@ h1.alert, h2.alert {color: #000000;} .cultitalic {color: #960000; font-style: italic;} .cultbold {color: #960000; font-style: italic; font-weight: bold;} -.cultboldtalic {color: #960000; font-weight: bold; font-size: 24px;} +.cultboldtalic {color: #960000; font-weight: bold; font-size: 24px;} .cultlarge {color: #960000; font-weight: bold; font-size: 24px;} .narsie {color: #960000; font-weight: bold; font-size: 120px;} @@ -401,13 +183,38 @@ h1.alert, h2.alert {color: #000000;} .redtext {color: #FF0000; font-size: 24px;} .clown {color: #FF69Bf; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;} .his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;} +.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;} +@keyframes velvet { + 0% { color: #400020; } + 40% { color: #FF0000; } + 50% { color: #FF8888; } + 60% { color: #FF0000; } + 100% { color: #400020; } +} + +.hypnophrase {color: #202020; font-weight: bold; animation: hypnocolor 1500ms infinite;} +@keyframes hypnocolor { + 0% { color: #202020; } + 25% { color: #4b02ac; } + 50% { color: #9f41f1; } + 75% { color: #541c9c; } + 100% { color: #7adbf3; } +} + +.phobia {color: #dd0000; font-weight: bold; animation: phobia 750ms infinite;} +@keyframes phobia { + 0% { color: #f75a5a; } + 50% { color: #dd0000; } + 100% { color: #f75a5a; } +} + .icon {height: 1em; width: auto;} .memo {color: #638500; text-align: center;} .memoedit {text-align: center; font-size: 16px;} .abductor {color: #800080; font-style: italic;} -.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;} +.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;} .slime {color: #00CED1;} .drone {color: #848482;} .monkey {color: #975032;} @@ -419,9 +226,8 @@ h1.alert, h2.alert {color: #000000;} .connectionClosed, .fatalError {background: red; color: white; padding: 5px;} .connectionClosed.restored {background: green;} -.internal.boldnshit {color: blue; font-weight: bold;} +.internal.boldnshit {color: #000099; font-weight: bold;} /* HELPER CLASSES */ .text-normal {font-weight: normal; font-style: normal;} .hidden {display: none; visibility: hidden;} - diff --git a/code/modules/goonchat/browserassets/html/browserOutput.html b/code/modules/goonchat/browserassets/html/browserOutput.html index 9c6d462a..68da2517 100644 --- a/code/modules/goonchat/browserassets/html/browserOutput.html +++ b/code/modules/goonchat/browserassets/html/browserOutput.html @@ -5,8 +5,9 @@ - + + @@ -29,7 +30,7 @@ --ms
- +
diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js index 4375926c..06e735d1 100644 --- a/code/modules/goonchat/browserassets/js/browserOutput.js +++ b/code/modules/goonchat/browserassets/js/browserOutput.js @@ -35,7 +35,7 @@ var opts = { 'wasd': false, //Is the user in wasd mode? 'priorChatHeight': 0, //Thing for height-resizing detection 'restarting': false, //Is the round restarting? - 'darkmode':false, //Are we using darkmode? If not WHY ARE YOU LIVING IN 2009??? + 'colorPreset': 0, // index in the color presets list. //Options menu 'selectedSubLoop': null, //Contains the interval loop for closing the selected sub menu @@ -73,6 +73,14 @@ var opts = { }; +// Array of names for chat display color presets. +// If not set to normal, a CSS file `browserOutput_${name}.css` will be added to the head. +var colorPresets = [ + 'normal', + 'light', + 'dark' +] + function clamp(val, min, max) { return Math.max(min, Math.min(val, max)) } @@ -96,6 +104,12 @@ if (typeof String.prototype.trim !== 'function') { }; } +function updateColorPreset() { + var el = $("#colorPresetLink")[0]; + el.href = "browserOutput_"+colorPresets[opts.colorPreset]+".css"; + runByond('?_src_=chat&proc=colorPresetPost&preset='+colorPresets[opts.colorPreset]); +} + // Linkify the contents of a node, within its parent. function linkify(parent, insertBefore, text) { var start = 0; @@ -395,19 +409,6 @@ function toHex(n) { return "0123456789ABCDEF".charAt((n-n%16)/16) + "0123456789ABCDEF".charAt(n%16); } -function swap() { //Swap to darkmode - if (opts.darkmode){ - document.getElementById("sheetofstyles").href = "browserOutput_white.css"; - opts.darkmode = false; - runByond('?_src_=chat&proc=swaptolightmode'); - } else { - document.getElementById("sheetofstyles").href = "browserOutput.css"; - opts.darkmode = true; - runByond('?_src_=chat&proc=swaptodarkmode'); - } - setCookie('darkmode', (opts.darkmode ? 'true' : 'false'), 365); -} - function handleClientData(ckey, ip, compid) { //byond sends player info to here var currentData = {'ckey': ckey, 'ip': ip, 'compid': compid}; @@ -615,7 +616,7 @@ $(function() { 'shighlightColor': getCookie('highlightcolor'), 'smusicVolume': getCookie('musicVolume'), 'smessagecombining': getCookie('messagecombining'), - 'sdarkmode': getCookie('darkmode'), + 'scolorPreset': getCookie('colorpreset'), }; if (savedConfig.sfontSize) { @@ -626,9 +627,6 @@ $(function() { $("body").css('line-height', savedConfig.slineHeight); internalOutput('Loaded line height setting of: '+savedConfig.slineHeight+'', 'internal'); } - if(savedConfig.sdarkmode == 'true'){ - swap(); - } if (savedConfig.spingDisabled) { if (savedConfig.spingDisabled == 'true') { opts.pingDisabled = true; @@ -654,6 +652,13 @@ $(function() { opts.highlightColor = savedConfig.shighlightColor; internalOutput('Loaded highlight color of: '+savedConfig.shighlightColor+'', 'internal'); } + + if (savedConfig.scolorPreset) { + opts.colorPreset = Number(savedConfig.scolorPreset); + updateColorPreset(); + internalOutput('Loaded color preset of: '+colorPresets[opts.colorPreset]+'', 'internal'); + } + if (savedConfig.smusicVolume) { var newVolume = clamp(savedConfig.smusicVolume, 0, 100); $('#adminMusic').prop('volume', newVolume / 100); @@ -839,9 +844,6 @@ $(function() { $('#toggleOptions').click(function(e) { handleToggleClick($subOptions, $(this)); }); - $('#darkmodetoggle').click(function(e) { - swap(); - }); $('#toggleAudio').click(function(e) { handleToggleClick($subAudio, $(this)); }); @@ -913,7 +915,7 @@ $(function() { $.ajax({ type: 'GET', - url: 'browserOutput_white.css', + url: 'browserOutput.css', success: function(styleData) { var blob = new Blob(['Chat Log', $messages.html(), '']); @@ -991,7 +993,14 @@ $(function() { $messages.empty(); opts.messageCount = 0; }); - + + $('#changeColorPreset').click(function() { + opts.colorPreset = (opts.colorPreset+1) % colorPresets.length; + updateColorPreset(); + setCookie('colorpreset', opts.colorPreset, 365); + internalOutput('Changed color preset to: '+colorPresets[opts.colorPreset]); + }); + $('#musicVolumeSpan').hover(function() { $('#musicVolumeText').addClass('hidden'); $('#musicVolume').removeClass('hidden'); diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index 3fdbacc9..eb70ab82 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -261,7 +261,7 @@ desc = "A wing ripped from a watcher. Suitable as a trophy for a kinetic crusher." icon_state = "watcher_wing" denied_type = /obj/item/crusher_trophy/watcher_wing - bonus_value = 50 + bonus_value = 30 /obj/item/crusher_trophy/watcher_wing/effect_desc() return "mark detonation to prevent certain creatures from using certain attacks for [bonus_value*0.1] second\s" @@ -442,4 +442,4 @@ new /obj/effect/temp_visual/hierophant/wall/crusher(otherT, user) /obj/effect/temp_visual/hierophant/wall/crusher - duration = 75 + duration = 55 diff --git a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm index 31faabf6..84c9feaa 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm @@ -43,13 +43,668 @@ /datum/sprite_accessory/tails_animated/human/none name = "None" icon_state = "none" -/* + +/datum/sprite_accessory/tails/lizard/axolotl + name = "Axolotl" + icon_state = "axolotl" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/lizard/axolotl + name = "Axolotl" + icon_state = "axolotl" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/body_markings/guilmon + name = "Guilmon" + icon_state = "guilmon" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/markings_notmammals.dmi' + +/datum/sprite_accessory/tails/lizard/guilmon + name = "Guilmon" + icon_state = "guilmon" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/lizard/guilmon + name = "Guilmon" + icon_state = "guilmon" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/****************************************** +************** Human Tails **************** +*******************************************/ + +/datum/sprite_accessory/tails/human/none + name = "None" + icon_state = "none" + +/datum/sprite_accessory/tails_animated/human/none + name = "None" + icon_state = "none" + +/datum/sprite_accessory/tails/human/ailurus + name = "Red Panda" + icon_state = "wah" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails_animated/human/ailurus + name = "Red Panda" + icon_state = "wah" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails/human/axolotl + name = "Axolotl" + icon_state = "axolotl" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails_animated/human/axolotl + name = "Axolotl" + icon_state = "axolotl" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails/human/bee + name = "Bee" + icon_state = "bee" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails_animated/human/bee + name = "Bee" + icon_state = "bee" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + /datum/sprite_accessory/tails/human/cat name = "Cat" icon_state = "cat" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' color_src = HAIR /datum/sprite_accessory/tails_animated/human/cat name = "Cat" icon_state = "cat" - color_src = HAIR*/ \ No newline at end of file + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = HAIR + +/datum/sprite_accessory/tails/human/catbig + name = "Cat, Big" + icon_state = "catbig" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails_animated/human/catbig + name = "Cat, Big" + icon_state = "catbig" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails/human/cow + name = "Cow" + icon_state = "cow" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails_animated/human/cow + name = "Cow" + icon_state = "cow" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails/human/corvid + name = "Corvid" + icon_state = "crow" + +/datum/sprite_accessory/tails_animated/human/corvid + name = "Corvid" + icon_state = "crow" + +/datum/sprite_accessory/tails/human/eevee + name = "Eevee" + icon_state = "eevee" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails_animated/human/eevee + name = "Eevee" + icon_state = "eevee" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails/human/fennec + name = "Fennec" + icon_state = "fennec" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails_animated/human/fennec + name = "Fennec" + icon_state = "fennec" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails/human/fish + name = "Fish" + icon_state = "fish" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails_animated/human/fish + name = "Fish" + icon_state = "fish" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails/human/fox + name = "Fox" + icon_state = "fox" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails_animated/human/fox + name = "Fox" + icon_state = "fox" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails/human/horse + name = "Horse" + icon_state = "horse" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = HAIR + +/datum/sprite_accessory/tails_animated/human/horse + name = "Horse" + icon_state = "horse" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = HAIR + +/datum/sprite_accessory/tails/human/husky + name = "Husky" + icon_state = "husky" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails_animated/human/husky + name = "Husky" + icon_state = "husky" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails/human/insect + name = "Insect" + icon_state = "insect" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails_animated/human/insect + name = "insect" + icon_state = "insect" + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/tails/human/kitsune + name = "Kitsune" + icon_state = "kitsune" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/kitsune + name = "Kitsune" + icon_state = "kitsune" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails/human/murid + name = "Murid" + icon_state = "murid" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/murid + name = "Murid" + icon_state = "murid" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails/human/otie + name = "Otusian" + icon_state = "otie" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/otie + name = "Otusian" + icon_state = "otie" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails/orca + name = "Orca" + icon_state = "orca" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/orca + name = "Orca" + icon_state = "orca" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails/human/pede + name = "Scolipede" + icon_state = "pede" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/pede + name = "Scolipede" + icon_state = "pede" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails/human/rabbit + name = "Rabbit" + icon_state = "rabbit" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/rabbit + name = "Rabbit" + icon_state = "rabbit" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails/human/sergal + name = "Sergal" + icon_state = "sergal" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/sergal + name = "Sergal" + icon_state = "sergal" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails/human/skunk + name = "skunk" + icon_state = "skunk" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/skunk + name = "skunk" + icon_state = "skunk" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails/human/shark + name = "Shark" + icon_state = "shark" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/shark + name = "Shark" + icon_state = "shark" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails/human/datashark + name = "datashark" + icon_state = "datashark" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/datashark + name = "datashark" + icon_state = "datashark" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails/human/straighttail + name = "Straight Tail" + icon_state = "straighttail" + +/datum/sprite_accessory/tails_animated/human/straighttail + name = "Straight Tail" + icon_state = "straighttail" + +/datum/sprite_accessory/tails/human/squirrel + name = "Squirrel" + icon_state = "squirrel" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/squirrel + name = "Squirrel" + icon_state = "squirrel" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails/human/tentacle + name = "Tentacle" + icon_state = "tentacle" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/tentacle + name = "Tentacle" + icon_state = "tentacle" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails/human/tiger + name = "Tiger" + icon_state = "tiger" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/tiger + name = "Tiger" + icon_state = "tiger" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails/human/wolf + name = "Wolf" + icon_state = "wolf" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/wolf + name = "Wolf" + icon_state = "wolf" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/****************************************** +************** Furry Tails **************** +*******************************************/ + +/datum/sprite_accessory/mam_tails + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/mam_tails/none + name = "None" + icon_state = "none" + +/datum/sprite_accessory/mam_tails_animated + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/mam_tails_animated/none + name = "None" + icon_state = "none" + color_src = MATRIXED + +/datum/sprite_accessory/mam_tails/ailurus + name = "Red Panda" + icon_state = "wah" + extra = TRUE + +/datum/sprite_accessory/mam_tails_animated/ailurus + name = "Red Panda" + icon_state = "wah" + extra = TRUE + +/datum/sprite_accessory/mam_tails/axolotl + name = "Axolotl" + icon_state = "axolotl" + +/datum/sprite_accessory/mam_tails_animated/axolotl + name = "Axolotl" + icon_state = "axolotl" + +/datum/sprite_accessory/mam_tails/bee + name = "Bee" + icon_state = "bee" + +/datum/sprite_accessory/mam_tails_animated/bee + name = "Bee" + icon_state = "bee" + +/datum/sprite_accessory/mam_tails/cat + name = "Cat" + icon_state = "cat" + color_src = HAIR + +/datum/sprite_accessory/mam_tails_animated/cat + name = "Cat" + icon_state = "cat" + color_src = HAIR + +/datum/sprite_accessory/mam_tails/catbig + name = "Cat, Big" + icon_state = "catbig" + +/datum/sprite_accessory/mam_tails_animated/catbig + name = "Cat, Big" + icon_state = "catbig" + +/datum/sprite_accessory/mam_tails/corvid + name = "Corvid" + icon_state = "crow" + +/datum/sprite_accessory/mam_tails_animated/corvid + name = "Corvid" + icon_state = "crow" + +/datum/sprite_accessory/mam_tail/cow + name = "Cow" + icon_state = "cow" + +/datum/sprite_accessory/mam_tails_animated/cow + name = "Cow" + icon_state = "cow" + +/datum/sprite_accessory/mam_tails/eevee + name = "Eevee" + icon_state = "eevee" + +/datum/sprite_accessory/mam_tails_animated/eevee + name = "Eevee" + icon_state = "eevee" + +/datum/sprite_accessory/mam_tails/fennec + name = "Fennec" + icon_state = "fennec" + +/datum/sprite_accessory/mam_tails_animated/fennec + name = "Fennec" + icon_state = "fennec" + +/datum/sprite_accessory/mam_tails/human/fish + name = "Fish" + icon_state = "fish" + +/datum/sprite_accessory/mam_tails_animated/human/fish + name = "Fish" + icon_state = "fish" + +/datum/sprite_accessory/mam_tails/fox + name = "Fox" + icon_state = "fox" + +/datum/sprite_accessory/mam_tails_animated/fox + name = "Fox" + icon_state = "fox" + +/datum/sprite_accessory/mam_tails/hawk + name = "Hawk" + icon_state = "hawk" + +/datum/sprite_accessory/mam_tails_animated/hawk + name = "Hawk" + icon_state = "hawk" + +/datum/sprite_accessory/mam_tails/horse + name = "Horse" + icon_state = "horse" + color_src = HAIR + +/datum/sprite_accessory/mam_tails_animated/horse + name = "Horse" + icon_state = "horse" + color_src = HAIR + +/datum/sprite_accessory/mam_tails/husky + name = "Husky" + icon_state = "husky" + +/datum/sprite_accessory/mam_tails_animated/husky + name = "Husky" + icon_state = "husky" + +datum/sprite_accessory/mam_tails/insect + name = "Insect" + icon_state = "insect" + +/datum/sprite_accessory/mam_tails_animated/insect + name = "Insect" + icon_state = "insect" + +/datum/sprite_accessory/mam_tails/kangaroo + name = "kangaroo" + icon_state = "kangaroo" + +/datum/sprite_accessory/mam_tails_animated/kangaroo + name = "kangaroo" + icon_state = "kangaroo" + +/datum/sprite_accessory/mam_tails/kitsune + name = "Kitsune" + icon_state = "kitsune" + +/datum/sprite_accessory/mam_tails_animated/kitsune + name = "Kitsune" + icon_state = "kitsune" + +/datum/sprite_accessory/mam_tails/lab + name = "Lab" + icon_state = "lab" + +/datum/sprite_accessory/mam_tails_animated/lab + name = "Lab" + icon_state = "lab" + +/datum/sprite_accessory/mam_tails/murid + name = "Murid" + icon_state = "murid" + +/datum/sprite_accessory/mam_tails_animated/murid + name = "Murid" + icon_state = "murid" + +/datum/sprite_accessory/mam_tails/otie + name = "Otusian" + icon_state = "otie" + +/datum/sprite_accessory/mam_tails_animated/otie + name = "Otusian" + icon_state = "otie" + +/datum/sprite_accessory/mam_tails/orca + name = "Orca" + icon_state = "orca" + +/datum/sprite_accessory/mam_tails_animated/orca + name = "Orca" + icon_state = "orca" + +/datum/sprite_accessory/mam_tails/pede + name = "Scolipede" + icon_state = "pede" + +/datum/sprite_accessory/mam_tails_animated/pede + name = "Scolipede" + icon_state = "pede" + +/datum/sprite_accessory/mam_tails/rabbit + name = "Rabbit" + icon_state = "rabbit" + +/datum/sprite_accessory/mam_tails_animated/rabbit + name = "Rabbit" + icon_state = "rabbit" + +/datum/sprite_accessory/mam_tails/sergal + name = "Sergal" + icon_state = "sergal" + +/datum/sprite_accessory/mam_tails_animated/sergal + name = "Sergal" + icon_state = "sergal" + +/datum/sprite_accessory/mam_tails/skunk + name = "Skunk" + icon_state = "skunk" + +/datum/sprite_accessory/mam_tails_animated/skunk + name = "Skunk" + icon_state = "skunk" + +/datum/sprite_accessory/mam_tails/shark + name = "Shark" + icon_state = "shark" + +/datum/sprite_accessory/mam_tails_animated/shark + name = "Shark" + icon_state = "shark" + +/datum/sprite_accessory/mam_tails/shepherd + name = "Shepherd" + icon_state = "shepherd" + +/datum/sprite_accessory/mam_tails_animated/shepherd + name = "Shepherd" + icon_state = "shepherd" + +/datum/sprite_accessory/mam_tails/straighttail + name = "Straight Tail" + icon_state = "straighttail" + +/datum/sprite_accessory/mam_tails_animated/straighttail + name = "Straight Tail" + icon_state = "straighttail" + +/datum/sprite_accessory/mam_tails/squirrel + name = "Squirrel" + icon_state = "squirrel" + +/datum/sprite_accessory/mam_tails_animated/squirrel + name = "Squirrel" + icon_state = "squirrel" + +/datum/sprite_accessory/mam_tails/tentacle + name = "Tentacle" + icon_state = "tentacle" + +/datum/sprite_accessory/mam_tails_animated/tentacle + name = "Tentacle" + icon_state = "tentacle" + +/datum/sprite_accessory/mam_tails/tiger + name = "Tiger" + icon_state = "tiger" + +/datum/sprite_accessory/mam_tails_animated/tiger + name = "Tiger" + icon_state = "tiger" + +/datum/sprite_accessory/mam_tails/wolf + name = "Wolf" + icon_state = "wolf" + +/datum/sprite_accessory/mam_tails_animated/wolf + name = "Wolf" + icon_state = "wolf" \ No newline at end of file diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 89a7ec25..90ce091c 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -271,9 +271,13 @@ if(restrained()) changeNext_move(CLICK_CD_BREAKOUT) last_special = world.time + CLICK_CD_BREAKOUT + var/buckle_cd = 600 + if(handcuffed) + var/obj/item/restraints/O = src.get_item_by_slot(SLOT_HANDCUFFED) + buckle_cd = O.breakouttime visible_message("[src] attempts to unbuckle [p_them()]self!", \ - "You attempt to unbuckle yourself... (This will take around one minute and you need to stay still.)") - if(do_after(src, 600, 0, target = src)) + "You attempt to unbuckle yourself... (This will take around [round(buckle_cd/600,1)] minute\s, and you need to stay still.)") + if(do_after(src, buckle_cd, 0, target = src)) if(!buckled) return buckled.user_unbuckle_mob(src,src) @@ -809,7 +813,8 @@ drop_all_held_items() stop_pulling() throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = src.handcuffed) - SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "handcuffed", /datum/mood_event/handcuffed) + if(handcuffed.demoralize_criminals) + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "handcuffed", /datum/mood_event/handcuffed) else clear_alert("handcuffed") SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "handcuffed") diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b4a8839e..6312db1e 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -860,7 +860,7 @@ piggyback(target) return //If you dragged them to you and you're aggressively grabbing try to fireman carry them - else if(user != target && can_be_firemanned(target)) + else if(user != target) fireman_carry(target) return . = ..() diff --git a/code/modules/mob/living/carbon/human/species_types/corporate.dm b/code/modules/mob/living/carbon/human/species_types/corporate.dm index 620f0b25..146090b3 100644 --- a/code/modules/mob/living/carbon/human/species_types/corporate.dm +++ b/code/modules/mob/living/carbon/human/species_types/corporate.dm @@ -16,5 +16,5 @@ blacklisted = 1 use_skintones = 0 species_traits = list(NOBLOOD,EYECOLOR,NOGENITALS) - inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER) + inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOLIMBDISABLE,TRAIT_NOHUNGER) sexes = 0 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index dcb875e1..6c9d95e8 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -3,7 +3,7 @@ name = "Spooky Scary Skeleton" id = "skeleton" say_mod = "rattles" - blacklisted = 1 + blacklisted = 0 sexes = 0 meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL) @@ -12,13 +12,18 @@ mutanttongue = /obj/item/organ/tongue/bone damage_overlay_type = ""//let's not show bloody wounds or burns over bones. disliked_food = NONE - liked_food = GROSS | MEAT | RAW + liked_food = GROSS | MEAT | RAW | DAIRY /datum/species/skeleton/check_roundstart_eligible() if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) return TRUE return ..() -/datum/species/skeleton/pirate - name = "Space Queen's Skeleton" +/datum/species/skeleton/space + name = "Spooky Spacey Skeleton" + id = "spaceskeleton" + blacklisted = 1 inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER) + +/datum/species/skeleton/pirate/check_roundstart_eligible() + return FALSE diff --git a/code/modules/mob/living/carbon/human/species_types/synths.dm b/code/modules/mob/living/carbon/human/species_types/synths.dm index 378b97db..915e85f1 100644 --- a/code/modules/mob/living/carbon/human/species_types/synths.dm +++ b/code/modules/mob/living/carbon/human/species_types/synths.dm @@ -12,7 +12,7 @@ damage_overlay_type = "synth" limbs_id = "synth" var/list/initial_species_traits = list(NOTRANSSTING) //for getting these values back for assume_disguise() - var/list/initial_inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER,TRAIT_NOBREATH) + var/list/initial_inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER,TRAIT_NOLIMBDISABLE,TRAIT_NOBREATH) var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index 61454150..9263aea9 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -16,7 +16,12 @@ disliked_food = NONE liked_food = GROSS | MEAT | RAW -/datum/species/zombie/check_roundstart_eligible() +/datum/species/zombie/notspaceproof + id = "notspaceproofzombie" + blacklisted = 0 + inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_FAKEDEATH) + +/datum/species/zombie/notspaceproof/check_roundstart_eligible() if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) return TRUE return ..() @@ -47,7 +52,7 @@ /datum/species/zombie/infectious/spec_life(mob/living/carbon/C) . = ..() C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW - + //Zombies never actually die, they just fall down until they regenerate enough to rise back up. //They must be restrained, beheaded or gibbed to stop being a threat. if(regen_cooldown < world.time) @@ -58,7 +63,7 @@ C.adjustToxLoss(-heal_amt) if(!C.InCritical() && prob(4)) playsound(C, pick(spooks), 50, TRUE, 10) - + //Congrats you somehow died so hard you stopped being a zombie /datum/species/zombie/infectious/spec_death(mob/living/carbon/C) . = ..() diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 72ff7e7a..3df86ce4 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -123,15 +123,16 @@ There are several things that need to be remembered: if(U.adjusted == ALT_STYLE) t_color = "[t_color]_d" - if(U.mutantrace_variation) - if(U.suit_style == DIGITIGRADE_SUIT_STYLE) - U.alternate_worn_icon = 'modular_citadel/icons/mob/uniform_digi.dmi' - if(U.adjusted == ALT_STYLE) - t_color = "[t_color]_d_l" - else if(U.adjusted == NORMAL_STYLE) - t_color = "[t_color]_l" - else - U.alternate_worn_icon = null + if(!U.force_alternate_icon) + if(U.mutantrace_variation) + if(U.suit_style == DIGITIGRADE_SUIT_STYLE) + U.alternate_worn_icon = 'modular_citadel/icons/mob/uniform_digi.dmi' + if(U.adjusted == ALT_STYLE) + t_color = "[t_color]_d_l" + else if(U.adjusted == NORMAL_STYLE) + t_color = "[t_color]_l" + else + U.alternate_worn_icon = null var/mutable_appearance/uniform_overlay diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 1c2234bb..801a6cd2 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -35,6 +35,7 @@ */ if(stat == DEAD) stop_sound_channel(CHANNEL_HEARTBEAT) + handle_death() rot() //Updates the number of stored chemicals for powers @@ -43,6 +44,12 @@ if(stat != DEAD) return 1 +//Procs called while dead +/mob/living/carbon/proc/handle_death() + for(var/datum/reagent/R in reagents.reagent_list) + if(R.chemical_flags & REAGENT_DEAD_PROCESS) + R.on_mob_dead(src) + /////////////// // BREATHING // /////////////// diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 73274dcf..5aec56b1 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -44,7 +44,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians var/reset = 0 //if the summoner has reset the guardian already var/cooldown = 0 var/mob/living/carbon/summoner - var/range = 10 //how far from the user the spirit can be + var/range = 13 //how far from the user the spirit can be var/toggle_button_type = /obj/screen/guardian/ToggleMode/Inactive //what sort of toggle button the hud uses var/datum/guardianname/namedatum = new/datum/guardianname() var/playstyle_string = "You are a standard Guardian. You shouldn't exist!" diff --git a/code/modules/mob/living/simple_animal/guardian/types/assassin.dm b/code/modules/mob/living/simple_animal/guardian/types/assassin.dm index 45d8c17d..e507a4c8 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/assassin.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/assassin.dm @@ -1,7 +1,5 @@ //Assassin /mob/living/simple_animal/hostile/guardian/assassin - melee_damage_lower = 15 - melee_damage_upper = 15 attacktext = "slashes" attack_sound = 'sound/weapons/bladeslice.ogg' damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) @@ -12,7 +10,7 @@ toggle_button_type = /obj/screen/guardian/ToggleMode/Assassin var/toggle = FALSE - var/stealthcooldown = 160 + var/stealthcooldown = 100 var/obj/screen/alert/canstealthalert var/obj/screen/alert/instealthalert diff --git a/code/modules/mob/living/simple_animal/guardian/types/charger.dm b/code/modules/mob/living/simple_animal/guardian/types/charger.dm index 7a4c454f..3ece5d4e 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/charger.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/charger.dm @@ -1,13 +1,10 @@ //Charger /mob/living/simple_animal/hostile/guardian/charger - melee_damage_lower = 15 - melee_damage_upper = 15 ranged = 1 //technically ranged_message = "charges" - ranged_cooldown_time = 40 - speed = -1 - damage_coeff = list(BRUTE = 0.6, BURN = 0.6, TOX = 0.6, CLONE = 0.6, STAMINA = 0, OXY = 0.6) - playstyle_string = "As a charger type you do medium damage, have medium damage resistance, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding." + ranged_cooldown_time = 20 + damage_coeff = list(BRUTE = 0, BURN = 0.5, TOX = 0.5, CLONE = 0.5, STAMINA = 0, OXY = 0.5) + playstyle_string = "As a charger type you do medium damage, take half damage, immunity to brute damage, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding." magic_fluff_string = "..And draw the Hunter, an alien master of rapid assault." tech_fluff_string = "Boot sequence complete. Charge modules loaded. Holoparasite swarm online." carp_fluff_string = "CARP CARP CARP! Caught one! It's a charger carp, that likes running at people. But it doesn't have any legs..." diff --git a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm index e7dbbda2..a43d4b6d 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm @@ -3,7 +3,7 @@ melee_damage_lower = 10 melee_damage_upper = 10 damage_coeff = list(BRUTE = 0.75, BURN = 0.75, TOX = 0.75, CLONE = 0.75, STAMINA = 0, OXY = 0.75) - playstyle_string = "As a dextrous type you can hold items, store an item within yourself, and have medium damage resistance, but do low damage on attacks. Recalling and leashing will force you to drop unstored items!" + playstyle_string = "As a dextrous type you can hold items, store an item within yourself, and take half damage, but do low damage on attacks. Recalling and leashing will force you to drop unstored items!" magic_fluff_string = "..And draw the Drone, a dextrous master of construction and repair." tech_fluff_string = "Boot sequence complete. Dextrous combat modules loaded. Holoparasite swarm online." carp_fluff_string = "CARP CARP CARP! You caught one! It can hold stuff in its fins, sort of." diff --git a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm index ff2f4532..531c5138 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm @@ -1,10 +1,7 @@ //Bomb /mob/living/simple_animal/hostile/guardian/bomb - melee_damage_lower = 15 - melee_damage_upper = 15 damage_coeff = list(BRUTE = 0.6, BURN = 0.6, TOX = 0.6, CLONE = 0.6, STAMINA = 0, OXY = 0.6) - range = 13 - playstyle_string = "As an explosive type, you have moderate close combat abilities, may explosively teleport targets on attack, and are capable of converting nearby items and objects into disguised bombs via alt click." + playstyle_string = "As an explosive type, you have moderate close combat abilities, take half damage, may explosively teleport targets on attack, and are capable of converting nearby items and objects into disguised bombs via alt click." magic_fluff_string = "..And draw the Scientist, master of explosive death." tech_fluff_string = "Boot sequence complete. Explosive modules active. Holoparasite swarm online." carp_fluff_string = "CARP CARP CARP! Caught one! It's an explosive carp! Boom goes the fishy." diff --git a/code/modules/mob/living/simple_animal/guardian/types/fire.dm b/code/modules/mob/living/simple_animal/guardian/types/fire.dm index 7a469dd1..b111caae 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/fire.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/fire.dm @@ -1,13 +1,13 @@ //Fire /mob/living/simple_animal/hostile/guardian/fire a_intent = INTENT_HELP - melee_damage_lower = 7 - melee_damage_upper = 7 + melee_damage_lower = 10 + melee_damage_upper = 10 attack_sound = 'sound/items/welder.ogg' attacktext = "ignites" - damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7) - range = 7 - playstyle_string = "As a chaos type, you have only light damage resistance, but will ignite any enemy you bump into. In addition, your melee attacks will cause human targets to see everyone as you." + melee_damage_type = BURN + damage_coeff = list(BRUTE = 0.7, BURN = 0, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7) + playstyle_string = "As a chaos type, you take 30% damage reduction to all but burn, which you are immune to. You will ignite any enemy you bump into. in addition, your melee attacks will cause human targets to see everyone as you." magic_fluff_string = "..And draw the Wizard, bringer of endless chaos!" tech_fluff_string = "Boot sequence complete. Crowd control modules activated. Holoparasite swarm online." carp_fluff_string = "CARP CARP CARP! You caught one! OH GOD, EVERYTHING'S ON FIRE. Except you and the fish." @@ -38,6 +38,6 @@ /mob/living/simple_animal/hostile/guardian/fire/proc/collision_ignite(AM as mob|obj) if(isliving(AM)) var/mob/living/M = AM - if(!hasmatchingsummoner(M) && M != summoner && M.fire_stacks < 7) - M.fire_stacks = 7 + if(!hasmatchingsummoner(M) && M != summoner && M.fire_stacks < 10) + M.fire_stacks = 10 M.IgniteMob() diff --git a/code/modules/mob/living/simple_animal/guardian/types/lightning.dm b/code/modules/mob/living/simple_animal/guardian/types/lightning.dm index ad1c4773..7b765182 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/lightning.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/lightning.dm @@ -4,14 +4,13 @@ layer = LYING_MOB_LAYER /mob/living/simple_animal/hostile/guardian/beam - melee_damage_lower = 7 - melee_damage_upper = 7 + melee_damage_lower = 10 + melee_damage_upper = 10 attacktext = "shocks" melee_damage_type = BURN attack_sound = 'sound/machines/defib_zap.ogg' damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7) - range = 7 - playstyle_string = "As a lightning type, you will apply lightning chains to targets on attack and have a lightning chain to your summoner. Lightning chains will shock anyone near them." + playstyle_string = "As a lightning type, you have 30% damage reduction, apply lightning chains to targets on attack and have a lightning chain to your summoner. Lightning chains will shock anyone near them." magic_fluff_string = "..And draw the Tesla, a shocking, lethal source of power." tech_fluff_string = "Boot sequence complete. Lightning modules active. Holoparasite swarm online." carp_fluff_string = "CARP CARP CARP! Caught one! It's a lightning carp! Everyone else goes zap zap." @@ -31,7 +30,7 @@ var/datum/beam/C = pick(enemychains) qdel(C) enemychains -= C - enemychains += Beam(target, "lightning[rand(1,12)]", time=70, maxdistance=7, beam_type=/obj/effect/ebeam/chain) + enemychains += Beam(target, "lightning[rand(1,12)]", time=70, maxdistance=13, beam_type=/obj/effect/ebeam/chain) /mob/living/simple_animal/hostile/guardian/beam/Destroy() removechains() diff --git a/code/modules/mob/living/simple_animal/guardian/types/protector.dm b/code/modules/mob/living/simple_animal/guardian/types/protector.dm index 14430bb2..53964254 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/protector.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/protector.dm @@ -1,7 +1,5 @@ //Protector /mob/living/simple_animal/hostile/guardian/protector - melee_damage_lower = 15 - melee_damage_upper = 15 range = 15 //worse for it due to how it leashes damage_coeff = list(BRUTE = 0.4, BURN = 0.4, TOX = 0.4, CLONE = 0.4, STAMINA = 0, OXY = 0.4) playstyle_string = "As a protector type you cause your summoner to leash to you instead of you leashing to them and have two modes; Combat Mode, where you do and take medium damage, and Protection Mode, where you do and take almost no damage, but move slightly slower." @@ -33,9 +31,9 @@ cooldown = world.time + 10 if(toggle) cut_overlays() - melee_damage_lower = initial(melee_damage_lower) - melee_damage_upper = initial(melee_damage_upper) - speed = initial(speed) + melee_damage_lower = 15 + melee_damage_upper = 15 + speed = 0 damage_coeff = list(BRUTE = 0.4, BURN = 0.4, TOX = 0.4, CLONE = 0.4, STAMINA = 0, OXY = 0.4) to_chat(src, "You switch to combat mode.") toggle = FALSE @@ -44,8 +42,8 @@ if(namedatum) shield_overlay.color = namedatum.colour add_overlay(shield_overlay) - melee_damage_lower = 2 - melee_damage_upper = 2 + melee_damage_lower = 5 + melee_damage_upper = 5 speed = 1 damage_coeff = list(BRUTE = 0.05, BURN = 0.05, TOX = 0.05, CLONE = 0.05, STAMINA = 0, OXY = 0.05) //damage? what's damage? to_chat(src, "You switch to protection mode.") diff --git a/code/modules/mob/living/simple_animal/guardian/types/ranged.dm b/code/modules/mob/living/simple_animal/guardian/types/ranged.dm index 5adcc8b2..0e8f632d 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/ranged.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/ranged.dm @@ -16,8 +16,7 @@ ranged_cooldown_time = 1 //fast! projectilesound = 'sound/effects/hit_on_shattered_glass.ogg' ranged = 1 - range = 13 - playstyle_string = "As a ranged type, you have only light damage resistance, but are capable of spraying shards of crystal at incredibly high speed. You can also deploy surveillance snares to monitor enemy movement. Finally, you can switch to scout mode, in which you can't attack, but can move without limit." + playstyle_string = "As a ranged type, you have 10% damage reduction, but are capable of spraying shards of crystal at incredibly high speed. You can also deploy surveillance snares to monitor enemy movement. Finally, you can switch to scout mode, in which you can't attack, but can move without limit." magic_fluff_string = "..And draw the Sentinel, an alien master of ranged combat." tech_fluff_string = "Boot sequence complete. Ranged combat modules active. Holoparasite swarm online." carp_fluff_string = "CARP CARP CARP! Caught one, it's a ranged carp. This fishy can watch people pee in the ocean." @@ -36,7 +35,7 @@ obj_damage = initial(obj_damage) environment_smash = initial(environment_smash) alpha = 255 - range = initial(range) + range = 13 to_chat(src, "You switch to combat mode.") toggle = FALSE else diff --git a/code/modules/mob/living/simple_animal/guardian/types/standard.dm b/code/modules/mob/living/simple_animal/guardian/types/standard.dm index 4edd9d9e..2285167d 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/standard.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/standard.dm @@ -3,9 +3,9 @@ melee_damage_lower = 20 melee_damage_upper = 20 obj_damage = 80 - next_move_modifier = 0.8 //attacks 20% faster + next_move_modifier = 0.5 //attacks 50% faster environment_smash = ENVIRONMENT_SMASH_WALLS - playstyle_string = "As a standard type you have no special abilities, but have a high damage resistance and a powerful attack capable of smashing through walls." + playstyle_string = "As a standard type you have no special abilities, but take half damage and have powerful attack capable of smashing through walls." magic_fluff_string = "..And draw the Assistant, faceless and generic, but never to be underestimated." tech_fluff_string = "Boot sequence complete. Standard combat modules loaded. Holoparasite swarm online." carp_fluff_string = "CARP CARP CARP! You caught one! It's really boring and standard. Better punch some walls to ease the tension." diff --git a/code/modules/mob/living/simple_animal/guardian/types/support.dm b/code/modules/mob/living/simple_animal/guardian/types/support.dm index 794683e6..8bf1874d 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/support.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm @@ -2,11 +2,8 @@ /mob/living/simple_animal/hostile/guardian/healer a_intent = INTENT_HARM friendly = "heals" - speed = 0 damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7) - melee_damage_lower = 15 - melee_damage_upper = 15 - playstyle_string = "As a support type, you may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent object or mob will warp them to your bluespace beacon after a short delay." + playstyle_string = "As a support type, you have 30% damage reduction and may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent object or mob will warp them to your bluespace beacon after a short delay." magic_fluff_string = "..And draw the CMO, a potent force of life... and death." carp_fluff_string = "CARP CARP CARP! You caught a support carp. It's a kleptocarp!" tech_fluff_string = "Boot sequence complete. Support modules active. Holoparasite swarm online." diff --git a/code/modules/mob/living/simple_animal/hostile/goose.dm b/code/modules/mob/living/simple_animal/hostile/goose.dm new file mode 100644 index 00000000..6f6dc992 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/goose.dm @@ -0,0 +1,173 @@ +#define GOOSE_SATIATED 50 + +/mob/living/simple_animal/hostile/retaliate/goose + name = "goose" + desc = "It's loose" + icon_state = "goose" // sprites by cogwerks from goonstation, used with permission + icon_living = "goose" + icon_dead = "goose_dead" + mob_biotypes = list(MOB_ORGANIC, MOB_BEAST) + speak_chance = 0 + turns_per_move = 5 + butcher_results = list(/obj/item/reagent_containers/food/snacks/meat = 2) + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + emote_taunt = list("hisses") + taunt_chance = 30 + speed = 0 + maxHealth = 25 + health = 25 + harm_intent_damage = 5 + melee_damage_lower = 5 + melee_damage_upper = 5 + attacktext = "pecks" + attack_sound = "goose" + speak_emote = list("honks") + faction = list("neutral") + attack_same = TRUE + gold_core_spawnable = HOSTILE_SPAWN + var/random_retaliate = TRUE + var/icon_vomit_start = "vomit_start" + var/icon_vomit = "vomit" + var/icon_vomit_end = "vomit_end" + +/mob/living/simple_animal/hostile/retaliate/goose/handle_automated_movement() + . = ..() + if(prob(5) && random_retaliate == TRUE) + Retaliate() + +/mob/living/simple_animal/hostile/retaliate/goose/vomit + name = "Birdboat" + real_name = "Birdboat" + desc = "It's a sick-looking goose, probably ate too much maintenance trash. Best not to move it around too much." + gender = MALE + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + gold_core_spawnable = NO_SPAWN + random_retaliate = FALSE + var/vomiting = FALSE + var/vomitCoefficient = 1 + var/vomitTimeBonus = 0 + var/datum/action/cooldown/vomit/goosevomit + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/cargo + name = "Sickly Goose" + real_name = "Sickly Goose" + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/Initialize() + . = ..() + goosevomit = new + goosevomit.Grant(src) + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/Destroy() + QDEL_NULL(goosevomit) + return ..() + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/examine(user) + . = ..() + . += "Somehow, it still looks hungry." + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/attacked_by(obj/item/O, mob/user) + . = ..() + feed(O) + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/feed(obj/item/O) + var/obj/item/reagent_containers/food/tasty = O + if(!istype(O)) + return + if (contents.len > GOOSE_SATIATED) + visible_message("[src] looks too full to eat \the [tasty]!") + return + if (tasty.foodtype & GROSS) + visible_message("[src] hungrily gobbles up \the [tasty]!") + tasty.forceMove(src) + playsound(src,'sound/items/eatfood.ogg', 70, 1) + vomitCoefficient += 3 + vomitTimeBonus += 2 + else + visible_message("[src] refuses to eat \the [tasty].") + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit() + var/turf/T = get_turf(src) + var/obj/item/reagent_containers/food/consumed = locate() in contents //Barf out a single food item from our guts + if (prob(50) && consumed) + barf_food(consumed) + else + playsound(T, 'sound/effects/splat.ogg', 50, 1) + T.add_vomit_floor(src) + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/barf_food(var/atom/A, var/hard = FALSE) + if(!istype(A, /obj/item/reagent_containers/food)) + return + var/turf/currentTurf = get_turf(src) + var/obj/item/reagent_containers/food/consumed = A + consumed.forceMove(currentTurf) + var/destination = get_edge_target_turf(currentTurf, pick(GLOB.alldirs)) //Pick a random direction to toss them in + var/throwRange = hard ? rand(2,8) : 1 + consumed.safe_throw_at(destination, throwRange, 2) //Thow the food at a random tile 1 spot away + sleep(2) + if (QDELETED(src) || QDELETED(consumed)) + return + currentTurf = get_turf(consumed) + currentTurf.add_vomit_floor(src) + playsound(currentTurf, 'sound/effects/splat.ogg', 50, 1) + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit_prestart(duration) + flick("vomit_start",src) + addtimer(CALLBACK(src, .proc/vomit_start, duration), 13) //13 is the length of the vomit_start animation in gooseloose.dmi + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit_start(duration) + vomiting = TRUE + icon_state = "vomit" + vomit() + addtimer(CALLBACK(src, .proc/vomit_preend), duration) + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit_preend() + for (var/obj/item/consumed in contents) //Get rid of any food left in the poor thing + barf_food(consumed, TRUE) + sleep(1) + if (QDELETED(src)) + return + vomit_end() + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit_end() + flick("vomit_end",src) + vomiting = FALSE + icon_state = initial(icon_state) + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/Moved(oldLoc, dir) + . = ..() + if(vomiting) + vomit() // its supposed to keep vomiting if you move + return + var/turf/currentTurf = get_turf(src) + while (currentTurf == get_turf(src)) + var/obj/item/reagent_containers/food/tasty = locate() in currentTurf + if (tasty) + feed(tasty) + stoplag(20) + if(prob(vomitCoefficient * 0.2)) + vomit_prestart(vomitTimeBonus + 25) + vomitCoefficient = 1 + vomitTimeBonus = 0 + +/datum/action/cooldown/vomit + name = "Vomit" + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "vomit" + icon_icon = 'icons/mob/animal.dmi' + cooldown_time = 250 + +/datum/action/cooldown/vomit/Trigger() + if(!..()) + return FALSE + if(!istype(owner, /mob/living/simple_animal/hostile/retaliate/goose/vomit)) + return FALSE + var/mob/living/simple_animal/hostile/retaliate/goose/vomit/vomit = owner + if(!vomit.vomiting) + vomit.vomit_prestart(vomit.vomitTimeBonus + 25) + vomit.vomitCoefficient = 1 + vomit.vomitTimeBonus = 0 + return TRUE \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index b529d826..b88db1fa 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -125,6 +125,8 @@ Difficulty: Very Hard if(H.mind) if(H.mind.martial_art && prob(H.mind.martial_art.deflection_chance)) . = TRUE + if (is_species(H, /datum/species/golem/sand)) + . = TRUE /mob/living/simple_animal/hostile/megafauna/colossus/proc/alternating_dir_shots() dir_shots(GLOB.diagonals) diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index 9706526a..aa1fd7db 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -67,6 +67,9 @@ /obj/structure/filingcabinet/ui_interact(mob/user) . = ..() + if(isobserver(user)) + return + if(contents.len <= 0) to_chat(user, "[src] is empty.") return diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 135d9b85..19ff4728 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -267,7 +267,7 @@ to_chat(user, "There is an integration cog installed!") to_chat(user, "Alt-Click the APC to [ locked ? "unlock" : "lock"] the interface.") - + if(issilicon(user)) to_chat(user, "Ctrl-Click the APC to switch the breaker [ operating ? "off" : "on"].") @@ -793,7 +793,7 @@ if(damage_flag == "melee" && damage_amount < damage_deflection) return 0 . = ..() - + /obj/machinery/power/apc/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) if(!(stat & BROKEN)) @@ -846,8 +846,6 @@ if(!ui) ui = new(user, src, ui_key, "apc", name, 535, 515, master_ui, state) ui.open() - if(ui) - ui.set_autoupdate(state = (failure_timer ? 1 : 0)) /obj/machinery/power/apc/ui_data(mob/user) var/list/data = list( diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 7f6306e3..9837d4e7 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -329,6 +329,12 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(power) soundloop.volume = min(40, (round(power/100)/50)+1) // 5 +1 volume per 20 power. 2500 power is max + if(isclosedturf(T)) + var/turf/did_it_melt = T.Melt() + if(!isclosedturf(did_it_melt)) //In case some joker finds way to place these on indestructible walls + visible_message("[src] melts through [T]!") + return + //Ok, get the air from the turf var/datum/gas_mixture/env = T.return_air() diff --git a/code/modules/projectiles/ammunition/ballistic/pistol.dm b/code/modules/projectiles/ammunition/ballistic/pistol.dm index 13a284e9..ad962ebb 100644 --- a/code/modules/projectiles/ammunition/ballistic/pistol.dm +++ b/code/modules/projectiles/ammunition/ballistic/pistol.dm @@ -1,3 +1,9 @@ +// lato +/obj/item/ammo_casing/latob + name = "Lato-class bullet casing" + desc = "A Lato-class bullet casing. Signiature with lotus engravings." + projectile_type = /obj/item/projectile/bullet/latob + // 10mm (Stechkin) /obj/item/ammo_casing/c10mm diff --git a/code/modules/projectiles/ammunition/ballistic/revolver.dm b/code/modules/projectiles/ammunition/ballistic/revolver.dm index 9e2fa3a9..d5a9fab4 100644 --- a/code/modules/projectiles/ammunition/ballistic/revolver.dm +++ b/code/modules/projectiles/ammunition/ballistic/revolver.dm @@ -6,6 +6,11 @@ caliber = "357" projectile_type = /obj/item/projectile/bullet/a357 +/obj/item/ammo_casing/a357/ap + name = ".357 armor-piercing bullet casing" + desc = "A .357 armor-piercing bullet casing." + projectile_type = /obj/item/projectile/bullet/a357/ap + // 7.62x38mmR (Nagant Revolver) /obj/item/ammo_casing/n762 @@ -20,9 +25,26 @@ name = ".38 rubber bullet casing" desc = "A .38 rubber bullet casing." caliber = "38" - projectile_type = /obj/item/projectile/bullet/c38 + projectile_type = /obj/item/projectile/bullet/c38/rubber /obj/item/ammo_casing/c38/lethal name = ".38 bullet casing" desc = "A .38 bullet casing" - projectile_type = /obj/item/projectile/bullet/c38lethal + projectile_type = /obj/item/projectile/bullet/c38 + +/obj/item/ammo_casing/c38/trac + name = ".38 TRAC bullet casing" + desc = "A .38 \"TRAC\" bullet casing." + projectile_type = /obj/item/projectile/bullet/c38/trac + +/obj/item/ammo_casing/c38/hotshot + name = ".38 Hot Shot bullet casing" + desc = "A .38 Hot Shot bullet casing." + caliber = "38" + projectile_type = /obj/item/projectile/bullet/c38/hotshot + +/obj/item/ammo_casing/c38/iceblox + name = ".38 Iceblox bullet casing" + desc = "A .38 Iceblox bullet casing." + caliber = "38" + projectile_type = /obj/item/projectile/bullet/c38/iceblox \ No newline at end of file diff --git a/code/modules/projectiles/ammunition/ballistic/rifle.dm b/code/modules/projectiles/ammunition/ballistic/rifle.dm index 47c5c6d6..9c151667 100644 --- a/code/modules/projectiles/ammunition/ballistic/rifle.dm +++ b/code/modules/projectiles/ammunition/ballistic/rifle.dm @@ -26,3 +26,10 @@ caliber = "40mm" icon_state = "40mmHE" projectile_type = /obj/item/projectile/bullet/a40mm + +// bratonmag (Braton) +/obj/item/ammo_casing/bratonmag + name = "Braton-class bullet casing" + desc = "A signiature shell from a Braton, lined with engravings." + caliber = "bratonb" + projectile_type = /obj/item/projectile/bullet/bratonb diff --git a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm index 7cd27e85..b0e699a4 100644 --- a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm +++ b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm @@ -3,18 +3,39 @@ desc = "Designed to quickly reload revolvers." icon_state = "357" ammo_type = /obj/item/ammo_casing/a357 + caliber = "357" max_ammo = 7 multiple_sprites = 1 +/obj/item/ammo_box/a357/ap + name = "speed loader (.357 AP)" + ammo_type = /obj/item/ammo_casing/a357/ap + /obj/item/ammo_box/c38 name = "speed loader (.38 rubber)" desc = "Designed to quickly reload revolvers." icon_state = "38" + caliber = "38" ammo_type = /obj/item/ammo_casing/c38 max_ammo = 6 multiple_sprites = 1 materials = list(MAT_METAL = 20000) +/obj/item/ammo_box/c38/trac + name = "speed loader (.38 TRAC)" + desc = "Designed to quickly reload revolvers. TRAC bullets embed a tracking implant within the target's body." + ammo_type = /obj/item/ammo_casing/c38/trac + +/obj/item/ammo_box/c38/hotshot + name = "speed loader (.38 Hot Shot)" + desc = "Designed to quickly reload revolvers. Hot Shot bullets contain an incendiary payload." + ammo_type = /obj/item/ammo_casing/c38/hotshot + +/obj/item/ammo_box/c38/iceblox + name = "speed loader (.38 Iceblox)" + desc = "Designed to quickly reload revolvers. Iceblox bullets contain a cryogenic payload." + ammo_type = /obj/item/ammo_casing/c38/iceblox + /obj/item/ammo_box/c38/lethal name = "speed loader (.38)" ammo_type = /obj/item/ammo_casing/c38/lethal diff --git a/code/modules/projectiles/boxes_magazines/external/pistol.dm b/code/modules/projectiles/boxes_magazines/external/pistol.dm index dbde572d..93f3c86f 100644 --- a/code/modules/projectiles/boxes_magazines/external/pistol.dm +++ b/code/modules/projectiles/boxes_magazines/external/pistol.dm @@ -1,3 +1,11 @@ +//Lato Ammo +/obj/item/ammo_box/magazine/latomag + name = "pistol magazine (lato)" + desc = "A magazine fitted for lato-class weapons. A lotus decal is inscribed on the backside." + icon_state = "latomag" + ammo_type = /obj/item/ammo_casing/latob + max_ammo = 15 + /obj/item/ammo_box/magazine/m10mm name = "pistol magazine (10mm)" desc = "A gun magazine." diff --git a/code/modules/projectiles/boxes_magazines/external/rifle.dm b/code/modules/projectiles/boxes_magazines/external/rifle.dm index 4512ba58..436822ef 100644 --- a/code/modules/projectiles/boxes_magazines/external/rifle.dm +++ b/code/modules/projectiles/boxes_magazines/external/rifle.dm @@ -19,3 +19,11 @@ caliber = "a556" max_ammo = 30 multiple_sprites = 2 + +//braton +/obj/item/ammo_box/magazine/bratonmag + name = "toploader magazine (braton)" + icon_state = "bratonmag" + ammo_type = /obj/item/ammo_casing/bratonmag + caliber = "bratonb" + max_ammo = 60 \ No newline at end of file diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index 4bd65a7b..36f1fcfd 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -208,6 +208,21 @@ update_icon() return +//WARFRAME WEAPONS INSERT +/obj/item/gun/ballistic/automatic/braton + name = "\improper Braton" + desc = "An unusual weapon in design; sporting a high firing rate and capacity, but low damage. There is a lotus decal on the underside of the barrel." + icon_state = "braton" + item_state = "braton" + w_class = WEIGHT_CLASS_HUGE + slot_flags = 0 + mag_type = /obj/item/ammo_box/magazine/bratonmag + fire_sound = 'sound/weapons/gunshot_braton.ogg' + can_suppress = FALSE + burst_size = 5 + fire_delay = 1 +//ENDS HERE + /obj/item/gun/ballistic/automatic/tommygun name = "\improper Thompson SMG" desc = "Based on the classic 'Chicago Typewriter'." diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm index 5f67194b..43e98d6f 100644 --- a/code/modules/projectiles/guns/ballistic/pistol.dm +++ b/code/modules/projectiles/guns/ballistic/pistol.dm @@ -21,6 +21,20 @@ var/obj/item/suppressor/S = new(src) install_suppressor(S) +//WARFRAME WEAPONS INSERT +/obj/item/gun/ballistic/automatic/pistol/lato + name = "\improper Lato" + desc = "A strange sidearm, sporting low damage but a high firing rate and capacity. There is a lotus decal on the barrel." + icon_state = "lato" + item_state = "lato" + w_class = WEIGHT_CLASS_NORMAL + mag_type = /obj/item/ammo_box/magazine/latomag + can_suppress = FALSE + fire_sound = 'sound/weapons/gunshot_lato.ogg' + fire_delay = 0 +//ENDS HERE + + /obj/item/gun/ballistic/automatic/pistol/m1911 name = "\improper M1911" desc = "A classic .45 handgun with a small magazine capacity." diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm index 54cb9fe5..de738c90 100644 --- a/code/modules/projectiles/guns/energy/energy_gun.dm +++ b/code/modules/projectiles/guns/energy/energy_gun.dm @@ -118,11 +118,11 @@ switch(fail_tick) if(0 to 200) fail_tick += (2*(fail_chance)) - M.rad_act(40) + M.rad_act(400) to_chat(M, "Your [name] feels warmer.") if(201 to INFINITY) SSobj.processing.Remove(src) - M.rad_act(80) + M.rad_act(800) crit_fail = 1 to_chat(M, "Your [name]'s reactor overloads!") diff --git a/code/modules/projectiles/projectile/bullets/pistol.dm b/code/modules/projectiles/projectile/bullets/pistol.dm index b68c3847..1f94de17 100644 --- a/code/modules/projectiles/projectile/bullets/pistol.dm +++ b/code/modules/projectiles/projectile/bullets/pistol.dm @@ -14,6 +14,11 @@ damage = 10 fire_stacks = 1 +// lato +/obj/item/projectile/bullet/latob + name = "Lato-class bullet" + damage = 13 + // 10mm (Stechkin) /obj/item/projectile/bullet/c10mm diff --git a/code/modules/projectiles/projectile/bullets/revolver.dm b/code/modules/projectiles/projectile/bullets/revolver.dm index 68d51361..8ba2ba97 100644 --- a/code/modules/projectiles/projectile/bullets/revolver.dm +++ b/code/modules/projectiles/projectile/bullets/revolver.dm @@ -14,15 +14,58 @@ /obj/item/projectile/bullet/c38 name = ".38 rubber bullet" + damage = 25 + stamina = 48 + +/obj/item/projectile/bullet/c38/rubber + name = ".38 bullet" damage = 15 stamina = 48 -/obj/item/projectile/bullet/c38lethal - name = ".38 bullet" - damage = 25 +/obj/item/projectile/bullet/c38/trac + name = ".38 TRAC bullet" + damage = 10 + +/obj/item/projectile/bullet/c38/trac/on_hit(atom/target, blocked = FALSE) + . = ..() + var/mob/living/carbon/M = target + var/obj/item/implant/tracking/c38/imp + for(var/obj/item/implant/tracking/c38/TI in M.implants) //checks if the target already contains a tracking implant + imp = TI + return + if(!imp) + imp = new /obj/item/implant/tracking/c38(M) + imp.implant(M) + +/obj/item/projectile/bullet/c38/hotshot //similar to incendiary bullets, but do not leave a flaming trail + name = ".38 Hot Shot bullet" + damage = 20 + +/obj/item/projectile/bullet/c38/hotshot/on_hit(atom/target, blocked = FALSE) + . = ..() + if(iscarbon(target)) + var/mob/living/carbon/M = target + M.adjust_fire_stacks(6) + M.IgniteMob() + +/obj/item/projectile/bullet/c38/iceblox //see /obj/item/projectile/temp for the original code + name = ".38 Iceblox bullet" + damage = 20 + var/temperature = 100 + +/obj/item/projectile/bullet/c38/iceblox/on_hit(atom/target, blocked = FALSE) + . = ..() + if(isliving(target)) + var/mob/living/M = target + M.adjust_bodytemperature(((100-blocked)/100)*(temperature - M.bodytemperature)) // .357 (Syndie Revolver) /obj/item/projectile/bullet/a357 name = ".357 bullet" damage = 60 + +/obj/item/projectile/bullet/a357/ap + name = ".357 armor-piercing bullet" + damage = 45 + armour_penetration = 45 \ No newline at end of file diff --git a/code/modules/projectiles/projectile/bullets/rifle.dm b/code/modules/projectiles/projectile/bullets/rifle.dm index ae1611cb..e54d3141 100644 --- a/code/modules/projectiles/projectile/bullets/rifle.dm +++ b/code/modules/projectiles/projectile/bullets/rifle.dm @@ -14,3 +14,8 @@ name = "enchanted 7.62 bullet" damage = 5 stamina = 80 + +// bratonmag (Braton) +/obj/item/projectile/bullet/bratonb + name = "braton bullet" + damage = 10 \ No newline at end of file diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 476fc60c..8074bb67 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -1,4 +1,4 @@ -#define CHEMICAL_QUANTISATION_LEVEL 0.0001 + #define CHEMICAL_QUANTISATION_LEVEL 0.001 /proc/build_chemical_reagent_list() //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id @@ -466,7 +466,7 @@ if (C.FermiChem == TRUE && !continue_reacting) if (chem_temp > C.ExplodeTemp) //This is first to ensure explosions. - var/datum/chemical_reaction/fermi/Ferm = selected_reaction + var/datum/chemical_reaction/Ferm = selected_reaction fermiIsReacting = FALSE SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[Ferm] explosion")) Ferm.FermiExplode(src, my_atom, volume = total_volume, temp = chem_temp, pH = pH) @@ -496,7 +496,12 @@ //Standard reaction mechanics: else - if (C.FermiChem == TRUE)//Just to make sure + if (C.FermiChem == TRUE)//Just to make sure, should only proc when grenades are combining. + if (chem_temp > C.ExplodeTemp) //To allow fermigrenades + var/datum/chemical_reaction/fermi/Ferm = selected_reaction + fermiIsReacting = FALSE + SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[Ferm] explosion")) + Ferm.FermiExplode(src, my_atom, volume = total_volume, temp = chem_temp, pH = pH) return 0 for(var/B in cached_required_reagents) // @@ -539,7 +544,7 @@ return 0 /datum/reagents/process() - var/datum/chemical_reaction/fermi/C = fermiReactID + var/datum/chemical_reaction/C = fermiReactID var/list/cached_required_reagents = C.required_reagents//update reagents list var/list/cached_results = C.results//resultant chemical list @@ -575,16 +580,16 @@ return /datum/reagents/proc/fermiEnd() - var/datum/chemical_reaction/fermi/C = fermiReactID + var/datum/chemical_reaction/C = fermiReactID STOP_PROCESSING(SSprocessing, src) fermiIsReacting = FALSE - reactedVol = 0 - targetVol = 0 //pH check, handled at the end to reduce calls. if(istype(my_atom, /obj/item/reagent_containers)) var/obj/item/reagent_containers/RC = my_atom RC.pH_check() - C.FermiFinish(src, my_atom) + C.FermiFinish(src, my_atom, reactedVol) + reactedVol = 0 + targetVol = 0 handle_reactions() update_total() //Reaction sounds and words @@ -595,7 +600,7 @@ to_chat(M, "[iconhtml] [C.mix_message]") /datum/reagents/proc/fermiReact(selected_reaction, cached_temp, cached_pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier) - var/datum/chemical_reaction/fermi/C = selected_reaction + var/datum/chemical_reaction/C = selected_reaction var/deltaT = 0 var/deltapH = 0 var/stepChemAmmount = 0 @@ -704,7 +709,7 @@ return (reactedVol) //Currently calculates it irrespective of required reagents at the start -/datum/reagents/proc/reactant_purity(var/datum/chemical_reaction/fermi/C, holder) +/datum/reagents/proc/reactant_purity(var/datum/chemical_reaction/C, holder) var/list/cached_reagents = reagent_list var/i = 0 var/cachedPurity @@ -714,6 +719,14 @@ i++ return cachedPurity/i +/datum/reagents/proc/uncache_purity(id) + var/datum/reagent/R = has_reagent("[id]") + if(!R) + return + if(R.cached_purity == 1) + return + R.purity = R.cached_purity + /datum/reagents/proc/isolate_reagent(reagent) var/list/cached_reagents = reagent_list for(var/_reagent in cached_reagents) @@ -745,11 +758,14 @@ total_volume = 0 for(var/reagent in cached_reagents) var/datum/reagent/R = reagent - if(R.volume < CHEMICAL_QUANTISATION_LEVEL) + if(R.volume == 0) + del_reagent(R.id) + if((R.volume < 0.01) && !fermiIsReacting) del_reagent(R.id) else total_volume += R.volume - + if(!reagent_list) + pH = 7 return 0 /datum/reagents/proc/clear_reagents() @@ -878,17 +894,15 @@ var/datum/reagent/R = A if (R.id == reagent) //IF MERGING //Add amount and equalize purity - R.volume += amount + R.volume += round(amount, CHEMICAL_QUANTISATION_LEVEL) R.purity = ((R.purity * R.volume) + (other_purity * amount)) /((R.volume + amount)) //This should add the purity to the product update_total() if(my_atom) my_atom.on_reagent_change(ADD_REAGENT) if(isliving(my_atom)) - if(R.OnMobMergeCheck == TRUE)//Forces on_mob_add proc when a chem is merged + if(R.chemical_flags & REAGENT_ONMOBMERGE)//Forces on_mob_add proc when a chem is merged R.on_mob_add(my_atom, amount) - //else - // R.on_merge(data, amount, my_atom, other_purity) R.on_merge(data, amount, my_atom, other_purity) if(!no_react) handle_reactions() @@ -900,13 +914,13 @@ var/datum/reagent/R = new D.type(data) cached_reagents += R R.holder = src - R.volume = amount + R.volume = round(amount, CHEMICAL_QUANTISATION_LEVEL) R.purity = other_purity R.loc = get_turf(my_atom) if(data) R.data = data R.on_new(data) - if(R.addProc == TRUE)//Allows on new without data overhead. + if(R.chemical_flags & REAGENT_FORCEONNEW)//Allows on new without data overhead. R.on_new(pH) //Add more as desired. @@ -1134,4 +1148,4 @@ if(initial(R.can_synth)) random_reagents += initial(R.id) var/picked_reagent = pick(random_reagents) - return picked_reagent + return picked_reagent \ No newline at end of file diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm index 436ee80e..5af53789 100644 --- a/code/modules/reagents/chemistry/machinery/chem_heater.dm +++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm @@ -79,6 +79,15 @@ return return ..() + if(beaker) + if(istype(I, /obj/item/reagent_containers/dropper)) + var/obj/item/reagent_containers/dropper/D = I + D.afterattack(beaker, user, 1) + + if(istype(I, /obj/item/reagent_containers/syringe)) + var/obj/item/reagent_containers/syringe/S = I + S.afterattack(beaker, user, 1) + /obj/machinery/chem_heater/on_deconstruction() replace_beaker() return ..() diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index 002c54be..567c1873 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -233,6 +233,12 @@ else reagents.remove_reagent(id, amount) . = TRUE + else if (amount == -1) // -1 means custom amount + useramount = input("Enter the Amount you want to transfer:", name, useramount) as num|null + if (useramount > 0) + end_fermi_reaction() + reagents.trans_id_to(beaker, id, useramount) + . = TRUE if("toggleMode") mode = !mode @@ -332,7 +338,7 @@ var/vol_part = min(reagents.total_volume, 30) if(text2num(many)) amount_full = round(reagents.total_volume / 30) - vol_part = reagents.total_volume % 30 + vol_part = ((reagents.total_volume*1000) % 30000) / 1000 //% operator doesn't support decimals. var/name = stripped_input(usr, "Name:","Name your bottle!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN) if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr))) return @@ -379,7 +385,34 @@ reagents.trans_to(P, vol_part) . = TRUE //END CITADEL ADDITIONS - if("analyze") + if("analyzeBeak") + var/datum/reagent/R = GLOB.chemical_reagents_list[params["id"]] + if(R) + var/state = "Unknown" + if(initial(R.reagent_state) == 1) + state = "Solid" + else if(initial(R.reagent_state) == 2) + state = "Liquid" + else if(initial(R.reagent_state) == 3) + state = "Gas" + var/const/P = 3 //The number of seconds between life ticks + var/T = initial(R.metabolization_rate) * (60 / P) + var/datum/chemical_reaction/Rcr = get_chemical_reaction(R.id) + if(Rcr && Rcr.FermiChem) + fermianalyze = TRUE + var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2 + var/datum/reagent/targetReagent = beaker.reagents.has_reagent("[R.id]") + + if(!targetReagent) + CRASH("Tried to find a reagent that doesn't exist in the chem_master!") + analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache) + else + fermianalyze = FALSE + analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold)) + screen = "analyze" + return + + if("analyzeBuff") var/datum/reagent/R = GLOB.chemical_reagents_list[params["id"]] if(R) var/state = "Unknown" @@ -395,7 +428,11 @@ fermianalyze = TRUE var/datum/chemical_reaction/Rcr = get_chemical_reaction(R.id) var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2 - analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = initial(R.purity), "inverseRatioF" = initial(R.InverseChemVal), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache) + var/datum/reagent/targetReagent = reagents.has_reagent("[R.id]") + + if(!targetReagent) + CRASH("Tried to find a reagent that doesn't exist in the chem_master!") + analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache) else fermianalyze = FALSE analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold)) @@ -451,4 +488,4 @@ condi = TRUE #undef PILL_STYLE_COUNT -#undef RANDOM_PILL_STYLE +#undef RANDOM_PILL_STYLE \ No newline at end of file diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index 0e482f8c..720d411d 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -125,12 +125,6 @@ else cut_overlays() -/obj/machinery/computer/pandemic/proc/eject_beaker() - if(beaker) - beaker.forceMove(drop_location()) - beaker = null - update_icon() - /obj/machinery/computer/pandemic/ui_interact(mob/user, ui_key = "main", datum/tgui/ui, force_open = FALSE, datum/tgui/master_ui, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) @@ -165,7 +159,7 @@ return switch(action) if("eject_beaker") - eject_beaker() + replace_beaker(usr) . = TRUE if("empty_beaker") if(beaker) @@ -174,7 +168,7 @@ if("empty_eject_beaker") if(beaker) beaker.reagents.clear_reagents() - eject_beaker() + replace_beaker(usr) . = TRUE if("rename_disease") var/id = get_virus_id_by_index(text2num(params["index"])) @@ -232,18 +226,32 @@ . = TRUE //no afterattack if(stat & (NOPOWER|BROKEN)) return - if(beaker) - to_chat(user, "A container is already loaded into [src]!") + var/obj/item/reagent_containers/B = I + if(!user.transferItemToLoc(B, src)) return - if(!user.transferItemToLoc(I, src)) - return - - beaker = I + replace_beaker(user, B) to_chat(user, "You insert [I] into [src].") - update_icon() else return ..() +/obj/machinery/computer/pandemic/AltClick(mob/living/user) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + replace_beaker(user) + return + +/obj/machinery/computer/pandemic/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) + if(beaker) + beaker.forceMove(drop_location()) + if(user && Adjacent(user) && !issiliconoradminghost(user)) + user.put_in_hands(beaker) + if(new_beaker) + beaker = new_beaker + else + beaker = null + update_icon() + return TRUE + /obj/machinery/computer/pandemic/on_deconstruction() - eject_beaker() + replace_beaker(usr) . = ..() diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index c21629ce..aaccc6d0 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -32,19 +32,19 @@ var/addiction_stage3_end = 30 var/addiction_stage4_end = 40 var/overdosed = 0 // You fucked up and this is now triggering its overdose effects, purge that shit quick. - var/self_consuming = FALSE + var/self_consuming = FALSE //I think this uhhh, makes weird stuff happen when metabolising, but... doesn't seem to do what I think, so I'm gonna leave it. //Fermichem vars: - var/purity = 1 //How pure a chemical is from 0 - 1. - var/addProc = FALSE //If the chemical should force an on_new() call + var/purity = 1 //How pure a chemical is from 0 - 1. + var/cached_purity = 1 var/turf/loc = null //Should be the creation location! var/pH = 7 //pH of the specific reagent, used for calculating the sum pH of a holder. - var/ImpureChem = "fermiTox"// What chemical is metabolised with an inpure reaction - var/InverseChemVal = 0.25 // If the impurity is below 0.5, replace ALL of the chem with InverseChem upon metabolising - var/InverseChem = "fermiTox"// What chem is metabolised when purity is below InverseChemVal, this shouldn't be made, but if it does, well, I guess I'll know about it. - var/DoNotSplit = FALSE // If impurity is handled within the main chem itself - var/OnMobMergeCheck = FALSE //Call on_mob_life proc when reagents are merging. + //var/SplitChem = FALSE //If the chem splits on metabolism + var/impure_chem // What chemical is metabolised with an inpure reaction + var/inverse_chem_val = 0 // If the impurity is below 0.5, replace ALL of the chem with inverse_chemupon metabolising + var/inverse_chem // What chem is metabolised when purity is below inverse_chem_val, this shouldn't be made, but if it does, well, I guess I'll know about it. var/metabolizing = FALSE - var/invisible = FALSE //Set to true if it doesn't appear on handheld health analyzers. + var/chemical_flags // See fermi/readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_ONLYINVERSE, REAGENT_ONMOBMERGE, REAGENT_INVISIBLE, REAGENT_FORCEONNEW, REAGENT_SNEAKYNAME + /datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references . = ..() @@ -73,8 +73,47 @@ holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears. return +//called when a mob processes chems when dead. +/datum/reagent/proc/on_mob_dead(mob/living/carbon/M) + if(!(chemical_flags & REAGENT_DEAD_PROCESS)) //justincase + return + current_cycle++ + if(holder) + holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears. + return + // Called when this reagent is first added to a mob -/datum/reagent/proc/on_mob_add(mob/living/L) +/datum/reagent/proc/on_mob_add(mob/living/L, amount) + if(!iscarbon(L)) + return + var/mob/living/carbon/M = L + if (purity == 1) + log_game("CHEM: [L] ckey: [L.key] has ingested [volume]u of [id]") + return + if(cached_purity == 1) + cached_purity = purity + else if(purity < 0) + CRASH("Purity below 0 for chem: [id], Please let Fermis Know!") + if(chemical_flags & REAGENT_DONOTSPLIT) + return + + if ((inverse_chem_val > purity) && (inverse_chem))//Turns all of a added reagent into the inverse chem + M.reagents.remove_reagent(id, amount, FALSE) + M.reagents.add_reagent(inverse_chem, amount, FALSE, other_purity = 1-cached_purity) + var/datum/reagent/R = M.reagents.has_reagent("[inverse_chem]") + if(R.chemical_flags & REAGENT_SNEAKYNAME) + R.name = name//Negative effects are hidden + if(R.chemical_flags & REAGENT_INVISIBLE) + R.chemical_flags |= (REAGENT_INVISIBLE) + log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [inverse_chem]") + return + else if (impure_chem) + var/impureVol = amount * (1 - purity) //turns impure ratio into impure chem + if(!(chemical_flags & REAGENT_SPLITRETAINVOL)) + M.reagents.remove_reagent(id, (impureVol), FALSE) + M.reagents.add_reagent(impure_chem, impureVol, FALSE, other_purity = 1-cached_purity) + log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume - impureVol]u of [id]") + log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [impure_chem]") return // Called when this reagent is removed while inside a mob @@ -97,7 +136,35 @@ return // Called when two reagents of the same are mixing. -/datum/reagent/proc/on_merge(data) +/datum/reagent/proc/on_merge(data, amount, mob/living/carbon/M, purity) + if(!iscarbon(M)) + return + if (purity == 1) + log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [id]") + return + cached_purity = purity //purity SHOULD be precalculated from the add_reagent, update cache. + if (purity < 0) + CRASH("Purity below 0 for chem: [id], Please let Fermis Know!") + if(chemical_flags & REAGENT_DONOTSPLIT) + return + + if ((inverse_chem_val > purity) && (inverse_chem)) //INVERT + M.reagents.remove_reagent(id, amount, FALSE) + M.reagents.add_reagent(inverse_chem, amount, FALSE, other_purity = 1-cached_purity) + var/datum/reagent/R = M.reagents.has_reagent("[inverse_chem]") + if(R.chemical_flags & REAGENT_SNEAKYNAME) + R.name = name//Negative effects are hidden + if(R.chemical_flags & REAGENT_INVISIBLE) + R.chemical_flags |= (REAGENT_INVISIBLE) + log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [inverse_chem]") + return + else if (impure_chem) //SPLIT + var/impureVol = amount * (1 - purity) + if(!(chemical_flags & REAGENT_SPLITRETAINVOL)) + M.reagents.remove_reagent(id, impureVol, FALSE) + M.reagents.add_reagent(impure_chem, impureVol, FALSE, other_purity = 1-cached_purity) + log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume - impureVol]u of [id]") + log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [impure_chem]") return /datum/reagent/proc/on_update(atom/A) @@ -146,4 +213,4 @@ for (var/datum/reagent/R in reagent_list) rs += "[R.name], [R.volume]" - return rs.Join(" | ") + return rs.Join(" | ") \ No newline at end of file diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 7239da4a..b447802c 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -1384,6 +1384,10 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Neurotoxin" glass_desc = "A drink that is guaranteed to knock you silly." pH = 4.3 + //SplitChem = TRUE + impure_chem = "neuroweak" + inverse_chem_val = 0.5 //Clear conversion + inverse_chem = "neuroweak" /datum/reagent/consumable/ethanol/neurotoxin/proc/pickt() return (pick(TRAIT_PARALYSIS_L_ARM,TRAIT_PARALYSIS_R_ARM,TRAIT_PARALYSIS_R_LEG,TRAIT_PARALYSIS_L_LEG)) diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents.dm new file mode 100644 index 00000000..6251fbf7 --- /dev/null +++ b/code/modules/reagents/chemistry/reagents/impure_reagents.dm @@ -0,0 +1,26 @@ +//Reagents produced by metabolising/reacting fermichems inoptimally, i.e. inverse_chems or impure_chems +//Inverse = Splitting +//Invert = Whole conversion + +/datum/reagent/impure + chemical_flags = REAGENT_INVISIBLE | REAGENT_SNEAKYNAME //by default, it will stay hidden on splitting, but take the name of the source on inverting + + +/datum/reagent/impure/fermiTox + name = "Chemical Isomers" + id = "fermiTox" + description = "Toxic chemical isomers made from impure reactions. At low volumes will cause light toxin damage, but as the volume increases, it deals larger amounts, damages the liver, then eventually the heart." + data = "merge" + color = "FFFFFF" + can_synth = FALSE + var/potency = 1 //potency multiplies the volume when added. + + +//I'm concerned this is too weak, but I also don't want deathmixes. +//TODO: liver damage, 100+ heart +/datum/reagent/impure/fermiTox/on_mob_life(mob/living/carbon/C, method) + if(C.dna && istype(C.dna.species, /datum/species/jelly)) + C.adjustToxLoss(-2) + else + C.adjustToxLoss(2) + ..() \ No newline at end of file diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index aa8faa5f..7ff2a40d 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -236,10 +236,12 @@ /datum/reagent/medicine/silver_sulfadiazine name = "Silver Sulfadiazine" id = "silver_sulfadiazine" - description = "If used in touch-based applications, immediately restores burn wounds as well as restoring more over time. If ingested through other means, deals minor toxin damage." + description = "If used in touch-based applications, immediately restores burn wounds as well as restoring more over time. It is mildly poisonous taken orally or by injection. If overdosed, deals brute and minor liver damage." reagent_state = LIQUID pH = 7.2 color = "#ffeac9" + metabolization_rate = 5 * REAGENTS_METABOLISM + overdose_threshold = 50 /datum/reagent/medicine/silver_sulfadiazine/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M) && M.stat != DEAD) @@ -260,6 +262,15 @@ ..() . = 1 +/datum/reagent/medicine/silver_sulfadiazine/overdose_start(mob/living/M) + metabolization_rate = 15 * REAGENTS_METABOLISM + M.adjustBruteLoss(2*REM, 0) + if(iscarbon(M)) + var/mob/living/carbon/C = M + C.applyLiverDamage(1) + ..() + . = 1 + /datum/reagent/medicine/oxandrolone name = "Oxandrolone" id = "oxandrolone" @@ -287,10 +298,12 @@ /datum/reagent/medicine/styptic_powder name = "Styptic Powder" id = "styptic_powder" - description = "If used in touch-based applications, immediately restores bruising as well as restoring more over time. If ingested through other means, deals minor toxin damage." + description = "If used in touch-based applications, immediately restores bruising as well as restoring more over time. It is poisonous if taken orally or by injection. If overdosed, deals brute and minor liver damage." reagent_state = LIQUID color = "#FF9696" pH = 6.7 + metabolization_rate = 5 * REAGENTS_METABOLISM + overdose_threshold = 50 /datum/reagent/medicine/styptic_powder/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M) && M.stat != DEAD) @@ -312,6 +325,15 @@ ..() . = 1 +datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) + metabolization_rate = 15 * REAGENTS_METABOLISM + M.adjustBruteLoss(2*REM, 0) + if(iscarbon(M)) + var/mob/living/carbon/C = M + C.applyLiverDamage(1) + ..() + . = 1 + /datum/reagent/medicine/salglu_solution name = "Saline-Glucose Solution" id = "salglu_solution" @@ -398,23 +420,35 @@ /datum/reagent/medicine/synthflesh name = "Synthflesh" id = "synthflesh" - description = "Has a 100% chance of instantly healing brute and burn damage. One unit of the chemical will heal one point of damage. Touch application only." + description = "Has a 100% chance of healing large amounts of brute and burn damage very quickly. One unit of the chemical will heal one point of damage. Touch application only." reagent_state = LIQUID color = "#FFEBEB" pH = 11.5 + metabolization_rate = 5 * REAGENTS_METABOLISM + overdose_threshold = 40 /datum/reagent/medicine/synthflesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume,show_message = 1) if(iscarbon(M)) if (M.stat == DEAD) show_message = 0 - if(method in list(PATCH, TOUCH)) - M.adjustBruteLoss(-1.25 * reac_volume) - M.adjustFireLoss(-1.25 * reac_volume) + if(method in list(INGEST, VAPOR)) + var/mob/living/carbon/C = M + C.losebreath++ + C.emote("cough") + to_chat(M, "You feel your throat closing up!") + else if(method == INJECT) + return + else if(method in list(PATCH, TOUCH)) + M.adjustBruteLoss(-1 * reac_volume) + M.adjustFireLoss(-1 * reac_volume) if(show_message) to_chat(M, "You feel your burns and bruises healing! It stings like hell!") SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine) ..() +/datum/reagent/medicine/synthflesh/overdose_start(mob/living/M) + metabolization_rate = 15 * REAGENTS_METABOLISM + /datum/reagent/medicine/charcoal name = "Charcoal" id = "charcoal" diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 5ca1e31f..aebeed65 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -1587,7 +1587,7 @@ color = "#ffa6ff" //rgb: 255,166,255 taste_description = "a bad idea" id = "laughtervirusfood" - + /datum/reagent/consumable/virus_food/advvirusfood name = "highly unstable virus food" color = "#ffffff" //rgb: 255,255,255 ITS PURE WHITE CMON @@ -2151,7 +2151,7 @@ can_synth = FALSE var/datum/dna/original_dna var/reagent_ticks = 0 - invisible = TRUE + chemical_flags = REAGENT_INVISIBLE /datum/reagent/changeling_string/on_mob_metabolize(mob/living/carbon/C) if(C && C.dna && data["desired_dna"]) diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm index 32155c9b..a9150874 100644 --- a/code/modules/reagents/chemistry/recipes.dm +++ b/code/modules/reagents/chemistry/recipes.dm @@ -32,6 +32,7 @@ var/RateUpLim = 10 // Optimal/max rate possible if all conditions are perfect var/FermiChem = FALSE // If the chemical uses the Fermichem reaction mechanics//If the chemical uses the Fermichem reaction mechanics var/FermiExplode = FALSE // If the chemical explodes in a special way + var/clear_conversion //bitflags for clear conversions; REACTION_CLEAR_IMPURE or REACTION_CLEAR_INVERSE var/PurityMin = 0.15 //If purity is below 0.15, it explodes too. Set to 0 to disable this. diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index fe9f7d62..5521c40c 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -17,6 +17,7 @@ var/spillable = FALSE var/beaker_weakness_bitflag = NONE//Bitflag! var/container_HP = 2 + var/cached_icon var/splashable = FALSE /obj/item/reagent_containers/Initialize(mapload, vol) @@ -149,30 +150,71 @@ /obj/item/reagent_containers/proc/temp_check() if(beaker_weakness_bitflag & TEMP_WEAK) if(reagents.chem_temp >= 444)//assuming polypropylene - var/list/seen = viewers(5, get_turf(src)) - var/iconhtml = icon2html(src, seen) - for(var/mob/M in seen) - to_chat(M, "[iconhtml] \The [src]'s melts from the temperature!") - playsound(get_turf(src), 'sound/FermiChem/heatmelt.ogg', 80, 1) - to_chat(M, "[iconhtml] Have you tried using glass or meta beakers for high temperature reactions? These are immune to temperature effects.") - SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times beakers have melted from temperature") - qdel(src) + START_PROCESSING(SSobj, src) //melts glass beakers /obj/item/reagent_containers/proc/pH_check() if(beaker_weakness_bitflag & PH_WEAK) - if((reagents.pH < 0.5) || (reagents.pH > 13.5)) - var/list/seen = viewers(5, get_turf(src)) - var/iconhtml = icon2html(src, seen) - container_HP-- - if(container_HP <= 0) - for(var/mob/M in seen) - to_chat(M, "[iconhtml] \The [src]'s melts from the extreme pH!") - playsound(get_turf(src), 'sound/FermiChem/acidmelt.ogg', 80, 1) - SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times beakers have melted from pH") - qdel(src) + if((reagents.pH < 1.5) || (reagents.pH > 12.5)) + START_PROCESSING(SSobj, src) + + +/obj/item/reagent_containers/process() + if(!cached_icon) + cached_icon = icon_state + var/damage + var/cause + if(beaker_weakness_bitflag & PH_WEAK) + if(reagents.pH < 2) + damage = (2 - reagents.pH)/20 + cause = "from the extreme pH" + playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1) + + if(reagents.pH > 12) + damage = (reagents.pH - 12)/20 + cause = "from the extreme pH" + playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1) + + if(beaker_weakness_bitflag & TEMP_WEAK) + if(reagents.chem_temp >= 444) + if(damage) + damage += (reagents.chem_temp/444)/5 else - for(var/mob/M in seen) - to_chat(M, "[iconhtml] \The [src]'s is damaged by the extreme pH and begins to deform!") - playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1) - to_chat(M, "[iconhtml] Have you tried using plastic beakers (XL) or metabeakers for high pH reactions? These beakers are immune to pH effects.") + damage = (reagents.chem_temp/444)/5 + if(cause) + cause += " and " + cause += "from the high temperature" + playsound(get_turf(src), 'sound/FermiChem/heatdam.ogg', 50, 1) + + if(!damage || damage <= 0) + STOP_PROCESSING(SSobj, src) + + container_HP -= damage + + var/list/seen = viewers(5, get_turf(src)) + var/iconhtml = icon2html(src, seen) + + var/damage_percent = ((container_HP / initial(container_HP)*100)) + switch(damage_percent) + if(-INFINITY to 0) + for(var/mob/M in seen) + to_chat(M, "[iconhtml] \The [src]'s melts [cause]!") + playsound(get_turf(src), 'sound/FermiChem/acidmelt.ogg', 80, 1) + SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times beakers have melted") + STOP_PROCESSING(SSobj, src) + qdel(src) + return + if(0 to 35) + icon_state = "[cached_icon]_m3" + desc = "[initial(desc)] It is severely deformed." + if(35 to 70) + icon_state = "[cached_icon]_m2" + desc = "[initial(desc)] It is deformed." + if(70 to 85) + desc = "[initial(desc)] It is mildly deformed." + icon_state = "[cached_icon]_m1" + + update_icon() + if(prob(25)) + for(var/mob/M in seen) + to_chat(M, "[iconhtml] \The [src]'s is damaged by [cause] and begins to deform!") \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm index 31e893aa..3e555f38 100644 --- a/code/modules/reagents/reagent_containers/blood_pack.dm +++ b/code/modules/reagents/reagent_containers/blood_pack.dm @@ -90,3 +90,9 @@ update_pack_name() else return ..() + +/obj/item/reagent_containers/blood/bluespace + name = "bluespace blood pack" + desc = "Contains blood used for transfusion, this one has been made with bluespace technology to hold much more blood. Must be attached to an IV drip." + icon_state = "bsbloodpack" + volume = 600 //its a blood bath! \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index b886b2da..6df151fc 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -6,7 +6,7 @@ reagent_flags = OPENCONTAINER spillable = TRUE resistance_flags = ACID_PROOF - container_HP = 3 + container_HP = 2 /obj/item/reagent_containers/glass/attack(mob/M, mob/user, obj/target) @@ -115,7 +115,6 @@ item_state = "beaker" materials = list(MAT_GLASS=500) beaker_weakness_bitflag = PH_WEAK - container_HP = 5 /obj/item/reagent_containers/glass/beaker/Initialize() . = ..() @@ -126,34 +125,36 @@ /obj/item/reagent_containers/glass/beaker/on_reagent_change(changetype) update_icon() - + /obj/item/reagent_containers/glass/bottle/viralbase name = "Highly potent Viral Base Bottle" desc = "A small bottle. Contains a trace amount of a substance found by scientists that can be used to create extremely advanced diseases once exposed to uranium." list_reagents = list("viralbase" = 1) /obj/item/reagent_containers/glass/beaker/update_icon() + if(!cached_icon) + cached_icon = icon_state cut_overlays() if(reagents.total_volume) - var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[icon_state]10") + var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[cached_icon]10") var/percent = round((reagents.total_volume / volume) * 100) switch(percent) if(0 to 9) - filling.icon_state = "[icon_state]-10" + filling.icon_state = "[cached_icon]-10" if(10 to 24) - filling.icon_state = "[icon_state]10" + filling.icon_state = "[cached_icon]10" if(25 to 49) - filling.icon_state = "[icon_state]25" + filling.icon_state = "[cached_icon]25" if(50 to 74) - filling.icon_state = "[icon_state]50" + filling.icon_state = "[cached_icon]50" if(75 to 79) - filling.icon_state = "[icon_state]75" + filling.icon_state = "[cached_icon]75" if(80 to 90) - filling.icon_state = "[icon_state]80" + filling.icon_state = "[cached_icon]80" if(91 to INFINITY) - filling.icon_state = "[icon_state]100" + filling.icon_state = "[cached_icon]100" filling.color = mix_color_from_reagents(reagents.reagent_list) add_overlay(filling) @@ -172,7 +173,7 @@ volume = 100 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,20,25,30,50,100) - container_HP = 6 + container_HP = 3 /obj/item/reagent_containers/glass/beaker/plastic name = "x-large beaker" @@ -232,7 +233,7 @@ volume = 300 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300) - container_HP = 8 + container_HP = 4 /obj/item/reagent_containers/glass/beaker/cryoxadone list_reagents = list("cryoxadone" = 30) @@ -289,7 +290,7 @@ SLOT_L_STORE, SLOT_R_STORE,\ SLOT_GENERC_DEXTROUS_STORAGE ) - container_HP = 2 + container_HP = 1 /obj/item/reagent_containers/glass/bucket/Initialize() beaker_weakness_bitflag |= TEMP_WEAK @@ -343,7 +344,7 @@ materials = list(MAT_GLASS=0) volume = 50 amount_per_transfer_from_this = 10 - container_HP = 2 + container_HP = 1 /obj/item/reagent_containers/glass/beaker/waterbottle/Initialize() beaker_weakness_bitflag |= TEMP_WEAK @@ -359,7 +360,7 @@ list_reagents = list("water" = 100) volume = 100 amount_per_transfer_from_this = 20 - container_HP = 2 + container_HP = 1 /obj/item/reagent_containers/glass/beaker/waterbottle/large/empty list_reagents = list() diff --git a/code/modules/reagents/reagent_containers/medspray.dm b/code/modules/reagents/reagent_containers/medspray.dm index 54a38eef..df7c7af2 100644 --- a/code/modules/reagents/reagent_containers/medspray.dm +++ b/code/modules/reagents/reagent_containers/medspray.dm @@ -19,8 +19,8 @@ var/can_fill_from_container = TRUE var/apply_type = PATCH var/apply_method = "spray" - var/self_delay = 30 - var/squirt_mode = 0 + var/self_delay = 3 SECONDS + var/squirt_mode = FALSE var/squirt_amount = 5 /obj/item/reagent_containers/medspray/attack_self(mob/user) @@ -31,40 +31,51 @@ amount_per_transfer_from_this = initial(amount_per_transfer_from_this) to_chat(user, "You will now apply the medspray's contents in [squirt_mode ? "short bursts":"extended sprays"]. You'll now use [amount_per_transfer_from_this] units per use.") -/obj/item/reagent_containers/medspray/attack(mob/M, mob/user, def_zone) +/obj/item/reagent_containers/medspray/attack(mob/living/L, mob/user, def_zone) if(!reagents || !reagents.total_volume) to_chat(user, "[src] is empty!") return - if(M == user) - M.visible_message("[user] attempts to [apply_method] [src] on [user.p_them()]self.") + if(ishuman(L)) + var/obj/item/bodypart/affecting = L.get_bodypart(check_zone(user.zone_selected)) + if(!affecting) + to_chat(user, "The limb is missing!") + return + if(!L.can_inject(user, TRUE, user.zone_selected, FALSE, TRUE)) //stopped by clothing, like patches + return + if(affecting.status != BODYPART_ORGANIC) + to_chat(user, "Medicine won't work on a robotic limb!") + return + + if(L == user) + L.visible_message("[user] attempts to [apply_method] [src] on [user.p_them()]self.") if(self_delay) - if(!do_mob(user, M, self_delay)) + if(!do_mob(user, L, self_delay)) return if(!reagents || !reagents.total_volume) return - to_chat(M, "You [apply_method] yourself with [src].") + to_chat(L, "You [apply_method] yourself with [src].") else - log_combat(user, M, "attempted to apply", src, reagents.log_list()) - M.visible_message("[user] attempts to [apply_method] [src] on [M].", \ - "[user] attempts to [apply_method] [src] on [M].") - if(!do_mob(user, M)) + log_combat(user, L, "attempted to apply", src, reagents.log_list()) + L.visible_message("[user] attempts to [apply_method] [src] on [L].", \ + "[user] attempts to [apply_method] [src] on [L].") + if(!do_mob(user, L)) return if(!reagents || !reagents.total_volume) return - M.visible_message("[user] [apply_method]s [M] down with [src].", \ - "[user] [apply_method]s [M] down with [src].") + L.visible_message("[user] [apply_method]s [L] down with [src].", \ + "[user] [apply_method]s [L] down with [src].") if(!reagents || !reagents.total_volume) return else - log_combat(user, M, "applied", src, reagents.log_list()) + log_combat(user, L, "applied", src, reagents.log_list()) playsound(src, 'sound/effects/spray2.ogg', 50, 1, -6) var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1) - reagents.reaction(M, apply_type, fraction) - reagents.trans_to(M, amount_per_transfer_from_this) + reagents.reaction(L, apply_type, fraction) + reagents.trans_to(L, amount_per_transfer_from_this) return /obj/item/reagent_containers/medspray/styptic diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index b24b0cff..d95f4eeb 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -738,6 +738,13 @@ research_icon_state = "surgery_any" var/surgery +/datum/design/surgery/experimental_dissection + name = "Experimental Dissection" + desc = "A surgical procedure which deeply analyzes the biology of a corpse, and automatically adds new findings to the research database." + id = "surgery_exp_dissection" + surgery = /datum/surgery/advanced/bioware/experimental_dissection + research_icon_state = "surgery_chest" + /datum/design/surgery/lobotomy name = "Lobotomy" desc = "An invasive surgical procedure which guarantees removal of almost all brain traumas, but might cause another permanent trauma in return." @@ -808,6 +815,22 @@ surgery = /datum/surgery/advanced/bioware/vein_threading research_icon_state = "surgery_chest" +/datum/design/surgery/ligament_hook + name = "Ligament Hook" + desc = "A surgical procedure which reshapes the connections between torso and limbs, making it so limbs can be attached manually if severed. \ + However this weakens the connection, making them easier to detach as well." + id = "surgery_ligament_hook" + surgery = /datum/surgery/advanced/bioware/ligament_hook + research_icon_state = "surgery_chest" + +/datum/design/surgery/ligament_reinforcement + name = "Ligament Reinforcement" + desc = "A surgical procedure which adds a protective tissue and bone cage around the connections between the torso and limbs, preventing dismemberment. \ + However, the nerve connections as a result are more easily interrupted, making it easier to disable limbs with damage." + id = "surgery_ligament_reinforcement" + surgery = /datum/surgery/advanced/bioware/ligament_reinforcement + research_icon_state = "surgery_chest" + /datum/design/surgery/necrotic_revival name = "Necrotic Revival" desc = "An experimental surgical procedure that stimulates the growth of a Romerol tumor inside the patient's brain. Requires zombie powder or rezadone." @@ -907,7 +930,15 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - +/datum/design/bsblood_bag + name = "Blue Space Empty Blood Bag" + desc = "A large sterilized plastic bag for blood." + id = "bsblood_bag" + build_path = /obj/item/reagent_containers/blood/bluespace + build_type = PROTOLATHE + materials = list(MAT_GLASS = 2500, MAT_PLASTIC = 4500, MAT_BLUESPACE = 250) + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/adv_dis_hypo name = "Disposable Hypospray MK.II" diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 214ef36a..7dd85ea1 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -17,6 +17,36 @@ id = "sec_38lethal" build_path = /obj/item/ammo_box/c38/lethal +/datum/design/c38_trac + name = "Speed Loader (.38 TRAC)" + desc = "Designed to quickly reload revolvers. TRAC bullets embed a tracking implant within the target's body." + id = "c38_trac" + build_type = PROTOLATHE + materials = list(MAT_METAL = 20000, MAT_SILVER = 5000, MAT_GOLD = 1000) + build_path = /obj/item/ammo_box/c38/trac + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/c38_hotshot + name = "Speed Loader (.38 Hot Shot)" + desc = "Designed to quickly reload revolvers. Hot Shot bullets contain an incendiary payload." + id = "c38_hotshot" + build_type = PROTOLATHE + materials = list(MAT_METAL = 20000, MAT_PLASMA = 5000) + build_path = /obj/item/ammo_box/c38/hotshot + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/c38_iceblox + name = "Speed Loader (.38 Iceblox)" + desc = "Designed to quickly reload revolvers. Iceblox bullets contain a cryogenic payload." + id = "c38_iceblox" + build_type = PROTOLATHE + materials = list(MAT_METAL = 20000, MAT_PLASMA = 5000) + build_path = /obj/item/ammo_box/c38/iceblox + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + ////////////// //WT550 Mags// ////////////// diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 63525f03..843244c5 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -116,7 +116,7 @@ display_name = "Advanced Surgery" description = "When simple medicine doesn't cut it." prereq_ids = list("adv_biotech") - design_ids = list("surgery_lobotomy", "surgery_reconstruction","surgery_toxinhealing", "organbox",) + design_ids = list("surgery_lobotomy", "surgery_reconstruction","surgery_toxinhealing", "organbox", "surgery_exp_dissection") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -125,7 +125,7 @@ display_name = "Experimental Surgery" description = "When evolution isn't fast enough." prereq_ids = list("adv_surgery") - design_ids = list("surgery_revival","surgery_pacify","surgery_vein_thread","surgery_nerve_splice","surgery_nerve_ground","surgery_viral_bond") + design_ids = list("surgery_revival","surgery_pacify","surgery_vein_thread","surgery_nerve_splice","surgery_ligament_hook","surgery_ligament_reinforcement","surgery_nerve_ground","surgery_viral_bond") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) export_price = 5000 @@ -273,7 +273,7 @@ display_name = "Bluespace Pockets" description = "Studies into the mysterious alternate dimension known as bluespace and how to place items in the threads of reality." prereq_ids = list("adv_power", "adv_bluespace", "adv_biotech", "adv_plasma") - design_ids = list( "bluespacebodybag","bag_holding", "bluespace_pod", "borg_upgrade_trashofholding", "blutrash", "satchel_holding") + design_ids = list( "bluespacebodybag","bag_holding", "bluespace_pod", "borg_upgrade_trashofholding", "blutrash", "satchel_holding", "bsblood_bag") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5500) export_price = 5000 @@ -518,7 +518,7 @@ display_name = "Subdermal Implants" description = "Electronic implants buried beneath the skin." prereq_ids = list("biotech", "datatheory") - design_ids = list("implanter", "implantcase", "implant_chem", "implant_tracking", "locator") + design_ids = list("implanter", "implantcase", "implant_chem", "implant_tracking", "locator", "c38_trac") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -694,12 +694,12 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2750) export_price = 5000 -/datum/techweb_node/tech_shell - id = "tech_shell" - display_name = "Technological Shells" - description = "They're more technological than regular shot." +/datum/techweb_node/exotic_ammo + id = "exotic_ammo" + display_name = "Exotic Ammunition" + description = "They won't know what hit em." prereq_ids = list("weaponry", "ballistic_weapons") - design_ids = list("techshotshell") + design_ids = list("techshotshell", "c38_hotshot", "c38_iceblox") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500) export_price = 5000 @@ -1017,7 +1017,7 @@ prereq_ids = list("biotech","engineering") boost_item_paths = list(/obj/item/gun/energy/alien, /obj/item/scalpel/alien, /obj/item/hemostat/alien, /obj/item/retractor/alien, /obj/item/circular_saw/alien, /obj/item/cautery/alien, /obj/item/surgicaldrill/alien, /obj/item/screwdriver/abductor, /obj/item/wrench/abductor, /obj/item/crowbar/abductor, /obj/item/multitool/abductor, - /obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor, /obj/item/stack/sheet/mineral/abductor) + /obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor, /obj/item/stack/sheet/mineral/abductor, /obj/item/stock_parts/cell/infinite/abductor) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) export_price = 20000 hidden = TRUE @@ -1031,7 +1031,7 @@ design_ids = list("alien_scalpel", "alien_hemostat", "alien_retractor", "alien_saw", "alien_drill", "alien_cautery") boost_item_paths = list(/obj/item/gun/energy/alien, /obj/item/scalpel/alien, /obj/item/hemostat/alien, /obj/item/retractor/alien, /obj/item/circular_saw/alien, /obj/item/cautery/alien, /obj/item/surgicaldrill/alien, /obj/item/screwdriver/abductor, /obj/item/wrench/abductor, /obj/item/crowbar/abductor, /obj/item/multitool/abductor, - /obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor) + /obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor, /obj/item/stock_parts/cell/infinite/abductor) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 20000 hidden = TRUE @@ -1043,7 +1043,7 @@ prereq_ids = list("alientech", "adv_engi") design_ids = list("alien_wrench", "alien_wirecutters", "alien_screwdriver", "alien_crowbar", "alien_welder", "alien_multitool") boost_item_paths = list(/obj/item/screwdriver/abductor, /obj/item/wrench/abductor, /obj/item/crowbar/abductor, /obj/item/multitool/abductor, - /obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor) + /obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor, /obj/item/stock_parts/cell/infinite/abductor) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 20000 hidden = TRUE diff --git a/code/modules/research/xenobiology/crossbreeding/_weapons.dm b/code/modules/research/xenobiology/crossbreeding/_weapons.dm index 4753abff..1b2f43c5 100644 --- a/code/modules/research/xenobiology/crossbreeding/_weapons.dm +++ b/code/modules/research/xenobiology/crossbreeding/_weapons.dm @@ -27,9 +27,9 @@ return 0 charge_tick = 0 var/mob/living/M = loc - if(istype(M) && M.blood_volume >= 20) + if(istype(M) && M.blood_volume >= 5) charges++ - M.blood_volume -= 20 + M.blood_volume -= 5 if(charges == 1) recharge_newshot() return 1 diff --git a/code/modules/spells/spell_types/lichdom.dm b/code/modules/spells/spell_types/lichdom.dm index efc80101..0cbb3a82 100644 --- a/code/modules/spells/spell_types/lichdom.dm +++ b/code/modules/spells/spell_types/lichdom.dm @@ -57,7 +57,7 @@ new /obj/item/phylactery(marked_item, M.mind) to_chat(M, "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!") - M.set_species(/datum/species/skeleton) + M.set_species(/datum/species/skeleton/space) if(ishuman(M)) var/mob/living/carbon/human/H = M H.dropItemToGround(H.w_uniform) @@ -132,7 +132,7 @@ lich.real_name = mind.name mind.transfer_to(lich) mind.grab_ghost(force=TRUE) - lich.hardset_dna(null,null,lich.real_name,null, new /datum/species/skeleton) + lich.hardset_dna(null,null,lich.real_name,null, new /datum/species/skeleton/space) to_chat(lich, "Your bones clatter and shudder as you are pulled back into this world!") var/turf/body_turf = get_turf(old_body) lich.Knockdown(200 + 200*resurrections) diff --git a/code/modules/surgery/advanced/bioware/experimental_dissection..dm b/code/modules/surgery/advanced/bioware/experimental_dissection..dm new file mode 100644 index 00000000..6266480b --- /dev/null +++ b/code/modules/surgery/advanced/bioware/experimental_dissection..dm @@ -0,0 +1,72 @@ +/datum/surgery/advanced/bioware/experimental_dissection + name = "Experimental Dissection" + desc = "A surgical procedure which deeply analyzes the biology of a corpse, and automatically adds new findings to the research database." + steps = list(/datum/surgery_step/incise, + /datum/surgery_step/retract_skin, + /datum/surgery_step/clamp_bleeders, + /datum/surgery_step/incise, + /datum/surgery_step/dissection, + /datum/surgery_step/close) + possible_locs = list(BODY_ZONE_CHEST) + bioware_target = BIOWARE_DISSECTION + +/datum/surgery/advanced/bioware/experimental_dissection/can_start(mob/user, mob/living/carbon/target) + . = ..() + if(iscyborg(user)) + return FALSE //robots cannot be creative + //(also this surgery shouldn't be consistently successful, and cyborgs have a 100% success rate on surgery) + if(target.stat != DEAD) + return FALSE + +/datum/surgery_step/dissection + name = "dissection" + implements = list(/obj/item/scalpel = 60, /obj/item/kitchen/knife = 30, /obj/item/shard = 15) + time = 125 + +/datum/surgery_step/dissection/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + display_results(user, target, "You start dissecting [target].", + "[user] starts dissecting [target].", + "[user] starts dissecting [target].") + +/datum/surgery_step/dissection/proc/check_value(mob/living/carbon/target) + if(isalienroyal(target)) + return 10000 + else if(isalienadult(target)) + return 5000 + else if(ismonkey(target)) + return 1000 + else if(ishuman(target)) + var/mob/living/carbon/human/H = target + if(H.dna && H.dna.species) + if(isabductor(H)) + return 8000 + if(isgolem(H) || iszombie(H)) + return 4000 + if(isjellyperson(H) || ispodperson(H)) + return 3000 + return 2000 + +/datum/surgery_step/dissection/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + display_results(user, target, "You dissect [target], and add your discoveries to the research database!", + "[user] dissects [target], adding [user.p_their()] discoveries to the research database!", + "[user] dissects [target]!") + SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = check_value(target))) + var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST) + target.apply_damage(80, BRUTE, L) + new /datum/bioware/dissected(target) + return TRUE + +/datum/surgery_step/dissection/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + display_results(user, target, "You dissect [target], but do not find anything particularly interesting.", + "[user] dissects [target], however it seems [user.p_they()] didn't find anything useful.", + "[user] dissects [target], but looks a little dissapointed.") + SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = (check_value(target) * 0.2))) + var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST) + target.apply_damage(80, BRUTE, L) + new /datum/bioware/dissected(target) + return TRUE + +/datum/bioware/dissected + name = "Dissected" + desc = "This body has been dissected and analyzed. It is no longer worth experimenting on." + mod_type = BIOWARE_DISSECTION \ No newline at end of file diff --git a/code/modules/surgery/advanced/bioware/ligament_hook.dm b/code/modules/surgery/advanced/bioware/ligament_hook.dm new file mode 100644 index 00000000..2c154436 --- /dev/null +++ b/code/modules/surgery/advanced/bioware/ligament_hook.dm @@ -0,0 +1,45 @@ +/datum/surgery/advanced/bioware/ligament_hook + name = "Ligament Hook" + desc = "A surgical procedure which reshapes the connections between torso and limbs, making it so limbs can be attached manually if severed. \ + However this weakens the connection, making them easier to detach as well." + steps = list(/datum/surgery_step/incise, + /datum/surgery_step/retract_skin, + /datum/surgery_step/clamp_bleeders, + /datum/surgery_step/incise, + /datum/surgery_step/incise, + /datum/surgery_step/reshape_ligaments, + /datum/surgery_step/close) + possible_locs = list(BODY_ZONE_CHEST) + bioware_target = BIOWARE_LIGAMENTS + +/datum/surgery_step/reshape_ligaments + name = "reshape ligaments" + accept_hand = TRUE + time = 125 + +/datum/surgery_step/reshape_ligaments/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + display_results(user, target, "You start reshaping [target]'s ligaments into a hook-like shape.", + "[user] starts reshaping [target]'s ligaments into a hook-like shape.", + "[user] starts manipulating [target]'s ligaments.") + +/datum/surgery_step/reshape_ligaments/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + display_results(user, target, "You finish reshaping [target]'s ligaments into a connective hook!", + "[user] finishes reshaping [target]'s ligaments into a connective hook!", + "[user] finishes manipulating [target]'s ligaments!") + new /datum/bioware/hooked_ligaments(target) + return TRUE + +/datum/bioware/hooked_ligaments + name = "Hooked Ligaments" + desc = "The ligaments and nerve endings that connect the torso to the limbs are formed into a hook-like shape, so limbs can be attached without requiring surgery, but are easier to sever." + mod_type = BIOWARE_LIGAMENTS + +/datum/bioware/hooked_ligaments/on_gain() + ..() + ADD_TRAIT(owner, TRAIT_LIMBATTACHMENT, "ligament_hook") + ADD_TRAIT(owner, TRAIT_EASYDISMEMBER, "ligament_hook") + +/datum/bioware/hooked_ligaments/on_lose() + ..() + REMOVE_TRAIT(owner, TRAIT_LIMBATTACHMENT, "ligament_hook") + REMOVE_TRAIT(owner, TRAIT_EASYDISMEMBER, "ligament_hook") \ No newline at end of file diff --git a/code/modules/surgery/advanced/bioware/ligament_reinforcement.dm b/code/modules/surgery/advanced/bioware/ligament_reinforcement.dm new file mode 100644 index 00000000..ac034fce --- /dev/null +++ b/code/modules/surgery/advanced/bioware/ligament_reinforcement.dm @@ -0,0 +1,45 @@ +/datum/surgery/advanced/bioware/ligament_reinforcement + name = "Ligament Reinforcement" + desc = "A surgical procedure which adds a protective tissue and bone cage around the connections between the torso and limbs, preventing dismemberment. \ + However, the nerve connections as a result are more easily interrupted, making it easier to disable limbs with damage." + steps = list(/datum/surgery_step/incise, + /datum/surgery_step/retract_skin, + /datum/surgery_step/clamp_bleeders, + /datum/surgery_step/incise, + /datum/surgery_step/incise, + /datum/surgery_step/reinforce_ligaments, + /datum/surgery_step/close) + possible_locs = list(BODY_ZONE_CHEST) + bioware_target = BIOWARE_LIGAMENTS + +/datum/surgery_step/reinforce_ligaments + name = "reinforce ligaments" + accept_hand = TRUE + time = 125 + +/datum/surgery_step/reinforce_ligaments/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + display_results(user, target, "You start reinforcing [target]'s ligaments.", + "[user] starts reinforcing [target]'s ligaments.", + "[user] starts manipulating [target]'s ligaments.") + +/datum/surgery_step/reinforce_ligaments/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + display_results(user, target, "You finish reinforcing [target]'s ligaments!", + "[user] finishes reinforcing [target]'s ligaments!", + "[user] finishes manipulating [target]'s ligaments!") + new /datum/bioware/reinforced_ligaments(target) + return TRUE + +/datum/bioware/reinforced_ligaments + name = "Reinforced Ligaments" + desc = "The ligaments and nerve endings that connect the torso to the limbs are protected by a mix of bone and tissues, and are much harder to separate from the body, but are also easier to disable." + mod_type = BIOWARE_LIGAMENTS + +/datum/bioware/reinforced_ligaments/on_gain() + ..() + ADD_TRAIT(owner, TRAIT_NODISMEMBER, "reinforced_ligaments") + ADD_TRAIT(owner, TRAIT_EASYLIMBDISABLE, "reinforced_ligaments") + +/datum/bioware/reinforced_ligaments/on_lose() + ..() + REMOVE_TRAIT(owner, TRAIT_NODISMEMBER, "reinforced_ligaments") + REMOVE_TRAIT(owner, TRAIT_EASYLIMBDISABLE, "reinforced_ligaments") \ No newline at end of file diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm index f79cdaee..4dda78ec 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -235,7 +235,7 @@ return BODYPART_DISABLED_PARALYSIS if(can_dismember() && !HAS_TRAIT(owner, TRAIT_NODISMEMBER)) . = disabled //inertia, to avoid limbs healing 0.1 damage and being re-enabled - if((get_damage(TRUE) >= max_damage)) + if((get_damage(TRUE) >= max_damage) || (HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE) && (get_damage(TRUE) >= (max_damage * 0.6)))) //Easy limb disable disables the limb at 40% health instead of 0% return BODYPART_DISABLED_DAMAGE if(disabled && (get_damage(TRUE) <= (max_damage * 0.5))) return BODYPART_NOT_DISABLED @@ -861,7 +861,7 @@ icon_state = "default_monkey_r_leg" animal_origin = MONKEY_BODYPART px_y = 4 - + /obj/item/bodypart/r_leg/monkey/teratoma icon_state = "teratoma_r_leg" animal_origin = TERATOMA_BODYPART diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 95258c70..9d1c0e0c 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -374,3 +374,7 @@ name = "insect eyes" desc = "These eyes seem to have increased sensitivity to bright light, with no improvement to low light vision." flash_protect = -1 + +/obj/item/organ/eyes/ipc + name = "ipc eyes" + icon_state = "cybernetic_eyeballs" \ No newline at end of file diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index 0f9017fb..977a33b8 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -210,7 +210,10 @@ obj/item/organ/heart/cybernetic/upgraded/on_life() addtimer(VARSET_CALLBACK(src, dose_available, TRUE), 5 MINUTES) ramount = 0 - +/obj/item/organ/heart/ipc + name = "IPC heart" + desc = "An electronic pump that regulates hydraulic functions, the electronics have EMP shielding." + icon_state = "heart-c" /obj/item/organ/heart/freedom name = "heart of freedom" diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index bfffe9b6..3c80838f 100644 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -96,6 +96,10 @@ icon_state = "liver-p" desc = "A large crystal that is somehow capable of metabolizing chemicals, these are found in plasmamen." +/obj/item/organ/liver/ipc + name = "reagent processing liver" + icon_state = "liver-c" + /obj/item/organ/liver/cybernetic name = "cybernetic liver" icon_state = "liver-c" diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index d3805c5c..5452a1aa 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -2,6 +2,7 @@ /obj/item/organ/lungs name = "lungs" + desc = "Looking at them makes you start manual breathing." icon_state = "lungs" zone = BODY_ZONE_CHEST slot = ORGAN_SLOT_LUNGS @@ -461,6 +462,10 @@ S.reagents.add_reagent("salbutamol", 5) return S +/obj/item/organ/lungs/ipc + name = "ipc lungs" + icon_state = "lungs-c" + /obj/item/organ/lungs/plasmaman name = "plasma filter" desc = "A spongy rib-shaped mass for filtering plasma from the air." diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm index 93210fe3..1d1aa3d6 100644 --- a/code/modules/surgery/organs/stomach.dm +++ b/code/modules/surgery/organs/stomach.dm @@ -96,3 +96,7 @@ name = "digestive crystal" icon_state = "stomach-p" desc = "A strange crystal that is responsible for metabolizing the unseen energy force that feeds plasmamen." + +/obj/item/organ/stomach/ipc + name = "ipc stomach" + icon_state = "stomach-ipc" \ No newline at end of file diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm index 914c8cad..f09d61e5 100644 --- a/code/modules/surgery/organs/tongue.dm +++ b/code/modules/surgery/organs/tongue.dm @@ -212,6 +212,8 @@ phomeme_type = pick(phomeme_types) /obj/item/organ/tongue/bone/applyOrganDamage(var/d, var/maximum = maxHealth) + if(d < 0) + return if(!owner) return var/target = owner.get_bodypart(BODY_ZONE_HEAD) diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index 781fdb24..f93bdbae 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -767,9 +767,15 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes desc = "A speed loader that contains seven additional .357 Magnum rounds; usable with the Syndicate revolver. \ For when you really need a lot of things dead." item = /obj/item/ammo_box/a357 - cost = 4 + cost = 3 exclude_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/ammo/revolver/ap + name = ".357 Armor Piercing Speed Loader" + desc = "A speed loader that contains seven additional .357 AP Magnum rounds; usable with the Syndicate revolver. \ + Cuts through like a hot knife through butter." + item = /obj/item/ammo_box/a357/ap + /datum/uplink_item/ammo/a40mm name = "40mm Grenade" desc = "A 40mm HE grenade for use with the M-90gl's under-barrel grenade launcher. \ @@ -1487,9 +1493,10 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes /datum/uplink_item/device_tools/singularity_beacon name = "Power Beacon" desc = "When screwed to wiring attached to an electric grid and activated, this large device pulls any \ - active gravitational singularities or tesla balls towards it. This will not work when the engine is still \ - in containment. Because of its size, it cannot be carried. Ordering this \ - sends you a small beacon that will teleport the larger beacon to your location upon activation." + active gravitational singularities or tesla balls towards it (provided they are not safely \ + contained), as well as increasing the odds of incoming meteor waves. \ + Because of its size, it cannot be carried. Ordering this sends you a small beacon \ + that will teleport the larger beacon to your location upon activation." item = /obj/item/sbeacondrop cost = 14 diff --git a/config/config.txt b/config/config.txt index ba8303ff..d6a6f18f 100644 --- a/config/config.txt +++ b/config/config.txt @@ -242,10 +242,10 @@ CHECK_RANDOMIZER # WIKIURL http://www.tgstation13.org/wiki ## Rules address -# RULESURL http://www.tgstation13.org/wiki/Rules +# RULESURL https://hyperstation13.com/rules ## Github address -# GITHUBURL https://www.github.com/tgstation/tgstation +# GITHUBURL https://github.com/quotefox/Hyper-Station-13 ## Round specific stats address ## Link to round specific parsed logs; IE statbus. It is appended with the RoundID automatically by ticker/Reboot() diff --git a/hyperstation/code/mobs/hugbot.dm b/hyperstation/code/mobs/hugbot.dm new file mode 100644 index 00000000..89d7acbe --- /dev/null +++ b/hyperstation/code/mobs/hugbot.dm @@ -0,0 +1,311 @@ +//HUGBOT +//HUGBOT PATHFINDING +//HUGBOT ASSEMBLY + + +/mob/living/simple_animal/bot/hugbot + name = "\improper Hugbot" + desc = "A little cudly robot. He looks excited." + icon = 'hyperstation/icons/mobs/aibots.dmi' + icon_state = "hugbot0" + density = FALSE + anchored = FALSE + health = 20 + maxHealth = 20 + pass_flags = PASSMOB + + status_flags = (CANPUSH | CANSTUN) + + bot_type = HUG_BOT + model = "Hugbot" + bot_core_type = /obj/machinery/bot_core/hugbot + window_id = "autohug" + window_name = "Automatic Hugging Unit v1.0 Alpha" + path_image_color = "#FFDDDD" + + base_speed = 4 + + var/stationary_mode = 0 //If enabled, the Hugbot will not move automatically. + var/mob/living/carbon/patient = null + var/mob/living/carbon/oldpatient = null + var/last_found = 0 + + +/mob/living/simple_animal/bot/hugbot/update_icon() + cut_overlays() + if(!on) + icon_state = "hugbot0" + return + if(IsStun()) + icon_state = "hugbota" + return + if(mode == BOT_HEALING) + icon_state = "hugbots[stationary_mode]" + return + else if(stationary_mode) //Bot has yellow light to indicate stationary mode. + icon_state = "hugbot2" + else + icon_state = "hugbot1" + +/mob/living/simple_animal/bot/medbot/Initialize(mapload, new_skin) + . = ..() + update_icon() + + +/mob/living/simple_animal/bot/hugbot/update_canmove() + . = ..() + update_icon() + +/mob/living/simple_animal/bot/hugbot/bot_reset() + ..() + update_icon() + +/mob/living/simple_animal/bot/hugbot/proc/soft_reset() //Allows the medibot to still actively perform its medical duties without being completely halted as a hard reset does. + path = list() + patient = null + mode = BOT_IDLE + last_found = world.time + update_icon() + +/mob/living/simple_animal/bot/hugbot/set_custom_texts() + + text_hack = "You bypass [name]'s manipulator pressure sensors." + text_dehack = "You rewire [name]'s manipulator pressure sensors." + text_dehack_fail = "[name] seems damaged and does not respond to reprogramming!" + +/mob/living/simple_animal/bot/hugbot/attack_paw(mob/user) + return attack_hand(user) + +/mob/living/simple_animal/bot/hugbot/get_controls(mob/user) + var/dat + dat += hack(user) + dat += showpai(user) + dat += "Hugging Unit Controls v1.0 Alpha

" + dat += "Status: [on ? "On" : "Off"]
" + dat += "Maintenance panel panel is [open ? "opened" : "closed"]
" + dat += "Behaviour controls are [locked ? "locked" : "unlocked"]
" + if(!locked || issilicon(user) || IsAdminGhost(user)) + dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
" + dat += "Stationary Mode: [stationary_mode ? "Yes" : "No"]
" + + return dat + +/mob/living/simple_animal/bot/hugbot/Topic(href, href_list) + if(..()) + return 1 + + update_controls() + return + +/mob/living/simple_animal/bot/hugbot/attackby(obj/item/W as obj, mob/user as mob, params) + var/current_health = health + ..() + if(health < current_health) //if medbot took some damage + step_to(src, (get_step_away(src,user))) + +/mob/living/simple_animal/bot/hugbot/emag_act(mob/user) + ..() + if(emagged == 2) + if(user) + to_chat(user, "You short out [src]'s manipulator pressure sensors.") + audible_message("[src]'s arm twitches violently!") + flick("medibot_spark", src) + playsound(src, "sparks", 75, 1) + + +/mob/living/simple_animal/bot/hugbot/proc/assess_patient(mob/living/carbon/C) + //Time to see if they need medical help! + if(C.stat == DEAD || (HAS_TRAIT(C, TRAIT_FAKEDEATH))) + return FALSE //welp too late for them! + + if(!(loc == C.loc) && !(isturf(C.loc) && isturf(loc))) + return FALSE + + if(ishuman(C)) + var/mob/living/carbon/human/H = C + GET_COMPONENT_FROM(mood, /datum/component/mood, H) + if(emagged != 2) // EVERYONE GETS HUGS! + for(var/datum/mood_event/i in mood.mood_events) + if (i.description == "Hugs are nice.\n" ) + return FALSE + else if (C.IsKnockdown()) + return FALSE + return TRUE + + return FALSE + +/mob/living/simple_animal/bot/hugbot/process_scan(mob/living/carbon/human/H) + if(H.stat == DEAD) + return + + if((H == oldpatient) && (world.time < last_found + 200)) + return + + if(assess_patient(H)) + last_found = world.time + return H + else + return + +/mob/living/simple_animal/bot/hugbot/handle_automated_action() + if(!..()) + return + + if(mode == BOT_HEALING) + medicate_patient(patient) + return + + if(IsStun()) + oldpatient = patient + patient = null + mode = BOT_IDLE + update_icon() + return + + if(frustration > 8) + oldpatient = patient + soft_reset() + + if(QDELETED(patient)) + var/scan_range = (stationary_mode ? 1 : DEFAULT_SCAN_RANGE) //If in stationary mode, scan range is limited to adjacent patients. + patient = scan(/mob/living/carbon/human, oldpatient, scan_range) + oldpatient = patient + + if(patient && (get_dist(src,patient) <= 1)) //Patient is next to us, begin treatment! + if(mode != BOT_HEALING) + mode = BOT_HEALING + update_icon() + frustration = 0 + medicate_patient(patient) + return + + //Patient has moved away from us! + else if(patient && path.len && (get_dist(patient,path[path.len]) > 2)) + path = list() + mode = BOT_IDLE + last_found = world.time + + else if(stationary_mode && patient) //Since we cannot move in this mode, ignore the patient and wait for another. + soft_reset() + return + + if(patient && path.len == 0 && (get_dist(src,patient) > 1)) + path = get_path_to(src, get_turf(patient), /turf/proc/Distance_cardinal, 0, 30,id=access_card) + mode = BOT_MOVING + if(!path.len) //try to get closer if you can't reach the patient directly + path = get_path_to(src, get_turf(patient), /turf/proc/Distance_cardinal, 0, 30,1,id=access_card) + if(!path.len) //Do not chase a patient we cannot reach. + soft_reset() + + if(path.len > 0 && patient) + if(!bot_move(path[path.len])) + oldpatient = patient + soft_reset() + return + + if(path.len > 8 && patient) + frustration++ + + if(auto_patrol && !stationary_mode && !patient) + if(mode == BOT_IDLE || mode == BOT_START_PATROL) + start_patrol() + + if(mode == BOT_PATROL) + bot_patrol() + + return + +/mob/living/simple_animal/bot/hugbot/UnarmedAttack(atom/A) + if(iscarbon(A)) + var/mob/living/carbon/C = A + patient = C + mode = BOT_HEALING + update_icon() + medicate_patient(C) + update_icon() + else + ..() + +/mob/living/simple_animal/bot/hugbot/proc/medicate_patient(mob/living/carbon/C) + if(!on) + return + + if(!istype(C)) + oldpatient = patient + soft_reset() + return + + if(C.stat == DEAD || (HAS_TRAIT(C, TRAIT_FAKEDEATH))) + oldpatient = patient + soft_reset() + return + + visible_message("[src] hugs [C] to make [C.p_them()] feel better!", \ + "You hug [C] to make [C.p_them()] feel better!") + SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug) + + if (emagged != 2) + C.AdjustStun(-60) + C.AdjustKnockdown(-60) + C.AdjustUnconscious(-60) + C.AdjustSleeping(-100) + if(recoveringstam) + C.adjustStaminaLoss(-15) + else if(resting) + C.resting = 0 + C.update_canmove() + else + C.Knockdown(100) + C.Stun(100) + C.update_canmove() + + playsound(C.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + + oldpatient = patient + patient = null + mode = BOT_IDLE + update_icon() + return + +/mob/living/simple_animal/bot/hugbot/explode() + on = FALSE + visible_message("[src] blows apart!") + do_sparks(3, TRUE, src) + ..() + +/obj/machinery/bot_core/hugbot + req_one_access = list(ACCESS_ROBOTICS) + +/obj/item/bot_assembly/hugbot + desc = "It's a box of hugs with an arm attached." + name = "incomplete hugbot assembly" + icon = 'hyperstation/icons/mobs/aibots.dmi' + icon_state = "hugbot_arm" + created_name = "Hugbot" + +/obj/item/bot_assembly/hugbot/attackby(obj/item/W, mob/user, params) + ..() + if(istype(W, /obj/item/assembly/prox_sensor)) + if(!can_finish_build(W, user)) + return + var/mob/living/simple_animal/bot/hugbot/A = new(drop_location()) + A.name = created_name + A.robot_arm = W.type + to_chat(user, "You add [W] to [src]. Beep boop!") + qdel(W) + qdel(src) + +/obj/item/storage/box/hug/attackby(obj/item/I, mob/user, params) + if((istype(I, /obj/item/bodypart/l_arm/robot)) || (istype(I, /obj/item/bodypart/r_arm/robot))) + if(contents.len) //prevent accidently deleting contents + to_chat(user, "You need to empty [src] out first!") + return + if(!user.temporarilyRemoveItemFromInventory(I)) + return + qdel(I) + to_chat(user, "You add [I] to the [src]! You've got a hugbot assembly now!") + var/obj/item/bot_assembly/hugbot/A = new + qdel(src) + user.put_in_hands(A) + else + return ..() diff --git a/hyperstation/code/modules/crafting/recipes.dm b/hyperstation/code/modules/crafting/recipes.dm new file mode 100644 index 00000000..5be10633 --- /dev/null +++ b/hyperstation/code/modules/crafting/recipes.dm @@ -0,0 +1,11 @@ +/datum/crafting_recipe/milking_machine + name = "Milking Machine" + reqs = list(/obj/item/stack/cable_coil = 5, /obj/item/stack/rods = 2, /obj/item/stack/sheet/cardboard = 1, /obj/item/reagent_containers/glass/beaker = 2, /obj/item/stock_parts/manipulator = 1) + result = /obj/item/milking_machine + tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WIRECUTTER) + category = CAT_MISC + +/datum/crafting_recipe/milking_machine/penis + name = "Penis Milking Machine" + reqs = list(/obj/item/stack/cable_coil = 5, /obj/item/stack/rods = 1, /obj/item/stack/sheet/cardboard = 1, /obj/item/reagent_containers/glass/beaker/large = 1, /obj/item/stock_parts/manipulator = 1) + result = /obj/item/milking_machine/penis diff --git a/hyperstation/code/obj/milking machine.dm b/hyperstation/code/obj/milking machine.dm new file mode 100644 index 00000000..5783ad6f --- /dev/null +++ b/hyperstation/code/obj/milking machine.dm @@ -0,0 +1,83 @@ +/obj/item/milking_machine + icon = 'hyperstation/icons/obj/milking_machine.dmi' + name = "milking machine" + icon_state = "Off" + item_state = "Off" + desc = "A pocket sized pump and tubing assembly designed to collect and store products from mammary glands." + + slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_POCKET + + var/on = FALSE + var/obj/item/reagent_containers/glass/inserted_item = null + + var/transfer_rate = 0.25 // How much we transfer every 2 seconds + var/target_organ = "breasts" // What organ we are transfering from + +/obj/item/milking_machine/examine(mob/user) + . = ..() + to_chat(user, "[src] is currently [on ? "on" : "off"].") + if (inserted_item) + to_chat(user, "[inserted_item] contains [inserted_item.reagents.total_volume]/[inserted_item.reagents.maximum_volume] units") + +/obj/item/milking_machine/attackby(obj/item/W, mob/user, params) + add_fingerprint(user) + if(istype(W, /obj/item/reagent_containers/glass) && !inserted_item) + if(!user.transferItemToLoc(W, src)) + return ..() + inserted_item = W + UpdateIcon() + else + return ..() + +/obj/item/milking_machine/interact(mob/user) + if(!isAI(user) && inserted_item) + add_fingerprint(user) + on = !on + if (on) + to_chat(user, "You turn [src] on.") + START_PROCESSING(SSobj, src) + else + to_chat(user, "You turn [src] off.") + STOP_PROCESSING(SSobj, src) + UpdateIcon() + else + ..() + +/obj/item/milking_machine/proc/UpdateIcon() + icon_state = "[on ? "On" : "Off"][inserted_item ? "Beaker" : ""]" + item_state = icon_state + + +/obj/item/milking_machine/AltClick(mob/living/user) + add_fingerprint(user) + user.put_in_hands(inserted_item) + inserted_item = null + on = FALSE + STOP_PROCESSING(SSobj, src) + UpdateIcon() + +/obj/item/milking_machine/process() + var/mob/living/carbon/W = loc + if (W) + var/obj/item/organ/genital/breasts/O = W.getorganslot(target_organ) + if (O) + if (O.reagents.total_volume >= transfer_rate * 2) + if (inserted_item.reagents.total_volume < inserted_item.reagents.maximum_volume) + O.reagents.trans_to(inserted_item.reagents, amount = transfer_rate) + else + to_chat(W, "[src] stops pumping. [inserted_item] is full.") + on = FALSE + STOP_PROCESSING(SSobj, src) + UpdateIcon() + +/obj/item/milking_machine/penis + name = "penis milking machine" + icon_state = "PenisOff" + item_state = "PenisOff" + desc = "A pocket sized pump and tubing assembly designed to collect and store products from the penis." + + target_organ = "testicles" // Since semen is stored in the balls + +/obj/item/milking_machine/penis/UpdateIcon() + icon_state = "Penis[on ? "On" : "Off"][inserted_item ? "Beaker" : ""]" + item_state = icon_state diff --git a/hyperstation/code/obj/rewards.dm b/hyperstation/code/obj/rewards.dm index 1769f43b..b0c5d284 100644 --- a/hyperstation/code/obj/rewards.dm +++ b/hyperstation/code/obj/rewards.dm @@ -6,4 +6,12 @@ /obj/item/pen/bluemarker/attack_self(mob/user) user.emote("sniff") - to_chat(user, "Ahh~ blueberries!") \ No newline at end of file + to_chat(user, "Ahh~ blueberries!") + +/obj/item/clothing/suit/napoleonic + name = "napoleonic uniform" + desc = "An heirloom passed down from the Gruber family dynasty." + icon_state = "napoleonic" + item_state = "napoleonic" + body_parts_covered = CHEST|GROIN|ARMS + cold_protection = CHEST|GROIN|ARMS diff --git a/hyperstation/icons/mobs/aibots.dmi b/hyperstation/icons/mobs/aibots.dmi new file mode 100644 index 00000000..1710d3ad Binary files /dev/null and b/hyperstation/icons/mobs/aibots.dmi differ diff --git a/modular_citadel/icons/obj/milking machine.dmi b/hyperstation/icons/obj/milking_machine.dmi similarity index 100% rename from modular_citadel/icons/obj/milking machine.dmi rename to hyperstation/icons/obj/milking_machine.dmi diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index 2a85f8a4..e9343c7e 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/inhands/weapons/guns_lefthand.dmi b/icons/mob/inhands/weapons/guns_lefthand.dmi index 5b3efeb7..7c411c33 100644 Binary files a/icons/mob/inhands/weapons/guns_lefthand.dmi and b/icons/mob/inhands/weapons/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/guns_righthand.dmi b/icons/mob/inhands/weapons/guns_righthand.dmi index b5c60fc8..f1152c77 100644 Binary files a/icons/mob/inhands/weapons/guns_righthand.dmi and b/icons/mob/inhands/weapons/guns_righthand.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index fd041b1d..52e8d4c3 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index f6f55f8b..e31c340a 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/barsigns.dmi b/icons/obj/barsigns.dmi index 2c4d4010..3bbb57d9 100644 Binary files a/icons/obj/barsigns.dmi and b/icons/obj/barsigns.dmi differ diff --git a/icons/obj/bloodpack.dmi b/icons/obj/bloodpack.dmi index 3a5b9fd7..82b4c2e5 100644 Binary files a/icons/obj/bloodpack.dmi and b/icons/obj/bloodpack.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index b63e9344..e96de94c 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 019ab7d4..9aadd199 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index 7920004e..75611879 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index 588f58e5..6975fa1a 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/janitor.dmi b/icons/obj/janitor.dmi index 687fef60..6aa4615d 100644 Binary files a/icons/obj/janitor.dmi and b/icons/obj/janitor.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 0722b079..76ac0c71 100644 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm index 68ab229f..033057ba 100644 --- a/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm +++ b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm @@ -130,15 +130,6 @@ else return ..() -/obj/item/melee/transforming/energy/sword/cx/chaplain - name = "divine lightblade" - force_on = 20 //haha i'll regret this - block_chance = 50 - -/obj/item/melee/transforming/energy/sword/cx/chaplain/Initialize() - . = ..() - AddComponent(/datum/component/anti_magic, TRUE, TRUE) - //OBLIGATORY TOY MEMES ///////////////////////////////////// /obj/item/toy/sword/cx @@ -271,6 +262,24 @@ spinnable = FALSE total_mass_on = 4 +/obj/item/twohanded/dualsaber/hypereutactic/chaplain + name = "\improper divine lightblade" + desc = "A giant blade of bright and holy light, said to cut down the wicked with ease." + force = 5 + force_unwielded = 5 + force_wielded = 20 + block_chance = 50 + armour_penetration = 0 + var/chaplain_spawnable = TRUE + obj_flags = UNIQUE_RENAME + +/obj/item/twohanded/dualsaber/hypereutactic/chaplain/Initialize() + . = ..() + AddComponent(/datum/component/anti_magic, TRUE, TRUE) + +/obj/item/twohanded/dualsaber/hypereutactic/chaplain/IsReflect() + return FALSE + /obj/item/twohanded/dualsaber/hypereutactic/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes altafterattack(A, user, TRUE, params) return TRUE diff --git a/modular_citadel/code/modules/arousal/organs/testicles.dm b/modular_citadel/code/modules/arousal/organs/testicles.dm index f4ef4b50..dd983e0e 100644 --- a/modular_citadel/code/modules/arousal/organs/testicles.dm +++ b/modular_citadel/code/modules/arousal/organs/testicles.dm @@ -9,6 +9,9 @@ var/size_name = "average" shape = "single" var/sack_size = BALLS_SACK_SIZE_DEF + var/cached_size = 6 + fluid_mult = 0.133 // Set to a lower value due to production scaling with size (I.E. 6 inches the "normal" amount) + fluid_max_volume = 3 fluid_id = "semen" producing = TRUE can_masturbate_with = FALSE @@ -19,15 +22,14 @@ /obj/item/organ/genital/testicles/on_life() if(QDELETED(src)) return - if(reagents && producing) + if(!reagents || !owner) + return + reagents.maximum_volume = fluid_max_volume * cached_size// fluid amount is also scaled by the size of the organ + if(fluid_id && producing) if(reagents.total_volume == 0) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank. fluid_rate = 0.1 else - fluid_rate = CUM_RATE - if(reagents.total_volume >= 5) - fluid_mult = 0.5 - else - fluid_mult = 1 + fluid_rate = CUM_RATE * cached_size * fluid_mult // fluid rate is scaled by the size of the organ generate_cum() /obj/item/organ/genital/testicles/proc/generate_cum() @@ -42,7 +44,7 @@ if(!linked_organ) return FALSE reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally - reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum + reagents.add_reagent(fluid_id, (fluid_rate))//generate the cum /obj/item/organ/genital/testicles/update_link() if(owner && !QDELETED(src)) @@ -50,7 +52,8 @@ if(linked_organ) linked_organ.linked_organ = src size = linked_organ.size - + var/obj/item/organ/genital/penis/O = linked_organ + cached_size = O.length else if(linked_organ) linked_organ.linked_organ = null diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm index 2c6bb352..c0c2e3d9 100644 --- a/modular_citadel/code/modules/client/loadout/__donator.dm +++ b/modular_citadel/code/modules/client/loadout/__donator.dm @@ -11,7 +11,7 @@ //Just so admins can test the recent rewards added. name = "test reward" category = SLOT_IN_BACKPACK - path = /obj/item/pen/bluemarker + path = /obj/item/clothing/suit/napoleonic ckeywhitelist = list("quotefox") /datum/gear/winterblooplush @@ -37,4 +37,11 @@ name = "Blueberry Marker" category = SLOT_IN_BACKPACK path = /obj/item/pen/bluemarker - ckeywhitelist = list("blooberri") \ No newline at end of file + ckeywhitelist = list("blooberri") + +/datum/gear/hubertsuit + name = "Napoleonic Uniform" + category = SLOT_IN_BACKPACK + path = /obj/item/clothing/suit/napoleonic + ckeywhitelist = list("hackertdog") + diff --git a/modular_citadel/code/modules/clothing/clothing.dm b/modular_citadel/code/modules/clothing/clothing.dm index fc71d5bd..7f366ecf 100644 --- a/modular_citadel/code/modules/clothing/clothing.dm +++ b/modular_citadel/code/modules/clothing/clothing.dm @@ -38,6 +38,8 @@ var/secondary_color = "#FFFFFF" var/tertiary_color = "#808080" + var/force_alternate_icon = FALSE + /obj/item/clothing/update_icon() // picks the colored overlays from the ICON file ..() if(hasprimary) //Checks if the overlay is enabled diff --git a/modular_citadel/code/modules/clothing/under/trek_under.dm b/modular_citadel/code/modules/clothing/under/trek_under.dm index a60f7653..e29fd1a6 100644 --- a/modular_citadel/code/modules/clothing/under/trek_under.dm +++ b/modular_citadel/code/modules/clothing/under/trek_under.dm @@ -14,6 +14,7 @@ desc = "Oooh... right." icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi' alternate_worn_icon = 'modular_citadel/icons/mob/clothing/trek_mob_icon.dmi' + force_alternate_icon = TRUE item_state = "" can_adjust = FALSE //to prevent you from "wearing it casually" @@ -23,17 +24,20 @@ desc = "The uniform worn by command officers in the mid 2260s." icon_state = "trek_command" item_state = "trek_command" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + force_alternate_icon = TRUE + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) /obj/item/clothing/under/rank/trek/engsec name = "Operations Uniform" desc = "The uniform worn by operations officers of the mid 2260s. You feel strangely vulnerable just seeing this..." + force_alternate_icon = TRUE icon_state = "trek_engsec" item_state = "trek_engsec" /obj/item/clothing/under/rank/trek/medsci name = "MedSci Uniform" desc = "The uniform worn by medsci officers in the mid 2260s." + force_alternate_icon = TRUE icon_state = "trek_medsci" item_state = "trek_medsci" permeability_coefficient = 0.50 diff --git a/modular_citadel/code/modules/crafting/recipes.dm b/modular_citadel/code/modules/crafting/recipes.dm index ccdfb480..bf04f706 100644 --- a/modular_citadel/code/modules/crafting/recipes.dm +++ b/modular_citadel/code/modules/crafting/recipes.dm @@ -10,14 +10,3 @@ result = /obj/item/aicard/potato category = CAT_ROBOT -/datum/crafting_recipe/milker - name = "Milking Machine" - reqs = list(/obj/item/stack/cable_coil = 5, /obj/item/stack/sheet/plastic = 2, /obj/item/stack/rods = 2, /obj/item/stack/sheet/cardboard = 1, /obj/item/reagent_containers/glass/beaker = 2, /obj/item/stock_parts/manipulator = 1) - result = /obj/item/milker - tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WIRECUTTER) - category = CAT_MISC - -/datum/crafting_recipe/milker/penis - name = "Penis Milking Machine" - reqs = list(/obj/item/stack/cable_coil = 5, /obj/item/stack/sheet/plastic = 2, /obj/item/stack/rods = 1, /obj/item/stack/sheet/cardboard = 1, /obj/item/reagent_containers/glass/beaker/large = 1, /obj/item/stock_parts/manipulator = 1) - result = /obj/item/milker/penis diff --git a/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm b/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm index 25b8daf2..8fd01393 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm @@ -1,5 +1,5 @@ /datum/species/ipc - name = "IPC" + name = "I.P.C" id = "ipc" say_mod = "beeps" default_color = "00FF00" @@ -10,10 +10,16 @@ inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID) mutant_bodyparts = list("ipc_screen", "ipc_antenna") default_features = list("ipc_screen" = "Blank", "ipc_antenna" = "None") - meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc - mutanttongue = /obj/item/organ/tongue/robot/ipc + meat = null //robots can't make meat silly! +//Just robo looking parts. + mutant_heart = /obj/item/organ/heart/ipc + mutantlungs = /obj/item/organ/lungs/ipc + mutantliver = /obj/item/organ/liver/ipc + mutantstomach = /obj/item/organ/stomach/ipc + mutanteyes = /obj/item/organ/eyes/ipc + mutanttongue = /obj/item/organ/tongue/robot - exotic_blood = "oil" + exotic_bloodtype = "oil" var/datum/action/innate/monitor_change/screen diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm index c413644b..a3213ef1 100644 --- a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm +++ b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm @@ -18,7 +18,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! name = "combat jaws" desc = "The jaws of the law. Very sharp." icon_state = "jaws" - force = 12 + force = 10 //Lowered to match secborg. No reason it should be more than a secborg's baton. attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") /obj/item/dogborg/jaws/small @@ -32,7 +32,6 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! /obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user) ..() user.do_attack_animation(A, ATTACK_EFFECT_BITE) - log_combat(user, A, "bit") /obj/item/dogborg/jaws/small/attack_self(mob/user) var/mob/living/silicon/robot.R = user @@ -307,8 +306,8 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! /mob/living/silicon/robot var/leaping = 0 var/pounce_cooldown = 0 - var/pounce_cooldown_time = 50 //Nearly doubled, u happy? - var/pounce_spoolup = 3 + var/pounce_cooldown_time = 20 //Buffed to counter balance changes + var/pounce_spoolup = 1 var/leap_at var/disabler var/laser @@ -338,7 +337,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! //It's also extremely buggy visually, so it's balance+bugfix return - if(cell.charge <= 500) + if(cell.charge <= 750) to_chat(src,"Insufficent reserves for jump actuators!") return @@ -348,7 +347,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! pixel_y = 10 update_icons() throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1) - cell.use(500) //Doubled the energy consumption + cell.use(750) //Less than a stunbaton since stunbatons hit everytime. weather_immunities -= "lava" /mob/living/silicon/robot/throw_impact(atom/A) @@ -366,13 +365,13 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! blocked = 1 if(!blocked) L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") - L.Knockdown(iscarbon(L) ? 450 : 45) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice. + L.Knockdown(iscarbon(L) ? 225 : 45) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice. playsound(src, 'sound/weapons/Egloves.ogg', 50, 1) sleep(2)//Runtime prevention (infinite bump() calls on hulks) step_towards(src,L) log_combat(src, L, "borg pounced") else - Knockdown(45, 1, 1) + Knockdown(15, 1, 1) pounce_cooldown = !pounce_cooldown spawn(pounce_cooldown_time) //3s by default @@ -380,7 +379,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! else if(A.density && !A.CanPass(src)) visible_message("[src] smashes into [A]!", "You smash into [A]!") playsound(src, 'sound/items/trayhit1.ogg', 50, 1) - Knockdown(45, 1, 1) + Knockdown(15, 1, 1) if(leaping) leaping = 0 diff --git a/modular_citadel/code/modules/reagents/chemistry/fermi/fermi.md b/modular_citadel/code/modules/reagents/chemistry/fermi/fermi.md new file mode 100644 index 00000000..dfc89fb4 --- /dev/null +++ b/modular_citadel/code/modules/reagents/chemistry/fermi/fermi.md @@ -0,0 +1,23 @@ +How to code fermichem reactions: +First off, probably read though the readme for standard reagent mechanisms, this builds on top of that. + +#bitflags +for `datum/reagent/` you have the following options with `var/chemical_flags`: + +``` +REAGENT_DEAD_PROCESS calls on_mob_dead() if present in a dead body +REAGENT_DONOTSPLIT Do not split the chem at all during processing +REAGENT_ONLYINVERSE Only invert chem, no splitting +REAGENT_ONMOBMERGE Call on_mob_life proc when reagents are merging. +REAGENT_INVISIBLE Doesn't appear on handheld health analyzers. +REAGENT_FORCEONNEW Forces a on_new() call without a data overhead +REAGENT_SNEAKYNAME When inverted, the inverted chem uses the name of the original chem +REAGENT_SPLITRETAINVOL Retains initial volume of chem when splitting +``` + +for `datum/chemical_reaction/` under `var/clear_conversion` + +``` +REACTION_CLEAR_IMPURE Convert into impure/pure on reaction completion +REACTION_CLEAR_INVERSE Convert into inverse on reaction completion when purity is low enough +``` \ No newline at end of file diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm index 76d0951d..4e80f42d 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm @@ -136,7 +136,6 @@ Creating a chem with a low purity will make you permanently fall in love with so color = "#660015" // rgb: , 0, 255 taste_description = "synthetic chocolate, a base tone of alcohol, and high notes of roses" overdose_threshold = 100 //If this is too easy to get 100u of this, then double it please. - DoNotSplit = TRUE metabolization_rate = 0.1//It has to be slow, so there's time for the effect. data = list("creatorID" = null, "creatorGender" = null, "creatorName" = null) var/creatorID //ckey @@ -144,20 +143,19 @@ Creating a chem with a low purity will make you permanently fall in love with so var/creatorName var/mob/living/creator pH = 10 - OnMobMergeCheck = TRUE //Procs on_mob_add when merging into a human + chemical_flags = REAGENT_ONMOBMERGE | REAGENT_DONOTSPLIT //Procs on_mob_add when merging into a human can_synth = FALSE /datum/reagent/fermi/enthrall/test name = "MKUltraTest" id = "enthrallTest" - description = "A forbidden deep red mixture that overwhelms a foreign body with waves of joy, intoxicating them into servitude. When taken by the creator, it will enhance the draw of their voice to those affected by it." + description = "A forbidden deep red mixture that makes you like Fermis a little too much. Unobtainable and due to be removed from the wiki." data = list("creatorID" = "honkatonkbramblesnatch", "creatorGender" = "Mistress", "creatorName" = "Fermis Yakumo") creatorID = "honkatonkbramblesnatch"//ckey creatorGender = "Mistress" creatorName = "Fermis Yakumo" purity = 1 - DoNotSplit = TRUE /datum/reagent/fermi/enthrall/test/on_new() id = "enthrall" @@ -300,13 +298,13 @@ Creating a chem with a low purity will make you permanently fall in love with so //Creates a gas cloud when the reaction blows up, causing everyone in it to fall in love with someone/something while it's in their system. /datum/reagent/fermi/enthrallExplo//Created in a gas cloud when it explodes - name = "MKUltra" + name = "Gaseous MKUltra" id = "enthrallExplo" - description = "A forbidden deep red mixture that overwhelms a foreign body with waves of desire, inducing a chemial love for another. Also, how the HECC did you get this?" + description = "A forbidden deep red gas that overwhelms a foreign body, causing the person they next lay their eyes on to become more interesting. Studies have shown that people are 66% more likely to make friends with this in the air. Produced when MKUltra explodes." color = "#2C051A" // rgb: , 0, 255 metabolization_rate = 0.1 taste_description = "synthetic chocolate, a base tone of alcohol, and high notes of roses." - DoNotSplit = TRUE + chemical_flags = REAGENT_DONOTSPLIT can_synth = FALSE var/mob/living/carbon/love diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm index 0924f00f..3414e65b 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm @@ -54,9 +54,9 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING var/pollStarted = FALSE var/location_created var/startHunger - ImpureChem = "SDGFtox" - InverseChemVal = 0.5 - InverseChem = "SDZF" + impure_chem = "SDGFtox" + inverse_chem_val = 0.5 + inverse_chem = "SDZF" can_synth = TRUE @@ -270,8 +270,9 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING //Unobtainable, used in clone spawn. /datum/reagent/fermi/SDGFheal - name = "synthetic-derived growth factor" + name = "synthetic-derived healing factor" id = "SDGFheal" + description = "Leftover SDGF is transferred into the resulting clone, which quickly heals up the stresses from suddenly splitting. Restores blood, nutrition, and repaires brain and clone damage quickly. Only obtainable from using excess SDGF, and only enters the cloned body." metabolization_rate = 1 can_synth = FALSE @@ -284,29 +285,30 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING ..() //Unobtainable, used if SDGF is impure but not too impure -/datum/reagent/fermi/SDGFtox - name = "synthetic-derived growth factor" +/datum/reagent/impure/SDGFtox + name = "Synthetic-derived apoptosis factor" id = "SDGFtox" - description = "A chem that makes a certain chemcat angry at you if you're reading this, how did you get this???"//i.e. tell me please, figure it's a good way to get pinged for bugfixes. + description = "Impure synthetic-derived growth factor causes certain cells to undergo cell death, causing clone damage, and damaging blood cells."//i.e. tell me please, figure it's a good way to get pinged for bugfixes. metabolization_rate = 1 can_synth = FALSE -/datum/reagent/fermi/SDGFtox/on_mob_life(mob/living/carbon/M)//Damages the taker if their purity is low. Extended use of impure chemicals will make the original die. (thus can't be spammed unless you've very good) +/datum/reagent/impure/SDGFtox/on_mob_life(mob/living/carbon/M)//Damages the taker if their purity is low. Extended use of impure chemicals will make the original die. (thus can't be spammed unless you've very good) M.blood_volume -= 10 M.adjustCloneLoss(2, 0) ..() //Fail state of SDGF -/datum/reagent/fermi/SDZF - name = "synthetic-derived growth factor" +/datum/reagent/impure/SDZF + name = "synthetic-derived zombie factor" id = "SDZF" - description = "A horribly peverse mass of Embryonic stem cells made real by the hands of a failed chemist. This message should never appear, how did you manage to get a hold of this?" + description = "A horribly peverse mass of Embryonic stem cells made real by the hands of a failed chemist. Emulates normal synthetic-derived growth factor, but produces a hostile zombie at the end of it." color = "#a502e0" // rgb: 96, 0, 255 metabolization_rate = 0.5 * REAGENTS_METABOLISM var/startHunger can_synth = TRUE + chemical_flags = REAGENT_SNEAKYNAME -/datum/reagent/fermi/SDZF/on_mob_life(mob/living/carbon/M) //If you're bad at fermichem, turns your clone into a zombie instead. +/datum/reagent/impure/SDZF/on_mob_life(mob/living/carbon/M) //If you're bad at fermichem, turns your clone into a zombie instead. switch(current_cycle)//Pretends to be normal if(20) to_chat(M, "You feel the synethic cells rest uncomfortably within your body as they start to pulse and grow rapidly.") diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm index d05cfb55..88586b42 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm @@ -28,7 +28,7 @@ I'd like to point out from my calculations it'll take about 60-80 minutes to die var/datum/mind/originalmind var/antiGenetics = 255 var/sleepytime = 0 - InverseChemVal = 0.25 + inverse_chem_val = 0.25 can_synth = FALSE /datum/action/chem/astral diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm index 7c22d9d1..5ebad3b2 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm @@ -26,9 +26,9 @@ taste_description = "a milky ice cream like flavour." overdose_threshold = 17 metabolization_rate = 0.25 - ImpureChem = "BEsmaller" //If you make an inpure chem, it stalls growth - InverseChemVal = 0.35 - InverseChem = "BEsmaller" //At really impure vols, it just becomes 100% inverse + impure_chem = "BEsmaller" //If you make an inpure chem, it stalls growth + inverse_chem_val = 0.35 + inverse_chem = "BEsmaller" //At really impure vols, it just becomes 100% inverse can_synth = FALSE /datum/reagent/fermi/breast_enlarger/on_mob_add(mob/living/carbon/M) @@ -140,7 +140,7 @@ /datum/reagent/fermi/BEsmaller name = "Modesty milk" id = "BEsmaller" - description = "A volatile collodial mixture derived from milk that encourages mammary reduction via a potent estrogen mix." + description = "A volatile collodial mixture derived from milk that encourages mammary reduction via a potent estrogen mix. Produced by reacting impure Succubus milk." color = "#E60584" // rgb: 96, 0, 255 taste_description = "a milky ice cream like flavour." metabolization_rate = 0.25 @@ -211,9 +211,9 @@ taste_description = "chinese dragon powder" overdose_threshold = 17 //ODing makes you male and removes female genitals metabolization_rate = 0.5 - ImpureChem = "PEsmaller" //If you make an inpure chem, it stalls growth - InverseChemVal = 0.35 - InverseChem = "PEsmaller" //At really impure vols, it just becomes 100% inverse and shrinks instead. + impure_chem = "PEsmaller" //If you make an inpure chem, it stalls growth + inverse_chem_val = 0.35 + inverse_chem = "PEsmaller" //At really impure vols, it just becomes 100% inverse and shrinks instead. can_synth = FALSE /datum/reagent/fermi/penis_enlarger/on_mob_add(mob/living/carbon/M) @@ -311,7 +311,7 @@ /datum/reagent/fermi/PEsmaller // Due to cozmo's request...! name = "Chastity draft" id = "PEsmaller" - description = "A volatile collodial mixture derived from various masculine solutions that encourages a smaller gentleman's package via a potent testosterone mix, formula derived from a collaboration from Fermichem and Doctor Ronald Hyatt, who is well known for his phallus palace." + description = "A volatile collodial mixture derived from various masculine solutions that encourages a smaller gentleman's package via a potent testosterone mix. Produced by reacting impure Incubus draft." color = "#888888" // This is greyish..? taste_description = "chinese dragon powder" metabolization_rate = 0.5 diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm index a7c4ea00..4cb8ea0c 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm @@ -6,58 +6,20 @@ id = "fermi" taste_description = "affection and love!" can_synth = FALSE + //SplitChem = TRUE + impure_chem = "fermiTox"// What chemical is metabolised with an inpure reaction + inverse_chem_val = 0.25 // If the impurity is below 0.5, replace ALL of the chem with inverse_chemupon metabolising + inverse_chem = "fermiTox" //This should process fermichems to find out how pure they are and what effect to do. /datum/reagent/fermi/on_mob_add(mob/living/carbon/M, amount) . = ..() - if(!M) - return - if(purity < 0) - CRASH("Purity below 0 for chem: [id], Please let Fermis Know!") - if (purity == 1 || DoNotSplit == TRUE) - log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [id]") - return - else if (InverseChemVal > purity)//Turns all of a added reagent into the inverse chem - M.reagents.remove_reagent(id, amount, FALSE) - M.reagents.add_reagent(InverseChem, amount, FALSE, other_purity = 1) - log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [InverseChem]") - return - else - var/impureVol = amount * (1 - purity) //turns impure ratio into impure chem - M.reagents.remove_reagent(id, (impureVol), FALSE) - M.reagents.add_reagent(ImpureChem, impureVol, FALSE, other_purity = 1) - log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume - impureVol]u of [id]") - log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [ImpureChem]") - return + //When merging two fermichems, see above /datum/reagent/fermi/on_merge(data, amount, mob/living/carbon/M, purity)//basically on_mob_add but for merging . = ..() - if(!ishuman(M)) - return - if (purity < 0) - CRASH("Purity below 0 for chem: [id], Please let Fermis Know!") - if (purity == 1 || DoNotSplit == TRUE) - log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [id] in themselves") - return - else if (InverseChemVal > purity) - M.reagents.remove_reagent(id, amount, FALSE) - M.reagents.add_reagent(InverseChem, amount, FALSE, other_purity = 1) - for(var/datum/reagent/fermi/R in M.reagents.reagent_list) - if(R.name == "") - R.name = name//Negative effects are hidden - log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [InverseChem]") - return - else - var/impureVol = amount * (1 - purity) - M.reagents.remove_reagent(id, impureVol, FALSE) - M.reagents.add_reagent(ImpureChem, impureVol, FALSE, other_purity = 1) - for(var/datum/reagent/fermi/R in M.reagents.reagent_list) - if(R.name == "") - R.name = name//Negative effects are hidden - log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume - impureVol]u of [id]") - log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [ImpureChem]") - return + //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -77,7 +39,7 @@ taste_description = "like jerky, whiskey and an off aftertaste of a crypt." metabolization_rate = 0.2 overdose_threshold = 25 - DoNotSplit = TRUE + chemical_flags = REAGENT_DONOTSPLIT pH = 4 can_synth = TRUE @@ -122,9 +84,9 @@ color = "#f9b9bc" // rgb: , 0, 255 taste_description = "dewicious degenyewacy" metabolization_rate = 0.5 * REAGENTS_METABOLISM - InverseChemVal = 0 + inverse_chem_val = 0 var/obj/item/organ/tongue/nT - DoNotSplit = TRUE + chemical_flags = REAGENT_DONOTSPLIT pH = 5 var/obj/item/organ/tongue/T can_synth = TRUE @@ -211,9 +173,9 @@ description = "A stablised EMP that is highly volatile, shocking small nano machines that will kill them off at a rapid rate in a patient's system." color = "#708f8f" overdose_threshold = 15 - ImpureChem = "nanite_b_goneTox" //If you make an inpure chem, it stalls growth - InverseChemVal = 0.25 - InverseChem = "nanite_b_goneTox" //At really impure vols, it just becomes 100% inverse + impure_chem = "nanite_b_goneTox" //If you make an inpure chem, it stalls growth + inverse_chem_val = 0.25 + inverse_chem = "nanite_b_goneTox" //At really impure vols, it just becomes 100% inverse taste_description = "what can only be described as licking a battery." pH = 9 can_synth = FALSE @@ -236,7 +198,7 @@ //empulse((get_turf(C)), 3, 2)//So the nanites randomize var/atom/T = C T.emp_act(EMP_HEAVY) - to_chat(C, "The nanites short circuit within your system!") + to_chat(C, "You feel a strange tingling sensation come from your core.") if(isnull(N)) return ..() N.nanite_volume = -2 @@ -246,10 +208,11 @@ O.emp_act(EMP_HEAVY) /datum/reagent/fermi/nanite_b_goneTox - name = "Naninte bain" + name = "Electromagnetic crystals" id = "nanite_b_goneTox" - description = "Poorly made, and shocks you!" - metabolization_rate = 1 + description = "Causes items upon the patient to sometimes short out, as well as causing a shock in the patient, if the residual charge between the crystals builds up to sufficient quantities" + metabolization_rate = 0.5 + chemical_flags = REAGENT_INVISIBLE //Increases shock events. /datum/reagent/fermi/nanite_b_goneTox/on_mob_life(mob/living/carbon/C)//Damages the taker if their purity is low. Extended use of impure chemicals will make the original die. (thus can't be spammed unless you've very good) @@ -314,7 +277,7 @@ name = "Fermis Test Reagent" id = "fermiTest" description = "You should be really careful with this...! Also, how did you get this?" - addProc = TRUE + chemical_flags = REAGENT_FORCEONNEW can_synth = FALSE /datum/reagent/fermi/fermiTest/on_new(datum/reagents/holder) @@ -345,22 +308,6 @@ playsound(get_turf(M), 'modular_citadel/sound/voice/merowr.ogg', 50, 1) holder.clear_reagents() -/datum/reagent/fermi/fermiTox - name = "FermiTox" - id = "fermiTox" - description = "You should be really careful with this...! Also, how did you get this? You shouldn't have this!" - data = "merge" - color = "FFFFFF" - can_synth = FALSE - -//I'm concerned this is too weak, but I also don't want deathmixes. -/datum/reagent/fermi/fermiTox/on_mob_life(mob/living/carbon/C, method) - if(C.dna && istype(C.dna.species, /datum/species/jelly)) - C.adjustToxLoss(-2) - else - C.adjustToxLoss(2) - ..() - /datum/reagent/fermi/acidic_buffer name = "Acidic buffer" id = "acidic_buffer" @@ -371,9 +318,11 @@ //Consumes self on addition and shifts pH /datum/reagent/fermi/acidic_buffer/on_new(datapH) + if(holder.has_reagent("stabilizing_agent")) + return ..() data = datapH if(LAZYLEN(holder.reagent_list) == 1) - return + return ..() holder.pH = ((holder.pH * holder.total_volume)+(pH * (volume)))/(holder.total_volume + (volume)) var/list/seen = viewers(5, get_turf(holder)) for(var/mob/M in seen) @@ -391,9 +340,11 @@ can_synth = TRUE /datum/reagent/fermi/basic_buffer/on_new(datapH) + if(holder.has_reagent("stabilizing_agent")) + return ..() data = datapH if(LAZYLEN(holder.reagent_list) == 1) - return + return ..() holder.pH = ((holder.pH * holder.total_volume)+(pH * (volume)))/(holder.total_volume + (volume)) var/list/seen = viewers(5, get_turf(holder)) for(var/mob/M in seen) @@ -458,4 +409,4 @@ H.say("*wag")//force update sprites. to_chat(H, "[words]") qdel(catto) - log_game("FERMICHEM: [H] ckey: [H.key] has returned to normal") + log_game("FERMICHEM: [H] ckey: [H.key] has returned to normal") \ No newline at end of file diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm index d5c675ea..12c0ef43 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm @@ -6,9 +6,9 @@ color = "#68e83a" pH = 8.6 overdose_threshold = 35 - ImpureChem = "yamerol_tox" - InverseChemVal = 0.4 - InverseChem = "yamerol_tox" + impure_chem = "yamerol_tox" + inverse_chem_val = 0.4 + inverse_chem = "yamerol_tox" can_synth = TRUE /datum/reagent/fermi/yamerol/on_mob_life(mob/living/carbon/C) @@ -73,15 +73,15 @@ C.adjustOxyLoss(-3) ..() -/datum/reagent/fermi/yamerol_tox - name = "Yamerol" +/datum/reagent/impure/yamerol_tox + name = "Yamer oh no" id = "yamerol_tox" - description = "For when you've trouble speaking or breathing, just yell YAMEROL! A chem that helps soothe any congestion problems and at high concentrations restores damaged lungs and tongues!" + description = "A dangerous, cloying toxin that stucks to a patient’s respiratory system, damaging their tongue, lungs and causing suffocation." taste_description = "a weird, syrupy flavour, yamero" color = "#68e83a" pH = 8.6 -/datum/reagent/fermi/yamerol_tox/on_mob_life(mob/living/carbon/C) +/datum/reagent/impure/yamerol_tox/on_mob_life(mob/living/carbon/C) var/obj/item/organ/tongue/T = C.getorganslot(ORGAN_SLOT_TONGUE) var/obj/item/organ/lungs/L = C.getorganslot(ORGAN_SLOT_LUNGS) diff --git a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm index e2941519..fbad8c8f 100644 --- a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm +++ b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm @@ -6,7 +6,25 @@ return //Called when reaction STOP_PROCESSING -/datum/chemical_reaction/proc/FermiFinish(datum/reagents/holder) +/datum/chemical_reaction/proc/FermiFinish(datum/reagents/holder, var/atom/my_atom, reactVol) + if(clear_conversion == REACTION_CLEAR_IMPURE | REACTION_CLEAR_INVERSE) + for(var/id in results) + var/datum/reagent/R = my_atom.reagents.has_reagent("[id]") + if(R.purity == 1) + continue + + var/cached_volume = R.volume + if(clear_conversion == REACTION_CLEAR_INVERSE && R.inverse_chem) + if(R.inverse_chem_val > R.purity) + my_atom.reagents.remove_reagent(R.id, cached_volume, FALSE) + my_atom.reagents.add_reagent(R.inverse_chem, cached_volume, FALSE, other_purity = 1) + + else if (clear_conversion == REACTION_CLEAR_IMPURE && R.impure_chem) + var/impureVol = cached_volume * (1 - R.purity) + my_atom.reagents.remove_reagent(R.id, (impureVol), FALSE) + my_atom.reagents.add_reagent(R.impure_chem, impureVol, FALSE, other_purity = 1) + R.cached_purity = R.purity + R.purity = 1 return //Called when temperature is above a certain threshold, or if purity is too low. diff --git a/modular_citadel/code/modules/reagents/reagent container/milking machine.dm b/modular_citadel/code/modules/reagents/reagent container/milking machine.dm index 3f070be4..057c657e 100644 --- a/modular_citadel/code/modules/reagents/reagent container/milking machine.dm +++ b/modular_citadel/code/modules/reagents/reagent container/milking machine.dm @@ -9,7 +9,7 @@ var/on = FALSE var/obj/item/reagent_containers/glass/inserted_item = null - + var/transfer_rate = 0.25 // How much we transfer every 2 seconds var/target_organ = "breasts" // What organ we are transfering from @@ -42,11 +42,11 @@ UpdateIcon() else ..() - + /obj/item/milker/proc/UpdateIcon() icon_state = "[on ? "On" : "Off"][inserted_item ? "Beaker" : ""]" item_state = icon_state - + /obj/item/milker/AltClick(mob/living/user) add_fingerprint(user) @@ -75,9 +75,9 @@ icon_state = "PenisOff" item_state = "PenisOff" desc = "A pocket sized pump and tubing assembly designed to collect and store products from the penis." - + target_organ = "testicles" // Since semen is stored in the balls - + /obj/item/milker/penis/UpdateIcon() icon_state = "Penis[on ? "On" : "Off"][inserted_item ? "Beaker" : ""]" item_state = icon_state diff --git a/modular_citadel/icons/mob/mam_tails.dmi b/modular_citadel/icons/mob/mam_tails.dmi index b16de1c0..5e03cc86 100644 Binary files a/modular_citadel/icons/mob/mam_tails.dmi and b/modular_citadel/icons/mob/mam_tails.dmi differ diff --git a/modular_citadel/icons/obj/clothing/trek_item_icon.dmi b/modular_citadel/icons/obj/clothing/trek_item_icon.dmi index ed328661..570acbf4 100644 Binary files a/modular_citadel/icons/obj/clothing/trek_item_icon.dmi and b/modular_citadel/icons/obj/clothing/trek_item_icon.dmi differ diff --git a/modular_citadel/interface/skin.dmf b/modular_citadel/interface/skin.dmf index 3c766db6..7dddfa2e 100644 --- a/modular_citadel/interface/skin.dmf +++ b/modular_citadel/interface/skin.dmf @@ -54,7 +54,7 @@ window "mainwindow" size = 640x440 anchor1 = none anchor2 = none - background-color = #eeeeee + background-color = #242424 is-default = true saved-params = "pos;size;is-minimized;is-maximized" icon = 'icons\\ss13_64.png' @@ -66,7 +66,7 @@ window "mainwindow" size = 637x440 anchor1 = 0,0 anchor2 = 100,100 - background-color = #eeeeee + background-color = #272727 saved-params = "splitter" left = "mapwindow" right = "infowindow" @@ -78,7 +78,7 @@ window "mainwindow" size = 200x200 anchor1 = none anchor2 = none - background-color = #ffffff + background-color = #272727 is-visible = false saved-params = "" elem "tooltip" @@ -87,7 +87,7 @@ window "mainwindow" size = 999x999 anchor1 = none anchor2 = none - background-color = #ffffff + background-color = #272727 is-visible = false saved-params = "" @@ -119,7 +119,7 @@ window "infowindow" size = 640x480 anchor1 = none anchor2 = none - background-color = #eeeeee + background-color = #242424 saved-params = "pos;size;is-minimized;is-maximized" is-pane = true elem "info" @@ -128,6 +128,7 @@ window "infowindow" size = 640x445 anchor1 = 0,0 anchor2 = 100,100 + background-color = #272727 saved-params = "splitter" left = "statwindow" right = "outputwindow" @@ -138,7 +139,8 @@ window "infowindow" size = 104x20 anchor1 = 3,0 anchor2 = 19,0 - background-color = #90b3dd + text-color = #e0e0e0 + background-color = #40628a saved-params = "is-checked" text = "Changelog" command = "changelog" @@ -148,7 +150,8 @@ window "infowindow" size = 100x20 anchor1 = 19,0 anchor2 = 34,0 - background-color = #90b3dd + text-color = #e0e0e0 + background-color = #40628a saved-params = "is-checked" text = "Rules" command = "rules" @@ -158,7 +161,8 @@ window "infowindow" size = 100x20 anchor1 = 34,0 anchor2 = 50,0 - background-color = #90b3dd + text-color = #e0e0e0 + background-color = #40628a saved-params = "is-checked" text = "Wiki" command = "wiki" @@ -168,7 +172,8 @@ window "infowindow" size = 100x20 anchor1 = 50,0 anchor2 = 66,0 - background-color = #90b3dd + text-color = #e0e0e0 + background-color = #40628a saved-params = "is-checked" text = "Forum" command = "forum" @@ -178,7 +183,8 @@ window "infowindow" size = 100x20 anchor1 = 66,0 anchor2 = 81,0 - background-color = #90b3dd + text-color = #e0e0e0 + background-color = #40628a saved-params = "is-checked" text = "GitHub" command = "github" @@ -189,7 +195,8 @@ window "infowindow" anchor1 = 81,0 anchor2 = 97,0 font-size = 8 - background-color = #ef7f7f + text-color = #e0e0e0 + background-color = #A92c2c saved-params = "is-checked" text = "Report Issue" command = "report-issue" @@ -201,7 +208,7 @@ window "outputwindow" size = 640x480 anchor1 = none anchor2 = none - background-color = #eeeeee + background-color = #272727 saved-params = "pos;size;is-minimized;is-maximized" titlebar = false statusbar = false @@ -225,7 +232,8 @@ window "outputwindow" size = 37x20 anchor1 = 100,100 anchor2 = none - background-color = #eeeeee + text-color = #e0e0e0 + background-color = #272727 saved-params = "is-checked" text = "Chat" command = ".winset \"say.is-checked=true ? input.command=\"!say \\\"\" : input.command=\"" @@ -237,7 +245,7 @@ window "outputwindow" size = 640x456 anchor1 = 0,0 anchor2 = 100,100 - background-color = #ffffff + background-color = #272727 is-visible = false is-disabled = true saved-params = "" @@ -248,6 +256,8 @@ window "outputwindow" size = 640x456 anchor1 = 0,0 anchor2 = 100,100 + text-color = #e0e0e0 + background-color = #272727 is-default = true saved-params = "" @@ -258,7 +268,7 @@ window "statwindow" size = 640x480 anchor1 = none anchor2 = none - background-color = #eeeeee + background-color = #242424 saved-params = "pos;size;is-minimized;is-maximized" is-pane = true elem "stat" @@ -267,9 +277,14 @@ window "statwindow" size = 640x480 anchor1 = 0,0 anchor2 = 100,100 + text-color = #e0e0e0 + background-color = #272727 is-default = true saved-params = "" - tab-background-color = #eeeeee + tab-text-color = #e0e0e0 + tab-background-color = #242424 + prefix-color = #e0e0e0 + suffix-color = #e0e0e0 window "preferences_window" elem "preferences_window" diff --git a/sound/FermiChem/SoundSources.txt b/sound/FermiChem/SoundSources.txt index bd45f866..1420814d 100644 --- a/sound/FermiChem/SoundSources.txt +++ b/sound/FermiChem/SoundSources.txt @@ -6,5 +6,6 @@ heatacid.ogg - from https://freesound.org/people/klankbeeld/sounds/233697/ from bubbles2.ogg from fuse.ogg bufferadd.ogg- https://freesound.org/people/toiletrolltube/sounds/181483/ +heatdamn.ogg - from https://freesound.org/people/klankbeeld/sounds/233697/ Work is licensed under the Creative Commons and Attribution License. \ No newline at end of file diff --git a/sound/FermiChem/heatdam.ogg b/sound/FermiChem/heatdam.ogg new file mode 100644 index 00000000..ab8492e9 Binary files /dev/null and b/sound/FermiChem/heatdam.ogg differ diff --git a/sound/creatures/goose1.ogg b/sound/creatures/goose1.ogg new file mode 100644 index 00000000..3d605ad6 Binary files /dev/null and b/sound/creatures/goose1.ogg differ diff --git a/sound/creatures/goose2.ogg b/sound/creatures/goose2.ogg new file mode 100644 index 00000000..735faba7 Binary files /dev/null and b/sound/creatures/goose2.ogg differ diff --git a/sound/creatures/goose3.ogg b/sound/creatures/goose3.ogg new file mode 100644 index 00000000..1aeec773 Binary files /dev/null and b/sound/creatures/goose3.ogg differ diff --git a/sound/creatures/goose4.ogg b/sound/creatures/goose4.ogg new file mode 100644 index 00000000..699f143b Binary files /dev/null and b/sound/creatures/goose4.ogg differ diff --git a/sound/weapons/gunshot_braton.ogg b/sound/weapons/gunshot_braton.ogg new file mode 100644 index 00000000..6929d4d6 Binary files /dev/null and b/sound/weapons/gunshot_braton.ogg differ diff --git a/sound/weapons/gunshot_lato.ogg b/sound/weapons/gunshot_lato.ogg new file mode 100644 index 00000000..c29201eb Binary files /dev/null and b/sound/weapons/gunshot_lato.ogg differ diff --git a/tgstation.dme b/tgstation.dme index f152f011..bc108b37 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -231,6 +231,7 @@ #include "code\controllers\subsystem\augury.dm" #include "code\controllers\subsystem\autotransfer.dm" #include "code\controllers\subsystem\blackbox.dm" +#include "code\controllers\subsystem\chat.dm" #include "code\controllers\subsystem\communications.dm" #include "code\controllers\subsystem\dbcore.dm" #include "code\controllers\subsystem\dcs.dm" @@ -2183,6 +2184,7 @@ #include "code\modules\mob\living\simple_animal\hostile\eyeballs.dm" #include "code\modules\mob\living\simple_animal\hostile\faithless.dm" #include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm" +#include "code\modules\mob\living\simple_animal\hostile\goose.dm" #include "code\modules\mob\living\simple_animal\hostile\headcrab.dm" #include "code\modules\mob\living\simple_animal\hostile\heart.dm" #include "code\modules\mob\living\simple_animal\hostile\hivebot.dm" @@ -2520,6 +2522,7 @@ #include "code\modules\reagents\chemistry\reagents\drink_reagents.dm" #include "code\modules\reagents\chemistry\reagents\drug_reagents.dm" #include "code\modules\reagents\chemistry\reagents\food_reagents.dm" +#include "code\modules\reagents\chemistry\reagents\impure_reagents.dm" #include "code\modules\reagents\chemistry\reagents\medicine_reagents.dm" #include "code\modules\reagents\chemistry\reagents\other_reagents.dm" #include "code\modules\reagents\chemistry\reagents\pyrotechnic_reagents.dm" @@ -2769,6 +2772,9 @@ #include "code\modules\surgery\advanced\viral_bonding.dm" #include "code\modules\surgery\advanced\bioware\bioware.dm" #include "code\modules\surgery\advanced\bioware\bioware_surgery.dm" +#include "code\modules\surgery\advanced\bioware\experimental_dissection..dm" +#include "code\modules\surgery\advanced\bioware\ligament_hook.dm" +#include "code\modules\surgery\advanced\bioware\ligament_reinforcement.dm" #include "code\modules\surgery\advanced\bioware\nerve_grounding.dm" #include "code\modules\surgery\advanced\bioware\nerve_splicing.dm" #include "code\modules\surgery\advanced\bioware\vein_threading.dm" @@ -2871,11 +2877,14 @@ #include "code\modules\zombie\items.dm" #include "code\modules\zombie\organs.dm" #include "hyperstation\code\gamemode\werewolf\werewolf.dm" +#include "hyperstation\code\mobs\hugbot.dm" #include "hyperstation\code\mobs\mimic.dm" #include "hyperstation\code\mobs\werewolf.dm" #include "hyperstation\code\modules\antagonists\werewolf\werewolf.dm" +#include "hyperstation\code\modules\crafting\recipes.dm" #include "hyperstation\code\obj\decal.dm" #include "hyperstation\code\obj\fluff.dm" +#include "hyperstation\code\obj\milking machine.dm" #include "hyperstation\code\obj\plushes.dm" #include "hyperstation\code\obj\pregnancytester.dm" #include "hyperstation\code\obj\rewards.dm" @@ -3016,6 +3025,7 @@ #include "modular_citadel\code\modules\clothing\under\trek_under.dm" #include "modular_citadel\code\modules\clothing\under\turtlenecks.dm" #include "modular_citadel\code\modules\clothing\under\under.dm" +#include "modular_citadel\code\modules\crafting\recipes.dm" #include "modular_citadel\code\modules\custom_loadout\custom_items.dm" #include "modular_citadel\code\modules\custom_loadout\load_to_mob.dm" #include "modular_citadel\code\modules\custom_loadout\read_from_file.dm"