mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-20 03:25:49 +01:00
Merge remote-tracking branch 'upstream/master' into departmental-clothing-vendors
This commit is contained in:
@@ -122,7 +122,6 @@ GLOBAL_VAR_INIT(nologevent, 0)
|
||||
|
||||
if(M.ckey)
|
||||
body += "<A href='?_src_=holder;boot2=[M.UID()]'>Kick</A> | "
|
||||
body += "<A href='?_src_=holder;warn=[M.ckey]'>Warn</A> | "
|
||||
body += "<A href='?_src_=holder;newban=[M.UID()];dbbanaddckey=[M.ckey]'>Ban</A> | "
|
||||
body += "<A href='?_src_=holder;jobban2=[M.UID()];dbbanaddckey=[M.ckey]'>Jobban</A> | "
|
||||
body += "<A href='?_src_=holder;appearanceban=[M.UID()];dbbanaddckey=[M.ckey]'>Appearance Ban</A> | "
|
||||
@@ -141,14 +140,13 @@ GLOBAL_VAR_INIT(nologevent, 0)
|
||||
body += "\ <A href='?_src_=holder;sendbacktolobby=[M.UID()]'>Send back to Lobby</A> | "
|
||||
body += "\ <A href='?_src_=holder;eraseflavortext=[M.UID()]'>Erase Flavor Text</A> | "
|
||||
body += "\ <A href='?_src_=holder;userandomname=[M.UID()]'>Use Random Name</A> | "
|
||||
var/muted = M.client.prefs.muted
|
||||
body += {"<br><b>Mute: </b>
|
||||
\[<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_IC]'><font color='[(muted & MUTE_IC)?"red":"#6685f5"]'>IC</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_OOC]'><font color='[(muted & MUTE_OOC)?"red":"#6685f5"]'>OOC</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_PRAY]'><font color='[(muted & MUTE_PRAY)?"red":"#6685f5"]'>PRAY</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_ADMINHELP]'><font color='[(muted & MUTE_ADMINHELP)?"red":"#6685f5"]'>ADMINHELP</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_DEADCHAT]'><font color='[(muted & MUTE_DEADCHAT)?"red":"#6685f5"]'>DEADCHAT</font></a>\]
|
||||
(<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_ALL]'><font color='[(muted & MUTE_ALL)?"red":"#6685f5"]'>toggle all</font></a>)
|
||||
\[<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_IC]'><font color='[check_mute(M.client.ckey, MUTE_IC) ? "red" : "#6685f5"]'>IC</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_OOC]'><font color='[check_mute(M.client.ckey, MUTE_OOC) ? "red" : "#6685f5"]'>OOC</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_PRAY]'><font color='[check_mute(M.client.ckey, MUTE_PRAY) ? "red" : "#6685f5"]'>PRAY</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_ADMINHELP]'><font color='[check_mute(M.client.ckey, MUTE_ADMINHELP) ? "red" : "#6685f5"]'>ADMINHELP</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_DEADCHAT]'><font color='[check_mute(M.client.ckey, MUTE_DEADCHAT) ?" red" : "#6685f5"]'>DEADCHAT</font></a>]
|
||||
(<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_ALL]'><font color='[check_mute(M.client.ckey, MUTE_ALL) ? "red" : "#6685f5"]'>toggle all</font></a>)
|
||||
"}
|
||||
|
||||
var/jumptoeye = ""
|
||||
|
||||
@@ -492,51 +492,6 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list(
|
||||
log_admin("[key_name(usr)] has turned BB mode [holder.fakekey ? "ON" : "OFF"]")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Big Brother Mode")
|
||||
|
||||
#define MAX_WARNS 3
|
||||
#define AUTOBANTIME 10
|
||||
|
||||
/client/proc/warn(warned_ckey)
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
if(!warned_ckey || !istext(warned_ckey)) return
|
||||
if(warned_ckey in GLOB.admin_datums)
|
||||
to_chat(usr, "<font color='red'>Error: warn(): You can't warn admins.</font>")
|
||||
return
|
||||
|
||||
var/datum/preferences/D
|
||||
var/client/C = GLOB.directory[warned_ckey]
|
||||
if(C) D = C.prefs
|
||||
else D = GLOB.preferences_datums[warned_ckey]
|
||||
|
||||
if(!D)
|
||||
to_chat(src, "<font color='red'>Error: warn(): No such ckey found.</font>")
|
||||
return
|
||||
|
||||
if(++D.warns >= MAX_WARNS) //uh ohhhh...you'reee iiiiin trouuuubble O:)
|
||||
if(C)
|
||||
message_admins("[key_name_admin(src)] has warned [key_name_admin(C)] resulting in a [AUTOBANTIME] minute ban")
|
||||
log_admin("[key_name(src)] has warned [key_name(C)] resulting in a [AUTOBANTIME] minute ban")
|
||||
to_chat(C, "<font color='red'><BIG><B>You have been autobanned due to a warning by [ckey].</B></BIG><br>This is a temporary ban, it will be removed in [AUTOBANTIME] minutes.")
|
||||
qdel(C)
|
||||
else
|
||||
message_admins("[key_name_admin(src)] has warned [warned_ckey] resulting in a [AUTOBANTIME] minute ban")
|
||||
log_admin("[key_name(src)] has warned [warned_ckey] resulting in a [AUTOBANTIME] minute ban")
|
||||
AddBan(warned_ckey, D.last_id, "Autobanning due to too many formal warnings", ckey, 1, AUTOBANTIME)
|
||||
else
|
||||
if(C)
|
||||
to_chat(C, "<font color='red'><BIG><B>You have been formally warned by an administrator.</B></BIG><br>Further warnings will result in an autoban.</font>")
|
||||
message_admins("[key_name_admin(src)] has warned [key_name_admin(C)]. They have [MAX_WARNS-D.warns] strikes remaining.")
|
||||
log_admin("[key_name(src)] has warned [key_name(C)]. They have [MAX_WARNS-D.warns] strikes remaining.")
|
||||
else
|
||||
message_admins("[key_name_admin(src)] has warned [warned_ckey] (DC). They have [MAX_WARNS-D.warns] strikes remaining.")
|
||||
log_admin("[key_name(src)] has warned [warned_ckey] (DC). They have [MAX_WARNS-D.warns] strikes remaining.")
|
||||
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Warning") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
#undef MAX_WARNS
|
||||
#undef AUTOBANTIME
|
||||
|
||||
/client/proc/drop_bomb() // Some admin dickery that can probably be done better -- TLE
|
||||
set category = "Event"
|
||||
set name = "Drop Bomb"
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/// Associative list of people who are muted via admin mutes
|
||||
GLOBAL_LIST_EMPTY(admin_mutes_assoc)
|
||||
|
||||
/proc/check_mute(ckey, muteflag)
|
||||
if(isnull(GLOB.admin_mutes_assoc[ckey]))
|
||||
return FALSE
|
||||
|
||||
if(GLOB.admin_mutes_assoc[ckey] & muteflag)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/proc/toggle_mute(ckey, muteflag)
|
||||
if(isnull(GLOB.admin_mutes_assoc[ckey]))
|
||||
GLOB.admin_mutes_assoc[ckey] = 0
|
||||
|
||||
if(GLOB.admin_mutes_assoc[ckey] & muteflag)
|
||||
GLOB.admin_mutes_assoc[ckey] &= ~muteflag
|
||||
else
|
||||
GLOB.admin_mutes_assoc[ckey] |= muteflag
|
||||
|
||||
/proc/force_add_mute(ckey, muteflag)
|
||||
if(isnull(GLOB.admin_mutes_assoc[ckey]))
|
||||
GLOB.admin_mutes_assoc[ckey] = 0
|
||||
|
||||
GLOB.admin_mutes_assoc[ckey] |= muteflag
|
||||
|
||||
/proc/force_remove_mute(ckey, muteflag)
|
||||
if(isnull(GLOB.admin_mutes_assoc[ckey]))
|
||||
GLOB.admin_mutes_assoc[ckey] = 0
|
||||
|
||||
GLOB.admin_mutes_assoc[ckey] &= ~muteflag
|
||||
|
||||
@@ -446,9 +446,6 @@
|
||||
alert(usr, "This ban has already been lifted / does not exist.", "Error", "Ok")
|
||||
unbanpanel()
|
||||
|
||||
else if(href_list["warn"])
|
||||
usr.client.warn(href_list["warn"])
|
||||
|
||||
else if(href_list["unbane"])
|
||||
if(!check_rights(R_BAN)) return
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ GLOBAL_LIST_INIT(adminhelp_ignored_words, list("unknown", "the", "a", "an", "of"
|
||||
set name = "Adminhelp"
|
||||
|
||||
//handle muting and automuting
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
if(check_mute(ckey, MUTE_ADMINHELP))
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: You cannot send adminhelps (Muted).</font>")
|
||||
return
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
//takes input from cmd_admin_pm_context, cmd_admin_pm_panel or /client/Topic and sends them a PM.
|
||||
//Fetching a message if needed. src is the sender and C is the target client
|
||||
/client/proc/cmd_admin_pm(whom, msg, type = "PM")
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
if(check_mute(ckey, MUTE_ADMINHELP))
|
||||
to_chat(src, "<span class='danger'>Error: Private-Message: You are unable to use PM-s (muted).</span>")
|
||||
return
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
return
|
||||
|
||||
/client/proc/cmd_admin_discord_pm()
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
if(check_mute(ckey, MUTE_ADMINHELP))
|
||||
to_chat(src, "<span class='danger'>Error: Private-Message: You are unable to use PMs (muted).</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
|
||||
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
|
||||
log_mentorsay(msg, src)
|
||||
mob.create_log(OOC_LOG, "MSAY: [msg]")
|
||||
|
||||
if(!msg)
|
||||
return
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
if(!src.mob)
|
||||
return
|
||||
|
||||
if(prefs.muted & MUTE_DEADCHAT)
|
||||
if(check_mute(ckey, MUTE_DEADCHAT))
|
||||
to_chat(src, "<span class='warning'>You cannot send DSAY messages (muted).</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#define NUKE_INTACT 0
|
||||
#define NUKE_CORE_MISSING 1
|
||||
#define NUKE_MISSING 2
|
||||
|
||||
/mob/living/verb/pray(msg as text)
|
||||
set category = "IC"
|
||||
set name = "Pray"
|
||||
@@ -7,7 +11,7 @@
|
||||
return
|
||||
|
||||
if(usr.client)
|
||||
if(usr.client.prefs.muted & MUTE_PRAY)
|
||||
if(check_mute(client.ckey, MUTE_PRAY))
|
||||
to_chat(usr, "<span class='warning'>You cannot pray (muted).</span>")
|
||||
return
|
||||
if(client.handle_spam_prevention(msg, MUTE_PRAY, OOC_COOLDOWN))
|
||||
@@ -72,11 +76,21 @@
|
||||
|
||||
/proc/Nuke_request(text , mob/Sender)
|
||||
var/nuke_code = get_nuke_code()
|
||||
var/nuke_status = get_nuke_status()
|
||||
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
|
||||
msg = "<span class='adminnotice'><b><font color=orange>NUKE CODE REQUEST: </font>[key_name(Sender)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_CENTCOM_REPLY(Sender,"RPLY")]):</b> [msg]</span>"
|
||||
for(var/client/X in GLOB.admins)
|
||||
if(check_rights(R_EVENT,0,X.mob))
|
||||
to_chat(X, msg)
|
||||
to_chat(X, "<span class='adminnotice'><b>The nuke code is [nuke_code].</b></span>")
|
||||
if(nuke_status == NUKE_MISSING)
|
||||
to_chat(X, "<span class='userdanger'>The nuclear device is not on station!</span>")
|
||||
else
|
||||
to_chat(X, "<b>The nuke code is [nuke_code].</b>")
|
||||
if(nuke_status == NUKE_CORE_MISSING)
|
||||
to_chat(X, "<span class='userdanger'>The nuclear device does not have a core, and will not arm!</span>")
|
||||
if(X.prefs.sound & SOUND_ADMINHELP)
|
||||
SEND_SOUND(X, sound('sound/effects/adminhelp.ogg'))
|
||||
|
||||
#undef NUKE_INTACT
|
||||
#undef NUKE_CORE_MISSING
|
||||
#undef NUKE_MISSING
|
||||
|
||||
@@ -230,19 +230,19 @@
|
||||
|
||||
if(automute)
|
||||
muteunmute = "auto-muted"
|
||||
M.client.prefs.muted |= mute_type
|
||||
force_add_mute(M.client.ckey, mute_type)
|
||||
log_admin("SPAM AUTOMUTE: [muteunmute] [key_name(M)] from [mute_string]")
|
||||
message_admins("SPAM AUTOMUTE: [muteunmute] [key_name_admin(M)] from [mute_string].", 1)
|
||||
to_chat(M, "You have been [muteunmute] from [mute_string] by the SPAM AUTOMUTE system. Contact an admin.")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Automute") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
|
||||
if(M.client.prefs.muted & mute_type)
|
||||
muteunmute = "unmuted"
|
||||
M.client.prefs.muted &= ~mute_type
|
||||
else
|
||||
toggle_mute(M.client.ckey, mute_type)
|
||||
|
||||
if(check_mute(M.client.ckey, mute_type))
|
||||
muteunmute = "muted"
|
||||
M.client.prefs.muted |= mute_type
|
||||
else
|
||||
muteunmute = "unmuted"
|
||||
|
||||
log_admin("[key_name(usr)] has [muteunmute] [key_name(M)] from [mute_string]")
|
||||
message_admins("[key_name_admin(usr)] has [muteunmute] [key_name_admin(M)] from [mute_string].", 1)
|
||||
@@ -606,7 +606,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
"Custom" = "Cryptic Message")
|
||||
|
||||
var/list/MsgSound = list("Beep" = 'sound/misc/notice2.ogg',
|
||||
"Enemy Communications Intercepted" = 'sound/AI/intercept2.ogg',
|
||||
"Enemy Communications Intercepted" = 'sound/AI/intercept.ogg',
|
||||
"New Command Report Created" = 'sound/AI/commandreport.ogg')
|
||||
|
||||
var/type = input(usr, "Pick a type of report to send", "Report Type", "") as anything in MsgType
|
||||
|
||||
@@ -25,9 +25,6 @@
|
||||
H.dna.SetSEState(GLOB.hulkblock, TRUE)
|
||||
singlemutcheck(H, GLOB.hulkblock, MUTCHK_FORCED)
|
||||
|
||||
H.dna.SetSEState(GLOB.xrayblock, TRUE)
|
||||
singlemutcheck(H, GLOB.xrayblock, MUTCHK_FORCED)
|
||||
|
||||
H.dna.SetSEState(GLOB.fireblock, TRUE)
|
||||
singlemutcheck(H, GLOB.fireblock, MUTCHK_FORCED)
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/obj/effect/nanomob
|
||||
name = "Nano-Mob Avatar" //will be overridden by the mob datum name value when created
|
||||
desc = "A wild Nano-Mob appeared! Hit it with your PDA with the game open to attempt to capture it!"
|
||||
@@ -12,17 +11,29 @@
|
||||
var/list/clients_encountered = list() //tracks who has already interacted with us, so they can't attempt a second capture
|
||||
var/image/avatar
|
||||
|
||||
/obj/effect/nanomob/New(loc, datum/mob_hunt/new_info)
|
||||
..()
|
||||
/obj/effect/nanomob/Initialize(mapload, datum/mob_hunt/new_info)
|
||||
. = ..()
|
||||
if(!new_info)
|
||||
qdel(src)
|
||||
return
|
||||
return INITIALIZE_HINT_QDEL
|
||||
mob_info = new_info
|
||||
RegisterSignal(mob_info, COMSIG_PARENT_QDELETING, .proc/delete_wrapper)
|
||||
update_self()
|
||||
forceMove(mob_info.spawn_point)
|
||||
if(!mob_info.is_trap)
|
||||
addtimer(CALLBACK(src, .proc/despawn), mob_info.lifetime)
|
||||
|
||||
/obj/effect/nanomob/Destroy()
|
||||
SSmob_hunt.trap_spawns -= src
|
||||
SSmob_hunt.normal_spawns -= src
|
||||
mob_info = null // Can't delete this since multiple players can get the exact same /datum/mob_hunt. (This should be refactored)
|
||||
clients_encountered.Cut()
|
||||
QDEL_NULL(avatar)
|
||||
return ..()
|
||||
|
||||
/obj/effect/nanomob/proc/delete_wrapper()
|
||||
SIGNAL_HANDLER
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/nanomob/proc/update_self()
|
||||
if(!mob_info)
|
||||
return
|
||||
@@ -132,12 +143,6 @@
|
||||
icon_state = "placeholder"
|
||||
var/obj/machinery/computer/mob_battle_terminal/my_terminal
|
||||
|
||||
/obj/effect/nanomob/battle/New(loc, datum/mob_hunt/new_info)
|
||||
. = ..()
|
||||
if(new_info)
|
||||
mob_info = new_info
|
||||
update_self()
|
||||
|
||||
/obj/effect/nanomob/battle/update_self()
|
||||
if(!mob_info)
|
||||
name = "Nano-Mob Battle Avatar"
|
||||
|
||||
@@ -215,7 +215,7 @@
|
||||
var/life_cycles = 0
|
||||
var/life_cap = 20
|
||||
anchored = TRUE
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE | PASSFENCE
|
||||
|
||||
|
||||
/obj/effect/beam/i_beam/proc/hit()
|
||||
|
||||
@@ -71,10 +71,13 @@ Pipelines + Other Objects -> Pipe network
|
||||
// Icons/overlays/underlays
|
||||
/obj/machinery/atmospherics/update_icon()
|
||||
var/turf/T = get_turf(loc)
|
||||
if(!T || level == 2 || !T.intact)
|
||||
plane = GAME_PLANE
|
||||
else
|
||||
if(T && T.transparent_floor)
|
||||
plane = FLOOR_PLANE
|
||||
else
|
||||
if(!T || level == 2 || !T.intact)
|
||||
plane = GAME_PLANE
|
||||
else
|
||||
plane = FLOOR_PLANE
|
||||
|
||||
/obj/machinery/atmospherics/proc/update_pipe_image()
|
||||
pipe_image = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) //the 20 puts it above Byond's darkness (not its opacity view)
|
||||
@@ -95,15 +98,18 @@ Pipelines + Other Objects -> Pipe network
|
||||
|
||||
/obj/machinery/atmospherics/proc/add_underlay(turf/T, obj/machinery/atmospherics/node, direction, icon_connect_type)
|
||||
if(node)
|
||||
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe) && !T.transparent_floor)
|
||||
//underlays += SSair.icon_manager.get_atmos_icon("underlay_down", direction, color_cache_name(node))
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
|
||||
else
|
||||
//underlays += SSair.icon_manager.get_atmos_icon("underlay_intact", direction, color_cache_name(node))
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
|
||||
else
|
||||
//underlays += SSair.icon_manager.get_atmos_icon("underlay_exposed", direction, pipe_color)
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "exposed" + icon_connect_type)
|
||||
if(T.transparent_floor) //we want to keep pipes under transparent floors connected normally
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
|
||||
else
|
||||
//underlays += SSair.icon_manager.get_atmos_icon("underlay_exposed", direction, pipe_color)
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "exposed" + icon_connect_type)
|
||||
|
||||
/obj/machinery/atmospherics/proc/update_underlays()
|
||||
if(check_icon_cache())
|
||||
@@ -166,11 +172,14 @@ Pipelines + Other Objects -> Pipe network
|
||||
|
||||
//(De)construction
|
||||
/obj/machinery/atmospherics/attackby(obj/item/W, mob/user)
|
||||
var/turf/T = get_turf(src)
|
||||
if(can_unwrench && istype(W, /obj/item/wrench))
|
||||
var/turf/T = get_turf(src)
|
||||
if(T.transparent_floor && istype(src, /obj/machinery/atmospherics/pipe) && layer != GAS_PIPE_VISIBLE_LAYER) //pipes on GAS_PIPE_VISIBLE_LAYER are above the transparent floor and should be interactable
|
||||
to_chat(user, "<span class='danger'>You can't interact with something that's under the floor!</span>")
|
||||
return
|
||||
if(level == 1 && isturf(T) && T.intact)
|
||||
to_chat(user, "<span class='danger'>You must remove the plating first.</span>")
|
||||
return 1
|
||||
return
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
add_fingerprint(user)
|
||||
@@ -184,14 +193,14 @@ Pipelines + Other Objects -> Pipe network
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if(internal_pressure > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, "<span class='warning'>As you begin unwrenching \the [src] a gush of air blows in your face... maybe you should reconsider?</span>")
|
||||
to_chat(user, "<span class='warning'>As you begin unwrenching \the [src] a gust of air blows in your face... maybe you should reconsider?</span>")
|
||||
unsafe_wrenching = TRUE //Oh dear oh dear
|
||||
|
||||
if(do_after(user, 40 * W.toolspeed, target = src) && !QDELETED(src))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"<span class='italics'>You hear ratchet.</span>")
|
||||
"<span class='italics'>You hear ratcheting.</span>")
|
||||
investigate_log("was <span class='warning'>REMOVED</span> by [key_name(usr)]", "atmos")
|
||||
|
||||
for(var/obj/item/clothing/shoes/magboots/usermagboots in user.get_equipped_items())
|
||||
@@ -206,6 +215,9 @@ Pipelines + Other Objects -> Pipe network
|
||||
unsafe_pressure_release(user,internal_pressure)
|
||||
deconstruct(TRUE)
|
||||
else
|
||||
if(T.transparent_floor)
|
||||
to_chat(user, "<span class='danger'>You can't interact with something that's under the floor!</span>")
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
//Called when an atmospherics object is unwrenched while having a large pressure difference
|
||||
@@ -240,7 +252,12 @@ Pipelines + Other Objects -> Pipe network
|
||||
dir = D
|
||||
initialize_directions = P
|
||||
var/turf/T = loc
|
||||
level = T.intact ? 2 : 1
|
||||
if(!T.transparent_floor)
|
||||
level = T.intact ? 2 : 1
|
||||
else
|
||||
level = 2
|
||||
plane = GAME_PLANE
|
||||
layer = GAS_PIPE_VISIBLE_LAYER
|
||||
add_fingerprint(usr)
|
||||
if(!SSair.initialized) //If there's no atmos subsystem, we can't really initialize pipenets
|
||||
SSair.machinery_to_construct.Add(src)
|
||||
@@ -337,12 +354,15 @@ Pipelines + Other Objects -> Pipe network
|
||||
|
||||
/obj/machinery/atmospherics/proc/add_underlay_adapter(turf/T, obj/machinery/atmospherics/node, direction, icon_connect_type) //modified from add_underlay, does not make exposed underlays
|
||||
if(node)
|
||||
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe) && !T.transparent_floor)
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
|
||||
else
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
|
||||
else
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type)
|
||||
if(T.transparent_floor) //we want to keep pipes under transparent floors connected normally
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
|
||||
else
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type)
|
||||
|
||||
/obj/machinery/atmospherics/singularity_pull(S, current_size)
|
||||
if(current_size >= STAGE_FIVE)
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
if(!istype(L) || L.buckled)
|
||||
return
|
||||
if(L.abiotic())
|
||||
to_chat(user, "<span class='danger'>Subject cannot have abiotic items on.</span>")
|
||||
to_chat(user, "<span class='danger'>Subject may not hold anything in their hands.</span>")
|
||||
return
|
||||
if(L.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(user, "<span class='warning'>[L] will not fit into [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.</span>")
|
||||
@@ -462,7 +462,7 @@
|
||||
to_chat(usr, "<span class='danger'>The cryo cell is already occupied!</span>")
|
||||
return
|
||||
if(M.abiotic())
|
||||
to_chat(usr, "<span class='warning'>Subject may not have abiotic items on.</span>")
|
||||
to_chat(usr, "<span class='warning'>Subject may not hold anything in their hands.</span>")
|
||||
return
|
||||
if(!node)
|
||||
to_chat(usr, "<span class='warning'>The cell is not correctly connected to its pipe network!</span>")
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
icon = 'icons/atmos/vent_pump.dmi'
|
||||
icon_state = "map_vent"
|
||||
plane = FLOOR_PLANE
|
||||
layer = GAS_SCRUBBER_LAYER
|
||||
name = "passive vent"
|
||||
desc = "A large air vent"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/machinery/atmospherics/unary/tank
|
||||
icon = 'icons/atmos/tank.dmi'
|
||||
icon_state = "air_map"
|
||||
|
||||
layer = GAS_PIPE_VISIBLE_LAYER
|
||||
name = "pressure tank"
|
||||
desc = "A large vessel containing pressurized gas."
|
||||
|
||||
|
||||
@@ -159,9 +159,9 @@
|
||||
var/cache_name = state
|
||||
|
||||
for(var/D in GLOB.cardinal)
|
||||
var/image/I = image(icon('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D))
|
||||
var/image/I = image(icon('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D), layer = GAS_PIPE_HIDDEN_LAYER)
|
||||
underlays[cache_name + "[D]"] = I
|
||||
for(var/pipe_color in GLOB.pipe_colors)
|
||||
I = image(icon('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D))
|
||||
I = image(icon('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D), layer = GAS_PIPE_HIDDEN_LAYER)
|
||||
I.color = GLOB.pipe_colors[pipe_color]
|
||||
underlays[state + "[D]" + "[GLOB.pipe_colors[pipe_color]]"] = I
|
||||
|
||||
@@ -79,7 +79,8 @@
|
||||
break
|
||||
|
||||
var/turf/T = get_turf(src) // hide if turf is not intact
|
||||
if(!istype(T)) return
|
||||
if(!istype(T) || T.transparent_floor)
|
||||
return
|
||||
hide(T.intact)
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
node3 = target
|
||||
break
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(T.transparent_floor)
|
||||
return
|
||||
hide(T.intact)
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -165,7 +165,8 @@
|
||||
break
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
hide(T.intact)
|
||||
if(!T.transparent_floor)
|
||||
hide(T.intact)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/visible
|
||||
|
||||
@@ -46,10 +46,6 @@
|
||||
if(istype(W, /obj/item/analyzer))
|
||||
atmosanalyzer_scan(parent.air, user)
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/painter))
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/proc/pipeline_expansion()
|
||||
|
||||
@@ -68,7 +68,8 @@
|
||||
break
|
||||
|
||||
var/turf/T = loc // hide if turf is not intact
|
||||
hide(T.intact)
|
||||
if(!T.transparent_floor)
|
||||
hide(T.intact)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/check_pressure(pressure)
|
||||
|
||||
@@ -79,8 +79,6 @@
|
||||
ADD_TRAIT(user, TRAIT_LASEREYES, "ww_wishgranter")
|
||||
user.dna.SetSEState(GLOB.fireblock, TRUE)
|
||||
singlemutcheck(user, GLOB.fireblock, MUTCHK_FORCED)
|
||||
user.dna.SetSEState(GLOB.xrayblock, TRUE)
|
||||
singlemutcheck(user, GLOB.xrayblock, MUTCHK_FORCED)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/human = user
|
||||
if(!isshadowperson(human))
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#define UPLOAD_LIMIT 10485760 //Restricts client uploads to the server to 10MB //Boosted this thing. What's the worst that can happen?
|
||||
#define MIN_CLIENT_VERSION 513 // Minimum byond major version required to play.
|
||||
//I would just like the code ready should it ever need to be used.
|
||||
#define SUGGESTED_CLIENT_VERSION 513 // only integers (e.g: 513, 514) are useful here. This is the part BEFORE the ".", IE 513 out of 513.1542
|
||||
#define SUGGESTED_CLIENT_BUILD 1542 // only integers (e.g: 1542, 1543) are useful here. This is the part AFTER the ".", IE 1542 out of 513.1542
|
||||
#define SUGGESTED_CLIENT_VERSION 514 // only integers (e.g: 513, 514) are useful here. This is the part BEFORE the ".", IE 513 out of 513.1542
|
||||
#define SUGGESTED_CLIENT_BUILD 1566 // only integers (e.g: 1542, 1543) are useful here. This is the part AFTER the ".", IE 1542 out of 513.1542
|
||||
|
||||
#define SSD_WARNING_TIMER 30 // cycles, not seconds, so 30=60s
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
if(!holder && received_discord_pm < world.time - 6000) // Worse they can do is spam discord for 10 minutes
|
||||
to_chat(usr, "<span class='warning'>You are no longer able to use this, it's been more then 10 minutes since an admin on Discord has responded to you</span>")
|
||||
return
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
if(check_mute(ckey, MUTE_ADMINHELP))
|
||||
to_chat(usr, "<span class='warning'>You cannot use this as your client has been muted from sending messages to the admins on Discord</span>")
|
||||
return
|
||||
cmd_admin_discord_pm()
|
||||
|
||||
@@ -71,8 +71,6 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
var/max_gear_slots = 0
|
||||
|
||||
//non-preference stuff
|
||||
var/warns = 0
|
||||
var/muted = 0
|
||||
var/last_ip
|
||||
var/last_id
|
||||
|
||||
|
||||
@@ -356,3 +356,11 @@
|
||||
prefs.toggles2 ^= PREFTOGGLE_2_SIMPLE_STAT_PANEL
|
||||
prefs.save_preferences(src)
|
||||
to_chat(src, "You will [(prefs.toggles2 & PREFTOGGLE_2_SIMPLE_STAT_PANEL) ? "no longer" : "now"] get detailed information on the status panel.")
|
||||
|
||||
/client/verb/toggle_item_outlines()
|
||||
set name = "Toggle Item Outlines"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles seeing item outlines on hover."
|
||||
prefs.toggles2 ^= PREFTOGGLE_2_SEE_ITEM_OUTLINES
|
||||
prefs.save_preferences(src)
|
||||
to_chat(usr, "You will [(prefs.toggles2 & PREFTOGGLE_2_SEE_ITEM_OUTLINES) ? "now" : "no longer"] see item outlines on hover.")
|
||||
|
||||
@@ -5,6 +5,13 @@
|
||||
|
||||
/datum/event/anomaly/proc/findEventArea()
|
||||
var/static/list/allowed_areas
|
||||
var/static/list/existing_areas
|
||||
if(!existing_areas)
|
||||
existing_areas = list()
|
||||
for(var/area/AR in world)
|
||||
var/turf/picked = safepick(get_area_turfs(AR.type))
|
||||
if(picked && is_station_level(picked.z))
|
||||
existing_areas += AR
|
||||
if(!allowed_areas)
|
||||
//Places that shouldn't explode
|
||||
var/list/safe_area_types = typecacheof(list(
|
||||
@@ -20,10 +27,16 @@
|
||||
)
|
||||
|
||||
//Subtypes from the above that actually should explode.
|
||||
var/list/unsafe_area_subtypes = typecacheof(list(/area/engine/break_room))
|
||||
var/list/unsafe_area_subtypes = typecacheof(list(
|
||||
/area/engine/break_room,
|
||||
/area/engine/equipmentstorage,
|
||||
/area/engine/chiefs_office,
|
||||
/area/engine/controlroom,
|
||||
/area/engine/mechanic_workshop
|
||||
))
|
||||
|
||||
allowed_areas = make_associative(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
|
||||
var/list/possible_areas = typecache_filter_list(GLOB.all_areas, allowed_areas)
|
||||
allowed_areas = typecacheof(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
|
||||
var/list/possible_areas = typecache_filter_list(existing_areas, allowed_areas)
|
||||
if(length(possible_areas))
|
||||
return pick(possible_areas)
|
||||
|
||||
@@ -36,7 +49,7 @@
|
||||
CRASH("Anomaly: No valid turfs found for [impact_area] - [impact_area.type]")
|
||||
|
||||
/datum/event/anomaly/announce()
|
||||
GLOB.event_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert")
|
||||
GLOB.event_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert", 'sound/AI/anomaly_flux.ogg')
|
||||
|
||||
/datum/event/anomaly/start()
|
||||
var/turf/T = pick(get_area_turfs(impact_area))
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
anomaly_path = /obj/effect/anomaly/bluespace
|
||||
|
||||
/datum/event/anomaly/anomaly_bluespace/announce()
|
||||
GLOB.event_announcement.Announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
GLOB.event_announcement.Announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert", 'sound/AI/anomaly_bluespace.ogg')
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
anomaly_path = /obj/effect/anomaly/flux
|
||||
|
||||
/datum/event/anomaly/anomaly_flux/announce()
|
||||
GLOB.event_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
GLOB.event_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert", 'sound/AI/anomaly_flux.ogg')
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
anomaly_path = /obj/effect/anomaly/grav
|
||||
|
||||
/datum/event/anomaly/anomaly_grav/announce()
|
||||
GLOB.event_announcement.Announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
GLOB.event_announcement.Announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert", 'sound/AI/anomaly_gravity.ogg')
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
anomaly_path = /obj/effect/anomaly/pyro
|
||||
|
||||
/datum/event/anomaly/anomaly_pyro/announce()
|
||||
GLOB.event_announcement.Announce("Atmospheric anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
GLOB.event_announcement.Announce("Atmospheric anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert", 'sound/AI/anomaly_pyro.ogg')
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
anomaly_path = /obj/effect/anomaly/bhole
|
||||
|
||||
/datum/event/anomaly/anomaly_vortex/announce()
|
||||
GLOB.event_announcement.Announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert")
|
||||
GLOB.event_announcement.Announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert", 'sound/AI/anomaly_vortex.ogg')
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
SEND_SOUND(M, S)
|
||||
|
||||
/datum/event/apc_overload/announce()
|
||||
GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", new_sound = 'sound/AI/attention.ogg')
|
||||
GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", 'sound/AI/power_overload.ogg')
|
||||
|
||||
/datum/event/apc_overload/end()
|
||||
return TRUE
|
||||
@@ -33,7 +33,7 @@
|
||||
/area/turret_protected/ai)
|
||||
|
||||
if(announce)
|
||||
GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", new_sound = 'sound/AI/attention.ogg')
|
||||
GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", 'sound/AI/power_overload.ogg')
|
||||
|
||||
// break APC_BREAK_PROBABILITY% of all of the APCs on the station
|
||||
var/affected_apc_count = 0
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
SEND_SOUND(M, S)
|
||||
|
||||
/datum/event/apc_short/announce()
|
||||
GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", new_sound = 'sound/AI/attention.ogg')
|
||||
GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", 'sound/AI/power_overload.ogg')
|
||||
|
||||
/datum/event/apc_short/end()
|
||||
return TRUE
|
||||
@@ -30,7 +30,7 @@
|
||||
/area/engine/engineering,
|
||||
/area/engine/supermatter,
|
||||
/area/turret_protected/ai)
|
||||
GLOB.event_announcement.Announce("Power failure detected in [station_name()]'s powernet. All APCs have lost power. Gravity systems likely to fail.", "Systems Power Failure", new_sound = 'sound/AI/attention.ogg')
|
||||
GLOB.event_announcement.Announce("Power failure detected in [station_name()]'s powernet. All APCs have lost power. Gravity systems likely to fail.", "Systems Power Failure", 'sound/AI/attention.ogg')
|
||||
for(var/thing in GLOB.apcs)
|
||||
var/obj/machinery/power/apc/A = thing
|
||||
var/area/current_area = get_area(A)
|
||||
@@ -49,7 +49,7 @@
|
||||
/area/engine/supermatter,
|
||||
/area/turret_protected/ai)
|
||||
if(announce)
|
||||
GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", new_sound = 'sound/AI/attention.ogg')
|
||||
GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", 'sound/AI/power_overload.ogg')
|
||||
// break APC_BREAK_PROBABILITY% of all of the APCs on the station
|
||||
var/affected_apc_count = 0
|
||||
for(var/thing in GLOB.apcs)
|
||||
@@ -76,7 +76,7 @@
|
||||
/proc/power_restore(announce = TRUE, power_type)
|
||||
if(power_type == 0) //Power without Repairing
|
||||
if(announce)
|
||||
GLOB.event_announcement.Announce("All operational APCs on \the [station_name()] have been fully charged.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
|
||||
GLOB.event_announcement.Announce("All operational APCs on \the [station_name()] have been fully charged.", "Power Systems Nominal", 'sound/AI/power_restore.ogg')
|
||||
var/affected_apc_count = 0
|
||||
for(var/thing in GLOB.apcs)
|
||||
var/obj/machinery/power/apc/A = thing
|
||||
@@ -90,7 +90,7 @@
|
||||
log_and_message_admins("Power has been restored to [affected_apc_count] APCs.")
|
||||
if(power_type == 1) //Repair without charging
|
||||
if(announce)
|
||||
GLOB.event_announcement.Announce("All APCs on \the [station_name()] have been repaired.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
|
||||
GLOB.event_announcement.Announce("All APCs on \the [station_name()] have been repaired.", "Power Systems Nominal", 'sound/AI/power_restore.ogg')
|
||||
for(var/thing in GLOB.apcs)
|
||||
var/obj/machinery/power/apc/A = thing
|
||||
var/area/current_area = get_area(A)
|
||||
@@ -101,7 +101,7 @@
|
||||
log_and_message_admins("Power has been restored to all APCs.")
|
||||
if(power_type == 2) //Repair and Power APCs
|
||||
if(announce)
|
||||
GLOB.event_announcement.Announce("All APCs on \the [station_name()] have been repaired and recharged. We apologize for the inconvenience.", "Power Systems Optimal", new_sound = 'sound/AI/poweron.ogg')
|
||||
GLOB.event_announcement.Announce("All APCs on \the [station_name()] have been repaired and recharged. We apologize for the inconvenience.", "Power Systems Optimal", 'sound/AI/power_restore.ogg')
|
||||
// repair the APCs and recharge them
|
||||
for(var/thing in GLOB.apcs)
|
||||
var/obj/machinery/power/apc/A = thing
|
||||
@@ -115,7 +115,7 @@
|
||||
|
||||
/proc/power_restore_quick(announce = TRUE)
|
||||
if(announce)
|
||||
GLOB.event_announcement.Announce("All SMESs on \the [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
|
||||
GLOB.event_announcement.Announce("All SMESs on \the [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/AI/power_restore.ogg')
|
||||
// fix all of the SMESs
|
||||
for(var/obj/machinery/power/smes/S in GLOB.machines)
|
||||
if(!is_station_level(S.z))
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"You don't want to buy anything? Yeah, well I didn't want to buy your mom either.")
|
||||
|
||||
/datum/event/brand_intelligence/announce()
|
||||
GLOB.event_announcement.Announce("Rampant brand intelligence has been detected aboard [station_name()], please stand-by. The origin is believed to be \a [originMachine.name].", "Machine Learning Alert")
|
||||
GLOB.event_announcement.Announce("Rampant brand intelligence has been detected aboard [station_name()], please stand-by. The origin is believed to be \a [originMachine.name].", "Machine Learning Alert", 'sound/AI/brand_intelligence.ogg')
|
||||
|
||||
/datum/event/brand_intelligence/start()
|
||||
for(var/obj/machinery/vending/V in GLOB.machines)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
D.carrier = TRUE
|
||||
|
||||
/datum/event/disease_outbreak/announce()
|
||||
GLOB.event_announcement.Announce("Confirmed outbreak of level 7 major viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
|
||||
GLOB.event_announcement.Announce("Confirmed outbreak of level 7 major viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak7.ogg')
|
||||
for(var/p in GLOB.dead_mob_list)
|
||||
var/mob/M = p
|
||||
to_chat(M, "<span class='deadsay'><b>[patient_zero]</b> has been infected with <b>[D.name]</b> ([ghost_follow_link(patient_zero, M)])</span>")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/event/door_runtime
|
||||
|
||||
/datum/event/door_runtime/announce()
|
||||
GLOB.minor_announcement.Announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.", "Network Alert")
|
||||
GLOB.minor_announcement.Announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.", "Network Alert", 'sound/AI/door_runtimes.ogg')
|
||||
|
||||
/datum/event/door_runtime/start()
|
||||
for(var/obj/machinery/door/D in GLOB.airlocks)
|
||||
@@ -13,4 +13,4 @@
|
||||
post_status("alert", "lockdown")
|
||||
|
||||
/datum/event/door_runtime/proc/reboot()
|
||||
GLOB.minor_announcement.Announce("Automatic system reboot complete. Have a secure day.","Network reset:")
|
||||
GLOB.minor_announcement.Announce("Automatic system reboot complete. Have a secure day.","Network reset:", 'sound/AI/door_runtimes_fix.ogg')
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
var/lightsoutRange = 25
|
||||
|
||||
/datum/event/electrical_storm/announce()
|
||||
GLOB.event_announcement.Announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert")
|
||||
GLOB.event_announcement.Announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert", 'sound/AI/elec_storm.ogg')
|
||||
|
||||
/datum/event/electrical_storm/start()
|
||||
var/list/epicentreList = list()
|
||||
@@ -26,4 +26,3 @@
|
||||
var/obj/effect/landmark/epicentre = thing
|
||||
for(var/obj/machinery/power/apc/apc in range(epicentre, lightsoutRange))
|
||||
INVOKE_ASYNC(apc, /obj/machinery/power/apc.proc/overload_lighting)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
/datum/event/ion_storm/announce()
|
||||
if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(ionAnnounceChance)))
|
||||
GLOB.event_announcement.Announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", 'sound/AI/ionstorm.ogg')
|
||||
GLOB.event_announcement.Announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", 'sound/AI/ions.ogg')
|
||||
|
||||
/datum/event/ion_storm/start()
|
||||
//AI laws
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
|
||||
|
||||
/datum/event/carp_migration/koi/start()
|
||||
spawn_fish(GLOB.landmarks_list.len)
|
||||
spawn_fish(rand(4, 6)) //12 to 30 koi, in small groups
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
announceWhen = 1
|
||||
|
||||
/datum/event/solar_flare/announce()
|
||||
GLOB.event_announcement.Announce("A solar flare has been detected on collision course with the station.", "Incoming Solar Flare", 'sound/AI/attention.ogg')
|
||||
GLOB.event_announcement.Announce("A solar flare has been detected on collision course with the station.", "Incoming Solar Flare", 'sound/AI/flare.ogg')
|
||||
|
||||
/datum/event/solar_flare/start()
|
||||
SSweather.run_weather(/datum/weather/solar_flare)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/datum/event/spider_terror/announce()
|
||||
if(successSpawn)
|
||||
GLOB.command_announcement.Announce("Confirmed outbreak of level 3 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/effects/siren-spooky.ogg')
|
||||
GLOB.command_announcement.Announce("Confirmed outbreak of level 3 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/effects/siren-spooky.ogg', new_sound2 = 'sound/AI/outbreak3.ogg')
|
||||
else
|
||||
log_and_message_admins("Warning: Could not spawn any mobs for event Terror Spiders")
|
||||
|
||||
@@ -61,4 +61,3 @@
|
||||
successSpawn = TRUE
|
||||
|
||||
#undef TS_HIGHPOP_TRIGGER
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
var/obj/effect/tear/TE
|
||||
|
||||
/datum/event/tear/announce()
|
||||
GLOB.event_announcement.Announce("A tear in the fabric of space and time has opened. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
GLOB.event_announcement.Announce("A tear in the fabric of space and time has opened. Expected location: [impact_area.name].", "Anomaly Alert", 'sound/AI/anomaly.ogg')
|
||||
|
||||
/datum/event/tear/start()
|
||||
var/turf/T = pick(get_area_turfs(impact_area))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
var/list/vents = list()
|
||||
|
||||
/datum/event/vent_clog/announce()
|
||||
GLOB.event_announcement.Announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert")
|
||||
GLOB.event_announcement.Announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert", 'sound/AI/scrubbers.ogg')
|
||||
|
||||
/datum/event/vent_clog/setup()
|
||||
endWhen = rand(25, 100)
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
/obj/item/reagent_containers/food/snacks/grilledcheese
|
||||
name = "grilled cheese sandwich"
|
||||
desc = "Goes great with tomato soup!"
|
||||
icon_state = "toastedsandwich"
|
||||
icon_state = "grilledcheese"
|
||||
filling_color = "#D9BE29"
|
||||
list_reagents = list("nutriment" = 7, "vitamin" = 1) //why make a regualr sandwhich when you can make grilled cheese, with this nutriment value?
|
||||
tastes = list("toast" = 1, "grilled cheese" = 1)
|
||||
|
||||
@@ -139,8 +139,8 @@
|
||||
to_chat(user, "<span class='danger'>This is not suitable for [src]!</span>")
|
||||
return
|
||||
|
||||
if(victim.abiotic(1))
|
||||
to_chat(user, "<span class='danger'>Subject may not have abiotic items on.</span>")
|
||||
if(victim.abiotic(TRUE))
|
||||
to_chat(user, "<span class='danger'>Subject may not have anything on their body.</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='danger'>[user] starts to put [victim] into [src]!</span>")
|
||||
|
||||
@@ -277,6 +277,13 @@
|
||||
if(can_insert && istype(disk.gene, /datum/plant_gene/trait))
|
||||
dat += "<a href='?src=[UID()];op=insert'>Insert: [disk.gene.get_name()]</a>"
|
||||
dat += "</div>"
|
||||
|
||||
dat += "<div class='line'><h3>Variant</h3></div><div class='statusDisplay'><table>"
|
||||
dat += "<tr><td width='260px'>[seed.variant ? seed.variant : "None"]</td>"
|
||||
dat += "<td><a href='?src=[UID()];set_v=1'>Edit</a></td>"
|
||||
if(seed.variant)
|
||||
dat += "<td><a href='?src=[UID()];del_v=1'>Remove</a></td>"
|
||||
dat += "</tr></table></div>"
|
||||
else
|
||||
dat += "<br>No sample found.<br><span class='highlight'>Please, insert a plant sample to use this device.</span>"
|
||||
popup.set_content(dat)
|
||||
@@ -391,6 +398,16 @@
|
||||
else if(href_list["abort"])
|
||||
operation = ""
|
||||
target = null
|
||||
else if(href_list["set_v"])
|
||||
if(!seed)
|
||||
return
|
||||
seed.variant_prompt(usr, src)
|
||||
else if(href_list["del_v"])
|
||||
if(!seed)
|
||||
return
|
||||
seed.variant = null
|
||||
seed.apply_variant_name()
|
||||
to_chat(usr, "<span class='notice'>You remove the [seed.plantname]'s variant designation.</span>")
|
||||
|
||||
interact(usr)
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
seed.prepare_result(src)
|
||||
transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 //Makes the resulting produce's sprite larger or smaller based on potency!
|
||||
add_juice()
|
||||
if(seed.variant)
|
||||
name += " \[[seed.variant]]"
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/Destroy()
|
||||
QDEL_NULL(seed)
|
||||
|
||||
@@ -344,7 +344,10 @@
|
||||
/obj/machinery/hydroponics/examine(user)
|
||||
. = ..()
|
||||
if(myseed)
|
||||
. += "<span class='info'>It has <span class='name'>[myseed.plantname]</span> planted.</span>"
|
||||
if(myseed.variant)
|
||||
. += "<span class='info'>It has the <span class='name'>[myseed.variant]</span> variant of <span class='name'>[myseed.plantname]</span> planted.</span>"
|
||||
else
|
||||
. += "<span class='info'>It has <span class='name'>[myseed.plantname]</span> planted.</span>"
|
||||
if (dead)
|
||||
. += "<span class='warning'>It's dead!</span>"
|
||||
else if (harvest)
|
||||
@@ -875,7 +878,8 @@
|
||||
plant_hud_set_status()
|
||||
adjustWeeds(-10) //Has a side effect of cleaning up those nasty weeds
|
||||
update_icon()
|
||||
|
||||
else if(istype(O, /obj/item/pen) && myseed)
|
||||
myseed.variant_prompt(user, src)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -109,6 +109,7 @@
|
||||
|
||||
/datum/seed_pile
|
||||
var/name = ""
|
||||
var/variant = ""
|
||||
var/lifespan = 0 //Saved stats
|
||||
var/endurance = 0
|
||||
var/maturation = 0
|
||||
@@ -117,8 +118,9 @@
|
||||
var/potency = 0
|
||||
var/amount = 0
|
||||
|
||||
/datum/seed_pile/New(name, life, endur, matur, prod, yie, poten, am = 1)
|
||||
/datum/seed_pile/New(name, variant, life, endur, matur, prod, yie, poten, am = 1)
|
||||
src.name = name
|
||||
src.variant = variant
|
||||
src.lifespan = life
|
||||
src.endurance = endur
|
||||
src.maturation = matur
|
||||
@@ -145,9 +147,9 @@
|
||||
if (contents.len == 0)
|
||||
dat += "<font color='red'>No seeds</font>"
|
||||
else
|
||||
dat += "<table cellpadding='3' style='text-align:center;'><tr><td>Name</td><td>Lifespan</td><td>Endurance</td><td>Maturation</td><td>Production</td><td>Yield</td><td>Potency</td><td>Stock</td></tr>"
|
||||
dat += "<table cellpadding='3' style='text-align:center;'><tr><td>Name</td><td>Variant</td><td>Lifespan</td><td>Endurance</td><td>Maturation</td><td>Production</td><td>Yield</td><td>Potency</td><td>Stock</td></tr>"
|
||||
for (var/datum/seed_pile/O in piles)
|
||||
dat += "<tr><td>[O.name]</td><td>[O.lifespan]</td><td>[O.endurance]</td><td>[O.maturation]</td>"
|
||||
dat += "<tr><td>[O.name]</td><td>[O.variant]</td><td>[O.lifespan]</td><td>[O.endurance]</td><td>[O.maturation]</td>"
|
||||
dat += "<td>[O.production]</td><td>[O.yield]</td><td>[O.potency]</td><td>"
|
||||
dat += "<a href='byond://?src=[src.UID()];name=[O.name];li=[O.lifespan];en=[O.endurance];ma=[O.maturation];pr=[O.production];yi=[O.yield];pot=[O.potency]'>Vend</a> ([O.amount] left)</td></tr>"
|
||||
dat += "</table>"
|
||||
@@ -203,9 +205,9 @@
|
||||
O.forceMove(src)
|
||||
. = 1
|
||||
for (var/datum/seed_pile/N in piles)
|
||||
if (O.plantname == N.name && O.lifespan == N.lifespan && O.endurance == N.endurance && O.maturation == N.maturation && O.production == N.production && O.yield == N.yield && O.potency == N.potency)
|
||||
if (O.plantname == N.name && O.variant == N.variant && O.lifespan == N.lifespan && O.endurance == N.endurance && O.maturation == N.maturation && O.production == N.production && O.yield == N.yield && O.potency == N.potency)
|
||||
++N.amount
|
||||
return
|
||||
|
||||
piles += new /datum/seed_pile(O.plantname, O.lifespan, O.endurance, O.maturation, O.production, O.yield, O.potency)
|
||||
piles += new /datum/seed_pile(O.plantname, O.variant, O.lifespan, O.endurance, O.maturation, O.production, O.yield, O.potency)
|
||||
return
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
var/plantname = "Plants" // Name of plant when planted.
|
||||
var/product // A type path. The thing that is created when the plant is harvested.
|
||||
var/species = "" // Used to update icons. Should match the name in the sprites unless all icon_* are overriden.
|
||||
var/variant = null // Optional custom name to track modified plants. Can be set with pen or from gene modder.
|
||||
|
||||
var/growing_icon = 'icons/obj/hydroponics/growing.dmi' //the file that stores the sprites of the growing plant from this seed.
|
||||
var/icon_grow // Used to override grow icon (default is "[species]-grow"). You can use one grow icon for multiple closely related plants with it.
|
||||
@@ -83,6 +84,8 @@
|
||||
S.potency = potency
|
||||
S.weed_rate = weed_rate
|
||||
S.weed_chance = weed_chance
|
||||
S.variant = variant
|
||||
S.apply_variant_name()
|
||||
S.genes = list()
|
||||
for(var/g in genes)
|
||||
var/datum/plant_gene/G = g
|
||||
@@ -317,16 +320,43 @@
|
||||
return
|
||||
|
||||
/obj/item/seeds/attackby(obj/item/O, mob/user, params)
|
||||
if (istype(O, /obj/item/plant_analyzer))
|
||||
if(istype(O, /obj/item/plant_analyzer))
|
||||
to_chat(user, "<span class='info'>*---------*\n This is \a <span class='name'>[src]</span>.</span>")
|
||||
var/text = get_analyzer_text()
|
||||
if(text)
|
||||
to_chat(user, "<span class='notice'>[text]</span>")
|
||||
|
||||
return
|
||||
if(istype(O, /obj/item/pen))
|
||||
variant_prompt(user)
|
||||
return
|
||||
..() // Fallthrough to item/attackby() so that bags can pick seeds up
|
||||
|
||||
|
||||
/obj/item/seeds/proc/variant_prompt(mob/user, obj/item/container = null)
|
||||
var/prev = variant
|
||||
var/V = input(user, "Choose variant name:", "Plant Variant Naming", variant) as text|null
|
||||
if(isnull(V)) // Did the user cancel?
|
||||
return
|
||||
if(container && (loc != container)) // Was the seed removed from the container, if there is a container?
|
||||
return
|
||||
if(!(container ? container : src).Adjacent(user)) // Is the user next to the seed/container?
|
||||
return
|
||||
variant = copytext(sanitize(html_encode(trim(V))), 1, 64) // Sanitization must happen after null check because it converts nulls to empty strings
|
||||
if(variant == "")
|
||||
variant = null
|
||||
if(prev != variant)
|
||||
to_chat(user, "<span class='notice'>You [variant ? "change" : "remove"] the [plantname]'s variant designation.</span>")
|
||||
apply_variant_name()
|
||||
|
||||
/obj/item/seeds/proc/apply_variant_name()
|
||||
var/V = variant ? " \[[variant]]" : "" // If we have a non-empty variant add it to the name
|
||||
var/N = initial(name)
|
||||
if(copytext(name, 1, 13) == "experimental") // Don't delete 'experimental'
|
||||
N = "experimental " + N
|
||||
name = N + V
|
||||
if(GetComponent(/datum/component/label))
|
||||
GetComponent(/datum/component/label).apply_label() // Don't delete labels
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
do { \
|
||||
var/timer = start_watch(); \
|
||||
proc2run ;\
|
||||
log_debug("\[MAZE] Operation '[opname]' on maze at [##x],[##y],[##z] took [stop_watch(timer)]s"); \
|
||||
log_debug("\[MAZE] Operation '[opname]' on maze at [x],[y],[z] took [stop_watch(timer)]s"); \
|
||||
} while (FALSE)
|
||||
|
||||
|
||||
|
||||
@@ -104,21 +104,7 @@
|
||||
new /obj/item/toy/katana(src)
|
||||
if(85 to 86)
|
||||
new /obj/item/defibrillator/compact(src)
|
||||
if(87) //1% chance
|
||||
new /obj/item/weed_extract(src)
|
||||
if(88)
|
||||
new /obj/item/organ/internal/brain(src)
|
||||
if(89)
|
||||
new /obj/item/organ/internal/brain/xeno(src)
|
||||
if(90)
|
||||
new /obj/item/organ/internal/heart(src)
|
||||
if(91)
|
||||
new /obj/item/soulstone/anybody(src)
|
||||
if(92)
|
||||
new /obj/item/katana(src)
|
||||
if(93)
|
||||
new /obj/item/dnainjector/xraymut(src)
|
||||
if(94)
|
||||
if(87 to 88)
|
||||
new /obj/item/storage/backpack/clown(src)
|
||||
new /obj/item/clothing/under/rank/clown(src)
|
||||
new /obj/item/clothing/shoes/clown_shoes(src)
|
||||
@@ -128,6 +114,18 @@
|
||||
new /obj/item/toy/crayon/rainbow(src)
|
||||
new /obj/item/reagent_containers/spray/waterflower(src)
|
||||
new /obj/item/reagent_containers/food/drinks/bottle/bottleofbanana(src)
|
||||
if(89) //1% chance
|
||||
new /obj/item/weed_extract(src)
|
||||
if(90)
|
||||
new /obj/item/organ/internal/brain(src)
|
||||
if(91)
|
||||
new /obj/item/organ/internal/brain/xeno(src)
|
||||
if(92)
|
||||
new /obj/item/organ/internal/heart(src)
|
||||
if(93)
|
||||
new /obj/item/soulstone/anybody(src)
|
||||
if(94)
|
||||
new /obj/item/katana(src)
|
||||
if(95)
|
||||
new /obj/item/clothing/under/mime(src)
|
||||
new /obj/item/clothing/shoes/black(src)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
log_ghostemote(message, src)
|
||||
|
||||
if(src.client)
|
||||
if(src.client.prefs.muted & MUTE_DEADCHAT)
|
||||
if(check_mute(client.ckey, MUTE_DEADCHAT))
|
||||
to_chat(src, "<span class='warning'>You cannot emote in deadchat (muted).</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
O.show_message(message, m_type)
|
||||
|
||||
/mob/proc/emote_dead(message)
|
||||
if(client.prefs.muted & MUTE_DEADCHAT)
|
||||
if(check_mute(client.ckey, MUTE_DEADCHAT))
|
||||
to_chat(src, "<span class='warning'>You cannot send deadchat emotes (muted).</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
if(silent)
|
||||
return
|
||||
if(src.client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
if(check_mute(client.ckey, MUTE_IC))
|
||||
to_chat(src, "<span class='warning'>You cannot send IC messages (muted).</span>")
|
||||
return
|
||||
if(src.client.handle_spam_prevention(message,MUTE_IC))
|
||||
if(src.client.handle_spam_prevention(message, MUTE_IC))
|
||||
return
|
||||
if(stat)
|
||||
return
|
||||
|
||||
@@ -1203,6 +1203,14 @@ so that different stomachs can handle things in different ways VB*/
|
||||
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
|
||||
see_in_dark = max(see_in_dark, 8)
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_MESON_VISION))
|
||||
sight |= SEE_TURFS
|
||||
lighting_alpha = min(lighting_alpha, LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE)
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_NIGHT_VISION))
|
||||
see_in_dark = max(see_in_dark, 8)
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
|
||||
sync_lighting_plane_alpha()
|
||||
|
||||
|
||||
@@ -446,15 +446,14 @@
|
||||
SpinAnimation(5,1)
|
||||
|
||||
if("spin", "spins")
|
||||
if(!restrained() && !lying)
|
||||
if(!incapacitated(ignore_lying = TRUE))
|
||||
if(prob(5))
|
||||
spin(30, 1)
|
||||
message = "<B>[src]</B> spins too much!"
|
||||
spin(32, 1)
|
||||
to_chat(src, "<span class='warning'>You spin too much!</span>")
|
||||
Dizzy(12)
|
||||
Confused(12)
|
||||
else
|
||||
spin(20, 1)
|
||||
message = "<B>[src]</B> spins!"
|
||||
|
||||
if("aflap", "aflaps")
|
||||
if(!restrained())
|
||||
|
||||
@@ -39,7 +39,7 @@ emp_act
|
||||
if(mind?.martial_art?.deflection_chance) //Some martial arts users can deflect projectiles!
|
||||
if(!lying && !HAS_TRAIT(src, TRAIT_HULK) && mind.martial_art.try_deflect(src)) //But only if they're not lying down, and hulks can't do it
|
||||
add_attack_logs(P.firer, src, "hit by [P.type] but got deflected by martial arts '[mind.martial_art]'")
|
||||
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
|
||||
visible_message("<span class='danger'>[src] deflects the projectile!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
|
||||
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, TRUE)
|
||||
if(mind.martial_art.reroute_deflection)
|
||||
P.firer = src
|
||||
|
||||
@@ -894,13 +894,21 @@ It'll return null if the organ doesn't correspond, so include null checks when u
|
||||
if(!isnull(H.vision_type.lighting_alpha))
|
||||
H.lighting_alpha = min(H.vision_type.lighting_alpha, H.lighting_alpha)
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_THERMAL_VISION))
|
||||
if(HAS_TRAIT(H, TRAIT_MESON_VISION))
|
||||
H.sight |= SEE_TURFS
|
||||
H.lighting_alpha = min(H.lighting_alpha, LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE)
|
||||
|
||||
if(HAS_TRAIT(H, TRAIT_THERMAL_VISION))
|
||||
H.sight |= (SEE_MOBS)
|
||||
H.lighting_alpha = min(H.lighting_alpha, LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE)
|
||||
|
||||
if(HAS_TRAIT(H, TRAIT_XRAY_VISION))
|
||||
H.sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
|
||||
|
||||
if(HAS_TRAIT(H, TRAIT_NIGHT_VISION))
|
||||
H.see_in_dark = max(H.see_in_dark, 8)
|
||||
H.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
|
||||
if(H.has_status_effect(STATUS_EFFECT_SUMMONEDGHOST))
|
||||
H.see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
death_message = "gives a short series of shrill beeps, their chassis shuddering before falling limp, nonfunctional."
|
||||
death_sounds = list('sound/voice/borg_deathsound.ogg') //I've made this a list in the event we add more sounds for dead robots.
|
||||
|
||||
species_traits = list(IS_WHITELISTED, NO_BLOOD, NO_CLONESCAN, NO_INTORGANS, NOTRANSSTING)
|
||||
species_traits = list(IS_WHITELISTED, NO_BLOOD, NO_CLONESCAN, NO_INTORGANS)
|
||||
inherent_traits = list(TRAIT_VIRUSIMMUNE, TRAIT_NOBREATH, TRAIT_RADIMMUNE, TRAIT_NOGERMS, TRAIT_NODECAY, TRAIT_NOPAIN, TRAIT_GENELESS) //Computers that don't decay? What a lie!
|
||||
inherent_biotypes = MOB_ROBOTIC | MOB_HUMANOID
|
||||
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
dangerous_existence = TRUE //So so much
|
||||
//language = "Clatter"
|
||||
|
||||
species_traits = list(IS_WHITELISTED, NO_BLOOD, NOTRANSSTING, NO_HAIR)
|
||||
species_traits = list(IS_WHITELISTED, NO_BLOOD, NO_HAIR)
|
||||
inherent_traits = list(TRAIT_RADIMMUNE, TRAIT_NOHUNGER)
|
||||
inherent_biotypes = MOB_HUMANOID | MOB_MINERAL
|
||||
forced_heartattack = TRUE // Plasmamen have no blood, but they should still get heart-attacks
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
eyes = "vox_eyes_s"
|
||||
|
||||
species_traits = list(NO_CLONESCAN, IS_WHITELISTED, NOTRANSSTING)
|
||||
species_traits = list(NO_CLONESCAN, IS_WHITELISTED)
|
||||
inherent_traits = list(TRAIT_NOGERMS, TRAIT_NODECAY)
|
||||
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS //Species-fitted 'em all.
|
||||
dietflags = DIET_OMNI
|
||||
|
||||
@@ -760,7 +760,7 @@
|
||||
|
||||
//called when the mob receives a bright flash
|
||||
/mob/living/proc/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
|
||||
if(check_eye_prot() < intensity && (override_blindness_check || !HAS_TRAIT(src, TRAIT_BLIND)))
|
||||
if(check_eye_prot() < intensity && (override_blindness_check || !HAS_TRAIT(src, TRAIT_BLIND)) && !HAS_TRAIT(src, TRAIT_FLASH_PROTECTION))
|
||||
overlay_fullscreen("flash", type)
|
||||
addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
|
||||
return 1
|
||||
|
||||
@@ -110,7 +110,7 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
|
||||
|
||||
/mob/living/say(message, verb = "says", sanitize = TRUE, ignore_speech_problems = FALSE, ignore_atmospherics = FALSE, ignore_languages = FALSE)
|
||||
if(client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
if(check_mute(client.ckey, MUTE_IC))
|
||||
to_chat(src, "<span class='danger'>You cannot speak in IC (Muted).</span>")
|
||||
return
|
||||
|
||||
@@ -297,7 +297,7 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
|
||||
|
||||
/mob/living/emote(act, type, message, force) //emote code is terrible, this is so that anything that isn't already snowflaked to shit can call the parent and handle emoting sanely
|
||||
if(client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
if(check_mute(client.ckey, MUTE_IC))
|
||||
to_chat(src, "<span class='danger'>You cannot speak in IC (Muted).</span>")
|
||||
return
|
||||
|
||||
@@ -352,7 +352,7 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
|
||||
|
||||
/mob/living/proc/whisper_say(list/message_pieces, verb = "whispers")
|
||||
if(client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
if(check_mute(client.ckey, MUTE_IC))
|
||||
to_chat(src, "<span class='danger'>You cannot speak in IC (Muted).</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -212,6 +212,20 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
GLOB.shuttle_caller_list += src
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/Destroy()
|
||||
GLOB.ai_list -= src
|
||||
GLOB.shuttle_caller_list -= src
|
||||
SSshuttle.autoEvac()
|
||||
if(malfhacking)
|
||||
deltimer(malfhacking)
|
||||
malfhacking = null
|
||||
QDEL_NULL(eyeobj) // No AI, no Eye
|
||||
QDEL_NULL(aiPDA)
|
||||
QDEL_NULL(aiMulti)
|
||||
QDEL_NULL(aiRadio)
|
||||
QDEL_NULL(builtInCamera)
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/ai/proc/on_mob_init()
|
||||
to_chat(src, "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>")
|
||||
to_chat(src, "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>")
|
||||
@@ -314,17 +328,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/ai/Destroy()
|
||||
GLOB.ai_list -= src
|
||||
GLOB.shuttle_caller_list -= src
|
||||
SSshuttle.autoEvac()
|
||||
QDEL_NULL(eyeobj) // No AI, no Eye
|
||||
if(malfhacking)
|
||||
deltimer(malfhacking)
|
||||
malfhacking = null
|
||||
malfhack = null
|
||||
return ..()
|
||||
|
||||
|
||||
/*
|
||||
The AI Power supply is a dummy object used for powering the AI since only machinery should be using power.
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_STRANDED)
|
||||
SSshuttle.emergency.mode = SHUTTLE_DOCKED
|
||||
SSshuttle.emergency.timer = world.time
|
||||
GLOB.priority_announcement.Announce("Hostile environment resolved. You have 3 minutes to board the Emergency Shuttle.", "Priority Announcement", 'sound/AI/shuttledock.ogg')
|
||||
GLOB.priority_announcement.Announce("Hostile environment resolved. You have 3 minutes to board the Emergency Shuttle.", "Priority Announcement", 'sound/AI/eshuttle_dock.ogg')
|
||||
qdel(doomsday_device)
|
||||
|
||||
if(explosive)
|
||||
|
||||
@@ -1147,55 +1147,18 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
cell = null
|
||||
qdel(src)
|
||||
|
||||
#define BORG_CAMERA_BUFFER 30
|
||||
/mob/living/silicon/robot/Move(a, b, flag)
|
||||
var/oldLoc = src.loc
|
||||
#define BORG_CAMERA_BUFFER 3 SECONDS
|
||||
|
||||
/mob/living/silicon/robot/Move(atom/newloc, direct, movetime)
|
||||
var/oldLoc = loc
|
||||
. = ..()
|
||||
if(.)
|
||||
if(src.camera)
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(BORG_CAMERA_BUFFER)
|
||||
if(camera && oldLoc != src.loc)
|
||||
GLOB.cameranet.updatePortableCamera(src.camera)
|
||||
updating = 0
|
||||
if(module)
|
||||
if(module.type == /obj/item/robot_module/janitor)
|
||||
var/turf/tile = loc
|
||||
if(stat != DEAD && isturf(tile))
|
||||
var/floor_only = TRUE
|
||||
for(var/A in tile)
|
||||
if(istype(A, /obj/effect))
|
||||
var/obj/effect/E = A
|
||||
if(E.is_cleanable())
|
||||
var/obj/effect/decal/cleanable/blood/B = E
|
||||
if(istype(B) && B.off_floor)
|
||||
floor_only = FALSE
|
||||
else
|
||||
qdel(E)
|
||||
else if(istype(A, /obj/item))
|
||||
var/obj/item/cleaned_item = A
|
||||
cleaned_item.clean_blood()
|
||||
else if(istype(A, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/cleaned_human = A
|
||||
if(cleaned_human.lying)
|
||||
if(cleaned_human.head)
|
||||
cleaned_human.head.clean_blood()
|
||||
cleaned_human.update_inv_head()
|
||||
if(cleaned_human.wear_suit)
|
||||
cleaned_human.wear_suit.clean_blood()
|
||||
cleaned_human.update_inv_wear_suit()
|
||||
else if(cleaned_human.w_uniform)
|
||||
cleaned_human.w_uniform.clean_blood()
|
||||
cleaned_human.update_inv_w_uniform()
|
||||
if(cleaned_human.shoes)
|
||||
cleaned_human.shoes.clean_blood()
|
||||
cleaned_human.update_inv_shoes()
|
||||
cleaned_human.clean_blood()
|
||||
to_chat(cleaned_human, "<span class='danger'>[src] cleans your face!</span>")
|
||||
if(floor_only)
|
||||
tile.clean_blood()
|
||||
return
|
||||
if(. && !updating && camera)
|
||||
updating = TRUE
|
||||
spawn(BORG_CAMERA_BUFFER)
|
||||
if(camera && oldLoc != loc)
|
||||
GLOB.cameranet.updatePortableCamera(camera)
|
||||
updating = FALSE
|
||||
|
||||
#undef BORG_CAMERA_BUFFER
|
||||
|
||||
/mob/living/silicon/robot/proc/self_destruct()
|
||||
|
||||
@@ -447,6 +447,43 @@
|
||||
/obj/item/extinguisher/mini
|
||||
)
|
||||
|
||||
/obj/item/robot_module/janitor/Initialize(mapload)
|
||||
. = ..()
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
RegisterSignal(R, COMSIG_MOVABLE_MOVED, .proc/on_cyborg_move)
|
||||
|
||||
/**
|
||||
* Proc called after the janitor cyborg has moved, in order to clean atoms at it's new location.
|
||||
*
|
||||
* Arguments:
|
||||
* * mob/living/silicon/robot/R - The cyborg who moved.
|
||||
*/
|
||||
/obj/item/robot_module/janitor/proc/on_cyborg_move(mob/living/silicon/robot/R)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(R.stat == DEAD || !isturf(R.loc))
|
||||
return
|
||||
var/turf/tile = R.loc
|
||||
for(var/A in tile)
|
||||
if(iseffect(A))
|
||||
var/obj/effect/E = A
|
||||
if(!E.is_cleanable())
|
||||
continue
|
||||
var/obj/effect/decal/cleanable/blood/B = E
|
||||
if(istype(B) && B.off_floor)
|
||||
tile.clean_blood()
|
||||
else
|
||||
qdel(E)
|
||||
else if(isitem(A))
|
||||
var/obj/item/I = A
|
||||
I.clean_blood()
|
||||
else if(ishuman(A))
|
||||
var/mob/living/carbon/human/cleaned_human = A
|
||||
if(!cleaned_human.lying)
|
||||
continue
|
||||
cleaned_human.clean_blood()
|
||||
to_chat(cleaned_human, "<span class='danger'>[src] cleans your face!</span>")
|
||||
|
||||
/obj/item/reagent_containers/spray/cyborg_lube
|
||||
name = "Lube spray"
|
||||
list_reagents = list("lube" = 250)
|
||||
|
||||
@@ -33,27 +33,16 @@
|
||||
// break_stuff_probability = 2
|
||||
|
||||
faction = list("scarybat")
|
||||
var/mob/living/owner
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/New(loc, mob/living/L as mob)
|
||||
..()
|
||||
/mob/living/simple_animal/hostile/scarybat/Initialize(mapload, mob/living/L)
|
||||
. = ..()
|
||||
if(istype(L))
|
||||
owner = L
|
||||
faction += "\ref[L]"
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/Process_Spacemove(check_drift = 0)
|
||||
return ..() //No drifting in space for space carp! //original comments do not steal
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/Found(atom/A)//This is here as a potential override to pick a specific target if available
|
||||
if(istype(A) && A == owner)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/CanAttack(atom/the_target)//This is here as a potential override to pick a specific target if available
|
||||
if(istype(the_target) && the_target == owner)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/AttackingTarget()
|
||||
. =..()
|
||||
var/mob/living/L = .
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
move_to_delay = 0
|
||||
obj_damage = 0
|
||||
environment_smash = 0
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
density = FALSE
|
||||
mob_size = MOB_SIZE_TINY
|
||||
@@ -51,6 +50,8 @@
|
||||
var/isqueen = FALSE
|
||||
var/bee_syndicate = FALSE
|
||||
var/icon_base = "bee"
|
||||
var/last_attack = 0
|
||||
var/opacity_time = 1 MINUTES
|
||||
var/static/list/bee_icons = list()
|
||||
var/static/beehometypecache = typecacheof(/obj/structure/beebox)
|
||||
var/static/hydroponicstypecache = typecacheof(/obj/machinery/hydroponics)
|
||||
@@ -162,6 +163,7 @@
|
||||
else
|
||||
. = ..()
|
||||
if(. && isliving(target) && (!client || a_intent == INTENT_HARM))
|
||||
make_opaque()
|
||||
var/mob/living/L = target
|
||||
if(L.reagents)
|
||||
if(beegent)
|
||||
@@ -170,6 +172,23 @@
|
||||
else
|
||||
L.reagents.add_reagent("spidertoxin", 5)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/proc/make_opaque()
|
||||
// If a bee attacks someone, make it very easy to hit for a while
|
||||
last_attack = world.time
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/Life(seconds, times_fired)
|
||||
. = ..()
|
||||
if(mind || (mouse_opacity == initial(mouse_opacity)))
|
||||
return
|
||||
var/diff = world.time - last_attack
|
||||
if(diff >= opacity_time)
|
||||
mouse_opacity = initial(mouse_opacity)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/sentience_act()
|
||||
. = ..()
|
||||
make_opaque()
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/proc/assign_reagent(datum/reagent/R)
|
||||
if(istype(R))
|
||||
beegent = R
|
||||
@@ -233,6 +252,7 @@
|
||||
desc = "She's the queen of bees, BZZ BZZ"
|
||||
icon_base = "queen"
|
||||
isqueen = TRUE
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
|
||||
|
||||
//the Queen doesn't leave the box on her own, and she CERTAINLY doesn't pollinate by herself
|
||||
@@ -324,6 +344,7 @@
|
||||
search_objects = FALSE //these bees don't care about trivial things like plants, especially when there is havoc to sow
|
||||
bee_syndicate = TRUE
|
||||
var/list/master_and_friends = list()
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/syndi/New()
|
||||
beegent = GLOB.chemical_reagents_list["facid"] //Prepare to die
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/netherworld/migo/Initialize(mapload)
|
||||
. = ..()
|
||||
migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/voice/bcreep.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/mpatchedup.ogg', 'sound/voice/mfeelbetter.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heartbeat.ogg', 'sound/effects/hyperspace_begin.ogg', 'sound/effects/hyperspace_end.ogg', 'sound/goonstation/effects/screech.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/goonstation/misc/airraid_loop.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/chainsaw.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gunshots/gunshot_silenced.ogg', 'sound/weapons/gunshots/gunshot.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlock_close.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlock_open.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/ambience/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', 'sound/ai/outbreak5.ogg', 'sound/ai/outbreak7.ogg', 'sound/ai/poweroff.ogg', 'sound/ai/radiation.ogg', 'sound/ai/shuttlecalled.ogg', 'sound/ai/shuttledock.ogg', 'sound/ai/shuttlerecalled.ogg', 'sound/ai/aimalf.ogg', 'sound/ambience/ambigen1.ogg', 'sound/ambience/ambigen3.ogg', 'sound/ambience/ambigen4.ogg', 'sound/ambience/ambigen5.ogg', 'sound/ambience/ambigen6.ogg', 'sound/ambience/ambigen10.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg') //hahahaha fuck you code divers
|
||||
migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/voice/bcreep.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/mpatchedup.ogg', 'sound/voice/mfeelbetter.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heartbeat.ogg', 'sound/effects/hyperspace_begin.ogg', 'sound/effects/hyperspace_end.ogg', 'sound/goonstation/effects/screech.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/goonstation/misc/airraid_loop.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/chainsaw.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gunshots/gunshot_silenced.ogg', 'sound/weapons/gunshots/gunshot.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlock_close.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlock_open.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/ambience/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', 'sound/ai/outbreak5.ogg', 'sound/ai/outbreak7.ogg', 'sound/ai/alert.ogg', 'sound/ai/radiation.ogg', 'sound/ai/eshuttle_call.ogg', 'sound/ai/eshuttle_dock.ogg', 'sound/ai/eshuttle_recall.ogg', 'sound/ai/aimalf.ogg', 'sound/ambience/ambigen1.ogg', 'sound/ambience/ambigen3.ogg', 'sound/ambience/ambigen4.ogg', 'sound/ambience/ambigen5.ogg', 'sound/ambience/ambigen6.ogg', 'sound/ambience/ambigen10.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg') //hahahaha fuck you code divers
|
||||
|
||||
/mob/living/simple_animal/hostile/netherworld/migo/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
|
||||
..()
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
if(silent)
|
||||
return
|
||||
if(src.client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
if(check_mute(client.ckey, MUTE_IC))
|
||||
to_chat(src, "<span class='warning'>You cannot send IC messages (muted).</span>")
|
||||
return
|
||||
if(src.client.handle_spam_prevention(message,MUTE_IC))
|
||||
if(src.client.handle_spam_prevention(message, MUTE_IC))
|
||||
return
|
||||
if(stat)
|
||||
return
|
||||
|
||||
+13
-9
@@ -1351,17 +1351,21 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
|
||||
return FALSE //overridden in living.dm
|
||||
|
||||
/mob/proc/spin(spintime, speed)
|
||||
set waitfor = 0
|
||||
set waitfor = FALSE
|
||||
if(!spintime || !speed || spintime > 100)
|
||||
CRASH("Aborted attempted call of /mob/proc/spin with invalid args ([spintime],[speed]) which could have frozen the server.")
|
||||
var/end_time = world.time + spintime
|
||||
var/spin_dir = prob(50)
|
||||
while(world.time <= end_time)
|
||||
while(spintime >= speed)
|
||||
sleep(speed)
|
||||
if(spin_dir)
|
||||
dir = turn(dir, 90)
|
||||
else
|
||||
dir = turn(dir, -90)
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
setDir(EAST)
|
||||
if(SOUTH)
|
||||
setDir(WEST)
|
||||
if(EAST)
|
||||
setDir(SOUTH)
|
||||
if(WEST)
|
||||
setDir(NORTH)
|
||||
spintime -= speed
|
||||
|
||||
/mob/proc/is_literate()
|
||||
return FALSE
|
||||
@@ -1479,7 +1483,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
|
||||
MA.plane = GAME_PLANE
|
||||
pic.appearance = MA
|
||||
flick_overlay(pic, list(client), 10)
|
||||
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(holy_areas, typecacheof(list(
|
||||
/area/chapel
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
to_chat(src, "<span class='danger'>Deadchat is globally muted.</span>")
|
||||
return
|
||||
|
||||
if(client.prefs.muted & MUTE_DEADCHAT)
|
||||
if(check_mute(client.ckey, MUTE_DEADCHAT))
|
||||
to_chat(src, "<span class='warning'>You cannot talk in deadchat (muted).</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -40,11 +40,15 @@ GLOBAL_LIST_EMPTY(fax_blacklist)
|
||||
/// Target department to send outgoing faxes to
|
||||
var/destination
|
||||
|
||||
/obj/machinery/photocopier/faxmachine/New()
|
||||
..()
|
||||
/obj/machinery/photocopier/faxmachine/Initialize(mapload)
|
||||
. = ..()
|
||||
GLOB.allfaxes += src
|
||||
update_network()
|
||||
|
||||
/obj/machinery/photocopier/faxmachine/Destroy()
|
||||
GLOB.allfaxes -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/photocopier/faxmachine/proc/update_network()
|
||||
if(department != "Unknown")
|
||||
if(!(("[department]" in GLOB.alldepartments) || ("[department]" in GLOB.hidden_departments) || ("[department]" in GLOB.admin_departments) || ("[department]" in GLOB.hidden_admin_departments)))
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
disconnect("Program Terminated")
|
||||
STOP_PROCESSING(SSobj, pda)
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/Destroy()
|
||||
STOP_PROCESSING(SSobj, pda)
|
||||
SSmob_hunt.connected_clients -= src
|
||||
return ..()
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/proc/scan_nearby()
|
||||
if(!SSmob_hunt || !connected)
|
||||
return
|
||||
@@ -74,13 +79,14 @@
|
||||
return
|
||||
scan_nearby()
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/proc/register_capture(datum/mob_hunt/captured, wild = 0)
|
||||
/datum/data/pda/app/mob_hunter_game/proc/register_capture(datum/mob_hunt/captured, wild = FALSE)
|
||||
if(!captured)
|
||||
return 0
|
||||
my_collection.Add(captured)
|
||||
return FALSE
|
||||
my_collection += captured
|
||||
RegisterSignal(captured, COMSIG_PARENT_QDELETING, .proc/remove_mob)
|
||||
if(wild)
|
||||
wild_captures++
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/update_ui(mob/user, list/data)
|
||||
if(!SSmob_hunt || !(src in SSmob_hunt.connected_clients))
|
||||
@@ -138,12 +144,27 @@
|
||||
card.forceMove(get_turf(pda))
|
||||
remove_mob()
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/proc/remove_mob()
|
||||
if(!my_collection.len)
|
||||
/**
|
||||
* Removes a Nanomob from the [my_collection] list.
|
||||
*
|
||||
* The Nanomob that is currently selected in the app ([current_index]) will be removed from the list unless a `mob_override` argument is given, in which case that will be removed instead.
|
||||
*
|
||||
* Arguments:
|
||||
* * mob_override - A specific Nanomob to remove from the list. (Optional)
|
||||
*/
|
||||
/datum/data/pda/app/mob_hunter_game/proc/remove_mob(datum/mob_hunt/mob_override = null)
|
||||
SIGNAL_HANDLER
|
||||
if(!length(my_collection))
|
||||
return
|
||||
my_collection.Remove(my_collection[current_index])
|
||||
if(current_index > my_collection.len)
|
||||
current_index = my_collection.len
|
||||
|
||||
if(mob_override)
|
||||
my_collection -= mob_override
|
||||
else
|
||||
my_collection -= my_collection[current_index]
|
||||
|
||||
var/collection_length = length(my_collection)
|
||||
if(current_index > collection_length)
|
||||
current_index = collection_length
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/proc/set_trap()
|
||||
if(!my_collection.len || !pda || !hacked)
|
||||
|
||||
@@ -35,6 +35,7 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
icon_state = "0-1"
|
||||
var/d1 = 0
|
||||
var/d2 = 1
|
||||
plane = FLOOR_PLANE
|
||||
layer = WIRE_LAYER //Just below unary stuff, which is at 2.45 and above pipes, which are at 2.4
|
||||
color = COLOR_RED
|
||||
|
||||
@@ -68,9 +69,11 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
d2 = text2num(copytext( icon_state, dash+1 ))
|
||||
|
||||
var/turf/T = get_turf(src) // hide if turf is not intact
|
||||
LAZYADD(GLOB.cable_list, src) //add it to the global cable list
|
||||
if(T.transparent_floor)
|
||||
return
|
||||
if(level == 1)
|
||||
hide(T.intact)
|
||||
LAZYADD(GLOB.cable_list, src) //add it to the global cable list
|
||||
|
||||
/obj/structure/cable/Destroy() // called when a cable is deleted
|
||||
if(powernet)
|
||||
@@ -162,7 +165,8 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
//
|
||||
/obj/structure/cable/attackby(obj/item/W, mob/user)
|
||||
var/turf/T = get_turf(src)
|
||||
if(T.intact)
|
||||
if(T.transparent_floor || T.intact)
|
||||
to_chat(user, "<span class='danger'>You can't interact with something that's under the floor!</span>")
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
@@ -204,7 +208,8 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
/obj/structure/cable/wirecutter_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
var/turf/T = get_turf(src)
|
||||
if(T.intact)
|
||||
if(T.transparent_floor || T.intact)
|
||||
to_chat(user, "<span class='danger'>You can't interact with something that's under the floor!</span>")
|
||||
return
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
@@ -703,7 +708,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe/cable_restrain
|
||||
|
||||
var/turf/T = get_turf(C)
|
||||
|
||||
if(!isturf(T) || T.intact) // sanity checks, also stop use interacting with T-scanner revealed cable
|
||||
if(!isturf(T) || T.intact || T.transparent_floor) // sanity checks, also stop use interacting with T-scanner revealed cable
|
||||
return
|
||||
|
||||
if(get_dist(C, user) > 1) // make sure it's close enough
|
||||
@@ -719,7 +724,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe/cable_restrain
|
||||
|
||||
// one end of the clicked cable is pointing towards us
|
||||
if(C.d1 == dirn || C.d2 == dirn)
|
||||
if(U.intact) // can't place a cable if the floor is complete
|
||||
if(U.intact || U.transparent_floor) // can't place a cable if the floor is complete
|
||||
to_chat(user, "<span class='warning'>You can't lay cable there unless the floor tiles are removed!</span>")
|
||||
return
|
||||
else
|
||||
|
||||
@@ -284,6 +284,12 @@
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/bluespace/charging
|
||||
name = "self-charging bluespace power cell"
|
||||
desc = "An experimental, self-charging, transdimensional power cell."
|
||||
origin_tech = "powerstorage=10;bluespace=10"
|
||||
self_recharge = TRUE
|
||||
|
||||
/obj/item/stock_parts/cell/infinite
|
||||
name = "infinite-capacity power cell!"
|
||||
icon_state = "icell"
|
||||
@@ -294,7 +300,7 @@
|
||||
chargerate = 30000
|
||||
|
||||
/obj/item/stock_parts/cell/infinite/use()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/item/stock_parts/cell/infinite/abductor
|
||||
name = "void core"
|
||||
|
||||
@@ -352,8 +352,6 @@
|
||||
overlays += "[icon_state]_broken"
|
||||
else
|
||||
overlays += icon_screen
|
||||
if(cdir > -1)
|
||||
overlays += image('icons/obj/computer.dmi', "solcon-o", FLY_LAYER, angle2dir(cdir))
|
||||
|
||||
/obj/machinery/power/solar_control/attack_ai(mob/user as mob)
|
||||
add_hiddenprint(user)
|
||||
|
||||
@@ -221,7 +221,7 @@
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/immune = istype(H.glasses, /obj/item/clothing/glasses/meson)
|
||||
if(!immune && (get_dist(user, src) < HALLUCINATION_RANGE(power)))
|
||||
if(!immune && !HAS_TRAIT(H, TRAIT_MESON_VISION) && (get_dist(user, src) < HALLUCINATION_RANGE(power)))
|
||||
. += "<span class='danger'>You get headaches just from looking at it.</span>"
|
||||
|
||||
/obj/machinery/power/supermatter_crystal/detailed_examine()
|
||||
@@ -537,7 +537,7 @@
|
||||
|
||||
//Makes em go mad and accumulate rads.
|
||||
for(var/mob/living/carbon/human/l in view(src, HALLUCINATION_RANGE(power))) // If they can see it without mesons on. Bad on them.
|
||||
if(!istype(l.glasses, /obj/item/clothing/glasses/meson))
|
||||
if(!istype(l.glasses, /obj/item/clothing/glasses/meson) && !HAS_TRAIT(l, TRAIT_MESON_VISION))
|
||||
var/D = sqrt(1 / max(1, get_dist(l, src)))
|
||||
l.hallucination += power * hallucination_power * D
|
||||
l.hallucination = clamp(l.hallucination, 0, 200)
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
/obj/machinery/power/terminal/Initialize(mapload)
|
||||
. = ..()
|
||||
var/turf/T = get_turf(src)
|
||||
if(T.transparent_floor)
|
||||
return
|
||||
if(level == 1)
|
||||
hide(T.intact)
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
fire_sound = 'sound/magic/staff_door.ogg'
|
||||
|
||||
/obj/item/gun/magic/staff/slipping
|
||||
name = "wand of slipping"
|
||||
name = "staff of slipping"
|
||||
desc = "An artefact that spits... bananas?"
|
||||
ammo_type = /obj/item/ammo_casing/magic/slipping
|
||||
icon_state = "staffofslipping"
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
user.visible_message("<span class='danger'>[user] zaps [user.p_them()]self with [src].</span>")
|
||||
playsound(user, fire_sound, 50, 1)
|
||||
user.create_attack_log("<b>[key_name(user)]</b> zapped [user.p_them()]self with a <b>[src]</b>")
|
||||
add_attack_logs(null, user, "zapped [user.p_them()]self with a [src]", ATKLOG_ALL)
|
||||
add_attack_logs(user, user, "zapped [user.p_them()]self with a [src]", ATKLOG_ALL)
|
||||
|
||||
/////////////////////////////////////
|
||||
//WAND OF DEATH
|
||||
@@ -182,7 +182,7 @@
|
||||
desc = "This wand shoots... banana peels?"
|
||||
fire_sound = 'sound/items/bikehorn.ogg'
|
||||
ammo_type = /obj/item/ammo_casing/magic/slipping
|
||||
icon_state = "staffofslipping"
|
||||
icon_state = "wandofslipping"
|
||||
max_charges = 5 //5, 4, 3, 2
|
||||
|
||||
/obj/item/gun/magic/wand/slipping/zap_self(mob/living/user)
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
if(!istype(user_turf))
|
||||
return 0
|
||||
var/obj/dummy = new(user_turf)
|
||||
dummy.pass_flags |= PASSTABLE & PASSGLASS & PASSGRILLE //Grille/Glass so it can be used through common windows
|
||||
dummy.pass_flags |= PASSTABLE & PASSGLASS & PASSGRILLE & PASSFENCE //Grille/Glass so it can be used through common windows
|
||||
for(var/turf/turf in getline(user_turf,target))
|
||||
if(turf.density)
|
||||
qdel(dummy)
|
||||
|
||||
@@ -142,8 +142,8 @@
|
||||
|
||||
/obj/item/projectile/beam/immolator/on_hit(atom/target, blocked = 0)
|
||||
. = ..()
|
||||
if(istype(target, /mob/living/carbon))
|
||||
var/mob/living/carbon/M = target
|
||||
if(isliving(target))
|
||||
var/mob/living/M = target
|
||||
M.adjust_fire_stacks(1)
|
||||
M.IgniteMob()
|
||||
|
||||
|
||||
@@ -275,7 +275,7 @@
|
||||
return
|
||||
|
||||
M.create_attack_log("<font color='orange'>[key_name(M)] became [new_mob.real_name].</font>")
|
||||
add_attack_logs(null, M, "became [new_mob.real_name]", ATKLOG_ALL)
|
||||
add_attack_logs(M, M, "became [new_mob.real_name]", ATKLOG_ALL)
|
||||
|
||||
new_mob.a_intent = INTENT_HARM
|
||||
if(M.mind)
|
||||
|
||||
@@ -915,8 +915,8 @@
|
||||
name = "Gimlet"
|
||||
id = "gimlet"
|
||||
result = "gimlet"
|
||||
required_reagents = list("gin" = 1, "limejuice" = 1)
|
||||
result_amount = 2
|
||||
required_reagents = list("gin" = 1, "limejuice" = 1, "sugar" = 1)
|
||||
result_amount = 3
|
||||
mix_sound = 'sound/goonstation/misc/drinkfizz.ogg'
|
||||
|
||||
/datum/chemical_reaction/sidecar
|
||||
|
||||
@@ -691,6 +691,7 @@
|
||||
armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30)
|
||||
damage_deflection = 10
|
||||
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
|
||||
plane = FLOOR_PLANE
|
||||
layer = DISPOSAL_PIPE_LAYER // slightly lower than wires and other pipes
|
||||
var/base_icon_state // initial icon state on map
|
||||
|
||||
@@ -757,6 +758,9 @@
|
||||
// update the icon_state to reflect hidden status
|
||||
/obj/structure/disposalpipe/proc/update()
|
||||
var/turf/T = get_turf(src)
|
||||
if(T.transparent_floor)
|
||||
update_icon()
|
||||
return
|
||||
hide(T.intact && !istype(T, /turf/space)) // space never hides pipes
|
||||
update_icon()
|
||||
|
||||
@@ -889,15 +893,20 @@
|
||||
|
||||
/obj/structure/disposalpipe/attackby(obj/item/I, mob/user, params)
|
||||
var/turf/T = get_turf(src)
|
||||
if(T.intact)
|
||||
return // prevent interaction with T-scanner revealed pipes
|
||||
if(T.intact || T.transparent_floor)
|
||||
to_chat(user, "<span class='danger'>You can't interact with something that's under the floor!</span>")
|
||||
return // prevent interaction with T-scanner revealed pipes and pipes under glass
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/structure/disposalpipe/welder_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
var/turf/T = get_turf(src)
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
if(T.transparent_floor)
|
||||
to_chat(user, "<span class='danger'>You can't interact with something that's under the floor!</span>")
|
||||
return
|
||||
WELDER_ATTEMPT_SLICING_MESSAGE
|
||||
if(!I.use_tool(src, user, 30, volume = I.tool_volume))
|
||||
return
|
||||
@@ -1201,7 +1210,7 @@
|
||||
return
|
||||
|
||||
var/turf/T = src.loc
|
||||
if(T.intact)
|
||||
if(T.intact || T.transparent_floor)
|
||||
return // prevent interaction with T-scanner revealed pipes
|
||||
src.add_fingerprint(user)
|
||||
|
||||
|
||||
@@ -11,19 +11,17 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
|
||||
container_type = OPENCONTAINER
|
||||
|
||||
categories = list(
|
||||
"AI Modules",
|
||||
"Computer Boards",
|
||||
"Engineering Machinery",
|
||||
"Exosuit Modules",
|
||||
"Hydroponics Machinery",
|
||||
"Medical Machinery",
|
||||
"Misc. Machinery",
|
||||
"Research Machinery",
|
||||
"Subspace Telecomms",
|
||||
"Teleportation Machinery"
|
||||
)
|
||||
|
||||
reagents = new()
|
||||
"AI Modules",
|
||||
"Computer Boards",
|
||||
"Engineering Machinery",
|
||||
"Exosuit Modules",
|
||||
"Hydroponics Machinery",
|
||||
"Medical Machinery",
|
||||
"Misc. Machinery",
|
||||
"Research Machinery",
|
||||
"Subspace Telecomms",
|
||||
"Teleportation Machinery"
|
||||
)
|
||||
|
||||
/obj/machinery/r_n_d/circuit_imprinter/New()
|
||||
..()
|
||||
@@ -33,8 +31,8 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
|
||||
component_parts += new /obj/item/stock_parts/manipulator(null)
|
||||
component_parts += new /obj/item/reagent_containers/glass/beaker(null)
|
||||
component_parts += new /obj/item/reagent_containers/glass/beaker(null)
|
||||
create_reagents()
|
||||
RefreshParts()
|
||||
reagents.my_atom = src
|
||||
|
||||
/obj/machinery/r_n_d/circuit_imprinter/upgraded/New()
|
||||
..()
|
||||
@@ -45,7 +43,11 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
|
||||
component_parts += new /obj/item/reagent_containers/glass/beaker/large(null)
|
||||
component_parts += new /obj/item/reagent_containers/glass/beaker/large(null)
|
||||
RefreshParts()
|
||||
reagents.my_atom = src
|
||||
|
||||
/obj/machinery/r_n_d/circuit_imprinter/Destroy()
|
||||
if(linked_console)
|
||||
linked_console.linked_imprinter = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/r_n_d/circuit_imprinter/RefreshParts()
|
||||
reagents.maximum_volume = 0
|
||||
|
||||
@@ -72,6 +72,16 @@
|
||||
build_path = /obj/item/defibrillator
|
||||
category = list("Medical")
|
||||
|
||||
/datum/design/compact_defib
|
||||
name = "Compact Defibrillator"
|
||||
desc = "A belt-mounted defibrillator for rapid deployment."
|
||||
id = "compact_defib"
|
||||
req_tech = list("materials" = 7, "biotech" = 7, "powerstorage" = 6)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 10000, MAT_GLASS = 4000, MAT_SILVER = 2000)
|
||||
build_path = /obj/item/defibrillator/compact
|
||||
category = list("Medical")
|
||||
|
||||
/datum/design/defib_mount
|
||||
name = "Defibrillator Wall Mount"
|
||||
desc = "A wall mount for defibrillator units."
|
||||
|
||||
@@ -29,6 +29,11 @@ Note: Must be placed within 3 tiles of the R&D Console
|
||||
component_parts += new /obj/item/stock_parts/micro_laser/ultra(null)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/r_n_d/destructive_analyzer/Destroy()
|
||||
if(linked_console)
|
||||
linked_console.linked_destroy = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/r_n_d/destructive_analyzer/RefreshParts()
|
||||
var/T = 0
|
||||
for(var/obj/item/stock_parts/S in component_parts)
|
||||
|
||||
@@ -60,14 +60,16 @@ GLOBAL_LIST_EMPTY(message_servers)
|
||||
var/active = TRUE
|
||||
var/decryptkey = "password"
|
||||
|
||||
/obj/machinery/message_server/New()
|
||||
/obj/machinery/message_server/Initialize(mapload)
|
||||
. = ..()
|
||||
GLOB.message_servers += src
|
||||
decryptkey = GenerateKey()
|
||||
send_pda_message("System Administrator", "system", "This is an automated message. The messaging system is functioning correctly.")
|
||||
..()
|
||||
|
||||
/obj/machinery/message_server/Destroy()
|
||||
GLOB.message_servers -= src
|
||||
QDEL_LIST(pda_msgs)
|
||||
QDEL_LIST(rc_msgs)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/message_server/process()
|
||||
|
||||
@@ -14,19 +14,16 @@ Note: Must be placed west/left of and R&D console to function.
|
||||
container_type = OPENCONTAINER
|
||||
|
||||
categories = list(
|
||||
"Bluespace",
|
||||
"Equipment",
|
||||
"Janitorial",
|
||||
"Medical",
|
||||
"Mining",
|
||||
"Miscellaneous",
|
||||
"Power",
|
||||
"Stock Parts",
|
||||
"Weapons"
|
||||
)
|
||||
|
||||
reagents = new()
|
||||
|
||||
"Bluespace",
|
||||
"Equipment",
|
||||
"Janitorial",
|
||||
"Medical",
|
||||
"Mining",
|
||||
"Miscellaneous",
|
||||
"Power",
|
||||
"Stock Parts",
|
||||
"Weapons"
|
||||
)
|
||||
|
||||
/obj/machinery/r_n_d/protolathe/New()
|
||||
..()
|
||||
@@ -38,10 +35,9 @@ Note: Must be placed west/left of and R&D console to function.
|
||||
component_parts += new /obj/item/stock_parts/manipulator(null)
|
||||
component_parts += new /obj/item/reagent_containers/glass/beaker/large(null)
|
||||
component_parts += new /obj/item/reagent_containers/glass/beaker/large(null)
|
||||
create_reagents()
|
||||
RefreshParts()
|
||||
|
||||
reagents.my_atom = src
|
||||
|
||||
/obj/machinery/r_n_d/protolathe/upgraded/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
@@ -54,7 +50,10 @@ Note: Must be placed west/left of and R&D console to function.
|
||||
component_parts += new /obj/item/reagent_containers/glass/beaker/large(null)
|
||||
RefreshParts()
|
||||
|
||||
reagents.my_atom = src
|
||||
/obj/machinery/r_n_d/protolathe/Destroy()
|
||||
if(linked_console)
|
||||
linked_console.linked_lathe = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/r_n_d/protolathe/RefreshParts()
|
||||
var/T = 0
|
||||
|
||||
@@ -176,6 +176,20 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
SyncRDevices()
|
||||
|
||||
/obj/machinery/computer/rdconsole/Destroy()
|
||||
QDEL_NULL(files)
|
||||
QDEL_NULL(t_disk)
|
||||
QDEL_NULL(d_disk)
|
||||
QDEL_LIST(matching_designs)
|
||||
if(linked_destroy)
|
||||
linked_destroy.linked_console = null
|
||||
linked_destroy = null
|
||||
if(linked_lathe)
|
||||
linked_lathe.linked_console = null
|
||||
linked_lathe = null
|
||||
if(linked_imprinter)
|
||||
linked_imprinter.linked_console = null
|
||||
linked_imprinter = null
|
||||
|
||||
if(wait_message_timer)
|
||||
deltimer(wait_message_timer)
|
||||
wait_message_timer = 0
|
||||
|
||||
@@ -32,12 +32,17 @@
|
||||
wires["Black"] = 0
|
||||
wires["White"] = 0
|
||||
var/list/w = list("Red","Blue","Green","Yellow","Black","White")
|
||||
src.hack_wire = pick(w)
|
||||
w -= src.hack_wire
|
||||
src.shock_wire = pick(w)
|
||||
w -= src.shock_wire
|
||||
src.disable_wire = pick(w)
|
||||
w -= src.disable_wire
|
||||
hack_wire = pick_n_take(w)
|
||||
shock_wire = pick_n_take(w)
|
||||
disable_wire = pick_n_take(w)
|
||||
|
||||
/obj/machinery/r_n_d/Destroy()
|
||||
if(loaded_item)
|
||||
loaded_item.forceMove(get_turf(src))
|
||||
loaded_item = null
|
||||
linked_console = null
|
||||
materials = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/r_n_d/attack_hand(mob/user as mob)
|
||||
if(shocked)
|
||||
|
||||
@@ -340,7 +340,7 @@
|
||||
/obj/item/organ/internal/cyberimp/arm/surgery,
|
||||
/obj/item/organ/internal/cyberimp/chest/nutriment
|
||||
)
|
||||
belt = /obj/item/defibrillator/compact/loaded
|
||||
belt = /obj/item/defibrillator/compact/advanced/loaded
|
||||
|
||||
l_pocket = /obj/item/reagent_containers/hypospray/safety/ert
|
||||
r_pocket = /obj/item/melee/classic_baton/telescopic
|
||||
@@ -369,7 +369,7 @@
|
||||
mask = /obj/item/clothing/mask/gas/sechailer/swat
|
||||
suit_store = /obj/item/gun/energy/gun/blueshield/pdw9
|
||||
|
||||
belt = /obj/item/defibrillator/compact/loaded
|
||||
belt = /obj/item/defibrillator/compact/advanced/loaded
|
||||
|
||||
l_pocket = /obj/item/reagent_containers/hypospray/combat/nanites
|
||||
r_pocket = /obj/item/reagent_containers/hypospray/autoinjector
|
||||
|
||||
@@ -33,7 +33,7 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur
|
||||
|
||||
switch(level)
|
||||
if(SEC_LEVEL_GREEN)
|
||||
GLOB.security_announcement_down.Announce("All threats to the station have passed. All weapons need to be holstered and privacy laws are once again fully enforced.","Attention! Security level lowered to green.")
|
||||
GLOB.security_announcement_down.Announce("All threats to the station have passed. All weapons need to be holstered and privacy laws are once again fully enforced.","Attention! Security level lowered to green.", 'sound/AI/green.ogg')
|
||||
GLOB.security_level = SEC_LEVEL_GREEN
|
||||
|
||||
post_status("alert", "outline")
|
||||
@@ -45,9 +45,9 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur
|
||||
|
||||
if(SEC_LEVEL_BLUE)
|
||||
if(GLOB.security_level < SEC_LEVEL_BLUE)
|
||||
GLOB.security_announcement_up.Announce("The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible and random searches are permitted.","Attention! Security level elevated to blue.")
|
||||
GLOB.security_announcement_up.Announce("The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible and random searches are permitted.","Attention! Security level elevated to blue.", 'sound/AI/blue.ogg')
|
||||
else
|
||||
GLOB.security_announcement_down.Announce("The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed.","Attention! Security level lowered to blue.")
|
||||
GLOB.security_announcement_down.Announce("The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed.","Attention! Security level lowered to blue.", 'sound/AI/blue.ogg')
|
||||
GLOB.security_level = SEC_LEVEL_BLUE
|
||||
|
||||
post_status("alert", "outline")
|
||||
@@ -59,9 +59,9 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur
|
||||
|
||||
if(SEC_LEVEL_RED)
|
||||
if(GLOB.security_level < SEC_LEVEL_RED)
|
||||
GLOB.security_announcement_up.Announce("There is an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised.","Attention! Code Red!")
|
||||
GLOB.security_announcement_up.Announce("There is an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised.","Attention! Code Red!", 'sound/AI/red.ogg')
|
||||
else
|
||||
GLOB.security_announcement_down.Announce("The station's self-destruct mechanism has been deactivated, but there is still an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised.","Attention! Code Red!")
|
||||
GLOB.security_announcement_down.Announce("The station's self-destruct mechanism has been deactivated, but there is still an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised.","Attention! Code Red!", 'sound/AI/red.ogg')
|
||||
GLOB.security_level = SEC_LEVEL_RED
|
||||
|
||||
var/obj/machinery/door/airlock/highsecurity/red/R = locate(/obj/machinery/door/airlock/highsecurity/red) in GLOB.airlocks
|
||||
@@ -77,7 +77,7 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur
|
||||
FA.overlays += image('icons/obj/monitors.dmi', "overlay_red")
|
||||
|
||||
if(SEC_LEVEL_GAMMA)
|
||||
GLOB.security_announcement_up.Announce("Central Command has ordered the Gamma security level on the station. Security is to have weapons equipped at all times, and all civilians are to immediately seek their nearest head for transportation to a secure location.", "Attention! Gamma security level activated!", sound('sound/effects/new_siren.ogg'))
|
||||
GLOB.security_announcement_up.Announce("Central Command has ordered the Gamma security level on the station. Security is to have weapons equipped at all times, and all civilians are to immediately seek their nearest head for transportation to a secure location.", "Attention! Gamma security level activated!", 'sound/effects/new_siren.ogg', new_sound2 = 'sound/AI/gamma.ogg')
|
||||
GLOB.security_level = SEC_LEVEL_GAMMA
|
||||
|
||||
if(GLOB.security_level < SEC_LEVEL_RED)
|
||||
@@ -95,7 +95,7 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur
|
||||
FA.update_icon()
|
||||
|
||||
if(SEC_LEVEL_EPSILON)
|
||||
GLOB.security_announcement_up.Announce("Central Command has ordered the Epsilon security level on the station. Consider all contracts terminated.","Attention! Epsilon security level activated!", new_sound = sound('sound/effects/purge_siren.ogg'))
|
||||
GLOB.security_announcement_up.Announce("Central Command has ordered the Epsilon security level on the station. Consider all contracts terminated.","Attention! Epsilon security level activated!", 'sound/effects/purge_siren.ogg', new_sound2 = 'sound/AI/epsilon.ogg')
|
||||
GLOB.security_level = SEC_LEVEL_EPSILON
|
||||
|
||||
post_status("alert", "epsilonalert")
|
||||
@@ -106,7 +106,7 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur
|
||||
FA.overlays += image('icons/obj/monitors.dmi', "overlay_epsilon")
|
||||
|
||||
if(SEC_LEVEL_DELTA)
|
||||
GLOB.security_announcement_up.Announce("The station's self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill.","Attention! Delta security level reached!", new_sound = sound('sound/effects/deltaalarm.ogg'))
|
||||
GLOB.security_announcement_up.Announce("The station's self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill.","Attention! Delta security level reached!", 'sound/effects/deltaalarm.ogg', new_sound2 = 'sound/AI/delta.ogg')
|
||||
GLOB.security_level = SEC_LEVEL_DELTA
|
||||
|
||||
post_status("alert", "deltaalert")
|
||||
|
||||
@@ -86,12 +86,15 @@
|
||||
travelDir = 0
|
||||
var/sound_played = 0 //If the launch sound has been sent to all players on the shuttle itself
|
||||
|
||||
var/datum/announcement/priority/emergency_shuttle_docked = new(0, new_sound = sound('sound/AI/shuttledock.ogg'))
|
||||
var/datum/announcement/priority/emergency_shuttle_called = new(0, new_sound = sound('sound/AI/shuttlecalled.ogg'))
|
||||
var/datum/announcement/priority/emergency_shuttle_recalled = new(0, new_sound = sound('sound/AI/shuttlerecalled.ogg'))
|
||||
var/datum/announcement/priority/emergency_shuttle_docked = new(0, new_sound = sound('sound/AI/eshuttle_dock.ogg'))
|
||||
var/datum/announcement/priority/emergency_shuttle_called = new(0, new_sound = sound('sound/AI/eshuttle_call.ogg'))
|
||||
var/datum/announcement/priority/emergency_shuttle_recalled = new(0, new_sound = sound('sound/AI/eshuttle_recall.ogg'))
|
||||
|
||||
var/canRecall = TRUE //no bad condom, do not recall the crew transfer shuttle!
|
||||
|
||||
var/datum/announcement/priority/crew_shuttle_called = new(0, new_sound = sound('sound/AI/cshuttle.ogg'))
|
||||
var/datum/announcement/priority/crew_shuttle_docked = new(0, new_sound = sound('sound/AI/cshuttle_dock.ogg'))
|
||||
|
||||
|
||||
/obj/docking_port/mobile/emergency/register()
|
||||
if(!..())
|
||||
@@ -146,9 +149,10 @@
|
||||
SSshuttle.emergencyLastCallLoc = signalOrigin
|
||||
else
|
||||
SSshuttle.emergencyLastCallLoc = null
|
||||
|
||||
emergency_shuttle_called.Announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]")
|
||||
|
||||
if(canRecall)
|
||||
emergency_shuttle_called.Announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]")
|
||||
else
|
||||
crew_shuttle_called.Announce("The crew transfer shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason]")
|
||||
|
||||
/obj/docking_port/mobile/emergency/cancel(area/signalOrigin)
|
||||
if(!canRecall)
|
||||
@@ -230,7 +234,10 @@
|
||||
return
|
||||
mode = SHUTTLE_DOCKED
|
||||
timer = world.time
|
||||
emergency_shuttle_docked.Announce("The Emergency Shuttle has docked with the station. You have [timeLeft(600)] minutes to board the Emergency Shuttle.")
|
||||
if(canRecall)
|
||||
emergency_shuttle_docked.Announce("The emergency shuttle has docked with the station. You have [timeLeft(600)] minutes to board the emergency shuttle.")
|
||||
else
|
||||
crew_shuttle_docked.Announce("The crew transfer shuttle has docked with the station. You have [timeLeft(600)] minutes to board the crew transfer shuttle.")
|
||||
|
||||
/*
|
||||
//Gangs only have one attempt left if the shuttle has docked with the station to prevent suffering from dominator delays
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user