Merge remote-tracking branch 'ParadiseSS13/master' into toml-config

This commit is contained in:
AffectedArc07
2021-07-09 11:42:23 +01:00
210 changed files with 1803 additions and 2434 deletions
+32 -6
View File
@@ -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
-1
View File
@@ -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"
-2
View File
@@ -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))
+5
View File
@@ -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
+3 -2
View File
@@ -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
))
+8
View File
@@ -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
+2 -2
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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))
+7 -5
View File
@@ -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))))
+2 -1
View File
@@ -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())
+1 -1
View File
@@ -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",
+5
View File
@@ -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)
-38
View File
@@ -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 "&nbsp;&nbsp;&nbsp;&nbsp;"
GLOBAL_VAR_INIT(timezoneOffset, 0) // The difference betwen midnight (of the host computer) and 0 world.ticks.
+1
View File
@@ -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,
-8
View File
@@ -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
View File
@@ -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.
+1 -1
View File
@@ -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)
+8 -2
View File
@@ -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
+16
View File
@@ -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)]")
+110 -57
View File
@@ -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
+1 -1
View File
@@ -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)
+5 -1
View File
@@ -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
View File
@@ -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)
+1
View File
@@ -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)
+3 -3
View File
@@ -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."
+1 -1
View File
@@ -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
+7
View File
@@ -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)
+4
View File
@@ -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
+1
View File
@@ -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
+77 -12
View File
@@ -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()
+27 -27
View File
@@ -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
+2 -1
View File
@@ -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
View File
@@ -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
+2
View File
@@ -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
+1
View File
@@ -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
+1 -1
View File
@@ -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()
+6 -2
View File
@@ -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,
+6
View File
@@ -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
+1 -1
View File
@@ -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
+28 -24
View File
@@ -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
+27 -26
View File
@@ -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
View File
@@ -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>")
+1 -1
View File
@@ -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]"
+2 -2
View File
@@ -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"
+1 -1
View File
@@ -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
+38 -105
View File
@@ -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()
+1 -123
View File
@@ -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
-118
View File
@@ -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
+4
View File
@@ -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"
+2
View File
@@ -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 ..()
+6 -1
View File
@@ -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>")
+1 -1
View File
@@ -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.
+6 -3
View File
@@ -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)
+1 -1
View File
@@ -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)
+32 -24
View File
@@ -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
+3 -2
View File
@@ -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)
+1 -1
View File
@@ -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
+4
View File
@@ -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))
+3
View File
@@ -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
+6 -2
View File
@@ -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
+11
View File
@@ -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
+6
View File
@@ -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))
-23
View File
@@ -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)
+1 -1
View File
@@ -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), \
))
-1
View File
@@ -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