Merge remote-tracking branch 'upstream/master' into blood-changes

This commit is contained in:
Couls
2019-08-04 21:14:30 -04:00
275 changed files with 12340 additions and 5101 deletions
+2 -1
View File
@@ -254,7 +254,7 @@ CREATE TABLE `player` (
`UI_style_alpha` smallint(4) DEFAULT '255',
`be_role` mediumtext,
`default_slot` smallint(4) DEFAULT '1',
`toggles` mediumint(8) DEFAULT '383',
`toggles` int(8) DEFAULT '383',
`sound` mediumint(8) DEFAULT '31',
`randomslot` tinyint(1) DEFAULT '0',
`volume` smallint(4) DEFAULT '100',
@@ -268,6 +268,7 @@ CREATE TABLE `player` (
`atklog` smallint(4) DEFAULT '0',
`fuid` BIGINT(20) NULL DEFAULT NULL,
`fupdate` SMALLINT(4) NULL DEFAULT 0,
`afk_watch` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `ckey` (`ckey`)
) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=latin1;
+2 -1
View File
@@ -253,7 +253,7 @@ CREATE TABLE `SS13_player` (
`UI_style_alpha` smallint(4) DEFAULT '255',
`be_role` mediumtext,
`default_slot` smallint(4) DEFAULT '1',
`toggles` mediumint(8) DEFAULT '383',
`toggles` int(8) DEFAULT '383',
`sound` mediumint(8) DEFAULT '31',
`randomslot` tinyint(1) DEFAULT '0',
`volume` smallint(4) DEFAULT '100',
@@ -267,6 +267,7 @@ CREATE TABLE `SS13_player` (
`atklog` smallint(4) DEFAULT '0',
`fuid` BIGINT(20) NULL DEFAULT NULL,
`fupdate` SMALLINT(4) NULL DEFAULT 0,
`afk_watch` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `ckey` (`ckey`)
) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=latin1;
+2
View File
@@ -0,0 +1,2 @@
ALTER TABLE player
MODIFY COLUMN toggles int;
+2
View File
@@ -0,0 +1,2 @@
# Add afk_watch which gives users the option to make use of the AFK watcher subsystem
ALTER TABLE `player` ADD `afk_watch` tinyint(1) NOT NULL DEFAULT '0';
+92 -78
View File
@@ -6588,8 +6588,8 @@
d2 = 2
},
/obj/machinery/power/tracker,
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxstarboard)
"alE" = (
/obj/structure/closet/secure_closet/brig,
@@ -7012,8 +7012,8 @@
pixel_y = 0;
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxstarboard)
"amp" = (
/obj/structure/chair{
@@ -7391,8 +7391,8 @@
d2 = 2
},
/obj/machinery/power/tracker,
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxport)
"amV" = (
/obj/structure/sign/nosmoking_2,
@@ -7544,8 +7544,8 @@
/area/security/permabrig)
"ann" = (
/obj/structure/cable,
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxstarboard)
"ano" = (
/obj/structure/cable{
@@ -7791,8 +7791,8 @@
pixel_y = 0;
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxport)
"anH" = (
/turf/simulated/wall/r_wall,
@@ -8469,8 +8469,8 @@
icon_state = "2-4";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxstarboard)
"aoL" = (
/obj/structure/cable{
@@ -8845,8 +8845,8 @@
icon_state = "1-2";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxstarboard)
"apo" = (
/obj/structure/grille/broken,
@@ -9768,8 +9768,8 @@
},
/area/lawoffice)
"aqZ" = (
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxstarboard)
"ara" = (
/obj/structure/table/reinforced,
@@ -9796,8 +9796,8 @@
/area/lawoffice)
"arb" = (
/obj/structure/cable,
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxport)
"arc" = (
/obj/effect/spawner/window/reinforced,
@@ -10307,8 +10307,8 @@
icon_state = "2-4";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxport)
"arM" = (
/obj/structure/cable{
@@ -10330,16 +10330,16 @@
icon_state = "2-4";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxport)
"arN" = (
/obj/structure/cable{
d2 = 8;
icon_state = "0-8"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxport)
"arO" = (
/obj/structure/cable{
@@ -10411,8 +10411,8 @@
icon_state = "0-4";
d2 = 4
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxport)
"arV" = (
/obj/structure/shuttle/engine/propulsion{
@@ -10467,8 +10467,8 @@
/turf/simulated/shuttle/floor,
/area/shuttle/trade/sol)
"asb" = (
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxport)
"asc" = (
/obj/effect/spawner/random_barrier/obstruction,
@@ -11025,8 +11025,8 @@
icon_state = "1-8";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxport)
"asM" = (
/obj/structure/cable{
@@ -11041,8 +11041,8 @@
icon_state = "1-8";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxport)
"asN" = (
/turf/simulated/floor/carpet,
@@ -13086,8 +13086,8 @@
pixel_y = -25;
req_access_txt = "13"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space/nearstation)
"avN" = (
/obj/machinery/atmospherics/unary/vent_pump/on{
@@ -13434,8 +13434,8 @@
pixel_y = 1;
d2 = 2
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxport)
"awl" = (
/turf/simulated/wall,
@@ -13729,16 +13729,16 @@
d2 = 4;
icon_state = "2-4"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxstarboard)
"awR" = (
/obj/structure/cable{
d2 = 8;
icon_state = "0-8"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxstarboard)
"awS" = (
/obj/item/twohanded/required/kirbyplants,
@@ -14016,8 +14016,8 @@
icon_state = "1-2";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxstarboard)
"axr" = (
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
@@ -14826,8 +14826,8 @@
icon_state = "1-2";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/auxstarboard)
"ayF" = (
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
@@ -15170,8 +15170,8 @@
pixel_y = -25;
req_access_txt = "13"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space/nearstation)
"azc" = (
/obj/effect/spawner/window/reinforced,
@@ -16536,8 +16536,8 @@
pixel_y = 0;
req_access_txt = "13"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space/nearstation)
"aBy" = (
/obj/effect/landmark/damageturf,
@@ -18254,8 +18254,8 @@
pixel_y = -25;
req_access_txt = "13"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space/nearstation)
"aEN" = (
/obj/structure/closet/emcloset,
@@ -58234,6 +58234,9 @@
d2 = 4;
icon_state = "0-4"
},
/obj/effect/landmark/start{
name = "Shaft Miner"
},
/turf/simulated/floor/plasteel,
/area/quartermaster/miningdock)
"cbI" = (
@@ -60241,6 +60244,9 @@
/area/quartermaster/miningdock)
"cfc" = (
/obj/machinery/hologram/holopad,
/obj/effect/landmark/start{
name = "Shaft Miner"
},
/turf/simulated/floor/plasteel,
/area/quartermaster/miningdock)
"cfd" = (
@@ -63467,6 +63473,9 @@
pixel_x = 24
},
/obj/structure/disposalpipe/segment,
/obj/effect/landmark/start{
name = "Shaft Miner"
},
/turf/simulated/floor/plasteel,
/area/quartermaster/miningdock)
"ckp" = (
@@ -66610,8 +66619,8 @@
icon_state = "2-4";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/port)
"cpA" = (
/obj/effect/decal/warning_stripes/southwestcorner,
@@ -72259,8 +72268,8 @@
/turf/simulated/floor/plating,
/area/maintenance/asmaint)
"cyO" = (
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/port)
"cyP" = (
/obj/effect/spawner/random_barrier/obstruction,
@@ -79926,8 +79935,8 @@
icon_state = "1-2";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/port)
"cMC" = (
/obj/effect/landmark{
@@ -80473,8 +80482,8 @@
dir = 10;
level = 2
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space/nearstation)
"cNF" = (
/obj/structure/cable{
@@ -81479,13 +81488,13 @@
/area/assembly/assembly_line)
"cPw" = (
/obj/machinery/atmospherics/pipe/simple/visible/yellow,
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space/nearstation)
"cPx" = (
/obj/structure/cable,
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/port)
"cPy" = (
/obj/structure/table/reinforced,
@@ -81532,8 +81541,8 @@
icon_state = "0-4";
d2 = 4
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/port)
"cPD" = (
/obj/machinery/atmospherics/pipe/manifold/visible/yellow{
@@ -81578,24 +81587,24 @@
icon_state = "4-8";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/port)
"cPH" = (
/obj/structure/cable{
d2 = 8;
icon_state = "0-8"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/port)
"cPI" = (
/obj/structure/cable{
icon_state = "0-4";
d2 = 4
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/port)
"cPJ" = (
/obj/structure/table,
@@ -81778,8 +81787,8 @@
icon_state = "4-8";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/port)
"cQb" = (
/obj/machinery/particle_accelerator/control_box,
@@ -81913,8 +81922,8 @@
icon_state = "0-2";
d2 = 2
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/port)
"cQr" = (
/obj/structure/disposalpipe/segment{
@@ -82427,8 +82436,8 @@
icon_state = "1-2";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/port)
"cRf" = (
/obj/machinery/door/poddoor{
@@ -83122,8 +83131,8 @@
icon_state = "1-4";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/port)
"cSl" = (
/obj/machinery/atmospherics/unary/vent_pump/on,
@@ -84097,8 +84106,8 @@
pixel_y = 8;
req_access_txt = "13"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space/nearstation)
"cTS" = (
/obj/effect/landmark/burnturf,
@@ -84143,8 +84152,8 @@
/turf/simulated/floor/plasteel,
/area/maintenance/turbine)
"cTW" = (
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"cTX" = (
/obj/structure/cable{
@@ -86754,8 +86763,8 @@
pixel_x = -25;
pixel_y = -8
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space/nearstation)
"cYA" = (
/obj/structure/cable{
@@ -89325,8 +89334,8 @@
pixel_y = 0;
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"ddB" = (
/obj/structure/disposalpipe/segment{
@@ -89339,13 +89348,13 @@
/obj/structure/transit_tube{
icon_state = "E-W-Pass"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space)
"ddD" = (
/obj/item/wrench,
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space/nearstation)
"ddE" = (
/obj/structure/cable{
@@ -89355,8 +89364,8 @@
pixel_y = 0;
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"ddF" = (
/obj/structure/sign/biohazard{
@@ -89418,21 +89427,21 @@
pixel_y = 25;
req_access_txt = "75;13"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space/nearstation)
"ddN" = (
/obj/structure/cable,
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"ddO" = (
/obj/machinery/atmospherics/pipe/simple/visible/yellow{
dir = 6;
level = 2
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space/nearstation)
"ddP" = (
/obj/structure/cable{
@@ -89447,8 +89456,8 @@
icon_state = "1-4";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"ddQ" = (
/obj/structure/cable{
@@ -89470,16 +89479,16 @@
pixel_x = 0;
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"ddR" = (
/obj/structure/cable{
d2 = 8;
icon_state = "0-8"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"ddS" = (
/obj/structure/particle_accelerator/fuel_chamber,
@@ -89490,8 +89499,8 @@
icon_state = "0-4";
d2 = 4
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"ddU" = (
/obj/structure/cable{
@@ -89513,8 +89522,8 @@
pixel_x = 0;
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"ddV" = (
/obj/structure/cable{
@@ -89529,8 +89538,8 @@
icon_state = "2-8";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"ddW" = (
/obj/structure/shuttle/engine/propulsion/burst{
@@ -89553,8 +89562,8 @@
pixel_y = 25;
req_access_txt = "13"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space/nearstation)
"ddY" = (
/obj/structure/shuttle/engine/propulsion/burst{
@@ -89599,8 +89608,8 @@
d2 = 8;
icon_state = "2-8"
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"dec" = (
/obj/machinery/atmospherics/pipe/manifold/visible,
@@ -89611,8 +89620,8 @@
icon_state = "0-2";
d2 = 2
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"dee" = (
/obj/structure/cable{
@@ -89622,8 +89631,8 @@
pixel_x = 0;
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"def" = (
/obj/structure/cable{
@@ -89644,14 +89653,14 @@
icon_state = "1-2";
tag = ""
},
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"deg" = (
/obj/structure/cable,
/obj/machinery/power/tracker,
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/solar/starboard)
"deh" = (
/obj/machinery/space_heater,
@@ -93815,8 +93824,8 @@
/turf/simulated/floor/plating,
/area/maintenance/asmaint2)
"dmo" = (
/turf/space,
/obj/structure/lattice/catwalk,
/turf/space,
/area/space/nearstation)
"dmp" = (
/obj/structure/table,
@@ -95140,10 +95149,6 @@
/obj/item/crowbar,
/turf/simulated/floor/wood,
/area/crew_quarters/captain)
"doE" = (
/turf/space,
/obj/structure/lattice/catwalk,
/area/space/nearstation)
"doF" = (
/turf/simulated/floor/plating,
/area/toxins/launch{
@@ -96595,6 +96600,15 @@
icon_state = "floor4"
},
/area/shuttle/administration)
"qnV" = (
/obj/effect/landmark/start{
name = "Shaft Miner"
},
/turf/simulated/floor/plasteel{
dir = 8;
icon_state = "brown"
},
/area/quartermaster/miningdock)
"qUv" = (
/obj/machinery/atmospherics/pipe/simple/heat_exchanging,
/turf/space,
@@ -118177,7 +118191,7 @@ cam
cgH
cit
ckn
ckn
qnV
cnm
cam
cgQ
@@ -118432,7 +118446,7 @@ cam
cam
cam
cgG
cfb
cir
cfb
cnG
cnl
@@ -142392,7 +142406,7 @@ dnR
dnS
dnX
dom
doE
dmo
aab
aaa
aaa
@@ -142649,7 +142663,7 @@ bZZ
bZZ
bZZ
bZZ
doE
dmo
aab
aaa
aaa
@@ -149048,7 +149062,7 @@ aaa
aab
aaa
aaa
doE
dmo
aab
aaa
aaa
@@ -149305,7 +149319,7 @@ aaa
aab
aaa
aaa
doE
dmo
aab
aaa
aaa
@@ -149813,7 +149827,7 @@ aaa
aaa
aaa
aaa
doE
dmo
aaa
aaa
aaa
@@ -150070,7 +150084,7 @@ aaa
aaa
aaa
aaa
doE
dmo
aaa
aaa
aaa
@@ -150327,7 +150341,7 @@ aaa
aaa
aaa
aaa
doE
dmo
aaa
aaa
aaa
@@ -150584,7 +150598,7 @@ aaa
aaa
aaa
aaa
doE
dmo
aaa
aaa
aaa
@@ -150841,7 +150855,7 @@ aaa
aaa
aaa
aaa
doE
dmo
aaa
aaa
aaa
@@ -151098,7 +151112,7 @@ aaa
aaa
aaa
aaa
doE
dmo
aaa
aaa
aaa
+42 -46
View File
@@ -200,7 +200,8 @@
dir = 1;
pixel_y = -24
},
/turf/simulated/floor/mech_bay_recharge_floor,
/obj/machinery/suit_storage_unit/lavaland,
/turf/simulated/floor/plasteel,
/area/mine/eva)
"aJ" = (
/obj/machinery/light/small{
@@ -436,12 +437,6 @@
/turf/simulated/floor/plasteel/freezer,
/area/mine/living_quarters)
"bp" = (
/obj/structure/table,
/obj/item/pickaxe,
/obj/item/gps/mining,
/obj/item/gps/mining,
/obj/item/gps/mining,
/obj/item/gps/mining,
/obj/effect/turf_decal/tile/purple{
dir = 1
},
@@ -451,6 +446,7 @@
/obj/effect/turf_decal/tile/purple{
dir = 4
},
/obj/machinery/suit_storage_unit/lavaland,
/turf/simulated/floor/plasteel,
/area/mine/eva)
"bq" = (
@@ -594,11 +590,6 @@
/obj/machinery/light{
dir = 8
},
/obj/structure/table,
/obj/item/storage/toolbox/mechanical{
pixel_x = -2;
pixel_y = -1
},
/obj/effect/turf_decal/tile/brown{
dir = 8
},
@@ -611,7 +602,19 @@
/obj/effect/turf_decal/tile/purple{
dir = 8
},
/obj/machinery/suit_storage_unit/lavaland,
/obj/structure/table,
/obj/item/storage/toolbox/mechanical{
pixel_x = -2;
pixel_y = -1
},
/obj/item/gps/mining,
/obj/item/gps/mining,
/obj/item/gps/mining,
/obj/item/gps/mining,
/obj/item/gps/mining,
/obj/item/gps/mining,
/obj/item/gps/mining,
/obj/item/gps/mining,
/turf/simulated/floor/plasteel,
/area/mine/eva)
"bF" = (
@@ -758,9 +761,6 @@
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
dir = 4
},
/obj/structure/cable{
icon_state = "2-8"
},
/turf/simulated/floor/plasteel,
/area/mine/eva)
"bV" = (
@@ -943,16 +943,15 @@
pixel_y = -23
},
/obj/structure/cable,
/obj/machinery/recharge_station,
/obj/effect/turf_decal/tile/purple{
dir = 1
},
/obj/machinery/suit_storage_unit/lavaland,
/turf/simulated/floor/plasteel,
/area/mine/eva)
"cp" = (
/obj/machinery/mech_bay_recharge_port,
/obj/structure/cable,
/turf/simulated/floor/plating,
/obj/machinery/suit_storage_unit/lavaland,
/turf/simulated/floor/plasteel,
/area/mine/eva)
"cq" = (
/obj/effect/turf_decal/tile/brown{
@@ -977,9 +976,6 @@
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
dir = 4
},
/obj/structure/cable{
icon_state = "4-8"
},
/obj/effect/turf_decal/tile/brown{
dir = 1
},
@@ -1854,13 +1850,10 @@
/turf/simulated/wall,
/area/mine/production)
"eo" = (
/obj/machinery/computer/mech_bay_power_console{
icon_state = "computer";
dir = 1
},
/obj/effect/turf_decal/tile/purple{
dir = 4
},
/obj/machinery/suit_storage_unit/lavaland,
/turf/simulated/floor/plasteel,
/area/mine/eva)
"ep" = (
@@ -2023,6 +2016,9 @@
/obj/structure/cable{
icon_state = "1-8"
},
/obj/structure/cable{
icon_state = "2-8"
},
/turf/simulated/floor/plasteel,
/area/mine/production)
"eD" = (
@@ -2100,6 +2096,7 @@
/obj/effect/turf_decal/tile/brown{
dir = 8
},
/obj/structure/ore_box,
/turf/simulated/floor/plasteel,
/area/mine/production)
"eK" = (
@@ -2148,6 +2145,9 @@
/obj/machinery/atmospherics/unary/vent_pump/on{
dir = 1
},
/obj/structure/cable{
icon_state = "1-2"
},
/turf/simulated/floor/plasteel,
/area/mine/production)
"eQ" = (
@@ -2237,13 +2237,11 @@
dir = 1;
pixel_y = -22
},
/obj/structure/closet/crate{
icon_state = "crateopen"
},
/obj/effect/turf_decal/tile/purple{
dir = 8
},
/obj/effect/turf_decal/tile/purple,
/obj/machinery/recharge_station,
/turf/simulated/floor/plasteel,
/area/mine/production)
"fc" = (
@@ -2253,9 +2251,6 @@
/turf/simulated/floor/plasteel,
/area/mine/living_quarters)
"fd" = (
/obj/structure/closet/crate{
icon_state = "crateopen"
},
/obj/machinery/light,
/obj/effect/turf_decal/tile/brown{
dir = 8
@@ -2263,6 +2258,8 @@
/obj/effect/turf_decal/tile/brown{
dir = 2
},
/obj/machinery/mech_bay_recharge_port,
/obj/structure/cable,
/turf/simulated/floor/plasteel,
/area/mine/production)
"fe" = (
@@ -2290,12 +2287,7 @@
/turf/simulated/floor/plasteel,
/area/mine/living_quarters)
"fh" = (
/obj/structure/closet/crate,
/obj/effect/turf_decal/tile/purple{
dir = 8
},
/obj/effect/turf_decal/tile/purple,
/turf/simulated/floor/plasteel,
/turf/simulated/floor/mech_bay_recharge_floor,
/area/mine/production)
"fi" = (
/obj/machinery/atmospherics/pipe/manifold/hidden/supply{
@@ -2304,15 +2296,16 @@
/turf/simulated/floor/plasteel,
/area/mine/living_quarters)
"fj" = (
/obj/structure/closet/crate{
icon_state = "crateopen"
},
/obj/effect/turf_decal/tile/brown{
dir = 8
},
/obj/effect/turf_decal/tile/brown{
dir = 2
},
/obj/machinery/computer/mech_bay_power_console{
icon_state = "computer";
dir = 1
},
/turf/simulated/floor/plasteel,
/area/mine/production)
"fk" = (
@@ -2500,7 +2493,6 @@
/turf/simulated/floor/plasteel,
/area/mine/living_quarters)
"fE" = (
/obj/structure/ore_box,
/obj/effect/turf_decal/tile/purple{
dir = 8
},
@@ -2579,7 +2571,6 @@
/turf/simulated/floor/plasteel,
/area/mine/living_quarters)
"fL" = (
/obj/structure/ore_box,
/obj/effect/turf_decal/tile/brown{
dir = 8
},
@@ -2589,14 +2580,15 @@
/obj/effect/turf_decal/tile/brown{
dir = 2
},
/obj/structure/closet/secure_closet/miner,
/turf/simulated/floor/plasteel,
/area/mine/living_quarters)
"fM" = (
/obj/machinery/recharge_station,
/obj/effect/turf_decal/tile/purple,
/obj/effect/turf_decal/tile/purple{
dir = 8
},
/obj/structure/closet/secure_closet/miner,
/turf/simulated/floor/plasteel,
/area/mine/living_quarters)
"fN" = (
@@ -4090,6 +4082,10 @@
},
/turf/simulated/floor/plasteel/freezer,
/area/mine/living_quarters)
"tK" = (
/obj/structure/ore_box,
/turf/simulated/floor/plasteel,
/area/mine/production)
"vq" = (
/obj/machinery/atmospherics/unary/vent_scrubber/on,
/turf/simulated/floor/plasteel,
@@ -20710,7 +20706,7 @@ dL
ej
eG
ct
eW
tK
bN
ab
ab
+2 -1
View File
@@ -248,7 +248,8 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new())
// Ventcrawling
#define VENT_SOUND_DELAY 30
/obj/machinery/atmospherics/relaymove(mob/living/user, direction)
if(!(direction & initialize_directions)) //can't go in a way we aren't connecting to
direction &= initialize_directions
if(!direction || !(direction in cardinal)) //cant go this way.
return
if(buckled_mob == user)
+54
View File
@@ -0,0 +1,54 @@
#define COLOR_INPUT_DISABLED "#F0F0F0"
#define COLOR_INPUT_ENABLED "#D3B5B5"
#define COLOR_WHITE "#EEEEEE"
#define COLOR_SILVER "#C0C0C0"
#define COLOR_GRAY "#808080"
#define COLOR_FLOORTILE_GRAY "#8D8B8B"
#define COLOR_ALMOST_BLACK "#333333"
#define COLOR_BLACK "#000000"
#define COLOR_RED "#FF0000"
#define COLOR_RED_LIGHT "#FF3333"
#define COLOR_MAROON "#800000"
#define COLOR_YELLOW "#FFFF00"
#define COLOR_OLIVE "#808000"
#define COLOR_LIME "#32CD32"
#define COLOR_GREEN "#008000"
#define COLOR_CYAN "#00FFFF"
#define COLOR_TEAL "#008080"
#define COLOR_BLUE "#0000FF"
#define COLOR_BLUE_LIGHT "#33CCFF"
#define COLOR_NAVY "#000080"
#define COLOR_PINK "#FFC0CB"
#define COLOR_MAGENTA "#FF00FF"
#define COLOR_PURPLE "#800080"
#define COLOR_ORANGE "#FF9900"
#define COLOR_BEIGE "#CEB689"
#define COLOR_BLUE_GRAY "#75A2BB"
#define COLOR_BROWN "#BA9F6D"
#define COLOR_DARK_BROWN "#997C4F"
#define COLOR_DARK_ORANGE "#C3630C"
#define COLOR_GREEN_GRAY "#99BB76"
#define COLOR_RED_GRAY "#B4696A"
#define COLOR_PALE_BLUE_GRAY "#98C5DF"
#define COLOR_PALE_GREEN_GRAY "#B7D993"
#define COLOR_PALE_RED_GRAY "#D59998"
#define COLOR_PALE_PURPLE_GRAY "#CBB1CA"
#define COLOR_PURPLE_GRAY "#AE8CA8"
//Color defines used by the assembly detailer.
#define COLOR_ASSEMBLY_BLACK "#545454"
#define COLOR_ASSEMBLY_BGRAY "#9497AB"
#define COLOR_ASSEMBLY_WHITE "#E2E2E2"
#define COLOR_ASSEMBLY_RED "#CC4242"
#define COLOR_ASSEMBLY_ORANGE "#E39751"
#define COLOR_ASSEMBLY_BEIGE "#AF9366"
#define COLOR_ASSEMBLY_BROWN "#97670E"
#define COLOR_ASSEMBLY_GOLD "#AA9100"
#define COLOR_ASSEMBLY_YELLOW "#CECA2B"
#define COLOR_ASSEMBLY_GURKHA "#999875"
#define COLOR_ASSEMBLY_LGREEN "#789876"
#define COLOR_ASSEMBLY_GREEN "#44843C"
#define COLOR_ASSEMBLY_LBLUE "#5D99BE"
#define COLOR_ASSEMBLY_BLUE "#38559E"
#define COLOR_ASSEMBLY_PURPLE "#6F6192"
+20
View File
@@ -70,6 +70,10 @@
#define ATTACK_EFFECT_MECHFIRE "mech_fire"
#define ATTACK_EFFECT_MECHTOXIN "mech_toxin"
#define ATTACK_EFFECT_BOOP "boop" //Honk
//NOTE: INTENT_HOTKEY_* defines are not actual intents!
//they are here to support hotkeys
#define INTENT_HOTKEY_LEFT "left"
#define INTENT_HOTKEY_RIGHT "right"
//Embedded objects
#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user)
@@ -82,6 +86,22 @@
#define EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER 8 //Coefficient of multiplication for the damage the item does when removed without a surgery (this*item.w_class)
#define EMBEDDED_UNSAFE_REMOVAL_TIME 30 //A Time in ticks, total removal time = (this*item.w_class)
// Body Parts
#define BODY_ZONE_HEAD "head"
#define BODY_ZONE_CHEST "chest"
#define BODY_ZONE_L_ARM "l_arm"
#define BODY_ZONE_R_ARM "r_arm"
#define BODY_ZONE_L_LEG "l_leg"
#define BODY_ZONE_R_LEG "r_leg"
#define BODY_ZONE_PRECISE_EYES "eyes"
#define BODY_ZONE_PRECISE_MOUTH "mouth"
#define BODY_ZONE_PRECISE_GROIN "groin"
#define BODY_ZONE_PRECISE_L_HAND "l_hand"
#define BODY_ZONE_PRECISE_R_HAND "r_hand"
#define BODY_ZONE_PRECISE_L_FOOT "l_foot"
#define BODY_ZONE_PRECISE_R_FOOT "r_foot"
//Gun Stuff
#define SAWN_INTACT 0
#define SAWN_OFF 1
+3
View File
@@ -1,6 +1,9 @@
#define ALL ~0 //For convenience.
#define NONE 0
// for /datum/var/datum_flags
#define DF_USE_TAG (1<<0)
//FLAGS BITMASK
#define STOPSPRESSUREDMAGE 1 //This flag is used on the flags variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere To successfully stop you taking all pressure damage you must have both a suit and head item with this flag.
#define NODROP 2 // This flag makes it so that an item literally cannot be removed at all, or at least that's how it should be. Only deleted.
+1 -12
View File
@@ -57,17 +57,6 @@
#define MAX_STACK_AMOUNT_GLASS 50
#define MAX_STACK_AMOUNT_RODS 60
//some colors
#define COLOR_RED "#FF0000"
#define COLOR_GREEN "#00FF00"
#define COLOR_BLUE "#0000FF"
#define COLOR_CYAN "#00FFFF"
#define COLOR_PINK "#FF00FF"
#define COLOR_YELLOW "#FFFF00"
#define COLOR_ORANGE "#FF9900"
#define COLOR_WHITE "#FFFFFF"
#define COLOR_GRAY "#808080"
//FONTS:
// Used by Paper and PhotoCopier (and PaperBin once a year).
// Used by PDA's Notekeeper.
@@ -328,7 +317,7 @@
#define INVESTIGATE_BOMB "bombs"
// The SQL version required by this version of the code
#define SQL_VERSION 6
#define SQL_VERSION 8
// Vending machine stuff
#define CAT_NORMAL 1
+5 -2
View File
@@ -16,6 +16,7 @@
#define CHAT_GHOSTSIGHT 8
#define CHAT_PRAYER 16
#define CHAT_RADIO 32
#define AZERTY 64
#define CHAT_DEBUGLOGS 128
#define CHAT_LOOC 256
#define CHAT_GHOSTRADIO 512
@@ -31,10 +32,12 @@
#define CHAT_NO_MENTORTICKETLOGS 524288
#define TYPING_ONCE 1048576
#define AMBIENT_OCCLUSION 2097152
#define CHAT_GHOSTPDA 4194304
#define NUMPAD_TARGET 8388608
#define TOGGLES_TOTAL 16777215 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined.
#define TOGGLES_TOTAL 4194303 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined.
#define TOGGLES_DEFAULT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_LOOC|MEMBER_PUBLIC|DONATOR_PUBLIC|AMBIENT_OCCLUSION)
#define TOGGLES_DEFAULT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_LOOC|MEMBER_PUBLIC|DONATOR_PUBLIC|AMBIENT_OCCLUSION|CHAT_GHOSTPDA|NUMPAD_TARGET)
// Admin attack logs filter system, see /proc/add_attack_logs and /proc/msg_admin_attack
#define ATKLOG_ALL 0
+2 -2
View File
@@ -353,12 +353,12 @@
var/middle = L.len / 2 + 1 // Copy is first,second-1
return mergeLists(sortList(L.Copy(0,middle)), sortList(L.Copy(middle))) //second parameter null = to end of list
//Mergsorge: uses sortList() but uses the var's name specifically. This should probably be using mergeAtom() instead
//Mergsorge: uses sortAssoc() but uses the var's name specifically. This should probably be using mergeAtom() instead
/proc/sortNames(var/list/L)
var/list/Q = new()
for(var/atom/x in L)
Q[x.name] = x
return sortList(Q)
return sortAssoc(Q)
/proc/mergeLists(var/list/L, var/list/R)
var/Li=1
+8 -8
View File
@@ -43,7 +43,7 @@
. = "e[.]"
//like clients, which do have gender.
/client/proc/p_they(capitalized, temp_gender)
/client/p_they(capitalized, temp_gender)
if(!temp_gender)
temp_gender = gender
. = "they"
@@ -55,7 +55,7 @@
if(capitalized)
. = capitalize(.)
/client/proc/p_their(capitalized, temp_gender)
/client/p_their(capitalized, temp_gender)
if(!temp_gender)
temp_gender = gender
. = "their"
@@ -67,7 +67,7 @@
if(capitalized)
. = capitalize(.)
/client/proc/p_them(capitalized, temp_gender)
/client/p_them(capitalized, temp_gender)
if(!temp_gender)
temp_gender = gender
. = "them"
@@ -79,35 +79,35 @@
if(capitalized)
. = capitalize(.)
/client/proc/p_have(temp_gender)
/client/p_have(temp_gender)
if(!temp_gender)
temp_gender = gender
. = "has"
if(temp_gender == PLURAL || temp_gender == NEUTER)
. = "have"
/client/proc/p_are(temp_gender)
/client/p_are(temp_gender)
if(!temp_gender)
temp_gender = gender
. = "is"
if(temp_gender == PLURAL || temp_gender == NEUTER)
. = "are"
/client/proc/p_were(temp_gender)
/client/p_were(temp_gender)
if(!temp_gender)
temp_gender = gender
. = "was"
if(temp_gender == PLURAL || temp_gender == NEUTER)
. = "were"
/client/proc/p_do(temp_gender)
/client/p_do(temp_gender)
if(!temp_gender)
temp_gender = gender
. = "does"
if(temp_gender == PLURAL || temp_gender == NEUTER)
. = "do"
/client/proc/p_s(temp_gender)
/client/p_s(temp_gender)
if(!temp_gender)
temp_gender = gender
if(temp_gender != PLURAL && temp_gender != NEUTER)
+11
View File
@@ -157,6 +157,17 @@
if(degree < 315) return WEST
return NORTH|WEST
/proc/angle2dir_cardinal(angle)
switch(round(angle, 0.1))
if(315.5 to 360, 0 to 45.5)
return NORTH
if(45.6 to 135.5)
return EAST
if(135.6 to 225.5)
return SOUTH
if(225.6 to 315.5)
return WEST
//returns the north-zero clockwise angle in degrees, given a direction
/proc/dir2angle(var/D)
+1 -7
View File
@@ -16,7 +16,7 @@
var/global/next_unique_datum_id = 1
/client/var/tmp/unique_datum_id = null
// /client/var/tmp/unique_datum_id = null
/datum/proc/UID()
if(!unique_datum_id)
@@ -26,12 +26,6 @@ var/global/next_unique_datum_id = 1
tag = tag_backup
return unique_datum_id
/client/proc/UID()
if(!unique_datum_id)
unique_datum_id = "\ref[src]_[next_unique_datum_id++]"
return unique_datum_id
/proc/locateUID(uid)
if(!istext(uid))
return null
+2065 -2065
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -12,6 +12,7 @@ GLOBAL_LIST_INIT(mime_names, file2list("config/names/mime.txt"))
GLOBAL_LIST_INIT(golem_names, file2list("config/names/golem.txt"))
GLOBAL_LIST_INIT(verbs, file2list("config/names/verbs.txt"))
GLOBAL_LIST_INIT(nouns, file2list("config/names/nouns.txt"))
GLOBAL_LIST_INIT(adjectives, file2list("config/names/adjectives.txt"))
GLOBAL_LIST_INIT(dream_strings, file2list("config/names/dreams.txt"))
GLOBAL_LIST_INIT(nightmare_strings, file2list("config/names/nightmares.txt"))
+20 -9
View File
@@ -1,4 +1,3 @@
/obj/screen/movable/action_button
var/datum/action/linked_action
screen_loc = null
@@ -6,18 +5,26 @@
/obj/screen/movable/action_button/Click(location,control,params)
var/list/modifiers = params2list(params)
if(modifiers["shift"])
moved = 0
if(locked)
to_chat(usr, "<span class='warning'>Action button \"[name]\" is locked, unlock it first.</span>")
return TRUE
moved = FALSE
usr.update_action_buttons() //redraw buttons that are no longer considered "moved"
return 1
if(usr.next_move >= world.time) // Is this needed ?
return TRUE
if(modifiers["ctrl"])
locked = !locked
to_chat(usr, "<span class='notice'>Action button \"[name]\" [locked ? "" : "un"]locked.</span>")
return TRUE
if(usr.next_click > world.time)
return
usr.next_click = world.time + 1
linked_action.Trigger()
return 1
return TRUE
//Hide/Show Action Buttons ... Button
/obj/screen/movable/action_button/hide_toggle
name = "Hide Buttons"
desc = "Shift-click any button to reset its position. Alt-click to reset all buttons to their default positions."
desc = "Shift-click any button to reset its position, and Control-click it to lock/unlock its position. Alt-click this button to reset all buttons to their default positions."
icon = 'icons/mob/actions/actions.dmi'
icon_state = "bg_default"
var/hidden = 0
@@ -25,9 +32,16 @@
/obj/screen/movable/action_button/hide_toggle/Click(location,control,params)
var/list/modifiers = params2list(params)
if(modifiers["shift"])
if(locked)
to_chat(usr, "<span class='warning'>Action button \"[name]\" is locked, unlock it first.</span>")
return TRUE
moved = FALSE
usr.update_action_buttons(TRUE)
return TRUE
if(modifiers["ctrl"])
locked = !locked
to_chat(usr, "<span class='notice'>Action button \"[name]\" [locked ? "" : "un"]locked.</span>")
return TRUE
if(modifiers["alt"])
for(var/V in usr.actions)
var/datum/action/A = V
@@ -69,7 +83,6 @@
var/image/img = image(icon, src, hidden ? "show" : "hide")
overlays += img
/obj/screen/movable/action_button/MouseEntered(location,control,params)
openToolTip(usr,src,params,title = name,content = desc)
@@ -77,7 +90,6 @@
/obj/screen/movable/action_button/MouseExited()
closeToolTip(usr)
/mob/proc/update_action_buttons_icon()
for(var/X in actions)
var/datum/action/A = X
@@ -122,7 +134,6 @@
client.screen += hud_used.hide_actions_toggle
#define AB_MAX_COLUMNS 10
/datum/hud/proc/ButtonNumberToScreenCoords(number) // TODO : Make this zero-indexed for readabilty
+35
View File
@@ -177,6 +177,41 @@
desc = "You're severely malnourished. The hunger pains make moving around a chore."
icon_state = "starving"
///Vampire "hunger"
/obj/screen/alert/fat/vampire
name = "Fat"
desc = "You somehow drank too much blood, lardass. Run around the station and lose some weight."
icon_state = "v_fat"
/obj/screen/alert/full/vampire
name = "Full"
desc = "You feel full and satisfied, but you know you will thirst for more blood soon..."
icon_state = "v_full"
/obj/screen/alert/well_fed/vampire
name = "Well Fed"
desc = "You feel quite satisfied, but you could do with a bit more blood."
icon_state = "v_well_fed"
/obj/screen/alert/fed/vampire
name = "Fed"
desc = "You feel moderately satisfied, but a bit more blood wouldn't hurt."
icon_state = "v_fed"
/obj/screen/alert/hungry/vampire
name = "Hungry"
desc = "You currently thirst for blood."
icon_state = "v_hungry"
/obj/screen/alert/starving/vampire
name = "Starving"
desc = "You're severely thirsty. The thirst pains make moving around a chore."
icon_state = "v_starving"
//End of Vampire "hunger"
/obj/screen/alert/hot
name = "Too Hot"
desc = "You're flaming hot! Get somewhere cooler and take off any insulating clothing like a fire suit."
+5 -4
View File
@@ -11,6 +11,7 @@
/obj/screen/movable
var/snap2grid = FALSE
var/moved = FALSE
var/locked = TRUE
var/x_off = -16
var/y_off = -16
@@ -20,8 +21,10 @@
/obj/screen/movable/snap
snap2grid = TRUE
/obj/screen/movable/MouseDrop(over_object, src_location, over_location, src_control, over_control, params)
if(locked) //no! I am locked! begone!
return
var/list/PM = params2list(params)
//No screen-loc information? abort.
@@ -47,7 +50,6 @@
moved = screen_loc
//Debug procs
/client/proc/test_movable_UI()
set category = "Debug"
@@ -67,7 +69,6 @@
screen += M
/client/proc/test_snap_UI()
set category = "Debug"
set name = "Spawn Snap UI Object"
@@ -84,4 +85,4 @@
S.screen_loc = screen_l
screen += S
screen += S
+6 -3
View File
@@ -453,7 +453,6 @@
/obj/screen/healths/corgi
icon = 'icons/mob/screen_corgi.dmi'
/obj/screen/healths/guardian
name = "summoner health"
icon = 'icons/mob/guardian.dmi'
@@ -467,14 +466,18 @@
screen_loc = ui_healthdoll
var/list/cached_healthdoll_overlays = list() // List of icon states (strings) for overlays
/obj/screen/healthdoll/Click()
if(ishuman(usr))
var/mob/living/carbon/H = usr
H.check_self_for_injuries()
/obj/screen/component_button
var/obj/screen/parent
/obj/screen/component_button/Initialize(mapload, obj/screen/new_parent)
. = ..()
parent = new_parent
/obj/screen/component_button/Click(params)
if(parent)
parent.component_click(src, params)
parent.component_click(src, params)
+12
View File
@@ -72,6 +72,11 @@
var/assistantlimit = 0 //enables assistant limiting
var/assistantratio = 2 //how many assistants to security members
// The AFK subsystem will not be activated if any of the below config values are equal or less than 0
var/warn_afk_minimum = 0 // How long till you get a warning while being AFK
var/auto_cryo_afk = 0 // How long till you get put into cryo when you're AFK
var/auto_despawn_afk = 0 // How long till you actually despawn in cryo when you're AFK (Not ssd so not automatic)
var/auto_cryo_ssd_mins = 0
var/ssd_warning = 0
@@ -314,6 +319,13 @@
if("shadowling_max_age")
config.shadowling_max_age = text2num(value)
if("warn_afk_minimum")
config.warn_afk_minimum = text2num(value)
if("auto_cryo_afk")
config.auto_cryo_afk = text2num(value)
if("auto_despawn_afk")
config.auto_despawn_afk = text2num(value)
if("auto_cryo_ssd_mins")
config.auto_cryo_ssd_mins = text2num(value)
if("ssd_warning")
+81
View File
@@ -0,0 +1,81 @@
#define AFK_WARNED 1
#define AFK_CRYOD 2
SUBSYSTEM_DEF(afk)
name = "AFK Watcher"
wait = 300
flags = SS_BACKGROUND
var/list/afk_players = list() // Associative list. ckey as key and AFK state as value
/datum/controller/subsystem/afk/Initialize()
if(config.warn_afk_minimum <= 0 || config.auto_cryo_afk <= 0 || config.auto_despawn_afk <= 0)
flags |= SS_NO_FIRE
/datum/controller/subsystem/afk/fire()
var/list/toRemove = list()
for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
if(!H.ckey) // Useless non ckey creatures
continue
var/turf/T
// Only players and players with the AFK watch enabled
// No dead, unconcious, restrained, people without jobs, people on other Z levels than the station or antags
if(!H.client || !H.client.prefs.afk_watch || !H.mind || \
H.stat || H.restrained() || !H.job || H.mind.special_role || \
!is_station_level((T = get_turf(H)).z)) // Assign the turf as last. Small optimization
if(afk_players[H.ckey])
toRemove += H.ckey
continue
var/mins_afk = round(H.client.inactivity / 600)
if(mins_afk < config.warn_afk_minimum)
if(afk_players[H.ckey])
toRemove += H.ckey
continue
if(!afk_players[H.ckey])
afk_players[H.ckey] = AFK_WARNED
warn(H, "<span class='danger'>You are AFK for [mins_afk] minutes. You will be cryod after [config.auto_cryo_afk] total minutes and fully despawned after [config.auto_despawn_afk] total minutes. Please move or click in game if you want to avoid being despawned.</span>")
else
var/area/A = T.loc // Turfs loc is the area
if(afk_players[H.ckey] == AFK_WARNED)
if(mins_afk >= config.auto_cryo_afk && A.can_get_auto_cryod)
if(A.fast_despawn)
toRemove += H.ckey
warn(H, "<span class='danger'>You are have been despawned after being AFK for [mins_afk] minutes. You have been despawned instantly due to you being in a secure area.</span>")
msg_admins(H, mins_afk, T, "forcefully despawned", "AFK in a fast despawn area")
force_cryo_human(H)
else if(cryo_ssd(H))
afk_players[H.ckey] = AFK_CRYOD
msg_admins(H, mins_afk, T, "put into cryostorage")
warn(H, "<span class='danger'>You are AFK for [mins_afk] minutes and have been moved to cryostorage. After being AFK for [config.auto_despawn_afk] total minutes you will be fully despawned. Please eject yourself (right click, eject) out of the cryostorage if you want to avoid being despawned.</span>")
else if(mins_afk >= config.auto_despawn_afk)
var/obj/machinery/cryopod/P = H.loc
msg_admins(H, mins_afk, T, "forcefully despawned")
warn(H, "<span class='danger'>You are have been despawned after being AFK for [mins_afk] minutes.</span>")
toRemove += H.ckey
P.despawn_occupant()
removeFromWatchList(toRemove)
/datum/controller/subsystem/afk/proc/warn(mob/living/carbon/human/H, text)
to_chat(H, text)
SEND_SOUND(H, 'sound/effects/adminhelp.ogg')
if(H.client)
window_flash(H.client)
/datum/controller/subsystem/afk/proc/msg_admins(mob/living/carbon/human/H, mins_afk, turf/location, action, info)
log_admin("[key_name(H)] has been [action] by the AFK Watcher subsystem after being AFK for [mins_afk] minutes.[info ? " Extra info:" + info : ""]")
message_admins("[key_name_admin(H)] at ([get_area(location).name] [ADMIN_JMP(location)]) has been [action] by the AFK Watcher subsystem after being AFK for [mins_afk] minutes.[info ? " Extra info:" + info : ""]")
/datum/controller/subsystem/afk/proc/removeFromWatchList(list/toRemove)
for(var/C in toRemove)
for(var/i in 1 to afk_players.len)
if(afk_players[i] == C)
afk_players.Cut(i, i + 1)
break
#undef AFK_WARNED
#undef AFK_CRYOD
+122
View File
@@ -0,0 +1,122 @@
SUBSYSTEM_DEF(input)
name = "Input"
wait = 1 //SS_TICKER means this runs every tick
init_order = INIT_ORDER_INPUT
flags = SS_TICKER
priority = FIRE_PRIORITY_INPUT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
var/list/macro_sets
var/list/movement_keys
var/list/alt_movement_keys
/datum/controller/subsystem/input/Initialize()
setup_default_macro_sets()
setup_default_movement_keys()
initialized = TRUE
refresh_client_macro_sets()
return ..()
// This is for when macro sets are eventualy datumized
/datum/controller/subsystem/input/proc/setup_default_macro_sets()
var/list/static/default_macro_sets
if(default_macro_sets)
macro_sets = default_macro_sets
return
default_macro_sets = list(
"default" = list(
"Tab" = "\".winset \\\"input.focus=true?map.focus=true input.background-color=[COLOR_INPUT_DISABLED]:input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"",
"O" = "ooc",
"T" = ".say",
"M" = ".me",
"Back" = "\".winset \\\"input.focus=true input.text=\\\"\\\"\\\"\"", // This makes it so backspace can remove default inputs
"Any" = "\"KeyDown \[\[*\]\]\"",
"Any+UP" = "\"KeyUp \[\[*\]\]\"",
),
"old_default" = list(
"Tab" = "\".winset \\\"mainwindow.macro=old_hotkeys map.focus=true input.background-color=[COLOR_INPUT_DISABLED]\\\"\"",
"Ctrl+T" = ".say",
"Ctrl+O" = "ooc",
),
"old_hotkeys" = list(
"Tab" = "\".winset \\\"mainwindow.macro=old_default input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"",
"O" = "ooc",
"T" = ".say",
"M" = ".me",
"Back" = "\".winset \\\"input.focus=true input.text=\\\"\\\"\\\"\"", // This makes it so backspace can remove default inputs
"Any" = "\"KeyDown \[\[*\]\]\"",
"Any+UP" = "\"KeyUp \[\[*\]\]\"",
),
)
// Because i'm lazy and don't want to type all these out twice
var/list/old_default = default_macro_sets["old_default"]
var/list/static/oldmode_keys = list(
"North", "East", "South", "West",
"Northeast", "Southeast", "Northwest", "Southwest",
"Insert", "Delete", "Ctrl", "Alt",
"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
)
for(var/i in 1 to oldmode_keys.len)
var/key = oldmode_keys[i]
old_default[key] = "\"KeyDown [key]\""
old_default["[key]+UP"] = "\"KeyUp [key]\""
var/list/static/oldmode_ctrl_override_keys = list(
"W" = "W", "A" = "A", "S" = "S", "D" = "D", // movement
"1" = "1", "2" = "2", "3" = "3", "4" = "4", // intent
"B" = "B", // resist
"E" = "E", // quick equip
"F" = "F", // intent left
"G" = "G", // intent right
"H" = "H", // stop pulling
"Q" = "Q", // drop
"R" = "R", // throw
"X" = "X", // switch hands
"Y" = "Y", // activate item
"Z" = "Z", // activate item
)
for(var/i in 1 to oldmode_ctrl_override_keys.len)
var/key = oldmode_ctrl_override_keys[i]
var/override = oldmode_ctrl_override_keys[key]
old_default["Ctrl+[key]"] = "\"KeyDown [override]\""
old_default["Ctrl+[key]+UP"] = "\"KeyUp [override]\""
macro_sets = default_macro_sets
// For initially setting up or resetting to default the movement keys
/datum/controller/subsystem/input/proc/setup_default_movement_keys()
var/static/list/default_movement_keys = list(
"W" = NORTH, "A" = WEST, "S" = SOUTH, "D" = EAST, // WASD
"North" = NORTH, "West" = WEST, "South" = SOUTH, "East" = EAST, // Arrow keys & Numpad
)
var/static/list/azerty_movement_keys = list(
"Z" = NORTH, "Q" = WEST, "S" = SOUTH, "D" = EAST, // WASD
"North" = NORTH, "West" = WEST, "South" = SOUTH, "East" = EAST, // Arrow keys & Numpad
)
movement_keys = default_movement_keys.Copy()
alt_movement_keys = azerty_movement_keys.Copy()
// Badmins just wanna have fun ♪
/datum/controller/subsystem/input/proc/refresh_client_macro_sets()
var/list/clients = GLOB.clients
for(var/i in 1 to clients.len)
var/client/user = clients[i]
user.set_macros()
/datum/controller/subsystem/input/fire()
var/list/clients = GLOB.clients // Let's sing the list cache song
if(listclearnulls(clients)) // clear nulls before we run keyloop
log_world("Found a null in clients list!")
for(var/i in 1 to clients.len)
var/client/C = clients[i]
C.keyLoop()
+3 -3
View File
@@ -25,9 +25,9 @@ SUBSYSTEM_DEF(jobs)
// Only fires every 5 minutes
/datum/controller/subsystem/jobs/fire()
if(!config.sql_enabled || !config.use_exp_tracking)
return
return
update_exp(5,0)
/datum/controller/subsystem/jobs/proc/SetupOccupations(var/list/faction = list("Station"))
occupations = list()
var/list/all_jobs = subtypesof(/datum/job)
@@ -284,7 +284,7 @@ SUBSYSTEM_DEF(jobs)
//Get the players who are ready
for(var/mob/new_player/player in GLOB.player_list)
if(player.ready && player.mind && !player.mind.assigned_role)
if(player.ready && player.has_valid_preferences() && player.mind && !player.mind.assigned_role)
unassigned += player
if(player.client.prefs.randomslot)
player.client.prefs.load_random_character_slot(player.client)
+4 -1
View File
@@ -21,7 +21,7 @@
/client/proc/debug_controller(controller in list("failsafe", "Master", "Ticker", "Air", "Jobs", "Sun", "Radio", "Configuration", "pAI",
"Cameras", "Garbage", "Event", "Alarm", "Nano", "Vote", "Fires",
"Mob", "NPC Pool", "Shuttle", "Timer", "Weather", "Space", "Mob Hunt Server"))
"Mob", "NPC Pool", "Shuttle", "Timer", "Weather", "Space", "Mob Hunt Server","Input"))
set category = "Debug"
set name = "Debug Controller"
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
@@ -97,5 +97,8 @@
if("Mob Hunt Server")
debug_variables(SSmob_hunt)
feedback_add_details("admin_verb","DMobHuntServer")
if("Input")
debug_variables(SSinput)
feedback_add_details("admin_verb","DInput")
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
+2
View File
@@ -43,6 +43,7 @@
M.actions += src
if(M.client)
M.client.screen += button
button.locked = TRUE
M.update_action_buttons()
/datum/action/proc/Remove(mob/M)
@@ -52,6 +53,7 @@
if(M.client)
M.client.screen -= button
button.moved = FALSE //so the button appears in its normal position when given to another owner.
button.locked = FALSE
M.actions -= src
M.update_action_buttons()
+1 -1
View File
@@ -5,8 +5,8 @@
var/list/comp_lookup
var/list/signal_procs
var/signal_enabled = FALSE
var/datum_flags = NONE
var/var_edited = FALSE //Warranty void if seal is broken
var/tmp/unique_datum_id = null
#ifdef TESTING
+5 -15
View File
@@ -3,8 +3,8 @@
/datum/proc/can_vv_get(var_name)
return TRUE
/client/proc/can_vv_get(var_name)
return TRUE
// /client/proc/can_vv_get(var_name)
// return TRUE
/datum/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited
switch(var_name)
@@ -18,7 +18,7 @@
. = TRUE
/client/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited
/client/vv_edit_var(var_name, var_value) //called whenever a var is edited
switch(var_name)
if("vars")
return FALSE
@@ -37,7 +37,7 @@
return debug_variable(var_name, list(), 0, src)
return debug_variable(var_name, vars[var_name], 0, src)
/client/proc/vv_get_var(var_name)
/client/vv_get_var(var_name)
switch(var_name)
if("vars")
return debug_variable(var_name, list(), 0, src)
@@ -57,7 +57,7 @@
.["Delete"] = "?_src_=vars;delete=[UID()]"
. += "---"
/client/proc/vv_get_dropdown()
/client/vv_get_dropdown()
. = list()
. += "---"
.["Call Proc"] = "?_src_=vars;proc_call=[UID()]"
@@ -1019,16 +1019,6 @@
return
holder.Topic(href, list("makeai"=href_list["makeai"]))
else if(href_list["makemask"])
if(!check_rights(R_SPAWN)) return
var/mob/currentMob = locateUID(href_list["makemask"])
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
if(!currentMob)
to_chat(usr, "Mob doesn't exist anymore")
return
holder.Topic(href, list("makemask"=href_list["makemask"]))
else if(href_list["setspecies"])
if(!check_rights(R_SPAWN)) return
-27
View File
@@ -1,27 +0,0 @@
/datum/hotkey_mode
var/name
var/macro_hotkeys_inactive
var/macro_hotkeys_active
var/mob/my_mob
/datum/hotkey_mode/New(mob)
my_mob = mob
/datum/hotkey_mode/proc/set_winset_values()
winset(my_mob, null, "mainwindow.macro=[macro_hotkeys_inactive] hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5")
winset(my_mob, null, "hotkey_toggle.command=\".winset \\\"mainwindow.macro != [macro_hotkeys_inactive] ? mainwindow.macro=[macro_hotkeys_inactive] hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5 : mainwindow.macro=[macro_hotkeys_active] hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#f0f0f0\\\"\"")
/datum/hotkey_mode/qwerty
name = "QWERTY"
macro_hotkeys_inactive = "macro"
macro_hotkeys_active = "hotkeymode"
/datum/hotkey_mode/azerty
name = "AZERTY"
macro_hotkeys_inactive = "azertymacro"
macro_hotkeys_active = "azertyhotkeymode"
/datum/hotkey_mode/cyborg
name = "Cyborg"
macro_hotkeys_inactive = "borgmacro"
macro_hotkeys_active = "borghotkeymode"
+81 -21
View File
@@ -1,71 +1,90 @@
/proc/input_async(mob/user=usr, prompt, list/choices)
var/datum/async_input/A = new(choices, prompt)
A.show(user)
var/datum/async_input/A = new(choices, prompt, , user)
A.show()
return A
/proc/input_ranked_async(mob/user=usr, prompt="Order by greatest to least preference", list/choices)
var/datum/async_input/ranked/A = new(choices, prompt)
A.show(user)
var/datum/async_input/ranked/A = new(choices, prompt, "ranked_input", user)
A.show()
return A
/proc/input_autocomplete_async(mob/user=usr, prompt="Enter text: ", list/choices)
var/datum/async_input/autocomplete/A = new(choices, prompt, "ac_input", user)
A.show()
return A
/datum/async_input
var/datum/browser/popup
// If associative list, key will be used for display, but the final result will be the value
var/list/choices
var/datum/callback/onCloseCb
var/flash = TRUE
var/immediate_submit = FALSE
var/prompt
var/result = null
var/style = "text-align: center;"
var/mob/user
var/window_id
var/height = 200
var/width = 400
/datum/async_input/New(list/new_choices, new_prompt="Pick an option:", new_window_id="async_input")
/datum/async_input/New(list/new_choices, new_prompt="Pick an option:", new_window_id="async_input", mob/new_user=usr)
choices = new_choices
prompt = new_prompt
window_id = new_window_id
user = new_user
popup = new(user, window_id, , width, height, src)
/datum/async_input/proc/close()
if(popup)
popup.close()
if(result && choices[result])
result = choices[result]
if(onCloseCb)
onCloseCb.Invoke(result)
return result
/datum/async_input/proc/show(mob/user)
var/dat = create_ui(user)
popup = new(user, window_id, , width, height, src)
popup.set_content(dat)
// Callback function should take the result as the last argument
/datum/async_input/proc/on_close(var/datum/callback/cb)
onCloseCb = cb
/datum/async_input/proc/show()
popup.set_content(create_ui())
if(flash && result == null)
window_flash(user.client)
popup.open()
/datum/async_input/proc/create_ui(mob/user)
/datum/async_input/proc/create_ui()
var/dat = "<div style=\"[style]\">"
dat += render_prompt(user)
dat += render_choices(user)
dat += render_prompt()
dat += render_choices()
dat += "<br>"
dat += "<br>"
dat += button("Submit", "submit=1", , result == null && !immediate_submit)
dat += render_buttons()
dat += "</div>"
return dat
/datum/async_input/proc/render_prompt(mob/user)
/datum/async_input/proc/render_prompt()
return "<h2>[prompt]</h2>"
/datum/async_input/proc/render_choices(mob/user)
/datum/async_input/proc/render_choices()
var/dat = " "
for(var/choice in choices)
dat += button(choice, "choice=[choice]", choice == result)
dat += " "
return dat
/datum/async_input/proc/button(label, topic, on=FALSE, disabled=FALSE)
/datum/async_input/proc/render_buttons()
return button("Submit", "submit=1", , result == null && !immediate_submit)
/datum/async_input/proc/button(label, topic, on=FALSE, disabled=FALSE, id="")
var/class = ""
if(on)
class = "linkOn"
if(disabled)
class = "linkOff"
topic = ""
return "<a class=\"[class]\" href='?src=[UID()];[topic]'>[label]</a>"
return "<a class=\"[class]\" id='[id]' href='?src=[UID()];[topic]'>[label]</a>"
/datum/async_input/Topic(href, href_list)
if(href_list["submit"] || href_list["close"])
@@ -74,14 +93,14 @@
if(href_list["choice"])
result = href_list["choice"]
show(usr)
show()
return
/datum/async_input/ranked
height = 400
immediate_submit = TRUE
/datum/async_input/ranked/render_choices(mob/user)
/datum/async_input/ranked/render_choices()
var/dat = "<div>"
dat += "<table style='margin: auto; text-align: left;'>"
for(var/i = 1, i <= choices.len, i++)
@@ -103,13 +122,54 @@
if(href_list["upvote"])
var/index = text2num(href_list["upvote"])
choices.Swap(index, index - 1)
show(usr)
show()
return
if(href_list["downvote"])
var/index = text2num(href_list["downvote"])
choices.Swap(index, index + 1)
show(usr)
show()
return
..()
/datum/async_input/autocomplete
immediate_submit = TRUE
height = 150
/datum/async_input/autocomplete/New()
..()
popup.add_script("autocomplete.js", 'html/browser/autocomplete.js')
for(var/i=1, i <= choices.len, i++)
var/C = choices[choices[i]]
choices[i] = url_encode(choices[i], TRUE)
choices[choices[i]] = C
/datum/async_input/autocomplete/render_prompt()
return "<label for='input'>[prompt]</label>"
/datum/async_input/autocomplete/render_choices()
var/dat = "<input list='choices' id='input' name='choices' oninput='updateTopic()' />"
dat += "<datalist id='choices'>"
for(var/choice in choices)
dat += "<option value='[choice]'>"
dat += "</datalist>"
return dat
/datum/async_input/autocomplete/render_buttons()
var/dat = button("Submit", "", , result == null && !immediate_submit, "submit-button")
dat += button("Cancel", "close=1")
return dat
/datum/async_input/autocomplete/Topic(href, href_list)
if(href_list["submit"])
// Entering an invalid choice is the same as canceling
if(href_list["submit"] in choices)
result = href_list["submit"]
else if(url_encode(href_list["submit"], TRUE) in choices)
result = url_encode(href_list["submit"], TRUE)
close()
return
..()
+3 -2
View File
@@ -1440,7 +1440,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/device_tools/medgun
name = "Medbeam Gun"
desc = "Medical Beam Gun, useful in prolonged firefights."
desc = "Medical Beam Gun, useful in prolonged firefights. DO NOT CROSS THE BEAMS. Crossing beams with another medbeam or attaching two beams to one target will have explosive consequences."
item = /obj/item/gun/medbeam
reference = "MBG"
cost = 15
@@ -1627,7 +1627,8 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
reference = "CIB"
item = /obj/item/storage/box/cyber_implants/bundle
cost = 40
gamemodes = list(/datum/game_mode/nuclear)
/datum/uplink_item/bundles_TC/medical
name = "Medical Bundle"
desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a tactical medkit, \
+8
View File
@@ -1400,10 +1400,12 @@ var/list/ghostteleportlocs = list()
name = "\improper Prison Wing"
icon_state = "sec_prison_perma"
fast_despawn = TRUE
can_get_auto_cryod = FALSE
/area/security/prison
name = "\improper Prison Wing"
icon_state = "sec_prison"
can_get_auto_cryod = FALSE
/area/security/prison/prison_break()
for(var/obj/structure/closet/secure_closet/brig/temp_closet in src)
@@ -1432,14 +1434,17 @@ var/list/ghostteleportlocs = list()
/area/security/execution
name = "\improper Execution"
icon_state = "execution"
can_get_auto_cryod = FALSE
/area/security/processing
name = "\improper Prisoner Processing"
icon_state = "prisonerprocessing"
can_get_auto_cryod = FALSE
/area/security/interrogation
name = "\improper Interrogation"
icon_state = "interrogation"
can_get_auto_cryod = FALSE
/area/security/seceqstorage
name = "\improper Security Equipment Storage"
@@ -1456,6 +1461,7 @@ var/list/ghostteleportlocs = list()
/area/security/interrogationobs
name = "\improper Interrogation Observation"
icon_state = "security"
can_get_auto_cryod = FALSE
/area/security/evidence
name = "\improper Evidence Room"
@@ -1464,6 +1470,7 @@ var/list/ghostteleportlocs = list()
/area/security/prisonlockers
name = "\improper Prisoner Lockers"
icon_state = "sec_prison_lockers"
can_get_auto_cryod = FALSE
/area/security/medbay
name = "\improper Security Medbay"
@@ -1472,6 +1479,7 @@ var/list/ghostteleportlocs = list()
/area/security/prisonershuttle
name = "\improper Security Prisoner Shuttle"
icon_state = "security"
can_get_auto_cryod = FALSE
/area/security/warden
name = "\improper Warden's Office"
+1
View File
@@ -64,6 +64,7 @@
'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg')
var/fast_despawn = FALSE
var/can_get_auto_cryod = TRUE
/area/Initialize(mapload)
GLOB.all_areas += src
+1 -1
View File
@@ -361,7 +361,7 @@
fingerprintshidden += text("\[[time_stamp()]\] (Wearing gloves). Real name: [], Key: []",H.real_name, H.key)
fingerprintslast = H.ckey
return 0
if(!( fingerprints ))
if(!fingerprints)
if(fingerprintslast != H.ckey)
//Add the list if it does not exist.
if(!fingerprintshidden)
+44 -18
View File
@@ -58,13 +58,17 @@
pulledby = null
return ..()
//Returns an atom's power cell, if it has one. Overload for individual items.
/atom/movable/proc/get_cell()
return
/atom/movable/proc/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
if(QDELETED(AM))
return FALSE
if(!(AM.can_be_pulled(src, state, force)))
return FALSE
// If we're pulling something then drop what we're currently pulling and pull this instead.
// if we're pulling something then drop what we're currently pulling and pull this instead.
if(pulling)
if(state == 0)
stop_pulling()
@@ -114,7 +118,9 @@
if(pulling.anchored)
stop_pulling()
return
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1) //separated from our puller and not in the middle of a diagonal move.
pulledby.stop_pulling()
/atom/movable/proc/can_be_pulled(user, grab_state, force)
if(src == user || !isturf(loc))
return FALSE
@@ -137,36 +143,55 @@
. = ..()
else //Diagonal move, split it into cardinal moves
moving_diagonally = FIRST_DIAG_STEP
if(direct & 1)
if(direct & 4)
if(step(src, NORTH))
var/first_step_dir
// The `&& moving_diagonally` checks are so that a forceMove taking
// place due to a Crossed, Bumped, etc. call will interrupt
// the second half of the diagonal movement, or the second attempt
// at a first half if step() fails because we hit something.
if(direct & NORTH)
if(direct & EAST)
if(step(src, NORTH) && moving_diagonally)
first_step_dir = NORTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, EAST)
else if(step(src, EAST))
else if(moving_diagonally && step(src, EAST))
first_step_dir = EAST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, NORTH)
else if(direct & 8)
if(step(src, NORTH))
else if(direct & WEST)
if(step(src, NORTH) && moving_diagonally)
first_step_dir = NORTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, WEST)
else if(step(src, WEST))
else if(moving_diagonally && step(src, WEST))
first_step_dir = WEST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, NORTH)
else if(direct & 2)
if(direct & 4)
if(step(src, SOUTH))
else if(direct & SOUTH)
if(direct & EAST)
if(step(src, SOUTH) && moving_diagonally)
first_step_dir = SOUTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, EAST)
else if(step(src, EAST))
else if(moving_diagonally && step(src, EAST))
first_step_dir = EAST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, SOUTH)
else if(direct & 8)
if(step(src, SOUTH))
else if(direct & WEST)
if(step(src, SOUTH) && moving_diagonally)
first_step_dir = SOUTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, WEST)
else if(step(src, WEST))
else if(moving_diagonally && step(src, WEST))
first_step_dir = WEST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, SOUTH)
if(moving_diagonally == SECOND_DIAG_STEP)
if(!.)
setDir(first_step_dir)
else if(!inertia_moving)
inertia_next_move = world.time + inertia_move_delay
newtonian_move(direct)
moving_diagonally = 0
return
@@ -187,7 +212,7 @@
// Called after a successful Move(). By this point, we've already moved
/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE)
SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, OldLoc, Dir, Forced)
if (!inertia_moving)
if(!inertia_moving)
inertia_next_move = world.time + inertia_move_delay
newtonian_move(Dir)
return TRUE
@@ -210,6 +235,7 @@
/atom/movable/proc/forceMove(atom/destination)
var/turf/old_loc = loc
loc = destination
moving_diagonally = 0
if(old_loc)
old_loc.Exited(src, destination)
@@ -239,7 +265,7 @@
return 1
/atom/movable/proc/onTransitZ(old_z,new_z)
for(var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care.
for(var/item in src) // Notify contents of Z-transition. This can be overridden if we know the items contents do not care.
var/atom/movable/AM = item
AM.onTransitZ(old_z,new_z)
+1 -1
View File
@@ -228,7 +228,7 @@
// Assemble a list of active players without jobbans.
for(var/mob/new_player/player in GLOB.player_list)
if(player.client && player.ready)
if(player.client && player.ready && player.has_valid_preferences())
if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, roletext))
if(player_old_enough_antag(player.client,role))
players += player
+7 -4
View File
@@ -165,10 +165,13 @@
var/targetitem = input("Select item to search for.", "Item Mode Select","") as null|anything in item_names
if(!targetitem)
return
var/list/obj/item/target_candidates = get_all_of_type(item_paths[targetitem], subtypes = TRUE)
for(var/obj/item/candidate in target_candidates)
if(!is_admin_level(candidate.loc.z))
target = candidate
var/list/target_candidates = get_all_of_type(item_paths[targetitem], subtypes = TRUE)
for(var/obj/item/candidate in target_candidates)
if(!is_admin_level((get_turf(candidate)).z))
target = candidate
break
if(!target)
to_chat(usr, "<span class='warning'>Failed to locate [targetitem]!</span>")
return
+17 -9
View File
@@ -297,19 +297,27 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
to_chat(owner, "<span class='warning'>They've got no blood left to give.</span>")
break
if(H.stat < DEAD)
blood = min(20, H.blood_volume) // if they have less than 20 blood, give them the remnant else they get 20 blood
bloodtotal += blood / 2 //divide by 2 to counted the double suction since removing cloneloss -Melandor0
bloodusable += blood / 2
if(!issmall(H) || H.ckey)
blood = min(20, H.blood_volume) // if they have less than 20 blood, give them the remnant else they get 20 blood
bloodtotal += blood / 2 //divide by 2 to counted the double suction since removing cloneloss -Melandor0
bloodusable += blood / 2
else
blood = min(5, H.blood_volume) // The dead only give 5 blood
bloodtotal += blood
if(!issmall(H) || H.ckey)
blood = min(5, H.blood_volume) // The dead only give 5 blood
bloodtotal += blood
if(old_bloodtotal != bloodtotal)
to_chat(owner, "<span class='notice'><b>You have accumulated [bloodtotal] [bloodtotal > 1 ? "units" : "unit"] of blood[bloodusable != old_bloodusable ? ", and have [bloodusable] left to use" : ""].</b></span>")
if(!issmall(H) || H.ckey) // not small OR has a ckey, monkeys with ckeys can be sucked, humanized monkeys can be sucked monkeys without ckeys cannot be sucked
to_chat(owner, "<span class='notice'><b>You have accumulated [bloodtotal] [bloodtotal > 1 ? "units" : "unit"] of blood[bloodusable != old_bloodusable ? ", and have [bloodusable] left to use" : ""].</b></span>")
check_vampire_upgrade()
H.blood_volume = max(H.blood_volume - 25, 0)
if(ishuman(owner))
var/mob/living/carbon/human/V = owner
V.nutrition = min(NUTRITION_LEVEL_WELL_FED, V.nutrition + (blood / 2))
if(issmall(H) && !H.ckey)
to_chat(V, "<span class='notice'><b>Feeding on [H] reduces your hunger, but you get no usable blood from it.</b></span>")
V.nutrition = min(NUTRITION_LEVEL_WELL_FED, V.nutrition + 5)
else
V.nutrition = min(NUTRITION_LEVEL_WELL_FED, V.nutrition + (blood / 2))
draining = null
to_chat(owner, "<span class='notice'>You stop draining [H.name] of blood.</span>")
@@ -402,11 +410,11 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
if(!hud.vampire_blood_display)
hud.vampire_blood_display = new /obj/screen()
hud.vampire_blood_display.name = "Usable Blood"
hud.vampire_blood_display.icon_state = "power_display"
hud.vampire_blood_display.icon_state = "blood_display"
hud.vampire_blood_display.screen_loc = "WEST:6,CENTER-1:15"
hud.static_inventory += hud.vampire_blood_display
hud.show_hud(hud.hud_version)
hud.vampire_blood_display.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#dd66dd'>[bloodusable]</font></div>"
hud.vampire_blood_display.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#ce0202'>[bloodusable]</font></div>"
handle_vampire_cloak()
if(istype(owner.loc, /turf/space))
check_sun()
@@ -261,8 +261,10 @@
for(var/mob/living/carbon/C in hearers(4))
if(C == user)
continue
if(ishuman(C) && (C:l_ear || C:r_ear) && istype((C:l_ear || C:r_ear), /obj/item/clothing/ears/earmuffs))
continue
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(istype(H.l_ear, /obj/item/clothing/ears/earmuffs) || istype(H.r_ear, /obj/item/clothing/ears/earmuffs))
continue
if(!affects(C))
continue
to_chat(C, "<span class='warning'><font size='3'><b>You hear a ear piercing shriek and your senses dull!</font></b></span>")
+2 -2
View File
@@ -160,8 +160,8 @@
title = "Shaft Miner"
flag = MINER
department_flag = SUPPORT
total_positions = 3
spawn_positions = 3
total_positions = 6
spawn_positions = 8
is_supply = 1
supervisors = "the quartermaster"
department_head = list("Head of Personnel")
+4 -1
View File
@@ -15,6 +15,10 @@
var/obj/item/defibrillator/defib //this mount's defibrillator
var/clamps_locked = FALSE //if true, and a defib is loaded, it can't be removed without unlocking the clamps
/obj/machinery/defibrillator_mount/get_cell()
if(defib)
return defib.get_cell()
/obj/machinery/defibrillator_mount/New(location, direction, building = 0)
..()
@@ -28,7 +32,6 @@
pixel_x = (dir & 3)? 0 : (dir == 4 ? -30 : 30)
pixel_y = (dir & 3)? (dir == 1 ? -30 : 30) : 0
/obj/machinery/defibrillator_mount/loaded/New() //loaded subtype for mapping use
..()
defib = new/obj/item/defibrillator/loaded(src)
+2
View File
@@ -12,6 +12,8 @@
var/open = FALSE
var/brightness_on = 14
/obj/machinery/floodlight/get_cell()
return cell
/obj/machinery/floodlight/Initialize()
. = ..()
+25 -8
View File
@@ -8,6 +8,7 @@
idle_power_usage = 4
active_power_usage = 250
var/obj/item/charging = null
var/using_power = FALSE
var/list/allowed_devices = list(/obj/item/gun/energy, /obj/item/melee/baton, /obj/item/modular_computer, /obj/item/rcs, /obj/item/bodyanalyzer)
var/icon_state_off = "rechargeroff"
var/icon_state_charged = "recharger2"
@@ -81,22 +82,21 @@
if(stat & (NOPOWER|BROKEN) || !anchored)
return
var/using_power = 0
using_power = FALSE
if(charging)
if(istype(charging, /obj/item/gun/energy))
var/obj/item/gun/energy/E = charging
if(E.power_supply.charge < E.power_supply.maxcharge)
E.power_supply.give(E.power_supply.chargerate)
use_power(250)
using_power = 1
using_power = TRUE
if(istype(charging, /obj/item/melee/baton))
var/obj/item/melee/baton/B = charging
if(B.bcell)
if(B.bcell.give(B.bcell.chargerate))
use_power(200)
using_power = 1
using_power = TRUE
if(istype(charging, /obj/item/modular_computer))
var/obj/item/modular_computer/C = charging
@@ -107,21 +107,21 @@
if(B.battery.charge < B.battery.maxcharge)
B.battery.give(B.battery.chargerate)
use_power(200)
using_power = 1
using_power = TRUE
if(istype(charging, /obj/item/rcs))
var/obj/item/rcs/R = charging
if(R.rcell)
if(R.rcell.give(R.rcell.chargerate))
use_power(200)
using_power = 1
using_power = TRUE
if(istype(charging, /obj/item/bodyanalyzer))
var/obj/item/bodyanalyzer/B = charging
if(B.power_supply)
if(B.power_supply.give(B.power_supply.chargerate))
use_power(200)
using_power = 1
using_power = TRUE
update_icon(using_power)
@@ -141,7 +141,7 @@
B.bcell.charge = 0
..(severity)
/obj/machinery/recharger/update_icon(using_power = 0) //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
/obj/machinery/recharger/update_icon(using_power = FALSE) //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
if(stat & (NOPOWER|BROKEN) || !anchored)
icon_state = icon_state_off
return
@@ -153,6 +153,23 @@
return
icon_state = icon_state_idle
/obj/machinery/recharger/examine(mob/user)
..()
if(charging && (!in_range(user, src) && !issilicon(user) && !isobserver(user)))
to_chat(user, "<span class='warning'>You're too far away to examine [src]'s contents and display!</span>")
return
if(charging)
to_chat(user, "<span class='notice'>\The [src] contains:</span>")
to_chat(user, "<span class='notice'>- \A [charging].</span>")
if(!(stat & (NOPOWER|BROKEN)))
var/obj/item/stock_parts/cell/C = charging.get_cell()
to_chat(user, "<span class='notice'>The status display reads:<span>")
if(using_power)
to_chat(user, "<span class='notice'>- Recharging <b>[(C.chargerate/C.maxcharge)*100]%</b> cell charge per cycle.<span>")
if(charging)
to_chat(user, "<span class='notice'>- \The [charging]'s cell is at <b>[C.percent()]%</b>.<span>")
// Atlantis: No need for that copy-pasta code, just use var to store icon_states instead.
/obj/machinery/recharger/wallcharger
name = "wall recharger"
+3 -1
View File
@@ -12,6 +12,9 @@
var/set_temperature = 50 // in celcius, add T0C for kelvin
var/heating_power = 40000
/obj/machinery/space_heater/get_cell()
return cell
/obj/machinery/space_heater/New()
..()
cell = new(src)
@@ -39,7 +42,6 @@
else
to_chat(user, "The charge meter reads [cell ? round(cell.percent(),1) : 0]%")
/obj/machinery/space_heater/emp_act(severity)
if(stat & (BROKEN|NOPOWER))
..(severity)
+4
View File
@@ -137,6 +137,10 @@
////////////////////////
////// Helpers /////////
////////////////////////
/obj/mecha/get_cell()
return cell
/obj/mecha/proc/add_airtank()
internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src)
return internal_tank
+10 -8
View File
@@ -65,8 +65,8 @@
/obj/item/areaeditor/permit/create_area()
..()
qdel(src)
if(..())
qdel(src)
//free golem blueprints, like permit but can claim as much as needed
@@ -186,25 +186,26 @@
/obj/item/areaeditor/proc/create_area()
var/area_created = FALSE
var/res = detect_room(get_turf(usr))
if(!istype(res,/list))
switch(res)
if(ROOM_ERR_SPACE)
to_chat(usr, "<span class='warning'>The new area must be completely airtight.</span>")
return
return area_created
if(ROOM_ERR_TOOLARGE)
to_chat(usr, "<span class='warning'>The new area is too large.</span>")
return
return area_created
else
to_chat(usr, "<span class='warning'>Error! Please notify administration.</span>")
return
return area_created
var/list/turf/turfs = res
var/str = trim(stripped_input(usr,"New area name:", "Blueprint Editing", "", MAX_NAME_LEN))
if(!str || !length(str)) //cancel
return
return area_created
if(length(str) > 50)
to_chat(usr, "<span class='warning'>The given name is too long. The area remains undefined.</span>")
return
return area_created
var/area/A = new
A.name = str
A.power_equip = FALSE
@@ -220,7 +221,8 @@
thing.change_area(old_area, A)
interact()
return
area_created = TRUE
return area_created
/obj/item/areaeditor/proc/edit_area()
var/area/A = get_area()
@@ -591,6 +591,9 @@ REAGENT SCANNER
var/scan_time = 10 SECONDS //how long does it take to scan
var/scan_cd = 60 SECONDS //how long before we can scan again
/obj/item/bodyanalyzer/get_cell()
return power_supply
/obj/item/bodyanalyzer/advanced
cell_type = /obj/item/stock_parts/cell/upgraded/plus
@@ -32,6 +32,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
created_window = /obj/structure/window/basic
full_window = /obj/structure/window/full/basic
merge_type = /obj/item/stack/sheet/glass
point_value = 1
/obj/item/stack/sheet/glass/fifty
amount = 50
@@ -90,6 +91,7 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \
created_window = /obj/structure/window/reinforced
full_window = /obj/structure/window/full/reinforced
merge_type = /obj/item/stack/sheet/rglass
point_value = 4
/obj/item/stack/sheet/rglass/cyborg
materials = list()
@@ -113,6 +115,7 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \
origin_tech = "plasmatech=2;materials=2"
created_window = /obj/structure/window/plasmabasic
full_window = /obj/structure/window/full/plasmabasic
point_value = 19
/obj/item/stack/sheet/plasmaglass/New(loc, amount)
recipes = GLOB.pglass_recipes
@@ -154,6 +157,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \
created_window = /obj/structure/window/plasmareinforced
full_window = /obj/structure/window/full/plasmareinforced
armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0)
point_value = 23
/obj/item/stack/sheet/plasmarglass/New(loc, amount)
recipes = GLOB.prglass_recipes
@@ -144,6 +144,7 @@ var/global/list/datum/stack_recipe/snow_recipes = list(
origin_tech = "materials=6"
sheettype = "diamond"
materials = list(MAT_DIAMOND=MINERAL_MATERIAL_AMOUNT)
point_value = 25
/obj/item/stack/sheet/mineral/diamond/New()
..()
@@ -156,6 +157,7 @@ var/global/list/datum/stack_recipe/snow_recipes = list(
origin_tech = "materials=5"
sheettype = "uranium"
materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT)
point_value = 20
/obj/item/stack/sheet/mineral/uranium/New()
..()
@@ -170,6 +172,7 @@ var/global/list/datum/stack_recipe/snow_recipes = list(
materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT)
burn_state = FLAMMABLE
burntime = 5
point_value = 20
/obj/item/stack/sheet/mineral/plasma/New()
..()
@@ -196,6 +199,7 @@ var/global/list/datum/stack_recipe/snow_recipes = list(
origin_tech = "materials=4"
sheettype = "gold"
materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT)
point_value = 20
/obj/item/stack/sheet/mineral/gold/New()
..()
@@ -208,6 +212,7 @@ var/global/list/datum/stack_recipe/snow_recipes = list(
origin_tech = "materials=4"
sheettype = "silver"
materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT)
point_value = 20
/obj/item/stack/sheet/mineral/silver/New()
..()
@@ -220,6 +225,7 @@ var/global/list/datum/stack_recipe/snow_recipes = list(
origin_tech = "materials=4"
sheettype = "bananium"
materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT)
point_value = 50
/obj/item/stack/sheet/mineral/bananium/New(loc, amount=null)
..()
@@ -233,6 +239,7 @@ var/global/list/datum/stack_recipe/snow_recipes = list(
sheettype = "tranquillite"
materials = list(MAT_TRANQUILLITE=MINERAL_MATERIAL_AMOUNT)
wall_allowed = FALSE //no tranquilite walls in code
point_value = 50
/obj/item/stack/sheet/mineral/tranquillite/New(loc, amount=null)
..()
@@ -253,6 +260,7 @@ var/global/list/datum/stack_recipe/snow_recipes = list(
throw_range = 3
sheettype = "titanium"
materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT)
point_value = 20
var/global/list/datum/stack_recipe/titanium_recipes = list (
new/datum/stack_recipe("titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20),
@@ -282,6 +290,7 @@ var/global/list/datum/stack_recipe/titanium_recipes = list (
throw_range = 3
sheettype = "plastitanium"
materials = list(MAT_TITANIUM=2000, MAT_PLASMA=2000)
point_value = 45
var/global/list/datum/stack_recipe/plastitanium_recipes = list (
new/datum/stack_recipe("plas-titanium tile", /obj/item/stack/tile/mineral/plastitanium, 1, 4, 20),
@@ -105,6 +105,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list(
flags = CONDUCT
origin_tech = "materials=1"
merge_type = /obj/item/stack/sheet/metal
point_value = 2
/obj/item/stack/sheet/metal/cyborg
materials = list()
@@ -151,6 +152,7 @@ var/global/list/datum/stack_recipe/plasteel_recipes = list(
flags = CONDUCT
origin_tech = "materials=2"
merge_type = /obj/item/stack/sheet/plasteel
point_value = 23
/obj/item/stack/sheet/plasteel/New(var/loc, var/amount=null)
recipes = plasteel_recipes
@@ -9,22 +9,10 @@
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
var/perunit = MINERAL_MATERIAL_AMOUNT
var/sheettype = null //this is used for girders in the creation of walls/false walls
var/point_value = 0 //turn-in value for the gulag stacker - loosely relative to its rarity.
var/created_window = null //apparently glass sheets don't share a base type for glass specifically, so each had to define these vars individually
var/full_window = null //moving the var declaration to here so this can be checked cleaner until someone is willing to make them share a base type properly
usesound = 'sound/items/deconstruct.ogg'
toolspeed = 1
var/wall_allowed = TRUE //determines if sheet can be used in wall construction or not.
// Since the sheetsnatcher was consolidated into weapon/storage/bag we now use
// item/attackby() properly, making this unnecessary
/*/obj/item/stack/sheet/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/storage/bag/sheetsnatcher))
var/obj/item/storage/bag/sheetsnatcher/S = W
if(!S.mode)
S.add(src,user)
else
for(var/obj/item/stack/sheet/stack in locate(src.x,src.y,src.z))
S.add(stack,user)
..()*/
+3
View File
@@ -22,6 +22,9 @@
var/obj/item/stock_parts/cell/high/bcell = null
var/combat = 0 //can we revive through space suits?
/obj/item/defibrillator/get_cell()
return bcell
/obj/item/defibrillator/New() //starts without a cell for rnd
..()
paddles = make_paddles()
+47
View File
@@ -4,6 +4,9 @@
#define RPD_COOLDOWN_TIME 4 //How long should we have to wait between dispensing pipes?
#define RPD_WALLBUILD_TIME 40 //How long should drilling into a wall take?
#define RPD_MENU_ROTATE "Rotate pipes" //Stuff for radial menu
#define RPD_MENU_FLIP "Flip pipes" //Stuff for radial menu
#define RPD_MENU_DELETE "Delete pipes" //Stuff for radial menu
/obj/item/rpd
name = "rapid pipe dispenser"
@@ -172,6 +175,9 @@ var/list/pipemenu = list(
ui.open()
ui.set_auto_update(1)
/obj/item/rpd/AltClick(mob/user)
radial_menu(user)
/obj/item/rpd/ui_data(mob/user, ui_key = "main", datum/topic_state/state = inventory_state)
var/data[0]
data["iconrotation"] = iconrotation
@@ -200,6 +206,44 @@ var/list/pipemenu = list(
return
SSnanoui.update_uis(src)
//RPD radial menu
/obj/item/rpd/proc/check_menu(mob/living/user)
if(!istype(user))
return
if(user.incapacitated())
return
if(loc != user)
return
return TRUE
/obj/item/rpd/proc/radial_menu(mob/user)
if(!check_menu(user))
to_chat(user, "<span class='notice'>You can't do that right now!</span>")
return
var/list/choices = list(
RPD_MENU_ROTATE = image(icon = 'icons/obj/interface.dmi', icon_state = "rpd_rotate"),
RPD_MENU_FLIP = image(icon = 'icons/obj/interface.dmi', icon_state = "rpd_flip"),
RPD_MENU_DELETE = image(icon = 'icons/obj/interface.dmi', icon_state = "rpd_delete"),
"UI" = image(icon = 'icons/obj/interface.dmi', icon_state = "ui_interact")
)
var/selected_mode = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, .proc/check_menu, user))
if(!check_menu(user))
return
if(selected_mode == "UI")
ui_interact(user)
else
switch(selected_mode)
if(RPD_MENU_ROTATE)
mode = RPD_ROTATE_MODE
if(RPD_MENU_FLIP)
mode = RPD_FLIP_MODE
if(RPD_MENU_DELETE)
mode = RPD_DELETE_MODE
else
return //Either nothing was selected, or an invalid mode was selected
to_chat(user, "<span class='notice'>You set [src]'s mode.</span>")
/obj/item/rpd/afterattack(atom/target, mob/user, proximity)
..()
if(loc != user)
@@ -236,3 +280,6 @@ var/list/pipemenu = list(
#undef RPD_COOLDOWN_TIME
#undef RPD_WALLBUILD_TIME
#undef RPD_MENU_ROTATE
#undef RPD_MENU_FLIP
#undef RPD_MENU_DELETE
@@ -20,6 +20,9 @@
user.visible_message("<span class='suicide'>[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide.</span>")
return FIRELOSS
/obj/item/melee/baton/get_cell()
return bcell
/obj/item/melee/baton/New()
..()
update_icon()
+1 -2
View File
@@ -39,8 +39,7 @@
return T.attackby(C, user) //hand this off to the turf instead (for building plating, catwalks, etc)
/obj/structure/lattice/deconstruct(disassembled = TRUE)
if(!can_deconstruct)
new /obj/item/stack/rods(get_turf(src), number_of_rods)
new /obj/item/stack/rods(get_turf(src), number_of_rods)
qdel(src)
/obj/structure/lattice/blob_act()
@@ -35,7 +35,7 @@
/obj/structure/mineral_door/Move()
var/turf/T = loc
..()
. = ..()
move_update_air(T)
/obj/structure/mineral_door/Bumped(atom/user)
+1 -1
View File
@@ -13,7 +13,7 @@
return ..()
/obj/structure/target_stake/Move()
..()
. = ..()
// Move the pinned target along with the stake
if(pinned_target in view(3, src))
pinned_target.loc = loc
@@ -46,7 +46,7 @@ obj/structure/windoor_assembly/Destroy()
/obj/structure/windoor_assembly/Move()
var/turf/T = loc
..()
. = ..()
setDir(ini_dir)
move_update_air(T)
+1 -1
View File
@@ -431,7 +431,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
/obj/structure/window/Move()
var/turf/T = loc
..()
. = ..()
setDir(ini_dir)
move_update_air(T)
+3 -4
View File
@@ -23,13 +23,12 @@
/turf/simulated/proc/burn_tile()
return
/turf/simulated/proc/water_act(volume, temperature, source)
/turf/simulated/water_act(volume, temperature, source)
. = ..()
if(volume >= 3)
MakeSlippery()
for(var/mob/living/carbon/slime/M in src)
M.apply_water()
var/hotspot = (locate(/obj/effect/hotspot) in src)
if(hotspot)
var/datum/gas_mixture/lowertemp = remove_air(air.total_moles())
@@ -27,6 +27,9 @@
/turf/simulated/floor/plating/asteroid/MakeDry(wet_setting)
return
/turf/simulated/floor/plating/asteroid/remove_plating()
return
/turf/simulated/floor/plating/asteroid/ex_act(severity, target)
switch(severity)
if(3)
+3
View File
@@ -38,6 +38,9 @@
/turf/simulated/floor/plating/lava/make_plating()
return
/turf/simulated/floor/plating/lava/remove_plating()
return
/turf/simulated/floor/plating/lava/proc/is_safe()
var/static/list/lava_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile))
var/list/found_safeties = typecache_filter_list(contents, lava_safeties_typecache)
+28 -3
View File
@@ -56,10 +56,14 @@
to_chat(user, "<span class='warning'>This section is too damaged to support a tile! Use a welder to fix the damage.</span>")
return TRUE
else if(istype(C, /obj/item/weldingtool))
else if(iswelder(C))
var/obj/item/weldingtool/welder = C
if(welder.isOn() && (broken || burnt))
if(welder.remove_fuel(0, user))
if(welder.isOn())
if(!welder.remove_fuel(0, user))
to_chat(user, "<span class='warning'>You need more welding fuel to complete this task.</span>")
return TRUE
if(broken || burnt)
to_chat(user, "<span class='danger'>You fix some dents on the broken plating.</span>")
playsound(src, welder.usesound, 80, 1)
overlays -= current_overlay
@@ -67,8 +71,23 @@
burnt = FALSE
broken = FALSE
update_icon()
else
to_chat(user, "<span class='notice'>You start removing [src].</span>")
playsound(src, welder.usesound, 100, 1)
if(do_after(user, 50 * welder.toolspeed, target = src) && welder && welder.isOn())
to_chat(user, "<span class='notice'>You remove [src].</span>")
new /obj/item/stack/tile/plasteel(get_turf(src))
remove_plating(user)
return TRUE
return TRUE
/turf/simulated/floor/plating/proc/remove_plating(mob/user)
if(baseturf == /turf/space)
ReplaceWithLattice()
else
TerraformTurf(baseturf)
/turf/simulated/floor/plating/airless
icon_state = "plating"
name = "airless plating"
@@ -208,6 +227,9 @@
..()
icon_state = "ironsand[rand(1,15)]"
/turf/simulated/floor/plating/ironsand/remove_plating()
return
/turf/simulated/floor/plating/snow
name = "snow"
icon = 'icons/turf/snow.dmi'
@@ -216,6 +238,9 @@
/turf/simulated/floor/plating/snow/ex_act(severity)
return
/turf/simulated/floor/plating/snow/remove_plating()
return
/turf/simulated/floor/snow
name = "snow"
icon = 'icons/turf/snow.dmi'
+4
View File
@@ -509,3 +509,7 @@
/turf/AllowDrop()
return TRUE
/turf/proc/water_act(volume, temperature, source)
for(var/mob/living/carbon/slime/M in src)
M.apply_water()
+5 -6
View File
@@ -369,15 +369,14 @@ var/world_topic_spam_protect_time = world.timeofday
if(config && config.server_tag_line)
s += "<br>[config.server_tag_line]"
if(SSticker && ROUND_TIME > 0)
s += "<br>[round(ROUND_TIME / 36000)]:[add_zero(num2text(ROUND_TIME / 600 % 60), 2)], " + capitalize(get_security_level())
else
s += "<br><b>STARTING</b>"
s += "<br>"
var/list/features = list()
if(SSticker)
if(master_mode && master_mode != "secret")
features += master_mode
else
features += "<b>STARTING</b>"
if(!enter_allowed)
features += "closed"
+1 -1
View File
@@ -108,7 +108,7 @@ world/IsBanned(key, address, computer_id, check_ipintel = TRUE)
var/appealmessage = ""
if(config.banappeals)
appealmessage = " You may appeal it at <a href='[config.banappeals]'>[config.banappeals]</a>."
expires = " This is a permanent ban.[appealmessage]"
expires = " This ban does not expire automatically and must be appealed.[appealmessage]"
var/desc = "\nReason: You, or another user of this computer or connection ([pckey]) is banned from playing here. The ban reason is:\n[reason]\nThis ban was applied by [ackey] on [bantime].[expires]"
-1
View File
@@ -167,7 +167,6 @@ var/global/nologevent = 0
body += "<B>Is an AI</B> "
else if(ishuman(M))
body += {"<A href='?_src_=holder;makeai=[M.UID()]'>Make AI</A> |
<A href='?_src_=holder;makemask=[M.UID()]'>Make Mask</A> |
<A href='?_src_=holder;makerobot=[M.UID()]'>Make Robot</A> |
<A href='?_src_=holder;makealien=[M.UID()]'>Make Alien</A> |
<A href='?_src_=holder;makeslime=[M.UID()]'>Make Slime</A> |
+4 -4
View File
@@ -1015,14 +1015,14 @@
return
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0, M.lastKnownIP)
to_chat(M, "<span class='warning'><BIG><B>You have been banned by [usr.client.ckey].\nReason: [reason].</B></BIG></span>")
to_chat(M, "<span class='warning'>This is a permanent ban.</span>")
to_chat(M, "<span class='warning'>This ban does not expire automatically and must be appealed.</span>")
if(config.banappeals)
to_chat(M, "<span class='warning'>To try to resolve this matter head to [config.banappeals]</span>")
else
to_chat(M, "<span class='warning'>No ban appeals URL has been set.</span>")
ban_unban_log_save("[usr.client.ckey] has permabanned [M.ckey]. - Reason: [reason] - This is a permanent ban.")
log_admin("[key_name(usr)] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
message_admins("<span class='notice'>[key_name_admin(usr)] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.</span>")
ban_unban_log_save("[usr.client.ckey] has permabanned [M.ckey]. - Reason: [reason] - This ban does not expire automatically and must be appealed.")
log_admin("[key_name(usr)] has banned [M.ckey].\nReason: [reason]\nThis ban does not expire automatically and must be appealed.")
message_admins("<span class='notice'>[key_name_admin(usr)] has banned [M.ckey].\nReason: [reason]\nThis ban does not expire automatically and must be appealed.</span>")
feedback_inc("ban_perma",1)
DB_ban_record(BANTYPE_PERMA, M, -1, reason)
+1
View File
@@ -185,3 +185,4 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
else
send2irc(source, "[msg] - All admins AFK ([admin_number_afk]/[admin_number_total]) or skipped ([admin_number_ignored]/[admin_number_total])")
return admin_number_present
+21 -3
View File
@@ -279,6 +279,9 @@
/datum/pm_tracker/proc/add_message(client/title, client/sender, message, mob/user)
if(!pms[title.key])
pms[title.key] = new /datum/pm_convo(title)
else if(!pms[title.key].client)
// If they DCed earlier, we need to add the client reference back
pms[title.key].client = title
pms[title.key].add(sender, message)
if(!open)
@@ -308,16 +311,25 @@
dat += "<a class='[class]' href='?src=[UID()];newtitle=[title]'>[label]</a>"
var/datum/pm_convo/convo = pms[current_title]
var/datum/browser/popup = new(user, window_id, "Messages", 1000, 600, src)
if(convo)
popup.add_head_content(@{"<script type='text/javascript'>
window.onload = function () {
var msgs = document.getElementById('msgs');
msgs.scrollTop = msgs.scrollHeight;
}
</script>"})
convo.read = TRUE
dat += "<h2>[check_rights(R_ADMIN, FALSE, user) ? fancy_title(current_title) : current_title]</h2>"
dat += "<h4>"
dat += "<table style='width:950px; border: 3px solid;'>"
dat += "<div id='msgs' style='width:950px; border: 3px solid; overflow-y: scroll; height: 350px;'>"
dat += "<table>"
for(var/message in convo.messages)
dat += "<tr><td>[message]</td></tr>"
dat += "</table>"
dat += "</div>"
if(convo.typing)
dat += "<i><span class='typing'>[current_title] is typing</span></i>"
dat += "<br>"
@@ -327,17 +339,23 @@
if(check_rights(R_ADMIN, FALSE, user))
dat += "<a href='?src=[UID()];ping=[current_title]'>Ping</a>"
var/datum/browser/popup = new(user, window_id, "Messages", 1000, 600, src)
popup.set_content(dat)
popup.open()
open = TRUE
/datum/pm_tracker/proc/fancy_title(title)
var/client/C = pms[title].client
var/client/C = pms[title].client || update_client(title)
if(!C)
return "[title] (Disconnected)"
return "[key_name(C, FALSE)] ([ADMIN_QUE(C.mob,"?")]) ([ADMIN_PP(C.mob,"PP")]) ([ADMIN_VV(C.mob,"VV")]) ([ADMIN_SM(C.mob,"SM")]) ([admin_jump_link(C.mob)]) (<A HREF='?_src_=holder;check_antagonist=1'>CA</A>)"
/datum/pm_tracker/proc/update_client(title)
var/client/C = GLOB.directory[ckey(title)]
if(C)
pms[title].client = C
return C
return null
/datum/pm_tracker/Topic(href, href_list)
if(href_list["archive"])
pms[href_list["archive"]].archived = !pms[href_list["archive"]].archived
+4
View File
@@ -17,6 +17,10 @@
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/get_admin_say()
var/msg = input(src, null, "asay \"text\"") as text|null
cmd_admin_say(msg)
/client/proc/cmd_mentor_say(msg as text)
set category = "Admin"
set name = "Msay"
+4
View File
@@ -43,3 +43,7 @@
say_dead_direct("<span class='name'>[prefix]</span> says, <span class='message'>\"[msg]\"</span>")
feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/get_dead_say()
var/msg = input(src, null, "dsay \"text\"") as text
dsay(msg)
+1 -1
View File
@@ -116,7 +116,7 @@
a_right.holder_movement()
/obj/item/assembly_holder/Move()
..()
. = ..()
process_movement()
return
+1 -1
View File
@@ -106,7 +106,7 @@
/obj/item/assembly/infra/Move()
var/t = dir
..()
. = ..()
dir = t
qdel(first)
+7 -3
View File
@@ -1,4 +1,8 @@
/client
//////////////////////
//BLACK MAGIC THINGS//
//////////////////////
parent_type = /datum
////////////////
//ADMIN THINGS//
////////////////
@@ -24,7 +28,7 @@
var/adminhelped = 0
var/gc_destroyed //Time when this object was destroyed.
// var/gc_destroyed //Time when this object was destroyed. [Inherits from datum]
#ifdef TESTING
var/running_find_references
@@ -89,5 +93,5 @@
// If set to true, this client can interact with atoms such as buttons and doors on top of regular machinery interaction
var/advanced_admin_interaction = FALSE
// Has the client been varedited by an admin?
var/var_edited = FALSE
// Has the client been varedited by an admin? [Inherits from datum now]
// var/var_edited = FALSE
+9 -14
View File
@@ -297,14 +297,14 @@
return null
if(byond_build < config.minimum_client_build)
alert(src, "You are using a byond build which is not supported by this server. Please use a build version of atleast [config.minimum_client_build].", "Incorrect build", "OK")
del(src)
qdel(src)
return
if(byond_version < SUGGESTED_CLIENT_VERSION) // Update is suggested, but not required.
to_chat(src,"<span class='userdanger'>Your BYOND client (v: [byond_version]) is out of date. This can cause glitches. We highly suggest you download the latest client from http://www.byond.com/ before playing. </span>")
if(IsGuestKey(key))
alert(src,"This server doesn't allow guest accounts to play. Please go to http://www.byond.com/ and register for a key.","Guest","OK")
del(src)
qdel(src)
return
// Change the way they should download resources.
@@ -317,7 +317,6 @@
GLOB.clients += src
GLOB.directory[ckey] = src
//Admin Authorisation
// Automatically makes localhost connection an admin
if(!config.disable_localhost_admin)
@@ -365,11 +364,14 @@
. = ..() //calls mob.Login()
if(ckey in clientmessages)
for(var/message in clientmessages[ckey])
to_chat(src, message)
clientmessages.Remove(ckey)
if(SSinput.initialized)
set_macros()
donator_check()
check_ip_intel()
@@ -404,8 +406,7 @@
if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
to_chat(src, "<span class='warning'>Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.</span>")
//This is down here because of the browse() calls in tooltip/New()
if(!tooltips)
tooltips = new /datum/tooltip(src)
@@ -664,7 +665,7 @@
sleep(10) // Since browse is non-instant, and kinda async
to_chat(src, "<pre class=\"system system\">you're a huge nerd. wakka wakka doodle doop nobody's ever gonna see this, the chat system shouldn't be online by this point</pre>")
del(src)
qdel(src)
return TRUE
else
if (!topic || !topic["token"] || !tokens[ckey] || topic["token"] != tokens[ckey])
@@ -675,7 +676,7 @@
tokens[ckey] = cid_check_reconnect()
sleep(10) //browse is queued, we don't want them to disconnect before getting the browse() command.
del(src)
qdel(src)
return TRUE
// We DO have their cached CID handy - compare it, now
if(oldcid != computer_id)
@@ -693,7 +694,7 @@
log_adminwarn("Failed Login: [key] [computer_id] [address] - CID randomizer confirmed (oldcid: [oldcid])")
del(src)
qdel(src)
return TRUE
else
// don't shoot, I'm innocent
@@ -795,18 +796,15 @@
/* Mainwindow */
winset(src, "mainwindow.saybutton", "background-color=#40628a;text-color=#FFFFFF")
winset(src, "mainwindow.mebutton", "background-color=#40628a;text-color=#FFFFFF")
winset(src, "mainwindow.hotkey_toggle", "background-color=#40628a;text-color=#FFFFFF")
///// UI ELEMENTS /////
/* Mainwindow */
winset(src, "mainwindow", "background-color=#272727")
winset(src, "mainwindow.mainvsplit", "background-color=#272727")
winset(src, "mainwindow.tooltip", "background-color=#272727")
/* Outputwindow */
winset(src, "outputwindow.outputwindow", "background-color=#272727")
winset(src, "outputwindow.browseroutput", "background-color=#272727")
/* Rpane */
winset(src, "rpane", "background-color=#272727")
winset(src, "rpane.rpane", "background-color=#272727")
winset(src, "rpane.rpanewindow", "background-color=#272727")
/* Browserwindow */
winset(src, "browserwindow", "background-color=#272727")
@@ -830,18 +828,15 @@
/* Mainwindow */
winset(src, "mainwindow.saybutton", "background-color=none;text-color=#000000")
winset(src, "mainwindow.mebutton", "background-color=none;text-color=#000000")
winset(src, "mainwindow.hotkey_toggle", "background-color=none;text-color=#000000")
///// UI ELEMENTS /////
/* Mainwindow */
winset(src, "mainwindow", "background-color=none")
winset(src, "mainwindow.mainvsplit", "background-color=none")
winset(src, "mainwindow.tooltip", "background-color=none")
/* Outputwindow */
winset(src, "outputwindow.outputwindow", "background-color=none")
winset(src, "outputwindow.browseroutput", "background-color=none")
/* Rpane */
winset(src, "rpane", "background-color=none")
winset(src, "rpane.rpane", "background-color=none")
winset(src, "rpane.rpanewindow", "background-color=none")
/* Browserwindow */
winset(src, "browserwindow", "background-color=none")
+14 -1
View File
@@ -81,7 +81,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
var/lastchangelog = "" //Saved changlog filesize to detect if there was a change
var/exp
var/ooccolor = "#b82e00"
var/be_special = list() //Special role selection
var/list/be_special = list() //Special role selection
var/UI_style = "Midnight"
var/nanoui_fancy = TRUE
var/toggles = TOGGLES_DEFAULT
@@ -93,6 +93,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
var/clientfps = 0
var/atklog = ATKLOG_ALL
var/fuid // forum userid
var/afk_watch = FALSE // If the player wants to be kept track of by the AFK system
//ghostly preferences
var/ghost_anonsay = 0
@@ -439,6 +440,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
dat += "<h2>General Settings</h2>"
if(user.client.holder)
dat += "<b>Adminhelp sound:</b> <a href='?_src_=prefs;preference=hear_adminhelps'><b>[(sound & SOUND_ADMINHELP)?"On":"Off"]</b></a><br>"
dat += "<b>AFK Cryoing:</b> <a href='?_src_=prefs;preference=afk_watch'>[(afk_watch) ? "Yes" : "No"]</a><br>"
dat += "<b>Ambient Occlusion:</b> <a href='?_src_=prefs;preference=ambientocclusion'><b>[toggles & AMBIENT_OCCLUSION ? "Enabled" : "Disabled"]</b></a><br>"
dat += "<b>Attack Animations:</b> <a href='?_src_=prefs;preference=ghost_att_anim'>[(show_ghostitem_attack) ? "Yes" : "No"]</a><br>"
if(unlock_content)
@@ -455,6 +457,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
dat += "<b>Ghost Ears:</b> <a href='?_src_=prefs;preference=ghost_ears'><b>[(toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</b></a><br>"
dat += "<b>Ghost Radio:</b> <a href='?_src_=prefs;preference=ghost_radio'><b>[(toggles & CHAT_GHOSTRADIO) ? "All Chatter" : "Nearest Speakers"]</b></a><br>"
dat += "<b>Ghost Sight:</b> <a href='?_src_=prefs;preference=ghost_sight'><b>[(toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]</b></a><br>"
dat += "<b>Ghost PDA:</b> <a href='?_src_=prefs;preference=ghost_pda'><b>[(toggles & CHAT_GHOSTPDA) ? "All PDA Messages" : "No PDA Messages"]</b></a><br>"
if(check_rights(R_ADMIN,0))
dat += "<b>OOC Color:</b> <span style='border: 1px solid #161616; background-color: [ooccolor ? ooccolor : normal_ooc_colour];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=ooccolor;task=input'><b>Change</b></a><br>"
if(config.allow_Metadata)
@@ -1976,6 +1979,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if("winflash")
windowflashing = !windowflashing
if("afk_watch")
afk_watch = !afk_watch
if("UIcolor")
var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!", UI_style_color) as color|null
if(!UI_style_color_new) return
@@ -2029,6 +2035,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if("ghost_radio")
toggles ^= CHAT_GHOSTRADIO
if("ghost_pda")
toggles ^= CHAT_GHOSTPDA
if("ghost_anonsay")
ghost_anonsay = !ghost_anonsay
@@ -2280,3 +2289,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
/datum/preferences/proc/close_load_dialog(mob/user)
user << browse(null, "window=saves")
//Check if the user has ANY job selected.
/datum/preferences/proc/check_any_job()
return(job_support_high || job_support_med || job_support_low || job_medsci_high || job_medsci_med || job_medsci_low || job_engsec_high || job_engsec_med || job_engsec_low || job_karma_high || job_karma_med || job_karma_low)
@@ -19,7 +19,8 @@
exp,
clientfps,
atklog,
fuid
fuid,
afk_watch
FROM [format_table_name("player")]
WHERE ckey='[C.ckey]'"}
)
@@ -52,6 +53,7 @@
clientfps = text2num(query.item[17])
atklog = text2num(query.item[18])
fuid = text2num(query.item[19])
afk_watch = text2num(query.item[20])
//Sanitize
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
@@ -72,6 +74,7 @@
clientfps = sanitize_integer(clientfps, 0, 1000, initial(clientfps))
atklog = sanitize_integer(atklog, 0, 100, initial(atklog))
fuid = sanitize_integer(fuid, 0, 10000000, initial(fuid))
afk_watch = sanitize_integer(afk_watch, 0, 1, initial(afk_watch))
return 1
/datum/preferences/proc/save_preferences(client/C)
@@ -90,7 +93,7 @@
UI_style_alpha='[UI_style_alpha]',
be_role='[sanitizeSQL(list2params(be_special))]',
default_slot='[default_slot]',
toggles='[num2text(toggles, 7)]',
toggles='[num2text(toggles, Ceiling(log(10, (TOGGLES_TOTAL))))]',
atklog='[atklog]',
sound='[sound]',
randomslot='[randomslot]',
@@ -101,7 +104,8 @@
windowflashing='[windowflashing]',
ghost_anonsay='[ghost_anonsay]',
clientfps='[clientfps]',
atklog='[atklog]'
atklog='[atklog]',
afk_watch='[afk_watch]'
WHERE ckey='[C.ckey]'"}
)
@@ -241,4 +241,36 @@
to_chat(usr, "<span class='notice'>You have enabled text popup limiting.")
else
to_chat(usr, "<span class='notice'>You have disabled text popup limiting.")
return
/client/verb/numpad_target()
set name = "Toggle Numpad targetting"
set category = "Preferences"
set desc = "This button will allow you to enable or disable Numpad Targetting"
prefs.toggles ^= NUMPAD_TARGET
prefs.save_preferences(src)
if (prefs.toggles & NUMPAD_TARGET)
to_chat(usr, "<span class='notice'>You have enabled Numpad Targetting.")
else
to_chat(usr, "<span class='notice'>You have disabled Numpad Targetting.")
return
/client/verb/azerty_toggle()
set name = "Toggle QWERTY/AZERTY"
set category = "Preferences"
set desc = "This button will switch you between QWERTY and AZERTY control sets"
prefs.toggles ^= AZERTY
prefs.save_preferences(src)
if (prefs.toggles & AZERTY)
to_chat(usr, "<span class='notice'>You are now in AZERTY mode.")
else
to_chat(usr, "<span class='notice'>You are now in QWERTY mode.")
return
/client/verb/toggle_ghost_pda()
set name = "Show/Hide GhostPDA"
set category = "Preferences"
set desc = ".Toggle seeing PDA messages as an observer."
prefs.toggles ^= CHAT_GHOSTPDA
to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTPDA) ? "see all PDA messages" : "no longer see PDA messages"].")
prefs.save_preferences(src)
feedback_add_details("admin_verb","TGP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -64,7 +64,6 @@
item_state = "lgloves"
flags = NODROP
/obj/item/clothing/gloves/color/yellow/stun
name = "stun gloves"
desc = "Horrendous and awful. It smells like cancer. The fact it has wires attached to it is incidental."
@@ -72,6 +71,9 @@
var/stun_strength = 5
var/stun_cost = 2000
/obj/item/clothing/gloves/color/yellow/stun/get_cell()
return cell
/obj/item/clothing/gloves/color/yellow/stun/New()
..()
update_icon()
+12 -1
View File
@@ -110,12 +110,23 @@
/obj/item/clothing/mask/muzzle/safety
name = "safety muzzle"
desc = "A muzzle designed to prevent biting."
resist_time = 600
icon_state = "muzzle_secure"
item_state = "muzzle_secure"
resist_time = 0
mute = MUZZLE_MUTE_NONE
security_lock = TRUE
locked = FALSE
materials = list(MAT_METAL=500, MAT_GLASS=50)
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/mask.dmi',
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
"Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
"Grey" = 'icons/mob/species/grey/mask.dmi',
"Drask" = 'icons/mob/species/drask/mask.dmi'
)
/obj/item/clothing/mask/muzzle/safety/shock
name = "shock muzzle"
desc = "A muzzle designed to prevent biting. This one is fitted with a behavior correction system."
@@ -97,6 +97,9 @@
to_chat(usr, "The maintenance panel is [open ? "open" : "closed"].")
to_chat(usr, "Hardsuit systems are [offline ? "<font color='red'>offline</font>" : "<font color='green'>online</font>"].")
/obj/item/rig/get_cell()
return cell
/obj/item/rig/New()
..()
+9 -5
View File
@@ -1,7 +1,7 @@
/datum/event/disease_outbreak
announceWhen = 15
var/virus_type
var/datum/disease/advance/virus_type
/datum/event/disease_outbreak/setup()
announceWhen = rand(15, 30)
@@ -10,9 +10,13 @@
event_announcement.Announce("Confirmed outbreak of level 7 major viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
/datum/event/disease_outbreak/start()
if(!virus_type)
if(prob(25))
virus_type = pick(/datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis, /datum/disease/beesease, /datum/disease/anxiety, /datum/disease/fake_gbs, /datum/disease/fluspanish, /datum/disease/pierrot_throat, /datum/disease/lycan)
else
virus_type = new /datum/disease/advance
virus_type.name = capitalize(pick(GLOB.adjectives)) + " " + capitalize(pick(GLOB.nouns,GLOB.verbs)) // random silly name
virus_type.GenerateSymptoms(1,9,6)
virus_type.AssignProperties(list("resistance" = rand(0,11), "stealth" = rand(0,2), "stage_rate" = rand(0,5), "transmittable" = rand(0,5), "severity" = rand(0,10)))
for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list))
if(issmall(H)) //don't infect monkies; that's a waste
continue
@@ -32,8 +36,8 @@
if(H.stat == DEAD || foundAlready)
continue
var/datum/disease/D
D = new virus_type()
var/datum/disease/advance/D
D = virus_type
D.carrier = TRUE
H.AddDisease(D)
break
@@ -256,6 +256,7 @@
desc = "Full of vitamins and deliciousness!"
icon_state = "orangejuice"
item_state = "carton"
throwforce = 0
isGlass = 0
list_reagents = list("orangejuice" = 100)
@@ -264,6 +265,7 @@
desc = "It's cream. Made from milk. What else did you think you'd find in there?"
icon_state = "cream"
item_state = "carton"
throwforce = 0
isGlass = 0
list_reagents = list("cream" = 100)
@@ -272,6 +274,7 @@
desc = "Well, at least it LOOKS like tomato juice. You can't tell with all that redness."
icon_state = "tomatojuice"
item_state = "carton"
throwforce = 0
isGlass = 0
list_reagents = list("tomatojuice" = 100)
@@ -280,6 +283,7 @@
desc = "Sweet-sour goodness."
icon_state = "limejuice"
item_state = "carton"
throwforce = 0
isGlass = 0
list_reagents = list("limejuice" = 100)
@@ -288,6 +292,7 @@
desc = "Soothing milk."
icon_state = "milk"
item_state = "carton"
throwforce = 0
isGlass = 0
list_reagents = list("milk" = 100)
@@ -164,7 +164,7 @@
// Virology Medical Smartfridge
// ----------------------------
/obj/machinery/smartfridge/secure/chemistry/virology
name = "smart virus storage"
name = "Smart Virus Storage"
desc = "A refrigerated storage unit for volatile sample storage."
req_access_txt = "39"
spawn_meds = list(/obj/item/reagent_containers/syringe/antiviral = 4,
@@ -386,7 +386,8 @@
return data
/obj/machinery/smartfridge/Topic(href, href_list)
if(..()) return 0
if(..())
return FALSE
var/mob/user = usr
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
@@ -396,7 +397,7 @@
if(href_list["close"])
user.unset_machine()
ui.close()
return 0
return FALSE
if(href_list["vend"])
var/index = text2num(href_list["vend"])
@@ -409,17 +410,26 @@
item_quants[K] = max(count - amount, 0)
var/i = amount
for(var/obj/O in contents)
if(O.name == K)
O.forceMove(loc)
adjust_item_drop_location(O)
update_icon()
i--
if(i <= 0)
return 1
return 1
return 0
if(i == 1 && Adjacent(user) && !issilicon(user))
for(var/obj/O in contents)
if(O.name == K)
if(!user.put_in_hands(O))
O.forceMove(loc)
adjust_item_drop_location(O)
update_icon()
break
return TRUE
else
for(var/obj/O in contents)
if(O.name == K)
O.forceMove(loc)
adjust_item_drop_location(O)
update_icon()
i--
if(i <= 0)
return TRUE
return TRUE
return FALSE
/obj/machinery/smartfridge/proc/throw_item()
var/obj/throw_item = null
@@ -0,0 +1,21 @@
/datum/admins/key_down(_key, client/user)
switch(_key)
if("F5")
user.get_admin_say()
return
if("F6")
user.admin_ghost()
return
if("F7")
player_panel_new()
return
if("F8")
user.cmd_admin_pm_panel()
return
if("F9")
user.stealth()
return
if("F10")
user.get_dead_say()
return
..()
+21
View File
@@ -0,0 +1,21 @@
// You might be wondering why this isn't client level. If focus is null, we don't want you to move.
// Only way to do that is to tie the behavior into the focus's keyLoop().
/atom/movable/keyLoop(client/user)
if(!user.keys_held["Ctrl"])
var/movement_dir = NONE
var/list/movement = SSinput.movement_keys
if(user.prefs.toggles & AZERTY)
movement = SSinput.alt_movement_keys
for(var/_key in user.keys_held)
movement_dir = movement_dir | movement[_key]
if(user.next_move_dir_add)
movement_dir |= user.next_move_dir_add
if(user.next_move_dir_sub)
movement_dir &= ~user.next_move_dir_sub
// Sanity checks in case you hold left and right and up to make sure you only go up
if((movement_dir & NORTH) && (movement_dir & SOUTH))
movement_dir &= ~(NORTH|SOUTH)
if((movement_dir & EAST) && (movement_dir & WEST))
movement_dir &= ~(EAST|WEST)
user.Move(get_step(src, movement_dir), movement_dir)
@@ -0,0 +1,20 @@
/mob/living/carbon/key_down(_key, client/user)
user.keys_held[_key] = world.time
if(!user.keys_held["Shift"])
switch(_key)
if("R", "Southwest") // Southwest is End
toggle_throw_mode()
return
if("1")
a_intent_change("help")
return
if("2")
a_intent_change("disarm")
return
if("3")
a_intent_change("grab")
return
if("4")
a_intent_change("harm")
return
return ..()
@@ -0,0 +1,59 @@
// Clients aren't datums so we have to define these procs indpendently.
// These verbs are called for all key press and release events
/client/verb/keyDown(_key as text)
set instant = TRUE
set hidden = TRUE
keys_held[_key] = world.time
var/movement = SSinput.movement_keys[_key]
if (prefs.toggles & AZERTY) movement = SSinput.alt_movement_keys[_key]
if(!(next_move_dir_sub & movement) && !keys_held["Ctrl"])
next_move_dir_add |= movement
// Client-level keybindings are ones anyone should be able to do at any time
// Things like taking screenshots, hitting tab, and adminhelps.
switch(_key)
if("F1")
if(keys_held["Ctrl"] && keys_held["Shift"]) // Is this command ever used?
winset(src, null, "command=.options")
else
adminhelp()
return
if("F2") // Screenshot. Hold shift to choose a name and location to save in
ooc()
return
if("F3")
mob.say_wrapper()
return
if("F4")
mob.me_wrapper()
return
if("F12") // Toggles minimal HUD
mob.button_pressed_F12()
return
if(holder)
holder.key_down(_key, src)
if(mob.focus)
mob.focus.key_down(_key, src)
/client/verb/keyUp(_key as text)
set instant = TRUE
set hidden = TRUE
keys_held -= _key
var/movement = SSinput.movement_keys[_key]
if (prefs.toggles & AZERTY) movement = SSinput.alt_movement_keys[_key]
if(!(next_move_dir_add & movement))
next_move_dir_sub |= movement
if(holder)
holder.key_up(_key, src)
if(mob.focus)
mob.focus.key_up(_key, src)
// Called every game tick
/client/keyLoop()
if(holder)
holder.keyLoop(src)
if(mob.focus)
mob.focus.keyLoop(src)
@@ -0,0 +1,80 @@
/mob/living/carbon/human/key_down(_key, client/user)
if(_key == "H")
var/obj/item/clothing/accessory/holster/H = null
if(istype(w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/S = w_uniform
if(S.accessories.len)
H = locate() in S.accessories
if (!H)
return
if(!H.holstered)
if(!istype(get_active_hand(), /obj/item/gun))
to_chat(usr, "<span class='warning'>You need your gun equiped to holster it.</span>")
return
var/obj/item/gun/W = get_active_hand()
H.holster(W, usr)
else
H.unholster(usr)
if(client.keys_held["Shift"])
switch(_key)
if("E") // Put held thing in belt or take out most recent thing from belt
quick_equip() // Implementing the storage component is going to take way too long
// var/obj/item/thing = get_active_hand()
// var/obj/item/equipped_belt = get_item_by_slot(slot_belt)
// if(!equipped_belt) // We also let you equip a belt like this
// if(!thing)
// to_chat(user, "<span class='notice'>You have no belt to take something out of.</span>")
// return
// if(equip_to_slot_if_possible(thing, slot_belt))
// update_inv_r_hand()
// update_inv_l_hand()
// return
// if(!SEND_SIGNAL(equipped_belt, COMSIG_CONTAINS_STORAGE)) // not a storage item
// if(!thing)
// equipped_belt.attack_hand(src)
// else
// to_chat(user, "<span class='notice'>You can't fit anything in.</span>")
// return
// if(thing) // put thing in belt
// if(!SEND_SIGNAL(equipped_belt, COMSIG_TRY_STORAGE_INSERT, thing, user.mob))
// to_chat(user, "<span class='notice'>You can't fit anything in.</span>")
// return
// if(!equipped_belt.contents.len) // nothing to take out
// to_chat(user, "<span class='notice'>There's nothing in your belt to take out.</span>")
// return
// var/obj/item/stored = equipped_belt.contents[equipped_belt.contents.len]
// if(!stored || stored.on_found(src))
// return
// stored.attack_hand(src) // take out thing from belt
// return
/* if("B") // Put held thing in backpack or take out most recent thing from backpack
var/obj/item/thing = get_active_hand()
var/obj/item/equipped_back = get_item_by_slot(slot_back)
if(!equipped_back) // We also let you equip a backpack like this
if(!thing)
to_chat(user, "<span class='notice'>You have no backpack to take something out of.</span>")
return
if(equip_to_slot_if_possible(thing, slot_back))
update_inv_r_hand()
update_inv_l_hand()
return
if(!SEND_SIGNAL(equipped_back, COMSIG_CONTAINS_STORAGE)) // not a storage item
if(!thing)
equipped_back.attack_hand(src)
else
to_chat(user, "<span class='notice'>You can't fit anything in.</span>")
return
if(thing) // put thing in backpack
if(!SEND_SIGNAL(equipped_back, COMSIG_TRY_STORAGE_INSERT, thing, user.mob))
to_chat(user, "<span class='notice'>You can't fit anything in.</span>")
return
if(!equipped_back.contents.len) // nothing to take out
to_chat(user, "<span class='notice'>There's nothing in your backpack to take out.</span>")
return
var/obj/item/stored = equipped_back.contents[equipped_back.contents.len]
if(!stored || stored.on_found(src))
return
stored.attack_hand(src) // take out thing from backpack
return */
return ..()
@@ -0,0 +1,7 @@
/mob/living/key_down(_key, client/user)
switch(_key)
if("B")
resist()
return
return ..()
+145
View File
@@ -0,0 +1,145 @@
// Technically the client argument is unncessary here since that SHOULD be src.client but let's not assume things
// All it takes is one badmin setting their focus to someone else's client to mess things up
// Or we can have NPC's send actual keypresses and detect that by seeing no client
/mob/key_down(_key, client/user)
if(user.prefs.toggles & AZERTY)
switch(_key)
if("Delete")
if(!pulling)
to_chat(src, "<span class='notice'>You are not pulling anything.</span>")
else
stop_pulling()
return
if("Insert", "G")
a_intent_change(INTENT_HOTKEY_RIGHT)
return
if("F")
a_intent_change(INTENT_HOTKEY_LEFT)
return
if("X", "Northeast") // Northeast is Page-up
swap_hand()
return
if("Y", "W", "Southeast") // Southeast is Page-down
mode() // attack_self(). No idea who came up with "mode()"
return
if("A", "Northwest") // Northwest is Home
var/obj/item/I = get_active_hand()
if(!I)
to_chat(src, "<span class='warning'>You have nothing to drop in your hand!</span>")
else
drop_item(I)
return
if("E")
quick_equip()
return
if("Alt")
toggle_move_intent()
return
else
switch(_key)
if("Delete")
if(!pulling)
to_chat(src, "<span class='notice'>You are not pulling anything.</span>")
else
stop_pulling()
return
if("Insert", "G")
a_intent_change(INTENT_HOTKEY_RIGHT)
return
if("F")
a_intent_change(INTENT_HOTKEY_LEFT)
return
if("X", "Northeast") // Northeast is Page-up
swap_hand()
return
if("Y", "Z", "Southeast") // Southeast is Page-down
mode() // attack_self(). No idea who came up with "mode()"
return
if("Q", "Northwest") // Northwest is Home
var/obj/item/I = get_active_hand()
if(!I)
to_chat(src, "<span class='warning'>You have nothing to drop in your hand!</span>")
else
drop_item(I)
return
if("E")
quick_equip()
return
if("Alt")
toggle_move_intent()
return
//Bodypart selections
if(client.prefs.toggles & NUMPAD_TARGET)
switch(_key)
if("Numpad8")
user.body_toggle_head()
return
if("Numpad4")
user.body_r_arm()
return
if("Numpad5")
user.body_chest()
return
if("Numpad6")
user.body_l_arm()
return
if("Numpad1")
user.body_r_leg()
return
if("Numpad2")
user.body_groin()
return
if("Numpad3")
user.body_l_leg()
return
else
switch(_key)
if("Numpad1")
a_intent_change("help")
return
if("Numpad2")
a_intent_change("disarm")
return
if("Numpad3")
a_intent_change("grab")
return
if("Numpad4")
a_intent_change("harm")
return
if(client.keys_held["Ctrl"] && client.prefs.toggles & AZERTY)
switch(SSinput.alt_movement_keys[_key])
if(NORTH)
northface()
return
if(SOUTH)
southface()
return
if(WEST)
westface()
return
if(EAST)
eastface()
return
else if(client.keys_held["Ctrl"])
switch(SSinput.movement_keys[_key])
if(NORTH)
northface()
return
if(SOUTH)
southface()
return
if(WEST)
westface()
return
if(EAST)
eastface()
return
return ..()
/mob/key_up(_key, client/user)
switch(_key)
if("Alt")
toggle_move_intent()
return
return ..()
@@ -0,0 +1,20 @@
/mob/living/silicon/robot/key_down(_key, client/user)
switch(_key)
if("1", "2", "3")
toggle_module(text2num(_key))
return
if("4")
a_intent_change(INTENT_HOTKEY_LEFT)
return
if("X")
cycle_modules()
return
if("Q")
if(!(client.prefs.toggles & AZERTY))
uneq_active()
return
if("A")
if(client.prefs.toggles & AZERTY)
uneq_active()
return
return ..()
+8
View File
@@ -0,0 +1,8 @@
/mob
var/datum/focus //What receives our keyboard inputs. src by default
/mob/proc/set_focus(datum/new_focus)
if(focus == new_focus)
return
focus = new_focus
reset_perspective(focus) //Maybe this should be done manually? You figure it out, reader
+42
View File
@@ -0,0 +1,42 @@
# In-code keypress handling system
This whole system is heavily based off of forum_account's keyboard library.
Thanks to forum_account for saving the day, the library can be found
[here](https://secure.byond.com/developer/Forum_account/Keyboard)!
.dmf macros have some very serious shortcomings. For example, they do not allow reusing parts
of one macro in another, so giving cyborgs their own shortcuts to swap active module couldn't
inherit the movement that all mobs should have anyways. The webclient only supports one macro,
so having more than one was problematic. Additionally each keybind has to call an actual
verb, which meant a lot of hidden verbs that just call one other proc. Also our existing
macro was really bad and tied unrelated behavior into `Northeast()`, `Southeast()`, `Northwest()`,
and `Southwest()`.
The basic premise of this system is to not screw with .dmf macro setup at all and handle
pressing those keys in the code instead. We have every key call `client.keyDown()`
or `client.keyUp()` with the pressed key as an argument. Certain keys get processed
directly by the client because they should be doable at any time, then we call
`keyDown()` or `keyUp()` on the client's holder and the client's mob's focus.
By default `mob.focus` is the mob itself, but you can set it to any datum to give control of a
client's keypresses to another object. This would be a good way to handle a menu or driving
a mech. You can also set it to null to disregard input from a certain user.
Movement is handled by having each client call `client.keyLoop()` every game tick.
As above, this calls holder and `focus.keyLoop()`. `atom/movable/keyLoop()` handles movement
Try to keep the calculations in this proc light. It runs every tick for every client after all!
You can also tell which keys are being held down now. Each client a list of keys pressed called
`keys_held`. Each entry is a key as a text string associated with the world.time when it was
pressed.
No client-set keybindings at this time, but it shouldn't be too hard if someone wants.
Notes about certain keys:
* `Tab` has client-sided behavior but acts normally
* `T`, `O`, and `M` move focus to the input when pressed. This fires the keyUp macro right away.
* `\` needs to be escaped in the dmf so any usage is `\\`
You cannot `TICK_CHECK` or check `world.tick_usage` inside of procs called by key down and up
events. They happen outside of a byond tick and have no meaning there. Key looping
works correctly since it's part of a subsystem, not direct input.
+46
View File
@@ -0,0 +1,46 @@
/client
var/list/keys_held = list() // A list of any keys held currently
// These next two vars are to apply movement for keypresses and releases made while move delayed.
// Because discarding that input makes the game less responsive.
var/next_move_dir_add // On next move, add this dir to the move that would otherwise be done
var/next_move_dir_sub // On next move, subtract this dir from the move that would otherwise be done
// Set a client's focus to an object and override these procs on that object to let it handle keypresses
/datum/proc/key_down(key, client/user) // Called when a key is pressed down initially
return
/datum/proc/key_up(key, client/user) // Called when a key is released
return
/datum/proc/keyLoop(client/user) // Called once every frame
set waitfor = FALSE
return
// removes all the existing macros
/client/proc/erase_all_macros()
var/list/macro_sets = params2list(winget(src, null, "macros"))
var/erase_output = ""
for(var/i in 1 to macro_sets.len)
var/setname = macro_sets[i]
var/list/macro_set = params2list(winget(src, "[setname].*", "command")) // The third arg doesnt matter here as we're just removing them all
for(var/k in 1 to macro_set.len)
var/list/split_name = splittext(macro_set[k], ".")
var/macro_name = "[split_name[1]].[split_name[2]]" // [3] is "command"
erase_output = "[erase_output];[macro_name].parent=null"
winset(src, null, erase_output)
/client/proc/set_macros()
set waitfor = FALSE
erase_all_macros()
var/list/macro_sets = SSinput.macro_sets
for(var/i in 1 to macro_sets.len)
var/setname = macro_sets[i]
if(setname != "default")
winclone(src, "default", setname)
var/list/macro_set = macro_sets[setname]
for(var/k in 1 to macro_set.len)
var/key = macro_set[k]
var/command = macro_set[key]
winset(src, "[setname]-\ref[key]", "parent=[setname];name=[key];command=[command]")
winset(src, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=old_default")
@@ -238,6 +238,9 @@
/obj/machinery/smartfridge/survival_pod/accept_check(obj/item/O)
return isitem(O)
/obj/machinery/smartfridge/survival_pod/default_unfasten_wrench()
return FALSE
/obj/machinery/smartfridge/survival_pod/empty
name = "dusty survival pod storage"
desc = "A heated storage unit. This one's seen better days."
+43 -42
View File
@@ -1,43 +1,44 @@
/****************Explorer's Suit and Mask****************/
/obj/item/clothing/suit/hooded/explorer
name = "explorer suit"
desc = "An armoured suit for exploring harsh environments."
icon_state = "explorer"
item_state = "explorer"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
hoodtype = /obj/item/clothing/head/hooded/explorer
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
resistance_flags = FIRE_PROOF
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/suit.dmi',
"Drask" = 'icons/mob/species/drask/suit.dmi',
"Tajaran" = 'icons/mob/species/tajaran/suit.dmi',
"Unathi" = 'icons/mob/species/unathi/suit.dmi',
"Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi'
)
/obj/item/clothing/head/hooded/explorer
name = "explorer hood"
desc = "An armoured hood for exploring harsh environments."
icon_state = "explorer"
item_state = "explorer"
body_parts_covered = HEAD
flags = BLOCKHAIR | NODROP
flags_cover = HEADCOVERSEYES
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
resistance_flags = FIRE_PROOF
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/head.dmi',
"Drask" = 'icons/mob/species/drask/head.dmi',
"Grey" = 'icons/mob/species/grey/head.dmi',
"Skrell" = 'icons/mob/species/skrell/head.dmi'
/****************Explorer's Suit and Mask****************/
/obj/item/clothing/suit/hooded/explorer
name = "explorer suit"
desc = "An armoured suit for exploring harsh environments."
icon_state = "explorer"
item_state = "explorer"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
hoodtype = /obj/item/clothing/head/hooded/explorer
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
resistance_flags = FIRE_PROOF
hide_tail_by_species = list("Vox" , "Vulpkanin" , "Unathi" , "Tajaran")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/suit.dmi',
"Drask" = 'icons/mob/species/drask/suit.dmi',
"Tajaran" = 'icons/mob/species/tajaran/suit.dmi',
"Unathi" = 'icons/mob/species/unathi/suit.dmi',
"Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi'
)
/obj/item/clothing/head/hooded/explorer
name = "explorer hood"
desc = "An armoured hood for exploring harsh environments."
icon_state = "explorer"
item_state = "explorer"
body_parts_covered = HEAD
flags = BLOCKHAIR | NODROP
flags_cover = HEADCOVERSEYES
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
resistance_flags = FIRE_PROOF
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/head.dmi',
"Drask" = 'icons/mob/species/drask/head.dmi',
"Grey" = 'icons/mob/species/grey/head.dmi',
"Skrell" = 'icons/mob/species/skrell/head.dmi'
)

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