diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm
index 500fc80ded..b62ce3c317 100644
--- a/_maps/map_files/OmegaStation/OmegaStation.dmm
+++ b/_maps/map_files/OmegaStation/OmegaStation.dmm
@@ -1552,10 +1552,6 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
-/obj/machinery/camera{
- c_tag = "Bridge Center";
- dir = 1
- },
/obj/item/storage/fancy/donut_box,
/obj/item/clothing/mask/cigarette/cigar/havana{
pixel_x = -3
@@ -1859,7 +1855,6 @@
/turf/closed/wall,
/area/command/heads_quarters/captain/private)
"adI" = (
-/obj/structure/filingcabinet,
/obj/structure/cable/white{
icon_state = "2-4"
},
@@ -1871,6 +1866,7 @@
dir = 4;
name = "command camera"
},
+/obj/structure/closet/secure_closet/captains,
/turf/open/floor/wood,
/area/command/heads_quarters/captain/private)
"adJ" = (
@@ -1883,16 +1879,10 @@
/obj/structure/cable/white{
icon_state = "4-8"
},
-/obj/item/kirbyplants{
- icon_state = "plant-22"
- },
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 1
},
-/obj/machinery/camera{
- c_tag = "Captain's Quarters";
- dir = 1
- },
+/obj/structure/filingcabinet,
/turf/open/floor/wood{
icon_state = "wood-broken"
},
@@ -2555,13 +2545,15 @@
/turf/open/floor/plating,
/area/cargo/qm)
"aeS" = (
-/obj/structure/closet/crate,
-/obj/effect/turf_decal/delivery,
-/obj/item/toy/figure/cargotech,
-/turf/open/floor/plasteel,
-/area/cargo/storage)
+/obj/machinery/camera{
+ c_tag = "MiniSat External Southwest";
+ dir = 8;
+ network = list("minisat");
+ start_active = 1
+ },
+/turf/open/floor/plating/asteroid/airless,
+/area/asteroid/nearstation)
"aeT" = (
-/obj/structure/closet/crate,
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel,
/area/cargo/storage)
@@ -3337,10 +3329,6 @@
/obj/structure/cable/white{
icon_state = "1-2"
},
-/obj/machinery/camera{
- c_tag = "Head of Personnel's Office";
- dir = 1
- },
/turf/open/floor/wood{
icon_state = "wood-broken5"
},
@@ -3430,6 +3418,8 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
+/obj/item/toy/figure/cargotech,
+/obj/structure/closet/crate,
/turf/open/floor/plasteel,
/area/cargo/storage)
"agA" = (
@@ -4055,10 +4045,10 @@
/obj/structure/sign/warning/securearea{
pixel_x = -32
},
-/obj/structure/closet/secure_closet/captains,
/obj/effect/turf_decal/stripes/end{
dir = 1
},
+/obj/machinery/vending/wardrobe/cap_wardrobe,
/turf/open/floor/plasteel/dark,
/area/command/heads_quarters/captain/private)
"ahI" = (
@@ -5250,7 +5240,6 @@
/obj/effect/turf_decal/tile/blue{
dir = 8
},
-/obj/effect/landmark/start/paramedic,
/turf/open/floor/plasteel,
/area/medical/medbay/zone3)
"ajO" = (
@@ -6310,6 +6299,28 @@
},
/turf/open/floor/plasteel,
/area/cargo/storage)
+"alE" = (
+/obj/structure/filingcabinet/chestdrawer,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/neutral,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj/machinery/camera{
+ c_tag = "Chief Engineer's Office";
+ network = list("ss13","engine")
+ },
+/mob/living/simple_animal/parrot/Polly,
+/obj/machinery/atmospherics/pipe/simple/orange/visible{
+ dir = 10
+ },
+/turf/open/floor/plasteel/dark,
+/area/command/heads_quarters/ce)
"alF" = (
/obj/machinery/power/apc{
areastring = "/area/cargo/storage";
@@ -7222,6 +7233,13 @@
},
/obj/effect/turf_decal/tile/yellow,
/obj/machinery/atmospherics/pipe/simple/orange/visible,
+/obj/machinery/button/door{
+ id = "engstorage";
+ name = "Engineering Secure Storage Control";
+ pixel_x = -25;
+ pixel_y = 7;
+ req_access_txt = "10"
+ },
/turf/open/floor/plasteel,
/area/command/heads_quarters/ce)
"anw" = (
@@ -8022,6 +8040,9 @@
/obj/item/stack/cable_coil/white,
/obj/item/hand_labeler,
/obj/item/hand_labeler_refill,
+/obj/machinery/status_display/ai{
+ pixel_x = -32
+ },
/turf/open/floor/plasteel,
/area/service/bar/atrium)
"aoO" = (
@@ -8392,12 +8413,6 @@
/obj/structure/cable/white{
icon_state = "2-4"
},
-/obj/machinery/button/door{
- id = "engstorage";
- name = "Engineering Secure Storage Control";
- pixel_y = 24;
- req_access_txt = "10"
- },
/obj/effect/turf_decal/stripes/line{
dir = 9
},
@@ -8784,6 +8799,9 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 9
},
+/obj/machinery/status_display{
+ pixel_x = 32
+ },
/turf/open/floor/plasteel,
/area/service/bar/atrium)
"apY" = (
@@ -11840,7 +11858,6 @@
/turf/open/floor/plasteel/freezer,
/area/commons/toilet/restrooms)
"avx" = (
-/obj/machinery/atmospherics/pipe/simple/yellow/visible,
/obj/machinery/computer/atmos_control/tank/oxygen_tank{
dir = 1
},
@@ -11848,6 +11865,7 @@
dir = 4
},
/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/layer_manifold,
/turf/open/floor/plasteel/dark/side,
/area/engineering/atmos)
"avy" = (
@@ -17963,8 +17981,9 @@
},
/obj/machinery/door/window/southright,
/obj/item/radio/intercom{
- name = "Station Intercom";
- pixel_y = 26
+ frequency = 1485;
+ name = "Station Intercom (Medbay)";
+ pixel_y = 30
},
/turf/open/floor/plasteel/dark/side{
dir = 1
@@ -18964,6 +18983,10 @@
/obj/item/paper_bin,
/obj/item/pen,
/obj/effect/turf_decal/delivery,
+/obj/machinery/door/window/westright{
+ name = "Hydroponics Desk";
+ req_access_txt = "35"
+ },
/turf/open/floor/plasteel,
/area/service/hydroponics)
"aIQ" = (
@@ -19639,6 +19662,11 @@
/obj/item/reagent_containers/food/snacks/grown/pumpkin,
/obj/item/reagent_containers/food/snacks/grown/grapes,
/obj/effect/turf_decal/delivery,
+/obj/machinery/door/window/northleft{
+ dir = 8;
+ name = "Hydroponics Desk";
+ req_access_txt = "35"
+ },
/turf/open/floor/plasteel,
/area/service/hydroponics)
"aJW" = (
@@ -21679,7 +21707,7 @@
name = "Cloning Lab";
req_access_txt = "5"
},
-/turf/open/floor/plasteel,
+/turf/open/floor/plasteel/white,
/area/medical/genetics)
"aNR" = (
/obj/effect/spawner/structure/window/reinforced,
@@ -22195,13 +22223,13 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
-/obj/machinery/status_display{
- pixel_y = 32
- },
/obj/structure/cable/white{
icon_state = "4-8"
},
/obj/effect/turf_decal/bot,
+/obj/machinery/status_display/ai{
+ pixel_y = 32
+ },
/turf/open/floor/plasteel/dark/side{
dir = 8
},
@@ -22916,6 +22944,9 @@
pixel_x = -24
},
/obj/effect/turf_decal/bot,
+/obj/machinery/status_display/evac{
+ pixel_y = -32
+ },
/turf/open/floor/plasteel/dark/side{
dir = 8
},
@@ -22924,10 +22955,6 @@
/obj/item/kirbyplants{
icon_state = "plant-21"
},
-/obj/machinery/camera{
- c_tag = "Central Primary Hallway South-West";
- dir = 1
- },
/turf/open/floor/plasteel{
heat_capacity = 1e+006
},
@@ -23664,16 +23691,13 @@
/obj/structure/cable/white{
icon_state = "1-4"
},
-/obj/item/radio/intercom{
- name = "Station Intercom";
- pixel_x = -28
- },
/obj/effect/turf_decal/stripes/line{
dir = 8
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
+/obj/structure/closet/secure_closet/engineering_electrical,
/turf/open/floor/engine,
/area/engineering/main)
"aRG" = (
@@ -23785,6 +23809,32 @@
},
/turf/open/floor/plating,
/area/maintenance/port/aft)
+"aRT" = (
+/obj/structure/table/wood,
+/obj/item/flashlight/lamp,
+/obj/machinery/computer/security/telescreen/entertainment{
+ pixel_x = -32
+ },
+/obj/machinery/camera{
+ c_tag = "Library 2";
+ dir = 4
+ },
+/obj/structure/sign/painting/library{
+ pixel_y = 32
+ },
+/turf/open/floor/plasteel/dark/side{
+ dir = 10
+ },
+/area/service/library)
+"aRU" = (
+/obj/structure/table/wood,
+/obj/item/folder,
+/obj/item/pen,
+/obj/structure/sign/painting/library{
+ pixel_x = 32
+ },
+/turf/open/floor/plasteel/dark,
+/area/service/library)
"aRV" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/structure/cable/white{
@@ -23848,6 +23898,19 @@
/obj/machinery/computer/libraryconsole,
/turf/open/floor/plasteel/dark,
/area/service/library)
+"aSd" = (
+/obj/structure/table/wood,
+/obj/item/flashlight/lamp,
+/obj/machinery/newscaster{
+ pixel_x = 32
+ },
+/obj/structure/sign/painting/library{
+ pixel_x = 32
+ },
+/turf/open/floor/plasteel/dark/side{
+ dir = 10
+ },
+/area/service/library)
"aSe" = (
/obj/machinery/vending/wallmed{
pixel_y = 32
@@ -24178,7 +24241,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 10
},
-/obj/structure/closet/secure_closet/engineering_electrical,
+/obj/machinery/vending/tool,
/turf/open/floor/engine,
/area/engineering/main)
"aSQ" = (
@@ -24801,6 +24864,15 @@
"aUi" = (
/turf/closed/wall/rust,
/area/maintenance/port/aft)
+"aUj" = (
+/obj/machinery/photocopier,
+/obj/structure/sign/painting/library{
+ pixel_x = 32
+ },
+/turf/open/floor/plasteel/dark/side{
+ dir = 10
+ },
+/area/service/library)
"aUk" = (
/obj/structure/table/wood,
/obj/item/storage/pill_bottle,
@@ -25051,20 +25123,6 @@
/obj/effect/turf_decal/trimline/green/line,
/turf/open/floor/plasteel/dark,
/area/maintenance/port/aft)
-"aUK" = (
-/obj/structure/cable/white{
- icon_state = "4-8"
- },
-/obj/machinery/door/firedoor,
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
- dir = 4
- },
-/obj/machinery/door/airlock/virology{
- name = "Virology Access";
- req_access_txt = "39"
- },
-/turf/open/floor/plasteel,
-/area/medical/virology)
"aUL" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -25661,7 +25719,7 @@
name = "Crematorium";
req_access_txt = "27"
},
-/turf/open/floor/plasteel/dark,
+/turf/open/floor/plating,
/area/maintenance/port/aft)
"aVZ" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
@@ -26049,6 +26107,9 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
+/obj/machinery/newscaster{
+ pixel_y = 32
+ },
/turf/open/floor/plasteel/white,
/area/medical/virology)
"aWJ" = (
@@ -26076,24 +26137,14 @@
dir = 4
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
-/obj/machinery/newscaster{
- pixel_x = 32
- },
-/turf/open/floor/plasteel,
-/area/medical/virology)
-"aWM" = (
-/obj/machinery/door/firedoor,
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
- dir = 4
- },
-/obj/structure/cable/white{
- icon_state = "4-8"
- },
-/obj/machinery/door/airlock/virology{
- name = "Virology Access";
+/obj/machinery/doorButtons/access_button{
+ idDoor = "virology_airlock_interior";
+ idSelf = "virology_airlock_control";
+ name = "Virology Access Button";
+ pixel_x = 24;
req_access_txt = "39"
},
-/turf/open/floor/plasteel/white,
+/turf/open/floor/plasteel,
/area/medical/virology)
"aWN" = (
/obj/machinery/door/firedoor,
@@ -26105,7 +26156,7 @@
name = "Chemistry Lab";
req_access_txt = "5; 33"
},
-/turf/open/floor/plasteel,
+/turf/open/floor/plasteel/white,
/area/medical/chemistry)
"aWO" = (
/obj/effect/spawner/structure/window/reinforced,
@@ -26247,7 +26298,6 @@
/obj/effect/turf_decal/stripes/line{
dir = 8
},
-/obj/machinery/light/small,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 9
},
@@ -26257,6 +26307,13 @@
/obj/effect/turf_decal/trimline/green/corner{
dir = 1
},
+/obj/machinery/doorButtons/access_button{
+ idDoor = "virology_airlock_exterior";
+ idSelf = "virology_airlock_control";
+ name = "Virology Access Button";
+ pixel_y = -24;
+ req_access_txt = "39"
+ },
/turf/open/floor/plating,
/area/maintenance/port/aft)
"aXe" = (
@@ -26265,12 +26322,30 @@
/obj/structure/cable/white{
icon_state = "1-8"
},
+/obj/machinery/light/small{
+ dir = 4
+ },
/turf/open/floor/plating,
/area/maintenance/port/aft)
"aXf" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/closed/wall,
/area/service/library)
+"aXg" = (
+/obj/structure/sign/painting/library{
+ pixel_y = -32
+ },
+/turf/open/floor/plasteel/dark/side{
+ dir = 10
+ },
+/area/service/library)
+"aXh" = (
+/obj/machinery/light,
+/obj/structure/sign/painting/library{
+ pixel_y = -32
+ },
+/turf/open/floor/plasteel/dark,
+/area/service/library)
"aXi" = (
/obj/structure/bonfire,
/obj/item/reagent_containers/food/drinks/bottle/orangejuice{
@@ -26285,6 +26360,27 @@
/obj/effect/decal/remains/human,
/turf/open/floor/plating,
/area/maintenance/port/aft)
+"aXj" = (
+/obj/structure/sign/painting/library{
+ pixel_y = -32
+ },
+/turf/open/floor/plasteel/dark,
+/area/service/library)
+"aXl" = (
+/obj/structure/table/wood,
+/obj/item/paper_bin,
+/obj/item/pen,
+/obj/machinery/camera{
+ c_tag = "Library 1";
+ dir = 8
+ },
+/obj/structure/sign/painting/library{
+ pixel_x = 32
+ },
+/turf/open/floor/plasteel/dark/side{
+ dir = 10
+ },
+/area/service/library)
"aXm" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -26593,10 +26689,6 @@
/area/medical/medbay/zone3)
"aXQ" = (
/obj/structure/closet/secure_closet/medical3,
-/obj/item/radio/intercom{
- name = "Station Intercom";
- pixel_y = 26
- },
/obj/machinery/light_switch{
pixel_x = 24;
pixel_y = 24
@@ -26613,6 +26705,11 @@
/obj/item/clothing/neck/stethoscope,
/obj/item/clothing/neck/stethoscope,
/obj/item/gun/syringe/dart,
+/obj/item/radio/intercom{
+ frequency = 1485;
+ name = "Station Intercom (Medbay)";
+ pixel_y = 30
+ },
/turf/open/floor/plasteel,
/area/medical/medbay/zone3)
"aXR" = (
@@ -27017,7 +27114,7 @@
name = "Medbay Storage";
req_access_txt = "5"
},
-/turf/open/floor/plasteel,
+/turf/open/floor/plasteel/white,
/area/medical/medbay/zone3)
"aYK" = (
/obj/effect/turf_decal/delivery,
@@ -27047,6 +27144,7 @@
/obj/effect/turf_decal/tile/blue{
dir = 8
},
+/obj/effect/landmark/start/medical_doctor,
/turf/open/floor/plasteel,
/area/medical/medbay/zone3)
"aYN" = (
@@ -27133,7 +27231,7 @@
name = "Medbay";
req_access_txt = "5"
},
-/turf/open/floor/plasteel,
+/turf/open/floor/plasteel/white,
/area/medical/medbay/zone3)
"aYU" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
@@ -27476,7 +27574,7 @@
name = "Medbay Storage";
req_access_txt = "5"
},
-/turf/open/floor/plasteel,
+/turf/open/floor/plasteel/white,
/area/medical/medbay/zone3)
"aZG" = (
/obj/structure/cable/white{
@@ -27612,7 +27710,7 @@
name = "Medbay";
req_access_txt = "5"
},
-/turf/open/floor/plasteel,
+/turf/open/floor/plasteel/white,
/area/medical/medbay/zone3)
"aZQ" = (
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
@@ -27978,12 +28076,16 @@
/area/medical/medbay/zone3)
"bay" = (
/obj/machinery/atmospherics/pipe/manifold/supply/hidden,
-/obj/machinery/defibrillator_mount/loaded{
- pixel_y = -32
- },
/obj/effect/turf_decal/tile/blue{
dir = 8
},
+/obj/item/radio/intercom{
+ broadcasting = 1;
+ frequency = 1485;
+ listening = 0;
+ name = "Station Intercom (Medbay)";
+ pixel_y = -30
+ },
/turf/open/floor/plasteel/white,
/area/medical/medbay/zone3)
"baz" = (
@@ -28658,6 +28760,7 @@
},
/obj/effect/decal/cleanable/oil,
/obj/effect/turf_decal/bot,
+/obj/item/bot_assembly/cleanbot,
/turf/open/floor/plasteel,
/area/science/robotics/lab)
"bbN" = (
@@ -28817,15 +28920,15 @@
},
/obj/item/storage/backpack/duffelbag/med/surgery,
/obj/structure/table/reinforced,
+/obj/item/radio/intercom{
+ name = "Station Intercom";
+ pixel_y = 26
+ },
/turf/open/floor/plasteel/dark,
/area/medical/medbay/zone3)
"bce" = (
/obj/structure/table/optable,
/obj/effect/decal/cleanable/blood/old,
-/obj/item/radio/intercom{
- name = "Station Intercom";
- pixel_y = 26
- },
/obj/effect/turf_decal/tile/blue{
dir = 1
},
@@ -28880,6 +28983,11 @@
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/effect/turf_decal/delivery,
+/obj/item/reagent_containers/glass/bottle/epinephrine,
+/obj/item/reagent_containers/glass/bottle/charcoal{
+ pixel_x = 6
+ },
+/obj/item/reagent_containers/syringe,
/turf/open/floor/plasteel,
/area/medical/medbay/zone3)
"bck" = (
@@ -28889,10 +28997,11 @@
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/machinery/door/airlock/medical/glass{
- name = "Medbay Desk";
- req_access_txt = "5"
+ id_tag = "MedbayFoyer";
+ name = "Paramedic's Office";
+ req_access_txt = "5;6;12;64"
},
-/turf/open/floor/plasteel,
+/turf/open/floor/plasteel/white,
/area/medical/medbay/zone3)
"bcl" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
@@ -29278,9 +29387,7 @@
},
/area/medical/medbay/zone3)
"bda" = (
-/obj/machinery/computer/med_data{
- dir = 4
- },
+/obj/machinery/suit_storage_unit/paramedic,
/turf/open/floor/plasteel/dark/side{
dir = 8
},
@@ -29289,7 +29396,6 @@
/obj/structure/chair/office/light{
dir = 1
},
-/obj/effect/landmark/start/medical_doctor,
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 1
},
@@ -29302,17 +29408,10 @@
/obj/effect/turf_decal/tile/blue{
dir = 8
},
+/obj/effect/landmark/start/paramedic,
/turf/open/floor/plasteel/white,
/area/medical/medbay/zone3)
"bdc" = (
-/obj/machinery/button/door{
- desc = "A remote control switch for the medbay foyer.";
- id = "MedbayFoyer";
- name = "Medbay Doors Control";
- normaldoorcontrol = 1;
- pixel_x = 24;
- pixel_y = 24
- },
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/effect/turf_decal/tile/blue{
dir = 1
@@ -29874,7 +29973,7 @@
name = "Surgery Theatre";
req_access_txt = "45"
},
-/turf/open/floor/plasteel,
+/turf/open/floor/plasteel/dark,
/area/medical/medbay/zone3)
"bdU" = (
/obj/machinery/firealarm{
@@ -29923,23 +30022,23 @@
/obj/machinery/computer/crew{
dir = 4
},
-/obj/machinery/newscaster{
- pixel_y = -32
- },
/obj/machinery/firealarm{
dir = 1;
pixel_x = -26;
pixel_y = -26
},
+/obj/machinery/newscaster{
+ pixel_x = -32
+ },
+/obj/machinery/airalarm{
+ dir = 1;
+ pixel_y = -22
+ },
/turf/open/floor/plasteel/dark/side{
dir = 8
},
/area/medical/medbay/zone3)
"bdY" = (
-/obj/machinery/airalarm{
- dir = 1;
- pixel_y = -22
- },
/obj/effect/turf_decal/tile/blue{
dir = 1
},
@@ -29947,16 +30046,27 @@
/obj/effect/turf_decal/tile/blue{
dir = 8
},
+/obj/structure/chair/office/light{
+ dir = 8
+ },
+/obj/machinery/button/door{
+ desc = "A remote control switch for the medbay foyer.";
+ id = "MedbayFoyer";
+ name = "Medbay Doors Control";
+ normaldoorcontrol = 1;
+ pixel_x = 24;
+ pixel_y = -24
+ },
+/obj/item/radio/intercom{
+ broadcasting = 1;
+ frequency = 1485;
+ listening = 0;
+ name = "Station Intercom (Medbay)";
+ pixel_y = -30
+ },
/turf/open/floor/plasteel/white,
/area/medical/medbay/zone3)
"bdZ" = (
-/obj/structure/chair/office/light{
- dir = 4
- },
-/obj/item/radio/intercom{
- name = "Station Intercom";
- pixel_y = -26
- },
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 1
},
@@ -29967,23 +30077,23 @@
/obj/effect/turf_decal/tile/blue{
dir = 8
},
+/obj/structure/closet/secure_closet/paramedic,
+/obj/machinery/camera{
+ c_tag = "Paramedic Disbatch";
+ dir = 10;
+ network = list("ss13","medbay")
+ },
/turf/open/floor/plasteel/white,
/area/medical/medbay/zone3)
"bea" = (
-/obj/structure/table/reinforced,
-/obj/machinery/door/firedoor,
-/obj/item/reagent_containers/glass/bottle/charcoal{
- pixel_x = 6
+/obj/machinery/camera{
+ c_tag = "MiniSat External South";
+ dir = 6;
+ network = list("minisat");
+ start_active = 1
},
-/obj/item/reagent_containers/glass/bottle/epinephrine,
-/obj/item/reagent_containers/syringe,
-/obj/machinery/door/window/westleft{
- name = "Medbay Desk";
- req_access_txt = "5"
- },
-/obj/effect/turf_decal/delivery,
-/turf/open/floor/plasteel,
-/area/medical/medbay/zone3)
+/turf/open/space/basic,
+/area/space)
"beb" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable/white,
@@ -31356,7 +31466,10 @@
},
/area/hallway/primary/aft)
"bgm" = (
-/turf/open/floor/plasteel/dark,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 6
+ },
+/turf/open/floor/engine,
/area/science/xenobiology)
"bgn" = (
/obj/structure/extinguisher_cabinet{
@@ -31377,6 +31490,9 @@
/obj/structure/cable/white{
icon_state = "0-2"
},
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
/turf/open/floor/plating,
/area/science/xenobiology)
"bgp" = (
@@ -31394,13 +31510,16 @@
pixel_y = 32
},
/obj/effect/turf_decal/bot,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
/turf/open/floor/plasteel/dark/side{
dir = 9
},
/area/science/xenobiology)
"bgq" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/effect/turf_decal/stripes/line,
+/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden,
/turf/open/floor/plasteel/dark/side{
dir = 1
},
@@ -31411,6 +31530,9 @@
icon_state = "1-2"
},
/obj/effect/turf_decal/stripes/line,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
/turf/open/floor/plasteel/dark/side{
dir = 1
},
@@ -31654,11 +31776,14 @@
/obj/machinery/light{
dir = 8
},
-/turf/open/floor/plasteel/dark,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
+ dir = 1
+ },
+/turf/open/floor/engine,
/area/science/xenobiology)
"bgZ" = (
/mob/living/simple_animal/slime,
-/turf/open/floor/circuit/green,
+/turf/open/floor/engine,
/area/science/xenobiology)
"bha" = (
/obj/structure/cable/white{
@@ -31688,7 +31813,6 @@
},
/area/science/xenobiology)
"bhc" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/structure/cable/white{
icon_state = "4-8"
},
@@ -31701,10 +31825,12 @@
/obj/effect/turf_decal/tile/purple{
dir = 8
},
+/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
+ dir = 4
+ },
/turf/open/floor/plasteel/white,
/area/science/xenobiology)
"bhd" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/structure/cable/white{
icon_state = "1-2"
},
@@ -31723,16 +31849,22 @@
/obj/effect/turf_decal/tile/purple{
dir = 4
},
+/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
+ dir = 8
+ },
/turf/open/floor/plasteel/white,
/area/science/xenobiology)
"bhg" = (
-/turf/open/floor/circuit/green,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
+ dir = 1
+ },
+/turf/open/floor/engine,
/area/science/xenobiology)
"bhi" = (
/obj/machinery/light{
dir = 4
},
-/turf/open/floor/plasteel/dark,
+/turf/open/floor/engine,
/area/science/xenobiology)
"bhj" = (
/obj/effect/turf_decal/sand/plating,
@@ -31989,7 +32121,7 @@
/obj/structure/disposaloutlet{
dir = 8
},
-/turf/open/floor/plasteel/dark,
+/turf/open/floor/engine,
/area/science/xenobiology)
"bhN" = (
/obj/effect/spawner/structure/window/reinforced,
@@ -32379,7 +32511,7 @@
name = "Chapel Quarters";
req_access_txt = "27"
},
-/turf/open/floor/plasteel,
+/turf/open/floor/plasteel/grimy,
/area/service/chapel/main)
"biI" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
@@ -32418,7 +32550,7 @@
name = "Chapel Office";
req_access_txt = "27"
},
-/turf/open/floor/plasteel,
+/turf/open/floor/plasteel/dark,
/area/service/chapel/main)
"biN" = (
/obj/machinery/light_switch{
@@ -32532,6 +32664,9 @@
/obj/structure/cable/white{
icon_state = "0-2"
},
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
/turf/open/floor/plating,
/area/science/xenobiology)
"biX" = (
@@ -32542,6 +32677,9 @@
req_access_txt = "55"
},
/obj/effect/turf_decal/bot,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
/turf/open/floor/plasteel/dark/side{
dir = 8
},
@@ -32592,7 +32730,7 @@
name = "server vent";
pressure_checks = 0
},
-/turf/open/floor/circuit/green/telecomms/mainframe,
+/turf/open/floor/circuit/telecomms,
/area/science/xenobiology)
"bje" = (
/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{
@@ -32605,7 +32743,7 @@
name = "science camera";
network = list("ss13","rd")
},
-/turf/open/floor/circuit/green/telecomms/mainframe,
+/turf/open/floor/circuit/telecomms,
/area/science/xenobiology)
"bjf" = (
/obj/structure/dresser,
@@ -32692,9 +32830,6 @@
/turf/open/floor/plasteel/dark,
/area/science/xenobiology)
"bjq" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
- dir = 1
- },
/obj/structure/cable/white{
icon_state = "4-8"
},
@@ -32704,6 +32839,9 @@
/obj/effect/turf_decal/tile/purple{
dir = 8
},
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
+ dir = 1
+ },
/turf/open/floor/plasteel/white,
/area/science/xenobiology)
"bjr" = (
@@ -32756,13 +32894,13 @@
/area/science/xenobiology)
"bjw" = (
/obj/machinery/atmospherics/pipe/manifold/general/hidden,
-/turf/open/floor/plasteel/dark/telecomms,
+/turf/open/floor/circuit/telecomms,
/area/science/xenobiology)
"bjx" = (
/obj/machinery/atmospherics/pipe/simple/general/hidden{
dir = 9
},
-/turf/open/floor/plasteel/dark/telecomms,
+/turf/open/floor/circuit/telecomms,
/area/science/xenobiology)
"bjy" = (
/obj/machinery/airalarm{
@@ -32835,6 +32973,7 @@
/obj/effect/turf_decal/tile/purple{
dir = 4
},
+/obj/machinery/portable_atmospherics/canister/bz,
/turf/open/floor/plasteel/white,
/area/science/xenobiology)
"bjH" = (
@@ -32847,7 +32986,7 @@
/turf/open/floor/plasteel,
/area/science/xenobiology)
"bjI" = (
-/turf/open/floor/circuit/green/telecomms/mainframe,
+/turf/open/floor/circuit/telecomms,
/area/science/xenobiology)
"bjJ" = (
/obj/machinery/photocopier,
@@ -33438,7 +33577,7 @@
/obj/structure/disposaloutlet{
dir = 4
},
-/turf/open/floor/plasteel/dark,
+/turf/open/floor/engine,
/area/science/xenobiology)
"boD" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
@@ -34000,6 +34139,10 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{
dir = 9
},
+/obj/item/radio/intercom{
+ name = "Station Intercom";
+ pixel_x = -28
+ },
/turf/open/floor/engine,
/area/engineering/main)
"bwW" = (
@@ -34355,6 +34498,27 @@
dir = 1
},
/area/engineering/atmos)
+"bNJ" = (
+/obj/structure/table/wood,
+/obj/item/crowbar/red,
+/obj/item/book/manual/splurt_space_law{
+ pixel_x = 3;
+ pixel_y = 3
+ },
+/obj/item/book/manual/wiki/detective,
+/obj/item/camera/detective,
+/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/security/detectives_office)
"bOy" = (
/obj/item/stack/ore/iron,
/obj/machinery/light/small{
@@ -34544,9 +34708,6 @@
/obj/structure/cable/white{
icon_state = "2-8"
},
-/obj/machinery/atmospherics/components/unary/vent_pump/on{
- dir = 8
- },
/obj/effect/turf_decal/delivery,
/obj/effect/turf_decal/tile/neutral{
dir = 1
@@ -34602,6 +34763,10 @@
},
/turf/open/floor/plasteel,
/area/command/gateway)
+"cVZ" = (
+/obj/structure/dresser,
+/turf/open/floor/plasteel,
+/area/security/prison)
"cWv" = (
/obj/machinery/atmospherics/pipe/simple/cyan/hidden,
/turf/closed/wall/r_wall,
@@ -34691,23 +34856,6 @@
},
/turf/open/floor/plating,
/area/science/mixing)
-"djq" = (
-/obj/structure/table/wood,
-/obj/item/flashlight/lamp,
-/obj/machinery/computer/security/telescreen/entertainment{
- pixel_x = -32
- },
-/obj/machinery/camera{
- c_tag = "Library 2";
- dir = 4
- },
-/obj/structure/sign/painting/library{
- pixel_y = 32
- },
-/turf/open/floor/plasteel/dark/side{
- dir = 10
- },
-/area/service/library)
"doD" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/machinery/door/firedoor,
@@ -34745,13 +34893,41 @@
},
/turf/open/floor/plasteel/dark/corner,
/area/engineering/atmos)
-"dJV" = (
-/obj/machinery/light,
-/obj/structure/sign/painting/library{
- pixel_y = -32
+"dHD" = (
+/obj/machinery/door/firedoor,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
},
-/turf/open/floor/plasteel/dark,
-/area/service/library)
+/obj/structure/cable/white{
+ icon_state = "4-8"
+ },
+/obj/effect/mapping_helpers/airlock/locked,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper{
+ dir = 8
+ },
+/obj/machinery/door/airlock/virology{
+ autoclose = 0;
+ frequency = 1449;
+ id_tag = "virology_airlock_exterior";
+ name = "Virology Exterior Airlock";
+ req_access_txt = "39"
+ },
+/turf/open/floor/plasteel/white,
+/area/medical/virology)
+"dIK" = (
+/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/obj/item/radio/intercom{
+ frequency = 1485;
+ name = "Station Intercom (Medbay)";
+ pixel_x = -30
+ },
+/turf/open/floor/plasteel,
+/area/hallway/primary/aft)
"dMl" = (
/obj/structure/sign/warning/fire,
/obj/machinery/atmospherics/pipe/simple/dark/visible{
@@ -34785,32 +34961,6 @@
dir = 4
},
/area/maintenance/starboard/aft)
-"dWc" = (
-/obj/structure/table/wood,
-/obj/item/book/manual/splurt_space_law,
-/obj/item/camera/detective,
-/obj/item/radio/intercom{
- name = "Station Intercom";
- pixel_x = -26
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj{
- name = "---Merge conflict marker---"
- },
-/obj/structure/table/wood,
-/obj/item/book/manual/wiki/security_space_law,
-/obj/item/camera/detective,
-/obj/item/radio/intercom{
- name = "Station Intercom";
- pixel_x = -26
- },
-/turf/open/floor/plasteel/dark/side{
- dir = 8
- },
-/area/command/heads_quarters/hos)
"dXv" = (
/obj/item/transfer_valve{
pixel_x = -5
@@ -34842,6 +34992,9 @@
/obj/effect/turf_decal/tile/purple{
dir = 1
},
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
/turf/open/floor/plasteel/white,
/area/science/xenobiology)
"eaf" = (
@@ -34852,6 +35005,13 @@
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/plasteel,
/area/engineering/atmos)
+"ebS" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
+/obj/machinery/status_display/evac{
+ pixel_x = -32
+ },
+/turf/open/floor/plasteel,
+/area/hallway/primary/starboard)
"eew" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/structure/cable{
@@ -34885,14 +35045,29 @@
},
/turf/open/floor/plating,
/area/maintenance/starboard/aft)
-"ete" = (
-/obj/structure/sign/painting/library{
- pixel_y = -32
+"ept" = (
+/obj/machinery/shower{
+ dir = 1
},
-/turf/open/floor/plasteel/dark/side{
- dir = 10
+/obj/structure/curtain,
+/obj/structure/window/spawner/north,
+/obj/structure/sign/poster/contraband/yes_erp{
+ pixel_x = 32
},
-/area/service/library)
+/obj/effect/turf_decal/bot,
+/obj{
+ name = "---Merge conflict marker---"
+ },
+/obj/machinery/shower{
+ dir = 1
+ },
+/obj/structure/curtain,
+/obj/structure/window/spawner/north,
+/obj/structure/sign/poster/contraband/yes_erp{
+ pixel_x = 32
+ },
+/turf/open/floor/plasteel/freezer,
+/area/commons/toilet/restrooms)
"eva" = (
/obj/machinery/atmospherics/pipe/simple/green/visible{
dir = 4
@@ -34973,12 +35148,12 @@
/obj/machinery/atmospherics/pipe/simple/green/visible{
dir = 4
},
-/obj/machinery/atmospherics/pipe/simple/yellow/visible,
/obj/machinery/computer/atmos_control/tank/nitrogen_tank{
dir = 1
},
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/yellow,
+/obj/machinery/atmospherics/pipe/layer_manifold,
/turf/open/floor/plasteel/dark/corner{
dir = 8
},
@@ -35121,22 +35296,6 @@
/obj/effect/turf_decal/sand/plating,
/turf/open/floor/plating/airless,
/area/asteroid/nearstation)
-"fja" = (
-/obj/structure/table/reinforced,
-/obj/item/book/manual/splurt_space_law,
-/obj/item/radio,
-/obj/structure/reagent_dispensers/peppertank{
- pixel_x = 32
- },
-/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/checkpoint)
"fji" = (
/obj/structure/disposaloutlet,
/obj/structure/disposalpipe/trunk{
@@ -35243,6 +35402,25 @@
},
/turf/open/floor/plasteel,
/area/engineering/atmos)
+"fBc" = (
+/obj/structure/table/reinforced,
+/obj/item/book/manual/splurt_space_law,
+/obj/item/taperecorder,
+/obj/machinery/status_display{
+ pixel_y = -32
+ },
+/obj/item/flashlight/seclite,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/turf/open/floor/plasteel/dark,
+/area/security/brig)
"fDZ" = (
/obj/machinery/sparker/toxmix{
pixel_x = 25
@@ -35272,6 +35450,15 @@
/obj/machinery/portable_atmospherics/canister,
/turf/open/floor/plasteel,
/area/engineering/atmos)
+"fHF" = (
+/obj/structure/table/wood,
+/obj/item/folder,
+/obj/item/pen,
+/obj/structure/sign/painting/library{
+ pixel_x = -32
+ },
+/turf/open/floor/plasteel/dark,
+/area/service/library)
"fIN" = (
/obj/machinery/atmospherics/pipe/simple/general/visible{
dir = 10
@@ -35336,15 +35523,6 @@
/obj/structure/fans/tiny,
/turf/open/floor/plasteel,
/area/hallway/secondary/exit)
-"fXe" = (
-/obj/structure/chair/office/dark,
-/obj/effect/turf_decal/tile/red,
-/obj/effect/turf_decal/tile/red{
- dir = 8
- },
-/obj/effect/landmark/start/peacekeeper,
-/turf/open/floor/plasteel,
-/area/hallway/secondary/exit)
"fYx" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -35501,7 +35679,10 @@
/obj/structure/sign/poster/random{
pixel_y = 32
},
-/turf/open/floor/plasteel/dark,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 10
+ },
+/turf/open/floor/engine,
/area/science/xenobiology)
"gGq" = (
/obj/machinery/mass_driver{
@@ -35548,6 +35729,13 @@
},
/turf/open/floor/plasteel/white/corner,
/area/hallway/primary/starboard/fore)
+"gMF" = (
+/mob/living/simple_animal/slime,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
+ dir = 1
+ },
+/turf/open/floor/engine,
+/area/science/xenobiology)
"gNH" = (
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 4
@@ -35566,6 +35754,12 @@
/obj/machinery/vr_sleeper,
/turf/open/floor/plasteel,
/area/service/bar/atrium)
+"gRa" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/engine,
+/area/science/xenobiology)
"gRe" = (
/obj/structure/cable/white{
icon_state = "1-2"
@@ -35577,18 +35771,6 @@
dir = 8
},
/area/maintenance/starboard/aft)
-"gSv" = (
-/obj/structure/cable/yellow{
- icon_state = "4-8"
- },
-/obj/machinery/atmospherics/pipe/simple/dark/visible,
-/obj/effect/turf_decal/tile/yellow{
- dir = 8
- },
-/turf/open/floor/plasteel/dark/corner{
- dir = 1
- },
-/area/engineering/atmos)
"gVX" = (
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/co2{
dir = 8
@@ -35615,6 +35797,7 @@
/area/asteroid/nearstation)
"heH" = (
/obj/structure/table/reinforced,
+/mob/living/carbon/monkey/punpun,
/turf/open/floor/plasteel/dark/side{
dir = 1
},
@@ -35661,6 +35844,22 @@
},
/turf/open/floor/plasteel,
/area/service/bar/atrium)
+"hqO" = (
+/obj/structure/table/reinforced,
+/obj/item/book/manual/splurt_space_law,
+/obj/item/radio,
+/obj/structure/reagent_dispensers/peppertank{
+ pixel_x = 32
+ },
+/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/checkpoint)
"hqX" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{
dir = 4
@@ -35695,6 +35894,27 @@
},
/turf/open/floor/plasteel,
/area/service/bar/atrium)
+"huW" = (
+/obj/structure/cable/white{
+ icon_state = "4-8"
+ },
+/obj/machinery/door/firedoor,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/obj/effect/mapping_helpers/airlock/locked,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper{
+ dir = 4
+ },
+/obj/machinery/door/airlock/virology{
+ autoclose = 0;
+ frequency = 1449;
+ id_tag = "virology_airlock_interior";
+ name = "Virology Interior Airlock";
+ req_access_txt = "39"
+ },
+/turf/open/floor/plasteel,
+/area/medical/virology)
"hvC" = (
/obj/structure/disposalpipe/segment{
dir = 9
@@ -35773,24 +35993,18 @@
},
/turf/open/floor/plasteel,
/area/engineering/atmos)
-"hJP" = (
-/obj/structure/table/reinforced,
-/obj/item/book/manual/splurt_space_law,
-/obj/item/taperecorder,
-/obj/machinery/status_display{
- pixel_y = -32
+"hJc" = (
+/obj/structure/chair{
+ dir = 8
},
-/obj/item/flashlight/seclite,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral{
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
-/turf/open/floor/plasteel/dark,
+/obj/effect/turf_decal/tile/red{
+ dir = 4
+ },
+/obj/effect/landmark/start/peacekeeper,
+/turf/open/floor/plasteel,
/area/security/brig)
"hNO" = (
/obj/machinery/atmospherics/pipe/simple/cyan/hidden{
@@ -35885,9 +36099,39 @@
},
/turf/open/floor/plasteel,
/area/engineering/atmos)
+"hVi" = (
+/obj/structure/cable/white{
+ icon_state = "1-8"
+ },
+/obj/structure/cable/white{
+ icon_state = "1-2"
+ },
+/obj/structure/chair/office/dark{
+ dir = 8
+ },
+/obj/structure/cable/white{
+ icon_state = "1-4"
+ },
+/obj/effect/landmark/start/peacekeeper,
+/turf/open/floor/plasteel,
+/area/security/checkpoint)
"hVE" = (
/turf/open/floor/plasteel,
/area/science/mixing)
+"hWW" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/red{
+ dir = 4
+ },
+/obj/machinery/status_display/ai{
+ pixel_y = 32
+ },
+/turf/open/floor/plasteel/white/corner{
+ dir = 1
+ },
+/area/hallway/secondary/exit)
"hXc" = (
/turf/closed/wall/rust,
/area/science/mixing)
@@ -35903,27 +36147,6 @@
/obj/structure/lattice,
/turf/open/floor/plating/asteroid,
/area/maintenance/starboard/aft)
-"hZt" = (
-/obj/structure/table/wood,
-/obj/item/crowbar/red,
-/obj/item/book/manual/splurt_space_law{
- pixel_x = 3;
- pixel_y = 3
- },
-/obj/item/book/manual/wiki/detective,
-/obj/item/camera/detective,
-/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/security/detectives_office)
"hZH" = (
/turf/open/floor/plating/airless{
icon_state = "platingdmg2"
@@ -35965,15 +36188,6 @@
heat_capacity = 1e+006
},
/area/hallway/primary/aft)
-"igZ" = (
-/obj/structure/table/wood,
-/obj/item/folder,
-/obj/item/pen,
-/obj/structure/sign/painting/library{
- pixel_x = -32
- },
-/turf/open/floor/plasteel/dark,
-/area/service/library)
"iio" = (
/turf/closed/wall,
/area/science/mixing)
@@ -36012,15 +36226,6 @@
},
/turf/open/floor/engine/vacuum,
/area/maintenance/disposal/incinerator)
-"iBd" = (
-/obj/effect/turf_decal/stripes/line,
-/obj/machinery/door/airlock/external{
- name = "External Airlock";
- req_access_txt = "13"
- },
-/obj/effect/mapping_helpers/airlock/cyclelink_helper,
-/obj/effect/turf_decal/stripes/line,
-/area/maintenance/solars/starboard/fore)
"iGT" = (
/turf/closed/wall,
/area/service/lawoffice)
@@ -36149,6 +36354,36 @@
},
/turf/open/floor/carpet/green,
/area/service/lawoffice)
+"iZt" = (
+/obj/item/folder/red,
+/obj/item/book/manual/splurt_space_law,
+/obj/item/taperecorder,
+/obj/structure/cable/white{
+ icon_state = "1-2"
+ },
+/obj/structure/table/reinforced,
+/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{
+ name = "---Merge conflict marker---"
+ },
+/obj/item/folder/red,
+/obj/item/book/manual/wiki/security_space_law,
+/obj/item/taperecorder,
+/obj/structure/cable/white{
+ icon_state = "1-2"
+ },
+/obj/structure/table/reinforced,
+/turf/open/floor/plasteel/dark,
+/area/command/bridge)
"iZQ" = (
/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/carbon_input,
/turf/open/floor/engine/co2,
@@ -36198,6 +36433,9 @@
req_access_txt = "55"
},
/obj/effect/turf_decal/bot,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
/turf/open/floor/plasteel/dark/side{
dir = 8
},
@@ -36367,9 +36605,7 @@
/obj/structure/cable/white{
icon_state = "1-8"
},
-/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
- dir = 8
- },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel/white,
/area/science/xenobiology)
"jCi" = (
@@ -36699,26 +36935,23 @@
/obj/effect/turf_decal/stripes/corner,
/turf/open/floor/plasteel,
/area/engineering/atmos)
-"kUi" = (
-/obj/structure/cable/white{
- icon_state = "1-8"
- },
-/obj/structure/cable/white{
- icon_state = "1-2"
- },
-/obj/structure/chair/office/dark{
- dir = 8
- },
-/obj/structure/cable/white{
- icon_state = "1-4"
- },
-/obj/effect/landmark/start/peacekeeper,
-/turf/open/floor/plasteel,
-/area/security/checkpoint)
"kUu" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/wood,
/area/maintenance/starboard/aft)
+"kVy" = (
+/obj/structure/cable/yellow{
+ icon_state = "4-8"
+ },
+/obj/machinery/atmospherics/pipe/simple/dark/visible,
+/obj/effect/turf_decal/tile/yellow{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/line,
+/turf/open/floor/plasteel/dark/corner{
+ dir = 1
+ },
+/area/engineering/atmos)
"kWQ" = (
/obj/machinery/atmospherics/components/unary/portables_connector/visible,
/obj/effect/turf_decal/stripes/line{
@@ -36856,6 +37089,18 @@
},
/turf/open/floor/plasteel,
/area/science/mixing)
+"lBN" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/obj/structure/cable/white{
+ icon_state = "4-8"
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_y = -28
+ },
+/turf/open/floor/plasteel,
+/area/hallway/secondary/exit)
"lCg" = (
/obj/machinery/door/airlock/external{
name = "Supply Dock Airlock";
@@ -37048,15 +37293,6 @@
},
/turf/open/floor/plasteel,
/area/engineering/atmos)
-"muL" = (
-/obj/structure/table/wood,
-/obj/item/folder,
-/obj/item/pen,
-/obj/structure/sign/painting/library{
- pixel_x = 32
- },
-/turf/open/floor/plasteel/dark,
-/area/service/library)
"mvB" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel,
@@ -37095,10 +37331,6 @@
"mQi" = (
/turf/closed/wall/rust,
/area/maintenance/starboard/central)
-"mSM" = (
-/obj/structure/dresser,
-/turf/open/floor/plasteel,
-/area/security/prison)
"mTv" = (
/obj/machinery/atmospherics/pipe/manifold/cyan/visible{
dir = 1
@@ -37246,19 +37478,22 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/hallway/primary/starboard/fore)
-"nBl" = (
+"nAF" = (
/obj/structure/table/wood,
-/obj/item/flashlight/lamp,
-/obj/machinery/newscaster{
- pixel_x = 32
+/obj/machinery/firealarm{
+ dir = 1;
+ pixel_y = -24
},
-/obj/structure/sign/painting/library{
- pixel_x = 32
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -26;
+ pixel_y = -32
},
-/turf/open/floor/plasteel/dark/side{
- dir = 10
- },
-/area/service/library)
+/obj/item/clipboard,
+/obj/item/stack/packageWrap,
+/obj/item/book/manual/splurt_space_law,
+/obj/item/hand_labeler,
+/turf/open/floor/wood,
+/area/command/heads_quarters/hop)
"nBu" = (
/obj/structure/chair/stool/bar,
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
@@ -37273,28 +37508,6 @@
/obj/machinery/meter,
/turf/open/floor/plasteel,
/area/engineering/atmos)
-"nGO" = (
-/obj/structure/filingcabinet/chestdrawer,
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/machinery/camera{
- c_tag = "Chief Engineer's Office";
- network = list("ss13","engine")
- },
-/mob/living/simple_animal/parrot/Polly,
-/obj/machinery/atmospherics/pipe/simple/orange/visible{
- dir = 10
- },
-/turf/open/floor/plasteel/dark,
-/area/command/heads_quarters/ce)
"nHD" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{
dir = 4
@@ -37375,7 +37588,7 @@
"oaV" = (
/obj/structure/grille,
/obj/machinery/meter,
-/obj/machinery/atmospherics/pipe/simple/yellow/visible,
+/obj/machinery/atmospherics/pipe/layer_manifold,
/turf/closed/wall/r_wall,
/area/engineering/atmos)
"ogx" = (
@@ -37584,6 +37797,15 @@
},
/turf/open/floor/plasteel/dark,
/area/command/gateway)
+"pcU" = (
+/obj/structure/chair/office/dark,
+/obj/effect/turf_decal/tile/red,
+/obj/effect/turf_decal/tile/red{
+ dir = 8
+ },
+/obj/effect/landmark/start/peacekeeper,
+/turf/open/floor/plasteel,
+/area/hallway/secondary/exit)
"pdQ" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -37605,6 +37827,9 @@
dir = 1
},
/area/science/mixing)
+"pej" = (
+/turf/open/floor/engine,
+/area/science/xenobiology)
"pgH" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/closed/wall/r_wall,
@@ -37690,29 +37915,6 @@
},
/turf/open/floor/plasteel,
/area/science/mixing)
-"pqg" = (
-/obj/machinery/shower{
- dir = 1
- },
-/obj/structure/curtain,
-/obj/structure/window/spawner/north,
-/obj/structure/sign/poster/contraband/yes_erp{
- pixel_x = 32
- },
-/obj/effect/turf_decal/bot,
-/obj{
- name = "---Merge conflict marker---"
- },
-/obj/machinery/shower{
- dir = 1
- },
-/obj/structure/curtain,
-/obj/structure/window/spawner/north,
-/obj/structure/sign/poster/contraband/yes_erp{
- pixel_x = 32
- },
-/turf/open/floor/plasteel/freezer,
-/area/commons/toilet/restrooms)
"pqs" = (
/obj/machinery/power/turbine{
dir = 8;
@@ -37773,6 +37975,23 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel/white,
/area/science/mixing)
+"pDm" = (
+/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
+ },
+/obj/machinery/status_display/ai{
+ pixel_x = 32
+ },
+/turf/open/floor/plasteel/dark,
+/area/command/gateway)
"pEt" = (
/obj/machinery/power/apc{
areastring = "/area/hallway/primary/starboard/fore";
@@ -37813,47 +38032,15 @@
/obj/structure/cable/white{
icon_state = "4-8"
},
-/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
- dir = 4
- },
/obj/effect/turf_decal/tile/purple{
dir = 1
},
/obj/effect/turf_decal/tile/purple{
dir = 8
},
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel/white,
/area/science/xenobiology)
-"pLU" = (
-/obj/item/folder/red,
-/obj/item/book/manual/splurt_space_law,
-/obj/item/taperecorder,
-/obj/structure/cable/white{
- icon_state = "1-2"
- },
-/obj/structure/table/reinforced,
-/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{
- name = "---Merge conflict marker---"
- },
-/obj/item/folder/red,
-/obj/item/book/manual/wiki/security_space_law,
-/obj/item/taperecorder,
-/obj/structure/cable/white{
- icon_state = "1-2"
- },
-/obj/structure/table/reinforced,
-/turf/open/floor/plasteel/dark,
-/area/command/bridge)
"pMh" = (
/obj/machinery/atmospherics/components/binary/valve{
dir = 8
@@ -38014,22 +38201,6 @@
},
/turf/open/floor/plasteel,
/area/engineering/atmos)
-"qxY" = (
-/obj/structure/table/wood,
-/obj/machinery/firealarm{
- dir = 1;
- pixel_y = -24
- },
-/obj/structure/extinguisher_cabinet{
- pixel_x = -26;
- pixel_y = -32
- },
-/obj/item/clipboard,
-/obj/item/stack/packageWrap,
-/obj/item/book/manual/splurt_space_law,
-/obj/item/hand_labeler,
-/turf/open/floor/wood,
-/area/command/heads_quarters/hop)
"qyQ" = (
/obj/effect/turf_decal/stripes/line{
dir = 5
@@ -38152,6 +38323,18 @@
},
/turf/open/floor/plasteel,
/area/engineering/atmos)
+"rbN" = (
+/obj/structure/cable/white{
+ icon_state = "4-8"
+ },
+/obj/effect/turf_decal/delivery,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
+ dir = 4
+ },
+/turf/open/floor/plasteel/dark/side{
+ dir = 8
+ },
+/area/science/xenobiology)
"ria" = (
/obj/effect/turf_decal/bot_white/right,
/obj/effect/turf_decal/tile/neutral{
@@ -38177,6 +38360,16 @@
/obj/machinery/atmospherics/pipe/simple/cyan/visible,
/turf/open/floor/plasteel,
/area/engineering/atmos)
+"rll" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
+/obj/machinery/door/airlock/maintenance_hatch{
+ name = "Maintenance Hatch";
+ req_access_txt = "12"
+ },
+/turf/open/floor/plating,
+/area/maintenance/starboard)
"rlq" = (
/obj/machinery/door/firedoor,
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
@@ -38215,6 +38408,9 @@
/obj/structure/cable/white{
icon_state = "4-8"
},
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
/turf/open/floor/plasteel/white,
/area/science/xenobiology)
"rEx" = (
@@ -38285,19 +38481,6 @@
/obj/structure/lattice,
/turf/open/space/basic,
/area/space/nearstation)
-"sie" = (
-/obj/structure/chair{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
- dir = 4
- },
-/obj/effect/turf_decal/tile/red{
- dir = 4
- },
-/obj/effect/landmark/start/peacekeeper,
-/turf/open/floor/plasteel,
-/area/security/brig)
"sjr" = (
/obj/item/reagent_containers/food/snacks/grown/wheat,
/turf/open/space/basic,
@@ -38417,6 +38600,12 @@
"sxC" = (
/turf/closed/wall/r_wall/rust,
/area/ai_monitored/turret_protected/ai)
+"syb" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 10
+ },
+/turf/open/floor/engine,
+/area/science/xenobiology)
"syC" = (
/turf/closed/wall/r_wall/rust,
/area/command/teleporter)
@@ -38497,6 +38686,16 @@
icon_state = "platingdmg2"
},
/area/maintenance/port/central)
+"sCW" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/obj/structure/cable/white{
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/plasteel/white,
+/area/science/xenobiology)
"sDl" = (
/turf/closed/wall/rust,
/area/commons/dorms)
@@ -38955,9 +39154,6 @@
/obj/structure/cable/white{
icon_state = "4-8"
},
-/obj/structure/extinguisher_cabinet{
- pixel_y = -28
- },
/obj/machinery/camera{
c_tag = "Departures Hallway";
dir = 1
@@ -38965,6 +39161,9 @@
/obj/effect/turf_decal/tile/brown{
dir = 8
},
+/obj/machinery/status_display/ai{
+ pixel_y = -32
+ },
/turf/open/floor/plasteel/white/corner,
/area/hallway/secondary/exit)
"sIx" = (
@@ -39989,6 +40188,12 @@
},
/obj/effect/turf_decal/delivery,
/obj/effect/turf_decal/sand/plating,
+/obj/machinery/camera{
+ c_tag = "MiniSat External SouthEast";
+ dir = 4;
+ network = list("minisat");
+ start_active = 1
+ },
/turf/open/floor/plating/airless,
/area/ai_monitored/turret_protected/aisat_interior)
"sNj" = (
@@ -40083,6 +40288,7 @@
uses = 10
},
/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden,
+/mob/living/simple_animal/bot/secbot/pingsky,
/turf/open/floor/circuit/green,
/area/ai_monitored/turret_protected/aisat_interior)
"sNr" = (
@@ -40660,6 +40866,10 @@
},
/turf/open/floor/plasteel,
/area/service/lawoffice)
+"tsB" = (
+/obj/item/hilbertshotel/ghostdojo,
+/turf/open/floor/carpet,
+/area/hallway/primary/aft)
"ttp" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/structure/cable/white{
@@ -40705,15 +40915,6 @@
icon_state = "wood-broken6"
},
/area/maintenance/starboard/aft)
-"tyk" = (
-/obj/machinery/photocopier,
-/obj/structure/sign/painting/library{
- pixel_x = 32
- },
-/turf/open/floor/plasteel/dark/side{
- dir = 10
- },
-/area/service/library)
"tFk" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 4
@@ -41133,10 +41334,6 @@
},
/turf/open/floor/plasteel,
/area/engineering/atmos)
-"uWA" = (
-/obj/item/hilbertshotel/ghostdojo,
-/turf/open/floor/carpet,
-/area/hallway/primary/aft)
"uXD" = (
/obj/effect/landmark/carpspawn,
/turf/open/space,
@@ -41236,6 +41433,9 @@
/obj/structure/closet/l3closet/scientist,
/obj/effect/turf_decal/stripes/line,
/obj/item/extinguisher/mini,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
/turf/open/floor/plasteel/dark/side{
dir = 1
},
@@ -41413,16 +41613,19 @@
},
/turf/open/floor/plasteel,
/area/science/mixing)
-"vRo" = (
-/obj/structure/sign/painting/library{
- pixel_y = -32
- },
-/turf/open/floor/plasteel/dark,
-/area/service/library)
"vTk" = (
/obj/item/hatchet,
/turf/open/space/basic,
/area/space)
+"vTW" = (
+/obj/effect/turf_decal/stripes/line,
+/obj/machinery/door/airlock/external{
+ name = "External Airlock";
+ req_access_txt = "13"
+ },
+/obj/effect/mapping_helpers/airlock/cyclelink_helper,
+/obj/effect/turf_decal/stripes/line,
+/area/maintenance/solars/starboard/fore)
"vVA" = (
/obj/machinery/atmospherics/pipe/simple/green/visible{
dir = 4
@@ -41451,21 +41654,6 @@
/obj/machinery/door/firedoor,
/turf/open/floor/plasteel,
/area/hallway/primary/starboard/fore)
-"vXg" = (
-/obj/structure/table/wood,
-/obj/item/paper_bin,
-/obj/item/pen,
-/obj/machinery/camera{
- c_tag = "Library 1";
- dir = 8
- },
-/obj/structure/sign/painting/library{
- pixel_x = 32
- },
-/turf/open/floor/plasteel/dark/side{
- dir = 10
- },
-/area/service/library)
"vZb" = (
/obj/machinery/light/small{
dir = 4
@@ -41516,6 +41704,11 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
+/mob/living/simple_animal/bot/cleanbot{
+ auto_patrol = 1;
+ icon_state = "cleanbot1";
+ name = "Rustbucket"
+ },
/turf/open/floor/plasteel/dark/side{
dir = 1
},
@@ -41654,17 +41847,12 @@
/turf/open/floor/engine,
/area/engineering/supermatter)
"wUL" = (
-/obj/structure/cable/white{
- icon_state = "4-8"
- },
-/obj/effect/turf_decal/delivery,
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
-/turf/open/floor/plasteel/dark/side{
- dir = 8
- },
-/area/science/xenobiology)
+/obj/structure/closet/crate,
+/turf/open/floor/plasteel,
+/area/cargo/storage)
"wWj" = (
/obj/structure/window/reinforced{
dir = 4
@@ -41723,6 +41911,28 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/aft)
+"xjR" = (
+/obj/effect/turf_decal/tile/purple{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/purple{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden,
+/turf/open/floor/plasteel/white,
+/area/science/xenobiology)
+"xlL" = (
+/obj/effect/turf_decal/tile/purple{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/purple{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/plasteel/white,
+/area/science/xenobiology)
"xoR" = (
/obj/structure/table/reinforced,
/obj/item/storage/box/monkeycubes,
@@ -41909,10 +42119,39 @@
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 8
+ },
/turf/open/floor/plasteel/dark/side{
dir = 4
},
/area/science/xenobiology)
+"xLA" = (
+/obj/structure/table/wood,
+/obj/item/book/manual/splurt_space_law,
+/obj/item/camera/detective,
+/obj/item/radio/intercom{
+ name = "Station Intercom";
+ pixel_x = -26
+ },
+/obj/effect/turf_decal/tile/neutral,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj{
+ name = "---Merge conflict marker---"
+ },
+/obj/structure/table/wood,
+/obj/item/book/manual/wiki/security_space_law,
+/obj/item/camera/detective,
+/obj/item/radio/intercom{
+ name = "Station Intercom";
+ pixel_x = -26
+ },
+/turf/open/floor/plasteel/dark/side{
+ dir = 8
+ },
+/area/command/heads_quarters/hos)
"xMv" = (
/obj/structure/lattice,
/obj/structure/fluff/broken_flooring{
@@ -42028,9 +42267,6 @@
/obj/structure/cable/white{
icon_state = "4-8"
},
-/obj/machinery/atmospherics/pipe/simple/supply/hidden{
- dir = 4
- },
/turf/open/floor/plasteel/white,
/area/science/xenobiology)
"yeO" = (
@@ -68934,7 +69170,7 @@ fbH
lvw
xrf
pvX
-gSv
+kVy
xtL
uhz
nHD
@@ -70736,7 +70972,7 @@ aqA
qsc
lUu
akN
-nGO
+alE
anv
anK
aoo
@@ -75394,7 +75630,7 @@ aUo
aMG
aSg
aKV
-aUK
+huW
aXY
aTo
aTQ
@@ -76102,7 +76338,7 @@ acH
abR
afh
azi
-mSM
+cVZ
aiS
acH
aAw
@@ -76146,8 +76382,8 @@ aEt
atE
aMG
aQW
-djq
-igZ
+aRT
+fHF
aUc
aUV
aVN
@@ -76165,7 +76401,7 @@ aUp
aUi
aTj
aKV
-aWM
+dHD
aKV
aKV
aZE
@@ -77142,14 +77378,14 @@ ait
aiY
ajY
akZ
-sie
+hJc
ajY
anF
aow
apB
aqP
arK
-hJP
+fBc
agF
auM
avR
@@ -77437,7 +77673,7 @@ sJX
bxS
aVS
eIk
-dJV
+aXh
ajG
ajG
ajG
@@ -77694,7 +77930,7 @@ sJX
aUY
aVT
aVQ
-ete
+aXg
ajG
bdW
aOl
@@ -77951,7 +78187,7 @@ aUg
sKe
aVU
lxu
-vRo
+aXj
ajG
aOb
aPF
@@ -78208,7 +78444,7 @@ aBn
aDf
aWE
aVQ
-ete
+aXg
ajG
aOZ
bey
@@ -78420,7 +78656,7 @@ acK
adD
adC
afb
-dWc
+xLA
ahx
ajR
aqw
@@ -78716,13 +78952,13 @@ aOf
aDp
aQb
aRa
-nBl
-muL
-tyk
+aSd
+aRU
+aUj
aVb
aVX
aWG
-vXg
+aXl
aSh
aOg
aGC
@@ -81556,8 +81792,8 @@ aZL
baC
aHs
aSi
-aWK
-aWK
+aSh
+aSh
aSh
aVg
aWa
@@ -82585,7 +82821,7 @@ aXR
aSh
aSh
aWK
-bea
+aWK
beG
aUi
aWv
@@ -82839,7 +83075,7 @@ aYa
aYU
aZQ
baG
-bbv
+dIK
bbv
baG
baG
@@ -83550,7 +83786,7 @@ aae
aaa
aal
aas
-pLU
+iZt
aaR
abc
ggq
@@ -83859,7 +84095,7 @@ ami
sEG
aTA
aUy
-uWA
+tsB
sNz
aWR
tWh
@@ -83869,7 +84105,7 @@ byq
baJ
bbz
bco
-kUi
+hVi
bed
beI
bff
@@ -84123,7 +84359,7 @@ lIM
ugK
hOc
byo
-fja
+hqO
bbA
bcp
bdg
@@ -84824,7 +85060,7 @@ aad
aad
aad
aad
-aac
+aeS
aac
aaa
sdX
@@ -85675,15 +85911,15 @@ sOV
bfP
bgm
bgY
-bgm
+pej
ibv
bgm
bgY
-bgm
+pej
ibv
bgm
bgY
-bgm
+pej
bfP
aad
jpG
@@ -85855,7 +86091,7 @@ sMV
sNl
sNA
sMr
-aaa
+bea
aaa
aae
aaa
@@ -85873,7 +86109,7 @@ adg
adU
aeJ
afw
-qxY
+nAF
abs
ahZ
aiD
@@ -85930,16 +86166,16 @@ bei
beL
aTS
sKZ
-bgm
+gRa
bgZ
bhM
ibv
-bgm
+gRa
bgZ
bhM
ibv
-bgm
-bhg
+gRa
+pej
bhM
sKZ
aad
@@ -86445,11 +86681,11 @@ beL
nKi
bfP
bgp
-bhb
+rbN
bhO
ibv
biX
-wUL
+bhb
bhO
nTi
jdD
@@ -86705,11 +86941,11 @@ bgq
bhc
bhP
bfN
-bhP
+xjR
pLb
bhP
bgc
-bhP
+xlL
bjq
bjD
bgg
@@ -86962,7 +87198,7 @@ bgr
bhd
bhQ
plz
-iVw
+sCW
jBG
iVw
biD
@@ -87440,7 +87676,7 @@ azT
aAZ
aCg
ank
-aly
+ebS
aly
aFX
aGX
@@ -87662,7 +87898,7 @@ aaa
aaa
bbX
bbZ
-iBd
+vTW
bcG
bcM
bcT
@@ -87729,12 +87965,12 @@ ben
beP
bfn
bfP
-bgm
-bgm
+gRa
+pej
bnS
ibv
-bgm
-bgm
+gRa
+pej
bnS
xFw
bjb
@@ -87986,13 +88222,13 @@ beo
aZl
sPK
bfP
-bgm
+syb
bhg
-bgm
+pej
ibv
gBW
-bgZ
-bgm
+gMF
+pej
bfP
bjc
bjv
@@ -88207,7 +88443,7 @@ acx
axf
oyD
aRz
-sEK
+rll
sJN
aRz
aRz
@@ -88243,13 +88479,13 @@ bep
aZl
sPI
bfP
-bgm
+pej
bhi
-bgm
+pej
ibv
-bgm
+pej
bhi
-bgm
+pej
sKZ
bjd
bjw
@@ -88718,7 +88954,7 @@ bfo
oyD
oXj
xpX
-pqg
+ept
oyD
bfp
adm
@@ -88955,9 +89191,9 @@ aeb
aeP
adu
aec
-aeS
+ajI
afF
-agx
+wUL
aii
adp
aiL
@@ -88994,7 +89230,7 @@ sIU
aae
ata
atr
-hZt
+bNJ
abv
swG
swG
@@ -89499,7 +89735,7 @@ sGy
sHb
aRz
bxM
-bsC
+lBN
axW
aae
sIU
@@ -90012,7 +90248,7 @@ aRz
aSD
sHd
aRz
-bxM
+hWW
bsC
sIG
aRz
@@ -90517,7 +90753,7 @@ bvg
xMZ
uIq
pcD
-ria
+pDm
kQz
xWb
sEQ
@@ -91806,7 +92042,7 @@ aae
axW
ayX
azW
-fXe
+pcU
aCj
aDe
aEc
diff --git a/code/__DEFINES/_auxtools.dm b/code/__DEFINES/_auxtools.dm
index ab07becbd9..fc5dfd4378 100644
--- a/code/__DEFINES/_auxtools.dm
+++ b/code/__DEFINES/_auxtools.dm
@@ -1,9 +1,12 @@
#define AUXMOS (world.system_type == MS_WINDOWS ? "auxmos.dll" : __detect_auxmos())
/proc/__detect_auxmos()
- if (fexists("./libauxmos.so"))
- return "./libauxmos.so"
- else if (fexists("[world.GetConfig("env", "HOME")]/.byond/bin/libauxmos.so"))
- return "[world.GetConfig("env", "HOME")]/.byond/bin/libauxmos.so"
- else
- CRASH("Could not find libauxmos.so")
+ var/static/known_auxmos_var
+ if(!known_auxmos_var)
+ if (fexists("./libauxmos.so"))
+ known_auxmos_var = "./libauxmos.so"
+ else if (fexists("[world.GetConfig("env", "HOME")]/.byond/bin/libauxmos.so"))
+ known_auxmos_var = "[world.GetConfig("env", "HOME")]/.byond/bin/libauxmos.so"
+ else
+ CRASH("Could not find libauxmos.so")
+ return known_auxmos_var
diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 1c8770dafd..d23fe74bd2 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -44,6 +44,9 @@
/// from SSsun when the sun changes position : (primary_sun, suns)
#define COMSIG_SUN_MOVED "sun_moved"
+///from SSsecurity_level when the security level changes : (new_level)
+#define COMSIG_SECURITY_LEVEL_CHANGED "security_level_changed"
+
/// from SSactivity for things that add threat but aren't "global" (e.g. phylacteries)
#define COMSIG_THREAT_CALC "threat_calculation"
diff --git a/code/__DEFINES/rust_g.dm b/code/__DEFINES/rust_g.dm
index 8a7883e37a..48a2ee5389 100644
--- a/code/__DEFINES/rust_g.dm
+++ b/code/__DEFINES/rust_g.dm
@@ -192,7 +192,14 @@
#define rustg_time_milliseconds(id) text2num(call(RUST_G, "time_milliseconds")(id))
#define rustg_time_reset(id) call(RUST_G, "time_reset")(id)
-#define rustg_read_toml_file(path) json_decode(call(RUST_G, "toml_file_to_json")(path) || "null")
+#define rustg_raw_read_toml_file(path) json_decode(call(RUST_G, "toml_file_to_json")(path) || "null")
+
+/proc/rustg_read_toml_file(path)
+ var/list/output = rustg_raw_read_toml_file(path)
+ if (output["success"])
+ return json_decode(output["content"])
+ else
+ CRASH(output["content"])
#define rustg_unzip_download_async(url, unzip_directory) call(RUST_G, "unzip_download_async")(url, unzip_directory)
#define rustg_unzip_check(job_id) call(RUST_G, "unzip_check")("[job_id]")
@@ -205,3 +212,20 @@
#define url_decode(text) rustg_url_decode(text)
#endif
+/**
+ * This proc generates a noise grid using worley noise algorithm
+ *
+ * Returns a single string that goes row by row, with values of 1 representing an alive cell, and a value of 0 representing a dead cell.
+ *
+ * Arguments:
+ * * region_size: The size of regions
+ * * threshold: the value that determines wether a cell is dead or alive
+ * * node_per_region_chance: chance of a node existiing in a region
+ * * size: size of the returned grid
+ * * node_min: minimum amount of nodes in a region (after the node_per_region_chance is applied)
+ * * node_max: maximum amount of nodes in a region
+ */
+#define rustg_worley_generate(region_size, threshold, node_per_region_chance, size, node_min, node_max) \
+ call(RUST_G, "worley_generate")(region_size, threshold, node_per_region_chance, size, node_min, node_max)
+
+
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 560bc2daf3..49bad31a60 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -111,6 +111,7 @@
#define INIT_ORDER_SOUNDS 83
#define INIT_ORDER_INSTRUMENTS 82
#define INIT_ORDER_VIS 80
+#define INIT_ORDER_SECURITY_LEVEL 79 // We need to load before events so that it has a security level to choose from.
#define INIT_ORDER_ACHIEVEMENTS 77
#define INIT_ORDER_RESEARCH 75
#define INIT_ORDER_STATION 74 //This is high priority because it manipulates a lot of the subsystems that will initialize after it.
diff --git a/code/__HELPERS/sanitize_values.dm b/code/__HELPERS/sanitize_values.dm
index 0441e0bcb7..c4708f81f6 100644
--- a/code/__HELPERS/sanitize_values.dm
+++ b/code/__HELPERS/sanitize_values.dm
@@ -157,10 +157,7 @@
#undef RGB_FORMAT_SHORT
#undef RGB_FORMAT_LONG
+/// Makes sure the input color is text with a # at the start followed by 6 hexadecimal characters. Examples: "#ff1234", "#A38321", COLOR_GREEN_GRAY
/proc/sanitize_ooccolor(color)
- if(length(color) != length_char(color))
- CRASH("Invalid characters in color '[color]'")
- var/list/HSL = rgb2hsl(hex2num(copytext(color, 2, 4)), hex2num(copytext(color, 4, 6)), hex2num(copytext(color, 6, 8)))
- HSL[3] = min(HSL[3],0.4)
- var/list/RGB = hsl2rgb(arglist(HSL))
- return "#[num2hex(RGB[1],2)][num2hex(RGB[2],2)][num2hex(RGB[3],2)]"
+ var/static/regex/color_regex = regex(@"^#[0-9a-fA-F]{6}$")
+ return findtext(color, color_regex) ? color : GLOB.normal_ooc_colour
diff --git a/code/__SPLURTCODE/DEFINES/configuration.dm b/code/__SPLURTCODE/DEFINES/configuration.dm
new file mode 100644
index 0000000000..859e74cdc0
--- /dev/null
+++ b/code/__SPLURTCODE/DEFINES/configuration.dm
@@ -0,0 +1,2 @@
+/// like CONFIG_GET_ENTRY() but uses a full path
+#define CONFIG_GET_ENTRY_FROM_PATH(P) global.config.GetEntryDatum(P)
diff --git a/code/controllers/subsystem/fail2topic.dm b/code/controllers/subsystem/fail2topic.dm
index fc18d7dabe..47f14a0065 100644
--- a/code/controllers/subsystem/fail2topic.dm
+++ b/code/controllers/subsystem/fail2topic.dm
@@ -44,7 +44,24 @@ SUBSYSTEM_DEF(fail2topic)
/datum/controller/subsystem/fail2topic/Shutdown()
DropFirewallRule()
+/datum/controller/subsystem/fail2topic/vv_edit_var(var_name, var_value)
+ if(var_name == NAMEOF(src, rule_name))
+ return FALSE
+ return ..()
+
+/datum/controller/subsystem/fail2topic/CanProcCall(procname)
+ . = ..()
+ if(.)
+ switch(procname)
+ if("IsRateLimited")
+ return FALSE
+ if("BanFromFirewall")
+ return FALSE
+
/datum/controller/subsystem/fail2topic/proc/IsRateLimited(ip)
+ if(IsAdminAdvancedProcCall())
+ return FALSE
+
var/last_attempt = rate_limiting[ip]
var/static/datum/config_entry/keyed_list/topic_rate_limit_whitelist/cached_whitelist_entry
@@ -82,6 +99,8 @@ SUBSYSTEM_DEF(fail2topic)
/datum/controller/subsystem/fail2topic/proc/BanFromFirewall(ip)
if (!enabled)
return
+ if(IsAdminAdvancedProcCall())
+ return
active_bans[ip] = REALTIMEOFDAY
fail_counts -= ip
diff --git a/code/controllers/subsystem/security_level.dm b/code/controllers/subsystem/security_level.dm
new file mode 100644
index 0000000000..94fa822e8b
--- /dev/null
+++ b/code/controllers/subsystem/security_level.dm
@@ -0,0 +1,114 @@
+// NOT THE SAME AS TG! THIS IS BAREMETAL JUST TO MAKE COMSIGS WORK!
+SUBSYSTEM_DEF(security_level)
+ name = "Security Level"
+ can_fire = FALSE // We will control when we fire in this subsystem
+ init_order = INIT_ORDER_SECURITY_LEVEL
+
+/**
+ * Sets a new security level as our current level
+ *
+ * This is how everything should change the security level.
+ *
+ * Arguments:
+ * * new_level - The new security level that will become our current level
+ */
+/datum/controller/subsystem/security_level/proc/set_level(new_level)
+ if(!isnum(new_level))
+ new_level = GLOB.all_security_levels.Find()
+
+ //Will not be announced if you try to set to the same level as it already is
+ if(new_level >= SEC_LEVEL_GREEN && new_level <= SEC_LEVEL_DELTA && new_level != GLOB.security_level)
+ switch(new_level)
+ if(SEC_LEVEL_GREEN)
+ minor_announce(CONFIG_GET(string/alert_green), "Attention! Security level lowered to green:")
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ if(GLOB.security_level >= SEC_LEVEL_RED)
+ SSshuttle.emergency.modTimer(4)
+ else if(GLOB.security_level == SEC_LEVEL_AMBER)
+ SSshuttle.emergency.modTimer(2.5)
+ else
+ SSshuttle.emergency.modTimer(1.66)
+ GLOB.security_level = SEC_LEVEL_GREEN
+ for(var/obj/machinery/firealarm/FA in GLOB.machines)
+ if(is_station_level(FA.z))
+ FA.update_icon()
+ if(SEC_LEVEL_BLUE)
+ if(GLOB.security_level < SEC_LEVEL_BLUE)
+ minor_announce(CONFIG_GET(string/alert_blue_upto), "Attention! Security level elevated to blue:",1)
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ SSshuttle.emergency.modTimer(0.6)
+ else
+ minor_announce(CONFIG_GET(string/alert_blue_downto), "Attention! Security level lowered to blue:")
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ if(GLOB.security_level >= SEC_LEVEL_RED)
+ SSshuttle.emergency.modTimer(2.4)
+ else
+ SSshuttle.emergency.modTimer(1.5)
+ GLOB.security_level = SEC_LEVEL_BLUE
+ sound_to_playing_players('sound/misc/voybluealert.ogg', volume = 50) // Citadel change - Makes alerts play a sound
+ for(var/obj/machinery/firealarm/FA in GLOB.machines)
+ if(is_station_level(FA.z))
+ FA.update_icon()
+ if(SEC_LEVEL_AMBER)
+ if(GLOB.security_level < SEC_LEVEL_AMBER)
+ minor_announce(CONFIG_GET(string/alert_amber_upto), "Attention! Security level elevated to amber:",1)
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ if(GLOB.security_level == SEC_LEVEL_GREEN)
+ SSshuttle.emergency.modTimer(0.4)
+ else
+ SSshuttle.emergency.modTimer(0.66)
+ else
+ minor_announce(CONFIG_GET(string/alert_amber_downto), "Attention! Security level lowered to amber:")
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ SSshuttle.emergency.modTimer(1.6)
+ GLOB.security_level = SEC_LEVEL_AMBER
+ sound_to_playing_players('sound/effects/alert.ogg', volume = 50) // Citadel change - Makes alerts play a sound
+ for(var/obj/machinery/firealarm/FA in GLOB.machines)
+ if(is_station_level(FA.z))
+ FA.update_icon()
+ if(SEC_LEVEL_RED)
+ if(GLOB.security_level < SEC_LEVEL_RED)
+ minor_announce(CONFIG_GET(string/alert_red_upto), "Attention! Code red!",1)
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ if(GLOB.security_level == SEC_LEVEL_GREEN)
+ SSshuttle.emergency.modTimer(0.25)
+ else if(GLOB.security_level == SEC_LEVEL_BLUE)
+ SSshuttle.emergency.modTimer(0.416)
+ else
+ SSshuttle.emergency.modTimer(0.625)
+ else
+ minor_announce(CONFIG_GET(string/alert_red_downto), "Attention! Code red!")
+ GLOB.security_level = SEC_LEVEL_RED
+ sound_to_playing_players('sound/misc/voyalert.ogg', volume = 50) // Citadel change - Makes alerts play a sound
+
+ for(var/obj/machinery/firealarm/FA in GLOB.machines)
+ if(is_station_level(FA.z))
+ FA.update_icon()
+ for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines)
+ pod.admin_controlled = FALSE
+ if(SEC_LEVEL_DELTA)
+ minor_announce(CONFIG_GET(string/alert_delta), "Attention! Delta security level reached!",1)
+ if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
+ if(GLOB.security_level < SEC_LEVEL_BLUE)
+ SSshuttle.emergency.modTimer(0.25)
+ else if(GLOB.security_level == SEC_LEVEL_BLUE)
+ SSshuttle.emergency.modTimer(0.416)
+ else
+ SSshuttle.emergency.modTimer(0.625)
+ GLOB.security_level = SEC_LEVEL_DELTA
+ sound_to_playing_players('sound/misc/deltakalaxon.ogg') // Citadel change - Makes alerts play a sound
+ for(var/obj/machinery/firealarm/FA in GLOB.machines)
+ if(is_station_level(FA.z))
+ FA.update_icon()
+ for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines)
+ pod.admin_controlled = FALSE
+ if(new_level >= SEC_LEVEL_RED)
+ for(var/obj/machinery/door/D in GLOB.machines)
+ if(D.red_alert_access)
+ D.visible_message("[D] whirrs as it automatically lifts access requirements!")
+ playsound(D, 'sound/machines/boltsup.ogg', 50, TRUE)
+ SEND_SIGNAL(src, COMSIG_SECURITY_LEVEL_CHANGED, new_level)
+ SSblackbox.record_feedback("tally", "security_level_changes", 1, NUM2SECLEVEL(GLOB.security_level))
+ SSnightshift.check_nightshift()
+ else
+ return
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
old mode 100755
new mode 100644
index a68b68f3ec..2417210f8f
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -301,6 +301,7 @@ SUBSYSTEM_DEF(ticker)
cb.InvokeAsync()
LAZYCLEARLIST(round_start_events)
+ SEND_SIGNAL(src, COMSIG_TICKER_ROUND_STARTING)
real_round_start_time = world.timeofday
log_world("Game start took [(world.timeofday - init_start)/10]s")
diff --git a/code/datums/skills/modifiers/job.dm b/code/datums/skills/modifiers/job.dm
index e751fbf120..5cf99f6138 100644
--- a/code/datums/skills/modifiers/job.dm
+++ b/code/datums/skills/modifiers/job.dm
@@ -35,5 +35,8 @@
/datum/skill_modifier/job/level/wiring/basic
level_mod = JOB_SKILL_BASIC
+/datum/skill_modifier/job/level/wiring/expert
+ level_mod = JOB_SKILL_EXPERT
+
/datum/skill_modifier/job/level/dwarfy/blacksmithing
target_skills = /datum/skill/level/dwarfy/blacksmithing
diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm
index 28999ef0b5..cc9fc8c2b3 100644
--- a/code/game/objects/effects/decals/cleanable/misc.dm
+++ b/code/game/objects/effects/decals/cleanable/misc.dm
@@ -126,7 +126,7 @@
icon_state = "greenglow"
beauty = -300
mergeable_decal = TRUE
- persistent = TRUE
+ persistent = FALSE
/obj/effect/decal/cleanable/greenglow/Initialize(mapload)
. = ..()
diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm
index 9ad75b5d8f..abc81b0f8e 100644
--- a/code/game/objects/items/devices/radio/encryptionkey.dm
+++ b/code/game/objects/items/devices/radio/encryptionkey.dm
@@ -11,7 +11,7 @@
/obj/item/encryptionkey/Initialize(mapload)
. = ..()
- if(!channels.len)
+ if(!length(channels) && !translate_binary)
desc = "An encryption key for a radio headset. Has no special codes in it. You should probably tell a coder!"
/obj/item/encryptionkey/examine(mob/user)
@@ -22,6 +22,8 @@
examine_text_list += "[GLOB.channel_tokens[i]] - [lowertext(i)]"
. += "It can access the following channels; [jointext(examine_text_list, ", ")]."
+ if(translate_binary)
+ . += "It also allows access to the special binary channel used by silicons."
/obj/item/encryptionkey/syndicate
name = "syndicate encryption key"
diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm
index 1a6e0747b2..e15b735a55 100644
--- a/code/game/objects/items/dna_injector.dm
+++ b/code/game/objects/items/dna_injector.dm
@@ -1,7 +1,7 @@
/obj/item/dnainjector
name = "\improper DNA injector"
desc = "This injects the person with DNA."
- icon = 'icons/obj/items_and_weapons.dmi'
+ icon = 'icons/obj/syringe.dmi'
icon_state = "dnainjector"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
diff --git a/code/game/objects/items/implants/implantcase.dm b/code/game/objects/items/implants/implantcase.dm
index a97874b1c0..14bdfd77d0 100644
--- a/code/game/objects/items/implants/implantcase.dm
+++ b/code/game/objects/items/implants/implantcase.dm
@@ -1,7 +1,7 @@
/obj/item/implantcase
name = "implant case"
desc = "A glass case containing an implant."
- icon = 'icons/obj/items_and_weapons.dmi'
+ icon = 'icons/obj/syringe.dmi'
icon_state = "implantcase-0"
item_state = "implantcase"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
diff --git a/code/game/objects/items/implants/implanter.dm b/code/game/objects/items/implants/implanter.dm
index c921942541..f36c2b5937 100644
--- a/code/game/objects/items/implants/implanter.dm
+++ b/code/game/objects/items/implants/implanter.dm
@@ -1,7 +1,7 @@
/obj/item/implanter
name = "implanter"
desc = "A sterile automatic implant injector."
- icon = 'icons/obj/items_and_weapons.dmi'
+ icon = 'icons/obj/syringe.dmi'
icon_state = "implanter0"
item_state = "syringe_0"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm
index 6b97772b00..dcacd00fe2 100644
--- a/code/game/objects/items/storage/backpack.dm
+++ b/code/game/objects/items/storage/backpack.dm
@@ -357,8 +357,69 @@
item_state = "duffel-med"
/obj/item/storage/backpack/duffelbag/med/surgery
- name = "surgical duffel bag"
- desc = "A large duffel bag for holding extra medical supplies - this one seems to be designed for holding surgical tools."
+ name = "surgical tools case"
+ desc = "A large plastic case for holding surgical tools or most other medical supplies you could imagine."
+ icon_state = "firstaid-surgery"
+ item_state = "firstaid"
+ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
+ slot_flags = NONE
+
+/obj/item/storage/backpack/duffelbag/med/surgery/ComponentInitialize()
+ . = ..()
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ var/static/list/can_hold = typecacheof(list(
+ /obj/item/healthanalyzer,
+ /obj/item/dnainjector,
+ /obj/item/reagent_containers/dropper,
+ /obj/item/reagent_containers/glass/beaker,
+ /obj/item/reagent_containers/glass/bottle,
+ /obj/item/reagent_containers/pill,
+ /obj/item/reagent_containers/syringe,
+ /obj/item/reagent_containers/medspray,
+ /obj/item/lighter,
+ /obj/item/storage/fancy/cigarettes,
+ /obj/item/storage/pill_bottle,
+ /obj/item/stack/medical,
+ /obj/item/flashlight/pen,
+ /obj/item/extinguisher/mini,
+ /obj/item/reagent_containers/hypospray,
+ /obj/item/hypospray/mkii,
+ /obj/item/sensor_device,
+ /obj/item/radio,
+ /obj/item/clothing/gloves/,
+ /obj/item/lazarus_injector,
+ /obj/item/bikehorn/rubberducky,
+ /obj/item/clothing/mask/surgical,
+ /obj/item/clothing/mask/breath,
+ /obj/item/clothing/mask/breath/medical,
+ /obj/item/surgical_drapes,
+ /obj/item/scalpel,
+ /obj/item/circular_saw,
+ /obj/item/bonesetter,
+ /obj/item/surgicaldrill,
+ /obj/item/retractor,
+ /obj/item/cautery,
+ /obj/item/hemostat,
+ /obj/item/geiger_counter,
+ /obj/item/clothing/neck/stethoscope,
+ /obj/item/stamp,
+ /obj/item/clothing/glasses,
+ /obj/item/wrench/medical,
+ /obj/item/clothing/mask/muzzle,
+ /obj/item/storage/bag/chemistry,
+ /obj/item/storage/bag/bio,
+ /obj/item/reagent_containers/blood,
+ /obj/item/tank/internals/emergency_oxygen,
+ /obj/item/gun/syringe/syndicate,
+ /obj/item/implantcase,
+ /obj/item/implant,
+ /obj/item/implanter,
+ /obj/item/pinpointer/crew,
+ /obj/item/reagent_containers/chem_pack,
+ /obj/item/stack/sticky_tape
+ ))
+ STR.can_hold = can_hold
/obj/item/storage/backpack/duffelbag/med/surgery/PopulateContents()
new /obj/item/scalpel(src)
@@ -368,6 +429,7 @@
new /obj/item/surgicaldrill(src)
new /obj/item/cautery(src)
new /obj/item/bonesetter(src)
+ new /obj/item/stack/medical/bone_gel(src)
new /obj/item/surgical_drapes(src)
new /obj/item/clothing/mask/surgical(src)
new /obj/item/reagent_containers/medspray/sterilizine(src)
diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm
index 454475625d..f64cdbc98b 100644
--- a/code/game/objects/items/storage/briefcase.dm
+++ b/code/game/objects/items/storage/briefcase.dm
@@ -105,7 +105,7 @@
/obj/item/storage/briefcase/medical
name = "medical briefcase"
- icon_state = "medbriefcase"
+ icon_state = "firstaid-briefcase"
desc = "A white with a blue cross brieface, this is meant to hold medical gear that would not be able to normally fit in a bag."
/obj/item/storage/briefcase/medical/PopulateContents()
diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm
index e700bf87e0..bcfcbe20f8 100644
--- a/code/game/objects/items/storage/firstaid.dm
+++ b/code/game/objects/items/storage/firstaid.dm
@@ -18,12 +18,6 @@
throw_speed = 3
throw_range = 7
var/empty = FALSE
- var/list/possible_icons = list("firstaid","firstaid2","firstaid3","firstaid4")
-
-/obj/item/storage/firstaid/Initialize(mapload)
- . = ..()
- if(LAZYLEN(possible_icons))
- icon_state = pick(possible_icons)
/obj/item/storage/firstaid/regular
icon_state = "firstaid"
@@ -45,7 +39,7 @@
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/emergency
- icon_state = "medbriefcase"
+ icon_state = "firstaid-briefcase"
name = "emergency first-aid kit"
desc = "A very simple first aid kit meant to secure and stabilize serious wounds for later treatment."
@@ -75,12 +69,30 @@
new /obj/item/stack/medical/mesh(src)
new /obj/item/stack/medical/mesh(src)
+/obj/item/storage/firstaid/brute
+ name = "trauma treatment kit"
+ desc = "A first aid kit for when you get toolboxed."
+ icon_state = "firstaid-brute"
+ item_state = "firstaid-brute"
+
+/obj/item/storage/firstaid/brute/suicide_act(mob/living/carbon/user)
+ user.visible_message("[user] begins beating [user.p_them()]self over the head with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!")
+ return BRUTELOSS
+
+/obj/item/storage/firstaid/brute/PopulateContents()
+ if(empty)
+ return
+ for(var/i in 1 to 4)
+ new /obj/item/reagent_containers/pill/patch/styptic(src)
+ new /obj/item/stack/medical/gauze(src)
+ new /obj/item/stack/medical/gauze(src)
+ new /obj/item/healthanalyzer(src)
+
/obj/item/storage/firstaid/fire
name = "burn treatment kit"
desc = "A specialized medical kit for when the toxins lab -spontaneously- burns down."
- icon_state = "burn"
- item_state = "firstaid-ointment"
- possible_icons = list("burn","burn2","burn3","burn4")
+ icon_state = "firstaid-burn"
+ item_state = "firstaid-burn"
/obj/item/storage/firstaid/fire/suicide_act(mob/living/carbon/user)
user.visible_message("[user] begins rubbing \the [src] against [user.p_them()]self! It looks like [user.p_theyre()] trying to start a fire!")
@@ -99,9 +111,8 @@
/obj/item/storage/firstaid/toxin
name = "toxin treatment kit"
desc = "Used to treat toxic blood content and radiation poisoning."
- icon_state = "toxin"
+ icon_state = "firstaid-toxin"
item_state = "firstaid-toxin"
- possible_icons = list("toxin","toxin2","toxin3","toxin4")
/obj/item/storage/firstaid/toxin/suicide_act(mob/living/carbon/user)
user.visible_message("[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!")
@@ -116,38 +127,11 @@
new /obj/item/storage/pill_bottle/charcoal(src)
new /obj/item/healthanalyzer(src)
-/obj/item/storage/firstaid/radbgone
- name = "radiation treatment kit"
- desc = "Used to treat minor toxic blood content and major radiation poisoning."
- icon_state = "rad"
- item_state = "firstaid-toxin"
- possible_icons = list("rad","rad2","rad3")
-
-/obj/item/storage/firstaid/radbgone/suicide_act(mob/living/carbon/user)
- user.visible_message("[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!")
- return TOXLOSS
-
-/obj/item/storage/firstaid/radbgone/PopulateContents()
- if(empty)
- return
- if(prob(50))
- new /obj/item/reagent_containers/pill/mutarad(src)
- if(prob(80))
- new /obj/item/reagent_containers/pill/antirad_plus(src)
- new /obj/item/reagent_containers/syringe/charcoal(src)
- new /obj/item/storage/pill_bottle/charcoal(src)
- new /obj/item/reagent_containers/pill/mutadone(src)
- new /obj/item/reagent_containers/pill/antirad(src)
- new /obj/item/reagent_containers/food/drinks/bottle/vodka(src)
- new /obj/item/healthanalyzer(src)
-
-
/obj/item/storage/firstaid/o2
name = "oxygen deprivation treatment kit"
desc = "A box full of oxygen goodies."
- icon_state = "oxy"
+ icon_state = "firstaid-o2"
item_state = "firstaid-o2"
- possible_icons = list("oxy", "oxy2", "oxy3", "oxy4")
/obj/item/storage/firstaid/o2/suicide_act(mob/living/carbon/user)
user.visible_message("[user] begins hitting [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!")
@@ -162,31 +146,11 @@
new /obj/item/reagent_containers/hypospray/medipen(src)
new /obj/item/healthanalyzer(src)
-/obj/item/storage/firstaid/brute
- name = "brute trauma treatment kit"
- desc = "A first aid kit for when you get toolboxed."
- icon_state = "brute"
- item_state = "firstaid-brute"
- possible_icons = list("brute", "brute2", "brute3", "brute4")
-
-/obj/item/storage/firstaid/brute/suicide_act(mob/living/carbon/user)
- user.visible_message("[user] begins beating [user.p_them()]self over the head with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!")
- return BRUTELOSS
-
-/obj/item/storage/firstaid/brute/PopulateContents()
- if(empty)
- return
- for(var/i in 1 to 4)
- new /obj/item/reagent_containers/pill/patch/styptic(src)
- new /obj/item/stack/medical/gauze(src)
- new /obj/item/stack/medical/gauze(src)
- new /obj/item/healthanalyzer(src)
-
/obj/item/storage/firstaid/tactical
- name = "combat medical kit"
+ name = "tactical first-aid kit"
desc = "I hope you've got insurance."
- icon_state = "tactical"
- possible_icons = null
+ icon_state = "firstaid-tactical"
+ item_state = "firstaid-tactical"
/obj/item/storage/firstaid/tactical/ComponentInitialize()
. = ..()
@@ -208,7 +172,6 @@
new /obj/item/clothing/glasses/hud/health/night/syndicate(src)
/obj/item/storage/firstaid/tactical/nukeop
- name = "improved combat medical kit"
/obj/item/storage/firstaid/tactical/nukeop/PopulateContents()
if(empty)
@@ -222,6 +185,30 @@
new /obj/item/reagent_containers/syringe/lethal/choral(src) // what the fuck does anyone use this piece of shit for
new /obj/item/clothing/glasses/hud/health/night/syndicate(src)
+/obj/item/storage/firstaid/radbgone
+ name = "radiation treatment kit"
+ desc = "Used to treat minor toxic blood content and major radiation poisoning."
+ icon_state = "firstaid-rad"
+ item_state = "firstaid-rad"
+
+/obj/item/storage/firstaid/radbgone/suicide_act(mob/living/carbon/user)
+ user.visible_message("[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!")
+ return TOXLOSS
+
+/obj/item/storage/firstaid/radbgone/PopulateContents()
+ if(empty)
+ return
+ if(prob(50))
+ new /obj/item/reagent_containers/pill/mutarad(src)
+ if(prob(80))
+ new /obj/item/reagent_containers/pill/antirad_plus(src)
+ new /obj/item/reagent_containers/syringe/charcoal(src)
+ new /obj/item/storage/pill_bottle/charcoal(src)
+ new /obj/item/reagent_containers/pill/mutadone(src)
+ new /obj/item/reagent_containers/pill/antirad(src)
+ new /obj/item/reagent_containers/food/drinks/bottle/vodka(src)
+ new /obj/item/healthanalyzer(src)
+
/*
* Pill Bottles
*/
@@ -479,12 +466,12 @@
name = "hypospray kit"
desc = "It's a kit designed for containing a hypospray and specific treatment chemical-filled vials."
icon_state = "firstaid-mini"
+ item_state = "firstaid"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
throw_speed = 3
throw_range = 7
var/empty = FALSE
- item_state = "firstaid"
custom_price = PRICE_ABOVE_NORMAL
custom_premium_price = PRICE_EXPENSIVE
@@ -497,7 +484,7 @@
/obj/item/reagent_containers/glass/bottle/vial))
/obj/item/storage/hypospraykit/regular
- icon_state = "firstaid-mini"
+ name = "first-aid hypospray kit"
desc = "A hypospray kit with general use vials."
/obj/item/storage/hypospraykit/regular/PopulateContents()
@@ -507,11 +494,24 @@
new /obj/item/reagent_containers/glass/bottle/vial/small/tricord(src)
new /obj/item/reagent_containers/glass/bottle/vial/small/tricord(src)
+/obj/item/storage/hypospraykit/brute
+ name = "trauma hypospray kit"
+ icon_state = "firstaid-brute-mini"
+ item_state = "firstaid-brute"
+
+/obj/item/storage/hypospraykit/brute/PopulateContents()
+ if(empty)
+ return
+ new /obj/item/hypospray/mkii/brute(src)
+ new /obj/item/reagent_containers/glass/bottle/vial/small/bicaridine(src)
+ new /obj/item/reagent_containers/glass/bottle/vial/small/bicaridine(src)
+
+
/obj/item/storage/hypospraykit/fire
name = "burn treatment hypospray kit"
desc = "A specialized hypospray kit for burn treatments. Apply with sass."
- icon_state = "burn-mini"
- item_state = "firstaid-ointment"
+ icon_state = "firstaid-burn-mini"
+ item_state = "firstaid-burn"
/obj/item/storage/hypospraykit/fire/PopulateContents()
if(empty)
@@ -522,7 +522,7 @@
/obj/item/storage/hypospraykit/toxin
name = "toxin treatment hypospray kit"
- icon_state = "toxin-mini"
+ icon_state = "firstaid-toxin-mini"
item_state = "firstaid-toxin"
/obj/item/storage/hypospraykit/toxin/PopulateContents()
@@ -534,7 +534,7 @@
/obj/item/storage/hypospraykit/o2
name = "oxygen deprivation hypospray kit"
- icon_state = "oxy-mini"
+ icon_state = "firstaid-o2-mini"
item_state = "firstaid-o2"
/obj/item/storage/hypospraykit/o2/PopulateContents()
@@ -546,9 +546,39 @@
/obj/item/storage/hypospraykit/enlarge
name = "organomegaly trauma hypospray kit"
- icon_state = "enlarge-mini"
+ icon_state = "firstaid-enlarge-mini"
item_state = "firstaid-brute"
+/obj/item/storage/hypospraykit/tactical
+ name = "tactical first-aid hypospray kit"
+ desc = "A hypospray kit best suited for combat situations."
+ icon_state = "firstaid-tactical-mini"
+ item_state = "firstaid-tactical-mini"
+
+/obj/item/storage/hypospraykit/tactical/PopulateContents()
+ if(empty)
+ return
+ new /obj/item/defibrillator/compact/combat/loaded(src)
+ new /obj/item/hypospray/mkii/CMO/combat(src)
+ new /obj/item/reagent_containers/glass/bottle/vial/large/combat(src)
+ new /obj/item/reagent_containers/glass/bottle/vial/large/combat(src)
+
+/obj/item/storage/hypospraykit/cmo
+ name = "deluxe hypospray kit"
+ desc = "A kit containing a Deluxe hypospray and Vials."
+ icon_state = "firstaid-rad-mini"
+ item_state = "firstaid-rad"
+
+/obj/item/storage/hypospraykit/cmo/PopulateContents()
+ if(empty)
+ return
+ new /obj/item/hypospray/mkii/CMO(src)
+ new /obj/item/reagent_containers/glass/bottle/vial/large/tricord(src)
+ new /obj/item/reagent_containers/glass/bottle/vial/large/charcoal(src)
+ new /obj/item/reagent_containers/glass/bottle/vial/large/salglu(src)
+ new /obj/item/reagent_containers/glass/bottle/vial/large/dexalin(src)
+ new /obj/item/reagent_containers/glass/bottle/vial/large/synthflesh(src)
+
/obj/item/storage/hypospraykit/enlarge/PopulateContents()
if(empty)
return
@@ -563,46 +593,6 @@
new /obj/item/reagent_containers/glass/bottle/vial/small/buttreduction(src)
new /obj/item/reagent_containers/glass/bottle/vial/small/buttreduction(src)
-/obj/item/storage/hypospraykit/brute
- name = "brute trauma hypospray kit"
- icon_state = "brute-mini"
- item_state = "firstaid-brute"
-
-/obj/item/storage/hypospraykit/brute/PopulateContents()
- if(empty)
- return
- new /obj/item/hypospray/mkii/brute(src)
- new /obj/item/reagent_containers/glass/bottle/vial/small/bicaridine(src)
- new /obj/item/reagent_containers/glass/bottle/vial/small/bicaridine(src)
-
-/obj/item/storage/hypospraykit/tactical
- name = "combat hypospray kit"
- desc = "A hypospray kit best suited for combat situations."
- icon_state = "tactical-mini"
-
-/obj/item/storage/hypospraykit/tactical/PopulateContents()
- if(empty)
- return
- new /obj/item/defibrillator/compact/combat/loaded(src)
- new /obj/item/hypospray/mkii/CMO/combat(src)
- new /obj/item/reagent_containers/glass/bottle/vial/large/combat(src)
- new /obj/item/reagent_containers/glass/bottle/vial/large/combat(src)
-
-/obj/item/storage/hypospraykit/cmo
- name = "deluxe hypospray kit"
- desc = "A kit containing a Deluxe hypospray and Vials."
- icon_state = "tactical-mini"
-
-/obj/item/storage/hypospraykit/cmo/PopulateContents()
- if(empty)
- return
- new /obj/item/hypospray/mkii/CMO(src)
- new /obj/item/reagent_containers/glass/bottle/vial/large/tricord(src)
- new /obj/item/reagent_containers/glass/bottle/vial/large/charcoal(src)
- new /obj/item/reagent_containers/glass/bottle/vial/large/salglu(src)
- new /obj/item/reagent_containers/glass/bottle/vial/large/dexalin(src)
- new /obj/item/reagent_containers/glass/bottle/vial/large/synthflesh(src)
-
/obj/item/storage/box/vials
name = "box of hypovials"
diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm
index bb5ca6da1a..a62fc70917 100644
--- a/code/game/turfs/change_turf.dm
+++ b/code/game/turfs/change_turf.dm
@@ -151,17 +151,18 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
return
var/turf/open/newTurf = .
newTurf.air.copy_from(stashed_air)
- update_air_ref(planetary_atmos ? 1 : 2)
+ newTurf.update_air_ref(planetary_atmos ? 1 : 2)
QDEL_NULL(stashed_air)
else
+ flags |= CHANGETURF_RECALC_ADJACENT
if(ispath(path,/turf/closed))
- flags |= CHANGETURF_RECALC_ADJACENT
- update_air_ref(-1)
. = ..()
+ var/turf/open/newTurf = .
+ newTurf.update_air_ref(-1)
else
. = ..()
- if(!istype(air,/datum/gas_mixture))
- Initalize_Atmos(0)
+ var/turf/open/newTurf = .
+ newTurf.Initalize_Atmos(0)
// Take off the top layer turf and replace it with the next baseturf down
/turf/proc/ScrapeAway(amount=1, flags)
diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm
index aa5e02819c..dcf687d53f 100644
--- a/code/game/turfs/open.dm
+++ b/code/game/turfs/open.dm
@@ -218,11 +218,10 @@
flash_color(L, flash_color = "#C80000", flash_time = 10)
/turf/open/Initalize_Atmos(times_fired)
- if(!blocks_air)
- if(!istype(air,/datum/gas_mixture/turf))
- air = new(2500,src)
- air.copy_from_turf(src)
- update_air_ref(planetary_atmos ? 1 : 2)
+ if(!istype(air,/datum/gas_mixture/turf))
+ air = new(2500,src)
+ air.copy_from_turf(src)
+ update_air_ref(planetary_atmos ? 1 : 2)
update_visuals()
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index c11db249ed..acc431a40c 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -89,6 +89,8 @@ GLOBAL_PROTECT(admin_verbs_admin)
/client/proc/revokebunkerbypass, //CIT
/client/proc/adddiscordbypass, //SPLURT
/client/proc/revokediscordbypass, //SPLURT
+ /client/proc/addvpnbypass, //SPLURT
+ /client/proc/revokevpnbypass, //SPLURT
/datum/admins/proc/open_borgopanel
)
GLOBAL_LIST_INIT(admin_verbs_ban, list(/client/proc/unban_panel, /client/proc/DB_ban_panel, /client/proc/stickybanpanel))
@@ -149,6 +151,7 @@ GLOBAL_PROTECT(admin_verbs_server)
/client/proc/adminchangemap,
/client/proc/panicbunker,
/client/proc/discordbunker, // SPLURT
+ /client/proc/vpnbunker, //SPLURT
// /client/proc/toggle_interviews,
/client/proc/toggle_hub,
/client/proc/toggle_cdn
@@ -279,10 +282,13 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
/client/proc/reload_admins,
/client/proc/panicbunker,
/client/proc/discordbunker, // SPLURT
+ /client/proc/vpnbunker, // SPLURT
/client/proc/addbunkerbypass, //CIT
/client/proc/revokebunkerbypass, //CIT
/client/proc/adddiscordbypass, //SPLURT
/client/proc/revokediscordbypass, //SPLURT
+ /client/proc/addvpnbypass, //SPLURT
+ /client/proc/revokevpnbypass, //SPLURT
// /client/proc/toggle_interviews,
/client/proc/admin_change_sec_level,
/client/proc/toggle_nuke,
diff --git a/code/modules/antagonists/bloodsucker/items/bloodsucker_stake.dm b/code/modules/antagonists/bloodsucker/items/bloodsucker_stake.dm
index 69410027a4..5e6989806a 100644
--- a/code/modules/antagonists/bloodsucker/items/bloodsucker_stake.dm
+++ b/code/modules/antagonists/bloodsucker/items/bloodsucker_stake.dm
@@ -66,6 +66,7 @@
/obj/item/stake/afterattack(atom/target, mob/user, proximity)
//to_chat(world, "DEBUG: Staking ")
// Invalid Target, or not targetting chest with HARM intent?
+ . = ..()
if(!iscarbon(target) || check_zone(user.zone_selected) != "chest" || user.a_intent != INTENT_HARM)
return
var/mob/living/carbon/C = target
@@ -139,9 +140,8 @@
// Convert back to Silver
/obj/item/stake/hardened/silver/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/weldingtool))
- var/obj/item/weldingtool/WT = I
- if(WT.use(0))//remove_fuel(0, user))
+ if(I.tool_behaviour == TOOL_WELDER)
+ if(I.use(0))//remove_fuel(0, user))
var/obj/item/stack/sheet/mineral/silver/newsheet = new (user.loc)
for(var/obj/item/stack/sheet/mineral/silver/S in user.loc)
if(S == newsheet)
diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm
index b104c51fb7..23b73cea35 100644
--- a/code/modules/atmospherics/gasmixtures/reactions.dm
+++ b/code/modules/atmospherics/gasmixtures/reactions.dm
@@ -86,7 +86,7 @@
min_requirements[R.get_gas()] = MOLES_GAS_VISIBLE
name = "[R.name] condensation"
id = "[R.type] condensation"
- condensing_reagent = R
+ condensing_reagent = GLOB.chemical_reagents_list[R.type]
exclude = FALSE
/datum/gas_reaction/condensation/react(datum/gas_mixture/air, datum/holder)
@@ -101,7 +101,10 @@
var/G = condensing_reagent.get_gas()
var/amt = air.get_moles(G)
air.adjust_moles(G, -min(initial(condensing_reagent.condensation_amount), amt))
- reagents_holder.add_reagent(condensing_reagent, amt)
+ if(air.get_moles(G) < MOLES_GAS_VISIBLE)
+ amt += air.get_moles(G)
+ air.set_moles(G, 0.0)
+ reagents_holder.add_reagent(condensing_reagent.type, amt)
. = REACTING
for(var/atom/movable/AM in location)
if(location.intact && AM.level == 1)
diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm
index 767304f799..4fbe5f467a 100644
--- a/code/modules/awaymissions/gateway.dm
+++ b/code/modules/awaymissions/gateway.dm
@@ -85,7 +85,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
. = "Exit gateway unpowered."
/datum/gateway_destination/gateway/get_target_turf()
- return get_step(target_gateway, SOUTH)
+ return get_step(target_gateway.portal,SOUTH)
/datum/gateway_destination/gateway/post_transfer(atom/movable/AM)
. = ..()
@@ -112,7 +112,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
/datum/gateway_destination/gateway/home/proc/check_exile_implant(mob/living/L)
for(var/obj/item/implant/exile/E in L.implants)//Checking that there is an exile implant
- to_chat(L, "The station gate has detected your exile implant and is blocking your entry.")
+ to_chat(L, span_userdanger("The station gate has detected your exile implant and is blocking your entry."))
return TRUE
return FALSE
@@ -156,8 +156,6 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
bound_y = 0
density = TRUE
- use_power = IDLE_POWER_USE
- idle_power_usage = 100
active_power_usage = 5000
var/calibrated = TRUE
@@ -173,14 +171,22 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
var/obj/effect/gateway_portal_bumper/portal
/// Visual object for handling the viscontents
var/obj/effect/gateway_portal_effect/portal_visuals
+ /// Overlay of the lights. They light up fully when it charges fully.
+ var/image/light_overlay
/obj/machinery/gateway/Initialize(mapload)
generate_destination()
- update_icon()
+ update_appearance()
portal_visuals = new
vis_contents += portal_visuals
return ..()
+/obj/machinery/gateway/Destroy()
+ destination.target_gateway = null
+ GLOB.gateway_destinations -= destination
+ destination = null
+ return ..()
+
/obj/machinery/gateway/proc/generate_destination()
destination = new destination_type
destination.name = destination_name
@@ -194,7 +200,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
QDEL_NULL(portal)
if(use_power == ACTIVE_POWER_USE)
use_power = IDLE_POWER_USE
- update_icon()
+ update_appearance()
portal_visuals.reset_visuals()
/obj/machinery/gateway/process()
@@ -202,6 +208,15 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
if(target)
deactivate()
return
+ if(light_overlay)
+ return
+ for(var/datum/gateway_destination/destination as anything in GLOB.gateway_destinations)
+ if(!destination.is_available())
+ continue
+ light_overlay = image(icon, "portal_light")
+ light_overlay.alpha = 0
+ animate(light_overlay, 3 SECONDS, alpha = 255)
+ add_overlay(light_overlay)
/obj/machinery/gateway/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG, gentle = FALSE)
return
@@ -218,7 +233,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
portal_visuals.setup_visuals(target)
generate_bumper()
use_power = ACTIVE_POWER_USE
- update_icon()
+ update_appearance()
/obj/machinery/gateway/proc/Transfer(atom/movable/AM)
if(!target || !target.incoming_pass_check(AM))
@@ -243,9 +258,9 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
/obj/machinery/gateway/multitool_act(mob/living/user, obj/item/I)
if(calibrated)
- to_chat(user, "The gate is already calibrated, there is no work for you to do here.")
+ to_chat(user, span_alert("The gate is already calibrated, there is no work for you to do here."))
else
- to_chat(user, "Recalibration successful!: \black This gate's systems have been fine tuned. Travel to this gate will now be on target.")
+ to_chat(user, "[span_boldnotice("Recalibration successful!")]: \black This gate's systems have been fine tuned. Travel to this gate will now be on target.")
calibrated = TRUE
return TRUE
@@ -258,7 +273,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
. = ..()
if(!target)
if(!GLOB.the_gateway)
- to_chat(user,"Home gateway is not responding!")
+ to_chat(user,span_warning("Home gateway is not responding!"))
if(GLOB.the_gateway.target)
GLOB.the_gateway.deactivate() //this will turn the home gateway off so that it's free for us to connect to
activate(GLOB.the_gateway.destination)
@@ -276,6 +291,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
try_to_linkup()
/obj/machinery/computer/gateway_control/ui_interact(mob/user, datum/tgui/ui)
+ . = ..()
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Gateway", name)
@@ -350,15 +366,11 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
if(!our_destination)
return
-
add_filter("portal_alpha", 1, list("type" = "alpha", "icon" = icon(alpha_icon, alpha_icon_state), "x" = 32, "y" = 32))
add_filter("portal_blur", 1, list("type" = "blur", "size" = 0.5))
add_filter("portal_ripple", 1, list("type" = "ripple", "size" = 2, "radius" = 1, "falloff" = 1, "y" = 7))
animate(get_filter("portal_ripple"), time = 1.3 SECONDS, loop = -1, easing = LINEAR_EASING, radius = 32)
- /// DISABLED DUE TO BYOND BUG CAUSING STACK OVERFLOWS OF ANY HUMAN INSTANTIATION NEAR AN ACTIVATED GATEWAY.
- /// Probably due to it referencing each other through the gateway (there's a deep loop, maybe BYOND isn't catching something when it usually would)
- //var/turf/center_turf = our_destination.get_target_turf()
-
- //vis_contents += block(locate(center_turf.x - 1, center_turf.y - 1, center_turf.z), locate(center_turf.x + 1, center_turf.y + 1, center_turf.z))
+ var/turf/center_turf = our_destination.get_target_turf()
+ vis_contents += block(locate(center_turf.x - 1, center_turf.y - 1, center_turf.z), locate(center_turf.x + 1, center_turf.y + 1, center_turf.z))
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index ef99ffbbea..0dd16bc044 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -2866,12 +2866,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("ooccolor")
var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference",ooccolor) as color|null
if(new_ooccolor)
- ooccolor = new_ooccolor
+ ooccolor = sanitize_ooccolor(new_ooccolor)
if("aooccolor")
var/new_aooccolor = input(user, "Choose your Antag OOC colour:", "Game Preference",ooccolor) as color|null
if(new_aooccolor)
- aooccolor = new_aooccolor
+ aooccolor = sanitize_ooccolor(new_aooccolor)
if("bag")
var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in GLOB.backbaglist
diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm
index 07087e70a3..93f91ad3a0 100644
--- a/code/modules/client/verbs/ooc.dm
+++ b/code/modules/client/verbs/ooc.dm
@@ -108,16 +108,38 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8")
else
GLOB.dooc_allowed = !GLOB.dooc_allowed
-/client/proc/set_ooc(newColor as color)
+/client/proc/set_ooc()
set name = "Set Player OOC Color"
set desc = "Modifies player OOC Color"
set category = "Admin.Fun"
- GLOB.OOC_COLOR = sanitize_ooccolor(newColor)
+ if(IsAdminAdvancedProcCall())
+ return
+ var/newColor = input(src, "Please select the new player OOC color.", "OOC color") as color|null
+ if(isnull(newColor))
+ return
+ if(!check_rights(R_FUN))
+ message_admins("[usr.key] has attempted to use the Set Player OOC Color verb!")
+ log_admin("[key_name(usr)] tried to set player ooc color without authorization.")
+ return
+ var/new_color = sanitize_ooccolor(newColor)
+ message_admins("[key_name_admin(usr)] has set the players' ooc color to [new_color].")
+ log_admin("[key_name_admin(usr)] has set the player ooc color to [new_color].")
+ GLOB.OOC_COLOR = new_color
/client/proc/reset_ooc()
set name = "Reset Player OOC Color"
set desc = "Returns player OOC Color to default"
set category = "Admin.Fun"
+ if(IsAdminAdvancedProcCall())
+ return
+ if(alert(usr, "Are you sure you want to reset the OOC color of all players?", "Reset Player OOC Color", "Yes", "No") != "Yes")
+ return
+ if(!check_rights(R_FUN))
+ message_admins("[usr.key] has attempted to use the Reset Player OOC Color verb!")
+ log_admin("[key_name(usr)] tried to reset player ooc color without authorization.")
+ return
+ message_admins("[key_name_admin(usr)] has reset the players' ooc color.")
+ log_admin("[key_name_admin(usr)] has reset player ooc color.")
GLOB.OOC_COLOR = null
/client/verb/colorooc() //this is admin and people who bought byond.
@@ -129,11 +151,12 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8")
return
var/new_ooccolor = input(src, "Please select your OOC color.", "OOC color", prefs.ooccolor) as color|null
- if(new_ooccolor)
- prefs.ooccolor = sanitize_ooccolor(new_ooccolor)
- prefs.save_preferences()
+ if(isnull(new_ooccolor))
+ return
+ new_ooccolor = sanitize_ooccolor(new_ooccolor)
+ prefs.ooccolor = new_ooccolor
+ prefs.save_preferences()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Set OOC Color") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- return
/client/verb/resetcolorooc()
set name = "Reset Your OOC Color"
diff --git a/code/modules/events/dust.dm b/code/modules/events/dust.dm
index 3bece46dcd..39c04003a9 100644
--- a/code/modules/events/dust.dm
+++ b/code/modules/events/dust.dm
@@ -19,7 +19,7 @@
typepath = /datum/round_event/sandstorm
weight = 5
max_occurrences = 1
- min_players = 5
+ min_players = 10
earliest_start = 20 MINUTES
/datum/round_event/sandstorm
@@ -28,5 +28,8 @@
announceWhen = 0
fakeable = FALSE
+/datum/round_event/sandstorm/announce(fake)
+ priority_announce("The station is passing through a heavy debris cloud. Watch out for breaches.", "Collision Alert")
+
/datum/round_event/sandstorm/tick()
- spawn_meteors(10, GLOB.meteorsC)
+ spawn_meteors(rand(6,10), GLOB.meteorsC)
diff --git a/code/modules/jobs/job_types/atmospheric_technician.dm b/code/modules/jobs/job_types/atmospheric_technician.dm
index 82eae55bde..2e89035bfa 100644
--- a/code/modules/jobs/job_types/atmospheric_technician.dm
+++ b/code/modules/jobs/job_types/atmospheric_technician.dm
@@ -21,7 +21,7 @@
paycheck = PAYCHECK_MEDIUM
paycheck_department = ACCOUNT_ENG
- starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic, /datum/skill_modifier/job/affinity/wiring)
+ starting_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/affinity/wiring)
display_order = JOB_DISPLAY_ORDER_ATMOSPHERIC_TECHNICIAN
threat = 0.5
diff --git a/code/modules/jobs/job_types/chief_engineer.dm b/code/modules/jobs/job_types/chief_engineer.dm
index bfc52e9437..e77338365d 100644
--- a/code/modules/jobs/job_types/chief_engineer.dm
+++ b/code/modules/jobs/job_types/chief_engineer.dm
@@ -31,7 +31,7 @@
paycheck = PAYCHECK_COMMAND
paycheck_department = ACCOUNT_ENG
- starting_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/affinity/wiring)
+ starting_modifiers = list(/datum/skill_modifier/job/level/wiring/expert, /datum/skill_modifier/job/affinity/wiring)
display_order = JOB_DISPLAY_ORDER_CHIEF_ENGINEER
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/paraplegic, /datum/quirk/insanity)
diff --git a/code/modules/jobs/job_types/research_director.dm b/code/modules/jobs/job_types/research_director.dm
index 51f5296b16..50ce44a8b4 100644
--- a/code/modules/jobs/job_types/research_director.dm
+++ b/code/modules/jobs/job_types/research_director.dm
@@ -34,6 +34,7 @@
paycheck_department = ACCOUNT_SCI
display_order = JOB_DISPLAY_ORDER_RESEARCH_DIRECTOR
+ starting_modifiers = list(/datum/skill_modifier/job/level/wiring)
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity)
threat = 5
diff --git a/code/modules/jobs/job_types/scientist.dm b/code/modules/jobs/job_types/scientist.dm
index a851b333fe..eda88a5911 100644
--- a/code/modules/jobs/job_types/scientist.dm
+++ b/code/modules/jobs/job_types/scientist.dm
@@ -18,7 +18,7 @@
minimal_access = list(ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_RESEARCH, ACCESS_XENOBIOLOGY, ACCESS_MINERAL_STOREROOM)
paycheck = PAYCHECK_MEDIUM
paycheck_department = ACCOUNT_SCI
-
+ starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic)
display_order = JOB_DISPLAY_ORDER_SCIENTIST
threat = 1.2
diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm
index 1c65a1f6f6..9f3668c2db 100644
--- a/code/modules/mining/equipment/kinetic_crusher.dm
+++ b/code/modules/mining/equipment/kinetic_crusher.dm
@@ -29,8 +29,10 @@
var/brightness_on = 7
var/wielded = FALSE // track wielded status on item
-/obj/item/kinetic_crusher/cyborg //probably give this a unique sprite later
- desc = "An integrated version of the standard kinetic crusher with a grinded down axe head to dissuade mis-use against crewmen. Deals damage equal to the standard crusher against creatures, however."
+/obj/item/kinetic_crusher/cyborg
+ icon_state = "crusher-cyborg"
+ item_state = "crusher0-cyborg"
+ desc = "An integrated version of the standard kinetic crusher with a kinetic dampener module installed to limit harmful usage misusage against organics. Deals damage equal to the standard crusher against creatures."
force = 10 //wouldn't want to give a borg a 20 brute melee weapon unemagged now would we
detonation_damage = 60
wielded = 1
diff --git a/code/modules/mining/equipment/mineral_scanner.dm b/code/modules/mining/equipment/mineral_scanner.dm
index 98818cb957..ee8389f2a5 100644
--- a/code/modules/mining/equipment/mineral_scanner.dm
+++ b/code/modules/mining/equipment/mineral_scanner.dm
@@ -3,7 +3,7 @@
desc = "A scanner that checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations."
name = "manual mining scanner"
icon = 'icons/obj/device.dmi'
- icon_state = "mining1"
+ icon_state = "miningmanual"
item_state = "analyzer"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
@@ -33,7 +33,7 @@
/obj/item/t_scanner/adv_mining_scanner
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. This one has an extended range."
name = "advanced automatic mining scanner"
- icon_state = "mining0"
+ icon_state = "adv_mining0"
item_state = "analyzer"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
@@ -47,6 +47,7 @@
/obj/item/t_scanner/adv_mining_scanner/lesser
name = "automatic mining scanner"
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations."
+ icon_state = "mining0"
range = 4
cooldown = 50
diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm
index 0cb63d51a2..c56b511b83 100644
--- a/code/modules/mining/equipment/mining_tools.dm
+++ b/code/modules/mining/equipment/mining_tools.dm
@@ -95,7 +95,7 @@
/obj/item/pickaxe/drill
name = "mining drill"
icon_state = "handdrill"
- item_state = "jackhammer"
+ item_state = "handdrill"
slot_flags = ITEM_SLOT_BELT
toolspeed = 0.6 //available from roundstart, faster than a pickaxe.
usesound = 'sound/weapons/drill.ogg'
@@ -115,12 +115,14 @@
/obj/item/pickaxe/drill/diamonddrill
name = "diamond-tipped mining drill"
icon_state = "diamonddrill"
+ item_state = "diamonddrill"
toolspeed = 0.4
desc = "Yours is the drill that will pierce the heavens!"
/obj/item/pickaxe/drill/cyborg/diamond //This is the BORG version!
name = "diamond-tipped cyborg mining drill" //To inherit the NODROP_1 flag, and easier to change borg specific drill mechanics.
icon_state = "diamonddrill"
+ item_state = "diamonddrill"
toolspeed = 0.4
digrange = 2
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index e6d60a7085..6d91774465 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -770,6 +770,12 @@
total_mass_on = 5
attack_speed = 0
attack_unwieldlyness = CLICK_CD_MELEE * 0.5
+ /// how much stamina does it cost to roll?
+ var/roll_stamcost = 15
+ /// how far are we rolling?
+ var/roll_range = 3
+ /// do you spin when dodgerolling
+ var/roll_orientation = TRUE
/obj/item/melee/transforming/cleaving_saw/examine(mob/user)
. = ..()
@@ -815,6 +821,11 @@
else
B.add_stacks(bleed_stacks_per_hit)
+/obj/item/melee/transforming/cleaving_saw/AltClick(mob/user)
+ . = ..()
+ roll_orientation = !roll_orientation
+ to_chat(user, span_notice("You are now [roll_orientation ? "rolling" : "quick-stepping"] when you dodge. (This only affects if you spin or not during a dodge.)"))
+
/obj/item/melee/transforming/cleaving_saw/attack(mob/living/target, mob/living/carbon/human/user)
if(!active || swiping || !target.density || get_turf(target) == get_turf(user))
if(!active)
@@ -834,6 +845,43 @@
melee_attack_chain(user, L)
swiping = FALSE
+/obj/item/melee/transforming/cleaving_saw/alt_pre_attack(atom/A, mob/living/user, params)
+ return TRUE // Let's dance.
+
+/obj/item/melee/transforming/cleaving_saw/altafterattack(atom/target, mob/living/user, proximity_flag, click_parameters)
+ if(user.IsImmobilized()) // no free dodgerolls
+ return
+ var/turf/where_to = get_turf(target)
+ user.apply_damage(damage = roll_stamcost, damagetype = STAMINA)
+ user.Immobilize(0.8 SECONDS) // you dont get to adjust your roll
+ user.throw_at(where_to, range = roll_range, speed = 1, force = MOVE_FORCE_NORMAL, spin = roll_orientation)
+ user.apply_status_effect(/datum/status_effect/dodgeroll_iframes)
+ playsound(user, 'sound/effects/body-armor-rolling.ogg', 50, FALSE)
+ return ..()
+
+/datum/status_effect/dodgeroll_iframes
+ id = "dodgeroll_dodging"
+ alert_type = null
+ status_type = STATUS_EFFECT_REFRESH
+ duration = 0.8 SECONDS // worth tweaking?
+
+/datum/status_effect/dodgeroll_iframes/on_apply()
+ . = ..()
+ RegisterSignal(owner, COMSIG_LIVING_RUN_BLOCK, .proc/trolled)
+
+/datum/status_effect/dodgeroll_iframes/on_remove()
+ UnregisterSignal(owner, list(
+ COMSIG_LIVING_RUN_BLOCK
+ ))
+ return ..()
+
+/datum/status_effect/dodgeroll_iframes/proc/trolled(mob/living/source, real_attack, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list)
+ SIGNAL_HANDLER
+ owner.balloon_alert_to_viewers("missed!")
+ playsound(src, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
+ return_list[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_PASSTHROUGH
+ return BLOCK_SUCCESS | BLOCK_SHOULD_REDIRECT | BLOCK_TARGET_DODGED
+
//Dragon
/obj/structure/closet/crate/necropolis/dragon
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/wings.dm b/code/modules/mob/dead/new_player/sprite_accessories/wings.dm
index 154ec4f53b..9257a094dc 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/wings.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/wings.dm
@@ -22,7 +22,6 @@
/datum/sprite_accessory/wings/angel
name = "Angel"
icon_state = "angel"
- color_src = 0
dimension_x = 46
center = TRUE
dimension_y = 34
@@ -31,7 +30,6 @@
/datum/sprite_accessory/wings_open/angel
name = "Angel"
icon_state = "angel"
- color_src = 0
dimension_x = 46
center = TRUE
dimension_y = 34
@@ -156,7 +154,6 @@
/datum/sprite_accessory/deco_wings/angel
name = "Angel"
icon_state = "angel"
- color_src = 0
dimension_x = 46
center = TRUE
dimension_y = 34
@@ -183,7 +180,11 @@
/datum/sprite_accessory/deco_wings/dragon
name = "Dragon"
icon_state = "dragon"
+ color_src = MATRIXED
+ matrixed_sections = MATRIX_RED_BLUE
upgrade_to = SPECIES_WINGS_DRAGON //lol
+ extra = TRUE //IF NOBODY CAN HAVE UNIQUE DUAL-COLOR DUE TO SHITCODE, I SHALL MAKE IT SO THAT THE MOST USELESS COLOR SLOT IS USED.
+ extra_color_src = MUTCOLORS3
/datum/sprite_accessory/deco_wings/dragonfly
name = "Dragonfly"
@@ -387,13 +388,16 @@
/datum/sprite_accessory/insect_wings/dragon
name = "Dragon"
icon_state = "dragon"
- upgrade_to = SPECIES_WINGS_DRAGON
+ color_src = MATRIXED
+ matrixed_sections = MATRIX_RED_BLUE
+ upgrade_to = SPECIES_WINGS_DRAGON //lol
+ extra = TRUE //IF NOBODY CAN HAVE UNIQUE DUAL-COLOR DUE TO SHITCODE, I SHALL MAKE IT SO THAT THE MOST USELESS COLOR SLOT IS USED.
+ extra_color_src = MUTCOLORS3
/datum/sprite_accessory/insect_wings/dragonfly
name = "Dragonfly"
icon_state = "dragonfly"
upgrade_to = SPECIES_WINGS_INSECT
-
/datum/sprite_accessory/insect_wings/fairy
name = "Fairy"
icon_state = "fairy"
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 63ff67d88a..f4628a5edd 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1872,7 +1872,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
"You slap [user == target ? "your" : "\the [target]'s"] ass, but feel an intense amount of pain as you realise their buns are harder than steel!",\
"You hear a slap."
)
- playsound(target.loc, 'sound/weapons/tap.ogg', 50, 1, -1)
+ var/list/ouchies = list(
+ 'modular_splurt/sound/effects/pan0.ogg',
+ 'modular_splurt/sound/effects/pan1.ogg'
+ )
+ playsound(target.loc, pick(ouchies), 50, 1, -1)
user.emote("scream")
return FALSE
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index e9150f202d..084da459f2 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -725,6 +725,8 @@
var/bleed_amount = bleedDragAmount()
blood_volume = max(blood_volume - bleed_amount, 0) //that depends on our brute damage.
+ if(bleed_amount < 0.1)
+ return
var/newdir = get_dir(target_turf, start)
if(newdir != direction)
newdir = newdir | direction
diff --git a/code/modules/modular_computers/file_system/programs/signaler.dm b/code/modules/modular_computers/file_system/programs/signaler.dm
index ded70f7f37..dfbef9f6d6 100644
--- a/code/modules/modular_computers/file_system/programs/signaler.dm
+++ b/code/modules/modular_computers/file_system/programs/signaler.dm
@@ -57,8 +57,11 @@
var/time = time2text(world.realtime,"hh:mm:ss")
var/turf/T = get_turf(src)
+ if(!istype(T))
+ T = get_turf(usr)
+
var/logging_data
- if(usr)
+ if(usr && T)
logging_data = "[time] : [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(signal_frequency)]/[signal_code]"
GLOB.lastsignalers.Add(logging_data)
diff --git a/code/modules/ninja/suit/shoes.dm b/code/modules/ninja/suit/shoes.dm
index fdc9c068ac..38ddd20eee 100644
--- a/code/modules/ninja/suit/shoes.dm
+++ b/code/modules/ninja/suit/shoes.dm
@@ -11,6 +11,7 @@
name = "ninja shoes"
desc = "A pair of running shoes. Excellent for running and even better for smashing skulls."
icon_state = "s-ninja"
+ item_state = "s-ninja"
permeability_coefficient = 0.01
clothing_flags = NOSLIP
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm
index 789ce852aa..44ff5c7098 100644
--- a/code/modules/ninja/suit/suit.dm
+++ b/code/modules/ninja/suit/suit.dm
@@ -182,6 +182,8 @@
n_shoes = ninja.shoes
ADD_TRAIT(n_shoes, TRAIT_NODROP, NINJA_SUIT_TRAIT)
n_shoes.slowdown--
+ n_shoes.icon_state = "s-ninjan"
+ n_shoes.item_state = "s-ninjan"
n_gloves = ninja.gloves
ADD_TRAIT(n_gloves, TRAIT_NODROP, NINJA_SUIT_TRAIT)
n_gloves.icon_state = "s-ninjan"
@@ -212,6 +214,8 @@
if(n_shoes)
REMOVE_TRAIT(n_shoes, TRAIT_NODROP, NINJA_SUIT_TRAIT)
n_shoes.slowdown++
+ n_shoes.icon_state = "s-ninja"
+ n_shoes.item_state = "s-ninja"
if(n_gloves)
n_gloves.icon_state = "s-ninja"
n_gloves.item_state = "s-ninja"
diff --git a/code/modules/projectiles/boxes_magazines/external/magweapon.dm b/code/modules/projectiles/boxes_magazines/external/magweapon.dm
index a1b7f58698..de8766819f 100644
--- a/code/modules/projectiles/boxes_magazines/external/magweapon.dm
+++ b/code/modules/projectiles/boxes_magazines/external/magweapon.dm
@@ -1,4 +1,5 @@
/obj/item/ammo_box/magazine/mmag
+ name = "magrifle magazine (non-lethal disabler)"
icon_state = "mediummagmag"
ammo_type = /obj/item/ammo_casing/caseless/magnetic/disabler
caliber = "mag"
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index bb7b21596f..67e7b58bd3 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -175,6 +175,7 @@
/obj/item/gun/energy/plasmacutter/adv
name = "advanced plasma cutter"
icon_state = "adv_plasmacutter"
+ item_state = "adv_plasmacutter"
force = 15
ammo_type = list(/obj/item/ammo_casing/energy/plasma/adv)
diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm
index 0bb847a573..2fb8f58019 100644
--- a/code/modules/reagents/chemistry/reagents.dm
+++ b/code/modules/reagents/chemistry/reagents.dm
@@ -257,8 +257,6 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
return rs.Join(" | ")
/datum/reagent/proc/define_gas()
- if(reagent_state == SOLID)
- return null // doesn't make that much sense
var/list/cached_reactions = GLOB.chemical_reactions_list
for(var/reaction in cached_reactions[src.type])
var/datum/chemical_reaction/C = reaction
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 0eb3f6cc7a..2784fa6752 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -405,6 +405,8 @@
metabolization_rate = 0.5 * REAGENTS_METABOLISM
chemical_flags = REAGENT_ALL_PROCESS
overdose_threshold = 60
+ boiling_point = T0C+100
+ gas = GAS_H2O
taste_description = "sweetness and salt"
var/extra_regen = 0.25 // in addition to acting as temporary blood, also add this much to their actual blood per tick
var/last_added = 0
@@ -692,6 +694,7 @@
description = "Rapidly restores oxygen deprivation as well as preventing more of it to an extent. Causes jittering."
reagent_state = LIQUID
color = "#00FFFF"
+ boiling_point = 300
metabolization_rate = 0.25 * REAGENTS_METABOLISM
pH = 2
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 87bb204afe..16f78076bf 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -266,24 +266,27 @@
/datum/reagent/water/reaction_turf(turf/open/T, reac_volume)
if (!istype(T))
return
- var/CT = cooling_temperature
+ if(holder?.chem_temp > T0C + 100)
+ T.atmos_spawn_air("[GAS_H2O]=[reac_volume/molarity];TEMP=[holder.chem_temp]")
+ else
+ var/CT = cooling_temperature
- if(reac_volume >= 5)
- T.MakeSlippery(TURF_WET_WATER, 10 SECONDS, min(reac_volume*1.5 SECONDS, 60 SECONDS))
+ if(reac_volume >= 5)
+ T.MakeSlippery(TURF_WET_WATER, 10 SECONDS, min(reac_volume*1.5 SECONDS, 60 SECONDS))
- for(var/mob/living/simple_animal/slime/M in T)
- M.apply_water()
+ for(var/mob/living/simple_animal/slime/M in T)
+ M.apply_water()
- var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
- if(hotspot && !isspaceturf(T))
- if(T.air)
- var/datum/gas_mixture/G = T.air
- G.set_temperature(max(min(G.return_temperature()-(CT*1000),G.return_temperature()/CT),TCMB))
- G.react(src)
- qdel(hotspot)
- var/obj/effect/acid/A = (locate(/obj/effect/acid) in T)
- if(A)
- A.acid_level = max(A.acid_level - reac_volume*50, 0)
+ var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
+ if(hotspot && !isspaceturf(T))
+ if(T.air)
+ var/datum/gas_mixture/G = T.air
+ G.set_temperature(max(min(G.return_temperature()-(CT*1000),G.return_temperature()/CT),TCMB))
+ G.react(src)
+ qdel(hotspot)
+ var/obj/effect/acid/A = (locate(/obj/effect/acid) in T)
+ if(A)
+ A.acid_level = max(A.acid_level - reac_volume*50, 0)
/*
* Water reaction to an object
@@ -562,9 +565,11 @@
chemical_flags = REAGENT_ALL_PROCESS
color = "#009CA8" // rgb: 0, 156, 168
taste_description = "cherry" // by popular demand
+ boiling_point = 330
var/lube_kind = TURF_WET_LUBE ///What kind of slipperiness gets added to turfs.
/datum/reagent/lube/reaction_turf(turf/open/T, reac_volume)
+ ..()
if (!istype(T))
return
if(reac_volume >= 1)
@@ -1324,6 +1329,8 @@
taste_description = "sourness"
boiling_point = T0C+50
pH = 5.5
+ molarity = 1
+ condensation_amount = MOLES_GAS_VISIBLE_STEP
/datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume)
if(istype(O, /obj/effect/decal/cleanable) || istype(O, /obj/item/projectile/bullet/reusable/foam_dart) || istype(O, /obj/item/ammo_casing/caseless/foam_dart))
@@ -1871,6 +1878,15 @@
reagent_state = LIQUID
taste_description = "solvent"//It's neutral though..?
color = "#e6e6e6"
+ boiling_point = 329.2
+
+/datum/reagent/acetone/define_gas()
+ var/datum/gas/G = ..()
+ G.fire_burn_rate = 1 / 4
+ G.fire_products = list(GAS_H2O = 3, GAS_CO2 = 3)
+ G.enthalpy = -217100
+ G.fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
+ return G
/datum/reagent/colorful_reagent
name = "Colorful Reagent"
@@ -2002,6 +2018,7 @@
reagent_state = LIQUID
color = "#A70FFF"
taste_description = "dryness"
+ boiling_point = 310
pH = 10.7
value = REAGENT_VALUE_UNCOMMON
@@ -2268,6 +2285,7 @@
color = "#AAAAAA55"
taste_description = "water"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
+ boiling_point = 325
value = REAGENT_VALUE_RARE
pH = 15
@@ -2507,6 +2525,8 @@
reagent_state = LIQUID
color = "#FFFFFF" // rgb: 255, 255, 255
can_synth = FALSE
+ // you know i wouldn't
+ // boiling_point = T0C + 100
nutriment_factor = 0.5 * REAGENTS_METABOLISM
var/decal_path = /obj/effect/decal/cleanable/semen
diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm
index 99357d802a..4b0208889c 100644
--- a/code/modules/security_levels/security_levels.dm
+++ b/code/modules/security_levels/security_levels.dm
@@ -14,101 +14,4 @@ GLOBAL_LIST_INIT(all_security_levels, list("green", "blue", "amber", "red", "del
//config.alert_desc_blue_downto
/proc/set_security_level(level)
- if(!isnum(level))
- level = GLOB.all_security_levels.Find(level)
-
- //Will not be announced if you try to set to the same level as it already is
- if(level >= SEC_LEVEL_GREEN && level <= SEC_LEVEL_DELTA && level != GLOB.security_level)
- switch(level)
- if(SEC_LEVEL_GREEN)
- minor_announce(CONFIG_GET(string/alert_green), "Attention! Security level lowered to green:")
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- if(GLOB.security_level >= SEC_LEVEL_RED)
- SSshuttle.emergency.modTimer(4)
- else if(GLOB.security_level == SEC_LEVEL_AMBER)
- SSshuttle.emergency.modTimer(2.5)
- else
- SSshuttle.emergency.modTimer(1.66)
- GLOB.security_level = SEC_LEVEL_GREEN
- for(var/obj/machinery/firealarm/FA in GLOB.machines)
- if(is_station_level(FA.z))
- FA.update_icon()
- if(SEC_LEVEL_BLUE)
- if(GLOB.security_level < SEC_LEVEL_BLUE)
- minor_announce(CONFIG_GET(string/alert_blue_upto), "Attention! Security level elevated to blue:",1)
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- SSshuttle.emergency.modTimer(0.6)
- else
- minor_announce(CONFIG_GET(string/alert_blue_downto), "Attention! Security level lowered to blue:")
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- if(GLOB.security_level >= SEC_LEVEL_RED)
- SSshuttle.emergency.modTimer(2.4)
- else
- SSshuttle.emergency.modTimer(1.5)
- GLOB.security_level = SEC_LEVEL_BLUE
- sound_to_playing_players('sound/misc/voybluealert.ogg', volume = 50) // Citadel change - Makes alerts play a sound
- for(var/obj/machinery/firealarm/FA in GLOB.machines)
- if(is_station_level(FA.z))
- FA.update_icon()
- if(SEC_LEVEL_AMBER)
- if(GLOB.security_level < SEC_LEVEL_AMBER)
- minor_announce(CONFIG_GET(string/alert_amber_upto), "Attention! Security level elevated to amber:",1)
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- if(GLOB.security_level == SEC_LEVEL_GREEN)
- SSshuttle.emergency.modTimer(0.4)
- else
- SSshuttle.emergency.modTimer(0.66)
- else
- minor_announce(CONFIG_GET(string/alert_amber_downto), "Attention! Security level lowered to amber:")
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- SSshuttle.emergency.modTimer(1.6)
- GLOB.security_level = SEC_LEVEL_AMBER
- sound_to_playing_players('sound/effects/alert.ogg', volume = 50) // Citadel change - Makes alerts play a sound
- for(var/obj/machinery/firealarm/FA in GLOB.machines)
- if(is_station_level(FA.z))
- FA.update_icon()
- if(SEC_LEVEL_RED)
- if(GLOB.security_level < SEC_LEVEL_RED)
- minor_announce(CONFIG_GET(string/alert_red_upto), "Attention! Code red!",1)
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- if(GLOB.security_level == SEC_LEVEL_GREEN)
- SSshuttle.emergency.modTimer(0.25)
- else if(GLOB.security_level == SEC_LEVEL_BLUE)
- SSshuttle.emergency.modTimer(0.416)
- else
- SSshuttle.emergency.modTimer(0.625)
- else
- minor_announce(CONFIG_GET(string/alert_red_downto), "Attention! Code red!")
- GLOB.security_level = SEC_LEVEL_RED
- sound_to_playing_players('sound/misc/voyalert.ogg', volume = 50) // Citadel change - Makes alerts play a sound
-
- for(var/obj/machinery/firealarm/FA in GLOB.machines)
- if(is_station_level(FA.z))
- FA.update_icon()
- for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines)
- pod.admin_controlled = FALSE
- if(SEC_LEVEL_DELTA)
- minor_announce(CONFIG_GET(string/alert_delta), "Attention! Delta security level reached!",1)
- if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
- if(GLOB.security_level < SEC_LEVEL_BLUE)
- SSshuttle.emergency.modTimer(0.25)
- else if(GLOB.security_level == SEC_LEVEL_BLUE)
- SSshuttle.emergency.modTimer(0.416)
- else
- SSshuttle.emergency.modTimer(0.625)
- GLOB.security_level = SEC_LEVEL_DELTA
- sound_to_playing_players('sound/misc/deltakalaxon.ogg') // Citadel change - Makes alerts play a sound
- for(var/obj/machinery/firealarm/FA in GLOB.machines)
- if(is_station_level(FA.z))
- FA.update_icon()
- for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines)
- pod.admin_controlled = FALSE
- if(level >= SEC_LEVEL_RED)
- for(var/obj/machinery/door/D in GLOB.machines)
- if(D.red_alert_access)
- D.visible_message("[D] whirrs as it automatically lifts access requirements!")
- playsound(D, 'sound/machines/boltsup.ogg', 50, TRUE)
- SSblackbox.record_feedback("tally", "security_level_changes", 1, NUM2SECLEVEL(GLOB.security_level))
- SSnightshift.check_nightshift()
- else
- return
+ SSsecurity_level.set_level(level)
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index d4e6f3e050..d87e34f4a7 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -538,6 +538,10 @@
density = FALSE
clockwork = TRUE //it'd look weird
+/obj/machinery/computer/shuttle/pod/Initialize(mapload)
+ . = ..()
+ RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, .proc/check_lock)
+
/obj/machinery/computer/shuttle/pod/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_blocker)
@@ -555,6 +559,21 @@
if(possible_destinations == initial(possible_destinations) || override)
possible_destinations = "pod_lavaland[idnum]"
+/**
+ * Signal handler for checking if we should lock or unlock escape pods accordingly to a newly set security level
+ *
+ * Arguments:
+ * * source The datum source of the signal
+ * * new_level The new security level that is in effect
+ */
+/obj/machinery/computer/shuttle/pod/proc/check_lock(datum/source, new_level)
+ SIGNAL_HANDLER
+
+ if(obj_flags & EMAGGED)
+ return
+
+ admin_controlled = !(new_level < SEC_LEVEL_RED)
+
/obj/docking_port/stationary/random
name = "escape pod"
id = "pod"
diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm
index 61e75e3179..fb18d6d155 100644
--- a/code/modules/surgery/organ_manipulation.dm
+++ b/code/modules/surgery/organ_manipulation.dm
@@ -118,7 +118,7 @@
O.on_find(user)
organs -= O
organs[O.name] = O
- I = show_radial_menu(user, target, organs, custom_check = FALSE, require_near = TRUE, tooltips = TRUE)
+ I = show_radial_menu(user, target, organs, require_near = TRUE, tooltips = TRUE)
if(I && user && target && user.Adjacent(target) && user.get_active_held_item() == tool)
I = organs[I]
if(!I)
diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm
index 4161ed1f70..b193e5917a 100644
--- a/code/modules/surgery/tools.dm
+++ b/code/modules/surgery/tools.dm
@@ -3,6 +3,8 @@
desc = "Retracts stuff."
icon = 'icons/obj/surgery.dmi'
icon_state = "retractor"
+ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
custom_materials = list(/datum/material/iron=6000, /datum/material/glass=3000)
item_flags = SURGICAL_TOOL
flags_1 = CONDUCT_1
@@ -19,7 +21,6 @@
/obj/item/retractor/advanced
name = "mechanical pinches"
desc = "An agglomerate of rods and gears."
- icon = 'icons/obj/surgery.dmi'
icon_state = "retractor_a"
toolspeed = 0.7
@@ -41,8 +42,6 @@
/obj/item/retractor/augment
name = "retractor"
desc = "Micro-mechanical manipulator for retracting stuff."
- icon = 'icons/obj/surgery.dmi'
- icon_state = "retractor"
custom_materials = list(/datum/material/iron=6000, /datum/material/glass=3000)
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_TINY
@@ -60,6 +59,8 @@
desc = "You think you have seen this before."
icon = 'icons/obj/surgery.dmi'
icon_state = "hemostat"
+ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
custom_materials = list(/datum/material/iron=5000, /datum/material/glass=2500)
item_flags = SURGICAL_TOOL
flags_1 = CONDUCT_1
@@ -77,8 +78,6 @@
/obj/item/hemostat/augment
name = "hemostat"
desc = "Tiny servos power a pair of pincers to stop bleeding."
- icon = 'icons/obj/surgery.dmi'
- icon_state = "hemostat"
custom_materials = list(/datum/material/iron=5000, /datum/material/glass=2500)
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_TINY
@@ -98,6 +97,8 @@
desc = "This stops bleeding."
icon = 'icons/obj/surgery.dmi'
icon_state = "cautery"
+ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
custom_materials = list(/datum/material/iron=2500, /datum/material/glass=750)
item_flags = SURGICAL_TOOL
flags_1 = CONDUCT_1
@@ -105,6 +106,7 @@
attack_verb = list("burnt")
tool_behaviour = TOOL_CAUTERY
toolspeed = 1
+ heat = 3500
/obj/item/cautery/attack(mob/living/L, mob/user)
if(user.a_intent == INTENT_HELP)
@@ -115,8 +117,6 @@
/obj/item/cautery/augment
name = "cautery"
desc = "A heated element that cauterizes wounds."
- icon = 'icons/obj/surgery.dmi'
- icon_state = "cautery"
custom_materials = list(/datum/material/iron=2500, /datum/material/glass=750)
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_TINY
@@ -135,8 +135,8 @@
desc = "You can drill using this item. You dig?"
icon = 'icons/obj/surgery.dmi'
icon_state = "drill"
- lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
+ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
hitsound = 'sound/weapons/circsawhit.ogg'
custom_materials = list(/datum/material/iron=10000, /datum/material/glass=6000)
item_flags = SURGICAL_TOOL
@@ -156,9 +156,9 @@
/obj/item/surgicaldrill/advanced
name = "searing tool"
desc = "It projects a high power laser used for medical application."
- icon = 'icons/obj/surgery.dmi'
icon_state = "surgicaldrill_a"
hitsound = 'sound/items/welder.ogg'
+ heat = 3500
/obj/item/surgicaldrill/advanced/Initialize(mapload)
. = ..()
@@ -182,8 +182,6 @@
/obj/item/surgicaldrill/augment
name = "surgical drill"
desc = "Effectively a small power drill contained within your arm, edges dulled to prevent tissue damage. May or may not pierce the heavens."
- icon = 'icons/obj/surgery.dmi'
- icon_state = "drill"
hitsound = 'sound/weapons/circsawhit.ogg'
custom_materials = list(/datum/material/iron=10000, /datum/material/glass=6000)
flags_1 = CONDUCT_1
@@ -227,13 +225,13 @@
/obj/item/scalpel/advanced
name = "laser scalpel"
desc = "An advanced scalpel which uses laser technology to cut."
- icon = 'icons/obj/surgery.dmi'
icon_state = "scalpel_a"
hitsound = 'sound/weapons/blade1.ogg'
force = 16
toolspeed = 0.7
- light_color = LIGHT_COLOR_GREEN
+ light_color = LIGHT_COLOR_BLUE
sharpness = SHARP_POINTY
+ heat = 3500
/obj/item/scalpel/advanced/Initialize(mapload)
. = ..()
@@ -261,8 +259,6 @@
/obj/item/scalpel/augment
name = "scalpel"
desc = "Ultra-sharp blade attached directly to your bone for extra-accuracy."
- icon = 'icons/obj/surgery.dmi'
- icon_state = "scalpel"
flags_1 = CONDUCT_1
force = 10
w_class = WEIGHT_CLASS_TINY
@@ -324,8 +320,6 @@
/obj/item/circular_saw/augment
name = "circular saw"
desc = "A small but very fast spinning saw. Edges dulled to prevent accidental cutting inside of the surgeon."
- icon = 'icons/obj/surgery.dmi'
- icon_state = "saw"
hitsound = 'sound/weapons/circsawhit.ogg'
mob_throw_hit_sound = 'sound/weapons/pierce.ogg'
flags_1 = CONDUCT_1
@@ -462,7 +456,7 @@
name = "bonesetter"
desc = "For setting things right."
icon = 'icons/obj/surgery.dmi'
- icon_state = "bone setter"
+ icon_state = "bonesetter"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
custom_materials = list(/datum/material/iron=5000, /datum/material/glass=2500)
diff --git a/config/config.txt b/config/config.txt
index 8bef06f4dd..8db6b1f725 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -42,6 +42,7 @@ $include entries/vote.txt
$include plushies/defines.txt
# Special Sandstorm configs
$include sandstorm/config.txt
+
# Special SPLURT configs
$include splurt/fetish_content.txt
$include splurt/discord.txt
@@ -49,3 +50,5 @@ $include splurt/general.txt
$include splurt/comms.txt
$include splurt/maps.txt
$include splurt/server.txt
+$include splurt/connections.txt
+$include splurt/donator.txt
diff --git a/config/splurt/connections.txt b/config/splurt/connections.txt
new file mode 100644
index 0000000000..e9036bd515
--- /dev/null
+++ b/config/splurt/connections.txt
@@ -0,0 +1,15 @@
+# Need discord account to join
+## Uncomment to make players need to link their discord accounts to ckeys in order to join the game_mode ##
+## The discord verification system makes use of https://github.com/optimumtact/orangescogs ##
+## Needs a working database with the station's current schema ##
+#NEED_DISCORD_TO_JOIN
+
+# Uncomment to kick players who are probably trying to connect using a vpn
+# Keep in mind this depends on your ipintel configuration and can potentially kick players not actually using a vpn
+#KICK_VPN
+
+# VPN bypass ckeys
+## Use these if you activate the option above but have some people that for one reason or another should be allowed to bypass it ##
+#VPN_BYPASS test_ckey1
+#VPN_BYPASS test_ckey2
+#VPN_BYPASS test_ckey3
diff --git a/config/splurt/donator.toml b/config/splurt/donator.toml
new file mode 100644
index 0000000000..373c60d583
--- /dev/null
+++ b/config/splurt/donator.toml
@@ -0,0 +1,4 @@
+[donators]
+tier_1 = []
+tier_2 = []
+tier_3 = []
diff --git a/config/splurt/donator.txt b/config/splurt/donator.txt
new file mode 100644
index 0000000000..57c06ba848
--- /dev/null
+++ b/config/splurt/donator.txt
@@ -0,0 +1,6 @@
+# New donator system mode
+## Mode in which donator info added in donator.toml will be handled ##
+## 0 legacy donator system ##
+## 1 add the information from both systems ##
+## 2 only use info from the new system ##
+TOML_DONATORS_MODE 0
diff --git a/config/splurt/general.txt b/config/splurt/general.txt
index 9ba4dc93b5..a9f9883d44 100644
--- a/config/splurt/general.txt
+++ b/config/splurt/general.txt
@@ -1,9 +1,3 @@
-# Need discord account to join
-## Uncomment to make players need to link their discord accounts to ckeys in order to join the game_mode ##
-## The discord verification system makes use of https://github.com/optimumtact/orangescogs ##
-## Needs a working database with the station's current schema ##
-#NEED_DISCORD_TO_JOIN
-
# Enable global barks
# Uncomment this to allow player's speech barks #
ENABLE_GLOBAL_BARKS
diff --git a/html/changelogs/archive/2022-08.yml b/html/changelogs/archive/2022-08.yml
index e4a6a8423a..4b1a6225ee 100644
--- a/html/changelogs/archive/2022-08.yml
+++ b/html/changelogs/archive/2022-08.yml
@@ -85,3 +85,118 @@
- code_imp: changes our modular sprite accessory paths to avoid nulls and bugs in
the character creation
- code_imp: Fixes a typo in our modular file for underwear
+2022-08-16:
+ BongaTheProto:
+ - soundadd: Makes the pain of hitting someone with buns of steel in the ass more
+ hearable (?
+ - code_imp: deletes some unused interaction code
+ Putnam3145:
+ - bugfix: added a missing signal call to SSticker
+ TripleShades:
+ - rscadd: '[Omega] Cleanbot named "Rustbucket" to the Bridge'
+ - rscadd: '[Omega] Securitron "Pingsky" to AI Sat'
+ - rscadd: '[Omega] External AI Sat cams around the south'
+ - rscadd: '[Omega] Unfinished cleanbot to Robotics'
+ - rscadd: '[Omega] More status displays and AI displays'
+ - rscadd: '[Omega] Captain''s Wardrobe vendor'
+ - rscadd: '[Omega] Engineering Supermatter Room now has a YouTool'
+ - rscadd: '[Omega] Hydroponics front desk now has windoors'
+ - rscadd: '[Omega] Bar monkey Punpun placed at the Bar'
+ - rscadd: '[Omega] Paramedical room'
+ - rscadd: '[Omega] Scrubbers to Xenobiology slime pens'
+ - rscadd: '[Omega] Xenobiology now has one canister of BZ'
+ - rscdel: '[Omega] Tiny Medbay reception desk'
+ - rscdel: '[Omega] Overlapping cams and window-sitting cams'
+ - rscdel: '[Omega] Defibrillator outside of Medbay Surgery'
+ - rscdel: '[Omega] Rogue isolated power wire under East Maintenence Airlock'
+ - tweak: '[Omega] Virology now has a cycling airlock'
+ - tweak: '[Omega] Xenobiology slime pen floors and kill room floor now match other
+ stations'
+ - tweak: '[Omega] Xenobiology main scrubber and vent shifted around'
+ - tweak: '[Omega] Medbay intercoms are now largely on the unique frequency other
+ stations use'
+ - tweak: '[Omega] Certain floors under airlocks now properly match their surroundings'
+ - tweak: '[Omega] Atmospherics now has layer adaptors'
+ - tweak: '[Omega] Cargo''s starting crates are shifted around to better show which
+ belt goes to the shuttle'
+ - tweak: '[Omega] Engineering Secure Storage button is now in Chief Engineer''s
+ office'
+ WoolyAypa:
+ - rscadd: 'Added a new hairstyle: Emma'
+ - rscadd: 'Added a new hairstyle: Damsel'
+ - rscadd: 'Added a new hairstyle: Ozen'
+ - rscadd: 'Added a new tail: Dragon Western'
+ - rscadd: 'Added a new tail: Succubus Tail'
+ - rscadd: 'Added a new horn: Succ Horns'
+ - rscadd: 'Added a new wing: Harpy (Large)'
+ - tweak: The decorative angel wings can now be coloured
+ Yawet330:
+ - imageadd: Better wings
+2022-08-19:
+ BlueWildrose:
+ - balance: Removes persistence from the cleanable glowing goo. It'll no longer last
+ between rounds.
+ BongaTheProto:
+ - server: Adds the option to kick players who are likely connecting through a vpn
+ on join
+ - code_imp: reorganizes modular config code just a bit
+ SpookyTheFox:
+ - bugfix: fixed non-lethal magrifle ammo magazine name
+ TripleShades:
+ - rscadd: '[Omega] One decal to better indicate Turbine area'
+ - rscdel: '[Omega] Duplicate leftover intercom'
+ - bugfix: '[Omega] Virology Airlock access buttons should actually work'
+2022-08-20:
+ BongaTheProto:
+ - code_imp: Updates rust_g to 1.0.2
+ - qol: Upgrades our donator system to support automatic updates! Making sure all
+ donators always have at least the loadout tiers perk
+ Hatterhat:
+ - tweak: Chief engineers now have expert wiring skills, as befitting a crew member
+ of their assumed caliber. Atmos techs also get more wire skill.
+ - tweak: Research directors now have trained wiring skills, and scientists have
+ basic wiring expertise.
+ - rscadd: 'Cleaving saws now have a Certified FromSoft Classic mechanic: dodge-rolling.
+ Combat mode RMB with it inhand to use.'
+ Linzolle:
+ - rscadd: radial menu to organ manipulation surgery
+ Onule, PositiveEntropy, TetraZeta, Axietheaxolotl, Thgvr, AdipemDragon:
+ - imageadd: Completely resprites all medkits!
+ - imageadd: Completely resprites all medical tools!
+ - imageadd: Removes the clamp sprite and instead creates separate hemostat and retractor
+ inhand sprites!
+ - imageadd: Adds missing inhands for the bonesetter, advanced med tools, tactical
+ medkit, surgical drill and bone gel!
+ Putnam3145:
+ - bugfix: Stake (maybe)
+ - bugfix: Caches the auxmos file if found
+ - balance: Sandstorm now happens less often, tends to be less powerful and is announced.
+ - bugfix: update air ref more aggressively
+ - bugfix: Binary translator key now has a proper description
+ - rscadd: Space lube, drying agent, salbutamol, colorful reagent, drying agent chem
+ gases
+ - bugfix: Signal commander works now
+ - tweak: Infinite blood trails are no longer possible
+ Rohesie:
+ - tweak: Admins and byond users can now set their OOC color to light values and
+ it will save in the preferences.
+ zeroisthebiggay:
+ - tweak: cauteries searing tools and energy scalpels now have heat and can be used
+ to light cigarettes
+ - imageadd: crushers
+ - imageadd: glaives
+ - imageadd: drills
+ - imageadd: mining scammers
+ - imageadd: my mom
+ - imageadd: new ninja sprites
+ - imageadd: makes the long gloves look more like their normal counterparts
+ - imageadd: mauler gauntlets have lost a grand total of three pixels in order to
+ make them slimmer
+2022-08-22:
+ Anonymous:
+ - soundadd: Added weh2, weh3 and weh-s.
+ BongaTheProto:
+ - server: adds a bypass list for the VPN blocker
+ - admin: adds verbs to toggle the VPN blocker and also add people to the bypass
+ list for a round
+ - spellcheck: Fixes some typos in the discordbunker verbs
diff --git a/icons/mob/clothing/feet.dmi b/icons/mob/clothing/feet.dmi
index 9ca0762ca4..3360521b51 100644
Binary files a/icons/mob/clothing/feet.dmi and b/icons/mob/clothing/feet.dmi differ
diff --git a/icons/mob/clothing/feet_digi.dmi b/icons/mob/clothing/feet_digi.dmi
index e82ae468e2..82d4856d38 100644
Binary files a/icons/mob/clothing/feet_digi.dmi and b/icons/mob/clothing/feet_digi.dmi differ
diff --git a/icons/mob/clothing/hands.dmi b/icons/mob/clothing/hands.dmi
index 9bd206e04e..1d4a76e519 100644
Binary files a/icons/mob/clothing/hands.dmi and b/icons/mob/clothing/hands.dmi differ
diff --git a/icons/mob/clothing/suit.dmi b/icons/mob/clothing/suit.dmi
index e99623dfc6..ca3aa9be73 100644
Binary files a/icons/mob/clothing/suit.dmi and b/icons/mob/clothing/suit.dmi differ
diff --git a/icons/mob/inhands/equipment/medical_lefthand.dmi b/icons/mob/inhands/equipment/medical_lefthand.dmi
index 679b6c1159..38f2a00525 100644
Binary files a/icons/mob/inhands/equipment/medical_lefthand.dmi and b/icons/mob/inhands/equipment/medical_lefthand.dmi differ
diff --git a/icons/mob/inhands/equipment/medical_righthand.dmi b/icons/mob/inhands/equipment/medical_righthand.dmi
index a8f4580881..829735f11f 100644
Binary files a/icons/mob/inhands/equipment/medical_righthand.dmi and b/icons/mob/inhands/equipment/medical_righthand.dmi differ
diff --git a/icons/mob/inhands/equipment/mining_lefthand.dmi b/icons/mob/inhands/equipment/mining_lefthand.dmi
index 7496aba625..c3519482a7 100644
Binary files a/icons/mob/inhands/equipment/mining_lefthand.dmi and b/icons/mob/inhands/equipment/mining_lefthand.dmi differ
diff --git a/icons/mob/inhands/equipment/mining_righthand.dmi b/icons/mob/inhands/equipment/mining_righthand.dmi
index de3d11978a..dc605cd2a0 100644
Binary files a/icons/mob/inhands/equipment/mining_righthand.dmi and b/icons/mob/inhands/equipment/mining_righthand.dmi differ
diff --git a/icons/mob/inhands/weapons/bombs_lefthand.dmi b/icons/mob/inhands/weapons/bombs_lefthand.dmi
index 4772c01a22..123f4f3a7d 100644
Binary files a/icons/mob/inhands/weapons/bombs_lefthand.dmi and b/icons/mob/inhands/weapons/bombs_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/bombs_righthand.dmi b/icons/mob/inhands/weapons/bombs_righthand.dmi
index 9046e788d2..b4e3d17ada 100644
Binary files a/icons/mob/inhands/weapons/bombs_righthand.dmi and b/icons/mob/inhands/weapons/bombs_righthand.dmi differ
diff --git a/icons/mob/inhands/weapons/guns_lefthand.dmi b/icons/mob/inhands/weapons/guns_lefthand.dmi
index ca742c9c7f..a8ca244865 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 a277b29993..d1019fa3d1 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/inhands/weapons/hammers_lefthand.dmi b/icons/mob/inhands/weapons/hammers_lefthand.dmi
index cb3ecd4e99..d32402e371 100644
Binary files a/icons/mob/inhands/weapons/hammers_lefthand.dmi and b/icons/mob/inhands/weapons/hammers_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/hammers_righthand.dmi b/icons/mob/inhands/weapons/hammers_righthand.dmi
index f3d9ca52b7..402ac32126 100644
Binary files a/icons/mob/inhands/weapons/hammers_righthand.dmi and b/icons/mob/inhands/weapons/hammers_righthand.dmi differ
diff --git a/icons/mob/wings.dmi b/icons/mob/wings.dmi
index 45a0cdc307..278dd724dc 100644
Binary files a/icons/mob/wings.dmi and b/icons/mob/wings.dmi differ
diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi
index 17073805c9..70c48c52da 100644
Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index 25c93428a4..6e8ea50d39 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi
index b86731babd..70121cb9dc 100644
Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ
diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi
index d1e422eb6b..50de425aad 100644
Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index a6e5e1f037..a5ae3dcf40 100644
Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 4d2cc4f730..838da754a9 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/grenade.dmi b/icons/obj/grenade.dmi
index e2f06621e4..7fc2eaae7f 100644
Binary files a/icons/obj/grenade.dmi and b/icons/obj/grenade.dmi differ
diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi
index bc887e707d..3e57f4eca4 100644
Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ
diff --git a/icons/obj/mining.dmi b/icons/obj/mining.dmi
index e03f6e9b97..9ad3c2578e 100644
Binary files a/icons/obj/mining.dmi and b/icons/obj/mining.dmi differ
diff --git a/icons/obj/nuke_tools.dmi b/icons/obj/nuke_tools.dmi
index 7f5c730fe5..eb724e29be 100644
Binary files a/icons/obj/nuke_tools.dmi and b/icons/obj/nuke_tools.dmi differ
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index 96340cc883..d5cacfa83a 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ
diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi
index 0f1ec3712d..fbd6cecc56 100755
Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ
diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi
index 3515545514..cea955ac64 100644
Binary files a/icons/obj/syringe.dmi and b/icons/obj/syringe.dmi differ
diff --git a/modular_sand/code/game/machinery/cryptominers.dm b/modular_sand/code/game/machinery/cryptominers.dm
index e1c51fd11f..df17cf0c25 100644
--- a/modular_sand/code/game/machinery/cryptominers.dm
+++ b/modular_sand/code/game/machinery/cryptominers.dm
@@ -56,8 +56,8 @@
to_chat(user, "ERROR: No bank account found.")
return
to_chat(user, "You link \the [CARD] to \the [src].")
- say("Now using [pay_me.account_holder ? "[pay_me.account_holder]'s" : "ERROR"] account.")
pay_me = CARD.registered_account
+ say("Now using [pay_me.account_holder ? "[pay_me.account_holder]'s" : "ERROR"] account.")
return
/obj/machinery/cryptominer/AltClick(mob/user)
diff --git a/modular_splurt/code/controllers/configuration/entries/splurt_connections.dm b/modular_splurt/code/controllers/configuration/entries/splurt_connections.dm
new file mode 100644
index 0000000000..5f713e7e9d
--- /dev/null
+++ b/modular_splurt/code/controllers/configuration/entries/splurt_connections.dm
@@ -0,0 +1,23 @@
+/datum/config_entry/flag/need_discord_to_join
+
+/datum/config_entry/flag/kick_vpn
+
+/datum/config_entry/multi_keyed_flag/vpn_bypass
+ postload_required = TRUE
+
+/datum/config_entry/multi_keyed_flag/vpn_bypass/OnPostload()
+ var/list/new_entries = list()
+ for(var/key in config_entry_value)
+ new_entries[ckey(key)] = world.realtime
+ config_entry_value = new_entries
+
+/datum/config_entry/multi_keyed_flag/vpn_bypass/proc/add_bypass(ckeytobypass)
+ if(IsAdminAdvancedProcCall())
+ return
+ config_entry_value |= ckey(ckeytobypass)
+ config_entry_value[ckey(ckeytobypass)] = world.realtime
+
+/datum/config_entry/multi_keyed_flag/vpn_bypass/proc/rev_bypass(ckeytobypass)
+ if(IsAdminAdvancedProcCall())
+ return
+ config_entry_value -= ckey(ckeytobypass)
diff --git a/modular_splurt/code/controllers/configuration/entries/splurt_donator.dm b/modular_splurt/code/controllers/configuration/entries/splurt_donator.dm
new file mode 100644
index 0000000000..2b3fcac47d
--- /dev/null
+++ b/modular_splurt/code/controllers/configuration/entries/splurt_donator.dm
@@ -0,0 +1,53 @@
+#define DONATOR_TOML_FILE "config/splurt/donator.toml"
+
+// New donator system
+// Reminder that you must setup autodonator and ckeytools on
+// a discord redbot on your guild for this to work
+// https://github.com/SPLURT-Station/Mal0-cogs
+
+/datum/config_entry/number/toml_donators_mode
+ postload_required = TRUE
+
+/datum/config_entry/number/toml_donators_mode/OnPostload()
+ if(config_entry_value != 1 && config_entry_value != 2)
+ return ..()
+
+ var/list/donators = rustg_read_toml_file(DONATOR_TOML_FILE)
+ if(!donators)
+ CRASH("Attempted to read donator file, but none was found!")
+
+ for(var/tier in subtypesof(/datum/config_entry/multi_keyed_flag/donator_group))
+ var/datum/config_entry/multi_keyed_flag/donator_group/group = CONFIG_GET_ENTRY_FROM_PATH(tier)
+ group.load_new_donators(donators, config_entry_value)
+
+ regenerate_donator_grouping_list()
+
+ . = ..()
+
+/datum/config_entry/multi_keyed_flag/donator_group
+ var/toml_tier
+
+/datum/config_entry/multi_keyed_flag/donator_group/proc/load_new_donators(list/donators, mode)
+ if(IsAdminAdvancedProcCall() || !toml_tier)
+ return
+ switch(mode)
+ if(1)
+ LAZYADD(config_entry_value, donators["donators"][toml_tier])
+ if(2)
+ config_entry_value = donators["donators"][toml_tier]
+ else
+ return
+ for(var/ckey in config_entry_value)
+ if(isnull(config_entry_value[ckey]))
+ config_entry_value[ckey] = TRUE
+
+/datum/config_entry/multi_keyed_flag/donator_group/tier_1_donators
+ toml_tier = "tier_1"
+
+/datum/config_entry/multi_keyed_flag/donator_group/tier_2_donators
+ toml_tier = "tier_2"
+
+/datum/config_entry/multi_keyed_flag/donator_group/tier_3_donators
+ toml_tier = "tier_3"
+
+#undef DONATOR_TOML_FILE
diff --git a/modular_splurt/code/controllers/configuration/entries/splurt_general.dm b/modular_splurt/code/controllers/configuration/entries/splurt_general.dm
index c4e26c6d0a..24f93f3f8c 100644
--- a/modular_splurt/code/controllers/configuration/entries/splurt_general.dm
+++ b/modular_splurt/code/controllers/configuration/entries/splurt_general.dm
@@ -1,5 +1,3 @@
-/datum/config_entry/flag/need_discord_to_join
-
/datum/config_entry/flag/enable_global_barks
/datum/config_entry/number/max_infinidorms
diff --git a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/_lewd.dm b/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/_lewd.dm
deleted file mode 100644
index 54ed0324b4..0000000000
--- a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/_lewd.dm
+++ /dev/null
@@ -1,1774 +0,0 @@
-#define CUM_TARGET_MOUTH "mouth"
-#define CUM_TARGET_THROAT "throat"
-#define CUM_TARGET_VAGINA "vagina"
-#define CUM_TARGET_ANUS "anus"
-#define CUM_TARGET_HAND "hand"
-#define CUM_TARGET_BREASTS "breasts"
-#define CUM_TARGET_FEET "feet"
-#define CUM_TARGET_PENIS "penis"
-//Weird defines go here
-#define CUM_TARGET_EARS "ears"
-#define CUM_TARGET_EYES "eyes"
-//
-#define GRINDING_FACE_WITH_ANUS "faceanus"
-#define GRINDING_FACE_WITH_FEET "facefeet"
-#define GRINDING_MOUTH_WITH_FEET "mouthfeet"
-#define THIGH_SMOTHERING "thigh_smother"
-#define NUTS_TO_FACE "nut_face"
-
-#define NORMAL_LUST 10
-#define LOW_LUST 1
-
-#define REQUIRE_NONE 0
-#define REQUIRE_EXPOSED 1
-#define REQUIRE_UNEXPOSED 2
-#define REQUIRE_ANY 3
-
-/*--------------------------------------------------
--------------------MOB STUFF----------------------
---------------------------------------------------
-*/
-//I'm sorry, lewd should not have mob procs such as life() and such in it. //NO SHIT IT SHOULDNT I REMOVED THEM
-
-// Lewd interactions have a blacklist for certain mobs. When we evalute the user and target, both of
-// their requirements must be satisfied, and the mob must not be of a blacklisted type.
-// This should not be too weighty on the server, as the check is only run to generate the menu options.
-/datum/interaction/lewd/evaluate_user(mob/living/user, silent, action_check)
- . = ..()
- if(.)
- if((user.stat == DEAD))
- return FALSE
- for(var/check in blacklisted_mobs)
- if(istype(user, check))
- return FALSE
-
-/datum/interaction/lewd/evaluate_target(mob/living/user, mob/living/target, silent = TRUE)
- . = ..()
- if(.)
- if((target.stat == DEAD))
- return FALSE
- for(var/check in blacklisted_mobs)
- if(istype(target, check))
- return FALSE
-
-/proc/playlewdinteractionsound(turf/turf_source, soundin, vol as num, vary, extrarange as num, frequency, falloff, channel = 0, pressure_affected = TRUE, sound/S, envwet = -10000, envdry = 0, manual_x, manual_y, list/ignored_mobs)
- var/list/hearing_mobs
- for(var/mob/H in get_hearers_in_view(4, turf_source))
- if(!H.client || (H.client.prefs.toggles & LEWD_VERB_SOUNDS))
- continue
- LAZYADD(hearing_mobs, H)
- if(ignored_mobs?.len)
- LAZYREMOVE(hearing_mobs, ignored_mobs)
- for(var/mob/H in hearing_mobs)
- H.playsound_local(turf_source, soundin, vol, vary, frequency, falloff)
-
-/mob/living
- var/has_penis = FALSE
- var/has_balls = FALSE
- var/has_vagina = FALSE
- var/has_anus = TRUE
- var/has_breasts = FALSE
- var/has_butt = FALSE
- var/anus_exposed = FALSE
- var/last_partner
- var/last_orifice
- var/obj/item/organ/last_genital
- var/lastmoan
- var/sexual_potency = 15
- var/lust_tolerance = 100
- var/lastlusttime = 0
- var/lust = 0
- var/multiorgasms = 1
- var/refractory_period = 0
- var/last_interaction_time = 0
- var/datum/interaction/lewd/last_lewd_datum //Recording our last lewd datum allows us to do stuff like custom cum messages.
- //Yes i feel like an idiot writing this.
- var/cleartimer //Timer for clearing the "last_lewd_datum". This prevents some oddities.
-
-/mob/living/proc/clear_lewd_datum()
- last_lewd_datum = null
- last_genital = null
-
-/mob/living/Initialize()
- . = ..()
- sexual_potency =rand(10,25)
- lust_tolerance = rand(75,200)
-
-/mob/living/proc/get_lust_tolerance()
- . = lust_tolerance
- if(has_dna())
- var/mob/living/carbon/user = src
- if(user.dna.features["lust_tolerance"])
- . = user.dna.features["lust_tolerance"]
-
-/mob/living/proc/get_sexual_potency()
- . = sexual_potency
- if(has_dna())
- var/mob/living/carbon/user = src
- if(user.dna.features["sexual_potency"])
- . = user.dna.features["sexual_potency"]
-
-/mob/living/proc/get_refraction_dif()
- var/dif = (refractory_period - world.time)
- if(dif < 0)
- return 0
- else
- return dif
-
-/mob/living/proc/add_lust(add)
- var/cur = get_lust() //GetLust handles per-time lust loss
- if((cur + add) < 0) //in case we retract lust
- lust = 0
- else
- lust = cur + add
-
-
-/mob/living/proc/get_lust()
- var/curtime = world.time
- var/dif = (curtime - lastlusttime) / 10 //how much lust would we lose over time
- if((lust - dif) < 0)
- lust = 0
- else
- lust = lust - dif
-
- lastlusttime = world.time
- return lust
-
-/mob/living/proc/set_lust(num)
- lust = num
- lastlusttime = world.time
-
-/mob/living/proc/has_penis(var/nintendo = REQUIRE_ANY)
- var/mob/living/carbon/C = src
- if(has_penis && !istype(C))
- return TRUE
- if(istype(C))
- var/obj/item/organ/genital/peepee = C.getorganslot(ORGAN_SLOT_PENIS)
- if(peepee)
- switch(nintendo)
- if(REQUIRE_ANY)
- return TRUE
- if(REQUIRE_EXPOSED)
- if(peepee.is_exposed())
- return TRUE
- else
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!peepee.is_exposed())
- return TRUE
- else
- return FALSE
- else
- return TRUE
- return FALSE
-
-/mob/living/proc/has_balls(var/nintendo = REQUIRE_ANY)
- var/mob/living/carbon/C = src
- if(has_balls && !istype(C))
- return TRUE
- if(istype(C))
- var/obj/item/organ/genital/peepee = C.getorganslot(ORGAN_SLOT_TESTICLES)
- if(peepee)
- switch(nintendo)
- if(REQUIRE_ANY)
- return TRUE
- if(REQUIRE_EXPOSED)
- if(peepee.is_exposed())
- return TRUE
- else
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!peepee.is_exposed())
- return TRUE
- else
- return FALSE
- else
- return TRUE
- return FALSE
-
-/mob/living/proc/has_vagina(var/nintendo = REQUIRE_ANY)
- var/mob/living/carbon/C = src
- if(has_vagina && !istype(C))
- return TRUE
- if(istype(C))
- var/obj/item/organ/genital/peepee = C.getorganslot(ORGAN_SLOT_VAGINA)
- if(peepee)
- switch(nintendo)
- if(REQUIRE_ANY)
- return TRUE
- if(REQUIRE_EXPOSED)
- if(peepee.is_exposed())
- return TRUE
- else
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!peepee.is_exposed())
- return TRUE
- else
- return FALSE
- else
- return TRUE
- return FALSE
-
-/mob/living/proc/has_breasts(var/nintendo = REQUIRE_ANY)
- var/mob/living/carbon/C = src
- if(has_breasts && !istype(C))
- return TRUE
- if(istype(C))
- var/obj/item/organ/genital/peepee = C.getorganslot(ORGAN_SLOT_BREASTS)
- if(peepee)
- switch(nintendo)
- if(REQUIRE_ANY)
- return TRUE
- if(REQUIRE_EXPOSED)
- if(peepee.is_exposed())
- return TRUE
- else
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!peepee.is_exposed())
- return TRUE
- else
- return FALSE
- else
- return TRUE
- return FALSE
-
-/mob/living/proc/has_anus(var/nintendo = REQUIRE_ANY)
- if(has_anus && !iscarbon(src))
- return TRUE
- switch(nintendo)
- if(REQUIRE_ANY)
- return TRUE
- if(REQUIRE_EXPOSED)
- switch(anus_exposed)
- if(-1)
- return FALSE
- if(1)
- return TRUE
- else
- if(is_bottomless())
- return TRUE
- else
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(anus_exposed == -1)
- if(!anus_exposed)
- if(!is_bottomless())
- return TRUE
- else
- return FALSE
- else
- return FALSE
- else
- return TRUE
- else
- return TRUE
-
-/mob/living/proc/has_hand(var/nintendo = REQUIRE_ANY)
- if(iscarbon(src))
- var/mob/living/carbon/C = src
- var/handcount = 0
- var/covered = 0
- var/iscovered = FALSE
- for(var/obj/item/bodypart/l_arm/L in C.bodyparts)
- handcount++
- for(var/obj/item/bodypart/r_arm/R in C.bodyparts)
- handcount++
- if(C.get_item_by_slot(ITEM_SLOT_HANDS))
- var/obj/item/clothing/gloves/G = C.get_item_by_slot(ITEM_SLOT_HANDS)
- covered = G.body_parts_covered
- if(covered & HANDS)
- iscovered = TRUE
- switch(nintendo)
- if(REQUIRE_ANY)
- return handcount
- if(REQUIRE_EXPOSED)
- if(iscovered)
- return FALSE
- else
- return handcount
- if(REQUIRE_UNEXPOSED)
- if(!iscovered)
- return FALSE
- else
- return handcount
- else
- return handcount
- return FALSE
-
-/mob/living/proc/has_feet(var/nintendo = REQUIRE_ANY)
- if(iscarbon(src))
- var/mob/living/carbon/C = src
- var/feetcount = 0
- var/covered = 0
- var/iscovered = FALSE
- for(var/obj/item/bodypart/l_leg/L in C.bodyparts)
- feetcount++
- for(var/obj/item/bodypart/r_leg/R in C.bodyparts)
- feetcount++
- if(!C.is_barefoot())
- covered = TRUE
- if(covered)
- iscovered = TRUE
- switch(nintendo)
- if(REQUIRE_ANY)
- return feetcount
- if(REQUIRE_EXPOSED)
- if(iscovered)
- return FALSE
- else
- return feetcount
- if(REQUIRE_UNEXPOSED)
- if(!iscovered)
- return FALSE
- else
- return feetcount
- else
- return feetcount
- return FALSE
-
-/mob/living/proc/get_num_feet()
- return has_feet(REQUIRE_ANY)
-
-//weird procs go here
-/mob/living/proc/has_ears(var/nintendo = REQUIRE_ANY)
- var/mob/living/carbon/C = src
- if(istype(C))
- var/obj/item/organ/peepee = C.getorganslot(ORGAN_SLOT_EARS)
- if(peepee)
- switch(nintendo)
- if(REQUIRE_ANY)
- return TRUE
- if(REQUIRE_EXPOSED)
- if(C.get_item_by_slot(ITEM_SLOT_EARS_LEFT) || C.get_item_by_slot(ITEM_SLOT_EARS_RIGHT))
- return FALSE
- else
- return TRUE
- if(REQUIRE_UNEXPOSED)
- if(!C.get_item_by_slot(ITEM_SLOT_EARS_LEFT || C.get_item_by_slot(ITEM_SLOT_EARS_RIGHT)))
- return FALSE
- else
- return TRUE
- else
- return TRUE
- return FALSE
-
-/mob/living/proc/has_earsockets(var/nintendo = REQUIRE_ANY)
- var/mob/living/carbon/C = src
- if(istype(C))
- var/obj/item/organ/peepee = C.getorganslot(ORGAN_SLOT_EARS)
- if(!peepee)
- switch(nintendo)
- if(REQUIRE_ANY)
- return TRUE
- if(REQUIRE_EXPOSED)
- if(C.get_item_by_slot(ITEM_SLOT_EARS_LEFT) || C.get_item_by_slot(ITEM_SLOT_EARS_RIGHT))
- return FALSE
- else
- return TRUE
- if(REQUIRE_UNEXPOSED)
- if(!C.get_item_by_slot(ITEM_SLOT_EARS_LEFT) || !C.get_item_by_slot(ITEM_SLOT_EARS_RIGHT))
- return FALSE
- else
- return TRUE
- else
- return TRUE
- return FALSE
-
-/mob/living/proc/has_eyes(var/nintendo = REQUIRE_ANY)
- var/mob/living/carbon/C = src
- if(istype(C))
- var/obj/item/organ/peepee = C.getorganslot(ORGAN_SLOT_EYES)
- if(peepee)
- switch(nintendo)
- if(REQUIRE_ANY)
- return TRUE
- if(REQUIRE_EXPOSED)
- if(C.get_item_by_slot(ITEM_SLOT_EYES))
- return FALSE
- else
- return TRUE
- if(REQUIRE_UNEXPOSED)
- if(!C.get_item_by_slot(ITEM_SLOT_EYES))
- return FALSE
- else
- return TRUE
- else
- return TRUE
- return FALSE
-
-/mob/living/proc/has_eyesockets(var/nintendo = REQUIRE_ANY)
- var/mob/living/carbon/C = src
- if(istype(C))
- var/obj/item/organ/peepee = C.getorganslot(ORGAN_SLOT_EYES)
- if(!peepee)
- switch(nintendo)
- if(REQUIRE_ANY)
- return TRUE
- if(REQUIRE_EXPOSED)
- if(get_item_by_slot(ITEM_SLOT_EYES))
- return FALSE
- else
- return TRUE
- if(REQUIRE_UNEXPOSED)
- if(!get_item_by_slot(ITEM_SLOT_EYES))
- return FALSE
- else
- return TRUE
- else
- return TRUE
- return FALSE
-
-/mob/living/proc/has_butt(var/nintendo = REQUIRE_ANY)
- var/mob/living/carbon/C = src
- if(has_butt && !istype(C))
- return TRUE
- if(istype(C))
- var/obj/item/organ/genital/peepee = C.getorganslot(ORGAN_SLOT_BUTT)
- if(peepee)
- switch(nintendo)
- if(REQUIRE_ANY)
- return TRUE
- if(REQUIRE_EXPOSED)
- if(peepee.is_exposed())
- return TRUE
- else
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!peepee.is_exposed())
- return TRUE
- else
- return FALSE
- else
- return TRUE
- return FALSE
-
-///Are we wearing something that covers our chest?
-/mob/living/proc/is_topless()
- if(istype(src, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = src
- if((!(H.wear_suit) || !(H.wear_suit.body_parts_covered & CHEST)) && (!(H.w_uniform) || !(H.w_uniform.body_parts_covered & CHEST)) && (!(H.w_shirt) || !(H.w_shirt.body_parts_covered & CHEST)))
- return TRUE
- else
- return TRUE
-
-///Are we wearing something that covers our groin?
-/mob/living/proc/is_bottomless()
- if(istype(src, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = src
- if((!(H.wear_suit) || !(H.wear_suit.body_parts_covered & GROIN)) && (!(H.w_uniform) || !(H.w_uniform.body_parts_covered & GROIN)) && (!(H.w_underwear) || !(H.w_underwear.body_parts_covered & GROIN)))
- return TRUE
- else
- return TRUE
-
-///Are we wearing something that covers our shoes?
-/mob/living/proc/is_barefoot()
- if(istype(src, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = src
- if((!(H.wear_suit) || !(H.wear_suit.body_parts_covered & GROIN)) && (!(H.w_socks) || !(H.w_socks.body_parts_covered & FEET)))
- return TRUE
- else
- return TRUE
-
-/mob/living/proc/moan()
- if(!(prob(get_lust() / get_lust_tolerance() * 65)))
- return
- var/moan = rand(1, 7)
- if(moan == lastmoan)
- moan--
- if(!is_muzzled())
- visible_message(message = "\The [src] [pick("moans", "moans in pleasure")].", ignored_mobs = get_unconsenting())
- if(is_muzzled())//immursion
- audible_message("[src] [pick("mimes a pleasured moan","moans in silence")].")
- lastmoan = moan
-
-/mob/living/proc/cum(mob/living/partner, target_orifice)
- var/message
- var/u_His = p_their()
- var/u_He = p_they()
- var/u_S = p_s()
- var/t_His = partner?.p_their()
- var/cumin = FALSE
- var/partner_carbon_check = FALSE
- var/obj/item/organ/genital/target_gen = null
- var/mob/living/carbon/c_partner = null
- //Carbon checks
- if(iscarbon(partner))
- c_partner = partner
- partner_carbon_check = TRUE
-
- if(src != partner)
- if(!last_genital)
- if(has_penis())
- if(!istype(partner))
- target_orifice = null
- switch(target_orifice)
- if(CUM_TARGET_MOUTH)
- if(partner.has_mouth() && partner.mouth_is_free())
- message = "cums right in \the [partner]'s mouth."
- cumin = TRUE
- else
- message = "cums on \the [partner]'s face."
- if(CUM_TARGET_THROAT)
- if(partner.has_mouth() && partner.mouth_is_free())
- message = "shoves deep into \the [partner]'s throat and cums."
- cumin = TRUE
- else
- message = "cums on \the [partner]'s face."
- if(CUM_TARGET_VAGINA)
- if(partner.has_vagina(REQUIRE_EXPOSED))
- if(partner_carbon_check)
- target_gen = c_partner.getorganslot(ORGAN_SLOT_VAGINA)
- message = "cums in \the [partner]'s pussy."
- cumin = TRUE
- else
- message = "cums on \the [partner]'s belly."
- if(CUM_TARGET_ANUS)
- if(partner.has_anus(REQUIRE_EXPOSED))
- message = "cums in \the [partner]'s asshole."
- cumin = TRUE
- else
- message = "cums on \the [partner]'s backside."
- if(CUM_TARGET_HAND)
- if(partner.has_hand(REQUIRE_ANY))
- message = "cums in \the [partner]'s hand."
- else
- message = "cums on \the [partner]."
- if(CUM_TARGET_BREASTS)
- if(partner.has_breasts(REQUIRE_EXPOSED))
- message = "cums onto \the [partner]'s breasts."
- else
- message = "cums on \the [partner]'s chest and neck."
- if(CUM_TARGET_BELLY)
- if(partner.has_belly(REQUIRE_EXPOSED))
- message = "cums into the [partner]'s navel, [pick(list("making it into a massive pond of jizz", "[p_their()] spunk drooling out of it"))]."
- if(partner_carbon_check)
- target_gen = c_partner.getorganslot(ORGAN_SLOT_VAGINA)
- else
- message = "cums on the [partner]'s midsection."
- if(NUTS_TO_FACE)
- if(partner.has_mouth() && partner.mouth_is_free())
- message = "vigorously ruts [u_His] nutsack into \the [partner]'s mouth before shooting [u_His] thick, sticky jizz all over [t_His] eyes and hair."
- if(THIGH_SMOTHERING)
- if(has_penis(REQUIRE_EXPOSED)) //it already checks for the cock before, why the hell would you do this redundant shit
- message = "keeps \the [partner] locked in [u_His] thighs as [u_His] cock throbs, dumping its heavy load all over [t_His] face."
- else
- message = "reaches [u_His] peak, locking [u_His] legs around \the [partner]'s head extra hard as [u_He] cum[u_S] straight onto the head stuck between [u_His] thighs"
- cumin = TRUE
- if(CUM_TARGET_FEET)
- if(!last_lewd_datum.require_target_num_feet)
- if(partner.has_feet())
- message = "cums on \the [partner]'s [partner.has_feet() == 1 ? pick("foot", "sole") : pick("feet", "soles")]."
- else
- message = "cums on the floor!"
- else
- if(partner.has_feet())
- message = "cums on \the [partner]'s [last_lewd_datum.require_target_feet == 1 ? pick("foot", "sole") : pick("feet", "soles")]."
- else
- message = "cums on the floor!"
- //weird shit goes here
- if(CUM_TARGET_EARS)
- if(partner.has_ears())
- message = "cums inside \the [partner]'s ear."
- else
- message = "cums inside \the [partner]'s earsocket."
- cumin = TRUE
- if(CUM_TARGET_EYES)
- if(partner.has_eyes())
- message = "cums on \the [partner]'s eyeball."
- else
- message = "cums inside \the [partner]'s eyesocket."
- cumin = TRUE
- //
- if(CUM_TARGET_PENIS)
- if(partner.has_penis(REQUIRE_EXPOSED))
- message = "cums on \the [partner]."
- else
- message = "cums on the floor!"
- else
- message = "cums on the floor!"
- else if(has_vagina())
- if(!istype(partner))
- target_orifice = null
-
- switch(target_orifice)
- if(CUM_TARGET_MOUTH)
- if(partner.has_mouth() && partner.mouth_is_free())
- message = "squirts right in \the [partner]'s mouth."
- cumin = TRUE
- else
- message = "squirts on \the [partner]'s face."
- if(CUM_TARGET_THROAT)
- if(partner.has_mouth() && partner.mouth_is_free())
- message = "rubs [u_His] vagina against \the [partner]'s mouth and cums."
- cumin = TRUE
- else
- message = "squirts on \the [partner]'s face."
- if(CUM_TARGET_VAGINA)
- if(partner.has_vagina(REQUIRE_EXPOSED))
- message = "squirts on \the [partner]'s pussy."
- cumin = TRUE
- else
- message = "squirts on \the [partner]'s belly."
- if(CUM_TARGET_ANUS)
- if(partner.has_anus(REQUIRE_EXPOSED))
- message = "squirts on \the [partner]'s asshole."
- cumin = TRUE
- else
- message = "squirts on \the [partner]'s backside."
- if(CUM_TARGET_HAND)
- if(partner.has_hand(REQUIRE_ANY))
- message = "squirts on \the [partner]'s hand."
- else
- message = "squirts on \the [partner]."
- if(CUM_TARGET_BREASTS)
- if(partner.has_breasts(REQUIRE_EXPOSED))
- message = "squirts onto \the [partner]'s breasts."
- else
- message = "squirts on \the [partner]'s chest and neck."
- if(CUM_TARGET_BELLY)
- if(partner.has_belly(REQUIRE_EXPOSED))
- message = "cums into the [partner]'s navel, [pick(list("making it into a massive pond of jizz", "[p_their()] spunk drooling out of it"))]."
- if(partner_carbon_check)
- target_gen = c_partner.getorganslot(ORGAN_SLOT_BELLY)
- else
- message = "cums on the [partner]'s midsection."
- if(NUTS_TO_FACE)
- if(partner.has_mouth() && partner.mouth_is_free())
- message = "vigorously ruts [u_His] clit into \the [partner]'s mouth before shooting [u_His] femcum all over [t_His] eyes and hair."
- if(THIGH_SMOTHERING)
- message = "keeps \the [partner] locked in [u_His] thighs as [u_He] orgasm[u_S], squirting over [t_His] face."
- cumin = TRUE
- if(CUM_TARGET_FEET)
- if(!last_lewd_datum.require_target_num_feet)
- if(partner.has_feet())
- message = "squirts on \the [partner]'s [partner.has_feet() == 1 ? pick("foot", "sole") : pick("feet", "soles")]."
- else
- message = "squirts on the floor!"
- else
- if(partner.has_feet())
- message = "squirts on \the [partner]'s [last_lewd_datum.require_target_feet == 1 ? pick("foot", "sole") : pick("feet", "soles")]."
- else
- message = "squirts on the floor!"
- //weird shit goes here
- if(CUM_TARGET_EARS)
- if(partner.has_ears())
- message = "squirts on \the [partner]'s ear."
- else
- message = "squirts on \the [partner]'s earsocket."
- cumin = TRUE
- if(CUM_TARGET_EYES)
- if(partner.has_eyes())
- message = "squirts on \the [partner]'s eyeball."
- else
- message = "squirts on \the [partner]'s eyesocket."
- cumin = TRUE
- //
- if(CUM_TARGET_PENIS)
- if(partner.has_penis(REQUIRE_EXPOSED))
- message = "squirts on \the [partner]'s penis"
- else
- message = "squirts on the floor!"
- else
- message = "squirts on the floor!"
-
- else
- message = pick("orgasms violently!", "twists in orgasm.")
- else
- switch(last_genital.type)
- if(/obj/item/organ/genital/penis)
- if(!istype(partner))
- target_orifice = null
-
- switch(target_orifice)
- if(CUM_TARGET_MOUTH)
- if(partner.has_mouth() && partner.mouth_is_free())
- message = "cums right in \the [partner]'s mouth."
- cumin = TRUE
- else
- message = "cums on \the [partner]'s face."
- if(CUM_TARGET_THROAT)
- if(partner.has_mouth() && partner.mouth_is_free())
- message = "shoves deep into \the [partner]'s throat and cums."
- cumin = TRUE
- else
- message = "cums on \the [partner]'s face."
- if(CUM_TARGET_VAGINA)
- if(partner.has_vagina(REQUIRE_EXPOSED))
- if(partner_carbon_check)
- target_gen = c_partner.getorganslot(ORGAN_SLOT_VAGINA)
- message = "cums in \the [partner]'s pussy."
- cumin = TRUE
- else
- message = "cums on \the [partner]'s belly."
- if(CUM_TARGET_ANUS)
- if(partner.has_anus(REQUIRE_EXPOSED))
- message = "cums in \the [partner]'s asshole."
- cumin = TRUE
- else
- message = "cums on \the [partner]'s backside."
- if(CUM_TARGET_HAND)
- if(partner.has_hand())
- message = "cums in \the [partner]'s hand."
- else
- message = "cums on \the [partner]."
- if(CUM_TARGET_BREASTS)
- if(partner.is_topless() && partner.has_breasts())
- message = "cums onto \the [partner]'s breasts."
- else
- message = "cums on \the [partner]'s chest and neck."
- if(NUTS_TO_FACE)
- if(partner.has_mouth() && partner.mouth_is_free())
- message = "vigorously ruts [u_His] nutsack into \the [partner]'s mouth before shooting [u_His] thick, sticky jizz all over [t_His] eyes and hair."
- if(THIGH_SMOTHERING)
- if(has_penis()) //it already checks for the cock before, why the hell would you do this redundant shit
- message = "keeps \the [partner] locked in [u_His] thighs as [u_His] cock throbs, dumping its heavy load all over [t_His] face."
- else
- message = "reaches [u_His] peak, locking [u_His] legs around \the [partner]'s head extra hard as [u_He] cum[u_S] straight onto the head stuck between [u_His] thighs"
- cumin = TRUE
- if(CUM_TARGET_FEET)
- if(!last_lewd_datum || !last_lewd_datum.require_target_num_feet)
- if(partner.has_feet())
- message = "cums on \the [partner]'s [partner.has_feet() == 1 ? pick("foot", "sole") : pick("feet", "soles")]."
- else
- message = "cums on the floor!"
- else
- if(partner.has_feet())
- message = "cums on \the [partner]'s [last_lewd_datum.require_target_feet == 1 ? pick("foot", "sole") : pick("feet", "soles")]."
- else
- message = "cums on the floor!"
- //weird shit goes here
- if(CUM_TARGET_EARS)
- if(partner.has_ears())
- message = "cums inside \the [partner]'s ear."
- else
- message = "cums inside \the [partner]'s earsocket."
- cumin = TRUE
- if(CUM_TARGET_EYES)
- if(partner.has_eyes())
- message = "cums on \the [partner]'s eyeball."
- else
- message = "cums inside \the [partner]'s eyesocket."
- cumin = TRUE
- //
- if(CUM_TARGET_PENIS)
- if(partner.has_penis(REQUIRE_EXPOSED))
- message = "cums on \the [partner]."
- else
- message = "cums on the floor!"
- else
- message = "cums on the floor!"
- if(/obj/item/organ/genital/vagina)
- if(!istype(partner))
- target_orifice = null
-
- switch(target_orifice)
- if(CUM_TARGET_MOUTH)
- if(partner.has_mouth() && partner.mouth_is_free())
- message = "squirts right in \the [partner]'s mouth."
- cumin = TRUE
- else
- message = "squirts on \the [partner]'s face."
- if(CUM_TARGET_THROAT)
- if(partner.has_mouth() && partner.mouth_is_free())
- message = "rubs [u_His] vagina against \the [partner]'s mouth and cums."
- cumin = TRUE
- else
- message = "squirts on \the [partner]'s face."
- if(CUM_TARGET_VAGINA)
- if(partner.has_vagina(REQUIRE_EXPOSED))
- message = "squirts on \the [partner]'s pussy."
- cumin = TRUE
- else
- message = "squirts on \the [partner]'s belly."
- if(CUM_TARGET_ANUS)
- if(partner.has_anus(REQUIRE_EXPOSED))
- message = "squirts on \the [partner]'s asshole."
- cumin = TRUE
- else
- message = "squirts on \the [partner]'s backside."
- if(CUM_TARGET_HAND)
- if(partner.has_hand())
- message = "squirts on \the [partner]'s hand."
- else
- message = "squirts on \the [partner]."
- if(CUM_TARGET_BREASTS)
- if(partner.has_breasts(REQUIRE_EXPOSED))
- message = "squirts onto \the [partner]'s breasts."
- else
- message = "squirts on \the [partner]'s chest and neck."
- if(NUTS_TO_FACE)
- if(partner.has_mouth() && partner.mouth_is_free())
- message = "vigorously ruts [u_His] clit into \the [partner]'s mouth before shooting [u_His] femcum all over [t_His] eyes and hair."
-
- if(THIGH_SMOTHERING)
- message = "keeps \the [partner] locked in [u_His] thighs as [u_He] orgasm[u_S], squirting over [t_His] face."
-
- if(CUM_TARGET_FEET)
- if(!last_lewd_datum || !last_lewd_datum.require_target_num_feet)
- if(partner.has_feet())
- message = "squirts on \the [partner]'s [partner.has_feet() == 1 ? pick("foot", "sole") : pick("feet", "soles")]."
- else
- message = "squirts on the floor!"
- else
- if(partner.has_feet())
- message = "squirts on \the [partner]'s [last_lewd_datum.require_target_feet == 1 ? pick("foot", "sole") : pick("feet", "soles")]."
- else
- message = "squirts on the floor!"
- //weird shit goes here
- if(CUM_TARGET_EARS)
- if(partner.has_ears())
- message = "squirts on \the [partner]'s ear."
- else
- message = "squirts on \the [partner]'s earsocket."
- cumin = TRUE
- if(CUM_TARGET_EYES)
- if(partner.has_eyes())
- message = "squirts on \the [partner]'s eyeball."
- else
- message = "squirts on \the [partner]'s eyesocket."
- cumin = TRUE
- //
- if(CUM_TARGET_PENIS)
- if(partner.has_penis(REQUIRE_EXPOSED))
- message = "squirts on \the [partner]'s penis"
- else
- message = "squirts on the floor!"
- else
- message = "squirts on the floor!"
- else
- message = pick("orgasms violently!", "twists in orgasm.")
- else //todo: better self cum messages
- message = "cums all over themselves!"
- if(gender == MALE)
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/final_m1.ogg',
- 'modular_sand/sound/interactions/final_m2.ogg',
- 'modular_sand/sound/interactions/final_m3.ogg',
- 'modular_sand/sound/interactions/final_m4.ogg',
- 'modular_sand/sound/interactions/final_m5.ogg'), 90, 1, 0)
- else if(gender == FEMALE)
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/final_f1.ogg',
- 'modular_sand/sound/interactions/final_f2.ogg',
- 'modular_sand/sound/interactions/final_f3.ogg'), 70, 1, 0)
- else
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/final_f1.ogg',
- 'modular_sand/sound/interactions/final_f2.ogg',
- 'modular_sand/sound/interactions/final_f3.ogg'), 70, 1, 0)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- multiorgasms += 1
-
- if(multiorgasms > (get_sexual_potency() * 0.34)) //AAAAA, WE DONT WANT NEGATIVES HERE, RE
- refractory_period = world.time + rand(300, 900) - get_sexual_potency()//sex cooldown
- // set_drugginess(rand(20, 30))
- else
- refractory_period = world.time + rand(300, 900) - get_sexual_potency()
- // set_drugginess(rand(5, 10))
- if(multiorgasms < get_sexual_potency())
- if(ishuman(src))
- var/mob/living/carbon/human/H = src
- if(!partner)
- H.mob_climax(TRUE, "masturbation", "none")
- else
- H.mob_climax(TRUE, "sex", partner, !cumin, target_gen)
- set_lust(0)
- SEND_SIGNAL(src, COMSIG_MOB_CAME, target_orifice, partner)
-
-/mob/living/proc/is_fucking(mob/living/partner, orifice)
- if(partner == last_partner && orifice == last_orifice)
- return TRUE
- return FALSE
-
-/mob/living/proc/set_is_fucking(mob/living/partner, orifice, var/obj/item/organ/genital/genepool)
- last_partner = partner
- last_orifice = orifice
- last_genital = genepool
-
-/*
- --------------------------------------------------
- ---------------LEWD PROCESS DATUM-----------------
- --------------------------------------------------
-*/
-
-/mob/living/proc/do_oral(mob/living/partner, var/fucktarget = "penis")
- var/message
- var/obj/item/organ/genital/peepee = null
- var/lust_increase = NORMAL_LUST
- var/u_His = p_their()
- var/u_He = p_they()
- var/u_Were = p_theyre()
-
- if(partner.is_fucking(src, CUM_TARGET_MOUTH))
- if(prob(partner.get_sexual_potency()))
- if(istype(src, /mob/living)) // Argh.
- var/mob/living/H = src
- H.adjustOxyLoss(3)
- message = "goes in deep on \the [partner]."
- lust_increase += 5
- else
- var/improv = FALSE
- switch(fucktarget)
- if("vagina")
- if(partner.has_vagina())
- message = pick(
- "licks \the [partner]'s pussy.",
- "runs [u_His] tongue up the shape of \the [partner]'s pussy.",
- "traces \the [partner]'s slit with [u_His] tongue.",
- "darts the tip of [u_His] tongue around \the [partner]'s clit.",
- "laps slowly at \the [partner].",
- "kisses \the [partner]'s delicate folds.",
- "tastes \the [partner].",
- )
- else
- improv = TRUE
- if("penis")
- if(partner.has_penis())
- message = pick(
- "sucks \the [partner]'s off.",
- "runs [u_His] tongue up the shape of \the [partner]'s cock.",
- "traces \the [partner]'s cock with [u_His] tongue.",
- "darts the tip of [u_His] tongue around tip of \the [partner]'s cock.",
- "laps slowly at \the [partner]'s shaft.",
- "kisses the base of \the [partner]'s shaft.",
- "takes \the [partner] deeper into [u_His] mouth.",
- )
- else
- improv = TRUE
- if(improv)
- // get confused about how to do the sex
- message = pick(
- "licks \the [partner].",
- "looks a little unsure of where to lick \the [partner].",
- "runs [u_His] tongue between \the [partner]'s legs.",
- "kisses \the [partner]'s thigh.",
- "tries [u_His] best with \the [partner].",
- )
- else
- var/improv = FALSE
- switch(fucktarget)
- if("vagina")
- if(partner.has_vagina())
- message = pick(
- "buries [u_His] face in \the [partner]'s pussy.",
- "nuzzles \the [partner]'s wet sex.",
- "finds [u_His] face caught between \the [partner]'s thighs.",
- "kneels down between \the [partner]'s legs.",
- "grips \the [partner]'s legs, pushing them apart.",
- "sinks [u_His] face in between \the [partner]'s thighs.",
- )
- else
- improv = TRUE
- if("penis")
- if(partner.has_penis())
- message = pick(
- "takes \the [partner]'s cock into [u_His] mouth.",
- "wraps [u_His] lips around \the [partner]'s cock.",
- "finds [u_His] face between \the [partner]'s thighs.",
- "kneels down between \the [partner]'s legs.",
- "grips \the [partner]'s legs, kissing at the tip of [u_His] cock.",
- "goes down on \the [partner].",
- )
- else
- improv = TRUE
- if(improv)
- message = pick(
- "begins to lick \the [partner].",
- "starts kissing \the [partner]'s thigh.",
- "sinks down between \the [partner]'s thighs.",
- "briefly flashes a puzzled look from between \the [partner]'s legs.",
- "looks unsure of how to handle \the [partner]'s lack of genitalia.",
- "seems like [u_He] [u_Were] expecting \the [partner] to have a cock or a pussy or ... something.",
- )
- peepee = null
- else
- if(ishuman(partner))
- var/mob/living/carbon/human/pardner = partner
- switch(fucktarget)
- if("vagina")
- peepee = pardner.getorganslot(ORGAN_SLOT_VAGINA)
- if("penis")
- peepee = pardner.getorganslot(ORGAN_SLOT_PENIS)
- partner.set_is_fucking(src, CUM_TARGET_MOUTH, peepee)
-
- playlewdinteractionsound(get_turf(src), pick('modular_sand/sound/interactions/bj1.ogg',
- 'modular_sand/sound/interactions/bj2.ogg',
- 'modular_sand/sound/interactions/bj3.ogg',
- 'modular_sand/sound/interactions/bj4.ogg',
- 'modular_sand/sound/interactions/bj5.ogg',
- 'modular_sand/sound/interactions/bj6.ogg',
- 'modular_sand/sound/interactions/bj7.ogg',
- 'modular_sand/sound/interactions/bj8.ogg',
- 'modular_sand/sound/interactions/bj9.ogg',
- 'modular_sand/sound/interactions/bj10.ogg',
- 'modular_sand/sound/interactions/bj11.ogg'), 50, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- partner.handle_post_sex(lust_increase, CUM_TARGET_MOUTH, src)
- lust_increase = NORMAL_LUST //RESET IT REE
-
-/mob/living/proc/do_facefuck(mob/living/partner, var/fucktarget = "penis")
- var/message
- var/obj/item/organ/genital/peepee = null
- var/retaliation_message = FALSE
-
- var/u_His = p_their()
- var/t_Him = partner.p_them()
- var/t_Hes = partner.p_theyre()
-
- if(is_fucking(partner, CUM_TARGET_MOUTH))
- var/improv = FALSE
- switch(fucktarget)
- if("vagina")
- if(has_vagina())
- message = pick(
- "grinds [u_His] pussy into \the [partner]'s face.",
- "grips the back of \the [partner]'s head, forcing [t_Him] onto [u_His] pussy.",
- "rolls [u_His] pussy against \the [partner]'s tongue.",
- "slides \the [partner]'s mouth between [u_His] legs.",
- "looks \the [partner]'s in the eyes as [u_His] pussy presses into a waiting tongue.",
- "sways [u_His] hips, pushing [u_His] sex into \the [partner]'s face.",
- )
- if(partner.a_intent == INTENT_HARM)
- // adjustBruteLoss(5)
- retaliation_message = pick(
- "looks deeply displeased to be there.",
- "struggles to escape from between \the [src]'s thighs.",
- )
- else
- improv = TRUE
- if("penis")
- if(has_penis())
- message = pick(
- "roughly fucks \the [partner]'s mouth.",
- "forces [u_His] cock down \the [partner]'s throat.",
- "pushes in against \the [partner]'s tongue until a tight gagging sound comes.",
- "grips \the [partner]'s hair and draws [t_Him] to the base of the cock.",
- "looks \the [partner]'s in the eyes as [u_His] cock presses into a waiting tongue.",
- "rolls [u_His] hips hard, sinking into \the [partner]'s mouth.",
- )
- if(partner.a_intent == INTENT_HARM)
- // adjustBruteLoss(5)
- retaliation_message = pick(
- "stares up from between \the [src]'s knees, trying to squirm away.",
- "struggles to escape from between \the [src]'s legs.",
- )
- else
- improv = TRUE
- if(improv)
- message = pick(
- "grinds against \the [partner]'s face.",
- "feels \the [partner]'s face between bare legs.",
- "pushes in against \the [partner]'s tongue.",
- "grips \the [partner]'s hair, drawing [t_Him] into the strangely sexless spot between [u_His] legs.",
- "looks \the [partner]'s in the eyes as [t_Hes] caught beneath two thighs.",
- "rolls [u_His] hips hard against \the [partner]'s face.",
- )
- if(partner.a_intent == INTENT_HARM)
- // adjustBruteLoss(5)
- retaliation_message = pick(
- "stares up from between \the [src]'s knees, trying to squirm away.",
- "struggles to escape from between \the [src]'s legs.",
- )
- else
- var/improv = FALSE
- switch(fucktarget)
- if("vagina")
- if(has_vagina())
- message = "forces \the [partner]'s face into [u_His] pussy."
- else
- improv = TRUE
- if("penis")
- if(has_penis())
- if(is_fucking(partner, CUM_TARGET_THROAT))
- message = "retracts [u_His] cock from \the [partner]'s throat"
- else
- message = "shoves [u_His] cock into \the [partner]'s mouth"
- else
- improv = TRUE
- if(improv)
- message = "shoves [u_His] crotch into \the [partner]'s face."
- else
- if(ishuman(partner))
- var/mob/living/carbon/human/pardner = partner
- switch(fucktarget)
- if("vagina")
- peepee = pardner.getorganslot(ORGAN_SLOT_VAGINA)
- if("penis")
- peepee = pardner.getorganslot(ORGAN_SLOT_PENIS)
- set_is_fucking(partner , CUM_TARGET_MOUTH, peepee)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/oral1.ogg',
- 'modular_sand/sound/interactions/oral2.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- if(retaliation_message)
- visible_message(message = "\The [partner] [retaliation_message]", ignored_mobs = get_unconsenting())
- handle_post_sex(NORMAL_LUST, CUM_TARGET_MOUTH, partner)
-
-/mob/living/proc/thigh_smother(mob/living/partner, var/fucktarget = "penis")
- var/message
- var/obj/item/organ/genital/peepee = null
- var/lust_increase = 1
-
- var/u_His = p_their()
- var/t_His = partner.p_their()
- var/t_Him = partner.p_them()
- var/t_Hes = partner.p_theyre()
-
- if(is_fucking(partner, THIGH_SMOTHERING))
- var/improv = FALSE
- switch(fucktarget)
- if("vagina")
- if(has_vagina())
- message = pick(list(
- "presses [u_His] weight down onto \the [partner]'s face, blocking [t_His] vision completely.",
- "rides \the [partner]'s face, grinding [u_His] wet pussy all over it."))
- else
- improv = TRUE
- if("penis")
- if(has_penis())
- message = pick(list("presses [u_His] weight down onto \the [partner]'s face, blocking [t_His] vision completely.",
- "forces [u_His] dick and nutsack into \the [partner]'s face as [t_Hes] stuck locked in between [u_His] thighs.",
- "slips [u_His] cock into \the [partner]'s helpless mouth, keeping [u_His] shaft pressed hard into [t_His] face."))
- else
- improv = TRUE
- if(improv)
- message = "rubs [u_His] groin up and down \the [partner]'s face."
- else
- var/improv = FALSE
- switch(fucktarget)
- if("vagina")
- if(has_vagina())
- message = pick(list(
- "clambers over \the [partner]'s face and pins [t_Him] down with [u_His] thighs, [u_His] moist slit rubbing all over \the [partner]'s mouth and nose.",
- "locks [u_His] legs around \the [partner]'s head before pulling it into [u_His] mound."))
- else
- improv = TRUE
- if("penis")
- if(has_penis())
- message = pick(list(
- "clambers over \the [partner]'s face and pins [t_Him] down with [u_His] thighs, then slowly inching closer and covering [t_His] eyes and nose with [u_His] leaking erection.",
- "locks [u_His] legs around \the [partner]'s head before pulling it into [u_His] fat package, smothering [t_Him]."))
- else
- improv = TRUE
- if(improv)
- message = "deviously locks [u_His] legs around \the [partner]'s head and smothers it in [u_His] thighs."
- else
- if(ishuman(partner))
- var/mob/living/carbon/human/pardner = partner
- switch(fucktarget)
- if("vagina")
- peepee = pardner.getorganslot(ORGAN_SLOT_VAGINA)
- if("penis")
- peepee = pardner.getorganslot(ORGAN_SLOT_PENIS)
- set_is_fucking(partner , THIGH_SMOTHERING, peepee)
-
- var/file = pick('modular_sand/sound/interactions/bj10.ogg',
- 'modular_sand/sound/interactions/bj3.ogg',
- 'modular_sand/sound/interactions/foot_wet1.ogg',
- 'modular_sand/sound/interactions/foot_dry3.ogg')
- playlewdinteractionsound(loc, file, 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- handle_post_sex(lust_increase, THIGH_SMOTHERING, partner)
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/oral1.ogg',
- 'modular_sand/sound/interactions/oral2.ogg'), 70, 1, -1)
- handle_post_sex(NORMAL_LUST, CUM_TARGET_MOUTH, partner)
-
-/mob/living/proc/do_throatfuck(mob/living/partner)
- var/message
- var/obj/item/organ/genital/peepee = null
- var/retaliation_message = FALSE
-
- var/u_His = p_their()
- var/t_His = partner.p_their()
- var/t_Him = partner.p_them()
-
- if(is_fucking(partner, CUM_TARGET_THROAT))
- message = "[pick(
- "brutally shoves [u_His] cock into \the [partner]'s throat to make [t_Him] gag.",
- "chokes \the [partner] on [u_His] dick, going in balls deep.",
- "slams in and out of \the [partner]'s mouth, [u_His] balls slapping off [t_His] face.")]"
- if(rand(0, 1) == 1)
- partner.emote("chokes on \The [src]")
- if(istype(partner, /mob/living))
- var/mob/living/H = partner
- var/statBefore = H.stat
- H.adjustOxyLoss(3)
-
- if(H.stat == UNCONSCIOUS && statBefore != UNCONSCIOUS)
- visible_message(message = "\The [partner] passes out on \The [src]'s cock.", ignored_mobs = get_unconsenting())
-
- if(partner.a_intent == INTENT_HARM)
- // adjustBruteLoss(5)
- retaliation_message = pick(
- "stares up from between \the [src]'s knees, trying to squirm away.",
- "struggles to escape from between \the [src]'s legs.",
- )
- else if(is_fucking(partner, CUM_TARGET_MOUTH))
- message = "thrusts deeper into \the [partner]'s mouth and down [t_His] throat."
- if(ishuman(src))
- var/mob/living/carbon/human/coomer = partner
- peepee = coomer.getorganslot(ORGAN_SLOT_PENIS)
- set_is_fucking(partner , CUM_TARGET_THROAT, peepee)
- else
- message = "forces [u_His] dick deep down \the [partner]'s throat"
- if(ishuman(src))
- var/mob/living/carbon/human/coomer = partner
- peepee = coomer.getorganslot(ORGAN_SLOT_PENIS)
- set_is_fucking(partner , CUM_TARGET_THROAT, peepee)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/oral1.ogg',
- 'modular_sand/sound/interactions/oral2.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- if(retaliation_message)
- visible_message(message = "\The [partner] [retaliation_message]", ignored_mobs = get_unconsenting())
- handle_post_sex(NORMAL_LUST, CUM_TARGET_THROAT, partner)
-
-/mob/living/proc/nut_face(var/mob/living/partner)
-
- var/message
-
- var/u_His = p_their()
- var/t_His = partner.p_their()
-
- var/lust_increase = 1
-
- if(is_fucking(partner, NUTS_TO_FACE))
- message = pick(list(
- "grabs the back of [partner]'s head and pulls it into [u_His] crotch.",
- "jams [u_His] nutsack right into [partner]'s face.",
- "roughly grinds [u_His] fat nutsack into [partner]'s mouth.",
- "pulls out [u_His] saliva-covered nuts from [partner]'s violated mouth and then wipes off the slime onto [t_His] face."))
- else
- message = pick(list("wedges a digit into the side of [partner]'s jaw and pries it open before using [u_His] other hand to shove [u_His] whole nutsack inside!", "stands with [u_His] groin inches away from [partner]'s face, then thrusting [u_His] hips forward and smothering [partner]'s whole face with [u_His] heavy ballsack."))
- set_is_fucking(partner , NUTS_TO_FACE, getorganslot(ORGAN_SLOT_PENIS) ? getorganslot(ORGAN_SLOT_PENIS) : null)
-
- /*playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/nuts1.ogg',
- 'modular_sand/sound/interactions/nuts2.ogg',
- 'modular_sand/sound/interactions/nuts3.ogg',
- 'modular_sand/sound/interactions/nuts4.ogg'), 70, 1, -1)*/ //These files don't even exist but nobody noticed because double-quotes were used instead of single.
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- handle_post_sex(lust_increase, CUM_TARGET_MOUTH, partner)
-
-/mob/living/proc/do_anal(mob/living/partner)
- var/message
-
- var/u_His = p_their()
- var/t_His = partner.p_their()
-
- if(is_fucking(partner, CUM_TARGET_ANUS))
- message = "[pick(
- "thrusts in and out of \the [partner]'s ass.",
- "pounds \the [partner]'s ass.",
- "slams [u_His] hips up against \the [partner]'s ass hard.",
- "goes balls deep into \the [partner]'s ass over and over again.")]"
- else
- message = "[pick(
- "works [u_His] cock into \the [partner]'s asshole.",
- "grabs the base of [u_His] twitching cock and presses the tip into \the [partner]'s asshole.",
- "shoves [u_His] dick deep inside of \the [partner]'s ass, making [t_His] rear jiggle.")]"
- set_is_fucking(partner, CUM_TARGET_ANUS, getorganslot(ORGAN_SLOT_PENIS) ? getorganslot(ORGAN_SLOT_PENIS) : null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/bang1.ogg',
- 'modular_sand/sound/interactions/bang2.ogg',
- 'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- handle_post_sex(NORMAL_LUST, CUM_TARGET_ANUS, partner)
- partner.handle_post_sex(NORMAL_LUST, null, src)
-
-/mob/living/proc/do_vaginal(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(is_fucking(partner, CUM_TARGET_VAGINA))
- message = "[pick(
- "pounds \the [partner]'s pussy.",
- "shoves [u_His] dick deep into \the [partner]'s pussy",
- "thrusts in and out of \the [partner]'s cunt.",
- "goes balls deep into \the [partner]'s pussy over and over again.")]"
- else
- message = "slides [u_His] cock into \the [partner]'s pussy."
- set_is_fucking(partner, CUM_TARGET_VAGINA, getorganslot(ORGAN_SLOT_PENIS) ? getorganslot(ORGAN_SLOT_PENIS) : null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/champ1.ogg',
- 'modular_sand/sound/interactions/champ2.ogg'), 50, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- handle_post_sex(NORMAL_LUST, CUM_TARGET_VAGINA, partner)
- partner.handle_post_sex(NORMAL_LUST, null, src)
-
-/mob/living/proc/do_mount(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(partner.is_fucking(src, CUM_TARGET_VAGINA))
- message = "[pick("rides \the [partner]'s dick.",
- "forces [partner]'s cock on [u_His] pussy")]"
- else
- message = "slides [u_His] pussy onto \the [partner]'s cock."
- partner.set_is_fucking(src, CUM_TARGET_VAGINA, partner.getorganslot(ORGAN_SLOT_PENIS) ? partner.getorganslot(ORGAN_SLOT_PENIS) : null)
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/bang1.ogg',
- 'modular_sand/sound/interactions/bang2.ogg',
- 'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_VAGINA, src)
- handle_post_sex(NORMAL_LUST, null, partner)
-
-/mob/living/proc/do_mountass(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(partner.is_fucking(src, CUM_TARGET_ANUS))
- message = "[pick("rides \the [partner]'s dick.",
- "forces [partner]'s cock on [u_His] ass")]"
- else
- message = "lowers [u_His] ass onto \the [partner]'s cock."
- partner.set_is_fucking(src, CUM_TARGET_ANUS, partner.getorganslot(ORGAN_SLOT_PENIS) ? partner.getorganslot(ORGAN_SLOT_PENIS) : null)
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/bang1.ogg',
- 'modular_sand/sound/interactions/bang2.ogg',
- 'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_ANUS, src)
- handle_post_sex(NORMAL_LUST, null, partner)
-
-/mob/living/proc/do_tribadism(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(partner.is_fucking(src, CUM_TARGET_VAGINA))
- message = "[pick("grinds [u_His] pussy against \the [partner]'s cunt.",
- "rubs [u_His] cunt against \the [partner]'s pussy.",
- "thrusts against \the [partner]'s pussy.",
- "humps \the [partner], [u_His] pussies grinding against each other.")]"
- else
- message = "presses [u_His] pussy into \the [partner]'s own."
- partner.set_is_fucking(src, CUM_TARGET_VAGINA, partner.getorganslot(ORGAN_SLOT_VAGINA) ? partner.getorganslot(ORGAN_SLOT_VAGINA) : null)
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/squelch1.ogg',
- 'modular_sand/sound/interactions/squelch2.ogg',
- 'modular_sand/sound/interactions/squelch3.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_VAGINA, src)
- handle_post_sex(NORMAL_LUST, null, partner)
-
-/mob/living/proc/do_fingering(mob/living/partner)
- visible_message(message = "\The [src] [pick("fingers \the [partner].",
- "fingers \the [partner]'s pussy.",
- "fingers \the [partner] hard.")]", ignored_mobs = get_unconsenting())
- playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1)
- partner.handle_post_sex(NORMAL_LUST, null, src)
-
-/mob/living/proc/do_fingerass(mob/living/partner)
- visible_message(message = "\The [src] [pick("fingers \the [partner].",
- "fingers \the [partner]'s asshole.",
- "fingers \the [partner] hard.")]", ignored_mobs = get_unconsenting())
- playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1)
- partner.handle_post_sex(NORMAL_LUST, null, src)
-
-/mob/living/proc/do_rimjob(mob/living/partner)
- visible_message(message = "\The [src] licks \the [partner]'s asshole.", ignored_mobs = get_unconsenting())
- playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1)
- partner.handle_post_sex(NORMAL_LUST, null, src)
-
-/mob/living/proc/do_handjob(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(partner.is_fucking(src, CUM_TARGET_HAND))
- message = "[pick("jerks \the [partner] off.",
- "works \the [partner]'s shaft.",
- "wanks \the [partner]'s cock hard.")]"
- else
- message = "[pick("wraps [u_His] hand around \the [partner]'s cock.",
- "starts playing with \the [partner]'s cock")]"
- partner.set_is_fucking(src, CUM_TARGET_HAND, partner.getorganslot(ORGAN_SLOT_PENIS) ? partner.getorganslot(ORGAN_SLOT_PENIS) : null)
-
- playlewdinteractionsound(src, pick('modular_sand/sound/interactions/bang1.ogg',
- 'modular_sand/sound/interactions/bang2.ogg',
- 'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src)
-
-/mob/living/proc/do_breastfuck(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(is_fucking(partner, CUM_TARGET_BREASTS))
- message = "[pick("fucks \the [partner]'s' breasts.",
- "grinds [u_His] cock between \the [partner]'s boobs.",
- "thrusts into \the [partner]'s tits.",
- "grabs \the [partner]'s breasts together and presses [u_His] dick between them.")]"
- else
- message = "pushes \the [partner]'s breasts together and presses [u_His] dick between them."
- set_is_fucking(partner , CUM_TARGET_BREASTS, getorganslot(ORGAN_SLOT_PENIS) ? getorganslot(ORGAN_SLOT_PENIS) : null)
-
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/bang1.ogg',
- 'modular_sand/sound/interactions/bang2.ogg',
- 'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- handle_post_sex(NORMAL_LUST, CUM_TARGET_BREASTS, partner)
-
-/mob/living/proc/do_mountface(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(is_fucking(partner, GRINDING_FACE_WITH_ANUS))
- message = "[pick("grinds [u_His] ass into \the [partner]'s face.",
- "shoves [u_His] ass into \the [partner]'s face.")]"
- else
- message = "[pick(
- "grabs the back of \the [partner]'s head and forces it into [u_His] asscheeks.",
- "squats down and plants [u_His] ass right on \the [partner]'s face")]"
- set_is_fucking(partner , GRINDING_FACE_WITH_ANUS, null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/squelch1.ogg',
- 'modular_sand/sound/interactions/squelch2.ogg',
- 'modular_sand/sound/interactions/squelch3.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- handle_post_sex(LOW_LUST, null, src)
-
-/mob/living/proc/do_lickfeet(mob/living/partner)
- var/message
-
- if(partner.get_item_by_slot(ITEM_SLOT_FEET) != null)
- message = "licks \the [partner]'s [partner.get_shoes()]."
- else
- message = "licks \the [partner]'s [partner.has_feet() == 1 ? "foot" : "feet"]."
-
- playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- handle_post_sex(LOW_LUST, null, src)
-
-/*Grinding YOUR feet in TARGET's face*/
-/mob/living/proc/do_grindface(mob/living/partner)
- var/message
-
- var/u_His = p_their()
- var/t_His = partner.p_their()
-
- if(is_fucking(partner, GRINDING_FACE_WITH_FEET))
- if(get_item_by_slot(ITEM_SLOT_FEET) != null)
- message = "[pick(list("grinds [u_His] [get_shoes()] into [partner]'s face.",
- "presses [u_His] footwear down hard on [partner]'s face.",
- "rubs off the dirt from [u_His] [get_shoes()] onto [partner]'s face."))]"
- else
- message = "[pick(list("grinds [u_His] bare feet into [partner]'s face.",
- "deviously covers [partner]'s mouth and nose with [u_His] bare feet.",
- "runs the soles of [u_His] bare feet against [partner]'s lips."))]"
-
- else if(is_fucking(partner, GRINDING_MOUTH_WITH_FEET))
- if(get_item_by_slot(ITEM_SLOT_FEET) != null)
- message = "[pick(list("pulls [u_His] [get_shoes()] out of [partner]'s mouth and puts them on [t_His] face.",
- "slowly retracts [u_His] [get_shoes()] from [partner]'s mouth, putting them on [t_His] face instead."))]"
- else
- message = "[pick(list("pulls [u_His] bare feet out of [partner]'s mouth and rests them on [t_His] face instead.",
- "retracts [u_His] bare feet from [partner]'s mouth and grinds them into [t_His] face instead."))]"
-
- set_is_fucking(partner , GRINDING_FACE_WITH_FEET, null)
-
- else
- if(get_item_by_slot(ITEM_SLOT_FEET) != null)
- message = "[pick(list("plants [u_His] [get_shoes()] ontop of [partner]'s face.",
- "rests [u_His] [get_shoes()] on [partner]'s face and presses down hard.",
- "harshly places [u_His] [get_shoes()] atop [partner]'s face."))]"
- else
- message = "[pick(list("plants [u_His] bare feet ontop of [partner]'s face.",
- "rests [u_His] feet on [partner]'s face, smothering them.",
- "positions [u_His] bare feet atop [partner]'s face."))]"
-
- set_is_fucking(partner, GRINDING_FACE_WITH_FEET, null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/foot_dry1.ogg',
- 'modular_sand/sound/interactions/foot_dry2.ogg',
- 'modular_sand/sound/interactions/foot_dry3.ogg',
- 'modular_sand/sound/interactions/foot_dry4.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- partner.handle_post_sex(LOW_LUST, null, src)
-
-/*Grinding YOUR feet in TARGET's mouth*/
-/mob/living/proc/do_grindmouth(mob/living/partner)
- var/message
-
- var/u_His = p_their()
- var/t_His = partner.p_their()
- var/t_Him = partner.p_them()
- var/t_He = partner.p_they()
- var/t_S = partner.p_s()
-
- if(is_fucking(partner, GRINDING_MOUTH_WITH_FEET))
- if(get_item_by_slot(ITEM_SLOT_FEET) != null)
- message = "[pick(list("roughly shoves [u_His] [get_shoes()] deeper into [partner]'s mouth.",
- "harshly forces another inch of [u_His] [get_shoes()] into [partner]'s mouth.",
- "presses [u_His] weight down, [u_His] [get_shoes()] prying deeper into [partner]'s mouth."))]"
- else
- message = "[pick(list("wiggles [u_His] toes deep inside [partner]'s mouth.",
- "crams [u_His] barefeet down deeper into [partner]'s mouth, making [t_Him] gag.",
- "roughly grinds [u_His] feet on [partner]'s tongue."))]"
-
- else if(is_fucking(partner, GRINDING_FACE_WITH_FEET))
- if(get_item_by_slot(ITEM_SLOT_FEET) != null)
- message = "[pick(list("decides to force [u_His] [get_shoes()] deep into [partner]'s mouth.",
- "pressed the tip of [u_His] [get_shoes()] against [partner]'s lips and shoves inwards."))]"
- else
- message = "[pick(list("pries open [partner]'s mouth with [u_His] toes and shoves [u_His] bare foot in.",
- "presses down [u_His] foot even harder, cramming [u_His] foot into [partner]'s mouth."))]"
-
- set_is_fucking(partner , GRINDING_MOUTH_WITH_FEET, null)
-
- else
- if(get_item_by_slot(ITEM_SLOT_FEET) != null)
- message = "[pick(list("readies themselves and in one swift motion, shoves [u_His] [get_shoes()] into [partner]'s mouth.",
- "grinds the tip of [u_His] [get_shoes()] against [partner]'s mouth before pushing themselves in."))]"
- else
- message = "[pick(list("rubs [u_His] dirty bare feet across [partner]'s face before prying them into [t_His] muzzle.",
- "forces [u_His] barefeet into [partner]'s mouth.",
- "covers [partner]'s mouth and nose with [u_His] foot until [t_He] gasp[t_S] for breath, then shoves both feet inside before [t_He] can react."))]"
- set_is_fucking(partner , GRINDING_MOUTH_WITH_FEET, null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/foot_wet1.ogg',
- 'modular_sand/sound/interactions/foot_wet2.ogg',
- 'modular_sand/sound/interactions/foot_wet3.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- partner.handle_post_sex(LOW_LUST, null, src)
-
-/mob/living/proc/do_footfuck(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(is_fucking(src, CUM_TARGET_FEET))
- message = "[pick("fucks \the [partner]'s [partner.get_shoes() ? partner.get_shoes(TRUE) : pick("foot", "sole")].",
- "rubs [u_His] dick on \the [partner]'s [partner.get_shoes() ? partner.get_shoes(TRUE) : pick("foot", "sole")].",
- "grinds [u_His] cock on \the [partner]'s [partner.get_shoes() ? partner.get_shoes(TRUE) : pick("foot", "sole")].")]"
- else
- message = "[pick("positions [u_His] cock on \the [partner]'s [partner.get_shoes() ? partner.get_shoes(TRUE) : pick("foot", "sole")].",
- "positions [u_His] cock on \the [partner]'s [partner.get_shoes() ? partner.get_shoes(TRUE) : pick("foot","sole")].",
- "starts grinding [u_His] cock against \the [partner]'s [partner.get_shoes() ? partner.get_shoes(TRUE) : pick("foot", "sole")].")]"
- set_is_fucking(src, CUM_TARGET_FEET, getorganslot(ORGAN_SLOT_PENIS) ? getorganslot(ORGAN_SLOT_PENIS) : null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/foot_dry1.ogg',
- 'modular_sand/sound/interactions/foot_dry3.ogg',
- 'modular_sand/sound/interactions/foot_wet1.ogg',
- 'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, src)
-
-/mob/living/proc/do_dfootfuck(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(is_fucking(src, CUM_TARGET_FEET))
- message = "[pick("fucks \the [partner]'s [partner.get_shoes() ? partner.get_shoes() : pick("feet", "soles")].",
- "rubs [u_His] dick between \the [partner]'s [partner.get_shoes() ? partner.get_shoes() : pick("feet", "soles")].",
- "thrusts [u_His] cock between \the [partner]'s [partner.get_shoes() ? partner.get_shoes() : pick("feet", "soles")].")]"
- else
- message = "[pick("positions [u_His] cock between \the [partner]'s [partner.get_shoes() ? partner.get_shoes() : pick("feet", "soles")].",
- "starts grinding [u_His] cock against \the [partner]'s [partner.get_shoes() ? partner.get_shoes() : pick("feet", "soles")].",
- "starts grinding [u_His] cock between \the [partner]'s [partner.get_shoes() ? partner.get_shoes() : pick("feet", "soles")].")]"
- set_is_fucking(src, CUM_TARGET_FEET, getorganslot(ORGAN_SLOT_PENIS) ? getorganslot(ORGAN_SLOT_PENIS) : null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/foot_dry1.ogg',
- 'modular_sand/sound/interactions/foot_dry3.ogg',
- 'modular_sand/sound/interactions/foot_wet1.ogg',
- 'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, src)
-
-/mob/living/proc/do_vfootfuck(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(is_fucking(src, CUM_TARGET_FEET))
- message = "[pick("grinds [u_His] pussy against \the [partner]'s [partner.get_shoes() ? partner.get_shoes(TRUE) : pick("foot", "sole")].",
- "rubs [u_His] clit on \the [partner]'s [partner.get_shoes() ? partner.get_shoes(TRUE) : pick("foot", "sole")].",
- "ruts on \the [partner]'s [partner.get_shoes() ? partner.get_shoes(TRUE) : pick("foot", "sole")].")]"
- else
- message = "[pick("positions [u_His] vagina on \the [partner]'s [partner.get_shoes() ? partner.get_shoes(TRUE) : pick("foot", "sole")].",
- "positions [u_His] clit on \the [partner]'s [partner.get_shoes() ? partner.get_shoes(TRUE) : pick("foot","sole")].",
- "starts grinding [u_His] pussy against \the [partner]'s [partner.get_shoes() ? partner.get_shoes(TRUE) : pick("foot", "sole")].")]"
- set_is_fucking(src, CUM_TARGET_FEET, getorganslot(ORGAN_SLOT_VAGINA) ? getorganslot(ORGAN_SLOT_VAGINA) : null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/foot_dry1.ogg',
- 'modular_sand/sound/interactions/foot_dry3.ogg',
- 'modular_sand/sound/interactions/foot_wet1.ogg',
- 'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, src)
-
-/mob/living/proc/do_footjob(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(partner.is_fucking(src, CUM_TARGET_FEET))
- message = "[pick("jerks \the [partner] off with [u_His] [get_shoes() ? get_shoes(TRUE) : pick("foot", "sole")].",
- "rubs [u_His] [get_shoes() ? get_shoes(TRUE) : pick("foot", "sole", "toes")] on \the [partner]'s shaft.",
- "works [u_His] [get_shoes() ? get_shoes(TRUE) : pick("foot", "sole")] up and down on \the [partner]'s cock.")]"
- else
- message = "[pick("[get_shoes() ? "positions [u_His] [get_shoes(TRUE)] on" :"positions [u_His] foot on"] \the [partner]'s cock.",
- "starts playing around with \the [partner]'s cock, using [u_His] [get_shoes() ? get_shoes(TRUE) :"foot"].")]"
- partner.set_is_fucking(src, CUM_TARGET_FEET, partner.getorganslot(ORGAN_SLOT_PENIS) ? partner.getorganslot(ORGAN_SLOT_PENIS) : null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/foot_dry1.ogg',
- 'modular_sand/sound/interactions/foot_dry3.ogg',
- 'modular_sand/sound/interactions/foot_wet1.ogg',
- 'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, src)
-
-/mob/living/proc/do_dfootjob(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(partner.is_fucking(src, CUM_TARGET_FEET))
- message = "[pick("jerks \the [partner] off with [u_His] [get_shoes() ? get_shoes() : pick("feet", "soles")].",
- "rubs [u_His] [get_shoes() ? get_shoes() : pick("feet", "soles")] on \the [partner]'s shaft.",
- "rubs [get_shoes() ? "[u_His] [get_shoes()]" : "all of [u_His] toes"] on \the [partner]'s cock.",
- "works [u_His] [get_shoes() ? get_shoes() : pick("feet", "soles")] up and down on \the [partner]'s cock.")]"
- else
- message = "[pick("[get_shoes() ? "wraps [u_His] [get_shoes()] around" : "wraps [u_His] [pick("feet", "soles")] around"] \the [partner]'s cock.",
- "starts playing around with \the [partner]'s cock, using [u_His] [get_shoes() ? get_shoes() : "feet"].")]"
- partner.set_is_fucking(src, CUM_TARGET_FEET, partner.getorganslot(ORGAN_SLOT_PENIS) ? partner.getorganslot(ORGAN_SLOT_PENIS) : null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/foot_dry1.ogg',
- 'modular_sand/sound/interactions/foot_dry3.ogg',
- 'modular_sand/sound/interactions/foot_wet1.ogg',
- 'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, src)
-
-/mob/living/proc/do_footjob_v(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(partner.is_fucking(src, CUM_TARGET_FEET))
- message = "[pick("rubs \the [partner] clit with [u_His] [get_shoes() ? get_shoes(TRUE) : pick("foot", "sole")].",
- "rubs [u_His] [get_shoes() ? get_shoes(TRUE) : pick("foot", "sole", "toes")] on \the [partner]'s coochie.",
- "rubs [u_His] [get_shoes() ? get_shoes(TRUE) : pick("foot", "sole", "toes")] on \the [partner]'s vagina.",
- "rubs [u_His] foot up and down on \the [partner]'s pussy.")]"
- else
- message = "[pick("[get_shoes() ? "positions [u_His] [get_shoes(TRUE)] on" : "positions [u_His] foot on"] \the [partner]'s pussy.",
- "starts playing around with \the [partner]'s pussy, using [u_His] [get_shoes() ? get_shoes(TRUE) : "foot"].")]"
- partner.set_is_fucking(src, CUM_TARGET_FEET, partner.getorganslot(ORGAN_SLOT_VAGINA) ? partner.getorganslot(ORGAN_SLOT_VAGINA) : null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/foot_dry1.ogg',
- 'modular_sand/sound/interactions/foot_dry3.ogg',
- 'modular_sand/sound/interactions/foot_wet1.ogg',
- 'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, src)
-
-/mob/living/proc/get_shoes(var/singular = FALSE)
- var/obj/A = get_item_by_slot(ITEM_SLOT_FEET)
- if(A)
- var/txt = A.name
- if(findtext (A.name,"the"))
- txt = copytext(A.name, 5, length(A.name)+1)
- if(singular)
- txt = copytext(A.name, 5, length(A.name))
- return txt
- else
- if(singular)
- txt = copytext(A.name, 1, length(A.name))
- return txt
-
-/// Handles the sex, if cumming returns true.
-/mob/living/proc/handle_post_sex(amount, orifice, mob/living/partner)
- if(stat != CONSCIOUS)
- return FALSE
-
- if(amount)
- add_lust(amount)
- if(get_lust() >= get_lust_tolerance())
- if(prob(10))
- to_chat(src, "You struggle to not orgasm!")
- return FALSE
- if(lust >= get_lust_tolerance()*3)
- cum(partner, orifice)
- return TRUE
- else
- moan()
- return FALSE
-
-/mob/living/proc/get_unconsenting(var/extreme = FALSE, var/list/ignored_mobs)
- var/list/nope = list()
- nope += ignored_mobs
- for(var/mob/M in range(7, src))
- if(M.client)
- var/client/cli = M.client
- if(!(cli.prefs.toggles & VERB_CONSENT)) //Note: This probably could do with a specific preference
- nope += M
- else if(extreme && (cli.prefs.extremepref == "No"))
- nope += M
- else
- nope += M
- return nope
-
-//Yep, weird shit goes down here.
-/mob/living/proc/do_eyefuck(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(is_fucking(partner, CUM_TARGET_EYES))
- message = "[pick(
- "pounds into \the [partner]'s [has_eyes() ? "eye":"eyesocket"].",
- "shoves [u_His] dick deep into \the [partner]'s skull",
- "thrusts in and out of \the [partner]'s [has_eyes() ? "eye":"eyesocket"].",
- "goes balls deep into \the [partner]'s cranium over and over again.")]"
- var/client/cli = partner.client
- var/mob/living/carbon/C = partner
- if(cli && istype(C))
- if(cli.prefs.extremeharm != "No")
- if(prob(15))
- C.bleed(2)
- if(prob(25))
- C.adjustOrganLoss(ORGAN_SLOT_EYES,rand(3,7))
- C.adjustOrganLoss(ORGAN_SLOT_BRAIN, rand(3,7))
- else
- message = "forcefully slides [u_His] cock inbetween \the [partner]'s [has_eyes() ? "eyelid":"eyesocket"]."
- set_is_fucking(partner, CUM_TARGET_EYES, getorganslot(ORGAN_SLOT_PENIS) ? getorganslot(ORGAN_SLOT_PENIS) : null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/champ1.ogg',
- 'modular_sand/sound/interactions/champ2.ogg'), 50, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting(TRUE))
- handle_post_sex(NORMAL_LUST, CUM_TARGET_EYES, partner)
- partner.handle_post_sex(LOW_LUST, null, src)
-
-/mob/living/proc/do_earfuck(mob/living/partner)
- var/message
-
- var/u_His = p_their()
-
- if(is_fucking(partner, CUM_TARGET_EARS))
- message = "[pick(
- "pounds into \the [partner]'s [has_eyes() ? "ear":"earsocker"].",
- "shoves [u_His] dick deep into \the [partner]'s skull",
- "thrusts in and out of \the [partner]'s [has_eyes() ? "ear":"eyesocket"].",
- "goes balls deep into \the [partner]'s cranium over and over again.")]"
- var/client/cli = partner.client
- var/mob/living/carbon/C = partner
- if(cli && istype(C))
- if(cli.prefs.extremeharm != "No")
- if(prob(15))
- C.bleed(2)
- if(prob(25))
- C.adjustOrganLoss(ORGAN_SLOT_EARS, rand(3,7))
- C.adjustOrganLoss(ORGAN_SLOT_BRAIN, rand(3,7))
- else
- message = "forcefully slides [u_His] cock inside \the [partner]'s [has_ears() ? "ear":"earsocket"]."
- set_is_fucking(partner, CUM_TARGET_EARS, getorganslot(ORGAN_SLOT_PENIS) ? getorganslot(ORGAN_SLOT_PENIS) : null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/champ1.ogg',
- 'modular_sand/sound/interactions/champ2.ogg'), 50, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting(TRUE))
- handle_post_sex(NORMAL_LUST, CUM_TARGET_EARS, partner)
- partner.handle_post_sex(LOW_LUST, null, src)
diff --git a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/_lewd_extra.dm b/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/_lewd_extra.dm
deleted file mode 100644
index bd474d06ba..0000000000
--- a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/_lewd_extra.dm
+++ /dev/null
@@ -1,365 +0,0 @@
-/mob/living/proc/do_frot(mob/living/target)
- var/message
- var/t_His = p_their()
-
- message = "rubs [t_His] penis against [target]'s."
- set_is_fucking(target, CUM_TARGET_PENIS, getorganslot(ORGAN_SLOT_PENIS))
- visible_message("\The [src] [message]", ignored_mobs = get_unconsenting())
- handle_post_sex(NORMAL_LUST, CUM_TARGET_PENIS, target)
- target.handle_post_sex(NORMAL_LUST, CUM_TARGET_PENIS, src)
-
-/mob/living/proc/do_breastfeed(mob/living/target)
- var/message
- var/u_His = p_their()
- var/u_He = p_they()
- var/t_His = target.p_their()
- var/obj/item/organ/genital/breasts/milkers = getorganslot(ORGAN_SLOT_BREASTS)
- var/milktype = milkers?.fluid_id
- var/modifier
- var/list/lines
-
- if(!milkers || !milktype)
- return
- var/datum/reagent/b_fluid = new milktype
-
- if(target == src)
- lines = list(
- "brings [u_His] own milktanks to [u_His] mouth and sucks deeply into them",
- "takes a big sip of [u_His] own fresh [b_fluid.name]",
- "fills [u_His] own mouth with a big gulp of [u_His] warm [b_fluid.name]"
- )
- else
- lines = list(
- "pushes [u_His] breasts against \the [target]'s mouth, squirting [u_His] warm [b_fluid.name] into [t_His] mouth",
- "fills \the [target]'s mouth with warm, sweet [b_fluid.name] as [u_He] squeezes [u_His] boobs, panting",
- "lets a large stream of [u_His] own abundant [b_fluid.name] coat the back of \the [target]'s throat"
- )
-
- message = "\The [src] [pick(lines)]"
- visible_message(message, ignored_mobs = get_unconsenting())
- playlewdinteractionsound(src, pick('modular_sand/sound/interactions/oral1.ogg',
- 'modular_sand/sound/interactions/oral2.ogg'), 70, 1, -1)
-
- switch(milkers.size)
- if("c", "d", "e")
- modifier = 2
- if("f", "g", "h")
- modifier = 3
- else
- if(milkers.size in milkers.breast_values)
- modifier = clamp(milkers.breast_values[milkers.size] - 5, 0, INFINITY)
- else
- modifier = 1
- target.reagents.add_reagent(milktype, rand(1,3 * modifier))
-
-/mob/living/proc/do_jackoff(mob/living/user)
- var/message
- var/t_His = p_their()
- var/t_Him = p_them()
-
- if(user.is_fucking(src, CUM_TARGET_HAND))
- message = "[pick("jerks [t_Him]self off.",
- "works [t_His] shaft.",
- "strokes [t_His] penis.",
- "wanks [t_His] cock hard.")]"
- else
- message = "[pick("wraps [t_His] hand around [t_His] cock.",
- "starts to stroke [t_His] cock.",
- "starts playing with [t_His] cock.")]"
- user.set_is_fucking(src, CUM_TARGET_HAND, user.getorganslot(ORGAN_SLOT_PENIS) ? user.getorganslot(ORGAN_SLOT_PENIS) : null)
-
- playlewdinteractionsound(src, pick('modular_sand/sound/interactions/bang1.ogg',
- 'modular_sand/sound/interactions/bang2.ogg',
- 'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src)
-
-/mob/living/proc/do_oral_self(mob/living/user, var/fucktarget = "penis")
- var/message
- var/obj/item/organ/genital/peepee = null
- var/lust_increase = NORMAL_LUST
- var/t_His = p_their()
- var/t_Him = p_them()
-
- if(user.is_fucking(src, CUM_TARGET_MOUTH))
- if(prob(user.get_sexual_potency()))
- if(istype(src, /mob/living)) // Argh.
- var/mob/living/H = src
- H.adjustOxyLoss(3)
- message = "sucks [t_Him]self off"
- lust_increase += 5
- else
- var/improv = FALSE
- switch(fucktarget)
- if("vagina")
- if(user.has_vagina())
- message = pick(
- "licks [t_His] pussy.",
- "runs their tongue up the shape of [t_His] pussy.",
- "traces [t_His] slit with their tongue.",
- "darts the tip of their tongue around [t_His] clit.",
- "laps slowly at [t_Him].",
- "kisses [t_His] delicate folds.",
- "tastes [t_Him].",
- )
- else
- improv = TRUE
- if("penis")
- if(user.has_penis())
- message = pick(
- "sucks [t_Him] off.",
- "runs their tongue up the shape of [t_His] cock.",
- "traces [t_His] cock with their tongue.",
- "darts the tip of their tongue around tip of [t_His] cock.",
- "laps slowly at [t_His] shaft.",
- "kisses the base of [t_His] shaft.",
- "takes [t_Him] deeper into their mouth.",
- )
- else
- improv = TRUE
- if(improv)
- // get confused about how to do the sex
- message = pick(
- "licks [t_Him].",
- "looks a little unsure of where to lick [t_Him].",
- "runs their tongue between [t_His] legs.",
- "kisses [t_His] thigh.",
- "tries their best with [t_Him].",
- )
- else
- var/improv = FALSE
- switch(fucktarget)
- if("vagina")
- if(user.has_vagina())
- message = pick(
- "buries their face in [t_His] pussy.",
- "nuzzles [t_His] wet sex.",
- "finds their face caught between [t_His] thighs.",
- "kneels down between [t_His] legs.",
- "grips [t_His] legs, pushing them apart.",
- "sinks their face in between [t_His] thighs.",
- )
- else
- improv = TRUE
- if("penis")
- if(user.has_penis())
- message = pick(
- "takes [t_His] cock into their mouth.",
- "wraps their lips around [t_His] cock.",
- "finds their face between [t_His] thighs.",
- "kneels down between [t_His] legs.",
- "grips [t_His] legs, kissing at the tip of their cock.",
- "goes down on [t_Him].",
- )
- else
- improv = TRUE
- if(improv)
- message = pick(
- "begins to lick [t_His].",
- "starts kissing [t_His] thigh.",
- "sinks down between [t_His] thighs.",
- "briefly flashes a puzzled look from between [t_His] legs.",
- "looks unsure of how to handle [t_His] lack of genitalia.",
- "seems like they were expecting [t_His] to have a cock or a pussy or ... something.",
- )
- peepee = null
- else
- if(ishuman(user))
- var/mob/living/carbon/human/pardner = user
- switch(fucktarget)
- if("vagina")
- peepee = pardner.getorganslot(ORGAN_SLOT_VAGINA)
- if("penis")
- peepee = pardner.getorganslot(ORGAN_SLOT_PENIS)
- user.set_is_fucking(src, CUM_TARGET_MOUTH, peepee)
-
- playlewdinteractionsound(get_turf(src), pick('modular_sand/sound/interactions/bj1.ogg',
- 'modular_sand/sound/interactions/bj2.ogg',
- 'modular_sand/sound/interactions/bj3.ogg',
- 'modular_sand/sound/interactions/bj4.ogg',
- 'modular_sand/sound/interactions/bj5.ogg',
- 'modular_sand/sound/interactions/bj6.ogg',
- 'modular_sand/sound/interactions/bj7.ogg',
- 'modular_sand/sound/interactions/bj8.ogg',
- 'modular_sand/sound/interactions/bj9.ogg',
- 'modular_sand/sound/interactions/bj10.ogg',
- 'modular_sand/sound/interactions/bj11.ogg'), 50, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- user.handle_post_sex(lust_increase, CUM_TARGET_MOUTH, src)
- lust_increase = NORMAL_LUST //RESET IT REE
-
-/mob/living/proc/do_breastfuck_self(mob/living/user)
- var/message
- var/t_His = p_their()
-
- if(is_fucking(user, CUM_TARGET_BREASTS))
- message = "[pick("fucks [t_His] breasts.",
- "grinds their cock between [t_His] boobs.",
- "thrusts into [t_His] tits.",
- "grabs [t_His] breasts together and presses their dick between them.")]"
- else
- message = "pushes [t_His] breasts together and presses their dick between them."
- set_is_fucking(user, CUM_TARGET_BREASTS, getorganslot(ORGAN_SLOT_PENIS) ? getorganslot(ORGAN_SLOT_PENIS) : null)
-
- playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/bang1.ogg',
- 'modular_sand/sound/interactions/bang2.ogg',
- 'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1)
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- handle_post_sex(NORMAL_LUST, CUM_TARGET_BREASTS, user)
-
-/mob/living/proc/do_fingerass_self(mob/living/user)
- var/t_His = p_their()
- var/t_Him = p_them()
-
- visible_message(message = "\The [src] [pick("fingers [t_Him]self.",
- "fingers [t_His] asshole.",
- "fingers [t_Him]self hard.")]", ignored_mobs = get_unconsenting())
- playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1)
- user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src)
-
-/mob/living/proc/do_fingering_self(mob/living/user)
- var/t_His = p_their()
-
- visible_message(message = "\The [src] [pick("fingers [t_His] pussy deep.",
- "fingers [t_His] pussy.",
- "plays with [t_His] pussy.",
- "fingers [t_His] own pussy hard.")]", ignored_mobs = get_unconsenting())
- playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1)
- user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src)
-
-/mob/living/proc/do_titgrope_self(mob/living/user)
- var/message
- var/t_His = p_their()
-
- if(user.a_intent == INTENT_HARM)
- message = "[pick("aggressively gropes [t_His] breast.",
- "grabs [t_His] breasts.",
- "tightly squeezes [t_His] breasts.",
- "slaps at [t_His] breasts.",
- "gropes [t_His] breasts roughly.")]"
- else
- message = "[pick("gently gropes [t_His] breast.",
- "softly squeezes [t_His] breasts.",
- "grips [t_His] breasts.",
- "runs a few fingers over [t_His] breast.",
- "delicately teases [t_His] nipple.",
- "traces a touch across [t_His] breast.")]"
- if(prob(5 + user.get_lust()))
- visible_message(message = "\The [src] [pick("shivers in arousal.",
- "moans quietly.",
- "breathes out a soft moan.",
- "gasps.",
- "shudders softly.",
- "trembles as [t_His] hands run across bare skin.")]")
- visible_message(message = "\The [src] [message]", ignored_mobs = get_unconsenting())
- playlewdinteractionsound(loc, 'modular_sand/sound/interactions/squelch1.ogg', 50, 1, -1)
- user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, src)
-/*
-/mob/living/proc/remove_condom(mob/living/carbon/user)
- var/list/cock_names = list("rod", "bitchbreaker", "cock", "penis", "schlong")
- var/s_His = p_their()
- var/t_He = user.p_they()
- if(src == user)
- if(P.equipment[GENITAL_EQUIPEMENT_CONDOM])
- user.visible_message(message = "\The [user] slides the condom out of [s_His] [pick(cock_names)]",
- self_message = "You feel the condom slide off your [pick(cock_names)]",
- ignored_mobs = get_unconsenting()
- )
- P.equipment.Remove(GENITAL_EQUIPEMENT_CONDOM)
- new /obj/item/clothing/head/condom(user.loc)
- else
- to_chat(src, "You need a condom for that!")
- else
- if(P.condom)
- user.visible_message(message = "\The [src] tries to remove the condom off of [user]'s [pick(cock_names)]",
- self_message = "\The [src] gently takes your [pick(cock_names)] and starts sliding the condom off of it",
- ignored_mobs = get_unconsenting()
- )
- if(!do_mob(src, user, 4 SECONDS))
- return
- user.visible_message(message = "\The [src] slides the condom out of [user]'s [pick(cock_names)]!",
- self_message = "You feel [src]'s warm hand slide the condom out of your [pick(cock_names)]",
- ignored_mobs = get_unconsenting()
- )
- P.condom = FALSE
- new /obj/item/clothing/head/condom(user.loc)
- else
- to_chat(src, "[t_He] needs a condom for that!")
-*/
-/*
-/obj/item/organ/genital/proc/remove_sounding(mob/living/carbon/remover)
- if(!equipment[GENITAL_EQUIPMENT_SOUNDING])
- to_chat(remover, "There doesn't seem to be a sounding rod in here")
- return
-
- if(remover == owner)
- owner.visible_message(message = "\The [owner] slides the sounding rod out of [owner.p_their()] [name]",
- self_message = "You feel the sounding rod slide out of your [name]",
- ignored_mobs = get_unconsenting()
- )
- else
-
-
-
-
-/mob/living/carbon/proc/remove_sounding(mob/living/carbon/human/user)
- var/list/cock_names = list("rod", "bitchbreaker", "cock", "penis", "schlong")
- var/obj/item/organ/genital/penis/P
- var/s_His = p_their()
- var/t_He = user.p_they()
- if(src == user)
- P = getorganslot(ORGAN_SLOT_PENIS)
- if(P.sounding)
- visible_message(message = "\The [src] slides the sounding rod out of [s_His] [pick(cock_names)]",
- self_message = "You feel the sounding rod slide off your [pick(cock_names)]'s urethra",
- ignored_mobs = get_unconsenting()
- )
- P.sounding = FALSE
- new /obj/item/genital_equipment/sounding/used_sounding(loc)
- else
- to_chat(src, "You need a sounding rod for that!")
- else
- P = user.getorganslot(ORGAN_SLOT_PENIS)
- if(P.sounding)
- user.visible_message(message = "\The [src] tries to remove the sounding rod from [user]'s [pick(cock_names)]",
- self_message = "\The [src] gently takes your [pick(cock_names)] and starts sliding the sounding rod out of its urethra",
- ignored_mobs = get_unconsenting()
- )
- if(!do_mob(src, user, 4 SECONDS))
- return
- user.visible_message(message = "\The [src] slides the sounding rod out of [user]'s [pick(cock_names)]!",
- self_message = "You feel your urethra relax and throb as [src]'s warm hand slides the sounding rod out of your [pick(cock_names)]",
- ignored_mobs = get_unconsenting()
- )
- P.sounding = FALSE
- new /obj/item/genital_equipment/sounding/used_sounding(user.loc)
- else
- to_chat(src, "[t_He] needs a sounding rod for that!")
-*/
-
-/mob/living/proc/remove_equipment(mob/living/carbon/target)
- var/obj/item/organ/genital/holder = pick_receiving_organ(target, HAS_EQUIPMENT, "Remove equipment", "What genital?")
- if(!holder)
- to_chat(src, " You need exposed genitals!")
- return
- if(!LAZYLEN(holder.equipment))
- to_chat(src, "You'll have to put something in it first, since it seems to be clean")
- return
-
- var/obj/item/gimme = input(src, "What do you want to remove?", "Remove equipment", null) as null|anything in holder.equipment
- if(gimme)
- holder.remove_equipment(src, gimme)
-
-/mob/living/proc/nuzzle_belly(mob/living/target)
- var/message
- var/u_His = p_their()
- var/list/belly_names = list("stomach", "belly", "gut", "midsection", "rolls")
- var/list/nuzzles = list(
- "rubs [u_His] face all accross [target]'s [pick(belly_names)]",
- "nuzzles [target]'s [pick(belly_names)][pick(list(" lovingly", ""))]",
- "shoves [u_His] face into [target]'s [pick(belly_names)] and gives it kisses all over",
- "licks right into [target]'s [pick(list("belly button", "navel"))]"
- )
-
- message = "\The [src] [pick(nuzzles)]. "
- visible_message(message, ignored_mobs = get_unconsenting())
diff --git a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/lewd_datums.dm b/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/lewd_datums.dm
deleted file mode 100644
index 645aa3f1bd..0000000000
--- a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/lewd_datums.dm
+++ /dev/null
@@ -1,642 +0,0 @@
-/datum/interaction/lewd
- var/list/blacklisted_mobs = list(/mob/living/simple_animal/pet,
- /mob/living/simple_animal/cockroach,
- /mob/living/simple_animal/babyKiwi,
- /mob/living/simple_animal/butterfly,
- /mob/living/simple_animal/chick,
- /mob/living/simple_animal/chicken,
- /mob/living/simple_animal/cow,
- /mob/living/simple_animal/crab,
- /mob/living/simple_animal/kiwi,
- /mob/living/simple_animal/parrot,
- /mob/living/simple_animal/sloth,
- /mob/living/simple_animal/pickle,
- /mob/living/simple_animal/hostile/retaliate/goat)
-
-/datum/interaction/lewd/kiss
- command = "deepkiss"
- description = "Kiss them deeply."
- require_user_mouth = TRUE
- require_target_mouth = TRUE
- write_log_user = "kissed"
- write_log_target = "was kissed by"
- interaction_sound = null
- max_distance = 1
-
-/datum/interaction/lewd/kiss/post_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- . = ..()
- if(user.get_lust() < 5)
- user.set_lust(5)
- if(target.get_lust() < 5)
- target.set_lust(5)
-
-/datum/interaction/lewd/kiss/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- if(user.get_lust() >= 3)
- user.visible_message("\The [user] gives an intense, lingering kiss to \the [target].")
- else
- user.visible_message("\The [user] kisses \the [target] deeply.")
-
-/datum/interaction/lewd/titgrope
- command = "titgrope"
- description = "Grope their breasts."
- require_user_hands = TRUE
- require_target_breasts = REQUIRE_ANY
- write_log_user = "groped"
- write_log_target = "was groped by"
- interaction_sound = null
- max_distance = 1
-
-/datum/interaction/lewd/titgrope/post_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- . = ..()
-
-/datum/interaction/lewd/titgrope/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- if(user.a_intent == INTENT_HELP)
- user.visible_message(
- pick("\The [user] gently gropes \the [target]'s breast.",
- "\The [user] softly squeezes \the [target]'s breasts.",
- "\The [user] grips \the [target]'s breasts.",
- "\The [user] runs a few fingers over \the [target]'s breast.",
- "\The [user] delicately teases \the [target]'s nipple.",
- "\The [user] traces a touch across \the [target]'s breast."))
- if(user.a_intent == INTENT_HARM)
- user.visible_message(
- pick("\The [user] aggressively gropes \the [target]'s breast.",
- "\The [user] grabs \the [target]'s breasts.",
- "\The [user] tightly squeezes \the [target]'s breasts.",
- "\The [user] slaps at \the [target]'s breasts.",
- "\The [user] gropes \the [target]'s breasts roughly."))
- if(prob(5 + target.get_lust()))
- if(target.a_intent == INTENT_HELP)
- user.visible_message(
- pick("\The [target] shivers in arousal.",
- "\The [target] moans quietly.",
- "\The [target] breathes out a soft moan.",
- "\The [target] gasps.",
- "\The [target] shudders softly.",
- "\The [target] trembles as hands run across bare skin."))
- if(target.get_lust() < 5)
- target.set_lust(5)
- if(target.a_intent == INTENT_DISARM)
- if (target.restrained())
- user.visible_message(
- pick("\The [target] twists playfully against the restraints.",
- "\The [target] squirms away from [user]'s hand.",
- "\The [target] slides back from [user]'s roaming hand.",
- "\The [target] thrusts bare breasts forward into [user]'s hands."))
- else
- user.visible_message(
- pick("\The [target] playfully bats at [user]'s hand.",
- "\The [target] squirms away from [user]'s hand.",
- "\The [target] guides [user]'s hand across bare breasts.",
- "\The [target] teasingly laces a few fingers over [user]'s knuckles."))
- if(target.get_lust() < 10)
- target.add_lust(1)
- if(target.a_intent == INTENT_GRAB)
- user.visible_message(
- pick("\The [target] grips [user]'s wrist tight.",
- "\The [target] digs nails into [user]'s arm.",
- "\The [target] grabs [user]'s wrist for a second."))
- if(target.a_intent == INTENT_HARM)
- user.adjustBruteLoss(1)
- user.visible_message(
- pick("\The [target] pushes [user] roughly away.",
- "\The [target] digs nails angrily into [user]'s arm.",
- "\The [target] fiercely struggles against [user].",
- "\The [target] claws [user]'s forearm, drawing blood.",
- "\The [target] slaps [user]'s hand away."))
- return
-
-/datum/interaction/lewd/nipsuck
- command = "nipsuck"
- description = "Suck their nipples."
- require_target_topless = TRUE
- require_user_mouth = TRUE
- write_log_user = "sucked nipples"
- write_log_target = "had their nipples sucked by"
- interaction_sound = null
- max_distance = 1
-
-/datum/interaction/lewd/nipsuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- if((user.a_intent == INTENT_HELP) || (user.a_intent == INTENT_DISARM))
- user.visible_message(
- pick("\The [user] gently sucks on \the [target]'s [pick("nipple", "nipples")].",
- "\The [user] gently nibs \the [target]'s [pick("nipple", "nipples")].",
- "\The [user] licks \the [target]'s [pick("nipple", "nipples")]."))
- if(target.has_breasts(REQUIRE_EXPOSED))
- var/modifier = 1
- var/obj/item/organ/genital/breasts/B = target.getorganslot(ORGAN_SLOT_BREASTS)
- switch(B.size)
- if("c", "d", "e")
- modifier = 2
- if("f", "g", "h")
- modifier = 3
- else
- if(B.size in B.breast_values)
- modifier = clamp(B.breast_values[B.size] - 5, 0, INFINITY)
- else
- modifier = 1
- if(B.fluid_id)
- user.reagents.add_reagent(B.fluid_id, rand(1,2 * modifier))
-
- if(user.a_intent == INTENT_HARM)
- user.visible_message(
- pick("\The [user] bites \the [target]'s [pick("nipple", "nipples")].",
- "\The [user] aggressively sucks \the [target]'s [pick("nipple", "nipples")]."))
- if(target.has_breasts(REQUIRE_EXPOSED))
- var/modifier = 1
- var/obj/item/organ/genital/breasts/B = target.getorganslot(ORGAN_SLOT_BREASTS)
- switch(B.size)
- if("c", "d", "e")
- modifier = 2
- if("f", "g", "h")
- modifier = 3
- else
- if(B.size in B.breast_values)
- modifier = clamp(B.breast_values[B.size] - 5, 0, INFINITY)
- else
- modifier = 1
- if(B.fluid_id)
- user.reagents.add_reagent(B.fluid_id, rand(1,3 * modifier)) //aggressive sucking leads to high rewards
-
- if(user.a_intent == INTENT_GRAB)
- user.visible_message(
- pick("\The [user] sucks \the [target]'s [pick("nipple", "nipples")] intently.",
- "\The [user] feasts \the [target]'s [pick("nipple", "nipples")].",
- "\The [user] glomps \the [target]'s [pick("nipple", "nipples")]."))
- if(target.has_breasts(REQUIRE_EXPOSED))
- var/modifier = 1
- var/obj/item/organ/genital/breasts/B = target.getorganslot(ORGAN_SLOT_BREASTS)
- switch(B.size)
- if("c", "d", "e")
- modifier = 2
- if("f", "g", "h")
- modifier = 3
- else
- if(B.size in B.breast_values)
- modifier = clamp(B.breast_values[B.size] - 5, 0, INFINITY)
- else
- modifier = 1
- if(B.fluid_id)
- user.reagents.add_reagent(B.fluid_id, rand(1,3 * modifier)) //aggressive sucking leads to high rewards
-
- if(prob(5 + target.get_lust()))
- if(target.a_intent == INTENT_HELP)
- if(!target.has_breasts())
- user.visible_message(
- pick("\The [target] shivers in arousal.",
- "\The [target] moans quietly.",
- "\The [target] breathes out a soft moan.",
- "\The [target] gasps.",
- "\The [target] shudders softly.",
- "\The [target] trembles as their chest gets molested."))
- else
- user.visible_message(
- pick("\The [target] shivers in arousal.",
- "\The [target] moans quietly.",
- "\The [target] breathes out a soft moan.",
- "\The [target] gasps.",
- "\The [target] shudders softly.",
- "\The [target] trembles as their breasts get molested.",
- "\The [target] quivers in arousal as \the [user] delights themselves on their milk."))
- if(target.get_lust() < 5)
- target.set_lust(5)
- if(target.a_intent == INTENT_DISARM)
- if (target.restrained())
- if(!target.has_breasts())
- user.visible_message(
- pick("\The [target] twists playfully against the restraints.",
- "\The [target] squirms away from \the [user]'s mouth.",
- "\The [target] slides back from \the [user]'s mouth.",
- "\The [target] thrusts their bare chest forward into \the [user]'s mouth."))
- else
- user.visible_message(
- pick("\The [target] twists playfully against the restraints.",
- "\The [target] squirms away from \the [user]'s mouth.",
- "\The [target] slides back from \the [user]'s mouth.",
- "\The [target] thrust their bare breasts forward into \the [user]'s mouth."))
- else
- if(!target.has_breasts())
- user.visible_message(
- pick("\The [target] playfully shoos away \the [user]'s head.",
- "\The [target] squirms away from \the [user]'s mouth.",
- "\The [target] holds \the [user]'s head against their chest.",
- "\The [target] teasingly caresses \the [user]'s neck."))
- else
- user.visible_message(
- pick("\The [target] playfully shoos away \the [user]'s head.",
- "\The [target] squirms away from \the [user]'s mouth.",
- "\The [target] holds \the [user]'s head against their breast.",
- "\The [target] teasingly caresses \the [user]'s neck.",
- "\The [target] rubs their breasts against \the [user]'s head."))
- if(target.get_lust() < 10)
- target.add_lust(1)
- if(target.a_intent == INTENT_GRAB)
- user.visible_message(
- pick("\The [target] grips \the [user]'s head tight.",
- "\The [target] digs nails into \the [user]'s scalp.",
- "\The [target] grabs and shoves \the [user]'s head away."))
- if(target.a_intent == INTENT_HARM)
- user.adjustBruteLoss(1)
- user.visible_message(
- pick("\The [target] slaps \the [user] away.",
- "\The [target] scratches [user]'s face.",
- "\The [target] fiercely struggles against [user].",
- "\The [target] claws [user]'s face, drawing blood.",
- "\The [target] elbows [user]'s mouth away."))
- target.dir = get_dir(target, user)
- user.dir = get_dir(user, target)
- playlewdinteractionsound(user.loc, pick('modular_sand/sound/interactions/oral1.ogg',
- 'modular_sand/sound/interactions/oral2.ogg'), 70, 1, -1)
- return
-
-/datum/interaction/lewd/oral
- command = "suckvag"
- description = "Go down on them."
- require_user_mouth = TRUE
- require_target_vagina = REQUIRE_EXPOSED
- write_log_user = "gave head to"
- write_log_target = "was given head by"
- interaction_sound = null
- max_distance = 1
-
-/datum/interaction/lewd/oral/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_oral(target, "vagina")
-
-/datum/interaction/lewd/oral/blowjob
- command = "suckcock"
- description = "Suck them off."
- require_target_vagina = REQUIRE_NONE
- require_target_penis = REQUIRE_EXPOSED
-
-/datum/interaction/lewd/oral/blowjob/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_oral(target, "penis")
-
-/datum/interaction/lewd/fuck
- command = "fuckvag"
- description = "Fuck their pussy."
- require_user_penis = REQUIRE_EXPOSED
- require_target_vagina = REQUIRE_EXPOSED
- write_log_user = "fucked"
- write_log_target = "was fucked by"
- interaction_sound = null
- max_distance = 1
-
-/datum/interaction/lewd/fuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_vaginal(target)
-
-/datum/interaction/lewd/fuck/anal
- command = "fuckass"
- description = "Fuck their ass."
- require_target_vagina = REQUIRE_NONE
- require_target_anus = REQUIRE_EXPOSED
- write_log_user = "ass fucked"
- write_log_target = "was ass fucked by"
-
-/datum/interaction/lewd/fuck/anal/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_anal(target)
-
-/datum/interaction/lewd/fuck/belly
- command = "fuckbelly"
- description = "Fuck their belly."
- require_target_vagina = REQUIRE_NONE
- require_target_belly = REQUIRE_EXPOSED
- write_log_user = "belly fucked"
- write_log_target = "was belly fucked by"
-
-/datum/interaction/lewd/fuck/belly/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_bellyfuck(target)
-
-/datum/interaction/lewd/finger
- command = "finger"
- description = "Finger their pussy."
- require_user_hands = TRUE
- require_target_vagina = REQUIRE_EXPOSED
- interaction_sound = null
- max_distance = 1
- write_log_user = "pussy fingered"
- write_log_target = "was fingered in the pussy by"
-
-/datum/interaction/lewd/finger/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_fingering(target)
-
-/datum/interaction/lewd/fingerass
- command = "fingerm"
- description = "Finger their ass."
- interaction_sound = null
- require_user_hands = TRUE
- require_target_anus = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "ass fingered"
- write_log_target = "was fingered in the ass by"
-
-/datum/interaction/lewd/fingerass/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_fingerass(target)
-
-
-/datum/interaction/lewd/facefuck
- command = "facefuck"
- description = "Fuck their mouth."
- interaction_sound = null
- require_target_mouth = TRUE
- require_user_penis = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "facefucked"
- write_log_target = "was facefucked by"
-
-/datum/interaction/lewd/facefuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_facefuck(target)
-
-/datum/interaction/lewd/throatfuck
- command = "throatfuck"
- description = "Fuck their throat. | Does oxy damage."
- interaction_sound = null
- require_user_penis = REQUIRE_EXPOSED
- require_target_mouth = TRUE
- max_distance = 1
- write_log_user = "throatfucked"
- write_log_target = "was throatfucked by"
-
-/datum/interaction/lewd/throatfuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_throatfuck(target)
-
-/datum/interaction/lewd/handjob
- command = "handjob"
- description = "Jerk them off."
- interaction_sound = null
- require_user_hands = TRUE
- require_target_penis = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "tugged off"
- write_log_target = "got a handjob from"
-
-/datum/interaction/lewd/handjob/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_handjob(target)
-
-/datum/interaction/lewd/breastfuck
- command = "breastfuck"
- description = "Fuck their breasts."
- interaction_sound = null
- require_user_penis = REQUIRE_EXPOSED
- require_target_breasts = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "breastfucked"
- write_log_target = "was breastfucked by"
-
-/datum/interaction/lewd/breastfuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_breastfuck(target)
-
-/datum/interaction/lewd/mount
- command = "mount"
- description = "Mount with your pussy."
- interaction_sound = null
- require_user_vagina = REQUIRE_EXPOSED
- require_target_penis = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "pussy-mounted"
- write_log_target = "was pussy-mounted by"
-
-/datum/interaction/lewd/mount/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_mount(target)
-
-/datum/interaction/lewd/mountass
- command = "mountm"
- description = "Mount with your ass."
- interaction_sound = null
- require_user_anus = REQUIRE_EXPOSED
- require_target_penis = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "ass-mounted"
- write_log_target = "was ass-mounted by"
-
-/datum/interaction/lewd/mountass/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_mountass(target)
-
-/datum/interaction/lewd/tribadism
- command = "tribadism"
- description = "Grind your pussy against theirs."
- interaction_sound = null
- require_target_vagina = REQUIRE_EXPOSED
- require_user_vagina = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "pussy-rubbed"
- write_log_target = "was pussy-rubbed by"
-
-/datum/interaction/lewd/tribadism/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_tribadism(target)
-
-/datum/interaction/lewd/rimjob
- command = "rimjob"
- description = "Lick their ass."
- interaction_sound = null
- require_user_mouth = TRUE
- require_target_anus = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "ass licked"
- write_log_target = "was ass licked by"
-
-/datum/interaction/lewd/rimjob/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_rimjob(target)
-
-/datum/interaction/lewd/mountface
- command = "mountface"
- description = "Ass to face."
- interaction_sound = null
- require_target_mouth = TRUE
- require_user_anus = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "face-sat"
- write_log_target = "was face-sat by"
-
-/datum/interaction/lewd/mountface/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_mountface(target)
-
-/datum/interaction/lewd/lickfeet
- command = "lickfeet"
- description = "Lick their feet."
- interaction_sound = null
- require_user_mouth = TRUE
- require_target_feet = REQUIRE_ANY
- require_target_num_feet = 1
- max_distance = 1
- write_log_user = "licked the feet of"
- write_log_target = "got their feet licked by"
-
-
-/datum/interaction/lewd/lickfeet/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_lickfeet(target)
-
-/datum/interaction/lewd/grindface
- command = "grindface"
- description = "Feet grind their face."
- interaction_sound = null
- require_target_mouth = TRUE
- require_user_num_feet = 1
- require_user_feet = REQUIRE_ANY
- max_distance = 1
- write_log_user = "put their feet in the face of"
- write_log_target = "got feet in their face from"
-
-/datum/interaction/lewd/grindface/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_grindface(target)
-
-/datum/interaction/lewd/grindmouth
- command = "grindmouth"
- description = "Feet grind their mouth."
- interaction_sound = null
- require_target_mouth = TRUE
- require_user_num_feet = 1
- require_user_feet = REQUIRE_ANY
- max_distance = 1
- write_log_user = "put their feet in the mouth of"
- write_log_target = "got feet in their mouth from"
-
-/datum/interaction/lewd/grindmouth/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_grindmouth(target)
-
-/datum/interaction/lewd/footfuck
- command = "footfuck"
- description = "Rub your cock on their foot."
- interaction_sound = null
- require_target_num_feet = 1
- require_target_feet = REQUIRE_ANY
- require_user_penis = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "rubbed their cock on the foot of"
- write_log_target = "got cock rubbed on their feet from"
-
-/datum/interaction/lewd/footfuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_footfuck(target)
-
-/datum/interaction/lewd/footfuck/double
- command = "footfuckdouble"
- description = "Rub your cock between their feet."
- require_target_num_feet = 2
-
-/datum/interaction/lewd/footfuck/double/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_dfootfuck(target)
-
-/datum/interaction/lewd/footjob
- command = "footjob"
- description = "Jerk them off with your foot."
- interaction_sound = null
- require_user_num_feet = 1
- require_user_feet = REQUIRE_ANY
- require_target_penis = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "gave a footjob to"
- write_log_target = "got a footjob from"
-
-/datum/interaction/lewd/footjob/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_footjob(target)
-
-/datum/interaction/lewd/footjob/double
- command = "footjob_double"
- description = "Jerk them off with both of your feet."
- require_user_num_feet = 2
-
-/datum/interaction/lewd/footjob/double/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_dfootjob(target)
-
-/datum/interaction/lewd/footjob/vagina
- command = "footjob_vaginal"
- description = "Rub their vagina with your foot."
- require_target_vagina = REQUIRE_EXPOSED
- require_target_penis = REQUIRE_NONE
- write_log_user = "footfucked the vagina of"
- write_log_target = "got their pussy fucked by the foot of"
-
-/datum/interaction/lewd/footjob/vagina/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_footjob_v(target)
-
-/datum/interaction/lewd/thighs
- command = "thigh_smother"
- description = "Smother them."
- max_distance = 1
- require_user_bottomless = TRUE
- require_target_mouth = TRUE
- interaction_sound = null
- write_log_user = "thigh-trapped"
- write_log_target = "was smothered by"
-
-/datum/interaction/lewd/thighs/display_interaction(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target)
- user.thigh_smother(target)
-
-/datum/interaction/lewd/nuts
- command = "nut_face"
- description = "Nuts to face."
- interaction_sound = null
- require_user_balls = REQUIRE_EXPOSED
- require_target_mouth = TRUE
- max_distance = 1
- write_log_user = "make-them-suck-their-nuts"
- write_log_target = "was made to suck nuts by"
-
-/datum/interaction/lewd/nuts/display_interaction(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target)
- user.nut_face(target)
-
-/datum/interaction/lewd/nut_smack
- command = "smack_nuts"
- description = "Smack their nuts."
- interaction_sound = 'modular_sand/sound/interactions/slap.ogg'
- simple_message = "USER slaps TARGET's nuts!"
- require_target_balls = REQUIRE_EXPOSED
- needs_physical_contact = TRUE
- max_distance = 1
- write_log_user = "slapped-nuts"
- write_log_target = "had their nuts slapped by"
-
-//Weird shit section
-/datum/interaction/lewd/earfuck
- command = "earfuck"
- description = "Fuck their ear."
- interaction_sound = null
- simple_message = "USER penetrates TARGET's ear!"
- require_user_penis = REQUIRE_EXPOSED
- require_target_ears = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "earfucked"
- write_log_target = "had their ear fucked by"
- extreme = TRUE
-
-/datum/interaction/lewd/earfuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_earfuck(target)
-
-/datum/interaction/lewd/earfuck/earsocketfuck
- command = "earsocketfuck"
- description = "Fuck their earsocket."
- interaction_sound = null
- simple_message = "USER penetrates TARGET's earsocket!"
- require_user_penis = REQUIRE_EXPOSED
- require_target_earsockets = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "earsocket fucked"
- write_log_target = "had their earsocket fucked by"
- extreme = TRUE
-
-/datum/interaction/lewd/eyefuck
- command = "eyefuck"
- description = "Fuck their eye."
- interaction_sound = null
- simple_message = "USER penetrates TARGET's eye!"
- require_user_penis = REQUIRE_EXPOSED
- require_target_eyes = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "eyefucked"
- write_log_target = "had their eye fucked by"
- extreme = TRUE
-
-/datum/interaction/lewd/eyefuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.do_eyefuck(target)
-
-/datum/interaction/lewd/eyefuck/eyesocketfuck
- command = "eyesocketfuck"
- description = "Fuck their eyesocket."
- interaction_sound = null
- simple_message = "USER penetrates TARGET's eyesocket!"
- require_user_penis = REQUIRE_EXPOSED
- require_target_eyesockets = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "eyesocketfucked"
- write_log_target = "had their eyesocket fucked by"
- extreme = TRUE
-//
diff --git a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/lewd_datums_extra.dm b/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/lewd_datums_extra.dm
deleted file mode 100644
index 4d9ca48432..0000000000
--- a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/lewd_datums_extra.dm
+++ /dev/null
@@ -1,257 +0,0 @@
-/datum/interaction/lewd/frotting
- command = "frotting"
- description = "Rub your penis against theirs"
- require_user_penis = REQUIRE_EXPOSED
- require_target_penis = REQUIRE_EXPOSED
- max_distance = 1
- write_log_user = "frotted"
- write_log_target = "was frotted by"
- interaction_sound = null
-
-/datum/interaction/lewd/frotting/display_interaction(mob/living/user, mob/living/target)
- user.do_frot(target)
-
-/datum/interaction/lewd/do_breastfeed
- command = "do_breastfeed"
- description = "Breastfeed them"
- require_user_breasts = REQUIRE_EXPOSED
- require_target_mouth = TRUE
- max_distance = 1
- write_log_user = "breastfed"
- write_log_target = "was breastfed by"
- interaction_sound = null
-
-/datum/interaction/lewd/do_breastfeed/display_interaction(mob/living/user, mob/living/target)
- user.do_breastfeed(target)
-
-/**
- * Self Interactions!
- */
-
-/datum/interaction/lewd/jack
- command = "jack"
- description = "Jerk yourself off."
- interaction_sound = null
- require_user_hands = TRUE
- require_user_penis = REQUIRE_EXPOSED
- user_is_target = TRUE
- max_distance = 0
- write_log_user = "jerked off"
- write_log_target = null
-
-/datum/interaction/lewd/jack/display_interaction(mob/living/carbon/human/user)
- user.do_jackoff(user)
-
-/datum/interaction/lewd/oral/selfsuck
- command = "selfsuck"
- description = "Suck yourself off."
- interaction_sound = null
- require_target_vagina = REQUIRE_NONE
- require_user_penis = REQUIRE_EXPOSED
- user_not_tired = TRUE
- user_is_target = TRUE
- max_distance = 0
- write_log_user = "sucked off"
- write_log_target = null
-
-/datum/interaction/lewd/oral/selfsuck/display_interaction(mob/living/carbon/human/user)
- user.do_oral_self(user, "penis")
-
-/datum/interaction/lewd/oral/suckvagself
- command = "suckvagself"
- description = "Lick your own pussy."
- interaction_sound = null
- require_user_penis = REQUIRE_NONE
- user_not_tired = TRUE
- user_is_target = TRUE
- max_distance = 0
- write_log_user = "Сunni off"
- write_log_target = null
-
-/datum/interaction/lewd/oral/suckvagself/display_interaction(mob/living/carbon/human/user)
- user.do_oral_self(user, "vagina")
-
-/datum/interaction/lewd/breastfuckself
- command = "breastfuckself"
- description = "Fuck your breasts"
- interaction_sound = null
- require_user_penis = REQUIRE_EXPOSED
- require_user_breasts = REQUIRE_EXPOSED
- user_not_tired = TRUE
- user_is_target = TRUE
- max_distance = 0
- write_log_user = "Breastfucked"
- write_log_target = null
-
-/datum/interaction/lewd/breastfuckself/display_interaction(mob/living/carbon/human/user)
- user.do_breastfuck_self(user)
-
-/datum/interaction/lewd/fingerass_self
- command = "fingerm_self"
- description = "Finger yourself."
- interaction_sound = null
- require_user_hands = TRUE
- require_user_anus = REQUIRE_EXPOSED
- user_is_target = TRUE
- max_distance = 0
- write_log_user = "fingered"
- write_log_target = null
-
-/datum/interaction/lewd/fingerass_self/display_interaction(mob/living/carbon/human/user)
- user.do_fingerass_self(user)
-
-/datum/interaction/lewd/finger_self
- command = "finger_self"
- description = "Finger your own pussy."
- require_user_hands = TRUE
- require_user_vagina = REQUIRE_EXPOSED
- interaction_sound = null
- user_is_target = TRUE
- max_distance = 0
- write_log_user = "fingered the pussy of"
- write_log_target = null
-
-/datum/interaction/lewd/finger_self/display_interaction(mob/living/carbon/human/user)
- user.do_fingering_self(user)
-
-/datum/interaction/lewd/titgrope_self
- command = "titgrope_self"
- description = "Grope your own breasts."
- require_user_hands = TRUE
- require_user_breasts = REQUIRE_ANY
- user_is_target = TRUE
- interaction_sound = null
- max_distance = 0
- write_log_user = "groped own breasts"
- write_log_target = null
-
-/datum/interaction/lewd/titgrope_self/display_interaction(mob/living/carbon/human/user)
- user.do_titgrope_self(user)
-
-/datum/interaction/lewd/self_nipsuck
- command = "self_nipsuck"
- description = "Suck your own nips."
- require_user_breasts = REQUIRE_EXPOSED
- require_user_mouth = TRUE
- user_is_target = TRUE
- interaction_sound = null
- max_distance = 0
- write_log_user = "sucked their own nips"
- write_log_target = null
-
-/datum/interaction/lewd/self_nipsuck/display_interaction(mob/living/user, mob/living/target)
- user.do_breastfeed(user)
-
-/*
-/datum/interaction/lewd/remove_self_condom
- command = "remove_self_condom"
- description = "Remove your condom"
- require_user_hands = TRUE
- require_user_penis = REQUIRE_EXPOSED
- user_is_target = TRUE
- interaction_sound = 'modular_sand/sound/lewd/latex.ogg'
- max_distance = 0
- write_log_user = "removed their condom"
- write_log_target = null
-
-/datum/interaction/lewd/remove_self_condom/display_interaction(mob/living/carbon/human/user)
- user.remove_condom(user)
-
-/datum/interaction/lewd/remove_other_condom
- command = "remove_other_condom"
- description = "Remove their condom"
- require_user_hands = TRUE
- require_target_penis = REQUIRE_ANY
- interaction_sound = 'modular_sand/sound/lewd/latex.ogg'
- max_distance = 1
- write_log_target = "got his condom removed by"
- write_log_user = null
-
-/datum/interaction/lewd/remove_other_condom/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.remove_condom(target)
-
-/datum/interaction/lewd/remove_self_sounding
- command = "remove_self_sounding"
- description = "Remove your sounding rod"
- require_user_hands = TRUE
- require_user_penis = REQUIRE_EXPOSED
- user_is_target = TRUE
- interaction_sound = 'modular_sand/sound/lewd/champ_fingering.ogg'
- max_distance = 0
- write_log_user = "removed his sounding rod"
- write_log_target = null
-
-/datum/interaction/lewd/remove_self_sounding/display_interaction(mob/living/carbon/human/user)
- user.remove_sounding(user)
-
-/datum/interaction/lewd/remove_other_sounding
- command = "remove_other_sounding"
- description = "Remove their sounding rod"
- require_user_hands = TRUE
- require_target_penis = REQUIRE_EXPOSED
- interaction_sound = 'modular_sand/sound/lewd/champ_fingering.ogg'
- max_distance = 1
- write_log_target = "got his sounding rod removed by"
- write_log_user = null
-
-/datum/interaction/lewd/remove_other_sounding/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
- user.remove_sounding(target)
-*/
-
-/datum/interaction/lewd/remove_self_equipment
- command = "remove_self_equipment"
- description = "Remove your genital's equipment"
- require_user_hands = TRUE
- interaction_sound = null
- max_distance = 0
- user_is_target = TRUE
- write_log_user = "messed with their genital equipment"
- write_log_target = null
- user_is_target = TRUE
-
-/datum/interaction/lewd/remove_self_equipment/display_interaction(mob/living/user)
- if(!iscarbon(user))
- to_chat(user, "You don't seem like someone who'd use cock equipment my dude")
- return
- user.remove_equipment(user)
-
-/datum/interaction/lewd/remove_other_equipment
- command = "remove_other_equipment"
- description = "Remove their genital's equipment"
- require_user_hands = TRUE
- interaction_sound = null
- max_distance = 1
- write_log_user = null
- write_log_target = "got their genital's equipment edited by"
-
-/datum/interaction/lewd/remove_other_equipment/display_interaction(mob/living/user, mob/living/target)
- if(!iscarbon(target))
- to_chat(user, "[target.p_they()] don't look like someone who'd use balls equipment")
- user.remove_equipment(target)
-
-/datum/interaction/lewd/deflate_belly
- command = "deflate_belly"
- description = "Deflate belly"
- require_user_belly = REQUIRE_EXPOSED
- interaction_sound = null
- max_distance = 0
- user_is_target = TRUE
- write_log_user = "deflated their belly"
- write_log_target = null
-
-/datum/interaction/lewd/deflate_belly/display_interaction(mob/living/carbon/user)
- var/obj/item/organ/genital/belly/gut = user.getorganslot(ORGAN_SLOT_BELLY)
- if(gut)
- gut.modify_size(-1)
-
-/datum/interaction/lewd/nuzzle_belly
- command = "nuzzle_belly"
- description = "Nuzzle their belly"
- require_target_belly = REQUIRE_EXPOSED
- interaction_sound = null
- max_distance = 1
- write_log_target = "got their belly nuzzled by"
- write_log_user = null
-
-/datum/interaction/lewd/nuzzle_belly/display_interaction(mob/living/user, mob/living/target)
- user.nuzzle_belly(target)
diff --git a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/lewd_interactions.dm b/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/lewd_interactions.dm
deleted file mode 100644
index ec5e85be46..0000000000
--- a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/lewd_interactions.dm
+++ /dev/null
@@ -1,614 +0,0 @@
-// If I could have gotten away with using a tilde in the type path, I would have.
-/datum/interaction/lewd
- command = "assslap"
- description = "Slap their ass."
- simple_message = "USER slaps TARGET right on the ass!"
- simple_style = "danger"
- interaction_sound = 'sound/weapons/slap.ogg'
- needs_physical_contact = TRUE
- require_ooc_consent = TRUE
- max_distance = 1
-
- write_log_user = "ass-slapped"
- write_log_target = "was ass-slapped by"
-
- var/user_not_tired = FALSE
- var/target_not_tired = FALSE
- //Avoid using these!
- //Should only really use in case there are no related organs
- //but you want the target or user to be topless/bottomless.
- //Example: Nipple licking/sucking.
- //Otherwise, simply use the "require" vars, which
- //i have changed to actually check for the appropriate organs.
- //This is better because it means that exposing a genital while still
- //wearing something actually means you can do the s*x.
- var/require_user_topless
- var/require_target_topless
- var/require_user_bottomless
- var/require_target_bottomless
- //
-
- //REQUIRE_NONE for doesn't require.
- //REQUIRE_EXPOSED for requires exposed.
- //REQUIRE_ANY for both exposed and unexposed.
- //REQUIRE_UNEXPOSED for requires unexposed.
- var/require_user_penis
- var/require_user_anus
- var/require_user_vagina
- var/require_user_breasts
- var/require_user_feet
- var/require_user_balls
- var/require_user_belly
-
- //Different from the others above. Use the number of required feet.
- var/require_user_num_feet
-
- //Same logic presented before
- var/require_target_penis
- var/require_target_anus
- var/require_target_vagina
- var/require_target_breasts
- var/require_target_feet
- var/require_target_balls
- var/require_target_belly
-
- var/require_target_num_feet
-
- //"just fucking kill me" variables
- //also the same logic as before
- var/extreme = FALSE //Boolean. Used to hide extreme shit from those who do not want it.
- var/require_target_ears
- var/require_target_earsockets
- var/require_target_eyes
- var/require_target_eyesockets
- var/require_user_ears
- var/require_user_earsockets
- var/require_user_eyes
- var/require_user_eyesockets
- //
-
- var/user_refractory_cost
- var/target_refractory_cost
-
-/datum/interaction/lewd/evaluate_user(mob/living/user, silent = TRUE, action_check = TRUE)
- if(..(user, silent, action_check))
- if(user_not_tired && user.get_refraction_dif())
- if(!silent) //bye spam
- to_chat(user, "You're still exhausted from the last time. You need to wait [DisplayTimeText(user.get_refraction_dif(), TRUE)] until you can do that!")
- if(action_check)
- return FALSE
-
- if(require_user_bottomless && !user.is_bottomless())
- if(!silent)
- to_chat(user, "Your pants are in the way.")
- return FALSE
-
- if(require_user_topless && !user.is_topless())
- if(!silent)
- to_chat(user, "Your top is in the way.")
- return FALSE
-
- if(require_user_penis)
- switch(require_user_penis)
- if(REQUIRE_EXPOSED)
- if(!user.has_penis(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Your penis need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!user.has_penis(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "You don't have a penis.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!user.has_penis(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Your penis need to be unexposed.")
- return FALSE
-
- if(require_user_balls)
- switch(require_user_balls)
- if(REQUIRE_EXPOSED)
- if(!user.has_balls(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Your balls need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!user.has_balls(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "You don't have balls.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!user.has_balls(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Your balls need to be unexposed.")
- return FALSE
-
- if(require_user_anus)
- switch(require_user_anus)
- if(REQUIRE_EXPOSED)
- if(!user.has_anus(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Your anus need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!user.has_anus(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "You don't have an anus.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!user.has_anus(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Your anus need to be unexposed.")
- return FALSE
-
- if(require_user_vagina)
- switch(require_user_vagina)
- if(REQUIRE_EXPOSED)
- if(!user.has_vagina(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Your vagina need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!user.has_vagina(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "You don't have a vagina.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!user.has_vagina(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Your vagina need to be unexposed.")
- return FALSE
-
- if(require_user_breasts)
- switch(require_user_breasts)
- if(REQUIRE_EXPOSED)
- if(!user.has_breasts(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Your breasts need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!user.has_breasts(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "You don't have breasts.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!user.has_breasts(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Your breasts need to be unexposed.")
- return FALSE
-
- if(require_user_belly)
- switch(require_user_belly)
- if(REQUIRE_EXPOSED)
- if(!user.has_belly(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Your belly needs to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!user.has_belly(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "Your belly seems to be too flat for that.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!user.has_belly(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Your belly needs to be unexposed.")
- return FALSE
-
- if(require_user_feet)
- switch(require_user_feet)
- if(REQUIRE_EXPOSED)
- if(!user.has_feet(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Your feet need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!user.has_feet(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "You don't have enough feet.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!user.has_feet(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Your feet need to be unexposed.")
- return FALSE
-
- if(require_user_num_feet && (user.get_num_feet() < require_user_num_feet))
- if(!silent)
- to_chat(user, "You don't have enough feet.")
- return FALSE
-
- if(require_user_eyes)
- switch(require_user_eyes)
- if(REQUIRE_EXPOSED)
- if(!user.has_eyes(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Your eyes need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!user.has_eyes(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "You don't have eyes.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!user.has_eyes(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Your eyes need to be unexposed.")
- return FALSE
-
- if(require_user_eyesockets)
- switch(require_user_eyesockets)
- if(REQUIRE_EXPOSED)
- if(!user.has_eyesockets(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Your eyesockets need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!user.has_eyesockets(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "You still have eyes.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!user.has_eyesockets(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Your eyesockets need to be unexposed.")
- return FALSE
-
- if(require_user_ears)
- switch(require_user_ears)
- if(REQUIRE_EXPOSED)
- if(!user.has_ears(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Your ears need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!user.has_ears(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "You don't have ears.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!user.has_ears(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Your ears need to be unexposed.")
- return FALSE
-
- if(require_user_earsockets)
- switch(require_user_earsockets)
- if(REQUIRE_EXPOSED)
- if(!user.has_earsockets(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Your earsockets need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!user.has_earsockets(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "You still have eyes.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!user.has_earsockets(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Your earsockets need to be unexposed.")
- return FALSE
-
- if(extreme)
- var/client/cli = user.client
- if(cli)
- if(cli.prefs.extremepref == "No")
- if(!silent)
- to_chat(user, "That's way too much for you.")
- return FALSE
-
- if(require_ooc_consent)
- if((!user.ckey) || (user.client && user.client.prefs.toggles & VERB_CONSENT))
- return TRUE
- if(action_check)
- return FALSE
- if(action_check)
- return FALSE
-
-/datum/interaction/lewd/evaluate_target(mob/living/user, mob/living/target, silent = TRUE)
- if(..(user, target, silent))
- if(target_not_tired && target.get_refraction_dif())
- if(!silent) //same with this
- to_chat(user, "They're still exhausted from the last time. They need to wait [DisplayTimeText(target.get_refraction_dif(), TRUE)] until you can do that!")
- return FALSE
-
- if(require_target_penis)
- switch(require_target_penis)
- if(REQUIRE_EXPOSED)
- if(!target.has_penis(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Their penis needs to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!target.has_penis(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "They don't have a penis.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!target.has_penis(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Their penis needs to be unexposed.")
- return FALSE
-
- if(require_target_balls)
- switch(require_target_balls)
- if(REQUIRE_EXPOSED)
- if(!target.has_balls(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Their balls need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!target.has_balls(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "They don't have balls.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!target.has_balls(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Their balls need to be unexposed.")
- return FALSE
-
- if(require_target_anus)
- switch(require_target_anus)
- if(REQUIRE_EXPOSED)
- if(!target.has_anus(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Their anus needs to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!target.has_anus(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "They don't have an anus.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!target.has_anus(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Their anus needs to be unexposed.")
- return FALSE
-
- if(require_target_vagina)
- switch(require_target_vagina)
- if(REQUIRE_EXPOSED)
- if(!target.has_vagina(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Their vagina needs to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!target.has_vagina(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "They don't have a vagina.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!target.has_vagina(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Their vagina needs to be unexposed.")
- return FALSE
-
- if(require_target_breasts)
- switch(require_target_breasts)
- if(REQUIRE_EXPOSED)
- if(!target.has_breasts(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Their breasts need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!target.has_breasts(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "They don't have breasts.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!target.has_breasts(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Their breasts need to be unexposed.")
- return FALSE
-
- if(require_target_belly)
- switch(require_target_belly)
- if(REQUIRE_EXPOSED)
- if(!target.has_belly(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Their belly needs to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!target.has_belly(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "Their belly seems to be too flat for that.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!target.has_belly(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Their belly needs to be unexposed.")
- return FALSE
-
- if(require_target_feet)
- switch(require_target_feet)
- if(REQUIRE_EXPOSED)
- if(!target.has_feet(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Their feet need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!target.has_feet(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "They don't have enough feet.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!target.has_feet(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Their feet need to be unexposed.")
- return FALSE
-
- if(require_target_num_feet && (target.get_num_feet() < require_target_num_feet))
- if(!silent)
- to_chat(user, "They don't have enough feet.")
- return FALSE
-
- if(require_target_eyes)
- switch(require_target_eyes)
- if(REQUIRE_EXPOSED)
- if(!target.has_eyes(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Their eyes need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!target.has_eyes(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "They don't have eyes.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!target.has_eyes(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Their eyes need to be unexposed.")
- return FALSE
-
- if(require_target_eyesockets)
- switch(require_target_eyesockets)
- if(REQUIRE_EXPOSED)
- if(!target.has_eyesockets(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Their eyesockets need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!target.has_eyesockets(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "They still have eyes.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!target.has_eyesockets(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Their eyesockets need to be unexposed.")
- return FALSE
-
- if(require_target_ears)
- switch(require_target_ears)
- if(REQUIRE_EXPOSED)
- if(!target.has_ears(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Their ears need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!target.has_ears(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "They don't have ears.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!target.has_ears(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Their ears need to be unexposed.")
- return FALSE
-
- if(require_target_earsockets)
- switch(require_target_earsockets)
- if(REQUIRE_EXPOSED)
- if(!target.has_earsockets(REQUIRE_EXPOSED))
- if(!silent)
- to_chat(user, "Their earsockets need to be exposed.")
- return FALSE
- if(REQUIRE_ANY)
- if(!target.has_earsockets(REQUIRE_ANY))
- if(!silent)
- to_chat(user, "They still have eyes.")
- return FALSE
- if(REQUIRE_UNEXPOSED)
- if(!target.has_earsockets(REQUIRE_UNEXPOSED))
- if(!silent)
- to_chat(user, "Their earsockets need to be unexposed.")
- return FALSE
-
- if(require_target_bottomless && !target.is_bottomless())
- if(!silent)
- to_chat(user, "Their pants are in the way.")
- return FALSE
-
- if(require_target_topless && !target.is_topless())
- if(!silent)
- to_chat(user, "Their clothes are in the way.")
- return FALSE
-
- if(extreme)
- var/client/cli = target.client
- if(cli)
- if(target.client.prefs.extremepref == "No")
- if(!silent)
- to_chat(user, "For some reason, you don't want to do this to [target].")
- return FALSE
-
- if(require_ooc_consent)
- if((!target.ckey) || (target.client && target.client.prefs.toggles & VERB_CONSENT)) //sneaky change, let hell go through earth
- return TRUE
- return FALSE
- return FALSE
-
-/datum/interaction/lewd/post_interaction(mob/living/user, mob/living/target)
- if(user_refractory_cost)
- user.refractory_period = world.time + user_refractory_cost*10
- if(target_refractory_cost)
- target.refractory_period = world.time + target_refractory_cost*10
- user.last_lewd_datum = src
- if(user.cleartimer)
- deltimer(user.cleartimer)
- user.cleartimer = addtimer(CALLBACK(user, /mob/living/proc/clear_lewd_datum), 300, TIMER_STOPPABLE)
- return ..()
-
-/mob/living/list_interaction_attributes(var/mob/living/LM)
- var/dat = ..()
- if(get_refraction_dif())
- dat += "...are sexually exhausted for the time being."
- switch(a_intent)
- if(INTENT_HELP)
- dat += "...are acting gentle."
- if(INTENT_DISARM)
- dat += "...are acting playful."
- if(INTENT_GRAB)
- dat += "...are acting rough."
- if(INTENT_HARM)
- dat += "...are fighting anyone who comes near."
- //Here comes the fucking weird shit.
- if(client)
- var/client/cli = client
- var/client/ucli = LM.client
- if(cli.prefs.extremepref != "No")
- if(!ucli || (ucli.prefs.extremepref != "No"))
- if(!get_item_by_slot(ITEM_SLOT_EARS_LEFT) && !get_item_by_slot(ITEM_SLOT_EARS_RIGHT))
- if(has_ears())
- dat += "...have unprotected ears."
- else
- dat += "...have a hole where their ears should be."
- else
- dat += "...have covered ears."
- if(!get_item_by_slot(ITEM_SLOT_EYES))
- if(has_eyes())
- dat += "...have exposed eyes."
- else
- dat += "...have exposed eyesockets."
- else
- dat += "...have covered eyes."
- //
- if(is_topless() && is_bottomless())
- dat += "...are naked."
- else
- if((is_topless() && !is_bottomless()) || (!is_topless() && is_bottomless()))
- dat += "...are partially clothed."
- else
- dat += "...are clothed."
- if(has_breasts(REQUIRE_EXPOSED))
- dat += "...have breasts."
- if(has_penis(REQUIRE_EXPOSED))
- dat += "...have a penis."
- if(has_balls(REQUIRE_EXPOSED))
- dat += "...have a ballsack."
- if(has_vagina(REQUIRE_EXPOSED))
- dat += "...have a vagina."
- if(has_anus(REQUIRE_EXPOSED))
- dat += "...have an anus."
- if(has_belly(REQUIRE_EXPOSED))
- dat += "...have a belly"
- if(has_feet(REQUIRE_EXPOSED))
- switch(has_feet(REQUIRE_EXPOSED))
- if(2)
- dat += "...have a pair of feet."
- if(1)
- dat += "...have a single foot."
- return dat
diff --git a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/lewd_species.dm b/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/lewd_species.dm
deleted file mode 100644
index bf8c9e55a9..0000000000
--- a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/lewd_species.dm
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Seriously this is the worst way to do this,
- * warn me if there's ANY reason i would ever
- * use this. Humans have GENITALS, ACTUAL ORGANS,
- * we don't need to check booleans!
- * If this does not get an use sometime,
- * i want this file gone.
- */
-
-/*
-/datum/species
- var/has_genitals = TRUE //if this goes to 2, blame coders
- var/has_anus = TRUE //same with this
- var/has_breasts = FALSE
-
-/datum/species/proc/has_penis(mob/living/carbon/human/H)
- return has_genitals && H.has_penis
-
-/datum/species/proc/has_vagina(mob/living/carbon/human/H)
- return has_genitals && H.has_vagina
-
-/datum/species/proc/has_anus(mob/living/carbon/human/H)
- return has_anus
-
-/datum/species/proc/has_breasts(mob/living/carbon/human/H)
- return has_breasts
-*/
diff --git a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/objects.dm b/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/objects.dm
deleted file mode 100644
index c68d027c22..0000000000
--- a/modular_splurt/code/datums/interactions/lewd/old_sandstorm_backup/lewd/objects.dm
+++ /dev/null
@@ -1,59 +0,0 @@
-//Dildo changes.
-/obj/item/dildo
- var/hole = CUM_TARGET_VAGINA
-
-/obj/item/dildo/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
- var/possessive_verb = user.p_their()
- var/message = ""
- var/lust_amt = 0
- if(ishuman(M) && (M?.client?.prefs?.toggles & VERB_CONSENT))
- switch(user.zone_selected)
- if(BODY_ZONE_PRECISE_GROIN)
- switch(hole)
- if(CUM_TARGET_VAGINA)
- if(M.has_vagina(REQUIRE_EXPOSED))
- message = (user == M) ? pick("fucks [possessive_verb] own pussy with \the [src]","shoves \the [src] into [possessive_verb] pussy", "jams \the [src] into [possessive_verb] pussy") : pick("fucks [M] right in the pussy with \the [src]", "jams \the [src] right into [M]'s pussy")
- lust_amt = NORMAL_LUST
- if(CUM_TARGET_ANUS)
- if(M.has_anus(REQUIRE_EXPOSED))
- message = (user == M) ? pick("fucks [possessive_verb] own ass with \the [src]","shoves \the [src] into [possessive_verb] ass", "jams \the [src] into [possessive_verb] ass") : pick("fucks [M]'s asshole with \the [src]", "jams \the [src] into [M]'s ass")
- lust_amt = NORMAL_LUST
- if(BODY_ZONE_PRECISE_MOUTH)
- if(M.has_mouth() && !M.is_mouth_covered())
- message = (user == M) ? pick("fucks [possessive_verb] own mouth with \the [src]", "shoves \the [src] into [possessive_verb] mouth", "jams \the [src] into [possessive_verb] mouth") : pick("fucks [M]'s mouth with \the [src]", "jams \the [src] into [M]'s mouth")
- if(message)
- user.visible_message("[user] [message].")
- M.handle_post_sex(lust_amt, null, user)
- playsound(loc, pick('modular_sand/sound/interactions/bang4.ogg',
- 'modular_sand/sound/interactions/bang5.ogg',
- 'modular_sand/sound/interactions/bang6.ogg'), 70, 1, -1)
- else if(user.a_intent == INTENT_HARM)
- return ..()
-
-/obj/item/dildo/attack_self(mob/living/carbon/human/user as mob)
- hole = hole == CUM_TARGET_VAGINA ? CUM_TARGET_ANUS : CUM_TARGET_VAGINA
- to_chat(user, "Now targetting \the [hole].")
-
-//begin redds code
-/obj/item/dildo/cyborg
- name = "F.I.S.T.R. Machine"
- desc = "Fully Integrated Sexual Tension Relief Machine"
-//end redds code
-
-/obj/item/pneumatic_cannon/dildo
- color = "#FFC0CB"
- name = "pneumatic cannon"
- desc = "A pneumatic cannon with a picture of a bus printed on the side that resembles an A-shape."
- automatic = TRUE
- selfcharge = TRUE
- gasPerThrow = 0
- checktank = FALSE
- fire_mode = PCANNON_FIFO
- throw_amount = 1
- maxWeightClass = 60
- var/static/list/dildo_typecache = typecacheof(/obj/item/dildo)
- charge_type = /obj/item/dildo
-
-/obj/item/pneumatic_cannon/dildo/Initialize()
- . = ..()
- allowed_typecache = dildo_typecache
diff --git a/modular_splurt/code/modules/admin/verbs/discordbunker.dm b/modular_splurt/code/modules/admin/verbs/discordbunker.dm
index 46d5db257b..149479289a 100644
--- a/modular_splurt/code/modules/admin/verbs/discordbunker.dm
+++ b/modular_splurt/code/modules/admin/verbs/discordbunker.dm
@@ -10,8 +10,8 @@
log_admin("[key_name(usr)] has toggled the Discord Bunker, it is now [new_dbun ? "on" : "off"]")
message_admins("[key_name_admin(usr)] has toggled the Discord Bunker, it is now [new_dbun ? "enabled" : "disabled"].")
- SSblackbox.record_feedback("nested tally", "discord_toggle", 1, list("Toggle Panic Bunker", "[new_dbun ? "Enabled" : "Disabled"]"))
- send2adminchat("Discord Bunker", "[key_name(usr)] has toggled the Panic Bunker, it is now [new_dbun ? "enabled" : "disabled"].")
+ SSblackbox.record_feedback("nested tally", "discord_toggle", 1, list("Toggle Discord Bunker", "[new_dbun ? "Enabled" : "Disabled"]"))
+ send2adminchat("Discord Bunker", "[key_name(usr)] has toggled the Discord Bunker, it is now [new_dbun ? "enabled" : "disabled"].")
/client/proc/adddiscordbypass(ckeytobypass as text) // In case someone's too lazy to verify on discord
set category = "Special Verbs"
diff --git a/modular_splurt/code/modules/admin/verbs/vpnbunker.dm b/modular_splurt/code/modules/admin/verbs/vpnbunker.dm
new file mode 100644
index 0000000000..af09e96427
--- /dev/null
+++ b/modular_splurt/code/modules/admin/verbs/vpnbunker.dm
@@ -0,0 +1,37 @@
+/client/proc/vpnbunker()
+ set category = "Server"
+ set name = "Toggle VPN Blocker"
+
+ var/new_vpnbun = !CONFIG_GET(flag/kick_vpn)
+ CONFIG_SET(flag/kick_vpn, new_vpnbun)
+
+ log_admin("[key_name(usr)] has toggled the VPN Blocker, it is now [new_vpnbun ? "on" : "off"]")
+ message_admins("[key_name_admin(usr)] has toggled the VPN Blocker, it is now [new_vpnbun ? "enabled" : "disabled"].")
+ SSblackbox.record_feedback("nested tally", "vpn_toggle", 1, list("Toggle VPN Blocker", "[new_vpnbun ? "Enabled" : "Disabled"]"))
+ send2adminchat("VPN Blocker", "[key_name(usr)] has toggled the VPN Bunker, it is now [new_vpnbun ? "enabled" : "disabled"].")
+
+/client/proc/addvpnbypass(ckeytobypass as text)
+ set category = "Special Verbs"
+ set name = "Add VPN Bypass"
+ set desc = "Allows a given ckey to connect through the VPN Blocker."
+ if(!CONFIG_GET(flag/kick_vpn))
+ to_chat(usr, span_adminnotice("VPN Blocker is currently off!"))
+
+ var/datum/config_entry/multi_keyed_flag/vpn_bypass/bypasses = CONFIG_GET_ENTRY(multi_keyed_flag/vpn_bypass)
+ bypasses.add_bypass(ckeytobypass)
+ log_admin("[key_name(usr)] has added [ckeytobypass] to the current round's VPN bypass list.")
+ message_admins("[key_name_admin(usr)] has added [ckeytobypass] to the current round's VPN bypass list.")
+ send2adminchat("VPN Blocker", "[key_name(usr)] has added [ckeytobypass] to the current round's VPN bypass list.")
+
+/client/proc/revokevpnbypass(ckeytobypass as text)
+ set category = "Special Verbs"
+ set name = "Revoke VPN Bypass"
+ set desc = "Removes a ckey from the VPN Blocker bypass list."
+ if(!CONFIG_GET(flag/kick_vpn))
+ to_chat(usr, span_adminnotice("VPN Blocker is currently off!"))
+
+ var/datum/config_entry/multi_keyed_flag/vpn_bypass/bypasses = CONFIG_GET_ENTRY(multi_keyed_flag/vpn_bypass)
+ bypasses.rev_bypass(ckeytobypass)
+ log_admin("[key_name(usr)] has removed [ckeytobypass] from the current round's VPN bypass list.")
+ message_admins("[key_name_admin(usr)] has removed [ckeytobypass] from the current round's VPN bypass list.")
+ send2adminchat("VPN Blocker", "[key_name(usr)] has removed [ckeytobypass] from the current round's VPN bypass list.")
diff --git a/modular_splurt/code/modules/client/client_procs.dm b/modular_splurt/code/modules/client/client_procs.dm
index 0da99d96de..7f82c94449 100644
--- a/modular_splurt/code/modules/client/client_procs.dm
+++ b/modular_splurt/code/modules/client/client_procs.dm
@@ -1,7 +1,25 @@
/client/check_ip_intel()
. = ..()
- if(ip_intel != initial(ip_intel) && ip_intel >= CONFIG_GET(number/ipintel_rating_bad))
- uses_vpn = TRUE
+ if(!(ip_intel != initial(ip_intel) && ip_intel >= CONFIG_GET(number/ipintel_rating_bad)))
+ uses_vpn = FALSE
+ return .
+
+ uses_vpn = TRUE //Puts the vpn flag on the player playtimes
+
+ //Kicks them automatically if 100% sure and they're not whitelisted
+ if(!CONFIG_GET(flag/kick_vpn) || ip_intel < 1)
+ return .
+ var/list/whitelist = CONFIG_GET(multi_keyed_flag/vpn_bypass)
+ if(whitelist.Find(ckey(ckey)))
+ log_admin("[key_name(src)] was allowed to join although they're using a vpn")
+ return .
+
+ to_chat(src, span_danger("You have been kicked from the server because your IP has been flagged as a VPN. \
+ Please turn it off in order to connect or contact staff in case this is an error."))
+ var/logg = "[key_name(src)] kicked for failing the vpn check."
+ log_admin(logg)
+ message_admins(span_adminnotice(logg))
+ qdel(src)
/client/proc/toggle_quirk(mob/living/carbon/human/H)
if (!istype(H))
diff --git a/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/hair_head.dm b/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/hair_head.dm
index 33afbdd858..13edb7d3a7 100644
--- a/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/hair_head.dm
+++ b/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/hair_head.dm
@@ -106,3 +106,18 @@
icon_state = "pod_hair_hibiscus"
icon = 'modular_splurt/icons/mob/hair.dmi'
recommended_species = list(SPECIES_POD, SPECIES_POD_WEAK)
+
+/datum/sprite_accessory/hair/emma
+ name = "Emma"
+ icon = 'modular_splurt/icons/mob/hair.dmi'
+ icon_state = "hair_emma"
+
+/datum/sprite_accessory/hair/immovable
+ name = "Ozen"
+ icon = 'modular_splurt/icons/mob/hair.dmi'
+ icon_state = "hair_immovable"
+
+/datum/sprite_accessory/hair/damsel
+ name = "Damsel"
+ icon = 'modular_splurt/icons/mob/hair.dmi'
+ icon_state = "hair_damsel"
diff --git a/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/horns.dm b/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/horns.dm
index b797a3ab08..b44cac9fd8 100644
--- a/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/horns.dm
+++ b/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/horns.dm
@@ -26,3 +26,8 @@
name = "Broken (Left)"
icon = 'modular_splurt/icons/mob/mutant_bodyparts.dmi'
icon_state = "broken-left"
+
+/datum/sprite_accessory/horns/albedo_horns
+ name = "Succ horns" // Not sure if I'll change that later
+ icon = 'modular_splurt/icons/mob/mutant_bodyparts.dmi'
+ icon_state = "albedo"
diff --git a/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/tails.dm b/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/tails.dm
index 402661857d..7fefe274bc 100644
--- a/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/tails.dm
+++ b/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/tails.dm
@@ -310,3 +310,17 @@
color_src = MATRIXED
icon = 'modular_splurt/icons/mob/mam_tails.dmi'
matrixed_sections = MATRIX_RED
+
+/datum/sprite_accessory/tails/mam_tails/westerndragon
+ name = "Dragon western"
+ icon = 'modular_splurt/icons/mob/64_mam_tails.dmi'
+ icon_state = "westerndragon"
+ dimension_x = 64
+ center = TRUE
+ matrixed_sections = MATRIX_RED_GREEN
+
+/datum/sprite_accessory/tails/human/succubus
+ name = "Succubus tail"
+ icon = 'modular_splurt/icons/mob/mam_tails.dmi'
+ icon_state = "succubus"
+ color_src = MUTCOLORS
diff --git a/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/wings.dm b/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/wings.dm
index 2bde7f9a4b..3169d94ade 100644
--- a/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/wings.dm
+++ b/modular_splurt/code/modules/mob/dead/new_player/sprite_accesories/wings.dm
@@ -108,3 +108,10 @@
color_src = MATRIXED
matrixed_sections = MATRIX_ALL
relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER)
+
+/datum/sprite_accessory/deco_wings/harpy
+ name = "Harpy (large)"
+ icon_state = "harpy"
+ icon = 'modular_splurt/icons/mob/64_wings.dmi'
+ dimension_x = 64
+ center = TRUE
diff --git a/modular_splurt/code/modules/mob/splurt_emotes.dm b/modular_splurt/code/modules/mob/splurt_emotes.dm
index 5a312bbce1..9ddd9f5e01 100644
--- a/modular_splurt/code/modules/mob/splurt_emotes.dm
+++ b/modular_splurt/code/modules/mob/splurt_emotes.dm
@@ -588,6 +588,45 @@
user.nextsoundemote = world.time + 10
playsound(user, 'modular_splurt/sound/voice/waterphone.ogg', 50, 1, -1)
+/datum/emote/living/weh2
+ key = "weh2"
+ key_third_person = "wehs2"
+ message = "let out a weh!"
+
+/datum/emote/living/weh2/run_emote(mob/user, params, type_override, intentional)
+ if(!(. = ..()))
+ return
+ if(user.nextsoundemote >= world.time)
+ return
+ user.nextsoundemote = world.time + 7
+ playsound(user, 'modular_splurt/sound/voice/weh2.ogg', 50, 1, -1)
+
+/datum/emote/living/weh3
+ key = "weh3"
+ key_third_person = "wehs3"
+ message = "let out a weh!"
+
+/datum/emote/living/weh3/run_emote(mob/user, params, type_override, intentional)
+ if(!(. = ..()))
+ return
+ if(user.nextsoundemote >= world.time)
+ return
+ user.nextsoundemote = world.time + 7
+ playsound(user, 'modular_splurt/sound/voice/weh3.ogg', 50, 1, -1)
+
+/datum/emote/living/weh4
+ key = "weh-s"
+ key_third_person = "wehs4"
+ message = "let out a surprised weh!"
+
+/datum/emote/living/weh4/run_emote(mob/user, params, type_override, intentional)
+ if(!(. = ..()))
+ return
+ if(user.nextsoundemote >= world.time)
+ return
+ user.nextsoundemote = world.time + 7
+ playsound(user, 'modular_splurt/sound/voice/weh_s.ogg', 50, 1, -1)
+
/datum/emote/living/snore/snore2
key = "snore2"
key_third_person = "snores"
diff --git a/modular_splurt/icons/mob/64_mam_tails.dmi b/modular_splurt/icons/mob/64_mam_tails.dmi
new file mode 100644
index 0000000000..9bea4c30a3
Binary files /dev/null and b/modular_splurt/icons/mob/64_mam_tails.dmi differ
diff --git a/modular_splurt/icons/mob/64_wings.dmi b/modular_splurt/icons/mob/64_wings.dmi
new file mode 100644
index 0000000000..c3e12071a3
Binary files /dev/null and b/modular_splurt/icons/mob/64_wings.dmi differ
diff --git a/modular_splurt/icons/mob/hair.dmi b/modular_splurt/icons/mob/hair.dmi
index d189236c19..1bb0ccf7be 100644
Binary files a/modular_splurt/icons/mob/hair.dmi and b/modular_splurt/icons/mob/hair.dmi differ
diff --git a/modular_splurt/icons/mob/mam_tails.dmi b/modular_splurt/icons/mob/mam_tails.dmi
index e4139d3edd..3650e3f819 100644
Binary files a/modular_splurt/icons/mob/mam_tails.dmi and b/modular_splurt/icons/mob/mam_tails.dmi differ
diff --git a/modular_splurt/icons/mob/mutant_bodyparts.dmi b/modular_splurt/icons/mob/mutant_bodyparts.dmi
index f1cbf6eb03..9010a8b35a 100644
Binary files a/modular_splurt/icons/mob/mutant_bodyparts.dmi and b/modular_splurt/icons/mob/mutant_bodyparts.dmi differ
diff --git a/modular_splurt/sound/effects/pan0.ogg b/modular_splurt/sound/effects/pan0.ogg
new file mode 100644
index 0000000000..123a83a919
Binary files /dev/null and b/modular_splurt/sound/effects/pan0.ogg differ
diff --git a/modular_splurt/sound/effects/pan1.ogg b/modular_splurt/sound/effects/pan1.ogg
new file mode 100644
index 0000000000..a63ad14de2
Binary files /dev/null and b/modular_splurt/sound/effects/pan1.ogg differ
diff --git a/modular_splurt/sound/voice/weh2.ogg b/modular_splurt/sound/voice/weh2.ogg
new file mode 100644
index 0000000000..516ed5af30
Binary files /dev/null and b/modular_splurt/sound/voice/weh2.ogg differ
diff --git a/modular_splurt/sound/voice/weh3.ogg b/modular_splurt/sound/voice/weh3.ogg
new file mode 100644
index 0000000000..0d50a6db3e
Binary files /dev/null and b/modular_splurt/sound/voice/weh3.ogg differ
diff --git a/modular_splurt/sound/voice/weh_s.ogg b/modular_splurt/sound/voice/weh_s.ogg
new file mode 100644
index 0000000000..2da9f4bbe9
Binary files /dev/null and b/modular_splurt/sound/voice/weh_s.ogg differ
diff --git a/rust_g.dll b/rust_g.dll
index bb3082e984..2197a22465 100644
Binary files a/rust_g.dll and b/rust_g.dll differ
diff --git a/sound/effects/body-armor-rolling.ogg b/sound/effects/body-armor-rolling.ogg
new file mode 100644
index 0000000000..220e6b4584
Binary files /dev/null and b/sound/effects/body-armor-rolling.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index d77b607ffa..6f4930a6b1 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -249,6 +249,7 @@
#include "code\__SPLURTCODE\DEFINES\atmospherics.dm"
#include "code\__SPLURTCODE\DEFINES\cit_defines.dm"
#include "code\__SPLURTCODE\DEFINES\click.dm"
+#include "code\__SPLURTCODE\DEFINES\configuration.dm"
#include "code\__SPLURTCODE\DEFINES\cooldowns.dm"
#include "code\__SPLURTCODE\DEFINES\genital_defines.dm"
#include "code\__SPLURTCODE\DEFINES\hud.dm"
@@ -444,6 +445,7 @@
#include "code\controllers\subsystem\radio.dm"
#include "code\controllers\subsystem\research.dm"
#include "code\controllers\subsystem\runechat.dm"
+#include "code\controllers\subsystem\security_level.dm"
#include "code\controllers\subsystem\server_maint.dm"
#include "code\controllers\subsystem\shuttle.dm"
#include "code\controllers\subsystem\sound_loops.dm"
@@ -4243,7 +4245,9 @@
#include "modular_splurt\code\_onclick\hud\screen_objects.dm"
#include "modular_splurt\code\_rendering\fullscreen\fullscreen.dm"
#include "modular_splurt\code\controllers\configuration\entries\splurt_comms.dm"
+#include "modular_splurt\code\controllers\configuration\entries\splurt_connections.dm"
#include "modular_splurt\code\controllers\configuration\entries\splurt_discord.dm"
+#include "modular_splurt\code\controllers\configuration\entries\splurt_donator.dm"
#include "modular_splurt\code\controllers\configuration\entries\splurt_fetish_content.dm"
#include "modular_splurt\code\controllers\configuration\entries\splurt_general.dm"
#include "modular_splurt\code\controllers\configuration\entries\splurt_maps.dm"
@@ -4405,6 +4409,7 @@
#include "modular_splurt\code\modules\admin\verbs\one_click_antag.dm"
#include "modular_splurt\code\modules\admin\verbs\pray.dm"
#include "modular_splurt\code\modules\admin\verbs\randomverbs.dm"
+#include "modular_splurt\code\modules\admin\verbs\vpnbunker.dm"
#include "modular_splurt\code\modules\antagonists\_common\antag_spawner.dm"
#include "modular_splurt\code\modules\antagonists\bloodsucker\levelup.dm"
#include "modular_splurt\code\modules\antagonists\ert_cleanup\ert_cleanup.dm"