diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm
index 6712e631a7..27c4f5074b 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm
@@ -198,6 +198,7 @@
/obj/structure/stone_tile{
dir = 4
},
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered/ash_walkers)
"aC" = (
@@ -287,6 +288,7 @@
/obj/structure/stone_tile/cracked{
dir = 4
},
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered/ash_walkers)
"aN" = (
@@ -305,6 +307,7 @@
/area/ruin/unpowered/ash_walkers)
"aP" = (
/obj/structure/stone_tile,
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered/ash_walkers)
"aQ" = (
@@ -379,6 +382,7 @@
/obj/structure/stone_tile/cracked{
dir = 1
},
+/obj/item/dildo/custom,
/turf/open/indestructible/boss,
/area/ruin/unpowered/ash_walkers)
"aZ" = (
@@ -401,6 +405,7 @@
/obj/structure/stone_tile{
dir = 4
},
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered/ash_walkers)
"bb" = (
@@ -489,6 +494,7 @@
dir = 4
},
/obj/item/storage/bag/plants/portaseeder,
+/obj/item/dildo/custom,
/turf/open/indestructible/boss,
/area/ruin/unpowered/ash_walkers)
"bk" = (
@@ -509,6 +515,7 @@
/obj/structure/stone_tile/cracked{
dir = 1
},
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered/ash_walkers)
"bm" = (
@@ -568,6 +575,7 @@
/obj/structure/stone_tile{
dir = 8
},
+/obj/item/dildo/custom,
/turf/open/indestructible/boss/air,
/area/ruin/unpowered/ash_walkers)
"br" = (
@@ -897,6 +905,7 @@
/obj/structure/stone_tile/surrounding_tile/cracked{
dir = 8
},
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
"ci" = (
@@ -1042,6 +1051,7 @@
icon_state = "cracked_slab1";
dir = 4
},
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered/ash_walkers)
"cB" = (
@@ -1475,6 +1485,26 @@
/obj/structure/stone_tile,
/turf/closed/mineral/volcanic,
/area/lavaland/surface/outdoors)
+"dG" = (
+/obj/structure/stone_tile/slab,
+/obj/item/dildo/custom,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"dH" = (
+/obj/structure/stone_tile/block/cracked,
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/item/dildo/custom,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"dI" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/item/dildo/custom,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
(1,1,1) = {"
aa
@@ -1597,7 +1627,7 @@ aO
bl
bx
bD
-bS
+dG
de
bV
dg
@@ -1625,7 +1655,7 @@ ci
bA
ct
bN
-bL
+dI
cI
ah
ah
@@ -1732,7 +1762,7 @@ ak
bP
bL
bX
-dh
+dH
do
du
dz
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index dcd0717e29..1ef76788eb 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -24665,7 +24665,7 @@
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plating,
-/area/maintenance/aft)
+/area/maintenance/department/medical/morgue)
"bgp" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on,
/turf/open/floor/plasteel/white,
@@ -26862,7 +26862,7 @@
dir = 4
},
/turf/open/floor/plating,
-/area/maintenance/aft)
+/area/maintenance/department/medical/morgue)
"blh" = (
/obj/structure/table/reinforced,
/obj/machinery/door/window/eastright{
@@ -26940,7 +26940,7 @@
dir = 4
},
/turf/open/floor/plating,
-/area/maintenance/aft)
+/area/maintenance/department/medical/morgue)
"blp" = (
/obj/machinery/power/apc{
dir = 8;
@@ -26974,7 +26974,7 @@
dir = 4
},
/turf/open/floor/plating,
-/area/maintenance/aft)
+/area/maintenance/department/medical/morgue)
"blr" = (
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
dir = 4
@@ -29030,7 +29030,7 @@
},
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
-/area/maintenance/aft)
+/area/maintenance/department/medical/morgue)
"bpR" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/structure/disposalpipe/segment{
@@ -60163,7 +60163,7 @@
icon_state = "2-4"
},
/turf/open/floor/plating,
-/area/maintenance/aft)
+/area/maintenance/department/medical/morgue)
"cHE" = (
/obj/machinery/door/airlock/maintenance{
name = "Mech Bay Maintenance";
@@ -63862,6 +63862,167 @@
},
/turf/open/floor/plating,
/area/maintenance/starboard/aft)
+"cTJ" = (
+/obj/machinery/door/airlock/maintenance{
+ req_access_txt = "12"
+ },
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTK" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTL" = (
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/structure/cable{
+ d1 = 2;
+ d2 = 4;
+ icon_state = "2-4"
+ },
+/turf/open/floor/plasteel/black,
+/area/medical/morgue)
+"cTM" = (
+/obj/machinery/power/apc{
+ dir = 4;
+ name = "Morgue Maintenance APC";
+ areastring = "/area/maintenance/department/medical/morgue";
+ pixel_x = 26
+ },
+/obj/structure/cable{
+ d2 = 8;
+ icon_state = "0-8"
+ },
+/turf/open/floor/plasteel/black,
+/area/medical/morgue)
+"cTN" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTO" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/cable{
+ d1 = 4;
+ d2 = 8;
+ icon_state = "4-8"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTP" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/cable{
+ d1 = 4;
+ d2 = 8;
+ icon_state = "4-8"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTQ" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/cable{
+ d1 = 4;
+ d2 = 8;
+ icon_state = "4-8"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTR" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/cable{
+ d1 = 4;
+ d2 = 8;
+ icon_state = "4-8"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTS" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTT" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTU" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTV" = (
+/obj/machinery/door/airlock/maintenance{
+ req_access_txt = "12"
+ },
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
(1,1,1) = {"
aaa
@@ -103574,7 +103735,7 @@ bfL
bhp
biB
biB
-biB
+cTL
bkU
bmX
bpE
@@ -103831,7 +103992,7 @@ bfL
bhq
bhm
bkb
-bhm
+cTM
bla
bmZ
bpH
@@ -104346,7 +104507,7 @@ bfS
biC
bkd
bfS
-bKH
+cTO
bmZ
bpJ
brc
@@ -104860,7 +105021,7 @@ bfS
biE
bkf
bfS
-bKH
+cTP
bmZ
bpL
bre
@@ -105117,7 +105278,7 @@ bfS
biD
bke
bfS
-bKH
+cTQ
bmZ
bpK
brd
@@ -105374,7 +105535,7 @@ bfS
bfS
bfS
bfS
-bKH
+cTR
bmZ
bon
bon
@@ -105626,17 +105787,17 @@ aYV
baR
bcb
bdl
-bdO
+cTJ
cHD
bgo
-bPv
-bPv
+cTK
+cTN
blq
-bna
-bPv
+cTS
+cTT
bpQ
-bPv
-bdO
+cTU
+cTV
btm
buy
bvz
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 5809176275..efae305c74 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -91795,7 +91795,7 @@
"dwO" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/closed/wall,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dwP" = (
/obj/machinery/door/firedoor,
/obj/structure/cable/white{
@@ -91815,7 +91815,7 @@
dir = 1
},
/turf/open/floor/plasteel,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dwQ" = (
/obj/structure/table/glass,
/obj/item/clipboard,
@@ -92448,7 +92448,7 @@
/turf/open/floor/plasteel/vault{
dir = 5
},
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dyb" = (
/obj/structure/bed/roller,
/obj/machinery/iv_drip,
@@ -92456,12 +92456,12 @@
/turf/open/floor/plasteel/vault{
dir = 5
},
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dyc" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dyd" = (
/obj/structure/cable/white{
d1 = 1;
@@ -92470,7 +92470,7 @@
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dye" = (
/obj/structure/table/glass,
/obj/item/folder/white,
@@ -92923,12 +92923,12 @@
"dzf" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plasteel/neutral,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dzg" = (
/obj/effect/decal/cleanable/blood/old,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dzh" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable/white{
@@ -92938,14 +92938,14 @@
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dzi" = (
/obj/structure/table,
/obj/effect/decal/cleanable/dirt,
/obj/item/storage/backpack/duffelbag/med,
/obj/item/device/flashlight/pen,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dzj" = (
/turf/closed/wall,
/area/crew_quarters/heads/cmo)
@@ -93674,7 +93674,7 @@
dir = 4
},
/turf/open/floor/plasteel,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dAw" = (
/obj/structure/cable/white{
d1 = 4;
@@ -93687,7 +93687,7 @@
/turf/open/floor/plasteel/vault{
dir = 5
},
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dAx" = (
/obj/structure/cable/white{
d1 = 4;
@@ -93699,7 +93699,7 @@
dir = 1
},
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dAy" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable/white{
@@ -93712,7 +93712,7 @@
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dAz" = (
/obj/structure/cable/white{
d1 = 1;
@@ -93733,14 +93733,14 @@
dir = 4
},
/turf/open/floor/plasteel/neutral,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dAA" = (
/obj/structure/table,
/obj/item/clothing/gloves/color/latex/nitrile,
/obj/item/clothing/suit/apron/surgical,
/obj/item/clothing/mask/breath/medical,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dAB" = (
/obj/structure/closet/secure_closet/CMO,
/obj/item/clothing/under/rank/nursesuit,
@@ -94324,7 +94324,7 @@
/turf/open/floor/plasteel/vault{
dir = 5
},
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dBP" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/components/unary/vent_pump/on{
@@ -94334,13 +94334,13 @@
dir = 4
},
/turf/open/floor/plasteel/neutral,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dBQ" = (
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
dir = 4
},
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dBR" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable/white{
@@ -94350,7 +94350,7 @@
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel/neutral,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dBS" = (
/obj/structure/rack,
/obj/effect/decal/cleanable/dirt,
@@ -94359,7 +94359,7 @@
/turf/open/floor/plasteel/vault{
dir = 5
},
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dBT" = (
/obj/machinery/light{
dir = 8
@@ -95032,15 +95032,15 @@
/obj/structure/closet/secure_closet/medical3,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dDe" = (
/obj/structure/closet/wardrobe/white/medical,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dDf" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dDg" = (
/obj/structure/cable/white{
d1 = 1;
@@ -95048,10 +95048,15 @@
icon_state = "1-2"
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/obj/structure/cable/white{
+ d1 = 2;
+ d2 = 4;
+ icon_state = "2-4"
+ },
/turf/open/floor/plasteel/vault{
dir = 5
},
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dDh" = (
/obj/machinery/suit_storage_unit/cmo,
/obj/effect/turf_decal/stripes/line{
@@ -95603,7 +95608,7 @@
dir = 1
},
/turf/open/floor/plasteel,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dEn" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/closed/wall,
@@ -113090,6 +113095,50 @@
/obj/structure/ore_box,
/turf/open/floor/plating,
/area/shuttle/auxillary_base)
+"esz" = (
+/turf/closed/wall/r_wall,
+/area/maintenance/department/medical/morgue)
+"esA" = (
+/turf/closed/wall/r_wall,
+/area/maintenance/department/medical/morgue)
+"esB" = (
+/turf/closed/wall,
+/area/maintenance/department/medical/morgue)
+"esC" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel/vault{
+ dir = 5
+ },
+/area/maintenance/department/medical/morgue)
+"esD" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"esE" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/power/apc{
+ dir = 2;
+ name = "Morgue Maintenance APC";
+ areastring = "/area/maintenance/department/medical/morgue";
+ pixel_y = -26
+ },
+/obj/structure/cable/white{
+ d2 = 8;
+ icon_state = "0-8"
+ },
+/turf/open/floor/plasteel/vault{
+ dir = 5
+ },
+/area/maintenance/department/medical/morgue)
+"esF" = (
+/turf/closed/wall,
+/area/maintenance/department/medical/morgue)
+"esG" = (
+/turf/closed/wall,
+/area/maintenance/department/medical/morgue)
+"esH" = (
+/turf/closed/wall,
+/area/maintenance/department/medical/morgue)
(1,1,1) = {"
aaa
@@ -155932,13 +155981,13 @@ drr
dsR
dur
dvw
-dwN
+esz
dya
-dyY
+esD
dAw
dBO
dDd
-dwK
+esF
dFd
dGE
dHP
@@ -156189,13 +156238,13 @@ drs
dsS
drs
dvx
-dwN
+esA
dyb
dzf
dAx
dBP
dDe
-dwK
+esG
dFe
dGF
dHP
@@ -156960,13 +157009,13 @@ drv
dlO
dus
dvA
-dwK
-dxS
+esB
+esC
dzi
dAA
dBS
-dxS
-dwK
+esE
+esH
dEY
dGA
dHP
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 21180a53bd..5a1762e989 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -4354,13 +4354,6 @@
/obj/structure/closet{
name = "Evidence Closet 1"
},
-/obj/item/storage/backpack{
- name = "Evidence Bag 1"
- },
-/obj/effect/spawner/lootdrop/maintenance{
- lootcount = 2;
- name = "2maintenance loot spawner"
- },
/turf/open/floor/plasteel/vault{
dir = 1
},
@@ -4387,11 +4380,6 @@
/area/security/warden)
"aiz" = (
/obj/structure/closet/secure_closet/evidence,
-/obj/item/storage/secure/briefcase{
- name = "Secure Evidence Briefcase";
- pixel_x = 3;
- pixel_y = -3
- },
/turf/open/floor/plasteel/vault{
dir = 4
},
@@ -4758,17 +4746,10 @@
/obj/structure/closet{
name = "Evidence Closet 2"
},
-/obj/item/storage/backpack{
- name = "Evidence Bag 2"
- },
/obj/machinery/airalarm{
dir = 4;
pixel_x = -23
},
-/obj/effect/spawner/lootdrop/maintenance{
- lootcount = 2;
- name = "2maintenance loot spawner"
- },
/turf/open/floor/plasteel/vault{
dir = 1
},
@@ -4792,13 +4773,6 @@
/obj/structure/closet{
name = "Evidence Closet 5"
},
-/obj/item/storage/backpack{
- name = "Evidence Bag 5"
- },
-/obj/effect/spawner/lootdrop/maintenance{
- lootcount = 2;
- name = "2maintenance loot spawner"
- },
/obj/machinery/firealarm{
dir = 4;
pixel_x = 28
@@ -5363,13 +5337,6 @@
/obj/structure/closet{
name = "Evidence Closet 4"
},
-/obj/item/storage/backpack{
- name = "Evidence Bag 4"
- },
-/obj/effect/spawner/lootdrop/maintenance{
- lootcount = 2;
- name = "2maintenance loot spawner"
- },
/turf/open/floor/plasteel/vault{
dir = 4
},
@@ -20485,13 +20452,6 @@
/obj/structure/closet{
name = "Evidence Closet 3"
},
-/obj/item/storage/backpack{
- name = "Evidence Bag 3"
- },
-/obj/effect/spawner/lootdrop/maintenance{
- lootcount = 2;
- name = "2maintenance loot spawner"
- },
/turf/open/floor/plasteel/vault{
dir = 4
},
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index b3016e3926..4376ba9c03 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -140,6 +140,8 @@
#define isstructure(A) (istype(A, /obj/structure))
+#define ismecha(A) (istype(A, /obj/mecha))
+
#define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable
#define isorgan(A) (istype(A, /obj/item/organ))
diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm
index 6d7c9568a9..819abd032f 100644
--- a/code/__DEFINES/lighting.dm
+++ b/code/__DEFINES/lighting.dm
@@ -70,6 +70,8 @@
#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" //Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175)
#define LIGHT_COLOR_HALOGEN "#F0FAFA" //Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250)
+#define LIGHT_RANGE_FIRE 3 //How many tiles standard fires glow.
+
#define LIGHTING_PLANE_ALPHA_VISIBLE 255
#define LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE 192
#define LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE 128 //For lighting alpha, small amounts lead to big changes. even at 128 its hard to figure out what is dark and what is light, at 64 you almost can't even tell.
diff --git a/code/__DEFINES/server_tools.dm b/code/__DEFINES/server_tools.dm
index b86a54959f..2773965d9c 100644
--- a/code/__DEFINES/server_tools.dm
+++ b/code/__DEFINES/server_tools.dm
@@ -1,4 +1,4 @@
-// /tg/station 13 server tools API v3.1
+// /tg/station 13 server tools API v3.1.0.1
//CONFIGURATION
//use this define if you want to do configuration outside of this file
@@ -21,6 +21,8 @@
#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]")
//Notify current in-game administrators of a string `event`
#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event)
+//The current amount of connected clients
+#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len
#endif
//Required hooks:
@@ -62,7 +64,7 @@
//IMPLEMENTATION
-#define SERVICE_API_VERSION_STRING "3.1.0.0"
+#define SERVICE_API_VERSION_STRING "3.1.0.1"
#define REBOOT_MODE_NORMAL 0
#define REBOOT_MODE_HARD 1
@@ -78,12 +80,13 @@
#define SERVICE_CMD_GRACEFUL_SHUTDOWN "graceful_shutdown"
#define SERVICE_CMD_WORLD_ANNOUNCE "world_announce"
#define SERVICE_CMD_LIST_CUSTOM "list_custom_commands"
+#define SERVICE_CMD_API_COMPATIBLE "api_compat"
+#define SERVICE_CMD_PLAYER_COUNT "client_count"
#define SERVICE_CMD_PARAM_KEY "serviceCommsKey"
#define SERVICE_CMD_PARAM_COMMAND "command"
#define SERVICE_CMD_PARAM_SENDER "sender"
#define SERVICE_CMD_PARAM_CUSTOM "custom"
-#define SERVICE_CMD_API_COMPATIBLE "api_compat"
#define SERVICE_JSON_PARAM_HELPTEXT "help_text"
#define SERVICE_JSON_PARAM_ADMINONLY "admin_only"
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index e38a6826f9..a16f91b317 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -331,6 +331,20 @@
afk_bracket += 600 // Add a minute to the bracket, for every attempt
return candidates
+/proc/considered_alive(datum/mind/M, enforce_human = TRUE)
+ if(M && M.current)
+ if(enforce_human)
+ var/mob/living/carbon/human/H
+ if(ishuman(M.current))
+ H = M.current
+ return M.current.stat != DEAD && !issilicon(M.current) && !isbrain(M.current) && (!H || H.dna.species.id != "memezombies")
+ else if(isliving(M.current))
+ return M.current.stat != DEAD
+ return FALSE
+
+/proc/considered_afk(datum/mind/M)
+ return !M || !M.current || !M.current.client || M.current.client.is_afk()
+
/proc/ScreenText(obj/O, maptext="", screen_loc="CENTER-7,CENTER-7", maptext_height=480, maptext_width=480)
if(!isobj(O))
O = new /obj/screen/text()
diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm
index 522ff84ff0..d855c7f141 100644
--- a/code/_globalvars/lists/names.dm
+++ b/code/_globalvars/lists/names.dm
@@ -15,6 +15,7 @@ GLOBAL_LIST_INIT(carp_names, world.file2list("strings/names/carp.txt"))
GLOBAL_LIST_INIT(golem_names, world.file2list("strings/names/golem.txt"))
GLOBAL_LIST_INIT(plasmaman_names, world.file2list("strings/names/plasmaman.txt"))
GLOBAL_LIST_INIT(posibrain_names, world.file2list("strings/names/posibrain.txt"))
+GLOBAL_LIST_INIT(nightmare_names, world.file2list("strings/names/nightmare.txt"))
GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt"))
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 2bc6e144dd..99d12568bc 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -96,7 +96,7 @@
if(!modifiers["catcher"] && A.IsObscured())
return
- if(istype(loc, /obj/mecha))
+ if(ismecha(loc))
var/obj/mecha/M = loc
return M.click_action(A,src,params)
@@ -327,7 +327,7 @@
ML.pulled(src)
/mob/living/carbon/human/CtrlClick(mob/user)
- if(ishuman(user) && Adjacent(user))
+ if(ishuman(user) && Adjacent(user) && !user.incapacitated())
if(world.time < user.next_move)
return FALSE
var/mob/living/carbon/human/H = user
@@ -359,7 +359,6 @@
else
user.listed_turf = T
user.client.statpanel = T.name
- user.Stat() //responsive ui pls
/mob/proc/TurfAdjacent(turf/T)
return T.Adjacent(src)
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index 07c17b891f..4d1ca2c778 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -28,7 +28,7 @@
icon_state = "act_equip"
/obj/screen/human/equip/Click()
- if(istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
+ if(ismecha(usr.loc)) // stops inventory actions in a mech
return 1
var/mob/living/carbon/human/H = usr
H.quick_equip()
@@ -313,11 +313,15 @@
inv.hud = src
inv_slots[inv.slot_id] = inv
inv.update_icon()
+
+ update_locked_slots()
/datum/hud/human/update_locked_slots()
if(!mymob)
return
var/mob/living/carbon/human/H = mymob
+ if(!istype(H) || !H.dna.species)
+ return
var/datum/species/S = H.dna.species
for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory))
if(inv.slot_id)
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index 2d94f41ba9..0906a099a0 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -1,586 +1,586 @@
-/*
- Screen objects
- Todo: improve/re-implement
-
- Screen objects are only used for the hud and should not appear anywhere "in-game".
- They are used with the client/screen list and the screen_loc var.
- For more information, see the byond documentation on the screen_loc and screen vars.
-*/
-/obj/screen
- name = ""
- icon = 'icons/mob/screen_gen.dmi'
- layer = ABOVE_HUD_LAYER
- plane = ABOVE_HUD_PLANE
- resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
- appearance_flags = APPEARANCE_UI
- var/obj/master = null //A reference to the object in the slot. Grabs or items, generally.
- var/datum/hud/hud = null // A reference to the owner HUD, if any.
-
-/obj/screen/take_damage()
- return
-
-/obj/screen/Destroy()
- master = null
- hud = null
- return ..()
-
-/obj/screen/examine(mob/user)
- return
-
-/obj/screen/orbit()
- return
-
-/obj/screen/text
- icon = null
- icon_state = null
+/*
+ Screen objects
+ Todo: improve/re-implement
+
+ Screen objects are only used for the hud and should not appear anywhere "in-game".
+ They are used with the client/screen list and the screen_loc var.
+ For more information, see the byond documentation on the screen_loc and screen vars.
+*/
+/obj/screen
+ name = ""
+ icon = 'icons/mob/screen_gen.dmi'
+ layer = ABOVE_HUD_LAYER
+ plane = ABOVE_HUD_PLANE
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+ appearance_flags = APPEARANCE_UI
+ var/obj/master = null //A reference to the object in the slot. Grabs or items, generally.
+ var/datum/hud/hud = null // A reference to the owner HUD, if any.
+
+/obj/screen/take_damage()
+ return
+
+/obj/screen/Destroy()
+ master = null
+ hud = null
+ return ..()
+
+/obj/screen/examine(mob/user)
+ return
+
+/obj/screen/orbit()
+ return
+
+/obj/screen/text
+ icon = null
+ icon_state = null
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
- screen_loc = "CENTER-7,CENTER-7"
- maptext_height = 480
- maptext_width = 480
-
-/obj/screen/swap_hand
- layer = HUD_LAYER
- plane = HUD_PLANE
- name = "swap hand"
-
-/obj/screen/swap_hand/Click()
- // At this point in client Click() code we have passed the 1/10 sec check and little else
- // We don't even know if it's a middle click
- if(world.time <= usr.next_move)
- return 1
-
- if(usr.incapacitated())
- return 1
-
- if(ismob(usr))
- var/mob/M = usr
- M.swap_hand()
- return 1
-
-/obj/screen/craft
- name = "crafting menu"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "craft"
- screen_loc = ui_crafting
-
-/obj/screen/craft/Click()
- var/mob/living/M = usr
- if(isobserver(usr))
- return
- M.OpenCraftingMenu()
-
-/obj/screen/area_creator
- name = "create new area"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "area_edit"
- screen_loc = ui_building
-
-/obj/screen/area_creator/Click()
- if(usr.incapacitated())
- return 1
- var/area/A = get_area(usr)
- if(!A.outdoors)
- to_chat(usr, "There is already a defined structure here.")
- return 1
- create_area(usr)
-
-/obj/screen/language_menu
- name = "language menu"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "talk_wheel"
- screen_loc = ui_language_menu
-
-/obj/screen/language_menu/Click()
- var/mob/M = usr
- var/datum/language_holder/H = M.get_language_holder()
- H.open_language_menu(usr)
-
-/obj/screen/inventory
- var/slot_id // The indentifier for the slot. It has nothing to do with ID cards.
- var/icon_empty // Icon when empty. For now used only by humans.
- var/icon_full // Icon when contains an item. For now used only by humans.
- layer = HUD_LAYER
- plane = HUD_PLANE
-
-/obj/screen/inventory/Click(location, control, params)
- // At this point in client Click() code we have passed the 1/10 sec check and little else
- // We don't even know if it's a middle click
- if(world.time <= usr.next_move)
- return 1
-
- if(usr.incapacitated())
- return 1
- if(istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
- return 1
-
- if(hud && hud.mymob && slot_id)
- var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id)
- if(inv_item)
- return inv_item.Click(location, control, params)
-
- if(usr.attack_ui(slot_id))
- usr.update_inv_hands()
- return 1
-
-/obj/screen/inventory/update_icon()
- if(!icon_empty)
- icon_empty = icon_state
-
- if(hud && hud.mymob && slot_id && icon_full)
- if(hud.mymob.get_item_by_slot(slot_id))
- icon_state = icon_full
- else
- icon_state = icon_empty
-
-/obj/screen/inventory/hand
- var/mutable_appearance/handcuff_overlay
- var/static/mutable_appearance/blocked_overlay = mutable_appearance('icons/mob/screen_gen.dmi', "blocked")
- var/held_index = 0
-
-/obj/screen/inventory/hand/update_icon()
- ..()
-
- if(!handcuff_overlay)
- var/state = (!(held_index % 2)) ? "markus" : "gabrielle"
- handcuff_overlay = mutable_appearance('icons/mob/screen_gen.dmi', state)
-
- cut_overlays()
-
- if(hud && hud.mymob)
- if(iscarbon(hud.mymob))
- var/mob/living/carbon/C = hud.mymob
- if(C.handcuffed)
- add_overlay(handcuff_overlay)
-
- if(held_index)
- if(!C.has_hand_for_held_index(held_index))
- add_overlay(blocked_overlay)
-
- if(held_index == hud.mymob.active_hand_index)
- add_overlay("hand_active")
-
-
-/obj/screen/inventory/hand/Click(location, control, params)
- // At this point in client Click() code we have passed the 1/10 sec check and little else
- // We don't even know if it's a middle click
- if(world.time <= usr.next_move)
- return 1
- if(usr.incapacitated() || isobserver(usr))
- return 1
- if (istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
- return 1
-
- if(hud.mymob.active_hand_index == held_index)
- var/obj/item/I = hud.mymob.get_active_held_item()
- if(I)
- I.Click(location, control, params)
- else
- hud.mymob.swap_hand(held_index)
- return 1
-
-/obj/screen/close
- name = "close"
-
-/obj/screen/close/Click()
- if(istype(master, /obj/item/storage))
- var/obj/item/storage/S = master
- S.close(usr)
- return 1
-
-
-/obj/screen/drop
- name = "drop"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "act_drop"
- layer = HUD_LAYER
- plane = HUD_PLANE
-
-/obj/screen/drop/Click()
- usr.drop_item_v()
-
-/obj/screen/act_intent
- name = "intent"
- icon_state = "help"
- screen_loc = ui_acti
-
-/obj/screen/act_intent/Click(location, control, params)
- usr.a_intent_change(INTENT_HOTKEY_RIGHT)
-
-/obj/screen/act_intent/segmented/Click(location, control, params)
- if(usr.client.prefs.toggles & INTENT_STYLE)
- var/_x = text2num(params2list(params)["icon-x"])
- var/_y = text2num(params2list(params)["icon-y"])
-
- if(_x<=16 && _y<=16)
- usr.a_intent_change(INTENT_HARM)
-
- else if(_x<=16 && _y>=17)
- usr.a_intent_change(INTENT_HELP)
-
- else if(_x>=17 && _y<=16)
- usr.a_intent_change(INTENT_GRAB)
-
- else if(_x>=17 && _y>=17)
- usr.a_intent_change(INTENT_DISARM)
- else
- return ..()
-
-/obj/screen/act_intent/alien
- icon = 'icons/mob/screen_alien.dmi'
- screen_loc = ui_movi
-
-/obj/screen/act_intent/robot
- icon = 'icons/mob/screen_cyborg.dmi'
- screen_loc = ui_borg_intents
-
-/obj/screen/internals
- name = "toggle internals"
- icon_state = "internal0"
- screen_loc = ui_internal
-
-/obj/screen/internals/Click()
- if(!iscarbon(usr))
- return
- var/mob/living/carbon/C = usr
- if(C.incapacitated())
- return
-
- if(C.internal)
- C.internal = null
- to_chat(C, "You are no longer running on internals.")
- icon_state = "internal0"
- else
- if(!C.getorganslot("breathing_tube"))
- if(!istype(C.wear_mask, /obj/item/clothing/mask))
- to_chat(C, "You are not wearing an internals mask!")
- return 1
- else
- var/obj/item/clothing/mask/M = C.wear_mask
- if(M.mask_adjusted) // if mask on face but pushed down
- M.adjustmask(C) // adjust it back
+ screen_loc = "CENTER-7,CENTER-7"
+ maptext_height = 480
+ maptext_width = 480
+
+/obj/screen/swap_hand
+ layer = HUD_LAYER
+ plane = HUD_PLANE
+ name = "swap hand"
+
+/obj/screen/swap_hand/Click()
+ // At this point in client Click() code we have passed the 1/10 sec check and little else
+ // We don't even know if it's a middle click
+ if(world.time <= usr.next_move)
+ return 1
+
+ if(usr.incapacitated())
+ return 1
+
+ if(ismob(usr))
+ var/mob/M = usr
+ M.swap_hand()
+ return 1
+
+/obj/screen/craft
+ name = "crafting menu"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "craft"
+ screen_loc = ui_crafting
+
+/obj/screen/craft/Click()
+ var/mob/living/M = usr
+ if(isobserver(usr))
+ return
+ M.OpenCraftingMenu()
+
+/obj/screen/area_creator
+ name = "create new area"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "area_edit"
+ screen_loc = ui_building
+
+/obj/screen/area_creator/Click()
+ if(usr.incapacitated())
+ return 1
+ var/area/A = get_area(usr)
+ if(!A.outdoors)
+ to_chat(usr, "There is already a defined structure here.")
+ return 1
+ create_area(usr)
+
+/obj/screen/language_menu
+ name = "language menu"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "talk_wheel"
+ screen_loc = ui_language_menu
+
+/obj/screen/language_menu/Click()
+ var/mob/M = usr
+ var/datum/language_holder/H = M.get_language_holder()
+ H.open_language_menu(usr)
+
+/obj/screen/inventory
+ var/slot_id // The indentifier for the slot. It has nothing to do with ID cards.
+ var/icon_empty // Icon when empty. For now used only by humans.
+ var/icon_full // Icon when contains an item. For now used only by humans.
+ layer = HUD_LAYER
+ plane = HUD_PLANE
+
+/obj/screen/inventory/Click(location, control, params)
+ // At this point in client Click() code we have passed the 1/10 sec check and little else
+ // We don't even know if it's a middle click
+ if(world.time <= usr.next_move)
+ return 1
+
+ if(usr.incapacitated())
+ return 1
+ if(ismecha(usr.loc)) // stops inventory actions in a mech
+ return 1
+
+ if(hud && hud.mymob && slot_id)
+ var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id)
+ if(inv_item)
+ return inv_item.Click(location, control, params)
+
+ if(usr.attack_ui(slot_id))
+ usr.update_inv_hands()
+ return 1
+
+/obj/screen/inventory/update_icon()
+ if(!icon_empty)
+ icon_empty = icon_state
+
+ if(hud && hud.mymob && slot_id && icon_full)
+ if(hud.mymob.get_item_by_slot(slot_id))
+ icon_state = icon_full
+ else
+ icon_state = icon_empty
+
+/obj/screen/inventory/hand
+ var/mutable_appearance/handcuff_overlay
+ var/static/mutable_appearance/blocked_overlay = mutable_appearance('icons/mob/screen_gen.dmi', "blocked")
+ var/held_index = 0
+
+/obj/screen/inventory/hand/update_icon()
+ ..()
+
+ if(!handcuff_overlay)
+ var/state = (!(held_index % 2)) ? "markus" : "gabrielle"
+ handcuff_overlay = mutable_appearance('icons/mob/screen_gen.dmi', state)
+
+ cut_overlays()
+
+ if(hud && hud.mymob)
+ if(iscarbon(hud.mymob))
+ var/mob/living/carbon/C = hud.mymob
+ if(C.handcuffed)
+ add_overlay(handcuff_overlay)
+
+ if(held_index)
+ if(!C.has_hand_for_held_index(held_index))
+ add_overlay(blocked_overlay)
+
+ if(held_index == hud.mymob.active_hand_index)
+ add_overlay("hand_active")
+
+
+/obj/screen/inventory/hand/Click(location, control, params)
+ // At this point in client Click() code we have passed the 1/10 sec check and little else
+ // We don't even know if it's a middle click
+ if(world.time <= usr.next_move)
+ return 1
+ if(usr.incapacitated() || isobserver(usr))
+ return 1
+ if (ismecha(usr.loc)) // stops inventory actions in a mech
+ return 1
+
+ if(hud.mymob.active_hand_index == held_index)
+ var/obj/item/I = hud.mymob.get_active_held_item()
+ if(I)
+ I.Click(location, control, params)
+ else
+ hud.mymob.swap_hand(held_index)
+ return 1
+
+/obj/screen/close
+ name = "close"
+
+/obj/screen/close/Click()
+ if(istype(master, /obj/item/storage))
+ var/obj/item/storage/S = master
+ S.close(usr)
+ return 1
+
+
+/obj/screen/drop
+ name = "drop"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "act_drop"
+ layer = HUD_LAYER
+ plane = HUD_PLANE
+
+/obj/screen/drop/Click()
+ usr.drop_item_v()
+
+/obj/screen/act_intent
+ name = "intent"
+ icon_state = "help"
+ screen_loc = ui_acti
+
+/obj/screen/act_intent/Click(location, control, params)
+ usr.a_intent_change(INTENT_HOTKEY_RIGHT)
+
+/obj/screen/act_intent/segmented/Click(location, control, params)
+ if(usr.client.prefs.toggles & INTENT_STYLE)
+ var/_x = text2num(params2list(params)["icon-x"])
+ var/_y = text2num(params2list(params)["icon-y"])
+
+ if(_x<=16 && _y<=16)
+ usr.a_intent_change(INTENT_HARM)
+
+ else if(_x<=16 && _y>=17)
+ usr.a_intent_change(INTENT_HELP)
+
+ else if(_x>=17 && _y<=16)
+ usr.a_intent_change(INTENT_GRAB)
+
+ else if(_x>=17 && _y>=17)
+ usr.a_intent_change(INTENT_DISARM)
+ else
+ return ..()
+
+/obj/screen/act_intent/alien
+ icon = 'icons/mob/screen_alien.dmi'
+ screen_loc = ui_movi
+
+/obj/screen/act_intent/robot
+ icon = 'icons/mob/screen_cyborg.dmi'
+ screen_loc = ui_borg_intents
+
+/obj/screen/internals
+ name = "toggle internals"
+ icon_state = "internal0"
+ screen_loc = ui_internal
+
+/obj/screen/internals/Click()
+ if(!iscarbon(usr))
+ return
+ var/mob/living/carbon/C = usr
+ if(C.incapacitated())
+ return
+
+ if(C.internal)
+ C.internal = null
+ to_chat(C, "You are no longer running on internals.")
+ icon_state = "internal0"
+ else
+ if(!C.getorganslot("breathing_tube"))
+ if(!istype(C.wear_mask, /obj/item/clothing/mask))
+ to_chat(C, "You are not wearing an internals mask!")
+ return 1
+ else
+ var/obj/item/clothing/mask/M = C.wear_mask
+ if(M.mask_adjusted) // if mask on face but pushed down
+ M.adjustmask(C) // adjust it back
if( !(M.flags_1 & MASKINTERNALS_1) )
- to_chat(C, "You are not wearing an internals mask!")
- return
-
- var/obj/item/I = C.is_holding_item_of_type(/obj/item/tank)
- if(I)
- to_chat(C, "You are now running on internals from the [I] on your [C.get_held_index_name(C.get_held_index_of_item(I))].")
- C.internal = I
- else if(ishuman(C))
- var/mob/living/carbon/human/H = C
- if(istype(H.s_store, /obj/item/tank))
- to_chat(H, "You are now running on internals from the [H.s_store] on your [H.wear_suit].")
- H.internal = H.s_store
- else if(istype(H.belt, /obj/item/tank))
- to_chat(H, "You are now running on internals from the [H.belt] on your belt.")
- H.internal = H.belt
- else if(istype(H.l_store, /obj/item/tank))
- to_chat(H, "You are now running on internals from the [H.l_store] in your left pocket.")
- H.internal = H.l_store
- else if(istype(H.r_store, /obj/item/tank))
- to_chat(H, "You are now running on internals from the [H.r_store] in your right pocket.")
- H.internal = H.r_store
-
+ to_chat(C, "You are not wearing an internals mask!")
+ return
+
+ var/obj/item/I = C.is_holding_item_of_type(/obj/item/tank)
+ if(I)
+ to_chat(C, "You are now running on internals from the [I] on your [C.get_held_index_name(C.get_held_index_of_item(I))].")
+ C.internal = I
+ else if(ishuman(C))
+ var/mob/living/carbon/human/H = C
+ if(istype(H.s_store, /obj/item/tank))
+ to_chat(H, "You are now running on internals from the [H.s_store] on your [H.wear_suit].")
+ H.internal = H.s_store
+ else if(istype(H.belt, /obj/item/tank))
+ to_chat(H, "You are now running on internals from the [H.belt] on your belt.")
+ H.internal = H.belt
+ else if(istype(H.l_store, /obj/item/tank))
+ to_chat(H, "You are now running on internals from the [H.l_store] in your left pocket.")
+ H.internal = H.l_store
+ else if(istype(H.r_store, /obj/item/tank))
+ to_chat(H, "You are now running on internals from the [H.r_store] in your right pocket.")
+ H.internal = H.r_store
+
//Separate so CO2 jetpacks are a little less cumbersome.
- if(!C.internal && istype(C.back, /obj/item/tank))
- to_chat(C, "You are now running on internals from the [C.back] on your back.")
- C.internal = C.back
-
- if(C.internal)
- icon_state = "internal1"
- else
- to_chat(C, "You don't have an oxygen tank!")
- return
- C.update_action_buttons_icon()
-
-/obj/screen/mov_intent
- name = "run/walk toggle"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "running"
-
-/obj/screen/mov_intent/Click()
- toggle(usr)
-
-/obj/screen/mov_intent/proc/toggle(mob/user)
- if(isobserver(user))
- return
- switch(user.m_intent)
- if("run")
- user.m_intent = MOVE_INTENT_WALK
- icon_state = "walking"
- if("walk")
- user.m_intent = MOVE_INTENT_RUN
- icon_state = "running"
- user.update_icons()
-
-/obj/screen/pull
- name = "stop pulling"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "pull"
-
-/obj/screen/pull/Click()
- if(isobserver(usr))
- return
- usr.stop_pulling()
-
-/obj/screen/pull/update_icon(mob/mymob)
- if(!mymob) return
- if(mymob.pulling)
- icon_state = "pull"
- else
- icon_state = "pull0"
-
-/obj/screen/resist
- name = "resist"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "act_resist"
- layer = HUD_LAYER
- plane = HUD_PLANE
-
-/obj/screen/resist/Click()
- if(isliving(usr))
- var/mob/living/L = usr
- L.resist()
-
-/obj/screen/storage
- name = "storage"
-
-/obj/screen/storage/Click(location, control, params)
- if(world.time <= usr.next_move)
- return 1
- if(usr.stat || usr.IsUnconscious() || usr.IsKnockdown() || usr.IsStun())
- return 1
- if (istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
- return 1
- if(master)
- var/obj/item/I = usr.get_active_held_item()
- if(I)
- master.attackby(I, usr, params)
- return 1
-
-/obj/screen/throw_catch
- name = "throw/catch"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "act_throw_off"
-
-/obj/screen/throw_catch/Click()
- if(iscarbon(usr))
- var/mob/living/carbon/C = usr
- C.toggle_throw_mode()
-
-/obj/screen/zone_sel
- name = "damage zone"
- icon_state = "zone_sel"
- screen_loc = ui_zonesel
- var/selecting = "chest"
-
-/obj/screen/zone_sel/Click(location, control,params)
- if(isobserver(usr))
- return
-
- var/list/PL = params2list(params)
- var/icon_x = text2num(PL["icon-x"])
- var/icon_y = text2num(PL["icon-y"])
- var/choice
-
- switch(icon_y)
- if(1 to 9) //Legs
- switch(icon_x)
- if(10 to 15)
- choice = "r_leg"
- if(17 to 22)
- choice = "l_leg"
- else
- return 1
- if(10 to 13) //Hands and groin
- switch(icon_x)
- if(8 to 11)
- choice = "r_arm"
- if(12 to 20)
- choice = "groin"
- if(21 to 24)
- choice = "l_arm"
- else
- return 1
- if(14 to 22) //Chest and arms to shoulders
- switch(icon_x)
- if(8 to 11)
- choice = "r_arm"
- if(12 to 20)
- choice = "chest"
- if(21 to 24)
- choice = "l_arm"
- else
- return 1
- if(23 to 30) //Head, but we need to check for eye or mouth
- if(icon_x in 12 to 20)
- choice = "head"
- switch(icon_y)
- if(23 to 24)
- if(icon_x in 15 to 17)
- choice = "mouth"
- if(26) //Eyeline, eyes are on 15 and 17
- if(icon_x in 14 to 18)
- choice = "eyes"
- if(25 to 27)
- if(icon_x in 15 to 17)
- choice = "eyes"
-
- return set_selected_zone(choice, usr)
-
-/obj/screen/zone_sel/proc/set_selected_zone(choice, mob/user)
- if(isobserver(user))
- return
-
- if(choice != selecting)
- selecting = choice
- update_icon(usr)
- return 1
-
-/obj/screen/zone_sel/update_icon(mob/user)
- cut_overlays()
- add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[selecting]"))
- user.zone_selected = selecting
-
-/obj/screen/zone_sel/alien
- icon = 'icons/mob/screen_alien.dmi'
-
-/obj/screen/zone_sel/alien/update_icon(mob/user)
- cut_overlays()
- add_overlay(mutable_appearance('icons/mob/screen_alien.dmi', "[selecting]"))
- user.zone_selected = selecting
-
-/obj/screen/zone_sel/robot
- icon = 'icons/mob/screen_cyborg.dmi'
-
-
-/obj/screen/flash
- name = "flash"
- icon_state = "blank"
- blend_mode = BLEND_ADD
- screen_loc = "WEST,SOUTH to EAST,NORTH"
- layer = FLASH_LAYER
- plane = FULLSCREEN_PLANE
-
-/obj/screen/damageoverlay
- icon = 'icons/mob/screen_full.dmi'
- icon_state = "oxydamageoverlay0"
- name = "dmg"
- blend_mode = BLEND_MULTIPLY
- screen_loc = "CENTER-7,CENTER-7"
+ if(!C.internal && istype(C.back, /obj/item/tank))
+ to_chat(C, "You are now running on internals from the [C.back] on your back.")
+ C.internal = C.back
+
+ if(C.internal)
+ icon_state = "internal1"
+ else
+ to_chat(C, "You don't have an oxygen tank!")
+ return
+ C.update_action_buttons_icon()
+
+/obj/screen/mov_intent
+ name = "run/walk toggle"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "running"
+
+/obj/screen/mov_intent/Click()
+ toggle(usr)
+
+/obj/screen/mov_intent/proc/toggle(mob/user)
+ if(isobserver(user))
+ return
+ switch(user.m_intent)
+ if("run")
+ user.m_intent = MOVE_INTENT_WALK
+ icon_state = "walking"
+ if("walk")
+ user.m_intent = MOVE_INTENT_RUN
+ icon_state = "running"
+ user.update_icons()
+
+/obj/screen/pull
+ name = "stop pulling"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "pull"
+
+/obj/screen/pull/Click()
+ if(isobserver(usr))
+ return
+ usr.stop_pulling()
+
+/obj/screen/pull/update_icon(mob/mymob)
+ if(!mymob) return
+ if(mymob.pulling)
+ icon_state = "pull"
+ else
+ icon_state = "pull0"
+
+/obj/screen/resist
+ name = "resist"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "act_resist"
+ layer = HUD_LAYER
+ plane = HUD_PLANE
+
+/obj/screen/resist/Click()
+ if(isliving(usr))
+ var/mob/living/L = usr
+ L.resist()
+
+/obj/screen/storage
+ name = "storage"
+
+/obj/screen/storage/Click(location, control, params)
+ if(world.time <= usr.next_move)
+ return 1
+ if(usr.stat || usr.IsUnconscious() || usr.IsKnockdown() || usr.IsStun())
+ return 1
+ if (ismecha(usr.loc)) // stops inventory actions in a mech
+ return 1
+ if(master)
+ var/obj/item/I = usr.get_active_held_item()
+ if(I)
+ master.attackby(I, usr, params)
+ return 1
+
+/obj/screen/throw_catch
+ name = "throw/catch"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "act_throw_off"
+
+/obj/screen/throw_catch/Click()
+ if(iscarbon(usr))
+ var/mob/living/carbon/C = usr
+ C.toggle_throw_mode()
+
+/obj/screen/zone_sel
+ name = "damage zone"
+ icon_state = "zone_sel"
+ screen_loc = ui_zonesel
+ var/selecting = "chest"
+
+/obj/screen/zone_sel/Click(location, control,params)
+ if(isobserver(usr))
+ return
+
+ var/list/PL = params2list(params)
+ var/icon_x = text2num(PL["icon-x"])
+ var/icon_y = text2num(PL["icon-y"])
+ var/choice
+
+ switch(icon_y)
+ if(1 to 9) //Legs
+ switch(icon_x)
+ if(10 to 15)
+ choice = "r_leg"
+ if(17 to 22)
+ choice = "l_leg"
+ else
+ return 1
+ if(10 to 13) //Hands and groin
+ switch(icon_x)
+ if(8 to 11)
+ choice = "r_arm"
+ if(12 to 20)
+ choice = "groin"
+ if(21 to 24)
+ choice = "l_arm"
+ else
+ return 1
+ if(14 to 22) //Chest and arms to shoulders
+ switch(icon_x)
+ if(8 to 11)
+ choice = "r_arm"
+ if(12 to 20)
+ choice = "chest"
+ if(21 to 24)
+ choice = "l_arm"
+ else
+ return 1
+ if(23 to 30) //Head, but we need to check for eye or mouth
+ if(icon_x in 12 to 20)
+ choice = "head"
+ switch(icon_y)
+ if(23 to 24)
+ if(icon_x in 15 to 17)
+ choice = "mouth"
+ if(26) //Eyeline, eyes are on 15 and 17
+ if(icon_x in 14 to 18)
+ choice = "eyes"
+ if(25 to 27)
+ if(icon_x in 15 to 17)
+ choice = "eyes"
+
+ return set_selected_zone(choice, usr)
+
+/obj/screen/zone_sel/proc/set_selected_zone(choice, mob/user)
+ if(isobserver(user))
+ return
+
+ if(choice != selecting)
+ selecting = choice
+ update_icon(usr)
+ return 1
+
+/obj/screen/zone_sel/update_icon(mob/user)
+ cut_overlays()
+ add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[selecting]"))
+ user.zone_selected = selecting
+
+/obj/screen/zone_sel/alien
+ icon = 'icons/mob/screen_alien.dmi'
+
+/obj/screen/zone_sel/alien/update_icon(mob/user)
+ cut_overlays()
+ add_overlay(mutable_appearance('icons/mob/screen_alien.dmi', "[selecting]"))
+ user.zone_selected = selecting
+
+/obj/screen/zone_sel/robot
+ icon = 'icons/mob/screen_cyborg.dmi'
+
+
+/obj/screen/flash
+ name = "flash"
+ icon_state = "blank"
+ blend_mode = BLEND_ADD
+ screen_loc = "WEST,SOUTH to EAST,NORTH"
+ layer = FLASH_LAYER
+ plane = FULLSCREEN_PLANE
+
+/obj/screen/damageoverlay
+ icon = 'icons/mob/screen_full.dmi'
+ icon_state = "oxydamageoverlay0"
+ name = "dmg"
+ blend_mode = BLEND_MULTIPLY
+ screen_loc = "CENTER-7,CENTER-7"
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
- layer = UI_DAMAGE_LAYER
- plane = FULLSCREEN_PLANE
-
-/obj/screen/healths
- name = "health"
- icon_state = "health0"
- screen_loc = ui_health
-
-/obj/screen/healths/alien
- icon = 'icons/mob/screen_alien.dmi'
- screen_loc = ui_alien_health
-
-/obj/screen/healths/robot
- icon = 'icons/mob/screen_cyborg.dmi'
- screen_loc = ui_borg_health
-
-/obj/screen/healths/deity
- name = "Nexus Health"
- icon_state = "deity_nexus"
- screen_loc = ui_deityhealth
-
-/obj/screen/healths/blob
- name = "blob health"
- icon_state = "block"
- screen_loc = ui_internal
+ layer = UI_DAMAGE_LAYER
+ plane = FULLSCREEN_PLANE
+
+/obj/screen/healths
+ name = "health"
+ icon_state = "health0"
+ screen_loc = ui_health
+
+/obj/screen/healths/alien
+ icon = 'icons/mob/screen_alien.dmi'
+ screen_loc = ui_alien_health
+
+/obj/screen/healths/robot
+ icon = 'icons/mob/screen_cyborg.dmi'
+ screen_loc = ui_borg_health
+
+/obj/screen/healths/deity
+ name = "Nexus Health"
+ icon_state = "deity_nexus"
+ screen_loc = ui_deityhealth
+
+/obj/screen/healths/blob
+ name = "blob health"
+ icon_state = "block"
+ screen_loc = ui_internal
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
-
-/obj/screen/healths/blob/naut
- name = "health"
- icon = 'icons/mob/blob.dmi'
- icon_state = "nauthealth"
-
-/obj/screen/healths/blob/naut/core
- name = "overmind health"
- screen_loc = ui_health
- icon_state = "corehealth"
-
-/obj/screen/healths/guardian
- name = "summoner health"
- icon = 'icons/mob/guardian.dmi'
- icon_state = "base"
- screen_loc = ui_health
+
+/obj/screen/healths/blob/naut
+ name = "health"
+ icon = 'icons/mob/blob.dmi'
+ icon_state = "nauthealth"
+
+/obj/screen/healths/blob/naut/core
+ name = "overmind health"
+ screen_loc = ui_health
+ icon_state = "corehealth"
+
+/obj/screen/healths/guardian
+ name = "summoner health"
+ icon = 'icons/mob/guardian.dmi'
+ icon_state = "base"
+ screen_loc = ui_health
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
-
-/obj/screen/healths/clock
- icon = 'icons/mob/actions.dmi'
- icon_state = "bg_clock"
- screen_loc = ui_health
+
+/obj/screen/healths/clock
+ icon = 'icons/mob/actions.dmi'
+ icon_state = "bg_clock"
+ screen_loc = ui_health
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
-
-/obj/screen/healths/clock/gear
- icon = 'icons/mob/clockwork_mobs.dmi'
- icon_state = "bg_gear"
- screen_loc = ui_internal
-
-/obj/screen/healths/revenant
- name = "essence"
- icon = 'icons/mob/actions.dmi'
- icon_state = "bg_revenant"
- screen_loc = ui_health
+
+/obj/screen/healths/clock/gear
+ icon = 'icons/mob/clockwork_mobs.dmi'
+ icon_state = "bg_gear"
+ screen_loc = ui_internal
+
+/obj/screen/healths/revenant
+ name = "essence"
+ icon = 'icons/mob/actions.dmi'
+ icon_state = "bg_revenant"
+ screen_loc = ui_health
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
-
-/obj/screen/healths/construct
- icon = 'icons/mob/screen_construct.dmi'
- icon_state = "artificer_health0"
- screen_loc = ui_construct_health
+
+/obj/screen/healths/construct
+ icon = 'icons/mob/screen_construct.dmi'
+ icon_state = "artificer_health0"
+ screen_loc = ui_construct_health
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
-
-/obj/screen/healthdoll
- name = "health doll"
- screen_loc = ui_healthdoll
-
-/obj/screen/splash
- icon = 'config/title_screens/images/title1.dmi'
- icon_state = ""
- screen_loc = "1,1"
- layer = SPLASHSCREEN_LAYER
- plane = SPLASHSCREEN_PLANE
- var/client/holder
-
-/obj/screen/splash/New(client/C, visible, use_previous_title) //TODO: Make this use INITIALIZE_IMMEDIATE
- holder = C
-
- if(!visible)
- alpha = 0
-
- if(!use_previous_title)
- if(SStitle.icon)
- icon = SStitle.icon
- else
- if(!SStitle.previous_icon)
- qdel(src)
- return
- icon = SStitle.previous_icon
-
- holder.screen += src
-
- ..()
-
-/obj/screen/splash/proc/Fade(out, qdel_after = TRUE)
- if(QDELETED(src))
- return
- if(out)
- animate(src, alpha = 0, time = 30)
- else
- alpha = 0
- animate(src, alpha = 255, time = 30)
- if(qdel_after)
- QDEL_IN(src, 30)
-
-/obj/screen/splash/Destroy()
- if(holder)
- holder.screen -= src
- holder = null
- return ..()
+
+/obj/screen/healthdoll
+ name = "health doll"
+ screen_loc = ui_healthdoll
+
+/obj/screen/splash
+ icon = 'config/title_screens/images/title1.dmi'
+ icon_state = ""
+ screen_loc = "1,1"
+ layer = SPLASHSCREEN_LAYER
+ plane = SPLASHSCREEN_PLANE
+ var/client/holder
+
+/obj/screen/splash/New(client/C, visible, use_previous_title) //TODO: Make this use INITIALIZE_IMMEDIATE
+ holder = C
+
+ if(!visible)
+ alpha = 0
+
+ if(!use_previous_title)
+ if(SStitle.icon)
+ icon = SStitle.icon
+ else
+ if(!SStitle.previous_icon)
+ qdel(src)
+ return
+ icon = SStitle.previous_icon
+
+ holder.screen += src
+
+ ..()
+
+/obj/screen/splash/proc/Fade(out, qdel_after = TRUE)
+ if(QDELETED(src))
+ return
+ if(out)
+ animate(src, alpha = 0, time = 30)
+ else
+ alpha = 0
+ animate(src, alpha = 255, time = 30)
+ if(qdel_after)
+ QDEL_IN(src, 30)
+
+/obj/screen/splash/Destroy()
+ if(holder)
+ holder.screen -= src
+ holder = null
+ return ..()
diff --git a/code/citadel/cit_guns.dm b/code/citadel/cit_guns.dm
index e62884ecbc..73a98db4e3 100644
--- a/code/citadel/cit_guns.dm
+++ b/code/citadel/cit_guns.dm
@@ -596,10 +596,10 @@ obj/item/projectile/bullet/c10mm/soporific
if((blocked != 100) && isliving(target))
var/mob/living/L = target
L.blur_eyes(6)
- if(L.staminaloss >= 40)
+ if(L.staminaloss >= 60)
L.Sleeping(250)
else
- L.adjustStaminaLoss(58)
+ L.adjustStaminaLoss(25)
return 1
/obj/item/ammo_casing/c10mm/soporific
diff --git a/code/citadel/custom_loadout/custom_items.dm b/code/citadel/custom_loadout/custom_items.dm
index c100f0013c..397f4c6576 100644
--- a/code/citadel/custom_loadout/custom_items.dm
+++ b/code/citadel/custom_loadout/custom_items.dm
@@ -30,6 +30,14 @@
item_color = null
tagname = null
+/obj/item/clothing/accessory/medal/steele
+ name = "Insignia Of Steele"
+ desc = "An intricate pendant given to those who help a key member of the Steele Corporation."
+ icon = 'icons/obj/custom.dmi'
+ icon_state = "steele"
+ item_color = "steele"
+ medaltype = "medal-silver"
+
/*DirtyOldHarry*/
/obj/item/lighter/gold
@@ -55,6 +63,12 @@
item_color = "zombscarf"
dog_fashion = /datum/dog_fashion/head
+/obj/item/clothing/suit/toggle/labcoat/mad/red
+ name = "\improper The Mad's labcoat"
+ desc = "An oddly special looking coat."
+ icon_state = "labred"
+ item_state = "labred"
+
/*PLACEHOLDER*/
@@ -117,4 +131,14 @@
desc = "You would swear this was in your nightmares after eating too many veggies."
icon_state = "hos-g"
item_state = "hos-g"
- body_parts_covered = CHEST|GROIN|ARMS|LEGS
\ No newline at end of file
+ body_parts_covered = CHEST|GROIN|ARMS|LEGS
+
+
+/*Slomek*/
+/obj/item/reagent_containers/food/drinks/flask/russian
+ name = "russian flask"
+ desc = "Every good russian spaceman knows it's a good idea to bring along a couple of pints of whiskey wherever they go."
+ icon = 'icons/obj/custom.dmi'
+ icon_state = "russianflask"
+ item_state = "russianflask"
+ volume = 60
diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm
index 8df012e5de..49ccb411fc 100644
--- a/code/controllers/configuration/configuration.dm
+++ b/code/controllers/configuration/configuration.dm
@@ -24,8 +24,7 @@ GLOBAL_PROTECT(config_dir)
LoadModes()
for(var/I in config_files)
LoadEntries(I)
- if(Get(/datum/config_entry/flag/maprotation))
- loadmaplist(CONFIG_MAPS_FILE)
+ loadmaplist(CONFIG_MAPS_FILE)
/datum/controller/configuration/Destroy()
entries_by_type.Cut()
@@ -170,6 +169,7 @@ GLOBAL_PROTECT(config_dir)
/datum/controller/configuration/proc/loadmaplist(filename)
filename = "[GLOB.config_dir][filename]"
+ log_config("Loading config file [filename]...")
var/list/Lines = world.file2list(filename)
var/datum/map_config/currentmap = null
diff --git a/code/controllers/configuration/entries/config.dm b/code/controllers/configuration/entries/config.dm
index 62919afd06..ec96e88553 100644
--- a/code/controllers/configuration/entries/config.dm
+++ b/code/controllers/configuration/entries/config.dm
@@ -8,10 +8,8 @@ CONFIG_DEF(string/autoadmin_rank) // the rank for autoadmins
protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(string/servername) // server name (the name of the game window)
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(string/serversqlname) // short form server name used for the DB
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(string/stationname) // station name (the name of the station in-game)
@@ -24,52 +22,38 @@ CONFIG_DEF(number/round_end_countdown) // Post round murder death kill countdown
min_val = 0
CONFIG_DEF(flag/hub) // if the game appears on the hub or not
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_ooc) // log OOC channel
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_access) // log login/logout
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_say) // log client say
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_admin) // log admin actions
protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_prayer) // log prayers
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_law) // log lawchanges
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_game) // log game events
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_vote) // log voting
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_whisper) // log client whisper
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_attack) // log attack messages
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_emote) // log emotes
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_adminchat) // log admin chat messages
protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_pda) // log pda messages
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_twitter) // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_world_topic) // log all world.Topic() calls
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/allow_admin_ooccolor) // Allows admins with relevant permissions to have their own ooc colour
protection = CONFIG_ENTRY_LOCKED
@@ -85,14 +69,12 @@ CONFIG_DEF(number/vote_delay) // minimum time between voting sessions (decisecon
CONFIG_DEF(number/vote_period) // length of voting period (deciseconds, default 1 minute)
value = 600
min_val = 0
-
+
CONFIG_DEF(flag/default_no_vote) // vote does not default to nochange/norestart
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/no_dead_vote) // dead people can't vote
CONFIG_DEF(flag/allow_metadata) // Metadata is supported.
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/popup_admin_pm) // adminPMs to non-admins show in a pop-up 'reply' window when set
@@ -140,14 +122,12 @@ CONFIG_DEF(flag/admin_legacy_system) //Defines whether the server uses the legac
protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(string/hostedby)
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/norespawn)
CONFIG_DEF(flag/guest_jobban)
CONFIG_DEF(flag/usewhitelist)
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/ban_legacy_system) //Defines whether the server uses the legacy banning system with the files in /data or the SQL system.
protection = CONFIG_ENTRY_LOCKED
@@ -171,29 +151,22 @@ CONFIG_DEF(flag/use_exp_restrictions_other)
CONFIG_DEF(flag/use_exp_restrictions_admin_bypass)
CONFIG_DEF(string/server)
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(string/banappeals)
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(string/wikiurl)
- protection = CONFIG_ENTRY_LOCKED
value = "http://www.tgstation13.org/wiki"
CONFIG_DEF(string/forumurl)
- protection = CONFIG_ENTRY_LOCKED
value = "http://tgstation13.org/phpBB/index.php"
CONFIG_DEF(string/rulesurl)
- protection = CONFIG_ENTRY_LOCKED
value = "http://www.tgstation13.org/wiki/Rules"
CONFIG_DEF(string/githuburl)
- protection = CONFIG_ENTRY_LOCKED
value = "https://www.github.com/tgstation/-tg-station"
CONFIG_DEF(number/githubrepoid)
- protection = CONFIG_ENTRY_LOCKED
value = null
min_val = 0
@@ -233,7 +206,6 @@ CONFIG_DEF(flag/useircbot) //tgs2 support
CONFIG_DEF(flag/automute_on) //enables automuting/spam prevention
CONFIG_DEF(string/panic_server_name)
- protection = CONFIG_ENTRY_LOCKED
/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val)
return str_val != "\[Put the name here\]" && ..()
@@ -290,7 +262,6 @@ CONFIG_DEF(string/extreme_popcap_message)
value = "The server is currently serving a high number of users, find alternative servers."
CONFIG_DEF(flag/panic_bunker) // prevents people the server hasn't seen before from connecting
- protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(number/notify_new_player_age) // how long do we notify admins of a new player
min_val = -1
@@ -303,7 +274,6 @@ CONFIG_DEF(flag/irc_first_connection_alert) // do we notify the irc channel when
CONFIG_DEF(flag/check_randomizer)
CONFIG_DEF(string/ipintel_email)
- protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val)
return str_val != "ch@nge.me" && ..()
@@ -315,17 +285,14 @@ CONFIG_DEF(number/ipintel_rating_bad)
max_val = 1
CONFIG_DEF(number/ipintel_save_good)
- protection = CONFIG_ENTRY_LOCKED
value = 12
min_val = 0
CONFIG_DEF(number/ipintel_save_bad)
- protection = CONFIG_ENTRY_LOCKED
value = 1
min_val = 0
CONFIG_DEF(string/ipintel_domain)
- protection = CONFIG_ENTRY_LOCKED
value = "check.getipintel.net"
CONFIG_DEF(flag/aggressive_changelog)
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 911b72e4da..fc53bfa25a 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -344,6 +344,8 @@ SUBSYSTEM_DEF(ticker)
var/list/miscreants = list()
to_chat(world, "
The round has ended.")
+ if(LAZYLEN(GLOB.round_end_notifiees))
+ send2irc("Notice", "[GLOB.round_end_notifiees.Join(", ")] the round has ended.")
/* var/nocredits = config.no_credits_round_end
for(var/client/C in GLOB.clients)
diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm
index c790dcc1aa..d4b75e3892 100644
--- a/code/datums/components/material_container.dm
+++ b/code/datums/components/material_container.dm
@@ -17,6 +17,7 @@
var/show_on_examine
var/list/allowed_typecache
var/last_inserted_type
+ var/last_inserted_id
var/last_amount_inserted
var/last_insert_success
var/datum/callback/precondition
@@ -116,7 +117,7 @@
if(!amt)
return 0
- insert_materials(S,amt)
+ last_inserted_id = insert_materials(S,amt)
last_inserted_type = S.type
S.use(amt)
last_amount_inserted = amt
@@ -133,17 +134,22 @@
if(!material_amount || !has_space(material_amount))
return 0
- insert_materials(I, multiplier)
+ last_inserted_id = insert_materials(I, multiplier)
last_inserted_type = I.type
last_amount_inserted = material_amount
return material_amount
/datum/component/material_container/proc/insert_materials(obj/item/I, multiplier = 1) //for internal usage only
var/datum/material/M
+ var/primary_mat
+ var/max_mat_value = 0
for(var/MAT in materials)
M = materials[MAT]
M.amount += I.materials[MAT] * multiplier
total_amount += I.materials[MAT] * multiplier
+ if(I.materials[MAT] > max_mat_value)
+ primary_mat = MAT
+ return primary_mat
//For consuming material
//mats is a list of types of material to use and the corresponding amounts, example: list(MAT_METAL=100, MAT_GLASS=200)
diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm
index 1d3e7f2a12..a00d43ad8f 100644
--- a/code/datums/diseases/_MobProcs.dm
+++ b/code/datums/diseases/_MobProcs.dm
@@ -43,7 +43,7 @@
SSdisease.active_diseases += DD //Add it to the active diseases list, now that it's actually in a mob and being processed.
//Copy properties over. This is so edited diseases persist.
- var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed","symptoms")
+ var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed","symptoms","processing")
for(var/V in DD.vars)
if(V in skipped)
continue
diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index 64a1d4ff07..12555ee038 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -28,6 +28,10 @@
destination.dna.temporary_mutations = temporary_mutations.Copy()
if(transfer_SE)
destination.dna.struc_enzymes = struc_enzymes
+ if(ishuman(destination))
+ var/mob/living/carbon/human/H = destination
+ H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA
+ destination.flavor_text = destination.dna.features["flavor_text"] //Update the flavor_text to use new dna text
/datum/dna/proc/copy_dna(datum/dna/new_dna)
new_dna.unique_enzymes = unique_enzymes
@@ -227,6 +231,7 @@
if(newfeatures)
dna.features = newfeatures
+ flavor_text = dna.features["flavor_text"] //Update the flavor_text to use new dna text
if(mrace)
var/datum/species/newrace = new mrace.type
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index a3bfa7d497..093e828452 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -63,6 +63,7 @@
var/mob/living/enslaved_to //If this mind's master is another mob (i.e. adamantine golems)
var/datum/language_holder/language_holder
+ var/unconvertable = FALSE
/datum/mind/New(var/key)
src.key = key
diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index 69749475cd..25b04b4312 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -71,7 +71,7 @@
/datum/status_effect/vanguard_shield/on_apply()
owner.log_message("gained Vanguard stun immunity", INDIVIDUAL_ATTACK_LOG)
- owner.add_stun_absorption("vanguard", 200, 1, "'s yellow aura momentarily intensifies!", "Your ward absorbs the stun!", " radiating with a soft yellow light!")
+ owner.add_stun_absorption("vanguard", INFINITY, 1, "'s yellow aura momentarily intensifies!", "Your ward absorbs the stun!", " radiating with a soft yellow light!")
owner.visible_message("[owner] begins to faintly glow!", "You will absorb all stuns for the next twenty seconds.")
owner.SetStun(0, FALSE)
owner.SetKnockdown(0)
@@ -87,7 +87,8 @@
var/vanguard = owner.stun_absorption["vanguard"]
var/stuns_blocked = 0
if(vanguard)
- stuns_blocked = round(min(vanguard["stuns_absorbed"] * 0.25, 20))
+ stuns_blocked = Floor(min(vanguard["stuns_absorbed"] * 0.25, 400))
+ vanguard["end_time"] = 0 //so it doesn't absorb the stuns we're about to apply
if(owner.stat != DEAD)
var/message_to_owner = "You feel your Vanguard quietly fade..."
var/otheractiveabsorptions = FALSE
@@ -95,7 +96,6 @@
if(owner.stun_absorption[i]["end_time"] > world.time && owner.stun_absorption[i]["priority"] > vanguard["priority"])
otheractiveabsorptions = TRUE
if(!GLOB.ratvar_awakens && stuns_blocked && !otheractiveabsorptions)
- vanguard["end_time"] = 0 //so it doesn't absorb the stuns we're about to apply
owner.Knockdown(stuns_blocked)
message_to_owner = "The weight of the Vanguard's protection crashes down upon you!"
if(stuns_blocked >= 300)
diff --git a/code/datums/weather/weather_types/ash_storm.dm b/code/datums/weather/weather_types/ash_storm.dm
index 2c2212fde5..a1dc9ece69 100644
--- a/code/datums/weather/weather_types/ash_storm.dm
+++ b/code/datums/weather/weather_types/ash_storm.dm
@@ -27,7 +27,7 @@
probability = 90
/datum/weather/ash_storm/proc/is_ash_immune(mob/living/L)
- if(istype(L.loc, /obj/mecha)) //Mechs are immune
+ if(ismecha(L.loc)) //Mechs are immune
return TRUE
if(ishuman(L)) //Are you immune?
var/mob/living/carbon/human/H = L
diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm
index 4846cc2bc2..c4b5c5caae 100644
--- a/code/game/area/Space_Station_13_areas.dm
+++ b/code/game/area/Space_Station_13_areas.dm
@@ -151,7 +151,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/maintenance/department/medical
name = "Medbay Maintenance"
- icon_state = "asmaint"
+ icon_state = "medbay_maint"
+
+/area/maintenance/department/medical/morgue
+ name = "Morgue Maintenance"
+ icon_state = "morgue_maint"
/area/maintenance/department/science
name = "Science Maintenance"
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 508459188b..0774253d47 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -189,6 +189,7 @@
/atom/proc/CollidedWith(atom/movable/AM)
+ set waitfor = FALSE
return
// Convenience proc to see if a container is open for chemistry handling
diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
index 0e72fe93aa..7d6f9bcdd1 100644
--- a/code/game/gamemodes/clock_cult/clock_cult.dm
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -53,6 +53,8 @@ Credit where due:
return FALSE
if(M.mind.enslaved_to && !is_servant_of_ratvar(M.mind.enslaved_to))
return FALSE
+ if(M.mind.unconvertable)
+ return FALSE
else
return FALSE
if(iscultist(M) || isconstruct(M) || M.isloyal() || ispAI(M))
diff --git a/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm b/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm
index 0a7a1b53b0..cdff486eea 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm
@@ -75,7 +75,7 @@
if(GLOB.ratvar_awakens && L)
L.adjust_fire_stacks(damage_per_tick)
L.IgniteMob()
- else if(istype(target, /obj/mecha))
+ else if(ismecha(target))
var/obj/mecha/M = target
M.take_damage(damage_per_tick * get_efficiency_mod(), BURN, "melee", 1, get_dir(src, M))
@@ -90,7 +90,7 @@
if(isliving(target))
var/mob/living/L = target
to_chat(L, "\"I SEE YOU!\"\n[src]'s gaze [GLOB.ratvar_awakens ? "melts you alive" : "burns you"]!")
- else if(istype(target, /obj/mecha))
+ else if(ismecha(target))
var/obj/mecha/M = target
to_chat(M.occupant, "\"I SEE YOU!\"" )
else if(prob(0.5)) //Extremely low chance because of how fast the subsystem it uses processes
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index 868e02589b..01773f1ea6 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -21,6 +21,8 @@
return FALSE
if(M.mind.enslaved_to && !iscultist(M.mind.enslaved_to))
return FALSE
+ if(M.mind.unconvertable)
+ return FALSE
else
return FALSE
if(M.isloyal() || issilicon(M) || isbot(M) || isdrone(M) || is_servant_of_ratvar(M))
diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
index d919d5d277..c125f7648d 100644
--- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
+++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
@@ -468,11 +468,8 @@
return
var/turf/open/floor/F
- switch(z) //Only the station/lavaland
- if(ZLEVEL_STATION_PRIMARY)
- F =find_safe_turf(zlevels = ZLEVEL_STATION_PRIMARY, extended_safety_checks = TRUE)
- if(ZLEVEL_LAVALAND)
- F = find_safe_turf(zlevels = ZLEVEL_LAVALAND, extended_safety_checks = TRUE)
+ F = find_safe_turf(zlevels = z, extended_safety_checks = TRUE)
+
if(!F)
return
// If we're getting rid of a human, slap some energy cuffs on
diff --git a/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm b/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm
index 783cfdd930..fb0bdfb6f9 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm
@@ -34,17 +34,13 @@
var/list/spawn_locs = list()
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
+ for(var/obj/effect/landmark/revenantspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
- switch(L.name)
- if("revenantspawn")
- spawn_locs += L.loc
+ spawn_locs += L.loc
if(!spawn_locs.len) //If we can't find any revenant spawns, try the carp spawns
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
+ for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
- switch(L.name)
- if("carpspawn")
- spawn_locs += L.loc
+ spawn_locs += L.loc
if(!spawn_locs.len) //If we can't find either, just spawn the revenant at the player's location
spawn_locs += get_turf(selected)
if(!spawn_locs.len) //If we can't find THAT, then just give up and cry
diff --git a/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm b/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm
index 888a10669e..4d85744738 100644
--- a/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm
+++ b/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm
@@ -23,11 +23,9 @@
player_mind.active = 1
var/list/spawn_locs = list()
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
+ for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
- switch(L.name)
- if("carpspawn")
- spawn_locs += L.loc
+ spawn_locs += L.loc
if(!spawn_locs)
message_admins("No valid spawn locations found, aborting...")
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 1646996cf5..effe2212a7 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -17,14 +17,6 @@
if(owner)
. += owner
-/datum/objective/proc/considered_alive(var/datum/mind/M)
- if(M && M.current)
- var/mob/living/carbon/human/H
- if(ishuman(M.current))
- H = M.current
- return M.current.stat != DEAD && !issilicon(M.current) && !isbrain(M.current) && (!H || H.dna.species.id != "memezombies")
- return FALSE
-
/datum/objective/proc/considered_escaped(datum/mind/M)
if(!considered_alive(M))
return FALSE
@@ -37,9 +29,6 @@
return FALSE
return location.onCentCom() || location.onSyndieBase()
-/datum/objective/proc/considered_afk(datum/mind/M)
- return !M || !M.current || !M.current.client || M.current.client.is_afk()
-
/datum/objective/proc/check_completion()
return completed
@@ -348,13 +337,14 @@
return FALSE
return TRUE
-//Like survive, but works for silicons and zombies and such.
-/datum/objective/survive/exist/considered_alive(var/datum/mind/M)
- if(M && M.current)
- if(isliving(M.current))
- var/mob/living/L = M.current
- return L.stat != DEAD
- return FALSE
+/datum/objective/survive/exist //Like survive, but works for silicons and zombies and such.
+
+/datum/objective/survive/exist/check_completion()
+ var/list/datum/mind/owners = get_owners()
+ for(var/datum/mind/M in owners)
+ if(!considered_alive(M, FALSE))
+ return FALSE
+ return TRUE
/datum/objective/martyr
explanation_text = "Die a glorious death."
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index ecfe8cfc44..c1b6d13456 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -253,12 +253,14 @@
/datum/game_mode/proc/add_revolutionary(datum/mind/rev_mind)
if(rev_mind.assigned_role in GLOB.command_positions)
- return 0
+ return FALSE
var/mob/living/carbon/human/H = rev_mind.current//Check to see if the potential rev is implanted
if(H.isloyal())
- return 0
+ return FALSE
if((rev_mind in revolutionaries) || (rev_mind in head_revolutionaries))
- return 0
+ return FALSE
+ if(rev_mind.unconvertable)
+ return FALSE
revolutionaries += rev_mind
if(iscarbon(rev_mind.current))
var/mob/living/carbon/carbon_mob = rev_mind.current
@@ -271,7 +273,7 @@
update_rev_icons_added(rev_mind)
if(jobban_isbanned(rev_mind.current, ROLE_REV))
INVOKE_ASYNC(src, .proc/replace_jobbaned_player, rev_mind.current, ROLE_REV, ROLE_REV)
- return 1
+ return TRUE
//////////////////////////////////////////////////////////////////////////////
//Deals with players being converted from the revolution (Not a rev anymore)// // Modified to handle borged MMIs. Accepts another var if the target is being borged at the time -- Polymorph.
//////////////////////////////////////////////////////////////////////////////
@@ -329,7 +331,7 @@
/datum/game_mode/revolution/proc/check_heads_victory()
for(var/datum/mind/rev_mind in head_revolutionaries)
var/turf/T = get_turf(rev_mind.current)
- if((rev_mind) && (rev_mind.current) && (rev_mind.current.stat != DEAD) && T && (T.z in GLOB.station_z_levels))
+ if(!considered_afk(rev_mind) && considered_alive(rev_mind) && (T.z in GLOB.station_z_levels))
if(ishuman(rev_mind.current))
return 0
return 1
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index 054bf07f70..23b398605c 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -95,6 +95,7 @@ Class Procs:
/obj/machinery
name = "machinery"
icon = 'icons/obj/stationobjs.dmi'
+ desc = "Some kind of machine."
verb_say = "beeps"
verb_yell = "blares"
pressure_resistance = 15
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 9fa53765ed..4894952a69 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -134,12 +134,11 @@
if(ispath(lit, /obj/item/ore/bluespace_crystal))
use_power(max(500,M.last_amount_inserted/10))
else
- var/obj/item/stack/S = lit
- var/list/initmats = initial(S.materials)
- if (initmats[MAT_METAL])
- flick("autolathe_o",src)//plays metal insertion animation
- if (initmats[MAT_GLASS])
- flick("autolathe_r",src)//plays glass insertion animation
+ switch(M.last_inserted_id)
+ if (MAT_METAL)
+ flick("autolathe_o",src)//plays metal insertion animation
+ if (MAT_GLASS)
+ flick("autolathe_r",src)//plays glass insertion animation
use_power(M.last_amount_inserted*100)
updateUsrDialog()
diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm
index 5f2324f236..cfc3c13cfc 100644
--- a/code/game/machinery/computer/dna_console.dm
+++ b/code/game/machinery/computer/dna_console.dm
@@ -168,7 +168,7 @@
if("working")
temp_html += status
temp_html += "
System Busy
"
- temp_html += "Working ... Please wait ([DisplayTimeText(radduration)])"
+ temp_html += "Working ... Please wait ([DisplayTimeText(radduration*10)])"
if("buffer")
temp_html += status
temp_html += buttons
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 25bbe1bc1d..883cc3986f 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -83,7 +83,7 @@
bumpopen(M)
return
- if(istype(AM, /obj/mecha))
+ if(ismecha(AM))
var/obj/mecha/mecha = AM
if(density)
if(mecha.occupant)
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index f76412199c..4809f3ff49 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -62,7 +62,7 @@
if( operating || !src.density )
return
if (!( ismob(AM) ))
- if(istype(AM, /obj/mecha))
+ if(ismecha(AM))
var/obj/mecha/mecha = AM
if(mecha.occupant && src.allowed(mecha.occupant))
open_and_close()
diff --git a/code/game/machinery/embedded_controller/access_controller.dm b/code/game/machinery/embedded_controller/access_controller.dm
index c23f4d0ba8..5e0d018554 100644
--- a/code/game/machinery/embedded_controller/access_controller.dm
+++ b/code/game/machinery/embedded_controller/access_controller.dm
@@ -42,6 +42,7 @@
icon = 'icons/obj/airlock_machines.dmi'
icon_state = "access_button_standby"
name = "access button"
+ desc = "A button used for the explicit purpose of opening an airlock."
var/idDoor
var/obj/machinery/door/airlock/door
var/obj/machinery/doorButtons/airlock_controller/controller
@@ -107,6 +108,7 @@
icon = 'icons/obj/airlock_machines.dmi'
icon_state = "access_control_standby"
name = "access console"
+ desc = "A small console that can cycle opening between two airlocks."
var/obj/machinery/door/airlock/interiorAirlock
var/obj/machinery/door/airlock/exteriorAirlock
var/idInterior
diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm
index a979ba6398..102be57f9b 100644
--- a/code/game/machinery/lightswitch.dm
+++ b/code/game/machinery/lightswitch.dm
@@ -6,6 +6,7 @@
icon = 'icons/obj/power.dmi'
icon_state = "light1"
anchored = TRUE
+ desc = "Make dark."
var/on = TRUE
var/area/area = null
var/otherarea = null
diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm
index 17f573fe6d..9acd4730d8 100644
--- a/code/game/machinery/mass_driver.dm
+++ b/code/game/machinery/mass_driver.dm
@@ -20,7 +20,7 @@
var/O_limit
var/atom/target = get_edge_target_turf(src, dir)
for(var/atom/movable/O in loc)
- if(!O.anchored || istype(O, /obj/mecha)) //Mechs need their launch platforms.
+ if(!O.anchored || ismecha(O)) //Mechs need their launch platforms.
O_limit++
if(O_limit >= 20)
audible_message("[src] lets out a screech, it doesn't seem to be able to handle the load.")
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index 39b3760f7e..cedb94b7b3 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -2,6 +2,7 @@
name = "pipe dispenser"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "pipe_d"
+ desc = "Dispenses countless types of pipes. Very useful if you need pipes."
density = TRUE
anchored = TRUE
var/wait = 0
@@ -108,6 +109,7 @@
name = "disposal pipe dispenser"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "pipe_d"
+ desc = "Dispenses pipes that will ultimately be used to move trash around."
density = TRUE
anchored = TRUE
@@ -183,6 +185,7 @@ Nah
icon = 'icons/obj/stationobjs.dmi'
icon_state = "pipe_d"
density = TRUE
+ desc = "Dispenses pipes that will move beings around."
anchored = TRUE
/obj/machinery/pipedispenser/disposal/transit_tube/attack_hand(mob/user)
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index b84de7cf18..8f8202fe19 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -12,6 +12,7 @@
layer = OBJ_LAYER
invisibility = INVISIBILITY_OBSERVER //the turret is invisible if it's inside its cover
density = TRUE
+ desc = "A covered turret that shoots at its enemies."
use_power = IDLE_POWER_USE //this turret uses and requires power
idle_power_usage = 50 //when inactive, this turret takes up constant 50 Equipment power
active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power
@@ -389,7 +390,7 @@
if(!in_faction(C))
targets += C
- if(istype(A, /obj/mecha))
+ if(ismecha(A))
var/obj/mecha/M = A
//If there is a user and they're not in our faction
if(M.occupant && !in_faction(M.occupant))
@@ -552,6 +553,7 @@
base_icon_state = "syndie"
faction = "syndicate"
emp_vunerable = 0
+ desc = "A ballistic machine gun auto-turret."
/obj/machinery/porta_turret/syndicate/energy
icon_state = "standard_stun"
@@ -560,6 +562,7 @@
stun_projectile_sound = 'sound/weapons/taser.ogg'
lethal_projectile = /obj/item/projectile/beam/laser/heavylaser
lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
+ desc = "An energy blaster auto-turret."
/obj/machinery/porta_turret/syndicate/setup()
return
diff --git a/code/game/machinery/porta_turret/portable_turret_construct.dm b/code/game/machinery/porta_turret/portable_turret_construct.dm
index 1dbdc52b1e..7eace08636 100644
--- a/code/game/machinery/porta_turret/portable_turret_construct.dm
+++ b/code/game/machinery/porta_turret/portable_turret_construct.dm
@@ -12,6 +12,7 @@
name = "turret frame"
icon = 'icons/obj/turrets.dmi'
icon_state = "turret_frame"
+ desc = "An unfinished covered turret frame."
density = TRUE
var/build_step = PTURRET_UNSECURED //the current step in the building process
var/finish_name = "turret" //the name applied to the product turret
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index fbe02dca37..d2ea1a4fd6 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -1,197 +1,198 @@
-#define SAFETY_COOLDOWN 100
-
-/obj/machinery/recycler
- name = "recycler"
- desc = "A large crushing machine used to recycle small items inefficiently. There are lights on the side."
- icon = 'icons/obj/recycling.dmi'
- icon_state = "grinder-o0"
- layer = ABOVE_ALL_MOB_LAYER // Overhead
- anchored = TRUE
- density = TRUE
- circuit = /obj/item/circuitboard/machine/recycler
- var/safety_mode = FALSE // Temporarily stops machine if it detects a mob
- var/icon_name = "grinder-o"
- var/blood = 0
- var/eat_dir = WEST
- var/amount_produced = 50
- var/crush_damage = 1000
- var/eat_victim_items = TRUE
- var/item_recycle_sound = 'sound/items/welder.ogg'
-
-/obj/machinery/recycler/Initialize()
- AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM))
- . = ..()
- update_icon()
-
-/obj/machinery/recycler/RefreshParts()
- var/amt_made = 0
- var/mat_mod = 0
- for(var/obj/item/stock_parts/matter_bin/B in component_parts)
- mat_mod = 2 * B.rating
- mat_mod *= 50000
- for(var/obj/item/stock_parts/manipulator/M in component_parts)
- amt_made = 12.5 * M.rating //% of materials salvaged
- GET_COMPONENT(materials, /datum/component/material_container)
- materials.max_amount = mat_mod
- amount_produced = min(50, amt_made) + 50
-
-/obj/machinery/recycler/examine(mob/user)
- ..()
- to_chat(user, "The power light is [(stat & NOPOWER) ? "off" : "on"].")
- to_chat(user, "The safety-mode light is [safety_mode ? "on" : "off"].")
- to_chat(user, "The safety-sensors status light is [emagged ? "off" : "on"].")
-
-/obj/machinery/recycler/power_change()
- ..()
- update_icon()
-
-
-/obj/machinery/recycler/attackby(obj/item/I, mob/user, params)
- if(default_deconstruction_screwdriver(user, "grinder-oOpen", "grinder-o0", I))
- return
-
- if(exchange_parts(user, I))
- return
-
- if(default_pry_open(I))
- return
-
- if(default_unfasten_wrench(user, I))
- return
-
- if(default_deconstruction_crowbar(I))
- return
- return ..()
-
-/obj/machinery/recycler/emag_act(mob/user)
- if(emagged)
- return
- emagged = TRUE
- if(safety_mode)
- safety_mode = FALSE
- update_icon()
- playsound(src, "sparks", 75, 1, -1)
- to_chat(user, "You use the cryptographic sequencer on the [src].")
-
-/obj/machinery/recycler/update_icon()
- ..()
- var/is_powered = !(stat & (BROKEN|NOPOWER))
- if(safety_mode)
- is_powered = FALSE
- icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end
-
-/obj/machinery/recycler/CollidedWith(atom/movable/AM)
-
- if(stat & (BROKEN|NOPOWER))
- return
- if(!anchored)
- return
- if(safety_mode)
- return
-
- var/move_dir = get_dir(loc, AM.loc)
- if(move_dir == eat_dir)
- eat(AM)
-
-/obj/machinery/recycler/proc/eat(atom/AM0, sound=TRUE)
- var/list/to_eat
- if(istype(AM0, /obj/item))
- to_eat = AM0.GetAllContents()
- else
- to_eat = list(AM0)
-
- var/items_recycled = 0
-
- for(var/i in to_eat)
- var/atom/movable/AM = i
- var/obj/item/bodypart/head/as_head = AM
- var/obj/item/device/mmi/as_mmi = AM
- var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /mob/living/brain)
- if(isliving(AM) || brain_holder)
- if(emagged)
- if(!brain_holder)
- crush_living(AM)
- else
- emergency_stop(AM)
- else if(istype(AM, /obj/item))
- recycle_item(AM)
- items_recycled++
- else
- playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
- AM.loc = src.loc
-
- if(items_recycled && sound)
- playsound(src.loc, item_recycle_sound, 50, 1)
-
-/obj/machinery/recycler/proc/recycle_item(obj/item/I)
- I.loc = src.loc
-
- GET_COMPONENT(materials, /datum/component/material_container)
- var/material_amount = materials.get_item_material_amount(I)
- if(!material_amount)
- qdel(I)
- return
- materials.insert_item(I, multiplier = (amount_produced / 100))
- qdel(I)
- materials.retrieve_all()
-
-
-/obj/machinery/recycler/proc/emergency_stop(mob/living/L)
- playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
- safety_mode = TRUE
- update_icon()
- L.loc = src.loc
- addtimer(CALLBACK(src, .proc/reboot), SAFETY_COOLDOWN)
-
-/obj/machinery/recycler/proc/reboot()
- playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
- safety_mode = FALSE
- update_icon()
-
-/obj/machinery/recycler/proc/crush_living(mob/living/L)
-
- L.loc = src.loc
-
- if(issilicon(L))
- playsound(src.loc, 'sound/items/welder.ogg', 50, 1)
- else
- playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
-
- var/gib = TRUE
- // By default, the emagged recycler will gib all non-carbons. (human simple animal mobs don't count)
- if(iscarbon(L))
- gib = FALSE
- if(L.stat == CONSCIOUS)
- L.say("ARRRRRRRRRRRGH!!!")
- add_mob_blood(L)
-
- if(!blood && !issilicon(L))
- blood = TRUE
- update_icon()
-
- // Remove and recycle the equipped items
- if(eat_victim_items)
- for(var/obj/item/I in L.get_equipped_items())
- if(L.dropItemToGround(I))
- eat(I, sound=FALSE)
-
- // Instantly lie down, also go unconscious from the pain, before you die.
- L.Unconscious(100)
-
- // For admin fun, var edit emagged to 2.
- if(gib || emagged == 2)
- L.gib()
- else if(emagged == 1)
- L.adjustBruteLoss(crush_damage)
-
-/obj/machinery/recycler/deathtrap
- name = "dangerous old crusher"
- emagged = TRUE
- crush_damage = 120
- flags_1 = NODECONSTRUCT_1
-
-/obj/item/paper/guides/recycler
- name = "paper - 'garbage duty instructions'"
- info = "New Assignment
You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.
There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!"
-
-#undef SAFETY_COOLDOWN
+#define SAFETY_COOLDOWN 100
+
+/obj/machinery/recycler
+ name = "recycler"
+ desc = "A large crushing machine used to recycle small items inefficiently. There are lights on the side."
+ icon = 'icons/obj/recycling.dmi'
+ icon_state = "grinder-o0"
+ layer = ABOVE_ALL_MOB_LAYER // Overhead
+ anchored = TRUE
+ density = TRUE
+ circuit = /obj/item/circuitboard/machine/recycler
+ var/safety_mode = FALSE // Temporarily stops machine if it detects a mob
+ var/icon_name = "grinder-o"
+ var/blood = 0
+ var/eat_dir = WEST
+ var/amount_produced = 50
+ var/crush_damage = 1000
+ var/eat_victim_items = TRUE
+ var/item_recycle_sound = 'sound/items/welder.ogg'
+
+/obj/machinery/recycler/Initialize()
+ AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM))
+ . = ..()
+ update_icon()
+
+/obj/machinery/recycler/RefreshParts()
+ var/amt_made = 0
+ var/mat_mod = 0
+ for(var/obj/item/stock_parts/matter_bin/B in component_parts)
+ mat_mod = 2 * B.rating
+ mat_mod *= 50000
+ for(var/obj/item/stock_parts/manipulator/M in component_parts)
+ amt_made = 12.5 * M.rating //% of materials salvaged
+ GET_COMPONENT(materials, /datum/component/material_container)
+ materials.max_amount = mat_mod
+ amount_produced = min(50, amt_made) + 50
+
+/obj/machinery/recycler/examine(mob/user)
+ ..()
+ to_chat(user, "The power light is [(stat & NOPOWER) ? "off" : "on"].")
+ to_chat(user, "The safety-mode light is [safety_mode ? "on" : "off"].")
+ to_chat(user, "The safety-sensors status light is [emagged ? "off" : "on"].")
+
+/obj/machinery/recycler/power_change()
+ ..()
+ update_icon()
+
+
+/obj/machinery/recycler/attackby(obj/item/I, mob/user, params)
+ if(default_deconstruction_screwdriver(user, "grinder-oOpen", "grinder-o0", I))
+ return
+
+ if(exchange_parts(user, I))
+ return
+
+ if(default_pry_open(I))
+ return
+
+ if(default_unfasten_wrench(user, I))
+ return
+
+ if(default_deconstruction_crowbar(I))
+ return
+ return ..()
+
+/obj/machinery/recycler/emag_act(mob/user)
+ if(emagged)
+ return
+ emagged = TRUE
+ if(safety_mode)
+ safety_mode = FALSE
+ update_icon()
+ playsound(src, "sparks", 75, 1, -1)
+ to_chat(user, "You use the cryptographic sequencer on the [src].")
+
+/obj/machinery/recycler/update_icon()
+ ..()
+ var/is_powered = !(stat & (BROKEN|NOPOWER))
+ if(safety_mode)
+ is_powered = FALSE
+ icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end
+
+/obj/machinery/recycler/CollidedWith(atom/movable/AM)
+
+ if(stat & (BROKEN|NOPOWER))
+ return
+ if(!anchored)
+ return
+ if(safety_mode)
+ return
+
+ var/move_dir = get_dir(loc, AM.loc)
+ if(move_dir == eat_dir)
+ eat(AM)
+
+/obj/machinery/recycler/proc/eat(atom/AM0, sound=TRUE)
+ var/list/to_eat
+ if(istype(AM0, /obj/item))
+ to_eat = AM0.GetAllContents()
+ else
+ to_eat = list(AM0)
+
+ var/items_recycled = 0
+
+ for(var/i in to_eat)
+ var/atom/movable/AM = i
+ var/obj/item/bodypart/head/as_head = AM
+ var/obj/item/device/mmi/as_mmi = AM
+ var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /mob/living/brain)
+ if(brain_holder)
+ emergency_stop(AM)
+ else if(isliving(AM))
+ if(emagged)
+ crush_living(AM)
+ else
+ emergency_stop(AM)
+ else if(istype(AM, /obj/item))
+ recycle_item(AM)
+ items_recycled++
+ else
+ playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
+ AM.forceMove(loc)
+
+ if(items_recycled && sound)
+ playsound(src, item_recycle_sound, 50, 1)
+
+/obj/machinery/recycler/proc/recycle_item(obj/item/I)
+ I.forceMove(loc)
+
+ GET_COMPONENT(materials, /datum/component/material_container)
+ var/material_amount = materials.get_item_material_amount(I)
+ if(!material_amount)
+ qdel(I)
+ return
+ materials.insert_item(I, multiplier = (amount_produced / 100))
+ qdel(I)
+ materials.retrieve_all()
+
+
+/obj/machinery/recycler/proc/emergency_stop(mob/living/L)
+ playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
+ safety_mode = TRUE
+ update_icon()
+ L.forceMove(loc)
+ addtimer(CALLBACK(src, .proc/reboot), SAFETY_COOLDOWN)
+
+/obj/machinery/recycler/proc/reboot()
+ playsound(src, 'sound/machines/ping.ogg', 50, 0)
+ safety_mode = FALSE
+ update_icon()
+
+/obj/machinery/recycler/proc/crush_living(mob/living/L)
+
+ L.forceMove(loc)
+
+ if(issilicon(L))
+ playsound(src, 'sound/items/welder.ogg', 50, 1)
+ else
+ playsound(src, 'sound/effects/splat.ogg', 50, 1)
+
+ var/gib = TRUE
+ // By default, the emagged recycler will gib all non-carbons. (human simple animal mobs don't count)
+ if(iscarbon(L))
+ gib = FALSE
+ if(L.stat == CONSCIOUS)
+ L.say("ARRRRRRRRRRRGH!!!")
+ add_mob_blood(L)
+
+ if(!blood && !issilicon(L))
+ blood = TRUE
+ update_icon()
+
+ // Remove and recycle the equipped items
+ if(eat_victim_items)
+ for(var/obj/item/I in L.get_equipped_items())
+ if(L.dropItemToGround(I))
+ eat(I, sound=FALSE)
+
+ // Instantly lie down, also go unconscious from the pain, before you die.
+ L.Unconscious(100)
+
+ // For admin fun, var edit emagged to 2.
+ if(gib || emagged == 2)
+ L.gib()
+ else if(emagged == 1)
+ L.adjustBruteLoss(crush_damage)
+
+/obj/machinery/recycler/deathtrap
+ name = "dangerous old crusher"
+ emagged = TRUE
+ crush_damage = 120
+ flags_1 = NODECONSTRUCT_1
+
+/obj/item/paper/guides/recycler
+ name = "paper - 'garbage duty instructions'"
+ info = "New Assignment
You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.
There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!"
+
+#undef SAFETY_COOLDOWN
diff --git a/code/game/machinery/telecomms/computers/logbrowser.dm b/code/game/machinery/telecomms/computers/logbrowser.dm
index 92a4edfcd2..590c8d03a5 100644
--- a/code/game/machinery/telecomms/computers/logbrowser.dm
+++ b/code/game/machinery/telecomms/computers/logbrowser.dm
@@ -3,6 +3,7 @@
/obj/machinery/computer/telecomms/server
name = "telecommunications server monitoring console"
icon_screen = "comm_logs"
+ desc = "Has full access to all details and record of the telecommunications network it's monitoring."
var/screen = 0 // the screen number:
var/list/servers = list() // the servers located by the computer
diff --git a/code/game/machinery/telecomms/computers/telemonitor.dm b/code/game/machinery/telecomms/computers/telemonitor.dm
index bccbfd96fd..cb3ae78e72 100644
--- a/code/game/machinery/telecomms/computers/telemonitor.dm
+++ b/code/game/machinery/telecomms/computers/telemonitor.dm
@@ -8,6 +8,7 @@
/obj/machinery/computer/telecomms/monitor
name = "telecommunications monitoring console"
icon_screen = "comm_monitor"
+ desc = "Monitors the details of the telecommunications network it's synced with."
var/screen = 0 // the screen number:
var/list/machinelist = list() // the machines located by the computer
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 8efc14d966..747647b1a5 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -420,13 +420,7 @@
var/datum/component/material_container/M = C
if(!M.last_insert_success)
return
- var/lit = M.last_inserted_type
- var/stack_name
- if(ispath(lit, /obj/item/ore/bluespace_crystal))
- stack_name = "bluespace"
- else
- var/obj/item/stack/S = lit
- stack_name = material2name(initial(S.materials)[1])
+ var/stack_name = material2name(M.last_inserted_id)
add_overlay("fab-load-[stack_name]")
addtimer(CALLBACK(src, /atom/proc/cut_overlay, "fab-load-[stack_name]"), 10)
updateUsrDialog()
diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm
index 6f1348c741..431768500e 100644
--- a/code/game/mecha/mecha_control_console.dm
+++ b/code/game/mecha/mecha_control_console.dm
@@ -1,137 +1,137 @@
-/obj/machinery/computer/mecha
- name = "exosuit control console"
- desc = "Used to remotely locate or lockdown exosuits."
- icon_screen = "mecha"
- icon_keyboard = "tech_key"
+/obj/machinery/computer/mecha
+ name = "exosuit control console"
+ desc = "Used to remotely locate or lockdown exosuits."
+ icon_screen = "mecha"
+ icon_keyboard = "tech_key"
req_access = list(ACCESS_ROBOTICS)
- circuit = /obj/item/circuitboard/computer/mecha_control
- var/list/located = list()
- var/screen = 0
- var/stored_data
-
-/obj/machinery/computer/mecha/attack_hand(mob/user)
- if(..())
- return
- user.set_machine(src)
- var/dat = "[src.name]"
- if(screen == 0)
- dat += "Tracking beacons data
"
- var/list/trackerlist = list()
- for(var/obj/mecha/MC in GLOB.mechas_list)
- trackerlist += MC.trackers
- for(var/obj/item/mecha_parts/mecha_tracking/TR in trackerlist)
- var/answer = TR.get_mecha_info()
- if(answer)
- dat += {"
[answer]
- Send message
- Show exosuit log | (EMP pulse)
"}
-
- if(screen==1)
- dat += "Log contents
"
- dat += "Return
"
- dat += "[stored_data]"
-
- dat += "(Refresh)
"
- dat += ""
-
- user << browse(dat, "window=computer;size=400x500")
- onclose(user, "computer")
- return
-
-/obj/machinery/computer/mecha/Topic(href, href_list)
- if(..())
- return
- var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
- if(href_list["send_message"])
- var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message")
- var/message = stripped_input(usr,"Input message","Transmit message")
- var/obj/mecha/M = MT.in_mecha()
- if(trim(message) && M)
- M.occupant_message(message)
- return
- if(href_list["shock"])
- var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock")
- MT.shock()
- if(href_list["get_log"])
- var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log")
- stored_data = MT.get_mecha_log()
- screen = 1
- if(href_list["return"])
- screen = 0
- updateUsrDialog()
- return
-
-/obj/item/mecha_parts/mecha_tracking
- name = "exosuit tracking beacon"
- desc = "Device used to transmit exosuit data."
- icon = 'icons/obj/device.dmi'
- icon_state = "motion2"
- w_class = WEIGHT_CLASS_SMALL
- origin_tech = "programming=2;magnets=2"
- var/ai_beacon = FALSE //If this beacon allows for AI control. Exists to avoid using istype() on checking.
-
-/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info()
- if(!in_mecha())
- return 0
- var/obj/mecha/M = src.loc
- var/cell_charge = M.get_charge()
- var/answer = {"Name: [M.name]
-Integrity: [M.obj_integrity/M.max_integrity*100]%
-Cell charge: [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]
-Airtank: [M.return_pressure()]kPa
-Pilot: [M.occupant||"None"]
-Location: [get_area(M)||"Unknown"]
-Active equipment: [M.selected||"None"] "}
- if(istype(M, /obj/mecha/working/ripley))
- var/obj/mecha/working/ripley/RM = M
- answer += "Used cargo space: [RM.cargo.len/RM.cargo_capacity*100]%
"
-
- return answer
-
-/obj/item/mecha_parts/mecha_tracking/emp_act()
- qdel(src)
-
-/obj/item/mecha_parts/mecha_tracking/Destroy()
- if(istype(loc, /obj/mecha))
- var/obj/mecha/M = loc
- if(src in M.trackers)
- M.trackers -= src
- return ..()
-
-/obj/item/mecha_parts/mecha_tracking/proc/in_mecha()
- if(istype(src.loc, /obj/mecha))
- return src.loc
- return 0
-
-/obj/item/mecha_parts/mecha_tracking/proc/shock()
- var/obj/mecha/M = in_mecha()
- if(M)
+ circuit = /obj/item/circuitboard/computer/mecha_control
+ var/list/located = list()
+ var/screen = 0
+ var/stored_data
+
+/obj/machinery/computer/mecha/attack_hand(mob/user)
+ if(..())
+ return
+ user.set_machine(src)
+ var/dat = "[src.name]"
+ if(screen == 0)
+ dat += "Tracking beacons data
"
+ var/list/trackerlist = list()
+ for(var/obj/mecha/MC in GLOB.mechas_list)
+ trackerlist += MC.trackers
+ for(var/obj/item/mecha_parts/mecha_tracking/TR in trackerlist)
+ var/answer = TR.get_mecha_info()
+ if(answer)
+ dat += {"
[answer]
+ Send message
+ Show exosuit log | (EMP pulse)
"}
+
+ if(screen==1)
+ dat += "Log contents
"
+ dat += "Return
"
+ dat += "[stored_data]"
+
+ dat += "(Refresh)
"
+ dat += ""
+
+ user << browse(dat, "window=computer;size=400x500")
+ onclose(user, "computer")
+ return
+
+/obj/machinery/computer/mecha/Topic(href, href_list)
+ if(..())
+ return
+ var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
+ if(href_list["send_message"])
+ var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message")
+ var/message = stripped_input(usr,"Input message","Transmit message")
+ var/obj/mecha/M = MT.in_mecha()
+ if(trim(message) && M)
+ M.occupant_message(message)
+ return
+ if(href_list["shock"])
+ var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock")
+ MT.shock()
+ if(href_list["get_log"])
+ var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log")
+ stored_data = MT.get_mecha_log()
+ screen = 1
+ if(href_list["return"])
+ screen = 0
+ updateUsrDialog()
+ return
+
+/obj/item/mecha_parts/mecha_tracking
+ name = "exosuit tracking beacon"
+ desc = "Device used to transmit exosuit data."
+ icon = 'icons/obj/device.dmi'
+ icon_state = "motion2"
+ w_class = WEIGHT_CLASS_SMALL
+ origin_tech = "programming=2;magnets=2"
+ var/ai_beacon = FALSE //If this beacon allows for AI control. Exists to avoid using istype() on checking.
+
+/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info()
+ if(!in_mecha())
+ return 0
+ var/obj/mecha/M = src.loc
+ var/cell_charge = M.get_charge()
+ var/answer = {"Name: [M.name]
+Integrity: [M.obj_integrity/M.max_integrity*100]%
+Cell charge: [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]
+Airtank: [M.return_pressure()]kPa
+Pilot: [M.occupant||"None"]
+Location: [get_area(M)||"Unknown"]
+Active equipment: [M.selected||"None"] "}
+ if(istype(M, /obj/mecha/working/ripley))
+ var/obj/mecha/working/ripley/RM = M
+ answer += "Used cargo space: [RM.cargo.len/RM.cargo_capacity*100]%
"
+
+ return answer
+
+/obj/item/mecha_parts/mecha_tracking/emp_act()
+ qdel(src)
+
+/obj/item/mecha_parts/mecha_tracking/Destroy()
+ if(ismecha(loc))
+ var/obj/mecha/M = loc
+ if(src in M.trackers)
+ M.trackers -= src
+ return ..()
+
+/obj/item/mecha_parts/mecha_tracking/proc/in_mecha()
+ if(ismecha(loc))
+ return loc
+ return 0
+
+/obj/item/mecha_parts/mecha_tracking/proc/shock()
+ var/obj/mecha/M = in_mecha()
+ if(M)
M.emp_act(EMP_LIGHT)
- qdel(src)
-
-/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log()
- if(!istype(loc, /obj/mecha))
- return 0
- var/obj/mecha/M = src.loc
- return M.get_log_html()
-
-
-/obj/item/mecha_parts/mecha_tracking/ai_control
- name = "exosuit AI control beacon"
- desc = "A device used to transmit exosuit data. Also allows active AI units to take control of said exosuit."
- origin_tech = "programming=3;magnets=2;engineering=2"
- ai_beacon = TRUE
-
-
-/obj/item/storage/box/mechabeacons
- name = "exosuit tracking beacons"
-
-/obj/item/storage/box/mechabeacons/New()
- ..()
- new /obj/item/mecha_parts/mecha_tracking(src)
- new /obj/item/mecha_parts/mecha_tracking(src)
- new /obj/item/mecha_parts/mecha_tracking(src)
- new /obj/item/mecha_parts/mecha_tracking(src)
- new /obj/item/mecha_parts/mecha_tracking(src)
- new /obj/item/mecha_parts/mecha_tracking(src)
- new /obj/item/mecha_parts/mecha_tracking(src)
+ qdel(src)
+
+/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log()
+ if(!ismecha(loc))
+ return 0
+ var/obj/mecha/M = src.loc
+ return M.get_log_html()
+
+
+/obj/item/mecha_parts/mecha_tracking/ai_control
+ name = "exosuit AI control beacon"
+ desc = "A device used to transmit exosuit data. Also allows active AI units to take control of said exosuit."
+ origin_tech = "programming=3;magnets=2;engineering=2"
+ ai_beacon = TRUE
+
+
+/obj/item/storage/box/mechabeacons
+ name = "exosuit tracking beacons"
+
+/obj/item/storage/box/mechabeacons/New()
+ ..()
+ new /obj/item/mecha_parts/mecha_tracking(src)
+ new /obj/item/mecha_parts/mecha_tracking(src)
+ new /obj/item/mecha_parts/mecha_tracking(src)
+ new /obj/item/mecha_parts/mecha_tracking(src)
+ new /obj/item/mecha_parts/mecha_tracking(src)
+ new /obj/item/mecha_parts/mecha_tracking(src)
+ new /obj/item/mecha_parts/mecha_tracking(src)
diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm
index 97d00c339f..8bf0580e15 100644
--- a/code/game/objects/effects/portals.dm
+++ b/code/game/objects/effects/portals.dm
@@ -1,156 +1,154 @@
-
-/proc/create_portal_pair(turf/source, turf/destination, _creator = null, _lifespan = 300, accuracy = 0, newtype = /obj/effect/portal)
- if(!istype(source) || !istype(destination))
- return
- var/turf/actual_destination = get_teleport_turf(destination, accuracy)
- var/obj/effect/portal/P1 = new newtype(source, _creator, _lifespan, null, FALSE)
- var/obj/effect/portal/P2 = new newtype(actual_destination, _creator, _lifespan, P1, TRUE)
- if(!istype(P1)||!istype(P2))
- return
- P1.link_portal(P2)
- P1.hardlinked = TRUE
- return list(P1, P2)
-
-/obj/effect/portal
- name = "portal"
- desc = "Looks unstable. Best to test it with the clown."
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "portal"
- anchored = TRUE
- var/mech_sized = FALSE
- var/obj/effect/portal/linked
- var/hardlinked = TRUE //Requires a linked portal at all times. Destroy if there's no linked portal, if there is destroy it when this one is deleted.
- var/creator
- var/turf/hard_target //For when a portal needs a hard target and isn't to be linked.
- var/atmos_link = FALSE //Link source/destination atmos.
- var/turf/open/atmos_source //Atmos link source
- var/turf/open/atmos_destination //Atmos link destination
-
-/obj/effect/portal/anom
- name = "wormhole"
- icon = 'icons/obj/objects.dmi'
- icon_state = "anom"
- mech_sized = TRUE
-
-/obj/effect/portal/Move(newloc)
- for(var/T in newloc)
- if(istype(T, /obj/effect/portal))
- return FALSE
- return ..()
-
-/obj/effect/portal/attackby(obj/item/W, mob/user, params)
- if(user && Adjacent(user))
- teleport(user)
-
-/obj/effect/portal/Crossed(atom/movable/AM, oldloc)
- if(get_turf(oldloc) == get_turf(linked))
- return ..()
- if(!teleport(AM))
- return ..()
-
-/obj/effect/portal/attack_tk(mob/user)
- return
-
-/obj/effect/portal/attack_hand(mob/user)
- if(Adjacent(user))
- teleport(user)
-
-/obj/effect/portal/Initialize(mapload, _creator, _lifespan = 0, obj/effect/portal/_linked, automatic_link = FALSE, turf/hard_target_override, atmos_link_override)
- . = ..()
- GLOB.portals += src
- if(!istype(_linked) && automatic_link)
- . = INITIALIZE_HINT_QDEL
- CRASH("Somebody fucked up.")
- if(_lifespan > 0)
- QDEL_IN(src, _lifespan)
- if(!isnull(atmos_link_override))
- atmos_link = atmos_link_override
- link_portal(_linked)
- hardlinked = automatic_link
- creator = _creator
- if(isturf(hard_target_override))
- hard_target = hard_target_override
-
-/obj/effect/portal/proc/link_portal(obj/effect/portal/newlink)
- linked = newlink
- if(atmos_link)
- link_atmos()
-
-/obj/effect/portal/proc/link_atmos()
- if(atmos_source || atmos_destination)
- unlink_atmos()
- if(!isopenturf(get_turf(src)))
- return FALSE
- if(linked)
- if(isopenturf(get_turf(linked)))
- atmos_source = get_turf(src)
- atmos_destination = get_turf(linked)
- else if(hard_target)
- if(isopenturf(hard_target))
- atmos_source = get_turf(src)
- atmos_destination = hard_target
- else
- return FALSE
- if(!istype(atmos_source) || !istype(atmos_destination))
- return FALSE
- LAZYINITLIST(atmos_source.atmos_adjacent_turfs)
- LAZYINITLIST(atmos_destination.atmos_adjacent_turfs)
- if(atmos_source.atmos_adjacent_turfs[atmos_destination] || atmos_destination.atmos_adjacent_turfs[atmos_source]) //Already linked!
- return FALSE
- atmos_source.atmos_adjacent_turfs[atmos_destination] = TRUE
- atmos_destination.atmos_adjacent_turfs[atmos_source] = TRUE
- atmos_source.air_update_turf(FALSE)
- atmos_destination.air_update_turf(FALSE)
-
-/obj/effect/portal/proc/unlink_atmos()
- if(istype(atmos_source))
- if(istype(atmos_destination) && !atmos_source.Adjacent(atmos_destination) && !CANATMOSPASS(atmos_destination, atmos_source))
- LAZYREMOVE(atmos_source.atmos_adjacent_turfs, atmos_destination)
- atmos_source = null
- if(istype(atmos_destination))
- if(istype(atmos_source) && !atmos_destination.Adjacent(atmos_source) && !CANATMOSPASS(atmos_source, atmos_destination))
- LAZYREMOVE(atmos_destination.atmos_adjacent_turfs, atmos_source)
- atmos_destination = null
-
-/obj/effect/portal/Destroy() //Calls on_portal_destroy(destroyed portal, location of destroyed portal) on creator if creator has such call.
- if(creator && hascall(creator, "on_portal_destroy"))
- call(creator, "on_portal_destroy")(src, src.loc)
- creator = null
- GLOB.portals -= src
- unlink_atmos()
- if(hardlinked && !QDELETED(linked))
- QDEL_NULL(linked)
- else
- linked = null
- return ..()
-
-/obj/effect/portal/proc/teleport(atom/movable/M)
- if(!istype(M) || istype(M, /obj/effect) || (istype(M, /obj/mecha) && !mech_sized) || (!isobj(M) && !ismob(M))) //Things that shouldn't teleport.
- return
- var/turf/real_target = get_link_target_turf()
- if(!istype(real_target))
- return FALSE
- if(ismegafauna(M))
- message_admins("[M] has used a portal at [ADMIN_COORDJMP(src)] made by [usr].")
- if(do_teleport(M, real_target, 0))
- if(istype(M, /obj/item/projectile))
- var/obj/item/projectile/P = M
- P.ignore_source_check = TRUE
- return TRUE
- return FALSE
-
-/obj/effect/portal/proc/get_link_target_turf()
- var/turf/real_target
- if(!istype(linked) || QDELETED(linked))
- if(hardlinked)
- qdel(src)
- if(!istype(hard_target) || QDELETED(hard_target))
- hard_target = null
- return
- else
- real_target = hard_target
- linked = null
- else
- real_target = get_turf(linked)
- return real_target
-
+/proc/create_portal_pair(turf/source, turf/destination, _creator = null, _lifespan = 300, accuracy = 0, newtype = /obj/effect/portal)
+ if(!istype(source) || !istype(destination))
+ return
+ var/turf/actual_destination = get_teleport_turf(destination, accuracy)
+ var/obj/effect/portal/P1 = new newtype(source, _creator, _lifespan, null, FALSE)
+ var/obj/effect/portal/P2 = new newtype(actual_destination, _creator, _lifespan, P1, TRUE)
+ if(!istype(P1)||!istype(P2))
+ return
+ P1.link_portal(P2)
+ P1.hardlinked = TRUE
+ return list(P1, P2)
+
+/obj/effect/portal
+ name = "portal"
+ desc = "Looks unstable. Best to test it with the clown."
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "portal"
+ anchored = TRUE
+ var/mech_sized = FALSE
+ var/obj/effect/portal/linked
+ var/hardlinked = TRUE //Requires a linked portal at all times. Destroy if there's no linked portal, if there is destroy it when this one is deleted.
+ var/creator
+ var/turf/hard_target //For when a portal needs a hard target and isn't to be linked.
+ var/atmos_link = FALSE //Link source/destination atmos.
+ var/turf/open/atmos_source //Atmos link source
+ var/turf/open/atmos_destination //Atmos link destination
+
+/obj/effect/portal/anom
+ name = "wormhole"
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "anom"
+ mech_sized = TRUE
+
+/obj/effect/portal/Move(newloc)
+ for(var/T in newloc)
+ if(istype(T, /obj/effect/portal))
+ return FALSE
+ return ..()
+
+/obj/effect/portal/attackby(obj/item/W, mob/user, params)
+ if(user && Adjacent(user))
+ user.forceMove(get_turf(src))
+
+/obj/effect/portal/Crossed(atom/movable/AM, oldloc)
+ if(linked && (get_turf(oldloc) == get_turf(linked)))
+ return ..()
+ if(!teleport(AM))
+ return ..()
+
+/obj/effect/portal/attack_tk(mob/user)
+ return
+
+/obj/effect/portal/attack_hand(mob/user)
+ if(Adjacent(user))
+ user.forceMove(get_turf(src))
+
+/obj/effect/portal/Initialize(mapload, _creator, _lifespan = 0, obj/effect/portal/_linked, automatic_link = FALSE, turf/hard_target_override, atmos_link_override)
+ . = ..()
+ GLOB.portals += src
+ if(!istype(_linked) && automatic_link)
+ . = INITIALIZE_HINT_QDEL
+ CRASH("Somebody fucked up.")
+ if(_lifespan > 0)
+ QDEL_IN(src, _lifespan)
+ if(!isnull(atmos_link_override))
+ atmos_link = atmos_link_override
+ link_portal(_linked)
+ hardlinked = automatic_link
+ creator = _creator
+ if(isturf(hard_target_override))
+ hard_target = hard_target_override
+
+/obj/effect/portal/proc/link_portal(obj/effect/portal/newlink)
+ linked = newlink
+ if(atmos_link)
+ link_atmos()
+
+/obj/effect/portal/proc/link_atmos()
+ if(atmos_source || atmos_destination)
+ unlink_atmos()
+ if(!isopenturf(get_turf(src)))
+ return FALSE
+ if(linked)
+ if(isopenturf(get_turf(linked)))
+ atmos_source = get_turf(src)
+ atmos_destination = get_turf(linked)
+ else if(hard_target)
+ if(isopenturf(hard_target))
+ atmos_source = get_turf(src)
+ atmos_destination = hard_target
+ else
+ return FALSE
+ if(!istype(atmos_source) || !istype(atmos_destination))
+ return FALSE
+ LAZYINITLIST(atmos_source.atmos_adjacent_turfs)
+ LAZYINITLIST(atmos_destination.atmos_adjacent_turfs)
+ if(atmos_source.atmos_adjacent_turfs[atmos_destination] || atmos_destination.atmos_adjacent_turfs[atmos_source]) //Already linked!
+ return FALSE
+ atmos_source.atmos_adjacent_turfs[atmos_destination] = TRUE
+ atmos_destination.atmos_adjacent_turfs[atmos_source] = TRUE
+ atmos_source.air_update_turf(FALSE)
+ atmos_destination.air_update_turf(FALSE)
+
+/obj/effect/portal/proc/unlink_atmos()
+ if(istype(atmos_source))
+ if(istype(atmos_destination) && !atmos_source.Adjacent(atmos_destination) && !CANATMOSPASS(atmos_destination, atmos_source))
+ LAZYREMOVE(atmos_source.atmos_adjacent_turfs, atmos_destination)
+ atmos_source = null
+ if(istype(atmos_destination))
+ if(istype(atmos_source) && !atmos_destination.Adjacent(atmos_source) && !CANATMOSPASS(atmos_source, atmos_destination))
+ LAZYREMOVE(atmos_destination.atmos_adjacent_turfs, atmos_source)
+ atmos_destination = null
+
+/obj/effect/portal/Destroy() //Calls on_portal_destroy(destroyed portal, location of destroyed portal) on creator if creator has such call.
+ if(creator && hascall(creator, "on_portal_destroy"))
+ call(creator, "on_portal_destroy")(src, src.loc)
+ creator = null
+ GLOB.portals -= src
+ unlink_atmos()
+ if(hardlinked && !QDELETED(linked))
+ QDEL_NULL(linked)
+ else
+ linked = null
+ return ..()
+
+/obj/effect/portal/proc/teleport(atom/movable/M)
+ if(!istype(M) || istype(M, /obj/effect) || (ismecha(M) && !mech_sized) || (!isobj(M) && !ismob(M))) //Things that shouldn't teleport.
+ return
+ var/turf/real_target = get_link_target_turf()
+ if(!istype(real_target))
+ return FALSE
+ if(ismegafauna(M))
+ message_admins("[M] has used a portal at [ADMIN_COORDJMP(src)] made by [usr].")
+ if(do_teleport(M, real_target, 0))
+ if(istype(M, /obj/item/projectile))
+ var/obj/item/projectile/P = M
+ P.ignore_source_check = TRUE
+ return TRUE
+ return FALSE
+
+/obj/effect/portal/proc/get_link_target_turf()
+ var/turf/real_target
+ if(!istype(linked) || QDELETED(linked))
+ if(hardlinked)
+ qdel(src)
+ if(!istype(hard_target) || QDELETED(hard_target))
+ hard_target = null
+ return
+ else
+ real_target = hard_target
+ linked = null
+ else
+ real_target = get_turf(linked)
+ return real_target
diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
index 8b2d95f373..dfc5fb94d5 100644
--- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm
+++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
@@ -213,7 +213,7 @@
/obj/effect/temp_visual/fire
icon = 'icons/effects/fire.dmi'
icon_state = "3"
- light_range = 3
+ light_range = LIGHT_RANGE_FIRE
light_color = LIGHT_COLOR_FIRE
duration = 10
diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm
index 8b27659ada..513ffb8d2b 100644
--- a/code/game/objects/items/devices/radio/electropack.dm
+++ b/code/game/objects/items/devices/radio/electropack.dm
@@ -143,4 +143,82 @@ Code:
"}
user << browse(dat, "window=radio")
onclose(user, "radio")
- return
\ No newline at end of file
+ return
+
+/obj/item/device/electropack/shockcollar
+ name = "shock collar"
+ desc = "A reinforced metal collar. It seems to have some form of wiring near the front. Strange.."
+ icon = 'icons/obj/clothing/neck.dmi'
+ icon_state = "shockcollar"
+ item_state = "shockcollar"
+ body_parts_covered = NECK
+ slot_flags = SLOT_NECK
+ w_class = WEIGHT_CLASS_SMALL
+ strip_delay = 60
+ equip_delay_other = 60
+ materials = list(MAT_METAL=5000, MAT_GLASS=2000)
+ var/tagname = null
+
+/obj/item/device/electropack/shockcollar/attack_hand(mob/user)
+ if(loc == user)
+ if(slot_flags == SLOT_NECK)
+ to_chat(user, "The collar is fastened tight! You'll need help taking this off!")
+ return
+ ..()
+
+/obj/item/device/electropack/shockcollar/receive_signal(datum/signal/signal)
+ if(!signal || signal.encryption != code)
+ return
+
+ if(isliving(loc) && on)
+ if(shock_cooldown != 0)
+ return
+ shock_cooldown = 1
+ spawn(100)
+ shock_cooldown = 0
+ var/mob/living/L = loc
+ step(L, pick(GLOB.cardinals))
+
+ to_chat(L, "You feel a sharp shock from the collar!")
+ var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
+ s.set_up(3, 1, L)
+ s.start()
+
+ L.Knockdown(100)
+
+ if(master)
+ master.receive_signal()
+ return
+
+/obj/item/device/electropack/shockcollar/attack_self(mob/user) //Turns out can't fully source this from the parent item, spritepath gets confused if power toggled. Will come back to this when I know how to code better and readd powertoggle..
+ var/option = "Change Name"
+ option = input(user, "What do you want to do?", "[src]", option) as null|anything in list("Change Name", "Change Frequency")
+ switch(option)
+ if("Change Name")
+ var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text
+ if(t)
+ tagname = copytext(sanitize(t), 1, MAX_NAME_LEN)
+ name = "[initial(name)] - [tagname]"
+ if("Change Frequency")
+ if(!ishuman(user))
+ return
+ user.set_machine(src)
+ var/dat = {"
+ Frequency/Code for shock collar:
+ Frequency:
+ -
+ - [format_frequency(frequency)]
+ +
+ +
+
+ Code:
+ -
+ - [code]
+ +
+ +
+ "}
+
+ user << browse(dat, "window=radio")
+ onclose(user, "radio")
+ return
+
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 0f59d00ab8..83d29457f6 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -4,6 +4,7 @@
suffix = "\[3\]"
icon_state = "walkietalkie"
item_state = "walkietalkie"
+ desc = "A basic handheld radio that communicates with local telecommunication networks."
dog_fashion = /datum/dog_fashion/back
var/on = TRUE // 0 for off
var/last_transmission
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index e9a622365a..e55c728121 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -73,6 +73,7 @@ MASS SPECTROMETER
origin_tech = "magnets=1;biotech=1"
var/mode = 1
var/scanmode = 0
+ var/advanced = FALSE
/obj/item/device/healthanalyzer/attack_self(mob/user)
if(!scanmode)
@@ -97,7 +98,7 @@ MASS SPECTROMETER
user.visible_message("[user] has analyzed [M]'s vitals.")
if(scanmode == 0)
- healthscan(user, M, mode)
+ healthscan(user, M, mode, advanced)
else if(scanmode == 1)
chemscan(user, M)
@@ -105,7 +106,7 @@ MASS SPECTROMETER
// Used by the PDA medical scanner too
-/proc/healthscan(mob/living/user, mob/living/M, mode = 1)
+/proc/healthscan(mob/living/user, mob/living/M, mode = 1, advanced = FALSE)
if(user.incapacitated() || user.eye_blind)
return
//Damage specifics
@@ -115,8 +116,8 @@ MASS SPECTROMETER
var/brute_loss = M.getBruteLoss()
var/mob_status = (M.stat == DEAD ? "Deceased" : "[round(M.health/M.maxHealth,0.01)*100] % healthy")
- if(M.status_flags & FAKEDEATH)
- mob_status = "Deceased"
+ if(M.status_flags & FAKEDEATH && !advanced)
+ mob_status = "Deceased"
oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss
if(ishuman(M))
@@ -141,19 +142,77 @@ MASS SPECTROMETER
if(oxy_loss > 10)
to_chat(user, "\t[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected.")
if(tox_loss > 10)
- to_chat(user, "\t[tox_loss > 50 ? "Critical" : "Dangerous"] amount of toxins detected.")
+ to_chat(user, "\t[tox_loss > 50 ? "Severe" : "Minor"] amount of toxin damage detected.")
if(M.getStaminaLoss())
to_chat(user, "\tSubject appears to be suffering from fatigue.")
+ if(advanced)
+ to_chat(user, "\tFatigue Level: [M.getStaminaLoss()]%.")
if (M.getCloneLoss())
to_chat(user, "\tSubject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.")
- if (M.reagents && M.reagents.get_reagent_amount("epinephrine"))
- to_chat(user, "\tBloodstream analysis located [M.reagents.get_reagent_amount("epinephrine")] units of rejuvenation chemicals.")
+ if(advanced)
+ to_chat(user, "\tCellular Damage Level: [M.getCloneLoss()].")
if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/brain))
to_chat(user, "\tSubject brain function is non-existent.")
else if (M.getBrainLoss() >= 60)
to_chat(user, "\tSevere brain damage detected. Subject likely to have mental retardation.")
else if (M.getBrainLoss() >= 10)
to_chat(user, "\tBrain damage detected. Subject may have had a concussion.")
+ if(advanced)
+ to_chat(user, "\tBrain Activity Level: [100 - M.getBrainLoss()]%.")
+ if (M.radiation)
+ to_chat(user, "\tSubject is irradiated.")
+ if(advanced)
+ to_chat(user, "\tRadiation Level: [M.radiation]%.")
+
+ if(advanced && M.hallucinating())
+ to_chat(user, "\tSubject is hallucinating.")
+
+ //Eyes and ears
+ if(advanced)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ var/obj/item/organ/ears/ears = C.getorganslot("ears")
+ to_chat(user, "\t==EAR STATUS==")
+ if(istype(ears))
+ var/healthy = TRUE
+ if(C.disabilities & DEAF)
+ healthy = FALSE
+ to_chat(user, "\tSubject is genetically deaf.")
+ else
+ if(ears.ear_damage)
+ to_chat(user, "\tSubject has [ears.ear_damage > UNHEALING_EAR_DAMAGE? "permanent ": "temporary "]hearing damage.")
+ healthy = FALSE
+ if(ears.deaf)
+ to_chat(user, "\tSubject is [ears.ear_damage > UNHEALING_EAR_DAMAGE ? "permanently ": "temporarily "] deaf.")
+ healthy = FALSE
+ if(healthy)
+ to_chat(user, "\tHealthy.")
+ else
+ to_chat(user, "\tSubject does not have ears.")
+ var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight")
+ to_chat(user, "\t==EYE STATUS==")
+ if(istype(eyes))
+ var/healthy = TRUE
+ if(C.disabilities & BLIND)
+ to_chat(user, "\tSubject is blind.")
+ healthy = FALSE
+ if(C.disabilities & NEARSIGHT)
+ to_chat(user, "\tSubject is nearsighted.")
+ healthy = FALSE
+ if(eyes.eye_damage > 30)
+ to_chat(user, "\tSubject has severe eye damage.")
+ healthy = FALSE
+ else if(eyes.eye_damage > 20)
+ to_chat(user, "\tSubject has significant eye damage.")
+ healthy = FALSE
+ else if(eyes.eye_damage)
+ to_chat(user, "\tSubject has minor eye damage.")
+ healthy = FALSE
+ if(healthy)
+ to_chat(user, "\tHealthy.")
+ else
+ to_chat(user, "\tSubject does not have eyes.")
+
if(ishuman(M))
var/mob/living/carbon/human/H = M
@@ -177,7 +236,7 @@ MASS SPECTROMETER
to_chat(user, "Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)")
// Time of death
- if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
+ if(M.tod && (M.stat == DEAD || ((M.status_flags & FAKEDEATH) && !advanced)))
to_chat(user, "Time of Death: [M.tod]")
var/tdelta = round(world.time - M.timeofdeath)
if(tdelta < (DEFIB_TIME_LIMIT * 10))
@@ -251,6 +310,12 @@ MASS SPECTROMETER
if(0)
to_chat(usr, "The scanner no longer shows limb damage.")
+/obj/item/device/healthanalyzer/advanced
+ name = "advanced health analyzer"
+ icon_state = "health_adv"
+ desc = "A hand-held body scanner able to distinguish vital signs of the subject with high accuracy."
+ origin_tech = "magnets=3;biotech=3"
+ advanced = TRUE
/obj/item/device/analyzer
desc = "A hand-held environmental scanner which reports current gas levels."
diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm
index 1badef90cf..634fbee9d2 100644
--- a/code/game/objects/items/holy_weapons.dm
+++ b/code/game/objects/items/holy_weapons.dm
@@ -335,8 +335,8 @@
/obj/item/nullrod/carp
name = "carp-sie plushie"
desc = "An adorable stuffed toy that resembles the god of all carp. The teeth look pretty sharp. Activate it to receive the blessing of Carp-Sie."
- icon = 'icons/obj/toy.dmi'
- icon_state = "carpplushie"
+ icon = 'icons/obj/plushes.dmi'
+ icon_state = "carpplush"
item_state = "carp_plushie"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
diff --git a/code/game/objects/items/implants/implant_loyality.dm b/code/game/objects/items/implants/implant_loyality.dm
index a1e9a0e4d5..ffaebf5a63 100644
--- a/code/game/objects/items/implants/implant_loyality.dm
+++ b/code/game/objects/items/implants/implant_loyality.dm
@@ -19,12 +19,12 @@
/obj/item/implant/mindshield/implant(mob/living/target, mob/user, silent = 0)
if(..())
- if((target.mind in (SSticker.mode.head_revolutionaries)))
+ if((target.mind in (SSticker.mode.head_revolutionaries)) || target.mind.unconvertable)
if(!silent)
target.visible_message("[target] seems to resist the implant!", "You feel something interfering with your mental conditioning, but you resist it!")
removed(target, 1)
qdel(src)
- return 0
+ return FALSE
if(target.mind in SSticker.mode.revolutionaries)
SSticker.mode.remove_revolutionary(target.mind, FALSE, user)
if(!silent)
@@ -32,8 +32,8 @@
to_chat(target, "You feel something interfering with your mental conditioning, but you resist it!")
else
to_chat(target, "You feel a sense of peace and security. You are now protected from brainwashing.")
- return 1
- return 0
+ return TRUE
+ return FALSE
/obj/item/implant/mindshield/removed(mob/target, silent = 0, special = 0)
if(..())
diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm
index 28d4d13967..c8249024f8 100644
--- a/code/game/objects/items/shooting_range.dm
+++ b/code/game/objects/items/shooting_range.dm
@@ -41,7 +41,7 @@
/obj/item/target/syndicate
icon_state = "target_s"
- desc = "A shooting target that looks like a syndicate scum."
+ desc = "A shooting target that looks like syndicate scum."
hp = 2600
/obj/item/target/alien
diff --git a/code/game/objects/items/signs.dm b/code/game/objects/items/signs.dm
index c492b752f0..350daa0fc3 100644
--- a/code/game/objects/items/signs.dm
+++ b/code/game/objects/items/signs.dm
@@ -1,7 +1,7 @@
/obj/item/picket_sign
icon_state = "picket"
name = "blank picket sign"
- desc = "It's blank"
+ desc = "It's blank."
force = 5
w_class = WEIGHT_CLASS_BULKY
attack_verb = list("bashed","smacked")
diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm
index b5417e8f8e..435bc64c41 100644
--- a/code/game/objects/items/storage/fancy.dm
+++ b/code/game/objects/items/storage/fancy.dm
@@ -17,6 +17,7 @@
icon = 'icons/obj/food/containers.dmi'
icon_state = "donutbox6"
name = "donut box"
+ desc = "Mmm. Donuts."
resistance_flags = FLAMMABLE
var/icon_type = "donut"
var/spawn_type = null
diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm
index 385a069c00..50898e72e1 100644
--- a/code/game/objects/items/storage/lockbox.dm
+++ b/code/game/objects/items/storage/lockbox.dm
@@ -177,6 +177,14 @@
for(var/i in 1 to 3)
new /obj/item/clothing/accessory/medal/silver/security(src)
+/obj/item/storage/lockbox/medal/cargo
+ name = "cargo award box"
+ desc = "A locked box used to store awards to be given to members of the cargo department."
+ req_access = list(ACCESS_QM)
+
+/obj/item/storage/lockbox/medal/cargo/PopulateContents()
+ new /obj/item/clothing/accessory/medal/ribbon/cargo(src)
+
/obj/item/storage/lockbox/medal/sci
name = "science medal box"
desc = "A locked box used to store medals to be given to members of the science department."
diff --git a/code/game/objects/items/storage/secure.dm b/code/game/objects/items/storage/secure.dm
index ef65f2dac3..4d56b6a8e8 100644
--- a/code/game/objects/items/storage/secure.dm
+++ b/code/game/objects/items/storage/secure.dm
@@ -25,6 +25,7 @@
w_class = WEIGHT_CLASS_NORMAL
max_w_class = WEIGHT_CLASS_SMALL
max_combined_w_class = 14
+ desc = "This shouldn't exist. If it does, create an issue report."
/obj/item/storage/secure/examine(mob/user)
..()
@@ -177,6 +178,7 @@
icon_opened = "safe0"
icon_locking = "safeb"
icon_sparking = "safespark"
+ desc = "Excellent for securing things away from grubby hands."
force = 8
w_class = WEIGHT_CLASS_GIGANTIC
max_w_class = 8
diff --git a/code/game/objects/items/storage/storage.dm b/code/game/objects/items/storage/storage.dm
index 5a2b52184a..9a3769206c 100644
--- a/code/game/objects/items/storage/storage.dm
+++ b/code/game/objects/items/storage/storage.dm
@@ -34,7 +34,7 @@
if(!over_object)
return
- if (istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
+ if (ismecha(M.loc)) // stops inventory actions in a mech
return
// this must come before the screen objects only block, dunno why it wasn't before
diff --git a/code/game/objects/items/vending_items.dm b/code/game/objects/items/vending_items.dm
index b062c39ee5..e84295f8ed 100644
--- a/code/game/objects/items/vending_items.dm
+++ b/code/game/objects/items/vending_items.dm
@@ -5,6 +5,7 @@
icon = 'icons/obj/vending_restock.dmi'
icon_state = "refill_snack"
item_state = "restock_unit"
+ desc = "A vending machine restock cart."
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
flags_1 = CONDUCT_1
diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm
index 709d86d4d7..d01cd5a191 100644
--- a/code/game/objects/structures/ai_core.dm
+++ b/code/game/objects/structures/ai_core.dm
@@ -4,6 +4,7 @@
name = "\improper AI core"
icon = 'icons/mob/ai.dmi'
icon_state = "0"
+ desc = "The framework for an artificial intelligence core."
max_integrity = 500
var/state = 0
var/datum/ai_laws/laws = new()
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
index 77723e3e41..4e83a709b9 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
@@ -1,19 +1,20 @@
-/obj/structure/closet/secure_closet/quartermaster
- name = "\proper quartermaster's locker"
+/obj/structure/closet/secure_closet/quartermaster
+ name = "\proper quartermaster's locker"
req_access = list(ACCESS_QM)
- icon_state = "qm"
-
-/obj/structure/closet/secure_closet/quartermaster/PopulateContents()
- ..()
- new /obj/item/clothing/neck/cloak/qm(src)
- new /obj/item/clothing/under/rank/cargo(src)
- new /obj/item/clothing/shoes/sneakers/brown(src)
- new /obj/item/device/radio/headset/headset_cargo(src)
- new /obj/item/clothing/suit/fire/firefighter(src)
- new /obj/item/clothing/gloves/fingerless(src)
- new /obj/item/device/megaphone/cargo(src)
- new /obj/item/tank/internals/emergency_oxygen(src)
- new /obj/item/clothing/mask/gas(src)
- new /obj/item/clothing/head/soft(src)
- new /obj/item/device/export_scanner(src)
- new /obj/item/door_remote/quartermaster(src)
+ icon_state = "qm"
+
+/obj/structure/closet/secure_closet/quartermaster/PopulateContents()
+ ..()
+ new /obj/item/clothing/neck/cloak/qm(src)
+ new /obj/item/storage/lockbox/medal/cargo/(src)
+ new /obj/item/clothing/under/rank/cargo(src)
+ new /obj/item/clothing/shoes/sneakers/brown(src)
+ new /obj/item/device/radio/headset/headset_cargo(src)
+ new /obj/item/clothing/suit/fire/firefighter(src)
+ new /obj/item/clothing/gloves/fingerless(src)
+ new /obj/item/device/megaphone/cargo(src)
+ new /obj/item/tank/internals/emergency_oxygen(src)
+ new /obj/item/clothing/mask/gas(src)
+ new /obj/item/clothing/head/soft(src)
+ new /obj/item/device/export_scanner(src)
+ new /obj/item/door_remote/quartermaster(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
index a2a055f464..ee9ecfc908 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
@@ -1,93 +1,94 @@
-/obj/structure/closet/secure_closet/medical1
- name = "medicine closet"
- desc = "Filled to the brim with medical junk."
- icon_state = "med"
+/obj/structure/closet/secure_closet/medical1
+ name = "medicine closet"
+ desc = "Filled to the brim with medical junk."
+ icon_state = "med"
req_access = list(ACCESS_MEDICAL)
-
-/obj/structure/closet/secure_closet/medical1/PopulateContents()
- ..()
- new /obj/item/reagent_containers/glass/beaker(src)
- new /obj/item/reagent_containers/glass/beaker(src)
- new /obj/item/reagent_containers/dropper(src)
- new /obj/item/reagent_containers/dropper(src)
- new /obj/item/storage/belt/medical(src)
- new /obj/item/storage/box/syringes(src)
- new /obj/item/reagent_containers/glass/bottle/toxin(src)
- new /obj/item/reagent_containers/glass/bottle/morphine(src)
- new /obj/item/reagent_containers/glass/bottle/morphine(src)
- for(var/i in 1 to 3)
- new /obj/item/reagent_containers/glass/bottle/epinephrine(src)
- for(var/i in 1 to 3)
- new /obj/item/reagent_containers/glass/bottle/charcoal(src)
- new /obj/item/storage/box/rxglasses(src)
-
-/obj/structure/closet/secure_closet/medical2
- name = "anesthetic closet"
- desc = "Used to knock people out."
+
+/obj/structure/closet/secure_closet/medical1/PopulateContents()
+ ..()
+ new /obj/item/reagent_containers/glass/beaker(src)
+ new /obj/item/reagent_containers/glass/beaker(src)
+ new /obj/item/reagent_containers/dropper(src)
+ new /obj/item/reagent_containers/dropper(src)
+ new /obj/item/storage/belt/medical(src)
+ new /obj/item/storage/box/syringes(src)
+ new /obj/item/reagent_containers/glass/bottle/toxin(src)
+ new /obj/item/reagent_containers/glass/bottle/morphine(src)
+ new /obj/item/reagent_containers/glass/bottle/morphine(src)
+ for(var/i in 1 to 3)
+ new /obj/item/reagent_containers/glass/bottle/epinephrine(src)
+ for(var/i in 1 to 3)
+ new /obj/item/reagent_containers/glass/bottle/charcoal(src)
+ new /obj/item/storage/box/rxglasses(src)
+
+/obj/structure/closet/secure_closet/medical2
+ name = "anesthetic closet"
+ desc = "Used to knock people out."
req_access = list(ACCESS_SURGERY)
-
-/obj/structure/closet/secure_closet/medical2/PopulateContents()
- ..()
- for(var/i in 1 to 3)
- new /obj/item/tank/internals/anesthetic(src)
- for(var/i in 1 to 3)
- new /obj/item/clothing/mask/breath/medical(src)
-
-/obj/structure/closet/secure_closet/medical3
- name = "medical doctor's locker"
+
+/obj/structure/closet/secure_closet/medical2/PopulateContents()
+ ..()
+ for(var/i in 1 to 3)
+ new /obj/item/tank/internals/anesthetic(src)
+ for(var/i in 1 to 3)
+ new /obj/item/clothing/mask/breath/medical(src)
+
+/obj/structure/closet/secure_closet/medical3
+ name = "medical doctor's locker"
req_access = list(ACCESS_SURGERY)
- icon_state = "med_secure"
-
-/obj/structure/closet/secure_closet/medical3/PopulateContents()
- ..()
- new /obj/item/device/radio/headset/headset_med(src)
- new /obj/item/defibrillator/loaded(src)
- new /obj/item/clothing/gloves/color/latex/nitrile(src)
- new /obj/item/storage/belt/medical(src)
- new /obj/item/clothing/glasses/hud/health(src)
- return
-
-/obj/structure/closet/secure_closet/CMO
- name = "\proper chief medical officer's locker"
+ icon_state = "med_secure"
+
+/obj/structure/closet/secure_closet/medical3/PopulateContents()
+ ..()
+ new /obj/item/device/radio/headset/headset_med(src)
+ new /obj/item/defibrillator/loaded(src)
+ new /obj/item/clothing/gloves/color/latex/nitrile(src)
+ new /obj/item/storage/belt/medical(src)
+ new /obj/item/clothing/glasses/hud/health(src)
+ return
+
+/obj/structure/closet/secure_closet/CMO
+ name = "\proper chief medical officer's locker"
req_access = list(ACCESS_CMO)
- icon_state = "cmo"
-
-/obj/structure/closet/secure_closet/CMO/PopulateContents()
- ..()
- new /obj/item/clothing/neck/cloak/cmo(src)
- new /obj/item/storage/backpack/duffelbag/med(src)
- new /obj/item/clothing/suit/bio_suit/cmo(src)
- new /obj/item/clothing/head/bio_hood/cmo(src)
- new /obj/item/clothing/suit/toggle/labcoat/cmo(src)
- new /obj/item/clothing/under/rank/chief_medical_officer(src)
- new /obj/item/clothing/shoes/sneakers/brown (src)
- new /obj/item/cartridge/cmo(src)
- new /obj/item/device/radio/headset/heads/cmo(src)
- new /obj/item/device/megaphone/command(src)
- new /obj/item/defibrillator/compact/loaded(src)
- new /obj/item/clothing/gloves/color/latex/nitrile(src)
- new /obj/item/storage/belt/medical(src)
- new /obj/item/device/assembly/flash/handheld(src)
- new /obj/item/reagent_containers/hypospray/CMO(src)
- new /obj/item/device/autosurgeon/cmo(src)
- new /obj/item/door_remote/chief_medical_officer(src)
-
-/obj/structure/closet/secure_closet/animal
- name = "animal control"
+ icon_state = "cmo"
+
+/obj/structure/closet/secure_closet/CMO/PopulateContents()
+ ..()
+ new /obj/item/clothing/neck/cloak/cmo(src)
+ new /obj/item/storage/backpack/duffelbag/med(src)
+ new /obj/item/clothing/suit/bio_suit/cmo(src)
+ new /obj/item/clothing/head/bio_hood/cmo(src)
+ new /obj/item/clothing/suit/toggle/labcoat/cmo(src)
+ new /obj/item/clothing/under/rank/chief_medical_officer(src)
+ new /obj/item/clothing/shoes/sneakers/brown (src)
+ new /obj/item/cartridge/cmo(src)
+ new /obj/item/device/radio/headset/heads/cmo(src)
+ new /obj/item/device/megaphone/command(src)
+ new /obj/item/defibrillator/compact/loaded(src)
+ new /obj/item/clothing/gloves/color/latex/nitrile(src)
+ new /obj/item/storage/belt/medical(src)
+ new /obj/item/device/healthanalyzer/advanced(src)
+ new /obj/item/device/assembly/flash/handheld(src)
+ new /obj/item/reagent_containers/hypospray/CMO(src)
+ new /obj/item/device/autosurgeon/cmo(src)
+ new /obj/item/door_remote/chief_medical_officer(src)
+
+/obj/structure/closet/secure_closet/animal
+ name = "animal control"
req_access = list(ACCESS_SURGERY)
-
-/obj/structure/closet/secure_closet/animal/PopulateContents()
- ..()
- new /obj/item/device/assembly/signaler(src)
- for(var/i in 1 to 3)
- new /obj/item/device/electropack(src)
-
-/obj/structure/closet/secure_closet/chemical
- name = "chemical closet"
- desc = "Store dangerous chemicals in here."
- icon_door = "chemical"
-
-/obj/structure/closet/secure_closet/chemical/PopulateContents()
- ..()
- new /obj/item/storage/box/pillbottles(src)
- new /obj/item/storage/box/pillbottles(src)
+
+/obj/structure/closet/secure_closet/animal/PopulateContents()
+ ..()
+ new /obj/item/device/assembly/signaler(src)
+ for(var/i in 1 to 3)
+ new /obj/item/device/electropack(src)
+
+/obj/structure/closet/secure_closet/chemical
+ name = "chemical closet"
+ desc = "Store dangerous chemicals in here."
+ icon_door = "chemical"
+
+/obj/structure/closet/secure_closet/chemical/PopulateContents()
+ ..()
+ new /obj/item/storage/box/pillbottles(src)
+ new /obj/item/storage/box/pillbottles(src)
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index 9889d07b90..a5173a5f80 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -6,6 +6,7 @@
anchored = FALSE
density = TRUE
max_integrity = 200
+ desc = "The mechanical framework for an airlock."
var/state = 0
var/mineral = null
var/typetext = ""
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index 6aa338f047..c1b6c56bf5 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -6,6 +6,7 @@
//trees
/obj/structure/flora/tree
name = "tree"
+ desc = "A large tree."
density = TRUE
pixel_x = -16
layer = FLY_LAYER
@@ -40,6 +41,7 @@
/obj/structure/flora/tree/pine
name = "pine tree"
+ desc = "A coniferous pine tree."
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "pine_1"
@@ -49,6 +51,7 @@
/obj/structure/flora/tree/pine/xmas
name = "xmas tree"
+ desc = "A wondrous decorated Christmas tree."
icon_state = "pine_c"
/obj/structure/flora/tree/pine/xmas/Initialize()
@@ -57,10 +60,12 @@
/obj/structure/flora/tree/dead
icon = 'icons/obj/flora/deadtrees.dmi'
+ desc = "A dead tree. How it died, you know not."
icon_state = "tree_1"
/obj/structure/flora/tree/palm
icon = 'icons/misc/beach2.dmi'
+ desc = "A tree straight from the tropics."
icon_state = "palm1"
/obj/structure/flora/tree/palm/Initialize()
@@ -98,6 +103,7 @@
//grass
/obj/structure/flora/grass
name = "grass"
+ desc = "A patch of overgrown grass."
icon = 'icons/obj/flora/snowflora.dmi'
gender = PLURAL //"this is grass" not "this is a grass"
@@ -127,6 +133,7 @@
//bushes
/obj/structure/flora/bush
name = "bush"
+ desc = "Some type of shrub."
icon = 'icons/obj/flora/snowflora.dmi'
icon_state = "snowbush1"
anchored = TRUE
@@ -139,6 +146,7 @@
/obj/structure/flora/ausbushes
name = "bush"
+ desc = "Some kind of plant."
icon = 'icons/obj/flora/ausflora.dmi'
icon_state = "firstbush_1"
@@ -256,6 +264,7 @@
name = "potted plant"
icon = 'icons/obj/flora/plants.dmi'
icon_state = "plant-01"
+ desc = "A little bit of nature contained in a pot."
layer = ABOVE_MOB_LAYER
w_class = WEIGHT_CLASS_HUGE
force = 10
@@ -365,6 +374,7 @@
/obj/structure/flora/junglebush
name = "bush"
+ desc = "A wild plant that is found in jungles."
icon = 'icons/obj/flora/jungleflora.dmi'
icon_state = "busha"
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index 02f6d784df..3d7e9be21a 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -1,6 +1,7 @@
/obj/structure/girder
name = "girder"
icon_state = "girder"
+ desc = "A large structural assembly made out of metal; It requires a layer of metal before it can be considered a wall."
anchored = TRUE
density = TRUE
layer = BELOW_OBJ_LAYER
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 2e1f0af991..c767dd1c68 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -1,232 +1,232 @@
-//NOT using the existing /obj/machinery/door type, since that has some complications on its own, mainly based on its
-//machineryness
-
-/obj/structure/mineral_door
- name = "metal door"
+//NOT using the existing /obj/machinery/door type, since that has some complications on its own, mainly based on its
+//machineryness
+
+/obj/structure/mineral_door
+ name = "metal door"
density = TRUE
anchored = TRUE
- opacity = TRUE
-
- icon = 'icons/obj/doors/mineral_doors.dmi'
- icon_state = "metal"
-
- var/initial_state
- var/state = 0 //closed, 1 == open
- var/isSwitchingStates = 0
- var/close_delay = -1 //-1 if does not auto close.
- max_integrity = 200
- armor = list(melee = 10, bullet = 0, laser = 0, energy = 100, bomb = 10, bio = 100, rad = 100, fire = 50, acid = 50)
- var/sheetType = /obj/item/stack/sheet/metal
- var/sheetAmount = 7
- var/openSound = 'sound/effects/stonedoor_openclose.ogg'
- var/closeSound = 'sound/effects/stonedoor_openclose.ogg'
- CanAtmosPass = ATMOS_PASS_DENSITY
-
-/obj/structure/mineral_door/New(location)
- ..()
- initial_state = icon_state
- air_update_turf(1)
-
-/obj/structure/mineral_door/Destroy()
+ opacity = TRUE
+
+ icon = 'icons/obj/doors/mineral_doors.dmi'
+ icon_state = "metal"
+
+ var/initial_state
+ var/state = 0 //closed, 1 == open
+ var/isSwitchingStates = 0
+ var/close_delay = -1 //-1 if does not auto close.
+ max_integrity = 200
+ armor = list(melee = 10, bullet = 0, laser = 0, energy = 100, bomb = 10, bio = 100, rad = 100, fire = 50, acid = 50)
+ var/sheetType = /obj/item/stack/sheet/metal
+ var/sheetAmount = 7
+ var/openSound = 'sound/effects/stonedoor_openclose.ogg'
+ var/closeSound = 'sound/effects/stonedoor_openclose.ogg'
+ CanAtmosPass = ATMOS_PASS_DENSITY
+
+/obj/structure/mineral_door/New(location)
+ ..()
+ initial_state = icon_state
+ air_update_turf(1)
+
+/obj/structure/mineral_door/Destroy()
density = FALSE
- air_update_turf(1)
- return ..()
-
-/obj/structure/mineral_door/Move()
- var/turf/T = loc
- ..()
- move_update_air(T)
-
+ air_update_turf(1)
+ return ..()
+
+/obj/structure/mineral_door/Move()
+ var/turf/T = loc
+ ..()
+ move_update_air(T)
+
/obj/structure/mineral_door/CollidedWith(atom/movable/AM)
- ..()
- if(!state)
+ ..()
+ if(!state)
return TryToSwitchState(AM)
-
-/obj/structure/mineral_door/attack_ai(mob/user) //those aren't machinery, they're just big fucking slabs of a mineral
- if(isAI(user)) //so the AI can't open it
- return
- else if(iscyborg(user)) //but cyborgs can
- if(get_dist(user,src) <= 1) //not remotely though
- return TryToSwitchState(user)
-
-/obj/structure/mineral_door/attack_paw(mob/user)
- return TryToSwitchState(user)
-
-/obj/structure/mineral_door/attack_hand(mob/user)
- return TryToSwitchState(user)
-
+
+/obj/structure/mineral_door/attack_ai(mob/user) //those aren't machinery, they're just big fucking slabs of a mineral
+ if(isAI(user)) //so the AI can't open it
+ return
+ else if(iscyborg(user)) //but cyborgs can
+ if(get_dist(user,src) <= 1) //not remotely though
+ return TryToSwitchState(user)
+
+/obj/structure/mineral_door/attack_paw(mob/user)
+ return TryToSwitchState(user)
+
+/obj/structure/mineral_door/attack_hand(mob/user)
+ return TryToSwitchState(user)
+
/obj/structure/mineral_door/CanPass(atom/movable/mover, turf/target)
- if(istype(mover, /obj/effect/beam))
- return !opacity
- return !density
-
-/obj/structure/mineral_door/proc/TryToSwitchState(atom/user)
- if(isSwitchingStates)
- return
- if(isliving(user))
- var/mob/living/M = user
- if(world.time - M.last_bumped <= 60)
- return //NOTE do we really need that?
- if(M.client)
- if(iscarbon(M))
- var/mob/living/carbon/C = M
- if(!C.handcuffed)
- SwitchState()
- else
- SwitchState()
- else if(istype(user, /obj/mecha))
- SwitchState()
-
-/obj/structure/mineral_door/proc/SwitchState()
- if(state)
- Close()
- else
- Open()
-
-/obj/structure/mineral_door/proc/Open()
- isSwitchingStates = 1
- playsound(src, openSound, 100, 1)
- set_opacity(FALSE)
- flick("[initial_state]opening",src)
- sleep(10)
+ if(istype(mover, /obj/effect/beam))
+ return !opacity
+ return !density
+
+/obj/structure/mineral_door/proc/TryToSwitchState(atom/user)
+ if(isSwitchingStates)
+ return
+ if(isliving(user))
+ var/mob/living/M = user
+ if(world.time - M.last_bumped <= 60)
+ return //NOTE do we really need that?
+ if(M.client)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ if(!C.handcuffed)
+ SwitchState()
+ else
+ SwitchState()
+ else if(ismecha(user))
+ SwitchState()
+
+/obj/structure/mineral_door/proc/SwitchState()
+ if(state)
+ Close()
+ else
+ Open()
+
+/obj/structure/mineral_door/proc/Open()
+ isSwitchingStates = 1
+ playsound(src, openSound, 100, 1)
+ set_opacity(FALSE)
+ flick("[initial_state]opening",src)
+ sleep(10)
density = FALSE
- state = 1
- air_update_turf(1)
- update_icon()
- isSwitchingStates = 0
-
- if(close_delay != -1)
- addtimer(CALLBACK(src, .proc/Close), close_delay)
-
-/obj/structure/mineral_door/proc/Close()
- if(isSwitchingStates || state != 1)
- return
- var/turf/T = get_turf(src)
- for(var/mob/living/L in T)
- return
- isSwitchingStates = 1
- playsound(loc, closeSound, 100, 1)
- flick("[initial_state]closing",src)
- sleep(10)
+ state = 1
+ air_update_turf(1)
+ update_icon()
+ isSwitchingStates = 0
+
+ if(close_delay != -1)
+ addtimer(CALLBACK(src, .proc/Close), close_delay)
+
+/obj/structure/mineral_door/proc/Close()
+ if(isSwitchingStates || state != 1)
+ return
+ var/turf/T = get_turf(src)
+ for(var/mob/living/L in T)
+ return
+ isSwitchingStates = 1
+ playsound(loc, closeSound, 100, 1)
+ flick("[initial_state]closing",src)
+ sleep(10)
density = TRUE
- set_opacity(TRUE)
- state = 0
- air_update_turf(1)
- update_icon()
- isSwitchingStates = 0
-
-/obj/structure/mineral_door/update_icon()
- if(state)
- icon_state = "[initial_state]open"
- else
- icon_state = initial_state
-
-/obj/structure/mineral_door/attackby(obj/item/W, mob/user, params)
+ set_opacity(TRUE)
+ state = 0
+ air_update_turf(1)
+ update_icon()
+ isSwitchingStates = 0
+
+/obj/structure/mineral_door/update_icon()
+ if(state)
+ icon_state = "[initial_state]open"
+ else
+ icon_state = initial_state
+
+/obj/structure/mineral_door/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pickaxe))
- var/obj/item/pickaxe/digTool = W
- to_chat(user, "You start digging the [name]...")
- if(do_after(user,digTool.digspeed*(1+round(max_integrity*0.01)), target = src) && src)
- to_chat(user, "You finish digging.")
- deconstruct(TRUE)
- else if(user.a_intent != INTENT_HARM)
- attack_hand(user)
- else
- return ..()
-
-/obj/structure/mineral_door/deconstruct(disassembled = TRUE)
- var/turf/T = get_turf(src)
- if(disassembled)
- new sheetType(T, sheetAmount)
- else
- new sheetType(T, max(sheetAmount - 2, 1))
- qdel(src)
-
-/obj/structure/mineral_door/iron
- name = "iron door"
- max_integrity = 300
-
-/obj/structure/mineral_door/silver
- name = "silver door"
- icon_state = "silver"
- sheetType = /obj/item/stack/sheet/mineral/silver
- max_integrity = 300
-
-/obj/structure/mineral_door/gold
- name = "gold door"
- icon_state = "gold"
- sheetType = /obj/item/stack/sheet/mineral/gold
-
-/obj/structure/mineral_door/uranium
- name = "uranium door"
- icon_state = "uranium"
- sheetType = /obj/item/stack/sheet/mineral/uranium
- max_integrity = 300
- light_range = 2
-
-/obj/structure/mineral_door/sandstone
- name = "sandstone door"
- icon_state = "sandstone"
- sheetType = /obj/item/stack/sheet/mineral/sandstone
- max_integrity = 100
-
-/obj/structure/mineral_door/transparent
- opacity = FALSE
-
-/obj/structure/mineral_door/transparent/Close()
- ..()
- set_opacity(FALSE)
-
-/obj/structure/mineral_door/transparent/plasma
- name = "plasma door"
- icon_state = "plasma"
- sheetType = /obj/item/stack/sheet/mineral/plasma
-
-/obj/structure/mineral_door/transparent/plasma/attackby(obj/item/W, mob/user, params)
- if(W.is_hot())
- var/turf/T = get_turf(src)
- message_admins("Plasma mineral door ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1)
- log_game("Plasma mineral door ignited by [key_name(user)] in [COORD(T)]")
- TemperatureAct()
- else
- return ..()
-
-/obj/structure/mineral_door/transparent/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
- if(exposed_temperature > 300)
- TemperatureAct()
-
-/obj/structure/mineral_door/transparent/plasma/proc/TemperatureAct()
- atmos_spawn_air("plasma=500;TEMP=1000")
- deconstruct(FALSE)
-
-/obj/structure/mineral_door/transparent/diamond
- name = "diamond door"
- icon_state = "diamond"
- sheetType = /obj/item/stack/sheet/mineral/diamond
- max_integrity = 1000
-
-/obj/structure/mineral_door/wood
- name = "wood door"
- icon_state = "wood"
- openSound = 'sound/effects/doorcreaky.ogg'
- closeSound = 'sound/effects/doorcreaky.ogg'
- sheetType = /obj/item/stack/sheet/mineral/wood
- resistance_flags = FLAMMABLE
- max_integrity = 200
-
-/obj/structure/mineral_door/paperframe
- name = "paper frame door"
- icon_state = "paperframe"
- openSound = 'sound/effects/doorcreaky.ogg'
- closeSound = 'sound/effects/doorcreaky.ogg'
- sheetType = /obj/item/stack/sheet/paperframes
- sheetAmount = 3
- resistance_flags = FLAMMABLE
- max_integrity = 20
-
-/obj/structure/mineral_door/paperframe/Initialize()
- . = ..()
- queue_smooth_neighbors(src)
-
-/obj/structure/mineral_door/paperframe/Destroy()
- queue_smooth_neighbors(src)
- return ..()
+ var/obj/item/pickaxe/digTool = W
+ to_chat(user, "You start digging the [name]...")
+ if(do_after(user,digTool.digspeed*(1+round(max_integrity*0.01)), target = src) && src)
+ to_chat(user, "You finish digging.")
+ deconstruct(TRUE)
+ else if(user.a_intent != INTENT_HARM)
+ attack_hand(user)
+ else
+ return ..()
+
+/obj/structure/mineral_door/deconstruct(disassembled = TRUE)
+ var/turf/T = get_turf(src)
+ if(disassembled)
+ new sheetType(T, sheetAmount)
+ else
+ new sheetType(T, max(sheetAmount - 2, 1))
+ qdel(src)
+
+/obj/structure/mineral_door/iron
+ name = "iron door"
+ max_integrity = 300
+
+/obj/structure/mineral_door/silver
+ name = "silver door"
+ icon_state = "silver"
+ sheetType = /obj/item/stack/sheet/mineral/silver
+ max_integrity = 300
+
+/obj/structure/mineral_door/gold
+ name = "gold door"
+ icon_state = "gold"
+ sheetType = /obj/item/stack/sheet/mineral/gold
+
+/obj/structure/mineral_door/uranium
+ name = "uranium door"
+ icon_state = "uranium"
+ sheetType = /obj/item/stack/sheet/mineral/uranium
+ max_integrity = 300
+ light_range = 2
+
+/obj/structure/mineral_door/sandstone
+ name = "sandstone door"
+ icon_state = "sandstone"
+ sheetType = /obj/item/stack/sheet/mineral/sandstone
+ max_integrity = 100
+
+/obj/structure/mineral_door/transparent
+ opacity = FALSE
+
+/obj/structure/mineral_door/transparent/Close()
+ ..()
+ set_opacity(FALSE)
+
+/obj/structure/mineral_door/transparent/plasma
+ name = "plasma door"
+ icon_state = "plasma"
+ sheetType = /obj/item/stack/sheet/mineral/plasma
+
+/obj/structure/mineral_door/transparent/plasma/attackby(obj/item/W, mob/user, params)
+ if(W.is_hot())
+ var/turf/T = get_turf(src)
+ message_admins("Plasma mineral door ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1)
+ log_game("Plasma mineral door ignited by [key_name(user)] in [COORD(T)]")
+ TemperatureAct()
+ else
+ return ..()
+
+/obj/structure/mineral_door/transparent/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ if(exposed_temperature > 300)
+ TemperatureAct()
+
+/obj/structure/mineral_door/transparent/plasma/proc/TemperatureAct()
+ atmos_spawn_air("plasma=500;TEMP=1000")
+ deconstruct(FALSE)
+
+/obj/structure/mineral_door/transparent/diamond
+ name = "diamond door"
+ icon_state = "diamond"
+ sheetType = /obj/item/stack/sheet/mineral/diamond
+ max_integrity = 1000
+
+/obj/structure/mineral_door/wood
+ name = "wood door"
+ icon_state = "wood"
+ openSound = 'sound/effects/doorcreaky.ogg'
+ closeSound = 'sound/effects/doorcreaky.ogg'
+ sheetType = /obj/item/stack/sheet/mineral/wood
+ resistance_flags = FLAMMABLE
+ max_integrity = 200
+
+/obj/structure/mineral_door/paperframe
+ name = "paper frame door"
+ icon_state = "paperframe"
+ openSound = 'sound/effects/doorcreaky.ogg'
+ closeSound = 'sound/effects/doorcreaky.ogg'
+ sheetType = /obj/item/stack/sheet/paperframes
+ sheetAmount = 3
+ resistance_flags = FLAMMABLE
+ max_integrity = 20
+
+/obj/structure/mineral_door/paperframe/Initialize()
+ . = ..()
+ queue_smooth_neighbors(src)
+
+/obj/structure/mineral_door/paperframe/Destroy()
+ queue_smooth_neighbors(src)
+ return ..()
diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm
index aa9e8364c4..16e77c1141 100644
--- a/code/game/objects/structures/plasticflaps.dm
+++ b/code/game/objects/structures/plasticflaps.dm
@@ -76,7 +76,7 @@
if(C.move_delay)
return 0
- if(istype(A, /obj/mecha))
+ if(ismecha(A))
return 0
diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm
index ffc62ac127..1c2c0c326e 100644
--- a/code/game/objects/structures/transit_tubes/station.dm
+++ b/code/game/objects/structures/transit_tubes/station.dm
@@ -7,6 +7,7 @@
/obj/structure/transit_tube/station
name = "station tube station"
icon_state = "closed_station0"
+ desc = "The lynchpin of the transit system."
exit_delay = 1
enter_delay = 2
tube_construction = /obj/structure/c_transit_tube/station
diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm
index 10d883d392..e409eb533b 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube.dm
@@ -3,6 +3,7 @@
name = "transit tube"
icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
icon_state = "straight"
+ desc = "A transit tube for moving things around."
density = TRUE
layer = LOW_ITEM_LAYER
anchored = TRUE
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_construction.dm b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm
index a1f7bcc8de..62e46e49dd 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_construction.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm
@@ -1,158 +1,159 @@
-// transit tube construction
-
-// normal transit tubes
-/obj/structure/c_transit_tube
- name = "unattached transit tube"
- icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
- icon_state = "straight"
+// transit tube construction
+
+// normal transit tubes
+/obj/structure/c_transit_tube
+ name = "unattached transit tube"
+ icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
+ icon_state = "straight"
+ desc = "An unattached segment of transit tube."
density = FALSE
- layer = LOW_ITEM_LAYER //same as the built tube
+ layer = LOW_ITEM_LAYER //same as the built tube
anchored = FALSE
- var/flipped = 0
- var/build_type = /obj/structure/transit_tube
- var/flipped_build_type
- var/base_icon
-
-/obj/structure/c_transit_tube/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to rotate it clockwise.")
-
-/obj/structure/c_transit_tube/proc/tube_rotate()
- setDir(turn(dir, -90))
-
-/obj/structure/c_transit_tube/proc/tube_flip()
- if(flipped_build_type)
- flipped = !flipped
- var/cur_flip = initial(flipped) ? !flipped : flipped
- if(cur_flip)
- build_type = flipped_build_type
- else
- build_type = initial(build_type)
- icon_state = "[base_icon][flipped]"
- else
- setDir(turn(dir, 180))
-
-// disposals-style flip and rotate verbs
-/obj/structure/c_transit_tube/verb/rotate()
- set name = "Rotate Tube"
- set category = "Object"
- set src in view(1)
-
- if(usr.incapacitated())
- return
-
- tube_rotate()
-
-/obj/structure/c_transit_tube/AltClick(mob/user)
- ..()
- if(user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!in_range(src, user))
- return
- tube_rotate()
-
-/obj/structure/c_transit_tube/verb/flip()
- set name = "Flip"
- set category = "Object"
- set src in view(1)
-
- if(usr.incapacitated())
- return
- tube_flip()
-
-
-/obj/structure/c_transit_tube/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/wrench))
- to_chat(user, "You start attaching the [name]...")
- add_fingerprint(user)
- playsound(src.loc, I.usesound, 50, 1)
- if(do_after(user, 40*I.toolspeed, target = src))
- if(QDELETED(src))
- return
- to_chat(user, "You attach the [name].")
- var/obj/structure/transit_tube/R = new build_type(loc, dir)
- transfer_fingerprints_to(R)
- qdel(src)
- else
- return ..()
-
-// transit tube station
-/obj/structure/c_transit_tube/station
- name = "unattached through station"
- icon_state = "closed_station0"
- build_type = /obj/structure/transit_tube/station
- flipped_build_type = /obj/structure/transit_tube/station/flipped
- base_icon = "closed_station"
-
-/obj/structure/c_transit_tube/station/flipped
- icon_state = "closed_station1"
- flipped = 1
- build_type = /obj/structure/transit_tube/station/flipped
- flipped_build_type = /obj/structure/transit_tube/station
-
-
-// reverser station, used for the terminus
-/obj/structure/c_transit_tube/station/reverse
- name = "unattached terminus station"
- icon_state = "closed_terminus0"
- build_type = /obj/structure/transit_tube/station/reverse
- flipped_build_type = /obj/structure/transit_tube/station/reverse/flipped
- base_icon = "closed_terminus"
-
-/obj/structure/c_transit_tube/station/reverse/flipped
- icon_state = "closed_terminus1"
- flipped = 1
- build_type = /obj/structure/transit_tube/station/reverse/flipped
- flipped_build_type = /obj/structure/transit_tube/station/reverse
-
-
-/obj/structure/c_transit_tube/crossing
- icon_state = "crossing"
- build_type = /obj/structure/transit_tube/crossing
-
-
-/obj/structure/c_transit_tube/diagonal
- icon_state = "diagonal"
- build_type = /obj/structure/transit_tube/diagonal
-
-/obj/structure/c_transit_tube/diagonal/crossing
- icon_state = "diagonal_crossing"
- build_type = /obj/structure/transit_tube/diagonal/crossing
-
-
-/obj/structure/c_transit_tube/curved
- icon_state = "curved0"
- build_type = /obj/structure/transit_tube/curved
- flipped_build_type = /obj/structure/transit_tube/curved/flipped
- base_icon = "curved"
-
-/obj/structure/c_transit_tube/curved/flipped
- icon_state = "curved1"
- build_type = /obj/structure/transit_tube/curved/flipped
- flipped_build_type = /obj/structure/transit_tube/curved
- flipped = 1
-
-
-/obj/structure/c_transit_tube/junction
- icon_state = "junction0"
- build_type = /obj/structure/transit_tube/junction
- flipped_build_type = /obj/structure/transit_tube/junction/flipped
- base_icon = "junction"
-
-
-/obj/structure/c_transit_tube/junction/flipped
- icon_state = "junction1"
- flipped = 1
- build_type = /obj/structure/transit_tube/junction/flipped
- flipped_build_type = /obj/structure/transit_tube/junction
-
-
-//transit tube pod
-//see station.dm for the logic
-/obj/structure/c_transit_tube_pod
- name = "unattached transit tube pod"
- icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
- icon_state = "pod"
+ var/flipped = 0
+ var/build_type = /obj/structure/transit_tube
+ var/flipped_build_type
+ var/base_icon
+
+/obj/structure/c_transit_tube/examine(mob/user)
+ ..()
+ to_chat(user, "Alt-click to rotate it clockwise.")
+
+/obj/structure/c_transit_tube/proc/tube_rotate()
+ setDir(turn(dir, -90))
+
+/obj/structure/c_transit_tube/proc/tube_flip()
+ if(flipped_build_type)
+ flipped = !flipped
+ var/cur_flip = initial(flipped) ? !flipped : flipped
+ if(cur_flip)
+ build_type = flipped_build_type
+ else
+ build_type = initial(build_type)
+ icon_state = "[base_icon][flipped]"
+ else
+ setDir(turn(dir, 180))
+
+// disposals-style flip and rotate verbs
+/obj/structure/c_transit_tube/verb/rotate()
+ set name = "Rotate Tube"
+ set category = "Object"
+ set src in view(1)
+
+ if(usr.incapacitated())
+ return
+
+ tube_rotate()
+
+/obj/structure/c_transit_tube/AltClick(mob/user)
+ ..()
+ if(user.incapacitated())
+ to_chat(user, "You can't do that right now!")
+ return
+ if(!in_range(src, user))
+ return
+ tube_rotate()
+
+/obj/structure/c_transit_tube/verb/flip()
+ set name = "Flip"
+ set category = "Object"
+ set src in view(1)
+
+ if(usr.incapacitated())
+ return
+ tube_flip()
+
+
+/obj/structure/c_transit_tube/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/wrench))
+ to_chat(user, "You start attaching the [name]...")
+ add_fingerprint(user)
+ playsound(src.loc, I.usesound, 50, 1)
+ if(do_after(user, 40*I.toolspeed, target = src))
+ if(QDELETED(src))
+ return
+ to_chat(user, "You attach the [name].")
+ var/obj/structure/transit_tube/R = new build_type(loc, dir)
+ transfer_fingerprints_to(R)
+ qdel(src)
+ else
+ return ..()
+
+// transit tube station
+/obj/structure/c_transit_tube/station
+ name = "unattached through station"
+ icon_state = "closed_station0"
+ build_type = /obj/structure/transit_tube/station
+ flipped_build_type = /obj/structure/transit_tube/station/flipped
+ base_icon = "closed_station"
+
+/obj/structure/c_transit_tube/station/flipped
+ icon_state = "closed_station1"
+ flipped = 1
+ build_type = /obj/structure/transit_tube/station/flipped
+ flipped_build_type = /obj/structure/transit_tube/station
+
+
+// reverser station, used for the terminus
+/obj/structure/c_transit_tube/station/reverse
+ name = "unattached terminus station"
+ icon_state = "closed_terminus0"
+ build_type = /obj/structure/transit_tube/station/reverse
+ flipped_build_type = /obj/structure/transit_tube/station/reverse/flipped
+ base_icon = "closed_terminus"
+
+/obj/structure/c_transit_tube/station/reverse/flipped
+ icon_state = "closed_terminus1"
+ flipped = 1
+ build_type = /obj/structure/transit_tube/station/reverse/flipped
+ flipped_build_type = /obj/structure/transit_tube/station/reverse
+
+
+/obj/structure/c_transit_tube/crossing
+ icon_state = "crossing"
+ build_type = /obj/structure/transit_tube/crossing
+
+
+/obj/structure/c_transit_tube/diagonal
+ icon_state = "diagonal"
+ build_type = /obj/structure/transit_tube/diagonal
+
+/obj/structure/c_transit_tube/diagonal/crossing
+ icon_state = "diagonal_crossing"
+ build_type = /obj/structure/transit_tube/diagonal/crossing
+
+
+/obj/structure/c_transit_tube/curved
+ icon_state = "curved0"
+ build_type = /obj/structure/transit_tube/curved
+ flipped_build_type = /obj/structure/transit_tube/curved/flipped
+ base_icon = "curved"
+
+/obj/structure/c_transit_tube/curved/flipped
+ icon_state = "curved1"
+ build_type = /obj/structure/transit_tube/curved/flipped
+ flipped_build_type = /obj/structure/transit_tube/curved
+ flipped = 1
+
+
+/obj/structure/c_transit_tube/junction
+ icon_state = "junction0"
+ build_type = /obj/structure/transit_tube/junction
+ flipped_build_type = /obj/structure/transit_tube/junction/flipped
+ base_icon = "junction"
+
+
+/obj/structure/c_transit_tube/junction/flipped
+ icon_state = "junction1"
+ flipped = 1
+ build_type = /obj/structure/transit_tube/junction/flipped
+ flipped_build_type = /obj/structure/transit_tube/junction
+
+
+//transit tube pod
+//see station.dm for the logic
+/obj/structure/c_transit_tube_pod
+ name = "unattached transit tube pod"
+ icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
+ icon_state = "pod"
anchored = FALSE
density = FALSE
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index 6503acf6d3..c4a0d48dde 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -1,370 +1,371 @@
-/* Windoor (window door) assembly -Nodrak
- * Step 1: Create a windoor out of rglass
- * Step 2: Add r-glass to the assembly to make a secure windoor (Optional)
- * Step 3: Rotate or Flip the assembly to face and open the way you want
- * Step 4: Wrench the assembly in place
- * Step 5: Add cables to the assembly
- * Step 6: Set access for the door.
- * Step 7: Screwdriver the door to complete
- */
-
-
-/obj/structure/windoor_assembly
- icon = 'icons/obj/doors/windoor.dmi'
-
- name = "windoor Assembly"
- icon_state = "l_windoor_assembly01"
+/* Windoor (window door) assembly -Nodrak
+ * Step 1: Create a windoor out of rglass
+ * Step 2: Add r-glass to the assembly to make a secure windoor (Optional)
+ * Step 3: Rotate or Flip the assembly to face and open the way you want
+ * Step 4: Wrench the assembly in place
+ * Step 5: Add cables to the assembly
+ * Step 6: Set access for the door.
+ * Step 7: Screwdriver the door to complete
+ */
+
+
+/obj/structure/windoor_assembly
+ icon = 'icons/obj/doors/windoor.dmi'
+
+ name = "windoor Assembly"
+ icon_state = "l_windoor_assembly01"
+ desc = "A small glass and wire assembly for windoors."
anchored = FALSE
density = FALSE
- dir = NORTH
-
- var/ini_dir
- var/obj/item/electronics/airlock/electronics = null
- var/created_name = null
-
- //Vars to help with the icon's name
- var/facing = "l" //Does the windoor open to the left or right?
+ dir = NORTH
+
+ var/ini_dir
+ var/obj/item/electronics/airlock/electronics = null
+ var/created_name = null
+
+ //Vars to help with the icon's name
+ var/facing = "l" //Does the windoor open to the left or right?
var/secure = FALSE //Whether or not this creates a secure windoor
- var/state = "01" //How far the door assembly has progressed
- CanAtmosPass = ATMOS_PASS_PROC
-
-/obj/structure/windoor_assembly/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to rotate it clockwise.")
-
-/obj/structure/windoor_assembly/New(loc, set_dir)
- ..()
- if(set_dir)
- dir = set_dir
- ini_dir = dir
- air_update_turf(1)
-
-/obj/structure/windoor_assembly/Destroy()
+ var/state = "01" //How far the door assembly has progressed
+ CanAtmosPass = ATMOS_PASS_PROC
+
+/obj/structure/windoor_assembly/examine(mob/user)
+ ..()
+ to_chat(user, "Alt-click to rotate it clockwise.")
+
+/obj/structure/windoor_assembly/New(loc, set_dir)
+ ..()
+ if(set_dir)
+ dir = set_dir
+ ini_dir = dir
+ air_update_turf(1)
+
+/obj/structure/windoor_assembly/Destroy()
density = FALSE
- air_update_turf(1)
- return ..()
-
-/obj/structure/windoor_assembly/Move()
- var/turf/T = loc
- ..()
- setDir(ini_dir)
- move_update_air(T)
-
-/obj/structure/windoor_assembly/update_icon()
- icon_state = "[facing]_[secure ? "secure_" : ""]windoor_assembly[state]"
-
+ air_update_turf(1)
+ return ..()
+
+/obj/structure/windoor_assembly/Move()
+ var/turf/T = loc
+ ..()
+ setDir(ini_dir)
+ move_update_air(T)
+
+/obj/structure/windoor_assembly/update_icon()
+ icon_state = "[facing]_[secure ? "secure_" : ""]windoor_assembly[state]"
+
/obj/structure/windoor_assembly/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && mover.checkpass(PASSGLASS))
- return 1
- if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
- return !density
- if(istype(mover, /obj/structure/window))
- var/obj/structure/window/W = mover
- if(!valid_window_location(loc, W.ini_dir))
- return FALSE
- else if(istype(mover, /obj/structure/windoor_assembly))
- var/obj/structure/windoor_assembly/W = mover
- if(!valid_window_location(loc, W.ini_dir))
- return FALSE
- else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir))
- return FALSE
- return 1
-
-/obj/structure/windoor_assembly/CanAtmosPass(turf/T)
- if(get_dir(loc, T) == dir)
- return !density
- else
- return 1
-
-/obj/structure/windoor_assembly/CheckExit(atom/movable/mover as mob|obj, turf/target)
- if(istype(mover) && mover.checkpass(PASSGLASS))
- return 1
- if(get_dir(loc, target) == dir)
- return !density
- else
- return 1
-
-
-/obj/structure/windoor_assembly/attackby(obj/item/W, mob/user, params)
- //I really should have spread this out across more states but thin little windoors are hard to sprite.
- add_fingerprint(user)
- switch(state)
- if("01")
- if(istype(W, /obj/item/weldingtool) && !anchored )
- var/obj/item/weldingtool/WT = W
- if (WT.remove_fuel(0,user))
- user.visible_message("[user] disassembles the windoor assembly.", "You start to disassemble the windoor assembly...")
- playsound(loc, 'sound/items/welder2.ogg', 50, 1)
-
- if(do_after(user, 40*W.toolspeed, target = src))
- if(!src || !WT.isOn()) return
- to_chat(user, "You disassemble the windoor assembly.")
- var/obj/item/stack/sheet/rglass/RG = new (get_turf(src), 5)
- RG.add_fingerprint(user)
- if(secure)
- var/obj/item/stack/rods/R = new (get_turf(src), 4)
- R.add_fingerprint(user)
- qdel(src)
- else
- return
-
- //Wrenching an unsecure assembly anchors it in place. Step 4 complete
- if(istype(W, /obj/item/wrench) && !anchored)
- for(var/obj/machinery/door/window/WD in loc)
- if(WD.dir == dir)
- to_chat(user, "There is already a windoor in that location!")
- return
- playsound(loc, W.usesound, 100, 1)
- user.visible_message("[user] secures the windoor assembly to the floor.", "You start to secure the windoor assembly to the floor...")
-
- if(do_after(user, 40*W.toolspeed, target = src))
- if(!src || anchored)
- return
- for(var/obj/machinery/door/window/WD in loc)
- if(WD.dir == dir)
- to_chat(user, "There is already a windoor in that location!")
- return
- to_chat(user, "You secure the windoor assembly.")
+ if(istype(mover) && mover.checkpass(PASSGLASS))
+ return 1
+ if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
+ return !density
+ if(istype(mover, /obj/structure/window))
+ var/obj/structure/window/W = mover
+ if(!valid_window_location(loc, W.ini_dir))
+ return FALSE
+ else if(istype(mover, /obj/structure/windoor_assembly))
+ var/obj/structure/windoor_assembly/W = mover
+ if(!valid_window_location(loc, W.ini_dir))
+ return FALSE
+ else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir))
+ return FALSE
+ return 1
+
+/obj/structure/windoor_assembly/CanAtmosPass(turf/T)
+ if(get_dir(loc, T) == dir)
+ return !density
+ else
+ return 1
+
+/obj/structure/windoor_assembly/CheckExit(atom/movable/mover as mob|obj, turf/target)
+ if(istype(mover) && mover.checkpass(PASSGLASS))
+ return 1
+ if(get_dir(loc, target) == dir)
+ return !density
+ else
+ return 1
+
+
+/obj/structure/windoor_assembly/attackby(obj/item/W, mob/user, params)
+ //I really should have spread this out across more states but thin little windoors are hard to sprite.
+ add_fingerprint(user)
+ switch(state)
+ if("01")
+ if(istype(W, /obj/item/weldingtool) && !anchored )
+ var/obj/item/weldingtool/WT = W
+ if (WT.remove_fuel(0,user))
+ user.visible_message("[user] disassembles the windoor assembly.", "You start to disassemble the windoor assembly...")
+ playsound(loc, 'sound/items/welder2.ogg', 50, 1)
+
+ if(do_after(user, 40*W.toolspeed, target = src))
+ if(!src || !WT.isOn()) return
+ to_chat(user, "You disassemble the windoor assembly.")
+ var/obj/item/stack/sheet/rglass/RG = new (get_turf(src), 5)
+ RG.add_fingerprint(user)
+ if(secure)
+ var/obj/item/stack/rods/R = new (get_turf(src), 4)
+ R.add_fingerprint(user)
+ qdel(src)
+ else
+ return
+
+ //Wrenching an unsecure assembly anchors it in place. Step 4 complete
+ if(istype(W, /obj/item/wrench) && !anchored)
+ for(var/obj/machinery/door/window/WD in loc)
+ if(WD.dir == dir)
+ to_chat(user, "There is already a windoor in that location!")
+ return
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] secures the windoor assembly to the floor.", "You start to secure the windoor assembly to the floor...")
+
+ if(do_after(user, 40*W.toolspeed, target = src))
+ if(!src || anchored)
+ return
+ for(var/obj/machinery/door/window/WD in loc)
+ if(WD.dir == dir)
+ to_chat(user, "There is already a windoor in that location!")
+ return
+ to_chat(user, "You secure the windoor assembly.")
anchored = TRUE
- if(secure)
- name = "secure anchored windoor assembly"
- else
- name = "anchored windoor assembly"
-
- //Unwrenching an unsecure assembly un-anchors it. Step 4 undone
- else if(istype(W, /obj/item/wrench) && anchored)
- playsound(loc, W.usesound, 100, 1)
- user.visible_message("[user] unsecures the windoor assembly to the floor.", "You start to unsecure the windoor assembly to the floor...")
-
- if(do_after(user, 40*W.toolspeed, target = src))
- if(!src || !anchored)
- return
- to_chat(user, "You unsecure the windoor assembly.")
+ if(secure)
+ name = "secure anchored windoor assembly"
+ else
+ name = "anchored windoor assembly"
+
+ //Unwrenching an unsecure assembly un-anchors it. Step 4 undone
+ else if(istype(W, /obj/item/wrench) && anchored)
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] unsecures the windoor assembly to the floor.", "You start to unsecure the windoor assembly to the floor...")
+
+ if(do_after(user, 40*W.toolspeed, target = src))
+ if(!src || !anchored)
+ return
+ to_chat(user, "You unsecure the windoor assembly.")
anchored = FALSE
- if(secure)
- name = "secure windoor assembly"
- else
- name = "windoor assembly"
-
- //Adding plasteel makes the assembly a secure windoor assembly. Step 2 (optional) complete.
- else if(istype(W, /obj/item/stack/sheet/plasteel) && !secure)
- var/obj/item/stack/sheet/plasteel/P = W
- if(P.get_amount() < 2)
- to_chat(user, "You need more plasteel to do this!")
- return
- to_chat(user, "You start to reinforce the windoor with plasteel...")
-
- if(do_after(user,40, target = src))
- if(!src || secure || P.get_amount() < 2)
- return
-
- P.use(2)
- to_chat(user, "You reinforce the windoor.")
+ if(secure)
+ name = "secure windoor assembly"
+ else
+ name = "windoor assembly"
+
+ //Adding plasteel makes the assembly a secure windoor assembly. Step 2 (optional) complete.
+ else if(istype(W, /obj/item/stack/sheet/plasteel) && !secure)
+ var/obj/item/stack/sheet/plasteel/P = W
+ if(P.get_amount() < 2)
+ to_chat(user, "You need more plasteel to do this!")
+ return
+ to_chat(user, "You start to reinforce the windoor with plasteel...")
+
+ if(do_after(user,40, target = src))
+ if(!src || secure || P.get_amount() < 2)
+ return
+
+ P.use(2)
+ to_chat(user, "You reinforce the windoor.")
secure = TRUE
- if(anchored)
- name = "secure anchored windoor assembly"
- else
- name = "secure windoor assembly"
-
- //Adding cable to the assembly. Step 5 complete.
- else if(istype(W, /obj/item/stack/cable_coil) && anchored)
- user.visible_message("[user] wires the windoor assembly.", "You start to wire the windoor assembly...")
-
- if(do_after(user, 40, target = src))
- if(!src || !anchored || src.state != "01")
- return
- var/obj/item/stack/cable_coil/CC = W
- if(!CC.use(1))
- to_chat(user, "You need more cable to do this!")
- return
- to_chat(user, "You wire the windoor.")
- state = "02"
- if(secure)
- name = "secure wired windoor assembly"
- else
- name = "wired windoor assembly"
- else
- return ..()
-
- if("02")
-
- //Removing wire from the assembly. Step 5 undone.
- if(istype(W, /obj/item/wirecutters))
- playsound(loc, W.usesound, 100, 1)
- user.visible_message("[user] cuts the wires from the airlock assembly.", "You start to cut the wires from airlock assembly...")
-
- if(do_after(user, 40*W.toolspeed, target = src))
- if(!src || state != "02")
- return
-
- to_chat(user, "You cut the windoor wires.")
- new/obj/item/stack/cable_coil(get_turf(user), 1)
- state = "01"
- if(secure)
- name = "secure anchored windoor assembly"
- else
- name = "anchored windoor assembly"
-
- //Adding airlock electronics for access. Step 6 complete.
- else if(istype(W, /obj/item/electronics/airlock))
- if(!user.drop_item())
- return
- playsound(loc, W.usesound, 100, 1)
- user.visible_message("[user] installs the electronics into the airlock assembly.", "You start to install electronics into the airlock assembly...")
- W.loc = src
-
- if(do_after(user, 40, target = src))
- if(!src || electronics)
- W.loc = src.loc
- return
- to_chat(user, "You install the airlock electronics.")
- name = "near finished windoor assembly"
- electronics = W
- else
- W.loc = loc
-
- //Screwdriver to remove airlock electronics. Step 6 undone.
- else if(istype(W, /obj/item/screwdriver))
- if(!electronics)
- return
-
- playsound(loc, W.usesound, 100, 1)
- user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to uninstall electronics from the airlock assembly...")
-
- if(do_after(user, 40*W.toolspeed, target = src))
- if(!src || !electronics)
- return
- to_chat(user, "You remove the airlock electronics.")
- name = "wired windoor assembly"
- var/obj/item/electronics/airlock/ae
- ae = electronics
- electronics = null
- ae.loc = loc
-
- else if(istype(W, /obj/item/pen))
- var/t = stripped_input(user, "Enter the name for the door.", name, created_name,MAX_NAME_LEN)
- if(!t)
- return
- if(!in_range(src, usr) && loc != usr)
- return
- created_name = t
- return
-
-
-
- //Crowbar to complete the assembly, Step 7 complete.
- else if(istype(W, /obj/item/crowbar))
- if(!electronics)
- to_chat(usr, "The assembly is missing electronics!")
- return
- usr << browse(null, "window=windoor_access")
- playsound(loc, W.usesound, 100, 1)
- user.visible_message("[user] pries the windoor into the frame.", "You start prying the windoor into the frame...")
-
- if(do_after(user, 40*W.toolspeed, target = src))
-
- if(loc && electronics)
-
+ if(anchored)
+ name = "secure anchored windoor assembly"
+ else
+ name = "secure windoor assembly"
+
+ //Adding cable to the assembly. Step 5 complete.
+ else if(istype(W, /obj/item/stack/cable_coil) && anchored)
+ user.visible_message("[user] wires the windoor assembly.", "You start to wire the windoor assembly...")
+
+ if(do_after(user, 40, target = src))
+ if(!src || !anchored || src.state != "01")
+ return
+ var/obj/item/stack/cable_coil/CC = W
+ if(!CC.use(1))
+ to_chat(user, "You need more cable to do this!")
+ return
+ to_chat(user, "You wire the windoor.")
+ state = "02"
+ if(secure)
+ name = "secure wired windoor assembly"
+ else
+ name = "wired windoor assembly"
+ else
+ return ..()
+
+ if("02")
+
+ //Removing wire from the assembly. Step 5 undone.
+ if(istype(W, /obj/item/wirecutters))
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] cuts the wires from the airlock assembly.", "You start to cut the wires from airlock assembly...")
+
+ if(do_after(user, 40*W.toolspeed, target = src))
+ if(!src || state != "02")
+ return
+
+ to_chat(user, "You cut the windoor wires.")
+ new/obj/item/stack/cable_coil(get_turf(user), 1)
+ state = "01"
+ if(secure)
+ name = "secure anchored windoor assembly"
+ else
+ name = "anchored windoor assembly"
+
+ //Adding airlock electronics for access. Step 6 complete.
+ else if(istype(W, /obj/item/electronics/airlock))
+ if(!user.drop_item())
+ return
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] installs the electronics into the airlock assembly.", "You start to install electronics into the airlock assembly...")
+ W.loc = src
+
+ if(do_after(user, 40, target = src))
+ if(!src || electronics)
+ W.loc = src.loc
+ return
+ to_chat(user, "You install the airlock electronics.")
+ name = "near finished windoor assembly"
+ electronics = W
+ else
+ W.loc = loc
+
+ //Screwdriver to remove airlock electronics. Step 6 undone.
+ else if(istype(W, /obj/item/screwdriver))
+ if(!electronics)
+ return
+
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to uninstall electronics from the airlock assembly...")
+
+ if(do_after(user, 40*W.toolspeed, target = src))
+ if(!src || !electronics)
+ return
+ to_chat(user, "You remove the airlock electronics.")
+ name = "wired windoor assembly"
+ var/obj/item/electronics/airlock/ae
+ ae = electronics
+ electronics = null
+ ae.loc = loc
+
+ else if(istype(W, /obj/item/pen))
+ var/t = stripped_input(user, "Enter the name for the door.", name, created_name,MAX_NAME_LEN)
+ if(!t)
+ return
+ if(!in_range(src, usr) && loc != usr)
+ return
+ created_name = t
+ return
+
+
+
+ //Crowbar to complete the assembly, Step 7 complete.
+ else if(istype(W, /obj/item/crowbar))
+ if(!electronics)
+ to_chat(usr, "The assembly is missing electronics!")
+ return
+ usr << browse(null, "window=windoor_access")
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] pries the windoor into the frame.", "You start prying the windoor into the frame...")
+
+ if(do_after(user, 40*W.toolspeed, target = src))
+
+ if(loc && electronics)
+
density = TRUE //Shouldn't matter but just incase
- to_chat(user, "You finish the windoor.")
-
- if(secure)
- var/obj/machinery/door/window/brigdoor/windoor = new /obj/machinery/door/window/brigdoor(loc)
- if(facing == "l")
- windoor.icon_state = "leftsecureopen"
- windoor.base_state = "leftsecure"
- else
- windoor.icon_state = "rightsecureopen"
- windoor.base_state = "rightsecure"
- windoor.setDir(dir)
+ to_chat(user, "You finish the windoor.")
+
+ if(secure)
+ var/obj/machinery/door/window/brigdoor/windoor = new /obj/machinery/door/window/brigdoor(loc)
+ if(facing == "l")
+ windoor.icon_state = "leftsecureopen"
+ windoor.base_state = "leftsecure"
+ else
+ windoor.icon_state = "rightsecureopen"
+ windoor.base_state = "rightsecure"
+ windoor.setDir(dir)
windoor.density = FALSE
-
- if(electronics.one_access)
- windoor.req_one_access = electronics.accesses
- else
- windoor.req_access = electronics.accesses
- windoor.electronics = electronics
- electronics.loc = windoor
- if(created_name)
- windoor.name = created_name
- qdel(src)
- windoor.close()
-
-
- else
- var/obj/machinery/door/window/windoor = new /obj/machinery/door/window(loc)
- if(facing == "l")
- windoor.icon_state = "leftopen"
- windoor.base_state = "left"
- else
- windoor.icon_state = "rightopen"
- windoor.base_state = "right"
- windoor.setDir(dir)
+
+ if(electronics.one_access)
+ windoor.req_one_access = electronics.accesses
+ else
+ windoor.req_access = electronics.accesses
+ windoor.electronics = electronics
+ electronics.loc = windoor
+ if(created_name)
+ windoor.name = created_name
+ qdel(src)
+ windoor.close()
+
+
+ else
+ var/obj/machinery/door/window/windoor = new /obj/machinery/door/window(loc)
+ if(facing == "l")
+ windoor.icon_state = "leftopen"
+ windoor.base_state = "left"
+ else
+ windoor.icon_state = "rightopen"
+ windoor.base_state = "right"
+ windoor.setDir(dir)
windoor.density = FALSE
-
- windoor.req_access = electronics.accesses
- windoor.electronics = electronics
- electronics.loc = windoor
- if(created_name)
- windoor.name = created_name
- qdel(src)
- windoor.close()
-
-
- else
- return ..()
-
- //Update to reflect changes(if applicable)
- update_icon()
-
-
-//Rotates the windoor assembly clockwise
-/obj/structure/windoor_assembly/verb/revrotate()
- set name = "Rotate Windoor Assembly"
- set category = "Object"
- set src in oview(1)
- if(usr.stat || !usr.canmove || usr.restrained())
- return
- if(anchored)
- to_chat(usr, "[src] cannot be rotated while it is fastened to the floor!")
- return FALSE
-
- var/target_dir = turn(dir, 270)
-
- if(!valid_window_location(loc, target_dir))
- to_chat(usr, "[src] cannot be rotated in that direction!")
- return FALSE
-
- setDir(target_dir)
-
- ini_dir = dir
- update_icon()
- return TRUE
-
-/obj/structure/windoor_assembly/AltClick(mob/user)
- ..()
- if(user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!in_range(src, user))
- return
- else
- revrotate()
-
-//Flips the windoor assembly, determines whather the door opens to the left or the right
-/obj/structure/windoor_assembly/verb/flip()
- set name = "Flip Windoor Assembly"
- set category = "Object"
- set src in oview(1)
- if(usr.stat || !usr.canmove || usr.restrained())
- return
-
- if(facing == "l")
- to_chat(usr, "The windoor will now slide to the right.")
- facing = "r"
- else
- facing = "l"
- to_chat(usr, "The windoor will now slide to the left.")
-
- update_icon()
- return
+
+ windoor.req_access = electronics.accesses
+ windoor.electronics = electronics
+ electronics.loc = windoor
+ if(created_name)
+ windoor.name = created_name
+ qdel(src)
+ windoor.close()
+
+
+ else
+ return ..()
+
+ //Update to reflect changes(if applicable)
+ update_icon()
+
+
+//Rotates the windoor assembly clockwise
+/obj/structure/windoor_assembly/verb/revrotate()
+ set name = "Rotate Windoor Assembly"
+ set category = "Object"
+ set src in oview(1)
+ if(usr.stat || !usr.canmove || usr.restrained())
+ return
+ if(anchored)
+ to_chat(usr, "[src] cannot be rotated while it is fastened to the floor!")
+ return FALSE
+
+ var/target_dir = turn(dir, 270)
+
+ if(!valid_window_location(loc, target_dir))
+ to_chat(usr, "[src] cannot be rotated in that direction!")
+ return FALSE
+
+ setDir(target_dir)
+
+ ini_dir = dir
+ update_icon()
+ return TRUE
+
+/obj/structure/windoor_assembly/AltClick(mob/user)
+ ..()
+ if(user.incapacitated())
+ to_chat(user, "You can't do that right now!")
+ return
+ if(!in_range(src, user))
+ return
+ else
+ revrotate()
+
+//Flips the windoor assembly, determines whather the door opens to the left or the right
+/obj/structure/windoor_assembly/verb/flip()
+ set name = "Flip Windoor Assembly"
+ set category = "Object"
+ set src in oview(1)
+ if(usr.stat || !usr.canmove || usr.restrained())
+ return
+
+ if(facing == "l")
+ to_chat(usr, "The windoor will now slide to the right.")
+ facing = "r"
+ else
+ facing = "l"
+ to_chat(usr, "The windoor will now slide to the left.")
+
+ update_icon()
+ return
diff --git a/code/game/shuttle_engines.dm b/code/game/shuttle_engines.dm
index 4722991309..80329f20a1 100644
--- a/code/game/shuttle_engines.dm
+++ b/code/game/shuttle_engines.dm
@@ -12,6 +12,7 @@
/obj/structure/shuttle/engine
name = "engine"
+ desc = "A bluespace engine used to make shuttles move."
density = TRUE
anchored = TRUE
var/engine_power = 1
@@ -81,18 +82,21 @@
M.alter_engines(mod)
/obj/structure/shuttle/engine/heater
- name = "heater"
+ name = "engine heater"
icon_state = "heater"
+ desc = "Directs energy into compressed particles in order to power engines."
engine_power = 0 // todo make these into 2x1 parts
/obj/structure/shuttle/engine/platform
- name = "platform"
+ name = "engine platform"
icon_state = "platform"
+ desc = "A platform for engine components."
engine_power = 0
/obj/structure/shuttle/engine/propulsion
name = "propulsion engine"
icon_state = "propulsion"
+ desc = "A standard reliable bluespace engine used by many forms of shuttles."
opacity = 1
/obj/structure/shuttle/engine/propulsion/left
@@ -105,6 +109,7 @@
/obj/structure/shuttle/engine/propulsion/burst
name = "burst engine"
+ desc = "An engine that releases a large bluespace burst to propel it."
/obj/structure/shuttle/engine/propulsion/burst/cargo
state = ENGINE_UNWRENCHED
@@ -119,14 +124,16 @@
icon_state = "burst_r"
/obj/structure/shuttle/engine/router
- name = "router"
+ name = "engine router"
icon_state = "router"
+ desc = "Redirects around energized particles in engine structures."
/obj/structure/shuttle/engine/large
name = "engine"
opacity = 1
icon = 'icons/obj/2x2.dmi'
icon_state = "large_engine"
+ desc = "A very large bluespace engine used to propel very large ships."
bound_width = 64
bound_height = 64
appearance_flags = 0
@@ -136,6 +143,7 @@
opacity = 1
icon = 'icons/obj/3x3.dmi'
icon_state = "huge_engine"
+ desc = "An extremely large bluespace engine used to propel extremely large ships."
bound_width = 96
bound_height = 96
- appearance_flags = 0
\ No newline at end of file
+ appearance_flags = 0
diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm
index 69b1f345b1..c9eb1a6762 100644
--- a/code/game/turfs/closed.dm
+++ b/code/game/turfs/closed.dm
@@ -156,7 +156,7 @@
/turf/closed/bullet_act(obj/item/projectile/Proj)
. = ..()
- if(!Proj.nodamage && (Proj.damage_type == BRUTE || Proj.damage_type == BURN))
+ if((. != -1) && !Proj.nodamage && (Proj.damage_type == BRUTE || Proj.damage_type == BURN))
var/mutable_appearance/bullet_hole = mutable_appearance('icons/effects/effects.dmi', "bullet_hole", BULLET_HOLE_LAYER)
var/random_x = rand(-13, 13)
diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm
index 630ded7daa..a597022448 100644
--- a/code/game/turfs/simulated/minerals.dm
+++ b/code/game/turfs/simulated/minerals.dm
@@ -111,12 +111,6 @@
if(istype(R.module_active, /obj/item/pickaxe))
src.attackby(R.module_active,R)
return
-/* else if(istype(AM, /obj/mecha))
- var/obj/mecha/M = AM
- if(istype(M.selected, /obj/item/mecha_parts/mecha_equipment/drill))
- src.attackby(M.selected,M)
- return*/
-//Aparantly mechs are just TOO COOL to call Collide())
else
return
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 5bb90f618b..b02444281c 100755
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -121,8 +121,6 @@
return FALSE
/turf/Enter(atom/movable/mover as mob|obj, atom/forget as mob|obj|turf|area)
- if (!mover)
- return TRUE
// First, make sure it can leave its square
if(isturf(mover.loc))
// Nothing but border objects stop you from leaving a tile, only one loop is needed
@@ -131,32 +129,28 @@
mover.Collide(obstacle)
return FALSE
- var/list/large_dense = list()
-
- //Next, check objects to block entry that are on the border
- for(var/atom/movable/border_obstacle in src)
- if(border_obstacle.flags_1 & ON_BORDER_1)
- if(!border_obstacle.CanPass(mover, mover.loc, 1) && (forget != border_obstacle))
- mover.Collide(border_obstacle)
- return FALSE
- else
- large_dense += border_obstacle
-
//Then, check the turf itself
if (!src.CanPass(mover, src))
mover.Collide(src)
return FALSE
- //Finally, check objects/mobs to block entry that are not on the border
- var/atom/movable/tompost_bump
+
+ var/atom/movable/topmost_bump
var/top_layer = FALSE
- for(var/atom/movable/obstacle in large_dense)
+
+ //Next, check objects to block entry that are on the border
+ for(var/atom/movable/obstacle in src)
if(!obstacle.CanPass(mover, mover.loc, 1) && (forget != obstacle))
- if(obstacle.layer > top_layer)
- tompost_bump = obstacle
- top_layer = obstacle.layer
- if(tompost_bump)
- mover.Collide(tompost_bump)
+ if(obstacle.flags_1 & ON_BORDER_1)
+ mover.Collide(obstacle)
+ return FALSE
+ else
+ if(obstacle.layer > top_layer)
+ topmost_bump = obstacle
+ top_layer = obstacle.layer
+
+ if(topmost_bump)
+ mover.Collide(topmost_bump)
return FALSE
return TRUE //Nothing found to block so return success!
diff --git a/code/modules/admin/chat_commands.dm b/code/modules/admin/chat_commands.dm
index 1553c31204..f24e03aabc 100644
--- a/code/modules/admin/chat_commands.dm
+++ b/code/modules/admin/chat_commands.dm
@@ -60,3 +60,17 @@
/datum/server_tools_command/adminwho/Run(sender, params)
return ircadminwho()
+
+GLOBAL_LIST(round_end_notifiees)
+
+/datum/server_tools_command/notify
+ name = "notify"
+ help_text = "Pings the invoker when the round ends"
+ admin_only = TRUE
+
+/datum/server_tools_command/notify/Run(sender, params)
+ if(!SSticker.IsRoundInProgress() && SSticker.HasRoundStarted())
+ return "[sender], the round has already ended!"
+ LAZYINITLIST(GLOB.round_end_notifiees)
+ GLOB.round_end_notifiees[sender] = TRUE
+ return "I will notify [sender] when the round ends."
\ No newline at end of file
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 9e43ef92f8..95f4bd55c7 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -530,7 +530,7 @@
else
dat += "| [brother.name]([brother.key])Brother body destroyed! | "
dat += "PM |
"
- dat += ""
+ dat += ""
if(SSticker.mode.abductors.len)
dat += "
| Abductors | | |
"
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index 3a343b7f06..c9784dcf18 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -242,7 +242,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
/datum/admin_help/proc/LinkedReplyName(ref_src)
if(!ref_src)
ref_src = "\ref[src]"
- return "[initiator_key_name]"
+ return "[initiator_key_name]"
//private
/datum/admin_help/proc/TicketHref(msg, ref_src, action = "ticket")
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index d14fb1f167..3021f9badd 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -28,6 +28,22 @@
popup.set_content(dat)
popup.open()
+/datum/admins/proc/isReadytoRumble(mob/living/carbon/human/applicant, targetrole, onstation = TRUE, conscious = TRUE)
+ if(applicant.mind.special_role)
+ return FALSE
+ if(!(targetrole in applicant.client.prefs.be_special))
+ return FALSE
+ if(onstation)
+ var/turf/T = get_turf(applicant)
+ if(!(T.z in GLOB.station_z_levels))
+ return FALSE
+ if(conscious && applicant.stat) //incase you don't care about a certain antag being unconcious when made, ie if they have selfhealing abilities.
+ return FALSE
+ if(!considered_alive(applicant.mind) || considered_afk(applicant.mind)) //makes sure the player isn't a zombie, brain, or just afk all together
+ return FALSE
+ return (!jobban_isbanned(applicant, targetrole) && !jobban_isbanned(applicant, "Syndicate"))
+
+
/datum/admins/proc/makeTraitors()
var/datum/game_mode/traitor/temp = new
@@ -41,14 +57,10 @@
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
- if(ROLE_TRAITOR in applicant.client.prefs.be_special)
- if(!applicant.stat)
- if(applicant.mind)
- if (!applicant.mind.special_role)
- if(!jobban_isbanned(applicant, ROLE_TRAITOR) && !jobban_isbanned(applicant, "Syndicate"))
- if(temp.age_check(applicant.client))
- if(!(applicant.job in temp.restricted_jobs))
- candidates += applicant
+ if(isReadytoRumble(applicant, ROLE_TRAITOR, FALSE))
+ if(temp.age_check(applicant.client))
+ if(!(applicant.job in temp.restricted_jobs))
+ candidates += applicant
if(candidates.len)
var/numTraitors = min(candidates.len, 3)
@@ -77,13 +89,10 @@
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
- if(ROLE_CHANGELING in applicant.client.prefs.be_special)
- var/turf/T = get_turf(applicant)
- if(applicant.stat == CONSCIOUS && applicant.mind && !applicant.mind.special_role && (T.z in GLOB.station_z_levels))
- if(!jobban_isbanned(applicant, ROLE_CHANGELING) && !jobban_isbanned(applicant, "Syndicate"))
- if(temp.age_check(applicant.client))
- if(!(applicant.job in temp.restricted_jobs))
- candidates += applicant
+ if(isReadytoRumble(applicant, ROLE_CHANGELING))
+ if(temp.age_check(applicant.client))
+ if(!(applicant.job in temp.restricted_jobs))
+ candidates += applicant
if(candidates.len)
var/numChanglings = min(candidates.len, 3)
@@ -110,13 +119,10 @@
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
- if(ROLE_REV in applicant.client.prefs.be_special)
- var/turf/T = get_turf(applicant)
- if(applicant.stat == CONSCIOUS && applicant.mind && !applicant.mind.special_role && (T.z in GLOB.station_z_levels))
- if(!jobban_isbanned(applicant, ROLE_REV) && !jobban_isbanned(applicant, "Syndicate"))
- if(temp.age_check(applicant.client))
- if(!(applicant.job in temp.restricted_jobs))
- candidates += applicant
+ if(isReadytoRumble(applicant, ROLE_REV))
+ if(temp.age_check(applicant.client))
+ if(!(applicant.job in temp.restricted_jobs))
+ candidates += applicant
if(candidates.len)
var/numRevs = min(candidates.len, 3)
@@ -152,13 +158,10 @@
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
- if(ROLE_CULTIST in applicant.client.prefs.be_special)
- var/turf/T = get_turf(applicant)
- if(applicant.stat == CONSCIOUS && applicant.mind && !applicant.mind.special_role && (T.z in GLOB.station_z_levels))
- if(!jobban_isbanned(applicant, ROLE_CULTIST) && !jobban_isbanned(applicant, "Syndicate"))
- if(temp.age_check(applicant.client))
- if(!(applicant.job in temp.restricted_jobs))
- candidates += applicant
+ if(isReadytoRumble(applicant, ROLE_CULTIST))
+ if(temp.age_check(applicant.client))
+ if(!(applicant.job in temp.restricted_jobs))
+ candidates += applicant
if(candidates.len)
var/numCultists = min(candidates.len, 4)
@@ -185,13 +188,10 @@
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
- if(ROLE_SERVANT_OF_RATVAR in applicant.client.prefs.be_special)
- var/turf/T = get_turf(applicant)
- if(applicant.stat == CONSCIOUS && applicant.mind && !applicant.mind.special_role && (T.z in GLOB.station_z_levels))
- if(!jobban_isbanned(applicant, ROLE_SERVANT_OF_RATVAR) && !jobban_isbanned(applicant, "Syndicate"))
- if(temp.age_check(applicant.client))
- if(!(applicant.job in temp.restricted_jobs))
- candidates += applicant
+ if(isReadytoRumble(applicant, ROLE_SERVANT_OF_RATVAR))
+ if(temp.age_check(applicant.client))
+ if(!(applicant.job in temp.restricted_jobs))
+ candidates += applicant
if(candidates.len)
var/numCultists = min(candidates.len, 4)
diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm
index d63d0d712f..0cc1f72256 100644
--- a/code/modules/admin/verbs/playsound.dm
+++ b/code/modules/admin/verbs/playsound.dm
@@ -92,8 +92,7 @@
if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
pitch = pick(0.5, 0.7, 0.8, 0.85, 0.9, 0.95, 1.1, 1.2, 1.4, 1.6, 2.0, 2.5)
to_chat(src, "You feel the Honkmother messing with your song...")
-
- SSblackbox.add_details("played_url", web_sound_input)
+ SSblackbox.add_details("played_url", "[web_sound_input]|[ckey]")
log_admin("[key_name(src)] played web sound: [web_sound_input]")
message_admins("[key_name(src)] played web sound: [web_sound_input]")
else
diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm
index a39a9059f3..93862f16b4 100644
--- a/code/modules/atmospherics/environmental/LINDA_fire.dm
+++ b/code/modules/atmospherics/environmental/LINDA_fire.dm
@@ -49,7 +49,7 @@
icon = 'icons/effects/fire.dmi'
icon_state = "1"
layer = ABOVE_OPEN_TURF_LAYER
- light_range = 3
+ light_range = LIGHT_RANGE_FIRE
light_color = LIGHT_COLOR_FIRE
var/volume = 125
@@ -175,3 +175,15 @@
..()
if(isliving(L))
L.fire_act(temperature, volume)
+
+/obj/effect/dummy/fire
+ name = "fire"
+ desc = "OWWWWWW. IT BURNS. Tell a coder if you're seeing this."
+ icon_state = "nothing"
+ light_color = LIGHT_COLOR_FIRE
+ light_range = LIGHT_RANGE_FIRE
+
+/obj/effect/dummy/fire/Initialize()
+ . = ..()
+ if(!isliving(loc))
+ qdel(src)
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
index 7ef6cf2142..dbe1343667 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
@@ -5,7 +5,7 @@ It's like a regular ol' straight pipe, but you can turn it on and off.
/obj/machinery/atmospherics/components/binary/valve
icon_state = "mvalve_map"
name = "manual valve"
- desc = "A pipe valve"
+ desc = "A pipe with a valve that can be used to disable flow of gas through it."
can_unwrench = TRUE
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
index c777e5fe17..2b5a94ef64 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
@@ -1,6 +1,7 @@
/obj/machinery/atmospherics/components/trinary/filter
name = "gas filter"
icon_state = "filter_off"
+ desc = "Very useful for filtering gasses."
density = FALSE
can_unwrench = TRUE
var/on = FALSE
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
index cb515ec75f..1fb8b072c6 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
@@ -4,6 +4,7 @@
name = "gas mixer"
can_unwrench = TRUE
+ desc = "Very useful for mixing gasses."
var/on = FALSE
diff --git a/code/modules/atmospherics/machinery/other/zvent.dm b/code/modules/atmospherics/machinery/other/zvent.dm
index 3490c972d9..d12c6196ec 100644
--- a/code/modules/atmospherics/machinery/other/zvent.dm
+++ b/code/modules/atmospherics/machinery/other/zvent.dm
@@ -5,6 +5,7 @@
icon_state = "vent_map"
density = FALSE
anchored=1
+ desc = "This may be needed some day."
var/on = FALSE
var/volume_rate = 800
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 9d8b25cebf..237714eb8e 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -48,7 +48,7 @@
if(pockets && over_object == M)
return pockets.MouseDrop(over_object)
- if(istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
+ if(ismecha(M.loc)) // stops inventory actions in a mech
return
if(!M.incapacitated() && loc == M && istype(over_object, /obj/screen/inventory/hand))
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index db3bcd3538..87106d65b4 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -283,7 +283,7 @@
/obj/item/clothing/head/crown/fancy
name = "magnificent crown"
- desc = "A crown worn by only the highest emperors of the land."
+ desc = "A crown worn by only the highest emperors of the land space."
icon_state = "fancycrown"
/obj/item/clothing/head/scarecrow_hat
diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm
index 3e6a5ad371..c5e68ebcec 100644
--- a/code/modules/clothing/under/accessories.dm
+++ b/code/modules/clothing/under/accessories.dm
@@ -151,6 +151,16 @@
desc = "A bronze heart-shaped medal awarded for sacrifice. It is often awarded posthumously or for severe injury in the line of duty."
icon_state = "bronze_heart"
+/obj/item/clothing/accessory/medal/ribbon
+ name = "ribbon"
+ desc = "A ribbon"
+ icon_state = "cargo"
+ item_color = "cargo"
+
+/obj/item/clothing/accessory/medal/ribbon/cargo
+ name = "\"cargo tech of the shift\" award"
+ desc = "An award bestowed only upon those cargotechs who have exhibited devotion to their duty in keeping with the highest traditions of Cargonia."
+
/obj/item/clothing/accessory/medal/silver
name = "silver medal"
desc = "A silver medal."
diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm
index 34e5d5e9a2..ca6cd782fc 100644
--- a/code/modules/events/carp_migration.dm
+++ b/code/modules/events/carp_migration.dm
@@ -1,28 +1,25 @@
-/datum/round_event_control/carp_migration
- name = "Carp Migration"
- typepath = /datum/round_event/carp_migration
- weight = 15
- min_players = 2
- earliest_start = 6000
- max_occurrences = 6
-
-/datum/round_event/carp_migration
- announceWhen = 3
- startWhen = 50
-
-/datum/round_event/carp_migration/setup()
- startWhen = rand(40, 60)
-
-/datum/round_event/carp_migration/announce()
- priority_announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
-
-
-/datum/round_event/carp_migration/start()
- for(var/obj/effect/landmark/C in GLOB.landmarks_list)
- if(C.name == "carpspawn")
- if(prob(95))
- new /mob/living/simple_animal/hostile/carp(C.loc)
- else
- new /mob/living/simple_animal/hostile/carp/megacarp(C.loc)
-
-
+/datum/round_event_control/carp_migration
+ name = "Carp Migration"
+ typepath = /datum/round_event/carp_migration
+ weight = 15
+ min_players = 2
+ earliest_start = 6000
+ max_occurrences = 6
+
+/datum/round_event/carp_migration
+ announceWhen = 3
+ startWhen = 50
+
+/datum/round_event/carp_migration/setup()
+ startWhen = rand(40, 60)
+
+/datum/round_event/carp_migration/announce()
+ priority_announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
+
+
+/datum/round_event/carp_migration/start()
+ for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list)
+ if(prob(95))
+ new /mob/living/simple_animal/hostile/carp(C.loc)
+ else
+ new /mob/living/simple_animal/hostile/carp/megacarp(C.loc)
diff --git a/code/modules/events/electrical_storm.dm b/code/modules/events/electrical_storm.dm
index 0f1af1f8f9..a10e42d754 100644
--- a/code/modules/events/electrical_storm.dm
+++ b/code/modules/events/electrical_storm.dm
@@ -1,36 +1,36 @@
-/datum/round_event_control/electrical_storm
- name = "Electrical Storm"
- typepath = /datum/round_event/electrical_storm
- earliest_start = 6000
- min_players = 5
- weight = 40
- alertadmins = 0
-
-/datum/round_event/electrical_storm
- var/lightsoutAmount = 1
- var/lightsoutRange = 25
- announceWhen = 1
-
-/datum/round_event/electrical_storm/announce()
- priority_announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert")
-
-
-/datum/round_event/electrical_storm/start()
- var/list/epicentreList = list()
-
- for(var/i=1, i <= lightsoutAmount, i++)
- var/list/possibleEpicentres = list()
- for(var/obj/effect/landmark/newEpicentre in GLOB.landmarks_list)
- if(newEpicentre.name == "lightsout" && !(newEpicentre in epicentreList))
- possibleEpicentres += newEpicentre
- if(possibleEpicentres.len)
- epicentreList += pick(possibleEpicentres)
- else
- break
-
- if(!epicentreList.len)
- return
-
- for(var/obj/effect/landmark/epicentre in epicentreList)
- for(var/obj/machinery/power/apc/apc in urange(lightsoutRange, epicentre))
- apc.overload_lighting()
+/datum/round_event_control/electrical_storm
+ name = "Electrical Storm"
+ typepath = /datum/round_event/electrical_storm
+ earliest_start = 6000
+ min_players = 5
+ weight = 40
+ alertadmins = 0
+
+/datum/round_event/electrical_storm
+ var/lightsoutAmount = 1
+ var/lightsoutRange = 25
+ announceWhen = 1
+
+/datum/round_event/electrical_storm/announce()
+ priority_announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert")
+
+
+/datum/round_event/electrical_storm/start()
+ var/list/epicentreList = list()
+
+ for(var/i=1, i <= lightsoutAmount, i++)
+ var/list/possibleEpicentres = list()
+ for(var/obj/effect/landmark/lightsout/newEpicentre in GLOB.landmarks_list)
+ if(!(newEpicentre in epicentreList))
+ possibleEpicentres += newEpicentre
+ if(possibleEpicentres.len)
+ epicentreList += pick(possibleEpicentres)
+ else
+ break
+
+ if(!epicentreList.len)
+ return
+
+ for(var/obj/effect/landmark/epicentre in epicentreList)
+ for(var/obj/machinery/power/apc/apc in urange(lightsoutRange, epicentre))
+ apc.overload_lighting()
diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm
index 843f043bfa..5415eab386 100644
--- a/code/modules/events/holiday/halloween.dm
+++ b/code/modules/events/holiday/halloween.dm
@@ -1,138 +1,137 @@
-/datum/round_event_control/spooky
- name = "2 SPOOKY! (Halloween)"
- holidayID = HALLOWEEN
- typepath = /datum/round_event/spooky
- weight = -1 //forces it to be called, regardless of weight
- max_occurrences = 1
- earliest_start = 0
-
-/datum/round_event/spooky/start()
- ..()
- for(var/mob/living/carbon/human/H in GLOB.mob_list)
- var/obj/item/storage/backpack/b = locate() in H.contents
- new /obj/item/storage/spooky(b)
- if(ishuman(H) || islizard(H))
- if(prob(50))
- H.set_species(/datum/species/skeleton)
- else
- H.set_species(/datum/species/zombie)
-
- for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_list)
- Ian.place_on_head(new /obj/item/bedsheet(Ian))
- for(var/mob/living/simple_animal/parrot/Poly/Poly in GLOB.mob_list)
- new /mob/living/simple_animal/parrot/Poly/ghost(Poly.loc)
- qdel(Poly)
-
-/datum/round_event/spooky/announce()
- priority_announce(pick("RATTLE ME BONES!","THE RIDE NEVER ENDS!", "A SKELETON POPS OUT!", "SPOOKY SCARY SKELETONS!", "CREWMEMBERS BEWARE, YOU'RE IN FOR A SCARE!") , "THE CALL IS COMING FROM INSIDE THE HOUSE")
-
-//Eyeball migration
-/datum/round_event_control/carp_migration/eyeballs
- name = "Eyeball Migration"
- typepath = /datum/round_event/carp_migration/eyeballs
- holidayID = HALLOWEEN
- weight = 25
- earliest_start = 0
-
-/datum/round_event/carp_migration/eyeballs/start()
- for(var/obj/effect/landmark/C in GLOB.landmarks_list)
- if(C.name == "carpspawn")
- new /mob/living/simple_animal/hostile/carp/eyeball(C.loc)
-
-//Pumpking meteors waves
-/datum/round_event_control/meteor_wave/spooky
- name = "Pumpkin Wave"
- typepath = /datum/round_event/meteor_wave/spooky
- holidayID = HALLOWEEN
- weight = 20
- max_occurrences = 2
-
-/datum/round_event/meteor_wave/spooky
- endWhen = 40
-
-/datum/round_event/meteor_wave/spooky/tick()
- if(IsMultiple(activeFor, 4))
- spawn_meteors(3, GLOB.meteorsSPOOKY) //meteor list types defined in gamemode/meteor/meteors.dm
-
-//Creepy clown invasion
-/datum/round_event_control/creepy_clowns
- name = "Clowns"
- typepath = /datum/round_event/creepy_clowns
- holidayID = HALLOWEEN
- weight = 20
- earliest_start = 0
-
-/datum/round_event/creepy_clowns
- endWhen = 40
-
-/datum/round_event/creepy_clowns/start()
- for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
- if(!H.client || !istype(H))
- return
- to_chat(H, "Honk...")
+/datum/round_event_control/spooky
+ name = "2 SPOOKY! (Halloween)"
+ holidayID = HALLOWEEN
+ typepath = /datum/round_event/spooky
+ weight = -1 //forces it to be called, regardless of weight
+ max_occurrences = 1
+ earliest_start = 0
+
+/datum/round_event/spooky/start()
+ ..()
+ for(var/mob/living/carbon/human/H in GLOB.mob_list)
+ var/obj/item/storage/backpack/b = locate() in H.contents
+ new /obj/item/storage/spooky(b)
+ if(ishuman(H) || islizard(H))
+ if(prob(50))
+ H.set_species(/datum/species/skeleton)
+ else
+ H.set_species(/datum/species/zombie)
+
+ for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_list)
+ Ian.place_on_head(new /obj/item/bedsheet(Ian))
+ for(var/mob/living/simple_animal/parrot/Poly/Poly in GLOB.mob_list)
+ new /mob/living/simple_animal/parrot/Poly/ghost(Poly.loc)
+ qdel(Poly)
+
+/datum/round_event/spooky/announce()
+ priority_announce(pick("RATTLE ME BONES!","THE RIDE NEVER ENDS!", "A SKELETON POPS OUT!", "SPOOKY SCARY SKELETONS!", "CREWMEMBERS BEWARE, YOU'RE IN FOR A SCARE!") , "THE CALL IS COMING FROM INSIDE THE HOUSE")
+
+//Eyeball migration
+/datum/round_event_control/carp_migration/eyeballs
+ name = "Eyeball Migration"
+ typepath = /datum/round_event/carp_migration/eyeballs
+ holidayID = HALLOWEEN
+ weight = 25
+ earliest_start = 0
+
+/datum/round_event/carp_migration/eyeballs/start()
+ for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list)
+ new /mob/living/simple_animal/hostile/carp/eyeball(C.loc)
+
+//Pumpking meteors waves
+/datum/round_event_control/meteor_wave/spooky
+ name = "Pumpkin Wave"
+ typepath = /datum/round_event/meteor_wave/spooky
+ holidayID = HALLOWEEN
+ weight = 20
+ max_occurrences = 2
+
+/datum/round_event/meteor_wave/spooky
+ endWhen = 40
+
+/datum/round_event/meteor_wave/spooky/tick()
+ if(IsMultiple(activeFor, 4))
+ spawn_meteors(3, GLOB.meteorsSPOOKY) //meteor list types defined in gamemode/meteor/meteors.dm
+
+//Creepy clown invasion
+/datum/round_event_control/creepy_clowns
+ name = "Clowns"
+ typepath = /datum/round_event/creepy_clowns
+ holidayID = HALLOWEEN
+ weight = 20
+ earliest_start = 0
+
+/datum/round_event/creepy_clowns
+ endWhen = 40
+
+/datum/round_event/creepy_clowns/start()
+ for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
+ if(!H.client || !istype(H))
+ return
+ to_chat(H, "Honk...")
SEND_SOUND(H, sound('sound/spookoween/scary_clown_appear.ogg'))
- var/turf/T = get_turf(H)
- if(T)
- new /obj/effect/hallucination/simple/clown(T, H, 50)
-
-/datum/round_event/creepy_clowns/tick()
- if(IsMultiple(activeFor, 4))
- for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
- if (prob(66))
- playsound(H.loc, pick('sound/spookoween/scary_horn.ogg','sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 100, 1)
- if (prob(33))
- var/turf/T = get_turf(H)
- if(T)
- new /obj/effect/hallucination/simple/clown(T, H, 25)
- else if (prob(25))
- var/turf/T = get_turf(H)
- if(T)
- new /obj/effect/hallucination/simple/clown/scary(T, H, 25)
- else if (prob(5))
- var/turf/T = get_turf(H)
- if(T)
- spawn_atom_to_turf(/obj/effect/mob_spawn/human/clown/corpse, H, 1)
- else if (prob(1))
- spawn_atom_to_turf(/mob/living/simple_animal/hostile/retaliate/clown, H, 1)
-
-/datum/round_event/creepy_clowns/announce()
- priority_announce("Honk... Honk... honk... HONK! HONK! HONKHONKHONKHONKHONK", "HONK!", 'sound/spookoween/scary_horn.ogg')
-
-//spooky foods (you can't actually make these when it's not halloween)
-/obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull
- name = "skull cookie"
- desc = "Spooky! It's got delicious calcium flavouring!"
- icon = 'icons/obj/halloween_items.dmi'
- icon_state = "skeletoncookie"
-
-/obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin
- name = "coffin cookie"
- desc = "Spooky! It's got delicious coffee flavouring!"
- icon = 'icons/obj/halloween_items.dmi'
- icon_state = "coffincookie"
-
-
-//spooky items
-
-/obj/item/storage/spooky
- name = "trick-o-treat bag"
- desc = "A pumpkin-shaped bag that holds all sorts of goodies!"
- icon = 'icons/obj/halloween_items.dmi'
- icon_state = "treatbag"
-
-/obj/item/storage/spooky/New()
- ..()
- for(var/distrobuteinbag=0 to 5)
- var/type = pick(/obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull,
- /obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin,
- /obj/item/reagent_containers/food/snacks/candy_corn,
- /obj/item/reagent_containers/food/snacks/candy,
- /obj/item/reagent_containers/food/snacks/candiedapple,
- /obj/item/reagent_containers/food/snacks/chocolatebar,
- /obj/item/organ/brain ) // OH GOD THIS ISN'T CANDY!
- new type(src)
-
-/obj/item/card/emag/halloween
- name = "hack-o'-lantern"
- desc = "It's a pumpkin with a cryptographic sequencer sticking out."
- icon_state = "hack_o_lantern"
+ var/turf/T = get_turf(H)
+ if(T)
+ new /obj/effect/hallucination/simple/clown(T, H, 50)
+
+/datum/round_event/creepy_clowns/tick()
+ if(IsMultiple(activeFor, 4))
+ for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
+ if (prob(66))
+ playsound(H.loc, pick('sound/spookoween/scary_horn.ogg','sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 100, 1)
+ if (prob(33))
+ var/turf/T = get_turf(H)
+ if(T)
+ new /obj/effect/hallucination/simple/clown(T, H, 25)
+ else if (prob(25))
+ var/turf/T = get_turf(H)
+ if(T)
+ new /obj/effect/hallucination/simple/clown/scary(T, H, 25)
+ else if (prob(5))
+ var/turf/T = get_turf(H)
+ if(T)
+ spawn_atom_to_turf(/obj/effect/mob_spawn/human/clown/corpse, H, 1)
+ else if (prob(1))
+ spawn_atom_to_turf(/mob/living/simple_animal/hostile/retaliate/clown, H, 1)
+
+/datum/round_event/creepy_clowns/announce()
+ priority_announce("Honk... Honk... honk... HONK! HONK! HONKHONKHONKHONKHONK", "HONK!", 'sound/spookoween/scary_horn.ogg')
+
+//spooky foods (you can't actually make these when it's not halloween)
+/obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull
+ name = "skull cookie"
+ desc = "Spooky! It's got delicious calcium flavouring!"
+ icon = 'icons/obj/halloween_items.dmi'
+ icon_state = "skeletoncookie"
+
+/obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin
+ name = "coffin cookie"
+ desc = "Spooky! It's got delicious coffee flavouring!"
+ icon = 'icons/obj/halloween_items.dmi'
+ icon_state = "coffincookie"
+
+
+//spooky items
+
+/obj/item/storage/spooky
+ name = "trick-o-treat bag"
+ desc = "A pumpkin-shaped bag that holds all sorts of goodies!"
+ icon = 'icons/obj/halloween_items.dmi'
+ icon_state = "treatbag"
+
+/obj/item/storage/spooky/New()
+ ..()
+ for(var/distrobuteinbag=0 to 5)
+ var/type = pick(/obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull,
+ /obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin,
+ /obj/item/reagent_containers/food/snacks/candy_corn,
+ /obj/item/reagent_containers/food/snacks/candy,
+ /obj/item/reagent_containers/food/snacks/candiedapple,
+ /obj/item/reagent_containers/food/snacks/chocolatebar,
+ /obj/item/organ/brain ) // OH GOD THIS ISN'T CANDY!
+ new type(src)
+
+/obj/item/card/emag/halloween
+ name = "hack-o'-lantern"
+ desc = "It's a pumpkin with a cryptographic sequencer sticking out."
+ icon_state = "hack_o_lantern"
diff --git a/code/modules/events/operative.dm b/code/modules/events/operative.dm
index 4db2029ce7..0841a2fdbb 100644
--- a/code/modules/events/operative.dm
+++ b/code/modules/events/operative.dm
@@ -16,9 +16,8 @@
var/mob/dead/selected = pick_n_take(candidates)
var/list/spawn_locs = list()
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
- if(L.name in list("ninjaspawn","carpspawn"))
- spawn_locs += L.loc
+ for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
+ spawn_locs += L.loc
if(!spawn_locs.len)
return MAP_ERROR
diff --git a/code/modules/events/wizard/magicarp.dm b/code/modules/events/wizard/magicarp.dm
index cc632d9c87..5cebc55cbd 100644
--- a/code/modules/events/wizard/magicarp.dm
+++ b/code/modules/events/wizard/magicarp.dm
@@ -16,12 +16,11 @@
priority_announce("Unknown magical entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
/datum/round_event/wizard/magicarp/start()
- for(var/obj/effect/landmark/C in GLOB.landmarks_list)
- if(C.name == "carpspawn")
- if(prob(5))
- new /mob/living/simple_animal/hostile/carp/ranged/chaos(C.loc)
- else
- new /mob/living/simple_animal/hostile/carp/ranged(C.loc)
+ for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list)
+ if(prob(5))
+ new /mob/living/simple_animal/hostile/carp/ranged/chaos(C.loc)
+ else
+ new /mob/living/simple_animal/hostile/carp/ranged(C.loc)
/mob/living/simple_animal/hostile/carp/ranged
name = "magicarp"
diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm
index 6404307d34..74169df074 100644
--- a/code/modules/events/wormholes.dm
+++ b/code/modules/events/wormholes.dm
@@ -26,7 +26,7 @@
for(var/i = 1, i <= number_of_wormholes, i++)
var/turf/T = pick(pick_turfs)
- wormholes += new /obj/effect/portal/wormhole(T, null, 300, null, FALSE)
+ wormholes += new /obj/effect/portal/wormhole(T, null, 0, null, FALSE)
/datum/round_event/wormholes/announce()
priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", 'sound/ai/spanomalies.ogg')
@@ -40,6 +40,7 @@
/datum/round_event/wormholes/end()
QDEL_LIST(wormholes)
+ wormholes = null
/obj/effect/portal/wormhole
name = "wormhole"
@@ -48,17 +49,11 @@
icon_state = "anom"
mech_sized = TRUE
-/obj/effect/portal/wormhole/attack_hand(mob/user)
- teleport(user)
-
-/obj/effect/portal/wormhole/attackby(obj/item/I, mob/user, params)
- teleport(user)
-
/obj/effect/portal/wormhole/teleport(atom/movable/M)
if(istype(M, /obj/effect)) //sparks don't teleport
return
if(M.anchored)
- if(!(istype(M, /obj/mecha) && mech_sized))
+ if(!(ismecha(M) && mech_sized))
return
if(ismovableatom(M))
diff --git a/code/modules/food_and_drinks/food/snacks_meat.dm b/code/modules/food_and_drinks/food/snacks_meat.dm
index 7c8db01bcc..11426a4e04 100644
--- a/code/modules/food_and_drinks/food/snacks_meat.dm
+++ b/code/modules/food_and_drinks/food/snacks_meat.dm
@@ -185,7 +185,9 @@
/obj/item/reagent_containers/food/snacks/monkeycube/proc/Expand()
visible_message("[src] expands!")
- new /mob/living/carbon/monkey(get_turf(src))
+ var/mob/spammer = get_mob_by_key(src.fingerprintslast)
+ var/mob/living/carbon/monkey/bananas = new(get_turf(src))
+ bananas.log_message("Spawned via [src] at [COORD(src)], Last attached mob: [key_name(spammer)].", INDIVIDUAL_ATTACK_LOG)
qdel(src)
/obj/item/reagent_containers/food/snacks/enchiladas
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index 5f5752deec..d5cac19f32 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -17,9 +17,9 @@
resistance_flags = FLAMMABLE
origin_tech = "biotech=1"
-/obj/item/reagent_containers/food/snacks/grown/New(newloc, var/obj/item/seeds/new_seed = null)
- tastes = list(name = 1) // apples taste of apple, silly.
- ..()
+/obj/item/reagent_containers/food/snacks/grown/Initialize(mapload, obj/item/seeds/new_seed)
+ . = ..()
+ tastes = list("[name]" = 1) // apples taste of apple, silly.
if(new_seed)
seed = new_seed.Copy()
else if(ispath(seed))
@@ -35,7 +35,7 @@
if(seed)
for(var/datum/plant_gene/trait/T in seed.genes)
- T.on_new(src, newloc)
+ T.on_new(src, loc)
seed.prepare_result(src)
transform *= TransformUsingVariable(seed.potency, 100, 0.5) //Makes the resulting produce's sprite larger or smaller based on potency!
add_juice()
diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm
index 6058088f75..a77808f006 100644
--- a/code/modules/hydroponics/growninedible.dm
+++ b/code/modules/hydroponics/growninedible.dm
@@ -1,64 +1,64 @@
-// **********************
-// Other harvested materials from plants (that are not food)
-// **********************
-
-/obj/item/grown // Grown weapons
- name = "grown_weapon"
- icon = 'icons/obj/hydroponics/harvest.dmi'
- resistance_flags = FLAMMABLE
- var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item.
-
-/obj/item/grown/New(newloc, var/obj/item/seeds/new_seed = null)
- ..()
- create_reagents(50)
-
- if(new_seed)
- seed = new_seed.Copy()
- else if(ispath(seed))
- // This is for adminspawn or map-placed growns. They get the default stats of their seed type.
- seed = new seed()
- seed.adjust_potency(50-seed.potency)
-
- pixel_x = rand(-5, 5)
- pixel_y = rand(-5, 5)
-
- if(seed)
- for(var/datum/plant_gene/trait/T in seed.genes)
- T.on_new(src, newloc)
-
- if(istype(src, seed.product)) // no adding reagents if it is just a trash item
- seed.prepare_result(src)
- transform *= TransformUsingVariable(seed.potency, 100, 0.5)
- add_juice()
-
-
-/obj/item/grown/attackby(obj/item/O, mob/user, params)
- ..()
- if (istype(O, /obj/item/device/plant_analyzer))
- var/msg = "*---------*\n This is \a [src]\n"
- if(seed)
- msg += seed.get_analyzer_text()
- msg += ""
- to_chat(usr, msg)
- return
-
-/obj/item/grown/proc/add_juice()
- if(reagents)
- return 1
- return 0
-
-
-/obj/item/grown/Crossed(atom/movable/AM)
- if(seed)
- for(var/datum/plant_gene/trait/T in seed.genes)
- T.on_cross(src, AM)
- ..()
-
-/obj/item/grown/throw_impact(atom/hit_atom)
- if(!..()) //was it caught by a mob?
- if(seed)
- for(var/datum/plant_gene/trait/T in seed.genes)
- T.on_throw_impact(src, hit_atom)
-
-/obj/item/grown/microwave_act(obj/machine/microwave/M)
- return
+// **********************
+// Other harvested materials from plants (that are not food)
+// **********************
+
+/obj/item/grown // Grown weapons
+ name = "grown_weapon"
+ icon = 'icons/obj/hydroponics/harvest.dmi'
+ resistance_flags = FLAMMABLE
+ var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item.
+
+/obj/item/grown/Initialize(newloc, obj/item/seeds/new_seed)
+ . = ..()
+ create_reagents(50)
+
+ if(new_seed)
+ seed = new_seed.Copy()
+ else if(ispath(seed))
+ // This is for adminspawn or map-placed growns. They get the default stats of their seed type.
+ seed = new seed()
+ seed.adjust_potency(50-seed.potency)
+
+ pixel_x = rand(-5, 5)
+ pixel_y = rand(-5, 5)
+
+ if(seed)
+ for(var/datum/plant_gene/trait/T in seed.genes)
+ T.on_new(src, newloc)
+
+ if(istype(src, seed.product)) // no adding reagents if it is just a trash item
+ seed.prepare_result(src)
+ transform *= TransformUsingVariable(seed.potency, 100, 0.5)
+ add_juice()
+
+
+/obj/item/grown/attackby(obj/item/O, mob/user, params)
+ ..()
+ if (istype(O, /obj/item/device/plant_analyzer))
+ var/msg = "*---------*\n This is \a [src]\n"
+ if(seed)
+ msg += seed.get_analyzer_text()
+ msg += ""
+ to_chat(usr, msg)
+ return
+
+/obj/item/grown/proc/add_juice()
+ if(reagents)
+ return 1
+ return 0
+
+
+/obj/item/grown/Crossed(atom/movable/AM)
+ if(seed)
+ for(var/datum/plant_gene/trait/T in seed.genes)
+ T.on_cross(src, AM)
+ ..()
+
+/obj/item/grown/throw_impact(atom/hit_atom)
+ if(!..()) //was it caught by a mob?
+ if(seed)
+ for(var/datum/plant_gene/trait/T in seed.genes)
+ T.on_throw_impact(src, hit_atom)
+
+/obj/item/grown/microwave_act(obj/machine/microwave/M)
+ return
diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm
index 17d626b3a0..ae5f5c2fbb 100644
--- a/code/modules/library/lib_items.dm
+++ b/code/modules/library/lib_items.dm
@@ -1,320 +1,323 @@
-/* Library Items
- *
- * Contains:
- * Bookcase
- * Book
- * Barcode Scanner
- */
-
-/*
- * Bookcase
- */
-
-/obj/structure/bookcase
- name = "bookcase"
- icon = 'icons/obj/library.dmi'
- icon_state = "bookempty"
- anchored = FALSE
- density = TRUE
- opacity = 0
- resistance_flags = FLAMMABLE
- max_integrity = 200
- armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0)
- var/state = 0
- var/list/allowed_books = list(/obj/item/book, /obj/item/spellbook, /obj/item/storage/book) //Things allowed in the bookcase
-
-
-/obj/structure/bookcase/Initialize(mapload)
- . = ..()
- if(!mapload)
- return
- state = 2
- icon_state = "book-0"
- anchored = TRUE
- for(var/obj/item/I in loc)
- if(istype(I, /obj/item/book))
- I.loc = src
- update_icon()
-
-
-/obj/structure/bookcase/attackby(obj/item/I, mob/user, params)
- switch(state)
- if(0)
- if(istype(I, /obj/item/wrench))
- playsound(loc, I.usesound, 100, 1)
- if(do_after(user, 20*I.toolspeed, target = src))
- to_chat(user, "You wrench the frame into place.")
- anchored = TRUE
- state = 1
- if(istype(I, /obj/item/crowbar))
- playsound(loc, I.usesound, 100, 1)
- if(do_after(user, 20*I.toolspeed, target = src))
- to_chat(user, "You pry the frame apart.")
- deconstruct(TRUE)
-
- if(1)
- if(istype(I, /obj/item/stack/sheet/mineral/wood))
- var/obj/item/stack/sheet/mineral/wood/W = I
- if(W.get_amount() >= 2)
- W.use(2)
- to_chat(user, "You add a shelf.")
- state = 2
- icon_state = "book-0"
- if(istype(I, /obj/item/wrench))
- playsound(loc, I.usesound, 100, 1)
- to_chat(user, "You unwrench the frame.")
- anchored = FALSE
- state = 0
-
- if(2)
- if(is_type_in_list(I, allowed_books))
- if(!user.drop_item())
- return
- I.loc = src
- update_icon()
- else if(istype(I, /obj/item/storage/bag/books))
- var/obj/item/storage/bag/books/B = I
- for(var/obj/item/T in B.contents)
- if(istype(T, /obj/item/book) || istype(T, /obj/item/spellbook))
- B.remove_from_storage(T, src)
- to_chat(user, "You empty \the [I] into \the [src].")
- update_icon()
- else if(istype(I, /obj/item/pen))
- var/newname = stripped_input(user, "What would you like to title this bookshelf?")
- if(!newname)
- return
- else
- name = ("bookcase ([sanitize(newname)])")
- else if(istype(I, /obj/item/crowbar))
- if(contents.len)
- to_chat(user, "You need to remove the books first!")
- else
- playsound(loc, I.usesound, 100, 1)
- to_chat(user, "You pry the shelf out.")
- new /obj/item/stack/sheet/mineral/wood(loc, 2)
- state = 1
- icon_state = "bookempty"
- else
- return ..()
-
-
-/obj/structure/bookcase/attack_hand(mob/user)
- if(contents.len)
- var/obj/item/book/choice = input("Which book would you like to remove from the shelf?") as null|obj in contents
- if(choice)
- if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
- return
- if(ishuman(user))
- if(!user.get_active_held_item())
- user.put_in_hands(choice)
- else
- choice.loc = get_turf(src)
- update_icon()
-
-
-/obj/structure/bookcase/deconstruct(disassembled = TRUE)
- new /obj/item/stack/sheet/mineral/wood(loc, 4)
- for(var/obj/item/book/B in contents)
- B.forceMove(get_turf(src))
- qdel(src)
-
-
-/obj/structure/bookcase/update_icon()
- if(contents.len < 5)
- icon_state = "book-[contents.len]"
- else
- icon_state = "book-5"
-
-
-/obj/structure/bookcase/manuals/medical
- name = "medical manuals bookcase"
-
-/obj/structure/bookcase/manuals/medical/New()
- ..()
- new /obj/item/book/manual/medical_cloning(src)
- update_icon()
-
-
-/obj/structure/bookcase/manuals/engineering
- name = "engineering manuals bookcase"
-
-/obj/structure/bookcase/manuals/engineering/New()
- ..()
- new /obj/item/book/manual/wiki/engineering_construction(src)
- new /obj/item/book/manual/engineering_particle_accelerator(src)
- new /obj/item/book/manual/wiki/engineering_hacking(src)
- new /obj/item/book/manual/wiki/engineering_guide(src)
- new /obj/item/book/manual/engineering_singularity_safety(src)
- new /obj/item/book/manual/robotics_cyborgs(src)
- update_icon()
-
-
-/obj/structure/bookcase/manuals/research_and_development
- name = "\improper R&D manuals bookcase"
-
-/obj/structure/bookcase/manuals/research_and_development/New()
- ..()
- new /obj/item/book/manual/research_and_development(src)
- update_icon()
-
-
-/*
- * Book
- */
-/obj/item/book
- name = "book"
- icon = 'icons/obj/library.dmi'
- icon_state ="book"
- throw_speed = 1
- throw_range = 5
- w_class = WEIGHT_CLASS_NORMAL //upped to three because books are, y'know, pretty big. (and you could hide them inside eachother recursively forever)
- attack_verb = list("bashed", "whacked", "educated")
- resistance_flags = FLAMMABLE
- var/dat //Actual page content
- var/due_date = 0 //Game time in 1/10th seconds
- var/author //Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
- var/unique = 0 //0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified
- var/title //The real name of the book.
- var/window_size = null // Specific window size for the book, i.e: "1920x1080", Size x Width
-
-/obj/item/book/attack_self(mob/user)
- if(is_blind(user))
- to_chat(user, "As you are trying to read, you suddenly feel very stupid!")
- return
- if(ismonkey(user))
- to_chat(user, "You skim through the book but can't comprehend any of it.")
- return
- if(dat)
- user << browse("Penned by [author].
" + "[dat]", "window=book[window_size != null ? ";size=[window_size]" : ""]")
- user.visible_message("[user] opens a book titled \"[title]\" and begins reading intently.")
- onclose(user, "book")
- else
- to_chat(user, "This book is completely blank!")
-
-
-/obj/item/book/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/pen))
- if(is_blind(user))
- to_chat(user, " As you are trying to write on the book, you suddenly feel very stupid!")
- return
- if(unique)
- to_chat(user, "These pages don't seem to take the ink well! Looks like you can't modify it.")
- return
- var/choice = input("What would you like to change?") in list("Title", "Contents", "Author", "Cancel")
- switch(choice)
- if("Title")
- var/newtitle = reject_bad_text(stripped_input(usr, "Write a new title:"))
- if (length(newtitle) > 20)
- to_chat(usr, "That title won't fit on the cover!")
- return
- if(!newtitle)
- to_chat(usr, "That title is invalid.")
- return
- else
- name = newtitle
- title = newtitle
- if("Contents")
- var/content = stripped_input(usr, "Write your book's contents (HTML NOT allowed):","","",8192)
- if(!content)
- to_chat(usr, "The content is invalid.")
- return
- else
- dat += content
- if("Author")
- var/newauthor = stripped_input(usr, "Write the author's name:")
- if(!newauthor)
- to_chat(usr, "The name is invalid.")
- return
- else
- author = newauthor
- else
- return
-
- else if(istype(I, /obj/item/barcodescanner))
- var/obj/item/barcodescanner/scanner = I
- if(!scanner.computer)
- to_chat(user, "[I]'s screen flashes: 'No associated computer found!'")
- else
- switch(scanner.mode)
- if(0)
- scanner.book = src
- to_chat(user, "[I]'s screen flashes: 'Book stored in buffer.'")
- if(1)
- scanner.book = src
- scanner.computer.buffer_book = name
- to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Book title stored in associated computer buffer.'")
- if(2)
- scanner.book = src
- for(var/datum/borrowbook/b in scanner.computer.checkouts)
- if(b.bookname == name)
- scanner.computer.checkouts.Remove(b)
- to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Book has been checked in.'")
- return
- to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. No active check-out record found for current title.'")
- if(3)
- scanner.book = src
- for(var/obj/item/book in scanner.computer.inventory)
- if(book == src)
- to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Title already present in inventory, aborting to avoid duplicate entry.'")
- return
- scanner.computer.inventory.Add(src)
- to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Title added to general inventory.'")
-
- else if(istype(I, /obj/item/kitchen/knife) || istype(I, /obj/item/wirecutters))
- to_chat(user, "You begin to carve out [title]...")
- if(do_after(user, 30, target = src))
- to_chat(user, "You carve out the pages from [title]! You didn't want to read it anyway.")
- var/obj/item/storage/book/B = new
- B.name = src.name
- B.title = src.title
- B.icon_state = src.icon_state
- if(user.is_holding(src))
- qdel(src)
- user.put_in_hands(B)
- return
- else
- B.loc = src.loc
- qdel(src)
- return
- return
- else
- ..()
-
-
-/*
- * Barcode Scanner
- */
-/obj/item/barcodescanner
- name = "barcode scanner"
- icon = 'icons/obj/library.dmi'
- icon_state ="scanner"
- throw_speed = 3
- throw_range = 5
- w_class = WEIGHT_CLASS_TINY
- var/obj/machinery/computer/libraryconsole/bookmanagement/computer //Associated computer - Modes 1 to 3 use this
- var/obj/item/book/book //Currently scanned book
- var/mode = 0 //0 - Scan only, 1 - Scan and Set Buffer, 2 - Scan and Attempt to Check In, 3 - Scan and Attempt to Add to Inventory
-
-/obj/item/barcodescanner/attack_self(mob/user)
- mode += 1
- if(mode > 3)
- mode = 0
- to_chat(user, "[src] Status Display:")
- var/modedesc
- switch(mode)
- if(0)
- modedesc = "Scan book to local buffer."
- if(1)
- modedesc = "Scan book to local buffer and set associated computer buffer to match."
- if(2)
- modedesc = "Scan book to local buffer, attempt to check in scanned book."
- if(3)
- modedesc = "Scan book to local buffer, attempt to add book to general inventory."
- else
- modedesc = "ERROR"
- to_chat(user, " - Mode [mode] : [modedesc]")
- if(computer)
- to_chat(user, "Computer has been associated with this unit.")
- else
- to_chat(user, "No associated computer found. Only local scans will function properly.")
- to_chat(user, "\n")
\ No newline at end of file
+/* Library Items
+ *
+ * Contains:
+ * Bookcase
+ * Book
+ * Barcode Scanner
+ */
+
+/*
+ * Bookcase
+ */
+
+/obj/structure/bookcase
+ name = "bookcase"
+ icon = 'icons/obj/library.dmi'
+ icon_state = "bookempty"
+ desc = "A great place for storing knowledge."
+ anchored = FALSE
+ density = TRUE
+ opacity = 0
+ resistance_flags = FLAMMABLE
+ max_integrity = 200
+ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0)
+ var/state = 0
+ var/list/allowed_books = list(/obj/item/book, /obj/item/spellbook, /obj/item/storage/book) //Things allowed in the bookcase
+
+
+/obj/structure/bookcase/Initialize(mapload)
+ . = ..()
+ if(!mapload)
+ return
+ state = 2
+ icon_state = "book-0"
+ anchored = TRUE
+ for(var/obj/item/I in loc)
+ if(istype(I, /obj/item/book))
+ I.loc = src
+ update_icon()
+
+
+/obj/structure/bookcase/attackby(obj/item/I, mob/user, params)
+ switch(state)
+ if(0)
+ if(istype(I, /obj/item/wrench))
+ playsound(loc, I.usesound, 100, 1)
+ if(do_after(user, 20*I.toolspeed, target = src))
+ to_chat(user, "You wrench the frame into place.")
+ anchored = TRUE
+ state = 1
+ if(istype(I, /obj/item/crowbar))
+ playsound(loc, I.usesound, 100, 1)
+ if(do_after(user, 20*I.toolspeed, target = src))
+ to_chat(user, "You pry the frame apart.")
+ deconstruct(TRUE)
+
+ if(1)
+ if(istype(I, /obj/item/stack/sheet/mineral/wood))
+ var/obj/item/stack/sheet/mineral/wood/W = I
+ if(W.get_amount() >= 2)
+ W.use(2)
+ to_chat(user, "You add a shelf.")
+ state = 2
+ icon_state = "book-0"
+ if(istype(I, /obj/item/wrench))
+ playsound(loc, I.usesound, 100, 1)
+ to_chat(user, "You unwrench the frame.")
+ anchored = FALSE
+ state = 0
+
+ if(2)
+ if(is_type_in_list(I, allowed_books))
+ if(!user.drop_item())
+ return
+ I.loc = src
+ update_icon()
+ else if(istype(I, /obj/item/storage/bag/books))
+ var/obj/item/storage/bag/books/B = I
+ for(var/obj/item/T in B.contents)
+ if(istype(T, /obj/item/book) || istype(T, /obj/item/spellbook))
+ B.remove_from_storage(T, src)
+ to_chat(user, "You empty \the [I] into \the [src].")
+ update_icon()
+ else if(istype(I, /obj/item/pen))
+ var/newname = stripped_input(user, "What would you like to title this bookshelf?")
+ if(!newname)
+ return
+ else
+ name = ("bookcase ([sanitize(newname)])")
+ else if(istype(I, /obj/item/crowbar))
+ if(contents.len)
+ to_chat(user, "You need to remove the books first!")
+ else
+ playsound(loc, I.usesound, 100, 1)
+ to_chat(user, "You pry the shelf out.")
+ new /obj/item/stack/sheet/mineral/wood(loc, 2)
+ state = 1
+ icon_state = "bookempty"
+ else
+ return ..()
+
+
+/obj/structure/bookcase/attack_hand(mob/user)
+ if(contents.len)
+ var/obj/item/book/choice = input("Which book would you like to remove from the shelf?") as null|obj in contents
+ if(choice)
+ if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
+ return
+ if(ishuman(user))
+ if(!user.get_active_held_item())
+ user.put_in_hands(choice)
+ else
+ choice.loc = get_turf(src)
+ update_icon()
+
+
+/obj/structure/bookcase/deconstruct(disassembled = TRUE)
+ new /obj/item/stack/sheet/mineral/wood(loc, 4)
+ for(var/obj/item/book/B in contents)
+ B.forceMove(get_turf(src))
+ qdel(src)
+
+
+/obj/structure/bookcase/update_icon()
+ if(contents.len < 5)
+ icon_state = "book-[contents.len]"
+ else
+ icon_state = "book-5"
+
+
+/obj/structure/bookcase/manuals/medical
+ name = "medical manuals bookcase"
+
+/obj/structure/bookcase/manuals/medical/New()
+ ..()
+ new /obj/item/book/manual/medical_cloning(src)
+ update_icon()
+
+
+/obj/structure/bookcase/manuals/engineering
+ name = "engineering manuals bookcase"
+
+/obj/structure/bookcase/manuals/engineering/New()
+ ..()
+ new /obj/item/book/manual/wiki/engineering_construction(src)
+ new /obj/item/book/manual/engineering_particle_accelerator(src)
+ new /obj/item/book/manual/wiki/engineering_hacking(src)
+ new /obj/item/book/manual/wiki/engineering_guide(src)
+ new /obj/item/book/manual/engineering_singularity_safety(src)
+ new /obj/item/book/manual/robotics_cyborgs(src)
+ update_icon()
+
+
+/obj/structure/bookcase/manuals/research_and_development
+ name = "\improper R&D manuals bookcase"
+
+/obj/structure/bookcase/manuals/research_and_development/New()
+ ..()
+ new /obj/item/book/manual/research_and_development(src)
+ update_icon()
+
+
+/*
+ * Book
+ */
+/obj/item/book
+ name = "book"
+ icon = 'icons/obj/library.dmi'
+ icon_state ="book"
+ desc = "Crack it open, inhale the musk of its pages, and learn something new."
+ throw_speed = 1
+ throw_range = 5
+ w_class = WEIGHT_CLASS_NORMAL //upped to three because books are, y'know, pretty big. (and you could hide them inside eachother recursively forever)
+ attack_verb = list("bashed", "whacked", "educated")
+ resistance_flags = FLAMMABLE
+ var/dat //Actual page content
+ var/due_date = 0 //Game time in 1/10th seconds
+ var/author //Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
+ var/unique = 0 //0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified
+ var/title //The real name of the book.
+ var/window_size = null // Specific window size for the book, i.e: "1920x1080", Size x Width
+
+/obj/item/book/attack_self(mob/user)
+ if(is_blind(user))
+ to_chat(user, "As you are trying to read, you suddenly feel very stupid!")
+ return
+ if(ismonkey(user))
+ to_chat(user, "You skim through the book but can't comprehend any of it.")
+ return
+ if(dat)
+ user << browse("Penned by [author].
" + "[dat]", "window=book[window_size != null ? ";size=[window_size]" : ""]")
+ user.visible_message("[user] opens a book titled \"[title]\" and begins reading intently.")
+ onclose(user, "book")
+ else
+ to_chat(user, "This book is completely blank!")
+
+
+/obj/item/book/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/pen))
+ if(is_blind(user))
+ to_chat(user, " As you are trying to write on the book, you suddenly feel very stupid!")
+ return
+ if(unique)
+ to_chat(user, "These pages don't seem to take the ink well! Looks like you can't modify it.")
+ return
+ var/choice = input("What would you like to change?") in list("Title", "Contents", "Author", "Cancel")
+ switch(choice)
+ if("Title")
+ var/newtitle = reject_bad_text(stripped_input(usr, "Write a new title:"))
+ if (length(newtitle) > 20)
+ to_chat(usr, "That title won't fit on the cover!")
+ return
+ if(!newtitle)
+ to_chat(usr, "That title is invalid.")
+ return
+ else
+ name = newtitle
+ title = newtitle
+ if("Contents")
+ var/content = stripped_input(usr, "Write your book's contents (HTML NOT allowed):","","",8192)
+ if(!content)
+ to_chat(usr, "The content is invalid.")
+ return
+ else
+ dat += content
+ if("Author")
+ var/newauthor = stripped_input(usr, "Write the author's name:")
+ if(!newauthor)
+ to_chat(usr, "The name is invalid.")
+ return
+ else
+ author = newauthor
+ else
+ return
+
+ else if(istype(I, /obj/item/barcodescanner))
+ var/obj/item/barcodescanner/scanner = I
+ if(!scanner.computer)
+ to_chat(user, "[I]'s screen flashes: 'No associated computer found!'")
+ else
+ switch(scanner.mode)
+ if(0)
+ scanner.book = src
+ to_chat(user, "[I]'s screen flashes: 'Book stored in buffer.'")
+ if(1)
+ scanner.book = src
+ scanner.computer.buffer_book = name
+ to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Book title stored in associated computer buffer.'")
+ if(2)
+ scanner.book = src
+ for(var/datum/borrowbook/b in scanner.computer.checkouts)
+ if(b.bookname == name)
+ scanner.computer.checkouts.Remove(b)
+ to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Book has been checked in.'")
+ return
+ to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. No active check-out record found for current title.'")
+ if(3)
+ scanner.book = src
+ for(var/obj/item/book in scanner.computer.inventory)
+ if(book == src)
+ to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Title already present in inventory, aborting to avoid duplicate entry.'")
+ return
+ scanner.computer.inventory.Add(src)
+ to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Title added to general inventory.'")
+
+ else if(istype(I, /obj/item/kitchen/knife) || istype(I, /obj/item/wirecutters))
+ to_chat(user, "You begin to carve out [title]...")
+ if(do_after(user, 30, target = src))
+ to_chat(user, "You carve out the pages from [title]! You didn't want to read it anyway.")
+ var/obj/item/storage/book/B = new
+ B.name = src.name
+ B.title = src.title
+ B.icon_state = src.icon_state
+ if(user.is_holding(src))
+ qdel(src)
+ user.put_in_hands(B)
+ return
+ else
+ B.loc = src.loc
+ qdel(src)
+ return
+ return
+ else
+ ..()
+
+
+/*
+ * Barcode Scanner
+ */
+/obj/item/barcodescanner
+ name = "barcode scanner"
+ icon = 'icons/obj/library.dmi'
+ icon_state ="scanner"
+ desc = "A fabulous tool if you need to scan a barcode."
+ throw_speed = 3
+ throw_range = 5
+ w_class = WEIGHT_CLASS_TINY
+ var/obj/machinery/computer/libraryconsole/bookmanagement/computer //Associated computer - Modes 1 to 3 use this
+ var/obj/item/book/book //Currently scanned book
+ var/mode = 0 //0 - Scan only, 1 - Scan and Set Buffer, 2 - Scan and Attempt to Check In, 3 - Scan and Attempt to Add to Inventory
+
+/obj/item/barcodescanner/attack_self(mob/user)
+ mode += 1
+ if(mode > 3)
+ mode = 0
+ to_chat(user, "[src] Status Display:")
+ var/modedesc
+ switch(mode)
+ if(0)
+ modedesc = "Scan book to local buffer."
+ if(1)
+ modedesc = "Scan book to local buffer and set associated computer buffer to match."
+ if(2)
+ modedesc = "Scan book to local buffer, attempt to check in scanned book."
+ if(3)
+ modedesc = "Scan book to local buffer, attempt to add book to general inventory."
+ else
+ modedesc = "ERROR"
+ to_chat(user, " - Mode [mode] : [modedesc]")
+ if(computer)
+ to_chat(user, "Computer has been associated with this unit.")
+ else
+ to_chat(user, "No associated computer found. Only local scans will function properly.")
+ to_chat(user, "\n")
diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm
index 99127cd595..dc48bbae2d 100644
--- a/code/modules/library/lib_machines.dm
+++ b/code/modules/library/lib_machines.dm
@@ -20,6 +20,7 @@
icon_screen = "library"
icon_keyboard = null
circuit = /obj/item/circuitboard/computer/libraryconsole
+ desc = "Checked out books MUST be returned on time."
var/screenstate = 0
var/title
var/category = "Any"
@@ -161,6 +162,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
// It's December 25th, 2014, and this is STILL here, and it's STILL relevant. Kill me
/obj/machinery/computer/libraryconsole/bookmanagement
name = "book inventory management console"
+ desc = "Librarian's command station."
var/arcanecheckout = 0
screenstate = 0 // 0 - Main Menu, 1 - Inventory, 2 - Checked Out, 3 - Check Out a Book
verb_say = "beeps"
@@ -498,6 +500,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
name = "scanner control interface"
icon = 'icons/obj/library.dmi'
icon_state = "bigscanner"
+ desc = "It servers the purpose of scanning stuff."
anchored = TRUE
density = TRUE
var/obj/item/book/cache // Last scanned book
@@ -554,6 +557,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
name = "book binder"
icon = 'icons/obj/library.dmi'
icon_state = "binder"
+ desc = "Only intended for binding paper products."
anchored = TRUE
density = TRUE
var/busy = FALSE
diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm
index e0197cc4e3..d72d0e5f73 100644
--- a/code/modules/mining/equipment/wormhole_jaunter.dm
+++ b/code/modules/mining/equipment/wormhole_jaunter.dm
@@ -94,7 +94,7 @@
if(!ismob(M) && !isobj(M)) //No don't teleport lighting and effects!
return
- if(M.anchored && (!ismob(M) || (istype(M, /obj/mecha) && !mech_sized)))
+ if(M.anchored && (!ismob(M) || (ismecha(M) && !mech_sized)))
return
if(do_teleport(M, hard_target, 6))
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 58c971024f..e16077fec1 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -435,7 +435,7 @@
if(!over_object)
return
- if (istype(usr.loc, /obj/mecha))
+ if(ismecha(usr.loc))
return
if(!M.incapacitated())
diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm
index 96589fb575..0c9bcdc170 100644
--- a/code/modules/mining/machine_stacking.dm
+++ b/code/modules/mining/machine_stacking.dm
@@ -4,6 +4,7 @@
name = "stacking machine console"
icon = 'icons/obj/machines/mining_machines.dmi'
icon_state = "console"
+ desc = "Controls a stacking machine... in theory."
density = FALSE
anchored = TRUE
var/obj/machinery/mineral/stacking_machine/machine = null
@@ -60,6 +61,7 @@
name = "stacking machine"
icon = 'icons/obj/machines/mining_machines.dmi'
icon_state = "stacker"
+ desc = "A machine that automatically stacks acquired materials. Controlled by a nearby console."
density = TRUE
anchored = TRUE
var/obj/machinery/mineral/stacking_unit_console/CONSOLE
@@ -90,4 +92,4 @@
var/obj/item/stack/sheet/out = new inp.type()
out.amount = stack_amt
unload_mineral(out)
- storage.amount -= stack_amt
\ No newline at end of file
+ storage.amount -= stack_amt
diff --git a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm
index b684e1ef28..26d05c6ff0 100644
--- a/code/modules/mob/dead/new_player/login.dm
+++ b/code/modules/mob/dead/new_player/login.dm
@@ -21,15 +21,6 @@
sight |= SEE_TURFS
-/*
- var/list/watch_locations = list()
- for(var/obj/effect/landmark/landmark in landmarks_list)
- if(landmark.tag == "landmark*new_player")
- watch_locations += landmark.loc
-
- if(watch_locations.len>0)
- loc = pick(watch_locations)
-*/
new_player_panel()
client.playtitlemusic()
if(SSticker.current_state < GAME_STATE_SETTING_UP)
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index 167f1037c3..6661beff6d 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -115,15 +115,6 @@
//no longer is required
if(SSticker.current_state <= GAME_STATE_PREGAME)
ready = tready
-
- var/this_is_like_playing_right = alert(src,"Are you sure you wish to observe? You will not be able to play this round!","Player Setup","Yes","No")
-
- if(QDELETED(src) || !src.client || this_is_like_playing_right != "Yes")
- ready = PLAYER_NOT_READY
- src << browse(null, "window=playersetup") //closes the player setup window
- new_player_panel()
- return FALSE
-
//if it's post initialisation and they're trying to observe we do the needful
if(!SSticker.current_state < GAME_STATE_PREGAME && tready == PLAYER_READY_TO_OBSERVE)
ready = tready
@@ -268,7 +259,15 @@
if(QDELETED(src) || !src.client)
ready = PLAYER_NOT_READY
return FALSE
-
+
+ var/this_is_like_playing_right = alert(src,"Are you sure you wish to observe? You will not be able to play this round!","Player Setup","Yes","No")
+
+ if(QDELETED(src) || !src.client || this_is_like_playing_right != "Yes")
+ ready = PLAYER_NOT_READY
+ src << browse(null, "window=playersetup") //closes the player setup window
+ new_player_panel()
+ return FALSE
+
var/mob/dead/observer/observer = new()
spawning = TRUE
diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm
index cc98fd827e..831fde141e 100644
--- a/code/modules/mob/dead/new_player/preferences_setup.dm
+++ b/code/modules/mob/dead/new_player/preferences_setup.dm
@@ -59,6 +59,7 @@
if(previewJob && !nude)
mannequin.job = previewJob.title
previewJob.equip(mannequin, TRUE)
+ mannequin.compile_overlays()
CHECK_TICK
preview_icon = icon('icons/effects/effects.dmi', "nothing")
preview_icon.Scale(48+32, 16+32)
diff --git a/code/modules/mob/dead/new_player/sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories.dm
index 03b7fd53ec..1eb1379dce 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories.dm
@@ -67,317 +67,30 @@
/datum/sprite_accessory/hair
icon = 'icons/mob/human_face.dmi' // default icon for all hairs
-//Place in order by major style E.G "Afro, Bun, Ponytail"
-//Place different versions under the same style E.G "Bun > Large Bun, Ponytail > Long Ponytail"
-//A
+/datum/sprite_accessory/hair/short
+ name = "Short Hair" // try to capatilize the names please~ // try to spell
+ icon_state = "hair_a" // you do not need to define _s or _l sub-states, game automatically does this for you
-/datum/sprite_accessory/hair/afro
- name = "Afro" // try to capatilize the names please~ // try to spell
- icon_state = "hair_afro" // you do not need to define _s or _l sub-states, game automatically does this for you
+/datum/sprite_accessory/hair/shorthair2
+ name = "Short Hair 2"
+ icon_state = "hair_shorthair2"
-/datum/sprite_accessory/hair/afro2
- name = "Afro 2"
- icon_state = "hair_afro2"
-
-/datum/sprite_accessory/hair/afro_large
- name = "Big Afro"
- icon_state = "hair_bigafro"
-
-/datum/sprite_accessory/hair/antenna
- name = "Ahoge"
- icon_state = "hair_antenna"
-//B
-
-/datum/sprite_accessory/hair/bald
- name = "Bald"
- icon_state = null
-
-/datum/sprite_accessory/hair/balding
- name = "Balding Hair"
- icon_state = "hair_e"
-
-/datum/sprite_accessory/hair/longbangs
- name = "Long Bangs"
- icon_state = "hair_lbangs"
-
-/datum/sprite_accessory/hair/bedhead
- name = "Bedhead"
- icon_state = "hair_bedhead"
-
-/datum/sprite_accessory/hair/bedhead2
- name = "Bedhead 2"
- icon_state = "hair_bedheadv2"
-
-/datum/sprite_accessory/hair/bedhead3
- name = "Bedhead 3"
- icon_state = "hair_bedheadv3"
-
-/datum/sprite_accessory/hair/beehive
- name = "Beehive"
- icon_state = "hair_beehive"
-
-/datum/sprite_accessory/hair/beehive2
- name = "Beehive 2"
- icon_state = "hair_beehivev2"
-
-/datum/sprite_accessory/hair/bob
- name = "Bob"
- icon_state = "hair_bobcut"
-
-/datum/sprite_accessory/hair/bobcurl
- name = "Bobcurl"
- icon_state = "hair_bobcurl"
-
-/datum/sprite_accessory/hair/bob
- name = "Bob Hair"
- icon_state = "hair_bob"
-
-/datum/sprite_accessory/hair/bob2
- name = "Bob Hair 2"
- icon_state = "hair_bob2"
-
-/datum/sprite_accessory/hair/boddicker
- name = "Boddicker"
- icon_state = "hair_boddicker"
-
-/datum/sprite_accessory/hair/bowl
- name = "Bowl"
- icon_state = "hair_bowlcut"
-
-/datum/sprite_accessory/hair/braided
- name = "Braided"
- icon_state = "hair_braided"
-
-/datum/sprite_accessory/hair/front_braid
- name = "Braided front"
- icon_state = "hair_braidfront"
-
-/datum/sprite_accessory/hair/braidtail
- name = "Braided Tail"
- icon_state = "hair_braidtail"
-
-/datum/sprite_accessory/hair/lowbraid
- name = "Low Braid"
- icon_state = "hair_hbraid"
-
-/datum/sprite_accessory/hair/not_floorlength_braid
- name = "High Braid"
- icon_state = "hair_braid2"
-
-/datum/sprite_accessory/hair/shortbraid
- name = "Short Braid"
- icon_state = "hair_shortbraid"
-
-/datum/sprite_accessory/hair/braid
- name = "Floorlength Braid"
- icon_state = "hair_braid"
-
-/datum/sprite_accessory/hair/business
- name = "Business Hair"
- icon_state = "hair_business"
-
-/datum/sprite_accessory/hair/business2
- name = "Business Hair 2"
- icon_state = "hair_business2"
-
-/datum/sprite_accessory/hair/business3
- name = "Business Hair 3"
- icon_state = "hair_business3"
-
-/datum/sprite_accessory/hair/business4
- name = "Business Hair 4"
- icon_state = "hair_business4"
-
-/datum/sprite_accessory/hair/bun
- name = "Bun Head"
- icon_state = "hair_bun"
-
-/datum/sprite_accessory/hair/bun2
- name = "Bun Head 2"
- icon_state = "hair_bunhead2"
-
-/datum/sprite_accessory/hair/largebun
- name = "Large Bun"
- icon_state = "hair_largebun"
-
-/datum/sprite_accessory/hair/buzz
- name = "Buzzcut"
- icon_state = "hair_buzzcut"
-
-//C
-
-/datum/sprite_accessory/hair/crew
- name = "Crewcut"
- icon_state = "hair_crewcut"
-
-/datum/sprite_accessory/hair/combover
- name = "Combover"
- icon_state = "hair_combover"
-
-/datum/sprite_accessory/hair/curls
- name = "Curls"
- icon_state = "hair_curls"
-
-//D
-
-/datum/sprite_accessory/hair/devillock
- name = "Devil Lock"
- icon_state = "hair_devilock"
-
-/datum/sprite_accessory/hair/dreadlocks
- name = "Dreadlocks"
- icon_state = "hair_dreads"
-
-/datum/sprite_accessory/hair/drillhair
- name = "Drill Hair"
- icon_state = "hair_drillhair"
-
-//E
-
-/datum/sprite_accessory/hair/emo
- name = "Emo"
- icon_state = "hair_emo"
-
-/datum/sprite_accessory/hair/longemo
- name = "Long Emo"
- icon_state = "hair_longemo"
-
-//F
-
-/datum/sprite_accessory/hair/feather
- name = "Feather"
- icon_state = "hair_feather"
-
-/datum/sprite_accessory/hair/sargeant
- name = "Flat Top"
- icon_state = "hair_sargeant"
-
-/datum/sprite_accessory/hair/bigflattop
- name = "Big Flat Top"
- icon_state = "hair_bigflattop"
-
-/datum/sprite_accessory/hair/fag
- name = "Flow Hair"
- icon_state = "hair_f"
-
-/datum/sprite_accessory/hair/longfringe
- name = "Long Fringe"
- icon_state = "hair_longfringe"
-
-/datum/sprite_accessory/hair/longestalt
- name = "Longer Fringe"
- icon_state = "hair_vlongfringe"
-
-//G
-
-/datum/sprite_accessory/hair/gelled
- name = "Gelled Back"
- icon_state = "hair_gelled"
-
-/datum/sprite_accessory/hair/gentle
- name = "Gentle"
- icon_state = "hair_gentle"
-
-//H
+/datum/sprite_accessory/hair/shorthair3
+ name = "Short Hair 3"
+ icon_state = "hair_shorthair3"
/datum/sprite_accessory/hair/cut
name = "Cut Hair"
icon_state = "hair_c"
-/datum/sprite_accessory/hair/halfbang
- name = "Half-banged Hair"
- icon_state = "hair_halfbang"
-
-/datum/sprite_accessory/hair/halfbang2
- name = "Half-banged Hair 2"
- icon_state = "hair_halfbang2"
-
-/datum/sprite_accessory/hair/hedgehog
- name = "Hedgehog Hair"
- icon_state = "hair_hedgehog"
-
-/datum/sprite_accessory/hair/hitop
- name = "Hitop"
- icon_state = "hair_hitop"
-
-/datum/sprite_accessory/hair/himecut
- name = "Hime Cut"
- icon_state = "hair_himecut"
-
-/datum/sprite_accessory/hair/himecut2
- name = "Hime Cut 2"
- icon_state = "hair_himecut2"
-
-/datum/sprite_accessory/hair/himeup
- name = "Hime Updo"
- icon_state = "hair_himeup"
-
-//I
-
-//J
-
-/datum/sprite_accessory/hair/jensen
- name = "Jensen Hair"
- icon_state = "hair_jensen"
-
-//K
-
-/datum/sprite_accessory/hair/keanu
- name = "Keanu Hair"
- icon_state = "hair_keanu"
-
-/datum/sprite_accessory/hair/kusangi
- name = "Kusanagi Hair"
- icon_state = "hair_kusanagi"
-
-//L
+/datum/sprite_accessory/hair/long
+ name = "Shoulder-length Hair"
+ icon_state = "hair_b"
/datum/sprite_accessory/hair/longer
name = "Long Hair"
icon_state = "hair_vlong"
-/datum/sprite_accessory/hair/long
- name = "Long Hair 1"
- icon_state = "hair_long"
-
-/datum/sprite_accessory/hair/long2
- name = "Long Hair 2"
- icon_state = "hair_long2"
-
-/datum/sprite_accessory/hair/longest
- name = "Very Long Hair"
- icon_state = "hair_longest"
-
-//M
-
-/datum/sprite_accessory/hair/megaeyebrows
- name = "Mega Eyebrows"
- icon_state = "hair_megaeyebrows"
-
-/datum/sprite_accessory/hair/messy
- name = "Messy"
- icon_state = "hair_messy"
-
-/datum/sprite_accessory/hair/mohawk
- name = "Mohawk"
- icon_state = "hair_d"
-
-/datum/sprite_accessory/hair/reversemohawk
- name = "Reverse Mohawk"
- icon_state = "hair_reversemohawk"
-
-//N
-
-//O
-
-/datum/sprite_accessory/hair/odango
- name = "Odango"
- icon_state = "hair_odango"
-
-/datum/sprite_accessory/hair/ombre
- name = "Ombre"
- icon_state = "hair_ombre"
-
/datum/sprite_accessory/hair/over_eye
name = "Over Eye"
icon_state = "hair_shortovereye"
@@ -390,39 +103,29 @@
name = "Very Long Over Eye"
icon_state = "hair_longest2"
-//P
+/datum/sprite_accessory/hair/longest
+ name = "Very Long Hair"
+ icon_state = "hair_longest"
-/datum/sprite_accessory/hair/parted
- name = "Parted"
- icon_state = "hair_parted"
+/datum/sprite_accessory/hair/longfringe
+ name = "Long Fringe"
+ icon_state = "hair_longfringe"
-/datum/sprite_accessory/hair/sidepartlongalt
- name = "Long Side Part"
- icon_state = "hair_longsidepart"
+/datum/sprite_accessory/hair/longestalt
+ name = "Longer Fringe"
+ icon_state = "hair_vlongfringe"
-/datum/sprite_accessory/hair/kagami
- name = "Pigtails"
- icon_state = "hair_kagami"
+/datum/sprite_accessory/hair/gentle
+ name = "Gentle"
+ icon_state = "hair_gentle"
-/datum/sprite_accessory/hair/pigtail
- name = "Pigtails 2"
- icon_state = "hair_pigtails"
+/datum/sprite_accessory/hair/halfbang
+ name = "Half-banged Hair"
+ icon_state = "hair_halfbang"
-/datum/sprite_accessory/hair/pigtail
- name = "Pigtails 3"
- icon_state = "hair_pigtails2"
-
-/datum/sprite_accessory/hair/pixie
- name = "Pixie Cut"
- icon_state = "hair_pixie"
-
-/datum/sprite_accessory/hair/pompadour
- name = "Pompadour"
- icon_state = "hair_pompadour"
-
-/datum/sprite_accessory/hair/bigpompadour
- name = "Big Pompadour"
- icon_state = "hair_bigpompadour"
+/datum/sprite_accessory/hair/halfbang2
+ name = "Half-banged Hair 2"
+ icon_state = "hair_halfbang2"
/datum/sprite_accessory/hair/ponytail1
name = "Ponytail"
@@ -444,36 +147,6 @@
name = "Ponytail 5"
icon_state = "hair_ponytail5"
-/datum/sprite_accessory/hair/highponytail
- name = "High Ponytail"
- icon_state = "hair_highponytail"
-
-/datum/sprite_accessory/hair/longponytail
- name = "Long Ponytail"
- icon_state = "hair_longstraightponytail"
-
-//Q
-
-/datum/sprite_accessory/hair/quiff
- name = "Quiff"
- icon_state = "hair_quiff"
-
-
-//R
-
-//S
-
-/datum/sprite_accessory/hair/oneshoulder
- name = "One Shoulder"
- icon_state = "hair_oneshoulder"
-
-/datum/sprite_accessory/hair/tressshoulder
- name = "Tress Shoulder"
- icon_state = "hair_tressshoulder"
-
-/datum/sprite_accessory/hair/sidecut
- name = "Sidecut"
- icon_state = "hair_sidecut"
/datum/sprite_accessory/hair/sidetail
name = "Side Pony"
@@ -491,33 +164,141 @@
name = "Side Pony 4"
icon_state = "hair_sidetail4"
-/datum/sprite_accessory/hair/short
- name = "Short Hair"
- icon_state = "hair_a"
+/datum/sprite_accessory/hair/oneshoulder
+ name = "One Shoulder"
+ icon_state = "hair_oneshoulder"
-/datum/sprite_accessory/hair/shorthair2
- name = "Short Hair 2"
- icon_state = "hair_shorthair2"
-
-/datum/sprite_accessory/hair/shorthair3
- name = "Short Hair 3"
- icon_state = "hair_shorthair3"
-
-/datum/sprite_accessory/hair/long
- name = "Shoulder-length Hair"
- icon_state = "hair_b"
+/datum/sprite_accessory/hair/tressshoulder
+ name = "Tress Shoulder"
+ icon_state = "hair_tressshoulder"
/datum/sprite_accessory/hair/parted
- name = "Side Part"
- icon_state = "hair_part"
+ name = "Parted"
+ icon_state = "hair_parted"
-/datum/sprite_accessory/hair/skinhead
- name = "Skinhead"
- icon_state = "hair_skinhead"
+/datum/sprite_accessory/hair/pompadour
+ name = "Pompadour"
+ icon_state = "hair_pompadour"
-/datum/sprite_accessory/hair/protagonist
- name = "Slightly Long"
- icon_state = "hair_protagonist"
+/datum/sprite_accessory/hair/bigpompadour
+ name = "Big Pompadour"
+ icon_state = "hair_bigpompadour"
+
+/datum/sprite_accessory/hair/quiff
+ name = "Quiff"
+ icon_state = "hair_quiff"
+
+/datum/sprite_accessory/hair/bedhead
+ name = "Bedhead"
+ icon_state = "hair_bedhead"
+
+/datum/sprite_accessory/hair/bedhead2
+ name = "Bedhead 2"
+ icon_state = "hair_bedheadv2"
+
+/datum/sprite_accessory/hair/bedhead3
+ name = "Bedhead 3"
+ icon_state = "hair_bedheadv3"
+
+/datum/sprite_accessory/hair/messy
+ name = "Messy"
+ icon_state = "hair_messy"
+
+/datum/sprite_accessory/hair/beehive
+ name = "Beehive"
+ icon_state = "hair_beehive"
+
+/datum/sprite_accessory/hair/beehive2
+ name = "Beehive 2"
+ icon_state = "hair_beehivev2"
+
+/datum/sprite_accessory/hair/bobcurl
+ name = "Bobcurl"
+ icon_state = "hair_bobcurl"
+
+/datum/sprite_accessory/hair/bob
+ name = "Bob"
+ icon_state = "hair_bobcut"
+
+/datum/sprite_accessory/hair/bowl
+ name = "Bowl"
+ icon_state = "hair_bowlcut"
+
+/datum/sprite_accessory/hair/buzz
+ name = "Buzzcut"
+ icon_state = "hair_buzzcut"
+
+/datum/sprite_accessory/hair/crew
+ name = "Crewcut"
+ icon_state = "hair_crewcut"
+
+/datum/sprite_accessory/hair/combover
+ name = "Combover"
+ icon_state = "hair_combover"
+
+/datum/sprite_accessory/hair/devillock
+ name = "Devil Lock"
+ icon_state = "hair_devilock"
+
+/datum/sprite_accessory/hair/dreadlocks
+ name = "Dreadlocks"
+ icon_state = "hair_dreads"
+
+/datum/sprite_accessory/hair/curls
+ name = "Curls"
+ icon_state = "hair_curls"
+
+/datum/sprite_accessory/hair/afro
+ name = "Afro"
+ icon_state = "hair_afro"
+
+/datum/sprite_accessory/hair/afro2
+ name = "Afro 2"
+ icon_state = "hair_afro2"
+
+/datum/sprite_accessory/hair/afro_large
+ name = "Big Afro"
+ icon_state = "hair_bigafro"
+
+/datum/sprite_accessory/hair/sargeant
+ name = "Flat Top"
+ icon_state = "hair_sargeant"
+
+/datum/sprite_accessory/hair/emo
+ name = "Emo"
+ icon_state = "hair_emo"
+
+/datum/sprite_accessory/hair/longemo
+ name = "Long Emo"
+ icon_state = "hair_longemo"
+
+/datum/sprite_accessory/hair/fag
+ name = "Flow Hair"
+ icon_state = "hair_f"
+
+/datum/sprite_accessory/hair/feather
+ name = "Feather"
+ icon_state = "hair_feather"
+
+/datum/sprite_accessory/hair/hitop
+ name = "Hitop"
+ icon_state = "hair_hitop"
+
+/datum/sprite_accessory/hair/mohawk
+ name = "Mohawk"
+ icon_state = "hair_d"
+
+/datum/sprite_accessory/hair/reversemohawk
+ name = "Reverse Mohawk"
+ icon_state = "hair_reversemohawk"
+
+/datum/sprite_accessory/hair/jensen
+ name = "Jensen Hair"
+ icon_state = "hair_jensen"
+
+/datum/sprite_accessory/hair/gelled
+ name = "Gelled Back"
+ icon_state = "hair_gelled"
/datum/sprite_accessory/hair/spiky
name = "Spiky"
@@ -531,6 +312,122 @@
name = "Spiky 3"
icon_state = "hair_spiky2"
+/datum/sprite_accessory/hair/protagonist
+ name = "Slightly Long"
+ icon_state = "hair_protagonist"
+
+/datum/sprite_accessory/hair/kusangi
+ name = "Kusanagi Hair"
+ icon_state = "hair_kusanagi"
+
+/datum/sprite_accessory/hair/kagami
+ name = "Pigtails"
+ icon_state = "hair_kagami"
+
+/datum/sprite_accessory/hair/pigtail
+ name = "Pigtails 2"
+ icon_state = "hair_pigtails"
+
+/datum/sprite_accessory/hair/pigtail
+ name = "Pigtails 3"
+ icon_state = "hair_pigtails2"
+
+/datum/sprite_accessory/hair/himecut
+ name = "Hime Cut"
+ icon_state = "hair_himecut"
+
+/datum/sprite_accessory/hair/himecut2
+ name = "Hime Cut 2"
+ icon_state = "hair_himecut2"
+
+/datum/sprite_accessory/hair/himeup
+ name = "Hime Updo"
+ icon_state = "hair_himeup"
+
+/datum/sprite_accessory/hair/antenna
+ name = "Ahoge"
+ icon_state = "hair_antenna"
+
+/datum/sprite_accessory/hair/front_braid
+ name = "Braided front"
+ icon_state = "hair_braidfront"
+
+/datum/sprite_accessory/hair/lowbraid
+ name = "Low Braid"
+ icon_state = "hair_hbraid"
+
+/datum/sprite_accessory/hair/not_floorlength_braid
+ name = "High Braid"
+ icon_state = "hair_braid2"
+
+/datum/sprite_accessory/hair/shortbraid
+ name = "Short Braid"
+ icon_state = "hair_shortbraid"
+
+/datum/sprite_accessory/hair/braid
+ name = "Floorlength Braid"
+ icon_state = "hair_braid"
+
+/datum/sprite_accessory/hair/odango
+ name = "Odango"
+ icon_state = "hair_odango"
+
+/datum/sprite_accessory/hair/ombre
+ name = "Ombre"
+ icon_state = "hair_ombre"
+
+/datum/sprite_accessory/hair/updo
+ name = "Updo"
+ icon_state = "hair_updo"
+
+/datum/sprite_accessory/hair/skinhead
+ name = "Skinhead"
+ icon_state = "hair_skinhead"
+
+/datum/sprite_accessory/hair/longbangs
+ name = "Long Bangs"
+ icon_state = "hair_lbangs"
+
+/datum/sprite_accessory/hair/balding
+ name = "Balding Hair"
+ icon_state = "hair_e"
+
+/datum/sprite_accessory/hair/bald
+ name = "Bald"
+ icon_state = null
+
+/datum/sprite_accessory/hair/parted
+ name = "Side Part"
+ icon_state = "hair_part"
+
+/datum/sprite_accessory/hair/braided
+ name = "Braided"
+ icon_state = "hair_braided"
+
+/datum/sprite_accessory/hair/bun
+ name = "Bun Head"
+ icon_state = "hair_bun"
+
+/datum/sprite_accessory/hair/bun2
+ name = "Bun Head 2"
+ icon_state = "hair_bunhead2"
+
+/datum/sprite_accessory/hair/braidtail
+ name = "Braided Tail"
+ icon_state = "hair_braidtail"
+
+/datum/sprite_accessory/hair/bigflattop
+ name = "Big Flat Top"
+ icon_state = "hair_bigflattop"
+
+/datum/sprite_accessory/hair/drillhair
+ name = "Drill Hair"
+ icon_state = "hair_drillhair"
+
+/datum/sprite_accessory/hair/keanu
+ name = "Keanu Hair"
+ icon_state = "hair_keanu"
+
/datum/sprite_accessory/hair/swept
name = "Swept Back Hair"
icon_state = "hair_swept"
@@ -539,24 +436,73 @@
name = "Swept Back Hair 2"
icon_state = "hair_swept2"
-//T
+/datum/sprite_accessory/hair/business
+ name = "Business Hair"
+ icon_state = "hair_business"
-//U
+/datum/sprite_accessory/hair/business2
+ name = "Business Hair 2"
+ icon_state = "hair_business2"
-/datum/sprite_accessory/hair/updo
- name = "Updo"
- icon_state = "hair_updo"
+/datum/sprite_accessory/hair/business3
+ name = "Business Hair 3"
+ icon_state = "hair_business3"
-//V
+/datum/sprite_accessory/hair/business4
+ name = "Business Hair 4"
+ icon_state = "hair_business4"
-//W
+/datum/sprite_accessory/hair/hedgehog
+ name = "Hedgehog Hair"
+ icon_state = "hair_hedgehog"
-//X
+/datum/sprite_accessory/hair/bob
+ name = "Bob Hair"
+ icon_state = "hair_bob"
-//Y
+/datum/sprite_accessory/hair/bob2
+ name = "Bob Hair 2"
+ icon_state = "hair_bob2"
-//Z
+/datum/sprite_accessory/hair/boddicker
+ name = "Boddicker"
+ icon_state = "hair_boddicker"
+/datum/sprite_accessory/hair/long
+ name = "Long Hair 1"
+ icon_state = "hair_long"
+
+/datum/sprite_accessory/hair/long2
+ name = "Long Hair 2"
+ icon_state = "hair_long2"
+
+/datum/sprite_accessory/hair/pixie
+ name = "Pixie Cut"
+ icon_state = "hair_pixie"
+
+/datum/sprite_accessory/hair/megaeyebrows
+ name = "Mega Eyebrows"
+ icon_state = "hair_megaeyebrows"
+
+/datum/sprite_accessory/hair/highponytail
+ name = "High Ponytail"
+ icon_state = "hair_highponytail"
+
+/datum/sprite_accessory/hair/longponytail
+ name = "Long Ponytail"
+ icon_state = "hair_longstraightponytail"
+
+/datum/sprite_accessory/hair/sidepartlongalt
+ name = "Long Side Part"
+ icon_state = "hair_longsidepart"
+
+/datum/sprite_accessory/hair/sidecut
+ name = "Sidecut"
+ icon_state = "hair_sidecut"
+
+/datum/sprite_accessory/hair/largebun
+ name = "Large Bun"
+ icon_state = "hair_largebun"
/////////////////////////////
// Facial Hair Definitions //
@@ -570,81 +516,82 @@
icon_state = null
gender = NEUTER
-/datum/sprite_accessory/facial_hair/abe
- name = "Abraham Lincoln Beard"
- icon_state = "facial_abe"
-
-/datum/sprite_accessory/facial_hair/brokenman
- name = "Broken Man"
- icon_state = "facial_brokenman"
-
-/datum/sprite_accessory/facial_hair/chinstrap
- name = "Chinstrap"
- icon_state = "facial_chin"
-
-/datum/sprite_accessory/facial_hair/dwarf
- name = "Dwarf Beard"
- icon_state = "facial_dwarf"
-
-/datum/sprite_accessory/facial_hair/elvis
- name = "Elvis Sideburns"
- icon_state = "facial_elvis"
-
-/datum/sprite_accessory/facial_hair/fiveoclock
- name = "Five o Clock Shadow"
- icon_state = "facial_fiveoclock"
-
-/datum/sprite_accessory/facial_hair/fullbeard
- name = "Full Beard"
- icon_state = "facial_fullbeard"
-
-/datum/sprite_accessory/facial_hair/fu
- name = "Fu Manchu"
- icon_state = "facial_fumanchu"
-
-/datum/sprite_accessory/facial_hair/gt
- name = "Goatee"
- icon_state = "facial_gt"
-
-/datum/sprite_accessory/facial_hair/hip
- name = "Hipster Beard"
- icon_state = "facial_hip"
+/datum/sprite_accessory/facial_hair/watson
+ name = "Watson Mustache"
+ icon_state = "facial_watson"
/datum/sprite_accessory/facial_hair/hogan
name = "Hulk Hogan Mustache"
icon_state = "facial_hogan" //-Neek
-
-/datum/sprite_accessory/facial_hair/jensen
- name = "Jensen Beard"
- icon_state = "facial_jensen"
-
-/datum/sprite_accessory/facial_hair/longbeard
- name = "Long Beard"
- icon_state = "facial_longbeard"
-
-/datum/sprite_accessory/facial_hair/neckbeard
- name = "Neckbeard"
- icon_state = "facial_neckbeard"
-
-/datum/sprite_accessory/facial_hair/selleck
- name = "Selleck Mustache"
- icon_state = "facial_selleck"
-
-/datum/sprite_accessory/facial_hair/chaplin
- name = "Square Mustache"
- icon_state = "facial_chaplin"
-
+
/datum/sprite_accessory/facial_hair/vandyke
name = "Van Dyke Mustache"
icon_state = "facial_vandyke"
-
+
+/datum/sprite_accessory/facial_hair/chaplin
+ name = "Square Mustache"
+ icon_state = "facial_chaplin"
+
+/datum/sprite_accessory/facial_hair/selleck
+ name = "Selleck Mustache"
+ icon_state = "facial_selleck"
+
+/datum/sprite_accessory/facial_hair/neckbeard
+ name = "Neckbeard"
+ icon_state = "facial_neckbeard"
+
+/datum/sprite_accessory/facial_hair/fullbeard
+ name = "Full Beard"
+ icon_state = "facial_fullbeard"
+
+/datum/sprite_accessory/facial_hair/longbeard
+ name = "Long Beard"
+ icon_state = "facial_longbeard"
+
/datum/sprite_accessory/facial_hair/vlongbeard
name = "Very Long Beard"
icon_state = "facial_wise"
-
-/datum/sprite_accessory/facial_hair/watson
- name = "Watson Mustache"
- icon_state = "facial_watson"
+
+/datum/sprite_accessory/facial_hair/elvis
+ name = "Elvis Sideburns"
+ icon_state = "facial_elvis"
+
+/datum/sprite_accessory/facial_hair/abe
+ name = "Abraham Lincoln Beard"
+ icon_state = "facial_abe"
+
+/datum/sprite_accessory/facial_hair/chinstrap
+ name = "Chinstrap"
+ icon_state = "facial_chin"
+
+/datum/sprite_accessory/facial_hair/hip
+ name = "Hipster Beard"
+ icon_state = "facial_hip"
+
+/datum/sprite_accessory/facial_hair/gt
+ name = "Goatee"
+ icon_state = "facial_gt"
+
+/datum/sprite_accessory/facial_hair/jensen
+ name = "Jensen Beard"
+ icon_state = "facial_jensen"
+
+/datum/sprite_accessory/facial_hair/dwarf
+ name = "Dwarf Beard"
+ icon_state = "facial_dwarf"
+
+/datum/sprite_accessory/facial_hair/fiveoclock
+ name = "Five o Clock Shadow"
+ icon_state = "facial_fiveoclock"
+
+/datum/sprite_accessory/facial_hair/fu
+ name = "Fu Manchu"
+ icon_state = "facial_fumanchu"
+
+/datum/sprite_accessory/facial_hair/brokenman
+ name = "Broken Man"
+ icon_state = "facial_brokenman"
+
///////////////////////////
// Underwear Definitions //
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index 13a34b6bae..aa15e28e66 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -18,12 +18,12 @@
vital = FALSE
decoy_override = TRUE
-/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0)
+/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0,no_id_transfer = FALSE)
..()
name = "brain"
- if(C.mind && C.mind.changeling) //congrats, you're trapped in a body you don't control
+ if(C.mind && C.mind.changeling && !no_id_transfer) //congrats, you're trapped in a body you don't control
if(brainmob && !(C.stat == DEAD || (C.status_flags & FAKEDEATH)))
to_chat(brainmob, "You can't feel your body! You're still just a brain!")
loc = C
@@ -44,13 +44,9 @@
//Update the body's icon so it doesnt appear debrained anymore
C.update_hair()
-/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0)
+/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0, no_id_transfer = FALSE)
..()
- if(!special)
- if(C.has_brain_worms())
- var/mob/living/simple_animal/borer/B = C.has_brain_worms()
- B.leave_victim() //Should remove borer if the brain is removed - RR
- if(!gc_destroyed || (owner && !owner.gc_destroyed))
+ if((!gc_destroyed || (owner && !owner.gc_destroyed)) && !no_id_transfer)
transfer_identity(C)
C.update_hair()
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index a1b67fbee1..282de04ede 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -29,7 +29,7 @@
dizziness = 0
jitteriness = 0
- if(istype(loc, /obj/mecha))
+ if(ismecha(loc))
var/obj/mecha/M = loc
if(M.occupant == src)
M.go_out()
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 74ccdab19c..0ca0bed9fc 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -277,9 +277,11 @@
if(!appears_dead)
if(stat == UNCONSCIOUS)
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
- else if(getBrainLoss() >= 60)
- msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
-
+ else
+ if(getBrainLoss() >= 60)
+ msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
+ if(InCritical())
+ msg += "[t_He] is barely concious.\n"
if(getorgan(/obj/item/organ/brain))
if(istype(src, /mob/living/carbon/human/interactive))
var/mob/living/carbon/human/interactive/auto = src
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index d66e6f808a..70a5f5225c 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -21,41 +21,12 @@
set_species(dna.species.type)
//initialise organs
- create_internal_organs()
+ create_internal_organs() //most of it is done in set_species now, this is only for parent call
handcrafting = new()
. = ..()
-/mob/living/carbon/human/create_internal_organs()
- if(!(NOHUNGER in dna.species.species_traits))
- internal_organs += new /obj/item/organ/appendix
- if(!(NOBREATH in dna.species.species_traits))
- if(dna.species.mutantlungs)
- internal_organs += new dna.species.mutantlungs()
- else
- internal_organs += new /obj/item/organ/lungs()
- if(!(NOBLOOD in dna.species.species_traits))
- internal_organs += new /obj/item/organ/heart
-
- if(!(NOLIVER in dna.species.species_traits))
- if(dna.species.mutantliver)
- internal_organs += new dna.species.mutantliver()
- else
- internal_organs += new /obj/item/organ/liver()
-
- if(!(NOSTOMACH in dna.species.species_traits))
- if(dna.species.mutantstomach)
- internal_organs += new dna.species.mutantstomach()
- else
- internal_organs += new /obj/item/organ/stomach()
-
- internal_organs += new dna.species.mutanteyes
- internal_organs += new dna.species.mutantears
- internal_organs += new dna.species.mutanttongue
- internal_organs += new /obj/item/organ/brain
- ..()
-
/mob/living/carbon/human/OpenCraftingMenu()
handcrafting.ui_interact(src)
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 07f3acea48..34d4ae8e51 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -68,7 +68,8 @@
//Flight and floating
var/override_float = 0
-
+
+ var/obj/item/organ/brain/mutant_brain = /obj/item/organ/brain
var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes
var/obj/item/organ/ears/mutantears = /obj/item/organ/ears
var/obj/item/mutanthands
@@ -123,6 +124,113 @@
return 0
return 1
+//Will regenerate missing organs
+/datum/species/proc/regenerate_organs(mob/living/carbon/C,datum/species/old_species,replace_current=TRUE)
+ var/obj/item/organ/brain/brain = C.getorganslot("brain")
+ var/obj/item/organ/heart/heart = C.getorganslot("heart")
+ var/obj/item/organ/lungs/lungs = C.getorganslot("lungs")
+ var/obj/item/organ/appendix/appendix = C.getorganslot("appendix")
+ var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight")
+ var/obj/item/organ/ears/ears = C.getorganslot("ears")
+ var/obj/item/organ/tongue/tongue = C.getorganslot("tongue")
+ var/obj/item/organ/liver/liver = C.getorganslot("liver")
+ var/obj/item/organ/stomach/stomach = C.getorganslot("stomach")
+
+ var/should_have_brain = TRUE
+ var/should_have_heart = !(NOBLOOD in species_traits)
+ var/should_have_lungs = !(NOBREATH in species_traits)
+ var/should_have_appendix = !(NOHUNGER in species_traits)
+ var/should_have_eyes = TRUE
+ var/should_have_ears = TRUE
+ var/should_have_tongue = TRUE
+ var/should_have_liver = !(NOLIVER in species_traits)
+ var/should_have_stomach = !(NOSTOMACH in species_traits)
+
+ if(brain && (replace_current || !should_have_brain))
+ if(!brain.decoy_override)//Just keep it if it's fake
+ brain.Remove(C,TRUE,TRUE)
+ QDEL_NULL(brain)
+ if(should_have_brain && !brain)
+ brain = new mutant_brain()
+ brain.Insert(C, TRUE, TRUE)
+
+ if(heart && (!should_have_heart || replace_current))
+ heart.Remove(C,1)
+ QDEL_NULL(heart)
+ if(should_have_heart && !heart)
+ heart = new()
+ heart.Insert(C)
+
+ if(lungs && (replace_current || !should_have_lungs))
+ lungs.Remove(C,1)
+ QDEL_NULL(lungs)
+ if(should_have_lungs && !lungs)
+ if(mutantlungs)
+ lungs = new mutantlungs()
+ else
+ lungs = new()
+ lungs.Insert(C)
+
+ if(liver && (!should_have_liver || replace_current))
+ liver.Remove(C,1)
+ QDEL_NULL(liver)
+ if(should_have_liver && !liver)
+ if(mutantliver)
+ liver = new mutantliver()
+ else
+ liver = new()
+ liver.Insert(C)
+
+ if(stomach && (!should_have_stomach || replace_current))
+ stomach.Remove(C,1)
+ QDEL_NULL(stomach)
+ if(should_have_stomach && !stomach)
+ if(mutantstomach)
+ stomach = new mutantstomach()
+ else
+ stomach = new()
+ stomach.Insert(C)
+
+ if(appendix && (!should_have_appendix || replace_current))
+ appendix.Remove(C,1)
+ QDEL_NULL(appendix)
+ if(should_have_appendix && !appendix)
+ appendix = new()
+ appendix.Insert(C)
+
+ if(C.get_bodypart("head"))
+ if(eyes && (replace_current || !should_have_eyes))
+ eyes.Remove(C,1)
+ QDEL_NULL(eyes)
+ if(should_have_eyes && !eyes)
+ eyes = new mutanteyes
+ eyes.Insert(C)
+
+ if(ears && (replace_current || !should_have_ears))
+ ears.Remove(C,1)
+ QDEL_NULL(ears)
+ if(should_have_ears && !ears)
+ ears = new mutantears
+ ears.Insert(C)
+
+ if(tongue && (replace_current || !should_have_tongue))
+ tongue.Remove(C,1)
+ QDEL_NULL(tongue)
+ if(should_have_tongue && !tongue)
+ tongue = new mutanttongue
+ tongue.Insert(C)
+
+ if(old_species)
+ for(var/mutantorgan in old_species.mutant_organs)
+ var/obj/item/organ/I = C.getorgan(mutantorgan)
+ if(I)
+ I.Remove(C)
+ QDEL_NULL(I)
+
+ for(var/path in mutant_organs)
+ var/obj/item/organ/I = new path()
+ I.Insert(C)
+
/datum/species/proc/on_species_gain(mob/living/carbon/C, datum/species/old_species)
// Drop the items the new species can't wear
for(var/slot_id in no_equip)
@@ -138,79 +246,7 @@
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(FALSE)
- var/obj/item/organ/heart/heart = C.getorganslot("heart")
- var/obj/item/organ/lungs/lungs = C.getorganslot("lungs")
- var/obj/item/organ/appendix/appendix = C.getorganslot("appendix")
- var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight")
- var/obj/item/organ/ears/ears = C.getorganslot("ears")
- var/obj/item/organ/tongue/tongue = C.getorganslot("tongue")
-
- var/obj/item/organ/liver/liver = C.getorganslot("liver")
- var/obj/item/organ/stomach/stomach = C.getorganslot("stomach")
-
-
-
- if((NOBLOOD in species_traits) && heart)
- heart.Remove(C)
- qdel(heart)
- else if((!(NOBLOOD in species_traits)) && (!heart))
- heart = new()
- heart.Insert(C)
-
- if(lungs)
- qdel(lungs)
- lungs = null
-
- QDEL_NULL(liver)
-
- QDEL_NULL(stomach)
-
- if(C.get_bodypart("head"))
- if(eyes)
- qdel(eyes)
- eyes = new mutanteyes
- eyes.Insert(C)
-
- if(ears)
- qdel(ears)
- ears = new mutantears
- ears.Insert(C)
-
- if(tongue)
- qdel(tongue)
- tongue = new mutanttongue
- tongue.Insert(C)
-
- if((!(NOBREATH in species_traits)) && !lungs)
- if(mutantlungs)
- lungs = new mutantlungs()
- else
- lungs = new()
- lungs.Insert(C)
-
- if((!(NOLIVER in species_traits)) && (!liver))
- if(mutantliver)
- liver = new mutantliver()
- else
- liver = new()
- liver.Insert(C)
-
- if((!(NOSTOMACH in species_traits)) && (!stomach))
- if(mutantstomach)
- stomach = new mutantstomach()
- else
- stomach = new()
- stomach.Insert(C)
-
- if((NOHUNGER in species_traits) && appendix)
- qdel(appendix)
- else if((!(NOHUNGER in species_traits)) && (!appendix))
- appendix = new()
- appendix.Insert(C)
-
- for(var/path in mutant_organs)
- var/obj/item/organ/I = new path()
- I.Insert(C)
+ regenerate_organs(C,old_species)
if(exotic_bloodtype && C.dna.blood_type != exotic_bloodtype)
C.dna.blood_type = exotic_bloodtype
diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
index f5f59ae829..ef044e462b 100644
--- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
@@ -8,10 +8,13 @@
attack_sound = 'sound/weapons/slice.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
burnmod = 1.25
- heatmod = 1.5
+ heatmod = 1.55
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/plant
disliked_food = NONE
liked_food = NONE
+ toxic_food = NONE
+ roundstart = TRUE
+
/datum/species/pod/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
@@ -34,18 +37,21 @@
if(H.nutrition > NUTRITION_LEVEL_FULL)
H.nutrition = NUTRITION_LEVEL_FULL
if(light_amount > 0.2) //if there's enough light, heal
- H.heal_overall_damage(1,1)
- H.adjustToxLoss(-1)
- H.adjustOxyLoss(-1)
+ H.heal_overall_damage(0.05,0)
+ H.adjustOxyLoss(-0.5)
+
+ if(H.nutrition < NUTRITION_LEVEL_STARVING + 55)
+ H.adjustOxyLoss(5) //can eat to negate this unfortunately
+ H.adjustToxLoss(3)
- if(H.nutrition < NUTRITION_LEVEL_STARVING + 50)
- H.take_overall_damage(2,0)
/datum/species/pod/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.id == "plantbgone")
- H.adjustToxLoss(3)
+ H.adjustToxLoss(5)
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
- return 1
+ H.confused = max(H.confused, 1)
+ return TRUE
+
/datum/species/pod/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
switch(P.type)
diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
index 5c635fb870..4347a8331c 100644
--- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
@@ -1,3 +1,5 @@
+#define HEART_RESPAWN_THRESHHOLD 40
+
/datum/species/shadow
// Humans cursed to stay in the darkness, lest their life forces drain. They regain health in shadow and die in light.
name = "???"
@@ -32,31 +34,21 @@
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform, slot_s_store)
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR,NOHUNGER,NO_DNA_COPY,NOTRANSSTING)
mutanteyes = /obj/item/organ/eyes/night_vision/nightmare
- var/obj/effect/proc_holder/spell/targeted/shadowwalk/shadowwalk
+ mutant_organs = list(/obj/item/organ/heart/nightmare)
+ mutant_brain = /obj/item/organ/brain/nightmare
- var/info_text = "You are a Nightmare. The ability shadow walk allows unlimited, unrestricted movement in the dark using. \
- Your light eater will destroy any light producing objects you attack, as well as destroy any lights a living creature may be holding. You will automatically dodge gunfire and melee attacks when on a dark tile."
+ var/info_text = "You are a Nightmare. The ability shadow walk allows unlimited, unrestricted movement in the dark while activated. \
+ Your light eater will destroy any light producing objects you attack, as well as destroy any lights a living creature may be holding. You will automatically dodge gunfire and melee attacks when on a dark tile. If killed, you will eventually revive if left in darkness."
/datum/species/shadow/nightmare/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
- var/obj/effect/proc_holder/spell/targeted/shadowwalk/SW = new
- C.AddSpell(SW)
- shadowwalk = SW
- var/obj/item/light_eater/blade = new
- C.put_in_hands(blade)
-
to_chat(C, "[info_text]")
- C.real_name = "Nightmare"
- C.name = "Nightmare"
+ C.real_name = "[pick(GLOB.nightmare_names)]"
+ C.name = C.real_name
if(C.mind)
- C.mind.name = "Nightmare"
- C.dna.real_name = "Nightmare"
-
-/datum/species/shadow/nightmare/on_species_loss(mob/living/carbon/C)
- . = ..()
- if(shadowwalk)
- C.RemoveSpell(shadowwalk)
+ C.mind.name = C.real_name
+ C.dna.real_name = C.real_name
/datum/species/shadow/nightmare/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
var/turf/T = H.loc
@@ -68,6 +60,93 @@
return -1
return 0
+
+
+//Organs
+
+/obj/item/organ/brain/nightmare
+ name = "tumorous mass"
+ desc = "A fleshy growth that was dug out of the skull of a Nightmare."
+ icon_state = "brain-x-d"
+ var/obj/effect/proc_holder/spell/targeted/shadowwalk/shadowwalk
+
+/obj/item/organ/brain/nightmare/Insert(mob/living/carbon/M, special = 0)
+ ..()
+ if(M.dna.species.id != "nightmare")
+ M.set_species(/datum/species/shadow/nightmare)
+ visible_message("[M] thrashes as [src] takes root in their body!")
+ var/obj/effect/proc_holder/spell/targeted/shadowwalk/SW = new
+ M.AddSpell(SW)
+ shadowwalk = SW
+
+
+/obj/item/organ/brain/nightmare/Remove(mob/living/carbon/M, special = 0)
+ if(shadowwalk)
+ M.RemoveSpell(shadowwalk)
+ ..()
+
+
+/obj/item/organ/heart/nightmare
+ name = "heart of darkness"
+ desc = "An alien organ that twists and writhes when exposed to light."
+ icon = 'icons/obj/surgery.dmi'
+ icon_state = "demon_heart-on"
+ color = "#1C1C1C"
+ var/respawn_progress = 0
+ var/obj/item/light_eater/blade
+
+
+/obj/item/organ/heart/nightmare/attack(mob/M, mob/living/carbon/user, obj/target)
+ if(M != user)
+ return ..()
+ user.visible_message("[user] raises [src] to their mouth and tears into it with their teeth!", \
+ "[src] feels unnaturally cold in your hands. You raise [src] your mouth and devour it!")
+ playsound(user, 'sound/magic/demon_consume.ogg', 50, 1)
+
+
+ user.visible_message("Blood erupts from [user]'s arm as it reforms into a weapon!", \
+ "Icy blood pumps through your veins as your arm reforms itself!")
+ user.temporarilyRemoveItemFromInventory(src, TRUE)
+ Insert(user)
+
+/obj/item/organ/heart/nightmare/Insert(mob/living/carbon/M, special = 0)
+ ..()
+ blade = new/obj/item/light_eater
+ M.put_in_hands(blade)
+ START_PROCESSING(SSobj, src)
+
+/obj/item/organ/heart/nightmare/Remove(mob/living/carbon/M, special = 0)
+ STOP_PROCESSING(SSobj, src)
+ respawn_progress = 0
+ if(blade)
+ QDEL_NULL(blade)
+ M.visible_message("\The [blade] disintegrates!")
+ ..()
+
+/obj/item/organ/heart/nightmare/Stop()
+ return 0
+
+/obj/item/organ/heart/nightmare/update_icon()
+ return //always beating visually
+
+/obj/item/organ/heart/nightmare/process()
+ if(QDELETED(owner) || owner.stat != DEAD)
+ respawn_progress = 0
+ return
+ var/turf/T = get_turf(owner)
+ if(istype(T))
+ var/light_amount = T.get_lumcount()
+ if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
+ respawn_progress++
+ playsound(owner,'sound/effects/singlebeat.ogg',40,1)
+ if(respawn_progress >= HEART_RESPAWN_THRESHHOLD)
+ owner.revive(full_heal = TRUE)
+ owner.visible_message("[owner] staggers to their feet!")
+ playsound(owner, 'sound/hallucinations/far_noise.ogg', 50, 1)
+ respawn_progress = 0
+
+//Weapon
+
/obj/item/light_eater
name = "light eater"
icon_state = "arm_blade"
@@ -113,3 +192,5 @@
visible_message("[O] is disintegrated by [src]!")
O.burn()
playsound(src, 'sound/items/welder.ogg', 50, 1)
+
+#undef HEART_RESPAWN_THRESHHOLD
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
index 4302c43ff8..be03e591aa 100644
--- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm
+++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
@@ -1,13 +1,13 @@
-/datum/species/skeleton
- // 2spooky
- name = "Spooky Scary Skeleton"
- id = "skeleton"
- say_mod = "rattles"
- blacklisted = 1
- sexes = 0
- meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
- species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYDISMEMBER,EASYLIMBATTACHMENT)
- mutant_organs = list(/obj/item/organ/tongue/bone)
- damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
- disliked_food = NONE
- liked_food = NONE
+/datum/species/skeleton
+ // 2spooky
+ name = "Spooky Scary Skeleton"
+ id = "skeleton"
+ say_mod = "rattles"
+ blacklisted = 1
+ sexes = 0
+ meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
+ species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYDISMEMBER,EASYLIMBATTACHMENT)
+ mutanttongue = /obj/item/organ/tongue/bone
+ damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
+ disliked_food = NONE
+ liked_food = NONE
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index 04123102c0..4ce8570c2b 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -9,7 +9,7 @@
blacklisted = 1
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT,NOTRANSSTING)
- mutant_organs = list(/obj/item/organ/tongue/zombie)
+ mutanttongue = /obj/item/organ/tongue/zombie
var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
disliked_food = NONE
liked_food = NONE
@@ -64,6 +64,6 @@
limbs_id = "zombie" //They look like zombies
sexes = 0
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
- mutant_organs = list(/obj/item/organ/tongue/zombie)
+ mutanttongue = /obj/item/organ/tongue/zombie
#undef REGENERATION_DELAY
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index e1d854c0c8..f4e85e40fb 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -884,7 +884,7 @@
on_fire = 1
src.visible_message("[src] catches fire!", \
"You're set on fire!")
- src.set_light(3)
+ new/obj/effect/dummy/fire(src)
throw_alert("fire", /obj/screen/alert/fire)
update_fire()
return TRUE
@@ -894,7 +894,8 @@
if(on_fire)
on_fire = 0
fire_stacks = 0
- src.set_light(0)
+ for(var/obj/effect/dummy/fire/F in src)
+ qdel(F)
clear_alert("fire")
update_fire()
diff --git a/code/modules/mob/living/silicon/damage_procs.dm b/code/modules/mob/living/silicon/damage_procs.dm
index 07e6994db5..0f2c57c4fe 100644
--- a/code/modules/mob/living/silicon/damage_procs.dm
+++ b/code/modules/mob/living/silicon/damage_procs.dm
@@ -15,7 +15,7 @@
/mob/living/silicon/apply_effect(effect = 0,effecttype = STUN, blocked = FALSE)
- return 0 //The only effect that can hit them atm is flashes and they still directly edit so this works for now
+ return FALSE //The only effect that can hit them atm is flashes and they still directly edit so this works for now
/mob/living/silicon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE) //immune to tox damage
return FALSE
@@ -30,8 +30,13 @@
return FALSE
/mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = 1)//immune to stamina damage.
- return
+ return FALSE
/mob/living/silicon/setStaminaLoss(amount, updating_stamina = 1)
- return
+ return FALSE
+/mob/living/silicon/adjustBrainLoss(amount)
+ return FALSE
+
+/mob/living/silicon/setBrainLoss(amount)
+ return FALSE
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm
index 144f7081e0..592679d35b 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm
@@ -180,10 +180,13 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
new /obj/effect/temp_visual/guardian/phase(loc)
/mob/living/simple_animal/hostile/guardian/canSuicide()
- return 0
+ return FALSE
+
+/mob/living/simple_animal/hostile/guardian/proc/is_deployed()
+ return loc != summoner
/mob/living/simple_animal/hostile/guardian/AttackingTarget()
- if(loc == summoner)
+ if(!is_deployed())
to_chat(src, "You must be manifested to attack!")
return FALSE
else
diff --git a/code/modules/mob/living/simple_animal/guardian/types/support.dm b/code/modules/mob/living/simple_animal/guardian/types/support.dm
index db1581d8cb..a8a31ad89c 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/support.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm
@@ -28,7 +28,7 @@
/mob/living/simple_animal/hostile/guardian/healer/AttackingTarget()
. = ..()
- if(. && toggle && iscarbon(target))
+ if(is_deployed() && toggle && iscarbon(target))
var/mob/living/carbon/C = target
C.adjustBruteLoss(-5)
C.adjustFireLoss(-5)
diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm
index f2d29d3660..9f7a7d1bbf 100644
--- a/code/modules/mob/living/simple_animal/hostile/bees.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bees.dm
@@ -105,22 +105,22 @@
/mob/living/simple_animal/hostile/poison/bees/CanAttack(atom/the_target)
. = ..()
if(!.)
- return 0
+ return FALSE
if(isliving(the_target))
var/mob/living/H = the_target
return !H.bee_friendly()
/mob/living/simple_animal/hostile/poison/bees/Found(atom/A)
+ if(isliving(A))
+ var/mob/living/H = A
+ return !H.bee_friendly()
if(istype(A, /obj/machinery/hydroponics))
var/obj/machinery/hydroponics/Hydro = A
if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit)
wanted_objects |= typecacheof(/obj/machinery/hydroponics) //so we only hunt them while they're alive/seeded/not visisted
- return 1
- if(isliving(A))
- var/mob/living/H = A
- return !H.bee_friendly()
- return 0
+ return TRUE
+ return FALSE
/mob/living/simple_animal/hostile/poison/bees/AttackingTarget()
@@ -187,7 +187,7 @@
if(loc == beehome)
idle = min(100, ++idle)
if(idle >= BEE_IDLE_ROAMING && prob(BEE_PROB_GOROAM))
- forceMove(get_turf(beehome))
+ forceMove(beehome.drop_location())
else
idle = max(0, --idle)
if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME))
@@ -200,6 +200,7 @@
continue
BB.bees |= src
beehome = BB
+ break // End loop after the first compatible find.
/mob/living/simple_animal/hostile/poison/bees/toxin/Initialize()
. = ..()
@@ -215,7 +216,7 @@
//the Queen doesn't leave the box on her own, and she CERTAINLY doesn't pollinate by herself
/mob/living/simple_animal/hostile/poison/bees/queen/Found(atom/A)
- return 0
+ return FALSE
//leave pollination for the peasent bees
@@ -234,10 +235,10 @@
/mob/living/simple_animal/hostile/poison/bees/proc/reagent_incompatible(mob/living/simple_animal/hostile/poison/bees/B)
if(!B)
- return 0
+ return FALSE
if(B.beegent && beegent && B.beegent.id != beegent.id || B.beegent && !beegent || !B.beegent && beegent)
- return 1
- return 0
+ return TRUE
+ return FALSE
/obj/item/queen_bee
@@ -255,7 +256,7 @@
if(S.reagents.has_reagent("royal_bee_jelly")) //checked twice, because I really don't want royal bee jelly to be duped
if(S.reagents.has_reagent("royal_bee_jelly",5))
S.reagents.remove_reagent("royal_bee_jelly", 5)
- var/obj/item/queen_bee/qb = new(get_turf(user))
+ var/obj/item/queen_bee/qb = new(user.drop_location())
qb.queen = new(qb)
if(queen && queen.beegent)
qb.queen.assign_reagent(queen.beegent) //Bees use the global singleton instances of reagents, so we don't need to worry about one bee being deleted and her copies losing their reagents.
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index 9ab6f783f5..d4c9632a03 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -115,7 +115,11 @@
if(can_see(targets_from, HM, vision_range))
. += HM
else
- . = oview(vision_range, targets_from)
+ . = list() // The following code is only very slightly slower than just returning oview(vision_range, targets_from), but it saves us much more work down the line, particularly when bees are involved
+ for (var/obj/A in oview(vision_range, targets_from))
+ . += A
+ for (var/mob/A in oview(vision_range, targets_from))
+ . += A
/mob/living/simple_animal/hostile/proc/FindTarget(var/list/possible_targets, var/HasTargetsList = 0)//Step 2, filter down possible targets to things we actually care about
. = list()
@@ -165,7 +169,7 @@
return chosen_target
// Please do not add one-off mob AIs here, but override this function for your mob
-/mob/living/simple_animal/hostile/CanAttack(atom/the_target)//Can we actually attack a possible target?
+/mob/living/simple_animal/hostile/CanAttack(atom/the_target)//Can we actually attack a possible target?
if(isturf(the_target) || !the_target || the_target.type == /atom/movable/lighting_object) // bail out on invalids
return FALSE
@@ -187,7 +191,7 @@
return FALSE
return TRUE
- if(istype(the_target, /obj/mecha))
+ if(ismecha(the_target))
var/obj/mecha/M = the_target
if(M.occupant)//Just so we don't attack empty mechs
if(CanAttack(M.occupant))
diff --git a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm
index b84f3c8682..378b5d9b8e 100644
--- a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm
@@ -184,7 +184,7 @@
mecha_face_target(target)
target.mech_melee_attack(mecha)
else
- if(istype(target, /obj/mecha))
+ if(ismecha(target))
var/obj/mecha/M = target
if(is_valid_mecha(M))
enter_mecha(M)
@@ -259,7 +259,7 @@
//Yes they actually try and pull this shit
//~simple animals~
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/CanAttack(atom/the_target)
- if(istype(the_target, /obj/mecha))
+ if(ismecha(the_target))
var/obj/mecha/M = the_target
if(mecha)
if(M == mecha || !CanAttack(M.occupant))
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
index d1ddfa9a00..b81d58b329 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
@@ -385,6 +385,7 @@ Difficulty: Medium
melee_damage_lower = 30
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
loot = list()
+ butcher_results = list(/obj/item/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30)
/mob/living/simple_animal/hostile/megafauna/dragon/lesser/grant_achievement(medaltype,scoretype)
return
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
index dda0b3abad..04282d12fd 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
@@ -62,6 +62,9 @@
return TRUE
+ if(isobj(the_target) && is_type_in_typecache(the_target, wanted_objects))
+ return TRUE
+
return FALSE
/mob/living/simple_animal/hostile/asteroid/gutlunch/Destroy()
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm
index 4aa067c9ab..57df489d4e 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm
@@ -1,47 +1,47 @@
-/mob/living/simple_animal/hostile/retaliate
- var/list/enemies = list()
-
-/mob/living/simple_animal/hostile/retaliate/Found(atom/A)
- if(isliving(A))
- var/mob/living/L = A
- if(!L.stat)
- return L
- else
- enemies -= L
- else if(istype(A, /obj/mecha))
- var/obj/mecha/M = A
- if(M.occupant)
- return A
-
-/mob/living/simple_animal/hostile/retaliate/ListTargets()
- if(!enemies.len)
- return list()
- var/list/see = ..()
- see &= enemies // Remove all entries that aren't in enemies
- return see
-
-/mob/living/simple_animal/hostile/retaliate/proc/Retaliate()
- var/list/around = view(src, vision_range)
-
- for(var/atom/movable/A in around)
- if(A == src)
- continue
- if(isliving(A))
- var/mob/living/M = A
- if(faction_check_mob(M) && attack_same || !faction_check_mob(M))
- enemies |= M
- else if(istype(A, /obj/mecha))
- var/obj/mecha/M = A
- if(M.occupant)
- enemies |= M
- enemies |= M.occupant
-
- for(var/mob/living/simple_animal/hostile/retaliate/H in around)
- if(faction_check_mob(H) && !attack_same && !H.attack_same)
- H.enemies |= enemies
- return 0
-
-/mob/living/simple_animal/hostile/retaliate/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
- . = ..()
- if(. > 0 && stat == CONSCIOUS)
- Retaliate()
+/mob/living/simple_animal/hostile/retaliate
+ var/list/enemies = list()
+
+/mob/living/simple_animal/hostile/retaliate/Found(atom/A)
+ if(isliving(A))
+ var/mob/living/L = A
+ if(!L.stat)
+ return L
+ else
+ enemies -= L
+ else if(ismecha(A))
+ var/obj/mecha/M = A
+ if(M.occupant)
+ return A
+
+/mob/living/simple_animal/hostile/retaliate/ListTargets()
+ if(!enemies.len)
+ return list()
+ var/list/see = ..()
+ see &= enemies // Remove all entries that aren't in enemies
+ return see
+
+/mob/living/simple_animal/hostile/retaliate/proc/Retaliate()
+ var/list/around = view(src, vision_range)
+
+ for(var/atom/movable/A in around)
+ if(A == src)
+ continue
+ if(isliving(A))
+ var/mob/living/M = A
+ if(faction_check_mob(M) && attack_same || !faction_check_mob(M))
+ enemies |= M
+ else if(ismecha(A))
+ var/obj/mecha/M = A
+ if(M.occupant)
+ enemies |= M
+ enemies |= M.occupant
+
+ for(var/mob/living/simple_animal/hostile/retaliate/H in around)
+ if(faction_check_mob(H) && !attack_same && !H.attack_same)
+ H.enemies |= enemies
+ return 0
+
+/mob/living/simple_animal/hostile/retaliate/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
+ . = ..()
+ if(. > 0 && stat == CONSCIOUS)
+ Retaliate()
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 4e988c482c..4edf7a6dcb 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -317,7 +317,7 @@
var/mob/living/L = the_target
if(L.stat != CONSCIOUS)
return 0
- if (istype(the_target, /obj/mecha))
+ if (ismecha(the_target))
var/obj/mecha/M = the_target
if (M.occupant)
return 0
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 4f4b99e1e1..c75e0a27fb 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -386,7 +386,7 @@
set category = "Object"
set src = usr
- if(istype(loc, /obj/mecha))
+ if(ismecha(loc))
return
if(incapacitated())
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index a543e0825b..dc87736e5d 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -329,16 +329,14 @@
continue
loc_landmark = sloc.loc
if(!loc_landmark)
- for(var/obj/effect/landmark/tripai in GLOB.landmarks_list)
- if(tripai.name == "tripai")
- if(locate(/mob/living/silicon/ai) in tripai.loc)
- continue
- loc_landmark = tripai.loc
+ for(var/obj/effect/landmark/tripai/L in GLOB.landmarks_list)
+ if(locate(/mob/living/silicon/ai) in L.loc)
+ continue
+ loc_landmark = L.loc
if(!loc_landmark)
to_chat(src, "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone.")
- for(var/obj/effect/landmark/start/sloc in GLOB.landmarks_list)
- if (sloc.name == "AI")
- loc_landmark = sloc.loc
+ for(var/obj/effect/landmark/start/ai/sloc in GLOB.landmarks_list)
+ loc_landmark = sloc.loc
if(!transfer_after)
mind.active = FALSE
diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm
index a3184cbb20..1656a43505 100644
--- a/code/modules/ninja/ninja_event.dm
+++ b/code/modules/ninja/ninja_event.dm
@@ -39,11 +39,9 @@ Contents:
//selecting a spawn_loc
if(!spawn_loc)
var/list/spawn_locs = list()
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
+ for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
- switch(L.name)
- if("ninjaspawn","carpspawn")
- spawn_locs += L.loc
+ spawn_locs += L.loc
if(!spawn_locs.len)
return kill()
spawn_loc = pick(spawn_locs)
diff --git a/code/modules/power/antimatter/shielding.dm b/code/modules/power/antimatter/shielding.dm
index e6814c5c0a..39353737bb 100644
--- a/code/modules/power/antimatter/shielding.dm
+++ b/code/modules/power/antimatter/shielding.dm
@@ -32,16 +32,24 @@
. = ..()
addtimer(CALLBACK(src, .proc/controllerscan), 10)
+/obj/machinery/am_shielding/proc/overheat()
+ visible_message("[src] melts!")
+ new /obj/effect/hotspot(loc)
+ qdel(src)
+
+/obj/machinery/am_shielding/proc/collapse()
+ visible_message("[src] collapses back into a container!")
+ new /obj/item/device/am_shielding_container(drop_location())
+ qdel(src)
/obj/machinery/am_shielding/proc/controllerscan(priorscan = 0)
//Make sure we are the only one here
- if(!istype(src.loc, /turf))
- qdel(src)
- return
+ if(!isturf(loc))
+ collapse()
for(var/obj/machinery/am_shielding/AMS in loc.contents)
if(AMS == src)
continue
- qdel(src)
+ collapse()
return
//Search for shielding first
@@ -59,7 +67,7 @@
if(!priorscan)
addtimer(CALLBACK(src, .proc/controllerscan, 1), 20)
return
- qdel(src)
+ collapse()
/obj/machinery/am_shielding/Destroy()
@@ -67,7 +75,6 @@
control_unit.remove_shielding(src)
if(processing)
shutdown_core()
- visible_message("The [src.name] melts!")
//Might want to have it leave a mess on the floor but no sprites for now
return ..()
@@ -209,7 +216,7 @@
if(injecting_fuel && control_unit)
control_unit.exploding = 1
if(src)
- qdel(src)
+ overheat()
return
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index c64cb4f4ef..3d87de4e62 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -278,7 +278,7 @@
//dist_check - set to only shock mobs within 1 of source (vendors, airlocks, etc.)
//No animations will be performed by this proc.
/proc/electrocute_mob(mob/living/carbon/M, power_source, obj/source, siemens_coeff = 1, dist_check = FALSE)
- if(istype(M.loc, /obj/mecha))
+ if(ismecha(M.loc))
return 0 //feckin mechs are dumb
if(dist_check)
if(!in_range(source,M))
diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm
index 32967e2537..f2610f97b0 100644
--- a/code/modules/power/singularity/containment_field.dm
+++ b/code/modules/power/singularity/containment_field.dm
@@ -58,7 +58,7 @@
if(isliving(mover))
shock(mover)
- if(istype(mover, /obj/machinery) || isstructure(mover) || istype(mover, /obj/mecha))
+ if(istype(mover, /obj/machinery) || isstructure(mover) || ismecha(mover))
bump_field(mover)
/obj/machinery/field/containment/proc/set_master(master1,master2)
@@ -90,13 +90,13 @@
if(isliving(mover))
shock(mover)
return
- if(istype(mover, /obj/machinery) || isstructure(mover) || istype(mover, /obj/mecha))
+ if(istype(mover, /obj/machinery) || isstructure(mover) || ismecha(mover))
bump_field(mover)
return
/obj/machinery/field/CanPass(atom/movable/mover, turf/target)
- if(hasShocked || isliving(mover) || istype(mover, /obj/machinery) || isstructure(mover) || istype(mover, /obj/mecha))
+ if(hasShocked || isliving(mover) || istype(mover, /obj/machinery) || isstructure(mover) || ismecha(mover))
return FALSE
return ..()
diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm
index 4519835c1f..f04c61426b 100644
--- a/code/modules/power/singularity/particle_accelerator/particle.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle.dm
@@ -1,62 +1,65 @@
-/obj/effect/accelerated_particle
- name = "Accelerated Particles"
- desc = "Small things moving very fast."
- icon = 'icons/obj/machines/particle_accelerator.dmi'
- icon_state = "particle"
+/obj/effect/accelerated_particle
+ name = "Accelerated Particles"
+ desc = "Small things moving very fast."
+ icon = 'icons/obj/machines/particle_accelerator.dmi'
+ icon_state = "particle"
anchored = TRUE
density = FALSE
- var/movement_range = 10
- var/energy = 10
- var/speed = 1
-
-/obj/effect/accelerated_particle/weak
- movement_range = 8
- energy = 5
-
-/obj/effect/accelerated_particle/strong
- movement_range = 15
- energy = 15
-
-/obj/effect/accelerated_particle/powerful
- movement_range = 20
- energy = 50
-
-
-/obj/effect/accelerated_particle/New(loc)
- ..()
-
- addtimer(CALLBACK(src, .proc/move), 1)
-
-
+ var/movement_range = 10
+ var/energy = 10
+ var/speed = 1
+
+/obj/effect/accelerated_particle/weak
+ movement_range = 8
+ energy = 5
+
+/obj/effect/accelerated_particle/strong
+ movement_range = 15
+ energy = 15
+
+/obj/effect/accelerated_particle/powerful
+ movement_range = 20
+ energy = 50
+
+
+/obj/effect/accelerated_particle/New(loc)
+ ..()
+
+ addtimer(CALLBACK(src, .proc/move), 1)
+
+
/obj/effect/accelerated_particle/Collide(atom/A)
- if(A)
- if(isliving(A))
- toxmob(A)
- else if(istype(A, /obj/machinery/the_singularitygen))
- var/obj/machinery/the_singularitygen/S = A
- S.energy += energy
- else if(istype(A, /obj/singularity))
- var/obj/singularity/S = A
- S.energy += energy
-
-
-/obj/effect/accelerated_particle/Crossed(atom/A)
- if(isliving(A))
- toxmob(A)
-
-
-/obj/effect/accelerated_particle/ex_act(severity, target)
- qdel(src)
-
-/obj/effect/accelerated_particle/proc/toxmob(mob/living/M)
- M.rad_act(energy*6)
-
-/obj/effect/accelerated_particle/proc/move()
- if(!step(src,dir))
- forceMove(get_step(src,dir))
- movement_range--
- if(movement_range == 0)
- qdel(src)
- else
- sleep(speed)
- move()
+ if(A)
+ if(isliving(A))
+ toxmob(A)
+ else if(istype(A, /obj/machinery/the_singularitygen))
+ var/obj/machinery/the_singularitygen/S = A
+ S.energy += energy
+ else if(istype(A, /obj/singularity))
+ var/obj/singularity/S = A
+ S.energy += energy
+ else if(istype(A, /obj/structure/blob))
+ var/obj/structure/blob/B = A
+ B.take_damage(energy*0.6)
+ movement_range = 0
+
+/obj/effect/accelerated_particle/Crossed(atom/A)
+ if(isliving(A))
+ toxmob(A)
+
+
+/obj/effect/accelerated_particle/ex_act(severity, target)
+ qdel(src)
+
+/obj/effect/accelerated_particle/proc/toxmob(mob/living/M)
+ M.rad_act(energy*6)
+
+/obj/effect/accelerated_particle/proc/move()
+ if(!step(src,dir))
+ forceMove(get_step(src,dir))
+ movement_range--
+ if(movement_range == 0)
+ qdel(src)
+ else
+ sleep(speed)
+ move()
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 84db583282..3aba80fe64 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -144,7 +144,7 @@
ignore_source_check = TRUE
return FALSE
if(firer && !ignore_source_check)
- if(A == firer || (A == firer.loc && istype(A, /obj/mecha))) //cannot shoot yourself or your mech
+ if(A == firer || (A == firer.loc && ismecha(A))) //cannot shoot yourself or your mech
loc = A.loc
return FALSE
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index 79a3d51eec..a5ba7c15a4 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -45,7 +45,7 @@
..()
explosion(target, -1, 1, 3, 1, 0, flame_range = 4)
- if(istype(target, /obj/mecha))
+ if(ismecha(target))
var/obj/mecha/M = target
M.take_damage(anti_armour_damage)
if(issilicon(target))
diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm
index 5d089739d1..946ec70d38 100644
--- a/code/modules/research/designs/autolathe_designs.dm
+++ b/code/modules/research/designs/autolathe_designs.dm
@@ -608,6 +608,14 @@
build_path = /obj/item/device/electropack
category = list("hacked", "Tools")
+/datum/design/shock_collar
+ name = "Shock Collar"
+ id = "shock_collar"
+ build_type = AUTOLATHE
+ materials = list(MAT_METAL = 5000, MAT_GLASS = 2000)
+ build_path = /obj/item/device/electropack/shockcollar
+ category = list("hacked", "Security")
+
/datum/design/large_welding_tool
name = "Industrial Welding Tool"
id = "large_welding_tool"
diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm
index 650eebba1a..0cef65c07c 100644
--- a/code/modules/research/message_server.dm
+++ b/code/modules/research/message_server.dm
@@ -67,6 +67,7 @@ GLOBAL_LIST_INIT(message_servers, list())
icon = 'icons/obj/machines/research.dmi'
icon_state = "server"
name = "Messaging Server"
+ desc = "A machine that attempts to gather the secret knowledge of the universe."
density = TRUE
anchored = TRUE
use_power = IDLE_POWER_USE
diff --git a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm
index 5e0f43c7a9..1cc5b482f0 100644
--- a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm
+++ b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm
@@ -25,6 +25,9 @@
if(H.stat)
visible_message("Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs.")
playsound(get_turf(src),'sound/magic/demon_consume.ogg', 100, 1)
+ for(var/obj/item/W in H)
+ if(!H.dropItemToGround(W))
+ qdel(W)
if(ismegafauna(H))
meat_counter += 20
else
diff --git a/code/modules/server_tools/st_interface.dm b/code/modules/server_tools/st_interface.dm
index 12fb5a85c2..10b7f920e8 100644
--- a/code/modules/server_tools/st_interface.dm
+++ b/code/modules/server_tools/st_interface.dm
@@ -89,6 +89,8 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE)
return "No message set!"
SERVER_TOOLS_WORLD_ANNOUNCE(msg)
return "SUCCESS"
+ if(SERVICE_CMD_PLAYER_COUNT)
+ return "[SERVER_TOOLS_CLIENT_COUNT]"
if(SERVICE_CMD_LIST_CUSTOM)
return json_encode(ListServiceCustomCommands(FALSE))
else
diff --git a/code/modules/shuttle/computer.dm b/code/modules/shuttle/computer.dm
index 8384e978e5..47ceaef99e 100644
--- a/code/modules/shuttle/computer.dm
+++ b/code/modules/shuttle/computer.dm
@@ -1,5 +1,6 @@
/obj/machinery/computer/shuttle
name = "shuttle console"
+ desc = "A shuttle control computer."
icon_screen = "shuttle"
icon_keyboard = "tech_key"
light_color = LIGHT_COLOR_CYAN
diff --git a/code/modules/shuttle/ferry.dm b/code/modules/shuttle/ferry.dm
index 5b27e562f3..07103088d1 100644
--- a/code/modules/shuttle/ferry.dm
+++ b/code/modules/shuttle/ferry.dm
@@ -1,5 +1,6 @@
/obj/machinery/computer/shuttle/ferry
name = "transport ferry console"
+ desc = "A console that controls the transport ferry."
circuit = /obj/item/circuitboard/computer/ferry
shuttleId = "ferry"
possible_destinations = "ferry_home;ferry_away"
diff --git a/code/modules/shuttle/syndicate.dm b/code/modules/shuttle/syndicate.dm
index ac1339d33e..4574e62bd1 100644
--- a/code/modules/shuttle/syndicate.dm
+++ b/code/modules/shuttle/syndicate.dm
@@ -2,6 +2,7 @@
/obj/machinery/computer/shuttle/syndicate
name = "syndicate shuttle terminal"
+ desc = "The terminal used to control the syndicate transport shuttle."
circuit = /obj/item/circuitboard/computer/syndicate_shuttle
icon_screen = "syndishuttle"
icon_keyboard = "syndie_key"
@@ -13,6 +14,7 @@
/obj/machinery/computer/shuttle/syndicate/recall
name = "syndicate shuttle recall terminal"
+ desc = "Use this if your friends left you behind."
possible_destinations = "syndicate_away"
@@ -27,6 +29,7 @@
/obj/machinery/computer/shuttle/syndicate/drop_pod
name = "syndicate assault pod control"
+ desc = "Controls the drop pod's launch system."
icon = 'icons/obj/terminals.dmi'
icon_state = "dorm_available"
light_color = LIGHT_COLOR_BLUE
diff --git a/code/modules/spells/spell_types/godhand.dm b/code/modules/spells/spell_types/godhand.dm
index 455f5ef165..33f947408a 100644
--- a/code/modules/spells/spell_types/godhand.dm
+++ b/code/modules/spells/spell_types/godhand.dm
@@ -49,6 +49,9 @@
/obj/item/melee/touch_attack/disintegrate/afterattack(atom/target, mob/living/carbon/user, proximity)
if(!proximity || target == user || !ismob(target) || !iscarbon(user) || user.lying || user.handcuffed) //exploding after touching yourself would be bad
return
+ if(!user.can_speak_vocal())
+ to_chat(user, "You can't get the words out!")
+ return
var/mob/M = target
do_sparks(4, FALSE, M.loc)
M.gib()
@@ -68,6 +71,9 @@
if(user.lying || user.handcuffed)
to_chat(user, "You can't reach out!")
return
+ if(!user.can_speak_vocal())
+ to_chat(user, "You can't get the words out!")
+ return
var/mob/living/M = target
M.Stun(40)
M.petrify()
diff --git a/code/modules/spells/spell_types/shadow_walk.dm b/code/modules/spells/spell_types/shadow_walk.dm
index 45ea521098..9f9b4ac223 100644
--- a/code/modules/spells/spell_types/shadow_walk.dm
+++ b/code/modules/spells/spell_types/shadow_walk.dm
@@ -25,8 +25,9 @@
if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
playsound(get_turf(user), 'sound/magic/ethereal_enter.ogg', 50, 1, -1)
visible_message("[user] melts into the shadows!")
- user.AdjustStun(-20, 0)
- user.AdjustKnockdown(-20, 0)
+ user.SetStun(0, FALSE)
+ user.SetKnockdown(0, FALSE)
+ user.setStaminaLoss(0, 0)
var/obj/effect/dummy/shadow/S2 = new(get_turf(user.loc))
user.forceMove(S2)
S2.jaunter = user
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index f5a00d24cb..4fdda7a7bc 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -10,6 +10,8 @@
var/slot
// DO NOT add slots with matching names to different zones - it will break internal_organs_slot list!
var/vital = 0
+ //Was this organ implanted/inserted/etc, if true will not be removed during species change.
+ var/external = FALSE
/obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
diff --git a/code/modules/uplink/uplink_item_cit.dm b/code/modules/uplink/uplink_item_cit.dm
index 3aa1fd8bb1..40c74269eb 100644
--- a/code/modules/uplink/uplink_item_cit.dm
+++ b/code/modules/uplink/uplink_item_cit.dm
@@ -55,7 +55,7 @@
/datum/uplink_item/ammo/pistolzzz
name = "10mm Soporific Magazine"
desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with soporific rounds that put the target to sleep. \
- NOTE: Soporific is not instant acting due to the constraints of the round's scale. Will usually require two shots to take effect."
+ NOTE: Soporific is not instant acting due to the constraints of the round's scale. Will usually require three shots to take effect."
item = /obj/item/ammo_box/magazine/m10mm/soporific
cost = 2
diff --git a/config/config.txt b/config/config.txt
index 079ec0d9c6..d5d2725714 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -286,7 +286,7 @@ ANNOUNCE_ADMIN_LOGOUT
## Map rotation
## You should edit maps.txt to match your configuration when you enable this.
-#MAPROTATION
+MAPROTATION
## Map voting
## Allows players to vote for their preffered map
diff --git a/html/changelogs/AutoChangeLog-pr-2922.yml b/html/changelogs/AutoChangeLog-pr-2922.yml
new file mode 100644
index 0000000000..f46c3136a6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-2922.yml
@@ -0,0 +1,6 @@
+author: "Daniel0Mclovin"
+delete-after: True
+changes:
+ - rscadd: "Podpeople to roundstart"
+ - tweak: "Modified podpeople heatmod from 1.25 to 1.5"
+ - tweak: "plant-b-gone now does roughly 7 damage per tick on podpeople"
diff --git a/html/changelogs/AutoChangeLog-pr-2938.yml b/html/changelogs/AutoChangeLog-pr-2938.yml
new file mode 100644
index 0000000000..36a1129534
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-2938.yml
@@ -0,0 +1,4 @@
+author: "Arianya"
+delete-after: True
+changes:
+ - balance: "Lesser ash drakes no longer drop ash drake hide when butchered."
diff --git a/html/changelogs/AutoChangeLog-pr-2965.yml b/html/changelogs/AutoChangeLog-pr-2965.yml
new file mode 100644
index 0000000000..98ec6c9b83
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-2965.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - tweak: "Wizard cannot cast spoken or whispered spells while mute"
diff --git a/html/changelogs/AutoChangeLog-pr-3056.yml b/html/changelogs/AutoChangeLog-pr-3056.yml
new file mode 100644
index 0000000000..7963eca536
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3056.yml
@@ -0,0 +1,4 @@
+author: "MrDoomBringer"
+delete-after: True
+changes:
+ - rscadd: "Nanotrasen, as part of their new Employee Retention program, has encouraged more station point-makery by adding the \"Cargo Tech of the Shift\"! The award is located in a lockbox in the Quartermaster's locker."
diff --git a/html/changelogs/AutoChangeLog-pr-3063.yml b/html/changelogs/AutoChangeLog-pr-3063.yml
new file mode 100644
index 0000000000..a8c291e06f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3063.yml
@@ -0,0 +1,5 @@
+author: "XDTM"
+delete-after: True
+changes:
+ - bugfix: "Fixed a bug where Viral Aggressive Metabolism caused viruses to be cured instantly."
+ - bugfix: "Fixed a bug where viruses' symptoms would all instantly activate on infection."
diff --git a/html/changelogs/AutoChangeLog-pr-3071.yml b/html/changelogs/AutoChangeLog-pr-3071.yml
new file mode 100644
index 0000000000..924aea5179
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3071.yml
@@ -0,0 +1,4 @@
+author: "Joan"
+delete-after: True
+changes:
+ - bugfix: "Fixes Vanguard never stunning for more than 2 seconds."
diff --git a/html/changelogs/AutoChangeLog-pr-3085.yml b/html/changelogs/AutoChangeLog-pr-3085.yml
new file mode 100644
index 0000000000..90001fc8b9
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3085.yml
@@ -0,0 +1,4 @@
+author: "Toriate"
+delete-after: True
+changes:
+ - balance: "10mm Soporific bullets now have a threshold of 60 stamina damage, up from 40, and deal 25 with each shot, down from 50"
diff --git a/html/changelogs/AutoChangeLog-pr-3086.yml b/html/changelogs/AutoChangeLog-pr-3086.yml
new file mode 100644
index 0000000000..90798d5475
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3086.yml
@@ -0,0 +1,4 @@
+author: "Toriate"
+delete-after: True
+changes:
+ - spellcheck: "uplink description for soporific magazines now correctly says at least three shots are needed, rather than two"
diff --git a/html/changelogs/AutoChangeLog-pr-3088.yml b/html/changelogs/AutoChangeLog-pr-3088.yml
new file mode 100644
index 0000000000..1f32d861a6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3088.yml
@@ -0,0 +1,5 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - rscadd: "Wormhole event wormholes now actually teleport you."
+ - bugfix: "portals now actually teleport on click."
diff --git a/html/changelogs/AutoChangeLog-pr-3089.yml b/html/changelogs/AutoChangeLog-pr-3089.yml
new file mode 100644
index 0000000000..0ee37ab23d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3089.yml
@@ -0,0 +1,4 @@
+author: "Thefastfoodguy"
+delete-after: True
+changes:
+ - bugfix: "Antimatter shielding that can't find a control unit won't delete itself anymore"
diff --git a/html/changelogs/AutoChangeLog-pr-3092.yml b/html/changelogs/AutoChangeLog-pr-3092.yml
new file mode 100644
index 0000000000..efb4de6d35
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3092.yml
@@ -0,0 +1,4 @@
+author: "Thefastfoodguy"
+delete-after: True
+changes:
+ - bugfix: "Silicons can no longer take brain damage"
diff --git a/html/changelogs/AutoChangeLog-pr-3093.yml b/html/changelogs/AutoChangeLog-pr-3093.yml
new file mode 100644
index 0000000000..bc2a009a41
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3093.yml
@@ -0,0 +1,6 @@
+author: "Shock Collars"
+delete-after: True
+changes:
+ - rscadd: "Added Shock Collars to hacked autolathes."
+ - imageadd: "On character sprites, credit to Toriate"
+ - imageadd: "Object sprite, credit to Toriate"
diff --git a/html/changelogs/AutoChangeLog-pr-3096.yml b/html/changelogs/AutoChangeLog-pr-3096.yml
new file mode 100644
index 0000000000..4031580453
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3096.yml
@@ -0,0 +1,4 @@
+author: "Kor"
+delete-after: True
+changes:
+ - bugfix: "You can now tell when someone is in soft crit by examining them."
diff --git a/html/changelogs/AutoChangeLog-pr-3102.yml b/html/changelogs/AutoChangeLog-pr-3102.yml
new file mode 100644
index 0000000000..bc737b6a13
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3102.yml
@@ -0,0 +1,4 @@
+author: "Naksu"
+delete-after: True
+changes:
+ - bugfix: "Bees now come with reduced amounts of free lag"
diff --git a/html/changelogs/AutoChangeLog-pr-3104.yml b/html/changelogs/AutoChangeLog-pr-3104.yml
new file mode 100644
index 0000000000..e6f9d22374
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3104.yml
@@ -0,0 +1,4 @@
+author: "More Robust Than You"
+delete-after: True
+changes:
+ - balance: "Blobs now take damage from particle accelerators"
diff --git a/html/changelogs/AutoChangeLog-pr-3108.yml b/html/changelogs/AutoChangeLog-pr-3108.yml
new file mode 100644
index 0000000000..f1e03db19a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3108.yml
@@ -0,0 +1,4 @@
+author: "XDTM"
+delete-after: True
+changes:
+ - rscadd: "The CMO now has an advanced health analyzer in his closet! It can give more precise readings on the non-standard damage types."
diff --git a/html/changelogs/AutoChangeLog-pr-3110.yml b/html/changelogs/AutoChangeLog-pr-3110.yml
new file mode 100644
index 0000000000..7d06447f99
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3110.yml
@@ -0,0 +1,4 @@
+author: "Kor"
+delete-after: True
+changes:
+ - rscadd: "Nightmares now have mutant hearts and brains, with their own special properties when consumed or implanted in mobs. Experiment!"
diff --git a/html/changelogs/AutoChangeLog-pr-3115.yml b/html/changelogs/AutoChangeLog-pr-3115.yml
new file mode 100644
index 0000000000..c3a194f971
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3115.yml
@@ -0,0 +1,4 @@
+author: "Naksu"
+delete-after: True
+changes:
+ - bugfix: "Gutlunches will now once again look for gibs to eat."
diff --git a/icons/mob/accessories.dmi b/icons/mob/accessories.dmi
index 3e73083e3e..8e3e48230f 100644
Binary files a/icons/mob/accessories.dmi and b/icons/mob/accessories.dmi differ
diff --git a/icons/mob/neck.dmi b/icons/mob/neck.dmi
index fb43ae85ec..17f9d3ade4 100644
Binary files a/icons/mob/neck.dmi and b/icons/mob/neck.dmi differ
diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi
index 13141a4d4e..9ec6c06c9f 100644
Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ
diff --git a/icons/obj/abductor.dmi b/icons/obj/abductor.dmi
index 21ab5cf9f5..64a877c2a1 100644
Binary files a/icons/obj/abductor.dmi and b/icons/obj/abductor.dmi differ
diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi
index c0756a9f73..4c3c0fe5ce 100644
Binary files a/icons/obj/clothing/accessories.dmi and b/icons/obj/clothing/accessories.dmi differ
diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi
index 40c4aa03bc..c41db68326 100644
Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index 53930d778c..9d9801f3a2 100644
Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ
diff --git a/icons/obj/custom.dmi b/icons/obj/custom.dmi
index 3b812e445a..c8b96b8469 100644
Binary files a/icons/obj/custom.dmi and b/icons/obj/custom.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 79f0a207d4..71ce7d6df5 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi
index ae61dc2852..cb5499487d 100644
Binary files a/icons/turf/areas.dmi and b/icons/turf/areas.dmi differ
diff --git a/interface/interface.dm b/interface/interface.dm
index 9d420e9821..a67cc5d290 100644
--- a/interface/interface.dm
+++ b/interface/interface.dm
@@ -65,7 +65,9 @@
message += GLOB.revdata.GetTestMergeInfo(FALSE)
if(tgalert(src, message, "Report Issue","Yes","No")=="No")
return
- src << link("[githuburl]/issues/new")
+ var/static/issue_template = file2text(".github/ISSUE_TEMPLATE.md")
+ var/servername = CONFIG_GET(string/servername)
+ src << link("[githuburl]/issues/new[GLOB.round_id ? "?body=[url_encode("Issue reported from Round ID: [GLOB.round_id][servername ? " ([servername])" : ""]\n\n[issue_template]")]" : ""]")
else
to_chat(src, "The Github URL is not set in the server configuration.")
return
diff --git a/strings/names/nightmare.txt b/strings/names/nightmare.txt
new file mode 100644
index 0000000000..b8798b734d
--- /dev/null
+++ b/strings/names/nightmare.txt
@@ -0,0 +1,10 @@
+U'ruan
+Y`shej
+Nex
+Hel-uae
+Noaey'gief
+Mii`mahza
+Amerziox
+Gyrg-mylin
+Kanet'pruunance
+Vigistaezian
\ No newline at end of file
diff --git a/tools/WebhookProcessor/github_webhook_processor.php b/tools/WebhookProcessor/github_webhook_processor.php
index a8b32c7a92..ede37e4428 100644
--- a/tools/WebhookProcessor/github_webhook_processor.php
+++ b/tools/WebhookProcessor/github_webhook_processor.php
@@ -209,7 +209,7 @@ function tag_pr($payload, $opened) {
$tags[] = 'Merge Conflict';
$treetags = array('_maps' => 'Map Edit', 'tools' => 'Tools', 'SQL' => 'SQL');
- $addonlytags = array('icons' => 'Sprites', 'sounds' => 'Sound', 'config' => 'Config Update');
+ $addonlytags = array('icons' => 'Sprites', 'sounds' => 'Sound', 'config' => 'Config Update', 'code/controllers/configuration/entries' => 'Config Update');
foreach($treetags as $tree => $tag)
if(has_tree_been_edited($payload, $tree))
$tags[] = $tag;