Merge branch 'master' into TGUIs_Nexties

This commit is contained in:
Arturlang
2020-01-30 20:46:20 +02:00
committed by GitHub
418 changed files with 3862 additions and 4206 deletions
+3
View File
@@ -6,3 +6,6 @@ indent_size = 4
[*.yml]
indent_style = space
indent_size = 2
[*.txt]
insert_final_newline = false
+15 -15
View File
@@ -1,6 +1,5 @@
##Citadel Station 13 <BR>
Based and maintained from /tg/station.<BR>
## Citadel Station 13
Based and maintained from /tg/station.
[![forthebadge](http://forthebadge.com/images/badges/60-percent-of-the-time-works-every-time.svg)](https://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/pretty-risque.svg)](https://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/you-didnt-ask-for-this.svg)](http://forthebadge.com)
@@ -10,18 +9,19 @@ Based and maintained from /tg/station.<BR>
[![Percentage of issues still open](http://isitmaintained.com/badge/open/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Percentage of issues still open") [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Average time to resolve an issue")
**Upstream Information** <BR>
**Website:** http://www.tgstation13.org <BR>
**Code:** https://github.com/tgstation/tgstation <BR>
**Wiki** http://tgstation13.org/wiki/Main_Page <BR>
**IRC:** irc://irc.rizon.net/coderbus or if you dont have an IRC client, you can click [here](https://kiwiirc.com/client/irc.rizon.net:6667/?&theme=cli#coderbus).<BR>
**Citadel Station Information** <BR>
**Forums:** http://citadel-station.net/forum/ <BR>
**Ban Appeals:** http://citadel-station.net/forum/forumdisplay.php?fid=8 <BR>
**Code:** https://github.com/Citadel-Station-13/Citadel-Station-13 <BR>
**Discord:** [Here](https://discord.gg/E6SQuhz). <BR>
**Upstream Information**
**Website:** https://tgstation13.org
**Code:** https://github.com/tgstation/tgstation
**Wiki** https://tgstation13.org/wiki/Main_Page
**IRC:** irc://irc.rizon.net/coderbus or if you dont have an IRC client, you can click [here](https://kiwiirc.com/client/irc.rizon.net:6667/?&theme=cli#coderbus).
**Citadel Station Information**
**Website:** http://citadel-station.net
**Forums:** http://citadel-station.net/forum
**Ban Appeals:** http://citadel-station.net/forum/forumdisplay.php?fid=8
**Code:** https://github.com/Citadel-Station-13/Citadel-Station-13
**Discord:** [Here](https://discord.gg/E6SQuhz)
## DOWNLOADING
There are a number of ways to download the source code. Some are described here, an alternative all-inclusive guide is also located at http://www.tgstation13.org/wiki/Downloading_the_source_code
+268 -248
View File
@@ -173,6 +173,19 @@
"aay" = (
/turf/open/floor/plating,
/area/security/prison)
"aaz" = (
/obj/structure/lattice/catwalk,
/obj/item/stack/marker_beacon{
anchored = 1;
icon_state = "markerburgundy-on";
light_color = "#FA644B";
light_power = 3;
light_range = 3;
name = "Docking Beacon";
picked_color = "Burgundy"
},
/turf/open/space/basic,
/area/space/nearstation)
"aaA" = (
/obj/machinery/seed_extractor,
/turf/open/floor/plasteel,
@@ -234,10 +247,46 @@
/obj/structure/chair/stool,
/turf/open/floor/plasteel,
/area/security/prison)
"aaK" = (
/obj/structure/lattice/catwalk,
/obj/item/stack/marker_beacon{
anchored = 1;
icon_state = "markerburgundy-on";
light_color = "#FA644B";
light_power = 3;
light_range = 3;
name = "Docking Beacon";
picked_color = "Burgundy"
},
/turf/open/floor/plating,
/area/space/nearstation)
"aaL" = (
/obj/machinery/photocopier,
/turf/open/floor/wood,
/area/library)
"aaM" = (
/obj/structure/disposalpipe/segment,
/obj/structure/cable{
icon_state = "1-2"
},
/obj/structure/cable{
icon_state = "2-8"
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/effect/turf_decal/tile/brown,
/obj/effect/turf_decal/tile/brown{
dir = 8
},
/turf/open/floor/plasteel,
/area/quartermaster/office)
"aaN" = (
/obj/structure/chair/sofa/right,
/turf/open/floor/plasteel,
/area/security/prison)
"aaO" = (
/obj/effect/spawner/lootdrop/keg,
/turf/open/floor/plating,
/area/maintenance/starboard/aft)
"aaP" = (
/obj/machinery/computer/cryopod{
dir = 8;
@@ -248,6 +297,12 @@
},
/turf/open/floor/plasteel,
/area/security/prison)
"aaQ" = (
/obj/structure/sign/poster/contraband/random{
pixel_y = 32
},
/turf/open/floor/plating,
/area/maintenance/starboard/aft)
"aaR" = (
/obj/structure/lattice,
/obj/structure/sign/warning/securearea{
@@ -285,6 +340,15 @@
},
/turf/open/floor/plasteel,
/area/security/prison)
"aaY" = (
/obj/structure/closet,
/obj/effect/spawner/lootdrop/maintenance{
lootcount = 4;
name = "4maintenance loot spawner"
},
/obj/item/poster/random_official,
/turf/open/floor/plating,
/area/maintenance/starboard/aft)
"aaZ" = (
/turf/closed/wall/r_wall,
/area/ai_monitored/security/armory)
@@ -505,6 +569,11 @@
"abF" = (
/turf/open/floor/plasteel/freezer,
/area/security/prison)
"abG" = (
/obj/structure/door_assembly/door_assembly_mai,
/obj/item/electronics/airlock,
/turf/open/floor/plating,
/area/maintenance/starboard/aft)
"abH" = (
/obj/structure/table,
/obj/item/storage/box/chemimp{
@@ -1565,6 +1634,10 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/carpet,
/area/crew_quarters/heads/hos)
"adO" = (
/obj/effect/spawner/structure/window/shuttle,
/turf/open/floor/plating/airless,
/area/space/nearstation)
"adP" = (
/obj/structure/cable{
icon_state = "2-8"
@@ -1979,6 +2052,34 @@
},
/turf/open/floor/plating,
/area/maintenance/fore/secondary)
"aeD" = (
/obj/structure/grille/broken,
/turf/open/floor/plating/airless,
/area/space/nearstation)
"aeE" = (
/obj/structure/girder,
/turf/open/floor/plating/airless,
/area/space/nearstation)
"aeF" = (
/obj/machinery/airalarm{
dir = 4;
pixel_x = -23
},
/obj/machinery/computer/station_alert{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"aeG" = (
/obj/structure/cable,
/obj/machinery/power/solar{
@@ -2357,6 +2458,12 @@
},
/turf/open/floor/plasteel,
/area/security/main)
"afn" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 4
},
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"afo" = (
/obj/machinery/door/airlock/external{
name = "Escape Pod Three"
@@ -2377,6 +2484,39 @@
},
/turf/open/space/basic,
/area/space)
"afq" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"afr" = (
/obj/machinery/atmospherics/pipe/manifold4w/scrubbers,
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"afs" = (
/obj/machinery/computer/security/telescreen/entertainment{
pixel_x = -31
},
/obj/machinery/computer/monitor{
dir = 4
},
/obj/structure/cable{
icon_state = "0-4"
},
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"aft" = (
/obj/machinery/atmospherics/pipe/simple/general/visible{
dir = 5
@@ -2687,6 +2827,15 @@
/obj/machinery/atmospherics/pipe/manifold4w/general/visible,
/turf/open/floor/plasteel,
/area/engine/atmos)
"age" = (
/obj/structure/chair/office/dark{
dir = 8
},
/obj/structure/cable{
icon_state = "4-8"
},
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"agf" = (
/obj/structure/table,
/obj/item/stack/sheet/metal,
@@ -2836,6 +2985,10 @@
/obj/machinery/suit_storage_unit/security,
/turf/open/floor/plasteel/showroomfloor,
/area/security/warden)
"agv" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"agw" = (
/obj/structure/table,
/obj/machinery/syndicatebomb/training,
@@ -2965,6 +3118,14 @@
},
/turf/open/floor/plasteel,
/area/security/main)
"agH" = (
/obj/machinery/bluespace_beacon,
/obj/effect/turf_decal/stripes/line{
dir = 4
},
/obj/effect/landmark/start/cyborg,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"agI" = (
/obj/machinery/airalarm{
pixel_y = 23
@@ -3094,6 +3255,12 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/security/warden)
"agX" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 4
},
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"agY" = (
/obj/structure/table,
/obj/item/storage/fancy/donut_box,
@@ -3334,6 +3501,16 @@
},
/turf/open/floor/plasteel/showroomfloor,
/area/security/warden)
"ahw" = (
/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden,
/obj/structure/cable{
icon_state = "2-4"
},
/obj/structure/cable{
icon_state = "1-2"
},
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"ahx" = (
/obj/structure/cable{
icon_state = "4-8"
@@ -4474,6 +4651,16 @@
/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden,
/turf/open/floor/plasteel,
/area/security/brig)
"ajC" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/structure/cable{
icon_state = "4-8"
},
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"ajD" = (
/obj/structure/cable{
icon_state = "4-8"
@@ -4682,6 +4869,18 @@
/obj/effect/mapping_helpers/airlock/cyclelink_helper,
/turf/open/floor/plating,
/area/maintenance/solars/port/fore)
"ajX" = (
/obj/machinery/computer/teleporter{
dir = 8
},
/turf/open/floor/plating,
/area/ai_monitored/turret_protected/aisat_interior)
"ajY" = (
/obj/machinery/holopad,
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/effect/landmark/start/cyborg,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat/atmos)
"ajZ" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/sign/warning/vacuum/external{
@@ -4965,6 +5164,18 @@
},
/turf/open/floor/plasteel,
/area/security/courtroom)
"akz" = (
/obj/structure/cable{
icon_state = "1-2"
},
/obj/machinery/holopad,
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/obj/effect/landmark/start/cyborg,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"akA" = (
/obj/structure/chair{
dir = 8;
@@ -29979,17 +30190,6 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
"bwc" = (
/obj/structure/disposalpipe/segment,
/obj/structure/cable{
icon_state = "1-2"
},
/obj/structure/cable{
icon_state = "2-8"
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel,
/area/quartermaster/office)
"bwd" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -49288,47 +49488,9 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"ctu" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 4
},
/obj/effect/landmark/start/cyborg,
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"ctv" = (
/turf/closed/wall/r_wall,
/area/space/nearstation)
"ctw" = (
/obj/machinery/airalarm{
dir = 4;
pixel_x = -23
},
/obj/machinery/computer/station_alert,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"ctx" = (
/obj/machinery/atmospherics/pipe/manifold4w/scrubbers,
/obj/effect/landmark/start/cyborg,
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"cty" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/obj/effect/landmark/start/cyborg,
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"ctz" = (
/obj/machinery/door/poddoor/shutters{
id = "teledoor";
@@ -49373,41 +49535,6 @@
},
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"ctG" = (
/obj/structure/chair/office/dark{
dir = 8
},
/obj/structure/cable{
icon_state = "4-8"
},
/obj/effect/landmark/start/cyborg,
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"ctH" = (
/obj/machinery/computer/security/telescreen/entertainment{
pixel_x = -31
},
/obj/machinery/computer/monitor,
/obj/structure/cable{
icon_state = "0-4"
},
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"ctI" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/effect/landmark/start/cyborg,
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"ctJ" = (
/obj/machinery/holopad,
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
@@ -49431,13 +49558,6 @@
},
/turf/open/floor/plating,
/area/ai_monitored/turret_protected/aisat_interior)
"ctM" = (
/obj/machinery/bluespace_beacon,
/obj/effect/turf_decal/stripes/line{
dir = 4
},
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"ctN" = (
/obj/machinery/atmospherics/pipe/simple/yellow/visible{
dir = 10
@@ -49445,13 +49565,6 @@
/obj/structure/lattice,
/turf/open/space,
/area/space/nearstation)
"ctP" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 4
},
/obj/effect/landmark/start/cyborg,
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"ctQ" = (
/obj/structure/table,
/obj/machinery/microwave{
@@ -49477,28 +49590,6 @@
/obj/structure/sign/warning/radiation/rad_area,
/turf/closed/wall,
/area/engine/engineering)
"ctS" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/structure/cable{
icon_state = "4-8"
},
/obj/effect/landmark/start/cyborg,
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"ctT" = (
/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden,
/obj/structure/cable{
icon_state = "2-4"
},
/obj/structure/cable{
icon_state = "1-2"
},
/obj/effect/landmark/start/cyborg,
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
"ctU" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -49521,10 +49612,6 @@
/obj/structure/chair,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"ctW" = (
/obj/machinery/computer/teleporter,
/turf/open/floor/plating,
/area/ai_monitored/turret_protected/aisat_interior)
"ctX" = (
/obj/machinery/camera{
c_tag = "MiniSat Teleporter";
@@ -49805,11 +49892,6 @@
},
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat/atmos)
"cuC" = (
/obj/machinery/holopad,
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat/atmos)
"cuD" = (
/obj/machinery/light/small{
dir = 8
@@ -49858,17 +49940,6 @@
},
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"cuG" = (
/obj/structure/cable{
icon_state = "1-2"
},
/obj/machinery/holopad,
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"cuH" = (
/obj/machinery/light/small{
dir = 8
@@ -53259,13 +53330,6 @@
},
/turf/open/floor/mineral/titanium/blue,
/area/crew_quarters/dorms)
"dkk" = (
/obj/machinery/photocopier{
pixel_x = -5;
pixel_y = -5
},
/turf/open/floor/wood,
/area/library)
"dok" = (
/obj/item/twohanded/required/kirbyplants{
icon_state = "plant-22"
@@ -53692,18 +53756,6 @@
dir = 1
},
/area/crew_quarters/fitness)
"fsk" = (
/obj/structure/lattice/catwalk,
/obj/item/stack/marker_beacon{
anchored = 1;
icon_state = "markerburgundy-on";
light_power = 3;
light_range = 3;
name = "Docking Beacon";
picked_color = "Burgundy"
},
/turf/open/floor/plating,
/area/space/nearstation)
"ftv" = (
/obj/structure/table,
/obj/effect/spawner/lootdrop/maintenance{
@@ -54203,18 +54255,6 @@
dir = 1
},
/area/crew_quarters/fitness)
"hho" = (
/obj/structure/lattice/catwalk,
/obj/item/stack/marker_beacon{
anchored = 1;
icon_state = "markerburgundy-on";
light_power = 3;
light_range = 3;
name = "Docking Beacon";
picked_color = "Burgundy"
},
/turf/open/space/basic,
/area/space/nearstation)
"hik" = (
/obj/structure/lattice/catwalk,
/obj/structure/cable{
@@ -54439,9 +54479,6 @@
"iiW" = (
/turf/open/floor/wood,
/area/maintenance/bar)
"ikx" = (
/turf/open/floor/plating/foam,
/area/space/nearstation)
"ilJ" = (
/obj/effect/turf_decal/tile/red,
/obj/machinery/light{
@@ -55678,10 +55715,6 @@
/obj/structure/extinguisher_cabinet,
/turf/closed/wall/r_wall,
/area/hallway/primary/central)
"mwb" = (
/obj/effect/spawner/structure/window/shuttle,
/turf/open/floor/plating,
/area/space/nearstation)
"mwO" = (
/obj/structure/cable{
icon_state = "1-4"
@@ -56489,7 +56522,8 @@
icon_state = "4-8"
},
/obj/machinery/door/airlock/command{
name = "Command Access To Vault"
name = "Command Access To Vault";
req_access = "19"
},
/turf/open/floor/plasteel/dark,
/area/bridge/meeting_room)
@@ -56803,10 +56837,6 @@
/obj/item/target/syndicate,
/turf/open/floor/plating,
/area/security/prison)
"rxH" = (
/obj/structure/girder,
/turf/open/floor/plating,
/area/space/nearstation)
"rzg" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -57253,12 +57283,6 @@
},
/turf/open/floor/plating,
/area/maintenance/port/aft)
"thr" = (
/obj/structure/frame/computer{
dir = 1
},
/turf/open/floor/plating,
/area/space/nearstation)
"tkU" = (
/turf/open/floor/wood{
icon_state = "wood-broken5"
@@ -58002,10 +58026,10 @@
},
/obj/item/clothing/head/russobluecamohat,
/obj/item/clothing/head/russobluecamohat,
/obj/item/clothing/head/russofurhat,
/obj/item/clothing/head/russofurhat,
/obj/item/clothing/head/russofurhat,
/obj/item/clothing/head/russofurhat,
/obj/item/clothing/head/helmet/rus_ushanka,
/obj/item/clothing/head/helmet/rus_ushanka,
/obj/item/clothing/head/helmet/rus_ushanka,
/obj/item/clothing/head/helmet/rus_ushanka,
/obj/item/clothing/under/mw2_russian_para,
/obj/item/clothing/under/mw2_russian_para,
/obj/item/clothing/under/mw2_russian_para,
@@ -58554,10 +58578,6 @@
},
/turf/open/space/basic,
/area/space/nearstation)
"xWM" = (
/obj/structure/grille/broken,
/turf/open/floor/plating,
/area/space/nearstation)
"xXY" = (
/obj/structure/closet/lasertag/red,
/obj/item/clothing/under/pj/red,
@@ -64623,11 +64643,11 @@ aaa
aaa
aaa
aaa
fsk
aaK
aaa
aaa
aaa
fsk
aaK
aaa
aaa
aaa
@@ -64874,9 +64894,9 @@ aaa
aaa
aaa
aaa
fsk
aaK
aaa
fsk
aaK
aaa
aaa
aaa
@@ -64888,9 +64908,9 @@ gXs
aaa
aaa
aaa
fsk
aaK
aaa
fsk
aaK
aaa
aaa
aaa
@@ -81103,7 +81123,7 @@ bpB
bpB
brR
bsV
bwc
aaM
bxA
bvI
bwX
@@ -95688,9 +95708,9 @@ aaa
aaa
aaa
aaa
hho
aaz
aaa
hho
aaz
aaa
aaa
aaa
@@ -96072,7 +96092,7 @@ aaf
ctZ
cui
cuq
cuC
ajY
cuO
cuz
cvm
@@ -96580,8 +96600,8 @@ czk
cti
cua
cua
ctw
ctH
aeF
afs
ctQ
cuc
cuj
@@ -96837,9 +96857,9 @@ ctb
cth
cua
ctr
ctu
ctG
ctP
afn
age
agX
cub
cuj
cur
@@ -97094,13 +97114,13 @@ ctc
ctc
cto
ctt
cty
afq
ctJ
ctT
ahw
cue
cul
cuu
cuG
akz
cuS
cve
cvo
@@ -97351,9 +97371,9 @@ ctb
ctj
ctk
cts
ctx
ctI
ctS
afr
agv
ajC
cud
cuk
cus
@@ -98123,7 +98143,7 @@ aaa
aaf
cua
ctF
ctM
agH
ctX
cuf
cum
@@ -98381,7 +98401,7 @@ aaf
cua
ctE
ctL
ctW
ajX
cuf
cum
cuw
@@ -101379,7 +101399,7 @@ bbE
aIr
bav
aLf
dkk
aaL
kLR
aRO
aQp
@@ -101961,10 +101981,10 @@ aaa
aaa
aaa
aaa
ikx
mwb
xWM
rxH
aaH
adO
aeD
aeE
aaa
aaa
aaa
@@ -102219,10 +102239,10 @@ xNY
kvb
aaa
aaa
ikx
ikx
ikx
rxH
aaH
aaH
aaH
aeE
aaa
aaa
aaa
@@ -102473,13 +102493,13 @@ czZ
cOT
aaa
jmC
dbM
dbM
ikx
ikx
ikx
thr
mwb
aaH
aaH
aaH
aaH
aaH
aaH
adO
aaa
aaa
aaa
@@ -102732,8 +102752,8 @@ gXs
xNY
kvb
gJg
dbM
dbM
aaH
aaH
aaa
aaa
gJg
@@ -102990,8 +103010,8 @@ aaa
aaa
gJg
gJg
mwb
ikx
adO
aaH
gXs
aaa
aaa
@@ -106072,7 +106092,7 @@ cNW
clt
cQw
cNW
cNW
abG
cNW
cNW
aaf
@@ -106328,7 +106348,7 @@ aaa
cOT
clt
cQw
cOe
aaO
cOe
cOe
cNW
@@ -106585,11 +106605,11 @@ aaa
cOT
clt
cQw
aaQ
cOe
cOe
cOe
cOe
sQX
cNW
aaa
jzi
jzi
jzi
@@ -106842,11 +106862,11 @@ aaa
cNW
clt
cQw
cOe
bNB
cOe
cOe
cNW
aaf
lCL
aaS
aaa
aaf
@@ -107099,7 +107119,7 @@ cNW
cNW
clt
cQw
cOe
aaY
cOe
cOe
cNW
+1 -1
View File
@@ -44934,7 +44934,7 @@
/area/maintenance/port)
"bKY" = (
/obj/machinery/power/apc{
areastring = "/area/vacant_room/office";
areastring = "/area/security/vacantoffice";
dir = 8;
name = "Vacant Office APC";
pixel_x = -25
+2
View File
@@ -506,6 +506,7 @@
"bx" = (
/obj/structure/table,
/obj/machinery/readybutton,
/obj/item/storage/lockbox/dueling/hugbox/stamina,
/turf/open/floor/holofloor/basalt,
/area/holodeck/rec_center/thunderdome)
"by" = (
@@ -522,6 +523,7 @@
/area/holodeck/rec_center/thunderdome)
"bA" = (
/obj/machinery/readybutton,
/obj/item/storage/lockbox/dueling/hugbox/stamina,
/obj/effect/turf_decal/tile/red{
dir = 1
},
+6 -2
View File
@@ -136,8 +136,12 @@
#define ORGAN_SLOT_TESTICLES "testicles"
#define ORGAN_SLOT_BREASTS "breasts"
////organ defines
#define STANDARD_ORGAN_THRESHOLD 100
#define STANDARD_ORGAN_HEALING 0.001
#define STANDARD_ORGAN_DECAY 0.00222 //designed to fail organs when left to decay for ~15 minutes
#define STANDARD_ORGAN_DECAY 0.00222 //designed to fail organs when left to decay for ~15 minutes
#define G_MALE 1
#define G_FEMALE 2
#define G_PLURAL 3
#define G_NEUTER 4
+2 -2
View File
@@ -87,5 +87,5 @@
#define MAX_KEYPRESS_COMMANDLENGTH 16
///Max amount of keypress messages per second over two seconds before client is autokicked
#define MAX_KEYPRESS_AUTOKICK 100
///Length of held key rolling buffer
#define HELD_KEY_BUFFER_LENGTH 15
///Length of max held keys
#define MAX_HELD_KEYS 15
+2 -2
View File
@@ -184,7 +184,7 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
#define BODY_ZONE_PRECISE_R_FOOT "r_foot"
//We will round to this value in damage calculations.
#define DAMAGE_PRECISION 0.1
#define DAMAGE_PRECISION 0.01
//items total mass, used to calculate their attacks' stamina costs. If not defined, the cost will be (w_class * 1.25)
#define TOTAL_MASS_TINY_ITEM 1.25
@@ -202,4 +202,4 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
#define BULLET_ACT_HIT "HIT" //It's a successful hit, whatever that means in the context of the thing it's hitting.
#define BULLET_ACT_BLOCK "BLOCK" //It's a blocked hit, whatever that means in the context of the thing it's hitting.
#define BULLET_ACT_FORCE_PIERCE "PIERCE" //It pierces through the object regardless of the bullet being piercing by default.
#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs.
#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs.
+1
View File
@@ -1,6 +1,7 @@
//config files
#define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X)
#define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y)
#define CONFIG_GET_ENTRY(X) global.config.GetEntryDatum(/datum/config_entry/##X)
#define CONFIG_MAPS_FILE "maps.txt"
+6 -1
View File
@@ -8,7 +8,7 @@
#define REAGENT_PURITY_ACCURACY 0.001
#define DEFAULT_SPECIFIC_HEAT 200
// container_type defines
//reagents_holder_flags defines
#define INJECTABLE (1<<0) // Makes it possible to add reagents through droppers and syringes.
#define DRAWABLE (1<<1) // Makes it possible to remove reagents through syringes.
@@ -29,6 +29,11 @@
#define PATCH 4 // patches
#define INJECT 5 // injection
//container_flags
#define PH_WEAK (1 << 0)
#define TEMP_WEAK (1 << 1)
#define APTFT_VERB (1 << 2) //APTFT stands for "amount per transfer from this"
#define APTFT_ALTCLICK (1 << 3)
//defines passed through to the on_reagent_change proc
#define DEL_REAGENT 1 // reagent deleted (fully cleared)
+1 -1
View File
@@ -37,7 +37,7 @@
#define ROLE_GANG "gangster"
#define ROLE_BLOODSUCKER "bloodsucker"
//#define ROLE_MONSTERHUNTER "monster hunter" Disabled for now
#define ROLE_GHOSTCAFE "ghostcafe"
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
//(in game days played) to play that role
+6
View File
@@ -165,6 +165,12 @@
/proc/log_mapping(text)
WRITE_LOG(GLOB.world_map_error_log, text)
/proc/log_reagent(text)
WRITE_LOG(GLOB.reagent_log, text)
/proc/log_reagent_transfer(text)
log_reagent("TRANSFER: [text]")
/* For logging round startup. */
/proc/start_log(log)
WRITE_LOG(log, "Starting up round ID [GLOB.round_id].\n-------------------------")
+134
View File
@@ -1,5 +1,81 @@
#define BP_MAX_ROOM_SIZE 300
//Repopulates sortedAreas list
/proc/repopulate_sorted_areas()
GLOB.sortedAreas = list()
for(var/area/A in world)
GLOB.sortedAreas.Add(A)
sortTim(GLOB.sortedAreas, /proc/cmp_name_asc)
/area/proc/addSorted()
GLOB.sortedAreas.Add(src)
sortTim(GLOB.sortedAreas, /proc/cmp_name_asc)
//Takes: Area type as a text string from a variable.
//Returns: Instance for the area in the world.
/proc/get_area_instance_from_text(areatext)
if(istext(areatext))
areatext = text2path(areatext)
return GLOB.areas_by_type[areatext]
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all areas of that type in the world.
/proc/get_areas(areatype, subtypes=TRUE)
if(istext(areatype))
areatype = text2path(areatype)
else if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
else if(!ispath(areatype))
return null
var/list/areas = list()
if(subtypes)
var/list/cache = typecacheof(areatype)
for(var/V in GLOB.sortedAreas)
var/area/A = V
if(cache[A.type])
areas += V
else
for(var/V in GLOB.sortedAreas)
var/area/A = V
if(A.type == areatype)
areas += V
return areas
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all turfs in areas of that type of that type in the world.
/proc/get_area_turfs(areatype, target_z = 0, subtypes=FALSE)
if(istext(areatype))
areatype = text2path(areatype)
else if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
else if(!ispath(areatype))
return null
var/list/turfs = list()
if(subtypes)
var/list/cache = typecacheof(areatype)
for(var/V in GLOB.sortedAreas)
var/area/A = V
if(!cache[A.type])
continue
for(var/turf/T in A)
if(target_z == 0 || target_z == T.z)
turfs += T
else
for(var/V in GLOB.sortedAreas)
var/area/A = V
if(A.type != areatype)
continue
for(var/turf/T in A)
if(target_z == 0 || target_z == T.z)
turfs += T
return turfs
// Gets an atmos isolated contained space
// Returns an associative list of turf|dirs pairs
// The dirs are connected turfs in the same space
@@ -103,4 +179,62 @@
to_chat(creator, "<span class='notice'>You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered.</span>")
return TRUE
/**
* Returns the base area the target is located in if there is one.
* Alternatively, returns the area as is.
*/
/proc/get_base_area(atom/target)
var/area/A = get_area(target)
if(A?.base_area)
return A.base_area
return A
/**
* Returns either null, or a list containing every sub area associated with our base area.
* If include_base is TRUE, the base area will also be added to the return list.
*/
/proc/get_sub_areas(atom/target, include_base = TRUE)
var/area/A = get_area(target)
if(!A)
return
. = list()
if(A.base_area)
A = A.base_area
if(include_base)
. += A
if(A.sub_areas)
. += A.sub_areas
/**
* Proc used for purposes similar to get_areas_turfs(), but aimed to include associated areas.
* Only accepts area instances and paths for the first arg, no text strings.
* Returns a list of all turfs found in the sub areas (including the base's if include_base is TRUE)
* and located in a z level matching target_z, or anywhere if target_z is 0
*/
/proc/get_sub_areas_turfs(area/A, target_z = 0, include_base = TRUE)
var/list/contents = get_sub_areas_contents(A, include_base)
. = list()
for(var/turf/T in contents)
if(target_z == 0 || target_z == T.z)
. += T
/**
* Simple proc that returns a sum of all contents from every sub area,
* Think of the above but for all contents, not just turfs, and without target z.
*/
/proc/get_sub_areas_contents(area/A, include_base = TRUE)
if(ispath(A))
A = GLOB.areas_by_type[A]
else
A = get_area(A) //in case it's called on other atoms.
if(!A)
return
if(A.base_area)
A = A.base_area
. = list(A.contents)
for(var/i in A.sub_areas)
. += A.sub_areas[i].contents
#undef BP_MAX_ROOM_SIZE
+17 -36
View File
@@ -8,8 +8,8 @@
#define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL))
#define CULT_POLL_WAIT 2400
/proc/get_area_name(atom/X, format_text = FALSE)
var/area/A = isarea(X) ? X : get_area(X)
/proc/get_area_name(atom/X, format_text = FALSE, get_base_area = FALSE)
var/area/A = get_base_area ? get_base_area(X) : get_area(X)
if(!A)
return null
return format_text ? format_text(A.name) : A.name
@@ -145,20 +145,6 @@
turfs += T
return turfs
//This is the new version of recursive_mob_check, used for say().
//The other proc was left intact because morgue trays use it.
//Sped this up again for real this time
/proc/recursive_hear_check(O)
var/list/processing_list = list(O)
. = list()
while(processing_list.len)
var/atom/A = processing_list[1]
if(A.flags_1 & HEAR_1)
. += A
processing_list.Cut(1, 2)
processing_list += A.contents
/** recursive_organ_check
* inputs: O (object to start with)
* outputs:
@@ -238,35 +224,30 @@
return found_mobs
/proc/get_hearers_in_view(R, atom/source)
// Returns a list of hearers in view(R) from source (ignoring luminosity). Used in saycode.
var/turf/T = get_turf(source)
. = list()
if(!T)
return
var/list/processing_list = list()
if (R == 0) // if the range is zero, we know exactly where to look for, we can skip view
processing_list += T.contents // We can shave off one iteration by assuming turfs cannot hear
else // A variation of get_hear inlined here to take advantage of the compiler's fastpath for obj/mob in view
var/list/processing = list()
if(R == 0)
processing += T.contents
else
var/lum = T.luminosity
T.luminosity = 6 // This is the maximum luminosity
var/list/cachedview = view(R, T)
for(var/mob/M in cachedview)
processing_list += M
for(var/obj/O in cachedview)
processing_list += O
T.luminosity = 6
var/list/cached_view = view(R, T)
for(var/mob/M in cached_view)
processing += M
for(var/obj/O in cached_view)
processing += O
T.luminosity = lum
while(processing_list.len) // recursive_hear_check inlined here
var/atom/A = processing_list[1]
var/i = 0
while(i < length(processing))
var/atom/A = processing[++i]
if(A.flags_1 & HEAR_1)
. += A
SEND_SIGNAL(A, COMSIG_ATOM_HEARER_IN_VIEW, processing_list, .)
processing_list.Cut(1, 2)
processing_list += A.contents
SEND_SIGNAL(A, COMSIG_ATOM_HEARER_IN_VIEW, processing, .)
processing += A.contents
/proc/get_mobs_in_radio_ranges(list/obj/item/radio/radios)
. = list()
+15 -92
View File
@@ -457,36 +457,35 @@ Turf and target are separate in case you want to teleport some distance from a t
/atom/proc/GetAllContents(var/T)
var/list/processing_list = list(src)
var/list/assembled = list()
if(T)
while(processing_list.len)
var/atom/A = processing_list[1]
processing_list.Cut(1, 2)
. = list()
var/i = 0
while(i < length(processing_list))
var/atom/A = processing_list[++i]
//Byond does not allow things to be in multiple contents, or double parent-child hierarchies, so only += is needed
//This is also why we don't need to check against assembled as we go along
processing_list += A.contents
if(istype(A,T))
assembled += A
. += A
else
while(processing_list.len)
var/atom/A = processing_list[1]
processing_list.Cut(1, 2)
var/i = 0
while(i < length(processing_list))
var/atom/A = processing_list[++i]
processing_list += A.contents
assembled += A
return assembled
return processing_list
/atom/proc/GetAllContentsIgnoring(list/ignore_typecache)
if(!length(ignore_typecache))
return GetAllContents()
var/list/processing = list(src)
var/list/assembled = list()
while(processing.len)
var/atom/A = processing[1]
processing.Cut(1,2)
. = list()
var/i = 0
while(i < length(processing))
var/atom/A = processing[++i]
if(!ignore_typecache[A.type])
processing += A.contents
assembled += A
return assembled
. += A
//Step-towards method of determining whether one atom can see another. Similar to viewers()
/proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
@@ -566,82 +565,6 @@ Turf and target are separate in case you want to teleport some distance from a t
else
return 0
//Repopulates sortedAreas list
/proc/repopulate_sorted_areas()
GLOB.sortedAreas = list()
for(var/area/A in world)
GLOB.sortedAreas.Add(A)
sortTim(GLOB.sortedAreas, /proc/cmp_name_asc)
/area/proc/addSorted()
GLOB.sortedAreas.Add(src)
sortTim(GLOB.sortedAreas, /proc/cmp_name_asc)
//Takes: Area type as a text string from a variable.
//Returns: Instance for the area in the world.
/proc/get_area_instance_from_text(areatext)
if(istext(areatext))
areatext = text2path(areatext)
return GLOB.areas_by_type[areatext]
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all areas of that type in the world.
/proc/get_areas(areatype, subtypes=TRUE)
if(istext(areatype))
areatype = text2path(areatype)
else if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
else if(!ispath(areatype))
return null
var/list/areas = list()
if(subtypes)
var/list/cache = typecacheof(areatype)
for(var/V in GLOB.sortedAreas)
var/area/A = V
if(cache[A.type])
areas += V
else
for(var/V in GLOB.sortedAreas)
var/area/A = V
if(A.type == areatype)
areas += V
return areas
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all turfs in areas of that type of that type in the world.
/proc/get_area_turfs(areatype, target_z = 0, subtypes=FALSE)
if(istext(areatype))
areatype = text2path(areatype)
else if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
else if(!ispath(areatype))
return null
var/list/turfs = list()
if(subtypes)
var/list/cache = typecacheof(areatype)
for(var/V in GLOB.sortedAreas)
var/area/A = V
if(!cache[A.type])
continue
for(var/turf/T in A)
if(target_z == 0 || target_z == T.z)
turfs += T
else
for(var/V in GLOB.sortedAreas)
var/area/A = V
if(A.type != areatype)
continue
for(var/turf/T in A)
if(target_z == 0 || target_z == T.z)
turfs += T
return turfs
/proc/get_cardinal_dir(atom/A, atom/B)
var/dx = abs(B.x - A.x)
var/dy = abs(B.y - A.y)
+2
View File
@@ -32,6 +32,8 @@ GLOBAL_VAR(world_map_error_log)
GLOBAL_PROTECT(world_map_error_log)
GLOBAL_VAR(subsystem_log)
GLOBAL_PROTECT(subsystem_log)
GLOBAL_VAR(reagent_log)
GLOBAL_PROTECT(reagent_log)
GLOBAL_VAR(world_crafting_log)
GLOBAL_PROTECT(world_crafting_log)
+3 -1
View File
@@ -146,6 +146,8 @@
/datum/hud/proc/update_parallax_motionblur(client/C, animatedir, new_parallax_movedir, matrix/newtransform)
if(!C)
return
C.parallax_animate_timer = FALSE
for(var/thing in C.parallax_layers)
var/obj/screen/parallax_layer/L = thing
@@ -167,7 +169,7 @@
/datum/hud/proc/update_parallax()
var/client/C = mymob.client
var/turf/posobj = get_turf(C.eye)
if(!posobj)
if(!posobj)
return
var/area/areaobj = posobj.loc
@@ -193,6 +193,13 @@
stat("[name]:", statclick)
/datum/controller/configuration/proc/Get(entry_type)
var/datum/config_entry/E = GetEntryDatum(entry_type)
if((E.protection & CONFIG_ENTRY_HIDDEN) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]")
log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]")
return
return E.config_entry_value
/datum/controller/configuration/proc/GetEntryDatum(entry_type)
var/datum/config_entry/E = entry_type
var/entry_is_abstract = initial(E.abstract_type) == entry_type
if(entry_is_abstract)
@@ -200,10 +207,7 @@
E = entries_by_type[entry_type]
if(!E)
CRASH("Missing config entry for [entry_type]!")
if((E.protection & CONFIG_ENTRY_HIDDEN) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]")
log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]")
return
return E.config_entry_value
return E
/datum/controller/configuration/proc/Set(entry_type, new_val)
var/datum/config_entry/E = entry_type
@@ -249,6 +249,18 @@
/datum/config_entry/number/movedelay/walk_delay
/datum/config_entry/number/movedelay/sprint_speed_increase
config_entry_value = 1
/datum/config_entry/number/movedelay/sprint_buffer_max
config_entry_value = 42
/datum/config_entry/number/movedelay/sprint_stamina_cost
config_entry_value = 0.7
/datum/config_entry/number/movedelay/sprint_buffer_regen_per_ds
config_entry_value = 0.3
/////////////////////////////////////////////////Outdated move delay
/datum/config_entry/number/outdated_movedelay
deprecated_by = /datum/config_entry/keyed_list/multiplicative_movespeed
+1 -2
View File
@@ -239,7 +239,6 @@ SUBSYSTEM_DEF(air)
if (MC_TICK_CHECK)
return
/datum/controller/subsystem/air/proc/remove_from_active(turf/open/T)
active_turfs -= T
SSair_turfs.currentrun -= T
@@ -257,7 +256,7 @@ SUBSYSTEM_DEF(air)
#ifdef VISUALIZE_ACTIVE_TURFS
T.add_atom_colour("#00ff00", TEMPORARY_COLOUR_PRIORITY)
#endif
T.excited = 1
T.excited = TRUE
active_turfs |= T
SSair_turfs.currentrun |= T
if(blockchanges && T.excited_group)
-1
View File
@@ -11,7 +11,6 @@ SUBSYSTEM_DEF(air_turfs)
/datum/controller/subsystem/air_turfs/fire(resumed = 0)
var/fire_count = times_fired
//cache for sanic speed
if (!resumed)
src.currentrun = SSair.active_turfs.Copy()
//cache for sanic speed (lists are references anyways)
+2 -3
View File
@@ -31,10 +31,9 @@ SUBSYSTEM_DEF(fail2topic)
return ..()
/datum/controller/subsystem/fail2topic/fire()
while (rate_limiting.len)
var/ip = rate_limiting[1]
for(var/i in 1 to length(rate_limiting))
var/ip = rate_limiting[i]
var/last_attempt = rate_limiting[ip]
if (world.time - last_attempt > rate_limit)
rate_limiting -= ip
fail_counts -= ip
+1 -1
View File
@@ -114,6 +114,6 @@ SUBSYSTEM_DEF(input)
/datum/controller/subsystem/input/fire()
var/list/clients = GLOB.clients // Let's sing the list cache song
for(var/i in 1 to clients.len)
for(var/i in 1 to length(clients))
var/client/C = clients[i]
C.keyLoop()
+7 -1
View File
@@ -37,6 +37,8 @@ SUBSYSTEM_DEF(mapping)
var/datum/space_level/empty_space
var/num_of_res_levels = 1
var/stat_map_name = "Loading..."
//dlete dis once #39770 is resolved
/datum/controller/subsystem/mapping/proc/HACK_LoadMapConfig()
if(!config)
@@ -45,6 +47,7 @@ SUBSYSTEM_DEF(mapping)
#else
config = load_map_config(error_if_missing = FALSE)
#endif
stat_map_name = config.map_name
/datum/controller/subsystem/mapping/Initialize(timeofday)
HACK_LoadMapConfig()
@@ -330,7 +333,10 @@ GLOBAL_LIST_EMPTY(the_station_areas)
return
next_map_config = VM
return TRUE
. = TRUE
stat_map_name = "[config.map_name] (Next: [next_map_config.map_name])"
/datum/controller/subsystem/mapping/proc/preloadTemplates(path = "_maps/templates/") //see master controller setup
var/list/filelist = flist(path)
+4
View File
@@ -30,6 +30,7 @@ SUBSYSTEM_DEF(shuttle)
var/list/hostileEnvironments = list() //Things blocking escape shuttle from leaving
var/list/tradeBlockade = list() //Things blocking cargo from leaving.
var/supplyBlocked = FALSE
var/emergency_shuttle_stat_text
//supply shuttle stuff
var/obj/docking_port/mobile/supply/supply
@@ -118,6 +119,9 @@ SUBSYSTEM_DEF(shuttle)
points += point_gain
//Cargo stuff end
var/esETA = emergency?.getModeStr()
emergency_shuttle_stat_text = "[esETA? "[esETA] [emergency.getTimerStr()]" : ""]"
if(!SSmapping.clearing_reserved_turfs)
while(transit_requesters.len)
var/requester = popleft(transit_requesters)
+26 -16
View File
@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(time_track)
name = "Time Tracking"
wait = 600
wait = 1 SECONDS
flags = SS_NO_INIT|SS_NO_TICK_CHECK
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
@@ -16,23 +16,33 @@ SUBSYSTEM_DEF(time_track)
var/last_tick_byond_time = 0
var/last_tick_tickcount = 0
var/last_measurement = 0
var/measurement_delay = 60
var/stat_time_text
var/time_dilation_text
/datum/controller/subsystem/time_track/fire()
stat_time_text = "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]\n\nRound Time: [WORLDTIME2TEXT("hh:mm:ss")]\n\nStation Time: [STATION_TIME_TIMESTAMP("hh:mm:ss")]\n\n[time_dilation_text]"
var/current_realtime = REALTIMEOFDAY
var/current_byondtime = world.time
var/current_tickcount = world.time/world.tick_lag
if(++last_measurement == measurement_delay)
last_measurement = 0
var/current_realtime = REALTIMEOFDAY
var/current_byondtime = world.time
var/current_tickcount = world.time/world.tick_lag
if (!first_run)
var/tick_drift = max(0, (((current_realtime - last_tick_realtime) - (current_byondtime - last_tick_byond_time)) / world.tick_lag))
if (!first_run)
var/tick_drift = max(0, (((current_realtime - last_tick_realtime) - (current_byondtime - last_tick_byond_time)) / world.tick_lag))
time_dilation_current = tick_drift / (current_tickcount - last_tick_tickcount) * 100
time_dilation_current = tick_drift / (current_tickcount - last_tick_tickcount) * 100
time_dilation_avg_fast = MC_AVERAGE_FAST(time_dilation_avg_fast, time_dilation_current)
time_dilation_avg = MC_AVERAGE(time_dilation_avg, time_dilation_avg_fast)
time_dilation_avg_slow = MC_AVERAGE_SLOW(time_dilation_avg_slow, time_dilation_avg)
else
first_run = FALSE
last_tick_realtime = current_realtime
last_tick_byond_time = current_byondtime
last_tick_tickcount = current_tickcount
SSblackbox.record_feedback("associative", "time_dilation_current", 1, list("[SQLtime()]" = list("current" = "[time_dilation_current]", "avg_fast" = "[time_dilation_avg_fast]", "avg" = "[time_dilation_avg]", "avg_slow" = "[time_dilation_avg_slow]")))
time_dilation_avg_fast = MC_AVERAGE_FAST(time_dilation_avg_fast, time_dilation_current)
time_dilation_avg = MC_AVERAGE(time_dilation_avg, time_dilation_avg_fast)
time_dilation_avg_slow = MC_AVERAGE_SLOW(time_dilation_avg_slow, time_dilation_avg)
else
first_run = FALSE
last_tick_realtime = current_realtime
last_tick_byond_time = current_byondtime
last_tick_tickcount = current_tickcount
SSblackbox.record_feedback("associative", "time_dilation_current", 1, list("[SQLtime()]" = list("current" = "[time_dilation_current]", "avg_fast" = "[time_dilation_avg_fast]", "avg" = "[time_dilation_avg]", "avg_slow" = "[time_dilation_avg_slow]")))
time_dilation_text = "Time Dilation: [round(time_dilation_current,1)]% AVG:([round(time_dilation_avg_fast,1)]%, [round(time_dilation_avg,1)]%, [round(time_dilation_avg_slow,1)]%)"
+1 -1
View File
@@ -14,7 +14,7 @@
var/can_gain = TRUE
var/random_gain = TRUE //can this be gained through random traumas?
var/resilience = TRAUMA_RESILIENCE_BASIC //how hard is this to cure?
var/clonable = TRUE // will this transfer if the brain is cloned?
var/clonable = TRUE // will this transfer if the brain is cloned? - currently has no effect
/datum/brain_trauma/Destroy()
if(brain && brain.traumas)
+1 -1
View File
@@ -229,7 +229,7 @@
UnregisterSignal(mastermind, COMSIG_PRE_MIND_TRANSFER)
mastermind = null
if(cleanup)
var/obj/effect/vr_clean_master/cleanbot = locate() in get_area(M)
var/obj/effect/vr_clean_master/cleanbot = locate() in get_base_area(M)
if(cleanbot)
LAZYOR(cleanbot.corpse_party, M)
qdel(src)
+12 -2
View File
@@ -236,7 +236,12 @@
G.fields["fingerprint"] = md5(H.dna.uni_identity)
G.fields["p_stat"] = "Active"
G.fields["m_stat"] = "Stable"
G.fields["sex"] = H.gender
if(H.gender == MALE)
G.fields["gender"] = "Male"
else if(H.gender == FEMALE)
G.fields["gender"] = "Female"
else
G.fields["gender"] = "Other"
G.fields["photo_front"] = photo_front
G.fields["photo_side"] = photo_side
general += G
@@ -274,7 +279,12 @@
L.fields["name"] = H.real_name
L.fields["rank"] = H.mind.assigned_role
L.fields["age"] = H.age
L.fields["sex"] = H.gender
if(H.gender == MALE)
G.fields["gender"] = "Male"
else if(H.gender == FEMALE)
G.fields["gender"] = "Female"
else
G.fields["gender"] = "Other"
L.fields["blood_type"] = H.dna.blood_type
L.fields["b_dna"] = H.dna.unique_enzymes
L.fields["enzymes"] = H.dna.struc_enzymes
+1 -1
View File
@@ -110,7 +110,7 @@
// Randomly pick a symptom to activate.
/datum/disease/advance/stage_act()
..()
if(carrier)
if(carrier || QDELETED(src)) // Could be cured in parent call.
return
if(symptoms && symptoms.len)
@@ -43,7 +43,7 @@ Bonus
suppress_warning = TRUE
/datum/symptom/choking/Activate(datum/disease/advance/A)
if(!..())
if(!..() || HAS_TRAIT(A.affected_mob,TRAIT_NOBREATH))
return
var/mob/living/M = A.affected_mob
switch(A.stage)
@@ -116,7 +116,7 @@ Bonus
power = 2
/datum/symptom/asphyxiation/Activate(datum/disease/advance/A)
if(!..())
if(!..() || HAS_TRAIT(A.affected_mob,TRAIT_NOBREATH))
return
var/mob/living/M = A.affected_mob
switch(A.stage)
@@ -51,7 +51,7 @@ BONUS
symptom_delay_max = 10
/datum/symptom/cough/Activate(datum/disease/advance/A)
if(!..())
if(!..() || HAS_TRAIT(A.affected_mob,TRAIT_NOBREATH))
return
var/mob/living/M = A.affected_mob
switch(A.stage)
@@ -41,7 +41,7 @@ Bonus
suppress_warning = TRUE
/datum/symptom/sneeze/Activate(datum/disease/advance/A)
if(!..())
if(!..() || HAS_TRAIT(A.affected_mob,TRAIT_NOBREATH))
return
var/mob/living/M = A.affected_mob
switch(A.stage)
+1 -1
View File
@@ -94,7 +94,7 @@ STI KALY - blind
var/area/thearea = pick(theareas)
var/list/L = list()
for(var/turf/T in get_area_turfs(thearea.type))
for(var/turf/T in thearea)
if(T.z != affected_mob.z)
continue
if(T.name == "space")
+28 -3
View File
@@ -92,7 +92,15 @@
. = ""
var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS)
L[DNA_GENDER_BLOCK] = construct_block((holder.gender!=MALE)+1, 2)
switch(holder.gender)
if(MALE)
L[DNA_GENDER_BLOCK] = construct_block(G_MALE, 4)
if(FEMALE)
L[DNA_GENDER_BLOCK] = construct_block(G_FEMALE, 4)
if(PLURAL)
L[DNA_GENDER_BLOCK] = construct_block(G_PLURAL, 4)
else
L[DNA_GENDER_BLOCK] = construct_block(G_NEUTER, 4)
if(ishuman(holder))
var/mob/living/carbon/human/H = holder
if(!GLOB.hair_styles_list.len)
@@ -165,7 +173,15 @@
if(DNA_EYE_COLOR_BLOCK)
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color))
if(DNA_GENDER_BLOCK)
setblock(uni_identity, blocknumber, construct_block((H.gender!=MALE)+1, 2))
switch(H.gender)
if(MALE)
setblock(uni_identity, blocknumber, construct_block(G_MALE, 4))
if(FEMALE)
setblock(uni_identity, blocknumber, construct_block(G_FEMALE, 4))
if(PLURAL)
setblock(uni_identity, blocknumber, construct_block(G_PLURAL, 4))
else
setblock(uni_identity, blocknumber, construct_block(G_NEUTER, 4))
if(DNA_FACIAL_HAIR_STYLE_BLOCK)
setblock(uni_identity, blocknumber, construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len))
if(DNA_HAIR_STYLE_BLOCK)
@@ -307,7 +323,16 @@
/mob/living/carbon/proc/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
if(!has_dna())
return
gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE
switch(deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 4))
if(G_MALE)
gender = MALE
if(G_FEMALE)
gender = FEMALE
if(G_PLURAL)
gender = PLURAL
else
gender = NEUTER
/mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
..()
@@ -0,0 +1,28 @@
/datum/element/dusts_on_leaving_area
element_flags = ELEMENT_DETACH | ELEMENT_BESPOKE
id_arg_index = 2
var/list/attached_mobs = list()
var/list/area_types = list()
/datum/element/dusts_on_leaving_area/Attach(datum/target,types)
. = ..()
if(!ismob(target))
return ELEMENT_INCOMPATIBLE
attached_mobs += target
area_types = types
START_PROCESSING(SSprocessing,src)
/datum/element/dusts_on_leaving_area/Detach(mob/M)
. = ..()
if(M in attached_mobs)
attached_mobs -= M
if(!attached_mobs.len)
STOP_PROCESSING(SSprocessing,src)
/datum/element/dusts_on_leaving_area/process()
for(var/m in attached_mobs)
var/mob/M = m
var/area/A = get_area(M)
if(!(A.type in area_types))
M.dust(force = TRUE)
Detach(M)
+1
View File
@@ -15,6 +15,7 @@
/datum/quirk/New(mob/living/quirk_mob, spawn_effects)
if(!quirk_mob || (human_only && !ishuman(quirk_mob)) || quirk_mob.has_quirk(type))
qdel(src)
return
quirk_holder = quirk_mob
SSquirks.quirk_objects += src
to_chat(quirk_holder, gain_text)
+4 -5
View File
@@ -201,13 +201,12 @@
medical_record_text = "Patient's blood tests report an abnormal concentration of red blood cells in their bloodstream."
/datum/quirk/bloodpressure/add()
var/mob/living/M = quirk_holder
M.blood_ratio = 1.2
M.blood_volume += 150
quirk_holder.blood_ratio = 1.2
quirk_holder.blood_volume += 150
/datum/quirk/bloodpressure/remove()
var/mob/living/M = quirk_holder
M.blood_ratio = 1
if(quirk_holder)
quirk_holder.blood_ratio = 1
/datum/quirk/night_vision
name = "Night Vision"
+4 -1
View File
@@ -50,7 +50,10 @@
stage = STARTUP_STAGE
var/list/affectareas = list()
for(var/V in get_areas(area_type))
affectareas += V
var/area/A = V
affectareas |= A
if(A.sub_areas)
affectareas |= A.sub_areas
for(var/V in protected_areas)
affectareas -= get_areas(V)
for(var/V in affectareas)
+2 -2
View File
@@ -46,7 +46,7 @@
A.mode = 1 // AALARM_MODE_SCRUB
A.apply_mode()
if(WIRE_ALARM) // Clear alarms.
var/area/AA = get_area(A)
var/area/AA = get_base_area(A)
if(AA.atmosalert(0, holder))
A.post_alert(0)
A.update_icon()
@@ -68,7 +68,7 @@
A.mode = 3 // AALARM_MODE_PANIC
A.apply_mode()
if(WIRE_ALARM) // Post alarm.
var/area/AA = get_area(A)
var/area/AA = get_base_area(A)
if(AA.atmosalert(2, holder))
A.post_alert(2)
A.update_icon()
+88 -34
View File
@@ -63,6 +63,15 @@
var/xenobiology_compatible = FALSE //Can the Xenobio management console transverse this area by default?
var/list/canSmoothWithAreas //typecache to limit the areas that atoms in this area can smooth with
/**
* These two vars allow for multiple unique areas to be linked to a master area
* and share some functionalities such as APC powernet nodes, fire alarms etc, without sacrificing
* their own flags, statuses, variables and more snowflakes.
* Friendly reminder: no map edited areas.
*/
var/list/area/sub_areas //list of typepaths of the areas you wish to link here, will be replaced with a list of references on mapload.
var/area/base_area //The area we wish to use in place of src for certain actions such as APC area linking.
var/nightshift_public_area = NIGHTSHIFT_AREA_NONE //considered a public area for nightshift
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
@@ -123,10 +132,35 @@ GLOBAL_LIST_EMPTY(teleportlocs)
reg_in_areas_in_z()
//so far I'm only implementing it on mapped unique areas, it's easier this way.
if(unique && sub_areas)
if(type in sub_areas)
WARNING("\"[src]\" typepath found inside its own sub-areas list, please make sure it doesn't share its parent type initial sub-areas value.")
sub_areas = null
else
var/paths = sub_areas.Copy()
sub_areas = null
for(var/type in paths)
var/area/A = GLOB.areas_by_type[type]
if(!A) //By chance an area not loaded in the current world, no warning report.
continue
if(A == src)
WARNING("\"[src]\" area a attempted to link with itself.")
continue
if(A.base_area)
WARNING("[src] attempted to link with [A] while the latter is already linked to another area ([A.base_area]).")
continue
LAZYADD(sub_areas, A)
A.base_area = src
else if(LAZYLEN(sub_areas))
WARNING("sub-areas are currently not supported for non-unique areas such as [src].")
sub_areas = null
return INITIALIZE_HINT_LATELOAD
/area/LateInitialize()
power_change() // all machines set to current power level, also updates icon
if(!base_area) //we don't want to run it twice.
power_change() // all machines set to current power level, also updates icon
/area/proc/reg_in_areas_in_z()
if(contents.len)
@@ -149,6 +183,19 @@ GLOBAL_LIST_EMPTY(teleportlocs)
/area/Destroy()
if(GLOB.areas_by_type[type] == src)
GLOB.areas_by_type[type] = null
if(base_area)
LAZYREMOVE(base_area, src)
base_area = null
if(sub_areas)
for(var/i in sub_areas)
var/area/A = i
A.base_area = null
sub_areas -= A
if(A.requires_power)
A.power_light = FALSE
A.power_equip = FALSE
A.power_environ = FALSE
INVOKE_ASYNC(A, .proc/power_change)
STOP_PROCESSING(SSobj, src)
return ..()
@@ -214,9 +261,12 @@ GLOBAL_LIST_EMPTY(teleportlocs)
var/datum/computer_file/program/alarm_monitor/p = item
p.cancelAlarm("Atmosphere", src, source)
src.atmosalm = danger_level
return 1
return 0
atmosalm = danger_level
for(var/i in sub_areas)
var/area/A = i
A.atmosalm = danger_level
return TRUE
return FALSE
/area/proc/ModifyFiredoors(opening)
if(firedoors)
@@ -241,11 +291,8 @@ GLOBAL_LIST_EMPTY(teleportlocs)
return
if (!fire)
set_fire_alarm_effect()
set_fire_alarm_effects(TRUE)
ModifyFiredoors(FALSE)
for(var/item in firealarms)
var/obj/machinery/firealarm/F = item
F.update_icon()
for (var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
@@ -264,11 +311,8 @@ GLOBAL_LIST_EMPTY(teleportlocs)
/area/proc/firereset(obj/source)
if (fire)
unset_fire_alarm_effects()
set_fire_alarm_effects(FALSE)
ModifyFiredoors(TRUE)
for(var/item in firealarms)
var/obj/machinery/firealarm/F = item
F.update_icon()
for (var/item in GLOB.silicon_mobs)
var/mob/living/silicon/aiPlayer = item
@@ -300,9 +344,9 @@ GLOBAL_LIST_EMPTY(teleportlocs)
return
//Trigger alarm effect
set_fire_alarm_effect()
set_fire_alarm_effects(TRUE)
//Lockdown airlocks
for(var/obj/machinery/door/DOOR in src)
for(var/obj/machinery/door/DOOR in get_sub_areas_contents(src))
close_and_lock_door(DOOR)
for (var/i in GLOB.silicon_mobs)
@@ -311,23 +355,20 @@ GLOBAL_LIST_EMPTY(teleportlocs)
//Cancel silicon alert after 1 minute
addtimer(CALLBACK(SILICON, /mob/living/silicon.proc/cancelAlarm,"Burglar",src,trigger), 600)
/area/proc/set_fire_alarm_effect()
fire = TRUE
/area/proc/set_fire_alarm_effects(boolean)
fire = boolean
for(var/i in sub_areas)
var/area/A = i
A.fire = boolean
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
for(var/alarm in firealarms)
var/obj/machinery/firealarm/F = alarm
F.update_fire_light(fire)
for(var/obj/machinery/light/L in src)
F.update_icon()
for(var/obj/machinery/light/L in get_sub_areas_contents(src))
L.update()
/area/proc/unset_fire_alarm_effects()
fire = FALSE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
for(var/alarm in firealarms)
var/obj/machinery/firealarm/F = alarm
F.update_fire_light(fire)
for(var/obj/machinery/light/L in src)
L.update()
/area/proc/updateicon()
/**
* Update the icon state of the area
*
@@ -380,26 +421,35 @@ GLOBAL_LIST_EMPTY(teleportlocs)
/area/proc/power_change()
for(var/obj/machinery/M in src) // for each machine in the area
M.power_change() // reverify power status (to update icons etc.)
if(sub_areas)
for(var/i in sub_areas)
var/area/A = i
A.power_light = power_light
A.power_equip = power_equip
A.power_environ = power_environ
INVOKE_ASYNC(A, .proc/power_change)
update_icon()
/area/proc/usage(chan)
var/used = 0
switch(chan)
if(LIGHT)
used += used_light
. += used_light
if(EQUIP)
used += used_equip
. += used_equip
if(ENVIRON)
used += used_environ
. += used_environ
if(TOTAL)
used += used_light + used_equip + used_environ
. += used_light + used_equip + used_environ
if(STATIC_EQUIP)
used += static_equip
. += static_equip
if(STATIC_LIGHT)
used += static_light
. += static_light
if(STATIC_ENVIRON)
used += static_environ
return used
. += static_environ
if(sub_areas)
for(var/i in sub_areas)
var/area/A = i
. += A.usage(chan)
/area/proc/addStaticPower(value, powerchannel)
switch(powerchannel)
@@ -414,6 +464,10 @@ GLOBAL_LIST_EMPTY(teleportlocs)
used_equip = 0
used_light = 0
used_environ = 0
if(sub_areas)
for(var/i in sub_areas)
var/area/A = i
A.clear_usage()
/area/proc/use_power(amount, chan)
@@ -5,6 +5,7 @@
/datum/game_mode/traitor/bros
name = "traitor+brothers"
config_tag = "traitorbro"
required_players = 25
restricted_jobs = list("AI", "Cyborg")
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
+3 -2
View File
@@ -12,7 +12,7 @@
var/list/skipped_areas = list(/area/engine/engineering, /area/engine/supermatter, /area/engine/atmospherics_engine, /area/ai_monitored/turret_protected/ai)
for(var/area/A in world)
if( !A.requires_power || A.always_unpowered )
if( !A.requires_power || A.always_unpowered || A.base_area)
continue
var/skip = 0
@@ -61,8 +61,9 @@
S.output_attempt = 1
S.update_icon()
S.power_change()
for(var/area/A in world)
if(!istype(A, /area/space) && !istype(A, /area/shuttle) && !istype(A, /area/arrival))
if(!istype(A, /area/space) && !istype(A, /area/shuttle) && !istype(A, /area/arrival) && !A.always_unpowered && !A.base_area)
A.power_light = TRUE
A.power_equip = TRUE
A.power_environ = TRUE
+2 -2
View File
@@ -101,7 +101,7 @@
playsound(loc, 'sound/items/timer.ogg', 10, 0)
if(!warned && (time_remaining < 180))
warned = TRUE
var/area/domloc = get_area(loc)
var/area/domloc = get_base_area(loc)
gang.message_gangtools("Less than 3 minutes remains in hostile takeover. Defend your dominator at [domloc.map_name]!")
for(var/G in GLOB.gangs)
var/datum/team/gang/tempgang = G
@@ -179,7 +179,7 @@
if((tempgang.domination_time != NOT_DOMINATING) || !tempgang.dom_attempts || !in_range(src, user) || !isturf(loc))
return 0
var/area/A = get_area(loc)
var/area/A = get_base_area(loc)
var/locname = A.map_name
gang = tempgang
+2 -2
View File
@@ -19,7 +19,7 @@
return INITIALIZE_HINT_QDEL
gang = G
var/newcolor = G.color
var/area/territory = get_area(src)
var/area/territory = get_base_area(src)
icon_state = G.name
G.new_territories |= list(territory.type = territory.name)
//If this isn't tagged by a specific gangster there's no bonus income.
@@ -27,7 +27,7 @@
/obj/effect/decal/cleanable/crayon/gang/Destroy()
if(gang)
var/area/territory = get_area(src)
var/area/territory = get_base_area(src)
gang.territories -= territory.type
gang.new_territories -= territory.type
gang.lost_territories |= list(territory.type = territory.name)
+1 -7
View File
@@ -290,12 +290,6 @@ datum/gang_item/clothing/shades //Addition: Why not have cool shades on a gang m
cost = 5
item_path = /obj/item/grenade/syndieminibomb/concussion/frag
/datum/gang_item/equipment/stimpack
name = "Black Market Stimulants"
id = "stimpack"
cost = 12
item_path = /obj/item/reagent_containers/syringe/stimulants
/datum/gang_item/equipment/implant_breaker
name = "Implant Breaker"
id = "implant_breaker"
@@ -401,7 +395,7 @@ datum/gang_item/equipment/gangsheild
return "This device requires a 5x5 area clear of walls to FUNCTION. (Estimated Takeover Time: [round(gang.determine_domination_time()/60,0.1)] minutes)"
/datum/gang_item/equipment/dominator/purchase(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool)
var/area/userarea = get_area(user)
var/area/userarea = get_base_area(user)
if(!(userarea.type in gang.territories|gang.new_territories))
to_chat(user,"<span class='warning'>The <b>dominator</b> can be spawned only on territory controlled by your gang!</span>")
return FALSE
+4 -4
View File
@@ -21,16 +21,16 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
//Meteor spawning global procs
///////////////////////////////
/proc/spawn_meteors(number = 10, list/meteortypes)
/proc/spawn_meteors(number = 10, list/meteortypes, dir)
for(var/i = 0; i < number; i++)
spawn_meteor(meteortypes)
spawn_meteor(meteortypes, dir)
/proc/spawn_meteor(list/meteortypes)
/proc/spawn_meteor(list/meteortypes, dir)
var/turf/pickedstart
var/turf/pickedgoal
var/max_i = 10//number of tries to spawn meteor.
while(!isspaceturf(pickedstart))
var/startSide = pick(GLOB.cardinals)
var/startSide = dir || pick(GLOB.cardinals)
var/startZ = pick(SSmapping.levels_by_trait(ZTRAIT_STATION))
pickedstart = spaceDebrisStartLoc(startSide, startZ)
pickedgoal = spaceDebrisFinishLoc(startSide, startZ)
+1 -1
View File
@@ -527,7 +527,7 @@ GLOBAL_LIST_EMPTY(possible_items)
else if(targetinfo.check_special_completion(I))//Returns 1 by default. Items with special checks will return 1 if the conditions are fulfilled.
return TRUE
if(targetinfo && I.type in targetinfo.altitems) //Ok, so you don't have the item. Do you have an alternative, at least?
if(targetinfo && (I.type in targetinfo.altitems)) //Ok, so you don't have the item. Do you have an alternative, at least?
if(targetinfo.check_special_completion(I))//Yeah, we do! Don't return 0 if we don't though - then you could fail if you had 1 item that didn't pass and got checked first!
return TRUE
return FALSE
+2 -1
View File
@@ -319,7 +319,8 @@
if(status)
change_msg = "reactivates"
triggerCameraAlarm()
addtimer(CALLBACK(src, .proc/cancelCameraAlarm), 100)
if(!QDELETED(src)) //We'll be doing it anyway in destroy
addtimer(CALLBACK(src, .proc/cancelCameraAlarm), 100)
if(displaymessage)
if(user)
visible_message("<span class='danger'>[user] [change_msg] [src]!</span>")
+1 -1
View File
@@ -46,7 +46,7 @@
var/area/a = loc.loc // Gets our locations location, like a dream within a dream
if(!isarea(a))
return
if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power!
if(!a.powered(EQUIP)) // There's no APC in this area, don't try to cheat power!
to_chat(user, "<span class='warning'>[src] blinks red as you try to insert the cell!</span>")
return
if(!user.transferItemToLoc(W,src))
@@ -119,6 +119,9 @@
if(istype(P, /obj/item/circuitboard/machine))
var/obj/item/circuitboard/machine/B = P
if(!B.build_path)
to_chat(user, "<span class'warning'>This circuitboard seems to be broken.</span>")
return
if(!anchored && B.needs_anchored)
to_chat(user, "<span class='warning'>The frame needs to be secured first!</span>")
return
+4 -5
View File
@@ -406,12 +406,11 @@
lying_prev = 0
/obj/machinery/jukebox/proc/dance_over()
SSjukeboxes.removejukebox(SSjukeboxes.findjukeboxindex(src))
var/position = SSjukeboxes.findjukeboxindex(src)
if(!position)
return
SSjukeboxes.removejukebox(position)
STOP_PROCESSING(SSobj, src)
for(var/mob/living/L in rangers)
if(!L || !L.client)
continue
L.stop_sound_channel(CHANNEL_JUKEBOX)
rangers = list()
/obj/machinery/jukebox/disco/dance_over()
+2 -3
View File
@@ -288,9 +288,10 @@
return
operating = TRUE
do_animate("closing")
layer = closingLayer
if(!safe)
crush()
sleep(5)
density = TRUE
sleep(5)
@@ -302,8 +303,6 @@
update_freelook_sight()
if(safe)
CheckForMobs()
else
crush()
return 1
/obj/machinery/door/proc/CheckForMobs()
+1 -1
View File
@@ -44,7 +44,7 @@
/obj/machinery/door/firedoor/proc/CalculateAffectingAreas()
remove_from_areas()
affecting_areas = get_adjacent_open_areas(src) | get_area(src)
affecting_areas = get_adjacent_open_areas(src) | get_base_area(src)
for(var/I in affecting_areas)
var/area/A = I
LAZYADD(A.firedoors, src)
+7 -7
View File
@@ -44,7 +44,7 @@
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
update_icon()
myarea = get_area(src)
myarea = get_base_area(src)
LAZYADD(myarea.firealarms, src)
/obj/machinery/firealarm/Destroy()
@@ -124,7 +124,7 @@
if(!is_operational() || (last_alarm+FIREALARM_COOLDOWN > world.time))
return
last_alarm = world.time
var/area/A = get_area(src)
var/area/A = get_base_area(src)
A.firealert(src)
playsound(loc, 'goon/sound/machinery/FireAlarm.ogg', 75)
if(user)
@@ -133,7 +133,7 @@
/obj/machinery/firealarm/proc/reset(mob/user)
if(!is_operational())
return
var/area/A = get_area(src)
var/area/A = get_base_area(src)
A.firereset(src)
if(user)
log_game("[user] reset a fire alarm at [COORD(src)]")
@@ -142,7 +142,7 @@
if(buildstage != 2)
return ..()
add_fingerprint(user)
var/area/A = get_area(src)
var/area/A = get_base_area(src)
if(A.fire)
reset(user)
else
@@ -198,7 +198,7 @@
return
else if(W.force) //hit and turn it on
..()
var/area/A = get_area(src)
var/area/A = get_base_area(src)
if(!A.fire)
alarm()
return
@@ -322,7 +322,7 @@
/obj/machinery/firealarm/partyalarm/reset()
if (stat & (NOPOWER|BROKEN))
return
var/area/A = get_area(src)
var/area/A = get_base_area(src)
if (!A || !A.party)
return
A.party = FALSE
@@ -331,7 +331,7 @@
/obj/machinery/firealarm/partyalarm/alarm()
if (stat & (NOPOWER|BROKEN))
return
var/area/A = get_area(src)
var/area/A = get_base_area(src)
if (!A || A.party || A.name == "Space")
return
A.party = TRUE
+1 -1
View File
@@ -70,7 +70,7 @@
//Checks to make sure he's not in space doing it, and that the area got proper power.
var/area/a = get_area(src)
if(!isarea(a) || a.power_equip == 0)
if(!a || !a.powered(EQUIP))
to_chat(user, "<span class='notice'>[src] blinks red as you try to insert [G].</span>")
return 1
@@ -421,7 +421,7 @@
"name" = "[customsender]",
"job" = "[customjob]",
"message" = custommessage,
"emoji_message" = emoji_parse(custommessage),
"emojis" = TRUE,
"targets" = list("[customrecepient.owner] ([customrecepient.ownjob])")
))
// this will log the signal and transmit it to the target
@@ -106,11 +106,10 @@
return "Everyone"
return data["targets"][1]
/datum/signal/subspace/pda/proc/format_message(emojify = FALSE)
var/message = emojify ? data["emoji_message"] : data["message"]
/datum/signal/subspace/pda/proc/format_message()
if (logged && data["photo"])
return "\"[message]\" (<a href='byond://?src=[REF(logged)];photo=1'>Photo</a>)"
return "\"[message]\""
return "\"[data["message"]]\" (<a href='byond://?src=[REF(logged)];photo=1'>Photo</a>)"
return "\"[data["message"]]\""
/datum/signal/subspace/pda/broadcast()
if (!logged) // Can only go through if a message server logs it
@@ -283,7 +283,7 @@
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_charge()
if(equip_ready) //disabled
return
var/area/A = get_area(chassis)
var/area/A = get_base_area(chassis)
var/pow_chan = get_power_channel(A)
if(pow_chan)
return 1000 //making magic
@@ -328,7 +328,7 @@
occupant_message("No powercell detected.")
return
if(cur_charge < chassis.cell.maxcharge)
var/area/A = get_area(chassis)
var/area/A = get_base_area(chassis)
if(A)
var/pow_chan
for(var/c in list(EQUIP,ENVIRON,LIGHT))
@@ -48,6 +48,8 @@ would spawn and follow the beaker, even if it is carried or thrown.
holder = atom
/datum/effect_system/proc/start()
if(QDELETED(src))
return
for(var/i in 1 to number)
if(total_effects > 20)
return
@@ -69,7 +71,8 @@ would spawn and follow the beaker, even if it is carried or thrown.
for(var/j in 1 to steps_amt)
sleep(5)
step(E,direction)
addtimer(CALLBACK(src, .proc/decrement_total_effect), 20)
if(!QDELETED(src))
addtimer(CALLBACK(src, .proc/decrement_total_effect), 20)
/datum/effect_system/proc/decrement_total_effect()
total_effects--
@@ -126,7 +126,7 @@
T.PlaceOnTop(/turf/open/floor/plating/foam, flags = CHANGETURF_INHERIT_AIR)
for(var/direction in GLOB.cardinals)
var/turf/cardinal_turf = get_step(T, direction)
if(get_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf!
if(get_base_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf!
new/obj/structure/foamedmetal(T)
break
flick("[icon_state]-disolve", src)
+2 -2
View File
@@ -456,7 +456,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
if(!SSmapping.station_room_templates[t])
log_world("Station room spawner placed at ([T.x], [T.y], [T.z]) has invalid ruin name of \"[t]\" in its list")
templates -= t
template_name = pickweight(templates)
template_name = pickweightAllowZero(templates)
if(!template_name)
GLOB.stationroom_landmarks -= src
qdel(src)
@@ -485,4 +485,4 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
// Landmark for the mining station
/obj/effect/landmark/stationroom/lavaland/station
templates = list("Public Mining Base" = 3)
icon = 'icons/rooms/Lavaland/Mining.dmi'
icon = 'icons/rooms/Lavaland/Mining.dmi'
+4 -5
View File
@@ -146,7 +146,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(!proximity || lit) //can't dip if cigarette is lit (it will heat the reagents in the glass instead)
return
if(istype(glass)) //you can dip cigarettes into beakers
if(glass.reagents.trans_to(src, chem_volume)) //if reagents were transfered, show the message
if(glass.reagents.trans_to(src, chem_volume, log = "cigar fill: dip cigarette")) //if reagents were transfered, show the message
to_chat(user, "<span class='notice'>You dip \the [src] into \the [glass].</span>")
else //if not, either the beaker was empty, or the cigarette was full
if(!glass.reagents.total_volume)
@@ -154,7 +154,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM
else
to_chat(user, "<span class='notice'>[src] is full.</span>")
/obj/item/clothing/mask/cigarette/proc/light(flavor_text = null)
if(lit)
return
@@ -438,7 +437,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
packeditem = 1
name = "[O.name]-packed [initial(name)]"
if(O.reagents)
O.reagents.trans_to(src, O.reagents.total_volume)
O.reagents.trans_to(src, O.reagents.total_volume, log = "cigar fill: pipe pack")
qdel(O)
else
to_chat(user, "<span class='warning'>It has to be dried first!</span>")
@@ -687,7 +686,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(O.dry)
var/obj/item/clothing/mask/cigarette/rollie/R = new /obj/item/clothing/mask/cigarette/rollie(user.loc)
R.chem_volume = target.reagents.total_volume
target.reagents.trans_to(R, R.chem_volume)
target.reagents.trans_to(R, R.chem_volume, log = "cigar fill: rolling paper afterattack")
qdel(target)
qdel(src)
user.put_in_active_hand(R)
@@ -903,7 +902,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
//Transfer reagents and remove the plant
user.show_message("<span class='notice'>You stuff the [DP] into the [src]'s bowl.</span>", MSG_VISUAL)
DP.reagents.trans_to(src, 100)
DP.reagents.trans_to(src, 100, log = "cigar fill: bong")
qdel(DP)
return
else
+2 -2
View File
@@ -427,7 +427,7 @@
/obj/item/toy/crayon/proc/can_claim_for_gang(mob/user, atom/target)
// Check area validity.
// Reject space, player-created areas, and non-station z-levels.
var/area/A = get_area(target)
var/area/A = get_base_area(target)
if(!A || (!is_station_level(A.z)) || !A.valid_territory)
to_chat(user, "<span class='warning'>[A] is unsuitable for tagging.</span>")
return FALSE
@@ -461,7 +461,7 @@
qdel(old_marking)
var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang)
var/area/territory = get_area(target)
var/area/territory = get_base_area(target)
new /obj/effect/decal/cleanable/crayon/gang(target,G.gang,"graffiti",0,user) // Heres the gang tag.
to_chat(user, "<span class='notice'>You tagged [territory] for your gang!</span>")
+9 -8
View File
@@ -452,14 +452,15 @@
return TRUE
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
if(req_defib)
if(defib.pullshocksafely && isliving(H.pulledby))
H.visible_message("<span class='danger'>The defibrillator safely discharges the excessive charge into the floor!</span>")
else
var/mob/living/M = H.pulledby
if(M.electrocute_act(30, src))
M.visible_message("<span class='danger'>[M] is electrocuted by [M.p_their()] contact with [H]!</span>")
M.emote("scream")
if(!H.pulledby || !isliving(H.pulledby))
return
if(req_defib && defib.pullshocksafely)
H.visible_message("<span class='danger'>The defibrillator safely discharges the excessive charge into the floor!</span>")
return
var/mob/living/M = H.pulledby
if(M.electrocute_act(30, src))
M.visible_message("<span class='danger'>[M] is electrocuted by [M.p_their()] contact with [H]!</span>")
M.emote("scream")
/obj/item/twohanded/shockpaddles/proc/do_disarm(mob/living/M, mob/living/user)
if(req_defib && defib.safety)
+18 -6
View File
@@ -1,4 +1,3 @@
//The advanced pea-green monochrome lcd of tomorrow.
GLOBAL_LIST_EMPTY(PDAs)
@@ -77,6 +76,7 @@ GLOBAL_LIST_EMPTY(PDAs)
var/hidden = FALSE // Is the PDA hidden from the PDA list?
var/emped = FALSE
var/equipped = FALSE //used here to determine if this is the first time its been picked up
var/allow_emojis = TRUE //if the pda can send emojis and actually have them parsed as such
var/obj/item/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both.
var/ownjob = null //related to above
@@ -255,10 +255,14 @@ GLOBAL_LIST_EMPTY(PDAs)
var/datum/asset/spritesheet/assets = get_asset_datum(/datum/asset/spritesheet/simple/pda)
assets.send(user)
var/datum/asset/spritesheet/emoji_s = get_asset_datum(/datum/asset/spritesheet/goonchat)
emoji_s.send(user) //Already sent by chat but no harm doing this
user.set_machine(src)
var/dat = "<!DOCTYPE html><html><head><title>Personal Data Assistant</title><link href=\"https://fonts.googleapis.com/css?family=Orbitron|Share+Tech+Mono|VT323\" rel=\"stylesheet\"></head><body bgcolor=\"" + background_color + "\"><style>body{" + font_mode + "}ul,ol{list-style-type: none;}a, a:link, a:visited, a:active, a:hover { color: #000000;text-decoration:none; }img {border-style:none;}a img{padding-right: 9px;}</style>"
dat += assets.css_tag()
dat += emoji_s.css_tag()
dat += "<a href='byond://?src=[REF(src)];choice=Refresh'>[PDAIMG(refresh)]Refresh</a>"
@@ -338,6 +342,8 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "<li><a href='byond://?src=[REF(src)];choice=54'>[PDAIMG(medbot)]Bots Access</a></li>"
if (cartridge.access & CART_JANITOR)
dat += "<li><a href='byond://?src=[REF(src)];choice=49'>[PDAIMG(bucket)]Custodial Locator</a></li>"
if(cartridge.access & CART_MIME)
dat += "<li><a href='byond://?src=[REF(src)];choice=55'>[PDAIMG(emoji)]Emoji Guidebook</a></li>"
if (istype(cartridge.radio))
dat += "<li><a href='byond://?src=[REF(src)];choice=40'>[PDAIMG(signaler)]Signaler System</a></li>"
if (cartridge.access & CART_NEWSCASTER)
@@ -753,7 +759,6 @@ GLOBAL_LIST_EMPTY(PDAs)
return
if((last_text && world.time < last_text + 10) || (everyone && last_everyone && world.time < last_everyone + PDA_SPAM_DELAY))
return
var/emoji_message = emoji_parse(message)
if(prob(1))
message += "\nSent from my PDA"
// Send the signal
@@ -782,7 +787,7 @@ GLOBAL_LIST_EMPTY(PDAs)
"job" = "[ownjob]",
"message" = message,
"targets" = string_targets,
"emoji_message" = emoji_message
"emojis" = allow_emojis
))
if (picture)
signal.data["photo"] = picture
@@ -796,15 +801,18 @@ GLOBAL_LIST_EMPTY(PDAs)
playsound(src, 'sound/machines/terminal_error.ogg', 15, 1)
var/target_text = signal.format_target()
if(allow_emojis)
message = emoji_parse(message)//already sent- this just shows the sent emoji as one to the sender in the to_chat
signal.data["message"] = emoji_parse(signal.data["message"])
// Log it in our logs
tnote += "<i><b>&rarr; To [target_text]:</b></i><br>[signal.format_message()]<br>"
// Show it to ghosts
var/ghost_message = "<span class='name'>[owner] </span><span class='game say'>PDA Message</span> --> <span class='name'>[target_text]</span>: <span class='message'>[signal.format_message(TRUE)]</span>"
var/ghost_message = "<span class='name'>[owner] </span><span class='game say'>PDA Message</span> --> <span class='name'>[target_text]</span>: <span class='message'>[signal.format_message()]</span>"
for(var/i in GLOB.dead_mob_list)
var/mob/M = i
if(M?.client && M.client.prefs.chat_toggles & CHAT_GHOSTPDA)
to_chat(M, "[FOLLOW_LINK(M, user)] [ghost_message]")
to_chat(user, "<span class='info'>Message sent to [target_text]: \"[emoji_message]\"</span>")
to_chat(user, "<span class='info'>Message sent to [target_text]: \"[message]\"</span>")
// Log in the talk log
user.log_talk(message, LOG_PDA, tag="PDA: [initial(name)] to [target_text] (BLOCKED:[string_blocked])")
if (!silent)
@@ -835,7 +843,11 @@ GLOBAL_LIST_EMPTY(PDAs)
hrefstart = "<a href='?src=[REF(L)];track=[html_encode(signal.data["name"])]'>"
hrefend = "</a>"
to_chat(L, "[icon2html(src)] <b>Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], </b>[signal.format_message(TRUE)] (<a href='byond://?src=[REF(src)];choice=Message;skiprefresh=1;target=[REF(signal.source)]'>Reply</a>) <a href='byond://?src=[REF(src)];choice=toggle_block;target=[signal.data["name"]]'>(BLOCK/UNBLOCK)</a>")
var/inbound_message = signal.format_message()
if(signal.data["emojis"] == TRUE)//so will not parse emojis as such from pdas that don't send emojis
inbound_message = emoji_parse(inbound_message)
to_chat(L, "[icon2html(src)] <b>Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], </b>[inbound_message] (<a href='byond://?src=[REF(src)];choice=Message;skiprefresh=1;target=[REF(signal.source)]'>Reply</a>) (<a href='byond://?src=[REF(src)];choice=toggle_block;target=[signal.data["name"]]'>BLOCK/UNBLOCK</a>)")
update_icon(TRUE)
@@ -19,6 +19,26 @@
if(istype(cart) && cart.charges < 5)
cart.charges++
//Mime PDA sends "silent" messages.
/obj/item/pda/mime
name = "mime PDA"
default_cartridge = /obj/item/cartridge/virus/mime
inserted_item = /obj/item/toy/crayon/mime
icon_state = "pda-mime"
desc = "A portable microcomputer by Thinktronic Systems, LTD. The hardware has been modified for compliance with the vows of silence."
silent = TRUE
ttone = "silence"
/obj/item/pda/mime/msg_input(mob/living/U = usr)
if(emped || toff)
return
var/emojis = emoji_sanitize(stripped_input(U, "Please enter emojis", name))
if(!emojis)
return
if(!U.canUseTopic(src, BE_CLOSE))
return
return emojis
// Special AI/pAI PDAs that cannot explode.
/obj/item/pda/ai
icon = null
@@ -79,14 +99,6 @@
icon_state = "pda-science"
ttone = "boom"
/obj/item/pda/mime
name = "mime PDA"
default_cartridge = /obj/item/cartridge/virus/mime
inserted_item = /obj/item/toy/crayon/mime
icon_state = "pda-mime"
silent = TRUE
ttone = "silence"
/obj/item/pda/heads
default_cartridge = /obj/item/cartridge/head
icon_state = "pda-hop"
+23 -2
View File
@@ -326,7 +326,7 @@ Code:
if(active1 in GLOB.data_core.general)
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]<br>"
menu += "Sex: [active1.fields["sex"]]<br>"
menu += "Sex: [active1.fields["gender"]]<br>"
menu += "Age: [active1.fields["age"]]<br>"
menu += "Rank: [active1.fields["rank"]]<br>"
menu += "Fingerprint: [active1.fields["fingerprint"]]<br>"
@@ -370,7 +370,7 @@ Code:
if(active1 in GLOB.data_core.general)
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]<br>"
menu += "Sex: [active1.fields["sex"]]<br>"
menu += "Sex: [active1.fields["gender"]]<br>"
menu += "Age: [active1.fields["age"]]<br>"
menu += "Rank: [active1.fields["rank"]]<br>"
menu += "Fingerprint: [active1.fields["fingerprint"]]<br>"
@@ -579,6 +579,22 @@ Code:
if (54) // Beepsky, Medibot, Floorbot, and Cleanbot access
menu = "<h4>[PDAIMG(medbot)] Bots Interlink</h4>"
bot_control()
if (55) // Emoji Guidebook for mimes
menu = "<h4>[PDAIMG(emoji)] Emoji Guidebook</h4>"
var/static/list/emoji_icon_states
var/static/emoji_table
if(!emoji_table)
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/goonchat)
var/list/collate = list("<br><table>")
for(var/emoji in sortList(icon_states(icon('icons/emoji.dmi'))))
var/tag = sheet.icon_tag("emoji-[emoji]")
collate += "<tr><td>[emoji]</td><td>[tag]</td></tr>"
collate += "</table><br>"
emoji_table = collate.Join()
menu += "<br> To use an emoji in a pda message, refer to the guide and add \":\" around the emoji. Your PDA supports the following emoji:<br>"
menu += emoji_table
if (99) //Newscaster message permission error
menu = "<h5> ERROR : NOT AUTHORIZED [host_pda.id ? "" : "- ID SLOT EMPTY"] </h5>"
@@ -679,6 +695,11 @@ Code:
return
playsound(src, 'sound/machines/terminal_select.ogg', 50, 1)
//emoji previews
if(href_list["emoji"])
var/parse = emoji_parse(":[href_list["emoji"]]:")
to_chat(usr, parse)
//Bot control section! Viciously ripped from radios for being laggy and terrible.
if(href_list["op"])
switch(href_list["op"])
@@ -14,6 +14,7 @@
var/last_use = 0
var/next_use = 0
var/obj/effect/abstract/sync_holder/sync_holder
var/resync_timer
/obj/item/desynchronizer/attack_self(mob/living/user)
if(world.time < next_use)
@@ -56,16 +57,20 @@
SEND_SIGNAL(AM, COMSIG_MOVABLE_SECLUDED_LOCATION)
last_use = world.time
icon_state = "desynchronizer-on"
addtimer(CALLBACK(src, .proc/resync), duration)
resync_timer = addtimer(CALLBACK(src, .proc/resync), duration , TIMER_STOPPABLE)
/obj/item/desynchronizer/proc/resync()
new /obj/effect/temp_visual/desynchronizer(sync_holder.drop_location())
QDEL_NULL(sync_holder)
if(resync_timer)
deltimer(resync_timer)
resync_timer = null
icon_state = initial(icon_state)
next_use = world.time + (world.time - last_use) // Could be 2*world.time-last_use but that would just be confusing
/obj/item/desynchronizer/Destroy()
resync()
if(sync_holder)
resync()
return ..()
/obj/effect/abstract/sync_holder
@@ -309,6 +309,15 @@ GLOBAL_LIST_INIT(bamboo_recipes, list ( \
recipes = GLOB.bamboo_recipes
return ..()
/obj/item/stack/sheet/mineral/bamboo/ten
amount = 10
/obj/item/stack/sheet/mineral/bamboo/twenty
amount = 20
/obj/item/stack/sheet/mineral/bamboo/fifty
amount = 50
/*
* Cloth
*/
+1 -1
View File
@@ -178,7 +178,7 @@
machine = null
//called when the user unsets the machine.
/atom/movable/proc/on_unset_machine(mob/user)
/atom/proc/on_unset_machine(mob/user)
return
/mob/proc/set_machine(obj/O)
+1 -1
View File
@@ -52,7 +52,7 @@
var/area/A = get_area(src)
if(!A.blob_allowed)
return FALSE
if(!A.power_equip)
if(!A.powered(EQUIP))
return FALSE
if(!SSmapping.level_trait(T.z,ZTRAIT_STATION))
return FALSE
+1 -1
View File
@@ -305,7 +305,7 @@
/datum/barsign/meow_mix
name = "Meow Mix"
icon = "meow_mix"
icon = "Meow Mix"
desc = "No, we don't serve catnip, officer!"
/datum/barsign/hiddensigns
@@ -532,7 +532,7 @@
/obj/structure/closet/CtrlShiftClick(mob/living/user)
if(!HAS_TRAIT(user, TRAIT_SKITTISH))
return ..()
if(!user.canUseTopic(src) || !isturf(user.loc))
if(!user.canUseTopic(src) || !isturf(user.loc) || !user.Adjacent(src) || !user.CanReach(src))
return
dive_into(user)
+1 -1
View File
@@ -80,7 +80,7 @@
/obj/structure/displaycase/proc/trigger_alarm()
//Activate Anti-theft
if(alert)
var/area/alarmed = get_area(src)
var/area/alarmed = get_base_area(src)
alarmed.burglaralert(src)
playsound(src, 'sound/effects/alert.ogg', 50, 1)
@@ -205,6 +205,9 @@
if(!mineral)
if(istype(G, /obj/item/stack/sheet/mineral) && G.sheettype)
var/M = G.sheettype
var/mineralassembly = text2path("/obj/structure/door_assembly/door_assembly_[M]")
if(!mineralassembly)
return
if(G.get_amount() >= 2)
playsound(src, 'sound/items/crowbar.ogg', 100, 1)
user.visible_message("[user] adds [G.name] to the airlock assembly.", \
@@ -214,7 +217,6 @@
return
to_chat(user, "<span class='notice'>You install [M] plating into the airlock assembly.</span>")
G.use(2)
var/mineralassembly = text2path("/obj/structure/door_assembly/door_assembly_[M]")
var/obj/structure/door_assembly/MA = new mineralassembly(loc)
transfer_assembly_vars(src, MA, TRUE)
else
+1 -1
View File
@@ -7,7 +7,7 @@
anchored = TRUE
icon = 'icons/turf/walls/wall.dmi'
icon_state = "wall"
layer = CLOSED_TURF_LAYER
layer = LOW_OBJ_LAYER
density = TRUE
opacity = 1
max_integrity = 100
@@ -637,7 +637,7 @@
short_desc = "You are a Ghost Cafe Visitor!"
flavour_text = "You know one thing for sure. You arent actually alive. Are you in a simulation?"
skip_reentry_check = TRUE
banType = "ghostcafe"
banType = ROLE_GHOSTCAFE
/datum/action/toggle_dead_chat_mob
icon_icon = 'icons/mob/mob.dmi'
@@ -660,12 +660,14 @@
/obj/effect/mob_spawn/human/ghostcafe/special(mob/living/carbon/human/new_spawn)
if(new_spawn.client)
new_spawn.client.prefs.copy_to(new_spawn)
var/area/A = get_area(src)
var/datum/outfit/O = new /datum/outfit/ghostcafe()
O.equip(new_spawn, FALSE, new_spawn.client)
SSjob.equip_loadout(null, new_spawn, FALSE)
SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn)
new_spawn.AddElement(/datum/element/ghost_role_eligibility)
new_spawn.AddElement(/datum/element/dusts_on_catatonia)
new_spawn.AddElement(/datum/element/dusts_on_leaving_area,list(A.type,/area/hilbertshotel))
ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn,TRAIT_PACIFISM,GHOSTROLE_TRAIT)
+7 -2
View File
@@ -166,6 +166,9 @@
if(S.sheettype && S.sheettype != "runed")
var/M = S.sheettype
if(state == GIRDER_DISPLACED)
var/F = text2path("/obj/structure/falsewall/[M]")
if(!F)
return
if(S.get_amount() < 2)
to_chat(user, "<span class='warning'>You need at least two sheets to create a false wall!</span>")
return
@@ -174,11 +177,13 @@
return
S.use(2)
to_chat(user, "<span class='notice'>You create a false wall. Push on it to open or close the passage.</span>")
var/F = text2path("/obj/structure/falsewall/[M]")
var/obj/structure/FW = new F (loc)
transfer_fingerprints_to(FW)
qdel(src)
else
var/F = text2path("/turf/closed/wall/mineral/[M]")
if(!F)
return
if(S.get_amount() < 2)
to_chat(user, "<span class='warning'>You need at least two sheets to add plating!</span>")
return
@@ -189,7 +194,7 @@
S.use(2)
to_chat(user, "<span class='notice'>You add the plating.</span>")
var/turf/T = get_turf(src)
T.PlaceOnTop(text2path("/turf/closed/wall/mineral/[M]"))
T.PlaceOnTop(F)
transfer_fingerprints_to(T)
qdel(src)
return
+1 -1
View File
@@ -97,7 +97,7 @@
icon_state = "guillotine_raised"
/obj/structure/guillotine/proc/drop_blade(mob/user)
if (buckled_mobs.len && blade_sharpness)
if (has_buckled_mobs() && blade_sharpness)
var/mob/living/carbon/human/H = buckled_mobs[1]
if (!H)
+3 -2
View File
@@ -42,8 +42,9 @@
if(.)
return
to_chat(user, "<span class='notice'>You take down [src].</span>")
victim.forceMove(drop_location())
victim = null
if(victim)
victim.forceMove(drop_location())
victim = null
spear.forceMove(drop_location())
spear = null
qdel(src)
+2 -2
View File
@@ -20,14 +20,14 @@
return
if(broken || !Adjacent(user))
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
//see code/modules/mob/dead/new_player/preferences.dm at approx line 545 for comments!
//this is largely copypasted from there.
//handle facial hair (if necessary)
if(H.gender == MALE)
if(H.gender != FEMALE)
var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in GLOB.facial_hair_styles_list
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return //no tele-grooming
@@ -138,7 +138,8 @@
var/duration = (48/W.force) * 2 //In seconds, for now.
if(istype(W, /obj/item/hatchet) || istype(W, /obj/item/twohanded/fireaxe))
duration /= 4 //Much better with hatchets and axes.
if(do_after(user, duration*10, target=src)) //Into deciseconds.
var/src_type = type
if(do_after(user, duration*10, target=src) && type == src_type) //Into deciseconds.
dismantle_wall(FALSE,FALSE)
return
return ..()
+2
View File
@@ -117,6 +117,7 @@ GLOBAL_LIST(topic_status_cache)
GLOB.world_job_debug_log = "[GLOB.log_directory]/job_debug.log"
GLOB.tgui_log = "[GLOB.log_directory]/tgui.log"
GLOB.subsystem_log = "[GLOB.log_directory]/subsystem.log"
GLOB.reagent_log = "[GLOB.log_directory]/reagents.log"
GLOB.world_crafting_log = "[GLOB.log_directory]/crafting.log"
@@ -135,6 +136,7 @@ GLOBAL_LIST(topic_status_cache)
start_log(GLOB.world_job_debug_log)
start_log(GLOB.tgui_log)
start_log(GLOB.subsystem_log)
start_log(GLOB.reagent_log)
start_log(GLOB.world_crafting_log)
GLOB.changelog_hash = md5('html/changelog.html') //for telling if the changelog has changed recently
+18 -13
View File
@@ -222,18 +222,23 @@
/obj/effect/vr_clean_master/Initialize()
. = ..()
vr_area = get_area(src)
addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES)
vr_area = get_base_area(src)
if(!vr_area)
return INITIALIZE_HINT_QDEL
addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES, TIMER_LOOP)
/obj/effect/vr_clean_master/proc/clean_up()
if (vr_area)
for (var/obj/item/ammo_casing/casing in vr_area)
qdel(casing)
for(var/obj/effect/decal/cleanable/C in vr_area)
qdel(C)
for (var/A in corpse_party)
var/mob/M = A
if(M && M.stat == DEAD && get_area(M) == vr_area)
qdel(M)
corpse_party -= M
addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES)
if (!vr_area)
qdel(src)
return
var/list/contents = get_sub_areas_contents(vr_area)
for (var/obj/item/ammo_casing/casing in contents)
qdel(casing)
for(var/obj/effect/decal/cleanable/C in contents)
qdel(C)
for (var/A in corpse_party)
var/mob/M = A
if(!QDELETED(M) && (M in contents) && M.stat == DEAD)
qdel(M)
corpse_party -= M
addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES)
+1 -1
View File
@@ -408,7 +408,7 @@
var/obj/item/organ/tail/cat/tail = new
ears.Insert(H, drop_if_replaced=FALSE)
tail.Insert(H, drop_if_replaced=FALSE)
var/list/honorifics = list("[MALE]" = list("kun"), "[FEMALE]" = list("chan","tan"), "[NEUTER]" = list("san")) //John Robust -> Robust-kun
var/list/honorifics = list("[MALE]" = list("kun"), "[FEMALE]" = list("chan","tan"), "[NEUTER]" = list("san"), "[PLURAL]" = list("san")) //John Robust -> Robust-kun
var/list/names = splittext(H.real_name," ")
var/forename = names.len > 1 ? names[2] : names[1]
var/newname = "[forename]-[pick(honorifics["[H.gender]"])]"
+7 -1
View File
@@ -845,7 +845,11 @@
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_LAVALAND];jobban4=[REF(M)]'><font color=red>Lavaland</font></a></td>"
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_LAVALAND];jobban4=[REF(M)]'>Lavaland</a></td>"
// Ghost cafe
if(jobban_isbanned(M,ROLE_GHOSTCAFE))
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_GHOSTCAFE];jobban4=[REF(M)]'><font color=red>Lavaland</font></a></td>"
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_GHOSTCAFE];jobban4=[REF(M)]'>Lavaland</a></td>"
dat += "</tr></table>"
//Antagonist (Orange)
@@ -2878,6 +2882,8 @@
return
if(SSdbcore.Connect())
var/datum/DBQuery/query_get_mentor = SSdbcore.NewQuery("SELECT id FROM [format_table_name("mentor")] WHERE ckey = '[ckey]'")
if(!query_get_mentor.warn_execute())
return
if(query_get_mentor.NextRow())
to_chat(usr, "<span class='danger'>[ckey] is already a mentor.</span>")
return
+13 -3
View File
@@ -541,7 +541,9 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
var/list/areas_all = list()
var/list/areas_with_APC = list()
var/list/areas_with_multiple_APCs = list()
var/list/sub_areas_APC = list()
var/list/areas_with_air_alarm = list()
var/list/sub_areas_air_alarm = list()
var/list/areas_with_RC = list()
var/list/areas_with_light = list()
var/list/areas_with_LS = list()
@@ -578,6 +580,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
if(!A)
dat += "Skipped over [APC] in invalid location, [APC.loc]."
continue
LAZYSET(sub_areas_APC, A.type, get_sub_areas(A, FALSE))
if(!(A.type in areas_with_APC))
areas_with_APC.Add(A.type)
else if(A.type in areas_all)
@@ -585,10 +588,11 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
CHECK_TICK
for(var/obj/machinery/airalarm/AA in GLOB.machines)
var/area/A = get_area(AA)
var/area/A = get_base_area(AA)
if(!A) //Make sure the target isn't inside an object, which results in runtimes.
dat += "Skipped over [AA] in invalid location, [AA.loc].<br>"
continue
LAZYSET(sub_areas_air_alarm, A.type, get_sub_areas(A, FALSE))
if(!(A.type in areas_with_air_alarm))
areas_with_air_alarm.Add(A.type)
CHECK_TICK
@@ -638,8 +642,8 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
areas_with_camera.Add(A.type)
CHECK_TICK
var/list/areas_without_APC = areas_all - areas_with_APC
var/list/areas_without_air_alarm = areas_all - areas_with_air_alarm
var/list/areas_without_APC = areas_all - (areas_with_APC + flatten_list(sub_areas_APC))
var/list/areas_without_air_alarm = areas_all - (areas_with_air_alarm + flatten_list(sub_areas_air_alarm))
var/list/areas_without_RC = areas_all - areas_with_RC
var/list/areas_without_light = areas_all - areas_with_light
var/list/areas_without_LS = areas_all - areas_with_LS
@@ -656,12 +660,18 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
dat += "<h1>AREAS WITH MULTIPLE APCS:</h1>"
for(var/areatype in areas_with_multiple_APCs)
dat += "[areatype]<br>"
if(sub_areas_APC[areatype])
dat += "&nbsp;&nbsp;SUB-AREAS:<br>&nbsp;&nbsp;"
dat += jointext(sub_areas_APC[areatype], "<br>&nbsp;&nbsp;")
CHECK_TICK
if(areas_without_air_alarm.len)
dat += "<h1>AREAS WITHOUT AN AIR ALARM:</h1>"
for(var/areatype in areas_without_air_alarm)
dat += "[areatype]<br>"
if(sub_areas_air_alarm[areatype])
dat += "&nbsp;&nbsp;SUB-AREAS:<br>&nbsp;&nbsp;"
dat += jointext(sub_areas_air_alarm[areatype], "<br>&nbsp;&nbsp;")
CHECK_TICK
if(areas_without_RC.len)
+1 -1
View File
@@ -419,7 +419,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(record_found)//If they have a record we can determine a few things.
new_character.real_name = record_found.fields["name"]
new_character.gender = record_found.fields["sex"]
new_character.gender = record_found.fields["gender"]
new_character.age = record_found.fields["age"]
new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], new record_found.fields["species"], record_found.fields["features"])
else
@@ -0,0 +1,34 @@
/datum/antagonist/abductee
name = "Abductee"
roundend_category = "abductees"
antagpanel_category = "Abductee"
var/datum/brain_trauma/abductee/brain_trauma
/datum/antagonist/abductee/on_gain()
give_objective()
. = ..()
/datum/antagonist/abductee/greet()
to_chat(owner, "<span class='warning'><b>Your mind snaps!</b></span>")
to_chat(owner, "<big><span class='warning'><b>You can't remember how you got here...</b></span></big>")
owner.announce_objectives()
/datum/antagonist/abductee/proc/give_objective()
var/mob/living/carbon/human/H = owner.current
if(istype(H))
H.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_LOBOTOMY)
var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random))
var/datum/objective/abductee/O = new objtype()
objectives += O
/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override)
update_abductor_icons_added(mob_override ? mob_override.mind : owner,"abductee")
var/mob/living/carbon/C = mob_override || owner?.current
if(istype(C))
if(brain_trauma)
qdel(brain_trauma) //make sure there's no lingering trauma
brain_trauma = C.gain_trauma(/datum/brain_trauma/abductee, TRAUMA_RESILIENCE_SURGERY)
/datum/antagonist/abductee/remove_innate_effects(mob/living/mob_override)
update_abductor_icons_removed(mob_override ? mob_override.mind : owner)
qdel(brain_trauma)
@@ -18,7 +18,7 @@
/datum/objective/abductee/paint/New()
var/color = pick(list("red", "blue", "green", "yellow", "orange", "purple", "black", "in rainbows", "in blood"))
explanation_text+= " [color]!"
explanation_text = " [color]!"
/datum/objective/abductee/speech
explanation_text = "Your brain is broken... you can only communicate in"
@@ -0,0 +1,18 @@
/datum/brain_trauma/abductee
name = "abductee mindsnapped"
desc = "The patient's brain has been scrambled by experimental procedures."
scan_desc = "brain scrambling"
gain_text = "<span class='danger'>Your mind snaps.. you feel fragmented.</span>"
lose_text = "<span class='boldnotice'>Your mind heals itself and you feel whole again.</span>"
random_gain = FALSE
clonable = TRUE
/datum/brain_trauma/abductee/on_gain()
. = ..()
if(owner.mind)
if(!owner.mind.has_antag_datum(/datum/antagonist/abductee))
owner.mind.add_antag_datum(/datum/antagonist/abductee)
/datum/brain_trauma/abductee/on_lose()
. = ..()
owner.mind?.remove_antag_datum(/datum/antagonist/abductee)
@@ -159,35 +159,6 @@
return "<div class='panel redborder'>[result.Join("<br>")]</div>"
/datum/antagonist/abductee
name = "Abductee"
roundend_category = "abductees"
antagpanel_category = "Abductee"
/datum/antagonist/abductee/on_gain()
give_objective()
. = ..()
/datum/antagonist/abductee/greet()
to_chat(owner, "<span class='warning'><b>Your mind snaps!</b></span>")
to_chat(owner, "<big><span class='warning'><b>You can't remember how you got here...</b></span></big>")
owner.announce_objectives()
/datum/antagonist/abductee/proc/give_objective()
var/mob/living/carbon/human/H = owner.current
if(istype(H))
H.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_LOBOTOMY)
var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random))
var/datum/objective/abductee/O = new objtype()
objectives += O
/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override)
update_abductor_icons_added(mob_override ? mob_override.mind : owner,"abductee")
/datum/antagonist/abductee/remove_innate_effects(mob/living/mob_override)
update_abductor_icons_removed(mob_override ? mob_override.mind : owner)
// LANDMARKS
/obj/effect/landmark/abductor
var/team_number = 1
@@ -29,6 +29,11 @@
var/stealth_armor = list("melee" = 15, "bullet" = 15, "laser" = 15, "energy" = 15, "bomb" = 15, "bio" = 15, "rad" = 15, "fire" = 70, "acid" = 70)
var/combat_armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 90, "acid" = 90)
/obj/item/clothing/suit/armor/abductor/vest/Initialize()
. = ..()
stealth_armor = getArmor(arglist(stealth_armor))
combat_armor = getArmor(arglist(combat_armor))
/obj/item/clothing/suit/armor/abductor/vest/proc/toggle_nodrop()
if(HAS_TRAIT_FROM(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT))
REMOVE_TRAIT(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT)
+1 -1
View File
@@ -22,7 +22,7 @@ Runes can either be invoked by one's self or with many different cultists. Each
icon = 'icons/obj/rune.dmi'
icon_state = "1"
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
layer = LOW_OBJ_LAYER
layer = SIGIL_LAYER
color = RUNE_COLOR_RED
var/invocation = "Aiy ele-mayo." //This is said by cultists when the rune is invoked.
+2 -1
View File
@@ -275,7 +275,8 @@
/obj/machinery/camera/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S.DisIntegrate(src)
toggle_cam(S, 0)
if(!QDELETED(S)) //If it got blown up no need to turn it off.
toggle_cam(S, 0)
return TRUE
/obj/machinery/particle_accelerator/control_box/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
@@ -22,11 +22,19 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
desc = "You aren't entirely sure what this does, but it's very beepy and boopy."
background_icon_state = "bg_tech_blue"
icon_icon = 'icons/mob/actions/actions_AI.dmi'
check_flags = AB_CHECK_CONSCIOUS //can't doomsday if dead.
var/mob/living/silicon/ai/owner_AI //The owner AI, so we don't have to typecast every time
var/uses //If we have multiple uses of the same power
var/auto_use_uses = TRUE //If we automatically use up uses on each activation
var/cooldown_period //If applicable, the time in deciseconds we have to wait before using any more modules
/datum/action/innate/ai/New()
..()
if(uses > 1)
desc = "[desc] It has [uses] use\s remaining."
button.desc = desc
/datum/action/innate/ai/Grant(mob/living/L)
. = ..()
if(!isAI(owner))
@@ -38,7 +46,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/IsAvailable()
. = ..()
if(owner_AI && owner_AI.malf_cooldown > world.time)
return
return FALSE
/datum/action/innate/ai/Trigger()
. = ..()
@@ -49,12 +57,16 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/proc/adjust_uses(amt, silent)
uses += amt
if(!silent && uses)
to_chat(owner, "<span class='notice'>[name] now has <b>[uses]</b> use[uses > 1 ? "s" : ""] remaining.</span>")
if(!uses)
if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
to_chat(owner, "<span class='warning'>[name] has run out of uses!</span>")
qdel(src)
if(uses)
if(!silent)
to_chat(owner, "<span class='notice'>[name] now has <b>[uses]</b> use[uses > 1 ? "s" : ""] remaining.</span>")
desc = "[initial(desc)] It has [uses] use\s remaining."
UpdateButtonIcon()
return
if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
to_chat(owner, "<span class='warning'>[name] has run out of uses!</span>")
qdel(src)
//Framework for ranged abilities that can have different effects by left-clicking stuff.
/datum/action/innate/ai/ranged
@@ -74,13 +86,16 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/ranged/adjust_uses(amt, silent)
uses += amt
if(!silent && uses)
to_chat(owner, "<span class='notice'>[name] now has <b>[uses]</b> use[uses > 1 ? "s" : ""] remaining.</span>")
if(!uses)
if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
to_chat(owner, "<span class='warning'>[name] has run out of uses!</span>")
Remove(owner)
QDEL_IN(src, 100) //let any active timers on us finish up
if(uses)
if(!silent)
to_chat(owner, "<span class='notice'>[name] now has <b>[uses]</b> use[uses > 1 ? "s" : ""] remaining.</span>")
desc = "[initial(desc)] It has [uses] use\s remaining."
UpdateButtonIcon()
return
if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
to_chat(owner, "<span class='warning'>[name] has run out of uses!</span>")
Remove(owner)
QDEL_IN(src, 100) //let any active timers on us finish up
/datum/action/innate/ai/ranged/Destroy()
QDEL_NULL(linked_ability)
@@ -97,7 +112,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
var/datum/action/innate/ai/ranged/attached_action
/obj/effect/proc_holder/ranged_ai/Destroy()
QDEL_NULL(attached_action)
attached_action = null
return ..()
/obj/effect/proc_holder/ranged_ai/proc/toggle(mob/user)
@@ -185,6 +200,8 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
A.playsound_local(A, AM.unlock_sound, 50, 0)
else //Adding uses to an existing module
action.uses += initial(action.uses)
action.desc = "[initial(action.desc)] It has [action.uses] use\s remaining."
action.UpdateButtonIcon()
temp = "Additional use[action.uses > 1 ? "s" : ""] added to [action.name]!"
processing_time -= AM.cost
@@ -238,6 +255,8 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
return
if(alert(owner, "Send arming signal? (true = arm, false = cancel)", "purge_all_life()", "confirm = TRUE;", "confirm = FALSE;") != "confirm = TRUE;")
return
if (active)
return //prevent the AI from activating an already active doomsday
active = TRUE
set_us_up_the_bomb(owner)
@@ -245,64 +264,64 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
set waitfor = FALSE
to_chat(owner, "<span class='small boldannounce'>run -o -a 'selfdestruct'</span>")
sleep(5)
if(!owner || QDELETED(owner))
if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "<span class='small boldannounce'>Running executable 'selfdestruct'...</span>")
sleep(rand(10, 30))
if(!owner || QDELETED(owner))
if(QDELETED(owner) || owner.stat == DEAD)
return
owner.playsound_local(owner, 'sound/misc/bloblarm.ogg', 50, 0)
to_chat(owner, "<span class='userdanger'>!!! UNAUTHORIZED SELF-DESTRUCT ACCESS !!!</span>")
to_chat(owner, "<span class='boldannounce'>This is a class-3 security violation. This incident will be reported to Central Command.</span>")
for(var/i in 1 to 3)
sleep(20)
if(!owner || QDELETED(owner))
if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "<span class='boldannounce'>Sending security report to Central Command.....[rand(0, 9) + (rand(20, 30) * i)]%</span>")
sleep(3)
if(!owner || QDELETED(owner))
if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "<span class='small boldannounce'>auth 'akjv9c88asdf12nb' ******************</span>")
owner.playsound_local(owner, 'sound/items/timer.ogg', 50, 0)
sleep(30)
if(!owner || QDELETED(owner))
if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "<span class='boldnotice'>Credentials accepted. Welcome, akjv9c88asdf12nb.</span>")
owner.playsound_local(owner, 'sound/misc/server-ready.ogg', 50, 0)
sleep(5)
if(!owner || QDELETED(owner))
if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "<span class='boldnotice'>Arm self-destruct device? (Y/N)</span>")
owner.playsound_local(owner, 'sound/misc/compiler-stage1.ogg', 50, 0)
sleep(20)
if(!owner || QDELETED(owner))
if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "<span class='small boldannounce'>Y</span>")
sleep(15)
if(!owner || QDELETED(owner))
if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "<span class='boldnotice'>Confirm arming of self-destruct device? (Y/N)</span>")
owner.playsound_local(owner, 'sound/misc/compiler-stage2.ogg', 50, 0)
sleep(10)
if(!owner || QDELETED(owner))
if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "<span class='small boldannounce'>Y</span>")
sleep(rand(15, 25))
if(!owner || QDELETED(owner))
if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "<span class='boldnotice'>Please repeat password to confirm.</span>")
owner.playsound_local(owner, 'sound/misc/compiler-stage2.ogg', 50, 0)
sleep(14)
if(!owner || QDELETED(owner))
if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "<span class='small boldannounce'>******************</span>")
sleep(40)
if(!owner || QDELETED(owner))
if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "<span class='boldnotice'>Credentials accepted. Transmitting arming signal...</span>")
owner.playsound_local(owner, 'sound/misc/server-ready.ogg', 50, 0)
sleep(30)
if(!owner || QDELETED(owner))
if(QDELETED(owner) || owner.stat == DEAD)
return
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", "aimalf")
set_security_level("delta")
@@ -724,9 +743,10 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/blackout
name = "Blackout"
desc = "Overloads lights across the station."
desc = "Overloads random lights across the station."
button_icon_state = "blackout"
uses = 3
auto_use_uses = FALSE
/datum/action/innate/ai/blackout/Activate()
for(var/obj/machinery/power/apc/apc in GLOB.apcs_list)
@@ -736,6 +756,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
apc.overload++
to_chat(owner, "<span class='notice'>Overcurrent applied to the powernet.</span>")
owner.playsound_local(owner, "sparks", 50, 0)
adjust_uses(-1)
//Disable Emergency Lights
@@ -784,11 +805,6 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
auto_use_uses = FALSE
cooldown_period = 30
/datum/action/innate/ai/reactivate_cameras/New()
..()
desc = "[desc] There are 30 reactivations remaining."
button.desc = desc
/datum/action/innate/ai/reactivate_cameras/Activate()
var/fixed_cameras = 0
for(var/V in GLOB.cameranet.cameras)
@@ -803,8 +819,6 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
to_chat(owner, "<span class='notice'>Diagnostic complete! Cameras reactivated: <b>[fixed_cameras]</b>. Reactivations remaining: <b>[uses]</b>.</span>")
owner.playsound_local(owner, 'sound/items/wirecutter.ogg', 50, 0)
adjust_uses(0, TRUE) //Checks the uses remaining
if(src && uses) //Not sure if not having src here would cause a runtime, so it's here to be safe
desc = "[initial(desc)] There are [uses] reactivations remaining."
//Upgrade Camera Network: EMP-proofs all cameras, in addition to giving them X-ray vision.
+1 -1
View File
@@ -46,7 +46,7 @@
return FALSE
switch(type)
if("feet")
if(!H.shoes)
if(!H.shoes || !(H.shoes.body_parts_covered & FEET))
affecting = H.get_bodypart(pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
H.Knockdown(60)
if(BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND)
@@ -207,7 +207,7 @@
pixel_y = (dir & 3)? (dir == 1 ? -24 : 24) : 0
if(name == initial(name))
name = "[get_area_name(src)] Air Alarm"
name = "[get_area_name(src, get_base_area = TRUE)] Air Alarm"
power_change()
set_frequency(frequency)
@@ -250,7 +250,7 @@
"danger_level" = danger_level,
)
var/area/A = get_area(src)
var/area/A = get_base_area(src)
data["atmos_alarm"] = A.atmosalm
data["fire_alarm"] = A.fire
@@ -386,8 +386,10 @@
send_signal(device_id, list("checks" = text2num(params["val"])^2), usr)
. = TRUE
if("set_external_pressure", "set_internal_pressure")
var/target = params["value"]
if(!isnull(target))
send_signal(device_id, list("[action]" = target), usr)
. = TRUE
if("reset_external_pressure")
@@ -419,12 +421,12 @@
apply_mode()
. = TRUE
if("alarm")
var/area/A = get_area(src)
var/area/A = get_base_area(src)
if(A.atmosalert(2, src))
post_alert(2)
. = TRUE
if("reset")
var/area/A = get_area(src)
var/area/A = get_base_area(src)
if(A.atmosalert(0, src))
post_alert(0)
. = TRUE
@@ -455,7 +457,7 @@
return 0
/obj/machinery/airalarm/proc/refresh_all()
var/area/A = get_area(src)
var/area/A = get_base_area(src)
for(var/id_tag in A.air_vent_names)
var/list/I = A.air_vent_info[id_tag]
if(I && I["timestamp"] + AALARM_REPORT_TIMEOUT / 2 > world.time)
@@ -506,7 +508,7 @@
return "Flood"
/obj/machinery/airalarm/proc/apply_mode()
var/area/A = get_area(src)
var/area/A = get_base_area(src)
switch(mode)
if(AALARM_MODE_SCRUBBING)
for(var/device_id in A.air_scrub_names)
@@ -644,7 +646,7 @@
icon_state = "alarm1"
var/overlay_state = AALARM_OVERLAY_OFF
var/area/A = get_area(src)
var/area/A = get_base_area(src)
switch(max(danger_level, A.atmosalm))
if(0)
add_overlay(AALARM_OVERLAY_GREEN)
@@ -714,7 +716,7 @@
return
var/datum/signal/alert_signal = new(list(
"zone" = get_area_name(src),
"zone" = get_area_name(src, get_base_area = TRUE),
"type" = "Atmospheric"
))
if(alert_level==2)
@@ -727,7 +729,7 @@
frequency.post_signal(src, alert_signal, range = -1)
/obj/machinery/airalarm/proc/apply_danger_level()
var/area/A = get_area(src)
var/area/A = get_base_area(src)
var/new_area_danger_level = 0
for(var/obj/machinery/airalarm/AA in A)
@@ -5,6 +5,7 @@
icon_state = "relief_valve-t-map"
can_unwrench = TRUE
construction_type = /obj/item/pipe/binary
interaction_flags_machine = INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE
var/opened = FALSE
var/open_pressure = ONE_ATMOSPHERE * 3
var/close_pressure = ONE_ATMOSPHERE
@@ -50,9 +51,11 @@
if(!is_operational())
return
var/datum/gas_mixture/air_contents = airs[1]
var/our_pressure = air_contents.return_pressure()
if(opened && our_pressure < close_pressure)
var/datum/gas_mixture/air_one = airs[1]
var/datum/gas_mixture/air_two = airs[2]
var/air_one_pressure = air_one.return_pressure()
var/our_pressure = abs(air_one_pressure - air_two.return_pressure())
if(opened && air_one_pressure < close_pressure)
close()
else if(!opened && our_pressure >= open_pressure)
open()

Some files were not shown because too many files have changed in this diff Show More