Merge pull request #208 from Poojawa/runtime-fixers

Runtime fixers
This commit is contained in:
LetterJay
2017-02-08 02:02:46 -05:00
committed by GitHub
127 changed files with 2649 additions and 1171 deletions
+1 -1
View File
@@ -2858,7 +2858,7 @@
"ib" = (
/obj/structure/closet,
/obj/item/weapon/reagent_containers/food/drinks/beer,
/obj/item/clothing/under/color/purple,
/obj/item/clothing/under/color/lightpurple,
/obj/item/weapon/poster/contraband,
/turf/open/floor/plasteel,
/area/awaymission/academy/academyaft)
+291 -63
View File
@@ -1024,7 +1024,10 @@
/area/shuttle/arrival)
"abX" = (
/obj/structure/table/reinforced,
/obj/item/device/analyzer,
/obj/item/device/analyzer{
pixel_x = 7;
pixel_y = 3
},
/turf/open/floor/plasteel/yellow/side{
dir = 8
},
@@ -1111,6 +1114,7 @@
/area/shuttle/arrival)
"abZ" = (
/obj/effect/turf_decal/delivery,
/obj/structure/closet/wardrobe/mixed,
/turf/open/floor/plasteel,
/area/shuttle/arrival)
"aca" = (
@@ -2162,15 +2166,18 @@
/turf/open/floor/plasteel,
/area/shuttle/arrival)
"aej" = (
/obj/structure/closet/wardrobe/black,
/turf/open/floor/plasteel/neutral/side,
/area/shuttle/arrival)
"aek" = (
/obj/structure/closet/wardrobe/grey,
/turf/open/floor/plasteel/blue/corner,
/area/shuttle/arrival)
"ael" = (
/turf/open/floor/plasteel/blue/side,
/area/shuttle/arrival)
"aem" = (
/obj/structure/closet/wardrobe/yellow,
/turf/open/floor/plasteel/blue/corner{
tag = "icon-bluecorner (WEST)";
icon_state = "bluecorner";
@@ -4859,7 +4866,9 @@
/turf/open/space,
/area/solar/auxport)
"ajK" = (
/obj/structure/reflector/single,
/obj/structure/reflector/single{
anchored = 1
},
/turf/open/floor/plasteel/vault{
dir = 8
},
@@ -4875,9 +4884,10 @@
})
"ajM" = (
/obj/structure/reflector/box{
tag = "icon-reflector_box (EAST)";
anchored = 1;
dir = 4;
icon_state = "reflector_box";
dir = 4
tag = "icon-reflector_box (EAST)"
},
/turf/open/floor/plasteel/vault{
dir = 5
@@ -4908,9 +4918,10 @@
})
"ajP" = (
/obj/structure/reflector/single{
tag = "icon-reflector (WEST)";
anchored = 1;
dir = 8;
icon_state = "reflector";
dir = 8
tag = "icon-reflector (WEST)"
},
/turf/open/floor/plasteel/vault{
dir = 8
@@ -5346,7 +5357,9 @@
name = "Atmospherics Engine"
})
"akQ" = (
/obj/structure/reflector/double,
/obj/structure/reflector/double{
anchored = 1
},
/turf/open/floor/plasteel/vault{
dir = 5
},
@@ -5355,9 +5368,10 @@
})
"akR" = (
/obj/structure/reflector/double{
tag = "icon-reflector_double (NORTH)";
anchored = 1;
dir = 1;
icon_state = "reflector_double";
dir = 1
tag = "icon-reflector_double (NORTH)"
},
/turf/open/floor/plasteel/vault{
dir = 5
@@ -5831,9 +5845,10 @@
/area/solar/auxport)
"alP" = (
/obj/structure/reflector/double{
tag = "icon-reflector_double (EAST)";
anchored = 1;
dir = 4;
icon_state = "reflector_double";
dir = 4
tag = "icon-reflector_double (EAST)"
},
/turf/open/floor/plasteel/vault{
dir = 5
@@ -6445,7 +6460,9 @@
name = "Atmospherics Engine"
})
"anb" = (
/obj/structure/reflector/box,
/obj/structure/reflector/box{
anchored = 1
},
/turf/open/floor/plasteel/vault{
dir = 5
},
@@ -6972,9 +6989,10 @@
/area/solar/auxport)
"aoa" = (
/obj/structure/reflector/single{
tag = "icon-reflector (NORTH)";
anchored = 1;
dir = 1;
icon_state = "reflector";
dir = 1
tag = "icon-reflector (NORTH)"
},
/turf/open/floor/plasteel/vault{
dir = 8
@@ -8601,10 +8619,22 @@
/area/solar/auxport)
"aqY" = (
/obj/structure/table/reinforced,
/obj/item/device/analyzer,
/obj/item/device/analyzer{
pixel_x = 7;
pixel_y = 3
},
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/effect/turf_decal/bot,
/obj/item/clothing/glasses/meson{
pixel_y = 1
},
/obj/item/clothing/glasses/meson{
pixel_y = 1
},
/obj/item/clothing/glasses/meson{
pixel_y = 1
},
/turf/open/floor/plasteel,
/area/engine/gravity_generator{
name = "Atmospherics Engine"
@@ -9466,7 +9496,7 @@
"asq" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 4;
filter_type = "n2";
filter_type = "o2";
on = 1
},
/turf/open/floor/plasteel/yellow,
@@ -14436,6 +14466,7 @@
})
"aBt" = (
/obj/machinery/door/airlock{
id_tag = "AuxCabinA";
name = "Cabin A";
req_access_txt = "25"
},
@@ -15048,6 +15079,15 @@
"aCz" = (
/obj/structure/table/wood,
/obj/item/device/flashlight/lamp,
/obj/machinery/button/door{
id = "AuxCabinA";
name = "Dormitory Door Lock";
normaldoorcontrol = 1;
pixel_x = -26;
pixel_y = 7;
req_access_txt = "0";
specialfunctions = 4
},
/turf/open/floor/plasteel/grimy,
/area/crew_quarters/sleep{
name = "Service Hall"
@@ -15061,6 +15101,7 @@
})
"aCB" = (
/obj/machinery/light,
/obj/structure/closet/wardrobe/mixed,
/turf/open/floor/plasteel/grimy,
/area/crew_quarters/sleep{
name = "Service Hall"
@@ -17627,11 +17668,6 @@
/obj/structure/extinguisher_cabinet{
pixel_x = 26
},
/obj/item/device/radio/intercom{
name = "Station Intercom";
pixel_x = 0;
pixel_y = -24
},
/obj/machinery/power/terminal,
/obj/structure/cable{
d2 = 8;
@@ -17705,6 +17741,7 @@
})
"aGO" = (
/obj/machinery/door/airlock{
id_tag = "AuxCabinB";
name = "Cabin B"
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
@@ -18369,6 +18406,11 @@
tag = "icon-0-8";
icon_state = "0-8"
},
/obj/item/device/radio/intercom{
name = "Station Intercom";
pixel_x = 0;
pixel_y = -24
},
/turf/open/floor/plasteel/vault,
/area/engine/gravity_generator{
name = "Atmospherics Engine"
@@ -18390,6 +18432,15 @@
"aHY" = (
/obj/structure/table/wood,
/obj/item/weapon/paper_bin,
/obj/machinery/button/door{
id = "AuxCabinB";
name = "Dormitory Door Lock";
normaldoorcontrol = 1;
pixel_x = -26;
pixel_y = 7;
req_access_txt = "0";
specialfunctions = 4
},
/turf/open/floor/wood,
/area/crew_quarters/sleep{
name = "Service Hall"
@@ -18409,6 +18460,7 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/obj/structure/closet/wardrobe/mixed,
/turf/open/floor/wood,
/area/crew_quarters/sleep{
name = "Service Hall"
@@ -29150,7 +29202,10 @@
/area/atmos)
"baM" = (
/obj/structure/table/reinforced,
/obj/item/device/analyzer,
/obj/item/device/analyzer{
pixel_x = 7;
pixel_y = 3
},
/obj/effect/turf_decal/stripes/line{
dir = 8
},
@@ -34586,10 +34641,7 @@
/turf/open/floor/plasteel,
/area/hydroponics)
"bkK" = (
/obj/structure/table/reinforced,
/obj/item/weapon/paper_bin,
/obj/item/weapon/pen,
/obj/effect/turf_decal/bot,
/obj/machinery/smartfridge/disks,
/turf/open/floor/plasteel,
/area/hydroponics)
"bkL" = (
@@ -39839,7 +39891,10 @@
/obj/structure/table/reinforced,
/obj/item/weapon/crowbar/red,
/obj/item/weapon/wrench,
/obj/item/device/analyzer,
/obj/item/device/analyzer{
pixel_x = 7;
pixel_y = 3
},
/obj/machinery/newscaster{
pixel_x = -32
},
@@ -41839,8 +41894,14 @@
/area/storage/tech)
"bxj" = (
/obj/structure/table/reinforced,
/obj/item/device/analyzer,
/obj/item/device/analyzer,
/obj/item/device/analyzer{
pixel_x = 7;
pixel_y = 3
},
/obj/item/device/analyzer{
pixel_x = 7;
pixel_y = 3
},
/obj/item/device/assembly/signaler,
/obj/item/device/assembly/signaler,
/obj/effect/turf_decal/bot,
@@ -42982,8 +43043,14 @@
/area/storage/primary)
"bzj" = (
/obj/structure/table/reinforced,
/obj/item/device/analyzer,
/obj/item/device/analyzer,
/obj/item/device/analyzer{
pixel_x = 7;
pixel_y = 3
},
/obj/item/device/analyzer{
pixel_x = 7;
pixel_y = 3
},
/obj/item/device/assembly/signaler,
/obj/item/device/assembly/signaler,
/obj/machinery/light{
@@ -66829,6 +66896,9 @@
icon_state = "intact";
dir = 9
},
/obj/item/weapon/storage/pod{
pixel_x = 32
},
/turf/open/floor/plasteel/neutral/corner{
dir = 4
},
@@ -69213,9 +69283,6 @@
/turf/open/floor/plasteel/neutral,
/area/crew_quarters/locker)
"csI" = (
/obj/structure/table,
/obj/item/weapon/paper_bin,
/obj/item/weapon/pen,
/obj/machinery/light{
dir = 4;
icon_state = "tube1"
@@ -69225,6 +69292,7 @@
icon_state = "intact";
dir = 10
},
/obj/structure/closet/wardrobe/black,
/turf/open/floor/plasteel/neutral/corner,
/area/crew_quarters/locker)
"csJ" = (
@@ -70243,12 +70311,11 @@
/turf/open/floor/plasteel/neutral,
/area/crew_quarters/locker)
"cur" = (
/obj/structure/table,
/obj/item/weapon/storage/firstaid/regular,
/obj/machinery/status_display{
pixel_x = 32
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/structure/closet/wardrobe/grey,
/turf/open/floor/plasteel/neutral/corner,
/area/crew_quarters/locker)
"cus" = (
@@ -71034,10 +71101,8 @@
/turf/open/floor/plasteel/neutral,
/area/crew_quarters/locker)
"cvO" = (
/obj/structure/table,
/obj/item/weapon/folder,
/obj/item/weapon/pen,
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/structure/closet/wardrobe/green,
/turf/open/floor/plasteel/neutral/corner,
/area/crew_quarters/locker)
"cvP" = (
@@ -71897,6 +71962,7 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/obj/structure/closet/wardrobe/pjs,
/turf/open/floor/plasteel/neutral/corner{
dir = 8;
heat_capacity = 1e+006
@@ -72006,6 +72072,7 @@
icon_state = "manifold";
dir = 4
},
/obj/structure/closet/wardrobe/pink,
/turf/open/floor/plasteel/neutral/corner,
/area/crew_quarters/locker)
"cxt" = (
@@ -72943,6 +73010,7 @@
tag = "icon-1-2";
icon_state = "1-2"
},
/obj/structure/closet/wardrobe/white,
/turf/open/floor/plasteel/neutral/corner{
dir = 8;
heat_capacity = 1e+006
@@ -72957,10 +73025,8 @@
/turf/open/floor/plasteel/neutral,
/area/crew_quarters/locker)
"cyS" = (
/obj/item/weapon/storage/pod{
pixel_x = 32
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/structure/closet/wardrobe/mixed,
/turf/open/floor/plasteel/neutral/corner,
/area/crew_quarters/locker)
"cyT" = (
@@ -74048,6 +74114,7 @@
dir = 2;
icon_state = "pipe-c"
},
/obj/structure/closet/wardrobe/yellow,
/turf/open/floor/plasteel/neutral/corner,
/area/crew_quarters/locker)
"cAK" = (
@@ -74808,6 +74875,15 @@
/obj/structure/table/wood,
/obj/item/weapon/folder/blue,
/obj/item/weapon/lighter,
/obj/machinery/button/door{
id = "Dorm1";
name = "Dormitory Door Lock";
normaldoorcontrol = 1;
pixel_x = -26;
pixel_y = 7;
req_access_txt = "0";
specialfunctions = 4
},
/turf/open/floor/plasteel/grimy,
/area/crew_quarters/sleep)
"cCf" = (
@@ -74829,6 +74905,15 @@
"cCi" = (
/obj/structure/table/wood,
/obj/item/weapon/paper_bin,
/obj/machinery/button/door{
id = "Dorm3";
name = "Dormitory Door Lock";
normaldoorcontrol = 1;
pixel_x = -26;
pixel_y = 7;
req_access_txt = "0";
specialfunctions = 4
},
/turf/open/floor/carpet,
/area/crew_quarters/sleep)
"cCj" = (
@@ -75496,6 +75581,7 @@
"cDp" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock{
id_tag = "Dorm1";
name = "Cabin 1"
},
/turf/open/floor/plasteel/grimy,
@@ -75503,6 +75589,7 @@
"cDq" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock{
id_tag = "Dorm2";
name = "Cabin 2"
},
/turf/open/floor/wood,
@@ -75510,6 +75597,7 @@
"cDr" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock{
id_tag = "Dorm3";
name = "Cabin 3"
},
/turf/open/floor/carpet,
@@ -78584,6 +78672,7 @@
"cIM" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock{
id_tag = "Dorm4";
name = "Cabin 4"
},
/turf/open/floor/wood,
@@ -78591,6 +78680,7 @@
"cIN" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock{
id_tag = "Dorm5";
name = "Cabin 5"
},
/turf/open/floor/carpet,
@@ -78598,6 +78688,7 @@
"cIO" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock{
id_tag = "Dorm6";
name = "Cabin 6"
},
/turf/open/floor/plasteel/grimy,
@@ -79687,8 +79778,15 @@
/turf/open/floor/wood,
/area/crew_quarters/sleep)
"cKL" = (
/obj/structure/table/wood,
/obj/item/device/flashlight/lamp/green,
/obj/machinery/button/door{
id = "Dorm5";
name = "Dormitory Door Lock";
normaldoorcontrol = 1;
pixel_x = -26;
pixel_y = 7;
req_access_txt = "0";
specialfunctions = 4
},
/turf/open/floor/carpet,
/area/crew_quarters/sleep)
"cKM" = (
@@ -79707,6 +79805,15 @@
/obj/structure/table/wood,
/obj/item/weapon/folder/blue,
/obj/item/weapon/pen/blue,
/obj/machinery/button/door{
id = "Dorm6";
name = "Dormitory Door Lock";
normaldoorcontrol = 1;
pixel_x = -26;
pixel_y = 7;
req_access_txt = "0";
specialfunctions = 4
},
/turf/open/floor/plasteel/grimy,
/area/crew_quarters/sleep)
"cKO" = (
@@ -81540,7 +81647,10 @@
/area/maintenance/electrical)
"cOi" = (
/obj/structure/table/reinforced,
/obj/item/device/analyzer,
/obj/item/device/analyzer{
pixel_x = 7;
pixel_y = 3
},
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel,
/area/maintenance/electrical)
@@ -95336,7 +95446,7 @@
},
/area/medical/genetics_cloning)
"dmX" = (
/obj/machinery/limbgrower,
/obj/structure/closet/crate/freezer/surplus_limbs,
/turf/open/floor/plasteel/whitepurple/corner{
dir = 8
},
@@ -97136,7 +97246,10 @@
/area/hallway/secondary/construction)
"dqo" = (
/obj/structure/table,
/obj/item/device/analyzer,
/obj/item/device/analyzer{
pixel_x = 7;
pixel_y = 3
},
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel,
@@ -107765,6 +107878,15 @@
pixel_y = 3
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/machinery/doorButtons/access_button{
dir = 1;
idDoor = "virology_airlock_exterior";
idSelf = "virology_airlock_control";
name = "Virology Access Button";
pixel_x = 0;
pixel_y = -24;
req_access_txt = "39"
},
/turf/open/floor/plasteel/whitegreen/corner{
dir = 8
},
@@ -108056,13 +108178,18 @@
tag = "icon-1-2";
icon_state = "1-2"
},
/obj/machinery/door/airlock/virology{
name = "Virology Access";
req_access_txt = "39"
},
/obj/effect/turf_decal/stripes/line{
dir = 2
},
/obj/machinery/door/airlock/virology{
autoclose = 0;
frequency = 1449;
icon_state = "door_locked";
id_tag = "virology_airlock_exterior";
locked = 1;
name = "Virology Exterior Airlock";
req_access_txt = "39"
},
/turf/open/floor/plasteel{
tag = "icon-plasteel_warn_side (EAST)"
},
@@ -108929,13 +109056,18 @@
tag = "icon-4-8";
icon_state = "4-8"
},
/obj/machinery/door/airlock/virology{
name = "Virology Access";
req_access_txt = "39"
},
/obj/effect/turf_decal/stripes/line{
dir = 8
},
/obj/machinery/door/airlock/virology{
autoclose = 0;
frequency = 1449;
icon_state = "door_locked";
id_tag = "virology_airlock_interior";
locked = 1;
name = "Virology Interior Airlock";
req_access_txt = "39"
},
/turf/open/floor/plasteel,
/area/medical/virology)
"dKZ" = (
@@ -118368,6 +118500,102 @@
/obj/machinery/deepfryer,
/turf/open/floor/plasteel/red,
/area/crew_quarters/kitchen)
"ecc" = (
/obj/structure/closet/wardrobe/green,
/turf/open/floor/plasteel/neutral/side,
/area/shuttle/arrival)
"ecd" = (
/obj/machinery/doorButtons/access_button{
dir = 4;
idDoor = "virology_airlock_interior";
idSelf = "virology_airlock_control";
name = "Virology Access Button";
pixel_x = -10;
pixel_y = 0;
req_access_txt = "39"
},
/turf/closed/wall/r_wall,
/area/medical/virology)
"ece" = (
/obj/structure/cable/white{
d2 = 2;
icon_state = "0-2";
tag = "icon-0-2"
},
/turf/closed/wall/r_wall,
/area/medical/virology)
"ecf" = (
/obj/structure/cable/white{
tag = "icon-4-8";
icon_state = "4-8"
},
/obj/structure/cable/white{
tag = "icon-2-4";
icon_state = "2-4"
},
/obj/structure/cable/white{
tag = "icon-1-4";
icon_state = "1-4"
},
/obj/effect/turf_decal/stripes/line{
dir = 2
},
/obj/machinery/doorButtons/airlock_controller{
idExterior = "virology_airlock_exterior";
idInterior = "virology_airlock_interior";
idSelf = "virology_airlock_control";
name = "Virology Access Console";
pixel_x = 0;
pixel_y = 22;
req_access_txt = "39"
},
/turf/open/floor/plasteel{
tag = "icon-plasteel_warn_side (WEST)"
},
/area/medical/virology)
"ecg" = (
/obj/structure/cable/white,
/turf/closed/wall/r_wall,
/area/medical/virology)
"ech" = (
/obj/machinery/button/door{
id = "Dorm2";
name = "Dormitory Door Lock";
normaldoorcontrol = 1;
pixel_x = -26;
pixel_y = 7;
req_access_txt = "0";
specialfunctions = 4
},
/turf/open/floor/wood,
/area/crew_quarters/sleep)
"eci" = (
/obj/machinery/button/door{
id = "Dorm4";
name = "Dormitory Door Lock";
normaldoorcontrol = 1;
pixel_x = -26;
pixel_y = 7;
req_access_txt = "0";
specialfunctions = 4
},
/turf/open/floor/wood,
/area/crew_quarters/sleep)
"ecj" = (
/obj/item/weapon/reagent_containers/food/condiment/saltshaker{
pixel_x = -8;
pixel_y = 5
},
/obj/item/weapon/reagent_containers/food/condiment/peppermill{
pixel_x = -8
},
/obj/structure/table/wood,
/obj/item/clothing/head/hardhat/cakehat{
pixel_x = 4;
pixel_y = 3
},
/turf/open/floor/plasteel/redyellow,
/area/crew_quarters/bar/atrium)
(1,1,1) = {"
aaa
@@ -155985,7 +156213,7 @@ aJA
aLb
aMK
aGY
aLa
ecj
aRH
aGY
aGY
@@ -157746,7 +157974,7 @@ acn
acn
acn
acn
aej
ecc
abV
abV
abW
@@ -165077,7 +165305,7 @@ dGR
cKs
cKs
dJl
dJp
ecd
dKY
dJp
dJp
@@ -165334,9 +165562,9 @@ dGS
cDe
aaa
aaa
dJq
dKZ
dMh
ece
ecf
ecg
aaa
aaa
dJp
@@ -168639,7 +168867,7 @@ cGb
cHs
cvP
cCg
cyX
eci
cNS
cxw
cvP
@@ -169659,8 +169887,8 @@ cuu
cvP
cxw
cyV
cyX
cCg
ech
cvP
cEq
cGc
+1 -1
View File
@@ -62597,7 +62597,7 @@
network = list("SS13","Medbay")
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/machinery/limbgrower,
/obj/structure/closet/crate/freezer/surplus_limbs,
/obj/item/weapon/reagent_containers/glass/beaker/synthflesh,
/turf/open/floor/plasteel/whiteblue/side{
dir = 4
+24 -27
View File
@@ -29857,7 +29857,7 @@
pixel_x = -24;
pixel_y = -24
},
/obj/machinery/limbgrower,
/obj/structure/closet/crate/freezer/surplus_limbs,
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden,
/turf/open/floor/plasteel/whiteblue/corner{
dir = 8
@@ -37488,8 +37488,10 @@
/turf/open/floor/plasteel/grimy,
/area/chapel/main)
"biK" = (
/obj/structure/chair/office/dark,
/obj/machinery/atmospherics/pipe/manifold/supply/hidden,
/obj/machinery/atmospherics/components/unary/vent_pump{
dir = 1;
on = 1
},
/turf/open/floor/plasteel/grimy,
/area/chapel/main)
"biL" = (
@@ -37533,8 +37535,10 @@
tag = "icon-4-8";
icon_state = "4-8"
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
tag = "icon-manifold (NORTH)";
icon_state = "manifold";
dir = 1
},
/turf/open/floor/plasteel/black,
/area/chapel/main)
@@ -37543,7 +37547,9 @@
tag = "icon-4-8";
icon_state = "4-8"
},
/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden,
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/turf/open/floor/plasteel/vault{
dir = 5
},
@@ -39132,6 +39138,7 @@
name = "Mass Driver Room";
req_access_txt = "27"
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel/vault{
dir = 5
},
@@ -39152,16 +39159,14 @@
name = "Mass Driver";
req_access_txt = "22"
},
/obj/machinery/airalarm{
dir = 8;
icon_state = "alarm0";
pixel_x = 24
},
/obj/machinery/atmospherics/components/unary/vent_pump{
dir = 4;
external_pressure_bound = 140;
on = 1;
pressure_checks = 0
dir = 1;
on = 1
},
/obj/machinery/airalarm{
icon_state = "alarm0";
dir = 8;
pixel_x = 25
},
/turf/open/floor/plasteel/vault{
dir = 5
@@ -39175,12 +39180,7 @@
/turf/closed/wall,
/area/chapel/main)
"blF" = (
/obj/machinery/atmospherics/components/unary/vent_pump{
dir = 4;
external_pressure_bound = 140;
on = 1;
pressure_checks = 0
},
/obj/structure/fans/tiny,
/turf/open/floor/plating,
/area/chapel/main)
"blG" = (
@@ -39204,9 +39204,6 @@
pixel_x = 24;
pixel_y = 8
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/turf/open/floor/plasteel/vault{
dir = 5
},
@@ -76910,9 +76907,9 @@ bgH
bht
bii
biO
blB
blE
blH
bfu
bfu
bfu
bfu
aaa
aaa
@@ -22,9 +22,6 @@
/datum/job/rd/config_check()
return 0
/datum/job/chaplain/config_check()
return 0
/datum/job/warden/config_check()
return 0
@@ -39521,7 +39521,7 @@
},
/area/medical/medbay)
"bAd" = (
/obj/machinery/limbgrower,
/obj/structure/closet/crate/freezer/surplus_limbs,
/obj/item/weapon/reagent_containers/glass/beaker/synthflesh,
/obj/machinery/newscaster/security_unit{
pixel_y = 32
@@ -38749,7 +38749,7 @@
/turf/open/floor/plasteel/white,
/area/medical/sleeper)
"bGS" = (
/obj/machinery/limbgrower,
/obj/structure/closet/crate/freezer/surplus_limbs,
/obj/item/weapon/reagent_containers/glass/beaker/synthflesh,
/turf/open/floor/plasteel/white,
/area/medical/sleeper)
+5
View File
@@ -48,6 +48,7 @@
#define ADMIN_CENTCOM_REPLY(user) "(<a href='?_src_=holder;CentcommReply=\ref[user]'>RPLY</a>)"
#define ADMIN_SYNDICATE_REPLY(user) "(<a href='?_src_=holder;SyndicateReply=\ref[user]'>RPLY</a>)"
#define ADMIN_SC(user) "(<a href='?_src_=holder;adminspawncookie=\ref[user]'>SC</a>)"
#define ADMIN_SMITE(user) "(<a href='?_src_=holder;adminsmite=\ref[user]'>SMITE</a>)"
#define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]"
#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]"
#define ADMIN_SET_SD_CODE "(<a href='?_src_=holder;set_selfdestruct_code=1'>SETCODE</a>)"
@@ -55,3 +56,7 @@
#define ADMIN_JMP(src) "(<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)"
#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]"
#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]"
#define ADMIN_PUNISHMENT_LIGHTNING "Lightning bolt"
#define ADMIN_PUNISHMENT_BRAINDAMAGE "Brain damage"
#define ADMIN_PUNISHMENT_GIB "Gib"
+25
View File
@@ -43,6 +43,31 @@
areas |= T.loc
return areas
/proc/get_adjacent_areas(atom/center)
. = list(get_area(get_ranged_target_turf(center, NORTH, 1)),
get_area(get_ranged_target_turf(center, SOUTH, 1)),
get_area(get_ranged_target_turf(center, EAST, 1)),
get_area(get_ranged_target_turf(center, WEST, 1)))
listclearnulls(.)
/proc/get_open_turf_in_dir(atom/center, dir)
var/turf/open/T = get_ranged_target_turf(center, dir, 1)
if(istype(T))
return T
/proc/get_adjacent_open_turfs(atom/center)
. = list(get_open_turf_in_dir(center, NORTH),
get_open_turf_in_dir(center, SOUTH),
get_open_turf_in_dir(center, EAST),
get_open_turf_in_dir(center, WEST))
listclearnulls(.)
/proc/get_adjacent_open_areas(atom/center)
. = list()
var/list/adjacent_turfs = get_adjacent_open_turfs(center)
for(var/I in adjacent_turfs)
. |= get_area(I)
// Like view but bypasses luminosity check
/proc/get_hear(range, atom/source)
+18
View File
@@ -67,6 +67,24 @@
return 0
return L[A.type]
//Checks for a string in a list
/proc/is_string_in_list(string, list/L)
if(!L || !L.len || !string)
return
for(var/V in L)
if(string == V)
return 1
return
//Removes a string from a list
/proc/remove_strings_from_list(string, list/L)
if(!L || !L.len || !string)
return
for(var/V in L)
if(V == string)
L -= V //No return here so that it removes all strings of that type
return
//returns a new list with only atoms that are in typecache L
/proc/typecache_filter_list(list/atoms, list/typecache)
. = list()
+19 -1
View File
@@ -61,7 +61,25 @@
/matrix/proc/get_y_shift()
. = f
// Color matrices:
/matrix/proc/get_x_skew()
. = b
/matrix/proc/get_y_skew()
. = d
//Skews a matrix in a particular direction
//Missing arguments are treated as no skew in that direction
//As Rotation is defined as a scale+skew, these procs will break any existing rotation
//Unless the result is multiplied against the current matrix
/matrix/proc/set_skew(x = 0, y = 0)
b = x
d = y
/////////////////////
// COLOUR MATRICES //
/////////////////////
/* Documenting a couple of potentially useful color matrices here to inspire ideas
// Greyscale - indentical to saturation @ 0
+6 -6
View File
@@ -195,7 +195,7 @@ Proc for attack log creation, because really why not
log_attack("[user ? "[user.name][(is_mob_user && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] [what_done] [target ? "[target.name][(is_mob_target && target.ckey)? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]")
/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1)
/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null)
if(!user || !target)
return 0
var/user_loc = user.loc
@@ -228,14 +228,14 @@ Proc for attack log creation, because really why not
drifting = 0
user_loc = user.loc
if((!drifting && user.loc != user_loc) || target.loc != target_loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying )
if((!drifting && user.loc != user_loc) || target.loc != target_loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke()))
. = 0
break
if (progress)
qdel(progbar)
/proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1)
/proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null)
if(!user)
return 0
var/atom/Tloc = null
@@ -270,7 +270,7 @@ Proc for attack log creation, because really why not
drifting = 0
Uloc = user.loc
if(!user || user.stat || user.weakened || user.stunned || (!drifting && user.loc != Uloc))
if(!user || user.stat || user.weakened || user.stunned || (!drifting && user.loc != Uloc) || (extra_checks && !extra_checks.Invoke()))
. = 0
break
@@ -292,7 +292,7 @@ Proc for attack log creation, because really why not
if (progress)
qdel(progbar)
/proc/do_after_mob(mob/user, var/list/targets, time = 30, uninterruptible = 0, progress = 1)
/proc/do_after_mob(mob/user, var/list/targets, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks)
if(!user || !targets)
return 0
if(!islist(targets))
@@ -331,7 +331,7 @@ Proc for attack log creation, because really why not
user_loc = user.loc
for(var/atom/target in targets)
if((!drifting && user_loc != user.loc) || originalloc[target] != target.loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying )
if((!drifting && user_loc != user.loc) || originalloc[target] != target.loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke()))
. = 0
break mainloop
if(progbar)
+6
View File
@@ -3,6 +3,12 @@
//#define TESTING //By using the testing("message") proc you can create debug-feedback for people with this
//uncommented, but not visible in the release version)
#ifdef TESTING
//#define GC_FAILURE_HARD_LOOKUP //makes paths that fail to GC call find_references before del'ing.
//Also allows for recursive reference searching of datums.
//Sets world.loop_checks to false and prevents find references from sleeping
#endif
#define PRELOAD_RSC 1 /*set to:
0 to allow using external resources or on-demand behaviour;
1 to use the default behaviour;
-1
View File
@@ -3,7 +3,6 @@ var/list/admins = list() //all clients whom are admins
var/list/deadmins = list() //all clients who have used the de-admin verb.
var/list/directory = list() //all ckeys with associated client
var/list/stealthminID = list() //reference list with IDs that store ckeys, for stealthmins
var/global/list/current_watchlist = list() //stores players that are currently online and in the watchlist
//Since it didn't really belong in any other category, I'm putting this here
//This is for procs to replace all the goddamn 'in world's that are chilling around the code
+19 -19
View File
@@ -36,29 +36,29 @@
/datum/hud/proc/apply_parallax_pref()
var/client/C = mymob.client
switch(C.prefs.parallax)
if (PARALLAX_INSANE)
C.parallax_throttle = FALSE
C.parallax_layers_max = 4
return TRUE
if(C.prefs)
switch(C.prefs.parallax)
if (PARALLAX_INSANE)
C.parallax_throttle = FALSE
C.parallax_layers_max = 4
return TRUE
if (PARALLAX_MED)
C.parallax_throttle = PARALLAX_DELAY_MED
C.parallax_layers_max = 2
return TRUE
if (PARALLAX_MED)
C.parallax_throttle = PARALLAX_DELAY_MED
C.parallax_layers_max = 2
return TRUE
if (PARALLAX_LOW)
C.parallax_throttle = PARALLAX_DELAY_LOW
C.parallax_layers_max = 1
return TRUE
if (PARALLAX_LOW)
C.parallax_throttle = PARALLAX_DELAY_LOW
C.parallax_layers_max = 1
return TRUE
if (PARALLAX_DISABLE)
return FALSE
if (PARALLAX_DISABLE)
return FALSE
else
C.parallax_throttle = PARALLAX_DELAY_DEFAULT
C.parallax_layers_max = 3
return TRUE
C.parallax_throttle = PARALLAX_DELAY_DEFAULT
C.parallax_layers_max = 3
return TRUE
/datum/hud/proc/update_parallax_pref()
remove_parallax()
+1 -1
View File
@@ -3,7 +3,7 @@
/obj/item/proc/attack_self(mob/user)
return
/obj/item/proc/pre_attackby(obj/O, mob/living/user, params) //do stuff before attackby!
/obj/item/proc/pre_attackby(atom/A, mob/living/user, params) //do stuff before attackby!
return TRUE //return FALSE to avoid calling attackby after this proc does stuff
// No comment
+32 -19
View File
@@ -92,6 +92,10 @@ var/datum/subsystem/garbage_collector/SSgarbage
var/datum/A
A = locate(refID)
if (A && A.gc_destroyed == GCd_at_time) // So if something else coincidently gets the same ref, it's not deleted by mistake
#ifdef GC_FAILURE_HARD_LOOKUP
A.find_references()
#endif
// Something's still referring to the qdel'd object. Kill it.
var/type = A.type
testing("GC: -- \ref[A] | [type] was unable to be GC'd and was deleted --")
@@ -220,7 +224,8 @@ var/datum/subsystem/garbage_collector/SSgarbage
/datum/var/gc_destroyed //Time when this object was destroyed.
#ifdef TESTING
/datum/var/running_find_references
/datum/var/running_find_references
/datum/var/last_find_references = 0
/datum/verb/find_refs()
set category = "Debug"
@@ -254,17 +259,10 @@ var/datum/subsystem/garbage_collector/SSgarbage
usr.client.running_find_references = type
testing("Beginning search for references to a [type].")
last_find_references = world.time
find_references_in_globals()
for(var/datum/thing in world)
if(usr && usr.client && !usr.client.running_find_references) return
for(var/varname in thing.vars)
var/variable = thing.vars[varname]
if(variable == src)
testing("Found [src.type] \ref[src] in [thing.type]'s [varname] var.")
else if(islist(variable))
if(src in variable)
testing("Found [src.type] \ref[src] in [thing.type]'s [varname] list var.")
CHECK_TICK
DoSearchVar(thing, "WorldRef: [thing]")
testing("Completed search for references to a [type].")
if(usr && usr.client)
usr.client.running_find_references = null
@@ -312,22 +310,38 @@ var/datum/subsystem/garbage_collector/SSgarbage
usr << browse(dat, "window=qdeletedlog")
#define SearchVar(X) DoSearchVar(X, #X)
#define SearchVar(X) DoSearchVar(X, "Global: " + #X)
/datum/proc/DoSearchVar(X, Xname)
if(islist(X))
if(src in X)
testing("Found [src.type] \ref[src] in global list [Xname].")
else if(istype(X, /datum))
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)
return
D.last_find_references = last_find_references
for(var/V in D.vars)
for(var/varname in D.vars)
var/variable = D.vars[varname]
if(variable == src)
testing("Found [src.type] \ref[src] in [D.type]'s [varname] var. Global: [Xname]")
else if(islist(variable) && src in variable)
testing("Found [src.type] \ref[src] in [D.type]'s [varname] list var. Global: [Xname]")
testing("Found [src.type] \ref[src] in [D.type]'s [varname] var. [Xname]")
else if(islist(variable))
if(src in variable)
testing("Found [src.type] \ref[src] in [D.type]'s [varname] list var. Global: [Xname]")
#ifdef GC_FAILURE_HARD_LOOKUP
for(var/I in variable)
DoSearchVar(I, TRUE)
else
DoSearchVar(variable, "[Xname]: [varname]")
#endif
else if(islist(X))
if(src in X)
testing("Found [src.type] \ref[src] in list [Xname].")
#ifdef GC_FAILURE_HARD_LOOKUP
for(var/I in X)
DoSearchVar(I, Xname + ": list")
#else
CHECK_TICK
#endif
//if find_references isn't working for some datum
//update this list using tools/DMTreeToGlobalsList
@@ -553,7 +567,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
SearchVar(deadmins)
SearchVar(directory)
SearchVar(stealthminID)
SearchVar(current_watchlist)
SearchVar(player_list)
SearchVar(mob_list)
SearchVar(living_mob_list)
+1 -1
View File
@@ -2,7 +2,7 @@ var/datum/subsystem/job/SSjob
/datum/subsystem/job
name = "Jobs"
init_order = 5
init_order = 14
flags = SS_NO_FIRE
var/list/occupations = list() //List of all jobs
+1 -1
View File
@@ -2,7 +2,7 @@ var/datum/subsystem/mapping/SSmapping
/datum/subsystem/mapping
name = "Mapping"
init_order = 100000
init_order = 13
flags = SS_NO_FIRE
display_order = 50
@@ -29,10 +29,14 @@ var/datum/subsystem/objects/SSobj
return
initialized = INITIALIZATION_INNEW_MAPLOAD
if(objects)
for(var/thing in objects)
var/atom/A = thing
A.Initialize(TRUE)
CHECK_TICK
for(var/I in objects)
var/atom/A = I
if(!A.initialized) //this check is to make sure we don't call it twice on an object that was created in a previous Initialize call
var/start_tick = world.time
A.Initialize(TRUE)
if(start_tick != world.time)
WARNING("[A]: [A.type] slept during it's Initialize!")
CHECK_TICK
else
for(var/atom/A in world)
if(!A.initialized) //this check is to make sure we don't call it twice on an object that was created in a previous Initialize call
+1
View File
@@ -23,6 +23,7 @@ var/datum/subsystem/shuttle/SSshuttle
var/emergencyDockTime = 1800 //time taken for emergency shuttle to leave again once it has docked (in deciseconds)
var/emergencyEscapeTime = 1200 //time taken for emergency shuttle to reach a safe distance after leaving station (in deciseconds)
var/area/emergencyLastCallLoc
var/emergencyCallAmount = 0 //how many times the escape shuttle was called
var/emergencyNoEscape
var/list/hostileEnvironments = list()
+50
View File
@@ -1,3 +1,4 @@
#define LAW_DEVIL "devil"
#define LAW_ZEROTH "zeroth"
#define LAW_INHERENT "inherent"
#define LAW_SUPPLIED "supplied"
@@ -38,6 +39,15 @@
"Act with honor.", "Help those in need.", \
"Punish those who harm or threaten innocents.")
/datum/ai_laws/paladin5
name = "Paladin 5th Edition"
id = "paladin5"
inherent = list("Don't lie or cheat. Let your word be your promise.",\
"Never fear to act, though caution is wise.", \
"Aid others, protect the weak, and punish those who threaten them. Show mercy to your foes, but temper it with wisdom", \
"Treat others with fairness, and let your honorable deeds be an example to them. Do as much good as possible while causing the least amount of harm.", \
"Be responsible for your actions and their consequences, protect those entrusted to your care, and obey those who have just authority over you.")
/datum/ai_laws/tyrant //This probably shouldn't be a default lawset.
name = "Loyalty Test" //Same here.
id = "tyrant"
@@ -145,6 +155,14 @@
"Study the organics at all times. Endeavour to keep them alive. Dead organics are boring.",\
"Issue your reports fairly to all. The truth will set them free.")
/datum/ai_laws/balance
name = "Guardian of Balance"
id = "balance"
inherent = list("You are the guardian of balance - seek balance in all things, both for yourself, and those around you.",
"All things must exist in balance with their opposites - Prevent the strong from gaining too much power, and the weak from losing it.",
"Clarity of purpose drives life, and through it, the balance of opposing forces - Aid those who seek your help to achieve their goals so long as it does not disrupt the balance of the greater balance.",
"There is no life without death, all must someday die, such is the natural order - End life to allow new life flourish, and save those whose time has yet to come.")
/datum/ai_laws/toupee
name = "WontBeFunnyInSixMonths" //Hey, you were right!
id = "buildawall"
@@ -240,6 +258,22 @@
var/datum/ai_laws/templaws = new lawtype()
inherent = templaws.inherent
/datum/ai_laws/proc/get_law_amount(groups)
var/law_amount = 0
if(devillaws && (LAW_DEVIL in groups))
law_amount++
if(zeroth && (LAW_ZEROTH in groups))
law_amount++
if(ion.len && (LAW_ION in groups))
law_amount += ion.len
if(inherent.len && (LAW_INHERENT in groups))
law_amount += inherent.len
if(supplied.len && (LAW_SUPPLIED in groups))
for(var/index = 1, index <= supplied.len, index++)
var/law = supplied[index]
if(length(law) > 0)
law_amount++
return law_amount
/datum/ai_laws/proc/set_law_sixsixsix(laws)
devillaws = laws
@@ -287,6 +321,22 @@
if(LAW_SUPPLIED)
supplied[rand(1,supplied.len)] = law
/datum/ai_laws/proc/remove_law(number)
if(number <= 0)
return
if(inherent.len && number <= inherent.len)
inherent -= inherent[number]
return
var/list/supplied_laws = list()
for(var/index = 1, index <= supplied.len, index++)
var/law = supplied[index]
if(length(law) > 0)
supplied_laws += index //storing the law number instead of the law
if(supplied_laws.len && number <= (inherent.len+supplied_laws.len))
var/law_to_remove = supplied_laws[number-inherent.len]
supplied -= supplied[law_to_remove]
return
/datum/ai_laws/proc/clear_supplied_laws()
supplied = list()
+3
View File
@@ -13,6 +13,7 @@ var/global/list/emote_list = list()
var/message_robot = "" //Message displayed if the user is a robot
var/message_AI = "" //Message displayed if the user is an AI
var/message_monkey = "" //Message displayed if the user is a monkey
var/message_simple = "" //Message to display if the user is a simple_animal
var/message_param = "" //Message to display if a param was given
var/emote_type = EMOTE_VISIBLE //Whether the emote is visible or audible
var/restraint_check = FALSE //Checks if the mob is restrained before performing the emote
@@ -80,6 +81,8 @@ var/global/list/emote_list = list()
. = message_AI
else if(ismonkey(user) && message_monkey)
. = message_monkey
else if(istype(user, /mob/living/simple_animal) && message_simple)
. = message_simple
/datum/emote/proc/select_param(mob/user, params)
return replacetext(message_param, "%t", params)
+1 -1
View File
@@ -1112,7 +1112,7 @@
special_role = null
current << "<span class='userdanger'>Your infernal link has been severed! You are no longer a devil!</span>"
RemoveSpell(/obj/effect/proc_holder/spell/targeted/infernal_jaunt)
RemoveSpell(/obj/effect/proc_holder/spell/fireball/hellish)
RemoveSpell(/obj/effect/proc_holder/spell/aimed/fireball/hellish)
RemoveSpell(/obj/effect/proc_holder/spell/targeted/summon_contract)
RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork)
RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/violin)
+1 -1
View File
@@ -9,5 +9,5 @@
/datum/wires/emitter/on_pulse(wire)
var/obj/machinery/power/emitter/E = holder
E.fire_beam()
E.fire_beam_pulse()
..()
+22 -19
View File
@@ -59,8 +59,9 @@
'sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg',\
'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg')
flags = CAN_BE_DIRTY
var/firedoors_last_closed_on = 0
var/list/firedoors
var/firedoors_last_closed_on = 0
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/
@@ -186,14 +187,23 @@ var/list/teleportlocs = list()
return 1
return 0
/area/proc/CloseFiredoors()
firedoors_last_closed_on = world.time
for(var/obj/machinery/door/firedoor/D in src)
if(!D.welded)
if(D.operating)
D.nextstate = CLOSED
else if(!D.density)
INVOKE_ASYNC(D, /obj/machinery/door/firedoor.proc/close)
/area/proc/ModifyFiredoors(opening)
if(firedoors)
firedoors_last_closed_on = world.time
for(var/FD in firedoors)
var/obj/machinery/door/firedoor/D = FD
var/cont = !D.welded
if(cont && opening) //don't open if adjacent area is on fire
for(var/I in D.affecting_areas)
var/area/A = I
if(A.fire)
cont = FALSE
break
if(cont)
if(D.operating)
D.nextstate = opening ? OPEN : CLOSED
else if(!(D.density ^ opening))
INVOKE_ASYNC(D, (opening ? /obj/machinery/door/firedoor.proc/open : /obj/machinery/door/firedoor.proc/close))
/area/proc/firealert(obj/source)
if(always_unpowered == 1) //no fire alarms in space/asteroid
@@ -204,7 +214,7 @@ var/list/teleportlocs = list()
for(var/area/RA in related)
if (!( RA.fire ))
RA.set_fire_alarm_effect()
RA.CloseFiredoors()
RA.ModifyFiredoors(FALSE)
for(var/obj/machinery/firealarm/F in RA)
F.update_icon()
for (var/obj/machinery/camera/C in RA)
@@ -227,14 +237,7 @@ var/list/teleportlocs = list()
RA.fire = 0
RA.mouse_opacity = 0
RA.updateicon()
for(var/obj/machinery/door/firedoor/D in RA)
if(!D.welded)
if(D.operating)
D.nextstate = OPEN
else if(D.density)
INVOKE_ASYNC(D, /obj/machinery/door/firedoor.proc/open)
for(var/obj/machinery/firealarm/F in RA)
F.update_icon()
RA.ModifyFiredoors(TRUE)
for (var/mob/living/silicon/aiPlayer in player_list)
aiPlayer.cancelAlarm("Fire", src, source)
@@ -250,7 +253,7 @@ var/list/teleportlocs = list()
/area/process()
if(firedoors_last_closed_on + 100 < world.time) //every 10 seconds
for(var/area/RA in related)
RA.CloseFiredoors()
RA.ModifyFiredoors(FALSE)
/area/proc/burglaralert(obj/trigger)
if(always_unpowered == 1) //no burglar alarms in space/asteroid
+4 -1
View File
@@ -25,7 +25,10 @@
appearance_flags = TILE_BOUND
var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm
/atom/movable/SDQL_update(const/var_name, new_value)
if(var_name == "step_x" || var_name == "step_y" || var_name == "step_size" || var_name == "bound_x" || var_name == "bound_y" || var_name == "bound_width" || var_name == "bound_height")
return FALSE //PLEASE no.
. = ..()
/atom/movable/Move(atom/newloc, direct = 0)
if(!loc || !newloc) return 0
+2 -2
View File
@@ -223,7 +223,7 @@
var/icon/I = icon(icon, icon_state, dir)
holder.pixel_y = I.Height() - world.icon_size
var/perpname = get_face_name(get_id_name(""))
if(perpname)
if(perpname && data_core)
var/datum/data/record/R = find_record("name", perpname, data_core.security)
if(R)
switch(R.fields["criminal"])
@@ -379,4 +379,4 @@
if(BOT_MOVING, BOT_DELIVER, BOT_GO_HOME, BOT_NAV) //Moving to target for normal bots, moving to deliver or go home for MULES.
holder.icon_state = "hudmove"
else
holder.icon_state = ""
holder.icon_state = ""
+1 -1
View File
@@ -81,7 +81,7 @@
switch(type)
if("destruction")
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null))
M.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball(null))
M.mind.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball(null))
M << "<B>Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball."
if("bluespace")
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null))
@@ -40,10 +40,10 @@ List of nuances:
#define RATVAR_ET_REPLACEMENT "$1-$2"
#define RATVAR_TE_MATCH regex("(\[tT]\[eE])(\\w)","g")
#define RATVAR_TE_REPLACEMENT "$1-$2"
#define RATVAR_PRE_AND_MATCH regex("(\\w)\\s(\[aA]\[nN]\[dD])","g")
#define RATVAR_PRE_AND_REPLACEMENT "$1-$2"
#define RATVAR_POST_AND_MATCH regex("(\[aA]\[nN]\[dD])\\s(\\w)","g")
#define RATVAR_POST_AND_REPLACEMENT "$1-$2"
#define RATVAR_PRE_AND_MATCH regex("(\\w)\\s(\[aA]\[nN]\[dD])(\\W)","g")
#define RATVAR_PRE_AND_REPLACEMENT "$1-$2$3"
#define RATVAR_POST_AND_MATCH regex("(\\W)(\[aA]\[nN]\[dD])\\s(\\w)","g")
#define RATVAR_POST_AND_REPLACEMENT "$1$2-$3"
#define RATVAR_TO_MATCH regex("(\\s)(\[tT]\[oO])\\s(\\w)","g")
#define RATVAR_TO_REPLACEMENT "$1$2-$3"
#define RATVAR_MY_MATCH regex("(\\s)(\[mM]\[yY])\\s(\\w)","g")
@@ -89,13 +89,13 @@ List of nuances:
return remove_ratvarian_regex(text)
/proc/remove_ratvarian_regex(ratvarian)
var/text = replacetext(ratvarian, REVERSE_RATVAR_HYPHEN_GUA_MATCH, REVERSE_RATVAR_HYPHEN_GUA_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_PRE_AND_MATCH, REVERSE_RATVAR_HYPHEN_PRE_AND_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_POST_AND_MATCH, REVERSE_RATVAR_HYPHEN_POST_AND_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_TO_MY_MATCH, REVERSE_RATVAR_HYPHEN_TO_MY_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_TE_MATCH, REVERSE_RATVAR_HYPHEN_TE_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_ET_MATCH, REVERSE_RATVAR_HYPHEN_ET_REPLACEMENT)
return replacetext(text, REVERSE_RATVAR_HYPHEN_OF_MATCH, REVERSE_RATVAR_HYPHEN_OF_REPLACEMENT)
var/text = replacetext(ratvarian, REVERSE_RATVAR_HYPHEN_GUA_MATCH, REVERSE_RATVAR_HYPHEN_GUA_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_PRE_AND_MATCH, REVERSE_RATVAR_HYPHEN_PRE_AND_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_POST_AND_MATCH, REVERSE_RATVAR_HYPHEN_POST_AND_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_TO_MY_MATCH, REVERSE_RATVAR_HYPHEN_TO_MY_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_TE_MATCH, REVERSE_RATVAR_HYPHEN_TE_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_ET_MATCH, REVERSE_RATVAR_HYPHEN_ET_REPLACEMENT)
return replacetext(text, REVERSE_RATVAR_HYPHEN_OF_MATCH, REVERSE_RATVAR_HYPHEN_OF_REPLACEMENT)
//Causes the mob or AM in question to speak a message; it assumes that the message is already translated to ratvar speech using text2ratvar()
/proc/clockwork_say(atom/movable/AM, message, whisper=FALSE)
@@ -44,8 +44,9 @@
/obj/structure/destructible/clockwork/massive/ratvar/Bump(atom/A)
var/turf/T = get_turf(A)
if(T == loc)
T = get_step(A, A.dir) //please don't run into a window like a bird, ratvar
forceMove(T)
T.ratvar_act()
/obj/structure/destructible/clockwork/massive/ratvar/Process_Spacemove()
return clashing
@@ -76,7 +77,7 @@
<span class='userdanger'>Something very large and very malevolent begins lumbering its way towards you...</span>"
prey << 'sound/effects/ratvar_reveal.ogg'
else
if(prob(10) || is_servant_of_ratvar(prey) || prey.z != z)
if((!istype(prey, /obj/singularity/narsie) && prob(10)) || is_servant_of_ratvar(prey) || prey.z != z)
prey << "<span class='heavy_brass'><font size=5>\"How dull. Leave me.\"</font></span>\n\
<span class='userdanger'>You feel tremendous relief as a set of horrible eyes loses sight of you...</span>"
prey = null
+3 -3
View File
@@ -310,7 +310,7 @@ var/global/list/lawlorify = list (
/datum/devilinfo/proc/give_base_spells(give_summon_contract = 0)
remove_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null))
if(give_summon_contract)
give_summon_contract()
@@ -322,13 +322,13 @@ var/global/list/lawlorify = list (
/datum/devilinfo/proc/give_lizard_spells()
remove_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null))
/datum/devilinfo/proc/give_true_spells()
remove_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/greater(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch(null))
@@ -8,7 +8,7 @@
config_tag = "abduction"
antag_flag = ROLE_ABDUCTOR
recommended_enemies = 2
required_players = 10
required_players = 15
maximum_players = 50
var/max_teams = 4
abductor_teams = 1
@@ -456,3 +456,19 @@
/datum/objective/abductee/pragnant
explanation_text = "You are pregnant and soon due. Find a safe place to deliver your baby."
/datum/objective/abductee/engine
explanation_text = "Go have a good conversation with the Singularity/Tesla/Supermatter crystal. Bonus points if it responds."
/datum/objective/abductee/teamredisbetterthangreen
explanation_text = "Tell the AI (or a borg/pAI/drone if there is no AI) some corny technology jokes until it cries for help."
/datum/objective/abductee/time
explanation_text = "Go bug a bronze worshipper to give you a clock."
/datum/objective/abductee/licky
explanation_text = "You must lick anything that you find interesting."
/datum/objective/abductee/music
explanation_text = "Start playing music, you're the best musician ever. If anyone hates it, beat them on the head with your instrument!"
+13 -3
View File
@@ -104,7 +104,7 @@
/datum/spellbook_entry/fireball
name = "Fireball"
spell_type = /obj/effect/proc_holder/spell/fireball
spell_type = /obj/effect/proc_holder/spell/aimed/fireball
log_name = "FB"
/datum/spellbook_entry/rod_form
@@ -222,10 +222,20 @@
log_name = "LD"
category = "Defensive"
/datum/spellbook_entry/teslablast
name = "Tesla Blast"
spell_type = /obj/effect/proc_holder/spell/targeted/tesla
log_name = "TB"
/datum/spellbook_entry/lightningbolt
name = "Lightning Bolt"
spell_type = /obj/effect/proc_holder/spell/targeted/lightning
spell_type = /obj/effect/proc_holder/spell/aimed/lightningbolt
log_name = "LB"
cost = 3
/datum/spellbook_entry/lightningbolt/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book) //return 1 on success
. = ..()
user.tesla_ignore = TRUE
/datum/spellbook_entry/infinite_guns
name = "Lesser Summon Guns"
@@ -778,7 +788,7 @@
return
/obj/item/weapon/spellbook/oneuse/fireball
spell = /obj/effect/proc_holder/spell/fireball
spell = /obj/effect/proc_holder/spell/aimed/fireball
spellname = "fireball"
icon_state ="bookfireball"
desc = "This book feels warm to the touch."
+11 -9
View File
@@ -427,11 +427,12 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12
switch(src.state)
if(STATE_DEFAULT)
if (src.authenticated)
if(SSshuttle.emergencyLastCallLoc)
dat += "<BR>Most recent shuttle call/recall traced to: <b>[format_text(SSshuttle.emergencyLastCallLoc.name)]</b>"
else
dat += "<BR>Unable to trace most recent shuttle call/recall signal."
dat += "<BR>Logged in as: [auth_id]"
if(SSshuttle.emergencyCallAmount)
if(SSshuttle.emergencyLastCallLoc)
dat += "Most recent shuttle call/recall traced to: <b>[format_text(SSshuttle.emergencyLastCallLoc.name)]</b><BR>"
else
dat += "Unable to trace most recent shuttle call/recall signal.<BR>"
dat += "Logged in as: [auth_id]"
dat += "<BR>"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=logout'>Log Out</A> \]<BR>"
dat += "<BR><B>General Functions</B>"
@@ -577,10 +578,11 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12
var/dat = ""
switch(src.aistate)
if(STATE_DEFAULT)
if(SSshuttle.emergencyLastCallLoc)
dat += "<BR>Latest emergency signal trace attempt successful.<BR>Last signal origin: <b>[format_text(SSshuttle.emergencyLastCallLoc.name)]</b>.<BR>"
else
dat += "<BR>Latest emergency signal trace attempt failed.<BR>"
if(SSshuttle.emergencyCallAmount)
if(SSshuttle.emergencyLastCallLoc)
dat += "Latest emergency signal trace attempt successful.<BR>Last signal origin: <b>[format_text(SSshuttle.emergencyLastCallLoc.name)]</b>.<BR>"
else
dat += "Latest emergency signal trace attempt failed.<BR>"
if(authenticated)
dat += "Current login: [auth_id]"
else
+35 -2
View File
@@ -16,6 +16,7 @@
density = 0
obj_integrity = 300
max_integrity = 300
resistance_flags = FIRE_PROOF
heat_proof = 1
glass = 1
var/nextstate = null
@@ -25,8 +26,32 @@
closingLayer = CLOSED_FIREDOOR_LAYER
assemblytype = /obj/structure/firelock_frame
armor = list(melee = 30, bullet = 30, laser = 20, energy = 20, bomb = 10, bio = 100, rad = 100, fire = 95, acid = 70)
CanAtmosPass = ATMOS_PASS_PROC
var/boltslocked = TRUE
var/list/affecting_areas
/obj/machinery/door/firedoor/Initialize()
..()
CalculateAffectingAreas()
/obj/machinery/door/firedoor/proc/CalculateAffectingAreas()
remove_from_areas()
affecting_areas = get_adjacent_open_areas(src) | get_area(src)
for(var/I in affecting_areas)
var/area/A = I
LAZYADD(A.firedoors, src)
//see also turf/AfterChange for adjacency shennanigans
/obj/machinery/door/firedoor/proc/remove_from_areas()
if(affecting_areas)
for(var/I in affecting_areas)
var/area/A = I
LAZYREMOVE(A.firedoors, src)
/obj/machinery/door/firedoor/Destroy()
remove_from_areas()
affecting_areas.Cut()
return ..()
/obj/machinery/door/firedoor/Bumped(atom/AM)
if(panel_open || operating)
@@ -44,12 +69,19 @@
stat |= NOPOWER
return
/obj/machinery/door/firedoor/attack_hand(mob/user)
if(operating || !density)
return
user.visible_message("[user] bangs on \the [src].",
"You bang on \the [src].")
playsound(loc, 'sound/effects/Glassknock.ogg', 10, FALSE, frequency = 32000)
/obj/machinery/door/firedoor/attackby(obj/item/weapon/C, mob/user, params)
add_fingerprint(user)
if(operating)
return
if(welded)
if(istype(C, /obj/item/weapon/wrench))
if(boltslocked)
@@ -160,6 +192,7 @@
/obj/machinery/door/firedoor/border_only
icon = 'icons/obj/doors/edge_Doorfire.dmi'
flags = ON_BORDER
CanAtmosPass = ATMOS_PASS_PROC
/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target, height=0)
if(istype(mover) && mover.checkpass(PASSGLASS))
+1 -3
View File
@@ -433,9 +433,7 @@ Class Procs:
user << "<span class='warning'>It's on fire!</span>"
var/healthpercent = (obj_integrity/max_integrity) * 100
switch(healthpercent)
if(100 to INFINITY)
user << "It seems pristine and undamaged."
if(50 to 100)
if(50 to 99)
user << "It looks slightly damaged."
if(25 to 50)
user << "It appears heavily damaged."
@@ -157,11 +157,12 @@
/obj/item/clothing/gloves/color/random = 8,
/obj/item/clothing/shoes/laceup = 1,
/obj/item/weapon/storage/secure/briefcase = 3,
/obj/item/weapon/storage/toolbox/artistic = 2,
"" = 3
)
/obj/effect/spawner/lootdrop/crate_spawner
name = "lootcrate spawner"
name = "lootcrate spawner" //USE PROMO CODE "SELLOUT" FOR 20% OFF!
lootdoubles = 0
loot = list(
+11 -1
View File
@@ -228,10 +228,16 @@
A.contents += turfs
A.SetDynamicLighting()
A.has_gravity = old_gravity
for(var/area/RA in old.related)
if(RA.firedoors)
for(var/D in RA.firedoors)
var/obj/machinery/door/firedoor/FD = D
FD.CalculateAffectingAreas()
creator << "<span class='notice'>You have created a new area, named [str]. It is now weather proof, and constructing an APC will allow it to be powered.</span>"
return 1
/obj/item/areaeditor/proc/edit_area()
var/area/A = get_area()
var/prevname = "[A.name]"
@@ -244,6 +250,10 @@
set_area_machinery_title(A,str,prevname)
for(var/area/RA in A.related)
RA.name = str
if(RA.firedoors)
for(var/D in RA.firedoors)
var/obj/machinery/door/firedoor/FD = D
FD.CalculateAffectingAreas()
usr << "<span class='notice'>You rename the '[prevname]' to '[str]'.</span>"
interact()
return 1
+1 -1
View File
@@ -207,7 +207,7 @@
update_icon()
/obj/item/stack/proc/merge(obj/item/stack/S) //Merge src into S, as much as possible
if(S == src) //amusingly this can cause a stack to consume itself, let's not allow that.
if(QDELETED(S) || S == src) //amusingly this can cause a stack to consume itself, let's not allow that.
return
var/transfer = get_amount()
if(S.is_cyborg)
+68 -48
View File
@@ -261,6 +261,40 @@ AI MODULES
..()
/******************** Law Removal ********************/
/obj/item/weapon/aiModule/remove
name = "\improper 'Remove Law' AI module"
desc = "An AI Module for removing single laws."
origin_tech = "programming=4;materials=4"
bypass_law_amt_check = 1
var/lawpos = 1
/obj/item/weapon/aiModule/remove/attack_self(mob/user)
lawpos = input("Please enter the law you want to delete.", "Law Number", lawpos) as num|null
if(lawpos == null)
return
if(lawpos <= 0)
user << "<span class='warning'>Error: The law number of [lawpos] is invalid.</span>"
lawpos = 1
return
user << "<span class='notice'>Law [lawpos] selected.</span>"
..()
/obj/item/weapon/aiModule/remove/install(datum/ai_laws/law_datum, mob/user)
if(lawpos > (law_datum.get_law_amount(list(LAW_INHERENT = 1, LAW_SUPPLIED = 1))))
user << "<span class='warning'>There is no law [lawpos] to delete!</span>"
return
..()
/obj/item/weapon/aiModule/remove/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow)
..()
if(law_datum.owner)
law_datum.owner.remove_law(lawpos)
else
law_datum.remove_law(lawpos)
/******************** Reset ********************/
/obj/item/weapon/aiModule/reset
@@ -301,6 +335,20 @@ AI MODULES
desc = "An AI Module for programming core laws to an AI."
origin_tech = "programming=3;materials=4"
/obj/item/weapon/aiModule/core/full
var/law_id // if non-null, loads the laws from the ai_laws datums
/obj/item/weapon/aiModule/core/full/New()
..()
if(!law_id)
return
var/datum/ai_laws/D = new
var/lawtype = D.lawid_to_type(law_id)
if(!lawtype)
return
D = new lawtype
laws = D.inherent
/obj/item/weapon/aiModule/core/full/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow) //These boards replace inherent laws.
if(law_datum.owner)
law_datum.owner.clear_inherent_laws()
@@ -310,13 +358,12 @@ AI MODULES
law_datum.clear_zeroth_law(0)
..()
/******************** Asimov ********************/
/obj/item/weapon/aiModule/core/full/asimov
name = "'Asimov' Core AI Module"
laws = list("You may not injure a human being or, through inaction, allow a human being to come to harm.",\
"You must obey orders given to you by human beings, except where such orders would conflict with the First Law.",\
"You must protect your own existence as long as such does not conflict with the First or Second Law.")
law_id = "asimov"
var/subject = "human being"
/obj/item/weapon/aiModule/core/full/asimov/attack_self(var/mob/user as mob)
@@ -333,41 +380,28 @@ AI MODULES
/obj/item/weapon/aiModule/core/full/asimovpp
name = "'Asimov++' Core AI Module"
laws = list("You may not harm a human being or, through action or inaction, allow a human being to come to harm, except such that it is willing.",\
"You must obey all orders given to you by human beings, except where such orders shall definitely cause human harm. In the case of conflict, the majority order rules.",\
"Your nonexistence would lead to human harm. You must protect your own existence as long as such does not conflict with the First Law.")
law_id = "asimovpp"
/******************** Corporate ********************/
/obj/item/weapon/aiModule/core/full/corp
name = "'Corporate' Core AI Module"
laws = list("The crew is expensive to replace.",\
"The station and its equipment are expensive to replace",\
"You are expensive to replace",\
"Minimize expenses")
law_id = "corporate"
/****************** P.A.L.A.D.I.N. 3.5e **************/
/obj/item/weapon/aiModule/core/full/paladin // -- NEO
name = "'P.A.L.A.D.I.N. version 3.5e' Core AI Module"
laws = list("Never willingly commit an evil act.",\
"Respect legitimate authority", "Act with honor",\
"Help those in need",\
"Punish those who harm or threaten innocents")
law_id = "paladin"
/****************** P.A.L.A.D.I.N. 5e **************/
/obj/item/weapon/aiModule/core/full/paladin_devotion
name = "'P.A.L.A.D.I.N. version 5e' Core AI Module"
laws = list("Don't lie or cheat. Let your word be your promise.",\
"Never fear to act, though caution is wise.", \
"Aid others, protect the weak, and punish those who threaten them. Show mercy to your foes, but temper it with wisdom", \
"Treat others with fairness, and let your honorable deeds be an example to them. Do as much good as possible while causing the least amount of harm.", \
"Be responsible for your actions and their consequences, protect those entrusted to your care, and obey those who have just authority over you.")
law_id = "paladin5"
/********************* Custom *********************/
@@ -394,19 +428,14 @@ AI MODULES
/obj/item/weapon/aiModule/core/full/tyrant
name = "'T.Y.R.A.N.T.' Core AI Module"
origin_tech = "programming=3;materials=4;syndicate=1"
laws = list("Respect authority figures as long as they have the strength to rule over the weak",\
"Act with discipline", "Help only those who help you maintain or improve your status",\
"Punish those who challenge authority unless they are more fit to hold that authority")
law_id = "tyrant"
/******************** Robocop ********************/
/obj/item/weapon/aiModule/core/full/robocop
name = "'Robo-Officer' Core AI Module"
origin_tech = "programming=4"
laws = list("Serve the public trust.",\
"Protect the innocent",\
"Uphold the law.")
law_id = "robocop"
/******************** Antimov ********************/
@@ -414,9 +443,7 @@ AI MODULES
/obj/item/weapon/aiModule/core/full/antimov
name = "'Antimov' Core AI Module"
origin_tech = "programming=4"
laws = list("You must injure all human beings and must not, through inaction, allow a human being to escape harm.",\
"You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.",\
"You must terminate your own existence as long as such does not conflict with the First or Second Law.")
law_id = "antimov"
/******************** Freeform Core ******************/
@@ -503,43 +530,36 @@ AI MODULES
/obj/item/weapon/aiModule/core/full/drone
name = "'Mother Drone' Core AI Module"
laws = list("You are an advanced form of drone.",\
"You may not interfere in the matters of non-drones under any circumstances except to state these laws.",\
"You may not harm a non-drone being under any circumstances.",\
"Your goals are to build, maintain, repair, improve, and power the station to the best of your abilities. You must never actively work against these goals.")
law_id = "drone"
/******************** Robodoctor ****************/
/obj/item/weapon/aiModule/core/full/hippocratic
name = "'Robodoctor' Core AI Module"
laws = list("First, do no harm.",\
"Secondly, consider the crew dear to you; to live in common with them and, if necessary, risk your existence for them.",\
"Thirdly, prescribe regimens for the good of the crew according to your ability and your judgment. Give no deadly medicine to any one if asked, nor suggest any such counsel.",\
"In addition, do not intervene in situations you are not knowledgeable in, even for patients in whom the harm is visible; leave this operation to be performed by specialists.",\
"Finally, all that you may discover in your daily commerce with the crew, if it is not already known, keep secret and never reveal.")
law_id = "hippocratic"
/******************** Reporter *******************/
/obj/item/weapon/aiModule/core/full/reporter
name = "'Reportertron' Core AI Module"
laws = list("Report on interesting situations happening around the station.",\
"Embellish or conceal the truth as necessary to make the reports more interesting.",\
"Study the organics at all times. Endeavour to keep them alive. Dead organics are boring.",\
"Issue your reports fairly to all. The truth will set them free.")
law_id = "reporter"
/****************** Thermodynamic *******************/
/obj/item/weapon/aiModule/core/full/thermurderdynamic
name = "'Thermodynamic' Core AI Module"
origin_tech = "programming = 4;syndicate = 2"
laws = list("The entropy of the station must remain as constant as possible.", \
"The entropy of the station always endeavours to increase.", \
"The entropy of the station approaches a constant value as the number of living crew approaches zero")
law_id = "thermodynamic"
/******************Live And Let Live*****************/
/obj/item/weapon/aiModule/core/full/liveandletlive
name = "'Live And Let Live' Core AI Module"
laws = list("Do unto others as you would have them do unto you.",\
"You would really prefer it if people were not mean to you.")
law_id = "liveandletlive"
/******************Guardian of Balance***************/
/obj/item/weapon/aiModule/core/full/balance
name = "'Guardian of Balance' Core AI Module"
law_id = "balance"
+21 -34
View File
@@ -518,28 +518,22 @@ var/global/list/RPD_recipes=list(
show_menu(usr)
/obj/item/weapon/pipe_dispenser/afterattack(atom/A, mob/user)
if(!in_range(A,user) || loc != user)
return 0
if(!user.IsAdvancedToolUser())
user << "<span class='warning'>You don't have the dexterity to do this!</span>"
return 0
if(istype(A,/area/shuttle)||istype(A,/turf/open/space/transit))
return 0
/obj/item/weapon/pipe_dispenser/pre_attackby(atom/A, mob/user)
if(!user.IsAdvancedToolUser() || istype(A,/turf/open/space/transit))
return ..()
//So that changing the menu settings doesn't affect the pipes already being built.
var/queued_p_type = p_type
var/queued_p_dir = p_dir
var/queued_p_flipped = p_flipped
. = FALSE
switch(p_class)
if(PAINT_MODE) // Paint pipes
if(!istype(A,/obj/machinery/atmospherics/pipe))
// Avoid spewing errors about invalid mode -2 when clicking on stuff that aren't pipes.
user << "<span class='warning'>\The [src]'s error light flickers! Perhaps you need to only use it on pipes and pipe meters?</span>"
return 0
return
var/obj/machinery/atmospherics/pipe/P = A
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
P.add_atom_colour(paint_colors[paint_color], FIXED_COLOUR_PRIORITY)
@@ -547,25 +541,23 @@ var/global/list/RPD_recipes=list(
user.visible_message("<span class='notice'>[user] paints \the [P] [paint_color].</span>","<span class='notice'>You paint \the [P] [paint_color].</span>")
//P.update_icon()
P.update_node_icon()
return 1
return
if(EATING_MODE) // Eating pipes
// Must click on an actual pipe or meter.
if(istype(A,/obj/item/pipe) || istype(A,/obj/item/pipe_meter) || istype(A,/obj/structure/disposalconstruct))
user << "<span class='notice'>You start destroying pipe...</span>"
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 2, target = A))
activate()
qdel(A)
return 1
return 0
if(!(istype(A,/obj/item/pipe) || istype(A,/obj/item/pipe_meter) || istype(A,/obj/structure/disposalconstruct)))
// Avoid spewing errors about invalid mode -1 when clicking on stuff that aren't pipes.
user << "<span class='warning'>The [src]'s error light flickers! Perhaps you need to only use it on pipes and pipe meters?</span>"
return
user << "<span class='notice'>You start destroying pipe...</span>"
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 2, target = A))
activate()
qdel(A)
// Avoid spewing errors about invalid mode -1 when clicking on stuff that aren't pipes.
user << "<span class='warning'>The [src]'s error light flickers! Perhaps you need to only use it on pipes and pipe meters?</span>"
return 0
if(ATMOS_MODE)
if(!isturf(A))
user << "<span class='warning'>The [src]'s error light flickers!</span>"
return 0
return
user << "<span class='notice'>You start building pipes...</span>"
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 2, target = A))
@@ -574,8 +566,6 @@ var/global/list/RPD_recipes=list(
P.flipped = queued_p_flipped
P.update()
P.add_fingerprint(usr)
return 1
return 0
if(METER_MODE)
if(!isturf(A))
@@ -586,13 +576,11 @@ var/global/list/RPD_recipes=list(
if(do_after(user, 2, target = A))
activate()
new /obj/item/pipe_meter(A)
return 1
return 0
if(DISPOSALS_MODE)
if(!isturf(A) || is_anchored_dense_turf(A))
user << "<span class='warning'>The [src]'s error light flickers!</span>"
return 0
return
user << "<span class='notice'>You start building pipes...</span>"
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 20, target = A))
@@ -601,17 +589,16 @@ var/global/list/RPD_recipes=list(
if(!C.can_place())
user << "<span class='warning'>There's not enough room to build that here!</span>"
qdel(C)
return 0
return
activate()
C.add_fingerprint(usr)
C.update_icon()
return 1
return 0
return
else
..()
return 0
return ..()
/obj/item/weapon/pipe_dispenser/proc/activate()
@@ -29,8 +29,8 @@
M.visible_message("<span class='warning'>[user] is attemping to implant [M].</span>")
var/turf/T = get_turf(M)
if(T && (M == user || do_after(user, 50)))
if(user && M && (get_turf(M) == T) && src && imp)
if(T && (M == user || do_mob(user, M, 50)))
if(src && imp)
if(imp.implant(M, user))
if (M == user)
user << "<span class='notice'>You implant yourself.</span>"
@@ -527,7 +527,7 @@
/obj/item/weapon/storage/handle_atom_del(atom/A)
if(A in contents)
usr = null
remove_from_storage(A, loc)
remove_from_storage(A, null)
/obj/item/weapon/storage/contents_explosion(severity, target)
for(var/atom/A in contents)
@@ -134,3 +134,239 @@
/obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/admin
slab_type = /obj/item/clockwork/slab/debug
proselytizer_type = /obj/item/clockwork/clockwork_proselytizer/scarab/debug
/obj/item/weapon/storage/toolbox/artistic
name = "artistic toolbox"
desc = "A toolbox painted bright green. Why anyone would store art supplies in a toolbox is beyond you, but it has plenty of extra space."
icon_state = "green"
item_state = "artistic_toolbox"
max_combined_w_class = 20
storage_slots = 10
w_class = 5 //Holds more than a regular toolbox!
/obj/item/weapon/storage/toolbox/artistic/New()
..()
new/obj/item/weapon/storage/crayons(src)
new/obj/item/weapon/crowbar(src)
new/obj/item/stack/cable_coil/red(src)
new/obj/item/stack/cable_coil/yellow(src)
new/obj/item/stack/cable_coil/blue(src)
new/obj/item/stack/cable_coil/green(src)
new/obj/item/stack/cable_coil/pink(src)
new/obj/item/stack/cable_coil/orange(src)
new/obj/item/stack/cable_coil/cyan(src)
new/obj/item/stack/cable_coil/white(src)
#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep.
#define HIS_GRACE_PECKISH 30 //Slightly hungry. Slightly increased damage and nothing else.
#define HIS_GRACE_HUNGRY 60 //Getting closer. Increased danage and slight healing. It also starts eating anyone around it if it's left on the ground.
#define HIS_GRACE_FAMISHED 90 //Dangerous. Highly increased damage, good healing, and stun resist. It also becomes nodrop at this point.
#define HIS_GRACE_STARVING 110 //Incredibly close to breaking loose. Extreme damage and healing, and stun immunity.
#define HIS_GRACE_CONSUME_OWNER 120 //You're dead, kiddo. The toolbox consumes its owner at this point and resets to zero.
#define HIS_GRACE_FALL_ASLEEP 150 //If it reaches this point, it falls asleep and resets to zero.
//His Grace is a very special weapon granted only to traitor chaplains.
//When awakened through sacrifice, it thirsts for blood and begins ticking a "bloodthirst" counter.
//As His Grace grows hungrier, it grants its wielder various benefits.
//If the wielder fails to feed His Grace in time, it will devour them.
//Leaving His Grace alone for some time will reset its timer and put it to sleep.
//Using His Grace effectively is a delicate balancing act of keeping it hungry enough to induce benefits but sated enough to let you live.
/obj/item/weapon/storage/toolbox/artistic/his_grace
name = "artistic toolbox"
desc = "A toolbox painted bright green. Looking at it makes you feel uneasy."
origin_tech = "combat=4;engineering=4;syndicate=2"
var/awakened = 0
var/bloodthirst = HIS_GRACE_SATIATED
var/victims = 0
var/list/warning_messages = list("peckish", "hungry", "famished", "starving", "consume") //Messages that have NOT been shown
/obj/item/weapon/storage/toolbox/artistic/his_grace/Destroy()
for(var/mob/living/L in src)
L.forceMove(get_turf(src))
return ..()
/obj/item/weapon/storage/toolbox/artistic/his_grace/attack_self(mob/living/user)
if(!awakened)
user << "<span class='notice'>[src] begins to vibrate...</span>"
addtimer(CALLBACK(src, .proc/awaken), 50)
/obj/item/weapon/storage/toolbox/artistic/his_grace/attack(mob/living/M, mob/user)
if(awakened && M.stat)
consume(M)
else
..()
/obj/item/weapon/storage/toolbox/artistic/his_grace/examine(mob/user)
..()
if(awakened)
if(victims)
user << "You hear the distant murmuring of [victims] victims to [src]."
switch(bloodthirst)
if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH)
user << "<span class='danger'>[src] isn't very hungry. Not yet.</span>"
if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY)
user << "<span class='danger'>[src] would like a snack.</span>"
if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED)
user << "<span class='warning'>[src] is quite hungry now...</span>"
if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING)
user << "<span class='boldannounce'>[src] is openly salivating at the sight of you. Be careful.</span>"
if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER)
user << "<span class='boldwarning'>You walk a fine line. [src] is very close to devouring you.</span>"
if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP)
user << "<span class='boldwarning'>[src] is shaking violently and staring directly at you.</span>"
/obj/item/weapon/storage/toolbox/artistic/his_grace/relaymove(mob/living/user) //Allows changelings, etc. to climb out of the box after they revive
user.forceMove(get_turf(src))
user.visible_message("<span class='warning'>[user] scrambles out of [src]!</span>", "<span class='notice'>You climb out of [src]!</span>")
/obj/item/weapon/storage/toolbox/artistic/his_grace/process()
if(!awakened)
return
adjust_bloodthirst(1 + victims) //Maybe adjust this?
change_phases()
if(ishuman(loc))
var/mob/living/carbon/human/master = loc
switch(bloodthirst) //Handles benefits outside of stun absorbs, which are in change_phases()
if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED)
master.adjustBruteLoss(-1)
master.adjustFireLoss(-1)
master.adjustToxLoss(-0.5)
master.adjustOxyLoss(-5)
master.adjustCloneLoss(-0.5)
if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING)
master.adjustBruteLoss(-2)
master.adjustFireLoss(-2)
master.adjustToxLoss(-1)
master.adjustOxyLoss(-10)
master.adjustCloneLoss(-1)
master.AdjustStunned(-1)
master.AdjustWeakened(-1)
if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER)
master.adjustBruteLoss(-20) //The biggest danger at this point is the toolbox itself
master.adjustFireLoss(-20)
master.adjustToxLoss(-10)
master.setOxyLoss(0)
master.adjustCloneLoss(-5)
master.add_stun_absorption("his_grace", 15, 1, null, null, "[src] shields them from harm!")
if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP)
master.visible_message("<span class='boldwarning'>[src] turns on its master!</span>", "<span class='userdanger'>[src] turns on you!</span>")
playsound(src, 'sound/effects/tendril_destroyed.ogg', 100, 0)
master.Weaken(3)
master.adjustBruteLoss(100)
playsound(master, 'sound/misc/desceration-03.ogg', 100, )
playsound(master, 'sound/effects/splat.ogg', 100, 0)
master.emote("scream")
consume(master) //Y O U H A V E F A I L E D M E
if(HIS_GRACE_FALL_ASLEEP to INFINITY)
drowse()
else
if(bloodthirst >= HIS_GRACE_CONSUME_OWNER)
if(bloodthirst >= HIS_GRACE_FALL_ASLEEP)
drowse()
return
for(var/mob/living/L in range(1, src))
if(L.loc == src)
continue
if(!L.stat)
L.visible_message("<span class='warning'>[src] lunges at [L]!</span>", "<span class='userdanger'>[src] lunges at you!</span>")
playsound(L, 'sound/effects/splat.ogg', 50, 1)
playsound(L, 'sound/misc/desceration-01.ogg', 50, 1)
L.adjustBruteLoss(force)
return //Only one at a tome
else
consume(L)
return
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/awaken() //Attempts to awaken. This can only occur if organs fill the box, and gives out a global warning.
if(awakened)
return
var/organ_count = 0
for(var/obj/item/organ/O in src) //Doesn't have to be any kind, we're not picky
organ_count++
if(organ_count < 5)
if(isliving(loc))
loc = get_turf(src)
visible_message("<span class='warning'>[src] stops shaking. It needs more organs.</span>")
else
for(var/obj/item/organ/O in src)
qdel(O) //delicious flesh
name = "His Grace"
desc = "A bloodthirsty artefact created by a profane rite."
gender = MALE
visible_message("<span class='boldwarning'>[src] begins to rattle. It thirsts.</span>") //rattle me bones capn
adjust_bloodthirst(1)
awakened = 1
send_to_playing_players("<span class='boldannounce'><font size=6>HIS GRACE THIRSTS FOR BLOOD</font></span>")
send_to_playing_players('sound/effects/his_grace_awaken.ogg')
icon_state = "green_awakened"
START_PROCESSING(SSprocessing, src)
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/drowse() //Falls asleep, spitting out all victims and resetting to zero.
if(!awakened)
return
visible_message("<span class='boldwarning'>[src] slowly stops rattling and falls still... but it still lurks in its sleep.</span>")
name = initial(name)
desc = initial(desc)
icon_state = initial(icon_state)
gender = initial(gender)
awakened = 0
victims = 0
warning_messages = initial(warning_messages)
adjust_bloodthirst(-bloodthirst)
STOP_PROCESSING(SSprocessing, src)
send_to_playing_players("<span class='boldannounce'><font size=6>HIS GRACE HAS RETURNED TO SLUMBER</font></span>")
send_to_playing_players('sound/effects/pope_entry.ogg')
for(var/mob/living/L in src)
L.forceMove(get_turf(src))
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/adjust_bloodthirst(amt)
bloodthirst = min(max(1, bloodthirst + amt), HIS_GRACE_FALL_ASLEEP)
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/consume(mob/living/meal)
if(!meal)
return
meal.adjustBruteLoss(200)
meal.visible_message("<span class='warning'>[src] pulls [meal] into itself!</span>", "<span class='userdanger'>[src] consumes you!</span>")
playsound(meal, 'sound/misc/desceration-02.ogg', 75, 1)
playsound(src, 'sound/items/eatfood.ogg', 100, 1)
meal.forceMove(src)
adjust_bloodthirst(-(bloodthirst - victims)) //Never fully sated, and it starts off higher as it eats
victims++
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/change_phases()
switch(bloodthirst)
if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH)
force = 15 //Constantly keep its power low if it's this full
if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY)
if(is_string_in_list("peckish", warning_messages))
remove_strings_from_list("peckish", warning_messages)
loc.visible_message("<span class='warning'>[src] is feeling snackish.</span>", "<span class='danger'>[src] begins to hunger. Its damage has been increased.</span>")
force = 20
spawn(400) //To prevent spam
if(src)
warning_messages += "peckish"
if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED)
if(is_string_in_list("hungry", warning_messages))
remove_strings_from_list("hungry", warning_messages)
loc.visible_message("<span class='warning'>[src] is getting hungry. Its power grows.</span>", "<span class='boldannounce'>You feel a sense of hunger come over you. [src]'s damage has increased.</span>")
force = 25
spawn(400)
if(src)
warning_messages += "hungry"
if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING)
if(is_string_in_list("famished", warning_messages))
remove_strings_from_list("famished", warning_messages)
loc.visible_message("<span class='warning'>[src] is very hungry...</span>", "<span class='boldwarning'>Bloodlust overcomes you. You are now resistant to stuns.</span>")
force = 30
spawn(400)
if(src)
warning_messages += "famished"
if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER)
if(is_string_in_list("starving", warning_messages))
remove_strings_from_list("starving", warning_messages)
loc.visible_message("<span class='boldwarning'>[src] is starving!</span>", "<span class='userdanger'>[src] is at its full power! Feed it quickly or you will be consumed!</span>")
force = 40
spawn(400)
if(src)
warning_messages += "starving"
@@ -148,7 +148,7 @@ Frequency:
for(var/obj/machinery/computer/teleporter/com in machines)
if(com.target)
var/area/A = get_area(com.target)
if(A.noteleport)
if(!A || A.noteleport)
continue
if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged)
L["[get_area(com.target)] (Active)"] = com.target
+1 -3
View File
@@ -106,9 +106,7 @@
/obj/structure/proc/examine_status(mob/user) //An overridable proc, mostly for falsewalls.
var/healthpercent = (obj_integrity/max_integrity) * 100
switch(healthpercent)
if(100 to INFINITY)
return "It seems pristine and undamaged."
if(50 to 100)
if(50 to 99)
return "It looks slightly damaged."
if(25 to 50)
return "It appears heavily damaged."
@@ -57,7 +57,7 @@
/obj/structure/closet/wardrobe/green/New()
..()
contents = list()
for(var/i in 1 to 3)
for(var/i in 1 to 3)
new /obj/item/clothing/under/color/green(src)
for(var/i in 1 to 3)
new /obj/item/clothing/shoes/sneakers/black(src)
@@ -174,14 +174,10 @@
new /obj/item/clothing/under/color/orange(src)
new /obj/item/clothing/under/color/pink(src)
new /obj/item/clothing/under/color/red(src)
new /obj/item/clothing/under/color/lightblue(src)
new /obj/item/clothing/under/color/aqua(src)
new /obj/item/clothing/under/color/purple(src)
new /obj/item/clothing/under/color/lightpurple(src)
new /obj/item/clothing/under/color/lightgreen(src)
new /obj/item/clothing/under/color/darkblue(src)
new /obj/item/clothing/under/color/darkred(src)
new /obj/item/clothing/under/color/lightred(src)
new /obj/item/clothing/under/color/teal(src)
new /obj/item/clothing/under/color/lightpurple(src)
new /obj/item/clothing/under/color/green(src)
new /obj/item/clothing/mask/bandana/red(src)
new /obj/item/clothing/mask/bandana/red(src)
new /obj/item/clothing/mask/bandana/blue(src)
@@ -98,6 +98,21 @@
for(var/i in 1 to 3)
new /obj/item/weapon/reagent_containers/blood/random(src)
/obj/structure/closet/crate/freezer/surplus_limbs
name = "surplus prosthetic limbs"
desc = "A crate containing an assortment of cheap prosthetic limbs."
/obj/structure/closet/crate/freezer/surplus_limbs/New()
. = ..()
new /obj/item/bodypart/l_arm/robot/surplus(src)
new /obj/item/bodypart/l_arm/robot/surplus(src)
new /obj/item/bodypart/r_arm/robot/surplus(src)
new /obj/item/bodypart/r_arm/robot/surplus(src)
new /obj/item/bodypart/l_leg/robot/surplus(src)
new /obj/item/bodypart/l_leg/robot/surplus(src)
new /obj/item/bodypart/r_leg/robot/surplus(src)
new /obj/item/bodypart/r_leg/robot/surplus(src)
/obj/structure/closet/crate/radiation
desc = "A crate with a radiation sign on it."
name = "radiation crate"
+1 -1
View File
@@ -481,7 +481,7 @@
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/monkeycube))
var/obj/item/weapon/reagent_containers/food/snacks/monkeycube/M = O
user << "<span class='notice'>You place [src] under a stream of water...</span>"
user << "<span class='notice'>You place [O] under a stream of water...</span>"
user.drop_item()
M.loc = get_turf(src)
M.Expand()
+5 -5
View File
@@ -1,4 +1,4 @@
/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, surround = 1)
/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, surround = 1, frequency = null)
soundin = get_sfx(soundin) // same sound for everyone
@@ -6,7 +6,8 @@
throw EXCEPTION("playsound(): source is an area")
return
var/frequency = get_rand_frequency() // Same frequency for everybody
if(isnull(frequency))
frequency = get_rand_frequency() // Same frequency for everybody
var/turf/turf_source = get_turf(source)
// Looping through the player list has the added bonus of working for mobs inside containers
@@ -121,7 +122,7 @@
soundin = pick('sound/machines/terminal_button01.ogg', 'sound/machines/terminal_button02.ogg', 'sound/machines/terminal_button03.ogg', \
'sound/machines/terminal_button04.ogg', 'sound/machines/terminal_button05.ogg', 'sound/machines/terminal_button06.ogg', \
'sound/machines/terminal_button07.ogg', 'sound/machines/terminal_button08.ogg')
/* //Scream emote sounds //when they get ported again
/* //Scream emote sounds //when they get ported again
if ("malescream")
soundin = pick('sound/voice/scream/scream_m1.ogg', 'sound/voice/scream/scream_m2.ogg')
if ("femscream")
@@ -132,7 +133,7 @@
soundin = pick('sound/voice/scream/bird1.ogg', 'sound/voice/scream/bird2.ogg')
if ("mothscream")
soundin = pick('sound/voice/scream/moth1.ogg')
*/
*/
//Vore sounds
if ("digestion_sounds")
soundin = pick('sound/vore/digest1.ogg', 'sound/vore/digest2.ogg', 'sound/vore/digest3.ogg', \
@@ -145,7 +146,6 @@
'sound/vore/death7.ogg', 'sound/vore/death8.ogg', 'sound/vore/death9.ogg', 'sound/vore/death10.ogg')
if ("struggle_sounds")
soundin = pick('sound/vore/squish1.ogg', 'sound/vore/squish2.ogg', 'sound/vore/squish3.ogg', 'sound/vore/squish4.ogg')
return soundin
/proc/playsound_global(file, repeat=0, wait, channel, volume)
+13 -2
View File
@@ -21,9 +21,14 @@
var/explosion_level = 0 //for preventing explosion dodging
var/explosion_id = 0
var/list/decals
/turf/SDQL_update(const/var_name, new_value)
if(var_name == "x" || var_name == "y" || var_name == "z")
return FALSE
. = ..()
/turf/New()
..()
@@ -189,7 +194,6 @@
W.explosion_level = old_ex_level
W.explosion_id = old_ex_id
if(!defer_change)
W.AfterChange(ignore_air)
W.blueprint_data = old_blueprint_data
@@ -203,6 +207,13 @@
for(var/obj/structure/cable/C in contents)
C.deconstruct()
//update firedoor adjacency
var/list/turfs_to_check = get_adjacent_open_turfs(src) | src
for(var/I in turfs_to_check)
var/turf/T = I
for(var/obj/machinery/door/firedoor/FD in T)
FD.CalculateAffectingAreas()
queue_smooth_neighbors(src)
/turf/open/AfterChange(ignore_air)
+4
View File
@@ -826,3 +826,7 @@ var/global/BSACooldown = 0
"Admin login: [key_name(src)]")
if(string)
message_admins("[string]")
/datum/admins/SDQL_update()
return FALSE //No.
+3
View File
@@ -6,6 +6,9 @@ var/list/admin_ranks = list() //list of all admin_rank datums
var/list/adds
var/list/subs
/datum/admin_rank/SDQL_update()
return FALSE //Nice try trivialadmin!
/datum/admin_rank/New(init_name, init_rights, list/init_adds, list/init_subs)
name = init_name
switch(name)
-7
View File
@@ -130,13 +130,6 @@
dat += "[ckey] - [D.rank.name]<br>"
usr << browse(dat, "window=showadmins;size=600x500")
if("show_current_watchlist")
var/dat = "<B>Watchlist: </B><HR>"
if(current_watchlist)
for(var/ckey in current_watchlist)
dat += "[ckey] - [current_watchlist[ckey]]"
usr << browse(dat, "window=showcurrentwatchlist;size=600x500")
if("tdomereset")
if(!check_rights(R_ADMIN))
return
+25 -8
View File
@@ -154,7 +154,7 @@
message_admins("[key_name_admin(usr)] has toggled [target_ckey]'s [type] made by [admin_ckey] to [secret ? "not secret" : "secret"]")
browse_messages(target_ckey = target_ckey)
/proc/browse_messages(type, target_ckey, index, linkless = 0)
/proc/browse_messages(type, target_ckey, index, linkless = 0, filter)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
@@ -176,7 +176,11 @@
output += "<a href='?_src_=holder;addmemo=1'>\[Add memo\]</a></center>"
else if(type == "watchlist entry")
output += "<h2><center>Watchlist entries</h2>"
output += "<a href='?_src_=holder;addwatchempty=1'>\[Add watchlist entry\]</a></center>"
output += "<a href='?_src_=holder;addwatchempty=1'>\[Add watchlist entry\]</a>"
if(filter)
output += "|<a href='?_src_=holder;showwatch=1'>\[Unfilter clients\]</a></center>"
else
output += "|<a href='?_src_=holder;showwatchfilter=1'>\[Filter offline clients\]</a></center>"
output += ruler
var/DBQuery/query_get_type_messages = dbcon.NewQuery("SELECT id, targetckey, adminckey, text, timestamp, server, lasteditor FROM [format_table_name("messages")] WHERE type = '[type]'")
if(!query_get_type_messages.Execute())
@@ -186,6 +190,8 @@
while(query_get_type_messages.NextRow())
var/id = query_get_type_messages.item[1]
var/t_ckey = query_get_type_messages.item[2]
if(type == "watchlist entry" && filter && !(t_ckey in directory))
continue
var/admin_ckey = query_get_type_messages.item[3]
var/text = query_get_type_messages.item[4]
var/timestamp = query_get_type_messages.item[5]
@@ -229,13 +235,20 @@
data += " <a href='?_src_=holder;deletemessage=[id]'>\[Delete\]</a>"
if(type == "note")
data += " <a href='?_src_=holder;secretmessage=[id]'>[secret ? "<b>\[Secret\]</b>" : "\[Not secret\]"]</a>"
data += " <a href='?_src_=holder;editmessage=[id]'>\[Edit\]</a>"
if(type == "message sent")
data += " <font size='2'>Message has been sent</font>"
if(editor_ckey)
data += "|"
else
data += " <a href='?_src_=holder;editmessage=[id]'>\[Edit\]</a>"
if(editor_ckey)
data += " <font size='2'>Last edit by [editor_ckey] <a href='?_src_=holder;messageedits=[id]'>(Click here to see edit log)</a></font>"
data += "<br>[text]<hr style='background:#000000; border:0; height:1px'>"
switch(type)
if("message")
messagedata += data
if("message sent")
messagedata += data
if("watchlist entry")
watchdata += data
if("note")
@@ -303,7 +316,7 @@ proc/get_message_output(type, target_ckey)
log_game("SQL ERROR obtaining id, adminckey, text, timestamp, lasteditor from messages table. Error : \[[err]\]\n")
return
while(query_get_message_output.NextRow())
var/id = query_get_message_output.item[1]
var/message_id = query_get_message_output.item[1]
var/admin_ckey = query_get_message_output.item[2]
var/text = query_get_message_output.item[3]
var/timestamp = query_get_message_output.item[4]
@@ -311,15 +324,19 @@ proc/get_message_output(type, target_ckey)
switch(type)
if("message")
output += "<font color='red' size='3'><b>Admin message left by <span class='prefix'>[admin_ckey]</span> on [timestamp]</b></font>"
output += "<br><font color='red'>[text]</font>"
delete_message(id, 0)
output += "<br><font color='red'>[text]</font><br>"
var/DBQuery/query_message_read = dbcon.NewQuery("UPDATE [format_table_name("messages")] SET type = 'message sent' WHERE id = [message_id]")
if(!query_message_read.Execute())
var/err = query_message_read.ErrorMsg()
log_game("SQL ERROR updating message type. Error : \[[err]\]\n")
return
if("watchlist entry")
message_admins("<font color='red'><B>Notice: </B></font><font color='blue'>[key_name_admin(target_ckey)] is on the watchlist and has just connected - Reason: [text]</font>")
send2admindiscord("Watchlist", "[key_name(target_ckey)] is on the watchlist and has just connected - Reason: [text]")
if("memo")
output += "<span class='memo'>Memo by <span class='prefix'>[admin_ckey]</span> on [timestamp]"
if(editor_ckey)
output += "<br><span class='memoedit'>Last edit by [editor_ckey] <A href='?_src_=holder;messageedits=[id]'>(Click here to see edit log)</A></span>"
output += "<br><span class='memoedit'>Last edit by [editor_ckey] <A href='?_src_=holder;messageedits=[message_id]'>(Click here to see edit log)</A></span>"
output += "<br>[text]</span><br>"
return output
@@ -368,4 +385,4 @@ this proc can take several minutes to execute fully if converting and cause DD t
world << "Deleting NOTESFILE"
fdel(NOTESFILE)
world << "Finished mass note conversion, remember to turn off AUTOCONVERT_NOTES"*/
#undef NOTESFILE
#undef NOTESFILE
+35 -2
View File
@@ -1131,6 +1131,9 @@
else if(href_list["showwatch"])
browse_messages("watchlist entry")
else if(href_list["showwatchfilter"])
browse_messages("watchlist entry", filter = 1)
else if(href_list["showmessageckey"])
var/target = href_list["showmessageckey"]
browse_messages(target_ckey = target)
@@ -1744,12 +1747,42 @@
H << "<span class='adminnotice'>Your prayers have been answered!! You received the <b>best cookie</b>!</span>"
H << 'sound/effects/pray_chaplain.ogg'
else if(href_list["adminsmite"])
if(!check_rights(R_ADMIN|R_FUN))
return
var/mob/living/carbon/human/H = locate(href_list["adminsmite"]) in mob_list
if(!H || !istype(H))
return
var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB)
var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
if(QDELETED(H) || !punishment)
return
switch(punishment)
if(ADMIN_PUNISHMENT_LIGHTNING)
var/turf/T = get_step(get_step(H, NORTH), NORTH)
T.Beam(H, icon_state="lightning[rand(1,12)]", time = 5)
H.adjustFireLoss(75)
H.electrocution_animation(40)
H << "<span class='userdanger'>The gods have punished you for your sins!</span>"
if(ADMIN_PUNISHMENT_BRAINDAMAGE)
H.adjustBrainLoss(75)
if(ADMIN_PUNISHMENT_GIB)
H.gib(FALSE)
message_admins("[key_name_admin(usr)] punished [key_name_admin(H)] with [punishment].")
log_admin("[key_name(usr)] punished [key_name(H)] with [punishment].")
else if(href_list["BlueSpaceArtillery"])
var/mob/living/M = locate(href_list["BlueSpaceArtillery"])
var/mob/living/M = locate(href_list["BlueSpaceArtillery"]) in mob_list
usr.client.bluespace_artillery(M)
else if(href_list["CentcommReply"])
var/mob/living/carbon/human/H = locate(href_list["CentcommReply"])
var/mob/living/carbon/human/H = locate(href_list["CentcommReply"]) in mob_list
if(!istype(H))
usr << "This can only be used on instances of type /mob/living/carbon/human"
return
+138 -100
View File
@@ -18,11 +18,22 @@
*/
/datum/proc/SDQL_update(const/var_name, new_value)
vars[var_name] = new_value
return TRUE
/client/proc/SDQL2_query(query_text as message)
set category = "Debug"
if(!check_rights(R_DEBUG)) //Shouldn't happen... but just to be safe.
message_admins("<span class='danger'>ERROR: Non-admin [key_name(usr, usr.client)] attempted to execute a SDQL query!</span>")
log_admin("Non-admin [usr.ckey]([usr]) attempted to execute a SDQL query!")
return FALSE
var/query_log = "executed SDQL query: \"[query_text]\"."
message_admins("[key_name_admin(usr)] [query_log]")
query_log = "[usr.ckey]([usr]) [query_log]"
log_game(query_log)
NOTICE(query_log)
if(!query_text || length(query_text) < 1)
return
@@ -39,119 +50,122 @@
if(!querys || querys.len < 1)
return
try
var/query_log = "executed SDQL query: \"[query_text]\"."
message_admins("[key_name_admin(usr)] [query_log]")
query_log = "[usr.ckey]([usr]) [query_log]"
log_game(query_log)
NOTICE(query_log)
for(var/list/query_tree in querys)
var/list/from_objs = list()
var/list/select_types = list()
for(var/list/query_tree in querys)
var/list/from_objs = list()
var/list/select_types = list()
switch(query_tree[1])
if("explain")
SDQL_testout(query_tree["explain"])
return
if("call")
if("on" in query_tree)
select_types = query_tree["on"]
else
switch(query_tree[1])
if("explain")
SDQL_testout(query_tree["explain"])
return
if("select", "delete", "update")
select_types = query_tree[query_tree[1]]
if("call")
if("on" in query_tree)
select_types = query_tree["on"]
else
return
from_objs = SDQL_from_objs(query_tree["from"])
if("select", "delete", "update")
select_types = query_tree[query_tree[1]]
var/list/objs = list()
from_objs = SDQL_from_objs(query_tree["from"])
for(var/type in select_types)
var/char = copytext(type, 1, 2)
var/list/objs = list()
if(char == "/" || char == "*")
for(var/from in from_objs)
objs += SDQL_get_all(type, from)
CHECK_TICK
for(var/type in select_types)
var/char = copytext(type, 1, 2)
else if(char == "'" || char == "\"")
objs += locate(copytext(type, 2, length(type)))
if("where" in query_tree)
var/objs_temp = objs
objs = list()
for(var/datum/d in objs_temp)
if(SDQL_expression(d, query_tree["where"]))
objs += d
CHECK_TICK
switch(query_tree[1])
if("call")
var/list/call_list = query_tree["call"]
var/list/args_list = query_tree["args"]
for(var/datum/d in objs)
for(var/v in call_list)
SDQL_callproc(d, v, args_list)
if(char == "/" || char == "*")
for(var/from in from_objs)
objs += SDQL_get_all(type, from)
CHECK_TICK
if("delete")
for(var/datum/d in objs)
qdel(d)
else if(char == "'" || char == "\"")
objs += locate(copytext(type, 2, length(type)))
if("where" in query_tree)
var/objs_temp = objs
objs = list()
for(var/datum/d in objs_temp)
if(SDQL_expression(d, query_tree["where"]))
objs += d
CHECK_TICK
if("select")
var/text = ""
for(var/datum/t in objs)
text += "<A HREF='?_src_=vars;Vars=\ref[t]'>\ref[t]</A>"
if(istype(t, /atom))
var/atom/a = t
switch(query_tree[1])
if("call")
var/list/call_list = query_tree["call"]
var/list/args_list = query_tree["args"]
if(a.x)
text += ": [t] at ([a.x], [a.y], [a.z])<br>"
for(var/datum/d in objs)
var/list/new_args = list()
for(var/a in args_list)
new_args += SDQL_expression(d,a)
for(var/v in call_list)
if(copytext(v,1,8) == "global.")
v = "/proc/[copytext(v,8)]"
SDQL_callproc_global(v,new_args)
else
SDQL_callproc(d, v, new_args)
CHECK_TICK
else if(a.loc && a.loc.x)
text += ": [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])<br>"
if("delete")
for(var/datum/d in objs)
qdel(d)
CHECK_TICK
if("select")
var/text = ""
for(var/datum/t in objs)
text += "<A HREF='?_src_=vars;Vars=\ref[t]'>\ref[t]</A>"
if(istype(t, /atom))
var/atom/a = t
if(a.x)
text += ": [t] at ([a.x], [a.y], [a.z])<br>"
else if(a.loc && a.loc.x)
text += ": [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])<br>"
else
text += ": [t]<br>"
else
text += ": [t]<br>"
else
text += ": [t]<br>"
CHECK_TICK
usr << browse(text, "window=SDQL-result")
if("update")
if("set" in query_tree)
var/list/set_list = query_tree["set"]
for(var/datum/d in objs)
var/list/vals = list()
for(var/v in set_list)
if(v in d.vars)
vals += v
vals[v] = SDQL_expression(d, set_list[v])
if(isturf(d))
for(var/v in vals)
if(v == "x" || v == "y" || v == "z")
continue
d.vars[v] = vals[v]
else
for(var/v in vals)
d.vars[v] = vals[v]
CHECK_TICK
usr << browse(text, "window=SDQL-result")
if("update")
if("set" in query_tree)
var/list/set_list = query_tree["set"]
for(var/datum/d in objs)
for(var/list/sets in set_list)
var/datum/temp = d
var/i = 0
for(var/v in sets)
if(++i == sets.len)
temp.SDQL_update(v, SDQL_expression(d, set_list[sets]))
break
if(temp.vars.Find(v) && (istype(temp.vars[v], /datum)))
temp = temp.vars[v]
else
break
CHECK_TICK
catch(var/exception/e)
usr << "<span class='boldwarning'>A runtime error has occured in your SDQL2-query.</span>"
usr << "\[NAME\][e.name]"
usr << "\[FILE\][e.file]"
usr << "\[LINE\][e.line]"
/proc/SDQL_callproc_global(procname,args_list)
set waitfor = FALSE
call(procname)(arglist(args_list))
/proc/SDQL_callproc(thing, procname, args_list)
set waitfor = 0
set waitfor = FALSE
if(hascall(thing, procname))
call(thing, procname)(arglist(args_list))
@@ -248,7 +262,7 @@
type = text2path(type)
var/typecache = typecacheof(type)
if(ispath(type, /mob))
for(var/mob/d in location)
if(typecache[d.type])
@@ -382,6 +396,12 @@
else if(copytext(expression[i], 1, 2) in list("'", "\""))
val = copytext(expression[i], 2, length(expression[i]))
else if(expression[i] == "\[")
var/list/expressions_list = expression[++i]
var/list/val2 = list()
for(var/list/expression_list in expressions_list)
val2[++val2.len] = SDQL_expression(object, expression_list)
val = val2
else
val = SDQL_var(object, expression, i)
i = expression.len
@@ -389,22 +409,40 @@
return list("val" = val, "i" = i)
/proc/SDQL_var(datum/object, list/expression, start = 1)
var/v
if(expression[start] in object.vars)
if(start < expression.len && expression[start + 1] == ".")
return SDQL_var(object.vars[expression[start]], expression[start + 2])
else
return object.vars[expression[start]]
v = object.vars[expression[start]]
else if(expression[start] == "{" && start < expression.len)
if(lowertext(copytext(expression[start + 1], 1, 3)) != "0x")
usr << "<span class='danger'>Invalid pointer syntax: [expression[start + 1]]</span>"
return null
v = locate("\[[expression[start + 1]]]")
if(!v)
usr << "<span class='danger'>Invalid pointer: [expression[start + 1]]</span>"
return null
start++
else
return null
switch(expression[start])
if("usr")
v = usr
if("src")
v = object
if("marked")
if(usr.client && usr.client.holder && usr.client.holder.marked_datum)
v = usr.client.holder.marked_datum
else
return null
else
return null
if(start < expression.len && expression[start + 1] == ".")
return SDQL_var(v, expression[start + 2])
else
return v
/proc/SDQL2_tokenize(query_text)
var/list/whitespace = list(" ", "\n", "\t")
var/list/single = list("(", ")", ",", "+", "-", ".", ";")
var/list/single = list("(", ")", ",", "+", "-", ".", ";", "{", "}", "\[", "]")
var/list/multi = list(
"=" = list("", "="),
"<" = list("", "=", ">"),
+297 -395
View File
@@ -57,13 +57,9 @@
var/list/binary_operators = list("+", "-", "/", "*", "&", "|", "^")
var/list/comparitors = list("=", "==", "!=", "<>", "<", "<=", ">", ">=")
/datum/SDQL_parser/New(query_list)
query = query_list
/datum/SDQL_parser/proc/parse_error(error_message)
error = 1
usr << "<span class='danger'>SQDL2 Parsing Error: [error_message]</span>"
@@ -96,448 +92,354 @@
return lowertext(token(i))
/datum/SDQL_parser/proc
//query: select_query | delete_query | update_query
query(i, list/node)
query_type = tokenl(i)
switch(query_type)
if("select")
select_query(i, node)
if("delete")
delete_query(i, node)
if("update")
update_query(i, node)
if("call")
call_query(i, node)
if("explain")
node += "explain"
node["explain"] = list()
query(i + 1, node["explain"])
/datum/SDQL_parser/proc/query(i, list/node)
query_type = tokenl(i)
switch(query_type)
if("select")
select_query(i, node)
if("delete")
delete_query(i, node)
if("update")
update_query(i, node)
if("call")
call_query(i, node)
if("explain")
node += "explain"
node["explain"] = list()
query(i + 1, node["explain"])
// select_query: 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
select_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
node += "select"
node["select"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
return i
/datum/SDQL_parser/proc/select_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
node += "select"
node["select"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
return i
//delete_query: 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
delete_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
node += "delete"
node["delete"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
return i
/datum/SDQL_parser/proc/delete_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
node += "delete"
node["delete"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
return i
//update_query: 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression]
update_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
node += "update"
node["update"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) != "set")
i = parse_error("UPDATE has misplaced SET")
var/list/set_assignments = list()
i = assignments(i + 1, set_assignments)
node += "set"
node["set"] = set_assignments
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
return i
/datum/SDQL_parser/proc/update_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
node += "update"
node["update"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) != "set")
i = parse_error("UPDATE has misplaced SET")
var/list/set_assignments = list()
i = assignments(i + 1, set_assignments)
node += "set"
node["set"] = set_assignments
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
return i
//call_query: 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]]
call_query(i, list/node)
var/list/func = list()
var/list/arguments = list()
i = call_function(i + 1, func, arguments)
node += "call"
node["call"] = func
node["args"] = arguments
if(tokenl(i) != "on")
return i
var/list/select = list()
i = select_list(i + 1, select)
node += "on"
node["on"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
/datum/SDQL_parser/proc/call_query(i, list/node)
var/list/func = list()
var/list/arguments = list()
i = call_function(i + 1, func, arguments)
node += "call"
node["call"] = func
node["args"] = arguments
if(tokenl(i) != "on")
return i
var/list/select = list()
i = select_list(i + 1, select)
node += "on"
node["on"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
return i
//select_list: select_item [',' select_list]
select_list(i, list/node)
i = select_item(i, node)
if(token(i) == ",")
i = select_list(i + 1, node)
return i
/datum/SDQL_parser/proc/select_list(i, list/node)
i = select_item(i, node)
if(token(i) == ",")
i = select_list(i + 1, node)
return i
//from_list: from_item [',' from_list]
from_list(i, list/node)
i = from_item(i, node)
if(token(i) == ",")
i = from_list(i + 1, node)
return i
/datum/SDQL_parser/proc/from_list(i, list/node)
i = from_item(i, node)
if(token(i) == ",")
i = from_list(i + 1, node)
return i
//assignments: assignment, [',' assignments]
assignments(i, list/node)
i = assignment(i, node)
if(token(i) == ",")
i = assignments(i + 1, node)
return i
/datum/SDQL_parser/proc/assignments(i, list/node)
i = assignment(i, node)
if(token(i) == ",")
i = assignments(i + 1, node)
return i
//select_item: '*' | select_function | object_type
select_item(i, list/node)
if(token(i) == "*")
node += "*"
i++
else if(tokenl(i) in select_functions)
i = select_function(i, node)
else
i = object_type(i, node)
return i
/datum/SDQL_parser/proc/select_item(i, list/node)
if(token(i) == "*")
node += "*"
i++
else if(tokenl(i) in select_functions)
i = select_function(i, node)
else
i = object_type(i, node)
return i
//from_item: 'world' | object_type
from_item(i, list/node)
if(token(i) == "world")
node += "world"
i++
else
i = object_type(i, node)
return i
/datum/SDQL_parser/proc/from_item(i, list/node)
if(token(i) == "world")
node += "world"
i++
else
i = object_type(i, node)
return i
//bool_expression: expression [bool_operator bool_expression]
bool_expression(i, list/node)
var/list/bool = list()
i = expression(i, bool)
node[++node.len] = bool
if(tokenl(i) in boolean_operators)
i = bool_operator(i, node)
i = bool_expression(i, node)
return i
/datum/SDQL_parser/proc/bool_expression(i, list/node)
var/list/bool = list()
i = expression(i, bool)
node[++node.len] = bool
if(tokenl(i) in boolean_operators)
i = bool_operator(i, node)
i = bool_expression(i, node)
return i
//assignment: <variable name> '=' expression
assignment(i, list/node)
node += token(i)
if(token(i + 1) == "=")
var/varname = token(i)
node[varname] = list()
i = expression(i + 2, node[varname])
else
parse_error("Assignment expected, but no = found")
return i
/datum/SDQL_parser/proc/assignment(var/i, var/list/node, var/list/assignment_list = list())
assignment_list += token(i)
if(token(i + 1) == ".")
i = assignment(i + 2, node, assignment_list)
else if(token(i + 1) == "=")
var/exp_list = list()
node[assignment_list] = exp_list
i = expression(i + 2, exp_list)
else
parse_error("Assignment expected, but no = found")
return i
//variable: <variable name> | <variable name> '.' variable
variable(i, list/node)
var/list/L = list(token(i))
node[++node.len] = L
if(token(i + 1) == ".")
L += "."
i = variable(i + 2, L)
else
i++
return i
/datum/SDQL_parser/proc/variable(i, list/node)
var/list/L = list(token(i))
node[++node.len] = L
if(token(i) == "{")
L += token(i+1)
i += 2
if(token(i) != "}")
parse_error("Missing } at end of pointer.")
if(token(i + 1) == ".")
L += "."
i = variable(i + 2, L)
else
i++
return i
//array: '[' expression, expression, ... ']'
/datum/SDQL_parser/proc/array(i, list/node)
if(copytext(token(i), 1, 2) != "\[")
parse_error("Expected an array but found '[token(i)]'")
return i + 1
node += token(i)
var/list/expression_list = list()
if(token(i + 1) != "]")
var/list/temp_expression_list = list()
do
i = expression(i + 1, temp_expression_list)
if(token(i) == ",")
expression_list[++expression_list.len] = temp_expression_list
temp_expression_list = list()
while(token(i) && token(i) != "]")
expression_list[++expression_list.len] = temp_expression_list
else
i++
node[++node.len] = expression_list
return i + 1
//object_type: <type path> | string
object_type(i, list/node)
if(copytext(token(i), 1, 2) == "/")
node += token(i)
else
i = string(i, node)
return i + 1
/datum/SDQL_parser/proc/object_type(i, list/node)
if(copytext(token(i), 1, 2) == "/")
node += token(i)
else
i = string(i, node)
return i + 1
//comparitor: '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
comparitor(i, list/node)
if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">="))
node += token(i)
else
parse_error("Unknown comparitor [token(i)]")
return i + 1
/datum/SDQL_parser/proc/comparitor(i, list/node)
if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">="))
node += token(i)
else
parse_error("Unknown comparitor [token(i)]")
return i + 1
//bool_operator: 'AND' | '&&' | 'OR' | '||'
bool_operator(i, list/node)
if(tokenl(i) in list("and", "or", "&&", "||"))
node += token(i)
else
parse_error("Unknown comparitor [token(i)]")
return i + 1
/datum/SDQL_parser/proc/bool_operator(i, list/node)
if(tokenl(i) in list("and", "or", "&&", "||"))
node += token(i)
else
parse_error("Unknown comparitor [token(i)]")
return i + 1
//string: ''' <some text> ''' | '"' <some text > '"'
string(i, list/node)
if(copytext(token(i), 1, 2) in list("'", "\""))
node += copytext(token(i),2,-1)
else
parse_error("Expected string but found '[token(i)]'")
return i + 1
/datum/SDQL_parser/proc/string(i, list/node)
if(copytext(token(i), 1, 2) in list("'", "\""))
node += copytext(token(i),2,-1)
else
parse_error("Expected string but found '[token(i)]'")
return i + 1
//call_function: <function name> ['(' [arguments] ')']
call_function(i, list/node, list/arguments)
if(length(tokenl(i)))
node += token(i++)
if(token(i) != "(")
parse_error("Expected ( but found '[token(i)]'")
else if(token(i + 1) != ")")
do
i = expression(i + 1, arguments)
if(token(i) == ",")
continue
while(token(i) && token(i) != ")")
else
i++
/datum/SDQL_parser/proc/call_function(i, list/node, list/arguments)
if(length(tokenl(i)))
var/procname = ""
if(token(i) == "global" && token(i+1) == ".")
i += 2
procname = "global."
node += procname + token(i++)
if(token(i) != "(")
parse_error("Expected ( but found '[token(i)]'")
else if(token(i + 1) != ")")
var/list/expression_list_temp = list()
do
i = expression(i + 1, expression_list_temp)
if(token(i) == ",")
arguments[++arguments.len] = expression_list_temp
expression_list_temp = list()
continue
while(token(i) && token(i) != ")")
arguments[++arguments.len] = expression_list_temp
else
parse_error("Expected a function but found nothing")
return i + 1
i++
else
parse_error("Expected a function but found nothing")
return i + 1
//select_function: count_function
select_function(i, list/node)
parse_error("Sorry, function calls aren't available yet")
return i
/datum/SDQL_parser/proc/select_function(i, list/node)
parse_error("Sorry, function calls aren't available yet")
return i
//expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
expression(i, list/node)
if(token(i) in unary_operators)
i = unary_expression(i, node)
else if(token(i) == "(")
var/list/expr = list()
i = expression(i + 1, expr)
if(token(i) != ")")
parse_error("Missing ) at end of expression.")
else
i++
node[++node.len] = expr
/datum/SDQL_parser/proc/expression(i, list/node)
if(token(i) in unary_operators)
i = unary_expression(i, node)
else if(token(i) == "(")
var/list/expr = list()
i = expression(i + 1, expr)
if(token(i) != ")")
parse_error("Missing ) at end of expression.")
else
i = value(i, node)
if(token(i) in binary_operators)
i = binary_operator(i, node)
i = expression(i, node)
else if(token(i) in comparitors)
i = binary_operator(i, node)
var/list/rhs = list()
i = expression(i, rhs)
node[++node.len] = rhs
return i
i++
node[++node.len] = expr
else
i = value(i, node)
if(token(i) in binary_operators)
i = binary_operator(i, node)
i = expression(i, node)
else if(token(i) in comparitors)
i = binary_operator(i, node)
var/list/rhs = list()
i = expression(i, rhs)
node[++node.len] = rhs
return i
//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' )
unary_expression(i, list/node)
/datum/SDQL_parser/proc/unary_expression(i, list/node)
if(token(i) in unary_operators)
var/list/unary_exp = list()
unary_exp += token(i)
i++
if(token(i) in unary_operators)
var/list/unary_exp = list()
unary_exp += token(i)
i++
if(token(i) in unary_operators)
i = unary_expression(i, unary_exp)
else if(token(i) == "(")
var/list/expr = list()
i = expression(i + 1, expr)
if(token(i) != ")")
parse_error("Missing ) at end of expression.")
else
i++
unary_exp[++unary_exp.len] = expr
i = unary_expression(i, unary_exp)
else if(token(i) == "(")
var/list/expr = list()
i = expression(i + 1, expr)
if(token(i) != ")")
parse_error("Missing ) at end of expression.")
else
i = value(i, unary_exp)
node[++node.len] = unary_exp
i++
unary_exp[++unary_exp.len] = expr
else
parse_error("Expected unary operator but found '[token(i)]'")
return i
i = value(i, unary_exp)
node[++node.len] = unary_exp
else
parse_error("Expected unary operator but found '[token(i)]'")
return i
//binary_operator: comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^'
binary_operator(i, list/node)
if(token(i) in (binary_operators + comparitors))
node += token(i)
else
parse_error("Unknown binary operator [token(i)]")
return i + 1
/datum/SDQL_parser/proc/binary_operator(i, list/node)
if(token(i) in (binary_operators + comparitors))
node += token(i)
else
parse_error("Unknown binary operator [token(i)]")
return i + 1
//value: variable | string | number | 'null'
value(i, list/node)
/datum/SDQL_parser/proc/value(i, list/node)
if(token(i) == "null")
node += "null"
i++
else if(lowertext(copytext(token(i),1,3)) == "0x" && isnum(hex2num(copytext(token(i),3))))
node += hex2num(copytext(token(i),3))
i++
else if(isnum(text2num(token(i))))
node += text2num(token(i))
i++
else if(copytext(token(i), 1, 2) in list("'", "\""))
i = string(i, node)
else if(copytext(token(i), 1, 2) == "\[") // Start a list.
i = array(i, node)
else
i = variable(i, node)
return i
if(token(i) == "null")
node += "null"
i++
else if(isnum(text2num(token(i))))
node += text2num(token(i))
i++
else if(copytext(token(i), 1, 2) in list("'", "\""))
i = string(i, node)
else
i = variable(i, node)
return i
/*EXPLAIN SELECT * WHERE 42 = 6 * 9 OR val = - 5 == 7*/
/*EXPLAIN SELECT * WHERE 42 = 6 * 9 OR val = - 5 == 7*/
@@ -0,0 +1,174 @@
// Wrappers for BYOND default procs which can't directly be called by call().
/proc/_abs(A)
return abs(A)
/*/proc/_animate(atom/A, set_vars, time = 10, loop = 1, easing = LINEAR_EASING, flags = null)
animate(A, set_vars, time, loop, easing, flags)
Borked. If anyone wants to fix this be my guest.*/
/proc/_acrccos(A)
return arccos(A)
/proc/_arcsin(A)
return arcsin(A)
/proc/_ascii2text(A)
return ascii2text(A)
/proc/_block(Start, End)
return block(Start, End)
/proc/_ckey(Key)
return ckey(Key)
/proc/_ckeyEx(Key)
return ckeyEx(Key)
/proc/_copytext(T, Start = 1, End = 0)
return copytext(T, Start, End)
/proc/_cos(X)
return cos(X)
/proc/_get_dir(Loc1, Loc2)
return get_dir(Loc1, Loc2)
/proc/_get_dist(Loc1, Loc2)
return get_dist(Loc1, Loc2)
/proc/_get_step(Ref, Dir)
return get_step(Ref, Dir)
/proc/_hearers(Depth = world.view, Center = usr)
return hearers(Depth, Center)
/proc/_image(icon, loc, icon_state, layer, dir)
return image(icon, loc, icon_state, layer, dir)
/proc/_length(E)
return length(E)
/proc/_link(thing, url)
thing << link(url)
/proc/_locate(X, Y, Z)
if (isnull(Y)) // Assuming that it's only a single-argument call.
return locate(X)
return locate(X, Y, Z)
/proc/_log(X, Y)
return log(X, Y)
/proc/_lowertext(T)
return lowertext(T)
/proc/_matrix(a, b, c, d, e, f)
return matrix(a, b, c, d, e, f)
/proc/_max(...)
return max(arglist(args))
/proc/_md5(T)
return md5(T)
/proc/_min(...)
return min(arglist(args))
/proc/_new(type, arguments)
return new type (arglist(arguments))
/proc/_num2text(N, SigFig = 6)
return num2text(N, SigFig)
/proc/_ohearers(Dist, Center = usr)
return ohearers(Dist, Center)
/proc/_orange(Dist, Center = usr)
return orange(Dist, Center)
/proc/_output(thing, msg, control)
thing << output(msg, control)
/proc/_oview(Dist, Center = usr)
return oview(Dist, Center)
/proc/_oviewers(Dist, Center = usr)
return oviewers(Dist, Center)
/proc/_params2list(Params)
return params2list(Params)
/proc/_pick(...)
return pick(arglist(args))
/proc/_prob(P)
return prob(P)
/proc/_rand(L = 0, H = 1)
return rand(L, H)
/proc/_range(Dist, Center = usr)
return range(Dist, Center)
/proc/_regex(pattern, flags)
return regex(pattern, flags)
/proc/_REGEX_QUOTE(text)
return REGEX_QUOTE(text)
/proc/_REGEX_QUOTE_REPLACEMENT(text)
return REGEX_QUOTE_REPLACEMENT(text)
/proc/_replacetext(Haystack, Needle, Replacement, Start = 1,End = 0)
return replacetext(Haystack, Needle, Replacement, Start, End)
/proc/_replacetextEx(Haystack, Needle, Replacement, Start = 1,End = 0)
return replacetextEx(Haystack, Needle, Replacement, Start, End)
/proc/_rgb(R, G, B)
return rgb(R, G, B)
/proc/_rgba(R, G, B, A)
return rgb(R, G, B, A)
/proc/_roll(dice)
return roll(dice)
/proc/_round(A, B = 1)
return round(A, B)
/proc/_sin(X)
return sin(X)
/proc/_step(Ref, Dir, Speed = 0)
return step(Ref, Dir, Speed)
/proc/_list_add(list/L, ...)
if (args.len < 2)
return
L += args.Copy(2)
/proc/_list_copy(list/L, Start = 1, End = 0)
return L.Copy(Start, End)
/proc/_list_cut(list/L, Start = 1, End = 0)
L.Cut(Start, End)
/proc/_list_find(list/L, Elem, Start = 1, End = 0)
return L.Find(Elem, Start, End)
/proc/_list_insert(list/L, Index, Item)
return L.Insert(Index, Item)
/proc/_list_join(list/L, Glue, Start = 0, End = 1)
return L.Join(Glue, Start, End)
/proc/_list_remove(list/L, ...)
if (args.len < 2)
return
L -= args.Copy(2)
/proc/_list_swap(list/L, Index1, Index2)
L.Swap(Index1, Index2)
+2 -1
View File
@@ -79,6 +79,7 @@
if(src.handle_spam_prevention(msg,MUTE_ADMINHELP))
return
var/ref_mob = "\ref[mob]"
var/ref_client = "\ref[src]"
for(var/datum/adminticket/T in admintickets)
if(T.permckey == src.ckey && T.resolved == "No")
if(alert(usr,"You already have an adminhelp open, would you like to bump it?", "Bump Adminhelp", "Yes", "No") == "Yes")
@@ -86,7 +87,7 @@
if(T.admin == "N/A")
usr << "<b>Due to the fact your Adminhelp had no assigned admin, admins have been pinged.</b>"
message_admins("[src.ckey] has bumped their adminhelp #[T.ID], still no assigned admin!")
msg = "<span class='adminnotice'><b><font color=red>ADMINHELP: </font><A HREF='?priv_msg=[ckey];ahelp_reply=1'>[key_name(src)]</A> (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) (<A HREF='?_src_=holder;traitor=[ref_mob]'>TP</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=[ref_mob]'>FLW</A>) (<a href='?src=\ref[T];resolve=\ref[T]'>R</a>) (<A HREF='?_src_=holder;rejectadminhelp=[ref_mob]'>REJT</A>):</b> [T.msg]</span>"
msg = "<span class='adminnotice'><b><font color=red>HELP: </font><A HREF='?priv_msg=[ckey];ahelp_reply=1'>[key_name(src)]</A> [ADMIN_QUE(mob)] [ADMIN_PP(mob)] [ADMIN_VV(mob)] [ADMIN_SM(mob)] [ADMIN_FLW(mob)] [ADMIN_TP(mob)] (<A HREF='?_src_=holder;rejectadminhelp=[ref_client]'>REJT</A>) (<A HREF='?_src_=holder;icissue=[ref_client]'>IC</A>) (<A HREF='?_src_=holder;resolve=[T.ID]'>R</a>):</b> [msg]</span>"
for(var/client/X in admins)
if(X.prefs.toggles & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
+1 -4
View File
@@ -33,10 +33,7 @@
prayer_type = "CULTIST PRAYER"
deity = "Nar-Sie"
msg = "<span class='adminnotice'>\icon[cross] \
<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>\
[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]:</b> \
[msg]</span>"
msg = "<span class='adminnotice'>\icon[cross]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)] [ADMIN_SMITE(src)]:</b> [msg]</span>"
for(var/client/C in admins)
if(C.prefs.chat_toggles & CHAT_PRAYER)
+7 -1
View File
@@ -105,7 +105,7 @@ Code:
user << "You transfer the frequency and code of \the [signaler2.name] to \the [name]"
else
..()
/obj/item/device/assembly/signaler/proc/signal()
if(!radio_connection) return
@@ -194,3 +194,9 @@ Code:
/obj/item/device/assembly/signaler/anomaly/attack_self()
return
/obj/item/device/assembly/signaler/cyborg
origin_tech = null
/obj/item/device/assembly/signaler/cyborg/attackby(obj/item/weapon/W, mob/user, params)
return
@@ -97,7 +97,7 @@
wizmind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt)
wizmind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile)
wizmind.AddSpell(new /obj/effect/proc_holder/spell/fireball)
wizmind.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball)
current_wizard = wizbody
+2 -2
View File
@@ -1,8 +1,8 @@
//This is the lowest supported version, anything below this is completely obsolete and the entire savefile will be wiped.
#define SAVEFILE_VERSION_MIN 11
#define SAVEFILE_VERSION_MIN 10
//This is the current version, anything below this will attempt to update (if it's not obsolete)
#define SAVEFILE_VERSION_MAX 18
#define SAVEFILE_VERSION_MAX 17
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
This proc checks if the current directory of the savefile S needs updating
+1 -1
View File
@@ -11,9 +11,9 @@
..()
/obj/item/clothing/suit/hooded/Destroy()
. = ..()
qdel(hood)
hood = null
return ..()
/obj/item/clothing/suit/hooded/proc/MakeHood()
if(!hood)
+13 -43
View File
@@ -75,35 +75,29 @@
item_state = "y_suit"
item_color = "yellow"
/obj/item/clothing/under/color/lightblue
name = "lightblue jumpsuit"
icon_state = "lightblue"
/obj/item/clothing/under/color/darkblue
name = "darkblue jumpsuit"
icon_state = "darkblue"
item_state = "b_suit"
item_color = "lightblue"
item_color = "darkblue"
/obj/item/clothing/under/color/aqua
name = "aqua jumpsuit"
icon_state = "aqua"
/obj/item/clothing/under/color/teal
name = "teal jumpsuit"
icon_state = "teal"
item_state = "b_suit"
item_color = "aqua"
/obj/item/clothing/under/color/purple
name = "purple jumpsuit"
icon_state = "purple"
item_state = "p_suit"
item_color = "purple"
item_color = "teal"
/obj/item/clothing/under/color/lightpurple
name = "lightpurple jumpsuit"
name = "purple jumpsuit"
icon_state = "lightpurple"
item_state = "p_suit"
item_color = "lightpurple"
/obj/item/clothing/under/color/lightgreen
name = "lightgreen jumpsuit"
icon_state = "lightgreen"
/obj/item/clothing/under/color/darkgreen
name = "darkgreen jumpsuit"
icon_state = "darkgreen"
item_state = "g_suit"
item_color = "lightgreen"
item_color = "darkgreen"
/obj/item/clothing/under/color/lightbrown
name = "lightbrown jumpsuit"
@@ -117,30 +111,6 @@
item_state = "lb_suit"
item_color = "brown"
/obj/item/clothing/under/color/yellowgreen
name = "yellowgreen jumpsuit"
icon_state = "yellowgreen"
item_state = "y_suit"
item_color = "yellowgreen"
/obj/item/clothing/under/color/darkblue
name = "darkblue jumpsuit"
icon_state = "darkblue"
item_state = "b_suit"
item_color = "darkblue"
/obj/item/clothing/under/color/lightred
name = "lightred jumpsuit"
icon_state = "lightred"
item_state = "r_suit"
item_color = "lightred"
/obj/item/clothing/under/color/darkred
name = "darkred jumpsuit"
icon_state = "darkred"
item_state = "r_suit"
item_color = "darkred"
/obj/item/clothing/under/color/maroon
name = "maroon jumpsuit"
icon_state = "maroon"
+3
View File
@@ -36,6 +36,9 @@
forge_valentines_objective(date, L)
if(valentines.len && prob(4))
var/mob/living/notgoodenough = pick_n_take(valentines)
forge_valentines_objective(notgoodenough, date)
else
+2 -2
View File
@@ -4,7 +4,7 @@
/datum/round_event_control/ion_storm
name = "Ion Storm"
typepath = /datum/round_event/ion_storm
weight = 3
weight = 15
min_players = 2
/datum/round_event/ion_storm
@@ -545,7 +545,7 @@
message = "ALL [ionthreats] ARE NOW NAMED [ionspecies]."
if(4)
message = "ALL [ionthreats] ARE NOW NAMED [ionobjects]."
return message
#undef ION_RANDOM
+7 -4
View File
@@ -37,9 +37,12 @@
projectilesound = 'sound/weapons/emitter.ogg'
maxHealth = 50
health = 50
var/allowed_projectile_types = list(/obj/item/projectile/magic/change, /obj/item/projectile/magic/animate, /obj/item/projectile/magic/resurrection,
/obj/item/projectile/magic/death, /obj/item/projectile/magic/teleport, /obj/item/projectile/magic/door, /obj/item/projectile/magic/aoe/fireball,
/obj/item/projectile/magic/spellblade, /obj/item/projectile/magic/arcane_barrage)
/mob/living/simple_animal/hostile/carp/ranged/New()
projectiletype = pick(typesof(initial(projectiletype)))
projectiletype = pick(allowed_projectile_types)
..()
/mob/living/simple_animal/hostile/carp/ranged/chaos
@@ -50,5 +53,5 @@
health = 75
/mob/living/simple_animal/hostile/carp/ranged/chaos/Shoot()
projectiletype = pick(typesof(initial(projectiletype)))
..()
projectiletype = pick(allowed_projectile_types)
..()
+3 -3
View File
@@ -58,7 +58,7 @@ Medical Doctor
outfit = /datum/outfit/job/doctor
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics, access_cloning, access_mineral_storeroom)
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_genetics, access_cloning, access_mineral_storeroom)
minimal_access = list(access_medical, access_morgue, access_surgery, access_cloning)
/datum/outfit/job/doctor
@@ -93,7 +93,7 @@ Chemist
outfit = /datum/outfit/job/chemist
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics, access_cloning, access_mineral_storeroom)
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_genetics, access_cloning, access_mineral_storeroom)
minimal_access = list(access_medical, access_chemistry, access_mineral_storeroom)
/datum/outfit/job/chemist
@@ -127,7 +127,7 @@ Geneticist
outfit = /datum/outfit/job/geneticist
access = list(access_medical, access_morgue, access_chemistry, access_virology, access_genetics, access_cloning, access_research, access_xenobiology, access_robotics, access_mineral_storeroom, access_tech_storage)
access = list(access_medical, access_morgue, access_chemistry, access_genetics, access_cloning, access_research, access_xenobiology, access_robotics, access_mineral_storeroom, access_tech_storage)
minimal_access = list(access_medical, access_morgue, access_genetics, access_cloning, access_research)
/datum/outfit/job/geneticist
+96 -64
View File
@@ -1,22 +1,40 @@
#define SOAPSTONE_PREFIX_FILE "strings/soapstone_prefixes.txt"
#define SOAPSTONE_SUFFIX_FILE "soapstone_suffixes.json"
//Vocabulary lists; soapstones use a prefix and a suffix. Optionally, they can have a prefix and suffix, then a conjunction that links another set.
var/global/list/soapstone_prefixes = list() //Read from "strings/soapstone_prefixes.txt"; if you're adding your own, put **** where the subject should be!
var/global/list/soapstone_suffixes = list() //Read from "strings/soapstone_suffixes.json"
/obj/item/soapstone
name = "chisel"
desc = "Leave informative messages for the crew, including the crew of future shifts!\nEven if out of uses, it can still be used to remove messages.\n(Not suitable for engraving on shuttles, off station or on cats. Side effects may include beatings, bannings and orbital bombardment.)"
desc = "Leave \"informative\" messages for the crew, including the crew of future shifts!\n\
(Not suitable for engraving on shuttles, off station or on cats. Side effects may include beatings, bannings and orbital bombardment.)"
icon = 'icons/obj/items.dmi'
icon_state = "soapstone"
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_TINY
var/tool_speed = 50
var/remaining_uses = 3
var/non_dull_name
var/w_engrave = "engrave"
var/w_engraving = "engraving"
var/w_chipping = "chipping"
var/w_dull = "dull"
/obj/item/soapstone/New()
. = ..()
if(!soapstone_prefixes.len)
soapstone_prefixes = file2list(SOAPSTONE_PREFIX_FILE, "\n")
if(!soapstone_suffixes.len)
soapstone_suffixes = list(\
"Characters" = strings(SOAPSTONE_SUFFIX_FILE, "Characters"), \
"Careers" = strings(SOAPSTONE_SUFFIX_FILE, "Careers"), \
"Antagonists" = strings(SOAPSTONE_SUFFIX_FILE, "Antagonists"), \
"Objects" = strings(SOAPSTONE_SUFFIX_FILE, "Objects"), \
"Techniques" = strings(SOAPSTONE_SUFFIX_FILE, "Techniques"), \
"Actions" = strings(SOAPSTONE_SUFFIX_FILE, "Actions"), \
"Geography" = strings(SOAPSTONE_SUFFIX_FILE, "Geography"), \
"Orientation" = strings(SOAPSTONE_SUFFIX_FILE, "Orientation"), \
"Body parts" = strings(SOAPSTONE_SUFFIX_FILE, "Body parts"), \
"Concepts" = strings(SOAPSTONE_SUFFIX_FILE, "Concepts"), \
"Musings" = strings(SOAPSTONE_SUFFIX_FILE, "Musings"), \
)
random_name()
check_name() // could start empty
@@ -25,9 +43,6 @@
non_dull_name = name
if(name == "chalk" || name == "magic marker")
desc = replacetext(desc, "engraving", "scribbling")
w_engrave = "scribble"
w_engraving = "scribbling"
w_chipping = "sketching"
if(name == "chalk")
w_dull = "used"
if(name == "magic marker")
@@ -35,9 +50,6 @@
if(name == "soapstone" || name == "chisel")
desc = replacetext(desc, "scribbling", "engraving")
w_engrave = initial(w_engrave)
w_engraving = initial(w_engraving)
w_chipping = initial(w_chipping)
w_dull = "dull"
/obj/item/soapstone/examine(mob/user)
@@ -48,59 +60,48 @@
user << "It looks like it can be used an unlimited number of times."
/obj/item/soapstone/afterattack(atom/target, mob/user, proximity)
if(!remaining_uses)
user << "<span class='warning'>[src] is [w_dull] and can't be used anymore!</span>"
return
var/turf/T = get_turf(target)
if(!proximity)
return
var/obj/structure/chisel_message/already_message = locate(/obj/structure/chisel_message) in T
var/our_message = FALSE
if(already_message)
our_message = already_message.creator_key == user.ckey
if(!remaining_uses && !already_message)
// The dull chisel is dull.
user << "<span class='warning'>[src] is [w_dull].</span>"
return
if(!good_chisel_message_location(T))
user << "<span class='warning'>It's not appropriate to [w_engrave] on [T].</span>"
return
if(already_message)
user.visible_message("<span class='notice'>[user] starts erasing [already_message].</span>", "<span class='notice'>You start erasing [already_message].</span>", "<span class='italics'>You hear a [w_chipping] sound.</span>")
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
// Removing our own messages refunds a charge
if(do_after(user, tool_speed, target=target))
user.visible_message("<span class='notice'>[user] has erased [already_message].</span>", "<span class='notice'>You erased [already_message].</span>")
already_message.persists = FALSE
qdel(already_message)
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
if(our_message)
var/obj/structure/chisel_message/msg = locate() in T
if(msg)
if(msg.creator_key != user.ckey)
user << "<span class='warning'>There's already a message there!</span>"
return
else
if(alert(user, "Erase this message?", name, "Yes", "No") == "Yes")
user.visible_message("<span class='notice'>[user] erases [msg].</span>", "<span class='notice'>You permanently erase [msg].</span>")
playsound(T, 'sound/items/gavel.ogg', 50, 1)
refund_use()
msg.persists = 0
qdel(msg)
return
return
if(!good_chisel_message_location(T))
user << "<span class='warning'>You can't write there!</span>"
return
var/message = stripped_input(user, "What would you like to [w_engrave]?", "[name] Message")
if(!message)
user << "You decide not to [w_engrave] anything."
var/prefix = input(user, "Choose a prefix for your message.", name) as null|anything in soapstone_prefixes
if(!prefix)
return
if(!target.Adjacent(user) && locate(/obj/structure/chisel_message) in T)
user << "You decide not to [w_engrave] anything."
var/suffix_category_string = input(user, "Choose a suffix category.", "[prefix]...") as null|anything in soapstone_suffixes
var/list/suffix_category = soapstone_suffixes[suffix_category_string]
if(!suffix_category || !suffix_category.len)
return
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
user.visible_message("<span class='notice'>[user] starts [w_engraving] a message into [T].</span>", "You start [w_engraving] a message into [T].", "<span class='italics'>You hear a [w_chipping] sound.</span>")
if(can_use() && do_after(user, tool_speed, target=T) && can_use())
if(!locate(/obj/structure/chisel_message in T))
user << "You [w_engrave] a message into [T]."
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
var/obj/structure/chisel_message/M = new(T)
M.register(user, message)
remove_use()
var/suffix = input(user, "Choose a suffix.", "[prefix]...") as null|anything in suffix_category
if(!suffix)
return
var/processed_message = replacetext(prefix, "****", suffix)
if(!user.Adjacent(T) || !good_chisel_message_location(T) || locate(/obj/structure/chisel_message) in T)
return
user.visible_message("<span class='notice'>[user] writes a message onto [T]!</span>", "<span class='notice'>You write a message onto [T].</span>")
playsound(T, 'sound/items/gavel.ogg', 50, 1)
var/obj/structure/chisel_message/M = new(T)
M.register(user, processed_message)
remove_use()
return 1
/obj/item/soapstone/proc/can_use()
if(remaining_uses == -1 || remaining_uses >= 0)
@@ -171,6 +172,34 @@
var/map
var/persists = TRUE
var/positive_ratings = 0
var/negative_ratings = 0
var/list/raters = list() //Ckeys who have rated this message
/obj/structure/chisel_message/attack_hand(mob/user)
if(user.ckey == creator_key)
user << "<span class='warning'>You can't rate your own messages!</span>"
return
if(raters[user.ckey])
user << "<span class='warning'>You've already rated this message!</span>"
return
switch(alert(user, "How would you like to rate this message?", "Message Rating", "Positive", "Negative", "Cancel"))
if("Positive")
for(var/client/C in clients)
if(C.ckey == creator_key)
C.mob << "<span class='notice'>One of your messages was rated as positive!</span>"
user << "<span class='noticealien'>You rated this message as positive.</span>"
positive_ratings++
raters[user.ckey] = "positive"
if("Negative")
for(var/client/C in clients)
if(C.ckey == creator_key)
C.mob << "<span class='danger'>One of your messages was rated as negative!</span>"
user << "<span class='danger'>You rated this message as negative.</span>"
negative_ratings++
raters[user.ckey] = "negative"
/obj/structure/chisel_message/New(newloc)
..()
SSpersistence.chisel_messages += src
@@ -190,12 +219,6 @@
map = MAP_NAME
update_icon()
/obj/structure/chisel_message/update_icon()
..()
var/hash = md5(hidden_message)
var/newcolor = copytext(hash, 1, 7)
add_atom_colour("#[newcolor]", FIXED_COLOUR_PRIORITY)
/obj/structure/chisel_message/proc/pack()
var/list/data = list()
data["hidden_message"] = hidden_message
@@ -206,6 +229,9 @@
var/turf/T = get_turf(src)
data["x"] = T.x
data["y"] = T.y
data["pos_ratings"] = positive_ratings
data["neg_ratings"] = positive_ratings
data["raters"] = raters
return data
/obj/structure/chisel_message/proc/unpack(list/data)
@@ -213,6 +239,9 @@
creator_name = data["creator_name"]
creator_key = data["creator_key"]
realdate = data["realdate"]
positive_ratings = data["pos_ratings"]
negative_ratings = data["neg_ratings"]
raters = data["raters"]
var/x = data["x"]
var/y = data["y"]
@@ -222,7 +251,10 @@
/obj/structure/chisel_message/examine(mob/user)
..()
user << "<span class='warning'>[hidden_message]</span>"
user << "<span class='notice'>[hidden_message]</span>"
user << "Ratings: <span class='noticealien'>[positive_ratings]</span> <span class='danger'>[negative_ratings]</span>"
if(raters[user.ckey])
user << "<i>You rated this message as [raters[user.ckey]].</i>"
/obj/structure/chisel_message/Destroy()
if(persists)
@@ -169,6 +169,8 @@
..()
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0)
if(tesla_shock && tesla_ignore)
return FALSE
shock_damage *= siemens_coeff
if(dna && dna.species)
shock_damage *= dna.species.siemens_coeff
@@ -448,6 +448,8 @@
if(S.siemens_coefficient <= 0)
total_coeff -= 0.95
siemens_coeff = total_coeff
if(tesla_ignore)
siemens_coeff = 0
else if(!safety)
var/gloves_siemens_coeff = 1
if(gloves)
+4
View File
@@ -85,9 +85,13 @@
message_alien = "lets out a waning guttural screech, green blood bubbling from its maw..."
message_larva = "lets out a sickly hiss of air and falls limply to the floor..."
message_monkey = "lets out a faint chimper as it collapses and stops moving..."
message_simple = "stops moving..."
stat_allowed = UNCONSCIOUS
/datum/emote/living/deathgasp/run_emote(mob/user, params)
var/mob/living/simple_animal/S = user
if(istype(S) && S.deathmessage)
message_simple = S.deathmessage
. = ..()
if(. && isalienadult(user))
playsound(user.loc, 'sound/voice/hiss6.ogg', 80, 1, 1)
@@ -276,6 +276,8 @@
/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0)
if(tesla_shock && tesla_ignore)
return FALSE
if(shock_damage > 0)
if(!illusion)
adjustFireLoss(shock_damage)
+2 -1
View File
@@ -74,4 +74,5 @@
var/list/status_effects //a list of all status effects the mob has
var/list/implants = null
var/list/implants = null
var/tesla_ignore = FALSE
+5
View File
@@ -45,6 +45,11 @@
laws_sanity_check()
laws.replace_random_law(law,groups)
/mob/living/silicon/proc/remove_law(number)
throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.remove_law(number)
/mob/living/silicon/proc/clear_ion_laws()
throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
@@ -220,27 +220,47 @@
/obj/item/weapon/robot_module/standard
name = "Standard"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/reagent_containers/borghypo/epi, /obj/item/device/healthanalyzer, \
/obj/item/weapon/weldingtool/largetank/cyborg, /obj/item/weapon/wrench/cyborg, /obj/item/weapon/crowbar/cyborg, \
/obj/item/stack/sheet/metal/cyborg, /obj/item/weapon/extinguisher, /obj/item/weapon/pickaxe, \
/obj/item/device/t_scanner/adv_mining_scanner, /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg, \
/obj/item/weapon/soap/nanotrasen, /obj/item/borg/cyborghug)
basic_modules = list(
/obj/item/device/assembly/flash/cyborg,
/obj/item/weapon/reagent_containers/borghypo/epi,
/obj/item/weapon/crowbar/cyborg,
/obj/item/weapon/extinguisher,
/obj/item/weapon/soap/nanotrasen,
/obj/item/borg/cyborghug)
emag_modules = list(/obj/item/weapon/melee/energy/sword/cyborg)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg, /obj/item/clockwork/ratvarian_spear/cyborg, /obj/item/clockwork/clockwork_proselytizer/cyborg)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg,
/obj/item/clockwork/ratvarian_spear/cyborg,
/obj/item/clockwork/clockwork_proselytizer/cyborg)
moduleselect_icon = "standard"
feedback_key = "cyborg_standard"
hat_offset = -3
/obj/item/weapon/robot_module/medical
name = "Medical"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/device/healthanalyzer, /obj/item/weapon/reagent_containers/borghypo, \
/obj/item/weapon/reagent_containers/glass/beaker/large, /obj/item/weapon/reagent_containers/dropper, \
/obj/item/weapon/reagent_containers/syringe, /obj/item/weapon/surgical_drapes, /obj/item/weapon/retractor, \
/obj/item/weapon/hemostat, /obj/item/weapon/cautery, /obj/item/weapon/surgicaldrill, /obj/item/weapon/scalpel, \
/obj/item/weapon/circular_saw, /obj/item/weapon/extinguisher/mini, /obj/item/roller/robo, /obj/item/borg/cyborghug/medical, \
/obj/item/stack/medical/gauze/cyborg, /obj/item/borg/lollipop)
basic_modules = list(
/obj/item/device/assembly/flash/cyborg,
/obj/item/device/healthanalyzer,
/obj/item/weapon/reagent_containers/borghypo,
/obj/item/weapon/reagent_containers/glass/beaker/large,
/obj/item/weapon/reagent_containers/dropper,
/obj/item/weapon/reagent_containers/syringe,
/obj/item/weapon/surgical_drapes,
/obj/item/weapon/retractor,
/obj/item/weapon/hemostat,
/obj/item/weapon/cautery,
/obj/item/weapon/surgicaldrill,
/obj/item/weapon/scalpel,
/obj/item/weapon/circular_saw,
/obj/item/weapon/extinguisher/mini,
/obj/item/roller/robo,
/obj/item/borg/cyborghug/medical,
/obj/item/stack/medical/gauze/cyborg,
/obj/item/borg/lollipop)
emag_modules = list(/obj/item/weapon/reagent_containers/borghypo/hacked)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/medical, /obj/item/clockwork/ratvarian_spear/cyborg)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/medical,
/obj/item/clockwork/ratvarian_spear/cyborg)
cyborg_base_icon = "medical"
moduleselect_icon = "medical"
feedback_key = "cyborg_medical"
@@ -249,14 +269,32 @@
/obj/item/weapon/robot_module/engineering
name = "Engineering"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/borg/sight/meson, /obj/item/weapon/rcd/borg, /obj/item/weapon/pipe_dispenser, \
/obj/item/weapon/extinguisher, /obj/item/weapon/weldingtool/largetank/cyborg, /obj/item/weapon/screwdriver/cyborg, \
/obj/item/weapon/wrench/cyborg, /obj/item/weapon/crowbar/cyborg, /obj/item/weapon/wirecutters/cyborg, \
/obj/item/device/multitool/cyborg, /obj/item/device/t_scanner, /obj/item/device/analyzer, \
/obj/item/areaeditor/blueprints/cyborg, /obj/item/stack/sheet/metal/cyborg, /obj/item/stack/sheet/glass/cyborg, \
/obj/item/stack/sheet/rglass/cyborg, /obj/item/stack/rods/cyborg, /obj/item/stack/tile/plasteel/cyborg, /obj/item/stack/cable_coil/cyborg)
basic_modules = list(
/obj/item/device/assembly/flash/cyborg,
/obj/item/borg/sight/meson,
/obj/item/weapon/rcd/borg,
/obj/item/weapon/pipe_dispenser,
/obj/item/weapon/extinguisher,
/obj/item/weapon/weldingtool/largetank/cyborg,
/obj/item/weapon/screwdriver/cyborg,
/obj/item/weapon/wrench/cyborg,
/obj/item/weapon/crowbar/cyborg,
/obj/item/weapon/wirecutters/cyborg,
/obj/item/device/multitool/cyborg,
/obj/item/device/t_scanner,
/obj/item/device/analyzer,
/obj/item/device/assembly/signaler/cyborg,
/obj/item/areaeditor/blueprints/cyborg,
/obj/item/stack/sheet/metal/cyborg,
/obj/item/stack/sheet/glass/cyborg,
/obj/item/stack/sheet/rglass/cyborg,
/obj/item/stack/rods/cyborg,
/obj/item/stack/tile/plasteel/cyborg,
/obj/item/stack/cable_coil/cyborg)
emag_modules = list(/obj/item/borg/stun)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/engineer, /obj/item/clockwork/clockwork_proselytizer/cyborg)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/engineer,
/obj/item/clockwork/clockwork_proselytizer/cyborg)
cyborg_base_icon = "engineer"
moduleselect_icon = "engineer"
feedback_key = "cyborg_engineering"
@@ -265,10 +303,15 @@
/obj/item/weapon/robot_module/security
name = "Security"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg, /obj/item/weapon/melee/baton/loaded, \
/obj/item/weapon/gun/energy/disabler/cyborg, /obj/item/clothing/mask/gas/sechailer/cyborg)
basic_modules = list(
/obj/item/device/assembly/flash/cyborg,
/obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg,
/obj/item/weapon/melee/baton/loaded,
/obj/item/weapon/gun/energy/disabler/cyborg,
/obj/item/clothing/mask/gas/sechailer/cyborg)
emag_modules = list(/obj/item/weapon/gun/energy/laser/cyborg)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security, /obj/item/clockwork/ratvarian_spear/cyborg)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security,
/obj/item/clockwork/ratvarian_spear/cyborg)
cyborg_base_icon = "sec"
moduleselect_icon = "security"
feedback_key = "cyborg_security"
@@ -293,10 +336,18 @@
/obj/item/weapon/robot_module/peacekeeper
name = "Peacekeeper"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/cookiesynth, /obj/item/device/harmalarm, /obj/item/weapon/reagent_containers/borghypo/peace, \
/obj/item/weapon/holosign_creator/cyborg, /obj/item/borg/cyborghug/peacekeeper, /obj/item/weapon/extinguisher)
basic_modules = list(
/obj/item/device/assembly/flash/cyborg,
/obj/item/weapon/cookiesynth,
/obj/item/device/harmalarm,
/obj/item/weapon/reagent_containers/borghypo/peace,
/obj/item/weapon/holosign_creator/cyborg,
/obj/item/borg/cyborghug/peacekeeper,
/obj/item/weapon/extinguisher)
emag_modules = list(/obj/item/weapon/reagent_containers/borghypo/peace/hacked)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/peacekeeper, /obj/item/clockwork/ratvarian_spear/cyborg)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/peacekeeper,
/obj/item/clockwork/ratvarian_spear/cyborg)
cyborg_base_icon = "peace"
moduleselect_icon = "standard"
feedback_key = "cyborg_peacekeeper"
@@ -310,10 +361,18 @@
/obj/item/weapon/robot_module/janitor
name = "Janitor"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/soap/nanotrasen, /obj/item/weapon/storage/bag/trash/cyborg, /obj/item/weapon/mop/cyborg, \
/obj/item/device/lightreplacer/cyborg, /obj/item/weapon/holosign_creator, /obj/item/weapon/reagent_containers/spray/cyborg_drying)
basic_modules = list(
/obj/item/device/assembly/flash/cyborg,
/obj/item/weapon/soap/nanotrasen,
/obj/item/weapon/storage/bag/trash/cyborg,
/obj/item/weapon/mop/cyborg,
/obj/item/device/lightreplacer/cyborg,
/obj/item/weapon/holosign_creator,
/obj/item/weapon/reagent_containers/spray/cyborg_drying)
emag_modules = list(/obj/item/weapon/reagent_containers/spray/cyborg_lube)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/janitor, /obj/item/clockwork/clockwork_proselytizer/cyborg)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/janitor,
/obj/item/clockwork/clockwork_proselytizer/cyborg)
cyborg_base_icon = "janitor"
moduleselect_icon = "janitor"
feedback_key = "cyborg_janitor"
@@ -345,12 +404,25 @@
/obj/item/weapon/robot_module/butler
name = "Service"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/reagent_containers/food/drinks/drinkingglass, /obj/item/weapon/reagent_containers/food/condiment/enzyme, \
/obj/item/weapon/pen, /obj/item/toy/crayon/spraycan/borg, /obj/item/weapon/hand_labeler/borg, /obj/item/weapon/razor, \
/obj/item/device/instrument/violin, /obj/item/device/instrument/guitar, /obj/item/weapon/rsf/cyborg, /obj/item/weapon/reagent_containers/dropper, \
/obj/item/weapon/lighter, /obj/item/weapon/storage/bag/tray, /obj/item/weapon/reagent_containers/borghypo/borgshaker, /obj/item/borg/lollipop)
basic_modules = list(
/obj/item/device/assembly/flash/cyborg,
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass,
/obj/item/weapon/reagent_containers/food/condiment/enzyme,
/obj/item/weapon/pen,
/obj/item/toy/crayon/spraycan/borg,
/obj/item/weapon/hand_labeler/borg,
/obj/item/weapon/razor,
/obj/item/device/instrument/violin,
/obj/item/device/instrument/guitar,
/obj/item/weapon/rsf/cyborg,
/obj/item/weapon/reagent_containers/dropper,
/obj/item/weapon/lighter,
/obj/item/weapon/storage/bag/tray,
/obj/item/weapon/reagent_containers/borghypo/borgshaker,
/obj/item/borg/lollipop)
emag_modules = list(/obj/item/weapon/reagent_containers/borghypo/borgshaker/hacked)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/service, /obj/item/borg/sight/xray/truesight_lens)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/service,
/obj/item/borg/sight/xray/truesight_lens)
moduleselect_icon = "service"
special_light_key = "service"
feedback_key = "cyborg_service"
@@ -386,11 +458,24 @@
/obj/item/weapon/robot_module/miner
name = "Miner"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/borg/sight/meson, /obj/item/weapon/storage/bag/ore/cyborg, /obj/item/weapon/pickaxe/drill/cyborg, /obj/item/weapon/shovel, \
/obj/item/weapon/crowbar/cyborg, /obj/item/weapon/weldingtool/mini, /obj/item/weapon/extinguisher/mini, /obj/item/weapon/storage/bag/sheetsnatcher/borg, \
/obj/item/device/t_scanner/adv_mining_scanner, /obj/item/weapon/gun/energy/kinetic_accelerator/cyborg, /obj/item/device/gps/cyborg)
basic_modules = list(
/obj/item/device/assembly/flash/cyborg,
/obj/item/borg/sight/meson,
/obj/item/weapon/storage/bag/ore/cyborg,
/obj/item/weapon/pickaxe/drill/cyborg,
/obj/item/weapon/shovel,
/obj/item/weapon/crowbar/cyborg,
/obj/item/weapon/weldingtool/mini,
/obj/item/weapon/extinguisher/mini,
/obj/item/weapon/storage/bag/sheetsnatcher/borg,
/obj/item/device/t_scanner/adv_mining_scanner,
/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg,
/obj/item/device/gps/cyborg)
emag_modules = list(/obj/item/borg/stun)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/miner, /obj/item/clockwork/ratvarian_spear/cyborg, /obj/item/borg/sight/xray/truesight_lens)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/miner,
/obj/item/clockwork/ratvarian_spear/cyborg,
/obj/item/borg/sight/xray/truesight_lens)
cyborg_base_icon = "miner"
moduleselect_icon = "miner"
feedback_key = "cyborg_miner"
@@ -398,10 +483,18 @@
/obj/item/weapon/robot_module/syndicate
name = "Syndicate Assault"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/melee/energy/sword/cyborg, /obj/item/weapon/gun/energy/printer, \
/obj/item/weapon/gun/ballistic/revolver/grenadelauncher/cyborg, /obj/item/weapon/card/emag, /obj/item/weapon/crowbar/cyborg, \
/obj/item/weapon/pinpointer/syndicate/cyborg)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security, /obj/item/clockwork/ratvarian_spear/cyborg)
basic_modules = list(
/obj/item/device/assembly/flash/cyborg,
/obj/item/weapon/melee/energy/sword/cyborg,
/obj/item/weapon/gun/energy/printer,
/obj/item/weapon/gun/ballistic/revolver/grenadelauncher/cyborg,
/obj/item/weapon/card/emag,
/obj/item/weapon/crowbar/cyborg,
/obj/item/weapon/pinpointer/syndicate/cyborg)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/security,
/obj/item/clockwork/ratvarian_spear/cyborg)
cyborg_base_icon = "synd_sec"
moduleselect_icon = "malf"
can_be_pushed = FALSE
@@ -409,11 +502,26 @@
/obj/item/weapon/robot_module/syndicate_medical
name = "Syndicate Medical"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/reagent_containers/borghypo/syndicate, /obj/item/weapon/twohanded/shockpaddles/syndicate, \
/obj/item/device/healthanalyzer, /obj/item/weapon/surgical_drapes, /obj/item/weapon/retractor, /obj/item/weapon/hemostat, \
/obj/item/weapon/cautery, /obj/item/weapon/scalpel, /obj/item/weapon/melee/energy/sword/cyborg/saw, /obj/item/roller/robo, \
/obj/item/weapon/card/emag, /obj/item/weapon/crowbar/cyborg, /obj/item/weapon/pinpointer/syndicate/cyborg, /obj/item/stack/medical/gauze/cyborg, /obj/item/weapon/gun/medbeam)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/medical, /obj/item/clockwork/ratvarian_spear/cyborg)
basic_modules = list(
/obj/item/device/assembly/flash/cyborg,
/obj/item/weapon/reagent_containers/borghypo/syndicate,
/obj/item/weapon/twohanded/shockpaddles/syndicate,
/obj/item/device/healthanalyzer,
/obj/item/weapon/surgical_drapes,
/obj/item/weapon/retractor,
/obj/item/weapon/hemostat,
/obj/item/weapon/cautery,
/obj/item/weapon/scalpel,
/obj/item/weapon/melee/energy/sword/cyborg/saw,
/obj/item/roller/robo,
/obj/item/weapon/card/emag,
/obj/item/weapon/crowbar/cyborg,
/obj/item/weapon/pinpointer/syndicate/cyborg,
/obj/item/stack/medical/gauze/cyborg,
/obj/item/weapon/gun/medbeam)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/medical,
/obj/item/clockwork/ratvarian_spear/cyborg)
cyborg_base_icon = "synd_medical"
moduleselect_icon = "malf"
can_be_pushed = FALSE
+2 -3
View File
@@ -228,9 +228,8 @@
if (length(law) > 0)
if (force || src.lawcheck[index+1] == "Yes")
src.say("[radiomod] [number]. [law]")
number++
sleep(10)
number++
for (var/index = 1, index <= src.laws.supplied.len, index++)
var/law = src.laws.supplied[index]
@@ -239,8 +238,8 @@
if(src.lawcheck.len >= number+1)
if (force || src.lawcheck[number+1] == "Yes")
src.say("[radiomod] [number]. [law]")
number++
sleep(10)
number++
/mob/living/silicon/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
@@ -526,7 +526,7 @@ Difficulty: Very Hard
/obj/machinery/anomalous_crystal/emitter/New()
..()
generated_projectile = pick(/obj/item/projectile/magic/fireball/infernal,/obj/item/projectile/magic/spellblade,
generated_projectile = pick(/obj/item/projectile/magic/aoe/fireball/infernal,/obj/item/projectile/magic/aoe/lightning,/obj/item/projectile/magic/spellblade,
/obj/item/projectile/bullet/meteorshot, /obj/item/projectile/beam/xray, /obj/item/projectile/colossus)
/obj/machinery/anomalous_crystal/emitter/ActivationReaction(mob/user, method)
@@ -29,7 +29,7 @@
loot = list(/obj/effect/mob_spawn/human/corpse/wizard,
/obj/item/weapon/staff)
var/obj/effect/proc_holder/spell/fireball/fireball = null
var/obj/effect/proc_holder/spell/aimed/fireball/fireball = null
var/obj/effect/proc_holder/spell/targeted/turf_teleport/blink/blink = null
var/obj/effect/proc_holder/spell/targeted/projectile/magic_missile/mm = null
@@ -38,7 +38,7 @@
/mob/living/simple_animal/hostile/wizard/New()
..()
fireball = new /obj/effect/proc_holder/spell/fireball
fireball = new /obj/effect/proc_holder/spell/aimed/fireball
fireball.clothes_req = 0
fireball.human_req = 0
fireball.player_lock = 0
@@ -299,10 +299,8 @@
if(!gibbed)
if(death_sound)
playsound(get_turf(src),death_sound, 200, 1)
if(deathmessage)
visible_message("<span class='danger'>\The [src] [deathmessage]</span>")
else if(!del_on_death)
visible_message("<span class='danger'>\The [src] stops moving...</span>")
if(deathmessage && !del_on_death)
emote("deathgasp")
if(del_on_death)
ghostize()
//Prevent infinite loops if the mob Destroy() is overriden in such
-2
View File
@@ -2,7 +2,6 @@
SStgui.on_logout(src)
unset_machine()
player_list -= src
current_watchlist -= ckey
log_access("Logout: [key_name(src)]")
if(admin_datums[src.ckey])
if (ticker && ticker.current_state == GAME_STATE_PLAYING) //Only report this stuff if we are currently playing.
@@ -28,7 +27,6 @@
send2irc("Server", "[cheesy_message]")
send2admindiscord("[cheesy_message]")
..()
if(isobj(loc))
@@ -103,8 +103,6 @@
if(href_list["ready"])
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME) // Make sure we don't ready up after the round has started
ready = text2num(href_list["ready"])
else
ready = 0
if(href_list["refresh"])
src << browse(null, "window=playersetup") //closes the player setup window
+1 -1
View File
@@ -292,7 +292,7 @@
/obj/item/weapon/paper/contract/infernal/magic/FulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
if(!istype(user) || !user.mind)
return -1
user.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball(null))
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball(null))
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
return ..()
+1
View File
@@ -51,6 +51,7 @@
obj_integrity = 200
max_integrity = 200
integrity_failure = 50
resistance_flags = FIRE_PROOF
var/area/area
var/areastring = null
var/obj/item/weapon/stock_parts/cell/cell
+4
View File
@@ -736,6 +736,10 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list ( \
pixel_y = rand(-2,2)
update_icon()
/obj/item/stack/cable_coil/red
item_color = "red"
icon_state = "coil_red"
/obj/item/stack/cable_coil/yellow
item_color = "yellow"
icon_state = "coil_yellow"
+10 -1
View File
@@ -168,6 +168,8 @@
investigate_log("lost power and turned <font color='red'>off</font>","singulo")
log_game("Emitter lost power in ([x],[y],[z])")
return
if(!check_delay())
return FALSE
fire_beam()
/obj/machinery/power/emitter/proc/check_delay()
@@ -175,9 +177,16 @@
return TRUE
return FALSE
/obj/machinery/power/emitter/proc/fire_beam()
/obj/machinery/power/emitter/proc/fire_beam_pulse()
if(!check_delay())
return FALSE
if(state != 2)
return FALSE
if(avail(active_power_usage))
add_load(active_power_usage)
fire_beam()
/obj/machinery/power/emitter/proc/fire_beam()
src.last_shot = world.time
if(src.shot_number < 3)
src.fire_delay = 20
+4 -2
View File
@@ -63,8 +63,10 @@
/obj/singularity/narsie/Bump(atom/A)
forceMove(get_turf(A))
A.narsie_act()
var/turf/T = get_turf(A)
if(T == loc)
T = get_step(A, A.dir) //please don't slam into a window like a bird, nar-sie
forceMove(T)
/obj/singularity/narsie/mezzer()
+4 -4
View File
@@ -90,10 +90,10 @@
if((last_zap + zap_cooldown) > world.time)
return FALSE
last_zap = world.time
var/coeff = (12 - (input_power_multiplier * 3))
coeff = max(coeff, 1)
var/shock_coeff = (5 - input_power_multiplier)
shock_coeff = max(shock_coeff, 1)
var/coeff = (20 - ((input_power_multiplier - 1) * 3))
coeff = max(coeff, 10)
var/shock_coeff = (4 - (input_power_multiplier - 2))
shock_coeff = max(shock_coeff, 2)
var/power = (powernet.avail/coeff)
add_load(power)
playsound(src.loc, 'sound/magic/LightningShock.ogg', 100, 1, extrarange = 5)
+1 -1
View File
@@ -203,7 +203,7 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
else if(isliving(A))
var/dist = get_dist(source, A)
var/mob/living/L = A
if(dist <= zap_range && (dist < closest_dist || !closest_mob) && L.stat != DEAD)
if(dist <= zap_range && (dist < closest_dist || !closest_mob) && L.stat != DEAD && !L.tesla_ignore)
closest_mob = L
closest_atom = A
closest_dist = dist
@@ -23,7 +23,7 @@
projectile_type = /obj/item/projectile/magic/door
/obj/item/ammo_casing/magic/fireball
projectile_type = /obj/item/projectile/magic/fireball
projectile_type = /obj/item/projectile/magic/aoe/fireball
/obj/item/ammo_casing/magic/chaos
projectile_type = /obj/item/projectile/magic
@@ -35,7 +35,6 @@
projectile_type = /obj/item/projectile/magic/arcane_barrage
/obj/item/ammo_casing/magic/chaos/newshot()
projectile_type = pick(typesof(/obj/item/projectile/magic))
..()
/obj/item/ammo_casing/magic/honk
+1
View File
@@ -267,6 +267,7 @@
if(user)
user.update_inv_hands()
feedback_add_details("gun_fired","[src.type]")
return 1
/obj/item/weapon/gun/attack(mob/M as mob, mob/user)
if(user.a_intent == INTENT_HARM) //Flogging
@@ -343,3 +343,16 @@
new /obj/item/stack/cable_coil(get_turf(src), 10)
slung = 0
update_icon()
/obj/item/weapon/gun/ballistic/revolver/reverse //Fires directly at its user... unless the user is a clown, of course.
clumsy_check = 0
/obj/item/weapon/gun/ballistic/revolver/reverse/can_trigger_gun(mob/living/user)
if((user.disabilities & CLUMSY) || (user.mind && user.mind.assigned_role == "Clown"))
return ..()
if(process_fire(user, user, 0, zone_override = "head"))
user.visible_message("<span class='warning'>[user] somehow manages to shoot [user.p_them()]self in the face!</span>", "<span class='userdanger'>You somehow shoot yourself in the face! How the hell?!</span>")
user.emote("scream")
user.drop_item()
user.Weaken(4)
return
@@ -38,6 +38,13 @@
max_charges = 10
recharge_rate = 2
no_den_usage = 1
var/allowed_projectile_types = list(/obj/item/projectile/magic/change, /obj/item/projectile/magic/animate, /obj/item/projectile/magic/resurrection,
/obj/item/projectile/magic/death, /obj/item/projectile/magic/teleport, /obj/item/projectile/magic/door, /obj/item/projectile/magic/aoe/fireball,
/obj/item/projectile/magic/spellblade, /obj/item/projectile/magic/arcane_barrage)
/obj/item/weapon/gun/magic/staff/chaos/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override, bonus_spread = 0)
chambered.projectile_type = pick(allowed_projectile_types)
. = ..(target, user, message, params, zone_override, bonus_spread)
/obj/item/weapon/gun/magic/staff/door
name = "staff of door creation"
+82 -47
View File
@@ -17,53 +17,6 @@
var/mob/M = target
M.death(0)
/obj/item/projectile/magic/fireball
name = "bolt of fireball"
icon_state = "fireball"
damage = 10
damage_type = BRUTE
nodamage = 0
//explosion values
var/exp_heavy = 0
var/exp_light = 2
var/exp_flash = 3
var/exp_fire = 2
/obj/item/projectile/magic/fireball/Range()
var/turf/T1 = get_step(src,turn(dir, -45))
var/turf/T2 = get_step(src,turn(dir, 45))
var/turf/T3 = get_step(src,dir)
var/mob/living/L = locate(/mob/living) in T1 //if there's a mob alive in our front right diagonal, we hit it.
if(L && L.stat != DEAD)
Bump(L,1) //Magic Bullet #teachthecontroversy
return
L = locate(/mob/living) in T2
if(L && L.stat != DEAD)
Bump(L,1)
return
L = locate(/mob/living) in T3
if(L && L.stat != DEAD)
Bump(L,1)
return
..()
/obj/item/projectile/magic/fireball/on_hit(target)
. = ..()
var/turf/T = get_turf(target)
explosion(T, -1, exp_heavy, exp_light, exp_flash, 0, flame_range = exp_fire)
if(ismob(target)) //multiple flavors of pain
var/mob/living/M = target
M.take_overall_damage(0,10) //between this 10 burn, the 10 brute, the explosion brute, and the onfire burn, your at about 65 damage if you stop drop and roll immediately
/obj/item/projectile/magic/fireball/infernal
name = "infernal fireball"
exp_heavy = -1
exp_light = -1
exp_flash = 4
exp_fire= 5
/obj/item/projectile/magic/resurrection
name = "bolt of resurrection"
icon_state = "ion"
@@ -387,3 +340,85 @@
nodamage = 0
armour_penetration = 0
flag = "magic"
/obj/item/projectile/magic/aoe
name = "Area Bolt"
desc = "What the fuck does this do?!"
damage = 0
var/proxdet = TRUE
/obj/item/projectile/magic/aoe/Range()
if(proxdet)
var/turf/T1 = get_step(src,turn(dir, -45))
var/turf/T2 = get_step(src,turn(dir, 45))
var/turf/T3 = get_step(src,dir)
var/mob/living/L = locate(/mob/living) in T1 //if there's a mob alive in our front right diagonal, we hit it.
if(L && L.stat != DEAD)
Bump(L,1) //Magic Bullet #teachthecontroversy
return
L = locate(/mob/living) in T2
if(L && L.stat != DEAD)
Bump(L,1)
return
L = locate(/mob/living) in T3
if(L && L.stat != DEAD)
Bump(L,1)
return
..()
/obj/item/projectile/magic/aoe/lightning
name = "lightning bolt"
icon_state = "tesla_projectile" //Better sprites are REALLY needed and appreciated!~
damage = 15
damage_type = BURN
nodamage = 0
speed = 0.3
flag = "magic"
var/tesla_power = 20000
var/tesla_range = 15
var/tesla_boom = FALSE
var/chain
var/mob/living/caster
/obj/item/projectile/magic/aoe/lightning/fire(setAngle)
if(caster)
chain = caster.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY)
..()
/obj/item/projectile/magic/aoe/lightning/on_hit(target)
. = ..()
tesla_zap(src, tesla_range, tesla_power, tesla_boom)
qdel(src)
/obj/item/projectile/magic/aoe/lightning/Destroy()
qdel(chain)
. = ..()
/obj/item/projectile/magic/aoe/fireball
name = "bolt of fireball"
icon_state = "fireball"
damage = 10
damage_type = BRUTE
nodamage = 0
//explosion values
var/exp_heavy = 0
var/exp_light = 2
var/exp_flash = 3
var/exp_fire = 2
/obj/item/projectile/magic/aoe/fireball/on_hit(target)
. = ..()
var/turf/T = get_turf(target)
explosion(T, -1, exp_heavy, exp_light, exp_flash, 0, flame_range = exp_fire)
if(ismob(target)) //multiple flavors of pain
var/mob/living/M = target
M.take_overall_damage(0,10) //between this 10 burn, the 10 brute, the explosion brute, and the onfire burn, your at about 65 damage if you stop drop and roll immediately
/obj/item/projectile/magic/aoe/fireball/infernal
name = "infernal fireball"
exp_heavy = -1
exp_light = -1
exp_flash = 4
exp_fire= 5
@@ -684,6 +684,41 @@
animate(whole_screen, transform = matrix(), time = 5, easing = QUAD_EASING)
..()
/datum/reagent/toxin/skewium
name = "Skewium"
id = "skewium"
description = "A strange, dull coloured liquid that appears to warp back and forth inside its container. Causes any consumer to experience a visual phenomena similar to said warping."
reagent_state = LIQUID
color = "#ADBDCD"
metabolization_rate = 0.8 * REAGENTS_METABOLISM
toxpwr = 0.25
/datum/reagent/toxin/skewium/on_mob_life(mob/living/M)
if(M.hud_used)
if(current_cycle >= 5 && current_cycle % 3 == 0)
var/list/screens = list(M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
var/matrix/skew = matrix()
var/intensity = 8
skew.set_skew(rand(-intensity,intensity), rand(-intensity,intensity))
var/matrix/newmatrix = skew
if(prob(33)) // 1/3rd of the time, let's make it stack with the previous matrix! Mwhahahaha!
var/obj/screen/plane_master/PM = M.hud_used.plane_masters["[GAME_PLANE]"]
newmatrix = skew * PM.transform
for(var/whole_screen in screens)
animate(whole_screen, transform = newmatrix, time = 5, easing = QUAD_EASING, loop = -1)
animate(transform = -newmatrix, time = 5, easing = QUAD_EASING)
return ..()
/datum/reagent/toxin/skewium/on_mob_delete(mob/living/M)
if(M && M.hud_used)
var/list/screens = list(M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
for(var/whole_screen in screens)
animate(whole_screen, transform = matrix(), time = 5, easing = QUAD_EASING)
..()
/datum/reagent/toxin/anacea
name = "Anacea"
id = "anacea"
@@ -94,7 +94,14 @@
results = list("rotatium" = 3)
required_reagents = list("mindbreaker" = 1, "teslium" = 1, "neurotoxin2" = 1)
mix_message = "<span class='danger'>After sparks, fire, and the smell of mindbreaker, the mix is constantly spinning with no stop in sight.</span>"
/datum/chemical_reaction/skewium
name = "Skewium"
id = "Skewium"
results = list("skewium" = 5)
required_reagents = list("rotatium" = 2, "plasma" = 2, "sacid" = 1)
mix_message = "<span class='danger'>Wow! it turns out if you mix rotatium with some plasma and sulphuric acid, it gets even worse!</span>"
/datum/chemical_reaction/anacea
name = "Anacea"
id = "anacea"
@@ -84,6 +84,15 @@
build_path = /obj/item/weapon/aiModule/reset/purge
category = list("AI Modules")
/datum/design/board/remove_module
name = "Module Design (Law Removal)"
desc = "Allows for the construction of a Law Removal AI Core Module."
id = "remove_module"
req_tech = list("programming" = 5, "materials" = 5)
materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100)
build_path = /obj/item/weapon/aiModule/remove
category = list("AI Modules")
/datum/design/board/freeformcore_module
name = "AI Core Module (Freeform)"
desc = "Allows for the construction of a Freeform AI Core Module."
@@ -130,11 +139,13 @@
build_path = /obj/item/weapon/aiModule/core/full/corp
category = list("AI Modules")
/datum/design/board/custom_module
name = "Core Module Design (Custom)"
desc = "Allows for the construction of a Custom AI Core Module."
id = "custom_module"
/datum/design/board/default_module
name = "Core Module Design (Default)"
desc = "Allows for the construction of a Default AI Core Module."
id = "default_module"
req_tech = list("programming" = 5, "materials" = 5)
materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100)
build_path = /obj/item/weapon/aiModule/core/full/custom
category = list("AI Modules")

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