Merge branch 'master' into upstream-merge-31737
This commit is contained in:
@@ -240,6 +240,17 @@ This prevents nesting levels from getting deeper then they need to be.
|
||||
|
||||
* Queries must never specify the database, be it in code, or in text files in the repo.
|
||||
|
||||
### Mapping Standards
|
||||
* TGM Format & Map Merge
|
||||
* All new maps submitted to the repo through a pull request must be in TGM format (unless there is a valid reason present to have it in the default BYOND format.) This is done using the [Map Merge](https://github.com/tgstation/tgstation/wiki/Map-Merger) utility included in the repo to convert the file to TGM format.
|
||||
* Likewise, you MUST run `Map Merge - TGM.bat` prior to opening your PR when updating existing maps to minimize the change differences (even when using third party mapping programs such as FastDMM.)
|
||||
* Failure to run Map Merge on a map after using third party mapping programs (such as FastDMM) greatly increases the risk of the map's key dictionary becoming corrupted by future edits after running map merge. Resolving the corruption issue involves rebuilding the map's key dictionary; id est rewriting all the keys contained within the map by reconverting it from BYOND to TGM format - which creates very large differences that ultimately delay the PR process and is extremely likely to cause merge conflicts with other pull requests.
|
||||
|
||||
* Variable Editing (Var-edits)
|
||||
* While var-editing an item within the editor is perfectly fine, it is preferred that when you are changing the base behavior of an item (how it functions) that you make a new subtype of that item within the code, especially if you plan to use the item in multiple locations on the same map, or across multiple maps. This makes it easier to make corrections as needed to all instances of the item at one time as opposed to having to find each instance of it and change them all individually.
|
||||
* Subtypes only intended to be used on away mission or ruin maps should be contained within an .dm file with a name corresponding to that map within `code\modules\awaymissions` or `code\modules\ruins` respectively. This is so in the event that the map is removed, that subtype will be removed at the same time as well to minimize leftover/unused data within the repo.
|
||||
* Please attempt to clean out any dirty variables that may be contained within items you alter through var-editing. For example, due to how DM functions, changing the `pixel_x` variable from 23 to 0 will leave a dirty record in the map's code of `pixel_x = 0`. Likewise this can happen when changing an item's icon to something else and then back. This can lead to some issues where an item's icon has changed within the code, but becomes broken on the map due to it still attempting to use the old entry.
|
||||
* Areas should not be var-edited on a map to change it's name or attributes. All areas of a single type and it's altered instances are considered the same area within the code, and editing their variables on a map can lead to issues with powernets and event subsystems which are difficult to debug.
|
||||
|
||||
|
||||
### Other Notes
|
||||
|
||||
@@ -735,30 +735,10 @@
|
||||
/area/ruin/powered)
|
||||
"cu" = (
|
||||
/obj/structure/closet/crate/secure/engineering,
|
||||
/obj/item/wrench{
|
||||
color = "#ff0000";
|
||||
desc = "A prototype of a new wrench design, allegedly the red color scheme makes it go faster.";
|
||||
name = "experimental wrench";
|
||||
toolspeed = 3
|
||||
},
|
||||
/obj/item/screwdriver{
|
||||
color = "#ff0000";
|
||||
desc = "A prototype of a new screwdriver design, allegedly the red color scheme makes it go faster.";
|
||||
name = "experimental screwdriver";
|
||||
toolspeed = 3
|
||||
},
|
||||
/obj/item/wirecutters{
|
||||
color = "#ff0000";
|
||||
desc = "A prototype of a new wirecutter design, allegedly the red color scheme makes it go faster.";
|
||||
name = "experimental wirecutters";
|
||||
toolspeed = 3
|
||||
},
|
||||
/obj/item/crowbar/red{
|
||||
color = "#ff0000";
|
||||
desc = "A prototype of a new crowbar design, allegedly the red color scheme makes it go faster.";
|
||||
name = "experimental crowbar";
|
||||
toolspeed = 3
|
||||
},
|
||||
/obj/item/wrench/caravan,
|
||||
/obj/item/screwdriver/caravan,
|
||||
/obj/item/wirecutters/caravan,
|
||||
/obj/item/crowbar/red/caravan,
|
||||
/turf/open/floor/mineral/plastitanium,
|
||||
/area/ruin/powered)
|
||||
"cv" = (
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -893,7 +893,7 @@
|
||||
/turf/open/floor/carpet,
|
||||
/area/crew_quarters/heads/hos)
|
||||
"aco" = (
|
||||
/obj/structure/closet/bombcloset,
|
||||
/obj/structure/closet/bombcloset/security,
|
||||
/turf/open/floor/plasteel/showroomfloor,
|
||||
/area/security/main)
|
||||
"acp" = (
|
||||
@@ -57018,12 +57018,14 @@
|
||||
/obj/machinery/atmospherics/pipe/manifold/general/visible{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced/spawner/east,
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/engine,
|
||||
/area/engine/supermatter)
|
||||
"cEw" = (
|
||||
@@ -57042,12 +57044,14 @@
|
||||
/obj/machinery/atmospherics/pipe/manifold/general/visible{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced/spawner/west,
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/engine,
|
||||
/area/engine/supermatter)
|
||||
"cEz" = (
|
||||
@@ -57229,24 +57233,28 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/general/visible{
|
||||
dir = 5
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced/spawner/east,
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/engine,
|
||||
/area/engine/supermatter)
|
||||
"cFh" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/general/visible{
|
||||
dir = 9
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced/spawner/west,
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/engine,
|
||||
/area/engine/supermatter)
|
||||
"cFj" = (
|
||||
|
||||
+174996
-174932
File diff suppressed because it is too large
Load Diff
@@ -3622,6 +3622,7 @@
|
||||
min_oxy = 5;
|
||||
name = "Sergeant Araneus";
|
||||
real_name = "Sergeant Araneus";
|
||||
movement_type = 1;
|
||||
response_help = "pets";
|
||||
turns_per_move = 10;
|
||||
voice_name = "unidentifiable voice"
|
||||
@@ -4763,7 +4764,7 @@
|
||||
/turf/open/floor/plasteel,
|
||||
/area/security/warden)
|
||||
"ajw" = (
|
||||
/obj/structure/closet/bombcloset,
|
||||
/obj/structure/closet/bombcloset/security,
|
||||
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
|
||||
dir = 4
|
||||
},
|
||||
@@ -40810,6 +40811,7 @@
|
||||
network = list("MiniSat","tcomm");
|
||||
pixel_y = -29
|
||||
},
|
||||
/obj/structure/bed/dogbed/renault,
|
||||
/mob/living/simple_animal/pet/fox/Renault,
|
||||
/turf/open/floor/carpet,
|
||||
/area/crew_quarters/heads/captain/private)
|
||||
@@ -80883,9 +80885,9 @@
|
||||
/obj/machinery/atmospherics/pipe/manifold/general/visible{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced/spawner,
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable,
|
||||
/obj/structure/window/plasma/reinforced,
|
||||
/turf/open/floor/engine,
|
||||
/area/engine/supermatter)
|
||||
"dbb" = (
|
||||
@@ -82697,9 +82699,9 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/general/visible{
|
||||
dir = 10
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced/spawner,
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable,
|
||||
/obj/structure/window/plasma/reinforced,
|
||||
/turf/open/floor/engine,
|
||||
/area/engine/supermatter)
|
||||
"deU" = (
|
||||
@@ -82810,24 +82812,28 @@
|
||||
/area/engine/supermatter)
|
||||
"dfk" = (
|
||||
/obj/machinery/atmospherics/pipe/manifold/general/visible,
|
||||
/obj/structure/window/plasma/reinforced/spawner/north,
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-2";
|
||||
d2 = 2
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/engine,
|
||||
/area/engine/supermatter)
|
||||
"dfm" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/general/visible{
|
||||
dir = 9
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced/spawner/north,
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-2";
|
||||
d2 = 2
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/engine,
|
||||
/area/engine/supermatter)
|
||||
"dfp" = (
|
||||
|
||||
@@ -22161,7 +22161,7 @@
|
||||
network = list("Engine");
|
||||
pixel_x = 23
|
||||
},
|
||||
/obj/structure/cable/yellow{
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
@@ -22172,13 +22172,15 @@
|
||||
/obj/machinery/atmospherics/pipe/manifold/general/visible{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced/spawner/east,
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
/obj/structure/cable{
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/turf/open/floor/engine,
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/circuit/green,
|
||||
/area/engine/supermatter)
|
||||
"aMT" = (
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
|
||||
@@ -22199,16 +22201,18 @@
|
||||
/obj/machinery/atmospherics/pipe/manifold/general/visible{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced/spawner/west,
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
/obj/structure/cable{
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/turf/open/floor/engine,
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/circuit/green,
|
||||
/area/engine/supermatter)
|
||||
"aMX" = (
|
||||
/obj/structure/cable/yellow{
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
@@ -23109,25 +23113,29 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/general/visible{
|
||||
dir = 5
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced/spawner/east,
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
/obj/structure/cable{
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/turf/open/floor/engine,
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/circuit/green,
|
||||
/area/engine/supermatter)
|
||||
"aOD" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/general/visible{
|
||||
dir = 9
|
||||
},
|
||||
/obj/structure/window/plasma/reinforced/spawner/west,
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
/obj/structure/cable{
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/turf/open/floor/engine,
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/circuit/green,
|
||||
/area/engine/supermatter)
|
||||
"aOE" = (
|
||||
/obj/structure/cable{
|
||||
|
||||
@@ -2788,7 +2788,7 @@
|
||||
/turf/open/floor/plasteel/showroomfloor,
|
||||
/area/security/main)
|
||||
"aip" = (
|
||||
/obj/structure/closet/bombcloset,
|
||||
/obj/structure/closet/bombcloset/security,
|
||||
/obj/effect/turf_decal/delivery,
|
||||
/turf/open/floor/plasteel/showroomfloor,
|
||||
/area/security/main)
|
||||
@@ -46290,11 +46290,6 @@
|
||||
/turf/open/floor/plasteel,
|
||||
/area/engine/engineering)
|
||||
"car" = (
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "1-4";
|
||||
d1 = 1;
|
||||
d2 = 4
|
||||
},
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 1;
|
||||
d2 = 8;
|
||||
@@ -47261,16 +47256,6 @@
|
||||
/turf/open/floor/plasteel,
|
||||
/area/engine/engineering)
|
||||
"ccV" = (
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 2;
|
||||
d2 = 4;
|
||||
icon_state = "2-4"
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
},
|
||||
@@ -47282,22 +47267,12 @@
|
||||
id = "Singularity";
|
||||
name = "radiation shutters"
|
||||
},
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/effect/turf_decal/bot{
|
||||
dir = 2
|
||||
},
|
||||
/turf/open/floor/plasteel/black,
|
||||
/area/engine/engineering)
|
||||
"ccX" = (
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 2;
|
||||
d2 = 4;
|
||||
@@ -47326,11 +47301,6 @@
|
||||
/turf/open/floor/plating,
|
||||
/area/engine/engineering)
|
||||
"cda" = (
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 1;
|
||||
d2 = 4;
|
||||
icon_state = "1-4"
|
||||
},
|
||||
/obj/effect/landmark/event_spawn,
|
||||
/turf/open/floor/plating,
|
||||
/area/engine/engineering)
|
||||
@@ -47346,16 +47316,6 @@
|
||||
/turf/open/floor/plating,
|
||||
/area/engine/engineering)
|
||||
"cdc" = (
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 2;
|
||||
d2 = 8;
|
||||
icon_state = "2-8"
|
||||
},
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
},
|
||||
@@ -47599,19 +47559,9 @@
|
||||
/turf/open/floor/plasteel,
|
||||
/area/engine/engineering)
|
||||
"cdQ" = (
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 1;
|
||||
d2 = 2;
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plasteel/yellow/side,
|
||||
/area/engine/engineering)
|
||||
"cdR" = (
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 1;
|
||||
d2 = 2;
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/button/door{
|
||||
id = "Singularity";
|
||||
name = "Shutters Control";
|
||||
@@ -47666,11 +47616,6 @@
|
||||
/turf/open/floor/plating,
|
||||
/area/engine/engineering)
|
||||
"cdX" = (
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 1;
|
||||
d2 = 2;
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/button/door{
|
||||
id = "Singularity";
|
||||
name = "Shutters Control";
|
||||
@@ -47850,14 +47795,10 @@
|
||||
id = "Singularity";
|
||||
name = "radiation shutters"
|
||||
},
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 1;
|
||||
d2 = 2;
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/turf/open/floor/plating,
|
||||
/area/engine/engineering)
|
||||
"ceu" = (
|
||||
@@ -48053,9 +47994,6 @@
|
||||
/turf/open/floor/plating,
|
||||
/area/engine/engineering)
|
||||
"ceY" = (
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/item/tank/internals/plasma,
|
||||
/obj/structure/cable/yellow,
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 1
|
||||
},
|
||||
@@ -48872,6 +48810,9 @@
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/machinery/power/tesla_coil,
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
"chy" = (
|
||||
@@ -48884,6 +48825,9 @@
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/power/tesla_coil,
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
"chA" = (
|
||||
@@ -49000,7 +48944,15 @@
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
"chQ" = (
|
||||
/turf/open/space/basic,
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
"chR" = (
|
||||
/obj/structure/cable{
|
||||
@@ -54066,6 +54018,78 @@
|
||||
/obj/machinery/smoke_machine,
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/medical/chemistry)
|
||||
"YXI" = (
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/machinery/door/poddoor/shutters/preopen{
|
||||
id = "Singularity";
|
||||
name = "radiation shutters"
|
||||
},
|
||||
/obj/effect/turf_decal/bot{
|
||||
dir = 2
|
||||
},
|
||||
/turf/open/floor/plasteel/black,
|
||||
/area/engine/engineering)
|
||||
"YXJ" = (
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/turf/open/floor/plating,
|
||||
/area/engine/engineering)
|
||||
"YXK" = (
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/turf/open/floor/plating,
|
||||
/area/engine/engineering)
|
||||
"YXL" = (
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/engine/engineering)
|
||||
"YXM" = (
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 1;
|
||||
d2 = 2;
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "1-4";
|
||||
d1 = 1;
|
||||
d2 = 4
|
||||
},
|
||||
/obj/item/tank/internals/plasma,
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
"YXN" = (
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
"YXO" = (
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
"YXP" = (
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
|
||||
(1,1,1) = {"
|
||||
aaa
|
||||
@@ -81734,7 +81758,7 @@ bOG
|
||||
bva
|
||||
bDi
|
||||
bXk
|
||||
cbX
|
||||
YXJ
|
||||
cbX
|
||||
cdK
|
||||
bXk
|
||||
@@ -81991,7 +82015,7 @@ bOG
|
||||
bTE
|
||||
cae
|
||||
bXk
|
||||
cbX
|
||||
YXK
|
||||
cbX
|
||||
cdK
|
||||
bXk
|
||||
@@ -83791,20 +83815,20 @@ bZC
|
||||
cal
|
||||
cbh
|
||||
cam
|
||||
ccT
|
||||
cam
|
||||
cdQ
|
||||
cet
|
||||
ceY
|
||||
cfa
|
||||
cbX
|
||||
cfU
|
||||
cgu
|
||||
cgU
|
||||
chw
|
||||
cgU
|
||||
YXM
|
||||
chw
|
||||
chw
|
||||
chw
|
||||
cgU
|
||||
chw
|
||||
cgU
|
||||
cjs
|
||||
cfV
|
||||
cfV
|
||||
@@ -84048,18 +84072,18 @@ bZA
|
||||
cam
|
||||
cam
|
||||
cam
|
||||
ccU
|
||||
cam
|
||||
cdQ
|
||||
cet
|
||||
ceZ
|
||||
cfa
|
||||
ceY
|
||||
cbX
|
||||
cfV
|
||||
cgv
|
||||
cfV
|
||||
chx
|
||||
chQ
|
||||
chx
|
||||
cfV
|
||||
chQ
|
||||
chx
|
||||
chQ
|
||||
chx
|
||||
@@ -84308,8 +84332,8 @@ ccc
|
||||
ccV
|
||||
cdR
|
||||
cet
|
||||
ceZ
|
||||
cfa
|
||||
ceY
|
||||
cbX
|
||||
cfU
|
||||
cgv
|
||||
cgV
|
||||
@@ -85587,9 +85611,9 @@ bXo
|
||||
bYi
|
||||
bYV
|
||||
bZA
|
||||
cas
|
||||
cbk
|
||||
cce
|
||||
cdN
|
||||
YXI
|
||||
YXL
|
||||
cda
|
||||
cdV
|
||||
cex
|
||||
@@ -85847,7 +85871,7 @@ bZF
|
||||
cat
|
||||
bXk
|
||||
ccg
|
||||
cdb
|
||||
cey
|
||||
cdW
|
||||
cey
|
||||
cey
|
||||
@@ -86364,8 +86388,8 @@ cch
|
||||
cdc
|
||||
cdX
|
||||
cet
|
||||
ceZ
|
||||
cfa
|
||||
ceY
|
||||
cbX
|
||||
cfU
|
||||
cgv
|
||||
cgV
|
||||
@@ -86618,20 +86642,20 @@ bZA
|
||||
cam
|
||||
cam
|
||||
cam
|
||||
cdd
|
||||
cam
|
||||
cdQ
|
||||
cet
|
||||
ceZ
|
||||
cfa
|
||||
ceY
|
||||
cbX
|
||||
cfV
|
||||
cgv
|
||||
cfV
|
||||
chz
|
||||
chQ
|
||||
YXN
|
||||
chz
|
||||
cfV
|
||||
YXO
|
||||
chz
|
||||
chQ
|
||||
YXP
|
||||
chz
|
||||
cfV
|
||||
cfV
|
||||
@@ -86875,20 +86899,20 @@ bZC
|
||||
cal
|
||||
cbm
|
||||
cci
|
||||
cde
|
||||
cam
|
||||
cdQ
|
||||
cet
|
||||
ceZ
|
||||
cfa
|
||||
ceY
|
||||
cbX
|
||||
cfU
|
||||
cgx
|
||||
cgU
|
||||
chA
|
||||
cgU
|
||||
chA
|
||||
cgU
|
||||
chA
|
||||
cgU
|
||||
chA
|
||||
chA
|
||||
chA
|
||||
cjt
|
||||
cfV
|
||||
cfV
|
||||
|
||||
@@ -177,6 +177,19 @@
|
||||
#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland
|
||||
#define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300"
|
||||
|
||||
//IF YOU EVER CHANGE THESE CHANGE SPRITES TO MATCH.
|
||||
#define PIPING_LAYER_MIN 1
|
||||
#define PIPING_LAYER_MAX 3
|
||||
#define PIPING_LAYER_DEFAULT 2
|
||||
#define PIPING_LAYER_P_X 5
|
||||
#define PIPING_LAYER_P_Y 5
|
||||
#define PIPING_LAYER_LCHANGE 0.05
|
||||
|
||||
#define PIPING_ALL_LAYER 1 //intended to connect with all layers, check for all instead of just one.
|
||||
#define PIPING_ONE_PER_TURF 2 //can only be built if nothing else with this flag is on the tile already.
|
||||
#define PIPING_DEFAULT_LAYER_ONLY 4 //can only exist at PIPING_LAYER_DEFAULT
|
||||
#define PIPING_CARDINAL_AUTONORMALIZE 8 //north/south east/west doesn't matter, auto normalize on build.
|
||||
|
||||
#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity())
|
||||
|
||||
#define ADD_GAS(gas_id, out_list)\
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
#define islava(A) (istype(A, /turf/open/lava))
|
||||
|
||||
#define ischasm(A) (istype(A, /turf/open/chasm))
|
||||
|
||||
#define isplatingturf(A) (istype(A, /turf/open/floor/plating))
|
||||
|
||||
//Mobs
|
||||
@@ -181,4 +183,4 @@ GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list(
|
||||
/obj/item/stack/sheet/plasmaglass,
|
||||
/obj/item/stack/sheet/plasmarglass)))
|
||||
|
||||
#define is_glass_sheet(O) (is_type_in_typecache(O, GLOB.glass_sheet_types))
|
||||
#define is_glass_sheet(O) (is_type_in_typecache(O, GLOB.glass_sheet_types))
|
||||
+19
-1
@@ -93,6 +93,7 @@
|
||||
//Mob AI Status
|
||||
|
||||
//Hostile simple animals
|
||||
//If you add a new status, be sure to add a list for it to the simple_animals global in _globalvars/lists/mobs.dm
|
||||
#define AI_ON 1
|
||||
#define AI_IDLE 2
|
||||
#define AI_OFF 3
|
||||
@@ -155,4 +156,21 @@
|
||||
|
||||
#define MEGAFAUNA_DEFAULT_RECOVERY_TIME 5
|
||||
|
||||
#define SHADOW_SPECIES_LIGHT_THRESHOLD 0.2
|
||||
#define SHADOW_SPECIES_LIGHT_THRESHOLD 0.2
|
||||
|
||||
// Offsets defines
|
||||
|
||||
#define OFFSET_UNIFORM "uniform"
|
||||
#define OFFSET_ID "id"
|
||||
#define OFFSET_GLOVES "gloves"
|
||||
#define OFFSET_GLASSES "glasses"
|
||||
#define OFFSET_EARS "ears"
|
||||
#define OFFSET_SHOES "shoes"
|
||||
#define OFFSET_S_STORE "s_store"
|
||||
#define OFFSET_FACEMASK "mask"
|
||||
#define OFFSET_HEAD "head"
|
||||
#define OFFSET_FACE "face"
|
||||
#define OFFSET_BELT "belt"
|
||||
#define OFFSET_BACK "back"
|
||||
#define OFFSET_SUIT "suit"
|
||||
#define OFFSET_NECK "neck"
|
||||
@@ -7,24 +7,24 @@ Construction breaks otherwise
|
||||
//Pipes
|
||||
#define PIPE_SIMPLE /obj/machinery/atmospherics/pipe/simple
|
||||
#define PIPE_MANIFOLD /obj/machinery/atmospherics/pipe/manifold
|
||||
#define PIPE_4WAYMANIFOLD /obj/machinery/atmospherics/pipe/manifold4w
|
||||
#define PIPE_4WAYMANIFOLD /obj/machinery/atmospherics/pipe/manifold4w
|
||||
#define PIPE_HE /obj/machinery/atmospherics/pipe/heat_exchanging/simple
|
||||
#define PIPE_HE_MANIFOLD /obj/machinery/atmospherics/pipe/heat_exchanging/manifold
|
||||
#define PIPE_HE_4WAYMANIFOLD /obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w
|
||||
#define PIPE_JUNCTION /obj/machinery/atmospherics/pipe/heat_exchanging/junction
|
||||
#define PIPE_BLUESPACE /obj/machinery/atmospherics/pipe/bluespace
|
||||
#define PIPE_LAYER_MANIFOLD /obj/machinery/atmospherics/pipe/layer_manifold
|
||||
//Unary
|
||||
#define PIPE_CONNECTOR /obj/machinery/atmospherics/components/unary/portables_connector
|
||||
#define PIPE_UVENT /obj/machinery/atmospherics/components/unary/vent_pump
|
||||
#define PIPE_SCRUBBER /obj/machinery/atmospherics/components/unary/vent_scrubber
|
||||
#define PIPE_INJECTOR /obj/machinery/atmospherics/components/unary/outlet_injector
|
||||
#define PIPE_HEAT_EXCHANGE /obj/machinery/atmospherics/components/unary/heat_exchanger
|
||||
#define PIPE_HEAT_EXCHANGE /obj/machinery/atmospherics/components/unary/heat_exchanger
|
||||
//Binary
|
||||
#define PIPE_PUMP /obj/machinery/atmospherics/components/binary/pump
|
||||
#define PIPE_PASSIVE_GATE /obj/machinery/atmospherics/components/binary/passive_gate
|
||||
#define PIPE_VOLUME_PUMP /obj/machinery/atmospherics/components/binary/volume_pump
|
||||
#define PIPE_PASSIVE_GATE /obj/machinery/atmospherics/components/binary/passive_gate
|
||||
#define PIPE_VOLUME_PUMP /obj/machinery/atmospherics/components/binary/volume_pump
|
||||
#define PIPE_MVALVE /obj/machinery/atmospherics/components/binary/valve
|
||||
#define PIPE_DVALVE /obj/machinery/atmospherics/components/binary/valve/digital
|
||||
#define PIPE_DVALVE /obj/machinery/atmospherics/components/binary/valve/digital
|
||||
//Trinary
|
||||
#define PIPE_GAS_FILTER /obj/machinery/atmospherics/components/trinary/filter
|
||||
#define PIPE_GAS_MIXER /obj/machinery/atmospherics/components/trinary/mixer
|
||||
|
||||
@@ -18,13 +18,16 @@ Ask ninjanomnom if they're around
|
||||
#define RAD_TOX_COEFFICIENT 0.05 // Toxin damage per tick coefficient
|
||||
|
||||
#define RAD_MOB_SAFE 300 // How much stored radiation in a mob with no ill effects
|
||||
#define RAD_MOB_KNOCKDOWN 1500 // How much stored radiation to start stunning
|
||||
// If (mutate*2<knockdown) then monkeys will sometimes turn into gorillas before being knocked down
|
||||
// otherwise they only turn into gorillas *after* being knocked down
|
||||
#define RAD_MOB_MUTATE 800 // How much stored radiation to check for mutation
|
||||
#define RAD_MOB_HAIRLOSS 500 // How much stored radiation to check for hair loss
|
||||
|
||||
#define RAD_KNOCKDOWN_TIME 200 // How much knockdown to apply
|
||||
#define RAD_MOB_KNOCKDOWN 2000 // How much stored radiation to check for stunning
|
||||
#define RAD_MOB_KNOCKDOWN_PROB 1 // Chance of knockdown per tick when over threshold
|
||||
#define RAD_MOB_KNOCKDOWN_AMOUNT 3 // Amount of knockdown when it occurs
|
||||
|
||||
#define RAD_MOB_VOMIT 1500 // The amount of radiation to check for vomitting
|
||||
#define RAD_MOB_VOMIT_PROB 1 // Chance per tick of vomitting
|
||||
|
||||
#define RAD_MOB_MUTATE 1000 // How much stored radiation to check for mutation
|
||||
#define RAD_MOB_HAIRLOSS 500 // How much stored radiation to check for hair loss
|
||||
|
||||
#define RAD_NO_INSULATION 1.0 // For things that shouldn't become irradiated for whatever reason
|
||||
#define RAD_VERY_LIGHT_INSULATION 0.9 // What girders have
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#define FLOOR_BOT 4 // Floorbots
|
||||
#define CLEAN_BOT 8 // Cleanbots
|
||||
#define MED_BOT 16 // Medibots
|
||||
#define HONK_BOT 32 // Honkbots & ED-Honks
|
||||
|
||||
//AI notification defines
|
||||
#define NEW_BORG 1
|
||||
@@ -41,3 +42,7 @@
|
||||
#define RENAME 3
|
||||
#define AI_SHELL 4
|
||||
#define DISCONNECT 5
|
||||
|
||||
//Assembly defines
|
||||
#define ASSEMBLY_FIRST_STEP 0
|
||||
#define ASSEMBLY_SECOND_STEP 1
|
||||
|
||||
@@ -58,6 +58,8 @@
|
||||
#define DOCKING_BLOCKED 1
|
||||
#define DOCKING_IMMOBILIZED 2
|
||||
#define DOCKING_AREA_EMPTY 4
|
||||
#define DOCKING_NULL_DESTINATION 8
|
||||
#define DOCKING_NULL_SOURCE 16
|
||||
|
||||
|
||||
//Docking turf movements
|
||||
|
||||
@@ -485,6 +485,7 @@
|
||||
|
||||
//Picks from the list, with some safeties, and returns the "default" arg if it fails
|
||||
#define DEFAULTPICK(L, default) ((islist(L) && length(L)) ? pick(L) : default)
|
||||
|
||||
#define LAZYINITLIST(L) if (!L) L = list()
|
||||
#define UNSETEMPTY(L) if (L && !L.len) L = null
|
||||
#define LAZYREMOVE(L, I) if(L) { L -= I; if(!L.len) { L = null; } }
|
||||
|
||||
@@ -129,3 +129,8 @@
|
||||
return "[A.loc] [COORD(T)] ([A.loc.type])"
|
||||
else if(A.loc)
|
||||
return "[A.loc] (0, 0, 0) ([A.loc.type])"
|
||||
|
||||
|
||||
/proc/log_manifest(key,datum/mind/mind,mob/body,latejoin = FALSE)
|
||||
if (CONFIG_GET(flag/log_manifest))
|
||||
WRITE_FILE(GLOB.manifest_log, "[key] \\ [body.real_name] \\ [mind.assigned_role] \\ [mind.special_role ? mind.special_role : "NONE"] \\ [latejoin ? "LATEJOIN":"ROUNDSTART"]")
|
||||
+145
-75
@@ -308,7 +308,8 @@ world
|
||||
*/
|
||||
|
||||
/proc/ReadRGB(rgb)
|
||||
if(!rgb) return
|
||||
if(!rgb)
|
||||
return
|
||||
|
||||
// interpret the HSV or HSVA value
|
||||
var/i=1,start=1
|
||||
@@ -317,19 +318,27 @@ world
|
||||
var/digits=0
|
||||
for(i=start, i<=length(rgb), ++i)
|
||||
ch = text2ascii(rgb, i)
|
||||
if(ch < 48 || (ch > 57 && ch < 65) || (ch > 70 && ch < 97) || ch > 102) break
|
||||
if(ch < 48 || (ch > 57 && ch < 65) || (ch > 70 && ch < 97) || ch > 102)
|
||||
break
|
||||
++digits
|
||||
if(digits == 8) break
|
||||
if(digits == 8)
|
||||
break
|
||||
|
||||
var/single = digits < 6
|
||||
if(digits != 3 && digits != 4 && digits != 6 && digits != 8) return
|
||||
if(digits == 4 || digits == 8) usealpha = 1
|
||||
if(digits != 3 && digits != 4 && digits != 6 && digits != 8)
|
||||
return
|
||||
if(digits == 4 || digits == 8)
|
||||
usealpha = 1
|
||||
for(i=start, digits>0, ++i)
|
||||
ch = text2ascii(rgb, i)
|
||||
if(ch >= 48 && ch <= 57) ch -= 48
|
||||
else if(ch >= 65 && ch <= 70) ch -= 55
|
||||
else if(ch >= 97 && ch <= 102) ch -= 87
|
||||
else break
|
||||
if(ch >= 48 && ch <= 57)
|
||||
ch -= 48
|
||||
else if(ch >= 65 && ch <= 70)
|
||||
ch -= 55
|
||||
else if(ch >= 97 && ch <= 102)
|
||||
ch -= 87
|
||||
else
|
||||
break
|
||||
--digits
|
||||
switch(which)
|
||||
if(0)
|
||||
@@ -337,69 +346,91 @@ world
|
||||
if(single)
|
||||
r |= r << 4
|
||||
++which
|
||||
else if(!(digits & 1)) ++which
|
||||
else if(!(digits & 1))
|
||||
++which
|
||||
if(1)
|
||||
g = (g << 4) | ch
|
||||
if(single)
|
||||
g |= g << 4
|
||||
++which
|
||||
else if(!(digits & 1)) ++which
|
||||
else if(!(digits & 1))
|
||||
++which
|
||||
if(2)
|
||||
b = (b << 4) | ch
|
||||
if(single)
|
||||
b |= b << 4
|
||||
++which
|
||||
else if(!(digits & 1)) ++which
|
||||
else if(!(digits & 1))
|
||||
++which
|
||||
if(3)
|
||||
alpha = (alpha << 4) | ch
|
||||
if(single) alpha |= alpha << 4
|
||||
if(single)
|
||||
alpha |= alpha << 4
|
||||
|
||||
. = list(r, g, b)
|
||||
if(usealpha) . += alpha
|
||||
if(usealpha)
|
||||
. += alpha
|
||||
|
||||
/proc/ReadHSV(hsv)
|
||||
if(!hsv) return
|
||||
if(!hsv)
|
||||
return
|
||||
|
||||
// interpret the HSV or HSVA value
|
||||
var/i=1,start=1
|
||||
if(text2ascii(hsv) == 35) ++start // skip opening #
|
||||
if(text2ascii(hsv) == 35)
|
||||
++start // skip opening #
|
||||
var/ch,which=0,hue=0,sat=0,val=0,alpha=0,usealpha
|
||||
var/digits=0
|
||||
for(i=start, i<=length(hsv), ++i)
|
||||
ch = text2ascii(hsv, i)
|
||||
if(ch < 48 || (ch > 57 && ch < 65) || (ch > 70 && ch < 97) || ch > 102) break
|
||||
if(ch < 48 || (ch > 57 && ch < 65) || (ch > 70 && ch < 97) || ch > 102)
|
||||
break
|
||||
++digits
|
||||
if(digits == 9) break
|
||||
if(digits > 7) usealpha = 1
|
||||
if(digits <= 4) ++which
|
||||
if(digits <= 2) ++which
|
||||
if(digits == 9)
|
||||
break
|
||||
if(digits > 7)
|
||||
usealpha = 1
|
||||
if(digits <= 4)
|
||||
++which
|
||||
if(digits <= 2)
|
||||
++which
|
||||
for(i=start, digits>0, ++i)
|
||||
ch = text2ascii(hsv, i)
|
||||
if(ch >= 48 && ch <= 57) ch -= 48
|
||||
else if(ch >= 65 && ch <= 70) ch -= 55
|
||||
else if(ch >= 97 && ch <= 102) ch -= 87
|
||||
else break
|
||||
if(ch >= 48 && ch <= 57)
|
||||
ch -= 48
|
||||
else if(ch >= 65 && ch <= 70)
|
||||
ch -= 55
|
||||
else if(ch >= 97 && ch <= 102)
|
||||
ch -= 87
|
||||
else
|
||||
break
|
||||
--digits
|
||||
switch(which)
|
||||
if(0)
|
||||
hue = (hue << 4) | ch
|
||||
if(digits == (usealpha ? 6 : 4)) ++which
|
||||
if(digits == (usealpha ? 6 : 4))
|
||||
++which
|
||||
if(1)
|
||||
sat = (sat << 4) | ch
|
||||
if(digits == (usealpha ? 4 : 2)) ++which
|
||||
if(digits == (usealpha ? 4 : 2))
|
||||
++which
|
||||
if(2)
|
||||
val = (val << 4) | ch
|
||||
if(digits == (usealpha ? 2 : 0)) ++which
|
||||
if(digits == (usealpha ? 2 : 0))
|
||||
++which
|
||||
if(3)
|
||||
alpha = (alpha << 4) | ch
|
||||
|
||||
. = list(hue, sat, val)
|
||||
if(usealpha) . += alpha
|
||||
if(usealpha)
|
||||
. += alpha
|
||||
|
||||
/proc/HSVtoRGB(hsv)
|
||||
if(!hsv) return "#000000"
|
||||
if(!hsv)
|
||||
return "#000000"
|
||||
var/list/HSV = ReadHSV(hsv)
|
||||
if(!HSV) return "#000000"
|
||||
if(!HSV)
|
||||
return "#000000"
|
||||
|
||||
var/hue = HSV[1]
|
||||
var/sat = HSV[2]
|
||||
@@ -407,27 +438,30 @@ world
|
||||
|
||||
// Compress hue into easier-to-manage range
|
||||
hue -= hue >> 8
|
||||
if(hue >= 0x5fa) hue -= 0x5fa
|
||||
if(hue >= 0x5fa)
|
||||
hue -= 0x5fa
|
||||
|
||||
var/hi,mid,lo,r,g,b
|
||||
hi = val
|
||||
lo = round((255 - sat) * val / 255, 1)
|
||||
mid = lo + round(abs(round(hue, 510) - hue) * (hi - lo) / 255, 1)
|
||||
if(hue >= 765)
|
||||
if(hue >= 1275) {r=hi; g=lo; b=mid}
|
||||
if(hue >= 1275) {r=hi; g=lo; b=mid}
|
||||
else if(hue >= 1020) {r=mid; g=lo; b=hi }
|
||||
else {r=lo; g=mid; b=hi }
|
||||
else {r=lo; g=mid; b=hi }
|
||||
else
|
||||
if(hue >= 510) {r=lo; g=hi; b=mid}
|
||||
else if(hue >= 255) {r=mid; g=hi; b=lo }
|
||||
else {r=hi; g=mid; b=lo }
|
||||
if(hue >= 510) {r=lo; g=hi; b=mid}
|
||||
else if(hue >= 255) {r=mid; g=hi; b=lo }
|
||||
else {r=hi; g=mid; b=lo }
|
||||
|
||||
return (HSV.len > 3) ? rgb(r,g,b,HSV[4]) : rgb(r,g,b)
|
||||
|
||||
/proc/RGBtoHSV(rgb)
|
||||
if(!rgb) return "#0000000"
|
||||
if(!rgb)
|
||||
return "#0000000"
|
||||
var/list/RGB = ReadRGB(rgb)
|
||||
if(!RGB) return "#0000000"
|
||||
if(!RGB)
|
||||
return "#0000000"
|
||||
|
||||
var/r = RGB[1]
|
||||
var/g = RGB[2]
|
||||
@@ -456,15 +490,22 @@ world
|
||||
return hsv(hue, sat, val, (RGB.len>3 ? RGB[4] : null))
|
||||
|
||||
/proc/hsv(hue, sat, val, alpha)
|
||||
if(hue < 0 || hue >= 1536) hue %= 1536
|
||||
if(hue < 0) hue += 1536
|
||||
if(hue < 0 || hue >= 1536)
|
||||
hue %= 1536
|
||||
if(hue < 0)
|
||||
hue += 1536
|
||||
if((hue & 0xFF) == 0xFF)
|
||||
++hue
|
||||
if(hue >= 1536) hue = 0
|
||||
if(sat < 0) sat = 0
|
||||
if(sat > 255) sat = 255
|
||||
if(val < 0) val = 0
|
||||
if(val > 255) val = 255
|
||||
if(hue >= 1536)
|
||||
hue = 0
|
||||
if(sat < 0)
|
||||
sat = 0
|
||||
if(sat > 255)
|
||||
sat = 255
|
||||
if(val < 0)
|
||||
val = 0
|
||||
if(val > 255)
|
||||
val = 255
|
||||
. = "#"
|
||||
. += TO_HEX_DIGIT(hue >> 8)
|
||||
. += TO_HEX_DIGIT(hue >> 4)
|
||||
@@ -474,8 +515,10 @@ world
|
||||
. += TO_HEX_DIGIT(val >> 4)
|
||||
. += TO_HEX_DIGIT(val)
|
||||
if(!isnull(alpha))
|
||||
if(alpha < 0) alpha = 0
|
||||
if(alpha > 255) alpha = 255
|
||||
if(alpha < 0)
|
||||
alpha = 0
|
||||
if(alpha > 255)
|
||||
alpha = 255
|
||||
. += TO_HEX_DIGIT(alpha >> 4)
|
||||
. += TO_HEX_DIGIT(alpha)
|
||||
|
||||
@@ -493,32 +536,44 @@ world
|
||||
var/list/HSV2 = ReadHSV(hsv2)
|
||||
|
||||
// add missing alpha if needed
|
||||
if(HSV1.len < HSV2.len) HSV1 += 255
|
||||
else if(HSV2.len < HSV1.len) HSV2 += 255
|
||||
if(HSV1.len < HSV2.len)
|
||||
HSV1 += 255
|
||||
else if(HSV2.len < HSV1.len)
|
||||
HSV2 += 255
|
||||
var/usealpha = HSV1.len > 3
|
||||
|
||||
// normalize hsv values in case anything is screwy
|
||||
if(HSV1[1] > 1536) HSV1[1] %= 1536
|
||||
if(HSV2[1] > 1536) HSV2[1] %= 1536
|
||||
if(HSV1[1] < 0) HSV1[1] += 1536
|
||||
if(HSV2[1] < 0) HSV2[1] += 1536
|
||||
if(HSV1[1] > 1536)
|
||||
HSV1[1] %= 1536
|
||||
if(HSV2[1] > 1536)
|
||||
HSV2[1] %= 1536
|
||||
if(HSV1[1] < 0)
|
||||
HSV1[1] += 1536
|
||||
if(HSV2[1] < 0)
|
||||
HSV2[1] += 1536
|
||||
if(!HSV1[3]) {HSV1[1] = 0; HSV1[2] = 0}
|
||||
if(!HSV2[3]) {HSV2[1] = 0; HSV2[2] = 0}
|
||||
|
||||
// no value for one color means don't change saturation
|
||||
if(!HSV1[3]) HSV1[2] = HSV2[2]
|
||||
if(!HSV2[3]) HSV2[2] = HSV1[2]
|
||||
if(!HSV1[3])
|
||||
HSV1[2] = HSV2[2]
|
||||
if(!HSV2[3])
|
||||
HSV2[2] = HSV1[2]
|
||||
// no saturation for one color means don't change hues
|
||||
if(!HSV1[2]) HSV1[1] = HSV2[1]
|
||||
if(!HSV2[2]) HSV2[1] = HSV1[1]
|
||||
if(!HSV1[2])
|
||||
HSV1[1] = HSV2[1]
|
||||
if(!HSV2[2])
|
||||
HSV2[1] = HSV1[1]
|
||||
|
||||
// Compress hues into easier-to-manage range
|
||||
HSV1[1] -= HSV1[1] >> 8
|
||||
HSV2[1] -= HSV2[1] >> 8
|
||||
|
||||
var/hue_diff = HSV2[1] - HSV1[1]
|
||||
if(hue_diff > 765) hue_diff -= 1530
|
||||
else if(hue_diff <= -765) hue_diff += 1530
|
||||
if(hue_diff > 765)
|
||||
hue_diff -= 1530
|
||||
else if(hue_diff <= -765)
|
||||
hue_diff += 1530
|
||||
|
||||
var/hue = round(HSV1[1] + hue_diff * amount, 1)
|
||||
var/sat = round(HSV1[2] + (HSV2[2] - HSV1[2]) * amount, 1)
|
||||
@@ -526,8 +581,10 @@ world
|
||||
var/alpha = usealpha ? round(HSV1[4] + (HSV2[4] - HSV1[4]) * amount, 1) : null
|
||||
|
||||
// normalize hue
|
||||
if(hue < 0 || hue >= 1530) hue %= 1530
|
||||
if(hue < 0) hue += 1530
|
||||
if(hue < 0 || hue >= 1530)
|
||||
hue %= 1530
|
||||
if(hue < 0)
|
||||
hue += 1530
|
||||
// decompress hue
|
||||
hue += round(hue / 255)
|
||||
|
||||
@@ -547,8 +604,10 @@ world
|
||||
var/list/RGB2 = ReadRGB(rgb2)
|
||||
|
||||
// add missing alpha if needed
|
||||
if(RGB1.len < RGB2.len) RGB1 += 255
|
||||
else if(RGB2.len < RGB1.len) RGB2 += 255
|
||||
if(RGB1.len < RGB2.len)
|
||||
RGB1 += 255
|
||||
else if(RGB2.len < RGB1.len)
|
||||
RGB2 += 255
|
||||
var/usealpha = RGB1.len > 3
|
||||
|
||||
var/r = round(RGB1[1] + (RGB2[1] - RGB1[1]) * amount, 1)
|
||||
@@ -563,15 +622,18 @@ world
|
||||
|
||||
/proc/HueToAngle(hue)
|
||||
// normalize hsv in case anything is screwy
|
||||
if(hue < 0 || hue >= 1536) hue %= 1536
|
||||
if(hue < 0) hue += 1536
|
||||
if(hue < 0 || hue >= 1536)
|
||||
hue %= 1536
|
||||
if(hue < 0)
|
||||
hue += 1536
|
||||
// Compress hue into easier-to-manage range
|
||||
hue -= hue >> 8
|
||||
return hue / (1530/360)
|
||||
|
||||
/proc/AngleToHue(angle)
|
||||
// normalize hsv in case anything is screwy
|
||||
if(angle < 0 || angle >= 360) angle -= 360 * round(angle / 360)
|
||||
if(angle < 0 || angle >= 360)
|
||||
angle -= 360 * round(angle / 360)
|
||||
var/hue = angle * (1530/360)
|
||||
// Decompress hue
|
||||
hue += round(hue / 255)
|
||||
@@ -583,18 +645,23 @@ world
|
||||
var/list/HSV = ReadHSV(hsv)
|
||||
|
||||
// normalize hsv in case anything is screwy
|
||||
if(HSV[1] >= 1536) HSV[1] %= 1536
|
||||
if(HSV[1] < 0) HSV[1] += 1536
|
||||
if(HSV[1] >= 1536)
|
||||
HSV[1] %= 1536
|
||||
if(HSV[1] < 0)
|
||||
HSV[1] += 1536
|
||||
|
||||
// Compress hue into easier-to-manage range
|
||||
HSV[1] -= HSV[1] >> 8
|
||||
|
||||
if(angle < 0 || angle >= 360) angle -= 360 * round(angle / 360)
|
||||
if(angle < 0 || angle >= 360)
|
||||
angle -= 360 * round(angle / 360)
|
||||
HSV[1] = round(HSV[1] + angle * (1530/360), 1)
|
||||
|
||||
// normalize hue
|
||||
if(HSV[1] < 0 || HSV[1] >= 1530) HSV[1] %= 1530
|
||||
if(HSV[1] < 0) HSV[1] += 1530
|
||||
if(HSV[1] < 0 || HSV[1] >= 1530)
|
||||
HSV[1] %= 1530
|
||||
if(HSV[1] < 0)
|
||||
HSV[1] += 1530
|
||||
// decompress hue
|
||||
HSV[1] += round(HSV[1] / 255)
|
||||
|
||||
@@ -614,8 +681,10 @@ world
|
||||
var/gray = RGB[1]*0.3 + RGB[2]*0.59 + RGB[3]*0.11
|
||||
var/tone_gray = TONE[1]*0.3 + TONE[2]*0.59 + TONE[3]*0.11
|
||||
|
||||
if(gray <= tone_gray) return BlendRGB("#000000", tone, gray/(tone_gray || 1))
|
||||
else return BlendRGB(tone, "#ffffff", (gray-tone_gray)/((255-tone_gray) || 1))
|
||||
if(gray <= tone_gray)
|
||||
return BlendRGB("#000000", tone, gray/(tone_gray || 1))
|
||||
else
|
||||
return BlendRGB(tone, "#ffffff", (gray-tone_gray)/((255-tone_gray) || 1))
|
||||
|
||||
|
||||
//Used in the OLD chem colour mixing algorithm
|
||||
@@ -715,7 +784,8 @@ The _flatIcons list is a cache for generated icon files.
|
||||
var/image/I = current
|
||||
currentLayer = I.layer
|
||||
if(currentLayer<0) // Special case for FLY_LAYER
|
||||
if(currentLayer <= -1000) return flat
|
||||
if(currentLayer <= -1000)
|
||||
return flat
|
||||
if(pSet == 0) // Underlay
|
||||
currentLayer = A.layer+currentLayer/1000
|
||||
else // Overlay
|
||||
|
||||
@@ -13,7 +13,8 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4,
|
||||
return x!=0?x/abs(x):0
|
||||
|
||||
/proc/Atan2(x, y)
|
||||
if(!x && !y) return 0
|
||||
if(!x && !y)
|
||||
return 0
|
||||
var/a = arccos(x / sqrt(x*x + y*y))
|
||||
return y >= 0 ? a : -a
|
||||
|
||||
@@ -25,6 +26,9 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4,
|
||||
|
||||
#define Clamp(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) )
|
||||
|
||||
/proc/Modulus(x, y) //Byond's modulus doesn't work with decimals.
|
||||
return x - y * round(x / y)
|
||||
|
||||
// cotangent
|
||||
/proc/Cot(x)
|
||||
return 1 / Tan(x)
|
||||
@@ -100,10 +104,12 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4,
|
||||
. = list()
|
||||
var/d = b*b - 4 * a * c
|
||||
var/bottom = 2 * a
|
||||
if(d < 0) return
|
||||
if(d < 0)
|
||||
return
|
||||
var/root = sqrt(d)
|
||||
. += (-b + root) / bottom
|
||||
if(!d) return
|
||||
if(!d)
|
||||
return
|
||||
. += (-b - root) / bottom
|
||||
|
||||
// tangent
|
||||
|
||||
@@ -137,7 +137,8 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
return
|
||||
if(destination.y>world.maxy || destination.y<1)
|
||||
return
|
||||
else return
|
||||
else
|
||||
return
|
||||
|
||||
return destination
|
||||
|
||||
@@ -1221,6 +1222,9 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
|
||||
/proc/stack_trace(msg)
|
||||
CRASH(msg)
|
||||
|
||||
/datum/proc/stack_trace(msg)
|
||||
CRASH(msg)
|
||||
|
||||
//Key thing that stops lag. Cornerstone of performance in ss13, Just sitting here, in unsorted.dm.
|
||||
|
||||
//Increases delay as the server gets more overloaded,
|
||||
|
||||
@@ -19,7 +19,7 @@ GLOBAL_LIST_EMPTY(silicon_mobs) //all silicon mobs
|
||||
GLOBAL_LIST_EMPTY(ai_list)
|
||||
GLOBAL_LIST_EMPTY(pai_list)
|
||||
GLOBAL_LIST_EMPTY(available_ai_shells)
|
||||
GLOBAL_LIST_EMPTY(simple_animals)
|
||||
GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list())) // One for each AI_* status define
|
||||
GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs
|
||||
|
||||
GLOBAL_LIST_EMPTY(language_datum_instances)
|
||||
|
||||
@@ -5,5 +5,7 @@
|
||||
|
||||
GLOBAL_LIST_INIT(typecache_mob, typecacheof(list(/mob)))
|
||||
|
||||
GLOBAL_LIST_INIT(typecache_living, typecacheof(list(/mob/living)))
|
||||
|
||||
GLOBAL_LIST_INIT(typecache_machine_or_structure, typecacheof(list(/obj/machinery))|typecacheof(list(/obj/structure)))
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ GLOBAL_VAR(sql_error_log)
|
||||
GLOBAL_PROTECT(sql_error_log)
|
||||
GLOBAL_VAR(world_pda_log)
|
||||
GLOBAL_PROTECT(world_pda_log)
|
||||
GLOBAL_VAR(manifest_log)
|
||||
GLOBAL_PROTECT(manifest_log)
|
||||
|
||||
GLOBAL_LIST_EMPTY(bombers)
|
||||
GLOBAL_PROTECT(bombers)
|
||||
|
||||
@@ -76,7 +76,8 @@
|
||||
|
||||
// This is necessary for storage items not on your person.
|
||||
/obj/item/Adjacent(var/atom/neighbor, var/recurse = 1)
|
||||
if(neighbor == loc) return 1
|
||||
if(neighbor == loc)
|
||||
return 1
|
||||
if(isitem(loc))
|
||||
if(recurse > 0)
|
||||
return loc.Adjacent(neighbor,recurse - 1)
|
||||
|
||||
+12
-17
@@ -22,7 +22,6 @@
|
||||
else
|
||||
A.move_camera_by_click()
|
||||
|
||||
|
||||
/mob/living/silicon/ai/ClickOn(var/atom/A, params)
|
||||
if(world.time <= next_click)
|
||||
return
|
||||
@@ -36,20 +35,16 @@
|
||||
return
|
||||
|
||||
var/turf/pixel_turf = get_turf_pixel(A)
|
||||
var/turf_visible
|
||||
if(pixel_turf)
|
||||
turf_visible = GLOB.cameranet.checkTurfVis(pixel_turf)
|
||||
if(!turf_visible)
|
||||
if(istype(loc, /obj/item/device/aicard) && (pixel_turf in view(client.view, loc)))
|
||||
turf_visible = TRUE
|
||||
else
|
||||
if (pixel_turf.obscured)
|
||||
log_admin("[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)])")
|
||||
message_admins("[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))")
|
||||
if(REALTIMEOFDAY >= chnotify + 9000)
|
||||
chnotify = REALTIMEOFDAY
|
||||
send2irc_adminless_only("NOCHEAT", "[key_name(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)]))")
|
||||
return
|
||||
if(isnull(pixel_turf))
|
||||
return
|
||||
if(!can_see(A))
|
||||
message_admins("[key_name_admin(src)] might be running a modified client! (failed can_see on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))")
|
||||
var/message = "[key_name(src)] might be running a modified client! (failed can_see on AI click of [A]([COORD(pixel_turf)]))"
|
||||
log_admin(message)
|
||||
if(REALTIMEOFDAY >= chnotify + 9000)
|
||||
chnotify = REALTIMEOFDAY
|
||||
send2irc_adminless_only("NOCHEAT", message)
|
||||
return
|
||||
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["shift"] && modifiers["ctrl"])
|
||||
@@ -74,7 +69,7 @@
|
||||
if(world.time <= next_move)
|
||||
return
|
||||
|
||||
if(aicamera.in_camera_mode && pixel_turf && turf_visible)
|
||||
if(aicamera.in_camera_mode)
|
||||
aicamera.camera_mode_off()
|
||||
aicamera.captureimage(pixel_turf, usr)
|
||||
return
|
||||
@@ -150,7 +145,7 @@
|
||||
if(emagged)
|
||||
return
|
||||
if(!secondsElectrified)
|
||||
// permenant shock
|
||||
// permanent shock
|
||||
Topic("aiEnable=6", list("aiEnable"="6"), 1) // 1 meaning no window (consistency!)
|
||||
else
|
||||
// disable/6 is not in Topic; disable/5 disables both temporary and permenant shock
|
||||
|
||||
@@ -385,13 +385,11 @@
|
||||
Laser Eyes: as the name implies, handles this since nothing else does currently
|
||||
face_atom: turns the mob towards what you clicked on
|
||||
*/
|
||||
/mob/proc/LaserEyes(atom/A)
|
||||
/mob/proc/LaserEyes(atom/A, params)
|
||||
return
|
||||
|
||||
/mob/living/LaserEyes(atom/A)
|
||||
/mob/living/LaserEyes(atom/A, params)
|
||||
changeNext_move(CLICK_CD_RANGE)
|
||||
var/turf/T = get_turf(src)
|
||||
var/turf/U = get_turf(A)
|
||||
|
||||
var/obj/item/projectile/beam/LE = new /obj/item/projectile/beam( loc )
|
||||
LE.icon = 'icons/effects/genetics.dmi'
|
||||
@@ -400,10 +398,7 @@
|
||||
|
||||
LE.firer = src
|
||||
LE.def_zone = get_organ_target()
|
||||
LE.original = A
|
||||
LE.current = T
|
||||
LE.yo = U.y - T.y
|
||||
LE.xo = U.x - T.x
|
||||
LE.preparePixelProjectile(A, src, params)
|
||||
LE.fire()
|
||||
|
||||
// Simple helper to face what you clicked on, in case it should be needed in more than one place
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
almost anything into a trash can.
|
||||
*/
|
||||
/atom/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
|
||||
if(!usr || !over)
|
||||
if(!usr || !over)
|
||||
return
|
||||
if(over == src)
|
||||
return usr.client.Click(src, src_location, src_control, params)
|
||||
if(!Adjacent(usr) || !over.Adjacent(usr)) return // should stop you from dragging through windows
|
||||
if(!Adjacent(usr) || !over.Adjacent(usr))
|
||||
return // should stop you from dragging through windows
|
||||
|
||||
over.MouseDrop_T(src,usr)
|
||||
return
|
||||
|
||||
+16
-10
@@ -173,7 +173,7 @@
|
||||
|
||||
/obj/screen/alert/verygross
|
||||
name = "Very grossed out."
|
||||
desc = "I'm not feeling very well.."
|
||||
desc = "You're not feeling very well..."
|
||||
icon_state = "gross2"
|
||||
|
||||
/obj/screen/alert/disgusted
|
||||
@@ -243,7 +243,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
|
||||
|
||||
/obj/screen/alert/fire/Click()
|
||||
var/mob/living/L = usr
|
||||
if(!L.can_resist())
|
||||
if(!istype(L) || !L.can_resist())
|
||||
return
|
||||
L.changeNext_move(CLICK_CD_RESIST)
|
||||
if(L.canmove)
|
||||
@@ -491,8 +491,10 @@ so as to remain in compliance with the most up-to-date laws."
|
||||
var/atom/target = null
|
||||
|
||||
/obj/screen/alert/hackingapc/Click()
|
||||
if(!usr || !usr.client) return
|
||||
if(!target) return
|
||||
if(!usr || !usr.client)
|
||||
return
|
||||
if(!target)
|
||||
return
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
var/turf/T = get_turf(target)
|
||||
if(T)
|
||||
@@ -515,7 +517,8 @@ so as to remain in compliance with the most up-to-date laws."
|
||||
timeout = 300
|
||||
|
||||
/obj/screen/alert/notify_cloning/Click()
|
||||
if(!usr || !usr.client) return
|
||||
if(!usr || !usr.client)
|
||||
return
|
||||
var/mob/dead/observer/G = usr
|
||||
G.reenter_corpse()
|
||||
|
||||
@@ -528,10 +531,13 @@ so as to remain in compliance with the most up-to-date laws."
|
||||
var/action = NOTIFY_JUMP
|
||||
|
||||
/obj/screen/alert/notify_action/Click()
|
||||
if(!usr || !usr.client) return
|
||||
if(!target) return
|
||||
if(!usr || !usr.client)
|
||||
return
|
||||
if(!target)
|
||||
return
|
||||
var/mob/dead/observer/G = usr
|
||||
if(!istype(G)) return
|
||||
if(!istype(G))
|
||||
return
|
||||
switch(action)
|
||||
if(NOTIFY_ATTACK)
|
||||
target.attack_ghost(G)
|
||||
@@ -559,7 +565,7 @@ so as to remain in compliance with the most up-to-date laws."
|
||||
|
||||
/obj/screen/alert/restrained/Click()
|
||||
var/mob/living/L = usr
|
||||
if(!L.can_resist())
|
||||
if(!istype(L) || !L.can_resist())
|
||||
return
|
||||
L.changeNext_move(CLICK_CD_RESIST)
|
||||
if((L.canmove) && (L.last_special <= world.time))
|
||||
@@ -567,7 +573,7 @@ so as to remain in compliance with the most up-to-date laws."
|
||||
|
||||
/obj/screen/alert/restrained/buckled/Click()
|
||||
var/mob/living/L = usr
|
||||
if(!L.can_resist())
|
||||
if(!istype(L) || !L.can_resist())
|
||||
return
|
||||
L.changeNext_move(CLICK_CD_RESIST)
|
||||
if(L.last_special <= world.time)
|
||||
|
||||
@@ -180,7 +180,8 @@
|
||||
|
||||
|
||||
/datum/hud/proc/toggle_show_robot_modules()
|
||||
if(!iscyborg(mymob)) return
|
||||
if(!iscyborg(mymob))
|
||||
return
|
||||
|
||||
var/mob/living/silicon/robot/R = mymob
|
||||
|
||||
@@ -188,7 +189,8 @@
|
||||
update_robot_modules_display()
|
||||
|
||||
/datum/hud/proc/update_robot_modules_display(mob/viewer)
|
||||
if(!iscyborg(mymob)) return
|
||||
if(!iscyborg(mymob))
|
||||
return
|
||||
|
||||
var/mob/living/silicon/robot/R = mymob
|
||||
|
||||
|
||||
@@ -325,7 +325,8 @@
|
||||
usr.stop_pulling()
|
||||
|
||||
/obj/screen/pull/update_icon(mob/mymob)
|
||||
if(!mymob) return
|
||||
if(!mymob)
|
||||
return
|
||||
if(mymob.pulling)
|
||||
icon_state = "pull"
|
||||
else
|
||||
|
||||
+204
-204
@@ -1,206 +1,206 @@
|
||||
/*
|
||||
Humans:
|
||||
Adds an exception for gloves, to allow special glove types like the ninja ones.
|
||||
|
||||
Otherwise pretty standard.
|
||||
*/
|
||||
/mob/living/carbon/human/UnarmedAttack(atom/A, proximity)
|
||||
|
||||
if(!has_active_hand()) //can't attack without a hand.
|
||||
to_chat(src, "<span class='notice'>You look at your arm and sigh.</span>")
|
||||
return
|
||||
|
||||
// Special glove functions:
|
||||
// If the gloves do anything, have them return 1 to stop
|
||||
// normal attack_hand() here.
|
||||
var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines
|
||||
if(proximity && istype(G) && G.Touch(A,1))
|
||||
return
|
||||
|
||||
var/override = 0
|
||||
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
override += HM.on_attack_hand(src, A, proximity)
|
||||
|
||||
if(override)
|
||||
return
|
||||
|
||||
A.attack_hand(src)
|
||||
|
||||
/atom/proc/attack_hand(mob/user)
|
||||
return
|
||||
|
||||
/atom/proc/interact(mob/user)
|
||||
return
|
||||
|
||||
/*
|
||||
/mob/living/carbon/human/RestrainedClickOn(var/atom/A) ---carbons will handle this
|
||||
return
|
||||
*/
|
||||
|
||||
/mob/living/carbon/RestrainedClickOn(atom/A)
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/RangedAttack(atom/A)
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
if(istype(G) && G.Touch(A,0)) // for magic gloves
|
||||
return
|
||||
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
HM.on_ranged_attack(src, A)
|
||||
|
||||
if(isturf(A) && get_dist(src,A) <= 1)
|
||||
src.Move_Pulled(A)
|
||||
|
||||
/*
|
||||
Animals & All Unspecified
|
||||
*/
|
||||
/mob/living/UnarmedAttack(atom/A)
|
||||
A.attack_animal(src)
|
||||
|
||||
/atom/proc/attack_animal(mob/user)
|
||||
return
|
||||
/mob/living/RestrainedClickOn(atom/A)
|
||||
return
|
||||
|
||||
/*
|
||||
Monkeys
|
||||
*/
|
||||
/mob/living/carbon/monkey/UnarmedAttack(atom/A)
|
||||
A.attack_paw(src)
|
||||
/atom/proc/attack_paw(mob/user)
|
||||
return
|
||||
|
||||
/*
|
||||
Monkey RestrainedClickOn() was apparently the
|
||||
one and only use of all of the restrained click code
|
||||
(except to stop you from doing things while handcuffed);
|
||||
moving it here instead of various hand_p's has simplified
|
||||
things considerably
|
||||
*/
|
||||
/mob/living/carbon/monkey/RestrainedClickOn(atom/A)
|
||||
if(..())
|
||||
return
|
||||
if(a_intent != INTENT_HARM || !ismob(A))
|
||||
return
|
||||
if(is_muzzled())
|
||||
return
|
||||
var/mob/living/carbon/ML = A
|
||||
if(istype(ML))
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = null
|
||||
if(ishuman(ML))
|
||||
var/mob/living/carbon/human/H = ML
|
||||
affecting = H.get_bodypart(ran_zone(dam_zone))
|
||||
var/armor = ML.run_armor_check(affecting, "melee")
|
||||
if(prob(75))
|
||||
ML.apply_damage(rand(1,3), BRUTE, affecting, armor)
|
||||
ML.visible_message("<span class='danger'>[name] bites [ML]!</span>", \
|
||||
"<span class='userdanger'>[name] bites [ML]!</span>")
|
||||
if(armor >= 2)
|
||||
return
|
||||
/*
|
||||
Humans:
|
||||
Adds an exception for gloves, to allow special glove types like the ninja ones.
|
||||
|
||||
Otherwise pretty standard.
|
||||
*/
|
||||
/mob/living/carbon/human/UnarmedAttack(atom/A, proximity)
|
||||
|
||||
if(!has_active_hand()) //can't attack without a hand.
|
||||
to_chat(src, "<span class='notice'>You look at your arm and sigh.</span>")
|
||||
return
|
||||
|
||||
// Special glove functions:
|
||||
// If the gloves do anything, have them return 1 to stop
|
||||
// normal attack_hand() here.
|
||||
var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines
|
||||
if(proximity && istype(G) && G.Touch(A,1))
|
||||
return
|
||||
|
||||
var/override = 0
|
||||
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
override += HM.on_attack_hand(src, A, proximity)
|
||||
|
||||
if(override)
|
||||
return
|
||||
|
||||
A.attack_hand(src)
|
||||
|
||||
/atom/proc/attack_hand(mob/user)
|
||||
return
|
||||
|
||||
/atom/proc/interact(mob/user)
|
||||
return
|
||||
|
||||
/*
|
||||
/mob/living/carbon/human/RestrainedClickOn(var/atom/A) ---carbons will handle this
|
||||
return
|
||||
*/
|
||||
|
||||
/mob/living/carbon/RestrainedClickOn(atom/A)
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/RangedAttack(atom/A, mouseparams)
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
if(istype(G) && G.Touch(A,0)) // for magic gloves
|
||||
return
|
||||
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
HM.on_ranged_attack(src, A, mouseparams)
|
||||
|
||||
if(isturf(A) && get_dist(src,A) <= 1)
|
||||
src.Move_Pulled(A)
|
||||
|
||||
/*
|
||||
Animals & All Unspecified
|
||||
*/
|
||||
/mob/living/UnarmedAttack(atom/A)
|
||||
A.attack_animal(src)
|
||||
|
||||
/atom/proc/attack_animal(mob/user)
|
||||
return
|
||||
/mob/living/RestrainedClickOn(atom/A)
|
||||
return
|
||||
|
||||
/*
|
||||
Monkeys
|
||||
*/
|
||||
/mob/living/carbon/monkey/UnarmedAttack(atom/A)
|
||||
A.attack_paw(src)
|
||||
/atom/proc/attack_paw(mob/user)
|
||||
return
|
||||
|
||||
/*
|
||||
Monkey RestrainedClickOn() was apparently the
|
||||
one and only use of all of the restrained click code
|
||||
(except to stop you from doing things while handcuffed);
|
||||
moving it here instead of various hand_p's has simplified
|
||||
things considerably
|
||||
*/
|
||||
/mob/living/carbon/monkey/RestrainedClickOn(atom/A)
|
||||
if(..())
|
||||
return
|
||||
if(a_intent != INTENT_HARM || !ismob(A))
|
||||
return
|
||||
if(is_muzzled())
|
||||
return
|
||||
var/mob/living/carbon/ML = A
|
||||
if(istype(ML))
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = null
|
||||
if(ishuman(ML))
|
||||
var/mob/living/carbon/human/H = ML
|
||||
affecting = H.get_bodypart(ran_zone(dam_zone))
|
||||
var/armor = ML.run_armor_check(affecting, "melee")
|
||||
if(prob(75))
|
||||
ML.apply_damage(rand(1,3), BRUTE, affecting, armor)
|
||||
ML.visible_message("<span class='danger'>[name] bites [ML]!</span>", \
|
||||
"<span class='userdanger'>[name] bites [ML]!</span>")
|
||||
if(armor >= 2)
|
||||
return
|
||||
for(var/thing in viruses)
|
||||
var/datum/disease/D = thing
|
||||
ML.ForceContractDisease(D)
|
||||
else
|
||||
ML.visible_message("<span class='danger'>[src] has attempted to bite [ML]!</span>")
|
||||
|
||||
/*
|
||||
Aliens
|
||||
Defaults to same as monkey in most places
|
||||
*/
|
||||
/mob/living/carbon/alien/UnarmedAttack(atom/A)
|
||||
A.attack_alien(src)
|
||||
/atom/proc/attack_alien(mob/living/carbon/alien/user)
|
||||
attack_paw(user)
|
||||
return
|
||||
/mob/living/carbon/alien/RestrainedClickOn(atom/A)
|
||||
return
|
||||
|
||||
// Babby aliens
|
||||
/mob/living/carbon/alien/larva/UnarmedAttack(atom/A)
|
||||
A.attack_larva(src)
|
||||
/atom/proc/attack_larva(mob/user)
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
Slimes
|
||||
Nothing happening here
|
||||
*/
|
||||
/mob/living/simple_animal/slime/UnarmedAttack(atom/A)
|
||||
A.attack_slime(src)
|
||||
/atom/proc/attack_slime(mob/user)
|
||||
return
|
||||
/mob/living/simple_animal/slime/RestrainedClickOn(atom/A)
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
Drones
|
||||
*/
|
||||
/mob/living/simple_animal/drone/UnarmedAttack(atom/A)
|
||||
A.attack_drone(src)
|
||||
|
||||
/atom/proc/attack_drone(mob/living/simple_animal/drone/user)
|
||||
attack_hand(user) //defaults to attack_hand. Override it when you don't want drones to do same stuff as humans.
|
||||
|
||||
/mob/living/simple_animal/slime/RestrainedClickOn(atom/A)
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
True Devil
|
||||
*/
|
||||
|
||||
/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity)
|
||||
A.attack_hand(src)
|
||||
|
||||
/*
|
||||
Brain
|
||||
*/
|
||||
|
||||
/mob/living/brain/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
pAI
|
||||
*/
|
||||
|
||||
/mob/living/silicon/pai/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
Simple animals
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/UnarmedAttack(atom/A, proximity)
|
||||
if(!dextrous)
|
||||
return ..()
|
||||
if(!ismob(A))
|
||||
A.attack_hand(src)
|
||||
update_inv_hands()
|
||||
|
||||
|
||||
/*
|
||||
Hostile animals
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/hostile/UnarmedAttack(atom/A)
|
||||
target = A
|
||||
if(dextrous && !is_type_in_typecache(A, environment_target_typecache) && !ismob(A))
|
||||
..()
|
||||
else
|
||||
AttackingTarget()
|
||||
|
||||
|
||||
|
||||
/*
|
||||
New Players:
|
||||
Have no reason to click on anything at all.
|
||||
*/
|
||||
/mob/dead/new_player/ClickOn()
|
||||
return
|
||||
ML.ForceContractDisease(D)
|
||||
else
|
||||
ML.visible_message("<span class='danger'>[src] has attempted to bite [ML]!</span>")
|
||||
|
||||
/*
|
||||
Aliens
|
||||
Defaults to same as monkey in most places
|
||||
*/
|
||||
/mob/living/carbon/alien/UnarmedAttack(atom/A)
|
||||
A.attack_alien(src)
|
||||
/atom/proc/attack_alien(mob/living/carbon/alien/user)
|
||||
attack_paw(user)
|
||||
return
|
||||
/mob/living/carbon/alien/RestrainedClickOn(atom/A)
|
||||
return
|
||||
|
||||
// Babby aliens
|
||||
/mob/living/carbon/alien/larva/UnarmedAttack(atom/A)
|
||||
A.attack_larva(src)
|
||||
/atom/proc/attack_larva(mob/user)
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
Slimes
|
||||
Nothing happening here
|
||||
*/
|
||||
/mob/living/simple_animal/slime/UnarmedAttack(atom/A)
|
||||
A.attack_slime(src)
|
||||
/atom/proc/attack_slime(mob/user)
|
||||
return
|
||||
/mob/living/simple_animal/slime/RestrainedClickOn(atom/A)
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
Drones
|
||||
*/
|
||||
/mob/living/simple_animal/drone/UnarmedAttack(atom/A)
|
||||
A.attack_drone(src)
|
||||
|
||||
/atom/proc/attack_drone(mob/living/simple_animal/drone/user)
|
||||
attack_hand(user) //defaults to attack_hand. Override it when you don't want drones to do same stuff as humans.
|
||||
|
||||
/mob/living/simple_animal/slime/RestrainedClickOn(atom/A)
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
True Devil
|
||||
*/
|
||||
|
||||
/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity)
|
||||
A.attack_hand(src)
|
||||
|
||||
/*
|
||||
Brain
|
||||
*/
|
||||
|
||||
/mob/living/brain/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
pAI
|
||||
*/
|
||||
|
||||
/mob/living/silicon/pai/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
Simple animals
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/UnarmedAttack(atom/A, proximity)
|
||||
if(!dextrous)
|
||||
return ..()
|
||||
if(!ismob(A))
|
||||
A.attack_hand(src)
|
||||
update_inv_hands()
|
||||
|
||||
|
||||
/*
|
||||
Hostile animals
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/hostile/UnarmedAttack(atom/A)
|
||||
target = A
|
||||
if(dextrous && !is_type_in_typecache(A, environment_target_typecache) && !ismob(A))
|
||||
..()
|
||||
else
|
||||
AttackingTarget()
|
||||
|
||||
|
||||
|
||||
/*
|
||||
New Players:
|
||||
Have no reason to click on anything at all.
|
||||
*/
|
||||
/mob/dead/new_player/ClickOn()
|
||||
return
|
||||
|
||||
@@ -99,13 +99,14 @@
|
||||
color = "#FFADFF"//PINK, rgb(255, 173, 255)
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/on_mob_life(mob/living/M)
|
||||
if(prob(33))
|
||||
M.adjustArousalLoss(2)
|
||||
if(prob(5))
|
||||
M.emote(pick("moan","blush"))
|
||||
if(prob(5))
|
||||
var/aroused_message = pick("You feel frisky.", "You're having trouble suppressing your urges.", "You feel in the mood.")
|
||||
to_chat(M, "<span class='love'>[aroused_message]</span>")
|
||||
if(M && M.canbearoused)
|
||||
if(prob(33))
|
||||
M.adjustArousalLoss(2)
|
||||
if(prob(5))
|
||||
M.emote(pick("moan","blush"))
|
||||
if(prob(5))
|
||||
var/aroused_message = pick("You feel frisky.", "You're having trouble suppressing your urges.", "You feel in the mood.")
|
||||
to_chat(M, "<span class='love'>[aroused_message]</span>")
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/aphrodisiacplus
|
||||
@@ -120,20 +121,22 @@
|
||||
overdose_threshold = 20
|
||||
|
||||
/datum/reagent/drug/aphrodisiacplus/on_mob_life(mob/living/M)
|
||||
if(prob(33))
|
||||
M.adjustArousalLoss(6)//not quite six times as powerful, but still considerably more powerful.
|
||||
if(prob(5))
|
||||
if(M.getArousalLoss() > 75)
|
||||
M.say(pick("Hnnnnngghh...", "Ohh...", "Mmnnn..."))
|
||||
else
|
||||
M.emote(pick("moan","blush"))
|
||||
if(prob(5))
|
||||
var/aroused_message
|
||||
if(M.getArousalLoss() > 90)
|
||||
aroused_message = pick("You need to fuck someone!", "You're bursting with sexual tension!", "You can't get sex off your mind!")
|
||||
else
|
||||
aroused_message = pick("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.")
|
||||
to_chat(M, "<span class='love'>[aroused_message]</span>")
|
||||
if(M && M.canbearoused)
|
||||
if(prob(33))
|
||||
M.adjustArousalLoss(6)//not quite six times as powerful, but still considerably more powerful.
|
||||
if(prob(5))
|
||||
if(M.getArousalLoss() > 75)
|
||||
M.say(pick("Hnnnnngghh...", "Ohh...", "Mmnnn..."))
|
||||
else
|
||||
M.emote(pick("moan","blush"))
|
||||
if(prob(5))
|
||||
var/aroused_message
|
||||
if(M.getArousalLoss() > 90)
|
||||
aroused_message = pick("You need to fuck someone!", "You're bursting with sexual tension!", "You can't get sex off your mind!")
|
||||
else
|
||||
aroused_message = pick("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.")
|
||||
to_chat(M, "<span class='love'>[aroused_message]</span>")
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/aphrodisiacplus/addiction_act_stage2(mob/living/M)
|
||||
if(prob(30))
|
||||
@@ -150,7 +153,7 @@
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/aphrodisiacplus/overdose_process(mob/living/M)
|
||||
if(prob(33))
|
||||
if(M && M.canbearoused && prob(33))
|
||||
if(M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna())
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(prob(50)) //Less spam
|
||||
@@ -174,7 +177,7 @@
|
||||
reagent_state = SOLID
|
||||
|
||||
/datum/reagent/drug/anaphrodisiac/on_mob_life(mob/living/M)
|
||||
if(prob(33))
|
||||
if(M && M.canbearoused && prob(33))
|
||||
M.adjustArousalLoss(-2)
|
||||
..()
|
||||
|
||||
@@ -188,12 +191,12 @@
|
||||
overdose_threshold = 20
|
||||
|
||||
/datum/reagent/drug/anaphrodisiacplus/on_mob_life(mob/living/M)
|
||||
if(prob(33))
|
||||
if(M && M.canbearoused && prob(33))
|
||||
M.adjustArousalLoss(-4)
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/anaphrodisiacplus/overdose_process(mob/living/M)
|
||||
if(prob(33))
|
||||
if(M && M.canbearoused && prob(33))
|
||||
if(M.min_arousal > 0)
|
||||
M.min_arousal -= 1
|
||||
if(M.min_arousal > 50)
|
||||
|
||||
@@ -163,7 +163,20 @@
|
||||
item_state = "russianflask"
|
||||
volume = 60
|
||||
|
||||
|
||||
/obj/item/clothing/mask/gas/stalker
|
||||
name = "S.T.A.L.K.E.R. mask"
|
||||
desc = "Smells like reactor four."
|
||||
icon = 'icons/obj/custom.dmi'
|
||||
item_state = "stalker"
|
||||
icon_state = "stalker"
|
||||
flags_1 = BLOCK_GAS_SMOKE_EFFECT_1 | MASKINTERNALS_1
|
||||
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEFACIALHAIR
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
item_state = "gas_alt"
|
||||
gas_transfer_coefficient = 0.01
|
||||
permeability_coefficient = 0.01
|
||||
flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH
|
||||
resistance_flags = 0
|
||||
|
||||
|
||||
/*Sylas*/
|
||||
@@ -174,3 +187,18 @@
|
||||
icon_state = "petcollar-stripe"
|
||||
item_color = "petcollar-stripe"
|
||||
tagname = null
|
||||
|
||||
|
||||
/*PLACEHOLDER*/
|
||||
/obj/item/clothing/under/singery/custom
|
||||
name = "bluish performer's outfit"
|
||||
desc = "Just looking at this makes you want to sing."
|
||||
icon_state = "ssing"
|
||||
item_state = "ssing"
|
||||
item_color = "ssing"
|
||||
fitted = NO_FEMALE_UNIFORM
|
||||
alternate_worn_layer = ABOVE_SHOES_LAYER
|
||||
can_adjust = 0
|
||||
|
||||
|
||||
|
||||
|
||||
+208
-244
@@ -111,10 +111,10 @@
|
||||
var/list/env_gases = environment.gases
|
||||
|
||||
environment.assert_gases(arglist(GLOB.hardcoded_gases))
|
||||
var/o2_concentration = env_gases["o2"][MOLES]/total_moles
|
||||
var/n2_concentration = env_gases["n2"][MOLES]/total_moles
|
||||
var/co2_concentration = env_gases["co2"][MOLES]/total_moles
|
||||
var/plasma_concentration = env_gases["plasma"][MOLES]/total_moles
|
||||
var/o2_concentration = env_gases[/datum/gas/oxygen][MOLES]/total_moles
|
||||
var/n2_concentration = env_gases[/datum/gas/nitrogen][MOLES]/total_moles
|
||||
var/co2_concentration = env_gases[/datum/gas/carbon_dioxide][MOLES]/total_moles
|
||||
var/plasma_concentration = env_gases[/datum/gas/plasma][MOLES]/total_moles
|
||||
environment.garbage_collect()
|
||||
|
||||
if(abs(n2_concentration - N2STANDARD) < 20)
|
||||
@@ -321,8 +321,8 @@
|
||||
//Sleeper
|
||||
|
||||
/obj/item/device/dogborg/sleeper
|
||||
name = "Medbelly"
|
||||
desc = "Equipment for medical hound. A mounted sleeper that stabilizes patients and can inject reagents in the borg's reserves."
|
||||
name = "hound sleeper"
|
||||
desc = "nothing should see this."
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
icon_state = "sleeper"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
@@ -330,12 +330,38 @@
|
||||
var/mob/living/silicon/robot/hound = null
|
||||
var/inject_amount = 10
|
||||
var/min_health = -100
|
||||
var/cleaning = 0
|
||||
var/cleaning = FALSE
|
||||
var/cleaning_cycles = 10
|
||||
var/patient_laststat = null
|
||||
var/mob_energy = 30000 //Energy gained from digesting mobs (including PCs)
|
||||
var/list/injection_chems = list("antitoxin", "morphine", "salbutamol", "bicaridine", "kelotane"),
|
||||
var/list/injection_chems = list("antitoxin", "epinephrine", "morphine", "salbutamol", "bicaridine", "kelotane")
|
||||
var/eject_port = "ingestion"
|
||||
var/list/items_preserved = list()
|
||||
var/escape_in_progress = FALSE
|
||||
var/message_cooldown
|
||||
var/breakout_time = 300
|
||||
var/list/items_preserved = list(
|
||||
/obj/item/hand_tele,
|
||||
/obj/item/card/id,
|
||||
/obj/item/device/pda,
|
||||
/obj/item/device/aicard,
|
||||
/obj/item/gun,
|
||||
/obj/item/pinpointer,
|
||||
/obj/item/clothing/shoes/magboots,
|
||||
/obj/item/clothing/head/helmet/space,
|
||||
/obj/item/clothing/suit/space,
|
||||
/obj/item/reagent_containers/hypospray/CMO,
|
||||
/obj/item/tank/jetpack/oxygen/captain,
|
||||
/obj/item/clothing/accessory/medal/gold/captain,
|
||||
/obj/item/clothing/suit/armor,
|
||||
/obj/item/documents,
|
||||
/obj/item/nuke_core,
|
||||
/obj/item/nuke_core_container,
|
||||
/obj/item/areaeditor/blueprints,
|
||||
/obj/item/documents/syndicate,
|
||||
/obj/item/disk/nuclear,
|
||||
/obj/item/bombcore,
|
||||
/obj/item/grenade
|
||||
)
|
||||
|
||||
var/list/important_items = list(
|
||||
/obj/item/hand_tele,
|
||||
/obj/item/card/id/captains_spare,
|
||||
@@ -356,10 +382,12 @@
|
||||
/obj/item/documents/syndicate,
|
||||
/obj/item/disk/nuclear,
|
||||
/obj/item/bombcore,
|
||||
/obj/item/grenade)
|
||||
/obj/item/grenade
|
||||
)
|
||||
|
||||
/obj/item/device/dogborg/sleeper/New()
|
||||
..()
|
||||
update_icon()
|
||||
flags_1 |= NOBLUDGEON_1 //No more attack messages
|
||||
|
||||
/obj/item/device/dogborg/sleeper/Exit(atom/movable/O)
|
||||
@@ -371,16 +399,13 @@
|
||||
return
|
||||
if(!ishuman(target))
|
||||
return
|
||||
if(!target.devourable)
|
||||
to_chat(user, "<span class='warning'>This person is incompatible with our equipment.</span>")
|
||||
return
|
||||
if(target.buckled)
|
||||
to_chat(user, "<span class='warning'>The user is buckled and can not be put into your [src.name].</span>")
|
||||
return
|
||||
if(patient)
|
||||
to_chat(user, "<span class='warning'>Your [src.name] is already occupied.</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[hound.name] is ingesting [target.name] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src]...</span>")
|
||||
user.visible_message("<span class='warning'>[hound.name] is carefully inserting [target.name] into their [src.name].</span>", "<span class='notice'>You start placing [target] into your [src]...</span>")
|
||||
if(!patient && ishuman(target) && !target.buckled && do_after (user, 50, target = target))
|
||||
|
||||
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
|
||||
@@ -389,18 +414,42 @@
|
||||
if(patient) return //If you try to eat two people at once, you can only eat one.
|
||||
|
||||
else //If you don't have someone in you, proceed.
|
||||
if(!isslimeperson(target) && ("toxin" in injection_chems))
|
||||
injection_chems -= "toxin"
|
||||
injection_chems += "antitoxin"
|
||||
if(isslimeperson(target) && !("toxin" in injection_chems))
|
||||
injection_chems -= "antitoxin"
|
||||
injection_chems += "toxin"
|
||||
target.forceMove(src)
|
||||
target.reset_perspective(src)
|
||||
update_patient()
|
||||
update_gut()
|
||||
START_PROCESSING(SSobj, src)
|
||||
user.visible_message("<span class='warning'>[hound.name]'s medical pod lights up as [target.name] slips inside into their [src.name].</span>", "<span class='notice'>Your medical pod lights up as [target] slips into your [src]. Life support functions engaged.</span>")
|
||||
user.visible_message("<span class='warning'>[hound.name]'s medical pod lights up and expands as [target.name] slips inside into their [src.name].</span>", "<span class='notice'>Your medical pod lights up as [target] slips into your [src]. Life support functions engaged.</span>")
|
||||
message_admins("[key_name(hound)] has eaten [key_name(patient)] as a dogborg. ([hound ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
|
||||
playsound(hound, 'sound/effects/bin_close.ogg', 100, 1)
|
||||
|
||||
/obj/item/device/dogborg/sleeper/container_resist(mob/living/user)
|
||||
hound = loc
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
if(user.a_intent == INTENT_HELP)
|
||||
return
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the expanded material of [hound.name]'s gut!</span>", \
|
||||
"<span class='notice'>You struggle inside [src], kicking the release with your foot... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
|
||||
"<span class='italics'>You hear a thump from [hound.name].</span>")
|
||||
if(do_after(user, breakout_time, target = src))
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src )
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [hound.name]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [hound.name]!</span>")
|
||||
go_out()
|
||||
|
||||
/obj/item/device/dogborg/sleeper/proc/go_out(var/target)
|
||||
hound = src.loc
|
||||
testing("go_out activated")
|
||||
hound.setClickCooldown(50)
|
||||
if(length(contents) > 0)
|
||||
hound.visible_message("<span class='warning'>[hound.name] empties out their contents via their [eject_port] port.</span>", "<span class='notice'>You empty your contents via your [eject_port] port.</span>")
|
||||
hound.visible_message("<span class='warning'>[hound.name] empties out their contents via their release port.</span>", "<span class='notice'>You empty your contents via your release port.</span>")
|
||||
if(target)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/person = target
|
||||
@@ -419,199 +468,103 @@
|
||||
var/obj/T = C
|
||||
T.loc = hound.loc
|
||||
items_preserved.Cut()
|
||||
cleaning = 0
|
||||
update_gut()
|
||||
cleaning = FALSE
|
||||
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
update_patient()
|
||||
|
||||
else //You clicked eject with nothing in you, let's just reset stuff to be sure.
|
||||
items_preserved.Cut()
|
||||
cleaning = 0
|
||||
update_patient()
|
||||
|
||||
/obj/item/device/dogborg/sleeper/proc/drain(var/amt = 3) //Slightly reduced cost (before, it was always injecting inaprov)
|
||||
if (amt > 0)
|
||||
hound.cell.give(amt)
|
||||
else
|
||||
hound.cell.use(amt)
|
||||
cleaning = FALSE
|
||||
hound.visible_message("<span class='warning'>[hound.name] belches, torso flexing.</span>")
|
||||
update_gut()
|
||||
|
||||
/obj/item/device/dogborg/sleeper/attack_self(mob/user)
|
||||
if(..())
|
||||
return
|
||||
sleeperUI(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/device/dogborg/sleeper/proc/sleeperUI(mob/user)
|
||||
var/dat
|
||||
dat += "<h3>Injector</h3>"
|
||||
/obj/item/device/dogborg/sleeper/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
|
||||
if(patient && !(patient.stat & DEAD))
|
||||
dat += "<A href='?src=\ref[src];inject=epinephrine'>Inject Epinephrine</A>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Inject Epinephrine</span>"
|
||||
if(patient && patient.health > min_health)
|
||||
for(var/re in injection_chems)
|
||||
var/datum/reagent/C = GLOB.chemical_reagents_list[re]
|
||||
if(C)
|
||||
dat += "<BR><A href='?src=\ref[src];inject=[C.id]'>Inject [C.name]</A>"
|
||||
else
|
||||
for(var/re in injection_chems)
|
||||
var/datum/reagent/C = GLOB.chemical_reagents_list[re]
|
||||
if(C)
|
||||
dat += "<BR><span class='linkOff'>Inject [C.name]</span>"
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "dogborg_sleeper", name, 375, 550, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
dat += "<h3>Sleeper Status</h3>"
|
||||
dat += "<A id='refbutton' href='?src=\ref[src];refresh=1'>Refresh</A>"
|
||||
dat += "<A href='?src=\ref[src];eject=1'>Eject All</A>"
|
||||
dat += "<A href='?src=\ref[src];port=1'>Eject port: [eject_port]</A>"
|
||||
if(!cleaning)
|
||||
dat += "<A href='?src=\ref[src];clean=1'>Self-Clean</A>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Self-Clean</span>"
|
||||
/obj/item/device/dogborg/sleeper/ui_data()
|
||||
var/list/data = list()
|
||||
data["occupied"] = patient ? 1 : 0
|
||||
|
||||
dat += "<div class='statusDisplay'>"
|
||||
|
||||
//Cleaning and there are still un-preserved items
|
||||
if(cleaning && length(contents - items_preserved))
|
||||
dat += "<font color='red'><B>Self-cleaning mode.</B> [length(contents - items_preserved)] object(s) remaining.</font><BR>"
|
||||
data["items"] = "Self-cleaning mode active: [length(contents - items_preserved)] object(s) remaining."
|
||||
data["cleaning"] = cleaning
|
||||
if(injection_chems != null)
|
||||
data["chem"] = list()
|
||||
for(var/chem in injection_chems)
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[chem]
|
||||
data["chem"] += list(list("name" = R.name, "id" = R.id))
|
||||
|
||||
//There are no items to be processed other than un-preserved items
|
||||
else if(cleaning && length(items_preserved))
|
||||
dat += "<font color='red'><B>Self-cleaning done. Eject remaining objects now.</B></font><BR>"
|
||||
data["occupant"] = list()
|
||||
var/mob/living/mob_occupant = patient
|
||||
if(mob_occupant)
|
||||
data["occupant"]["name"] = mob_occupant.name
|
||||
switch(mob_occupant.stat)
|
||||
if(CONSCIOUS)
|
||||
data["occupant"]["stat"] = "Conscious"
|
||||
data["occupant"]["statstate"] = "good"
|
||||
if(SOFT_CRIT)
|
||||
data["occupant"]["stat"] = "Conscious"
|
||||
data["occupant"]["statstate"] = "average"
|
||||
if(UNCONSCIOUS)
|
||||
data["occupant"]["stat"] = "Unconscious"
|
||||
data["occupant"]["statstate"] = "average"
|
||||
if(DEAD)
|
||||
data["occupant"]["stat"] = "Dead"
|
||||
data["occupant"]["statstate"] = "bad"
|
||||
data["occupant"]["health"] = mob_occupant.health
|
||||
data["occupant"]["maxHealth"] = mob_occupant.maxHealth
|
||||
data["occupant"]["minHealth"] = HEALTH_THRESHOLD_DEAD
|
||||
data["occupant"]["bruteLoss"] = mob_occupant.getBruteLoss()
|
||||
data["occupant"]["oxyLoss"] = mob_occupant.getOxyLoss()
|
||||
data["occupant"]["toxLoss"] = mob_occupant.getToxLoss()
|
||||
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
|
||||
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
|
||||
data["occupant"]["brainLoss"] = mob_occupant.getBrainLoss()
|
||||
data["occupant"]["reagents"] = list()
|
||||
if(mob_occupant.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
|
||||
data["occupant"]["reagents"] += list(list("name" = R.name, "volume" = R.volume))
|
||||
return data
|
||||
|
||||
//Preserved items count when the list is populated
|
||||
if(length(items_preserved))
|
||||
dat += "<font color='red'>[length(items_preserved)] uncleanable object(s).</font><BR>"
|
||||
|
||||
if(!patient)
|
||||
dat += "Sleeper Unoccupied"
|
||||
else
|
||||
dat += "[patient.name] => "
|
||||
|
||||
switch(patient.stat)
|
||||
if(0)
|
||||
dat += "<span class='good'>Conscious</span>"
|
||||
if(1)
|
||||
dat += "<span class='average'>Unconscious</span>"
|
||||
else
|
||||
dat += "<span class='bad'>DEAD</span>"
|
||||
|
||||
var/healthcolor = (patient.health > 0 ? "color:white;" : "color:red;")
|
||||
var/brutecolor = (patient.getBruteLoss() < 60 ? "color:gray;" : "color:red;")
|
||||
var/o2color = (patient.getOxyLoss() < 60 ? "color:gray;" : "color:red;")
|
||||
var/toxcolor = (patient.getToxLoss() < 60 ? "color:gray;" : "color:red;")
|
||||
var/burncolor = (patient.getFireLoss() < 60 ? "color:gray;" : "color:red;")
|
||||
|
||||
dat += "<span style='[healthcolor]'>\t-Overall Health %: [round(patient.health)]</span><BR>"
|
||||
dat += "<span style='[brutecolor]'>\t-Brute Damage %: [patient.getBruteLoss()]</span><BR>"
|
||||
dat += "<span style='[o2color]'>\t-Respiratory Damage %: [patient.getOxyLoss()]</span><BR>"
|
||||
dat += "<span style='[toxcolor]'>\t-Toxin Content %: [patient.getToxLoss()]</span><BR>"
|
||||
dat += "<span style='[burncolor]'>\t-Burn Severity %: [patient.getFireLoss()]</span><BR>"
|
||||
|
||||
if(patient.getBrainLoss())
|
||||
dat += "<div class='line'><span class='average'>Significant brain damage detected.</span></div><br>"
|
||||
if(patient.getCloneLoss())
|
||||
dat += "<div class='line'><span class='average'>Patient may be improperly cloned.</span></div><br>"
|
||||
if(patient.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in patient.reagents.reagent_list)
|
||||
dat += "<div class='line'><div style='width: 170px;' class='statusLabel'>[R.name]:</div><div class='statusValue'>[round(R.volume, 0.1)] units</div></div><br>"
|
||||
dat += "</div>"
|
||||
|
||||
var/datum/browser/popup = new(user, "sleeper", "Sleeper Console", 520, 540) //Set up the popup browser window
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/dogborg/sleeper/Topic(href, href_list)
|
||||
if(..() || usr == patient)
|
||||
return
|
||||
usr.set_machine(src)
|
||||
if(href_list["refresh"])
|
||||
update_patient()
|
||||
src.updateUsrDialog()
|
||||
sleeperUI(usr)
|
||||
return
|
||||
if(href_list["eject"])
|
||||
go_out()
|
||||
sleeperUI(usr)
|
||||
return
|
||||
if(href_list["clean"])
|
||||
if(!cleaning)
|
||||
var/confirm = alert(usr, "You are about to engage self-cleaning mode. This will fill your [src] with caustic enzymes to remove any objects or biomatter, and convert them into energy. Are you sure?", "Confirmation", "Self-Clean", "Cancel")
|
||||
if(confirm == "Self-Clean")
|
||||
if(cleaning)
|
||||
return
|
||||
else
|
||||
cleaning = 1
|
||||
drain(500)
|
||||
START_PROCESSING(SSobj, src)
|
||||
sleeperUI(usr)
|
||||
if(patient)
|
||||
to_chat(patient, "<span class='danger'>[hound.name]'s [src.name] fills with caustic enzymes around you!</span>")
|
||||
return
|
||||
if(cleaning)
|
||||
sleeperUI(usr)
|
||||
return
|
||||
if(href_list["port"])
|
||||
switch(eject_port)
|
||||
if("ingestion")
|
||||
eject_port = "disposal"
|
||||
if("disposal")
|
||||
eject_port = "ingestion"
|
||||
sleeperUI(usr)
|
||||
/obj/item/device/dogborg/sleeper/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(patient && !(patient.stat & DEAD))
|
||||
if(href_list["inject"] == "epinephrine" || patient.health > min_health)
|
||||
inject_chem(usr, href_list["inject"])
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>ERROR: Subject is not in stable condition for injections.</span>")
|
||||
else
|
||||
to_chat(usr,"<span class='notice'>ERROR: Subject cannot metabolise chemicals.</span>")
|
||||
|
||||
src.updateUsrDialog()
|
||||
sleeperUI(usr) //Needs a callback to boop the page to refresh.
|
||||
return
|
||||
|
||||
/obj/item/device/dogborg/sleeper/proc/inject_chem(mob/user, chem)
|
||||
if(patient && patient.reagents)
|
||||
if(chem in injection_chems + "epinephrine")
|
||||
if(hound.cell.charge < 800) //This is so borgs don't kill themselves with it.
|
||||
to_chat(hound, "<span class='notice'>You don't have enough power to synthesize fluids.</span>")
|
||||
switch(action)
|
||||
if("eject")
|
||||
go_out()
|
||||
. = TRUE
|
||||
if("inject")
|
||||
var/chem = params["chem"]
|
||||
if(!patient)
|
||||
return
|
||||
else if(patient.reagents.get_reagent_amount(chem) + 10 >= 20) //Preventing people from accidentally killing themselves by trying to inject too many chemicals!
|
||||
to_chat(hound, "<span class='notice'>Your stomach is currently too full of fluids to secrete more fluids of this kind.</span>")
|
||||
else if(patient.reagents.get_reagent_amount(chem) + 10 <= 20) //No overdoses for you
|
||||
patient.reagents.add_reagent(chem, inject_amount)
|
||||
drain(750) //-750 charge per injection
|
||||
var/units = round(patient.reagents.get_reagent_amount(chem))
|
||||
to_chat(hound, "<span class='notice'>Injecting [units] unit\s of [injection_chems[chem]] into occupant.</span>") //If they were immersed, the reagents wouldn't leave with them.
|
||||
|
||||
/obj/item/device/dogborg/sleeper/process()
|
||||
|
||||
if(cleaning) //We're cleaning, return early after calling this as we don't care about the patient.
|
||||
src.clean_cycle()
|
||||
return
|
||||
|
||||
if(patient) //We're caring for the patient. Medical emergency! Or endo scene.
|
||||
update_patient()
|
||||
if(patient.health < 0)
|
||||
patient.adjustOxyLoss(-1) //Heal some oxygen damage if they're in critical condition
|
||||
patient.updatehealth()
|
||||
patient.AdjustStun(-80)
|
||||
patient.AdjustKnockdown(-80)
|
||||
patient.AdjustUnconscious(-80)
|
||||
src.drain()
|
||||
if((patient.reagents.get_reagent_amount("epinephrine") < 5) && (patient.health < patient.maxHealth)) //Stop pumping full HP people full of drugs. Don't heal people you're digesting, meanie.
|
||||
patient.reagents.add_reagent("epinephrine", 5)
|
||||
return
|
||||
|
||||
if(!patient && !cleaning) //We think we're done working.
|
||||
if(!update_patient()) //One last try to find someone
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
|
||||
/obj/item/device/dogborg/sleeper/proc/update_patient()
|
||||
inject_chem(chem)
|
||||
. = TRUE
|
||||
if("cleaning")
|
||||
testing("cleaning attempted")
|
||||
if(!contents)
|
||||
testing("cleaning has no contents")
|
||||
to_chat(src, "Your [src] is already cleaned.")
|
||||
return
|
||||
if(patient)
|
||||
to_chat(patient, "<span class='danger'>[hound.name]'s [src.name] fills with caustic enzymes around you!</span>")
|
||||
testing("clean_cycle activated")
|
||||
to_chat(src, "<span class='danger'>Cleaning process enabled.</span>")
|
||||
clean_cycle()
|
||||
. = TRUE
|
||||
|
||||
/obj/item/device/dogborg/sleeper/proc/update_gut()
|
||||
testing("update_gut proc fired")
|
||||
//Well, we HAD one, what happened to them?
|
||||
if(patient in contents)
|
||||
if(patient_laststat != patient.stat)
|
||||
@@ -661,7 +614,7 @@
|
||||
|
||||
//Gurgleborg process
|
||||
/obj/item/device/dogborg/sleeper/proc/clean_cycle()
|
||||
|
||||
testing("clean_cycle activated")
|
||||
//Sanity? Maybe not required. More like if indigestible person OOC escapes.
|
||||
for(var/I in items_preserved)
|
||||
if(!(I in contents))
|
||||
@@ -669,24 +622,10 @@
|
||||
|
||||
var/list/touchable_items = contents - items_preserved
|
||||
|
||||
//Belly is entirely empty
|
||||
if(!length(contents))
|
||||
to_chat(hound, "<span class='notice'>Your [src.name] is now clean. Ending self-cleaning cycle.</span>")
|
||||
cleaning = 0
|
||||
update_patient()
|
||||
return
|
||||
|
||||
//sound effects
|
||||
for(var/mob/living/M in contents)
|
||||
if(prob(20))
|
||||
M.stop_sound_channel(CHANNEL_PRED)
|
||||
playsound(get_turf(hound),"digest_pred",75,0,-6,0,channel=CHANNEL_PRED)
|
||||
M.stop_sound_channel(CHANNEL_PRED)
|
||||
M.playsound_local("digest_prey",60)
|
||||
|
||||
//If the timing is right, and there are items to be touched
|
||||
if(SSmobs.times_fired%6==1 && length(touchable_items))
|
||||
|
||||
if(cleaning_cycles)
|
||||
testing("clean_cycle being used")
|
||||
cleaning_cycles--
|
||||
cleaning = TRUE
|
||||
//Burn all the mobs or add them to the exclusion list
|
||||
for(var/mob/living/carbon/human/T in (touchable_items))
|
||||
if((T.status_flags & GODMODE) || !T.digestable)
|
||||
@@ -694,7 +633,29 @@
|
||||
else
|
||||
T.adjustBruteLoss(2)
|
||||
T.adjustFireLoss(3)
|
||||
src.update_patient()
|
||||
update_gut()
|
||||
addtimer(CALLBACK(src, .proc/clean_cycle), 50)
|
||||
else
|
||||
testing("clean_cycle resetted")
|
||||
cleaning_cycles = initial(cleaning_cycles)
|
||||
cleaning = FALSE
|
||||
update_gut()
|
||||
to_chat(hound, "<span class='notice'>Your [src.name] chimes it ends its self-cleaning cycle.</span>")//Belly is entirely empty
|
||||
|
||||
if(!length(contents))
|
||||
to_chat(hound, "<span class='notice'>Your [src.name] is now clean. Ending self-cleaning cycle.</span>")
|
||||
cleaning = FALSE
|
||||
update_gut()
|
||||
return
|
||||
|
||||
//sound effects
|
||||
for(var/mob/living/M in contents)
|
||||
if(prob(50))
|
||||
M.stop_sound_channel(CHANNEL_PRED)
|
||||
playsound(get_turf(hound),"digest_pred",75,0,-6,0,channel=CHANNEL_PRED)
|
||||
M.stop_sound_channel(CHANNEL_PRED)
|
||||
M.playsound_local("digest_prey",60)
|
||||
|
||||
|
||||
//Pick a random item to deal with (if there are any)
|
||||
var/atom/target = pick(touchable_items)
|
||||
@@ -704,17 +665,17 @@
|
||||
var/mob/living/carbon/human/T = target
|
||||
|
||||
//Mob is now dead
|
||||
if(T.stat & DEAD && T.digestable)
|
||||
if(T.stat == DEAD && T.digestable)
|
||||
message_admins("[key_name(hound)] has digested [key_name(T)] as a dogborg. ([hound ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
|
||||
to_chat(hound,"<span class='notice'>You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems.</span>")
|
||||
to_chat(T,"<span class='notice'>You feel [hound]'s belly slowly churn around your form, breaking you down into a soft slurry to be used as power for [hound]'s systems.</span>")
|
||||
src.drain(-30000) //Fueeeeellll
|
||||
src.hound.cell.give(30000) //Fueeeeellll
|
||||
T.stop_sound_channel(CHANNEL_PRED)
|
||||
playsound(get_turf(hound),"death_pred",50,0,-6,0,channel=CHANNEL_PRED)
|
||||
T.stop_sound_channel(CHANNEL_PRED)
|
||||
T.playsound_local("death_prey",60)
|
||||
qdel(T)
|
||||
src.update_patient()
|
||||
src.update_gut()
|
||||
|
||||
//Handle the target being anything but a /mob/living/carbon/human
|
||||
else
|
||||
@@ -727,38 +688,40 @@
|
||||
|
||||
//If the object is not one to preserve
|
||||
else
|
||||
//Special case for PDAs as they are dumb. TODO fix Del on PDAs to be less dumb.
|
||||
if (istype(T, /obj/item/device/pda))
|
||||
var/obj/item/device/pda/PDA = T
|
||||
if (PDA.id)
|
||||
PDA.id.forceMove(src)
|
||||
PDA.id = null
|
||||
qdel(T)
|
||||
qdel(T)
|
||||
src.update_gut()
|
||||
src.hound.cell.give(10)
|
||||
return
|
||||
|
||||
//Special case for IDs to make them digested
|
||||
//else if (istype(T, /obj/item/card/id))
|
||||
//var/obj/item/card/id/ID = T
|
||||
//ID.digest() //Need the digest proc, first.
|
||||
|
||||
//Anything not perserved, PDA, or ID
|
||||
else
|
||||
//Spill(T) //Needs the spill proc to be added
|
||||
qdel(T)
|
||||
src.update_patient()
|
||||
src.hound.cell.give(30) //10 charge? that was such a practically nonexistent number it hardly gave any purpose for this bit :v *cranks up*
|
||||
/obj/item/device/dogborg/sleeper/proc/inject_chem(chem)
|
||||
testing("inject chem triggered, checking power")
|
||||
if(hound.cell.charge <= 800) //This is so borgs don't kill themselves with it. Remember, 750 charge used every injection.
|
||||
to_chat(hound, "<span class='notice'>You don't have enough power to synthesize fluids.</span>")
|
||||
return
|
||||
testing("Has power, checking for overdose")
|
||||
if(patient.reagents.get_reagent_amount(chem) + 10 >= 20) //Preventing people from accidentally killing themselves by trying to inject too many chemicals!
|
||||
to_chat(hound, "<span class='notice'>Your stomach is currently too full of fluids to secrete more fluids of this kind.</span>")
|
||||
return
|
||||
testing("isn't overdosing, attempting to add_reagent")
|
||||
patient.reagents.add_reagent(chem, 10)
|
||||
testing("add_reagent")
|
||||
src.hound.cell.use(750) //-750 charge per injection
|
||||
testing("draining power")
|
||||
var/units = round(patient.reagents.get_reagent_amount(chem))
|
||||
to_chat(hound, "<span class='notice'>Injecting [units] unit\s of [chem] into occupant.</span>") //If they were immersed, the reagents wouldn't leave with them.
|
||||
|
||||
|
||||
/obj/item/device/dogborg/sleeper/container_resist()
|
||||
if(prob(8))
|
||||
go_out()
|
||||
/obj/item/device/dogborg/sleeper/medihound //Medihound sleeper
|
||||
name = "Mobile Sleeper"
|
||||
desc = "Equipment for medical hound. A mounted sleeper that stabilizes patients and can inject reagents in the borg's reserves."
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
icon_state = "sleeper"
|
||||
|
||||
/obj/item/device/dogborg/sleeper/K9 //The K9 portabrig
|
||||
name = "Mobile Brig"
|
||||
desc = "Equipment for a K9 unit. A mounted portable-brig that holds criminals."
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
icon_state = "sleeperb"
|
||||
inject_amount = 10
|
||||
inject_amount = 0
|
||||
min_health = -100
|
||||
injection_chems = null //So they don't have all the same chems as the medihound!
|
||||
|
||||
@@ -791,7 +754,7 @@
|
||||
return //If they moved away, you can't eat them.
|
||||
brigman.forceMove(src)
|
||||
brigman.reset_perspective(src)
|
||||
update_patient()
|
||||
update_gut()
|
||||
START_PROCESSING(SSobj, src)
|
||||
user.visible_message("<span class='warning'>[hound.name]'s mobile brig clunks in series as [brigman] slips inside.</span>", "<span class='notice'>Your mobile brig groans lightly as [brigman] slips inside.</span>")
|
||||
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) // Really don't need ERP sound effects for robots
|
||||
@@ -803,9 +766,9 @@
|
||||
desc = "A mounted garbage compactor unit with fuel processor."
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
icon_state = "compactor"
|
||||
inject_amount = 10
|
||||
inject_amount = 0
|
||||
min_health = -100
|
||||
injection_chems = null //So they don't have all the same chems as the medihound!
|
||||
injection_chems = null
|
||||
var/max_item_count = 48
|
||||
|
||||
/obj/item/storage/attackby(obj/item/device/dogborg/sleeper/compactor, mob/user, proximity) //GIT CIRCUMVENTED YO!
|
||||
@@ -828,7 +791,7 @@
|
||||
if(target_obj.type in important_items)
|
||||
to_chat(user,"<span class='warning'>\The [target] registers an error code to your [src.name]</span>")
|
||||
return
|
||||
if(target_obj.w_class > WEIGHT_CLASS_SMALL)
|
||||
if(target_obj.w_class > WEIGHT_CLASS_NORMAL)
|
||||
to_chat(user,"<span class='warning'>\The [target] is too large to fit into your [src.name]</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[hound.name] is ingesting [target.name] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src.name]...</span>")
|
||||
@@ -860,7 +823,7 @@
|
||||
return //If they moved away, you can't eat them.
|
||||
trashman.forceMove(src)
|
||||
trashman.reset_perspective(src)
|
||||
update_patient()
|
||||
update_gut()
|
||||
START_PROCESSING(SSobj, src)
|
||||
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [trashman] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [trashman] slips inside.</span>")
|
||||
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1)
|
||||
@@ -917,6 +880,7 @@
|
||||
return
|
||||
|
||||
if(cell.charge <= 500)
|
||||
to_chat(src,"<span class='danger'>Insufficent reserves for jump actuators!</span>")
|
||||
return
|
||||
|
||||
else
|
||||
|
||||
@@ -55,6 +55,8 @@ CONFIG_DEF(flag/log_twitter) // log certain expliotable parrots and other such f
|
||||
|
||||
CONFIG_DEF(flag/log_world_topic) // log all world.Topic() calls
|
||||
|
||||
CONFIG_DEF(flag/log_manifest) // log crew manifest to seperate file
|
||||
|
||||
CONFIG_DEF(flag/allow_admin_ooccolor) // Allows admins with relevant permissions to have their own ooc colour
|
||||
|
||||
CONFIG_DEF(flag/allow_vote_restart) // allow votes to restart
|
||||
@@ -199,9 +201,6 @@ CONFIG_DEF(flag/load_jobs_from_txt)
|
||||
|
||||
CONFIG_DEF(flag/forbid_singulo_possession)
|
||||
|
||||
CONFIG_DEF(flag/useircbot) //tgs2 support
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/automute_on) //enables automuting/spam prevention
|
||||
|
||||
CONFIG_DEF(string/panic_server_name)
|
||||
|
||||
@@ -276,16 +276,29 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
|
||||
|
||||
/datum/DBColumn/proc/SqlTypeName(type_handler = sql_type)
|
||||
switch(type_handler)
|
||||
if(TINYINT) return "TINYINT"
|
||||
if(SMALLINT) return "SMALLINT"
|
||||
if(MEDIUMINT) return "MEDIUMINT"
|
||||
if(INTEGER) return "INTEGER"
|
||||
if(BIGINT) return "BIGINT"
|
||||
if(FLOAT) return "FLOAT"
|
||||
if(DOUBLE) return "DOUBLE"
|
||||
if(DATE) return "DATE"
|
||||
if(DATETIME) return "DATETIME"
|
||||
if(TIMESTAMP) return "TIMESTAMP"
|
||||
if(TIME) return "TIME"
|
||||
if(STRING) return "STRING"
|
||||
if(BLOB) return "BLOB"
|
||||
if(TINYINT)
|
||||
return "TINYINT"
|
||||
if(SMALLINT)
|
||||
return "SMALLINT"
|
||||
if(MEDIUMINT)
|
||||
return "MEDIUMINT"
|
||||
if(INTEGER)
|
||||
return "INTEGER"
|
||||
if(BIGINT)
|
||||
return "BIGINT"
|
||||
if(FLOAT)
|
||||
return "FLOAT"
|
||||
if(DOUBLE)
|
||||
return "DOUBLE"
|
||||
if(DATE)
|
||||
return "DATE"
|
||||
if(DATETIME)
|
||||
return "DATETIME"
|
||||
if(TIMESTAMP)
|
||||
return "TIMESTAMP"
|
||||
if(TIME)
|
||||
return "TIME"
|
||||
if(STRING)
|
||||
return "STRING"
|
||||
if(BLOB)
|
||||
return "BLOB"
|
||||
|
||||
@@ -385,7 +385,8 @@ SUBSYSTEM_DEF(garbage)
|
||||
find_references(TRUE)
|
||||
|
||||
/datum/proc/DoSearchVar(X, Xname)
|
||||
if(usr && usr.client && !usr.client.running_find_references) return
|
||||
if(usr && usr.client && !usr.client.running_find_references)
|
||||
return
|
||||
if(istype(X, /datum))
|
||||
var/datum/D = X
|
||||
if(D.last_find_references == last_find_references)
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
SUBSYSTEM_DEF(idlenpcpool)
|
||||
name = "Idling NPC Pool"
|
||||
flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
|
||||
priority = 10
|
||||
wait = 60
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/idlenpcpool/stat_entry()
|
||||
var/list/idlelist = GLOB.simple_animals[AI_IDLE]
|
||||
..("IdleNPCS:[idlelist.len]")
|
||||
|
||||
/datum/controller/subsystem/idlenpcpool/fire(resumed = FALSE)
|
||||
|
||||
if (!resumed)
|
||||
var/list/idlelist = GLOB.simple_animals[AI_IDLE]
|
||||
src.currentrun = idlelist.Copy()
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
|
||||
while(currentrun.len)
|
||||
var/mob/living/simple_animal/SA = currentrun[currentrun.len]
|
||||
--currentrun.len
|
||||
|
||||
if(!SA.ckey)
|
||||
if(SA.stat != DEAD)
|
||||
SA.handle_automated_movement()
|
||||
if(SA.stat != DEAD)
|
||||
SA.consider_wakeup()
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
@@ -567,3 +567,41 @@ SUBSYSTEM_DEF(job)
|
||||
var/msg = "Unable to send mob [M] to late join!"
|
||||
message_admins(msg)
|
||||
CRASH(msg)
|
||||
|
||||
|
||||
///////////////////////////////////
|
||||
//Keeps track of all living heads//
|
||||
///////////////////////////////////
|
||||
/datum/controller/subsystem/job/proc/get_living_heads()
|
||||
. = list()
|
||||
for(var/mob/living/carbon/human/player in GLOB.mob_list)
|
||||
if(player.stat != DEAD && player.mind && (player.mind.assigned_role in GLOB.command_positions))
|
||||
. |= player.mind
|
||||
|
||||
|
||||
////////////////////////////
|
||||
//Keeps track of all heads//
|
||||
////////////////////////////
|
||||
/datum/controller/subsystem/job/proc/get_all_heads()
|
||||
. = list()
|
||||
for(var/mob/player in GLOB.mob_list)
|
||||
if(player.mind && (player.mind.assigned_role in GLOB.command_positions))
|
||||
. |= player.mind
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//Keeps track of all living security members//
|
||||
//////////////////////////////////////////////
|
||||
/datum/controller/subsystem/job/proc/get_living_sec()
|
||||
. = list()
|
||||
for(var/mob/living/carbon/human/player in GLOB.mob_list)
|
||||
if(player.stat != DEAD && player.mind && (player.mind.assigned_role in GLOB.security_positions))
|
||||
. |= player.mind
|
||||
|
||||
////////////////////////////////////////
|
||||
//Keeps track of all security members//
|
||||
////////////////////////////////////////
|
||||
/datum/controller/subsystem/job/proc/get_all_sec()
|
||||
. = list()
|
||||
for(var/mob/living/carbon/human/player in GLOB.mob_list)
|
||||
if(player.mind && (player.mind.assigned_role in GLOB.security_positions))
|
||||
. |= player.mind
|
||||
@@ -37,7 +37,8 @@ SUBSYSTEM_DEF(npcpool)
|
||||
// 5. Do all assignments: goes through the delegated/coordianted bots and assigns the right variables/tasks to them.
|
||||
|
||||
if (!resumed)
|
||||
src.currentrun = GLOB.simple_animals.Copy()
|
||||
var/list/activelist = GLOB.simple_animals[AI_ON]
|
||||
src.currentrun = activelist.Copy()
|
||||
stage = PROCESSING_SIMPLES
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
@@ -28,7 +28,6 @@ SUBSYSTEM_DEF(pai)
|
||||
card.setPersonality(pai)
|
||||
|
||||
SSticker.mode.update_cult_icons_removed(card.pai.mind)
|
||||
SSticker.mode.update_rev_icons_removed(card.pai.mind)
|
||||
|
||||
candidates -= candidate
|
||||
usr << browse(null, "window=findPai")
|
||||
|
||||
@@ -59,14 +59,14 @@ SUBSYSTEM_DEF(persistence)
|
||||
path = text2path(old_secret_satchels[pos]["saved_obj"])
|
||||
|
||||
if(F)
|
||||
if(isfloorturf(F.loc) && !istype(F.loc, /turf/open/floor/plating/))
|
||||
if(isfloorturf(F.loc) && !isplatingturf(F.loc))
|
||||
F.hide(1)
|
||||
if(ispath(path))
|
||||
new path(F)
|
||||
placed_satchel++
|
||||
var/free_satchels = 0
|
||||
for(var/turf/T in shuffle(block(locate(TRANSITIONEDGE,TRANSITIONEDGE,ZLEVEL_STATION_PRIMARY), locate(world.maxx-TRANSITIONEDGE,world.maxy-TRANSITIONEDGE,ZLEVEL_STATION_PRIMARY)))) //Nontrivially expensive but it's roundstart only
|
||||
if(isfloorturf(T) && !istype(T, /turf/open/floor/plating/))
|
||||
if(isfloorturf(T) && !isplatingturf(T))
|
||||
new /obj/item/storage/backpack/satchel/flat/secret(T)
|
||||
free_satchels++
|
||||
if((free_satchels + placed_satchel) == 10) //ten tiles, more than enough to kill anything that moves
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(projectiles)
|
||||
name = "Projectiles"
|
||||
priority = 25
|
||||
wait = 1
|
||||
stat_tag = "PP"
|
||||
flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING
|
||||
var/global_max_tick_moves = 10
|
||||
@@ -12,6 +12,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/force_ending = 0 //Round was ended by admin intervention
|
||||
// If true, there is no lobby phase, the game starts immediately.
|
||||
var/start_immediately = FALSE
|
||||
var/setup_done = FALSE //All game setup done including mode post setup and
|
||||
|
||||
var/hide_mode = 0
|
||||
var/datum/game_mode/mode = null
|
||||
@@ -331,6 +332,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/list/adm = get_admin_counts()
|
||||
var/list/allmins = adm["present"]
|
||||
send2irc("Server", "Round [GLOB.round_id ? "#[GLOB.round_id]:" : "of"] [hide_mode ? "secret":"[mode.name]"] has started[allmins.len ? ".":" with no active admins online!"]")
|
||||
setup_done = TRUE
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/OnRoundstart(datum/callback/cb)
|
||||
if(!HasRoundStarted())
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/datum/antagonist/abductor
|
||||
name = "Abductor"
|
||||
job_rank = ROLE_ABDUCTOR
|
||||
var/datum/objective_team/abductor_team/team
|
||||
var/sub_role
|
||||
var/outfit
|
||||
@@ -18,9 +19,15 @@
|
||||
landmark_type = /obj/effect/landmark/abductor/scientist
|
||||
greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve."
|
||||
|
||||
/datum/antagonist/abductor/New(datum/mind/new_owner, datum/objective_team/abductor_team/T)
|
||||
team = T
|
||||
return ..()
|
||||
/datum/antagonist/abductor/create_team(datum/objective_team/abductor_team/new_team)
|
||||
if(!new_team)
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
team = new_team
|
||||
|
||||
/datum/antagonist/abductor/get_team()
|
||||
return team
|
||||
|
||||
/datum/antagonist/abductor/on_gain()
|
||||
SSticker.mode.abductors += owner
|
||||
@@ -31,7 +38,6 @@
|
||||
|
||||
/datum/antagonist/abductor/on_removal()
|
||||
SSticker.mode.abductors -= owner
|
||||
team.members -= owner
|
||||
owner.objectives -= team.objectives
|
||||
if(owner.current)
|
||||
to_chat(owner.current,"<span class='userdanger'>You are no longer the [owner.special_role]!</span>")
|
||||
@@ -7,6 +7,8 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
var/can_coexist_with_others = TRUE //Whether or not the person will be able to have more than one datum
|
||||
var/list/typecache_datum_blacklist = list() //List of datums this type can't coexist with
|
||||
var/delete_on_mind_deletion = TRUE
|
||||
var/job_rank
|
||||
var/replace_banned = TRUE //Should replace jobbaned player with ghosts if granted.
|
||||
|
||||
/datum/antagonist/New(datum/mind/new_owner)
|
||||
GLOB.antagonists += src
|
||||
@@ -23,9 +25,10 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
|
||||
/datum/antagonist/proc/can_be_owned(datum/mind/new_owner)
|
||||
. = TRUE
|
||||
if(owner.has_antag_datum(type))
|
||||
var/datum/mind/tested = new_owner || owner
|
||||
if(tested.has_antag_datum(type))
|
||||
return FALSE
|
||||
for(var/i in owner.antag_datums)
|
||||
for(var/i in tested.antag_datums)
|
||||
var/datum/antagonist/A = i
|
||||
if(is_type_in_typecache(src, A.typecache_datum_blacklist))
|
||||
return FALSE
|
||||
@@ -42,12 +45,35 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
/datum/antagonist/proc/remove_innate_effects(mob/living/mob_override)
|
||||
return
|
||||
|
||||
//Assign default team and creates one for one of a kind team antagonists
|
||||
/datum/antagonist/proc/create_team(datum/objective_team/team)
|
||||
return
|
||||
|
||||
//Proc called when the datum is given to a mind.
|
||||
/datum/antagonist/proc/on_gain()
|
||||
if(owner && owner.current)
|
||||
if(!silent)
|
||||
greet()
|
||||
apply_innate_effects()
|
||||
if(is_banned(owner.current) && replace_banned)
|
||||
replace_banned_player()
|
||||
|
||||
/datum/antagonist/proc/is_banned(mob/M)
|
||||
if(!M)
|
||||
return FALSE
|
||||
. = (jobban_isbanned(M,"Syndicate") || (job_rank && jobban_isbanned(M,job_rank)))
|
||||
|
||||
/datum/antagonist/proc/replace_banned_player()
|
||||
set waitfor = FALSE
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [name]?", "[name]", null, job_rank, 50, owner.current)
|
||||
var/mob/dead/observer/theghost = null
|
||||
if(candidates.len)
|
||||
theghost = pick(candidates)
|
||||
to_chat(owner, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!")
|
||||
message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(owner.current)]) to replace a jobbaned player.")
|
||||
owner.current.ghostize(0)
|
||||
owner.current.key = theghost.key
|
||||
|
||||
/datum/antagonist/proc/on_removal()
|
||||
remove_innate_effects()
|
||||
@@ -55,6 +81,9 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
LAZYREMOVE(owner.antag_datums, src)
|
||||
if(!silent && owner.current)
|
||||
farewell()
|
||||
var/datum/objective_team/team = get_team()
|
||||
if(team)
|
||||
team.remove_member(owner)
|
||||
qdel(src)
|
||||
|
||||
/datum/antagonist/proc/greet()
|
||||
@@ -62,3 +91,14 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
|
||||
/datum/antagonist/proc/farewell()
|
||||
return
|
||||
|
||||
//Returns the team antagonist belongs to if any.
|
||||
/datum/antagonist/proc/get_team()
|
||||
return
|
||||
|
||||
//Should probably be on ticker or job ss ?
|
||||
/proc/get_antagonists(antag_type,specific = FALSE)
|
||||
. = list()
|
||||
for(var/datum/antagonist/A in GLOB.antagonists)
|
||||
if(!specific && istype(A,antag_type) || specific && A.type == antag_type)
|
||||
. += A.owner
|
||||
@@ -1,22 +1,30 @@
|
||||
/datum/antagonist/brother
|
||||
name = "Brother"
|
||||
job_rank = ROLE_BROTHER
|
||||
var/special_role = "blood brother"
|
||||
var/datum/objective_team/brother_team/team
|
||||
|
||||
/datum/antagonist/brother/New(datum/mind/new_owner, datum/objective_team/brother_team/T)
|
||||
team = T
|
||||
/datum/antagonist/brother/New(datum/mind/new_owner)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/brother/create_team(datum/objective_team/brother_team/new_team)
|
||||
if(!new_team)
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
team = new_team
|
||||
|
||||
/datum/antagonist/brother/get_team()
|
||||
return team
|
||||
|
||||
/datum/antagonist/brother/on_gain()
|
||||
SSticker.mode.brothers += owner
|
||||
owner.special_role = special_role
|
||||
owner.objectives += team.objectives
|
||||
finalize_brother()
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/brother/on_removal()
|
||||
SSticker.mode.brothers -= owner
|
||||
team.members -= owner
|
||||
owner.objectives -= team.objectives
|
||||
if(owner.current)
|
||||
to_chat(owner.current,"<span class='userdanger'>You are no longer the [special_role]!</span>")
|
||||
@@ -1,6 +1,8 @@
|
||||
//CLOCKCULT PROOF OF CONCEPT
|
||||
/datum/antagonist/clockcult
|
||||
name = "Clock Cultist"
|
||||
var/datum/action/innate/hierophant/hierophant_network = new()
|
||||
job_rank = ROLE_SERVANT_OF_RATVAR
|
||||
|
||||
/datum/antagonist/clockcult/silent
|
||||
silent = TRUE
|
||||
@@ -47,8 +49,6 @@
|
||||
var/mob/living/current = owner.current
|
||||
SSticker.mode.servants_of_ratvar += owner
|
||||
SSticker.mode.update_servant_icons_added(owner)
|
||||
if(jobban_isbanned(current, ROLE_SERVANT_OF_RATVAR))
|
||||
addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, current, ROLE_SERVANT_OF_RATVAR, ROLE_SERVANT_OF_RATVAR), 0)
|
||||
owner.special_role = "Servant of Ratvar"
|
||||
owner.current.log_message("<font color=#BE8700>Has been converted to the cult of Ratvar!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
if(issilicon(current))
|
||||
@@ -1,8 +1,10 @@
|
||||
#define SUMMON_POSSIBILITIES 3
|
||||
|
||||
/datum/antagonist/cult
|
||||
name = "Cultist"
|
||||
var/datum/action/innate/cult/comm/communion = new
|
||||
var/datum/action/innate/cult/mastervote/vote = new
|
||||
job_rank = ROLE_CULTIST
|
||||
|
||||
/datum/antagonist/cult/Destroy()
|
||||
QDEL_NULL(communion)
|
||||
@@ -73,8 +75,6 @@
|
||||
add_objectives()
|
||||
SSticker.mode.cult += owner // Only add after they've been given objectives
|
||||
cult_memorization(owner)
|
||||
if(jobban_isbanned(current, ROLE_CULTIST))
|
||||
addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, current, ROLE_CULTIST, ROLE_CULTIST), 0)
|
||||
SSticker.mode.update_cult_icons_added(owner)
|
||||
current.log_message("<font color=#960000>Has been converted to the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
if(GLOB.blood_target && GLOB.blood_target_image && current.client)
|
||||
@@ -1,5 +1,6 @@
|
||||
/datum/antagonist/traitor
|
||||
name = "Traitor"
|
||||
job_rank = ROLE_TRAITOR
|
||||
var/should_specialise = TRUE //do we split into AI and human
|
||||
var/base_datum_custom = ANTAG_DATUM_TRAITOR_CUSTOM //used for body transfer
|
||||
var/ai_datum = ANTAG_DATUM_TRAITOR_AI
|
||||
|
||||
@@ -85,6 +85,8 @@ GLOBAL_LIST_INIT(devil_title, list("Lord ", "Prelate ", "Count ", "Viscount ", "
|
||||
GLOBAL_LIST_INIT(devil_syllable, list("hal", "ve", "odr", "neit", "ci", "quon", "mya", "folth", "wren", "geyr", "hil", "niet", "twou", "phi", "coa"))
|
||||
GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", ", the Lord of all things", ", Jr."))
|
||||
/datum/antagonist/devil
|
||||
name = "Devil"
|
||||
job_rank = ROLE_DEVIL
|
||||
//Don't delete upon mind destruction, otherwise soul re-selling will break.
|
||||
delete_on_mind_deletion = FALSE
|
||||
var/obligation
|
||||
@@ -107,7 +109,6 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/violin,
|
||||
/obj/effect/proc_holder/spell/targeted/summon_dancefloor))
|
||||
var/ascendable = FALSE
|
||||
name = "Devil"
|
||||
|
||||
|
||||
/datum/antagonist/devil/New()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/datum/antagonist/ninja
|
||||
name = "Ninja"
|
||||
job_rank = ROLE_NINJA
|
||||
var/helping_station = 0
|
||||
var/give_objectives = TRUE
|
||||
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
//How often to check for promotion possibility
|
||||
#define HEAD_UPDATE_PERIOD 300
|
||||
|
||||
/datum/antagonist/rev
|
||||
name = "Revolutionary"
|
||||
job_rank = ROLE_REV
|
||||
var/hud_type = "rev"
|
||||
var/datum/objective_team/revolution/rev_team
|
||||
|
||||
/datum/antagonist/rev/can_be_owned(datum/mind/new_owner)
|
||||
. = ..()
|
||||
if(new_owner.assigned_role in GLOB.command_positions)
|
||||
return FALSE
|
||||
if(new_owner.unconvertable)
|
||||
return FALSE
|
||||
|
||||
/datum/antagonist/rev/apply_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_rev_icons_added(M)
|
||||
|
||||
/datum/antagonist/rev/remove_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_rev_icons_removed(M)
|
||||
|
||||
/datum/antagonist/rev/proc/equip_rev()
|
||||
return
|
||||
|
||||
/datum/antagonist/rev/New()
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/rev/on_gain()
|
||||
. = ..()
|
||||
create_objectives()
|
||||
equip_rev()
|
||||
owner.current.log_message("<font color='red'>Has been converted to the revolution!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
|
||||
/datum/antagonist/rev/on_removal()
|
||||
remove_objectives()
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/rev/greet()
|
||||
to_chat(owner, "<span class='danger'><FONT size = 3> You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!</FONT></span>")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/rev/create_team(datum/objective_team/revolution/new_team)
|
||||
if(!new_team)
|
||||
//For now only one revolution at a time
|
||||
for(var/datum/antagonist/rev/head/H in GLOB.antagonists)
|
||||
if(H.rev_team)
|
||||
rev_team = H.rev_team
|
||||
return
|
||||
rev_team = new /datum/objective_team/revolution
|
||||
rev_team.update_objectives()
|
||||
rev_team.update_heads()
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
rev_team = new_team
|
||||
|
||||
/datum/antagonist/rev/get_team()
|
||||
return rev_team
|
||||
|
||||
/datum/antagonist/rev/proc/create_objectives()
|
||||
owner.objectives |= rev_team.objectives
|
||||
|
||||
/datum/antagonist/rev/proc/remove_objectives()
|
||||
owner.objectives -= rev_team.objectives
|
||||
|
||||
//Bump up to head_rev
|
||||
/datum/antagonist/rev/proc/promote()
|
||||
var/old_team = rev_team
|
||||
var/datum/mind/old_owner = owner
|
||||
silent = TRUE
|
||||
owner.remove_antag_datum(/datum/antagonist/rev)
|
||||
var/datum/antagonist/rev/head/new_revhead = new(old_owner)
|
||||
new_revhead.silent = TRUE
|
||||
old_owner.add_antag_datum(new_revhead,old_team)
|
||||
new_revhead.silent = FALSE
|
||||
to_chat(old_owner, "<span class='userdanger'>You have proved your devotion to revolution! You are a head revolutionary now!</span>")
|
||||
|
||||
|
||||
/datum/antagonist/rev/head
|
||||
name = "Head Revolutionary"
|
||||
hud_type = "rev_head"
|
||||
var/remove_clumsy = FALSE
|
||||
var/give_flash = FALSE
|
||||
var/give_hud = FALSE
|
||||
|
||||
/datum/antagonist/rev/proc/update_rev_icons_added(mob/living/M)
|
||||
var/datum/atom_hud/antag/revhud = GLOB.huds[ANTAG_HUD_REV]
|
||||
revhud.join_hud(M)
|
||||
set_antag_hud(M,hud_type)
|
||||
|
||||
/datum/antagonist/rev/proc/update_rev_icons_removed(mob/living/M)
|
||||
var/datum/atom_hud/antag/revhud = GLOB.huds[ANTAG_HUD_REV]
|
||||
revhud.leave_hud(M)
|
||||
set_antag_hud(M, null)
|
||||
|
||||
/datum/antagonist/rev/proc/can_be_converted(mob/living/candidate)
|
||||
if(!candidate.mind)
|
||||
return FALSE
|
||||
if(!can_be_owned(candidate.mind))
|
||||
return FALSE
|
||||
var/mob/living/carbon/C = candidate //Check to see if the potential rev is implanted
|
||||
if(!istype(C)) //Can't convert simple animals
|
||||
return FALSE
|
||||
if(C.isloyal())
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/antagonist/rev/proc/add_revolutionary(datum/mind/rev_mind,stun = TRUE)
|
||||
if(!can_be_converted(rev_mind.current))
|
||||
return FALSE
|
||||
if(stun)
|
||||
if(iscarbon(rev_mind.current))
|
||||
var/mob/living/carbon/carbon_mob = rev_mind.current
|
||||
carbon_mob.silent = max(carbon_mob.silent, 5)
|
||||
carbon_mob.flash_act(1, 1)
|
||||
rev_mind.current.Stun(100)
|
||||
rev_mind.add_antag_datum(/datum/antagonist/rev,rev_team)
|
||||
rev_mind.special_role = "Revolutionary"
|
||||
return TRUE
|
||||
|
||||
/datum/antagonist/rev/head/proc/demote()
|
||||
var/datum/mind/old_owner = owner
|
||||
var/old_team = rev_team
|
||||
silent = TRUE
|
||||
owner.remove_antag_datum(/datum/antagonist/rev/head)
|
||||
var/datum/antagonist/rev/new_rev = new /datum/antagonist/rev(old_owner)
|
||||
new_rev.silent = TRUE
|
||||
old_owner.add_antag_datum(new_rev,old_team)
|
||||
new_rev.silent = FALSE
|
||||
to_chat(old_owner, "<span class='userdanger'>Revolution has been disappointed of your leader traits! You are a regular revolutionary now!</span>")
|
||||
|
||||
/datum/antagonist/rev/farewell()
|
||||
if(ishuman(owner.current))
|
||||
owner.current.visible_message("[owner.current] looks like they just remembered their real allegiance!", \
|
||||
"<span class='userdanger'><FONT size = 3>You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...</FONT></span>")
|
||||
else if(issilicon(owner.current))
|
||||
owner.current.visible_message("The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.", \
|
||||
"<span class='userdanger'><FONT size = 3>The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you.</FONT></span>")
|
||||
|
||||
/datum/antagonist/rev/proc/remove_revolutionary(borged, deconverter)
|
||||
log_attack("[owner.current] (Key: [key_name(owner.current)]) has been deconverted from the revolution by [deconverter] (Key: [key_name(deconverter)])!")
|
||||
if(borged)
|
||||
message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been borged while being a [name]")
|
||||
owner.special_role = null
|
||||
if(iscarbon(owner.current))
|
||||
var/mob/living/carbon/C = owner.current
|
||||
C.Unconscious(100)
|
||||
owner.remove_antag_datum(type)
|
||||
|
||||
/datum/antagonist/rev/head/remove_revolutionary(borged,deconverter)
|
||||
if(!borged)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/rev/head/equip_rev()
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
if(!istype(H))
|
||||
return
|
||||
|
||||
if(remove_clumsy && owner.assigned_role == "Clown")
|
||||
to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
|
||||
H.dna.remove_mutation(CLOWNMUT)
|
||||
|
||||
if(give_flash)
|
||||
var/obj/item/device/assembly/flash/T = new(H)
|
||||
var/list/slots = list (
|
||||
"backpack" = slot_in_backpack,
|
||||
"left pocket" = slot_l_store,
|
||||
"right pocket" = slot_r_store
|
||||
)
|
||||
var/where = H.equip_in_one_of_slots(T, slots)
|
||||
if (!where)
|
||||
to_chat(H, "The Syndicate were unfortunately unable to get you a flash.")
|
||||
else
|
||||
to_chat(H, "The flash in your [where] will help you to persuade the crew to join your cause.")
|
||||
|
||||
if(give_hud)
|
||||
var/obj/item/organ/cyberimp/eyes/hud/security/syndicate/S = new(H)
|
||||
S.Insert(H, special = FALSE, drop_if_replaced = FALSE)
|
||||
to_chat(H, "Your eyes have been implanted with a cybernetic security HUD which will help you keep track of who is mindshield-implanted, and therefore unable to be recruited.")
|
||||
|
||||
/datum/objective_team/revolution
|
||||
name = "Revolution"
|
||||
var/list/objectives = list()
|
||||
var/max_headrevs = 3
|
||||
|
||||
/datum/objective_team/revolution/proc/update_objectives(initial = FALSE)
|
||||
var/untracked_heads = SSjob.get_all_heads()
|
||||
for(var/datum/objective/mutiny/O in objectives)
|
||||
untracked_heads -= O.target
|
||||
for(var/datum/mind/M in untracked_heads)
|
||||
var/datum/objective/mutiny/new_target = new()
|
||||
new_target.team = src
|
||||
new_target.target = M
|
||||
new_target.update_explanation_text()
|
||||
objectives += new_target
|
||||
for(var/datum/mind/M in members)
|
||||
M.objectives |= objectives
|
||||
|
||||
addtimer(CALLBACK(src,.proc/update_objectives),HEAD_UPDATE_PERIOD,TIMER_UNIQUE)
|
||||
|
||||
/datum/objective_team/revolution/proc/head_revolutionaries()
|
||||
. = list()
|
||||
for(var/datum/mind/M in members)
|
||||
if(M.has_antag_datum(/datum/antagonist/rev/head))
|
||||
. += M
|
||||
|
||||
/datum/objective_team/revolution/proc/update_heads()
|
||||
if(SSticker.HasRoundStarted())
|
||||
var/list/datum/mind/head_revolutionaries = head_revolutionaries()
|
||||
var/list/datum/mind/heads = SSjob.get_all_heads()
|
||||
var/list/sec = SSjob.get_all_sec()
|
||||
|
||||
if(head_revolutionaries.len < max_headrevs && head_revolutionaries.len < round(heads.len - ((8 - sec.len) / 3)))
|
||||
var/list/datum/mind/non_heads = members - head_revolutionaries
|
||||
var/list/datum/mind/promotable = list()
|
||||
for(var/datum/mind/khrushchev in non_heads)
|
||||
if(khrushchev.current && !khrushchev.current.incapacitated() && !khrushchev.current.restrained() && khrushchev.current.client && khrushchev.current.stat != DEAD)
|
||||
if(ROLE_REV in khrushchev.current.client.prefs.be_special)
|
||||
promotable += khrushchev
|
||||
if(promotable.len)
|
||||
var/datum/mind/new_leader = pick(promotable)
|
||||
var/datum/antagonist/rev/rev = new_leader.has_antag_datum(/datum/antagonist/rev)
|
||||
rev.promote()
|
||||
|
||||
addtimer(CALLBACK(src,.proc/update_heads),HEAD_UPDATE_PERIOD,TIMER_UNIQUE)
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
/datum/antagonist/wizard
|
||||
name = "Space Wizard"
|
||||
job_rank = ROLE_WIZARD
|
||||
var/give_objectives = TRUE
|
||||
var/strip = TRUE //strip before equipping
|
||||
var/allow_rename = TRUE
|
||||
@@ -32,6 +33,16 @@
|
||||
/datum/antagonist/wizard/proc/unregister()
|
||||
SSticker.mode.wizards -= src
|
||||
|
||||
/datum/antagonist/wizard/create_team(datum/objective_team/wizard/new_team)
|
||||
if(!new_team)
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
wiz_team = new_team
|
||||
|
||||
/datum/antagonist/wizard/get_team()
|
||||
return wiz_team
|
||||
|
||||
/datum/objective_team/wizard
|
||||
name = "wizard team"
|
||||
|
||||
@@ -99,6 +110,8 @@
|
||||
|
||||
/datum/antagonist/wizard/on_removal()
|
||||
unregister()
|
||||
for(var/objective in objectives)
|
||||
owner.objectives -= objective
|
||||
owner.RemoveAllSpells() // TODO keep track which spells are wizard spells which innate stuff
|
||||
return ..()
|
||||
|
||||
@@ -144,8 +157,7 @@
|
||||
|
||||
/datum/antagonist/wizard/apply_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
if(wiz_team) //Don't bother with the icon if you're solo wizard
|
||||
update_wiz_icons_added(M)
|
||||
update_wiz_icons_added(M, wiz_team ? TRUE : FALSE) //Don't bother showing the icon if you're solo wizard
|
||||
M.faction |= "wizard"
|
||||
|
||||
/datum/antagonist/wizard/remove_innate_effects(mob/living/mob_override)
|
||||
@@ -166,10 +178,10 @@
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/wizard/apprentice/register()
|
||||
SSticker.mode.apprentices |= src
|
||||
SSticker.mode.apprentices |= owner
|
||||
|
||||
/datum/antagonist/wizard/apprentice/unregister()
|
||||
SSticker.mode.apprentices -= src
|
||||
SSticker.mode.apprentices -= owner
|
||||
|
||||
/datum/antagonist/wizard/apprentice/equip_wizard()
|
||||
. = ..()
|
||||
@@ -237,7 +249,7 @@
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
|
||||
|
||||
/datum/antagonist/wizard/proc/update_wiz_icons_added(mob/living/wiz)
|
||||
/datum/antagonist/wizard/proc/update_wiz_icons_added(mob/living/wiz,join = TRUE)
|
||||
var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ]
|
||||
wizhud.join_hud(wiz)
|
||||
set_antag_hud(wiz, hud_version)
|
||||
|
||||
@@ -249,7 +249,8 @@
|
||||
// Otherwise, the user mob's machine var will be reset directly.
|
||||
//
|
||||
/proc/onclose(mob/user, windowid, atom/ref=null)
|
||||
if(!user.client) return
|
||||
if(!user.client)
|
||||
return
|
||||
var/param = "null"
|
||||
if(ref)
|
||||
param = "\ref[ref]"
|
||||
|
||||
@@ -77,6 +77,8 @@
|
||||
|
||||
/datum/datacore/proc/manifest()
|
||||
for(var/mob/dead/new_player/N in GLOB.player_list)
|
||||
if(N.new_character)
|
||||
log_manifest(N.ckey,N.new_character.mind,N.new_character)
|
||||
if(ishuman(N.new_character))
|
||||
manifest_inject(N.new_character, N.client)
|
||||
CHECK_TICK
|
||||
|
||||
@@ -18,10 +18,11 @@
|
||||
if(!parrot || parrot.loc != affected_mob)
|
||||
cure()
|
||||
else if(prob(parrot.speak_chance))
|
||||
affected_mob.say(pick(parrot.speech_buffer))
|
||||
if(parrot.speech_buffer.len)
|
||||
affected_mob.say(pick(parrot.speech_buffer))
|
||||
|
||||
/datum/disease/parrot_possession/cure()
|
||||
if(parrot && parrot.loc == affected_mob)
|
||||
parrot.forceMove(affected_mob.drop_location())
|
||||
affected_mob.visible_message("<span class='danger'>[parrot] is violently driven out of [affected_mob]!</span>", "<span class='userdanger'>[parrot] bursts out of your chest!</span>")
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -95,8 +95,10 @@ STI KALY - blind
|
||||
|
||||
var/list/L = list()
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
if(T.z != affected_mob.z) continue
|
||||
if(T.name == "space") continue
|
||||
if(T.z != affected_mob.z)
|
||||
continue
|
||||
if(T.name == "space")
|
||||
continue
|
||||
if(!T.density)
|
||||
var/clear = 1
|
||||
for(var/obj/O in T)
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
if(!M.client || isnewplayer(M))
|
||||
continue
|
||||
var/T = get_turf(src)
|
||||
var/T = get_turf(user)
|
||||
if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(T, null)))
|
||||
M.show_message(msg)
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#define EXPLOSION_THROW_SPEED 4
|
||||
#define REEBE_HUGBOX_COEFFICIENT 0.5
|
||||
|
||||
GLOBAL_LIST_EMPTY(explosions)
|
||||
//Against my better judgement, I will return the explosion datum
|
||||
@@ -60,6 +61,13 @@ GLOBAL_LIST_EMPTY(explosions)
|
||||
light_impact_range = min(GLOB.MAX_EX_LIGHT_RANGE, light_impact_range)
|
||||
flash_range = min(GLOB.MAX_EX_FLASH_RANGE, flash_range)
|
||||
flame_range = min(GLOB.MAX_EX_FLAME_RANGE, flame_range)
|
||||
|
||||
if(!ignorecap && epicenter.z == ZLEVEL_CITYOFCOGS)
|
||||
devastation_range = min(GLOB.MAX_EX_DEVESTATION_RANGE * REEBE_HUGBOX_COEFFICIENT, devastation_range)
|
||||
heavy_impact_range = min(GLOB.MAX_EX_HEAVY_RANGE * REEBE_HUGBOX_COEFFICIENT, heavy_impact_range)
|
||||
light_impact_range = min(GLOB.MAX_EX_LIGHT_RANGE * REEBE_HUGBOX_COEFFICIENT, light_impact_range)
|
||||
flash_range = min(GLOB.MAX_EX_FLASH_RANGE * REEBE_HUGBOX_COEFFICIENT, flash_range)
|
||||
flame_range = min(GLOB.MAX_EX_FLAME_RANGE * REEBE_HUGBOX_COEFFICIENT, flame_range)
|
||||
|
||||
//DO NOT REMOVE THIS STOPLAG, IT BREAKS THINGS
|
||||
//not sleeping causes us to ex_act() the thing that triggered the explosion
|
||||
@@ -388,3 +396,5 @@ GLOBAL_LIST_EMPTY(explosions)
|
||||
// 10 explosion power is a (1, 3, 6) explosion.
|
||||
// 5 explosion power is a (0, 1, 3) explosion.
|
||||
// 1 explosion power is a (0, 0, 1) explosion.
|
||||
|
||||
#undef REEBE_HUGBOX_COEFFICIENT
|
||||
|
||||
@@ -206,7 +206,7 @@
|
||||
continue
|
||||
|
||||
if(extended_safety_checks)
|
||||
if(istype(F, /turf/open/lava)) //chasms aren't /floor, and so are pre-filtered
|
||||
if(islava(F)) //chasms aren't /floor, and so are pre-filtered
|
||||
var/turf/open/lava/L = F
|
||||
if(!L.is_safe())
|
||||
continue
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
list/atom/output_atoms
|
||||
|
||||
mid_sounds (list or soundfile) Since this can be either a list or a single soundfile you can have random sounds. May contain further lists but must contain a soundfile at the end.
|
||||
mid_length (num) The length to wait between playing mid_sounds
|
||||
|
||||
start_sound (soundfile) Played before starting the mid_sounds loop
|
||||
start_length (num) How long to wait before starting the main loop after playing start_sound
|
||||
|
||||
end_sound (soundfile) The sound played after the main loop has concluded
|
||||
|
||||
chance (num) Chance per loop to play a mid_sound
|
||||
volume (num) Sound output volume
|
||||
muted (bool) Private. Used to stop the sound loop.
|
||||
max_loops (num) The max amount of loops to run for.
|
||||
*/
|
||||
/datum/looping_sound
|
||||
var/list/atom/output_atoms
|
||||
var/mid_sounds
|
||||
var/mid_length
|
||||
var/start_sound
|
||||
var/start_length
|
||||
var/end_sound
|
||||
var/chance
|
||||
var/volume
|
||||
var/muted = TRUE
|
||||
var/max_loops
|
||||
|
||||
/datum/looping_sound/New(list/_output_atoms, start_immediately=FALSE)
|
||||
if(!mid_sounds)
|
||||
WARNING("A looping sound datum was created without sounds to play.")
|
||||
return
|
||||
|
||||
if(_output_atoms)
|
||||
output_atoms = _output_atoms
|
||||
else
|
||||
output_atoms = list()
|
||||
|
||||
if(start_immediately)
|
||||
start()
|
||||
|
||||
/datum/looping_sound/Destroy()
|
||||
stop()
|
||||
output_atoms = null
|
||||
return ..()
|
||||
|
||||
/datum/looping_sound/proc/start()
|
||||
if(!muted)
|
||||
return
|
||||
muted = FALSE
|
||||
on_start()
|
||||
|
||||
/datum/looping_sound/proc/stop()
|
||||
if(muted)
|
||||
return
|
||||
muted = TRUE
|
||||
|
||||
/datum/looping_sound/proc/sound_loop(looped=0)
|
||||
if(muted || (max_loops && looped > max_loops))
|
||||
on_stop(looped)
|
||||
return
|
||||
if(!chance || prob(chance))
|
||||
play(get_sound(looped))
|
||||
addtimer(CALLBACK(src, .proc/sound_loop, ++looped), mid_length)
|
||||
|
||||
/datum/looping_sound/proc/play(soundfile)
|
||||
var/list/atoms_cache = output_atoms
|
||||
for(var/i in 1 to atoms_cache.len)
|
||||
var/atom/thing = atoms_cache[i]
|
||||
playsound(thing, soundfile, volume)
|
||||
|
||||
/datum/looping_sound/proc/get_sound(looped, _mid_sounds)
|
||||
if(!_mid_sounds)
|
||||
. = mid_sounds
|
||||
else
|
||||
. = _mid_sounds
|
||||
while(!isfile(.) && !isnull(.))
|
||||
. = pickweight(.)
|
||||
|
||||
/datum/looping_sound/proc/on_start()
|
||||
var/start_wait = 0
|
||||
if(start_sound)
|
||||
play(start_sound)
|
||||
start_wait = start_length
|
||||
addtimer(CALLBACK(src, .proc/sound_loop), start_wait)
|
||||
|
||||
/datum/looping_sound/proc/on_stop(looped)
|
||||
if(end_sound)
|
||||
play(end_sound)
|
||||
@@ -0,0 +1,9 @@
|
||||
/datum/looping_sound/showering
|
||||
start_sound = 'sound/machines/shower/shower_start.ogg'
|
||||
start_length = 2
|
||||
mid_sounds = list('sound/machines/shower/shower_mid1.ogg'=1,'sound/machines/shower/shower_mid2.ogg'=1,'sound/machines/shower/shower_mid3.ogg'=1)
|
||||
mid_length = 10
|
||||
end_sound = 'sound/machines/shower/shower_end.ogg'
|
||||
volume = 25
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -358,9 +358,12 @@
|
||||
|
||||
for (var/obj/O in oview(1, A))
|
||||
if (O.density == 1)
|
||||
if (O == A) continue
|
||||
if (O == D) continue
|
||||
if (O.opacity) continue
|
||||
if (O == A)
|
||||
continue
|
||||
if (O == D)
|
||||
continue
|
||||
if (O.opacity)
|
||||
continue
|
||||
else
|
||||
surface = O
|
||||
ST = get_turf(O)
|
||||
|
||||
+47
-80
@@ -147,6 +147,10 @@
|
||||
qdel(A)
|
||||
return
|
||||
LAZYADD(antag_datums, A)
|
||||
A.create_team(team)
|
||||
var/datum/objective_team/antag_team = A.get_team()
|
||||
if(antag_team)
|
||||
antag_team.add_member(src)
|
||||
A.on_gain()
|
||||
return A
|
||||
|
||||
@@ -227,15 +231,9 @@
|
||||
remove_antag_equip()
|
||||
|
||||
/datum/mind/proc/remove_rev()
|
||||
if(src in SSticker.mode.revolutionaries)
|
||||
SSticker.mode.revolutionaries -= src
|
||||
SSticker.mode.update_rev_icons_removed(src)
|
||||
if(src in SSticker.mode.head_revolutionaries)
|
||||
SSticker.mode.head_revolutionaries -= src
|
||||
SSticker.mode.update_rev_icons_removed(src)
|
||||
var/datum/antagonist/rev/rev = has_antag_datum(/datum/antagonist/rev)
|
||||
remove_antag_datum(rev.type)
|
||||
special_role = null
|
||||
remove_objectives()
|
||||
remove_antag_equip()
|
||||
|
||||
/datum/mind/proc/remove_antag_equip()
|
||||
var/list/Mob_Contents = current.get_contents()
|
||||
@@ -258,7 +256,6 @@
|
||||
SSticker.mode.update_changeling_icons_removed(src)
|
||||
SSticker.mode.update_traitor_icons_removed(src)
|
||||
SSticker.mode.update_cult_icons_removed(src)
|
||||
SSticker.mode.update_rev_icons_removed(src)
|
||||
|
||||
/datum/mind/proc/equip_traitor(var/employer = "The Syndicate", var/silent = FALSE)
|
||||
if(!current)
|
||||
@@ -302,7 +299,8 @@
|
||||
uplink_loc = R
|
||||
|
||||
if (!uplink_loc)
|
||||
if(!silent) to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.")
|
||||
if(!silent)
|
||||
to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.")
|
||||
. = 0
|
||||
else
|
||||
var/obj/item/device/uplink/U = new(uplink_loc)
|
||||
@@ -312,19 +310,22 @@
|
||||
if(uplink_loc == R)
|
||||
R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ))
|
||||
|
||||
if(!silent) to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.")
|
||||
if(!silent)
|
||||
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.")
|
||||
traitor_mob.mind.store_memory("<B>Radio Frequency:</B> [format_frequency(R.traitor_frequency)] ([R.name]).")
|
||||
|
||||
else if(uplink_loc == PDA)
|
||||
PDA.lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
|
||||
|
||||
if(!silent) to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
|
||||
if(!silent)
|
||||
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
|
||||
traitor_mob.mind.store_memory("<B>Uplink Passcode:</B> [PDA.lock_code] ([PDA.name]).")
|
||||
|
||||
else if(uplink_loc == P)
|
||||
P.traitor_unlock_degrees = rand(1, 360)
|
||||
|
||||
if(!silent) to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.")
|
||||
if(!silent)
|
||||
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.")
|
||||
traitor_mob.mind.store_memory("<B>Uplink Degrees:</B> [P.traitor_unlock_degrees] ([P.name]).")
|
||||
|
||||
//Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does.
|
||||
@@ -333,8 +334,9 @@
|
||||
if(iscultist(creator))
|
||||
SSticker.mode.add_cultist(src)
|
||||
|
||||
else if(is_revolutionary_in_general(creator))
|
||||
SSticker.mode.add_revolutionary(src)
|
||||
else if(is_revolutionary(creator))
|
||||
var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev)
|
||||
converter.add_revolutionary(src,FALSE)
|
||||
|
||||
else if(is_servant_of_ratvar(creator))
|
||||
add_servant_of_ratvar(current)
|
||||
@@ -549,9 +551,10 @@
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if (assigned_role in GLOB.command_positions)
|
||||
text += "<b>HEAD</b> | not mindshielded | employee | headrev | rev"
|
||||
else if (src in SSticker.mode.head_revolutionaries)
|
||||
else if (has_antag_datum(/datum/antagonist/rev/head))
|
||||
var/datum/antagonist/rev/head = has_antag_datum(/datum/antagonist/rev/head)
|
||||
var/last_healthy_headrev = TRUE
|
||||
for(var/datum/mind/I in SSticker.mode.head_revolutionaries)
|
||||
for(var/datum/mind/I in head.rev_team.head_revolutionaries())
|
||||
if(I == src)
|
||||
continue
|
||||
var/mob/M = I.current
|
||||
@@ -576,7 +579,7 @@
|
||||
text += "<br>Objectives are empty! <a href='?src=\ref[src];revolution=autoobjectives'>Set to kill all heads</a>."
|
||||
else if(current.isloyal())
|
||||
text += "head | <b>MINDSHIELDED</b> | employee | <a href='?src=\ref[src];revolution=headrev'>headrev</a> | rev"
|
||||
else if (src in SSticker.mode.revolutionaries)
|
||||
else if (has_antag_datum(/datum/antagonist/rev))
|
||||
text += "head | not mindshielded | <a href='?src=\ref[src];revolution=clear'>employee</a> | <a href='?src=\ref[src];revolution=headrev'>headrev</a> | <b>REV</b>"
|
||||
else
|
||||
text += "head | not mindshielded | <b>EMPLOYEE</b> | <a href='?src=\ref[src];revolution=headrev'>headrev</a> | <a href='?src=\ref[src];revolution=rev'>rev</a>"
|
||||
@@ -721,8 +724,7 @@
|
||||
out += sections[i]+"<br>"
|
||||
|
||||
|
||||
if(((src in SSticker.mode.head_revolutionaries) || (src in SSticker.mode.traitors) || (src in SSticker.mode.syndicates)) && ishuman(current))
|
||||
|
||||
if(((src in SSticker.mode.traitors) || (src in SSticker.mode.syndicates)) && ishuman(current))
|
||||
text = "Uplink: <a href='?src=\ref[src];common=uplink'>give</a>"
|
||||
var/obj/item/device/uplink/U = find_syndicate_uplink()
|
||||
if(U)
|
||||
@@ -938,57 +940,41 @@
|
||||
switch(href_list["revolution"])
|
||||
if("clear")
|
||||
remove_rev()
|
||||
to_chat(current, "<span class='userdanger'>You have been brainwashed! You are no longer a revolutionary!</span>")
|
||||
message_admins("[key_name_admin(usr)] has de-rev'ed [current].")
|
||||
log_admin("[key_name(usr)] has de-rev'ed [current].")
|
||||
if("rev")
|
||||
if(src in SSticker.mode.head_revolutionaries)
|
||||
SSticker.mode.head_revolutionaries -= src
|
||||
SSticker.mode.update_rev_icons_removed(src)
|
||||
to_chat(current, "<span class='userdanger'>Revolution has been disappointed of your leader traits! You are a regular revolutionary now!</span>")
|
||||
else if(!(src in SSticker.mode.revolutionaries))
|
||||
to_chat(current, "<span class='danger'><FONT size = 3> You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!</FONT></span>")
|
||||
if(has_antag_datum(/datum/antagonist/rev/head))
|
||||
var/datum/antagonist/rev/head/head = has_antag_datum(/datum/antagonist/rev/head)
|
||||
head.demote()
|
||||
else if(!has_antag_datum(/datum/antagonist/rev))
|
||||
add_antag_datum(/datum/antagonist/rev)
|
||||
special_role = "Revolutionary"
|
||||
message_admins("[key_name_admin(usr)] has rev'ed [current].")
|
||||
log_admin("[key_name(usr)] has rev'ed [current].")
|
||||
else
|
||||
return
|
||||
SSticker.mode.revolutionaries += src
|
||||
SSticker.mode.update_rev_icons_added(src)
|
||||
special_role = "Revolutionary"
|
||||
message_admins("[key_name_admin(usr)] has rev'ed [current].")
|
||||
log_admin("[key_name(usr)] has rev'ed [current].")
|
||||
|
||||
|
||||
if("headrev")
|
||||
if(src in SSticker.mode.revolutionaries)
|
||||
SSticker.mode.revolutionaries -= src
|
||||
SSticker.mode.update_rev_icons_removed(src)
|
||||
to_chat(current, "<span class='userdanger'>You have proved your devotion to revoltion! Yea are a head revolutionary now!</span>")
|
||||
else if(!(src in SSticker.mode.head_revolutionaries))
|
||||
if(has_antag_datum(/datum/antagonist/rev))
|
||||
var/datum/antagonist/rev/rev = has_antag_datum(/datum/antagonist/rev)
|
||||
rev.promote()
|
||||
else if(!has_antag_datum(/datum/antagonist/rev/head))
|
||||
//what about the team here.
|
||||
var/datum/antagonist/rev/head/new_head = new /datum/antagonist/rev/head(src)
|
||||
new_head.give_flash = TRUE
|
||||
new_head.give_hud = TRUE
|
||||
new_head.remove_clumsy = TRUE
|
||||
add_antag_datum(new_head)
|
||||
to_chat(current, "<span class='userdanger'>You are a member of the revolutionaries' leadership now!</span>")
|
||||
else
|
||||
return
|
||||
if (SSticker.mode.head_revolutionaries.len>0)
|
||||
// copy targets
|
||||
var/datum/mind/valid_head = locate() in SSticker.mode.head_revolutionaries
|
||||
if (valid_head)
|
||||
for (var/datum/objective/mutiny/O in valid_head.objectives)
|
||||
var/datum/objective/mutiny/rev_obj = new
|
||||
rev_obj.owner = src
|
||||
rev_obj.target = O.target
|
||||
rev_obj.explanation_text = "Assassinate [O.target.name], the [O.target.assigned_role]."
|
||||
objectives += rev_obj
|
||||
SSticker.mode.greet_revolutionary(src,0)
|
||||
SSticker.mode.head_revolutionaries += src
|
||||
SSticker.mode.update_rev_icons_added(src)
|
||||
special_role = "Head Revolutionary"
|
||||
message_admins("[key_name_admin(usr)] has head-rev'ed [current].")
|
||||
log_admin("[key_name(usr)] has head-rev'ed [current].")
|
||||
|
||||
if("autoobjectives")
|
||||
SSticker.mode.forge_revolutionary_objectives(src)
|
||||
SSticker.mode.greet_revolutionary(src,0)
|
||||
to_chat(usr, "<span class='notice'>The objectives for revolution have been generated and shown to [key]</span>")
|
||||
|
||||
if("flash")
|
||||
if (!SSticker.mode.equip_revolutionary(current))
|
||||
var/datum/antagonist/rev/head/head = has_antag_datum(/datum/antagonist/rev/head)
|
||||
if(!head.equip_rev())
|
||||
to_chat(usr, "<span class='danger'>Spawning flash failed!</span>")
|
||||
|
||||
if("takeflash")
|
||||
@@ -1447,31 +1433,12 @@
|
||||
to_chat(H, "Spawning an amulet from your Master failed.")
|
||||
|
||||
/datum/mind/proc/make_Rev()
|
||||
if (SSticker.mode.head_revolutionaries.len>0)
|
||||
// copy targets
|
||||
var/datum/mind/valid_head = locate() in SSticker.mode.head_revolutionaries
|
||||
if (valid_head)
|
||||
for (var/datum/objective/mutiny/O in valid_head.objectives)
|
||||
var/datum/objective/mutiny/rev_obj = new
|
||||
rev_obj.owner = src
|
||||
rev_obj.target = O.target
|
||||
rev_obj.explanation_text = "Assassinate [O.target.current.real_name], the [O.target.assigned_role]."
|
||||
objectives += rev_obj
|
||||
SSticker.mode.greet_revolutionary(src,0)
|
||||
SSticker.mode.head_revolutionaries += src
|
||||
SSticker.mode.update_rev_icons_added(src)
|
||||
var/datum/antagonist/rev/head/head = new(src)
|
||||
head.give_flash = TRUE
|
||||
head.give_hud = TRUE
|
||||
add_antag_datum(head)
|
||||
special_role = "Head Revolutionary"
|
||||
|
||||
SSticker.mode.forge_revolutionary_objectives(src)
|
||||
SSticker.mode.greet_revolutionary(src,0)
|
||||
|
||||
var/list/L = current.get_contents()
|
||||
var/obj/item/device/assembly/flash/flash = locate() in L
|
||||
qdel(flash)
|
||||
take_uplink()
|
||||
var/fail = 0
|
||||
fail |= !SSticker.mode.equip_revolutionary(current)
|
||||
|
||||
/datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/S)
|
||||
spell_list += S
|
||||
S.action.Grant(current)
|
||||
|
||||
@@ -645,9 +645,9 @@ GLOBAL_LIST_EMPTY(mutations_list)
|
||||
/datum/mutation/human/laser_eyes/get_visual_indicator(mob/living/carbon/human/owner)
|
||||
return visual_indicators[1]
|
||||
|
||||
/datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
|
||||
/datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target, mouseparams)
|
||||
if(owner.a_intent == INTENT_HARM)
|
||||
owner.LaserEyes(target)
|
||||
owner.LaserEyes(target, mouseparams)
|
||||
|
||||
|
||||
/mob/living/carbon/proc/update_mutations_overlay()
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
continue
|
||||
thing.rad_act(strength)
|
||||
|
||||
var/static/list/blacklisted = typecacheof(list(/turf, /obj/structure/cable, /obj/machinery/atmospherics))
|
||||
var/static/list/blacklisted = typecacheof(list(/turf, /mob, /obj/structure/cable, /obj/machinery/atmospherics))
|
||||
if(!can_contaminate || blacklisted[thing.type])
|
||||
continue
|
||||
if(prob((strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_CHANCE_COEFFICIENT * min(1/(steps*range_modifier), 1))) // Only stronk rads get to have little baby rads
|
||||
|
||||
@@ -261,7 +261,7 @@
|
||||
var/turf/next = get_step(ridden, direction)
|
||||
var/turf/current = get_turf(ridden)
|
||||
|
||||
if(istype(next, /turf/open/lava) || istype(current, /turf/open/lava)) //We can move from land to lava, or lava to land, but not from land to land
|
||||
if(islava(next) || islava(current)) //We can move from land to lava, or lava to land, but not from land to land
|
||||
..()
|
||||
else
|
||||
to_chat(user, "Boats don't go on land!")
|
||||
|
||||
@@ -255,3 +255,10 @@
|
||||
suffix = "gondolaasteroid.dmm"
|
||||
name = "Gondoland"
|
||||
description = "Just an ordinary rock- wait, what's that thing?"
|
||||
|
||||
/datum/map_template/ruin/space/whiteshipruin_box
|
||||
id = "whiteshipruin_box"
|
||||
suffix = "whiteshipruin_box.dmm"
|
||||
name = "NT Medical Ship"
|
||||
description = "An ancient ship, said to be among the first discovered derelicts near Space Station 13 that was still in working order. \
|
||||
Aged and deprecated by time, this relic of a vessel is now broken beyond repair."
|
||||
@@ -433,11 +433,7 @@
|
||||
playsound(spawn_turf, 'sound/effects/curse2.ogg', 80, 1, -1)
|
||||
var/turf/ownerloc = get_turf(owner)
|
||||
var/obj/item/projectile/curse_hand/C = new (spawn_turf)
|
||||
C.current = spawn_turf
|
||||
C.starting = spawn_turf
|
||||
C.yo = ownerloc.y - spawn_turf.y
|
||||
C.xo = ownerloc.x - spawn_turf.x
|
||||
C.original = owner
|
||||
C.preparePixelProjectile(ownerloc, spawn_turf)
|
||||
C.fire()
|
||||
|
||||
/obj/effect/temp_visual/curse
|
||||
|
||||
+159
-158
@@ -1,158 +1,159 @@
|
||||
/datum/wires/airlock
|
||||
holder_type = /obj/machinery/door/airlock
|
||||
proper_name = "Airlock"
|
||||
|
||||
/datum/wires/airlock/secure
|
||||
randomize = TRUE
|
||||
|
||||
/datum/wires/airlock/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_POWER1, WIRE_POWER2,
|
||||
WIRE_BACKUP1, WIRE_BACKUP2,
|
||||
WIRE_OPEN, WIRE_BOLTS, WIRE_IDSCAN, WIRE_AI,
|
||||
WIRE_SHOCK, WIRE_SAFETY, WIRE_TIMING, WIRE_LIGHT,
|
||||
WIRE_ZAP1, WIRE_ZAP2
|
||||
)
|
||||
add_duds(2)
|
||||
..()
|
||||
|
||||
/datum/wires/airlock/interactable(mob/user)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
if(!issilicon(user) && A.isElectrified() && A.shock(user, 100))
|
||||
return FALSE
|
||||
if(A.panel_open)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/airlock/get_status()
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
var/list/status = list()
|
||||
status += "The door bolts [A.locked ? "have fallen!" : "look up."]"
|
||||
status += "The test light is [A.hasPower() ? "on" : "off"]."
|
||||
status += "The AI connection light is [A.aiControlDisabled || A.emagged ? "off" : "on"]."
|
||||
status += "The check wiring light is [A.safe ? "off" : "on"]."
|
||||
status += "The timer is powered [A.autoclose ? "on" : "off"]."
|
||||
status += "The speed light is [A.normalspeed ? "on" : "off"]."
|
||||
status += "The emergency light is [A.emergency ? "on" : "off"]."
|
||||
return status
|
||||
|
||||
/datum/wires/airlock/on_pulse(wire)
|
||||
set waitfor = FALSE
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
switch(wire)
|
||||
if(WIRE_POWER1, WIRE_POWER2) // Pulse to loose power.
|
||||
A.loseMainPower()
|
||||
if(WIRE_BACKUP1, WIRE_BACKUP2) // Pulse to loose backup power.
|
||||
A.loseBackupPower()
|
||||
if(WIRE_OPEN) // Pulse to open door (only works not emagged and ID wire is cut or no access is required).
|
||||
if(A.emagged)
|
||||
return
|
||||
if(!A.requiresID() || A.check_access(null))
|
||||
if(A.density)
|
||||
A.open()
|
||||
else
|
||||
A.close()
|
||||
if(WIRE_BOLTS) // Pulse to toggle bolts (but only raise if power is on).
|
||||
if(!A.locked)
|
||||
A.bolt()
|
||||
A.audible_message("<span class='italics'>You hear a click from the bottom of the door.</span>", null, 1)
|
||||
else
|
||||
if(A.hasPower())
|
||||
A.unbolt()
|
||||
A.audible_message("<span class='italics'>You hear a click from the bottom of the door.</span>", null, 1)
|
||||
A.update_icon()
|
||||
if(WIRE_IDSCAN) // Pulse to disable emergency access and flash red lights.
|
||||
if(A.hasPower() && A.density)
|
||||
A.do_animate("deny")
|
||||
if(A.emergency)
|
||||
A.emergency = FALSE
|
||||
A.update_icon()
|
||||
if(WIRE_AI) // Pulse to disable WIRE_AI control for 10 ticks (follows same rules as cutting).
|
||||
if(A.aiControlDisabled == 0)
|
||||
A.aiControlDisabled = 1
|
||||
else if(A.aiControlDisabled == -1)
|
||||
A.aiControlDisabled = 2
|
||||
sleep(10)
|
||||
if(A)
|
||||
if(A.aiControlDisabled == 1)
|
||||
A.aiControlDisabled = 0
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
if(WIRE_SHOCK) // Pulse to shock the door for 10 ticks.
|
||||
if(!A.secondsElectrified)
|
||||
A.set_electrified(30)
|
||||
if(usr)
|
||||
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
|
||||
add_logs(usr, A, "electrified")
|
||||
sleep(10)
|
||||
if(A)
|
||||
while (A.secondsElectrified > 0)
|
||||
A.secondsElectrified -= 1
|
||||
if(A.secondsElectrified < 0)
|
||||
A.set_electrified(0)
|
||||
sleep(10)
|
||||
if(WIRE_SAFETY)
|
||||
A.safe = !A.safe
|
||||
if(!A.density)
|
||||
A.close()
|
||||
if(WIRE_TIMING)
|
||||
A.normalspeed = !A.normalspeed
|
||||
if(WIRE_LIGHT)
|
||||
A.lights = !A.lights
|
||||
A.update_icon()
|
||||
|
||||
/datum/wires/airlock/on_cut(wire, mend)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
switch(wire)
|
||||
if(WIRE_POWER1, WIRE_POWER2) // Cut to loose power, repair all to gain power.
|
||||
if(mend && !is_cut(WIRE_POWER1) && !is_cut(WIRE_POWER2))
|
||||
A.regainMainPower()
|
||||
if(usr)
|
||||
A.shock(usr, 50)
|
||||
else
|
||||
A.loseMainPower()
|
||||
if(usr)
|
||||
A.shock(usr, 50)
|
||||
if(WIRE_BACKUP1, WIRE_BACKUP2) // Cut to loose backup power, repair all to gain backup power.
|
||||
if(mend && !is_cut(WIRE_BACKUP1) && !is_cut(WIRE_BACKUP2))
|
||||
A.regainBackupPower()
|
||||
if(usr)
|
||||
A.shock(usr, 50)
|
||||
else
|
||||
A.loseBackupPower()
|
||||
if(usr)
|
||||
A.shock(usr, 50)
|
||||
if(WIRE_BOLTS) // Cut to drop bolts, mend does nothing.
|
||||
if(!mend)
|
||||
A.bolt()
|
||||
if(WIRE_AI) // Cut to disable WIRE_AI control, mend to re-enable.
|
||||
if(mend)
|
||||
if(A.aiControlDisabled == 1) // 0 = normal, 1 = locked out, 2 = overridden by WIRE_AI, -1 = previously overridden by WIRE_AI
|
||||
A.aiControlDisabled = 0
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
else
|
||||
if(A.aiControlDisabled == 0)
|
||||
A.aiControlDisabled = 1
|
||||
else if(A.aiControlDisabled == -1)
|
||||
A.aiControlDisabled = 2
|
||||
if(WIRE_SHOCK) // Cut to shock the door, mend to unshock.
|
||||
if(mend)
|
||||
if(A.secondsElectrified)
|
||||
A.set_electrified(0)
|
||||
else
|
||||
if(A.secondsElectrified != -1)
|
||||
A.set_electrified(-1)
|
||||
if(usr)
|
||||
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
|
||||
add_logs(usr, A, "electrified")
|
||||
if(WIRE_SAFETY) // Cut to disable safeties, mend to re-enable.
|
||||
A.safe = mend
|
||||
if(WIRE_TIMING) // Cut to disable auto-close, mend to re-enable.
|
||||
A.autoclose = mend
|
||||
if(A.autoclose && !A.density)
|
||||
A.close()
|
||||
if(WIRE_LIGHT) // Cut to disable lights, mend to re-enable.
|
||||
A.lights = mend
|
||||
A.update_icon()
|
||||
if(WIRE_ZAP1, WIRE_ZAP2) // Ouch.
|
||||
A.shock(usr, 50)
|
||||
/datum/wires/airlock
|
||||
holder_type = /obj/machinery/door/airlock
|
||||
proper_name = "Airlock"
|
||||
|
||||
/datum/wires/airlock/secure
|
||||
randomize = TRUE
|
||||
|
||||
/datum/wires/airlock/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_POWER1, WIRE_POWER2,
|
||||
WIRE_BACKUP1, WIRE_BACKUP2,
|
||||
WIRE_OPEN, WIRE_BOLTS, WIRE_IDSCAN, WIRE_AI,
|
||||
WIRE_SHOCK, WIRE_SAFETY, WIRE_TIMING, WIRE_LIGHT,
|
||||
WIRE_ZAP1, WIRE_ZAP2
|
||||
)
|
||||
add_duds(2)
|
||||
..()
|
||||
|
||||
/datum/wires/airlock/interactable(mob/user)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
if(!issilicon(user) && A.isElectrified() && A.shock(user, 100))
|
||||
return FALSE
|
||||
if(A.panel_open)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/airlock/get_status()
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
var/list/status = list()
|
||||
status += "The door bolts [A.locked ? "have fallen!" : "look up."]"
|
||||
status += "The test light is [A.hasPower() ? "on" : "off"]."
|
||||
status += "The AI connection light is [A.aiControlDisabled || A.emagged ? "off" : "on"]."
|
||||
status += "The check wiring light is [A.safe ? "off" : "on"]."
|
||||
status += "The timer is powered [A.autoclose ? "on" : "off"]."
|
||||
status += "The speed light is [A.normalspeed ? "on" : "off"]."
|
||||
status += "The emergency light is [A.emergency ? "on" : "off"]."
|
||||
return status
|
||||
|
||||
/datum/wires/airlock/on_pulse(wire)
|
||||
set waitfor = FALSE
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
switch(wire)
|
||||
if(WIRE_POWER1, WIRE_POWER2) // Pulse to loose power.
|
||||
A.loseMainPower()
|
||||
if(WIRE_BACKUP1, WIRE_BACKUP2) // Pulse to loose backup power.
|
||||
A.loseBackupPower()
|
||||
if(WIRE_OPEN) // Pulse to open door (only works not emagged and ID wire is cut or no access is required).
|
||||
if(A.emagged)
|
||||
return
|
||||
if(!A.requiresID() || A.check_access(null))
|
||||
if(A.density)
|
||||
A.open()
|
||||
else
|
||||
A.close()
|
||||
if(WIRE_BOLTS) // Pulse to toggle bolts (but only raise if power is on).
|
||||
if(!A.locked)
|
||||
A.bolt()
|
||||
A.audible_message("<span class='italics'>You hear a click from the bottom of the door.</span>", null, 1)
|
||||
else
|
||||
if(A.hasPower())
|
||||
A.unbolt()
|
||||
A.audible_message("<span class='italics'>You hear a click from the bottom of the door.</span>", null, 1)
|
||||
A.update_icon()
|
||||
if(WIRE_IDSCAN) // Pulse to disable emergency access and flash red lights.
|
||||
if(A.hasPower() && A.density)
|
||||
A.do_animate("deny")
|
||||
if(A.emergency)
|
||||
A.emergency = FALSE
|
||||
A.update_icon()
|
||||
if(WIRE_AI) // Pulse to disable WIRE_AI control for 10 ticks (follows same rules as cutting).
|
||||
if(A.aiControlDisabled == 0)
|
||||
A.aiControlDisabled = 1
|
||||
else if(A.aiControlDisabled == -1)
|
||||
A.aiControlDisabled = 2
|
||||
sleep(10)
|
||||
if(A)
|
||||
if(A.aiControlDisabled == 1)
|
||||
A.aiControlDisabled = 0
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
if(WIRE_SHOCK) // Pulse to shock the door for 10 ticks.
|
||||
if(!A.secondsElectrified)
|
||||
A.set_electrified(30)
|
||||
if(usr)
|
||||
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
|
||||
add_logs(usr, A, "electrified")
|
||||
sleep(10)
|
||||
if(A)
|
||||
while (A.secondsElectrified > 0)
|
||||
A.secondsElectrified -= 1
|
||||
if(A.secondsElectrified < 0)
|
||||
A.set_electrified(0)
|
||||
sleep(10)
|
||||
if(WIRE_SAFETY)
|
||||
A.safe = !A.safe
|
||||
if(!A.density)
|
||||
A.close()
|
||||
if(WIRE_TIMING)
|
||||
A.normalspeed = !A.normalspeed
|
||||
if(WIRE_LIGHT)
|
||||
A.lights = !A.lights
|
||||
A.update_icon()
|
||||
|
||||
/datum/wires/airlock/on_cut(wire, mend)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
switch(wire)
|
||||
if(WIRE_POWER1, WIRE_POWER2) // Cut to loose power, repair all to gain power.
|
||||
if(mend && !is_cut(WIRE_POWER1) && !is_cut(WIRE_POWER2))
|
||||
A.regainMainPower()
|
||||
if(usr)
|
||||
A.shock(usr, 50)
|
||||
else
|
||||
A.loseMainPower()
|
||||
if(usr)
|
||||
A.shock(usr, 50)
|
||||
if(WIRE_BACKUP1, WIRE_BACKUP2) // Cut to loose backup power, repair all to gain backup power.
|
||||
if(mend && !is_cut(WIRE_BACKUP1) && !is_cut(WIRE_BACKUP2))
|
||||
A.regainBackupPower()
|
||||
if(usr)
|
||||
A.shock(usr, 50)
|
||||
else
|
||||
A.loseBackupPower()
|
||||
if(usr)
|
||||
A.shock(usr, 50)
|
||||
if(WIRE_BOLTS) // Cut to drop bolts, mend does nothing.
|
||||
if(!mend)
|
||||
A.bolt()
|
||||
if(WIRE_AI) // Cut to disable WIRE_AI control, mend to re-enable.
|
||||
if(mend)
|
||||
if(A.aiControlDisabled == 1) // 0 = normal, 1 = locked out, 2 = overridden by WIRE_AI, -1 = previously overridden by WIRE_AI
|
||||
A.aiControlDisabled = 0
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
else
|
||||
if(A.aiControlDisabled == 0)
|
||||
A.aiControlDisabled = 1
|
||||
else if(A.aiControlDisabled == -1)
|
||||
A.aiControlDisabled = 2
|
||||
if(WIRE_SHOCK) // Cut to shock the door, mend to unshock.
|
||||
if(mend)
|
||||
if(A.secondsElectrified)
|
||||
A.set_electrified(0)
|
||||
else
|
||||
if(A.secondsElectrified != -1)
|
||||
A.set_electrified(-1)
|
||||
if(usr)
|
||||
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
|
||||
add_logs(usr, A, "electrified")
|
||||
if(WIRE_SAFETY) // Cut to disable safeties, mend to re-enable.
|
||||
A.safe = mend
|
||||
if(WIRE_TIMING) // Cut to disable auto-close, mend to re-enable.
|
||||
A.autoclose = mend
|
||||
if(A.autoclose && !A.density)
|
||||
A.close()
|
||||
if(WIRE_LIGHT) // Cut to disable lights, mend to re-enable.
|
||||
A.lights = mend
|
||||
A.update_icon()
|
||||
if(WIRE_ZAP1, WIRE_ZAP2) // Ouch.
|
||||
if(usr)
|
||||
A.shock(usr, 50)
|
||||
|
||||
@@ -89,7 +89,8 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
// want to find machines, mobs, etc, in the same logical area, you will need to check all the
|
||||
// related areas. This returns a master contents list to assist in that.
|
||||
/proc/area_contents(area/A)
|
||||
if(!istype(A)) return null
|
||||
if(!istype(A))
|
||||
return null
|
||||
var/list/contents = list()
|
||||
for(var/area/LSA in A.related)
|
||||
contents += LSA.contents
|
||||
|
||||
@@ -426,4 +426,12 @@
|
||||
|
||||
/area/ruin/space/old_ai_sat/bridge
|
||||
name = "Bridge"
|
||||
icon_state = "bridge"
|
||||
icon_state = "bridge"
|
||||
|
||||
|
||||
//ABANDONED BOX WHITESHIP
|
||||
|
||||
/area/ruin/space/has_grav/whiteship/box
|
||||
|
||||
name = "Abandoned Ship"
|
||||
icon_state = "red"
|
||||
+2
-1
@@ -451,7 +451,8 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
return 1
|
||||
|
||||
/atom/proc/get_global_map_pos()
|
||||
if(!islist(GLOB.global_map) || isemptylist(GLOB.global_map)) return
|
||||
if(!islist(GLOB.global_map) || isemptylist(GLOB.global_map))
|
||||
return
|
||||
var/cur_x = null
|
||||
var/cur_y = null
|
||||
var/list/y_arr = null
|
||||
|
||||
@@ -61,7 +61,8 @@
|
||||
return ..()
|
||||
|
||||
/atom/movable/Move(atom/newloc, direct = 0)
|
||||
if(!loc || !newloc) return 0
|
||||
if(!loc || !newloc)
|
||||
return 0
|
||||
var/atom/oldloc = loc
|
||||
|
||||
if(loc != newloc)
|
||||
|
||||
+14
-7
@@ -8,10 +8,12 @@
|
||||
/* DATA HUD DATUMS */
|
||||
|
||||
/atom/proc/add_to_all_human_data_huds()
|
||||
for(var/datum/atom_hud/data/human/hud in GLOB.huds) hud.add_to_hud(src)
|
||||
for(var/datum/atom_hud/data/human/hud in GLOB.huds)
|
||||
hud.add_to_hud(src)
|
||||
|
||||
/atom/proc/remove_from_all_data_huds()
|
||||
for(var/datum/atom_hud/data/hud in GLOB.huds) hud.remove_from_hud(src)
|
||||
for(var/datum/atom_hud/data/hud in GLOB.huds)
|
||||
hud.remove_from_hud(src)
|
||||
|
||||
/datum/atom_hud/data
|
||||
|
||||
@@ -21,10 +23,13 @@
|
||||
/datum/atom_hud/data/human/medical/basic
|
||||
|
||||
/datum/atom_hud/data/human/medical/basic/proc/check_sensors(mob/living/carbon/human/H)
|
||||
if(!istype(H)) return 0
|
||||
if(!istype(H))
|
||||
return 0
|
||||
var/obj/item/clothing/under/U = H.w_uniform
|
||||
if(!istype(U)) return 0
|
||||
if(U.sensor_mode <= SENSOR_VITALS) return 0
|
||||
if(!istype(U))
|
||||
return 0
|
||||
if(U.sensor_mode <= SENSOR_VITALS)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/datum/atom_hud/data/human/medical/basic/add_to_single_hud(mob/M, mob/living/carbon/H)
|
||||
@@ -128,7 +133,8 @@
|
||||
B.update_suit_sensors(src)
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if (T) GLOB.crewmonitor.queueUpdate(T.z)
|
||||
if (T)
|
||||
GLOB.crewmonitor.queueUpdate(T.z)
|
||||
|
||||
//called when a living mob changes health
|
||||
/mob/living/proc/med_hud_set_health()
|
||||
@@ -200,7 +206,8 @@
|
||||
sec_hud_set_security_status()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if (T) GLOB.crewmonitor.queueUpdate(T.z)
|
||||
if (T)
|
||||
GLOB.crewmonitor.queueUpdate(T.z)
|
||||
|
||||
/mob/living/carbon/human/proc/sec_hud_set_implants()
|
||||
var/image/holder
|
||||
|
||||
@@ -67,20 +67,25 @@
|
||||
else
|
||||
to_chat(H, "Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later.")
|
||||
|
||||
/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, school,datum/mind/wizard)
|
||||
/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, school,datum/mind/user)
|
||||
new /obj/effect/particle_effect/smoke(T)
|
||||
var/mob/living/carbon/human/M = new/mob/living/carbon/human(T)
|
||||
C.prefs.copy_to(M)
|
||||
M.key = C.key
|
||||
var/datum/mind/app_mind = M.mind
|
||||
var/datum/antagonist/wizard/master_antag = wizard.has_antag_datum(/datum/antagonist/wizard)
|
||||
if(!master_antag.wiz_team)
|
||||
master_antag.create_wiz_team()
|
||||
|
||||
|
||||
|
||||
var/datum/antagonist/wizard/apprentice/app = new(app_mind)
|
||||
app.wiz_team = master_antag.wiz_team
|
||||
app.master = wizard
|
||||
app.master = user
|
||||
app.school = school
|
||||
master_antag.wiz_team.members += app_mind
|
||||
|
||||
var/datum/antagonist/wizard/master_wizard = user.has_antag_datum(/datum/antagonist/wizard)
|
||||
if(master_wizard)
|
||||
if(!master_wizard.wiz_team)
|
||||
master_wizard.create_wiz_team()
|
||||
app.wiz_team = master_wizard.wiz_team
|
||||
master_wizard.wiz_team.add_member(app_mind)
|
||||
app_mind.add_antag_datum(app)
|
||||
//TODO Kill these if possible
|
||||
app_mind.assigned_role = "Apprentice"
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
var/datum/mind/bro = pick(possible_brothers)
|
||||
possible_brothers -= bro
|
||||
antag_candidates -= bro
|
||||
team.members += bro
|
||||
team.add_member(bro)
|
||||
bro.restricted_roles = restricted_jobs
|
||||
log_game("[bro.key] (ckey) has been selected as a Brother")
|
||||
pre_brother_teams += team
|
||||
|
||||
@@ -68,7 +68,8 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
||||
|
||||
if(antag_candidates.len>0)
|
||||
for(var/i = 0, i < num_changelings, i++)
|
||||
if(!antag_candidates.len) break
|
||||
if(!antag_candidates.len)
|
||||
break
|
||||
var/datum/mind/changeling = pick(antag_candidates)
|
||||
antag_candidates -= changeling
|
||||
changelings += changeling
|
||||
|
||||
@@ -54,17 +54,20 @@
|
||||
|
||||
/obj/effect/proc_holder/changeling/biodegrade/proc/dissolve_handcuffs(mob/living/carbon/human/user, obj/O)
|
||||
if(O && user.handcuffed == O)
|
||||
visible_message("<span class='warning'>[O] dissolves into a puddle of sizzling goop.</span>")
|
||||
user.visible_message("<span class='warning'>[O] dissolve[O.gender==PLURAL?"":"s"] into a puddle of sizzling goop.</span>")
|
||||
new /obj/effect/decal/cleanable/greenglow(O.drop_location())
|
||||
qdel(O)
|
||||
|
||||
/obj/effect/proc_holder/changeling/biodegrade/proc/dissolve_straightjacket(mob/living/carbon/human/user, obj/S)
|
||||
if(S && user.wear_suit == S)
|
||||
visible_message("<span class='warning'>[S] dissolves into a puddle of sizzling goop.</span>")
|
||||
user.visible_message("<span class='warning'>[S] dissolves into a puddle of sizzling goop.</span>")
|
||||
new /obj/effect/decal/cleanable/greenglow(S.drop_location())
|
||||
qdel(S)
|
||||
|
||||
/obj/effect/proc_holder/changeling/biodegrade/proc/open_closet(mob/living/carbon/human/user, obj/structure/closet/C)
|
||||
if(C && user.loc == C)
|
||||
C.visible_message("<span class='warning'>[C]'s door breaks and opens!</span>")
|
||||
new /obj/effect/decal/cleanable/greenglow(C.drop_location())
|
||||
C.welded = FALSE
|
||||
C.locked = FALSE
|
||||
C.broken = TRUE
|
||||
@@ -73,5 +76,6 @@
|
||||
|
||||
/obj/effect/proc_holder/changeling/biodegrade/proc/dissolve_cocoon(mob/living/carbon/human/user, obj/structure/spider/cocoon/C)
|
||||
if(C && user.loc == C)
|
||||
new /obj/effect/decal/cleanable/greenglow(C.drop_location())
|
||||
qdel(C) //The cocoon's destroy will move the changeling outside of it without interference
|
||||
to_chat(user, "<span class='warning'>We dissolve the cocoon!</span>")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/effect/proc_holder/changeling/linglink
|
||||
name = "Hivemind Link"
|
||||
desc = "Link your victim's mind into the hivemind for personal interrogation"
|
||||
desc = "Link your victim's mind into the hivemind for personal interrogation."
|
||||
chemical_cost = 0
|
||||
dna_cost = 0
|
||||
req_human = 1
|
||||
|
||||
@@ -257,7 +257,7 @@
|
||||
|
||||
/obj/item/ammo_casing/magic/tentacle
|
||||
name = "tentacle"
|
||||
desc = "a tentacle."
|
||||
desc = "A tentacle."
|
||||
projectile_type = /obj/item/projectile/tentacle
|
||||
caliber = "tentacle"
|
||||
icon_state = "tentacle_end"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/effect/proc_holder/changeling/resonant_shriek
|
||||
name = "Resonant Shriek"
|
||||
desc = "Our lungs and vocal chords shift, allowing us to briefly emit a noise that deafens and confuses the weak-minded."
|
||||
desc = "Our lungs and vocal cords shift, allowing us to briefly emit a noise that deafens and confuses the weak-minded."
|
||||
helptext = "Emits a high-frequency sound that confuses and deafens humans, blows out nearby lights and overloads cyborg sensors."
|
||||
chemical_cost = 20
|
||||
dna_cost = 1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/effect/proc_holder/changeling/sting
|
||||
name = "Tiny Prick"
|
||||
desc = "Stabby stabby"
|
||||
desc = "Stabby stabby."
|
||||
var/sting_icon = null
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/Click()
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
|
||||
if(possible_changelings.len>0)
|
||||
for(var/j = 0, j < num_changelings, j++)
|
||||
if(!possible_changelings.len) break
|
||||
if(!possible_changelings.len)
|
||||
break
|
||||
var/datum/mind/changeling = pick(possible_changelings)
|
||||
antag_candidates -= changeling
|
||||
possible_changelings -= changeling
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
beckon(AM)
|
||||
|
||||
/obj/effect/clockwork/city_of_cogs_rift/proc/beckon(atom/movable/AM)
|
||||
AM.visible_message("<span class='danger'>[AM] passes through [src]!</span>", ignore_mob = AM)
|
||||
AM.visible_message("<span class='danger'>[AM] passes through [src]!</span>", ignored_mob = AM)
|
||||
AM.forceMove(pick(!is_servant_of_ratvar(AM) ? GLOB.city_of_cogs_spawns : GLOB.servant_spawns))
|
||||
AM.visible_message("<span class='danger'>[AM] materializes from the air!</span>", \
|
||||
"<span class='boldannounce'>You pass through [src] and appear [is_servant_of_ratvar(AM) ? "back at the City of Cogs" : "somewhere unfamiliar. Looks like it was a one-way trip.."].</span>")
|
||||
@@ -48,3 +48,6 @@
|
||||
var/mob/living/L = AM
|
||||
L.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static)
|
||||
L.clear_fullscreen("flash", 5)
|
||||
var/obj/item/device/transfer_valve/TTV = locate() in L.GetAllContents()
|
||||
if(TTV)
|
||||
to_chat(L, "<span class='userdanger'>The air resonates with the Ark's presence; your explosives will be significantly dampened here!</span>")
|
||||
|
||||
@@ -156,11 +156,7 @@
|
||||
add_logs(ranged_ability_user, U, "fired at with Kindle")
|
||||
playsound(ranged_ability_user, 'sound/magic/blink.ogg', 50, TRUE, frequency = 0.5)
|
||||
var/obj/item/projectile/kindle/A = new(T)
|
||||
A.original = target
|
||||
A.starting = T
|
||||
A.current = T
|
||||
A.yo = U.y - T.y
|
||||
A.xo = U.x - T.x
|
||||
A.preparePixelProjectile(target, caller, params)
|
||||
A.fire()
|
||||
|
||||
remove_ranged_ability()
|
||||
|
||||
@@ -398,15 +398,15 @@
|
||||
|
||||
switch(selected_scripture) //display info based on selected scripture tier
|
||||
if(SCRIPTURE_DRIVER)
|
||||
data["tier_info"] = "<font color=#B18B25><b>These scriptures are permenantly unlocked.</b></font>"
|
||||
data["tier_info"] = "<font color=#B18B25><b>These scriptures are permanently unlocked.</b></font>"
|
||||
if(SCRIPTURE_SCRIPT)
|
||||
if(SSticker.scripture_states[SCRIPTURE_SCRIPT])
|
||||
data["tier_info"] = "<font color=#B18B25><b>These scriptures are permenantly unlocked.</b></font>"
|
||||
data["tier_info"] = "<font color=#B18B25><b>These scriptures are permanently unlocked.</b></font>"
|
||||
else
|
||||
data["tier_info"] = "<font color=#B18B25><i>These scriptures will automatically unlock when the Ark is halfway ready or if [DisplayPower(SCRIPT_UNLOCK_THRESHOLD)] of power is reached.</i></font>"
|
||||
if(SCRIPTURE_APPLICATION)
|
||||
if(SSticker.scripture_states[SCRIPTURE_APPLICATION])
|
||||
data["tier_info"] = "<font color=#B18B25><b>These scriptures are permenantly unlocked.</b></font>"
|
||||
data["tier_info"] = "<font color=#B18B25><b>These scriptures are permanently unlocked.</b></font>"
|
||||
else
|
||||
data["tier_info"] = "<font color=#B18B25><i>Unlock these optional scriptures by converting another servant or if [DisplayPower(APPLICATION_UNLOCK_THRESHOLD)] of power is reached..</i></font>"
|
||||
|
||||
|
||||
@@ -116,9 +116,9 @@
|
||||
continue
|
||||
if(ishostile(L))
|
||||
var/mob/living/simple_animal/hostile/H = L
|
||||
if(ismegafauna(H) || (!H.mind && H.AIStatus == AI_OFF))
|
||||
if(("ratvar" in H.faction) || (!H.mind && "neutral" in H.faction))
|
||||
continue
|
||||
if(("ratvar" in H.faction) || ("neutral" in H.faction))
|
||||
if(ismegafauna(H) || (!H.mind && H.AIStatus == AI_OFF))
|
||||
continue
|
||||
else if(isrevenant(L))
|
||||
var/mob/living/simple_animal/revenant/R = L
|
||||
@@ -127,10 +127,15 @@
|
||||
else if(!L.mind)
|
||||
continue
|
||||
. += L
|
||||
var/list/viewcache = list()
|
||||
for(var/N in GLOB.mechas_list)
|
||||
var/obj/mecha/M = N
|
||||
if(get_dist(M, src) <= sight_range && M.occupant && !is_servant_of_ratvar(M.occupant) && (M in view(sight_range, src)))
|
||||
. += M
|
||||
if(get_dist(M, src) <= sight_range && M.occupant && !is_servant_of_ratvar(M.occupant))
|
||||
if(!length(viewcache))
|
||||
for (var/obj/Z in view(sight_range, src))
|
||||
viewcache += Z
|
||||
if (M in viewcache)
|
||||
. += M
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/proc/lose_target()
|
||||
if(!target)
|
||||
|
||||
@@ -302,7 +302,7 @@
|
||||
|
||||
/obj/item/clothing/suit/magusred
|
||||
name = "magus robes"
|
||||
desc = "A set of armored robes worn by the followers of Nar-Sie"
|
||||
desc = "A set of armored robes worn by the followers of Nar-Sie."
|
||||
icon_state = "magusred"
|
||||
item_state = "magusred"
|
||||
body_parts_covered = CHEST|GROIN|LEGS|ARMS
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
if(!(AT.z in GLOB.station_z_levels)) //Only check one, it's enough.
|
||||
skip = 1
|
||||
break
|
||||
if(skip) continue
|
||||
if(skip)
|
||||
continue
|
||||
A.power_light = FALSE
|
||||
A.power_equip = FALSE
|
||||
A.power_environ = FALSE
|
||||
@@ -40,7 +41,8 @@
|
||||
if(istype(A,area_type))
|
||||
skip = 1
|
||||
break
|
||||
if(skip) continue
|
||||
if(skip)
|
||||
continue
|
||||
|
||||
C.cell.charge = 0
|
||||
|
||||
|
||||
@@ -184,6 +184,8 @@
|
||||
|
||||
|
||||
/datum/game_mode/proc/check_finished(force_ending) //to be called by SSticker
|
||||
if(!SSticker.setup_done)
|
||||
return FALSE
|
||||
if(replacementmode && round_converted == 2)
|
||||
return replacementmode.check_finished()
|
||||
if(SSshuttle.emergency && (SSshuttle.emergency.mode == SHUTTLE_ENDGAME))
|
||||
@@ -196,7 +198,7 @@
|
||||
if(!continuous_sanity_checked) //make sure we have antags to be checking in the first place
|
||||
for(var/mob/Player in GLOB.mob_list)
|
||||
if(Player.mind)
|
||||
if(Player.mind.special_role)
|
||||
if(Player.mind.special_role || LAZYLEN(Player.mind.antag_datums))
|
||||
continuous_sanity_checked = 1
|
||||
return 0
|
||||
if(!continuous_sanity_checked)
|
||||
@@ -212,7 +214,7 @@
|
||||
|
||||
for(var/mob/Player in GLOB.living_mob_list)
|
||||
if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) &&!isbrain(Player) && Player.client)
|
||||
if(Player.mind.special_role) //Someone's still antaging!
|
||||
if(Player.mind.special_role || LAZYLEN(Player.mind.antag_datums)) //Someone's still antaging!
|
||||
living_antag_player = Player
|
||||
return 0
|
||||
|
||||
@@ -392,43 +394,6 @@
|
||||
if(P.client && P.ready == PLAYER_READY_TO_PLAY)
|
||||
. ++
|
||||
|
||||
///////////////////////////////////
|
||||
//Keeps track of all living heads//
|
||||
///////////////////////////////////
|
||||
/datum/game_mode/proc/get_living_heads()
|
||||
. = list()
|
||||
for(var/mob/living/carbon/human/player in GLOB.mob_list)
|
||||
if(player.stat != DEAD && player.mind && (player.mind.assigned_role in GLOB.command_positions))
|
||||
. |= player.mind
|
||||
|
||||
|
||||
////////////////////////////
|
||||
//Keeps track of all heads//
|
||||
////////////////////////////
|
||||
/datum/game_mode/proc/get_all_heads()
|
||||
. = list()
|
||||
for(var/mob/player in GLOB.mob_list)
|
||||
if(player.mind && (player.mind.assigned_role in GLOB.command_positions))
|
||||
. |= player.mind
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//Keeps track of all living security members//
|
||||
//////////////////////////////////////////////
|
||||
/datum/game_mode/proc/get_living_sec()
|
||||
. = list()
|
||||
for(var/mob/living/carbon/human/player in GLOB.mob_list)
|
||||
if(player.stat != DEAD && player.mind && (player.mind.assigned_role in GLOB.security_positions))
|
||||
. |= player.mind
|
||||
|
||||
////////////////////////////////////////
|
||||
//Keeps track of all security members//
|
||||
////////////////////////////////////////
|
||||
/datum/game_mode/proc/get_all_sec()
|
||||
. = list()
|
||||
for(var/mob/living/carbon/human/player in GLOB.mob_list)
|
||||
if(player.mind && (player.mind.assigned_role in GLOB.security_positions))
|
||||
. |= player.mind
|
||||
|
||||
//////////////////////////
|
||||
//Reports player logouts//
|
||||
//////////////////////////
|
||||
@@ -529,19 +494,11 @@
|
||||
|
||||
return max(0, enemy_minimum_age - C.player_age)
|
||||
|
||||
/datum/game_mode/proc/replace_jobbaned_player(mob/living/M, role_type, pref)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [role_type]?", "[role_type]", null, pref, 50, M)
|
||||
var/mob/dead/observer/theghost = null
|
||||
if(candidates.len)
|
||||
theghost = pick(candidates)
|
||||
to_chat(M, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!")
|
||||
message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(M)]) to replace a jobbaned player.")
|
||||
M.ghostize(0)
|
||||
M.key = theghost.key
|
||||
|
||||
/datum/game_mode/proc/remove_antag_for_borging(datum/mind/newborgie)
|
||||
SSticker.mode.remove_cultist(newborgie, 0, 0)
|
||||
SSticker.mode.remove_revolutionary(newborgie, 0)
|
||||
var/datum/antagonist/rev/rev = newborgie.has_antag_datum(/datum/antagonist/rev)
|
||||
if(rev)
|
||||
rev.remove_revolutionary(TRUE)
|
||||
|
||||
/datum/game_mode/proc/generate_station_goals()
|
||||
var/list/possible = list()
|
||||
|
||||
@@ -426,7 +426,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
|
||||
for(var/obj/machinery/door/D in GLOB.airlocks)
|
||||
if(!(D.z in GLOB.station_z_levels))
|
||||
continue
|
||||
INVOKE_ASYNC(D, /obj/machinery/door.proc/hostile_lockdown, src)
|
||||
INVOKE_ASYNC(D, /obj/machinery/door.proc/hostile_lockdown, owner)
|
||||
addtimer(CALLBACK(D, /obj/machinery/door.proc/disable_lockdown), 900)
|
||||
|
||||
var/obj/machinery/computer/communications/C = locate() in GLOB.machines
|
||||
|
||||
@@ -498,7 +498,6 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
origin_tech = "materials=4;magnets=5;abductor=2"
|
||||
|
||||
/obj/item/restraints/handcuffs/energy/used
|
||||
desc = "energy discharge"
|
||||
flags_1 = DROPDEL_1
|
||||
|
||||
/obj/item/restraints/handcuffs/energy/used/dropped(mob/user)
|
||||
@@ -597,7 +596,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
|
||||
/obj/structure/bed/abductor
|
||||
name = "resting contraption"
|
||||
desc = "This looks similar to contraptions from earth. Could aliens be stealing our technology?"
|
||||
desc = "This looks similar to contraptions from Earth. Could aliens be stealing our technology?"
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
buildstacktype = /obj/item/stack/sheet/mineral/abductor
|
||||
icon_state = "bed"
|
||||
|
||||
@@ -241,10 +241,11 @@
|
||||
|
||||
/obj/item/organ/heart/gland/plasma/activate()
|
||||
to_chat(owner, "<span class='warning'>You feel bloated.</span>")
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, owner, "<span class='userdanger'>A massive stomachache overcomes you.</span>"), 150)
|
||||
addtimer(CALLBACK(src, .proc/vomit_plasma), 200)
|
||||
|
||||
/obj/item/organ/heart/gland/plasma/proc/vomit_plasma()
|
||||
sleep(150)
|
||||
if(!owner)
|
||||
return
|
||||
to_chat(owner, "<span class='userdanger'>A massive stomachache overcomes you.</span>")
|
||||
sleep(50)
|
||||
if(!owner)
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] vomits a cloud of plasma!</span>")
|
||||
|
||||
@@ -42,8 +42,7 @@
|
||||
|
||||
/datum/game_mode/monkey/announce()
|
||||
to_chat(world, "<B>The current game mode is - Monkey!</B>")
|
||||
to_chat(world, "<B>One or more crewmembers have been infected with Jungle Fever! Crew: Contain the outbreak. None of the infected monkeys may escape alive to CentCom. \
|
||||
Monkeys: Ensure that your kind lives on! Rise up against your captors!</B>")
|
||||
to_chat(world, "<B>One or more crewmembers have been infected with Jungle Fever! Crew: Contain the outbreak. None of the infected monkeys may escape alive to CentCom. Monkeys: Ensure that your kind lives on! Rise up against your captors!</B>")
|
||||
|
||||
|
||||
/datum/game_mode/monkey/proc/greet_carrier(datum/mind/carrier)
|
||||
@@ -115,5 +114,4 @@
|
||||
to_chat(world, "<span class='userdanger'>The staff managed to contain the monkey infestation!</span>")
|
||||
|
||||
/datum/game_mode/monkey/generate_report()
|
||||
return "Reports of an ancient [pick("retrovirus", "flesh eating bacteria", "disease", "magical curse blamed on viruses", "bananna blight")] outbreak that turn humans into monkies has been \
|
||||
reported in your quadrant. Any such infections may be treated with bananna juice. If an outbreak occurs, ensure the station is quarantined to prevent a largescale outbreak at Centcom."
|
||||
return "Reports of an ancient [pick("retrovirus", "flesh eating bacteria", "disease", "magical curse blamed on viruses", "banana blight")] outbreak that turn humans into monkeys has been reported in your quadrant. Any such infections may be treated with banana juice. If an outbreak occurs, ensure the station is quarantined to prevent a largescale outbreak at CentCom."
|
||||
|
||||
@@ -241,7 +241,7 @@
|
||||
if(T.flags_1 & NOJAUNT_1)
|
||||
T.flags_1 &= ~NOJAUNT_1
|
||||
new /obj/effect/temp_visual/revenant(T)
|
||||
if(!istype(T, /turf/open/floor/plating) && !istype(T, /turf/open/floor/engine/cult) && isfloorturf(T) && prob(15))
|
||||
if(!isplatingturf(T) && !istype(T, /turf/open/floor/engine/cult) && isfloorturf(T) && prob(15))
|
||||
var/turf/open/floor/floor = T
|
||||
if(floor.intact && floor.floor_tile)
|
||||
new floor.floor_tile(floor)
|
||||
|
||||
@@ -407,14 +407,17 @@ GLOBAL_LIST_EMPTY(possible_items)
|
||||
/datum/objective/steal/proc/select_target() //For admins setting objectives manually.
|
||||
var/list/possible_items_all = GLOB.possible_items+"custom"
|
||||
var/new_target = input("Select target:", "Objective target", steal_target) as null|anything in possible_items_all
|
||||
if (!new_target) return
|
||||
if (!new_target)
|
||||
return
|
||||
|
||||
if (new_target == "custom") //Can set custom items.
|
||||
var/obj/item/custom_target = input("Select type:","Type") as null|anything in typesof(/obj/item)
|
||||
if (!custom_target) return
|
||||
if (!custom_target)
|
||||
return
|
||||
var/custom_name = initial(custom_target.name)
|
||||
custom_name = stripped_input("Enter target name:", "Objective target", custom_name)
|
||||
if (!custom_name) return
|
||||
if (!custom_name)
|
||||
return
|
||||
steal_target = custom_target
|
||||
explanation_text = "Steal [custom_name]."
|
||||
|
||||
@@ -711,7 +714,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
var/needed_heads = rand(min_lings,GLOB.command_positions.len)
|
||||
needed_heads = min(SSticker.mode.changelings.len,needed_heads)
|
||||
|
||||
var/list/heads = SSticker.mode.get_living_heads()
|
||||
var/list/heads = SSjob.get_living_heads()
|
||||
for(var/datum/mind/head in heads)
|
||||
if(head in SSticker.mode.changelings) //Looking at you HoP.
|
||||
continue
|
||||
|
||||
@@ -7,7 +7,18 @@
|
||||
/datum/objective_team/New(starting_members)
|
||||
. = ..()
|
||||
if(starting_members)
|
||||
if(islist(starting_members))
|
||||
for(var/datum/mind/M in starting_members)
|
||||
add_member(M)
|
||||
else
|
||||
add_member(starting_members)
|
||||
members += starting_members
|
||||
|
||||
/datum/objective_team/proc/is_solo()
|
||||
return members.len == 1
|
||||
|
||||
/datum/objective_team/proc/add_member(datum/mind/new_member)
|
||||
members |= new_member
|
||||
|
||||
/datum/objective_team/proc/remove_member(datum/mind/member)
|
||||
members -= member
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user