mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-14 00:23:29 +01:00
Merge https://github.com/ParadiseSS13/Paradise into SlimeHUD
This commit is contained in:
@@ -108,7 +108,7 @@ world/IsBanned(key, address, computer_id, check_ipintel = TRUE)
|
||||
var/appealmessage = ""
|
||||
if(config.banappeals)
|
||||
appealmessage = " You may appeal it at <a href='[config.banappeals]'>[config.banappeals]</a>."
|
||||
expires = " This is a permanent ban.[appealmessage]"
|
||||
expires = " This ban does not expire automatically and must be appealed.[appealmessage]"
|
||||
|
||||
var/desc = "\nReason: You, or another user of this computer or connection ([pckey]) is banned from playing here. The ban reason is:\n[reason]\nThis ban was applied by [ackey] on [bantime].[expires]"
|
||||
|
||||
|
||||
@@ -77,9 +77,11 @@ var/list/admin_verbs_admin = list(
|
||||
/client/proc/toggle_mentor_chat,
|
||||
/client/proc/toggle_advanced_interaction, /*toggle admin ability to interact with not only machines, but also atoms such as buttons and doors*/
|
||||
/client/proc/list_ssds,
|
||||
/client/proc/list_afks,
|
||||
/client/proc/cmd_admin_headset_message,
|
||||
/client/proc/spawn_floor_cluwne,
|
||||
/client/proc/show_discord_duplicates,
|
||||
/client/proc/show_discord_duplicates, // This needs removing at some point, ingame discord linking got removed in #11359
|
||||
/client/proc/toggle_panic_bunker
|
||||
)
|
||||
var/list/admin_verbs_ban = list(
|
||||
/client/proc/unban_panel,
|
||||
@@ -475,7 +477,7 @@ var/list/admin_verbs_ticket = list(
|
||||
if(holder.fakekey)
|
||||
holder.fakekey = null
|
||||
else
|
||||
var/new_key = ckeyEx(input("Enter your desired display name.", "Fake Key", key) as text|null)
|
||||
var/new_key = ckeyEx(clean_input("Enter your desired display name.", "Fake Key", key))
|
||||
if(!new_key) return
|
||||
if(length(new_key) >= 26)
|
||||
new_key = copytext(new_key, 1, 26)
|
||||
@@ -497,7 +499,7 @@ var/list/admin_verbs_ticket = list(
|
||||
holder.fakekey = null
|
||||
holder.big_brother = 0
|
||||
else
|
||||
var/new_key = ckeyEx(input("Enter your desired display name. Unlike normal stealth mode, this will not appear in Who at all, except for other heads.", "Fake Key", key) as text|null)
|
||||
var/new_key = ckeyEx(clean_input("Enter your desired display name. Unlike normal stealth mode, this will not appear in Who at all, except for other heads.", "Fake Key", key))
|
||||
if(!new_key)
|
||||
return
|
||||
if(length(new_key) >= 26)
|
||||
@@ -638,7 +640,7 @@ var/list/admin_verbs_ticket = list(
|
||||
return
|
||||
|
||||
if(O)
|
||||
var/message = input("What do you want the message to be?", "Make Sound") as text|null
|
||||
var/message = clean_input("What do you want the message to be?", "Make Sound")
|
||||
if(!message)
|
||||
return
|
||||
for(var/mob/V in hearers(O))
|
||||
@@ -889,7 +891,7 @@ var/list/admin_verbs_ticket = list(
|
||||
to_chat(usr, "Your attack logs preference is now: show ALMOST ALL attack logs (notable exceptions: NPCs attacking other NPCs, vampire bites, equipping/stripping, people pushing each other over)")
|
||||
else if(prefs.atklog == ATKLOG_ALMOSTALL)
|
||||
prefs.atklog = ATKLOG_MOST
|
||||
to_chat(usr, "Your attack logs preference is now: show MOST attack logs (like ALMOST ALL, except that it also hides attacks by players on NPCs)")
|
||||
to_chat(usr, "Your attack logs preference is now: show MOST attack logs (like ALMOST ALL, except that it also hides player v. NPC combat, and certain areas like lavaland syndie base and thunderdome)")
|
||||
else if(prefs.atklog == ATKLOG_MOST)
|
||||
prefs.atklog = ATKLOG_FEW
|
||||
to_chat(usr, "Your attack logs preference is now: show FEW attack logs (only the most important stuff: attacks on SSDs, use of explosives, messing with the engine, gibbing, AI wiping, forcefeeding, acid sprays, and organ extraction)")
|
||||
@@ -1026,4 +1028,17 @@ var/list/admin_verbs_ticket = list(
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
holder.discord_duplicates()
|
||||
holder.discord_duplicates()
|
||||
|
||||
/client/proc/toggle_panic_bunker()
|
||||
set name = "Toggle Panic Bunker"
|
||||
set category = "Admin"
|
||||
set desc = "Disables new players connecting."
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
GLOB.panic_bunker_enabled = !GLOB.panic_bunker_enabled
|
||||
|
||||
log_admin("[key_name(usr)] has [GLOB.panic_bunker_enabled ? "activated" : "deactivated"] the panic bunker.")
|
||||
message_admins("[key_name_admin(usr)] has [GLOB.panic_bunker_enabled ? "activated" : "deactivated"] the panic bunker.")
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return
|
||||
if(!target_ckey)
|
||||
var/new_ckey = ckey(input(usr,"Who would you like to add a note for?","Enter a ckey",null) as text|null)
|
||||
var/new_ckey = ckey(clean_input("Who would you like to add a note for?","Enter a ckey",null))
|
||||
if(!new_ckey)
|
||||
return
|
||||
new_ckey = ckey(new_ckey)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
if(data["ckey"])
|
||||
ckey = ckey(data["ckey"])
|
||||
else
|
||||
ckey = input(usr,"Ckey","Ckey","") as text|null
|
||||
ckey = clean_input("Ckey","Ckey","")
|
||||
if(!ckey)
|
||||
return
|
||||
ckey = ckey(ckey)
|
||||
@@ -26,7 +26,7 @@
|
||||
if(data["reason"])
|
||||
ban["message"] = data["reason"]
|
||||
else
|
||||
var/reason = input(usr,"Reason","Reason","Ban Evasion") as text|null
|
||||
var/reason = clean_input("Reason","Reason","Ban Evasion")
|
||||
if(!reason)
|
||||
return
|
||||
ban["message"] = "[reason]"
|
||||
@@ -112,7 +112,7 @@
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!")
|
||||
return
|
||||
var/oldreason = ban["message"]
|
||||
var/reason = input(usr,"Reason","Reason","[ban["message"]]") as text|null
|
||||
var/reason = clean_input("Reason","Reason","[ban["message"]]")
|
||||
if(!reason || reason == oldreason)
|
||||
return
|
||||
//we have to do this again incase something changed while we waited for input
|
||||
|
||||
+16
-11
@@ -189,7 +189,7 @@
|
||||
|
||||
var/task = href_list["editrights"]
|
||||
if(task == "add")
|
||||
var/new_ckey = ckey(input(usr,"New admin's ckey","Admin ckey", null) as text|null)
|
||||
var/new_ckey = ckey(clean_input("New admin's ckey","Admin ckey", null))
|
||||
if(!new_ckey) return
|
||||
if(new_ckey in admin_datums)
|
||||
to_chat(usr, "<font color='red'>Error: Topic 'editrights': [new_ckey] is already an admin</font>")
|
||||
@@ -1015,14 +1015,14 @@
|
||||
return
|
||||
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0, M.lastKnownIP)
|
||||
to_chat(M, "<span class='warning'><BIG><B>You have been banned by [usr.client.ckey].\nReason: [reason].</B></BIG></span>")
|
||||
to_chat(M, "<span class='warning'>This is a permanent ban.</span>")
|
||||
to_chat(M, "<span class='warning'>This ban does not expire automatically and must be appealed.</span>")
|
||||
if(config.banappeals)
|
||||
to_chat(M, "<span class='warning'>To try to resolve this matter head to [config.banappeals]</span>")
|
||||
else
|
||||
to_chat(M, "<span class='warning'>No ban appeals URL has been set.</span>")
|
||||
ban_unban_log_save("[usr.client.ckey] has permabanned [M.ckey]. - Reason: [reason] - This is a permanent ban.")
|
||||
log_admin("[key_name(usr)] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.</span>")
|
||||
ban_unban_log_save("[usr.client.ckey] has permabanned [M.ckey]. - Reason: [reason] - This ban does not expire automatically and must be appealed.")
|
||||
log_admin("[key_name(usr)] has banned [M.ckey].\nReason: [reason]\nThis ban does not expire automatically and must be appealed.")
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] has banned [M.ckey].\nReason: [reason]\nThis ban does not expire automatically and must be appealed.</span>")
|
||||
feedback_inc("ban_perma",1)
|
||||
DB_ban_record(BANTYPE_PERMA, M, -1, reason)
|
||||
|
||||
@@ -1700,7 +1700,7 @@
|
||||
var/eviltype = input(src.owner, "Which type of evil fax do you wish to send [H]?","Its good to be baaaad...", "") as null|anything in etypes
|
||||
if(!(eviltype in etypes))
|
||||
return
|
||||
var/customname = input(src.owner, "Pick a title for the evil fax.", "Fax Title") as text|null
|
||||
var/customname = clean_input("Pick a title for the evil fax.", "Fax Title", , owner)
|
||||
if(!customname)
|
||||
customname = "paper"
|
||||
var/obj/item/paper/evilfax/P = new /obj/item/paper/evilfax(null)
|
||||
@@ -2001,7 +2001,7 @@
|
||||
if(!istype(H))
|
||||
to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human")
|
||||
return
|
||||
if(!isLivingSSD(H))
|
||||
if(!href_list["cryoafk"] && !isLivingSSD(H))
|
||||
to_chat(usr, "This can only be used on living, SSD players.")
|
||||
return
|
||||
if(istype(H.loc, /obj/machinery/cryopod))
|
||||
@@ -2012,6 +2012,11 @@
|
||||
else if(cryo_ssd(H))
|
||||
log_admin("[key_name(usr)] sent [H.job] [H] to cryo.")
|
||||
message_admins("[key_name_admin(usr)] sent [H.job] [H] to cryo.")
|
||||
if(href_list["cryoafk"]) // Warn them if they are send to storage and are AFK
|
||||
to_chat(H, "<span class='danger'>The admins have moved you to cryo storage for being AFK. Please eject yourself (right click, eject) out of the cryostorage if you want to avoid being despawned.</span>")
|
||||
SEND_SOUND(H, 'sound/effects/adminhelp.ogg')
|
||||
if(H.client)
|
||||
window_flash(H.client)
|
||||
else if(href_list["FaxReplyTemplate"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
@@ -2183,7 +2188,7 @@
|
||||
return
|
||||
input = P.parsepencode(input) // Encode everything from pencode to html
|
||||
|
||||
var/customname = input(src.owner, "Pick a title for the fax.", "Fax Title") as text|null
|
||||
var/customname = clean_input("Pick a title for the fax.", "Fax Title", , owner)
|
||||
if(!customname)
|
||||
customname = "paper"
|
||||
|
||||
@@ -2216,14 +2221,14 @@
|
||||
if("clown")
|
||||
stampvalue = "clown"
|
||||
else if(stamptype == "text")
|
||||
stampvalue = input(src.owner, "What should the stamp say?", "Stamp Text") as text|null
|
||||
stampvalue = clean_input("What should the stamp say?", "Stamp Text", , owner)
|
||||
else if(stamptype == "none")
|
||||
stamptype = ""
|
||||
else
|
||||
qdel(P)
|
||||
return
|
||||
|
||||
sendername = input(src.owner, "What organization does the fax come from? This determines the prefix of the paper (i.e. Central Command- Title). This is optional.", "Organization") as text|null
|
||||
sendername = clean_input("What organization does the fax come from? This determines the prefix of the paper (i.e. Central Command- Title). This is optional.", "Organization", , owner)
|
||||
|
||||
if(sender)
|
||||
notify = alert(src.owner, "Would you like to inform the original sender that a fax has arrived?","Notify Sender","Yes","No")
|
||||
@@ -3283,7 +3288,7 @@
|
||||
return
|
||||
var/datum/station_goal/G = new picked()
|
||||
if(picked == /datum/station_goal)
|
||||
var/newname = input("Enter goal name:") as text|null
|
||||
var/newname = clean_input("Enter goal name:")
|
||||
if(!newname)
|
||||
return
|
||||
G.name = newname
|
||||
|
||||
@@ -18,7 +18,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
|
||||
var/list/type = list("Mentorhelp","Adminhelp")
|
||||
var/selected_type = input("Pick a category.", "Admin Help", null, null) as null|anything in type
|
||||
if(selected_type)
|
||||
msg = input("Please enter your message.", "Admin Help", null, null) as text|null
|
||||
msg = clean_input("Please enter your message.", "Admin Help", null)
|
||||
|
||||
//clean the input msg
|
||||
if(!msg)
|
||||
@@ -27,7 +27,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
|
||||
if(handle_spam_prevention(msg, MUTE_ADMINHELP, OOC_COOLDOWN))
|
||||
return
|
||||
|
||||
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
|
||||
msg = sanitize_simple(copytext(msg,1,MAX_MESSAGE_LEN))
|
||||
if(!msg) return
|
||||
var/original_msg = msg
|
||||
|
||||
@@ -185,3 +185,4 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
|
||||
else
|
||||
send2irc(source, "[msg] - All admins AFK ([admin_number_afk]/[admin_number_total]) or skipped ([admin_number_ignored]/[admin_number_total])")
|
||||
return admin_number_present
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
set category = null
|
||||
set name = "Admin PM Mob"
|
||||
if(!holder)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM-Context: Only administrators may use this command.</font>")
|
||||
to_chat(src, "<span class='danger'>Error: Admin-PM-Context: Only administrators may use this command.</span>")
|
||||
return
|
||||
if( !ismob(M) || !M.client ) return
|
||||
cmd_admin_pm(M.client,null)
|
||||
@@ -14,7 +14,7 @@
|
||||
set category = "Admin"
|
||||
set name = "Admin PM Name"
|
||||
if(!holder)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM-Panel: Only administrators may use this command.</font>")
|
||||
to_chat(src, "<span class='danger'>Error: Admin-PM-Panel: Only administrators may use this command.</span>")
|
||||
return
|
||||
var/list/client/targets[0]
|
||||
for(var/client/T)
|
||||
@@ -37,7 +37,7 @@
|
||||
set category = "Admin"
|
||||
set name = "Admin PM Key"
|
||||
if(!holder)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM-Panel: Only administrators may use this command.</font>")
|
||||
to_chat(src, "<span class='danger'>Error: Admin-PM-Panel: Only administrators may use this command.</span>")
|
||||
return
|
||||
var/list/client/targets[0]
|
||||
for(var/client/T)
|
||||
@@ -60,7 +60,7 @@
|
||||
//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)
|
||||
to_chat(src, "<font color='red'>Error: Private-Message: You are unable to use PM-s (muted).</font>")
|
||||
to_chat(src, "<span class='danger'>Error: Private-Message: You are unable to use PM-s (muted).</span>")
|
||||
return
|
||||
|
||||
var/client/C
|
||||
@@ -89,7 +89,7 @@
|
||||
//get message text, limit it's length.and clean/escape html
|
||||
if(!msg)
|
||||
set_typing(C, TRUE)
|
||||
msg = input(src,"Message:", "Private message to [holder ? key_name(C, FALSE) : key_name_hidden(C, FALSE)]") as text|null
|
||||
msg = clean_input("Message:", "Private message to [holder ? key_name(C, FALSE) : key_name_hidden(C, FALSE)]", , src)
|
||||
set_typing(C, FALSE)
|
||||
|
||||
if(!msg)
|
||||
@@ -106,9 +106,11 @@
|
||||
|
||||
//clean the message if it's not sent by a high-rank admin
|
||||
if(!check_rights(R_SERVER|R_DEBUG,0))
|
||||
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
|
||||
msg = sanitize_simple(copytext(msg,1,MAX_MESSAGE_LEN))
|
||||
if(!msg)
|
||||
return
|
||||
else
|
||||
msg = pencode_to_html(msg)
|
||||
|
||||
var/recieve_span = "playerreply"
|
||||
var/send_pm_type = " "
|
||||
@@ -127,7 +129,7 @@
|
||||
recieve_pm_type = holder.rank
|
||||
|
||||
else if(!C.holder)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.</font>")
|
||||
to_chat(src, "<span class='danger'>Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.</span>")
|
||||
return
|
||||
|
||||
var/recieve_message = ""
|
||||
@@ -147,7 +149,7 @@
|
||||
spawn(0) //so we don't hold the caller proc up
|
||||
var/sender = src
|
||||
var/sendername = key
|
||||
var/reply = input(C, msg,"[recieve_pm_type] [type] from-[sendername]", "") as text|null //show message and await a reply
|
||||
var/reply = clean_input(msg,"[recieve_pm_type] [type] from-[sendername]", "", C) //show message and await a reply
|
||||
if(C && reply)
|
||||
if(sender)
|
||||
C.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them
|
||||
@@ -159,7 +161,7 @@
|
||||
var/emoji_msg = "<span class='emoji_enabled'>[msg]</span>"
|
||||
recieve_message = "<span class='[recieve_span]'>[type] from-<b>[recieve_pm_type][C.holder ? key_name(src, TRUE, type) : key_name_hidden(src, TRUE, type)]</b>: [emoji_msg]</span>"
|
||||
to_chat(C, recieve_message)
|
||||
to_chat(src, "<font color='blue'>[send_pm_type][type] to-<b>[holder ? key_name(C, TRUE, type) : key_name_hidden(C, TRUE, type)]</b>: [emoji_msg]</font>")
|
||||
to_chat(src, "<span class='pmsend'>[send_pm_type][type] to-<b>[holder ? key_name(C, TRUE, type) : key_name_hidden(C, TRUE, type)]</b>: [emoji_msg]</span>")
|
||||
|
||||
/*if(holder && !C.holder)
|
||||
C.last_pm_recieved = world.time
|
||||
@@ -213,10 +215,10 @@
|
||||
|
||||
/client/proc/cmd_admin_irc_pm()
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
to_chat(src, "<font color='red'>Error: Private-Message: You are unable to use PM-s (muted).</font>")
|
||||
to_chat(src, "<span class='danger'>Error: Private-Message: You are unable to use PM-s (muted).</span>")
|
||||
return
|
||||
|
||||
var/msg = input(src,"Message:", "Private message to admins on IRC / 400 character limit") as text|null
|
||||
var/msg = clean_input("Message:", "Private message to admins on IRC / 400 character limit", , src) as text|null
|
||||
|
||||
if(!msg)
|
||||
return
|
||||
@@ -230,14 +232,14 @@
|
||||
|
||||
send2adminirc("PlayerPM from [key_name(src)]: [html_decode(msg)]")
|
||||
|
||||
to_chat(src, "<font color='blue'>IRC PM to-<b>IRC-Admins</b>: [msg]</font>")
|
||||
to_chat(src, "<span class='pmsend'>IRC PM to-<b>IRC-Admins</b>: [msg]</span>")
|
||||
|
||||
log_admin("PM: [key_name(src)]->IRC: [msg]")
|
||||
for(var/client/X in GLOB.admins)
|
||||
if(X == src)
|
||||
continue
|
||||
if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, X.mob))
|
||||
to_chat(X, "<B><font color='blue'>PM: [key_name(src, TRUE, 0)]->IRC-Admins:</B> <span class='notice'>[msg]</span></font>")
|
||||
to_chat(X, "<B><span class='pmsend'>PM: [key_name(src, TRUE, 0)]->IRC-Admins:</B> <span class='notice'>[msg]</span></span>")
|
||||
|
||||
/client/verb/open_pms_ui()
|
||||
set name = "My PMs"
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
|
||||
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/get_admin_say()
|
||||
var/msg = input(src, null, "asay \"text\"") as text|null
|
||||
cmd_admin_say(msg)
|
||||
|
||||
/client/proc/cmd_mentor_say(msg as text)
|
||||
set category = "Admin"
|
||||
set name = "Msay"
|
||||
|
||||
@@ -43,3 +43,7 @@
|
||||
say_dead_direct("<span class='name'>[prefix]</span> says, <span class='message'>\"[msg]\"</span>")
|
||||
|
||||
feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/get_dead_say()
|
||||
var/msg = input(src, null, "dsay \"text\"") as text
|
||||
dsay(msg)
|
||||
@@ -68,7 +68,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
target = null
|
||||
targetselected = 0
|
||||
|
||||
var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
|
||||
var/procname = clean_input("Proc path, eg: /proc/fake_blood","Path:", null)
|
||||
if(!procname) return
|
||||
|
||||
if(targetselected && !hascall(target,procname))
|
||||
@@ -102,7 +102,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
if(!check_rights(R_PROCCALL))
|
||||
return
|
||||
|
||||
var/procname = input("Proc name, eg: fake_blood","Proc:", null) as text|null
|
||||
var/procname = clean_input("Proc name, eg: fake_blood","Proc:", null)
|
||||
if(!procname)
|
||||
return
|
||||
|
||||
@@ -149,7 +149,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
return null
|
||||
|
||||
if("text")
|
||||
lst += input("Enter new text:","Text",null) as text
|
||||
lst += clean_input("Enter new text:","Text",null)
|
||||
|
||||
if("num")
|
||||
lst += input("Enter new number:","Num",0) as num
|
||||
@@ -271,7 +271,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
return 0
|
||||
var/obj/item/paicard/card = new(T)
|
||||
var/mob/living/silicon/pai/pai = new(card)
|
||||
var/raw_name = input(choice, "Enter your pAI name:", "pAI Name", "Personal AI") as text
|
||||
var/raw_name = clean_input("Enter your pAI name:", "pAI Name", "Personal AI", choice)
|
||||
var/new_name = reject_bad_name(raw_name, 1)
|
||||
if(new_name)
|
||||
pai.name = new_name
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/filter = input("Contains what?","Filter") as text|null
|
||||
var/filter = clean_input("Contains what?","Filter")
|
||||
if(!filter)
|
||||
return
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/refstring = input("Which reference?","Ref") as text|null
|
||||
var/refstring = clean_input("Which reference?","Ref")
|
||||
if(!refstring)
|
||||
return
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ var/global/list/frozen_mob_list = list()
|
||||
|
||||
/mob/living/proc/admin_Freeze(var/client/admin, skip_overlays = FALSE)
|
||||
if(istype(admin))
|
||||
to_chat(src, "<b><font color= red>You have been frozen by [key_name(admin)]</b></font>")
|
||||
to_chat(src, "<b><font color= red>You have been frozen by [admin]</b></font>")
|
||||
message_admins("<span class='notice'>[key_name_admin(admin)]</span> froze [key_name_admin(src)]")
|
||||
log_admin("[key_name(admin)] froze [key_name(src)]")
|
||||
|
||||
@@ -45,7 +45,7 @@ var/global/list/frozen_mob_list = list()
|
||||
|
||||
/mob/living/proc/admin_unFreeze(var/client/admin, skip_overlays = FALSE)
|
||||
if(istype(admin))
|
||||
to_chat(src, "<b><font color= red>You have been unfrozen by [key_name(admin)]</b></font>")
|
||||
to_chat(src, "<b><font color= red>You have been unfrozen by [admin]</b></font>")
|
||||
message_admins("<span class='notice'>[key_name_admin(admin)] unfroze [key_name_admin(src)]</span>")
|
||||
log_admin("[key_name(admin)] unfroze [key_name(src)]")
|
||||
|
||||
|
||||
@@ -132,13 +132,13 @@ var/intercom_range_display_status = 0
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/level = input("Which z-level?","Level?") as text
|
||||
var/level = clean_input("Which z-level?","Level?")
|
||||
if(!level) return
|
||||
var/num_level = text2num(level)
|
||||
if(!num_level) return
|
||||
if(!isnum(num_level)) return
|
||||
|
||||
var/type_text = input("Which type path?","Path?") as text
|
||||
var/type_text = clean_input("Which type path?","Path?")
|
||||
if(!type_text) return
|
||||
var/type_path = text2path(type_text)
|
||||
if(!type_path) return
|
||||
@@ -170,7 +170,7 @@ var/intercom_range_display_status = 0
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/type_text = input("Which type path?","") as text
|
||||
var/type_text = clean_input("Which type path?","")
|
||||
if(!type_text) return
|
||||
var/type_path = text2path(type_text)
|
||||
if(!type_path) return
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
if(!check_rights(R_SERVER|R_EVENT))
|
||||
return
|
||||
|
||||
var/msg = input("Message:", text("Subtle PM to [M.key]")) as text
|
||||
var/msg = clean_input("Message:", text("Subtle PM to [M.key]"))
|
||||
|
||||
if(!msg)
|
||||
return
|
||||
@@ -109,10 +109,11 @@
|
||||
if(!check_rights(R_SERVER|R_EVENT))
|
||||
return
|
||||
|
||||
var/msg = input("Message:", text("Enter the text you wish to appear to everyone:")) as text
|
||||
var/msg = clean_input("Message:", text("Enter the text you wish to appear to everyone:"))
|
||||
|
||||
if(!msg)
|
||||
return
|
||||
msg = pencode_to_html(msg)
|
||||
to_chat(world, "[msg]")
|
||||
log_admin("GlobalNarrate: [key_name(usr)] : [msg]")
|
||||
message_admins("<span class='boldnotice'>GlobalNarrate: [key_name_admin(usr)]: [msg]<BR></span>", 1)
|
||||
@@ -131,10 +132,11 @@
|
||||
if(!M)
|
||||
return
|
||||
|
||||
var/msg = input("Message:", text("Enter the text you wish to appear to your target:")) as text
|
||||
var/msg = clean_input("Message:", text("Enter the text you wish to appear to your target:"))
|
||||
|
||||
if( !msg )
|
||||
return
|
||||
msg = pencode_to_html(msg)
|
||||
|
||||
to_chat(M, msg)
|
||||
log_admin("DirectNarrate: [key_name(usr)] to ([key_name(M)]): [msg]")
|
||||
@@ -169,7 +171,7 @@
|
||||
return
|
||||
|
||||
message_admins("[key_name_admin(src)] has started answering [key_name_admin(H)]'s [sender] request.")
|
||||
var/input = input("Please enter a message to reply to [key_name(H)] via their headset.", "Outgoing message from [sender]", "") as text|null
|
||||
var/input = clean_input("Please enter a message to reply to [key_name(H)] via their headset.", "Outgoing message from [sender]", "")
|
||||
if(!input)
|
||||
message_admins("[key_name_admin(src)] decided not to answer [key_name_admin(H)]'s [sender] request.")
|
||||
return
|
||||
@@ -550,7 +552,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
if(!check_rights(R_EVENT))
|
||||
return
|
||||
|
||||
var/input = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "") as text|null
|
||||
var/input = clean_input("Please enter anything you want the AI to do. Anything. Serious.", "What?", "")
|
||||
if(!input)
|
||||
return
|
||||
|
||||
@@ -603,14 +605,15 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
var/type = input(usr, "Pick a type of report to send", "Report Type", "") as anything in MsgType
|
||||
|
||||
if(type == "Custom")
|
||||
type = input(usr, "What would you like the report type to be?", "Report Type", "Encrypted Transmission") as text|null
|
||||
type = clean_input("What would you like the report type to be?", "Report Type", "Encrypted Transmission")
|
||||
|
||||
var/customname = input(usr, "Pick a title for the report.", "Title", MsgType[type]) as text|null
|
||||
var/customname = clean_input("Pick a title for the report.", "Title", MsgType[type])
|
||||
if(!customname)
|
||||
return
|
||||
var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What's the message?") as message|null
|
||||
if(!input)
|
||||
return
|
||||
input = html_encode(input)
|
||||
|
||||
switch(alert("Should this be announced to the general population?",,"Yes","No", "Cancel"))
|
||||
if("Yes")
|
||||
@@ -1001,6 +1004,57 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
msg += "</TABLE></BODY></HTML>"
|
||||
src << browse(msg, "window=Player_ssd_check")
|
||||
|
||||
/client/proc/list_afks()
|
||||
set category = "Admin"
|
||||
set name = "List AFKs"
|
||||
set desc = "Lists AFK players"
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
var/msg = "<html><head><title>AFK Report</title></head><body>"
|
||||
msg += "AFK Players:<BR><TABLE border='1'>"
|
||||
msg += "<TR><TD><B>Key</B></TD><TD><B>Real Name</B></TD><TD><B>Job</B></TD><TD><B>Mins AFK</B></TD><TD><B>Special Role</B></TD><TD><B>Area</B></TD><TD><B>PPN</B></TD><TD><B>Cryo</B></TD></TR>"
|
||||
var/mins_afk
|
||||
var/job_string
|
||||
var/key_string
|
||||
var/role_string
|
||||
for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
|
||||
if(H.client == null || H.stat == DEAD) // No clientless or dead
|
||||
continue
|
||||
mins_afk = round(H.client.inactivity / 600)
|
||||
if(mins_afk < config.list_afk_minimum)
|
||||
continue
|
||||
if(H.job)
|
||||
job_string = H.job
|
||||
else
|
||||
job_string = "-"
|
||||
key_string = H.key
|
||||
if(job_string in command_positions)
|
||||
job_string = "<U>" + job_string + "</U>"
|
||||
role_string = "-"
|
||||
var/obj_count = 0
|
||||
var/obj_string = ""
|
||||
if(H.mind)
|
||||
if(H.mind.special_role)
|
||||
role_string = "<U>[H.mind.special_role]</U>"
|
||||
if(!H.key && H.mind.key)
|
||||
key_string = H.mind.key
|
||||
for(var/datum/objective/O in all_objectives)
|
||||
if(O.target == H.mind)
|
||||
obj_count++
|
||||
if(obj_count > 0)
|
||||
obj_string = "<BR><U>Obj Target</U>"
|
||||
msg += "<TR><TD>[key_string]</TD><TD>[H.real_name]</TD><TD>[job_string]</TD><TD>[mins_afk]</TD><TD>[role_string][obj_string]</TD>"
|
||||
msg += "<TD>[get_area(H)]</TD><TD>[ADMIN_PP(H,"PP")]</TD>"
|
||||
if(istype(H.loc, /obj/machinery/cryopod))
|
||||
msg += "<TD><A href='?_src_=holder;cryossd=[H.UID()];cryoafk=1'>De-Spawn</A></TD>"
|
||||
else
|
||||
msg += "<TD><A href='?_src_=holder;cryossd=[H.UID()];cryoafk=1'>Cryo</A></TD>"
|
||||
msg += "</TR>"
|
||||
msg += "</TABLE></BODY></HTML>"
|
||||
src << browse(msg, "window=Player_afk_check")
|
||||
|
||||
/client/proc/toggle_ert_calling()
|
||||
set category = "Event"
|
||||
set name = "Toggle ERT"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
if(!target_ckey)
|
||||
var/new_ckey = ckey(input(usr,"Who would you like to add to the watchlist?","Enter a ckey",null) as text)
|
||||
var/new_ckey = ckey(clean_input("Who would you like to add to the watchlist?","Enter a ckey",null))
|
||||
if(!new_ckey)
|
||||
return
|
||||
new_ckey = sanitizeSQL(new_ckey)
|
||||
|
||||
@@ -77,9 +77,9 @@
|
||||
if(bombassembly)
|
||||
bombassembly.HasProximity(AM)
|
||||
|
||||
/obj/item/onetankbomb/Crossed(atom/movable/AM) //for mousetraps
|
||||
/obj/item/onetankbomb/Crossed(atom/movable/AM, oldloc) //for mousetraps
|
||||
if(bombassembly)
|
||||
bombassembly.Crossed(AM)
|
||||
bombassembly.Crossed(AM, oldloc)
|
||||
|
||||
/obj/item/onetankbomb/on_found(mob/finder) //for mousetraps
|
||||
if(bombassembly)
|
||||
|
||||
@@ -85,11 +85,11 @@
|
||||
a_right.HasProximity(AM)
|
||||
|
||||
|
||||
/obj/item/assembly_holder/Crossed(atom/movable/AM)
|
||||
/obj/item/assembly_holder/Crossed(atom/movable/AM, oldloc)
|
||||
if(a_left)
|
||||
a_left.Crossed(AM)
|
||||
a_left.Crossed(AM, oldloc)
|
||||
if(a_right)
|
||||
a_right.Crossed(AM)
|
||||
a_right.Crossed(AM, oldloc)
|
||||
|
||||
/obj/item/assembly_holder/on_found(mob/finder)
|
||||
if(a_left)
|
||||
@@ -116,7 +116,7 @@
|
||||
a_right.holder_movement()
|
||||
|
||||
/obj/item/assembly_holder/Move()
|
||||
..()
|
||||
. = ..()
|
||||
process_movement()
|
||||
return
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
|
||||
/obj/item/assembly/infra/Move()
|
||||
var/t = dir
|
||||
..()
|
||||
. = ..()
|
||||
dir = t
|
||||
qdel(first)
|
||||
|
||||
@@ -269,7 +269,7 @@
|
||||
/obj/effect/beam/i_beam/Bumped()
|
||||
hit()
|
||||
|
||||
/obj/effect/beam/i_beam/Crossed(atom/movable/AM)
|
||||
/obj/effect/beam/i_beam/Crossed(atom/movable/AM, oldloc)
|
||||
if(!isobj(AM) && !isliving(AM))
|
||||
return
|
||||
if(istype(AM, /obj/effect))
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/assembly/mousetrap/Crossed(atom/movable/AM)
|
||||
/obj/item/assembly/mousetrap/Crossed(atom/movable/AM, oldloc)
|
||||
if(armed)
|
||||
if(ishuman(AM))
|
||||
var/mob/living/carbon/H = AM
|
||||
|
||||
@@ -432,6 +432,8 @@
|
||||
l_pocket = /obj/item/reagent_containers/food/pill/patch/styptic
|
||||
r_pocket = /obj/item/flashlight/seclite
|
||||
|
||||
/obj/effect/mob_spawn/human/miner/explorer
|
||||
outfit = /datum/outfit/job/mining/equipped
|
||||
|
||||
/obj/effect/mob_spawn/human/bartender
|
||||
name = "Space Bartender"
|
||||
|
||||
@@ -36,9 +36,226 @@
|
||||
if(prob(1))
|
||||
mezzer()
|
||||
|
||||
|
||||
/obj/item/clothing/glasses/meson/truesight
|
||||
name = "The Lens of Truesight"
|
||||
desc = "I can see forever!"
|
||||
icon_state = "monocle"
|
||||
item_state = "headset"
|
||||
item_state = "headset"
|
||||
|
||||
// Die of Fate
|
||||
/obj/item/dice/d20/fate
|
||||
name = "\improper Die of Fate"
|
||||
desc = "A die with twenty sides. You can feel unearthly energies radiating from it. Using this might be VERY risky."
|
||||
icon_state = "d20"
|
||||
var/reusable = TRUE
|
||||
var/used = FALSE
|
||||
|
||||
/obj/item/dice/d20/fate/stealth
|
||||
name = "d20"
|
||||
desc = "A die with twenty sides. The preferred die to throw at the GM."
|
||||
|
||||
/obj/item/dice/d20/fate/one_use
|
||||
reusable = FALSE
|
||||
|
||||
/obj/item/dice/d20/fate/one_use/stealth
|
||||
name = "d20"
|
||||
desc = "A die with twenty sides. The preferred die to throw at the GM."
|
||||
|
||||
/obj/item/dice/d20/fate/cursed
|
||||
name = "cursed Die of Fate"
|
||||
desc = "A die with twenty sides. You feel that rolling this is a REALLY bad idea."
|
||||
color = "#00BB00"
|
||||
|
||||
rigged = DICE_TOTALLY_RIGGED
|
||||
rigged_value = 1
|
||||
|
||||
/obj/item/dice/d20/fate/diceroll(mob/user)
|
||||
. = ..()
|
||||
if(!used)
|
||||
if(!ishuman(user) || !user.mind || (user.mind in SSticker.mode.wizards))
|
||||
to_chat(user, "<span class='warning'>You feel the magic of the dice is restricted to ordinary humans!</span>")
|
||||
return
|
||||
|
||||
if(!reusable)
|
||||
used = TRUE
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("<span class='userdanger'>[src] flares briefly.</span>")
|
||||
|
||||
addtimer(CALLBACK(src, .proc/effect, user, .), 1 SECONDS)
|
||||
|
||||
/obj/item/dice/d20/fate/equipped(mob/user, slot)
|
||||
if(!ishuman(user) || !user.mind || (user.mind in SSticker.mode.wizards))
|
||||
to_chat(user, "<span class='warning'>You feel the magic of the dice is restricted to ordinary humans! You should leave it alone.</span>")
|
||||
user.unEquip(src)
|
||||
|
||||
/obj/item/dice/d20/fate/proc/create_smoke(amount)
|
||||
var/datum/effect_system/smoke_spread/smoke = new
|
||||
smoke.set_up(amount, 0, drop_location())
|
||||
smoke.start()
|
||||
|
||||
/obj/item/dice/d20/fate/proc/effect(var/mob/living/carbon/human/user, roll)
|
||||
var/turf/T = get_turf(src)
|
||||
switch(roll)
|
||||
if(1)
|
||||
//Dust
|
||||
T.visible_message("<span class='userdanger'>[user] turns to dust!</span>")
|
||||
user.dust()
|
||||
if(2)
|
||||
//Death
|
||||
T.visible_message("<span class='userdanger'>[user] suddenly dies!</span>")
|
||||
user.death()
|
||||
if(3)
|
||||
//Swarm of creatures
|
||||
T.visible_message("<span class='userdanger'>A swarm of creatures surround [user]!</span>")
|
||||
for(var/direction in alldirs)
|
||||
new /mob/living/simple_animal/hostile/netherworld(get_step(get_turf(user),direction))
|
||||
if(4)
|
||||
//Destroy Equipment
|
||||
T.visible_message("<span class='userdanger'>Everything [user] is holding and wearing disappears!</span>")
|
||||
for(var/obj/item/I in user)
|
||||
if(istype(I, /obj/item/implant) || istype(I, /obj/item/organ))
|
||||
continue
|
||||
qdel(I)
|
||||
if(5)
|
||||
//Monkeying
|
||||
T.visible_message("<span class='userdanger'>[user] transforms into a monkey!</span>")
|
||||
user.monkeyize()
|
||||
if(6)
|
||||
//Cut speed
|
||||
T.visible_message("<span class='userdanger'>[user] starts moving slower!</span>")
|
||||
var/datum/species/S = user.dna.species
|
||||
S.slowdown += 1
|
||||
if(7)
|
||||
//Throw
|
||||
T.visible_message("<span class='userdanger'>Unseen forces throw [user]!</span>")
|
||||
user.Stun(6)
|
||||
user.adjustBruteLoss(50)
|
||||
var/throw_dir = cardinal
|
||||
var/atom/throw_target = get_edge_target_turf(user, throw_dir)
|
||||
user.throw_at(throw_target, 200, 4)
|
||||
if(8)
|
||||
//Fueltank Explosion
|
||||
T.visible_message("<span class='userdanger'>An explosion bursts into existence around [user]!</span>")
|
||||
explosion(get_turf(user),-1,0,2, flame_range = 2)
|
||||
if(9)
|
||||
//Cold
|
||||
var/datum/disease/D = new /datum/disease/cold()
|
||||
T.visible_message("<span class='userdanger'>[user] looks a little under the weather!</span>")
|
||||
user.ForceContractDisease(D)
|
||||
if(10)
|
||||
//Nothing
|
||||
T.visible_message("<span class='userdanger'>Nothing seems to happen.</span>")
|
||||
if(11)
|
||||
//Cookie
|
||||
T.visible_message("<span class='userdanger'>A cookie appears out of thin air!</span>")
|
||||
var/obj/item/reagent_containers/food/snacks/cookie/C = new(drop_location())
|
||||
create_smoke(2)
|
||||
C.name = "Cookie of Fate"
|
||||
if(12)
|
||||
//Healing
|
||||
T.visible_message("<span class='userdanger'>[user] looks very healthy!</span>")
|
||||
user.revive()
|
||||
if(13)
|
||||
//Mad Dosh
|
||||
T.visible_message("<span class='userdanger'>Mad dosh shoots out of [src]!</span>")
|
||||
var/turf/Start = get_turf(src)
|
||||
for(var/direction in alldirs)
|
||||
var/turf/dirturf = get_step(Start,direction)
|
||||
if(rand(0,1))
|
||||
new /obj/item/stack/spacecash/c1000(dirturf)
|
||||
else
|
||||
var/obj/item/storage/bag/money/M = new(dirturf)
|
||||
for(var/i in 1 to rand(5,50))
|
||||
new /obj/item/coin/gold(M)
|
||||
if(14)
|
||||
//Free Gun
|
||||
T.visible_message("<span class='userdanger'>An impressive gun appears!</span>")
|
||||
create_smoke(2)
|
||||
new /obj/item/gun/projectile/revolver/mateba(drop_location())
|
||||
if(15)
|
||||
//Random One-use spellbook
|
||||
T.visible_message("<span class='userdanger'>A magical looking book drops to the floor!</span>")
|
||||
create_smoke(2)
|
||||
new /obj/item/spellbook/oneuse/random(drop_location())
|
||||
if(16)
|
||||
//Servant & Servant Summon
|
||||
T.visible_message("<span class='userdanger'>A Dice Servant appears in a cloud of smoke!</span>")
|
||||
var/mob/living/carbon/human/H = new(drop_location())
|
||||
create_smoke(2)
|
||||
|
||||
H.equipOutfit(/datum/outfit/butler)
|
||||
var/datum/mind/servant_mind = new /datum/mind()
|
||||
var/datum/objective/O = new
|
||||
O.owner = servant_mind
|
||||
O.target = user.mind
|
||||
O.explanation_text = "Serve [user.real_name]."
|
||||
servant_mind.objectives += O
|
||||
servant_mind.transfer_to(H)
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the servant of [user.real_name]?", ROLE_WIZARD, poll_time = 50)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Dice Servant")
|
||||
H.key = C.key
|
||||
to_chat(H, "<span class='notice'>You are a servant of [user.real_name]. You must do everything in your power to follow their orders.</span>")
|
||||
|
||||
var/obj/effect/proc_holder/spell/targeted/summonmob/S = new
|
||||
S.target_mob = H
|
||||
user.mind.AddSpell(S)
|
||||
|
||||
if(17)
|
||||
//Tator Kit
|
||||
T.visible_message("<span class='userdanger'>A suspicious box appears!</span>")
|
||||
new /obj/item/storage/box/syndicate(drop_location())
|
||||
create_smoke(2)
|
||||
if(18)
|
||||
//Captain ID
|
||||
T.visible_message("<span class='userdanger'>A golden identification card appears!</span>")
|
||||
new /obj/item/card/id/captains_spare(drop_location())
|
||||
create_smoke(2)
|
||||
if(19)
|
||||
//Instrinct Resistance
|
||||
T.visible_message("<span class='userdanger'>[user] looks very robust!</span>")
|
||||
var/datum/species/S = user.dna.species
|
||||
S.brute_mod *= 0.5
|
||||
S.burn_mod *= 0.5
|
||||
|
||||
if(20)
|
||||
//Free wizard!
|
||||
T.visible_message("<span class='userdanger'>Magic flows out of [src] and into [user]!</span>")
|
||||
user.mind.make_Wizard()
|
||||
|
||||
// Butler outfit
|
||||
/datum/outfit/butler
|
||||
name = "Butler"
|
||||
uniform = /obj/item/clothing/under/suit_jacket/really_black
|
||||
shoes = /obj/item/clothing/shoes/laceup
|
||||
head = /obj/item/clothing/head/bowlerhat
|
||||
glasses = /obj/item/clothing/glasses/monocle
|
||||
gloves = /obj/item/clothing/gloves/color/white
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/summonmob
|
||||
name = "Summon Servant"
|
||||
desc = "This spell can be used to call your servant, whenever you need it."
|
||||
charge_max = 100
|
||||
clothes_req = 0
|
||||
invocation = "JE VES"
|
||||
invocation_type = "whisper"
|
||||
range = -1
|
||||
level_max = 0 //cannot be improved
|
||||
cooldown_min = 100
|
||||
include_user = 1
|
||||
|
||||
var/mob/living/target_mob
|
||||
|
||||
action_icon_state = "summons"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/summonmob/cast(list/targets, mob/user = usr)
|
||||
if(!target_mob)
|
||||
return
|
||||
var/turf/Start = get_turf(user)
|
||||
for(var/direction in alldirs)
|
||||
var/turf/T = get_step(Start,direction)
|
||||
if(!T.density)
|
||||
target_mob.Move(T)
|
||||
|
||||
@@ -19,22 +19,22 @@
|
||||
* Areas
|
||||
*/
|
||||
//Gateroom gets its own APC specifically for the gate
|
||||
/area/awaymission/gateroom
|
||||
/area/awaymission/gateroom
|
||||
|
||||
//Library, medbay, storage room
|
||||
/area/awaymission/southblock
|
||||
/area/awaymission/southblock
|
||||
|
||||
//Arrivals, security, hydroponics, shuttles (since they dont move, they dont need specific areas)
|
||||
/area/awaymission/arrivalblock
|
||||
/area/awaymission/arrivalblock
|
||||
|
||||
//Crew quarters, cafeteria, chapel
|
||||
/area/awaymission/midblock
|
||||
/area/awaymission/midblock
|
||||
|
||||
//engineering, bridge (not really north but it doesnt really need its own APC)
|
||||
/area/awaymission/northblock
|
||||
/area/awaymission/northblock
|
||||
|
||||
//That massive research room
|
||||
/area/awaymission/research
|
||||
/area/awaymission/research
|
||||
|
||||
//Syndicate shuttle
|
||||
/area/awaymission/syndishuttle
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
/obj/effect/meatgrinder/New()
|
||||
icon_state = "blobpod"
|
||||
|
||||
/obj/effect/meatgrinder/Crossed(AM as mob|obj)
|
||||
/obj/effect/meatgrinder/Crossed(AM as mob|obj, oldloc)
|
||||
Bumped(AM)
|
||||
|
||||
/obj/effect/meatgrinder/Bumped(mob/M as mob|obj)
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/obj/effect/step_trigger/message
|
||||
var/message //the message to give to the mob
|
||||
var/once = 1
|
||||
|
||||
/obj/effect/step_trigger/message/Trigger(mob/M as mob)
|
||||
if(M.client)
|
||||
to_chat(M, "<span class='info'>[message]</span>")
|
||||
if(once)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/step_trigger/teleport_fancy
|
||||
var/locationx
|
||||
var/locationy
|
||||
var/uses = 1 //0 for infinite uses
|
||||
var/entersparks = 0
|
||||
var/exitsparks = 0
|
||||
var/entersmoke = 0
|
||||
var/exitsmoke = 0
|
||||
|
||||
/obj/effect/step_trigger/teleport_fancy/Trigger(mob/M as mob)
|
||||
var/dest = locate(locationx, locationy, z)
|
||||
M.Move(dest)
|
||||
|
||||
if(entersparks)
|
||||
do_sparks(4, 1, src)
|
||||
if(exitsparks)
|
||||
do_sparks(4, 1, dest)
|
||||
|
||||
if(entersmoke)
|
||||
var/datum/effect_system/smoke_spread/s = new
|
||||
s.set_up(4, 1, src, 0)
|
||||
s.start()
|
||||
if(exitsmoke)
|
||||
var/datum/effect_system/smoke_spread/s = new
|
||||
s.set_up(4, 1, dest, 0)
|
||||
s.start()
|
||||
|
||||
uses--
|
||||
if(uses == 0)
|
||||
qdel(src)
|
||||
@@ -65,7 +65,7 @@
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/portal_sensor/Crossed(A)
|
||||
/obj/effect/portal_sensor/Crossed(A, oldloc)
|
||||
trigger()
|
||||
|
||||
/obj/effect/portal_sensor/Uncrossed(A)
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
/client
|
||||
//////////////////////
|
||||
//BLACK MAGIC THINGS//
|
||||
//////////////////////
|
||||
parent_type = /datum
|
||||
////////////////
|
||||
//ADMIN THINGS//
|
||||
////////////////
|
||||
@@ -24,7 +28,7 @@
|
||||
|
||||
var/adminhelped = 0
|
||||
|
||||
var/gc_destroyed //Time when this object was destroyed.
|
||||
// var/gc_destroyed //Time when this object was destroyed. [Inherits from datum]
|
||||
|
||||
#ifdef TESTING
|
||||
var/running_find_references
|
||||
@@ -56,7 +60,7 @@
|
||||
var/list/related_accounts_ip = list() //So admins know why it isn't working - Used to determine what other accounts previously logged in from this ip
|
||||
var/list/related_accounts_cid = list() //So admins know why it isn't working - Used to determine what other accounts previously logged in from this computer id
|
||||
|
||||
preload_rsc = 1 // This is 0 so we can set it to an URL once the player logs in and have them download the resources from a different server.
|
||||
preload_rsc = 0 // This is 0 so we can set it to an URL once the player logs in and have them download the resources from a different server.
|
||||
|
||||
var/global/obj/screen/click_catcher/void
|
||||
|
||||
@@ -89,5 +93,5 @@
|
||||
// If set to true, this client can interact with atoms such as buttons and doors on top of regular machinery interaction
|
||||
var/advanced_admin_interaction = FALSE
|
||||
|
||||
// Has the client been varedited by an admin?
|
||||
var/var_edited = FALSE
|
||||
// Has the client been varedited by an admin? [Inherits from datum now]
|
||||
// var/var_edited = FALSE
|
||||
|
||||
@@ -297,27 +297,21 @@
|
||||
return null
|
||||
if(byond_build < config.minimum_client_build)
|
||||
alert(src, "You are using a byond build which is not supported by this server. Please use a build version of atleast [config.minimum_client_build].", "Incorrect build", "OK")
|
||||
del(src)
|
||||
qdel(src)
|
||||
return
|
||||
if(byond_version < SUGGESTED_CLIENT_VERSION) // Update is suggested, but not required.
|
||||
to_chat(src,"<span class='userdanger'>Your BYOND client (v: [byond_version]) is out of date. This can cause glitches. We highly suggest you download the latest client from http://www.byond.com/ before playing. </span>")
|
||||
|
||||
if(IsGuestKey(key))
|
||||
alert(src,"This server doesn't allow guest accounts to play. Please go to http://www.byond.com/ and register for a key.","Guest","OK")
|
||||
del(src)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
// Change the way they should download resources.
|
||||
if(config.resource_urls)
|
||||
preload_rsc = pick(config.resource_urls)
|
||||
else preload_rsc = 1 // If config.resource_urls is not set, preload like normal.
|
||||
|
||||
to_chat(src, "<span class='warning'>If the title screen is black, resources are still downloading. Please be patient until the title screen appears.</span>")
|
||||
|
||||
|
||||
GLOB.clients += src
|
||||
GLOB.directory[ckey] = src
|
||||
|
||||
//Admin Authorisation
|
||||
// Automatically makes localhost connection an admin
|
||||
if(!config.disable_localhost_admin)
|
||||
@@ -365,11 +359,14 @@
|
||||
|
||||
. = ..() //calls mob.Login()
|
||||
|
||||
|
||||
if(ckey in clientmessages)
|
||||
for(var/message in clientmessages[ckey])
|
||||
to_chat(src, message)
|
||||
clientmessages.Remove(ckey)
|
||||
|
||||
if(SSinput.initialized)
|
||||
set_macros()
|
||||
|
||||
donator_check()
|
||||
check_ip_intel()
|
||||
@@ -404,14 +401,23 @@
|
||||
|
||||
if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
|
||||
to_chat(src, "<span class='warning'>Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.</span>")
|
||||
|
||||
|
||||
|
||||
//This is down here because of the browse() calls in tooltip/New()
|
||||
if(!tooltips)
|
||||
tooltips = new /datum/tooltip(src)
|
||||
|
||||
Master.UpdateTickRate()
|
||||
|
||||
// Check total playercount
|
||||
var/playercount = 0
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.client)
|
||||
playercount += 1
|
||||
|
||||
if(playercount >= 150 && GLOB.panic_bunker_enabled == 0)
|
||||
GLOB.panic_bunker_enabled = 1
|
||||
message_admins("Panic bunker has been automatically enabled due to playercount surpassing 150")
|
||||
|
||||
/client/proc/is_connecting_from_localhost()
|
||||
var/localhost_addresses = list("127.0.0.1", "::1") // Adresses
|
||||
if(!isnull(address) && address in localhost_addresses)
|
||||
@@ -537,6 +543,14 @@
|
||||
message_admins("SQL ERROR during log_client_to_db (update). Error : \[[err]\]\n")
|
||||
else
|
||||
//New player!! Need to insert all the stuff
|
||||
|
||||
// Check new peeps for panic bunker
|
||||
if(GLOB.panic_bunker_enabled)
|
||||
message_admins("<span class='adminnotice'>Failed Login: [key] - New account attempting to connect during panic bunker</span>")
|
||||
src << "Sorry but the server is currently not accepting connections from never before seen players. Please try again later."
|
||||
del(src)
|
||||
return // Dont insert or they can just go in again
|
||||
|
||||
var/DBQuery/query_insert = dbcon.NewQuery("INSERT INTO [format_table_name("player")] (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, '[ckey]', Now(), Now(), '[sql_ip]', '[sql_computerid]', '[sql_admin_rank]')")
|
||||
if(!query_insert.Execute())
|
||||
var/err = query_insert.ErrorMsg()
|
||||
@@ -664,7 +678,7 @@
|
||||
sleep(10) // Since browse is non-instant, and kinda async
|
||||
|
||||
to_chat(src, "<pre class=\"system system\">you're a huge nerd. wakka wakka doodle doop nobody's ever gonna see this, the chat system shouldn't be online by this point</pre>")
|
||||
del(src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
else
|
||||
if (!topic || !topic["token"] || !tokens[ckey] || topic["token"] != tokens[ckey])
|
||||
@@ -675,7 +689,7 @@
|
||||
tokens[ckey] = cid_check_reconnect()
|
||||
|
||||
sleep(10) //browse is queued, we don't want them to disconnect before getting the browse() command.
|
||||
del(src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
// We DO have their cached CID handy - compare it, now
|
||||
if(oldcid != computer_id)
|
||||
@@ -693,7 +707,7 @@
|
||||
|
||||
log_adminwarn("Failed Login: [key] [computer_id] [address] - CID randomizer confirmed (oldcid: [oldcid])")
|
||||
|
||||
del(src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
else
|
||||
// don't shoot, I'm innocent
|
||||
@@ -754,6 +768,11 @@
|
||||
|
||||
//Send resources to the client.
|
||||
/client/proc/send_resources()
|
||||
// Change the way they should download resources.
|
||||
if(config.resource_urls)
|
||||
preload_rsc = pick(config.resource_urls)
|
||||
else
|
||||
preload_rsc = 1 // If config.resource_urls is not set, preload like normal.
|
||||
// Most assets are now handled through global_cache.dm
|
||||
getFiles(
|
||||
'html/search.js', // Used in various non-NanoUI HTML windows for search functionality
|
||||
@@ -795,18 +814,15 @@
|
||||
/* Mainwindow */
|
||||
winset(src, "mainwindow.saybutton", "background-color=#40628a;text-color=#FFFFFF")
|
||||
winset(src, "mainwindow.mebutton", "background-color=#40628a;text-color=#FFFFFF")
|
||||
winset(src, "mainwindow.hotkey_toggle", "background-color=#40628a;text-color=#FFFFFF")
|
||||
///// UI ELEMENTS /////
|
||||
/* Mainwindow */
|
||||
winset(src, "mainwindow", "background-color=#272727")
|
||||
winset(src, "mainwindow.mainvsplit", "background-color=#272727")
|
||||
winset(src, "mainwindow.tooltip", "background-color=#272727")
|
||||
/* Outputwindow */
|
||||
winset(src, "outputwindow.outputwindow", "background-color=#272727")
|
||||
winset(src, "outputwindow.browseroutput", "background-color=#272727")
|
||||
/* Rpane */
|
||||
winset(src, "rpane", "background-color=#272727")
|
||||
winset(src, "rpane.rpane", "background-color=#272727")
|
||||
winset(src, "rpane.rpanewindow", "background-color=#272727")
|
||||
/* Browserwindow */
|
||||
winset(src, "browserwindow", "background-color=#272727")
|
||||
@@ -830,18 +846,15 @@
|
||||
/* Mainwindow */
|
||||
winset(src, "mainwindow.saybutton", "background-color=none;text-color=#000000")
|
||||
winset(src, "mainwindow.mebutton", "background-color=none;text-color=#000000")
|
||||
winset(src, "mainwindow.hotkey_toggle", "background-color=none;text-color=#000000")
|
||||
///// UI ELEMENTS /////
|
||||
/* Mainwindow */
|
||||
winset(src, "mainwindow", "background-color=none")
|
||||
winset(src, "mainwindow.mainvsplit", "background-color=none")
|
||||
winset(src, "mainwindow.tooltip", "background-color=none")
|
||||
/* Outputwindow */
|
||||
winset(src, "outputwindow.outputwindow", "background-color=none")
|
||||
winset(src, "outputwindow.browseroutput", "background-color=none")
|
||||
/* Rpane */
|
||||
winset(src, "rpane", "background-color=none")
|
||||
winset(src, "rpane.rpane", "background-color=none")
|
||||
winset(src, "rpane.rpanewindow", "background-color=none")
|
||||
/* Browserwindow */
|
||||
winset(src, "browserwindow", "background-color=none")
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
/datum/gear/accessory/armband_sec
|
||||
display_name = " armband, security"
|
||||
path = /obj/item/clothing/accessory/armband/sec
|
||||
allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer", "Brig Physician")
|
||||
allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer", "Brig Physician", "Security Pod Pilot")
|
||||
|
||||
/datum/gear/accessory/armband_cargo
|
||||
display_name = "cargo armband"
|
||||
|
||||
@@ -93,6 +93,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
var/clientfps = 0
|
||||
var/atklog = ATKLOG_ALL
|
||||
var/fuid // forum userid
|
||||
var/afk_watch = FALSE // If the player wants to be kept track of by the AFK system
|
||||
|
||||
//ghostly preferences
|
||||
var/ghost_anonsay = 0
|
||||
@@ -439,6 +440,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
dat += "<h2>General Settings</h2>"
|
||||
if(user.client.holder)
|
||||
dat += "<b>Adminhelp sound:</b> <a href='?_src_=prefs;preference=hear_adminhelps'><b>[(sound & SOUND_ADMINHELP)?"On":"Off"]</b></a><br>"
|
||||
dat += "<b>AFK Cryoing:</b> <a href='?_src_=prefs;preference=afk_watch'>[(afk_watch) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Ambient Occlusion:</b> <a href='?_src_=prefs;preference=ambientocclusion'><b>[toggles & AMBIENT_OCCLUSION ? "Enabled" : "Disabled"]</b></a><br>"
|
||||
dat += "<b>Attack Animations:</b> <a href='?_src_=prefs;preference=ghost_att_anim'>[(show_ghostitem_attack) ? "Yes" : "No"]</a><br>"
|
||||
if(unlock_content)
|
||||
@@ -1261,7 +1263,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
if("input")
|
||||
switch(href_list["preference"])
|
||||
if("name")
|
||||
var/raw_name = input(user, "Choose your character's name:", "Character Preference") as text|null
|
||||
var/raw_name = clean_input("Choose your character's name:", "Character Preference", , user)
|
||||
if(!isnull(raw_name)) // Check to ensure that the user entered text (rather than cancel.)
|
||||
var/new_name = reject_bad_name(raw_name, 1)
|
||||
if(new_name)
|
||||
@@ -1977,6 +1979,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
if("winflash")
|
||||
windowflashing = !windowflashing
|
||||
|
||||
if("afk_watch")
|
||||
afk_watch = !afk_watch
|
||||
|
||||
if("UIcolor")
|
||||
var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!", UI_style_color) as color|null
|
||||
if(!UI_style_color_new) return
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
exp,
|
||||
clientfps,
|
||||
atklog,
|
||||
fuid
|
||||
fuid,
|
||||
afk_watch
|
||||
FROM [format_table_name("player")]
|
||||
WHERE ckey='[C.ckey]'"}
|
||||
)
|
||||
@@ -52,6 +53,7 @@
|
||||
clientfps = text2num(query.item[17])
|
||||
atklog = text2num(query.item[18])
|
||||
fuid = text2num(query.item[19])
|
||||
afk_watch = text2num(query.item[20])
|
||||
|
||||
//Sanitize
|
||||
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
|
||||
@@ -72,6 +74,7 @@
|
||||
clientfps = sanitize_integer(clientfps, 0, 1000, initial(clientfps))
|
||||
atklog = sanitize_integer(atklog, 0, 100, initial(atklog))
|
||||
fuid = sanitize_integer(fuid, 0, 10000000, initial(fuid))
|
||||
afk_watch = sanitize_integer(afk_watch, 0, 1, initial(afk_watch))
|
||||
return 1
|
||||
|
||||
/datum/preferences/proc/save_preferences(client/C)
|
||||
@@ -90,7 +93,7 @@
|
||||
UI_style_alpha='[UI_style_alpha]',
|
||||
be_role='[sanitizeSQL(list2params(be_special))]',
|
||||
default_slot='[default_slot]',
|
||||
toggles='[num2text(toggles, 7)]',
|
||||
toggles='[num2text(toggles, Ceiling(log(10, (TOGGLES_TOTAL))))]',
|
||||
atklog='[atklog]',
|
||||
sound='[sound]',
|
||||
randomslot='[randomslot]',
|
||||
@@ -101,7 +104,8 @@
|
||||
windowflashing='[windowflashing]',
|
||||
ghost_anonsay='[ghost_anonsay]',
|
||||
clientfps='[clientfps]',
|
||||
atklog='[atklog]'
|
||||
atklog='[atklog]',
|
||||
afk_watch='[afk_watch]'
|
||||
WHERE ckey='[C.ckey]'"}
|
||||
)
|
||||
|
||||
|
||||
@@ -241,7 +241,31 @@
|
||||
to_chat(usr, "<span class='notice'>You have enabled text popup limiting.")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You have disabled text popup limiting.")
|
||||
return
|
||||
|
||||
/client/verb/numpad_target()
|
||||
set name = "Toggle Numpad targetting"
|
||||
set category = "Preferences"
|
||||
set desc = "This button will allow you to enable or disable Numpad Targetting"
|
||||
prefs.toggles ^= NUMPAD_TARGET
|
||||
prefs.save_preferences(src)
|
||||
if (prefs.toggles & NUMPAD_TARGET)
|
||||
to_chat(usr, "<span class='notice'>You have enabled Numpad Targetting.")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You have disabled Numpad Targetting.")
|
||||
return
|
||||
|
||||
/client/verb/azerty_toggle()
|
||||
set name = "Toggle QWERTY/AZERTY"
|
||||
set category = "Preferences"
|
||||
set desc = "This button will switch you between QWERTY and AZERTY control sets"
|
||||
prefs.toggles ^= AZERTY
|
||||
prefs.save_preferences(src)
|
||||
if (prefs.toggles & AZERTY)
|
||||
to_chat(usr, "<span class='notice'>You are now in AZERTY mode.")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You are now in QWERTY mode.")
|
||||
return
|
||||
/client/verb/toggle_ghost_pda()
|
||||
set name = "Show/Hide GhostPDA"
|
||||
set category = "Preferences"
|
||||
@@ -249,4 +273,4 @@
|
||||
prefs.toggles ^= CHAT_GHOSTPDA
|
||||
to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTPDA) ? "see all PDA messages" : "no longer see PDA messages"].")
|
||||
prefs.save_preferences(src)
|
||||
feedback_add_details("admin_verb","TGP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
feedback_add_details("admin_verb","TGP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -110,12 +110,23 @@
|
||||
/obj/item/clothing/mask/muzzle/safety
|
||||
name = "safety muzzle"
|
||||
desc = "A muzzle designed to prevent biting."
|
||||
resist_time = 600
|
||||
icon_state = "muzzle_secure"
|
||||
item_state = "muzzle_secure"
|
||||
resist_time = 0
|
||||
mute = MUZZLE_MUTE_NONE
|
||||
security_lock = TRUE
|
||||
locked = FALSE
|
||||
materials = list(MAT_METAL=500, MAT_GLASS=50)
|
||||
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/mask.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
|
||||
"Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/mask.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/mask.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/mask/muzzle/safety/shock
|
||||
name = "shock muzzle"
|
||||
desc = "A muzzle designed to prevent biting. This one is fitted with a behavior correction system."
|
||||
|
||||
@@ -71,6 +71,30 @@ obj/item/clothing/shoes/magboots/syndie/advance //For the Syndicate Strike Team
|
||||
silence_steps = 1
|
||||
shoe_sound = "clownstep"
|
||||
origin_tech = "magnets=4;syndicate=2"
|
||||
var/enabled_waddle = TRUE
|
||||
var/datum/component/waddle
|
||||
|
||||
/obj/item/clothing/shoes/magboots/clown/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(slot == slot_shoes && enabled_waddle)
|
||||
waddle = user.AddComponent(/datum/component/waddling)
|
||||
|
||||
/obj/item/clothing/shoes/magboots/clown/dropped(mob/user)
|
||||
. = ..()
|
||||
QDEL_NULL(waddle)
|
||||
|
||||
/obj/item/clothing/shoes/magboots/clown/CtrlClick(mob/living/user)
|
||||
if(!isliving(user))
|
||||
return
|
||||
if(user.get_active_hand() != src)
|
||||
to_chat(user, "You must hold [src] in your hand to do this.")
|
||||
return
|
||||
if(!enabled_waddle)
|
||||
to_chat(user, "<span class='notice'>You switch off the waddle dampeners!</span>")
|
||||
enabled_waddle = TRUE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You switch on the waddle dampeners!</span>")
|
||||
enabled_waddle = FALSE
|
||||
|
||||
/obj/item/clothing/shoes/magboots/wizard //bundled with the wiz hardsuit
|
||||
name = "boots of gripping"
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
t_loc.MakeDry(TURF_WET_WATER)
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes
|
||||
desc = "The prankster's standard-issue clowning shoes. Damn they're huge!"
|
||||
desc = "The prankster's standard-issue clowning shoes. Damn they're huge! Ctrl-click to toggle the waddle dampeners!"
|
||||
name = "clown shoes"
|
||||
icon_state = "clown"
|
||||
item_state = "clown_shoes"
|
||||
@@ -63,6 +63,30 @@
|
||||
item_color = "clown"
|
||||
var/footstep = 1 //used for squeeks whilst walking
|
||||
shoe_sound = "clownstep"
|
||||
var/enabled_waddle = TRUE
|
||||
var/datum/component/waddle
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(slot == slot_shoes && enabled_waddle)
|
||||
waddle = user.AddComponent(/datum/component/waddling)
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/dropped(mob/user)
|
||||
. = ..()
|
||||
QDEL_NULL(waddle)
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/CtrlClick(mob/living/user)
|
||||
if(!isliving(user))
|
||||
return
|
||||
if(user.get_active_hand() != src)
|
||||
to_chat(user, "You must hold [src] in your hand to do this.")
|
||||
return
|
||||
if(!enabled_waddle)
|
||||
to_chat(user, "<span class='notice'>You switch off the waddle dampeners!</span>")
|
||||
enabled_waddle = TRUE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You switch on the waddle dampeners!</span>")
|
||||
enabled_waddle = FALSE
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/magical
|
||||
name = "magical clown shoes"
|
||||
|
||||
@@ -182,34 +182,7 @@
|
||||
materials = list(MAT_METAL=1000)
|
||||
burn_state = FIRE_PROOF
|
||||
|
||||
/obj/item/clothing/accessory/medal/conduct
|
||||
name = "distinguished conduct medal"
|
||||
desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is the most basic award given by Nanotrasen. It is often awarded by a captain to a member of his crew."
|
||||
|
||||
/obj/item/clothing/accessory/medal/bronze_heart
|
||||
name = "bronze heart medal"
|
||||
desc = "A bronze heart-shaped medal awarded for sacrifice. It is often awarded posthumously or for severe injury in the line of duty."
|
||||
icon_state = "bronze_heart"
|
||||
|
||||
/obj/item/clothing/accessory/medal/nobel_science
|
||||
name = "nobel sciences award"
|
||||
desc = "A bronze medal which represents significant contributions to the field of science or engineering."
|
||||
|
||||
/obj/item/clothing/accessory/medal/silver
|
||||
name = "silver medal"
|
||||
desc = "A silver medal."
|
||||
icon_state = "silver"
|
||||
item_color = "silver"
|
||||
materials = list(MAT_SILVER=1000)
|
||||
|
||||
/obj/item/clothing/accessory/medal/silver/valor
|
||||
name = "medal of valor"
|
||||
desc = "A silver medal awarded for acts of exceptional valor."
|
||||
|
||||
/obj/item/clothing/accessory/medal/silver/security
|
||||
name = "robust security award"
|
||||
desc = "An award for distinguished combat and sacrifice in defence of Nanotrasen's commercial interests. Often awarded to security staff."
|
||||
|
||||
// GOLD (awarded by centcom)
|
||||
/obj/item/clothing/accessory/medal/gold
|
||||
name = "gold medal"
|
||||
desc = "A prestigious golden medal."
|
||||
@@ -223,7 +196,61 @@
|
||||
|
||||
/obj/item/clothing/accessory/medal/gold/heroism
|
||||
name = "medal of exceptional heroism"
|
||||
desc = "An extremely rare golden medal awarded only by CentComm. To recieve such a medal is the highest honor and as such, very few exist. This medal is almost never awarded to anybody but commanders."
|
||||
desc = "An extremely rare golden medal awarded only by CentComm. To recieve such a medal is the highest honor and as such, very few exist."
|
||||
|
||||
// SILVER (awarded by Captain)
|
||||
|
||||
/obj/item/clothing/accessory/medal/silver
|
||||
name = "silver medal"
|
||||
desc = "A silver medal."
|
||||
icon_state = "silver"
|
||||
item_color = "silver"
|
||||
materials = list(MAT_SILVER=1000)
|
||||
|
||||
/obj/item/clothing/accessory/medal/silver/valor
|
||||
name = "medal of valor"
|
||||
desc = "An award issued by Captains to crew members whose exceptional performance and service to the station has been commended by the station's top leadership."
|
||||
|
||||
/obj/item/clothing/accessory/medal/silver/leadership
|
||||
name = "medal of command"
|
||||
desc = "An award issued by Captains to heads of department who do an excellent job managing their department. Made of pure silver."
|
||||
|
||||
|
||||
// BRONZE (awarded by heads of department, except for the bronze heart)
|
||||
|
||||
|
||||
|
||||
/obj/item/clothing/accessory/medal/security
|
||||
name = "robust security medal"
|
||||
desc = "An award issued by the HoS to security staff who excel at upholding the law."
|
||||
|
||||
/obj/item/clothing/accessory/medal/science
|
||||
name = "smart science medal"
|
||||
desc = "An award issued by the RD to science staff who advance the frontiers of knowledge."
|
||||
|
||||
/obj/item/clothing/accessory/medal/engineering
|
||||
name = "excellent engineering medal"
|
||||
desc = "An award issued by the CE to engineering staff whose dedication keep the station running at its best."
|
||||
|
||||
/obj/item/clothing/accessory/medal/service
|
||||
name = "superior service medal"
|
||||
desc = "An award issued by the HoP to service staff who go above and beyond."
|
||||
|
||||
/obj/item/clothing/accessory/medal/medical
|
||||
name = "magnificient medical medal"
|
||||
desc = "An award issued by the CMO to medical staff who excel at saving lives."
|
||||
|
||||
/obj/item/clothing/accessory/medal/legal
|
||||
name = "meritous legal medal"
|
||||
desc = "An award issued by the Magistrate to legal staff who uphold the rule of law."
|
||||
|
||||
/obj/item/clothing/accessory/medal/heart
|
||||
name = "bronze heart medal"
|
||||
desc = "A rarely-awarded medal for those who sacrifice themselves in the line of duty to save their fellow crew."
|
||||
icon_state = "bronze_heart"
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Holobadges are worn on the belt or neck, and can be used to show that the holder is an authorized
|
||||
|
||||
@@ -463,6 +463,14 @@
|
||||
/obj/item/stack/sheet/animalhide/ashdrake = 5)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/tribal_splint
|
||||
name = "Tribal Splint"
|
||||
time = 20
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 1)
|
||||
result = /obj/item/stack/medical/splint/tribal
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/guillotine
|
||||
name = "Guillotine"
|
||||
result = /obj/structure/guillotine
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
else
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Unable to connect to accounts database.</span>")
|
||||
if("trans_purpose")
|
||||
var/purpose = input("Enter reason for EFTPOS transaction", "Transaction purpose", transaction_purpose) as text|null
|
||||
var/purpose = clean_input("Enter reason for EFTPOS transaction", "Transaction purpose", transaction_purpose)
|
||||
if(purpose)
|
||||
transaction_purpose = purpose
|
||||
if("trans_value")
|
||||
|
||||
@@ -7,21 +7,27 @@
|
||||
|
||||
/datum/event/blob/start()
|
||||
processing = FALSE //so it won't fire again in next tick
|
||||
|
||||
var/turf/T = pick(blobstart)
|
||||
if(!T)
|
||||
return kill()
|
||||
|
||||
var/list/candidates = pollCandidates("Do you want to play as a blob infested mouse?", ROLE_BLOB, 1)
|
||||
if(!candidates.len)
|
||||
return kill()
|
||||
|
||||
var/list/vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in GLOB.all_vent_pumps)
|
||||
if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
|
||||
if(temp_vent.parent.other_atmosmch.len > 50)
|
||||
vents += temp_vent
|
||||
|
||||
var/obj/vent = pick(vents)
|
||||
var/mob/living/simple_animal/mouse/blobinfected/B = new(vent.loc)
|
||||
var/mob/M = pick(candidates)
|
||||
B.key = M.key
|
||||
SSticker.mode.update_blob_icons_added(B.mind)
|
||||
|
||||
to_chat(B, "<span class='userdanger'>You are now a mouse, infected with blob spores. Find somewhere isolated... before you burst and become the blob! Use ventcrawl (alt-click on vents) to move around.</span>")
|
||||
notify_ghosts("Infected Mouse has appeared in [get_area(B)].", source = B)
|
||||
processing = TRUE // Let it naturally end, if it runs successfully
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/event/disease_outbreak
|
||||
announceWhen = 15
|
||||
|
||||
var/virus_type
|
||||
var/datum/disease/advance/virus_type
|
||||
|
||||
/datum/event/disease_outbreak/setup()
|
||||
announceWhen = rand(15, 30)
|
||||
@@ -10,9 +10,13 @@
|
||||
event_announcement.Announce("Confirmed outbreak of level 7 major viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
|
||||
|
||||
/datum/event/disease_outbreak/start()
|
||||
if(!virus_type)
|
||||
if(prob(25))
|
||||
virus_type = pick(/datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis, /datum/disease/beesease, /datum/disease/anxiety, /datum/disease/fake_gbs, /datum/disease/fluspanish, /datum/disease/pierrot_throat, /datum/disease/lycan)
|
||||
|
||||
else
|
||||
virus_type = new /datum/disease/advance
|
||||
virus_type.name = capitalize(pick(GLOB.adjectives)) + " " + capitalize(pick(GLOB.nouns,GLOB.verbs)) // random silly name
|
||||
virus_type.GenerateSymptoms(1,9,6)
|
||||
virus_type.AssignProperties(list("resistance" = rand(0,11), "stealth" = rand(0,2), "stage_rate" = rand(0,5), "transmittable" = rand(0,5), "severity" = rand(0,10)))
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list))
|
||||
if(issmall(H)) //don't infect monkies; that's a waste
|
||||
continue
|
||||
@@ -32,8 +36,8 @@
|
||||
if(H.stat == DEAD || foundAlready)
|
||||
continue
|
||||
|
||||
var/datum/disease/D
|
||||
D = new virus_type()
|
||||
var/datum/disease/advance/D
|
||||
D = virus_type
|
||||
D.carrier = TRUE
|
||||
H.AddDisease(D)
|
||||
break
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/event/sentience
|
||||
|
||||
/datum/event/sentience/start()
|
||||
processing = FALSE //so it won't fire again in next tick
|
||||
|
||||
var/ghostmsg = "Do you want to awaken as a sentient being?"
|
||||
var/list/candidates = pollCandidates(ghostmsg, ROLE_SENTIENT, 1)
|
||||
var/list/potential = list()
|
||||
@@ -41,6 +43,7 @@
|
||||
SA.del_on_death = FALSE
|
||||
greet_sentient(SA)
|
||||
print_command_report(sentience_report, "[command_name()] Update")
|
||||
processing = TRUE // Let it naturally end, if it runs successfully
|
||||
|
||||
/datum/event/sentience/proc/greet_sentient(var/mob/living/carbon/human/M)
|
||||
to_chat(M, "<span class='userdanger'>Hello world!</span>")
|
||||
|
||||
@@ -514,7 +514,7 @@
|
||||
/obj/structure/spacevine/obj_destruction()
|
||||
wither()
|
||||
|
||||
/obj/structure/spacevine/Crossed(mob/crosser)
|
||||
/obj/structure/spacevine/Crossed(mob/crosser, oldloc)
|
||||
if(isliving(crosser))
|
||||
for(var/datum/spacevine_mutation/SM in mutations)
|
||||
SM.on_cross(src, crosser)
|
||||
|
||||
@@ -589,7 +589,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
health -= P.force
|
||||
return
|
||||
|
||||
/obj/effect/fake_attacker/Crossed(mob/M, somenumber)
|
||||
/obj/effect/fake_attacker/Crossed(mob/M, oldloc)
|
||||
if(M == my_target)
|
||||
step_away(src,my_target,2)
|
||||
if(prob(30))
|
||||
|
||||
@@ -256,6 +256,7 @@
|
||||
desc = "Full of vitamins and deliciousness!"
|
||||
icon_state = "orangejuice"
|
||||
item_state = "carton"
|
||||
throwforce = 0
|
||||
isGlass = 0
|
||||
list_reagents = list("orangejuice" = 100)
|
||||
|
||||
@@ -264,6 +265,7 @@
|
||||
desc = "It's cream. Made from milk. What else did you think you'd find in there?"
|
||||
icon_state = "cream"
|
||||
item_state = "carton"
|
||||
throwforce = 0
|
||||
isGlass = 0
|
||||
list_reagents = list("cream" = 100)
|
||||
|
||||
@@ -272,6 +274,7 @@
|
||||
desc = "Well, at least it LOOKS like tomato juice. You can't tell with all that redness."
|
||||
icon_state = "tomatojuice"
|
||||
item_state = "carton"
|
||||
throwforce = 0
|
||||
isGlass = 0
|
||||
list_reagents = list("tomatojuice" = 100)
|
||||
|
||||
@@ -280,6 +283,7 @@
|
||||
desc = "Sweet-sour goodness."
|
||||
icon_state = "limejuice"
|
||||
item_state = "carton"
|
||||
throwforce = 0
|
||||
isGlass = 0
|
||||
list_reagents = list("limejuice" = 100)
|
||||
|
||||
@@ -288,6 +292,7 @@
|
||||
desc = "Soothing milk."
|
||||
icon_state = "milk"
|
||||
item_state = "carton"
|
||||
throwforce = 0
|
||||
isGlass = 0
|
||||
list_reagents = list("milk" = 100)
|
||||
|
||||
|
||||
@@ -68,3 +68,10 @@
|
||||
icon_state = "macncheese"
|
||||
filling_color = "#ffe45d"
|
||||
list_reagents = list("nutriment" = 5, "vitamin" = 2, "cheese" = 4)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/lasagna
|
||||
name = "Lasagna"
|
||||
icon_state = "lasagna"
|
||||
desc = "Tajarans loves to eat this, for some reason."
|
||||
filling_color = "#E18712"
|
||||
list_reagents = list("nutriment" = 10, "msg" = 3, "vitamin" = 4, "tomatojuice" = 10)
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
if(istype(I, /obj/item/pen/))
|
||||
if(open)
|
||||
return
|
||||
var/t = input("Enter what you want to add to the tag:", "Write", null, null) as text
|
||||
var/t = clean_input("Enter what you want to add to the tag:", "Write", null)
|
||||
var/obj/item/pizzabox/boxtotagto = src
|
||||
if(boxes.len > 0)
|
||||
boxtotagto = boxes[boxes.len]
|
||||
|
||||
@@ -467,3 +467,16 @@
|
||||
/obj/item/reagent_containers/food/snacks/stuffing
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/sliceable/turkey
|
||||
|
||||
/datum/recipe/oven/lasagna
|
||||
items = list(
|
||||
/obj/item/reagent_containers/food/snacks/meat,
|
||||
/obj/item/reagent_containers/food/snacks/meat,
|
||||
/obj/item/reagent_containers/food/snacks/cheesewedge,
|
||||
/obj/item/reagent_containers/food/snacks/cheesewedge,
|
||||
/obj/item/reagent_containers/food/snacks/cheesewedge,
|
||||
/obj/item/reagent_containers/food/snacks/grown/tomato,
|
||||
/obj/item/reagent_containers/food/snacks/grown/tomato,
|
||||
/obj/item/reagent_containers/food/snacks/dough
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/lasagna
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
T.on_consume(src, usr)
|
||||
..()
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/Crossed(atom/movable/AM)
|
||||
/obj/item/reagent_containers/food/snacks/grown/Crossed(atom/movable/AM, oldloc)
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_cross(src, AM)
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
..()
|
||||
StartBurning()
|
||||
|
||||
/obj/structure/bonfire/Crossed(atom/movable/AM)
|
||||
/obj/structure/bonfire/Crossed(atom/movable/AM, oldloc)
|
||||
if(burning)
|
||||
Burn()
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
return 0
|
||||
|
||||
|
||||
/obj/item/grown/Crossed(atom/movable/AM)
|
||||
/obj/item/grown/Crossed(atom/movable/AM, oldloc)
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_cross(src, AM)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/datum/admins/key_down(_key, client/user)
|
||||
switch(_key)
|
||||
if("F5")
|
||||
user.get_admin_say()
|
||||
return
|
||||
if("F6")
|
||||
user.admin_ghost()
|
||||
return
|
||||
if("F7")
|
||||
player_panel_new()
|
||||
return
|
||||
if("F8")
|
||||
user.cmd_admin_pm_panel()
|
||||
return
|
||||
if("F9")
|
||||
user.invisimin()
|
||||
return
|
||||
if("F10")
|
||||
user.get_dead_say()
|
||||
return
|
||||
..()
|
||||
@@ -0,0 +1,21 @@
|
||||
// You might be wondering why this isn't client level. If focus is null, we don't want you to move.
|
||||
// Only way to do that is to tie the behavior into the focus's keyLoop().
|
||||
|
||||
/atom/movable/keyLoop(client/user)
|
||||
if(!user.keys_held["Ctrl"])
|
||||
var/movement_dir = NONE
|
||||
var/list/movement = SSinput.movement_keys
|
||||
if(user.prefs.toggles & AZERTY)
|
||||
movement = SSinput.alt_movement_keys
|
||||
for(var/_key in user.keys_held)
|
||||
movement_dir = movement_dir | movement[_key]
|
||||
if(user.next_move_dir_add)
|
||||
movement_dir |= user.next_move_dir_add
|
||||
if(user.next_move_dir_sub)
|
||||
movement_dir &= ~user.next_move_dir_sub
|
||||
// Sanity checks in case you hold left and right and up to make sure you only go up
|
||||
if((movement_dir & NORTH) && (movement_dir & SOUTH))
|
||||
movement_dir &= ~(NORTH|SOUTH)
|
||||
if((movement_dir & EAST) && (movement_dir & WEST))
|
||||
movement_dir &= ~(EAST|WEST)
|
||||
user.Move(get_step(src, movement_dir), movement_dir)
|
||||
@@ -0,0 +1,20 @@
|
||||
/mob/living/carbon/key_down(_key, client/user)
|
||||
user.keys_held[_key] = world.time
|
||||
if(!user.keys_held["Shift"])
|
||||
switch(_key)
|
||||
if("R", "Southwest") // Southwest is End
|
||||
toggle_throw_mode()
|
||||
return
|
||||
if("1")
|
||||
a_intent_change("help")
|
||||
return
|
||||
if("2")
|
||||
a_intent_change("disarm")
|
||||
return
|
||||
if("3")
|
||||
a_intent_change("grab")
|
||||
return
|
||||
if("4")
|
||||
a_intent_change("harm")
|
||||
return
|
||||
return ..()
|
||||
@@ -0,0 +1,59 @@
|
||||
// Clients aren't datums so we have to define these procs indpendently.
|
||||
// These verbs are called for all key press and release events
|
||||
/client/verb/keyDown(_key as text)
|
||||
set instant = TRUE
|
||||
set hidden = TRUE
|
||||
keys_held[_key] = world.time
|
||||
var/movement = SSinput.movement_keys[_key]
|
||||
if (prefs.toggles & AZERTY) movement = SSinput.alt_movement_keys[_key]
|
||||
if(!(next_move_dir_sub & movement) && !keys_held["Ctrl"])
|
||||
next_move_dir_add |= movement
|
||||
|
||||
// Client-level keybindings are ones anyone should be able to do at any time
|
||||
// Things like taking screenshots, hitting tab, and adminhelps.
|
||||
|
||||
switch(_key)
|
||||
if("F1")
|
||||
if(keys_held["Ctrl"] && keys_held["Shift"]) // Is this command ever used?
|
||||
winset(src, null, "command=.options")
|
||||
else
|
||||
adminhelp()
|
||||
return
|
||||
if("F2") // Screenshot. Hold shift to choose a name and location to save in
|
||||
ooc()
|
||||
return
|
||||
if("F3")
|
||||
mob.say_wrapper()
|
||||
return
|
||||
if("F4")
|
||||
mob.me_wrapper()
|
||||
return
|
||||
if("F12") // Toggles minimal HUD
|
||||
mob.button_pressed_F12()
|
||||
return
|
||||
|
||||
if(holder)
|
||||
holder.key_down(_key, src)
|
||||
if(mob.focus)
|
||||
mob.focus.key_down(_key, src)
|
||||
|
||||
/client/verb/keyUp(_key as text)
|
||||
set instant = TRUE
|
||||
set hidden = TRUE
|
||||
keys_held -= _key
|
||||
var/movement = SSinput.movement_keys[_key]
|
||||
if (prefs.toggles & AZERTY) movement = SSinput.alt_movement_keys[_key]
|
||||
if(!(next_move_dir_add & movement))
|
||||
next_move_dir_sub |= movement
|
||||
|
||||
if(holder)
|
||||
holder.key_up(_key, src)
|
||||
if(mob.focus)
|
||||
mob.focus.key_up(_key, src)
|
||||
|
||||
// Called every game tick
|
||||
/client/keyLoop()
|
||||
if(holder)
|
||||
holder.keyLoop(src)
|
||||
if(mob.focus)
|
||||
mob.focus.keyLoop(src)
|
||||
@@ -0,0 +1,80 @@
|
||||
/mob/living/carbon/human/key_down(_key, client/user)
|
||||
if(_key == "H")
|
||||
var/obj/item/clothing/accessory/holster/H = null
|
||||
if(istype(w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/S = w_uniform
|
||||
if(S.accessories.len)
|
||||
H = locate() in S.accessories
|
||||
if (!H)
|
||||
return
|
||||
if(!H.holstered)
|
||||
if(!istype(get_active_hand(), /obj/item/gun))
|
||||
to_chat(usr, "<span class='warning'>You need your gun equiped to holster it.</span>")
|
||||
return
|
||||
var/obj/item/gun/W = get_active_hand()
|
||||
H.holster(W, usr)
|
||||
else
|
||||
H.unholster(usr)
|
||||
if(client.keys_held["Shift"])
|
||||
switch(_key)
|
||||
if("E") // Put held thing in belt or take out most recent thing from belt
|
||||
quick_equip() // Implementing the storage component is going to take way too long
|
||||
// var/obj/item/thing = get_active_hand()
|
||||
// var/obj/item/equipped_belt = get_item_by_slot(slot_belt)
|
||||
// if(!equipped_belt) // We also let you equip a belt like this
|
||||
// if(!thing)
|
||||
// to_chat(user, "<span class='notice'>You have no belt to take something out of.</span>")
|
||||
// return
|
||||
// if(equip_to_slot_if_possible(thing, slot_belt))
|
||||
// update_inv_r_hand()
|
||||
// update_inv_l_hand()
|
||||
// return
|
||||
// if(!SEND_SIGNAL(equipped_belt, COMSIG_CONTAINS_STORAGE)) // not a storage item
|
||||
// if(!thing)
|
||||
// equipped_belt.attack_hand(src)
|
||||
// else
|
||||
// to_chat(user, "<span class='notice'>You can't fit anything in.</span>")
|
||||
// return
|
||||
// if(thing) // put thing in belt
|
||||
// if(!SEND_SIGNAL(equipped_belt, COMSIG_TRY_STORAGE_INSERT, thing, user.mob))
|
||||
// to_chat(user, "<span class='notice'>You can't fit anything in.</span>")
|
||||
// return
|
||||
// if(!equipped_belt.contents.len) // nothing to take out
|
||||
// to_chat(user, "<span class='notice'>There's nothing in your belt to take out.</span>")
|
||||
// return
|
||||
// var/obj/item/stored = equipped_belt.contents[equipped_belt.contents.len]
|
||||
// if(!stored || stored.on_found(src))
|
||||
// return
|
||||
// stored.attack_hand(src) // take out thing from belt
|
||||
// return
|
||||
|
||||
/* if("B") // Put held thing in backpack or take out most recent thing from backpack
|
||||
var/obj/item/thing = get_active_hand()
|
||||
var/obj/item/equipped_back = get_item_by_slot(slot_back)
|
||||
if(!equipped_back) // We also let you equip a backpack like this
|
||||
if(!thing)
|
||||
to_chat(user, "<span class='notice'>You have no backpack to take something out of.</span>")
|
||||
return
|
||||
if(equip_to_slot_if_possible(thing, slot_back))
|
||||
update_inv_r_hand()
|
||||
update_inv_l_hand()
|
||||
return
|
||||
if(!SEND_SIGNAL(equipped_back, COMSIG_CONTAINS_STORAGE)) // not a storage item
|
||||
if(!thing)
|
||||
equipped_back.attack_hand(src)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You can't fit anything in.</span>")
|
||||
return
|
||||
if(thing) // put thing in backpack
|
||||
if(!SEND_SIGNAL(equipped_back, COMSIG_TRY_STORAGE_INSERT, thing, user.mob))
|
||||
to_chat(user, "<span class='notice'>You can't fit anything in.</span>")
|
||||
return
|
||||
if(!equipped_back.contents.len) // nothing to take out
|
||||
to_chat(user, "<span class='notice'>There's nothing in your backpack to take out.</span>")
|
||||
return
|
||||
var/obj/item/stored = equipped_back.contents[equipped_back.contents.len]
|
||||
if(!stored || stored.on_found(src))
|
||||
return
|
||||
stored.attack_hand(src) // take out thing from backpack
|
||||
return */
|
||||
return ..()
|
||||
@@ -0,0 +1,7 @@
|
||||
/mob/living/key_down(_key, client/user)
|
||||
switch(_key)
|
||||
if("B")
|
||||
resist()
|
||||
return
|
||||
|
||||
return ..()
|
||||
@@ -0,0 +1,145 @@
|
||||
// Technically the client argument is unncessary here since that SHOULD be src.client but let's not assume things
|
||||
// All it takes is one badmin setting their focus to someone else's client to mess things up
|
||||
// Or we can have NPC's send actual keypresses and detect that by seeing no client
|
||||
|
||||
/mob/key_down(_key, client/user)
|
||||
if(user.prefs.toggles & AZERTY)
|
||||
switch(_key)
|
||||
if("Delete")
|
||||
if(!pulling)
|
||||
to_chat(src, "<span class='notice'>You are not pulling anything.</span>")
|
||||
else
|
||||
stop_pulling()
|
||||
return
|
||||
if("Insert", "G")
|
||||
a_intent_change(INTENT_HOTKEY_RIGHT)
|
||||
return
|
||||
if("F")
|
||||
a_intent_change(INTENT_HOTKEY_LEFT)
|
||||
return
|
||||
if("X", "Northeast") // Northeast is Page-up
|
||||
swap_hand()
|
||||
return
|
||||
if("Y", "W", "Southeast") // Southeast is Page-down
|
||||
mode() // attack_self(). No idea who came up with "mode()"
|
||||
return
|
||||
if("A", "Northwest") // Northwest is Home
|
||||
var/obj/item/I = get_active_hand()
|
||||
if(!I)
|
||||
to_chat(src, "<span class='warning'>You have nothing to drop in your hand!</span>")
|
||||
else
|
||||
drop_item(I)
|
||||
return
|
||||
if("E")
|
||||
quick_equip()
|
||||
return
|
||||
if("Alt")
|
||||
toggle_move_intent()
|
||||
return
|
||||
else
|
||||
switch(_key)
|
||||
if("Delete")
|
||||
if(!pulling)
|
||||
to_chat(src, "<span class='notice'>You are not pulling anything.</span>")
|
||||
else
|
||||
stop_pulling()
|
||||
return
|
||||
if("Insert", "G")
|
||||
a_intent_change(INTENT_HOTKEY_RIGHT)
|
||||
return
|
||||
if("F")
|
||||
a_intent_change(INTENT_HOTKEY_LEFT)
|
||||
return
|
||||
if("X", "Northeast") // Northeast is Page-up
|
||||
swap_hand()
|
||||
return
|
||||
if("Y", "Z", "Southeast") // Southeast is Page-down
|
||||
mode() // attack_self(). No idea who came up with "mode()"
|
||||
return
|
||||
if("Q", "Northwest") // Northwest is Home
|
||||
var/obj/item/I = get_active_hand()
|
||||
if(!I)
|
||||
to_chat(src, "<span class='warning'>You have nothing to drop in your hand!</span>")
|
||||
else
|
||||
drop_item(I)
|
||||
return
|
||||
if("E")
|
||||
quick_equip()
|
||||
return
|
||||
if("Alt")
|
||||
toggle_move_intent()
|
||||
return
|
||||
//Bodypart selections
|
||||
if(client.prefs.toggles & NUMPAD_TARGET)
|
||||
switch(_key)
|
||||
if("Numpad8")
|
||||
user.body_toggle_head()
|
||||
return
|
||||
if("Numpad4")
|
||||
user.body_r_arm()
|
||||
return
|
||||
if("Numpad5")
|
||||
user.body_chest()
|
||||
return
|
||||
if("Numpad6")
|
||||
user.body_l_arm()
|
||||
return
|
||||
if("Numpad1")
|
||||
user.body_r_leg()
|
||||
return
|
||||
if("Numpad2")
|
||||
user.body_groin()
|
||||
return
|
||||
if("Numpad3")
|
||||
user.body_l_leg()
|
||||
return
|
||||
else
|
||||
switch(_key)
|
||||
if("Numpad1")
|
||||
a_intent_change("help")
|
||||
return
|
||||
if("Numpad2")
|
||||
a_intent_change("disarm")
|
||||
return
|
||||
if("Numpad3")
|
||||
a_intent_change("grab")
|
||||
return
|
||||
if("Numpad4")
|
||||
a_intent_change("harm")
|
||||
return
|
||||
if(client.keys_held["Ctrl"] && client.prefs.toggles & AZERTY)
|
||||
switch(SSinput.alt_movement_keys[_key])
|
||||
if(NORTH)
|
||||
northface()
|
||||
return
|
||||
if(SOUTH)
|
||||
southface()
|
||||
return
|
||||
if(WEST)
|
||||
westface()
|
||||
return
|
||||
if(EAST)
|
||||
eastface()
|
||||
return
|
||||
else if(client.keys_held["Ctrl"])
|
||||
switch(SSinput.movement_keys[_key])
|
||||
if(NORTH)
|
||||
northface()
|
||||
return
|
||||
if(SOUTH)
|
||||
southface()
|
||||
return
|
||||
if(WEST)
|
||||
westface()
|
||||
return
|
||||
if(EAST)
|
||||
eastface()
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/key_up(_key, client/user)
|
||||
switch(_key)
|
||||
if("Alt")
|
||||
toggle_move_intent()
|
||||
return
|
||||
return ..()
|
||||
@@ -0,0 +1,20 @@
|
||||
/mob/living/silicon/robot/key_down(_key, client/user)
|
||||
switch(_key)
|
||||
if("1", "2", "3")
|
||||
toggle_module(text2num(_key))
|
||||
return
|
||||
if("4")
|
||||
a_intent_change(INTENT_HOTKEY_LEFT)
|
||||
return
|
||||
if("X")
|
||||
cycle_modules()
|
||||
return
|
||||
if("Q")
|
||||
if(!(client.prefs.toggles & AZERTY))
|
||||
uneq_active()
|
||||
return
|
||||
if("A")
|
||||
if(client.prefs.toggles & AZERTY)
|
||||
uneq_active()
|
||||
return
|
||||
return ..()
|
||||
@@ -0,0 +1,8 @@
|
||||
/mob
|
||||
var/datum/focus //What receives our keyboard inputs. src by default
|
||||
|
||||
/mob/proc/set_focus(datum/new_focus)
|
||||
if(focus == new_focus)
|
||||
return
|
||||
focus = new_focus
|
||||
reset_perspective(focus) //Maybe this should be done manually? You figure it out, reader
|
||||
@@ -0,0 +1,42 @@
|
||||
# In-code keypress handling system
|
||||
|
||||
This whole system is heavily based off of forum_account's keyboard library.
|
||||
Thanks to forum_account for saving the day, the library can be found
|
||||
[here](https://secure.byond.com/developer/Forum_account/Keyboard)!
|
||||
|
||||
.dmf macros have some very serious shortcomings. For example, they do not allow reusing parts
|
||||
of one macro in another, so giving cyborgs their own shortcuts to swap active module couldn't
|
||||
inherit the movement that all mobs should have anyways. The webclient only supports one macro,
|
||||
so having more than one was problematic. Additionally each keybind has to call an actual
|
||||
verb, which meant a lot of hidden verbs that just call one other proc. Also our existing
|
||||
macro was really bad and tied unrelated behavior into `Northeast()`, `Southeast()`, `Northwest()`,
|
||||
and `Southwest()`.
|
||||
|
||||
The basic premise of this system is to not screw with .dmf macro setup at all and handle
|
||||
pressing those keys in the code instead. We have every key call `client.keyDown()`
|
||||
or `client.keyUp()` with the pressed key as an argument. Certain keys get processed
|
||||
directly by the client because they should be doable at any time, then we call
|
||||
`keyDown()` or `keyUp()` on the client's holder and the client's mob's focus.
|
||||
By default `mob.focus` is the mob itself, but you can set it to any datum to give control of a
|
||||
client's keypresses to another object. This would be a good way to handle a menu or driving
|
||||
a mech. You can also set it to null to disregard input from a certain user.
|
||||
|
||||
Movement is handled by having each client call `client.keyLoop()` every game tick.
|
||||
As above, this calls holder and `focus.keyLoop()`. `atom/movable/keyLoop()` handles movement
|
||||
Try to keep the calculations in this proc light. It runs every tick for every client after all!
|
||||
|
||||
You can also tell which keys are being held down now. Each client a list of keys pressed called
|
||||
`keys_held`. Each entry is a key as a text string associated with the world.time when it was
|
||||
pressed.
|
||||
|
||||
No client-set keybindings at this time, but it shouldn't be too hard if someone wants.
|
||||
|
||||
Notes about certain keys:
|
||||
|
||||
* `Tab` has client-sided behavior but acts normally
|
||||
* `T`, `O`, and `M` move focus to the input when pressed. This fires the keyUp macro right away.
|
||||
* `\` needs to be escaped in the dmf so any usage is `\\`
|
||||
|
||||
You cannot `TICK_CHECK` or check `world.tick_usage` inside of procs called by key down and up
|
||||
events. They happen outside of a byond tick and have no meaning there. Key looping
|
||||
works correctly since it's part of a subsystem, not direct input.
|
||||
@@ -0,0 +1,46 @@
|
||||
/client
|
||||
var/list/keys_held = list() // A list of any keys held currently
|
||||
// These next two vars are to apply movement for keypresses and releases made while move delayed.
|
||||
// Because discarding that input makes the game less responsive.
|
||||
var/next_move_dir_add // On next move, add this dir to the move that would otherwise be done
|
||||
var/next_move_dir_sub // On next move, subtract this dir from the move that would otherwise be done
|
||||
|
||||
// Set a client's focus to an object and override these procs on that object to let it handle keypresses
|
||||
|
||||
/datum/proc/key_down(key, client/user) // Called when a key is pressed down initially
|
||||
return
|
||||
/datum/proc/key_up(key, client/user) // Called when a key is released
|
||||
return
|
||||
/datum/proc/keyLoop(client/user) // Called once every frame
|
||||
set waitfor = FALSE
|
||||
return
|
||||
|
||||
// removes all the existing macros
|
||||
/client/proc/erase_all_macros()
|
||||
var/list/macro_sets = params2list(winget(src, null, "macros"))
|
||||
var/erase_output = ""
|
||||
for(var/i in 1 to macro_sets.len)
|
||||
var/setname = macro_sets[i]
|
||||
var/list/macro_set = params2list(winget(src, "[setname].*", "command")) // The third arg doesnt matter here as we're just removing them all
|
||||
for(var/k in 1 to macro_set.len)
|
||||
var/list/split_name = splittext(macro_set[k], ".")
|
||||
var/macro_name = "[split_name[1]].[split_name[2]]" // [3] is "command"
|
||||
erase_output = "[erase_output];[macro_name].parent=null"
|
||||
winset(src, null, erase_output)
|
||||
|
||||
/client/proc/set_macros()
|
||||
set waitfor = FALSE
|
||||
|
||||
erase_all_macros()
|
||||
|
||||
var/list/macro_sets = SSinput.macro_sets
|
||||
for(var/i in 1 to macro_sets.len)
|
||||
var/setname = macro_sets[i]
|
||||
if(setname != "default")
|
||||
winclone(src, "default", setname)
|
||||
var/list/macro_set = macro_sets[setname]
|
||||
for(var/k in 1 to macro_set.len)
|
||||
var/key = macro_set[k]
|
||||
var/command = macro_set[key]
|
||||
winset(src, "[setname]-\ref[key]", "parent=[setname];name=[key];command=[command]")
|
||||
winset(src, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=old_default")
|
||||
@@ -151,7 +151,7 @@
|
||||
/obj/structure/closet/crate/secure/loot/attack_hand(mob/user)
|
||||
if(locked)
|
||||
to_chat(user, "<span class='notice'>The crate is locked with a Deca-code lock.</span>")
|
||||
var/input = input(usr, "Enter [codelen] digits.", "Deca-Code Lock", "") as text
|
||||
var/input = clean_input("Enter [codelen] digits.", "Deca-Code Lock", "")
|
||||
if(in_range(src, user))
|
||||
if(input == code)
|
||||
to_chat(user, "<span class='notice'>The crate unlocks!</span>")
|
||||
|
||||
@@ -238,6 +238,9 @@
|
||||
/obj/machinery/smartfridge/survival_pod/accept_check(obj/item/O)
|
||||
return isitem(O)
|
||||
|
||||
/obj/machinery/smartfridge/survival_pod/default_unfasten_wrench()
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/smartfridge/survival_pod/empty
|
||||
name = "dusty survival pod storage"
|
||||
desc = "A heated storage unit. This one's seen better days."
|
||||
|
||||
@@ -474,7 +474,9 @@
|
||||
new /datum/data/mining_equipment("Royal Cape of the Liberator", /obj/item/bedsheet/rd/royal_cape, 500),
|
||||
new /datum/data/mining_equipment("Grey Slime Extract", /obj/item/slime_extract/grey, 1000),
|
||||
new /datum/data/mining_equipment("KA Trigger Modification Kit", /obj/item/borg/upgrade/modkit/trigger_guard, 1000),
|
||||
new /datum/data/mining_equipment("Shuttle Console Board", /obj/item/circuitboard/shuttle/golem_ship, 2000),
|
||||
new /datum/data/mining_equipment("The Liberator's Legacy", /obj/item/storage/box/rndboards, 2000)
|
||||
|
||||
)
|
||||
|
||||
/datum/data/mining_equipment
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
/****************Explorer's Suit and Mask****************/
|
||||
/obj/item/clothing/suit/hooded/explorer
|
||||
name = "explorer suit"
|
||||
desc = "An armoured suit for exploring harsh environments."
|
||||
icon_state = "explorer"
|
||||
item_state = "explorer"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
|
||||
cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
hoodtype = /obj/item/clothing/head/hooded/explorer
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
|
||||
resistance_flags = FIRE_PROOF
|
||||
hide_tail_by_species = list("Vox" , "Vulpkanin" , "Unathi" , "Tajaran")
|
||||
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/suit.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/suit.dmi',
|
||||
"Tajaran" = 'icons/mob/species/tajaran/suit.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/suit.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/head/hooded/explorer
|
||||
name = "explorer hood"
|
||||
desc = "An armoured hood for exploring harsh environments."
|
||||
icon_state = "explorer"
|
||||
item_state = "explorer"
|
||||
body_parts_covered = HEAD
|
||||
flags = BLOCKHAIR | NODROP
|
||||
flags_cover = HEADCOVERSEYES
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/head.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/head.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/head.dmi',
|
||||
"Skrell" = 'icons/mob/species/skrell/head.dmi'
|
||||
/****************Explorer's Suit and Mask****************/
|
||||
/obj/item/clothing/suit/hooded/explorer
|
||||
name = "explorer suit"
|
||||
desc = "An armoured suit for exploring harsh environments."
|
||||
icon_state = "explorer"
|
||||
item_state = "explorer"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
|
||||
cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
hoodtype = /obj/item/clothing/head/hooded/explorer
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
|
||||
resistance_flags = FIRE_PROOF
|
||||
hide_tail_by_species = list("Vox" , "Vulpkanin" , "Unathi" , "Tajaran")
|
||||
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/suit.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/suit.dmi',
|
||||
"Tajaran" = 'icons/mob/species/tajaran/suit.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/suit.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/head/hooded/explorer
|
||||
name = "explorer hood"
|
||||
desc = "An armoured hood for exploring harsh environments."
|
||||
icon_state = "explorer"
|
||||
item_state = "explorer"
|
||||
body_parts_covered = HEAD
|
||||
flags = BLOCKHAIR | NODROP
|
||||
flags_cover = HEADCOVERSEYES
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/head.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/head.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/head.dmi',
|
||||
"Skrell" = 'icons/mob/species/skrell/head.dmi'
|
||||
)
|
||||
@@ -1,3 +1,5 @@
|
||||
GLOBAL_LIST(labor_sheet_values)
|
||||
|
||||
/**********************Prisoners' Console**************************/
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console
|
||||
@@ -5,153 +7,153 @@
|
||||
desc = "A stacking console with an electromagnetic writer, used to track ore mined by prisoners."
|
||||
icon = 'icons/obj/machines/mining_machines.dmi'
|
||||
icon_state = "console"
|
||||
density = 0
|
||||
anchored = 1
|
||||
var/obj/machinery/mineral/stacking_machine/laborstacker/machine = null
|
||||
density = FALSE
|
||||
var/obj/machinery/mineral/stacking_machine/laborstacker/stacking_machine = null
|
||||
var/machinedir = SOUTH
|
||||
var/obj/item/card/id/prisoner/inserted_id
|
||||
var/obj/machinery/door/airlock/release_door
|
||||
var/door_tag = "prisonshuttle"
|
||||
var/use_release_door = 0
|
||||
var/obj/item/radio/intercom/announcer
|
||||
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/New()
|
||||
..()
|
||||
/obj/machinery/mineral/labor_claim_console/Initialize()
|
||||
. = ..()
|
||||
announcer = new /obj/item/radio/intercom(null)
|
||||
announcer.config(list("Security" = 0))
|
||||
locate_stacking_machine()
|
||||
|
||||
spawn(7)
|
||||
src.machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir))
|
||||
var/t
|
||||
for(var/obj/machinery/door/airlock/d in range(5,src))
|
||||
t = d.id_tag
|
||||
if(t == src.door_tag)
|
||||
src.release_door = d
|
||||
if(machine && (release_door || !use_release_door))
|
||||
machine.CONSOLE = src
|
||||
if(!GLOB.labor_sheet_values)
|
||||
var/sheet_list = list()
|
||||
for(var/sheet_type in subtypesof(/obj/item/stack/sheet))
|
||||
var/obj/item/stack/sheet/sheet = sheet_type
|
||||
if(!initial(sheet.point_value) || (initial(sheet.merge_type) && initial(sheet.merge_type) != sheet_type)) //ignore no-value sheets and x/fifty subtypes
|
||||
continue
|
||||
sheet_list += list(list("ore" = initial(sheet.name), "value" = initial(sheet.point_value)))
|
||||
GLOB.labor_sheet_values = sheet_list
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/Destroy()
|
||||
. = ..()
|
||||
QDEL_NULL(announcer)
|
||||
|
||||
/proc/cmp_sheet_list(list/a, list/b)
|
||||
return a["value"] - b["value"]
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/card/id/prisoner))
|
||||
if(!inserted_id)
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
I.forceMove(src)
|
||||
inserted_id = I
|
||||
to_chat(user, "<span class='notice'>You insert [I].</span>")
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
else
|
||||
qdel(src)
|
||||
to_chat(user, "<span class='notice'>There's an ID inserted already.</span>")
|
||||
return ..()
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/attack_hand(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/attack_ghost(mob/user)
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "labor_claim_console.tmpl", name, 450, 625, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/can_go_home = FALSE
|
||||
|
||||
data["emagged"] = (emagged) ? TRUE : FALSE
|
||||
if(inserted_id)
|
||||
data["id"] = inserted_id
|
||||
data["id_name"] = inserted_id.registered_name
|
||||
data["points"] = inserted_id.points
|
||||
data["goal"] = inserted_id.goal
|
||||
if(check_auth())
|
||||
can_go_home = TRUE
|
||||
|
||||
if(stacking_machine)
|
||||
data["unclaimed_points"] = stacking_machine.points
|
||||
|
||||
data["ores"] = GLOB.labor_sheet_values
|
||||
data["can_go_home"] = can_go_home
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/Topic(href, href_list)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(href_list["handle_id"])
|
||||
if(inserted_id)
|
||||
if(!usr.put_in_hands(inserted_id))
|
||||
inserted_id.forceMove(get_turf(src))
|
||||
inserted_id = null
|
||||
else
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if(istype(I, /obj/item/card/id/prisoner))
|
||||
if(!usr.unEquip(I))
|
||||
return
|
||||
I.forceMove(src)
|
||||
inserted_id = I
|
||||
if(href_list["claim_points"])
|
||||
inserted_id.points += stacking_machine.points
|
||||
stacking_machine.points = 0
|
||||
to_chat(usr, "Points transferred.")
|
||||
if(href_list["move_shuttle"])
|
||||
if(!alone_in_area(get_area(src), usr))
|
||||
to_chat(usr, "<span class='warning'>Prisoners are only allowed to be released while alone.</span>")
|
||||
else
|
||||
switch(SSshuttle.moveShuttle("laborcamp", "laborcamp_home", TRUE))
|
||||
if(1)
|
||||
to_chat(usr, "<span class='notice'>Shuttle not found.</span>")
|
||||
if(2)
|
||||
to_chat(usr, "<span class='notice'>Shuttle already at station.</span>")
|
||||
if(3)
|
||||
to_chat(usr, "<span class='notice'>No permission to dock could be granted.</span>")
|
||||
else
|
||||
if(!(emagged))
|
||||
var/message = "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval."
|
||||
announcer.autosay(message, "Labor Camp Controller", "Security")
|
||||
to_chat(usr, "<span class='notice'>Shuttle received message and will be sent shortly.</span>")
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/proc/check_auth()
|
||||
if(emagged) return 1 //Shuttle is emagged, let any ol' person through
|
||||
if(emagged)
|
||||
return TRUE //Shuttle is emagged, let any ol' person through
|
||||
return (istype(inserted_id) && inserted_id.points >= inserted_id.goal) //Otherwise, only let them out if the prisoner's reached his quota.
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/proc/locate_stacking_machine()
|
||||
stacking_machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir))
|
||||
if(stacking_machine)
|
||||
stacking_machine.CONSOLE = src
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/attack_hand(user as mob)
|
||||
var/dat
|
||||
dat += text("<b>Point Claim Console</b><br><br>")
|
||||
if(emagged) //Shit's broken
|
||||
dat += text("<b>QU&#t0A In%aL*D</b><br>")
|
||||
else if(istype(inserted_id)) //There's an ID in there.
|
||||
dat += text("ID: [inserted_id.registered_name] <A href='?src=[UID()];choice=eject'>Eject ID.</A><br>")
|
||||
dat += text("Points Collected:[inserted_id.points]<br>")
|
||||
dat += text("Point Quota: [inserted_id.goal] - Reach your quota to earn your release<br>")
|
||||
dat += text("Unclaimed Collection Points: [machine.points]. <A href='?src=[UID()];choice=claim'>Claim points.</A><br>")
|
||||
else //No ID in sight. Complain about it.
|
||||
dat += text("No ID inserted. <A href='?src=[UID()];choice=insert'>Insert ID.</A><br>")
|
||||
if(check_auth())
|
||||
dat += text("<A href='?src=[UID()];choice=station'>Proceed to station.</A><br>")
|
||||
if(use_release_door)
|
||||
dat += text("<A href='?src=[UID()];choice=release'>Open release door.</A><br>")
|
||||
if(machine)
|
||||
dat += text("<HR><b>Mineral Value List:</b><BR>[machine.get_ore_values()]")
|
||||
|
||||
|
||||
user << browse("[dat]", "window=console_stacking_machine")
|
||||
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/attackby(obj/item/I as obj, mob/user as mob, params)
|
||||
if(istype(I, /obj/item/card/id))
|
||||
return attack_hand(user)
|
||||
..()
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/emag_act(user as mob)
|
||||
emag(user)
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/proc/emag(mob/user as mob)
|
||||
if(!emagged)
|
||||
emagged = 1
|
||||
/obj/machinery/mineral/labor_claim_console/emag_act(mob/user)
|
||||
if(!(emagged))
|
||||
emagged = TRUE
|
||||
to_chat(user, "<span class='warning'>PZZTTPFFFT</span>")
|
||||
|
||||
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/Topic(href, href_list)
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["choice"])
|
||||
if(istype(inserted_id)) //Sanity check against href spoofs
|
||||
if(href_list["choice"] == "eject")
|
||||
inserted_id.loc = loc
|
||||
inserted_id.verb_pickup()
|
||||
inserted_id = null
|
||||
if(href_list["choice"] == "claim")
|
||||
inserted_id.points += machine.points
|
||||
machine.points = 0
|
||||
to_chat(src, "Points transferred.")
|
||||
else if(href_list["choice"] == "insert")
|
||||
var/obj/item/card/id/prisoner/I = usr.get_active_hand()
|
||||
if(istype(I))
|
||||
usr.drop_item()
|
||||
I.loc = src
|
||||
inserted_id = I
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Invalid ID.</span>")
|
||||
if(check_auth()) //Sanity check against hef spoofs
|
||||
if(href_list["choice"] == "station")
|
||||
if(!alone_in_area(get_area(src), usr))
|
||||
to_chat(usr, "<span class='warning'>Prisoners are only allowed to be released while alone.</span>")
|
||||
else
|
||||
switch(SSshuttle.moveShuttle("laborcamp","laborcamp_home"))
|
||||
if(1)
|
||||
to_chat(usr, "<span class='notice'>Shuttle not found</span>")
|
||||
if(2)
|
||||
to_chat(usr, "<span class='notice'>Shuttle already at station</span>")
|
||||
if(3)
|
||||
to_chat(usr, "<span class='notice'>No permission to dock could be granted.</span>")
|
||||
else
|
||||
var/message = "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval."
|
||||
announcer.autosay(message, "Labor Camp Controller", "Security")
|
||||
to_chat(usr, "<span class='notice'>Shuttle received message and will be sent shortly.</span>")
|
||||
|
||||
if(href_list["choice"] == "release")
|
||||
if(alone_in_area(get_area(loc), usr))
|
||||
var/obj/docking_port/stationary/S = SSshuttle.getDock("laborcamp_home")
|
||||
if(S && S.get_docked())
|
||||
if(release_door && release_door.density)
|
||||
release_door.open()
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Prisoners can only be released while docked with the station.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Prisoners are only allowed to be released while alone.</span>")
|
||||
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
|
||||
/**********************Prisoner Collection Unit**************************/
|
||||
|
||||
|
||||
/obj/machinery/mineral/stacking_machine/laborstacker
|
||||
var/points = 0 //The unclaimed value of ore stacked. Value for each ore loosely relative to its rarity.
|
||||
var/list/ore_values = list(("glass" = 1), ("metal" = 2), ("solid plasma" = 20), ("plasteel" = 23), ("reinforced glass" = 4), ("gold" = 20), ("silver" = 20), ("uranium" = 20), ("diamond" = 25), ("bananium" = 50), ("tranquillite" = 50))
|
||||
|
||||
/obj/machinery/mineral/stacking_machine/laborstacker/proc/get_ore_values()
|
||||
var/dat = "<table border='0' width='200'>"
|
||||
for(var/ore in ore_values)
|
||||
var/value = ore_values[ore]
|
||||
dat += "<tr><td>[capitalize(ore)]</td><td>[value]</td></tr>"
|
||||
dat += "</table>"
|
||||
return dat
|
||||
var/points = 0 //The unclaimed value of ore stacked.
|
||||
|
||||
/obj/machinery/mineral/stacking_machine/laborstacker/process_sheet(obj/item/stack/sheet/inp)
|
||||
if(istype(inp))
|
||||
var/n = inp.name
|
||||
var/a = inp.amount
|
||||
if(n in ore_values)
|
||||
points += ore_values[n] * a
|
||||
points += inp.point_value * inp.amount
|
||||
..()
|
||||
|
||||
/obj/machinery/mineral/stacking_machine/laborstacker/attackby(obj/item/I, mob/living/user)
|
||||
if(istype(I, /obj/item/stack/sheet) && user.canUnEquip(I))
|
||||
var/obj/item/stack/sheet/inp = I
|
||||
points += inp.point_value * inp.amount
|
||||
return ..()
|
||||
|
||||
/**********************Point Lookup Console**************************/
|
||||
/obj/machinery/mineral/labor_points_checker
|
||||
@@ -159,13 +161,15 @@
|
||||
desc = "A console used by prisoners to check the progress on their quotas. Simply swipe a prisoner ID."
|
||||
icon = 'icons/obj/machines/mining_machines.dmi'
|
||||
icon_state = "console"
|
||||
density = 0
|
||||
anchored = 1
|
||||
density = FALSE
|
||||
|
||||
/obj/machinery/mineral/labor_points_checker/attack_hand(mob/user)
|
||||
user.examine(src)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
user.examinate(src)
|
||||
|
||||
/obj/machinery/mineral/labor_points_checker/attackby(obj/item/I as obj, mob/user as mob, params)
|
||||
/obj/machinery/mineral/labor_points_checker/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/card/id))
|
||||
if(istype(I, /obj/item/card/id/prisoner))
|
||||
var/obj/item/card/id/prisoner/prisoner_id = I
|
||||
@@ -175,5 +179,5 @@
|
||||
to_chat(user, "<span class='notice'>Collect points by bringing smelted minerals to the Labor Shuttle stacking machine. Reach your quota to earn your release.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Error: Invalid ID</span>")
|
||||
return
|
||||
..()
|
||||
else
|
||||
return ..()
|
||||
@@ -27,6 +27,17 @@
|
||||
if(prob(15))
|
||||
harvest(null, TRUE)
|
||||
|
||||
/obj/structure/flora/ash/ex_act(severity, target)
|
||||
switch(severity)
|
||||
if(1)
|
||||
qdel(src)
|
||||
if(2)
|
||||
if(prob(80))
|
||||
qdel(src)
|
||||
if(3)
|
||||
if(prob(50))
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/flora/ash/proc/harvest(user, no_drop)
|
||||
if(harvested)
|
||||
return 0
|
||||
@@ -137,7 +148,7 @@
|
||||
regrowth_time_low = 4800
|
||||
regrowth_time_high = 7200
|
||||
|
||||
/obj/structure/flora/ash/cacti/Crossed(mob/AM)
|
||||
/obj/structure/flora/ash/cacti/Crossed(mob/AM, oldloc)
|
||||
if(ishuman(AM) && has_gravity(loc) && prob(70))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if(!H.shoes && !H.lying) //ouch, my feet.
|
||||
|
||||
@@ -12,8 +12,12 @@
|
||||
/obj/structure/closet/crate/necropolis/tendril
|
||||
desc = "It's watching you suspiciously."
|
||||
|
||||
/obj/structure/closet/crate/necropolis/tendril/New()
|
||||
/obj/structure/closet/crate/necropolis/tendril/New(add_loot = TRUE)
|
||||
..()
|
||||
|
||||
if(!add_loot)
|
||||
return
|
||||
|
||||
var/loot = rand(1,24)
|
||||
switch(loot)
|
||||
if(1)
|
||||
@@ -35,7 +39,7 @@
|
||||
if(8)
|
||||
new /obj/item/organ/internal/brain/xeno(src)
|
||||
if(9)
|
||||
new /obj/item/organ/internal/heart/cursed(src)
|
||||
new /obj/item/organ/internal/heart/cursed/wizard(src)
|
||||
if(10)
|
||||
new /obj/item/ship_in_a_bottle(src)
|
||||
if(11)
|
||||
@@ -68,4 +72,19 @@
|
||||
new /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor(src)
|
||||
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor(src)
|
||||
if(24)
|
||||
new /obj/item/spellbook/oneuse/summonitem(src)
|
||||
new /obj/item/spellbook/oneuse/summonitem(src)
|
||||
|
||||
/obj/structure/closet/crate/necropolis/puzzle
|
||||
name = "puzzling chest"
|
||||
|
||||
/obj/structure/closet/crate/necropolis/puzzle/New()
|
||||
..(FALSE)
|
||||
|
||||
var/loot = rand(1,3)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/soulstone/anybody(src)
|
||||
if(2)
|
||||
new /obj/item/wisp_lantern(src)
|
||||
if(3)
|
||||
new /obj/item/prisoncube(src)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
else if(W.isOn())
|
||||
to_chat(user, "<span class='info'>Not enough fuel to smelt [src].</span>")
|
||||
|
||||
/obj/item/stack/ore/Crossed(atom/movable/AM)
|
||||
/obj/item/stack/ore/Crossed(atom/movable/AM, oldloc)
|
||||
var/obj/item/storage/bag/ore/OB
|
||||
var/turf/simulated/floor/F = get_turf(src)
|
||||
if(loc != F)
|
||||
@@ -50,6 +50,12 @@
|
||||
break
|
||||
if(OB && istype(F, /turf/simulated/floor/plating/asteroid))
|
||||
F.attackby(OB, AM)
|
||||
// Then, if the user is dragging an ore box, empty the satchel
|
||||
// into the box.
|
||||
var/mob/living/L = AM
|
||||
if(istype(L.pulling, /obj/structure/ore_box))
|
||||
var/obj/structure/ore_box/box = L.pulling
|
||||
box.attackby(OB, AM)
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/ore/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
|
||||
|
||||
@@ -263,7 +263,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
..()
|
||||
statpanel("Status")
|
||||
if(client.statpanel == "Status")
|
||||
show_stat_station_time()
|
||||
show_stat_emergency_shuttle_eta()
|
||||
stat(null, "Respawnability: [(src in GLOB.respawnable_list) ? "Yes" : "No"]")
|
||||
|
||||
@@ -406,7 +405,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
A.on_close(CALLBACK(src, .proc/teleport))
|
||||
|
||||
/mob/dead/observer/proc/teleport(area/thearea)
|
||||
if(!thearea)
|
||||
if(!thearea || !isobserver(usr))
|
||||
return
|
||||
|
||||
var/list/L = list()
|
||||
@@ -417,7 +416,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
to_chat(usr, "<span class='warning'>No area available.</span>")
|
||||
return
|
||||
|
||||
usr.forceMove(pick(L))
|
||||
forceMove(pick(L))
|
||||
following = null
|
||||
|
||||
/mob/dead/observer/verb/follow()
|
||||
@@ -431,7 +430,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
// This is the ghost's follow verb with an argument
|
||||
/mob/dead/observer/proc/ManualFollow(var/atom/movable/target)
|
||||
if(!target)
|
||||
if(!target || !isobserver(usr))
|
||||
return
|
||||
|
||||
if(!get_turf(target))
|
||||
@@ -505,7 +504,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
A.on_close(CALLBACK(src, .proc/jump_to_mob))
|
||||
|
||||
/mob/dead/observer/proc/jump_to_mob(mob/M)
|
||||
if(!M)
|
||||
if(!M || !isobserver(usr))
|
||||
return
|
||||
var/mob/A = src //Source mob
|
||||
var/turf/T = get_turf(M) //Turf of the destination mob
|
||||
|
||||
@@ -58,19 +58,20 @@
|
||||
if(message)
|
||||
log_emote(message, src)
|
||||
|
||||
//Hearing gasp and such every five seconds is not good emotes were not global for a reason.
|
||||
// Maybe some people are okay with that.
|
||||
|
||||
// Hearing gasp and such every five seconds is not good emotes were not global for a reason.
|
||||
// Maybe some people are okay with that.
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue //skip monkeys and leavers
|
||||
if(istype(M, /mob/new_player))
|
||||
continue
|
||||
if(findtext(message," snores.")) //Because we have so many sleeping people.
|
||||
break
|
||||
if(M.stat == DEAD && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
|
||||
M.show_message(message)
|
||||
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(findtext(message, " snores.")) //Because we have so many sleeping people.
|
||||
break
|
||||
|
||||
if(isobserver(M) && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
M.show_message(message)
|
||||
|
||||
// Type 1 (Visual) emotes are sent to anyone in view of the item
|
||||
if(m_type & EMOTE_VISUAL)
|
||||
|
||||
@@ -63,10 +63,10 @@
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/pressure = environment ? environment.return_pressure() : 0
|
||||
if(pressure < SOUND_MINIMUM_PRESSURE && get_dist(speaker, src) > 1)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(pressure < ONE_ATMOSPHERE * 0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet
|
||||
italics = 1
|
||||
italics = TRUE
|
||||
sound_vol *= 0.5
|
||||
|
||||
if(sleeping || stat == UNCONSCIOUS)
|
||||
@@ -87,8 +87,6 @@
|
||||
|
||||
var/track = null
|
||||
if(isobserver(src))
|
||||
if(italics && client.prefs.toggles & CHAT_GHOSTRADIO)
|
||||
return
|
||||
if(speaker_name != speaker.real_name && speaker.real_name)
|
||||
speaker_name = "[speaker.real_name] ([speaker_name])"
|
||||
track = "([ghost_follow_link(speaker, ghost=src)]) "
|
||||
|
||||
@@ -6,6 +6,14 @@
|
||||
if(hand) return l_hand
|
||||
else return r_hand
|
||||
|
||||
/mob/verb/quick_equip()
|
||||
set name = "quick-equip"
|
||||
set hidden = 1
|
||||
|
||||
var/obj/item/I = get_active_hand()
|
||||
if(I)
|
||||
I.equip_to_best_slot(src)
|
||||
|
||||
/mob/proc/is_in_active_hand(obj/item/I)
|
||||
var/obj/item/item_to_test = get_active_hand()
|
||||
|
||||
@@ -254,3 +262,4 @@
|
||||
if(slot_r_hand)
|
||||
return r_hand
|
||||
return null
|
||||
|
||||
|
||||
@@ -455,6 +455,7 @@
|
||||
colour = "alien"
|
||||
key = "y"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/wryn/check_special_condition(mob/other)
|
||||
var/mob/living/carbon/M = other
|
||||
@@ -485,7 +486,7 @@
|
||||
colour = "alien"
|
||||
key = "a"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = 1
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/terrorspider
|
||||
name = "Spider Hivemind"
|
||||
@@ -496,7 +497,7 @@
|
||||
colour = "terrorspider"
|
||||
key = "ts"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = 1
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/ling
|
||||
name = "Changeling"
|
||||
@@ -505,10 +506,11 @@
|
||||
colour = "changeling"
|
||||
key = "g"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/ling/broadcast(mob/living/speaker, message, speaker_mask)
|
||||
if(speaker.mind && speaker.mind.changeling)
|
||||
..(speaker,message,speaker.mind.changeling.changelingID)
|
||||
..(speaker, message, speaker.mind.changeling.changelingID)
|
||||
else if(speaker.mind && speaker.mind.linglink)
|
||||
..()
|
||||
else
|
||||
@@ -521,6 +523,7 @@
|
||||
colour = "shadowling"
|
||||
key = "8"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/shadowling/broadcast(mob/living/speaker, message, speaker_mask)
|
||||
if(speaker.mind && speaker.mind.special_role == SPECIAL_ROLE_SHADOWLING)
|
||||
@@ -539,6 +542,7 @@
|
||||
colour = "abductor"
|
||||
key = "zw" //doesn't matter, this is their default and only language
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/abductor/broadcast(mob/living/speaker, message, speaker_mask)
|
||||
..(speaker,message,speaker.real_name)
|
||||
@@ -567,6 +571,7 @@
|
||||
colour = "alien"
|
||||
key = "bo"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/corticalborer/broadcast(mob/living/speaker, message, speaker_mask)
|
||||
var/mob/living/simple_animal/borer/B
|
||||
@@ -590,7 +595,7 @@
|
||||
exclaim_verb = "declares"
|
||||
key = "b"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = 1
|
||||
follow = TRUE
|
||||
var/drone_only
|
||||
|
||||
/datum/language/binary/broadcast(mob/living/speaker, message, speaker_mask)
|
||||
@@ -636,8 +641,8 @@
|
||||
colour = "say_quote"
|
||||
key = "d"
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
drone_only = 1
|
||||
follow = 1
|
||||
drone_only = TRUE
|
||||
follow = TRUE
|
||||
|
||||
/datum/language/drone
|
||||
name = "Drone"
|
||||
@@ -647,7 +652,7 @@
|
||||
exclaim_verb = "declares"
|
||||
key = "]"
|
||||
flags = RESTRICTED
|
||||
follow = 1
|
||||
follow = TRUE
|
||||
syllables = list ("beep", "boop")
|
||||
|
||||
/datum/language/swarmer
|
||||
@@ -659,7 +664,7 @@
|
||||
colour = "say_quote"
|
||||
key = "z"//Zwarmer...Or Zerg!
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
follow = 1
|
||||
follow = TRUE
|
||||
|
||||
// Language handling.
|
||||
/mob/proc/add_language(language)
|
||||
|
||||
@@ -73,7 +73,11 @@
|
||||
stat = CONSCIOUS
|
||||
return
|
||||
health = maxHealth - getOxyLoss() - getFireLoss() - getBruteLoss() - getCloneLoss()
|
||||
|
||||
update_stat("updatehealth([reason])")
|
||||
med_hud_set_health()
|
||||
med_hud_set_status()
|
||||
handle_hud_icons_health()
|
||||
|
||||
/mob/living/carbon/alien/handle_environment(var/datum/gas_mixture/environment)
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
. = -1 //hunters are sanic
|
||||
. += ..() //but they still need to slow down on stun
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/handle_regular_hud_updates()
|
||||
/mob/living/carbon/alien/humanoid/hunter/handle_hud_icons_health()
|
||||
..() //-Yvarov
|
||||
|
||||
if(healths)
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
alien_organs += new /obj/item/organ/internal/xenos/neurotoxin
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/sentinel/handle_regular_hud_updates()
|
||||
/mob/living/carbon/alien/humanoid/sentinel/handle_hud_icons_health()
|
||||
..() //-Yvarov
|
||||
|
||||
if(healths)
|
||||
|
||||
@@ -48,29 +48,26 @@
|
||||
alien_organs += new /obj/item/organ/internal/xenos/neurotoxin
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/empress
|
||||
/mob/living/carbon/alien/humanoid/empress/handle_hud_icons_health()
|
||||
..() //-Yvarov
|
||||
|
||||
handle_regular_hud_updates()
|
||||
|
||||
..() //-Yvarov
|
||||
|
||||
if(src.healths)
|
||||
if(src.stat != 2)
|
||||
switch(health)
|
||||
if(250 to INFINITY)
|
||||
src.healths.icon_state = "health0"
|
||||
if(175 to 250)
|
||||
src.healths.icon_state = "health1"
|
||||
if(100 to 175)
|
||||
src.healths.icon_state = "health2"
|
||||
if(50 to 100)
|
||||
src.healths.icon_state = "health3"
|
||||
if(0 to 50)
|
||||
src.healths.icon_state = "health4"
|
||||
else
|
||||
src.healths.icon_state = "health5"
|
||||
else
|
||||
src.healths.icon_state = "health6"
|
||||
if(healths)
|
||||
if(stat != 2)
|
||||
switch(health)
|
||||
if(250 to INFINITY)
|
||||
healths.icon_state = "health0"
|
||||
if(175 to 250)
|
||||
healths.icon_state = "health1"
|
||||
if(100 to 175)
|
||||
healths.icon_state = "health2"
|
||||
if(50 to 100)
|
||||
healths.icon_state = "health3"
|
||||
if(0 to 50)
|
||||
healths.icon_state = "health4"
|
||||
else
|
||||
healths.icon_state = "health5"
|
||||
else
|
||||
healths.icon_state = "health6"
|
||||
|
||||
/mob/living/carbon/alien/humanoid/empress/verb/lay_egg()
|
||||
set name = "Lay Egg (250)"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
. = ..()
|
||||
. += 3
|
||||
|
||||
/mob/living/carbon/alien/humanoid/queen/handle_regular_hud_updates()
|
||||
/mob/living/carbon/alien/humanoid/queen/handle_hud_icons_health()
|
||||
..() //-Yvarov
|
||||
|
||||
if(healths)
|
||||
|
||||
@@ -72,7 +72,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
/obj/item/clothing/mask/facehugger/equipped(mob/M)
|
||||
Attach(M)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/Crossed(atom/target)
|
||||
/obj/item/clothing/mask/facehugger/Crossed(atom/target, oldloc)
|
||||
HasProximity(target)
|
||||
return
|
||||
|
||||
|
||||
@@ -95,7 +95,6 @@ I'm using this for Stat to give it a more nifty interface to work with
|
||||
..()
|
||||
if(has_synthetic_assistance())
|
||||
statpanel("Status")
|
||||
show_stat_station_time()
|
||||
show_stat_emergency_shuttle_eta()
|
||||
|
||||
if(client.statpanel == "Status")
|
||||
|
||||
@@ -975,6 +975,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
|
||||
to_chat(src, "<span class='notice'>You [slipVerb]ped on [description]!</span>")
|
||||
playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3)
|
||||
// Something something don't run with scissors
|
||||
moving_diagonally = 0 //If this was part of diagonal move slipping will stop it.
|
||||
Stun(stun)
|
||||
Weaken(weaken)
|
||||
return 1
|
||||
|
||||
@@ -671,9 +671,9 @@
|
||||
if(!restrained())
|
||||
var/t1 = round(text2num(param))
|
||||
if(isnum(t1))
|
||||
if(t1 <= 5 && (!r_hand || !l_hand))
|
||||
if(t1 <= 5 && t1 >= 1 && (!r_hand || !l_hand))
|
||||
message = "<B>[src]</B> raises [t1] finger\s."
|
||||
else if(t1 <= 10 && (!r_hand && !l_hand))
|
||||
else if(t1 <= 10 && t1 >= 1 && (!r_hand && !l_hand))
|
||||
message = "<B>[src]</B> raises [t1] finger\s."
|
||||
m_type = 1
|
||||
|
||||
@@ -946,9 +946,13 @@
|
||||
// Maybe some people are okay with that.
|
||||
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
if(!M.client || istype(M, /mob/new_player))
|
||||
continue //skip monkeys, leavers and new players
|
||||
if(M.stat == DEAD && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
|
||||
if(!M.client)
|
||||
continue
|
||||
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(isobserver(M) && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
M.show_message(message)
|
||||
|
||||
switch(m_type)
|
||||
|
||||
@@ -338,18 +338,9 @@
|
||||
msg += "[p_they(TRUE)] [p_are()] mostly dessicated now, with only bones remaining of what used to be a person.\n"
|
||||
|
||||
if(hasHUD(user,"security"))
|
||||
var/perpname = "wot"
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
var/criminal = "None"
|
||||
|
||||
if(wear_id)
|
||||
var/obj/item/card/id/I = wear_id.GetID()
|
||||
if(I)
|
||||
perpname = I.registered_name
|
||||
else
|
||||
perpname = name
|
||||
else
|
||||
perpname = name
|
||||
|
||||
if(perpname)
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
@@ -361,18 +352,9 @@
|
||||
msg += "<span class = 'deptradio'>Security records:</span> <a href='?src=[UID()];secrecord=`'>\[View\]</a> <a href='?src=[UID()];secrecordadd=`'>\[Add comment\]</a>\n"
|
||||
|
||||
if(hasHUD(user,"medical"))
|
||||
var/perpname = "wot"
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
var/medical = "None"
|
||||
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.general)
|
||||
|
||||
@@ -162,8 +162,6 @@
|
||||
stat(null, "Intent: [a_intent]")
|
||||
stat(null, "Move Mode: [m_intent]")
|
||||
|
||||
show_stat_station_time()
|
||||
|
||||
show_stat_emergency_shuttle_eta()
|
||||
|
||||
if(client.statpanel == "Status")
|
||||
@@ -455,7 +453,7 @@
|
||||
popup.open()
|
||||
|
||||
|
||||
/mob/living/carbon/human/Crossed(atom/movable/AM)
|
||||
/mob/living/carbon/human/Crossed(atom/movable/AM, oldloc)
|
||||
var/mob/living/simple_animal/bot/mulebot/MB = AM
|
||||
if(istype(MB))
|
||||
MB.RunOver(src)
|
||||
@@ -713,17 +711,9 @@
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/found_record = 0
|
||||
var/perpname = "wot"
|
||||
if(wear_id)
|
||||
var/obj/item/card/id/I = wear_id.GetID()
|
||||
if(I)
|
||||
perpname = I.registered_name
|
||||
else
|
||||
perpname = name
|
||||
else
|
||||
perpname = name
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
|
||||
if(perpname)
|
||||
if(perpname != "Unknown")
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.security)
|
||||
@@ -760,17 +750,9 @@
|
||||
if(hasHUD(usr,"security"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
var/read = 0
|
||||
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.security)
|
||||
@@ -792,24 +774,16 @@
|
||||
if(hasHUD(usr,"security"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
var/read = 0
|
||||
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.security)
|
||||
if(R.fields["id"] == E.fields["id"])
|
||||
if(hasHUD(usr,"security"))
|
||||
read = 1
|
||||
if(length(R.fields["comments"]))
|
||||
if(LAZYLEN(R.fields["comments"]))
|
||||
for(var/c in R.fields["comments"])
|
||||
to_chat(usr, c)
|
||||
else
|
||||
@@ -823,15 +797,8 @@
|
||||
if(hasHUD(usr,"security"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.security)
|
||||
@@ -854,17 +821,8 @@
|
||||
if(hasHUD(usr,"medical"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
var/modified = 0
|
||||
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
@@ -889,17 +847,9 @@
|
||||
if(hasHUD(usr,"medical"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
var/read = 0
|
||||
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.medical)
|
||||
@@ -922,24 +872,16 @@
|
||||
if(hasHUD(usr,"medical"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
var/read = 0
|
||||
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.medical)
|
||||
if(R.fields["id"] == E.fields["id"])
|
||||
if(hasHUD(usr,"medical"))
|
||||
read = 1
|
||||
if(length(R.fields["comments"]))
|
||||
if(LAZYLEN(R.fields["comments"]))
|
||||
for(var/c in R.fields["comments"])
|
||||
to_chat(usr, c)
|
||||
else
|
||||
@@ -953,15 +895,7 @@
|
||||
if(hasHUD(usr,"medical"))
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/perpname = "wot"
|
||||
if(wear_id)
|
||||
if(istype(wear_id,/obj/item/card/id))
|
||||
perpname = wear_id:registered_name
|
||||
else if(istype(wear_id,/obj/item/pda))
|
||||
var/obj/item/pda/tempPda = wear_id
|
||||
perpname = tempPda.owner
|
||||
else
|
||||
perpname = src.name
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
for(var/datum/data/record/E in data_core.general)
|
||||
if(E.fields["name"] == perpname)
|
||||
for(var/datum/data/record/R in data_core.medical)
|
||||
@@ -976,6 +910,9 @@
|
||||
if(isrobot(usr))
|
||||
var/mob/living/silicon/robot/U = usr
|
||||
R.fields["comments"] += "Made by [U.name] ([U.modtype] [U.braintype]) on [current_date_string] [station_time_timestamp()]<BR>[t1]"
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
R.fields["comments"] += "Made by [U.name] (artificial intelligence) on [current_date_string] [station_time_timestamp()]<BR>[t1]"
|
||||
|
||||
if(href_list["lookitem"])
|
||||
var/obj/item/I = locate(href_list["lookitem"])
|
||||
@@ -1608,7 +1545,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
|
||||
|
||||
//Check for arrest warrant
|
||||
if(judgebot.check_records)
|
||||
var/perpname = get_face_name(get_id_name())
|
||||
var/perpname = get_visible_name(TRUE)
|
||||
var/datum/data/record/R = find_record("name", perpname, data_core.security)
|
||||
if(R && R.fields["criminal"])
|
||||
switch(R.fields["criminal"])
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
/mob/living/carbon/human/verb/quick_equip()
|
||||
set name = "quick-equip"
|
||||
set hidden = 1
|
||||
|
||||
var/obj/item/I = get_active_hand()
|
||||
if(I)
|
||||
I.equip_to_best_slot(src)
|
||||
|
||||
/mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/W, list/slots, del_on_fail = 1)
|
||||
for(var/slot in slots)
|
||||
if(equip_to_slot_if_possible(W, slots[slot], del_on_fail = 0))
|
||||
|
||||
@@ -341,9 +341,6 @@
|
||||
if(SKELETON in target.mutations)
|
||||
to_chat(user, "<span class='warning'>There is no blood in a skeleton!</span>")
|
||||
return
|
||||
if(issmall(target) && !target.ckey) //Monkeyized humans are okay, humanized monkeys are okay, NPC monkeys are not.
|
||||
to_chat(user, "<span class='warning'>Blood from a monkey is useless!</span>")
|
||||
return
|
||||
//we're good to suck the blood, blaah
|
||||
user.mind.vampire.handle_bloodsucking(target)
|
||||
add_attack_logs(user, target, "vampirebit")
|
||||
@@ -603,20 +600,37 @@
|
||||
H.healthdoll.cached_healthdoll_overlays = new_overlays
|
||||
|
||||
/datum/species/proc/handle_hud_icons_nutrition(mob/living/carbon/human/H)
|
||||
switch(H.nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fat)
|
||||
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/full)
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/well_fed)
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fed)
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/hungry)
|
||||
else
|
||||
H.throw_alert("nutrition", /obj/screen/alert/starving)
|
||||
return 1
|
||||
if(H.mind && H.mind.vampire && (H.mind in SSticker.mode.vampires)) //Vampires
|
||||
switch(H.nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fat/vampire)
|
||||
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/full/vampire)
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/well_fed/vampire)
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fed/vampire)
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/hungry/vampire)
|
||||
else
|
||||
H.throw_alert("nutrition", /obj/screen/alert/starving/vampire)
|
||||
return 1
|
||||
|
||||
else ///Any other non-vampires
|
||||
switch(H.nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fat)
|
||||
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/full)
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/well_fed)
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fed)
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/hungry)
|
||||
else
|
||||
H.throw_alert("nutrition", /obj/screen/alert/starving)
|
||||
return 1
|
||||
|
||||
/*
|
||||
Returns the path corresponding to the corresponding organ
|
||||
@@ -675,7 +689,7 @@ It'll return null if the organ doesn't correspond, so include null checks when u
|
||||
H.see_invisible = G.invis_override
|
||||
else
|
||||
H.see_invisible = min(G.invis_view, H.see_invisible)
|
||||
|
||||
|
||||
if(!isnull(G.lighting_alpha))
|
||||
H.lighting_alpha = min(G.lighting_alpha, H.lighting_alpha)
|
||||
|
||||
|
||||
@@ -59,8 +59,7 @@
|
||||
handle_status_effects() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc
|
||||
|
||||
if(client)
|
||||
//regular_hud_updates() //THIS DOESN'T FUCKING UPDATE SHIT
|
||||
handle_regular_hud_updates() //IT JUST REMOVES FUCKING HUD IMAGES
|
||||
handle_regular_hud_updates()
|
||||
|
||||
..()
|
||||
|
||||
|
||||
@@ -528,7 +528,7 @@
|
||||
return
|
||||
|
||||
var/pull_dir = get_dir(src, pulling)
|
||||
if(get_dist(src, pulling) > 1 || ((pull_dir - 1) & pull_dir)) // puller and pullee more than one tile away or in diagonal position
|
||||
if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir))) // puller and pullee more than one tile away or in diagonal position
|
||||
if(isliving(pulling))
|
||||
var/mob/living/M = pulling
|
||||
if(M.lying && !M.buckled && (prob(M.getBruteLoss() * 200 / M.maxHealth)))
|
||||
|
||||
@@ -216,7 +216,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
message_range = 1
|
||||
|
||||
if(pressure < ONE_ATMOSPHERE * 0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet
|
||||
italics = 1
|
||||
italics = TRUE
|
||||
sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact
|
||||
|
||||
var/list/hear = hear(message_range, T)
|
||||
@@ -236,12 +236,20 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue //skip monkeys and leavers
|
||||
continue
|
||||
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
if(M.stat == DEAD && M.client && M.get_preference(CHAT_GHOSTEARS) && client) // client is so that ghosts don't have to listen to mice
|
||||
listening |= M
|
||||
continue
|
||||
|
||||
if(isobserver(M))
|
||||
if(M.get_preference(CHAT_GHOSTEARS) && client) // The client check is so that ghosts don't have to listen to mice.
|
||||
listening |= M
|
||||
continue
|
||||
|
||||
if(message_range < world.view && (get_dist(T, M) <= world.view))
|
||||
listening |= M
|
||||
continue
|
||||
|
||||
if(get_turf(M) in hearturfs)
|
||||
listening |= M
|
||||
|
||||
@@ -291,10 +299,13 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
log_emote(message, src)
|
||||
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
if(!M.client || istype(M, /mob/new_player))
|
||||
continue //skip monkeys, leavers and new players //who the hell knows why new players are in the dead mob list
|
||||
if(!M.client)
|
||||
continue //skip monkeys and leavers
|
||||
|
||||
if(M.stat == DEAD && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(isobserver(M) && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
M.show_message(message)
|
||||
|
||||
switch(type)
|
||||
@@ -380,7 +391,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
|
||||
var/list/hearturfs = list()
|
||||
|
||||
//Pass whispers on to anything inside the immediate listeners.
|
||||
// Pass whispers on to anything inside the immediate listeners.
|
||||
// This comes before the ghosts do so that ghosts don't act as whisper relays
|
||||
for(var/atom/L in listening)
|
||||
if(ismob(L))
|
||||
@@ -391,22 +402,26 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
if(isobj(L))
|
||||
hearturfs += get_turf(L)
|
||||
|
||||
//ghosts
|
||||
for(var/mob/M in GLOB.dead_mob_list) //does this include players who joined as observers as well?
|
||||
// Loop through all players to see if they need to hear it.
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue
|
||||
if(M.stat == DEAD && M.client && M.get_preference(CHAT_GHOSTEARS))
|
||||
listening |= M
|
||||
|
||||
// This, in tandem with "hearturfs", lets nested mobs hear whispers that are in range
|
||||
// Grifted from saycode above.
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client || isnewplayer(M))
|
||||
continue //skip monkeys and leavers
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(isobserver(M))
|
||||
if(M.get_preference(CHAT_GHOSTEARS)) // The client check is so that ghosts don't have to listen to mice.
|
||||
listening |= M
|
||||
continue
|
||||
|
||||
if(message_range < world.view && (get_dist(whisper_loc, M) <= world.view))
|
||||
listening |= M
|
||||
continue
|
||||
|
||||
if(get_turf(M) in hearturfs)
|
||||
listening |= M
|
||||
|
||||
|
||||
//pass on the message to objects that can hear us.
|
||||
for(var/obj/O in view(message_range, whisper_loc))
|
||||
spawn(0)
|
||||
|
||||
@@ -498,7 +498,7 @@ var/list/ai_verbs_default = list(
|
||||
if(check_unable(AI_CHECK_WIRELESS))
|
||||
return
|
||||
|
||||
var/input = input(usr, "Please enter the reason for calling the shuttle.", "Shuttle Call Reason.","") as text|null
|
||||
var/input = clean_input("Please enter the reason for calling the shuttle.", "Shuttle Call Reason.","")
|
||||
if(!input || stat)
|
||||
return
|
||||
|
||||
@@ -634,7 +634,7 @@ var/list/ai_verbs_default = list(
|
||||
return
|
||||
|
||||
if(href_list["trackbot"])
|
||||
var/mob/living/simple_animal/bot/target = locate(href_list["trackbot"]) in GLOB.simple_animals
|
||||
var/mob/living/simple_animal/bot/target = locate(href_list["trackbot"]) in GLOB.bots_list
|
||||
if(target)
|
||||
ai_actual_track(target)
|
||||
else
|
||||
@@ -642,7 +642,7 @@ var/list/ai_verbs_default = list(
|
||||
return
|
||||
|
||||
if(href_list["callbot"]) //Command a bot to move to a selected location.
|
||||
Bot = locate(href_list["callbot"]) in GLOB.simple_animals
|
||||
Bot = locate(href_list["callbot"]) in GLOB.bots_list
|
||||
if(!Bot || Bot.remote_disabled || control_disabled)
|
||||
return //True if there is no bot found, the bot is manually emagged, or the AI is carded with wireless off.
|
||||
waypoint_mode = 1
|
||||
@@ -650,7 +650,7 @@ var/list/ai_verbs_default = list(
|
||||
return
|
||||
|
||||
if(href_list["interface"]) //Remotely connect to a bot!
|
||||
Bot = locate(href_list["interface"]) in GLOB.simple_animals
|
||||
Bot = locate(href_list["interface"]) in GLOB.bots_list
|
||||
if(!Bot || Bot.remote_disabled || control_disabled)
|
||||
return
|
||||
Bot.attack_ai(src)
|
||||
@@ -746,7 +746,7 @@ var/list/ai_verbs_default = list(
|
||||
d += "<A HREF=?src=[UID()];botrefresh=\ref[Bot]>Query network status</A><br>"
|
||||
d += "<table width='100%'><tr><td width='40%'><h3>Name</h3></td><td width='20%'><h3>Status</h3></td><td width='30%'><h3>Location</h3></td><td width='10%'><h3>Control</h3></td></tr>"
|
||||
|
||||
for(var/mob/living/simple_animal/bot/Bot in GLOB.simple_animals)
|
||||
for(var/mob/living/simple_animal/bot/Bot in GLOB.bots_list)
|
||||
if(is_ai_allowed(Bot.z) && !Bot.remote_disabled) //Only non-emagged bots on the allowed Z-level are detected!
|
||||
bot_area = get_area(Bot)
|
||||
d += "<tr><td width='30%'>[Bot.hacked ? "<span class='bad'>(!) </span>[Bot.name]" : Bot.name] ([Bot.model])</td>"
|
||||
@@ -1074,7 +1074,7 @@ var/list/ai_verbs_default = list(
|
||||
set desc = "Change the message that's transmitted when a new crew member arrives on station."
|
||||
set category = "AI Commands"
|
||||
|
||||
var/newmsg = input("What would you like the arrival message to be? List of options: $name, $rank, $species, $gender, $age", "Change Arrival Message", arrivalmsg) as text
|
||||
var/newmsg = clean_input("What would you like the arrival message to be? List of options: $name, $rank, $species, $gender, $age", "Change Arrival Message", arrivalmsg)
|
||||
if(newmsg != arrivalmsg)
|
||||
arrivalmsg = newmsg
|
||||
to_chat(usr, "The arrival message has been successfully changed.")
|
||||
|
||||
@@ -99,7 +99,7 @@ var/const/VOX_PATH = "sound/vox_fem/"
|
||||
to_chat(src, "<span class='warning'>Please wait [round((announcing_vox - world.time) / 10)] seconds.</span>")
|
||||
return
|
||||
|
||||
var/message = input(src, "WARNING: Misuse of this verb can result in you being job banned. More help is available in 'Announcement Help'", "Announcement", last_announcement) as text|null
|
||||
var/message = clean_input("WARNING: Misuse of this verb can result in you being job banned. More help is available in 'Announcement Help'", "Announcement", last_announcement, src)
|
||||
|
||||
last_announcement = message
|
||||
|
||||
|
||||
@@ -2,6 +2,3 @@
|
||||
..()
|
||||
regenerate_icons()
|
||||
show_laws(0)
|
||||
|
||||
var/datum/hotkey_mode/cyborg/C = new(src)
|
||||
C.set_winset_values()
|
||||
|
||||
@@ -1456,4 +1456,4 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
|
||||
sync_lighting_plane_alpha()
|
||||
|
||||
|
||||
|
||||
@@ -156,7 +156,6 @@
|
||||
/mob/living/silicon/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
show_stat_station_time()
|
||||
show_stat_emergency_shuttle_eta()
|
||||
show_system_integrity()
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
..()
|
||||
light_color = LIGHT_COLOR_PURE_RED //if you see a red one. RUN!!
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/griefsky/Crossed(atom/movable/AM)
|
||||
/mob/living/simple_animal/bot/secbot/griefsky/Crossed(atom/movable/AM, oldloc)
|
||||
..()
|
||||
if(ismob(AM) && AM == target)
|
||||
var/mob/living/carbon/C = AM
|
||||
|
||||
@@ -298,7 +298,7 @@
|
||||
target = user
|
||||
mode = BOT_HUNT
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/Crossed(atom/movable/AM)
|
||||
/mob/living/simple_animal/bot/honkbot/Crossed(atom/movable/AM, oldloc)
|
||||
if(ismob(AM) && on) //only if its online
|
||||
if(prob(30)) //you're far more likely to trip on a honkbot
|
||||
var/mob/living/carbon/C = AM
|
||||
|
||||
@@ -439,7 +439,7 @@ Auto Patrol: []"},
|
||||
target = user
|
||||
mode = BOT_HUNT
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Crossed(atom/movable/AM)
|
||||
/mob/living/simple_animal/bot/secbot/Crossed(atom/movable/AM, oldloc)
|
||||
if(ismob(AM) && target)
|
||||
var/mob/living/carbon/C = AM
|
||||
if(!istype(C) || !C || in_range(src, target))
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
/mob/living/simple_animal/cockroach/can_die()
|
||||
return ..() && !SSticker.cinematic //If the nuke is going off, then cockroaches are invincible. Keeps the nuke from killing them, cause cockroaches are immune to nukes.
|
||||
|
||||
/mob/living/simple_animal/cockroach/Crossed(var/atom/movable/AM)
|
||||
/mob/living/simple_animal/cockroach/Crossed(var/atom/movable/AM, oldloc)
|
||||
if(isliving(AM))
|
||||
var/mob/living/A = AM
|
||||
if(A.mob_size > MOB_SIZE_SMALL)
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
to_chat(src, "<span class='warning'>You are too small to pull anything.</span>")
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/mouse/Crossed(AM as mob|obj)
|
||||
/mob/living/simple_animal/mouse/Crossed(AM as mob|obj, oldloc)
|
||||
if(ishuman(AM))
|
||||
if(!stat)
|
||||
var/mob/M = AM
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
turns_per_move = 10
|
||||
icon = 'icons/mob/penguins.dmi'
|
||||
|
||||
/mob/living/simple_animal/pet/penguin/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/waddling)
|
||||
|
||||
/mob/living/simple_animal/pet/penguin/emperor
|
||||
name = "Emperor penguin"
|
||||
real_name = "penguin"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user