mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-18 02:24:11 +01:00
Merge remote-tracking branch 'ParadiseSS13/master' into toml-config
This commit is contained in:
+32
-6
@@ -1,12 +1,38 @@
|
||||
[langserver]
|
||||
dreamchecker = true
|
||||
|
||||
# Keep the keys in this file alphabetical please
|
||||
[code_standards]
|
||||
disallow_relative_type_definitions = true
|
||||
disallow_relative_proc_definitions = true
|
||||
disallow_relative_type_definitions = true
|
||||
|
||||
[debugger]
|
||||
engine = "auxtools"
|
||||
|
||||
[dmdoc]
|
||||
use_typepath_names = true
|
||||
|
||||
[debugger]
|
||||
engine = "auxtools"
|
||||
[langserver]
|
||||
dreamchecker = true
|
||||
|
||||
[map_renderer]
|
||||
hide_invisible = [
|
||||
"/obj/effect/landmark",
|
||||
"/obj/effect/mapping_helpers",
|
||||
"/obj/effect/spawner/random_barrier",
|
||||
"/obj/effect/spawner/random_spawners",
|
||||
]
|
||||
|
||||
[map_renderer.fancy_layers]
|
||||
# -10
|
||||
"/turf/simulated/floor/plating" = -10
|
||||
"/turf/space" = -10
|
||||
# -2
|
||||
"/turf/simulated/floor/bluegrid" = -2
|
||||
"/turf/simulated/floor/carpet" = -2
|
||||
"/turf/simulated/floor/engine" = -2
|
||||
"/turf/simulated/floor/plasteel" = -2
|
||||
"/turf/simulated/floor/wood" = -2
|
||||
"/turf/simulated/wall" = -2
|
||||
|
||||
[map_renderer.render_passes]
|
||||
icon-smoothing = false
|
||||
icon-smoothing-2016 = true
|
||||
smart-cables = false
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
/turf/simulated/floor/plating/airless,
|
||||
/area/space/nearstation)
|
||||
"F" = (
|
||||
/obj/structure/computerframe/HONKputer,
|
||||
/obj/structure/computerframe,
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space/nearstation)
|
||||
"G" = (
|
||||
|
||||
@@ -1,4 +1,78 @@
|
||||
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
|
||||
"aa" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8";
|
||||
pixel_y = 0;
|
||||
tag = ""
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4;
|
||||
level = 1
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/fans/tiny,
|
||||
/obj/machinery/door/poddoor{
|
||||
id_tag = "SSBtestchamber";
|
||||
name = "Syndicate Test Lab Blast Door"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"ab" = (
|
||||
/obj/machinery/door_control{
|
||||
id = "SSBtestchamber";
|
||||
name = "Blast Door Control"
|
||||
},
|
||||
/turf/simulated/wall/mineral/plastitanium/nodiagonal,
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"ac" = (
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/fans/tiny,
|
||||
/obj/machinery/door/poddoor{
|
||||
id_tag = "SSBtestchamber";
|
||||
name = "Syndicate Test Lab Blast Door"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"ad" = (
|
||||
/obj/machinery/light{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/obj/machinery/camera/emp_proof{
|
||||
c_tag = "Test Lab West";
|
||||
dir = 4;
|
||||
network = list("SyndicateTestLab")
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"ae" = (
|
||||
/obj/machinery/camera/emp_proof{
|
||||
c_tag = "Test Lab East";
|
||||
dir = 9;
|
||||
network = list("SyndicateTestLab")
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"aj" = (
|
||||
/obj/effect/spawner/window/reinforced,
|
||||
/turf/simulated/floor/plasteel{
|
||||
@@ -1191,18 +1265,6 @@
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/telecomms)
|
||||
"mE" = (
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/fans/tiny,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"mP" = (
|
||||
/obj/machinery/power/generator,
|
||||
/obj/structure/cable/yellow,
|
||||
@@ -1404,14 +1466,6 @@
|
||||
icon_state = "brown"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/cargo)
|
||||
"ol" = (
|
||||
/obj/machinery/light{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/turf/simulated/floor/engine,
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"ow" = (
|
||||
/obj/structure/closet/crate/medical,
|
||||
/obj/item/storage/firstaid/fire{
|
||||
@@ -1861,32 +1915,6 @@
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/main)
|
||||
"un" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8";
|
||||
pixel_y = 0;
|
||||
tag = ""
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4;
|
||||
level = 1
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/fans/tiny,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"uq" = (
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "freezerfloor"
|
||||
@@ -2388,7 +2416,7 @@
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/main)
|
||||
"yf" = (
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "Engine Grid Power Monitoring Computer"
|
||||
},
|
||||
/obj/structure/cable/yellow,
|
||||
@@ -4114,7 +4142,7 @@
|
||||
icon_state = "0-2";
|
||||
pixel_y = 1
|
||||
},
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "Output Grid Power Monitoring Computer"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
@@ -4926,6 +4954,13 @@
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/main)
|
||||
"ZG" = (
|
||||
/obj/machinery/computer/security/telescreen{
|
||||
name = "Test Lab Monitor";
|
||||
network = list("SyndicateTestLab")
|
||||
},
|
||||
/turf/simulated/wall/mineral/plastitanium/nodiagonal,
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"ZR" = (
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
@@ -6837,8 +6872,8 @@ TD
|
||||
TD
|
||||
rr
|
||||
CM
|
||||
TD
|
||||
TD
|
||||
ZG
|
||||
ab
|
||||
TD
|
||||
CM
|
||||
ZR
|
||||
@@ -6897,13 +6932,13 @@ ia
|
||||
ia
|
||||
ia
|
||||
TD
|
||||
un
|
||||
aa
|
||||
TD
|
||||
ia
|
||||
ia
|
||||
ia
|
||||
TD
|
||||
mE
|
||||
ac
|
||||
TD
|
||||
AV
|
||||
AV
|
||||
@@ -7022,7 +7057,7 @@ fH
|
||||
fH
|
||||
RC
|
||||
uN
|
||||
ol
|
||||
ad
|
||||
RF
|
||||
RF
|
||||
dH
|
||||
@@ -7952,7 +7987,7 @@ qv
|
||||
Vl
|
||||
Vl
|
||||
Vl
|
||||
Vl
|
||||
ae
|
||||
Vl
|
||||
Vl
|
||||
Vl
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
},
|
||||
/area/derelict/bridge)
|
||||
"av" = (
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 1;
|
||||
icon_state = "darkblue"
|
||||
@@ -3697,7 +3697,7 @@
|
||||
name = "Derelict Annex"
|
||||
})
|
||||
"hD" = (
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "caution";
|
||||
dir = 5
|
||||
|
||||
@@ -2536,7 +2536,7 @@
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/obj/effect/decal/warning_stripes/west,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/awaymission/BMPship/Aft)
|
||||
|
||||
@@ -2785,7 +2785,7 @@
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "yellow"
|
||||
},
|
||||
|
||||
@@ -1308,7 +1308,7 @@
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
@@ -5160,7 +5160,7 @@
|
||||
/turf/simulated/floor/plating,
|
||||
/area/awaycontent/a7)
|
||||
"hm" = (
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/obj/structure/cable,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/awaycontent/a7)
|
||||
|
||||
@@ -7975,7 +7975,7 @@
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "primary power monitoring console"
|
||||
},
|
||||
/obj/structure/sign/nosmoking_2{
|
||||
@@ -10652,7 +10652,7 @@
|
||||
/turf/simulated/floor/plating/asteroid/airless,
|
||||
/area/awaymission/UO71/outside)
|
||||
"vV" = (
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/awaymission/UO71/bridge)
|
||||
"vW" = (
|
||||
@@ -11805,7 +11805,7 @@
|
||||
},
|
||||
/area/awaymission/UO71/eng)
|
||||
"yc" = (
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "primary power monitoring console"
|
||||
},
|
||||
/obj/structure/cable,
|
||||
|
||||
@@ -11078,7 +11078,7 @@
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "primary power monitoring console"
|
||||
},
|
||||
/obj/structure/sign/nosmoking_2{
|
||||
@@ -15909,7 +15909,7 @@
|
||||
name = "UO45 Engineering"
|
||||
})
|
||||
"xg" = (
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "primary power monitoring console"
|
||||
},
|
||||
/obj/structure/cable,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,7 +32,6 @@
|
||||
#define SPECIAL_ROLE_FREE_GOLEM "Free Golem"
|
||||
#define SPECIAL_ROLE_GOLEM "Golem"
|
||||
#define SPECIAL_ROLE_HEAD_REV "Head Revolutionary"
|
||||
#define SPECIAL_ROLE_HONKSQUAD "Honksquad"
|
||||
#define SPECIAL_ROLE_REV "Revolutionary"
|
||||
#define SPECIAL_ROLE_MORPH "Morph"
|
||||
#define SPECIAL_ROLE_MULTIVERSE "Multiverse Traveller"
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
#define iseffect(A) (istype(A, /obj/effect))
|
||||
|
||||
#define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable
|
||||
|
||||
#define isclothing(A) (istype(A, /obj/item/clothing))
|
||||
|
||||
#define is_pen(W) (istype(W, /obj/item/pen))
|
||||
|
||||
@@ -39,11 +39,16 @@
|
||||
#define ROLE_ERT "emergency response team"
|
||||
#define ROLE_NYMPH "Dionaea"
|
||||
#define ROLE_GSPIDER "giant spider"
|
||||
#define ROLE_TSPIDER "terror spider"
|
||||
#define ROLE_DRONE "drone"
|
||||
#define ROLE_DEATHSQUAD "deathsquad"
|
||||
#define ROLE_EVENTMISC "eventmisc"
|
||||
#define ROLE_GHOST "ghost role"
|
||||
|
||||
// Misc jobban categories
|
||||
#define ROLEBAN_AHUD "AntagHUD"
|
||||
#define ROLEBAN_RECORDS "Records"
|
||||
|
||||
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
|
||||
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
|
||||
//(in game days played) to play that role
|
||||
|
||||
@@ -18,6 +18,7 @@ GLOBAL_LIST_INIT(antag_roles, list(
|
||||
ROLE_GUARDIAN,
|
||||
ROLE_MORPH,
|
||||
ROLE_GSPIDER,
|
||||
ROLE_TSPIDER,
|
||||
))
|
||||
|
||||
// Bannable other roles
|
||||
@@ -26,6 +27,6 @@ GLOBAL_LIST_INIT(other_roles, list(
|
||||
ROLE_NYMPH,
|
||||
ROLE_ERT,
|
||||
ROLE_GHOST,
|
||||
"AntagHUD",
|
||||
"Records"
|
||||
ROLEBAN_AHUD,
|
||||
ROLEBAN_RECORDS
|
||||
))
|
||||
|
||||
@@ -142,6 +142,14 @@ GLOBAL_PROTECT(log_end)
|
||||
/proc/log_tgui(text)
|
||||
rustg_log_write(GLOB.tgui_log, "[text][GLOB.log_end]")
|
||||
|
||||
#ifdef REFERENCE_TRACKING
|
||||
/proc/log_gc(text)
|
||||
rustg_log_write(GLOB.gc_log, "[text][GLOB.log_end]")
|
||||
for(var/client/C in GLOB.admins)
|
||||
if(check_rights(R_DEBUG, FALSE, C.mob) && (C.prefs.toggles & PREFTOGGLE_CHAT_DEBUGLOGS))
|
||||
to_chat(C, "GC DEBUG: [text]")
|
||||
#endif
|
||||
|
||||
/proc/log_sql(text)
|
||||
rustg_log_write(GLOB.sql_log, "[text][GLOB.log_end]")
|
||||
SEND_TEXT(world.log, text) // Redirect it to DD too
|
||||
|
||||
@@ -308,7 +308,7 @@
|
||||
if(G.client != null)
|
||||
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
|
||||
if(!G.client.is_afk(afk_bracket) && (be_special_type in G.client.prefs.be_special))
|
||||
if(!override_jobban || (!jobban_isbanned(G, roletext) && !jobban_isbanned(G,"Syndicate")))
|
||||
if(!override_jobban || (!jobban_isbanned(G, roletext) && !jobban_isbanned(G, ROLE_SYNDICATE)))
|
||||
if(override_age || player_old_enough_antag(G.client,be_special_type))
|
||||
candidates += G.client
|
||||
afk_bracket += 600 // Add a minute to the bracket, for every attempt
|
||||
@@ -324,7 +324,7 @@
|
||||
if(G.client != null)
|
||||
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
|
||||
if(!G.client.is_afk(afk_bracket) && (be_special_type in G.client.prefs.be_special))
|
||||
if(!override_jobban || (!jobban_isbanned(G, roletext) && !jobban_isbanned(G,"Syndicate")))
|
||||
if(!override_jobban || (!jobban_isbanned(G, roletext) && !jobban_isbanned(G, ROLE_SYNDICATE)))
|
||||
if(override_age || player_old_enough_antag(G.client,be_special_type))
|
||||
candidates += G
|
||||
afk_bracket += 600 // Add a minute to the bracket, for every attempt
|
||||
|
||||
@@ -119,6 +119,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_XENO_HOST "xeno_host" //Tracks whether we're gonna be a baby alien's mummy.
|
||||
#define TRAIT_SHOCKIMMUNE "shock_immunity"
|
||||
#define TRAIT_TESLA_SHOCKIMMUNE "tesla_shock_immunity"
|
||||
#define TRAIT_TELEKINESIS "telekinesis"
|
||||
#define TRAIT_RESISTHEAT "resist_heat"
|
||||
#define TRAIT_RESISTHEATHANDS "resist_heat_handsonly" //For when you want to be able to touch hot things, but still want fire to be an issue.
|
||||
#define TRAIT_RESISTCOLD "resist_cold"
|
||||
|
||||
+11
-14
@@ -31,19 +31,20 @@
|
||||
return 1
|
||||
|
||||
|
||||
/proc/Get_Angle(atom/movable/start,atom/movable/end)//For beams.
|
||||
if(!start || !end) return 0
|
||||
/proc/get_angle(atom/movable/start, atom/movable/end)//For beams.
|
||||
if(!start || !end)
|
||||
return 0
|
||||
var/dy
|
||||
var/dx
|
||||
dy=(32*end.y+end.pixel_y)-(32*start.y+start.pixel_y)
|
||||
dx=(32*end.x+end.pixel_x)-(32*start.x+start.pixel_x)
|
||||
dy = (32 * end.y + end.pixel_y) - (32 * start.y + start.pixel_y)
|
||||
dx = (32 * end.x + end.pixel_x) - (32 * start.x + start.pixel_x)
|
||||
if(!dy)
|
||||
return (dx>=0)?90:270
|
||||
.=arctan(dx/dy)
|
||||
if(dy<0)
|
||||
.+=180
|
||||
else if(dx<0)
|
||||
.+=360
|
||||
return (dx >= 0) ? 90 : 270
|
||||
. = arctan(dx / dy)
|
||||
if(dy < 0)
|
||||
. += 180
|
||||
else if(dx < 0)
|
||||
. += 360
|
||||
|
||||
//Returns location. Returns null if no location was found.
|
||||
/proc/get_teleport_loc(turf/location,mob/target,distance = 1, density = 0, errorx = 0, errory = 0, eoffsetx = 0, eoffsety = 0)
|
||||
@@ -1246,10 +1247,6 @@ GLOBAL_LIST_INIT(wall_items, typecacheof(list(/obj/machinery/power/apc, /obj/mac
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/proc/get_angle(atom/a, atom/b)
|
||||
return atan2(b.y - a.y, b.x - a.x)
|
||||
|
||||
/proc/atan2(x, y)
|
||||
if(!x && !y) return 0
|
||||
return y >= 0 ? arccos(x / sqrt(x * x + y * y)) : -arccos(x / sqrt(x * x + y * y))
|
||||
|
||||
@@ -9,13 +9,15 @@
|
||||
#define UNIT_TESTS
|
||||
#endif
|
||||
|
||||
#ifdef TESTING
|
||||
//#define GC_FAILURE_HARD_LOOKUP //makes paths that fail to GC call find_references before del'ing.
|
||||
//implies FIND_REF_NO_CHECK_TICK
|
||||
/***** All toggles for the GC ref finder *****/
|
||||
|
||||
//#define FIND_REF_NO_CHECK_TICK //Sets world.loop_checks to false and prevents find references from sleeping
|
||||
// #define REFERENCE_TRACKING // Uncomment to enable ref finding
|
||||
|
||||
#endif
|
||||
// #define GC_FAILURE_HARD_LOOKUP //makes paths that fail to GC call find_references before del'ing.
|
||||
|
||||
// #define FIND_REF_NO_CHECK_TICK //Sets world.loop_checks to false and prevents find references from sleeping
|
||||
|
||||
/***** End toggles for the GC ref finder *****/
|
||||
|
||||
#define IS_MODE_COMPILED(MODE) (ispath(text2path("/datum/game_mode/"+(MODE))))
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ GLOBAL_LIST_INIT(restricted_camera_networks, list(
|
||||
"UO45",
|
||||
"UO45R",
|
||||
"UO71",
|
||||
"Xeno"
|
||||
"Xeno",
|
||||
"SyndicateTestLab"
|
||||
)) //Those networks can only be accessed by preexisting terminals. AIs and new terminals can't use them.
|
||||
|
||||
GLOBAL_LIST_INIT(ruin_landmarks, list())
|
||||
|
||||
@@ -40,7 +40,7 @@ GLOBAL_LIST_INIT(drinks, list("beer2","hot_coco","orangejuice","tomatojuice","li
|
||||
"booger","bloodymary","gargleblaster","bravebull","tequilasunrise","toxinsspecial",
|
||||
"beepskysmash","salglu_solution","irishcream","manlydorf","longislandicedtea",
|
||||
"moonshine","b52","irishcoffee","margarita","blackrussian","manhattan",
|
||||
"manhattan_proj","whiskeysoda","antifreeze","barefoot","snowwhite","demonsblood",
|
||||
"manhattan_proj","whiskeysoda","adminfreeze","antifreeze","barefoot","snowwhite","demonsblood",
|
||||
"vodkatonic","ginfizz","bahama_mama","singulo","sbiten","devilskiss","red_mead",
|
||||
"mead","iced_beer","grog","aloe","andalusia","alliescocktail","soy_latte",
|
||||
"cafe_latte","acidspit","amasec","neurotoxin","hippiesdelight","bananahonk",
|
||||
|
||||
@@ -24,6 +24,11 @@ GLOBAL_PROTECT(chat_debug_log)
|
||||
GLOBAL_VAR(round_id)
|
||||
GLOBAL_PROTECT(round_id)
|
||||
|
||||
#ifdef REFERENCE_TRACKING
|
||||
GLOBAL_VAR(gc_log)
|
||||
GLOBAL_PROTECT(gc_log)
|
||||
#endif
|
||||
|
||||
GLOBAL_LIST_EMPTY(jobMax)
|
||||
GLOBAL_PROTECT(jobMax)
|
||||
GLOBAL_LIST_EMPTY(admin_log)
|
||||
|
||||
@@ -33,44 +33,6 @@ GLOBAL_VAR_INIT(gravity_is_on, 1) //basically unused, just one admin verb..
|
||||
// Recall time limit: 2 hours
|
||||
GLOBAL_VAR_INIT(recall_time_limit, 72000) //apparently used for the comm console
|
||||
|
||||
//////SCORE STUFF
|
||||
//Goonstyle scoreboard
|
||||
GLOBAL_VAR_INIT(score_crewscore, 0) // this is the overall var/score for the whole round
|
||||
GLOBAL_VAR_INIT(score_stuffshipped, 0) // how many useful items have cargo shipped out?
|
||||
GLOBAL_VAR_INIT(score_stuffharvested, 0) // how many harvests have hydroponics done?
|
||||
GLOBAL_VAR_INIT(score_oremined, 0) // obvious
|
||||
GLOBAL_VAR_INIT(score_researchdone, 0)
|
||||
GLOBAL_VAR_INIT(score_eventsendured, 0) // how many random events did the station survive?
|
||||
GLOBAL_VAR_INIT(score_powerloss, 0) // how many APCs have poor charge?
|
||||
GLOBAL_VAR_INIT(score_escapees, 0) // how many people got out alive?
|
||||
GLOBAL_VAR_INIT(score_deadcrew, 0) // dead bodies on the station, oh no
|
||||
GLOBAL_VAR_INIT(score_mess, 0) // how much poo, puke, gibs, etc went uncleaned
|
||||
GLOBAL_VAR_INIT(score_meals, 0)
|
||||
GLOBAL_VAR_INIT(score_disease, 0) // how many rampant, uncured diseases are on board the station
|
||||
GLOBAL_VAR_INIT(score_deadcommand, 0) // used during rev, how many command staff perished
|
||||
GLOBAL_VAR_INIT(score_arrested, 0) // how many traitors/revs/whatever are alive in the brig
|
||||
GLOBAL_VAR_INIT(score_traitorswon, 0) // how many traitors were successful?
|
||||
GLOBAL_VAR_INIT(score_allarrested, 0) // did the crew catch all the enemies alive?
|
||||
GLOBAL_VAR_INIT(score_opkilled, 0) // used during nuke mode, how many operatives died?
|
||||
GLOBAL_VAR_INIT(score_disc, 0) // is the disc safe and secure?
|
||||
GLOBAL_VAR_INIT(score_nuked, 0) // was the station blown into little bits?
|
||||
GLOBAL_VAR_INIT(score_nuked_penalty, 0) //penalty for getting blown to bits
|
||||
|
||||
// these ones are mainly for the stat panel
|
||||
GLOBAL_VAR_INIT(score_powerbonus, 0) // if all APCs on the station are running optimally, big bonus
|
||||
GLOBAL_VAR_INIT(score_messbonus, 0) // if there are no messes on the station anywhere, huge bonus
|
||||
GLOBAL_VAR_INIT(score_deadaipenalty, 0) // is the AI dead? if so, big penalty
|
||||
GLOBAL_VAR_INIT(score_foodeaten, 0) // nom nom nom
|
||||
GLOBAL_VAR_INIT(score_clownabuse, 0) // how many times a clown was punched, struck or otherwise maligned
|
||||
GLOBAL_VAR(score_richestname) // this is all stuff to show who was the richest alive on the shuttle
|
||||
GLOBAL_VAR(score_richestjob) // kinda pointless if you dont have a money system i guess
|
||||
GLOBAL_VAR_INIT(score_richestcash, 0)
|
||||
GLOBAL_VAR(score_richestkey)
|
||||
GLOBAL_VAR(score_dmgestname) // who had the most damage on the shuttle (but was still alive)
|
||||
GLOBAL_VAR(score_dmgestjob)
|
||||
GLOBAL_VAR_INIT(score_dmgestdamage, 0)
|
||||
GLOBAL_VAR(score_dmgestkey)
|
||||
|
||||
#define TAB " "
|
||||
|
||||
GLOBAL_VAR_INIT(timezoneOffset, 0) // The difference betwen midnight (of the host computer) and 0 world.ticks.
|
||||
|
||||
@@ -24,6 +24,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_XENO_HOST" = TRAIT_XENO_HOST,
|
||||
"TRAIT_SHOCKIMMUNE" = TRAIT_SHOCKIMMUNE,
|
||||
"TRAIT_TESLA_SHOCKIMMUNE" = TRAIT_TESLA_SHOCKIMMUNE,
|
||||
"TRAIT_TELEKINESIS" = TRAIT_TELEKINESIS,
|
||||
"TRAIT_RESISTHEAT" = TRAIT_RESISTHEAT,
|
||||
"TRAIT_RESISTHEATHANDS" = TRAIT_RESISTHEATHANDS,
|
||||
"TRAIT_RESISTCOLD" = TRAIT_RESISTCOLD,
|
||||
|
||||
@@ -215,11 +215,3 @@
|
||||
if(!ai_control_check(user))
|
||||
return
|
||||
toggle_light(user)
|
||||
|
||||
// AI-CONTROLLED SLIP GENERATOR IN AI CORE
|
||||
|
||||
/obj/machinery/ai_slipper/AICtrlClick(mob/living/silicon/ai/user) //Turns liquid dispenser on or off
|
||||
ToggleOn()
|
||||
|
||||
/obj/machinery/ai_slipper/AIAltClick() //Dispenses liquid if on
|
||||
Activate()
|
||||
|
||||
+1
-11
@@ -17,7 +17,7 @@
|
||||
|
||||
if(is_ventcrawling(src)) // To stop drones interacting with anything while ventcrawling
|
||||
return
|
||||
if(stat == DEAD)
|
||||
if(stat == DEAD || lockcharge || IsWeakened() || stunned || paralysis || low_power_mode)
|
||||
return
|
||||
|
||||
var/list/modifiers = params2list(params)
|
||||
@@ -169,16 +169,6 @@
|
||||
/obj/machinery/power/apc/BorgCtrlClick(mob/living/silicon/robot/user) // turns off/on APCs. Forwards to AI code.
|
||||
AICtrlClick(user)
|
||||
|
||||
|
||||
// AI SLIPPER
|
||||
|
||||
/obj/machinery/ai_slipper/BorgCtrlClick(mob/living/silicon/robot/user) //Turns liquid dispenser on or off
|
||||
ToggleOn()
|
||||
|
||||
/obj/machinery/ai_slipper/BorgAltClick(mob/living/silicon/robot/user) //Dispenses liquid if on
|
||||
Activate()
|
||||
|
||||
|
||||
// TURRETCONTROL
|
||||
|
||||
/obj/machinery/turretid/BorgCtrlClick(mob/living/silicon/robot/user) //turret control on/off. Forwards to AI code.
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
if(HAS_TRAIT(src, TRAIT_LASEREYES) && a_intent == INTENT_HARM)
|
||||
LaserEyes(A)
|
||||
|
||||
if(dna.GetSEState(GLOB.teleblock))
|
||||
if(HAS_TRAIT(src, TRAIT_TELEKINESIS))
|
||||
A.attack_tk(src)
|
||||
|
||||
if(isturf(A) && get_dist(src, A) <= 1)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
/obj/item/attack_tk(mob/user)
|
||||
if(user.stat || !isturf(loc))
|
||||
return
|
||||
if(user.dna?.GetSEState(GLOB.teleblock) && !user.get_active_hand()) // both should already be true to get here
|
||||
if(HAS_TRAIT(user, TRAIT_TELEKINESIS) && !user.get_active_hand()) // both should already be true to get here
|
||||
var/obj/item/tk_grab/O = new(src)
|
||||
O.form_grab(user, src)
|
||||
else
|
||||
@@ -109,7 +109,7 @@
|
||||
if(!host || host != user)
|
||||
qdel(src)
|
||||
return
|
||||
if(!host.dna?.GetSEState(GLOB.teleblock))
|
||||
if(!HAS_TRAIT(host, TRAIT_TELEKINESIS))
|
||||
qdel(src)
|
||||
return
|
||||
if(isobj(target) && !isturf(target.loc))
|
||||
@@ -139,6 +139,12 @@
|
||||
|
||||
|
||||
else
|
||||
if(focus.buckled_mobs)
|
||||
to_chat(user, "<span class='notice'>This object is too heavy to move with something buckled to it!</span>")
|
||||
return
|
||||
if(length(focus.client_mobs_in_contents))
|
||||
to_chat(user, "<span class='notice'>This object is too heavy to move with something inside of it!</span>")
|
||||
return
|
||||
apply_focus_overlay()
|
||||
focus.throw_at(target, 10, 1, user)
|
||||
last_throw = world.time
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
SUBSYSTEM_DEF(chat_pings)
|
||||
name = "Chat Pings"
|
||||
flags = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_INIT | RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME // ALL OF THEM
|
||||
wait = 30 SECONDS // Chat pings every 30 seconds
|
||||
/// List of all held chat datums
|
||||
var/list/datum/chatOutput/chat_datums = list() // Do NOT put this in Initialize(). You will cause issues.
|
||||
|
||||
/datum/controller/subsystem/chat_pings/fire(resumed)
|
||||
for(var/datum/chatOutput/CO as anything in chat_datums)
|
||||
CO.updatePing()
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/chat_pings/stat_entry()
|
||||
..("P: [length(chat_datums)]")
|
||||
@@ -26,8 +26,9 @@ SUBSYSTEM_DEF(garbage)
|
||||
//Queue
|
||||
var/list/queues
|
||||
|
||||
#ifdef TESTING
|
||||
#ifdef REFERENCE_TRACKING
|
||||
var/list/reference_find_on_fail = list()
|
||||
var/ref_search_stop = FALSE
|
||||
#endif
|
||||
|
||||
|
||||
@@ -137,7 +138,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
++gcedlasttick
|
||||
++totalgcs
|
||||
pass_counts[level]++
|
||||
#ifdef TESTING
|
||||
#ifdef REFERENCE_TRACKING
|
||||
reference_find_on_fail -= refID //It's deleted we don't care anymore.
|
||||
#endif
|
||||
if(MC_TICK_CHECK)
|
||||
@@ -146,20 +147,27 @@ SUBSYSTEM_DEF(garbage)
|
||||
|
||||
// Something's still referring to the qdel'd object.
|
||||
fail_counts[level]++
|
||||
#ifdef REFERENCE_TRACKING
|
||||
var/ref_searching = FALSE
|
||||
#endif
|
||||
switch(level)
|
||||
if(GC_QUEUE_CHECK)
|
||||
#ifdef TESTING
|
||||
if(reference_find_on_fail[refID])
|
||||
D.find_references()
|
||||
#ifdef REFERENCE_TRACKING
|
||||
if(reference_find_on_fail[refID] && !ref_search_stop)
|
||||
INVOKE_ASYNC(D, /datum/proc/find_references)
|
||||
ref_searching = TRUE
|
||||
#ifdef GC_FAILURE_HARD_LOOKUP
|
||||
else
|
||||
D.find_references()
|
||||
else if (!ref_search_stop)
|
||||
INVOKE_ASYNC(D, /datum/proc/find_references)
|
||||
ref_searching = TRUE
|
||||
#endif
|
||||
reference_find_on_fail -= refID
|
||||
#endif
|
||||
var/type = D.type
|
||||
var/datum/qdel_item/I = items[type]
|
||||
testing("GC: -- \ref[src] | [type] was unable to be GC'd --")
|
||||
#ifdef REFERENCE_TRACKING
|
||||
log_gc("GC: -- \ref[src] | [type] was unable to be GC'd --")
|
||||
#endif
|
||||
I.failures++
|
||||
if(GC_QUEUE_HARDDELETE)
|
||||
HardDelete(D)
|
||||
@@ -169,6 +177,11 @@ SUBSYSTEM_DEF(garbage)
|
||||
|
||||
Queue(D, level + 1)
|
||||
|
||||
#ifdef REFERENCE_TRACKING
|
||||
if(ref_searching)
|
||||
return
|
||||
#endif
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
if(count)
|
||||
@@ -243,10 +256,14 @@ SUBSYSTEM_DEF(garbage)
|
||||
/datum/qdel_item/New(mytype)
|
||||
name = "[mytype]"
|
||||
|
||||
#ifdef TESTING
|
||||
/proc/qdel_and_find_ref_if_fail(datum/D, force = FALSE)
|
||||
SSgarbage.reference_find_on_fail["\ref[D]"] = TRUE
|
||||
qdel(D, force)
|
||||
#ifdef REFERENCE_TRACKING
|
||||
/proc/qdel_and_find_ref_if_fail(datum/thing_to_del, force = FALSE)
|
||||
thing_to_del.qdel_and_find_ref_if_fail(force)
|
||||
|
||||
/datum/proc/qdel_and_find_ref_if_fail(force = FALSE)
|
||||
SSgarbage.reference_find_on_fail["\ref[src]"] = TRUE
|
||||
qdel(src, force)
|
||||
|
||||
#endif
|
||||
|
||||
// Should be treated as a replacement for the 'del' keyword.
|
||||
@@ -304,38 +321,39 @@ SUBSYSTEM_DEF(garbage)
|
||||
SSgarbage.HardDelete(D)
|
||||
if(QDEL_HINT_FINDREFERENCE)//qdel will, if TESTING is enabled, display all references to this object, then queue the object for deletion.
|
||||
SSgarbage.Queue(D)
|
||||
#ifdef TESTING
|
||||
#ifdef REFERENCE_TRACKING
|
||||
D.find_references()
|
||||
#endif
|
||||
if(QDEL_HINT_IFFAIL_FINDREFERENCE)
|
||||
SSgarbage.Queue(D)
|
||||
#ifdef TESTING
|
||||
#ifdef REFERENCE_TRACKING
|
||||
SSgarbage.reference_find_on_fail["\ref[D]"] = TRUE
|
||||
#endif
|
||||
else
|
||||
#ifdef TESTING
|
||||
#ifdef REFERENCE_TRACKING
|
||||
if(!I.no_hint)
|
||||
testing("WARNING: [D.type] is not returning a qdel hint. It is being placed in the queue. Further instances of this type will also be queued.")
|
||||
log_gc("WARNING: [D.type] is not returning a qdel hint. It is being placed in the queue. Further instances of this type will also be queued.")
|
||||
#endif
|
||||
I.no_hint++
|
||||
SSgarbage.Queue(D)
|
||||
else if(D.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
|
||||
CRASH("[D.type] destroy proc was called multiple times, likely due to a qdel loop in the Destroy logic")
|
||||
|
||||
#ifdef TESTING
|
||||
#ifdef REFERENCE_TRACKING
|
||||
|
||||
/datum/verb/find_refs()
|
||||
/datum/proc/find_refs()
|
||||
set category = "Debug"
|
||||
set name = "Find References"
|
||||
set src in world
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
find_references(FALSE)
|
||||
|
||||
/datum/proc/find_references(skip_alert)
|
||||
running_find_references = type
|
||||
if(usr && usr.client)
|
||||
if(usr.client.running_find_references)
|
||||
testing("CANCELLED search for references to a [usr.client.running_find_references].")
|
||||
log_gc("CANCELLED search for references to a [usr.client.running_find_references].")
|
||||
usr.client.running_find_references = null
|
||||
running_find_references = null
|
||||
//restart the garbage collector
|
||||
@@ -354,20 +372,27 @@ SUBSYSTEM_DEF(garbage)
|
||||
if(usr && usr.client)
|
||||
usr.client.running_find_references = type
|
||||
|
||||
testing("Beginning search for references to a [type].")
|
||||
last_find_references = world.time
|
||||
log_gc("Beginning search for references to a [type].")
|
||||
var/starting_time = world.time
|
||||
|
||||
DoSearchVar(GLOB) //globals
|
||||
DoSearchVar(GLOB, "GLOB") //globals
|
||||
log_gc("Finished searching globals")
|
||||
for(var/datum/thing in world) //atoms (don't beleive it's lies)
|
||||
DoSearchVar(thing, "World -> [thing]")
|
||||
DoSearchVar(thing, "World -> [thing.type]", search_time = starting_time)
|
||||
|
||||
log_gc("Finished searching atoms")
|
||||
|
||||
for(var/datum/thing) //datums
|
||||
DoSearchVar(thing, "World -> [thing]")
|
||||
DoSearchVar(thing, "World -> [thing.type]", search_time = starting_time)
|
||||
|
||||
log_gc("Finished searching datums")
|
||||
|
||||
for(var/client/thing) //clients
|
||||
DoSearchVar(thing, "World -> [thing]")
|
||||
DoSearchVar(thing, "World -> [thing.type]", search_time = starting_time)
|
||||
|
||||
testing("Completed search for references to a [type].")
|
||||
log_gc("Finished searching clients")
|
||||
|
||||
log_gc("Completed search for references to a [type].")
|
||||
if(usr && usr.client)
|
||||
usr.client.running_find_references = null
|
||||
running_find_references = null
|
||||
@@ -376,58 +401,86 @@ SUBSYSTEM_DEF(garbage)
|
||||
SSgarbage.can_fire = 1
|
||||
SSgarbage.next_fire = world.time + world.tick_lag
|
||||
|
||||
/datum/verb/qdel_then_find_references()
|
||||
/datum/proc/qdel_then_find_references()
|
||||
set category = "Debug"
|
||||
set name = "qdel() then Find References"
|
||||
set src in world
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
qdel(src, TRUE) //Force.
|
||||
qdel(src, TRUE) //force a qdel
|
||||
if(!running_find_references)
|
||||
find_references(TRUE)
|
||||
|
||||
/datum/verb/qdel_then_if_fail_find_references()
|
||||
/datum/proc/qdel_then_if_fail_find_references()
|
||||
set category = "Debug"
|
||||
set name = "qdel() then Find References if GC failure"
|
||||
set src in world
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
qdel_and_find_ref_if_fail(src, TRUE)
|
||||
|
||||
/datum/proc/DoSearchVar(X, Xname, recursive_limit = 64)
|
||||
if(usr && usr.client && !usr.client.running_find_references)
|
||||
return
|
||||
if(!recursive_limit)
|
||||
/datum/proc/DoSearchVar(potential_container, container_name, recursive_limit = 64, search_time = world.time)
|
||||
if((usr?.client && !usr.client.running_find_references) || SSgarbage.ref_search_stop)
|
||||
return
|
||||
|
||||
if(istype(X, /datum))
|
||||
var/datum/D = X
|
||||
if(D.last_find_references == last_find_references)
|
||||
if(!recursive_limit)
|
||||
log_gc("Recursion limit reached. [container_name]")
|
||||
return
|
||||
|
||||
//Check each time you go down a layer. This makes it a bit slow, but it won't effect the rest of the game at all
|
||||
#ifndef FIND_REF_NO_CHECK_TICK
|
||||
CHECK_TICK
|
||||
#endif
|
||||
|
||||
if(istype(potential_container, /datum))
|
||||
var/datum/datum_container = potential_container
|
||||
if(datum_container.last_find_references == search_time)
|
||||
return
|
||||
|
||||
D.last_find_references = last_find_references
|
||||
var/list/L = D.vars
|
||||
datum_container.last_find_references = search_time
|
||||
var/list/vars_list = datum_container.vars
|
||||
|
||||
for(var/varname in L)
|
||||
if(varname == "vars")
|
||||
for(var/varname in vars_list)
|
||||
#ifndef FIND_REF_NO_CHECK_TICK
|
||||
CHECK_TICK
|
||||
#endif
|
||||
if(varname == "vars" || varname == "vis_locs") //Fun fact, vis_locs don't count for references
|
||||
continue
|
||||
var/variable = L[varname]
|
||||
var/variable = vars_list[varname]
|
||||
|
||||
if(variable == src)
|
||||
testing("Found [src.type] \ref[src] in [D.type]'s [varname] var. [Xname]")
|
||||
log_gc("Found [type] \ref[src] in [datum_container.type]'s \ref[datum_container] [varname] var. [container_name]")
|
||||
continue
|
||||
|
||||
else if(islist(variable))
|
||||
DoSearchVar(variable, "[Xname] -> list", recursive_limit - 1)
|
||||
if(islist(variable))
|
||||
DoSearchVar(variable, "[container_name] \ref[datum_container] -> [varname] (list)", recursive_limit - 1, search_time)
|
||||
|
||||
else if(islist(X))
|
||||
var/normal = IS_NORMAL_LIST(X)
|
||||
for(var/I in X)
|
||||
if(I == src)
|
||||
testing("Found [src.type] \ref[src] in list [Xname].")
|
||||
else if(islist(potential_container))
|
||||
var/normal = IS_NORMAL_LIST(potential_container)
|
||||
var/list/potential_cache = potential_container
|
||||
for(var/element_in_list in potential_cache)
|
||||
#ifndef FIND_REF_NO_CHECK_TICK
|
||||
CHECK_TICK
|
||||
#endif
|
||||
//Check normal entrys
|
||||
if(element_in_list == src)
|
||||
log_gc("Found [type] \ref[src] in list [container_name].")
|
||||
continue
|
||||
|
||||
else if(I && !isnum(I) && normal && X[I] == src)
|
||||
testing("Found [src.type] \ref[src] in list [Xname]\[[I]\]")
|
||||
|
||||
else if(islist(I))
|
||||
DoSearchVar(I, "[Xname] -> list", recursive_limit - 1)
|
||||
var/assoc_val = null
|
||||
if(!isnum(element_in_list) && normal)
|
||||
assoc_val = potential_cache[element_in_list]
|
||||
//Check assoc entrys
|
||||
if(assoc_val == src)
|
||||
log_gc("Found [type] \ref[src] in list [container_name]\[[element_in_list]\]")
|
||||
continue
|
||||
//We need to run both of these checks, since our object could be hiding in either of them
|
||||
//Check normal sublists
|
||||
if(islist(element_in_list))
|
||||
DoSearchVar(element_in_list, "[container_name] -> [element_in_list] (list)", recursive_limit - 1, search_time)
|
||||
//Check assoc sublists
|
||||
if(islist(assoc_val))
|
||||
DoSearchVar(potential_container[element_in_list], "[container_name]\[[element_in_list]\] -> [assoc_val] (list)", recursive_limit - 1, search_time)
|
||||
|
||||
#ifndef FIND_REF_NO_CHECK_TICK
|
||||
CHECK_TICK
|
||||
|
||||
@@ -164,7 +164,7 @@ SUBSYSTEM_DEF(ghost_spawns)
|
||||
if(!player_old_enough_antag(M.client, role))
|
||||
return
|
||||
if(role_text)
|
||||
if(jobban_isbanned(M, role_text) || jobban_isbanned(M, "Syndicate"))
|
||||
if(jobban_isbanned(M, role_text) || jobban_isbanned(M, ROLE_SYNDICATE))
|
||||
return
|
||||
if(GLOB.configuration.jobs.enable_exp_restrictions && min_hours)
|
||||
if(M.client.get_exp_type_num(EXP_TYPE_LIVING) < min_hours * 60)
|
||||
|
||||
@@ -61,6 +61,8 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/end_state = "undefined"
|
||||
/// Time the real reboot kicks in
|
||||
var/real_reboot_time = 0
|
||||
/// Datum used to generate the end of round scoreboard.
|
||||
var/datum/scoreboard/score = null
|
||||
|
||||
/datum/controller/subsystem/ticker/Initialize()
|
||||
login_music = pick(\
|
||||
@@ -138,6 +140,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/setup()
|
||||
cultdat = setupcult()
|
||||
score = new()
|
||||
|
||||
// Create and announce mode
|
||||
if(GLOB.master_mode == "secret")
|
||||
@@ -486,7 +489,8 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(findtext("[handler]","auto_declare_completion_"))
|
||||
call(mode, handler)()
|
||||
|
||||
scoreboard()
|
||||
// Display the scoreboard window
|
||||
score.scoreboard()
|
||||
|
||||
// Declare the completion of the station goals
|
||||
mode.declare_station_goal_completion()
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@
|
||||
return ..()
|
||||
|
||||
/datum/beam/proc/Draw()
|
||||
var/Angle = round(Get_Angle(origin,target))
|
||||
var/Angle = round(get_angle(origin, target))
|
||||
|
||||
var/matrix/rot_matrix = matrix()
|
||||
rot_matrix.Turn(Angle)
|
||||
|
||||
Vendored
+1
@@ -49,6 +49,7 @@ GLOBAL_DATUM_INIT(crew_repository, /datum/repository/crew, new())
|
||||
|
||||
if(C.sensor_mode >= SUIT_SENSOR_VITAL)
|
||||
crewmemberData["stat"] = H.stat
|
||||
crewmemberData["health"] = H.health
|
||||
crewmemberData["oxy"] = round(H.getOxyLoss(), 1)
|
||||
crewmemberData["tox"] = round(H.getToxLoss(), 1)
|
||||
crewmemberData["fire"] = round(H.getFireLoss(), 1)
|
||||
|
||||
@@ -163,7 +163,7 @@ GLOBAL_VAR_INIT(record_id_num, 1001)
|
||||
G.fields["photo"] = get_id_photo(H)
|
||||
G.fields["photo-south"] = "data:image/png;base64,[icon2base64(icon(G.fields["photo"], dir = SOUTH))]"
|
||||
G.fields["photo-west"] = "data:image/png;base64,[icon2base64(icon(G.fields["photo"], dir = WEST))]"
|
||||
if(H.gen_record && !jobban_isbanned(H, "Records"))
|
||||
if(H.gen_record && !jobban_isbanned(H, ROLEBAN_RECORDS))
|
||||
G.fields["notes"] = H.gen_record
|
||||
else
|
||||
G.fields["notes"] = "No notes found."
|
||||
@@ -183,7 +183,7 @@ GLOBAL_VAR_INIT(record_id_num, 1001)
|
||||
M.fields["alg_d"] = "No allergies have been detected in this patient."
|
||||
M.fields["cdi"] = "None"
|
||||
M.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
|
||||
if(H.med_record && !jobban_isbanned(H, "Records"))
|
||||
if(H.med_record && !jobban_isbanned(H, ROLEBAN_RECORDS))
|
||||
M.fields["notes"] = H.med_record
|
||||
else
|
||||
M.fields["notes"] = "No notes found."
|
||||
@@ -199,7 +199,7 @@ GLOBAL_VAR_INIT(record_id_num, 1001)
|
||||
S.fields["ma_crim"] = "None"
|
||||
S.fields["ma_crim_d"] = "No major crime convictions."
|
||||
S.fields["notes"] = "No notes."
|
||||
if(H.sec_record && !jobban_isbanned(H, "Records"))
|
||||
if(H.sec_record && !jobban_isbanned(H, ROLEBAN_RECORDS))
|
||||
S.fields["notes"] = H.sec_record
|
||||
else
|
||||
S.fields["notes"] = "No notes found."
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
var/var_edited = FALSE //Warranty void if seal is broken
|
||||
var/tmp/unique_datum_id = null
|
||||
|
||||
#ifdef TESTING
|
||||
#ifdef REFERENCE_TRACKING
|
||||
var/running_find_references
|
||||
var/last_find_references = 0
|
||||
#endif
|
||||
|
||||
@@ -50,6 +50,10 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
|
||||
var/stage = 1
|
||||
var/max_stages = 0
|
||||
var/stage_prob = 4
|
||||
/// The fraction of stages the virus must at least be at to show up on medical HUDs. Rounded up.
|
||||
var/discovery_threshold = 0.5
|
||||
/// If TRUE, this virus will show up on medical HUDs. Automatically set when it reaches mid-stage.
|
||||
var/discovered = FALSE
|
||||
|
||||
//Other
|
||||
var/list/viable_mobtypes = list() //typepaths of viable mobs
|
||||
@@ -82,6 +86,9 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
|
||||
if(!cure)
|
||||
if(prob(stage_prob))
|
||||
stage = min(stage + 1,max_stages)
|
||||
if(!discovered && stage >= CEILING(max_stages * discovery_threshold, 1)) // Once we reach a late enough stage, medical HUDs can pick us up even if we regress
|
||||
discovered = TRUE
|
||||
affected_mob.med_hud_set_status()
|
||||
else
|
||||
if(prob(cure_chance))
|
||||
stage = max(stage - 1, 1)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
var/list/stage3 = list("You feel utterly plain.")
|
||||
var/list/stage4 = list("You feel white bread.")
|
||||
var/list/stage5 = list("Oh the humanity!")
|
||||
var/transformation_text = null
|
||||
var/new_form = /mob/living/carbon/human
|
||||
|
||||
/datum/disease/transformation/stage_act()
|
||||
@@ -44,6 +45,8 @@
|
||||
return
|
||||
if(affected_mob.notransform)
|
||||
return
|
||||
if(transformation_text)
|
||||
to_chat(affected_mob, transformation_text)
|
||||
affected_mob.notransform = 1
|
||||
affected_mob.canmove = 0
|
||||
affected_mob.icon = null
|
||||
@@ -243,4 +246,5 @@
|
||||
stage3 = list("<span class='danger'>Your appendages are melting away.</span>", "<span class='danger'>Your limbs begin to lose their shape.</span>")
|
||||
stage4 = list("<span class='danger'>You're ravenous.</span>")
|
||||
stage5 = list("<span class='danger'>You have become a morph.</span>")
|
||||
transformation_text = "<span class='userdanger'>This transformation does NOT make you an antagonist if you were not one already. If you were not an antagonist, you should not eat any steal objectives or the contents of the armory.</span>"
|
||||
new_form = /mob/living/simple_animal/hostile/morph
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
. = ..()
|
||||
var/obj/machinery/hologram/holopad/H = origin
|
||||
H.move_hologram(eye_user, loc)
|
||||
ai_detector_visible = FALSE // Holocalls dont trigger the Ai Detector
|
||||
|
||||
//this datum manages it's own references
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
shoes = /obj/item/clothing/shoes/magboots/syndie
|
||||
r_pocket = /obj/item/radio/uplink/nuclear
|
||||
l_pocket = /obj/item/pinpointer/advpinpointer
|
||||
l_hand = /obj/item/tank/jetpack/oxygen/harness
|
||||
l_hand = /obj/item/tank/internals/oxygen/red
|
||||
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/survival_syndi = 1,
|
||||
@@ -836,7 +836,7 @@
|
||||
apply_to_card(I, H, get_all_accesses(), "Space Explorer")
|
||||
|
||||
/datum/outfit/admin/hardsuit
|
||||
name = "Hardsuit Generic"
|
||||
name = "Hardsuit - Generic"
|
||||
back = /obj/item/tank/jetpack/oxygen
|
||||
mask = /obj/item/clothing/mask/breath
|
||||
shoes = /obj/item/clothing/shoes/magboots
|
||||
@@ -857,34 +857,34 @@
|
||||
apply_to_card(I, H, get_all_accesses(), "Hardsuit Tester")
|
||||
|
||||
/datum/outfit/admin/hardsuit/engineer
|
||||
name = "Engineer Hardsuit"
|
||||
name = "Hardsuit - Engineer"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/engine
|
||||
|
||||
/datum/outfit/admin/hardsuit/ce
|
||||
name = "CE Hardsuit"
|
||||
name = "Hardsuit - CE"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/engine/elite
|
||||
shoes = /obj/item/clothing/shoes/magboots/advance
|
||||
|
||||
/datum/outfit/admin/hardsuit/mining
|
||||
name = "Mining Hardsuit"
|
||||
name = "Hardsuit - Mining"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/mining
|
||||
|
||||
/datum/outfit/admin/hardsuit/syndi
|
||||
name = "Syndi Hardsuit"
|
||||
name = "Hardsuit - Syndi"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
shoes = /obj/item/clothing/shoes/magboots/syndie
|
||||
|
||||
/datum/outfit/admin/hardsuit/wizard
|
||||
name = "Wizard Hardsuit"
|
||||
name = "Hardsuit - Wizard"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/shielded/wizard
|
||||
shoes = /obj/item/clothing/shoes/magboots
|
||||
|
||||
/datum/outfit/admin/hardsuit/medical
|
||||
name = "Medical Hardsuit"
|
||||
name = "Hardsuit - Medical"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/medical
|
||||
|
||||
/datum/outfit/admin/hardsuit/atmos
|
||||
name = "Atmos Hardsuit"
|
||||
name = "Hardsuit - Atmos"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/engine/atmos
|
||||
|
||||
|
||||
@@ -1146,20 +1146,20 @@
|
||||
apply_to_card(I, H, get_all_accesses(), "Wizard")
|
||||
|
||||
/datum/outfit/admin/wizard/red
|
||||
name = "Red Wizard"
|
||||
name = "Wizard - Red Wizard"
|
||||
|
||||
suit = /obj/item/clothing/suit/wizrobe/red
|
||||
head = /obj/item/clothing/head/wizard/red
|
||||
|
||||
/datum/outfit/admin/wizard/marisa
|
||||
name = "Marisa Wizard"
|
||||
name = "Wizard - Marisa Wizard"
|
||||
|
||||
suit = /obj/item/clothing/suit/wizrobe/marisa
|
||||
shoes = /obj/item/clothing/shoes/sandal/marisa
|
||||
head = /obj/item/clothing/head/wizard/marisa
|
||||
|
||||
/datum/outfit/admin/wizard/arch
|
||||
name = "Arch Wizard"
|
||||
name = "Wizard - Arch Wizard"
|
||||
|
||||
suit = /obj/item/clothing/suit/wizrobe/magusred
|
||||
head = /obj/item/clothing/head/wizard/magus
|
||||
@@ -1223,3 +1223,68 @@
|
||||
var/obj/item/radio/headset/R = H.l_ear
|
||||
if(istype(R))
|
||||
R.flags |= NODROP
|
||||
|
||||
/datum/outfit/admin/honksquad
|
||||
name = "Honksquad"
|
||||
|
||||
uniform = /obj/item/clothing/under/rank/clown
|
||||
mask = /obj/item/clothing/mask/gas/clown_hat
|
||||
back = /obj/item/storage/backpack/clown
|
||||
id = /obj/item/card/id/clown
|
||||
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/survival = 1,
|
||||
/obj/item/bikehorn = 1,
|
||||
/obj/item/stamp/clown = 1,
|
||||
/obj/item/toy/crayon/rainbow = 1,
|
||||
/obj/item/reagent_containers/spray/waterflower = 1,
|
||||
/obj/item/reagent_containers/food/snacks/grown/banana = 1,
|
||||
)
|
||||
|
||||
shoes = /obj/item/clothing/shoes/clown_shoes
|
||||
suit = /obj/item/clothing/suit/storage/det_suit
|
||||
pda = /obj/item/pda/clown
|
||||
l_ear = /obj/item/radio/headset
|
||||
r_pocket = /obj/item/reagent_containers/food/pill/patch/jestosterone
|
||||
|
||||
/datum/outfit/admin/honksquad/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
. = ..()
|
||||
if(H.gender == FEMALE)
|
||||
uniform = /obj/item/clothing/under/rank/clown/sexy
|
||||
mask = /obj/item/clothing/mask/gas/clown_hat/sexy
|
||||
|
||||
if(prob(50))
|
||||
// You have to do it like this to make it work with assoc lists without a runtime.
|
||||
// Trust me.
|
||||
backpack_contents.Add(/obj/item/gun/energy/clown)
|
||||
backpack_contents[/obj/item/gun/energy/clown] = 1 // Amount. Not boolean. Do not TRUE this. You turkey.
|
||||
else
|
||||
backpack_contents.Add(/obj/item/gun/throw/piecannon)
|
||||
backpack_contents[/obj/item/gun/throw/piecannon] = 1
|
||||
|
||||
/datum/outfit/admin/honksquad/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
. = ..()
|
||||
if(visualsOnly)
|
||||
return
|
||||
|
||||
// Setup their clumsy gene
|
||||
H.dna.SetSEState(GLOB.clumsyblock, TRUE)
|
||||
H.check_mutations = TRUE
|
||||
|
||||
// Setup their headset
|
||||
var/obj/item/radio/R = H.l_ear
|
||||
if(istype(R))
|
||||
R.set_frequency(DTH_FREQ) // Clowns can be part of "special operations"
|
||||
|
||||
// And their PDA
|
||||
var/obj/item/pda/P = H.wear_pda
|
||||
if(istype(P))
|
||||
P.owner = H.real_name
|
||||
P.ownjob = "Clown"
|
||||
P.name = "PDA-[H.real_name] ([P.ownjob])"
|
||||
|
||||
// And their ID
|
||||
var/obj/item/card/id/I = H.wear_id
|
||||
if(istype(I))
|
||||
apply_to_card(I, H, list(ACCESS_CLOWN), "Clown")
|
||||
H.sec_hud_set_ID()
|
||||
|
||||
@@ -7,140 +7,140 @@
|
||||
mask = /obj/item/clothing/mask/breath
|
||||
|
||||
/datum/outfit/plasmaman/bar
|
||||
name = "Bartender Plasmaman"
|
||||
name = "Plasmaman Bartender"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/white
|
||||
uniform = /obj/item/clothing/under/plasmaman/enviroslacks
|
||||
|
||||
/datum/outfit/plasmaman/chef
|
||||
name = "Chef Plasmaman"
|
||||
name = "Plasmaman Chef"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/chef
|
||||
uniform = /obj/item/clothing/under/plasmaman/chef
|
||||
|
||||
/datum/outfit/plasmaman/botany
|
||||
name = "Botany Plasmaman"
|
||||
name = "Plasmaman Botany"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/botany
|
||||
uniform = /obj/item/clothing/under/plasmaman/botany
|
||||
|
||||
/datum/outfit/plasmaman/librarian
|
||||
name = "Librarian Plasmaman"
|
||||
name = "Plasmaman Librarian"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/librarian
|
||||
uniform = /obj/item/clothing/under/plasmaman/librarian
|
||||
|
||||
/datum/outfit/plasmaman/chaplain
|
||||
name = "Chaplain Plasmaman"
|
||||
name = "Plasmaman Chaplain"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/chaplain
|
||||
uniform = /obj/item/clothing/under/plasmaman/chaplain
|
||||
|
||||
/datum/outfit/plasmaman/janitor
|
||||
name = "Janitor Plasmaman"
|
||||
name = "Plasmaman Janitor"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/janitor
|
||||
uniform = /obj/item/clothing/under/plasmaman/janitor
|
||||
|
||||
/datum/outfit/plasmaman/security
|
||||
name = "Security Plasmaman"
|
||||
name = "Plasmaman Security"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/security
|
||||
uniform = /obj/item/clothing/under/plasmaman/security
|
||||
|
||||
/datum/outfit/plasmaman/detective
|
||||
name = "Detective Plasmaman"
|
||||
name = "Plasmaman Detective"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/white
|
||||
uniform = /obj/item/clothing/under/plasmaman/enviroslacks
|
||||
l_ear = /obj/item/radio/headset/headset_sec
|
||||
|
||||
/datum/outfit/plasmaman/warden
|
||||
name = "Warden Plasmaman"
|
||||
name = "Plasmaman Warden"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/security/warden
|
||||
uniform = /obj/item/clothing/under/plasmaman/security/warden
|
||||
|
||||
/datum/outfit/plasmaman/hos
|
||||
name = "Head of Security Plasmaman"
|
||||
name = "Plasmaman Head of Security"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/security/hos
|
||||
uniform = /obj/item/clothing/under/plasmaman/security/hos
|
||||
|
||||
/datum/outfit/plasmaman/cargo
|
||||
name = "Cargo Plasmaman"
|
||||
name = "Plasmaman Cargo"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/cargo
|
||||
uniform = /obj/item/clothing/under/plasmaman/cargo
|
||||
|
||||
/datum/outfit/plasmaman/mining
|
||||
name = "Mining Plasmaman"
|
||||
name = "Plasmaman Mining"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/mining
|
||||
uniform = /obj/item/clothing/under/plasmaman/mining
|
||||
|
||||
/datum/outfit/plasmaman/medical
|
||||
name = "Medical Plasmaman"
|
||||
name = "Plasmaman Medical"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/medical
|
||||
uniform = /obj/item/clothing/under/plasmaman/medical
|
||||
|
||||
/datum/outfit/plasmaman/cmo
|
||||
name = "Chief Medical Officer Plasmaman"
|
||||
name = "Plasmaman Chief Medical Officer"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/cmo
|
||||
uniform = /obj/item/clothing/under/plasmaman/cmo
|
||||
|
||||
/datum/outfit/plasmaman/viro
|
||||
name = "Virology Plasmaman"
|
||||
name = "Plasmaman Virology"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/viro
|
||||
uniform = /obj/item/clothing/under/plasmaman/viro
|
||||
|
||||
/datum/outfit/plasmaman/chemist
|
||||
name = "Chemist Plasmaman"
|
||||
name = "Plasmaman Chemist"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/chemist
|
||||
uniform = /obj/item/clothing/under/plasmaman/chemist
|
||||
|
||||
/datum/outfit/plasmaman/genetics
|
||||
name = "Genetics Plasmaman"
|
||||
name = "Plasmaman Genetics"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/genetics
|
||||
uniform = /obj/item/clothing/under/plasmaman/genetics
|
||||
|
||||
/datum/outfit/plasmaman/science
|
||||
name = "Science Plasmaman"
|
||||
name = "Plasmaman Science"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/science
|
||||
uniform = /obj/item/clothing/under/plasmaman/science
|
||||
|
||||
/datum/outfit/plasmaman/rd
|
||||
name = "Research Director Plasmaman"
|
||||
name = "Plasmaman Research Director"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/rd
|
||||
uniform = /obj/item/clothing/under/plasmaman/rd
|
||||
|
||||
/datum/outfit/plasmaman/robotics
|
||||
name = "Robotics Plasmaman"
|
||||
name = "Plasmaman Robotics"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/robotics
|
||||
uniform = /obj/item/clothing/under/plasmaman/robotics
|
||||
|
||||
/datum/outfit/plasmaman/engineering
|
||||
name = "Engineering Plasmaman"
|
||||
name = "Plasmaman Engineering"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/engineering
|
||||
uniform = /obj/item/clothing/under/plasmaman/engineering
|
||||
|
||||
/datum/outfit/plasmaman/ce
|
||||
name = "Chief Engineer Plasmaman"
|
||||
name = "Plasmaman Chief Engineer"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/engineering/ce
|
||||
uniform = /obj/item/clothing/under/plasmaman/engineering/ce
|
||||
|
||||
/datum/outfit/plasmaman/atmospherics
|
||||
name = "Atmospherics Plasmaman"
|
||||
name = "Plasmaman Atmospherics"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/atmospherics
|
||||
uniform = /obj/item/clothing/under/plasmaman/atmospherics
|
||||
@@ -160,25 +160,25 @@
|
||||
mask = /obj/item/clothing/mask/gas/clown_hat
|
||||
|
||||
/datum/outfit/plasmaman/hop
|
||||
name = "Head of Personnel Plasmaman"
|
||||
name = "Plasmaman Head of Personnel"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/hop
|
||||
uniform = /obj/item/clothing/under/plasmaman/hop
|
||||
|
||||
/datum/outfit/plasmaman/captain
|
||||
name = "Captain Plasmaman"
|
||||
name = "Plasmaman Captain"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/captain
|
||||
uniform = /obj/item/clothing/under/plasmaman/captain
|
||||
|
||||
/datum/outfit/plasmaman/blueshield
|
||||
name = "Blueshield Plasmaman"
|
||||
name = "Plasmaman Blueshield"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/blueshield
|
||||
uniform = /obj/item/clothing/under/plasmaman/blueshield
|
||||
|
||||
/datum/outfit/plasmaman/wizard
|
||||
name = "Wizard Plasmaman"
|
||||
name = "Plasmaman Wizard"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/wizard
|
||||
uniform = /obj/item/clothing/under/plasmaman/wizard
|
||||
|
||||
@@ -1017,6 +1017,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
cost = 11
|
||||
surplus = 0
|
||||
cant_discount = TRUE
|
||||
hijack_only = TRUE
|
||||
|
||||
/datum/uplink_item/explosives/emp_bomb
|
||||
name = "EMP bomb"
|
||||
@@ -1426,7 +1427,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
name = "Power Sink"
|
||||
desc = "When screwed to wiring attached to an electric grid, then activated, this large device places excessive load on the grid, causing a stationwide blackout. The sink cannot be carried because of its excessive size. Ordering this sends you a small beacon that will teleport the power sink to your location on activation."
|
||||
reference = "PS"
|
||||
item = /obj/item/powersink
|
||||
item = /obj/item/radio/beacon/syndicate/power_sink
|
||||
cost = 10
|
||||
|
||||
/datum/uplink_item/device_tools/singularity_beacon
|
||||
|
||||
+9
-1
@@ -1072,7 +1072,7 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
Returning TRUE here will override the above proc's result.
|
||||
*/
|
||||
/atom/proc/CanAStarPassTo(ID, dir, obj/destination)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/** Call this when you want to present a renaming prompt to the user.
|
||||
|
||||
@@ -1139,3 +1139,11 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
else
|
||||
name = "[prefix][t]"
|
||||
return t
|
||||
|
||||
/atom/proc/set_angle(degrees)
|
||||
var/matrix/M = matrix()
|
||||
M.Turn(degrees)
|
||||
// If we aint 0, make it NN transform
|
||||
if(degrees)
|
||||
appearance_flags |= PIXEL_SCALE
|
||||
transform = M
|
||||
|
||||
@@ -90,6 +90,8 @@
|
||||
/mob/living/carbon/proc/has_virus()
|
||||
for(var/thing in viruses)
|
||||
var/datum/disease/D = thing
|
||||
if(!D.discovered) // Early-stage viruses should not show up on med HUD (though health analywers can still pick them up)
|
||||
continue
|
||||
if((!(D.visibility_flags & HIDDEN_SCANNER)) && (D.severity != NONTHREAT))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
activation_messages = list("You feel smarter.")
|
||||
deactivation_messages = list("You feel dumber.")
|
||||
instability = GENE_INSTABILITY_MAJOR
|
||||
traits_to_add = list(TRAIT_TELEKINESIS)
|
||||
activation_prob = 15
|
||||
|
||||
/datum/mutation/tk/New()
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
traitorcount += 1
|
||||
continue
|
||||
if(ishuman(player) || isAI(player))
|
||||
if((ROLE_TRAITOR in player.client.prefs.be_special) && !player.client.skip_antag && !jobban_isbanned(player, ROLE_TRAITOR) && !jobban_isbanned(player, "Syndicate"))
|
||||
if((ROLE_TRAITOR in player.client.prefs.be_special) && !player.client.skip_antag && !jobban_isbanned(player, ROLE_TRAITOR) && !jobban_isbanned(player, ROLE_SYNDICATE))
|
||||
possible_traitors += player.mind
|
||||
for(var/datum/mind/player in possible_traitors)
|
||||
for(var/job in restricted_jobs)
|
||||
@@ -144,7 +144,7 @@
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_ESCAPE)
|
||||
return
|
||||
//message_admins("Late Join Check")
|
||||
if(character.client && (ROLE_TRAITOR in character.client.prefs.be_special) && !character.client.skip_antag && !jobban_isbanned(character, ROLE_TRAITOR) && !jobban_isbanned(character, "Syndicate"))
|
||||
if(character.client && (ROLE_TRAITOR in character.client.prefs.be_special) && !character.client.skip_antag && !jobban_isbanned(character, ROLE_TRAITOR) && !jobban_isbanned(character, ROLE_SYNDICATE))
|
||||
//message_admins("Late Joiner has Be Syndicate")
|
||||
//message_admins("Checking number of players")
|
||||
var/playercount = 0
|
||||
|
||||
@@ -57,7 +57,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
/datum/game_mode/blob/proc/get_blob_candidates()
|
||||
var/list/candidates = list()
|
||||
for(var/mob/living/carbon/human/player in GLOB.player_list)
|
||||
if(!player.stat && player.mind && !player.client.skip_antag && !player.mind.special_role && !jobban_isbanned(player, "Syndicate") && (ROLE_BLOB in player.client.prefs.be_special))
|
||||
if(!player.stat && player.mind && !player.client.skip_antag && !player.mind.special_role && !jobban_isbanned(player, ROLE_SYNDICATE) && (ROLE_BLOB in player.client.prefs.be_special))
|
||||
candidates += player
|
||||
return candidates
|
||||
|
||||
|
||||
@@ -93,5 +93,7 @@ the same goes for Remove(). if you override Remove(), call parent or else your p
|
||||
/datum/action/changeling/proc/transform_dna(mob/living/carbon/human/H, datum/dna/D)
|
||||
if(!D)
|
||||
return
|
||||
|
||||
H.change_dna(D, TRUE)
|
||||
var/changesSpecies = TRUE
|
||||
if (H.dna.species.name == D.species.name)
|
||||
changesSpecies = FALSE
|
||||
H.change_dna(D, changesSpecies)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/datum/action/changeling/digitalcamo
|
||||
name = "Digital Camouflage"
|
||||
desc = "By evolving the ability to distort our form and proprotions, we defeat common altgorithms used to detect lifeforms on cameras."
|
||||
helptext = "We cannot be tracked by camera while using this skill. However, humans looking at us will find us... uncanny."
|
||||
helptext = "We cannot be tracked by camera while using this skill."
|
||||
button_icon_state = "digital_camo"
|
||||
dna_cost = 1
|
||||
|
||||
//Prevents AIs tracking you but makes you easily detectable to the human-eye.
|
||||
//Prevents AIs tracking you.
|
||||
/datum/action/changeling/digitalcamo/sting_action(mob/user)
|
||||
|
||||
if(user.digitalcamo)
|
||||
|
||||
@@ -243,7 +243,6 @@
|
||||
damage_type = BRUTE
|
||||
range = 8
|
||||
hitsound = 'sound/weapons/thudswoosh.ogg'
|
||||
var/chain
|
||||
var/obj/item/ammo_casing/magic/tentacle/source //the item that shot it
|
||||
|
||||
/obj/item/projectile/tentacle/New(obj/item/ammo_casing/magic/tentacle/tentacle_casing)
|
||||
|
||||
@@ -7,51 +7,7 @@
|
||||
|
||||
//Revive from regenerative stasis
|
||||
/datum/action/changeling/revive/sting_action(mob/living/carbon/user)
|
||||
user.setToxLoss(0, FALSE)
|
||||
user.setOxyLoss(0, FALSE)
|
||||
user.setCloneLoss(0, FALSE)
|
||||
user.setBrainLoss(0, FALSE)
|
||||
user.SetParalysis(0, FALSE)
|
||||
user.SetStunned(0, FALSE)
|
||||
user.SetWeakened(0, FALSE)
|
||||
user.radiation = 0
|
||||
user.SetEyeBlind(0, FALSE)
|
||||
user.SetEyeBlurry(0, FALSE)
|
||||
user.RestoreEars()
|
||||
user.heal_overall_damage(user.getBruteLoss(), user.getFireLoss(), updating_health = FALSE)
|
||||
user.cure_blind(null, FALSE)
|
||||
user.CureDeaf()
|
||||
user.cure_nearsighted(null, FALSE)
|
||||
user.reagents.clear_reagents()
|
||||
user.germ_level = 0
|
||||
user.timeofdeath = 0
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.restore_blood()
|
||||
H.next_pain_time = 0
|
||||
H.dna.species.create_organs(H)
|
||||
// Now that recreating all organs is necessary, the rest of this organ stuff probably
|
||||
// isn't, but I don't want to remove it, just in case.
|
||||
for(var/organ_name in H.bodyparts_by_name)
|
||||
var/obj/item/organ/external/O = H.bodyparts_by_name[organ_name]
|
||||
if(!O)
|
||||
continue
|
||||
O.brute_dam = 0
|
||||
O.burn_dam = 0
|
||||
O.damage_state = "00"
|
||||
O.germ_level = 0
|
||||
QDEL_NULL(O.hidden)
|
||||
O.open = 0
|
||||
O.internal_bleeding = FALSE
|
||||
O.perma_injury = 0
|
||||
O.status = 0
|
||||
O.trace_chemicals.Cut()
|
||||
for(var/obj/item/organ/internal/IO in H.internal_organs)
|
||||
IO.rejuvenate()
|
||||
IO.trace_chemicals.Cut()
|
||||
H.remove_all_embedded_objects()
|
||||
for(var/datum/disease/critical/C in user.viruses)
|
||||
C.cure()
|
||||
user.revive()
|
||||
REMOVE_TRAIT(user, TRAIT_FAKEDEATH, "changeling")
|
||||
user.updatehealth("revive sting")
|
||||
user.update_blind_effects()
|
||||
|
||||
@@ -848,8 +848,12 @@
|
||||
uses += max(1, temp)
|
||||
|
||||
/obj/item/melee/blood_magic/manipulator/attack_self(mob/living/user)
|
||||
var/list/options = list("Blood Orb (50)", "Blood Recharge (75)", "Blood Spear (150)", "Blood Bolt Barrage (300)")
|
||||
var/choice = input(user, "Choose a greater blood rite...", "Greater Blood Rites") as null|anything in options
|
||||
var/list/options = list("Blood Orb (50)" = image(icon = 'icons/obj/cult.dmi', icon_state = "summoning_orb"),
|
||||
"Blood Recharge (75)" = image(icon = 'icons/mob/actions/actions_cult.dmi', icon_state = "blood_charge"),
|
||||
"Blood Spear (150)" = image(icon = 'icons/mob/actions/actions_cult.dmi', icon_state = "bloodspear"),
|
||||
"Blood Bolt Barrage (300)" = image(icon = 'icons/mob/actions/actions_cult.dmi', icon_state = "blood_barrage"))
|
||||
var/choice = show_radial_menu(user, src, options)
|
||||
|
||||
switch(choice)
|
||||
if("Blood Orb (50)")
|
||||
if(uses < BLOOD_ORB_COST)
|
||||
|
||||
@@ -195,6 +195,7 @@
|
||||
GLOBAL_LIST_INIT(blacklisted_pylon_turfs, typecacheof(list(
|
||||
/turf/simulated/floor/engine/cult,
|
||||
/turf/space,
|
||||
/turf/simulated/wall/indestructible,
|
||||
/turf/simulated/floor/plating/lava,
|
||||
/turf/simulated/floor/chasm,
|
||||
/turf/simulated/wall/cult,
|
||||
|
||||
@@ -130,6 +130,9 @@ To draw a rune, use a ritual dagger.
|
||||
visible_message("<span class='danger'>[src] suddenly appears!</span>")
|
||||
alpha = initial(alpha)
|
||||
|
||||
/obj/effect/rune/is_cleanable()
|
||||
return TRUE
|
||||
|
||||
|
||||
/*
|
||||
There are a few different procs each rune runs through when a cultist activates it.
|
||||
@@ -991,6 +994,9 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
/obj/effect/rune/narsie/cult_conceal() //can't hide this, and you wouldn't want to
|
||||
return
|
||||
|
||||
/obj/effect/rune/narsie/is_cleanable() //No, you can't just yeet a cleaning grenade to remove it.
|
||||
return FALSE
|
||||
|
||||
/obj/effect/rune/narsie/invoke(list/invokers)
|
||||
if(used)
|
||||
return
|
||||
|
||||
@@ -238,7 +238,7 @@
|
||||
// Assemble a list of active players without jobbans.
|
||||
for(var/mob/new_player/player in GLOB.player_list)
|
||||
if(player.client && player.ready && player.has_valid_preferences())
|
||||
if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, roletext))
|
||||
if(!jobban_isbanned(player, ROLE_SYNDICATE) && !jobban_isbanned(player, roletext))
|
||||
if(player_old_enough_antag(player.client,role))
|
||||
players += player
|
||||
|
||||
|
||||
@@ -128,8 +128,8 @@
|
||||
if(cannotPossess(user))
|
||||
to_chat(user, "<span class='boldnotice'>Upon using the antagHUD you forfeited the ability to join the round.</span>")
|
||||
return
|
||||
if(jobban_isbanned(user, "Syndicate"))
|
||||
to_chat(user, "<span class='warning'>You are banned from antagonists!</span>")
|
||||
if(jobban_isbanned(user, ROLE_SYNDICATE) || jobban_isbanned(user, ROLE_BORER))
|
||||
to_chat(user, "<span class='warning'>You are banned from playing this antagonist!</span>")
|
||||
return
|
||||
if(key)
|
||||
return
|
||||
|
||||
@@ -332,6 +332,14 @@
|
||||
to_chat(S, "<span class='warning'>An inhospitable area may be created as a result of destroying this object. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/structure/fans/tiny/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>An inhospitable area may be created as a result of destroying this object. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/structure/holosign/barrier/atmos/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>An inhospitable area may be created as a result of destroying this object. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/tcomms/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>This communications relay should be preserved, it will be a useful resource to our masters in the future. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 10
|
||||
damage_transfer = 0.9
|
||||
can_strip = TRUE
|
||||
projectiletype = /obj/item/projectile/guardian
|
||||
ranged_cooldown_time = 5 //fast!
|
||||
projectilesound = 'sound/effects/hit_on_shattered_glass.ogg'
|
||||
@@ -35,6 +36,7 @@
|
||||
alpha = 255
|
||||
range = 13
|
||||
incorporeal_move = 0
|
||||
can_strip = TRUE
|
||||
to_chat(src, "<span class='danger'>You switch to combat mode.</span>")
|
||||
toggle = FALSE
|
||||
else
|
||||
@@ -46,6 +48,7 @@
|
||||
alpha = 60
|
||||
range = 255
|
||||
incorporeal_move = 1
|
||||
can_strip = FALSE //spiritual pickpocketting is forbidden
|
||||
to_chat(src, "<span class='danger'>You switch to scout mode.</span>")
|
||||
toggle = TRUE
|
||||
else
|
||||
|
||||
@@ -188,6 +188,9 @@
|
||||
M.regenerate_icons()
|
||||
M.update_body()
|
||||
|
||||
if(!the_bomb)
|
||||
the_bomb = locate(/obj/machinery/nuclearbomb/syndicate) in GLOB.poi_list
|
||||
|
||||
if(the_bomb)
|
||||
synd_mind.store_memory("<B>Syndicate [the_bomb.name] Code</B>: [the_bomb.r_code]")
|
||||
to_chat(synd_mind.current, "The code for \the [the_bomb.name] is: <B>[the_bomb.r_code]</B>")
|
||||
@@ -436,54 +439,55 @@
|
||||
return newname
|
||||
|
||||
|
||||
/datum/game_mode/nuclear/set_scoreboard_gvars()
|
||||
/datum/game_mode/nuclear/set_scoreboard_vars()
|
||||
var/datum/scoreboard/scoreboard = SSticker.score
|
||||
var/foecount = 0
|
||||
|
||||
for(var/datum/mind/M in SSticker.mode.syndicates)
|
||||
foecount++
|
||||
if(!M || !M.current)
|
||||
GLOB.score_opkilled++
|
||||
scoreboard.score_ops_killed++
|
||||
continue
|
||||
|
||||
if(M.current.stat == DEAD)
|
||||
GLOB.score_opkilled++
|
||||
scoreboard.score_ops_killed++
|
||||
|
||||
else if(M.current.restrained())
|
||||
GLOB.score_arrested++
|
||||
scoreboard.score_arrested++
|
||||
|
||||
if(foecount == GLOB.score_arrested)
|
||||
GLOB.score_allarrested = 1
|
||||
if(foecount == scoreboard.score_arrested)
|
||||
scoreboard.all_arrested = TRUE // how the hell did they manage that
|
||||
|
||||
for(var/obj/machinery/nuclearbomb/nuke in GLOB.machines)
|
||||
if(nuke.r_code == "Nope") continue
|
||||
var/obj/machinery/nuclearbomb/syndicate/nuke = locate() in GLOB.poi_list
|
||||
if(nuke?.r_code != "Nope")
|
||||
var/area/A = get_area(nuke)
|
||||
|
||||
var/list/thousand_penalty = list(/area/solar)
|
||||
var/list/fiftythousand_penalty = list(/area/security/main, /area/security/brig, /area/security/armoury, /area/security/checkpoint2)
|
||||
|
||||
if(is_type_in_list(A, thousand_penalty))
|
||||
GLOB.score_nuked_penalty = 1000
|
||||
scoreboard.nuked_penalty = 1000
|
||||
|
||||
else if(is_type_in_list(A, fiftythousand_penalty))
|
||||
GLOB.score_nuked_penalty = 50000
|
||||
scoreboard.nuked_penalty = 50000
|
||||
|
||||
else if(istype(A, /area/engine))
|
||||
GLOB.score_nuked_penalty = 100000
|
||||
scoreboard.nuked_penalty = 100000
|
||||
|
||||
else
|
||||
GLOB.score_nuked_penalty = 10000
|
||||
scoreboard.nuked_penalty = 10000
|
||||
|
||||
break
|
||||
|
||||
var/killpoints = GLOB.score_opkilled * 250
|
||||
var/arrestpoints = GLOB.score_arrested * 1000
|
||||
GLOB.score_crewscore += killpoints
|
||||
GLOB.score_crewscore += arrestpoints
|
||||
if(GLOB.score_nuked)
|
||||
GLOB.score_crewscore -= GLOB.score_nuked_penalty
|
||||
var/killpoints = scoreboard.score_ops_killed * 250
|
||||
var/arrestpoints = scoreboard.score_arrested * 1000
|
||||
scoreboard.crewscore += killpoints
|
||||
scoreboard.crewscore += arrestpoints
|
||||
if(scoreboard.nuked)
|
||||
scoreboard.crewscore -= scoreboard.nuked_penalty
|
||||
|
||||
|
||||
|
||||
/datum/game_mode/nuclear/get_scoreboard_stats()
|
||||
var/datum/scoreboard/scoreboard = SSticker.score
|
||||
var/foecount = 0
|
||||
var/crewcount = 0
|
||||
|
||||
@@ -530,11 +534,11 @@
|
||||
|
||||
dat += "<br>"
|
||||
|
||||
dat += "<b>Operatives Arrested:</b> [GLOB.score_arrested] ([GLOB.score_arrested * 1000] Points)<br>"
|
||||
dat += "<b>All Operatives Arrested:</b> [GLOB.score_allarrested ? "Yes" : "No"] (Score tripled)<br>"
|
||||
dat += "<b>Operatives Arrested:</b> [scoreboard.score_arrested] ([scoreboard.score_arrested * 1000] Points)<br>"
|
||||
dat += "<b>All Operatives Arrested:</b> [scoreboard.all_arrested ? "Yes" : "No"] (Score tripled)<br>"
|
||||
|
||||
dat += "<b>Operatives Killed:</b> [GLOB.score_opkilled] ([GLOB.score_opkilled * 1000] Points)<br>"
|
||||
dat += "<b>Station Destroyed:</b> [GLOB.score_nuked ? "Yes" : "No"] (-[GLOB.score_nuked_penalty] Points)<br>"
|
||||
dat += "<b>Operatives Killed:</b> [scoreboard.score_ops_killed] ([scoreboard.score_ops_killed * 1000] Points)<br>"
|
||||
dat += "<b>Station Destroyed:</b> [scoreboard.nuked ? "Yes" : "No"] (-[scoreboard.nuked_penalty] Points)<br>"
|
||||
dat += "<hr>"
|
||||
|
||||
return dat
|
||||
|
||||
@@ -370,44 +370,45 @@
|
||||
text += "<br>"
|
||||
to_chat(world, text)
|
||||
|
||||
/datum/game_mode/revolution/set_scoreboard_gvars()
|
||||
/datum/game_mode/revolution/set_scoreboard_vars()
|
||||
var/datum/scoreboard/scoreboard = SSticker.score
|
||||
var/foecount = 0
|
||||
|
||||
for(var/datum/mind/M in SSticker.mode.head_revolutionaries)
|
||||
foecount++
|
||||
if(!M || !M.current)
|
||||
GLOB.score_opkilled++
|
||||
scoreboard.score_ops_killed++
|
||||
continue
|
||||
|
||||
if(M.current.stat == DEAD)
|
||||
GLOB.score_opkilled++
|
||||
scoreboard.score_ops_killed++
|
||||
|
||||
else if(M.current.restrained())
|
||||
GLOB.score_arrested++
|
||||
scoreboard.score_arrested++
|
||||
|
||||
if(foecount == GLOB.score_arrested)
|
||||
GLOB.score_allarrested = 1
|
||||
if(foecount == scoreboard.score_arrested)
|
||||
scoreboard.all_arrested = TRUE
|
||||
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/player = thing
|
||||
if(player.mind)
|
||||
var/role = player.mind.assigned_role
|
||||
if(role in list("Captain", "Head of Security", "Head of Personnel", "Chief Engineer", "Research Director"))
|
||||
if(player.stat == DEAD)
|
||||
GLOB.score_deadcommand++
|
||||
for(var/I in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = I
|
||||
if(H.stat == DEAD && H.mind?.assigned_role)
|
||||
if(H.mind.assigned_role in list("Captain", "Head of Security", "Head of Personnel", "Chief Engineer", "Research Director"))
|
||||
scoreboard.score_dead_command++
|
||||
|
||||
|
||||
var/arrestpoints = GLOB.score_arrested * 1000
|
||||
var/killpoints = GLOB.score_opkilled * 500
|
||||
var/comdeadpts = GLOB.score_deadcommand * 500
|
||||
if(GLOB.score_traitorswon)
|
||||
GLOB.score_crewscore -= 10000
|
||||
var/arrestpoints = scoreboard.score_arrested * 1000
|
||||
var/killpoints = scoreboard.score_ops_killed * 500
|
||||
var/comdeadpts = scoreboard.score_dead_command * 500
|
||||
if(scoreboard.score_greentext)
|
||||
scoreboard.crewscore -= 10000
|
||||
|
||||
GLOB.score_crewscore += arrestpoints
|
||||
GLOB.score_crewscore += killpoints
|
||||
GLOB.score_crewscore -= comdeadpts
|
||||
scoreboard.crewscore += arrestpoints
|
||||
scoreboard.crewscore += killpoints
|
||||
scoreboard.crewscore -= comdeadpts
|
||||
|
||||
|
||||
/datum/game_mode/revolution/get_scoreboard_stats()
|
||||
var/datum/scoreboard/scoreboard = SSticker.score
|
||||
var/foecount = 0
|
||||
var/comcount = 0
|
||||
var/revcount = 0
|
||||
@@ -444,12 +445,12 @@
|
||||
dat += "<b>Number of Surviving Loyal Crew:</b> [loycount]<br>"
|
||||
|
||||
dat += "<br>"
|
||||
dat += "<b>Revolution Heads Arrested:</b> [GLOB.score_arrested] ([GLOB.score_arrested * 1000] Points)<br>"
|
||||
dat += "<b>All Revolution Heads Arrested:</b> [GLOB.score_allarrested ? "Yes" : "No"] (Score tripled)<br>"
|
||||
dat += "<b>Revolution Heads Arrested:</b> [scoreboard.score_arrested] ([scoreboard.score_arrested * 1000] Points)<br>"
|
||||
dat += "<b>All Revolution Heads Arrested:</b> [scoreboard.all_arrested ? "Yes" : "No"] (Score tripled)<br>"
|
||||
|
||||
dat += "<b>Revolution Heads Slain:</b> [GLOB.score_opkilled] ([GLOB.score_opkilled * 500] Points)<br>"
|
||||
dat += "<b>Command Staff Slain:</b> [GLOB.score_deadcommand] (-[GLOB.score_deadcommand * 500] Points)<br>"
|
||||
dat += "<b>Revolution Successful:</b> [GLOB.score_traitorswon ? "Yes" : "No"] (-[GLOB.score_traitorswon * 10000] Points)<br>"
|
||||
dat += "<b>Revolution Heads Slain:</b> [scoreboard.score_ops_killed] ([scoreboard.score_ops_killed * 500] Points)<br>"
|
||||
dat += "<b>Command Staff Slain:</b> [scoreboard.score_dead_command] (-[scoreboard.score_dead_command * 500] Points)<br>"
|
||||
dat += "<b>Revolution Successful:</b> [scoreboard.score_greentext ? "Yes" : "No"] (-[scoreboard.score_greentext * 10000] Points)<br>"
|
||||
dat += "<HR>"
|
||||
|
||||
return dat
|
||||
|
||||
+237
-163
@@ -1,3 +1,5 @@
|
||||
GLOBAL_VAR(scoreboard) // Variable to save the scoreboard string once it's been generated
|
||||
|
||||
//Thresholds for Score Ratings
|
||||
#define SINGULARITY_DESERVES_BETTER -3500
|
||||
#define SINGULARITY_FODDER -3000
|
||||
@@ -14,190 +16,275 @@
|
||||
#define PRIDE_OF_SCIENCE 4000
|
||||
#define NANOTRANSEN_FINEST 5000
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/scoreboard()
|
||||
//Print a list of antagonists to the server log
|
||||
/datum/scoreboard
|
||||
/// Overall combined score for the whole round.
|
||||
var/crewscore = 0
|
||||
/// How many useful items have cargo shipped out?
|
||||
var/score_things_shipped = 0
|
||||
/// How many harvests have hydroponics done?
|
||||
var/score_things_harvested = 0
|
||||
/// How much ore has been mined on the mining z level?
|
||||
var/score_ore_mined = 0
|
||||
/// How much research was done by science?
|
||||
var/score_research_done = 0
|
||||
/// How many random events did the station survive?
|
||||
var/score_events_endured = 0
|
||||
/// How many APCs have poor charge?
|
||||
var/score_power_loss = 0
|
||||
/// How many people got out alive?
|
||||
var/score_escapees = 0
|
||||
/// How many people /didn't/ get out alive?
|
||||
var/score_dead_crew = 0
|
||||
/// How much blood, puke, stains etc went uncleaned?
|
||||
var/score_mess = 0
|
||||
/// How many meals were made?
|
||||
var/score_meals = 0
|
||||
/// How many rampant, uncured diseases are on board the station?
|
||||
var/score_disease = 0
|
||||
/// How many command members died? (Revolution)
|
||||
var/score_dead_command = 0
|
||||
/// How many antagonists are alive in the brig? (Nuke ops & Revolution)
|
||||
var/score_arrested = 0
|
||||
/// How many operatives were killed? (Nuke ops & Revolution)
|
||||
var/score_ops_killed = 0
|
||||
/// How much noms were had by the crew?
|
||||
var/score_food_eaten = 0
|
||||
/// How many times was the clown punched, struck, or otherwise maligned?
|
||||
var/score_clown_abuse = 0
|
||||
|
||||
// Booleans //
|
||||
/// Were the antagonists successful?
|
||||
var/score_greentext = FALSE
|
||||
/// Did the crew catch all of the antags alive?
|
||||
var/all_arrested = FALSE
|
||||
/// Is the NAD safe and secure?
|
||||
var/disc_secure = FALSE
|
||||
|
||||
// Points penalties/bonuses //
|
||||
/// If all APCs on the station are running optimally, big bonus.
|
||||
var/power_bonus = FALSE
|
||||
/// If there are no messes on the station anywhere, huge bonus.
|
||||
var/mess_bonus = FALSE
|
||||
/// If the AI is dead, big points penalty.
|
||||
var/dead_ai = FALSE
|
||||
/// Was the station blown into little bits?
|
||||
var/nuked = FALSE
|
||||
/// Points penalty for being blown to little bits.
|
||||
var/nuked_penalty = 0
|
||||
|
||||
// Player Stats //
|
||||
/// What was the name of the richest person on the shuttle?
|
||||
var/richest_name = ""
|
||||
/// What was the ckey of the richest person on the shuttle?
|
||||
var/richest_key = ""
|
||||
/// What was the job of the richest person on the shuttle?
|
||||
var/richest_job = ""
|
||||
/// How much money did the richest person on the shuttle have?
|
||||
var/richest_cash = 0
|
||||
|
||||
/// What was the name of the most injured person on the shuttle?
|
||||
var/damaged_name
|
||||
/// What was the ckey of the most injured person on the shuttle?
|
||||
var/damaged_key
|
||||
/// What was the job of the most injured person on the shuttle?
|
||||
var/damaged_job
|
||||
/// How damaged was the most injured person on the shuttle?
|
||||
var/damaged_health
|
||||
|
||||
|
||||
/datum/scoreboard/proc/scoreboard()
|
||||
// Print a list of antagonists to the server log.
|
||||
log_antags()
|
||||
|
||||
for(var/_I in GLOB.mob_list)
|
||||
var/mob/M = _I
|
||||
if(is_station_level(M.z))
|
||||
check_station_player(M)
|
||||
else if(SSshuttle.emergency.mode >= SHUTTLE_ENDGAME && istype(get_area(M), SSshuttle.emergency.areaInstance))
|
||||
check_shuttle_player(M)
|
||||
|
||||
check_apc_power()
|
||||
check_cleanables()
|
||||
|
||||
generate_scoreboard()
|
||||
|
||||
/datum/scoreboard/proc/log_antags()
|
||||
var/list/total_antagonists = list()
|
||||
//Look into all mobs in world, dead or alive
|
||||
for(var/datum/mind/Mind in SSticker.minds)
|
||||
var/temprole = Mind.special_role
|
||||
if(temprole) //if they are an antagonist of some sort.
|
||||
if(temprole in total_antagonists) //If the role exists already, add the name to it
|
||||
total_antagonists[temprole] += ", [Mind.name]([Mind.key])"
|
||||
else
|
||||
total_antagonists.Add(temprole) //If the role doesnt exist in the list, create it and add the mob
|
||||
total_antagonists[temprole] += ": [Mind.name]([Mind.key])"
|
||||
// Look into all mobs in the world, dead or alive
|
||||
for(var/mind in SSticker.minds)
|
||||
var/datum/mind/M = mind
|
||||
var/role = M.special_role
|
||||
|
||||
//Now print them all into the log!
|
||||
// If they're an antagonist of some sort.
|
||||
if(role)
|
||||
if(total_antagonists[role]) // If the role exists already, add the name to it.
|
||||
total_antagonists[role] += ", [M.name]([M.key])"
|
||||
else // If the role doesn't exist in the list, create it and add the mob
|
||||
total_antagonists[role] += ": [M.name]([M.key])"
|
||||
|
||||
// Now print them all into the log!
|
||||
log_game("Antagonists at round end were...")
|
||||
for(var/i in total_antagonists)
|
||||
log_game("[i]s[total_antagonists[i]].")
|
||||
|
||||
// Score Calculation and Display
|
||||
|
||||
// Who is alive/dead, who escaped
|
||||
for(var/mob/living/silicon/ai/I in GLOB.mob_list)
|
||||
if(I.stat == DEAD && is_station_level(I.z))
|
||||
GLOB.score_deadaipenalty++
|
||||
GLOB.score_deadcrew++
|
||||
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/I = thing
|
||||
if(I.stat == DEAD && is_station_level(I.z))
|
||||
GLOB.score_deadcrew++
|
||||
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_ENDGAME)
|
||||
for(var/mob/living/player in GLOB.mob_list)
|
||||
if(player.client)
|
||||
if(player.stat != DEAD)
|
||||
var/turf/location = get_turf(player.loc)
|
||||
var/area/escape_zone = locate(/area/shuttle/escape)
|
||||
if(location in escape_zone)
|
||||
GLOB.score_escapees++
|
||||
for(var/I in total_antagonists)
|
||||
log_game("[I]s[total_antagonists[I]].")
|
||||
|
||||
|
||||
/datum/scoreboard/proc/check_station_player(mob/M)
|
||||
if(!is_station_level(M.z) || M.stat < DEAD)
|
||||
return
|
||||
if(isAI(M))
|
||||
dead_ai = TRUE
|
||||
score_dead_crew++
|
||||
else if(ishuman(M))
|
||||
score_dead_crew++
|
||||
|
||||
var/cash_score = 0
|
||||
var/dmg_score = 0
|
||||
/datum/scoreboard/proc/check_shuttle_player(mob/M)
|
||||
if(!M.mind || M.stat == DEAD || !ishuman(M))
|
||||
return
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_ENDGAME)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/E = thing
|
||||
cash_score = 0
|
||||
dmg_score = 0
|
||||
var/turf/location = get_turf(E.loc)
|
||||
var/area/escape_zone = SSshuttle.emergency.areaInstance
|
||||
score_escapees++
|
||||
|
||||
if(E.stat != DEAD && (location in escape_zone)) // Escapee Scores
|
||||
cash_score = get_score_container_worth(E)
|
||||
var/cash_score = get_score_container_worth(H)
|
||||
if(cash_score > richest_cash)
|
||||
richest_cash = cash_score
|
||||
richest_name = H.real_name
|
||||
richest_job = H.job
|
||||
richest_key = H.key
|
||||
|
||||
if(cash_score > GLOB.score_richestcash)
|
||||
GLOB.score_richestcash = cash_score
|
||||
GLOB.score_richestname = E.real_name
|
||||
GLOB.score_richestjob = E.job
|
||||
GLOB.score_richestkey = E.key
|
||||
var/damage_score = H.getBruteLoss() + H.getFireLoss() + H.getToxLoss() + H.getOxyLoss()
|
||||
if(damage_score > damaged_health)
|
||||
damaged_health = damage_score
|
||||
damaged_name = H.real_name
|
||||
damaged_job = H.job
|
||||
damaged_key = H.key
|
||||
|
||||
dmg_score = E.getBruteLoss() + E.getFireLoss() + E.getToxLoss() + E.getOxyLoss()
|
||||
if(dmg_score > GLOB.score_dmgestdamage)
|
||||
GLOB.score_dmgestdamage = dmg_score
|
||||
GLOB.score_dmgestname = E.real_name
|
||||
GLOB.score_dmgestjob = E.job
|
||||
GLOB.score_dmgestkey = E.key
|
||||
// A recursive function to properly determine the wealthiest escapee
|
||||
/datum/scoreboard/proc/get_score_container_worth(atom/C, level = 0)
|
||||
. = 0
|
||||
if(level >= 5)
|
||||
// in case the containers recurse or something
|
||||
return 0
|
||||
|
||||
if(SSticker && SSticker.mode)
|
||||
SSticker.mode.set_scoreboard_gvars()
|
||||
for(var/obj/item/card/id/id in C.contents)
|
||||
var/datum/money_account/A = get_money_account(id.associated_account_number)
|
||||
// has an account?
|
||||
if(A)
|
||||
. += A.money
|
||||
for(var/obj/item/stack/spacecash/cash in C.contents)
|
||||
. += cash.amount
|
||||
for(var/obj/item/storage/S in C.contents)
|
||||
. += .(S, level + 1)
|
||||
|
||||
/datum/scoreboard/proc/check_apc_power()
|
||||
for(var/_A in GLOB.apcs)
|
||||
var/obj/machinery/power/apc/A = _A
|
||||
if(!is_station_level(A.z))
|
||||
continue
|
||||
var/obj/item/stock_parts/cell/C = A.cell
|
||||
if(!C || C.charge < 2300)
|
||||
score_power_loss++ //200 charge leeway
|
||||
|
||||
/datum/scoreboard/proc/check_cleanables()
|
||||
for(var/obj/effect/decal/cleanable/C in world)
|
||||
if(!is_station_level(C.z))
|
||||
continue
|
||||
if(istype(C, /obj/effect/decal/cleanable/blood/gibs))
|
||||
score_mess += 3
|
||||
else if(istype(C, /obj/effect/decal/cleanable/blood))
|
||||
score_mess += 1
|
||||
else if(istype(C, /obj/effect/decal/cleanable/vomit))
|
||||
score_mess += 1
|
||||
|
||||
|
||||
// Check station's power levels
|
||||
for(var/thing in GLOB.apcs)
|
||||
var/obj/machinery/power/apc/A = thing
|
||||
if(!is_station_level(A.z)) continue
|
||||
for(var/obj/item/stock_parts/cell/C in A.contents)
|
||||
if(C.charge < 2300)
|
||||
GLOB.score_powerloss++ //200 charge leeway
|
||||
/datum/scoreboard/proc/generate_scoreboard()
|
||||
// Point modifiers
|
||||
var/points_events_endured = score_events_endured * 50
|
||||
var/points_research_done = score_research_done * 30
|
||||
var/points_disease = score_disease * 30
|
||||
var/points_dead_crew = score_dead_crew * 25
|
||||
var/points_escapees = score_escapees * 25
|
||||
var/points_power_loss = score_power_loss * 20
|
||||
var/points_things_harvested = score_things_harvested * 5
|
||||
var/points_things_shipped = score_things_shipped * 5
|
||||
var/points_meals = score_meals * 5
|
||||
var/points_ore_mined = score_ore_mined * 2
|
||||
|
||||
// Bonuses
|
||||
crewscore += points_events_endured
|
||||
crewscore += points_research_done
|
||||
crewscore += points_escapees
|
||||
crewscore += points_things_harvested
|
||||
crewscore += points_things_shipped
|
||||
crewscore += points_meals
|
||||
crewscore += points_ore_mined
|
||||
|
||||
// Check how much uncleaned mess is on the station
|
||||
for(var/obj/effect/decal/cleanable/M in world)
|
||||
if(!is_station_level(M.z)) continue
|
||||
if(istype(M, /obj/effect/decal/cleanable/blood/gibs))
|
||||
GLOB.score_mess += 3
|
||||
if(!score_power_loss)
|
||||
crewscore += 2500
|
||||
power_bonus = TRUE
|
||||
|
||||
if(istype(M, /obj/effect/decal/cleanable/blood))
|
||||
GLOB.score_mess += 1
|
||||
if(!score_mess)
|
||||
crewscore += 1500
|
||||
mess_bonus = TRUE
|
||||
|
||||
if(istype(M, /obj/effect/decal/cleanable/vomit))
|
||||
GLOB.score_mess += 1
|
||||
if(all_arrested) // This only seems to be implemented for Rev and Nukies. -DaveKorhal
|
||||
crewscore *= 3 // This needs to be here for the bonus to be applied properly
|
||||
|
||||
// Penalties
|
||||
crewscore -= points_dead_crew
|
||||
crewscore -= points_power_loss
|
||||
crewscore -= points_disease
|
||||
crewscore -= score_mess
|
||||
|
||||
// Bonus Modifiers
|
||||
var/deathpoints = GLOB.score_deadcrew * 25 //done
|
||||
var/researchpoints = GLOB.score_researchdone * 30
|
||||
var/eventpoints = GLOB.score_eventsendured * 50
|
||||
var/escapoints = GLOB.score_escapees * 25 //done
|
||||
var/harvests = GLOB.score_stuffharvested * 5
|
||||
var/shipping = GLOB.score_stuffshipped * 5
|
||||
var/mining = GLOB.score_oremined * 2 //done, might want polishing
|
||||
var/meals = GLOB.score_meals * 5
|
||||
var/power = GLOB.score_powerloss * 20
|
||||
var/messpoints
|
||||
if(GLOB.score_mess != 0)
|
||||
messpoints = GLOB.score_mess //done
|
||||
var/plaguepoints = GLOB.score_disease * 30
|
||||
if(dead_ai)
|
||||
crewscore -= 250
|
||||
|
||||
|
||||
// Good Things
|
||||
GLOB.score_crewscore += shipping
|
||||
GLOB.score_crewscore += harvests
|
||||
GLOB.score_crewscore += mining
|
||||
GLOB.score_crewscore += researchpoints
|
||||
GLOB.score_crewscore += eventpoints
|
||||
GLOB.score_crewscore += escapoints
|
||||
|
||||
if(power == 0)
|
||||
GLOB.score_crewscore += 2500
|
||||
GLOB.score_powerbonus = 1
|
||||
|
||||
|
||||
GLOB.score_crewscore += meals
|
||||
if(GLOB.score_allarrested) // This only seems to be implemented for Rev and Nukies. -DaveKorhal
|
||||
GLOB.score_crewscore *= 3 // This needs to be here for the bonus to be applied properly
|
||||
|
||||
|
||||
GLOB.score_crewscore -= deathpoints
|
||||
if(GLOB.score_deadaipenalty)
|
||||
GLOB.score_crewscore -= 250
|
||||
GLOB.score_crewscore -= power
|
||||
|
||||
|
||||
GLOB.score_crewscore -= messpoints
|
||||
GLOB.score_crewscore -= plaguepoints
|
||||
|
||||
// Show the score - might add "ranks" later
|
||||
to_chat(world, "<b>The crew's final score is:</b>")
|
||||
to_chat(world, "<b><font size='4'>[GLOB.score_crewscore]</font></b>")
|
||||
|
||||
// Generate the score panel
|
||||
var/dat = "<b>Round Statistics and Score</b><br><hr>"
|
||||
if(mode)
|
||||
dat += mode.get_scoreboard_stats()
|
||||
var/list/dat = list("<b>Round Statistics and Score</b><br><hr>")
|
||||
if(SSticker.mode)
|
||||
dat += SSticker.mode.get_scoreboard_stats()
|
||||
|
||||
dat += {"
|
||||
<b><u>General Statistics</u></b><br>
|
||||
<u>The Good</u><br>
|
||||
<b>Ore Mined:</b> [GLOB.score_oremined] ([GLOB.score_oremined * 2] Points)<br>"}
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_ENDGAME) dat += "<b>Shuttle Escapees:</b> [GLOB.score_escapees] ([GLOB.score_escapees * 25] Points)<br>"
|
||||
dat += {"
|
||||
<b>Whole Station Powered:</b> [GLOB.score_powerbonus ? "Yes" : "No"] ([GLOB.score_powerbonus * 2500] Points)<br><br>
|
||||
<b>Ore Mined:</b> [score_ore_mined] ([points_ore_mined] Points)<br>"}
|
||||
if(score_escapees)
|
||||
dat += "<b>Shuttle Escapees:</b> [score_escapees] ([points_escapees] Points)<br>"
|
||||
dat += "<b>Whole Station Powered:</b> [power_bonus ? "Yes" : "No"] ([power_bonus * 2500] Points)<br>"
|
||||
dat += "<b>Whole Station Cleaned:</b> [mess_bonus ? "Yes" : "No"] ([mess_bonus * 1500] Points)<br><br>"
|
||||
|
||||
<U>The Bad</U><br>
|
||||
<b>Dead bodies on Station:</b> [GLOB.score_deadcrew] (-[GLOB.score_deadcrew * 25] Points)<br>
|
||||
<b>Uncleaned Messes:</b> [GLOB.score_mess] (-[GLOB.score_mess] Points)<br>
|
||||
<b>Station Power Issues:</b> [GLOB.score_powerloss] (-[GLOB.score_powerloss * 20] Points)<br>
|
||||
<b>AI Destroyed:</b> [GLOB.score_deadaipenalty ? "Yes" : "No"] (-[GLOB.score_deadaipenalty * 250] Points)<br><br>
|
||||
dat += "<U>The Bad</U><br>"
|
||||
dat += "<b>Dead bodies on Station:</b> [score_dead_crew] (-[points_dead_crew] Points)<br>"
|
||||
if(!mess_bonus)
|
||||
dat += "<b>Uncleaned Messes:</b> [score_mess] (-[score_mess] Points)<br>"
|
||||
if(!power_bonus)
|
||||
dat += "<b>Station Power Issues:</b> [score_power_loss] (-[points_power_loss] Points)<br>"
|
||||
dat += {"
|
||||
<b>AI Destroyed:</b> [dead_ai ? "Yes" : "No"] (-[dead_ai * 250] Points)<br><br>
|
||||
|
||||
<U>The Weird</U><br>
|
||||
<b>Food Eaten:</b> [GLOB.score_foodeaten] bites/sips<br>
|
||||
<b>Times a Clown was Abused:</b> [GLOB.score_clownabuse]<br><br>
|
||||
"}
|
||||
if(GLOB.score_escapees)
|
||||
dat += {"<b>Richest Escapee:</b> [GLOB.score_richestname], [GLOB.score_richestjob]: $[num2text(GLOB.score_richestcash,50)] ([GLOB.score_richestkey])<br>
|
||||
<b>Most Battered Escapee:</b> [GLOB.score_dmgestname], [GLOB.score_dmgestjob]: [GLOB.score_dmgestdamage] damage ([GLOB.score_dmgestkey])<br>"}
|
||||
<b>Food Eaten:</b> [score_food_eaten] bites/sips.<br>
|
||||
<b>Times a Clown was Abused:</b> [score_clown_abuse]<br><br>"}
|
||||
if(score_escapees)
|
||||
dat += "<b>Richest Escapee:</b> [richest_name], [richest_job]: $[num2text(richest_cash, 50)] ([richest_key])<br>"
|
||||
if(damaged_health)
|
||||
dat += "<b>Most Battered Escapee:</b> [damaged_name], [damaged_job]: [damaged_health] damage ([damaged_key])<br>"
|
||||
else
|
||||
if(SSshuttle.emergency.mode <= SHUTTLE_STRANDED)
|
||||
dat += "The station wasn't evacuated!<br>"
|
||||
else
|
||||
dat += "No-one escaped!<br>"
|
||||
|
||||
dat += mode.declare_job_completion()
|
||||
dat += SSticker.mode.declare_job_completion()
|
||||
|
||||
dat += {"
|
||||
<hr><br>
|
||||
<b><u>FINAL SCORE: [GLOB.score_crewscore]</u></b><br>
|
||||
<b><u>FINAL SCORE: [crewscore]</u></b><br>
|
||||
"}
|
||||
|
||||
var/score_rating = "The Aristocrats!"
|
||||
switch(GLOB.score_crewscore)
|
||||
if(-99999 to SINGULARITY_DESERVES_BETTER) score_rating = "Even the Singularity Deserves Better"
|
||||
switch(crewscore)
|
||||
if(-INFINITY to SINGULARITY_DESERVES_BETTER) score_rating = "Even the Singularity Deserves Better"
|
||||
if(SINGULARITY_DESERVES_BETTER+1 to SINGULARITY_FODDER) score_rating = "Singularity Fodder"
|
||||
if(SINGULARITY_FODDER+1 to ALL_FIRED) score_rating = "You're All Fired"
|
||||
if(ALL_FIRED+1 to WASTE_OF_OXYGEN) score_rating = "A Waste of Perfectly Good Oxygen"
|
||||
@@ -214,33 +301,20 @@
|
||||
if(NANOTRANSEN_FINEST to INFINITY) score_rating = "Nanotrasen's Finest"
|
||||
|
||||
dat += "<b><u>RATING:</u></b> [score_rating]"
|
||||
src << browse(dat, "window=roundstats;size=500x600")
|
||||
GLOB.scoreboard = jointext(dat, "")
|
||||
|
||||
for(var/mob/E in GLOB.player_list)
|
||||
if(E.client && !E.get_preference(PREFTOGGLE_DISABLE_SCOREBOARD))
|
||||
E << browse(dat, "window=roundstats;size=500x600")
|
||||
if(E.client)
|
||||
to_chat(E, "<b>The crew's final score is:</b>")
|
||||
to_chat(E, "<b><font size='4'><a href='?src=[E.UID()];scoreboard=1'>[crewscore]</a></font></b>")
|
||||
if(!E.get_preference(PREFTOGGLE_DISABLE_SCOREBOARD))
|
||||
E << browse(GLOB.scoreboard, "window=roundstats;size=500x600")
|
||||
|
||||
// A recursive function to properly determine the wealthiest escapee
|
||||
/datum/controller/subsystem/ticker/proc/get_score_container_worth(atom/C, level=0)
|
||||
if(level >= 5)
|
||||
// in case the containers recurse or something
|
||||
return 0
|
||||
else
|
||||
. = 0
|
||||
for(var/obj/item/card/id/id in C.contents)
|
||||
var/datum/money_account/A = get_money_account(id.associated_account_number)
|
||||
// has an account?
|
||||
if(A)
|
||||
. += A.money
|
||||
for(var/obj/item/stack/spacecash/cash in C.contents)
|
||||
. += cash.amount
|
||||
for(var/obj/item/storage/S in C.contents)
|
||||
. += .(S, level + 1)
|
||||
|
||||
/datum/game_mode/proc/get_scoreboard_stats()
|
||||
return null
|
||||
|
||||
/datum/game_mode/proc/set_scoreboard_gvars()
|
||||
/datum/game_mode/proc/set_scoreboard_vars()
|
||||
return null
|
||||
|
||||
#undef SINGULARITY_DESERVES_BETTER
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
action_background_icon_state = "bg_vampire"
|
||||
var/required_blood = 0
|
||||
var/gain_desc = null
|
||||
var/deduct_blood_on_cast = TRUE //Do we want to take the blood when this is cast, or at a later point?
|
||||
|
||||
/obj/effect/proc_holder/spell/vampire/New()
|
||||
..()
|
||||
@@ -99,6 +100,8 @@
|
||||
var/datum/vampire/vampire = usr.mind.vampire
|
||||
|
||||
if(required_blood <= vampire.bloodusable)
|
||||
if(!deduct_blood_on_cast) //don't take the blood yet if this is false!
|
||||
return
|
||||
vampire.bloodusable -= required_blood
|
||||
else
|
||||
// stop!!
|
||||
@@ -288,8 +291,10 @@
|
||||
gain_desc = "You have gained the Enthrall ability which at a heavy blood cost allows you to enslave a human that is not loyal to any other for a random period of time."
|
||||
action_icon_state = "vampire_enthrall"
|
||||
required_blood = 300
|
||||
deduct_blood_on_cast = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/vampire/targetted/enthrall/cast(list/targets, mob/user = usr)
|
||||
var/datum/vampire/vampire = user.mind.vampire
|
||||
for(var/mob/living/target in targets)
|
||||
user.visible_message("<span class='warning'>[user] bites [target]'s neck!</span>", "<span class='warning'>You bite [target]'s neck and begin the flow of power.</span>")
|
||||
to_chat(target, "<span class='warning'>You feel the tendrils of evil invade your mind.</span>")
|
||||
@@ -299,6 +304,7 @@
|
||||
if(do_mob(user, target, 50))
|
||||
if(can_enthrall(user, target))
|
||||
handle_enthrall(user, target)
|
||||
vampire.bloodusable -= required_blood //we take the blood after enthralling, not before
|
||||
else
|
||||
revert_cast(user)
|
||||
to_chat(user, "<span class='warning'>You or your target either moved or you dont have enough usable blood.</span>")
|
||||
|
||||
@@ -366,7 +366,7 @@
|
||||
qdel(SS)
|
||||
|
||||
/proc/make_new_construct(mob/living/simple_animal/hostile/construct/c_type, mob/target, mob/user, cult_override = FALSE)
|
||||
if(jobban_isbanned(target, "cultist"))
|
||||
if(jobban_isbanned(target, ROLE_CULTIST))
|
||||
return
|
||||
var/mob/living/simple_animal/hostile/construct/C = new c_type(get_turf(target))
|
||||
C.faction |= "\ref[user]"
|
||||
|
||||
@@ -446,7 +446,7 @@
|
||||
|
||||
/datum/spellbook_entry/item/warp_cubes
|
||||
name = "Warp Cubes"
|
||||
desc = "Two magic cubes, that when they are twisted in hand, teleports the user to the location of the other cube instantly. Great for silently teleporting to a fixed location, or teleporting you to an appretnance, or vice versa. Do not leave on the wizard den, it will not work."
|
||||
desc = "Two magic cubes, that when they are twisted in hand, teleports the user to the location of the other cube instantly. Great for silently teleporting to a fixed location, or teleporting you to an apprentice, or vice versa. Do not leave on the wizard den, it will not work."
|
||||
item_path = /obj/item/warp_cube/red
|
||||
log_name = "WC"
|
||||
cost = 1
|
||||
@@ -479,7 +479,7 @@
|
||||
|
||||
/datum/spellbook_entry/item/singularity_hammer
|
||||
name = "Singularity Hammer"
|
||||
desc = "A hammer that creates an intensely powerful field of gravity where it strikes, pulling everthing nearby to the point of impact."
|
||||
desc = "A hammer that creates an intensely powerful field of gravity where it strikes, pulling everything nearby to the point of impact."
|
||||
item_path = /obj/item/twohanded/singularityhammer
|
||||
log_name = "SI"
|
||||
category = "Weapons and Armors"
|
||||
|
||||
@@ -226,7 +226,7 @@
|
||||
to_chat(H, "<span class='danger'>Failed to locate a storage object on your mob, either you spawned with no hands free and no backpack or this is a bug.</span>")
|
||||
qdel(G)
|
||||
|
||||
qdel(gear_leftovers)
|
||||
gear_leftovers.Cut()
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
@@ -4,133 +4,66 @@
|
||||
icon_state = "liquid_dispenser"
|
||||
layer = 3
|
||||
plane = FLOOR_PLANE
|
||||
anchored = 1.0
|
||||
anchored = TRUE
|
||||
max_integrity = 200
|
||||
armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30)
|
||||
var/uses = 20
|
||||
var/disabled = TRUE
|
||||
var/lethal = 0
|
||||
var/locked = TRUE
|
||||
var/cooldown_time = 0
|
||||
var/cooldown_timeleft = 0
|
||||
var/cooldown_time = 10 SECONDS
|
||||
var/cooldown_on = FALSE
|
||||
req_access = list(ACCESS_AI_UPLOAD)
|
||||
|
||||
/obj/machinery/ai_slipper/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>A small counter shows it has: [uses] use\s remaining.</span>"
|
||||
|
||||
/obj/machinery/ai_slipper/power_change()
|
||||
if(stat & BROKEN)
|
||||
update_icon()
|
||||
if(powered())
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
if( powered() )
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
stat |= NOPOWER
|
||||
disabled = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/ai_slipper/proc/setState(enabled, uses)
|
||||
disabled = disabled
|
||||
uses = uses
|
||||
power_change()
|
||||
|
||||
/obj/machinery/ai_slipper/attackby(obj/item/W, mob/user, params)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(istype(user, /mob/living/silicon))
|
||||
return attack_hand(user)
|
||||
if(allowed(usr)) // trying to unlock the interface
|
||||
locked = !locked
|
||||
to_chat(user, "You [locked ? "lock" : "unlock"] the device.")
|
||||
if(locked)
|
||||
if(user.machine == src)
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=ai_slipper")
|
||||
else
|
||||
if(user.machine == src)
|
||||
attack_hand(usr)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/ai_slipper/proc/ToggleOn()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
disabled = !disabled
|
||||
stat |= NOPOWER
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/ai_slipper/proc/Activate()
|
||||
/obj/machinery/ai_slipper/attack_ai(mob/user)
|
||||
add_hiddenprint(user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/ai_slipper/attack_ghost(mob/user)
|
||||
if(user.can_advanced_admin_interact())
|
||||
Activate(user)
|
||||
|
||||
/obj/machinery/ai_slipper/attack_hand(mob/user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
to_chat(user, "<span class='warning'>[src] has no power or is broken!</span>")
|
||||
return
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
return
|
||||
Activate(user)
|
||||
|
||||
/obj/machinery/ai_slipper/proc/Activate(mob/user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(cooldown_on || disabled)
|
||||
if(!uses)
|
||||
to_chat(user, "<span class='warning'>[src] is empty!</span>")
|
||||
return
|
||||
if(cooldown_on)
|
||||
to_chat(user, "<span class='warning'>[src] is still recharging!</span>")
|
||||
return
|
||||
else
|
||||
new /obj/effect/particle_effect/foam(loc)
|
||||
uses--
|
||||
cooldown_on = TRUE
|
||||
cooldown_time = world.timeofday + 100
|
||||
slip_process()
|
||||
power_change()
|
||||
addtimer(CALLBACK(src, .proc/recharge), cooldown_time)
|
||||
|
||||
/obj/machinery/ai_slipper/update_icon()
|
||||
if(stat & (NOPOWER|BROKEN) || disabled)
|
||||
if(stat & (NOPOWER|BROKEN) || cooldown_on || !uses)
|
||||
icon_state = "liquid_dispenser"
|
||||
else
|
||||
icon_state = "liquid_dispenser_on"
|
||||
|
||||
/obj/machinery/ai_slipper/attack_ai(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/ai_slipper/attack_ghost(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/ai_slipper/attack_hand(mob/user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
/obj/machinery/ai_slipper/proc/recharge()
|
||||
if(!uses)
|
||||
return
|
||||
|
||||
if(get_dist(src, user) > 1 && (!issilicon(user) && !user.can_admin_interact()))
|
||||
to_chat(user, "<span class='warning'>Too far away.</span>")
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=ai_slipper")
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
var/area/myarea = get_area(src)
|
||||
var/t = "<TT><B>AI Liquid Dispenser</B> ([myarea.name])<HR>"
|
||||
|
||||
if(locked && (!issilicon(user) && !user.can_admin_interact()))
|
||||
t += "<I>(Swipe ID card to unlock control panel.)</I><BR>"
|
||||
else
|
||||
t += text("Dispenser [] - <A href='?src=[UID()];toggleOn=1'>[]?</a><br>\n", disabled ? "deactivated" : "activated", disabled ? "Enable" : "Disable")
|
||||
t += text("Uses Left: [uses]. <A href='?src=[UID()];toggleUse=1'>Activate the dispenser?</A><br>\n")
|
||||
|
||||
user << browse(t, "window=computer;size=575x450")
|
||||
onclose(user, "computer")
|
||||
|
||||
/obj/machinery/ai_slipper/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(locked && (!issilicon(usr) && !usr.can_admin_interact()))
|
||||
to_chat(usr, "Control panel is locked!")
|
||||
return 1
|
||||
|
||||
if(href_list["toggleOn"])
|
||||
ToggleOn()
|
||||
|
||||
if(href_list["toggleUse"])
|
||||
Activate()
|
||||
|
||||
attack_hand(usr)
|
||||
|
||||
/obj/machinery/ai_slipper/proc/slip_process()
|
||||
while(cooldown_time - world.timeofday > 0)
|
||||
var/ticksleft = cooldown_time - world.timeofday
|
||||
|
||||
if(ticksleft > 1e5)
|
||||
cooldown_time = world.timeofday + 10 // midnight rollover
|
||||
|
||||
|
||||
cooldown_timeleft = (ticksleft / 10)
|
||||
sleep(5)
|
||||
if(uses <= 0)
|
||||
return
|
||||
if(uses >= 0)
|
||||
cooldown_on = FALSE
|
||||
cooldown_on = FALSE
|
||||
power_change()
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
max_integrity = 100
|
||||
var/state = 0
|
||||
var/obj/item/circuitboard/circuit = null
|
||||
var/base_mineral = /obj/item/stack/sheet/metal
|
||||
|
||||
/obj/structure/computerframe/deconstruct(disassembled = TRUE)
|
||||
if(!(flags & NODECONSTRUCT))
|
||||
@@ -18,7 +17,7 @@
|
||||
deconstruct()
|
||||
|
||||
/obj/structure/computerframe/proc/drop_computer_parts()
|
||||
new base_mineral(loc, 5)
|
||||
new /obj/item/stack/sheet/metal(loc, 5)
|
||||
if(circuit)
|
||||
circuit.forceMove(loc)
|
||||
circuit = null
|
||||
@@ -357,14 +356,6 @@
|
||||
build_path = /obj/machinery/computer/turbine_computer
|
||||
origin_tech = "programming=4;engineering=4;powerstorage=4"
|
||||
|
||||
/obj/item/circuitboard/HONKputer
|
||||
name = "Circuit board (HONKputer)"
|
||||
build_path = /obj/machinery/computer/HONKputer
|
||||
origin_tech = "programming=2"
|
||||
icon = 'icons/obj/machines/HONKputer.dmi'
|
||||
icon_state = "bananium_board"
|
||||
board_type = "honkcomputer"
|
||||
|
||||
|
||||
/obj/item/circuitboard/supplycomp/attackby(obj/item/I as obj, mob/user as mob, params)
|
||||
if(istype(I,/obj/item/multitool))
|
||||
@@ -552,116 +543,3 @@
|
||||
if(I.use_tool(src, user, 50, volume = I.tool_volume) && !state)
|
||||
to_chat(user, "<span class='notice'>You deconstruct [src].</span>")
|
||||
deconstruct(TRUE)
|
||||
|
||||
|
||||
|
||||
/obj/structure/computerframe/HONKputer
|
||||
name = "Bananium Computer-frame"
|
||||
icon = 'icons/obj/machines/HONKputer.dmi'
|
||||
base_mineral = /obj/item/stack/sheet/mineral/bananium
|
||||
|
||||
/obj/structure/computerframe/HONKputer/attackby(obj/item/P as obj, mob/user as mob, params)
|
||||
switch(state)
|
||||
if(0)
|
||||
if(istype(P, /obj/item/wrench))
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
if(do_after(user, 20, target = src))
|
||||
to_chat(user, "<span class='notice'>You wrench the frame into place.</span>")
|
||||
anchored = 1
|
||||
state = 1
|
||||
if(1)
|
||||
if(istype(P, /obj/item/wrench))
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
if(do_after(user, 20 * P.toolspeed, target = src))
|
||||
to_chat(user, "<span class='notice'>You unfasten the frame.</span>")
|
||||
anchored = 0
|
||||
state = 0
|
||||
if(istype(P, /obj/item/circuitboard) && !circuit)
|
||||
var/obj/item/circuitboard/B = P
|
||||
if(B.board_type == "honkcomputer")
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You place the circuit board inside the frame.</span>")
|
||||
icon_state = "1"
|
||||
circuit = P
|
||||
user.drop_item()
|
||||
P.loc = src
|
||||
else
|
||||
to_chat(user, "<span class='warning'>This frame does not accept circuit boards of this type!</span>")
|
||||
if(istype(P, /obj/item/screwdriver) && circuit)
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You screw the circuit board into place.</span>")
|
||||
state = 2
|
||||
icon_state = "2"
|
||||
if(istype(P, /obj/item/crowbar) && circuit)
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You remove the circuit board.</span>")
|
||||
state = 1
|
||||
icon_state = "0"
|
||||
circuit.loc = loc
|
||||
circuit = null
|
||||
return
|
||||
if(2)
|
||||
if(istype(P, /obj/item/screwdriver) && circuit)
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You unfasten the circuit board.</span>")
|
||||
state = 1
|
||||
icon_state = "1"
|
||||
if(istype(P, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = P
|
||||
if(C.get_amount() >= 5)
|
||||
playsound(loc, C.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You start to add cables to the frame.</span>")
|
||||
if(do_after(user, 20 * C.toolspeed, target = src))
|
||||
if(state == 2 && C.get_amount() >= 5 && C.use(5))
|
||||
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
|
||||
state = 3
|
||||
icon_state = "3"
|
||||
else
|
||||
to_chat(user, "<span class='warning'>At some point during construction you lost some cable. Make sure you have five lengths before trying again.</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need five lengths of cable to wire the frame.</span>")
|
||||
return
|
||||
if(3)
|
||||
if(istype(P, /obj/item/wirecutters))
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You remove the cables.</span>")
|
||||
state = 2
|
||||
icon_state = "2"
|
||||
var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( loc )
|
||||
A.amount = 5
|
||||
|
||||
if(istype(P, /obj/item/stack/sheet/glass))
|
||||
var/obj/item/stack/sheet/glass/G = P
|
||||
if(G.get_amount() >= 2)
|
||||
playsound(loc, G.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You start to add the glass panel to the frame.</span>")
|
||||
if(do_after(user, 20 * G.toolspeed, target = src))
|
||||
if(state == 3 && G.get_amount() >= 2 && G.use(2))
|
||||
to_chat(user, "<span class='notice'>You put in the glass panel.</span>")
|
||||
state = 4
|
||||
icon_state = "4"
|
||||
else
|
||||
to_chat(user, "<span class='warning'>At some point during construction you lost some glass. Make sure you have two sheets before trying again.</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need two sheets of glass for this.</span>")
|
||||
return
|
||||
if(4)
|
||||
if(istype(P, /obj/item/crowbar))
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You remove the glass panel.</span>")
|
||||
state = 3
|
||||
icon_state = "3"
|
||||
new /obj/item/stack/sheet/glass(loc, 2)
|
||||
if(istype(P, /obj/item/screwdriver))
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You connect the monitor.</span>")
|
||||
var/B = new circuit.build_path (loc)
|
||||
if(circuit.powernet) B:powernet = circuit.powernet
|
||||
if(circuit.id) B:id = circuit.id
|
||||
if(circuit.records) B:records = circuit.records
|
||||
if(circuit.frequency) B:frequency = circuit.frequency
|
||||
qdel(src)
|
||||
return
|
||||
return ..()
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
if(C.network&networks)
|
||||
if(length(C.network & networks))
|
||||
camera_location = get_turf(C)
|
||||
break
|
||||
if(camera_location)
|
||||
@@ -101,6 +101,8 @@
|
||||
|
||||
/mob/camera/aiEye/remote
|
||||
name = "Inactive Camera Eye"
|
||||
// Abductors dont trigger the Ai Detector
|
||||
ai_detector_visible = FALSE
|
||||
var/sprint = 10
|
||||
var/cooldown = 0
|
||||
var/acceleration = 1
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
/obj/machinery/computer/HONKputer
|
||||
name = "\improper HONKputer Mark I"
|
||||
desc = "A yellow computer used in case of critically low levels of HONK."
|
||||
icon = 'icons/obj/machines/HONKputer.dmi'
|
||||
icon_state = "honkputer"
|
||||
icon_keyboard = "key_honk"
|
||||
icon_screen = "honkcomms"
|
||||
light_color = LIGHT_COLOR_PINK
|
||||
req_access = list(ACCESS_CLOWN)
|
||||
circuit = /obj/item/circuitboard/HONKputer
|
||||
var/authenticated = 0
|
||||
var/message_cooldown = 0
|
||||
var/state = STATE_DEFAULT
|
||||
var/const/STATE_DEFAULT = 1
|
||||
|
||||
/obj/machinery/computer/HONKputer/process()
|
||||
if(..())
|
||||
src.updateDialog()
|
||||
|
||||
/obj/machinery/computer/HONKputer/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(is_away_level(src.z))
|
||||
to_chat(usr, "<span class='danger'>Unable to establish a connection</span>: You're too far away from the station!")
|
||||
return
|
||||
usr.set_machine(src)
|
||||
|
||||
if(!href_list["operation"])
|
||||
return
|
||||
switch(href_list["operation"])
|
||||
// main interface
|
||||
if("main")
|
||||
src.state = STATE_DEFAULT
|
||||
if("login")
|
||||
var/mob/M = usr
|
||||
var/obj/item/card/id/I = M.get_active_hand()
|
||||
if(istype(I, /obj/item/pda))
|
||||
var/obj/item/pda/pda = I
|
||||
I = pda.id
|
||||
if(I && istype(I))
|
||||
if(src.check_access(I) || src.emagged==1)
|
||||
authenticated = 1
|
||||
if("logout")
|
||||
authenticated = 0
|
||||
|
||||
if("MessageHonkplanet")
|
||||
if(src.authenticated==1)
|
||||
if(message_cooldown)
|
||||
to_chat(usr, "Arrays recycling. Please stand by.")
|
||||
return
|
||||
var/input = stripped_input(usr, "Please choose a message to transmit to your HONKbrothers on the homeworld. Transmission does not guarantee a response.", "To abort, send an empty message.", "")
|
||||
if(!input || !(usr in view(1,src)))
|
||||
return
|
||||
HONK_announce(input, usr)
|
||||
to_chat(usr, "Message transmitted.")
|
||||
log_game("[key_name(usr)] has made a HONKplanet announcement: [input]")
|
||||
message_cooldown = 1
|
||||
spawn(6000)//10 minute cooldown
|
||||
message_cooldown = 0
|
||||
|
||||
src.updateUsrDialog()
|
||||
|
||||
/obj/machinery/computer/HONKputer/emag_act(user as mob)
|
||||
if(!emagged)
|
||||
src.emagged = 1
|
||||
to_chat(user, "You scramble the login circuits, allowing anyone to use the console!")
|
||||
|
||||
/obj/machinery/computer/HONKputer/attack_hand(mob/user as mob)
|
||||
if(..())
|
||||
return
|
||||
if(is_away_level(src.z))
|
||||
to_chat(user, "<span class='danger'>Unable to establish a connection</span>: You're too far away from the station!")
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
var/dat = "<head><title>HONKputer Interface</title></head><body>"
|
||||
|
||||
if(istype(user, /mob/living/silicon))
|
||||
to_chat(user, "This console is not networked to the rest of the grid.")
|
||||
return
|
||||
|
||||
switch(src.state)
|
||||
if(STATE_DEFAULT)
|
||||
if(src.authenticated)
|
||||
dat += "<BR>\[ <A HREF='?src=[UID()];operation=logout'>Log Out</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[UID()];operation=MessageHonkplanet'>Send an emergency message to Honkplanet</A> \]"
|
||||
else
|
||||
dat += "<BR>\[ <A HREF='?src=[UID()];operation=login'>Log In</A> \]"
|
||||
|
||||
|
||||
dat += "<BR>\[ [(src.state != STATE_DEFAULT) ? "<A HREF='?src=[UID()];operation=main'>Main Menu</A> | " : ""]<A HREF='?src=[user.UID()];mach_close=honkputer'>Close</A> \]"
|
||||
user << browse(dat, "window=honkputer;size=400x500")
|
||||
onclose(user, "honkputer")
|
||||
|
||||
|
||||
/obj/machinery/computer/HONKputer/attackby(obj/I, mob/user, params)
|
||||
if(istype(I, /obj/item/screwdriver) && circuit)
|
||||
var/obj/item/screwdriver/S = I
|
||||
playsound(src.loc, S.usesound, 50, 1)
|
||||
if(do_after(user, 20 * S.toolspeed, target = src))
|
||||
var/obj/structure/computerframe/HONKputer/A = new /obj/structure/computerframe/HONKputer( src.loc )
|
||||
var/obj/item/circuitboard/M = new circuit( A )
|
||||
A.circuit = M
|
||||
A.anchored = 1
|
||||
for(var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
if(src.stat & BROKEN)
|
||||
to_chat(user, "<span class='notice'>The broken glass falls out.</span>")
|
||||
new /obj/item/shard( src.loc )
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You disconnect the monitor.</span>")
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
qdel(src)
|
||||
else
|
||||
return ..()
|
||||
@@ -1,110 +0,0 @@
|
||||
#define SALVAGE_SHIP_MOVE_TIME 300
|
||||
#define SALVAGE_SHIP_COOLDOWN 800
|
||||
|
||||
/obj/machinery/computer/salvage_ship
|
||||
name = "salvage ship terminal"
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_keyboard = "syndie_key"
|
||||
icon_screen = "syndishuttle"
|
||||
req_access = list(ACCESS_SALVAGE_CAPTAIN)
|
||||
var/area/curr_location
|
||||
var/moving = 0
|
||||
var/lastMove = 0
|
||||
|
||||
|
||||
/obj/machinery/computer/salvage_ship/New()
|
||||
. = ..()
|
||||
curr_location = locate(/area/shuttle/salvage/start)
|
||||
|
||||
|
||||
/obj/machinery/computer/salvage_ship/proc/salvage_move_to(area/destination as area)
|
||||
if(moving) return
|
||||
if(lastMove + SALVAGE_SHIP_COOLDOWN > world.time) return
|
||||
var/area/dest_location = locate(destination)
|
||||
if(curr_location == dest_location) return
|
||||
|
||||
moving = 1
|
||||
lastMove = world.time
|
||||
|
||||
if(curr_location.z != dest_location.z)
|
||||
var/area/transit_location = locate(/area/shuttle/salvage/transit)
|
||||
curr_location.move_contents_to(transit_location)
|
||||
curr_location = transit_location
|
||||
sleep(SALVAGE_SHIP_MOVE_TIME)
|
||||
|
||||
curr_location.move_contents_to(dest_location)
|
||||
curr_location = dest_location
|
||||
moving = 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/salvage_ship/attack_ai(mob/user as mob)
|
||||
src.add_hiddenprint(user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/salvage_ship/attack_hand(mob/user as mob)
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access Denied</span>")
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
|
||||
var/dat = {"Location: [curr_location]<br>
|
||||
Ready to move[max(lastMove + SALVAGE_SHIP_COOLDOWN - world.time, 0) ? " in [max(round((lastMove + SALVAGE_SHIP_COOLDOWN - world.time) * 0.1), 0)] seconds" : ": now"]<br>
|
||||
<a href='?src=[UID()];start=1'>Middle of Nowhere</a><br>
|
||||
<a href='?src=[UID()];arrivals=1'>Station Auxiliary Docking</a> |
|
||||
<a href='?src=[UID()];north=1'>North of the Station</a> |
|
||||
<a href='?src=[UID()];east=1'>East of the Station</a> |
|
||||
<a href='?src=[UID()];south=1'>South of the Station</a><br>
|
||||
<a href='?src=[UID()];trading_post=1'>Trading Post</a><br>
|
||||
<a href='?src=[UID()];clown_asteroid=1'>Clown Asteroid</a> |
|
||||
<a href='?src=[UID()];derelict=1'>Derelict Station</a> |
|
||||
<a href='?src=[UID()];djstation=1'>Ruskie DJ Station</a><br>
|
||||
<a href='?src=[UID()];commssat=1'>Communications Satellite</a> |
|
||||
<a href='?src=[UID()];abandoned_ship=1'>Abandoned Ship</a><br>
|
||||
<a href='?src=[user.UID()];mach_close=computer'>Close</a>"}
|
||||
|
||||
user << browse(dat, "window=computer;size=575x450")
|
||||
onclose(user, "computer")
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/computer/salvage_ship/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(!isliving(usr)) return
|
||||
var/mob/living/user = usr
|
||||
|
||||
if(in_range(src, user) || istype(user, /mob/living/silicon))
|
||||
user.set_machine(src)
|
||||
|
||||
if(href_list["salvage"])
|
||||
salvage_move_to(/area/shuttle/salvage/start)
|
||||
else if(href_list["start"])
|
||||
salvage_move_to(/area/shuttle/salvage/start)
|
||||
else if(href_list["arrivals"])
|
||||
salvage_move_to(/area/shuttle/salvage/arrivals)
|
||||
else if(href_list["derelict"])
|
||||
salvage_move_to(/area/shuttle/salvage/derelict)
|
||||
else if(href_list["djstation"])
|
||||
salvage_move_to(/area/shuttle/salvage/djstation)
|
||||
else if(href_list["north"])
|
||||
salvage_move_to(/area/shuttle/salvage/north)
|
||||
else if(href_list["east"])
|
||||
salvage_move_to(/area/shuttle/salvage/east)
|
||||
else if(href_list["south"])
|
||||
salvage_move_to(/area/shuttle/salvage/south)
|
||||
else if(href_list["commssat"])
|
||||
salvage_move_to(/area/shuttle/salvage/commssat)
|
||||
else if(href_list["abandoned_ship"])
|
||||
salvage_move_to(/area/shuttle/salvage/abandoned_ship)
|
||||
else if(href_list["clown_asteroid"])
|
||||
salvage_move_to(/area/shuttle/salvage/clown_asteroid)
|
||||
else if(href_list["trading_post"])
|
||||
salvage_move_to(/area/shuttle/salvage/trading_post)
|
||||
|
||||
add_fingerprint(usr)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/salvage_ship/bullet_act(obj/item/projectile/Proj)
|
||||
visible_message("[Proj] ricochets off [src]!")
|
||||
@@ -1,338 +0,0 @@
|
||||
//Config stuff
|
||||
#define SPECOPS_MOVETIME 600 //Time to station is milliseconds. 60 seconds, enough time for everyone to be on the shuttle before it leaves.
|
||||
#define SPECOPS_STATION_AREATYPE "/area/shuttle/specops/station" //Type of the spec ops shuttle area for station
|
||||
#define SPECOPS_DOCK_AREATYPE "/area/shuttle/specops/centcom" //Type of the spec ops shuttle area for dock
|
||||
#define SPECOPS_RETURN_DELAY 6000 //Time between the shuttle is capable of moving.
|
||||
|
||||
GLOBAL_VAR_INIT(specops_shuttle_moving_to_station, 0)
|
||||
GLOBAL_VAR_INIT(specops_shuttle_moving_to_centcom, 0)
|
||||
GLOBAL_VAR_INIT(specops_shuttle_at_station, 0)
|
||||
GLOBAL_VAR_INIT(specops_shuttle_can_send, 1)
|
||||
GLOBAL_VAR_INIT(specops_shuttle_time, 0)
|
||||
GLOBAL_VAR_INIT(specops_shuttle_timeleft, 0)
|
||||
|
||||
/obj/machinery/computer/specops_shuttle
|
||||
name = "\improper Spec. Ops. shuttle console"
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_keyboard = "security_key"
|
||||
icon_screen = "syndishuttle"
|
||||
light_color = LIGHT_COLOR_PURE_CYAN
|
||||
req_access = list(ACCESS_CENT_SPECOPS)
|
||||
// req_access = list(ACCESS_CENT_SPECOPS)
|
||||
var/temp = null
|
||||
var/hacked = 0
|
||||
var/allowedtocall = 0
|
||||
var/specops_shuttle_timereset = 0
|
||||
|
||||
/proc/specops_return()
|
||||
var/obj/item/radio/intercom/announcer = new /obj/item/radio/intercom(null)//We need a fake AI to announce some stuff below. Otherwise it will be wonky.
|
||||
announcer.config(list("Response Team" = 0))
|
||||
|
||||
var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values.
|
||||
var/message = "\"THE SPECIAL OPERATIONS SHUTTLE IS PREPARING TO RETURN\""//Initial message shown.
|
||||
if(announcer)
|
||||
announcer.autosay(message, "A.L.I.C.E.", "Response Team", list(1,2))
|
||||
|
||||
while(GLOB.specops_shuttle_time - world.timeofday > 0)
|
||||
var/ticksleft = GLOB.specops_shuttle_time - world.timeofday
|
||||
|
||||
if(ticksleft > 1e5)
|
||||
GLOB.specops_shuttle_time = world.timeofday + 10 // midnight rollover
|
||||
GLOB.specops_shuttle_timeleft = (ticksleft / 10)
|
||||
|
||||
//All this does is announce the time before launch.
|
||||
if(announcer)
|
||||
var/rounded_time_left = round(GLOB.specops_shuttle_timeleft)//Round time so that it will report only once, not in fractions.
|
||||
if(rounded_time_left in message_tracker)//If that time is in the list for message announce.
|
||||
message = "\"ALERT: [rounded_time_left] SECOND[(rounded_time_left!=1)?"S":""] REMAIN\""
|
||||
if(rounded_time_left==0)
|
||||
message = "\"ALERT: TAKEOFF\""
|
||||
announcer.autosay(message, "A.L.I.C.E.", "Response Team")
|
||||
message_tracker -= rounded_time_left//Remove the number from the list so it won't be called again next cycle.
|
||||
//Should call all the numbers but lag could mean some issues. Oh well. Not much I can do about that.
|
||||
|
||||
sleep(5)
|
||||
|
||||
GLOB.specops_shuttle_moving_to_station = 0
|
||||
GLOB.specops_shuttle_moving_to_centcom = 0
|
||||
|
||||
GLOB.specops_shuttle_at_station = 1
|
||||
|
||||
var/area/start_location = locate(/area/shuttle/specops/station)
|
||||
var/area/end_location = locate(/area/shuttle/specops/centcom)
|
||||
|
||||
var/list/dstturfs = list()
|
||||
var/throwy = world.maxy
|
||||
|
||||
for(var/turf/T in end_location)
|
||||
dstturfs += T
|
||||
if(T.y < throwy)
|
||||
throwy = T.y
|
||||
|
||||
// hey you, get out of the way!
|
||||
for(var/turf/T in dstturfs)
|
||||
// find the turf to move things to
|
||||
var/turf/D = locate(T.x, throwy - 1, 1)
|
||||
//var/turf/E = get_step(D, SOUTH)
|
||||
for(var/atom/movable/AM as mob|obj in T)
|
||||
AM.Move(D)
|
||||
if(istype(T, /turf/simulated))
|
||||
qdel(T)
|
||||
|
||||
for(var/mob/living/carbon/bug in end_location) // If someone somehow is still in the shuttle's docking area...
|
||||
bug.gib()
|
||||
|
||||
for(var/mob/living/simple_animal/pest in end_location) // And for the other kind of bug...
|
||||
pest.gib()
|
||||
|
||||
start_location.move_contents_to(end_location)
|
||||
|
||||
for(var/turf/T in get_area_turfs(end_location) )
|
||||
var/mob/M = locate(/mob) in T
|
||||
to_chat(M, "<span class='warning'>You have arrived at Central Command. Operation has ended!</span>")
|
||||
|
||||
GLOB.specops_shuttle_at_station = 0
|
||||
|
||||
for(var/obj/machinery/computer/specops_shuttle/S in GLOB.machines)
|
||||
S.specops_shuttle_timereset = world.time + SPECOPS_RETURN_DELAY
|
||||
|
||||
qdel(announcer)
|
||||
|
||||
/proc/specops_process()
|
||||
var/area/centcom/specops/special_ops = locate()//Where is the specops area located?
|
||||
var/obj/item/radio/intercom/announcer = new /obj/item/radio/intercom(null)//We need a fake AI to announce some stuff below. Otherwise it will be wonky.
|
||||
announcer.config(list("Response Team" = 0))
|
||||
|
||||
var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values.
|
||||
var/message = "\"THE SPECIAL OPERATIONS SHUTTLE IS PREPARING FOR LAUNCH\""//Initial message shown.
|
||||
if(announcer)
|
||||
announcer.autosay(message, "A.L.I.C.E.", "Response Team")
|
||||
//message = "ARMORED SQUAD TAKE YOUR POSITION ON GRAVITY LAUNCH PAD"
|
||||
//announcer.autosay(message, "A.L.I.C.E.", "Response Team")
|
||||
|
||||
while(GLOB.specops_shuttle_time - world.timeofday > 0)
|
||||
var/ticksleft = GLOB.specops_shuttle_time - world.timeofday
|
||||
|
||||
if(ticksleft > 1e5)
|
||||
GLOB.specops_shuttle_time = world.timeofday + 10 // midnight rollover
|
||||
GLOB.specops_shuttle_timeleft = (ticksleft / 10)
|
||||
|
||||
//All this does is announce the time before launch.
|
||||
if(announcer)
|
||||
var/rounded_time_left = round(GLOB.specops_shuttle_timeleft)//Round time so that it will report only once, not in fractions.
|
||||
if(rounded_time_left in message_tracker)//If that time is in the list for message announce.
|
||||
message = "\"ALERT: [rounded_time_left] SECOND[(rounded_time_left!=1)?"S":""] REMAIN\""
|
||||
if(rounded_time_left==0)
|
||||
message = "\"ALERT: TAKEOFF\""
|
||||
announcer.autosay(message, "A.L.I.C.E.", "Response Team")
|
||||
message_tracker -= rounded_time_left//Remove the number from the list so it won't be called again next cycle.
|
||||
//Should call all the numbers but lag could mean some issues. Oh well. Not much I can do about that.
|
||||
|
||||
sleep(5)
|
||||
|
||||
GLOB.specops_shuttle_moving_to_station = 0
|
||||
GLOB.specops_shuttle_moving_to_centcom = 0
|
||||
|
||||
GLOB.specops_shuttle_at_station = 1
|
||||
if(GLOB.specops_shuttle_moving_to_station || GLOB.specops_shuttle_moving_to_centcom) return
|
||||
|
||||
if(!specops_can_move())
|
||||
to_chat(usr, "<span class='warning'>The Special Operations shuttle is unable to leave.</span>")
|
||||
return
|
||||
|
||||
//Begin Marauder launchpad.
|
||||
spawn(0)//So it parallel processes it.
|
||||
for(var/obj/machinery/door/poddoor/M in special_ops)
|
||||
switch(M.id_tag)
|
||||
if("ASSAULT0")
|
||||
spawn(10)//1 second delay between each.
|
||||
M.open()
|
||||
if("ASSAULT1")
|
||||
spawn(20)
|
||||
M.open()
|
||||
if("ASSAULT2")
|
||||
spawn(30)
|
||||
M.open()
|
||||
if("ASSAULT3")
|
||||
spawn(40)
|
||||
M.open()
|
||||
|
||||
sleep(10)
|
||||
|
||||
var/spawn_marauder[] = new()
|
||||
for(var/thing in GLOB.landmarks_list)
|
||||
var/obj/effect/landmark/L = thing
|
||||
if(L.name == "Marauder Entry")
|
||||
spawn_marauder.Add(L.loc)
|
||||
for(var/thing in GLOB.landmarks_list)
|
||||
var/obj/effect/landmark/L = thing
|
||||
if(L.name == "Marauder Exit")
|
||||
var/obj/effect/portal/P = new(L.loc, pick(spawn_marauder))
|
||||
//P.invisibility = 101//So it is not seen by anyone.
|
||||
P.failchance = 0//So it has no fail chance when teleporting.
|
||||
spawn_marauder.Remove(P.target)
|
||||
|
||||
sleep(10)
|
||||
|
||||
for(var/obj/machinery/mass_driver/M in special_ops)
|
||||
switch(M.id_tag)
|
||||
if("ASSAULT0")
|
||||
spawn(10)
|
||||
M.drive()
|
||||
if("ASSAULT1")
|
||||
spawn(20)
|
||||
M.drive()
|
||||
if("ASSAULT2")
|
||||
spawn(30)
|
||||
M.drive()
|
||||
if("ASSAULT3")
|
||||
spawn(40)
|
||||
M.drive()
|
||||
|
||||
sleep(50)//Doors remain open for 5 seconds.
|
||||
|
||||
for(var/obj/machinery/door/poddoor/M in special_ops)
|
||||
switch(M.id_tag)//Doors close at the same time.
|
||||
if("ASSAULT0")
|
||||
spawn(0)
|
||||
M.close()
|
||||
if("ASSAULT1")
|
||||
spawn(0)
|
||||
M.close()
|
||||
if("ASSAULT2")
|
||||
spawn(0)
|
||||
M.close()
|
||||
if("ASSAULT3")
|
||||
spawn(0)
|
||||
M.close()
|
||||
//End Marauder launchpad.
|
||||
|
||||
var/area/start_location = locate(/area/shuttle/specops/centcom)
|
||||
var/area/end_location = locate(/area/shuttle/specops/station)
|
||||
|
||||
var/list/dstturfs = list()
|
||||
var/throwy = world.maxy
|
||||
|
||||
for(var/turf/T in end_location)
|
||||
dstturfs += T
|
||||
if(T.y < throwy)
|
||||
throwy = T.y
|
||||
|
||||
// hey you, get out of the way!
|
||||
for(var/turf/T in dstturfs)
|
||||
// find the turf to move things to
|
||||
var/turf/D = locate(T.x, throwy - 1, 1)
|
||||
//var/turf/E = get_step(D, SOUTH)
|
||||
for(var/atom/movable/AM as mob|obj in T)
|
||||
AM.Move(D)
|
||||
if(istype(T, /turf/simulated))
|
||||
qdel(T)
|
||||
|
||||
start_location.move_contents_to(end_location)
|
||||
|
||||
for(var/turf/T in get_area_turfs(end_location) )
|
||||
var/mob/M = locate(/mob) in T
|
||||
to_chat(M, "<span class='warning'>You have arrived to [station_name()]. Commence operation!</span>")
|
||||
|
||||
for(var/obj/machinery/computer/specops_shuttle/S in GLOB.machines)
|
||||
S.specops_shuttle_timereset = world.time + SPECOPS_RETURN_DELAY
|
||||
|
||||
qdel(announcer)
|
||||
|
||||
/proc/specops_can_move()
|
||||
if(GLOB.specops_shuttle_moving_to_station || GLOB.specops_shuttle_moving_to_centcom)
|
||||
return 0
|
||||
for(var/obj/machinery/computer/specops_shuttle/S in GLOB.machines)
|
||||
if(world.timeofday <= S.specops_shuttle_timereset)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/specops_shuttle/attack_ai(mob/user as mob)
|
||||
to_chat(user, "<span class='warning'>Access Denied.</span>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/specops_shuttle/attackby(I as obj, user as mob, params)
|
||||
if(istype(I,/obj/item/card/emag))
|
||||
to_chat(user, "<span class='notice'>The electronic systems in this console are far too advanced for your primitive hacking peripherals.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/specops_shuttle/attack_hand(mob/user as mob)
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access Denied.</span>")
|
||||
return
|
||||
|
||||
//Commented out so admins can do shenanigans at their leisure. Also makes the force-spawned admin ERTs able to use the shuttle.
|
||||
// if(sent_strike_team == 0 && send_emergency_team == 0)
|
||||
// to_chat(usr, "<span class='warning'>The strike team has not yet deployed.</span>")
|
||||
// return
|
||||
|
||||
if(..())
|
||||
return
|
||||
|
||||
user.machine = src
|
||||
var/dat
|
||||
if(temp)
|
||||
dat = temp
|
||||
else
|
||||
dat += {"<BR><B>Special Operations Shuttle</B><HR>
|
||||
\nLocation: [GLOB.specops_shuttle_moving_to_station || GLOB.specops_shuttle_moving_to_centcom ? "Departing for [station_name()] in ([GLOB.specops_shuttle_timeleft] seconds.)":GLOB.specops_shuttle_at_station ? "Station":"Dock"]<BR>
|
||||
[GLOB.specops_shuttle_moving_to_station || GLOB.specops_shuttle_moving_to_centcom ? "\n*The Special Ops. shuttle is already leaving.*<BR>\n<BR>":GLOB.specops_shuttle_at_station ? "\n<A href='?src=[UID()];sendtodock=1'>Shuttle standing by...</A><BR>\n<BR>":"\n<A href='?src=[UID()];sendtostation=1'>Depart to [station_name()]</A><BR>\n<BR>"]
|
||||
\n<A href='?src=[user.UID()];mach_close=computer'>Close</A>"}
|
||||
|
||||
user << browse(dat, "window=computer;size=575x450")
|
||||
onclose(user, "computer")
|
||||
return
|
||||
|
||||
/obj/machinery/computer/specops_shuttle/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon)))
|
||||
usr.machine = src
|
||||
|
||||
if(href_list["sendtodock"])
|
||||
if(!GLOB.specops_shuttle_at_station|| GLOB.specops_shuttle_moving_to_station || GLOB.specops_shuttle_moving_to_centcom) return
|
||||
|
||||
if(!specops_can_move())
|
||||
to_chat(usr, "<span class='notice'>Central Command will not allow the Special Operations shuttle to return yet.</span>")
|
||||
if(world.timeofday <= specops_shuttle_timereset)
|
||||
if(((world.timeofday - specops_shuttle_timereset)/10) > 60)
|
||||
to_chat(usr, "<span class='notice'>[-((world.timeofday - specops_shuttle_timereset)/10)/60] minutes remain!</span>")
|
||||
to_chat(usr, "<span class='notice'>[-(world.timeofday - specops_shuttle_timereset)/10] seconds remain!</span>")
|
||||
return
|
||||
|
||||
to_chat(usr, "<span class='notice'>The Special Operations shuttle will arrive at Central Command in [(SPECOPS_MOVETIME/10)] seconds.</span>")
|
||||
|
||||
temp += "Shuttle departing.<BR><BR><A href='?src=[UID()];mainmenu=1'>OK</A>"
|
||||
updateUsrDialog()
|
||||
|
||||
GLOB.specops_shuttle_moving_to_centcom = 1
|
||||
GLOB.specops_shuttle_time = world.timeofday + SPECOPS_MOVETIME
|
||||
spawn(0)
|
||||
specops_return()
|
||||
|
||||
else if(href_list["sendtostation"])
|
||||
if(GLOB.specops_shuttle_at_station || GLOB.specops_shuttle_moving_to_station || GLOB.specops_shuttle_moving_to_centcom) return
|
||||
|
||||
if(!specops_can_move())
|
||||
to_chat(usr, "<span class='warning'>The Special Operations shuttle is unable to leave.</span>")
|
||||
return
|
||||
|
||||
to_chat(usr, "<span class='notice'>The Special Operations shuttle will arrive on [station_name()] in [(SPECOPS_MOVETIME/10)] seconds.</span>")
|
||||
|
||||
temp += "Shuttle departing.<BR><BR><A href='?src=[UID()];mainmenu=1'>OK</A>"
|
||||
updateUsrDialog()
|
||||
|
||||
GLOB.specops_shuttle_moving_to_station = 1
|
||||
|
||||
GLOB.specops_shuttle_time = world.timeofday + SPECOPS_MOVETIME
|
||||
spawn(0)
|
||||
specops_process()
|
||||
|
||||
else if(href_list["mainmenu"])
|
||||
temp = null
|
||||
|
||||
add_fingerprint(usr)
|
||||
updateUsrDialog()
|
||||
return
|
||||
@@ -1,254 +0,0 @@
|
||||
//Config stuff
|
||||
#define SYNDICATE_ELITE_MOVETIME 600 //Time to station is milliseconds. 60 seconds, enough time for everyone to be on the shuttle before it leaves.
|
||||
#define SYNDICATE_ELITE_STATION_AREATYPE "/area/shuttle/syndicate_elite/station" //Type of the spec ops shuttle area for station
|
||||
#define SYNDICATE_ELITE_DOCK_AREATYPE "/area/shuttle/syndicate_elite/mothership" //Type of the spec ops shuttle area for dock
|
||||
|
||||
GLOBAL_VAR_INIT(syndicate_elite_shuttle_moving_to_station, 0)
|
||||
GLOBAL_VAR_INIT(syndicate_elite_shuttle_moving_to_mothership, 0)
|
||||
GLOBAL_VAR_INIT(syndicate_elite_shuttle_at_station, 0)
|
||||
GLOBAL_VAR_INIT(syndicate_elite_shuttle_can_send, 1)
|
||||
GLOBAL_VAR_INIT(syndicate_elite_shuttle_time, 0)
|
||||
GLOBAL_VAR_INIT(syndicate_elite_shuttle_timeleft, 0)
|
||||
|
||||
/obj/machinery/computer/syndicate_elite_shuttle
|
||||
name = "\improper Elite Syndicate Squad shuttle console"
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_keyboard = "syndie_key"
|
||||
icon_screen = "syndishuttle"
|
||||
light_color = LIGHT_COLOR_PURE_CYAN
|
||||
req_access = list(ACCESS_SYNDICATE)
|
||||
bubble_icon = "syndibot"
|
||||
var/temp = null
|
||||
var/hacked = 0
|
||||
var/allowedtocall = 0
|
||||
|
||||
/proc/syndicate_elite_process()
|
||||
var/area/syndicate_mothership/control/syndicate_ship = locate()//To find announcer. This area should exist for this proc to work.
|
||||
//var/area/syndicate_mothership/elite_squad/elite_squad = locate()//Where is the specops area located?
|
||||
var/mob/living/silicon/decoy/announcer = locate() in syndicate_ship//We need a fake AI to announce some stuff below. Otherwise it will be wonky.
|
||||
|
||||
var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values.
|
||||
var/message = "THE SYNDICATE ELITE SHUTTLE IS PREPARING FOR LAUNCH"//Initial message shown.
|
||||
if(announcer)
|
||||
announcer.say(message)
|
||||
// message = "ARMORED SQUAD TAKE YOUR POSITION ON GRAVITY LAUNCH PAD"
|
||||
// announcer.say(message)
|
||||
|
||||
while(GLOB.syndicate_elite_shuttle_time - world.timeofday > 0)
|
||||
var/ticksleft = GLOB.syndicate_elite_shuttle_time - world.timeofday
|
||||
|
||||
if(ticksleft > 1e5)
|
||||
GLOB.syndicate_elite_shuttle_time = world.timeofday // midnight rollover
|
||||
GLOB.syndicate_elite_shuttle_timeleft = (ticksleft / 10)
|
||||
|
||||
//All this does is announce the time before launch.
|
||||
if(announcer)
|
||||
var/rounded_time_left = round(GLOB.syndicate_elite_shuttle_timeleft)//Round time so that it will report only once, not in fractions.
|
||||
if(rounded_time_left in message_tracker)//If that time is in the list for message announce.
|
||||
message = "ALERT: [rounded_time_left] SECOND[(rounded_time_left!=1)?"S":""] REMAIN"
|
||||
if(rounded_time_left==0)
|
||||
message = "ALERT: TAKEOFF"
|
||||
announcer.say(message)
|
||||
message_tracker -= rounded_time_left//Remove the number from the list so it won't be called again next cycle.
|
||||
//Should call all the numbers but lag could mean some issues. Oh well. Not much I can do about that.
|
||||
|
||||
sleep(5)
|
||||
|
||||
GLOB.syndicate_elite_shuttle_moving_to_station = 0
|
||||
GLOB.syndicate_elite_shuttle_moving_to_mothership = 0
|
||||
|
||||
GLOB.syndicate_elite_shuttle_at_station = 1
|
||||
if(GLOB.syndicate_elite_shuttle_moving_to_station || GLOB.syndicate_elite_shuttle_moving_to_mothership) return
|
||||
|
||||
if(!syndicate_elite_can_move())
|
||||
to_chat(usr, "<span class='warning'>The Syndicate Elite shuttle is unable to leave.</span>")
|
||||
return
|
||||
|
||||
/*
|
||||
//Begin Marauder launchpad.
|
||||
spawn(0)//So it parallel processes it.
|
||||
for(var/obj/machinery/door/poddoor/M in elite_squad)
|
||||
switch(M.id)
|
||||
if("ASSAULT0")
|
||||
spawn(10)//1 second delay between each.
|
||||
M.open()
|
||||
if("ASSAULT1")
|
||||
spawn(20)
|
||||
M.open()
|
||||
if("ASSAULT2")
|
||||
spawn(30)
|
||||
M.open()
|
||||
if("ASSAULT3")
|
||||
spawn(40)
|
||||
M.open()
|
||||
|
||||
sleep(10)
|
||||
|
||||
var/spawn_marauder[] = new()
|
||||
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
|
||||
if(L.name == "Marauder Entry")
|
||||
spawn_marauder.Add(L)
|
||||
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
|
||||
if(L.name == "Marauder Exit")
|
||||
var/obj/effect/portal/P = new(L.loc)
|
||||
P.invisibility = 101//So it is not seen by anyone.
|
||||
P.failchance = 0//So it has no fail chance when teleporting.
|
||||
P.target = pick(spawn_marauder)//Where the marauder will arrive.
|
||||
spawn_marauder.Remove(P.target)
|
||||
|
||||
sleep(10)
|
||||
|
||||
for(var/obj/machinery/mass_driver/M in elite_squad)
|
||||
switch(M.id)
|
||||
if("ASSAULT0")
|
||||
spawn(10)
|
||||
M.drive()
|
||||
if("ASSAULT1")
|
||||
spawn(20)
|
||||
M.drive()
|
||||
if("ASSAULT2")
|
||||
spawn(30)
|
||||
M.drive()
|
||||
if("ASSAULT3")
|
||||
spawn(40)
|
||||
M.drive()
|
||||
|
||||
sleep(50)//Doors remain open for 5 seconds.
|
||||
|
||||
for(var/obj/machinery/door/poddoor/M in elite_squad)
|
||||
switch(M.id)//Doors close at the same time.
|
||||
if("ASSAULT0")
|
||||
spawn(0)
|
||||
M.close()
|
||||
if("ASSAULT1")
|
||||
spawn(0)
|
||||
M.close()
|
||||
if("ASSAULT2")
|
||||
spawn(0)
|
||||
M.close()
|
||||
if("ASSAULT3")
|
||||
spawn(0)
|
||||
M.close()
|
||||
elite_squad.readyreset()//Reset firealarm after the team launched.
|
||||
*/
|
||||
//End Marauder launchpad.
|
||||
|
||||
for(var/thing in GLOB.landmarks_list)
|
||||
var/obj/effect/landmark/L = thing
|
||||
if(L.name == "Syndicate Breach Area")
|
||||
explosion(L.loc,4,6,8,10,0)
|
||||
|
||||
sleep(40)
|
||||
|
||||
|
||||
var/area/start_location = locate(/area/shuttle/syndicate_elite/mothership)
|
||||
var/area/end_location = locate(/area/shuttle/syndicate_elite/station)
|
||||
|
||||
var/list/dstturfs = list()
|
||||
var/throwy = world.maxy
|
||||
|
||||
for(var/turf/T in end_location)
|
||||
dstturfs = T
|
||||
if(T.y < throwy)
|
||||
throwy = T.y
|
||||
|
||||
// hey you, get out of the way!
|
||||
for(var/turf/T in dstturfs)
|
||||
// find the turf to move things to
|
||||
var/turf/D = locate(T.x, throwy - 1, 1)
|
||||
//var/turf/E = get_step(D, SOUTH)
|
||||
for(var/atom/movable/AM as mob|obj in T)
|
||||
AM.Move(D)
|
||||
if(istype(T, /turf/simulated))
|
||||
qdel(T)
|
||||
|
||||
for(var/mob/living/carbon/bug in end_location) // If someone somehow is still in the shuttle's docking area...
|
||||
bug.gib()
|
||||
|
||||
for(var/mob/living/simple_animal/pest in end_location) // And for the other kind of bug...
|
||||
pest.gib()
|
||||
|
||||
start_location.move_contents_to(end_location)
|
||||
|
||||
for(var/turf/T in get_area_turfs(end_location) )
|
||||
var/mob/M = locate(/mob) in T
|
||||
to_chat(M, "<span class='warning'>You have arrived to [station_name()]. Commence operation!</span>")
|
||||
|
||||
/proc/syndicate_elite_can_move()
|
||||
if(GLOB.syndicate_elite_shuttle_moving_to_station || GLOB.syndicate_elite_shuttle_moving_to_mothership) return 0
|
||||
else return 1
|
||||
|
||||
/obj/machinery/computer/syndicate_elite_shuttle/attack_ai(mob/user as mob)
|
||||
to_chat(user, "<span class='warning'>Access Denied.</span>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/syndicate_elite_shuttle/attackby(I as obj, user as mob, params)
|
||||
if(istype(I,/obj/item/card/emag))
|
||||
to_chat(user, "<span class='notice'>The electronic systems in this console are far too advanced for your primitive hacking peripherals.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/syndicate_elite_shuttle/attack_hand(mob/user as mob)
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access Denied.</span>")
|
||||
return
|
||||
|
||||
// if(sent_syndicate_strike_team == 0)
|
||||
// to_chat(usr, "<span class='warning'>The strike team has not yet deployed.</span>")
|
||||
// return
|
||||
|
||||
if(..())
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
var/dat
|
||||
if(temp)
|
||||
dat = temp
|
||||
else
|
||||
dat = {"<BR><B>Special Operations Shuttle</B><HR>
|
||||
\nLocation: [GLOB.syndicate_elite_shuttle_moving_to_station || GLOB.syndicate_elite_shuttle_moving_to_mothership ? "Departing for [station_name()] in ([GLOB.syndicate_elite_shuttle_timeleft] seconds.)":GLOB.syndicate_elite_shuttle_at_station ? "Station":"Dock"]<BR>
|
||||
[GLOB.syndicate_elite_shuttle_moving_to_station || GLOB.syndicate_elite_shuttle_moving_to_mothership ? "\n*The Syndicate Elite shuttle is already leaving.*<BR>\n<BR>":GLOB.syndicate_elite_shuttle_at_station ? "\n<A href='?src=[UID()];sendtodock=1'>Shuttle Offline</A><BR>\n<BR>":"\n<A href='?src=[UID()];sendtostation=1'>Depart to [station_name()]</A><BR>\n<BR>"]
|
||||
\n<A href='?src=[user.UID()];mach_close=computer'>Close</A>"}
|
||||
|
||||
user << browse(dat, "window=computer;size=575x450")
|
||||
onclose(user, "computer")
|
||||
return
|
||||
|
||||
/obj/machinery/computer/syndicate_elite_shuttle/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon)))
|
||||
usr.set_machine(src)
|
||||
|
||||
if(href_list["sendtodock"])
|
||||
if(!GLOB.syndicate_elite_shuttle_at_station|| GLOB.syndicate_elite_shuttle_moving_to_station || GLOB.syndicate_elite_shuttle_moving_to_mothership) return
|
||||
|
||||
to_chat(usr, "<span class='notice'>The Syndicate will not allow the Elite Squad shuttle to return.</span>")
|
||||
return
|
||||
|
||||
else if(href_list["sendtostation"])
|
||||
if(GLOB.syndicate_elite_shuttle_at_station || GLOB.syndicate_elite_shuttle_moving_to_station || GLOB.syndicate_elite_shuttle_moving_to_mothership) return
|
||||
|
||||
if(!specops_can_move())
|
||||
to_chat(usr, "<span class='warning'>The Syndicate Elite shuttle is unable to leave.</span>")
|
||||
return
|
||||
|
||||
to_chat(usr, "<span class='notice'>The Syndicate Elite shuttle will arrive on [station_name()] in [(SYNDICATE_ELITE_MOVETIME/10)] seconds.</span>")
|
||||
|
||||
temp = "Shuttle departing.<BR><BR><A href='?src=[UID()];mainmenu=1'>OK</A>"
|
||||
updateUsrDialog()
|
||||
|
||||
GLOB.syndicate_elite_shuttle_moving_to_station = 1
|
||||
|
||||
GLOB.syndicate_elite_shuttle_time = world.timeofday + SYNDICATE_ELITE_MOVETIME
|
||||
spawn(0)
|
||||
syndicate_elite_process()
|
||||
|
||||
|
||||
else if(href_list["mainmenu"])
|
||||
temp = null
|
||||
|
||||
add_fingerprint(usr)
|
||||
updateUsrDialog()
|
||||
return
|
||||
@@ -720,6 +720,10 @@
|
||||
// Won't announce when used for cryoing.
|
||||
silent = TRUE
|
||||
|
||||
/obj/machinery/cryopod/offstation/right
|
||||
orient_right = TRUE
|
||||
icon_state = "body_scanner_0-r"
|
||||
|
||||
/obj/machinery/computer/cryopod/robot
|
||||
name = "robotic storage console"
|
||||
desc = "An interface between crew and the robotic storage systems"
|
||||
|
||||
@@ -145,6 +145,8 @@
|
||||
else if(our_rpd.mode == RPD_FLIP_MODE)
|
||||
flip()
|
||||
else if(our_rpd.mode == RPD_DELETE_MODE)
|
||||
if(pipe_type == PIPE_CIRCULATOR) //Skip TEG heat circulators, they aren't really pipes
|
||||
return ..()
|
||||
our_rpd.delete_single_pipe(user, src)
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -657,6 +657,7 @@ GLOBAL_LIST_EMPTY(turret_icons)
|
||||
qdel(flick_holder)
|
||||
|
||||
set_raised_raising(FALSE, FALSE)
|
||||
set_angle(0)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/porta_turret/on_assess_perp(mob/living/carbon/human/perp)
|
||||
@@ -678,7 +679,8 @@ GLOBAL_LIST_EMPTY(turret_icons)
|
||||
last_target = target
|
||||
if(has_cover)
|
||||
popUp() //pop the turret up if it's not already up.
|
||||
setDir(get_dir(src, target)) //even if you can't shoot, follow the target
|
||||
// Set angle
|
||||
set_angle(get_angle(src, target))
|
||||
shootAt(target)
|
||||
return TRUE
|
||||
|
||||
@@ -842,6 +844,9 @@ GLOBAL_LIST_EMPTY(turret_icons)
|
||||
if(!user.unEquip(I))
|
||||
to_chat(user, "<span class='notice'>\the [I] is stuck to your hand, you cannot put it in \the [src]</span>")
|
||||
return
|
||||
if(!E.can_fit_in_turrets)
|
||||
to_chat(user, "<span class='notice'>[I] will not operate correctly in [src].</span>")
|
||||
return
|
||||
installation = I.type //installation becomes I.type
|
||||
gun_charge = E.cell.charge //the gun's charge is stored in gun_charge
|
||||
to_chat(user, "<span class='notice'>You add [I] to the turret.</span>")
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
name = "syndicate suit storage unit"
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
mask_type = /obj/item/clothing/mask/gas/syndicate
|
||||
storage_type = /obj/item/tank/jetpack/oxygen/harness
|
||||
storage_type = /obj/item/tank/internals/oxygen/red
|
||||
req_access = list(ACCESS_SYNDICATE)
|
||||
safeties = FALSE //in a syndicate base, everything can be used as a murder weapon at a moment's notice.
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@
|
||||
name = "teleporter hub"
|
||||
desc = "It's the hub of a teleporting machine."
|
||||
icon_state = "tele0"
|
||||
var/accurate = FALSE
|
||||
var/accurate = 0
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 2000
|
||||
@@ -353,6 +353,8 @@
|
||||
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
|
||||
A += M.rating
|
||||
accurate = A
|
||||
if(accurate >= 3)
|
||||
calibrated = TRUE
|
||||
|
||||
/obj/machinery/teleport/hub/proc/link_power_station()
|
||||
if(power_station)
|
||||
@@ -401,12 +403,13 @@
|
||||
if(!calibrated && com.cc_beacon)
|
||||
visible_message("<span class='alert'>Cannot lock on target. Please calibrate the teleporter before attempting long range teleportation.</span>")
|
||||
else if(!calibrated && prob(25 - ((accurate) * 10)) && !com.cc_beacon) //oh dear a problem
|
||||
var/list/target_z = levels_by_trait(REACHABLE)
|
||||
var/list/target_z = levels_by_trait(SPAWN_RUINS)
|
||||
target_z -= M.z //Where to sir? Anywhere but here.
|
||||
. = do_teleport(M, locate(rand((2*TRANSITIONEDGE), world.maxx - (2*TRANSITIONEDGE)), rand((2*TRANSITIONEDGE), world.maxy - (2*TRANSITIONEDGE)), pick(target_z)), 2, bypass_area_flag = com.area_bypass)
|
||||
else
|
||||
. = do_teleport(M, com.target, bypass_area_flag = com.area_bypass)
|
||||
calibrated = FALSE
|
||||
if(accurate < 3)
|
||||
calibrated = FALSE
|
||||
|
||||
/obj/machinery/teleport/hub/update_icon()
|
||||
if(panel_open)
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
to_chat(user, "<span class='warning'>You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's.</warning>")
|
||||
return TRUE
|
||||
|
||||
if(is_special_character(user) || jobban_isbanned(user, ROLE_TRAITOR) || jobban_isbanned(user, "Syndicate"))
|
||||
if(is_special_character(user) || jobban_isbanned(user, ROLE_TRAITOR) || jobban_isbanned(user, ROLE_SYNDICATE))
|
||||
to_chat(user, "<span class='warning'>Something instinctual makes you pull away.</span>")
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -483,7 +483,7 @@
|
||||
if(R.can_synth && add_known_reagent(R.id, R.name))
|
||||
occupant_message("Reagent analyzed, identified as [R.name] and added to database.")
|
||||
send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form())
|
||||
occupant_message("Analyzis complete.")
|
||||
occupant_message("Analysis complete.")
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/add_known_reagent(r_id,r_name)
|
||||
|
||||
@@ -30,28 +30,38 @@
|
||||
return
|
||||
if(!cargo_holder)
|
||||
return
|
||||
if(istype(target,/obj))
|
||||
if(isobj(target))
|
||||
var/obj/O = target
|
||||
if(!O.anchored)
|
||||
if(cargo_holder.cargo.len < cargo_holder.cargo_capacity)
|
||||
chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.")
|
||||
O.anchored = 1
|
||||
if(do_after_cooldown(target))
|
||||
cargo_holder.cargo += O
|
||||
O.loc = chassis
|
||||
O.anchored = 0
|
||||
occupant_message("<span class='notice'>[target] successfully loaded.</span>")
|
||||
log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]")
|
||||
else
|
||||
O.anchored = initial(O.anchored)
|
||||
else
|
||||
occupant_message("<span class='warning'>Not enough room in cargo compartment!</span>")
|
||||
else
|
||||
if(istype(target, /obj/machinery/power/supermatter_crystal)) //No, you can't pick up the SM with this you moron, did you think you were clever?
|
||||
var/obj/mecha/working/ripley/R = chassis
|
||||
QDEL_LIST(R.cargo) //We don't want to drop cargo that just spam hits the SM, let's delete it
|
||||
occupant_message("<span class='userdanger'>You realise in horror what you have done as [chassis] starts warping around you!</span>")
|
||||
chassis.occupant.dust()
|
||||
target.Bumped(chassis)
|
||||
return
|
||||
if(O.anchored)
|
||||
occupant_message("<span class='warning'>[target] is firmly secured!</span>")
|
||||
return
|
||||
if(length(cargo_holder.cargo) >= cargo_holder.cargo_capacity)
|
||||
occupant_message("<span class='warning'>Not enough room in cargo compartment!</span>")
|
||||
return
|
||||
chassis.visible_message("<span class='notice'>[chassis] lifts [target] and starts to load it into cargo compartment.</span>")
|
||||
var/anchor_state_before_load = O.anchored
|
||||
O.anchored = TRUE
|
||||
if(!do_after_cooldown(target))
|
||||
O.anchored = anchor_state_before_load
|
||||
return
|
||||
cargo_holder.cargo += O
|
||||
O.forceMove(chassis)
|
||||
O.anchored = FALSE
|
||||
occupant_message("<span class='notice'>[target] was successfully loaded.</span>")
|
||||
log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - length(cargo_holder.cargo)]")
|
||||
return
|
||||
|
||||
else if(istype(target,/mob/living))
|
||||
if(isliving(target))
|
||||
var/mob/living/M = target
|
||||
if(M.stat == DEAD) return
|
||||
if(M.stat == DEAD)
|
||||
return
|
||||
if(chassis.occupant.a_intent == INTENT_HARM)
|
||||
M.take_overall_damage(dam_force)
|
||||
if(!M)
|
||||
@@ -62,12 +72,10 @@
|
||||
"<span class='italics'>You hear something crack.</span>")
|
||||
add_attack_logs(chassis.occupant, M, "Squeezed with [src] ([uppertext(chassis.occupant.a_intent)]) ([uppertext(damtype)])")
|
||||
start_cooldown()
|
||||
else
|
||||
step_away(M,chassis)
|
||||
occupant_message("<span class='notice'>You push [target] out of the way.</span>")
|
||||
chassis.visible_message("<span class='notice'>[chassis] pushes [target] out of the way.</span>")
|
||||
return 1
|
||||
|
||||
return
|
||||
step_away(M, chassis)
|
||||
occupant_message("<span class='notice'>You push [target] out of the way.</span>")
|
||||
chassis.visible_message("<span class='notice'>[chassis] pushes [target] out of the way.</span>")
|
||||
|
||||
|
||||
//This is pretty much just for the death-ripley
|
||||
|
||||
@@ -1200,7 +1200,8 @@
|
||||
|
||||
/obj/mecha/Exited(atom/movable/M, atom/newloc)
|
||||
if(occupant && occupant == M) // The occupant exited the mech without calling go_out()
|
||||
go_out(1, newloc)
|
||||
if(!isAI(occupant)) //This causes carded AIS to gib, so we do not want this to be called during carding.
|
||||
go_out(1, newloc)
|
||||
|
||||
/obj/mecha/proc/go_out(forced, atom/newloc = loc)
|
||||
if(!occupant)
|
||||
@@ -1507,7 +1508,7 @@
|
||||
if(internal_tank)
|
||||
WR.crowbar_salvage += internal_tank
|
||||
internal_tank.forceMove(WR)
|
||||
cell = null
|
||||
internal_tank = null
|
||||
. = ..()
|
||||
|
||||
/obj/mecha/CtrlClick(mob/living/L)
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
user.visible_message("<span class='notice'>[user] pries [S] from [src].</span>", "<span class='notice'>You pry [S] from [src].</span>")
|
||||
crowbar_salvage -= S
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You don't see anything that can be cut with [I]!</span>")
|
||||
to_chat(user, "<span class='notice'>You don't see anything that can be pried with [I]!</span>")
|
||||
|
||||
/obj/structure/mecha_wreckage/welder_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
|
||||
@@ -122,6 +122,10 @@
|
||||
if(!in_range(user, src) || !isturf(user.loc) || user.incapacitated() || M.anchored)
|
||||
return FALSE
|
||||
|
||||
if (isguardian(user))
|
||||
if (M.loc == user.loc || user.alpha == 60) //Alpha is for detecting ranged guardians in scout mode
|
||||
return //unmanifested guardians shouldn't be able to buckle mobs
|
||||
|
||||
add_fingerprint(user)
|
||||
. = buckle_mob(M, check_loc = check_loc)
|
||||
if(.)
|
||||
|
||||
@@ -53,6 +53,9 @@
|
||||
/obj/effect/decal/cleanable/proc/can_bloodcrawl_in()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/is_cleanable()
|
||||
return TRUE
|
||||
|
||||
/obj/effect/decal/cleanable/Initialize(mapload)
|
||||
. = ..()
|
||||
if(loc && isturf(loc))
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
/obj/effect/acid_act()
|
||||
return
|
||||
|
||||
/obj/effect/proc/is_cleanable() //Called when you want to clean something, and usualy delete it after
|
||||
return FALSE
|
||||
|
||||
/obj/effect/mech_melee_attack(obj/mecha/M)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
var/precision = TRUE // how close to the portal you will teleport. FALSE = on the portal, TRUE = adjacent
|
||||
var/can_multitool_to_remove = FALSE
|
||||
var/ignore_tele_proof_area_setting = FALSE
|
||||
var/one_use = FALSE // Does this portal go away after one teleport?
|
||||
|
||||
/obj/effect/portal/New(loc, turf/target, creator = null, lifespan = 300)
|
||||
..()
|
||||
@@ -101,14 +102,17 @@
|
||||
|
||||
if(prob(failchance))
|
||||
icon_state = fail_icon
|
||||
if(!do_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), 3), 0, bypass_area_flag = ignore_tele_proof_area_setting)) // Try to send them to deep space.
|
||||
var/list/target_z = levels_by_trait(SPAWN_RUINS)
|
||||
target_z -= M.z
|
||||
if(!do_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), pick(target_z)), 0, bypass_area_flag = ignore_tele_proof_area_setting)) // Try to send them to deep space.
|
||||
invalid_teleport()
|
||||
return FALSE
|
||||
else
|
||||
if(!do_teleport(M, target, precision, bypass_area_flag = ignore_tele_proof_area_setting)) // Try to send them to a turf adjacent to target.
|
||||
invalid_teleport()
|
||||
return FALSE
|
||||
|
||||
if(one_use)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/portal/proc/invalid_teleport()
|
||||
|
||||
@@ -354,3 +354,12 @@
|
||||
/obj/effect/temp_visual/impact_effect/ion
|
||||
icon_state = "shieldsparkles"
|
||||
duration = 6
|
||||
|
||||
/obj/effect/temp_visual/bsg_kaboom
|
||||
name = "bluespace explosion"
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "explosionfast"
|
||||
color = "blue"
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
duration = 42
|
||||
|
||||
@@ -424,6 +424,17 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect
|
||||
/obj/item/proc/on_enter_storage(obj/item/storage/S as obj)
|
||||
return
|
||||
|
||||
/**
|
||||
* Called to check if this item can be put into a storage item.
|
||||
*
|
||||
* Return `FALSE` if `src` can't be inserted, and `TRUE` if it can.
|
||||
* Arguments:
|
||||
* * S - The [/obj/item/storage] that `src` is being inserted into.
|
||||
* * user - The mob trying to insert the item.
|
||||
*/
|
||||
/obj/item/proc/can_enter_storage(obj/item/storage/S, mob/user)
|
||||
return TRUE
|
||||
|
||||
// called when "found" in pockets and storage items. Returns 1 if the search should end.
|
||||
/obj/item/proc/on_found(mob/finder as mob)
|
||||
return
|
||||
|
||||
@@ -30,6 +30,12 @@
|
||||
else i = 3
|
||||
icon_state = "candle[i][lit ? "_lit" : ""]"
|
||||
|
||||
/obj/item/candle/can_enter_storage(obj/item/storage/S, mob/user)
|
||||
if(lit)
|
||||
to_chat(user, "<span class='warning'>[S] can't hold [src] while it's lit!</span>")
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/obj/item/candle/attackby(obj/item/W, mob/user, params)
|
||||
if(is_hot(W))
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/obj/item/changestone
|
||||
name = "An uncut ruby"
|
||||
desc = "The ruby shines and catches the light, despite being uncut"
|
||||
icon = 'icons/obj/artifacts.dmi'
|
||||
icon_state = "changerock"
|
||||
|
||||
/obj/item/changestone/attack_hand(mob/user as mob)
|
||||
if(istype(user,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H.gloves)
|
||||
if(H.gender == FEMALE)
|
||||
H.change_gender(MALE)
|
||||
else
|
||||
H.change_gender(FEMALE)
|
||||
H.dna.ready_dna(H)
|
||||
H.update_body()
|
||||
..()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
/obj/item/radio/beacon/bacon/proc/digest_delay()
|
||||
QDEL_IN(src, 600)
|
||||
|
||||
/obj/item/radio/beacon/emagged
|
||||
syndicate = TRUE
|
||||
emagged = TRUE
|
||||
|
||||
// SINGULO BEACON SPAWNER
|
||||
/obj/item/radio/beacon/syndicate
|
||||
name = "suspicious beacon"
|
||||
@@ -71,6 +75,18 @@
|
||||
user.drop_item()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/radio/beacon/syndicate/power_sink
|
||||
name = "suspicious beacon"
|
||||
desc = "A label on it reads: <i>Warning: Activating this device will send a power sink to your location</i>."
|
||||
|
||||
/obj/item/radio/beacon/syndicate/power_sink/attack_self(mob/user)
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>Locked In</span>")
|
||||
new /obj/item/powersink(user.loc)
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, TRUE, 1)
|
||||
user.drop_item()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/radio/beacon/syndicate/bomb
|
||||
name = "suspicious beacon"
|
||||
desc = "A label on it reads: <i>Warning: Activating this device will send a high-ordinance explosive to your location</i>."
|
||||
|
||||
@@ -273,20 +273,20 @@ effective or pretty fucking useless.
|
||||
/obj/item/teleporter/proc/dir_correction(mob/user) //Direction movement, screws with teleport distance and saving throw, and thus must be removed first
|
||||
var/temp_direction = user.dir
|
||||
switch(temp_direction)
|
||||
if(NORTHEAST || SOUTHEAST)
|
||||
if(NORTHEAST, SOUTHEAST)
|
||||
user.dir = EAST
|
||||
if(NORTHWEST || SOUTHWEST)
|
||||
if(NORTHWEST, SOUTHWEST)
|
||||
user.dir = WEST
|
||||
|
||||
/obj/item/teleporter/proc/panic_teleport(mob/user, turf/destination, direction = NORTH)
|
||||
var/saving_throw
|
||||
switch(direction)
|
||||
if(NORTH || SOUTH)
|
||||
if(NORTH, SOUTH)
|
||||
if(prob(50))
|
||||
saving_throw = EAST
|
||||
else
|
||||
saving_throw = WEST
|
||||
if(EAST || WEST)
|
||||
if(EAST, WEST)
|
||||
if(prob(50))
|
||||
saving_throw = NORTH
|
||||
else
|
||||
|
||||
@@ -28,5 +28,5 @@
|
||||
return TRUE
|
||||
|
||||
/obj/item/mounted/frame/apc_frame/do_build(turf/on_wall, mob/user)
|
||||
new /obj/machinery/power/apc(get_turf(src), get_dir(user, on_wall), 1)
|
||||
new /obj/machinery/power/apc(get_turf(src), get_dir(user, on_wall), TRUE)
|
||||
qdel(src)
|
||||
|
||||
@@ -226,7 +226,7 @@
|
||||
to_chat(user, "<span class='warning'>Sticking an empty [M] into the frame would sort of defeat the purpose.</span>")
|
||||
return
|
||||
|
||||
if(jobban_isbanned(M.brainmob, "Cyborg") || jobban_isbanned(M.brainmob,"nonhumandept"))
|
||||
if(jobban_isbanned(M.brainmob, "Cyborg") || jobban_isbanned(M.brainmob, "nonhumandept"))
|
||||
to_chat(user, "<span class='warning'>This [W] is not fit to serve as a cyborg!</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
if(replacement_type in special_rechargables)
|
||||
R.module.special_rechargables += replacement
|
||||
|
||||
R.module.rebuild_modules()
|
||||
R.module?.rebuild_modules()
|
||||
return TRUE
|
||||
|
||||
/obj/item/borg/upgrade/reset
|
||||
|
||||
@@ -19,7 +19,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
|
||||
new/datum/stack_recipe/window("fulltile window", /obj/structure/window/full/basic, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe("fishbowl", /obj/machinery/fishtank/bowl, 1, time = 10), \
|
||||
new/datum/stack_recipe("fish tank", /obj/machinery/fishtank/tank, 3, time = 20, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("wall aquariam", /obj/machinery/fishtank/wall, 4, time = 40, on_floor = TRUE) \
|
||||
new/datum/stack_recipe("wall aquarium", /obj/machinery/fishtank/wall, 4, time = 40, on_floor = TRUE) \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/glass
|
||||
|
||||
@@ -83,7 +83,6 @@ GLOBAL_LIST_INIT(bananium_recipes, list ( \
|
||||
null, \
|
||||
new/datum/stack_recipe("Clown Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("bananium computer frame", /obj/structure/computerframe/HONKputer, 50, time = 25, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("bananium grenade casing", /obj/item/grenade/bananade/casing, 4, on_floor = 1), \
|
||||
))
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
slot_flags = SLOT_BELT
|
||||
force = 5
|
||||
throwforce = 7
|
||||
item_state = "crowbar"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
materials = list(MAT_METAL=50)
|
||||
drop_sound = 'sound/items/handling/crowbar_drop.ogg'
|
||||
|
||||
@@ -83,6 +83,9 @@
|
||||
if(chunk)
|
||||
if(chunk.seenby.len)
|
||||
for(var/mob/camera/aiEye/A in chunk.seenby)
|
||||
//Checks if the A is to be detected or not
|
||||
if(!A.ai_detector_visible)
|
||||
continue
|
||||
var/turf/detect_turf = get_turf(A)
|
||||
if(get_dist(our_turf, detect_turf) < rangealert)
|
||||
detect_state = PROXIMITY_ON_SCREEN
|
||||
|
||||
@@ -57,4 +57,8 @@
|
||||
|
||||
// Used in a callback that is passed by use_tool into do_after call. Do not override, do not call manually.
|
||||
/obj/item/proc/tool_check_callback(mob/living/user, atom/target, amount, datum/callback/extra_checks)
|
||||
return tool_use_check(user, amount) && (extra_checks && !extra_checks.Invoke())
|
||||
if(!tool_use_check(user, amount))
|
||||
return TRUE
|
||||
if(extra_checks && !extra_checks.Invoke())
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user