TG sync Sunday (#201)

* stage one

* datums and shit

* game stuff

* modules

* tgstation.dme

* tools

* these things for icons

* compiling fixes

* merge spree on TG

* other updates

* updated maps with deepfryers

* My helpers were not helping
This commit is contained in:
Poojawa
2017-02-06 00:36:56 -06:00
committed by GitHub
parent aeeca195c7
commit 73b6b33f79
279 changed files with 3548 additions and 2585 deletions
+1 -1
View File
@@ -129,7 +129,7 @@
/obj/machinery/vr_sleeper/ui_data(mob/user)
var/list/data = list()
if(vr_human && !qdeleted(vr_human))
if(vr_human && !QDELETED(vr_human))
data["can_delete_avatar"] = TRUE
var/status
switch(user.stat)
+2 -2
View File
@@ -117,9 +117,9 @@ var/savefile/Banlist
if (temp)
Banlist["minutes"] << bantimestamp
if(!temp)
add_note(ckey, "Permanently banned - [reason]", null, bannedby, 0, null, 0)
create_message("note", ckey, bannedby, "Permanently banned - [reason]", null, null, 0, 0)
else
add_note(ckey, "Banned for [minutes] minutes - [reason]", null, bannedby, 0, null, 0)
create_message("note", ckey, bannedby, "Banned for [minutes] minutes - [reason]", null, null, 0, 0)
return 1
/proc/RemoveBan(foldername)
+1 -7
View File
@@ -61,14 +61,8 @@ var/global/BSACooldown = 0
else
body+= "<A href='?_src_=holder;jobban3=emote;jobban4=\ref[M]'>Emoteban</A> | "
body += "<A href='?_src_=holder;shownoteckey=[M.ckey]'>Notes</A> | "
body += "<A href='?_src_=holder;showmessageckey=[M.ckey]'>Notes | Messages | Watchlist</A> | "
if(M.client)
if(M.client.check_watchlist(M.client.ckey))
body += "<A href='?_src_=holder;watchremove=[M.ckey]'>Remove from Watchlist</A> | "
body += "<A href='?_src_=holder;watchedit=[M.ckey]'>Edit Watchlist reason</A> "
else
body += "<A href='?_src_=holder;watchadd=\ref[M.ckey]'>Add to Watchlist</A> "
body += "| <A href='?_src_=holder;sendtoprison=\ref[M]'>Prison</A> | "
body += "\ <A href='?_src_=holder;sendbacktolobby=\ref[M]'>Send back to Lobby</A> | "
var/muted = M.client.prefs.muted
+3 -5
View File
@@ -25,7 +25,7 @@
F << "<small>[time_stamp()] \ref[src] ([x],[y],[z])</small> || [src] [message]<br>"
//ADMINVERBS
/client/proc/investigate_show( subject in list("hrefs","notes","watchlist","singulo","wires","telesci", "gravity", "records", "cargo", "supermatter", "atmos", "experimentor", "kudzu") )
/client/proc/investigate_show( subject in list("hrefs","notes, memos, watchlist","singulo","wires","telesci", "gravity", "records", "cargo", "supermatter", "atmos", "experimentor", "kudzu") )
set name = "Investigate"
set category = "Admin"
if(!holder)
@@ -46,7 +46,5 @@
else
src << "<span class='danger'>No href logfile was found.</span>"
return
if("notes")
show_note()
if("watchlist")
watchlist_show()
if("notes, memos, watchlist")
browse_messages()
+1 -1
View File
@@ -15,7 +15,7 @@
. = ..()
/obj/effect/fun_balloon/process()
if(!popped && check() && !qdeleted(src))
if(!popped && check() && !QDELETED(src))
popped = TRUE
effect()
pop()
-1
View File
@@ -5,7 +5,6 @@ var/list/admin_datums = list()
var/client/owner = null
var/fakekey = null
var/following = null
var/datum/marked_datum
+1 -1
View File
@@ -76,7 +76,7 @@
body += "</td><td align='center'>";
body += "<a href='?_src_=holder;adminplayeropts="+ref+"'>PP</a> - "
body += "<a href='?_src_=holder;shownoteckey="+ckey+"'>N</a> - "
body += "<a href='?_src_=holder;showmessageckey="+ckey+"'>N</a> - "
body += "<a href='?_src_=vars;Vars="+ref+"'>VV</a> - "
body += "<a href='?_src_=holder;traitor="+ref+"'>TP</a> - "
body += "<a href='?priv_msg="+ckey+"'>PM</a> - "
+371
View File
@@ -0,0 +1,371 @@
/proc/create_message(type, target_ckey, admin_ckey, text, timestamp, server, secret, logged = 1, browse)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
if(!type)
return
if(!target_ckey && (type == "note" || type == "message" || type == "watchlist entry"))
var/new_ckey = ckey(input(usr,"Who would you like to create a [type] for?","Enter a ckey",null) as null|text)
if(!new_ckey)
return
new_ckey = sanitizeSQL(new_ckey)
var/DBQuery/query_find_ckey = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'")
if(!query_find_ckey.Execute())
var/err = query_find_ckey.ErrorMsg()
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
return
if(!query_find_ckey.NextRow())
if(alert(usr, "[new_ckey] has not been seen before, are you sure you want to create a [type] for them?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes")
return
target_ckey = new_ckey
if(target_ckey)
target_ckey = sanitizeSQL(target_ckey)
if(!admin_ckey)
admin_ckey = usr.ckey
if(!admin_ckey)
return
admin_ckey = sanitizeSQL(admin_ckey)
if(!target_ckey)
target_ckey = admin_ckey
if(!text)
text = input(usr,"Write your [type]","Create [type]") as null|message
if(!text)
return
text = sanitizeSQL(text)
if(!timestamp)
timestamp = SQLtime()
if(!server)
if (config && config.server_name)
server = config.server_name
server = sanitizeSQL(server)
if(isnull(secret))
switch(alert("Hide note from being viewed by players?", "Secret note?","Yes","No","Cancel"))
if("Yes")
secret = 1
if("No")
secret = 0
else
return
var/DBQuery/query_create_message = dbcon.NewQuery("INSERT INTO [format_table_name("messages")] (type, targetckey, adminckey, text, timestamp, server, secret) VALUES ('[type]', '[target_ckey]', '[admin_ckey]', '[text]', '[timestamp]', '[server]', '[secret]')")
if(!query_create_message.Execute())
var/err = query_create_message.ErrorMsg()
log_game("SQL ERROR creating new [type] in messages table. Error : \[[err]\]\n")
return
if(logged)
log_admin("[key_name(usr)] has created a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_ckey]" : ""]: [text]")
message_admins("[key_name_admin(usr)] has created a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_ckey]" : ""]:<br>[text]")
if(browse)
browse_messages("[type]")
else
browse_messages(target_ckey = target_ckey)
/proc/delete_message(message_id, logged = 1, browse)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
message_id = text2num(message_id)
if(!message_id)
return
var/type
var/target_ckey
var/text
var/DBQuery/query_find_del_message = dbcon.NewQuery("SELECT type, targetckey, adminckey, text FROM [format_table_name("messages")] WHERE id = [message_id]")
if(!query_find_del_message.Execute())
var/err = query_find_del_message.ErrorMsg()
log_game("SQL ERROR obtaining type, targetckey, adminckey text from messages table. Error : \[[err]\]\n")
return
if(query_find_del_message.NextRow())
type = query_find_del_message.item[1]
target_ckey = query_find_del_message.item[2]
text = query_find_del_message.item[4]
var/DBQuery/query_del_message = dbcon.NewQuery("DELETE FROM [format_table_name("messages")] WHERE id = [message_id]")
if(!query_del_message.Execute())
var/err = query_del_message.ErrorMsg()
log_game("SQL ERROR deleting [type] from messages table. Error : \[[err]\]\n")
return
if(logged)
log_admin("[key_name(usr)] has deleted a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for" : " made by"] [target_ckey]: [text]")
message_admins("[key_name_admin(usr)] has deleted a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for" : " made by"] [target_ckey]:<br>[text]")
if(browse)
browse_messages("[type]")
else
browse_messages(target_ckey = target_ckey)
/proc/edit_message(message_id, browse)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
message_id = text2num(message_id)
if(!message_id)
return
var/DBQuery/query_find_edit_message = dbcon.NewQuery("SELECT type, targetckey, adminckey, text FROM [format_table_name("messages")] WHERE id = [message_id]")
if(!query_find_edit_message.Execute())
var/err = query_find_edit_message.ErrorMsg()
log_game("SQL ERROR obtaining type, targetckey, adminckey, text from messages table. Error : \[[err]\]\n")
return
if(query_find_edit_message.NextRow())
var/type = query_find_edit_message.item[1]
var/target_ckey = query_find_edit_message.item[2]
var/admin_ckey = query_find_edit_message.item[3]
var/old_text = query_find_edit_message.item[4]
var/editor_ckey = sanitizeSQL(usr.ckey)
var/new_text = input("Input new [type]", "New [type]", "[old_text]") as null|message
if(!new_text)
return
new_text = sanitizeSQL(new_text)
var/edit_text = sanitizeSQL("Edited by [editor_ckey] on [SQLtime()] from<br>[old_text]<br>to<br>[new_text]<hr>")
var/DBQuery/query_edit_message = dbcon.NewQuery("UPDATE [format_table_name("messages")] SET text = '[new_text]', lasteditor = '[editor_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [message_id]")
if(!query_edit_message.Execute())
var/err = query_edit_message.ErrorMsg()
log_game("SQL ERROR editing messages table. Error : \[[err]\]\n")
return
log_admin("[key_name(usr)] has edited a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_ckey]" : ""] made by [admin_ckey] from [old_text] to [new_text]")
message_admins("[key_name_admin(usr)] has edited a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_ckey]" : ""] made by [admin_ckey] from<br>[old_text]<br>to<br>[new_text]")
if(browse)
browse_messages("[type]")
else
browse_messages(target_ckey = target_ckey)
/proc/toggle_message_secrecy(message_id)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
message_id = text2num(message_id)
if(!message_id)
return
var/DBQuery/query_find_message_secret = dbcon.NewQuery("SELECT type, targetckey, adminckey, secret FROM [format_table_name("messages")] WHERE id = [message_id]")
if(!query_find_message_secret.Execute())
var/err = query_find_message_secret.ErrorMsg()
log_game("SQL ERROR obtaining type, targetckey, adminckey, secret from messages table. Error : \[[err]\]\n")
return
if(query_find_message_secret.NextRow())
var/type = query_find_message_secret.item[1]
var/target_ckey = query_find_message_secret.item[2]
var/admin_ckey = query_find_message_secret.item[3]
var/secret = text2num(query_find_message_secret.item[4])
var/editor_ckey = sanitizeSQL(usr.ckey)
var/edit_text = "Made [secret ? "not secret" : "secret"] by [editor_ckey] on [SQLtime()]<hr>"
var/DBQuery/query_message_secret = dbcon.NewQuery("UPDATE [format_table_name("messages")] SET secret = NOT secret, lasteditor = '[editor_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [message_id]")
if(!query_message_secret.Execute())
var/err = query_message_secret.ErrorMsg()
log_game("SQL ERROR toggling message secrecy. Error : \[[err]\]\n")
return
log_admin("[key_name(usr)] has toggled [target_ckey]'s [type] made by [admin_ckey] to [secret ? "not secret" : "secret"]")
message_admins("[key_name_admin(usr)] has toggled [target_ckey]'s [type] made by [admin_ckey] to [secret ? "not secret" : "secret"]")
browse_messages(target_ckey = target_ckey)
/proc/browse_messages(type, target_ckey, index, linkless = 0)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
var/output
var/ruler = "<hr style='background:#000000; border:0; height:3px'>"
var/navbar = "<a href='?_src_=holder;nonalpha=1'>\[All\]</a>|<a href='?_src_=holder;nonalpha=2'>\[#\]</a>"
for(var/letter in alphabet)
navbar += "|<a href='?_src_=holder;showmessages=[letter]'>\[[letter]\]</a>"
navbar += "|<a href='?_src_=holder;showmemo=1'>\[Memos\]</a>|<a href='?_src_=holder;showwatch=1'>\[Watchlist\]</a>"
navbar += "<br><form method='GET' name='search' action='?'>\
<input type='hidden' name='_src_' value='holder'>\
<input type='text' name='searchmessages' value='[index]'>\
<input type='submit' value='Search'></form>"
if(!linkless)
output = navbar
if(type == "memo" || type == "watchlist entry")
if(type == "memo")
output += "<h2><center>Admin memos</h2>"
output += "<a href='?_src_=holder;addmemo=1'>\[Add memo\]</a></center>"
else if(type == "watchlist entry")
output += "<h2><center>Watchlist entries</h2>"
output += "<a href='?_src_=holder;addwatchempty=1'>\[Add watchlist entry\]</a></center>"
output += ruler
var/DBQuery/query_get_type_messages = dbcon.NewQuery("SELECT id, targetckey, adminckey, text, timestamp, server, lasteditor FROM [format_table_name("messages")] WHERE type = '[type]'")
if(!query_get_type_messages.Execute())
var/err = query_get_type_messages.ErrorMsg()
log_game("SQL ERROR obtaining id, targetckey, adminckey, text, timestamp, server, lasteditor from messages table. Error : \[[err]\]\n")
return
while(query_get_type_messages.NextRow())
var/id = query_get_type_messages.item[1]
var/t_ckey = query_get_type_messages.item[2]
var/admin_ckey = query_get_type_messages.item[3]
var/text = query_get_type_messages.item[4]
var/timestamp = query_get_type_messages.item[5]
var/server = query_get_type_messages.item[6]
var/editor_ckey = query_get_type_messages.item[7]
output += "<b>"
if(type == "watchlist entry")
output += "[t_ckey] | "
output += "[timestamp] | [server] | [admin_ckey]</b>"
output += " <a href='?_src_=holder;deletemessageempty=[id]'>\[Delete\]</a>"
output += " <a href='?_src_=holder;editmessageempty=[id]'>\[Edit\]</a>"
if(editor_ckey)
output += " <font size='2'>Last edit by [editor_ckey] <a href='?_src_=holder;messageedits=[id]'>(Click here to see edit log)</a></font>"
output += "<br>[text]<hr style='background:#000000; border:0; height:1px'>"
if(target_ckey)
target_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_get_messages = dbcon.NewQuery("SELECT type, secret, id, adminckey, text, timestamp, server, lasteditor FROM [format_table_name("messages")] WHERE type <> 'memo' AND targetckey = '[target_ckey]' ORDER BY timestamp")
if(!query_get_messages.Execute())
var/err = query_get_messages.ErrorMsg()
log_game("SQL ERROR obtaining type, secret, id, adminckey, text, timestamp, server, lasteditor from messages table. Error : \[[err]\]\n")
return
var/messagedata
var/watchdata
var/notedata
while(query_get_messages.NextRow())
type = query_get_messages.item[1]
if(type == "memo")
continue
var/secret = text2num(query_get_messages.item[2])
if(linkless && secret)
continue
var/id = query_get_messages.item[3]
var/admin_ckey = query_get_messages.item[4]
var/text = query_get_messages.item[5]
var/timestamp = query_get_messages.item[6]
var/server = query_get_messages.item[7]
var/editor_ckey = query_get_messages.item[8]
var/data
data += "<b>[timestamp] | [server] | [admin_ckey]</b>"
if(!linkless)
data += " <a href='?_src_=holder;deletemessage=[id]'>\[Delete\]</a>"
if(type == "note")
data += " <a href='?_src_=holder;secretmessage=[id]'>[secret ? "<b>\[Secret\]</b>" : "\[Not secret\]"]</a>"
data += " <a href='?_src_=holder;editmessage=[id]'>\[Edit\]</a>"
if(editor_ckey)
data += " <font size='2'>Last edit by [editor_ckey] <a href='?_src_=holder;messageedits=[id]'>(Click here to see edit log)</a></font>"
data += "<br>[text]<hr style='background:#000000; border:0; height:1px'>"
switch(type)
if("message")
messagedata += data
if("watchlist entry")
watchdata += data
if("note")
notedata += data
output += "<h2><center>[target_ckey]</center></h2><center>"
if(!linkless)
output += "<a href='?_src_=holder;addmessage=[target_ckey]'>\[Add message\]</a>"
output += " <a href='?_src_=holder;addwatch=[target_ckey]'>\[Add to watchlist\]</a>"
output += " <a href='?_src_=holder;addnote=[target_ckey]'>\[Add note\]</a>"
output += " <a href='?_src_=holder;showmessageckey=[target_ckey]'>\[Refresh page\]</a></center>"
else
output += " <a href='?_src_=holder;showmessageckeylinkless=[target_ckey]'>\[Refresh page\]</a></center>"
output += ruler
if(messagedata)
output += "<h4>Messages</h4>"
output += messagedata
if(watchdata)
output += "<h4>Watchlist</h4>"
output += watchdata
if(notedata)
output += "<h4>Notes</h4>"
output += notedata
if(index)
var/index_ckey
var/search
output += "<center><a href='?_src_=holder;addmessageempty=1'>\[Add message\]</a><a href='?_src_=holder;addwatchempty=1'>\[Add watchlist entry\]</a><a href='?_src_=holder;addnoteempty=1'>\[Add note\]</a></center>"
output += ruler
if(!isnum(index))
index = sanitizeSQL(index)
switch(index)
if(1)
search = "^."
if(2)
search = "^\[^\[:alpha:\]\]"
else
search = "^[index]"
var/DBQuery/query_list_messages = dbcon.NewQuery("SELECT DISTINCT targetckey FROM [format_table_name("messages")] WHERE type <> 'memo' AND targetckey REGEXP '[search]' ORDER BY targetckey")
if(!query_list_messages.Execute())
var/err = query_list_messages.ErrorMsg()
log_game("SQL ERROR obtaining distinct targetckey from messages table. Error : \[[err]\]\n")
return
while(query_list_messages.NextRow())
index_ckey = query_list_messages.item[1]
output += "<a href='?_src_=holder;showmessageckey=[index_ckey]'>[index_ckey]</a><br>"
else if(!type && !target_ckey && !index)
output += "<center></a> <a href='?_src_=holder;addmessageempty=1'>\[Add message\]</a><a href='?_src_=holder;addwatchempty=1'>\[Add watchlist entry\]</a><a href='?_src_=holder;addnoteempty=1'>\[Add note\]</a></center>"
output += ruler
usr << browse(output, "window=browse_messages;size=900x500")
proc/get_message_output(type, target_ckey)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
if(!type)
return
var/output
if(target_ckey)
target_ckey = sanitizeSQL(target_ckey)
var/query = "SELECT id, adminckey, text, timestamp, lasteditor FROM [format_table_name("messages")] WHERE type = '[type]'"
if(type == "message" || type == "watchlist entry")
query += " AND targetckey = '[target_ckey]'"
var/DBQuery/query_get_message_output = dbcon.NewQuery(query)
if(!query_get_message_output.Execute())
var/err = query_get_message_output.ErrorMsg()
log_game("SQL ERROR obtaining id, adminckey, text, timestamp, lasteditor from messages table. Error : \[[err]\]\n")
return
while(query_get_message_output.NextRow())
var/id = query_get_message_output.item[1]
var/admin_ckey = query_get_message_output.item[2]
var/text = query_get_message_output.item[3]
var/timestamp = query_get_message_output.item[4]
var/editor_ckey = query_get_message_output.item[5]
switch(type)
if("message")
output += "<font color='red' size='3'><b>Admin message left by <span class='prefix'>[admin_ckey]</span> on [timestamp]</b></font>"
output += "<br><font color='red'>[text]</font>"
delete_message(id, 0)
if("watchlist entry")
message_admins("<font color='red'><B>Notice: </B></font><font color='blue'>[key_name_admin(target_ckey)] is on the watchlist and has just connected - Reason: [text]</font>")
send2admindiscord("Watchlist", "[key_name(target_ckey)] is on the watchlist and has just connected - Reason: [text]")
if("memo")
output += "<span class='memo'>Memo by <span class='prefix'>[admin_ckey]</span> on [timestamp]"
if(editor_ckey)
output += "<br><span class='memoedit'>Last edit by [editor_ckey] <A href='?_src_=holder;messageedits=[id]'>(Click here to see edit log)</A></span>"
output += "<br>[text]</span><br>"
return output
#define NOTESFILE "data/player_notes.sav"
//if the AUTOCONVERT_NOTES is turned on, anytime a player connects this will be run to try and add all their notes to the databas
/proc/convert_notes_sql(ckey)
var/savefile/notesfile = new(NOTESFILE)
if(!notesfile)
log_game("Error: Cannot access [NOTESFILE]")
return
notesfile.cd = "/[ckey]"
while(!notesfile.eof)
var/notetext
notesfile >> notetext
var/server
if(config && config.server_name)
server = config.server_name
var/regex/note = new("^(\\d{2}-\\w{3}-\\d{4}) \\| (.+) ~(\\w+)$", "i")
note.Find(notetext)
var/timestamp = note.group[1]
notetext = note.group[2]
var/admin_ckey = note.group[3]
var/DBQuery/query_convert_time = dbcon.NewQuery("SELECT ADDTIME(STR_TO_DATE('[timestamp]','%d-%b-%Y'), '0')")
if(!query_convert_time.Execute())
var/err = query_convert_time.ErrorMsg()
log_game("SQL ERROR converting timestamp. Error : \[[err]\]\n")
return
if(query_convert_time.NextRow())
timestamp = query_convert_time.item[1]
if(ckey && notetext && timestamp && admin_ckey && server)
create_message("note", ckey, admin_ckey, notetext, timestamp, server, 1, 0)
notesfile.cd = "/"
notesfile.dir.Remove(ckey)
/*alternatively this proc can be run once to pass through every note and attempt to convert it before deleting the file, if done then AUTOCONVERT_NOTES should be turned off
this proc can take several minutes to execute fully if converting and cause DD to hang if converting a lot of notes; it's not advised to do so while a server is live
/proc/mass_convert_notes()
world << "Beginning mass note conversion"
var/savefile/notesfile = new(NOTESFILE)
if(!notesfile)
log_game("Error: Cannot access [NOTESFILE]")
return
notesfile.cd = "/"
for(var/ckey in notesfile.dir)
convert_notes_sql(ckey)
world << "Deleting NOTESFILE"
fdel(NOTESFILE)
world << "Finished mass note conversion, remember to turn off AUTOCONVERT_NOTES"*/
#undef NOTESFILE
-260
View File
@@ -1,260 +0,0 @@
/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server, secret)
if(!dbcon.IsConnected())
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)
if(!new_ckey)
return
new_ckey = sanitizeSQL(new_ckey)
var/DBQuery/query_find_ckey = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'")
if(!query_find_ckey.Execute())
var/err = query_find_ckey.ErrorMsg()
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
return
if(!query_find_ckey.NextRow())
if(alert(usr, "[new_ckey] has not been seen before, are you sure you want to add a note for them?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes")
return
target_ckey = new_ckey
var/target_sql_ckey = sanitizeSQL(target_ckey)
if(!notetext)
notetext = input(usr,"Write your Note","Add Note") as null|message
if(!notetext)
return
notetext = sanitizeSQL(notetext)
if(!timestamp)
timestamp = SQLtime()
if(!adminckey)
adminckey = usr.ckey
if(!adminckey)
return
var/admin_sql_ckey = sanitizeSQL(adminckey)
if(!server)
if (config && config.server_name)
server = config.server_name
server = sanitizeSQL(server)
if(isnull(secret))
switch(alert("Hide note from being viewed by players?", "Secret Note?","Yes","No","Cancel"))
if("Yes")
secret = 1
if("No")
secret = 0
else
return
var/DBQuery/query_noteadd = dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server, secret) VALUES ('[target_sql_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]', '[secret]')")
if(!query_noteadd.Execute())
var/err = query_noteadd.ErrorMsg()
log_game("SQL ERROR adding new note to table. Error : \[[err]\]\n")
return
if(logged)
log_admin("[key_name(usr)] has added a note to [target_ckey]: [notetext]")
message_admins("[key_name_admin(usr)] has added a note to [target_ckey]:<br>[notetext]")
show_note(target_ckey)
/proc/remove_note(note_id)
var/ckey
var/notetext
var/adminckey
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
if(!note_id)
return
note_id = text2num(note_id)
var/DBQuery/query_find_note_del = dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = [note_id]")
if(!query_find_note_del.Execute())
var/err = query_find_note_del.ErrorMsg()
log_game("SQL ERROR obtaining ckey, notetext, adminckey from notes table. Error : \[[err]\]\n")
return
if(query_find_note_del.NextRow())
ckey = query_find_note_del.item[1]
notetext = query_find_note_del.item[2]
adminckey = query_find_note_del.item[3]
var/DBQuery/query_del_note = dbcon.NewQuery("DELETE FROM [format_table_name("notes")] WHERE id = [note_id]")
if(!query_del_note.Execute())
var/err = query_del_note.ErrorMsg()
log_game("SQL ERROR removing note from table. Error : \[[err]\]\n")
return
log_admin("[key_name(usr)] has removed a note made by [adminckey] from [ckey]: [notetext]")
message_admins("[key_name_admin(usr)] has removed a note made by [adminckey] from [ckey]:<br>[notetext]")
show_note(ckey)
/proc/edit_note(note_id)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
if(!note_id)
return
note_id = text2num(note_id)
var/target_ckey
var/sql_ckey = sanitizeSQL(usr.ckey)
var/DBQuery/query_find_note_edit = dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = [note_id]")
if(!query_find_note_edit.Execute())
var/err = query_find_note_edit.ErrorMsg()
log_game("SQL ERROR obtaining notetext from notes table. Error : \[[err]\]\n")
return
if(query_find_note_edit.NextRow())
target_ckey = query_find_note_edit.item[1]
var/old_note = query_find_note_edit.item[2]
var/adminckey = query_find_note_edit.item[3]
var/new_note = input("Input new note", "New Note", "[old_note]") as null|message
if(!new_note)
return
new_note = sanitizeSQL(new_note)
var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from<br>[old_note]<br>to<br>[new_note]<hr>"
edit_text = sanitizeSQL(edit_text)
var/DBQuery/query_update_note = dbcon.NewQuery("UPDATE [format_table_name("notes")] SET notetext = '[new_note]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [note_id]")
if(!query_update_note.Execute())
var/err = query_update_note.ErrorMsg()
log_game("SQL ERROR editing note. Error : \[[err]\]\n")
return
log_admin("[key_name(usr)] has edited [target_ckey]'s note made by [adminckey] from [old_note] to [new_note]")
message_admins("[key_name_admin(usr)] has edited [target_ckey]'s note made by [adminckey] from<br>[old_note]<br>to<br>[new_note]")
show_note(target_ckey)
/proc/toggle_note_secrecy(note_id)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
if(!note_id)
return
note_id = text2num(note_id)
var/DBQuery/query_find_note_secret = dbcon.NewQuery("SELECT ckey, adminckey, secret FROM [format_table_name("notes")] WHERE id = [note_id]")
if(!query_find_note_secret.Execute())
var/err = query_find_note_secret.ErrorMsg()
log_game("SQL ERROR obtaining ckey, adminckey, secret from notes table. Error : \[[err]\]\n")
return
if(query_find_note_secret.NextRow())
var/target_ckey = query_find_note_secret.item[1]
var/adminckey = query_find_note_secret.item[2]
var/secret = text2num(query_find_note_secret.item[3])
var/sql_ckey = sanitizeSQL(usr.ckey)
var/edit_text = "Made [secret ? "not secret" : "secret"] by [sql_ckey] on [SQLtime()]<hr>"
var/DBQuery/query_update_note = dbcon.NewQuery("UPDATE [format_table_name("notes")] SET secret = NOT secret, last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [note_id]")
if(!query_update_note.Execute())
var/err = query_update_note.ErrorMsg()
log_game("SQL ERROR toggling note secrecy. Error : \[[err]\]\n")
return
log_admin("[key_name(usr)] has toggled [target_ckey]'s note made by [adminckey] to [secret ? "not secret" : "secret"]")
message_admins("[key_name_admin(usr)] has toggled [target_ckey]'s note made by [adminckey] to [secret ? "not secret" : "secret"]")
show_note(target_ckey)
/proc/show_note(target_ckey, index, linkless = 0)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
var/output
var/ruler = "<hr style='background:#000000; border:0; height:3px'>"
var/navbar = "<a href='?_src_=holder;nonalpha=1'>\[All\]</a>|<a href='?_src_=holder;nonalpha=2'>\[#\]</a>"
for(var/letter in alphabet)
navbar += "|<a href='?_src_=holder;shownote=[letter]'>\[[letter]\]</a>"
navbar += "<br><form method='GET' name='search' action='?'>\
<input type='hidden' name='_src_' value='holder'>\
<input type='text' name='notessearch' value='[index]'>\
<input type='submit' value='Search'></form>"
if(!linkless)
output = navbar
if(target_ckey)
var/target_sql_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT secret, timestamp, notetext, adminckey, last_editor, server, id FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
if(!query_get_notes.Execute())
var/err = query_get_notes.ErrorMsg()
usr << "<span class='danger'>SQL ERROR: Failed to obtain DB records. Error : \[[err]\]\</span>"
log_game("SQL ERROR obtaining secret, timestamp, notetext, adminckey, last_editor, server, id from notes table. Error : \[[err]\]\n")
return
output += "<h2><center>Notes of [target_ckey]</center></h2>"
if(!linkless)
output += "<center><a href='?_src_=holder;addnote=[target_ckey]'>\[Add Note\]</a>"
output += " <a href='?_src_=holder;shownoteckey=[target_ckey]'>\[Refresh Page\]</a></center>"
else
output += " <a href='?_src_=holder;shownoteckeylinkless=[target_ckey]'>\[Refresh Page\]</a></center>"
output += ruler
while(query_get_notes.NextRow())
var/secret = text2num(query_get_notes.item[1])
if(linkless && secret)
continue
var/timestamp = query_get_notes.item[2]
var/notetext = query_get_notes.item[3]
var/adminckey = query_get_notes.item[4]
var/last_editor = query_get_notes.item[5]
var/server = query_get_notes.item[6]
var/id = query_get_notes.item[7]
output += "<b>[timestamp] | [server] | [adminckey]</b>"
if(!linkless)
output += " <a href='?_src_=holder;removenote=[id]'>\[Remove Note\]</a> <a href='?_src_=holder;secretnote=[id]'>[secret ? "<b>\[Secret\]</b>" : "\[Not Secret\]"]</a> <a href='?_src_=holder;editnote=[id]'>\[Edit Note\]</a>"
if(last_editor)
output += " <font size='2'>Last edit by [last_editor] <a href='?_src_=holder;noteedits=[id]'>(Click here to see edit log)</a></font>"
output += "<br>[notetext]<hr style='background:#000000; border:0; height:1px'>"
else if(index)
var/index_ckey
var/search
output += "<center><a href='?_src_=holder;addnoteempty=1'>\[Add Note\]</a></center>"
output += ruler
if(!isnum(index))
index = sanitizeSQL(index)
switch(index)
if(1)
search = "^."
if(2)
search = "^\[^\[:alpha:\]\]"
else
search = "^[index]"
var/DBQuery/query_list_notes = dbcon.NewQuery("SELECT DISTINCT ckey FROM [format_table_name("notes")] WHERE ckey REGEXP '[search]' ORDER BY ckey")
if(!query_list_notes.Execute())
var/err = query_list_notes.ErrorMsg()
log_game("SQL ERROR obtaining ckey from notes table. Error : \[[err]\]\n")
return
while(query_list_notes.NextRow())
index_ckey = query_list_notes.item[1]
output += "<a href='?_src_=holder;shownoteckey=[index_ckey]'>[index_ckey]</a><br>"
else
output += "<center><a href='?_src_=holder;addnoteempty=1'>\[Add Note\]</a></center>"
output += ruler
usr << browse(output, "window=show_notes;size=900x500")
#define NOTESFILE "data/player_notes.sav"
//if the AUTOCONVERT_NOTES is turned on, anytime a player connects this will be run to try and add all their notes to the databas
/proc/convert_notes_sql(ckey)
var/savefile/notesfile = new(NOTESFILE)
if(!notesfile)
log_game("Error: Cannot access [NOTESFILE]")
return
notesfile.cd = "/[ckey]"
while(!notesfile.eof)
var/notetext
notesfile >> notetext
var/server
if(config && config.server_name)
server = config.server_name
var/regex/note = new("^(\\d{2}-\\w{3}-\\d{4}) \\| (.+) ~(\\w+)$", "i")
note.Find(notetext)
var/timestamp = note.group[1]
notetext = note.group[2]
var/adminckey = note.group[3]
var/DBQuery/query_convert_time = dbcon.NewQuery("SELECT ADDTIME(STR_TO_DATE('[timestamp]','%d-%b-%Y'), '0')")
if(!query_convert_time.Execute())
var/err = query_convert_time.ErrorMsg()
log_game("SQL ERROR converting timestamp. Error : \[[err]\]\n")
return
if(query_convert_time.NextRow())
timestamp = query_convert_time.item[1]
if(ckey && notetext && timestamp && adminckey && server)
add_note(ckey, notetext, timestamp, adminckey, 0, server, 1)
notesfile.cd = "/"
notesfile.dir.Remove(ckey)
/*alternatively this proc can be run once to pass through every note and attempt to convert it before deleting the file, if done then AUTOCONVERT_NOTES should be turned off
this proc can take several minutes to execute fully if converting and cause DD to hang if converting a lot of notes; it's not advised to do so while a server is live
/proc/mass_convert_notes()
world << "Beginning mass note conversion"
var/savefile/notesfile = new(NOTESFILE)
if(!notesfile)
log_game("Error: Cannot access [NOTESFILE]")
return
notesfile.cd = "/"
for(var/ckey in notesfile.dir)
convert_notes_sql(ckey)
world << "Deleting NOTESFILE"
fdel(NOTESFILE)
world << "Finished mass note conversion, remember to turn off AUTOCONVERT_NOTES"*/
#undef NOTESFILE
+97 -106
View File
@@ -8,7 +8,7 @@
if(href_list["rejectadminhelp"])
if(!check_rights(R_ADMIN))
return
var/client/C = locate(href_list["rejectadminhelp"])
var/client/C = locate(href_list["rejectadminhelp"]) in clients
if(!C)
return
if (deltimer(C.adminhelptimerid))
@@ -23,6 +23,20 @@
message_admins("[key_name_admin(usr)] Rejected [C.key]'s admin help. [C.key]'s Adminhelp verb has been returned to them.")
log_admin("[key_name(usr)] Rejected [C.key]'s admin help.")
else if(href_list["icissue"])
var/client/C = locate(href_list["icissue"]) in clients
if(!C)
return
var/msg = "<font color='red' size='4'><b>- AdminHelp marked as IC issue! -</b></font><br>"
msg += "<font color='red'><b>Losing is part of the game!</b></font><br>"
msg += "<font color='red'>Your character will frequently die, sometimes without even a possibility of avoiding it. Events will often be out of your control. No matter how good or prepared you are, sometimes you just lose.</font>"
C << msg
message_admins("[key_name_admin(usr)] marked [C.key]'s admin help as an IC issue.")
log_admin("[key_name(usr)] marked [C.key]'s admin help as an IC issue.")
else if(href_list["stickyban"])
stickyban(href_list["stickyban"],href_list)
@@ -238,10 +252,7 @@
if(!DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey, banip, bancid ))
usr << "<span class='danger'>Failed to apply ban.</span>"
return
add_note(banckey, banreason, null, usr.ckey, 0, null, 0)
else if(href_list["editrights"])
edit_rights_topic(href_list)
create_message("note", banckey, null, banreason, null, null, 0, 0)
else if(href_list["mentor"])
if(!check_rights(R_ADMIN)) return
@@ -287,6 +298,9 @@
M.verbs -= /client/proc/cmd_mentor_say
M.verbs -= /client/proc/show_mentor_memo
else if(href_list["editrights"])
edit_rights_topic(href_list)
else if(href_list["call_shuttle"])
if(!check_rights(R_ADMIN))
return
@@ -587,7 +601,7 @@
ban_unban_log_save("[key_name(usr)] appearance banned [key_name(M)]. reason: [reason]")
log_admin("[key_name(usr)] appearance banned [key_name(M)]. \nReason: [reason]")
feedback_inc("ban_appearance",1)
add_note(M.ckey, "Appearance banned - [reason]", null, usr.ckey, 0, null, 0)
create_message("note", M.ckey, null, "Appearance banned - [reason]", null, null, 0, 0)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] appearance banned [key_name_admin(M)].</span>")
M << "<span class='boldannounce'><BIG>You have been appearance banned by [usr.client.ckey].</BIG></span>"
M << "<span class='boldannounce'>The reason is: [reason]</span>"
@@ -977,7 +991,7 @@
msg = job
else
msg += ", [job]"
add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 0, null, 0)
create_message("note", M.ckey, null, "Banned from [msg] - [reason]", null, null, 0, 0)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes.</span>")
M << "<span class='boldannounce'><BIG>You have been [(msg == ("ooc" || "appearance")) ? "banned" : "jobbanned"] by [usr.client.ckey] from: [msg].</BIG></span>"
M << "<span class='boldannounce'>The reason is: [reason]</span>"
@@ -1002,7 +1016,7 @@
msg = job
else
msg += ", [job]"
add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 0, null, 0)
create_message("note", M.ckey, null, "Banned from [msg] - [reason]", null, null, 0, 0)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg].</span>")
M << "<span class='boldannounce'><BIG>You have been [(msg == ("ooc" || "appearance")) ? "banned" : "jobbanned"] by [usr.client.ckey] from: [msg].</BIG></span>"
M << "<span class='boldannounce'>The reason is: [reason]</span>"
@@ -1054,58 +1068,88 @@
//M.client = null
qdel(M.client)
//Player Notes
else if(href_list["addmessage"])
var/target_ckey = href_list["addmessage"]
create_message("message", target_ckey, secret = 0)
else if(href_list["addnote"])
var/target_ckey = href_list["addnote"]
add_note(target_ckey)
create_message("note", target_ckey)
else if(href_list["addwatch"])
var/target_ckey = href_list["addwatch"]
create_message("watchlist entry", target_ckey, secret = 1)
else if(href_list["addmemo"])
create_message("memo", secret = 0, browse = 1)
else if(href_list["addmessageempty"])
create_message("message", secret = 0)
else if(href_list["addnoteempty"])
add_note()
create_message("note")
else if(href_list["removenote"])
var/note_id = href_list["removenote"]
remove_note(note_id)
else if(href_list["addwatchempty"])
create_message("watchlist entry", secret = 1)
else if(href_list["editnote"])
var/note_id = href_list["editnote"]
edit_note(note_id)
else if(href_list["deletemessage"])
var/message_id = href_list["deletemessage"]
delete_message(message_id)
else if(href_list["shownote"])
var/target = href_list["shownote"]
show_note(index = target)
else if(href_list["deletemessageempty"])
var/message_id = href_list["deletemessageempty"]
delete_message(message_id, browse = 1)
else if(href_list["editmessage"])
var/message_id = href_list["editmessage"]
edit_message(message_id)
else if(href_list["editmessageempty"])
var/message_id = href_list["editmessageempty"]
edit_message(message_id, browse = 1)
else if(href_list["secretmessage"])
var/message_id = href_list["secretmessage"]
toggle_message_secrecy(message_id)
else if(href_list["searchmessages"])
var/target = href_list["searchmessages"]
browse_messages(index = target)
else if(href_list["nonalpha"])
var/target = href_list["nonalpha"]
target = text2num(target)
show_note(index = target)
browse_messages(index = target)
else if(href_list["shownoteckey"])
var/target_ckey = href_list["shownoteckey"]
show_note(target_ckey)
else if(href_list["showmessages"])
var/target = href_list["showmessages"]
browse_messages(index = target)
else if(href_list["shownoteckeylinkless"])
var/target_ckey = href_list["shownoteckeylinkless"]
show_note(target_ckey, null, 1)
else if(href_list["showmemo"])
browse_messages("memo")
else if(href_list["notessearch"])
var/target = href_list["notessearch"]
show_note(index = target)
else if(href_list["showwatch"])
browse_messages("watchlist entry")
else if(href_list["noteedits"])
var/note_id = sanitizeSQL("[href_list["noteedits"]]")
var/DBQuery/query_noteedits = dbcon.NewQuery("SELECT edits FROM [format_table_name("notes")] WHERE id = '[note_id]'")
if(!query_noteedits.Execute())
var/err = query_noteedits.ErrorMsg()
log_game("SQL ERROR obtaining edits from notes table. Error : \[[err]\]\n")
else if(href_list["showmessageckey"])
var/target = href_list["showmessageckey"]
browse_messages(target_ckey = target)
else if(href_list["showmessageckeylinkless"])
var/target = href_list["showmessageckeylinkless"]
browse_messages(target_ckey = target, linkless = 1)
else if(href_list["messageedits"])
var/message_id = sanitizeSQL("[href_list["messageedits"]]")
var/DBQuery/query_get_message_edits = dbcon.NewQuery("SELECT edits FROM [format_table_name("messages")] WHERE id = '[message_id]'")
if(!query_get_message_edits.Execute())
var/err = query_get_message_edits.ErrorMsg()
log_game("SQL ERROR obtaining edits from messages table. Error : \[[err]\]\n")
return
if(query_noteedits.NextRow())
var/edit_log = query_noteedits.item[1]
if(query_get_message_edits.NextRow())
var/edit_log = query_get_message_edits.item[1]
usr << browse(edit_log,"window=noteedits")
else if(href_list["secretnote"])
var/note_id = href_list["secretnote"]
toggle_note_secrecy(note_id)
else if(href_list["newban"])
if(!check_rights(R_BAN))
return
@@ -1170,48 +1214,6 @@
if("Cancel")
return
//Watchlist
else if(href_list["watchadd"])
var/target_ckey = locate(href_list["watchadd"])
usr.client.watchlist_add(target_ckey)
else if(href_list["watchremove"])
var/target_ckey = href_list["watchremove"]
usr.client.watchlist_remove(target_ckey)
else if(href_list["watchedit"])
var/target_ckey = href_list["watchedit"]
usr.client.watchlist_edit(target_ckey)
else if(href_list["watchaddbrowse"])
usr.client.watchlist_add(null, 1)
else if(href_list["watchremovebrowse"])
var/target_ckey = href_list["watchremovebrowse"]
usr.client.watchlist_remove(target_ckey, 1)
else if(href_list["watcheditbrowse"])
var/target_ckey = href_list["watcheditbrowse"]
usr.client.watchlist_edit(target_ckey, 1)
else if(href_list["watchsearch"])
var/target_ckey = href_list["watchsearch"]
usr.client.watchlist_show(target_ckey)
else if(href_list["watchshow"])
usr.client.watchlist_show()
else if(href_list["watcheditlog"])
var/target_ckey = sanitizeSQL("[href_list["watcheditlog"]]")
var/DBQuery/query_watchedits = dbcon.NewQuery("SELECT edits FROM [format_table_name("watch")] WHERE ckey = '[target_ckey]'")
if(!query_watchedits.Execute())
var/err = query_watchedits.ErrorMsg()
log_game("SQL ERROR obtaining edits from watch table. Error : \[[err]\]\n")
return
if(query_watchedits.NextRow())
var/edit_log = query_watchedits.item[1]
usr << browse(edit_log,"window=watchedits")
else if(href_list["mute"])
if(!check_rights(R_ADMIN))
return
@@ -2176,33 +2178,11 @@
FM.locked ^= 1
src.access_news_network()
else if(href_list["memoeditlist"])
var/sql_key = sanitizeSQL("[href_list["memoeditlist"]]")
var/DBQuery/query_memoedits = dbcon.NewQuery("SELECT edits FROM [format_table_name("memo")] WHERE (ckey = '[sql_key]')")
if(!query_memoedits.Execute())
var/err = query_memoedits.ErrorMsg()
log_game("SQL ERROR obtaining edits from memo table. Error : \[[err]\]\n")
return
if(query_memoedits.NextRow())
var/edit_log = query_memoedits.item[1]
usr << browse(edit_log,"window=memoeditlist")
else if(href_list["check_antagonist"])
if(!check_rights(R_ADMIN))
return
usr.client.check_antagonists()
else if(href_list["mentormemoeditlist"])
var/sql_key = sanitizeSQL("[href_list["memoeditlist"]]")
var/DBQuery/query_memoedits = dbcon.NewQuery("SELECT edits FROM [format_table_name("mentor_memo")] WHERE (ckey = '[sql_key]')")
if(!query_memoedits.Execute())
var/err = query_memoedits.ErrorMsg()
log_game("SQL ERROR obtaining edits from memo table. Error : \[[err]\]\n")
return
if(query_memoedits.NextRow())
var/edit_log = query_memoedits.item[1]
usr << browse(edit_log,"window=mentormemoeditlist")
else if(href_list["kick_all_from_lobby"])
if(!check_rights(R_ADMIN))
return
@@ -2277,3 +2257,14 @@
message_admins("[key_name(usr)] created \"[G.name]\" station goal.")
ticker.mode.station_goals += G
modify_goals()
else if(href_list["mentormemoeditlist"])
var/sql_key = sanitizeSQL("[href_list["memoeditlist"]]")
var/DBQuery/query_memoedits = dbcon.NewQuery("SELECT edits FROM [format_table_name("mentor_memo")] WHERE (ckey = '[sql_key]')")
if(!query_memoedits.Execute())
var/err = query_memoedits.ErrorMsg()
log_game("SQL ERROR obtaining edits from memo table. Error : \[[err]\]\n")
return
if(query_memoedits.NextRow())
var/edit_log = query_memoedits.item[1]
usr << browse(edit_log,"window=mentormemoeditlist")
-119
View File
@@ -1,119 +0,0 @@
/client/proc/watchlist_add(target_ckey, browse = 0)
if(!target_ckey)
var/new_ckey = ckey(input(usr,"Who would you like to add to the watchlist?","Enter a ckey",null) as text)
if(!new_ckey)
return
new_ckey = sanitizeSQL(new_ckey)
var/DBQuery/query_watchfind = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'")
if(!query_watchfind.Execute())
var/err = query_watchfind.ErrorMsg()
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
return
if(!query_watchfind.NextRow())
if(alert(usr, "[new_ckey] has not been seen before, are you sure you want to add them to the watchlist?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes")
return
target_ckey = new_ckey
var/target_sql_ckey = sanitizeSQL(target_ckey)
if(check_watchlist(target_sql_ckey))
usr << "<span class='redtext'>[target_sql_ckey] is already on the watchlist.</span>"
return
var/reason = input(usr,"Please State Reason","Reason") as message
if(!reason)
return
reason = sanitizeSQL(reason)
var/timestamp = SQLtime()
var/adminckey = usr.ckey
if(!adminckey)
return
var/admin_sql_ckey = sanitizeSQL(adminckey)
var/DBQuery/query_watchadd = dbcon.NewQuery("INSERT INTO [format_table_name("watch")] (ckey, reason, adminckey, timestamp) VALUES ('[target_sql_ckey]', '[reason]', '[admin_sql_ckey]', '[timestamp]')")
if(!query_watchadd.Execute())
var/err = query_watchadd.ErrorMsg()
log_game("SQL ERROR during adding new watch entry. Error : \[[err]\]\n")
return
log_admin("[key_name(usr)] has added [target_ckey] to the watchlist - Reason: [reason]")
message_admins("[key_name_admin(usr)] has added [target_ckey] to the watchlist - Reason: [reason]", 1)
if(browse)
watchlist_show(target_sql_ckey)
add_note(target_ckey, "Added to Watchlist - [reason]", null, usr.ckey, 0, null, 1)
/client/proc/watchlist_remove(target_ckey, browse = 0)
var/target_sql_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_watchdel = dbcon.NewQuery("DELETE FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
if(!query_watchdel.Execute())
var/err = query_watchdel.ErrorMsg()
log_game("SQL ERROR during removing watch entry. Error : \[[err]\]\n")
return
log_admin("[key_name(usr)] has removed [target_ckey] from the watchlist")
message_admins("[key_name_admin(usr)] has removed [target_ckey] from the watchlist", 1)
if(browse)
watchlist_show()
/client/proc/watchlist_edit(target_ckey, browse = 0)
var/target_sql_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_watchreason = dbcon.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
if(!query_watchreason.Execute())
var/err = query_watchreason.ErrorMsg()
log_game("SQL ERROR obtaining reason from watch table. Error : \[[err]\]\n")
return
if(query_watchreason.NextRow())
var/watch_reason = query_watchreason.item[1]
var/new_reason = input("Input new reason", "New Reason", "[watch_reason]") as message
new_reason = sanitizeSQL(new_reason)
if(!new_reason)
return
var/sql_ckey = sanitizeSQL(usr.ckey)
var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from<br>[watch_reason]<br>to<br>[new_reason]<hr>"
edit_text = sanitizeSQL(edit_text)
var/DBQuery/query_watchupdate = dbcon.NewQuery("UPDATE [format_table_name("watch")] SET reason = '[new_reason]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE ckey = '[target_sql_ckey]'")
if(!query_watchupdate.Execute())
var/err = query_watchupdate.ErrorMsg()
log_game("SQL ERROR editing watchlist reason. Error : \[[err]\]\n")
return
log_admin("[key_name(usr)] has edited [target_ckey]'s watchlist reason from [watch_reason] to [new_reason]")
message_admins("[key_name_admin(usr)] has edited [target_ckey]'s watchlist reason from<br>[watch_reason]<br>to<br>[new_reason]")
if(browse)
watchlist_show(target_sql_ckey)
/client/proc/watchlist_show(search)
var/output
output += "<form method='GET' name='search' action='?'>\
<input type='hidden' name='_src_' value='holder'>\
<input type='text' name='watchsearch' value='[search]'>\
<input type='submit' value='Search'></form>"
output += "<a href='?_src_=holder;watchshow=1'>\[Clear Search\]</a> <a href='?_src_=holder;watchaddbrowse=1'>\[Add Ckey\]</a>"
output += "<hr style='background:#000000; border:0; height:3px'>"
if(search)
search = "^[search]"
else
search = "^."
search = sanitizeSQL(search)
var/DBQuery/query_watchlist = dbcon.NewQuery("SELECT ckey, reason, adminckey, timestamp, last_editor FROM [format_table_name("watch")] WHERE ckey REGEXP '[search]' ORDER BY ckey")
if(!query_watchlist.Execute())
var/err = query_watchlist.ErrorMsg()
log_game("SQL ERROR obtaining ckey, reason, adminckey, timestamp, last_editor from watch table. Error : \[[err]\]\n")
return
while(query_watchlist.NextRow())
var/ckey = query_watchlist.item[1]
var/reason = query_watchlist.item[2]
var/adminckey = query_watchlist.item[3]
var/timestamp = query_watchlist.item[4]
var/last_editor = query_watchlist.item[5]
output += "<b>[ckey]</b> | Added by <b>[adminckey]</b> on <b>[timestamp]</b> <a href='?_src_=holder;watchremovebrowse=[ckey]'>\[Remove\]</a> <a href='?_src_=holder;watcheditbrowse=[ckey]'>\[Edit Reason\]</a>"
if(last_editor)
output += " <font size='2'>Last edit by [last_editor] <a href='?_src_=holder;watcheditlog=[ckey]'>(Click here to see edit log)</a></font>"
output += "<br>[reason]<hr style='background:#000000; border:0; height:1px'>"
usr << browse(output, "window=watchwin;size=900x500")
/client/proc/check_watchlist(target_ckey)
var/target_sql_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_watch = dbcon.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
if(!query_watch.Execute())
var/err = query_watch.ErrorMsg()
log_game("SQL ERROR obtaining reason from watch table. Error : \[[err]\]\n")
return
if(query_watch.NextRow())
return query_watch.item[1]
else
return 0
+1 -1
View File
@@ -69,7 +69,7 @@
// What the device does when turned on
/obj/item/device/assembly/proc/activate()
if(qdeleted(src) || !secured || (next_activate > world.time))
if(QDELETED(src) || !secured || (next_activate > world.time))
return FALSE
next_activate = world.time + 30
return TRUE
+1 -1
View File
@@ -252,7 +252,7 @@
else
user << "You begin to replace the bulb."
if(do_after(user, 20, target = src))
if(flash.crit_fail || !flash || qdeleted(flash))
if(flash.crit_fail || !flash || QDELETED(flash))
return
crit_fail = FALSE
times_used = 0
@@ -149,15 +149,13 @@
/obj/effect/hotspot/Destroy()
SetLuminosity(0)
SSair.hotspots -= src
if(isturf(loc))
var/turf/open/T = loc
if(T.active_hotspot == src)
T.active_hotspot = null
var/turf/open/T = loc
if(istype(T) && T.active_hotspot == src)
T.active_hotspot = null
DestroyTurf()
loc = null
. = ..()
/obj/effect/hotspot/proc/DestroyTurf()
if(isturf(loc))
var/turf/T = loc
@@ -142,7 +142,7 @@ Pipelines + Other Objects -> Pipe network
user << "<span class='warning'>As you begin unwrenching \the [src] a gush of air blows in your face... maybe you should reconsider?</span>"
unsafe_wrenching = TRUE //Oh dear oh dear
if (do_after(user, 20*W.toolspeed, target = src) && !qdeleted(src))
if (do_after(user, 20*W.toolspeed, target = src) && !QDELETED(src))
user.visible_message( \
"[user] unfastens \the [src].", \
"<span class='notice'>You unfasten \the [src].</span>", \
@@ -13,6 +13,7 @@
var/autoeject = FALSE
var/volume = 100
var/running_bob_animation = 0
var/efficiency = 1
var/sleep_factor = 750
var/paralyze_factor = 1000
@@ -26,7 +27,6 @@
var/radio_key = /obj/item/device/encryptionkey/headset_med
var/radio_channel = "Medical"
/obj/machinery/atmospherics/components/unary/cryo_cell/New()
..()
initialize_directions = dir
@@ -144,6 +144,7 @@
/obj/machinery/atmospherics/components/unary/cryo_cell/process()
..()
if(!on)
return
if(!is_operational())
@@ -214,12 +215,16 @@
/obj/machinery/atmospherics/components/unary/cryo_cell/relaymove(mob/user)
container_resist(user)
/obj/machinery/atmospherics/components/unary/cryo_cell/open_machine()
/obj/machinery/atmospherics/components/unary/cryo_cell/open_machine(drop = 0)
if(!state_open && !panel_open)
on = FALSE
..()
if(beaker)
beaker.forceMove(src)
for(var/mob/M in contents) //only drop mobs
M.forceMove(get_turf(src))
if(isliving(M))
var/mob/living/L = M
L.update_canmove()
occupant = null
/obj/machinery/atmospherics/components/unary/cryo_cell/close_machine(mob/living/carbon/user)
if((isnull(user) || istype(user)) && state_open && !panel_open)
@@ -350,4 +355,4 @@
return //can't ventcrawl in or out of cryo.
/obj/machinery/atmospherics/components/unary/cryo_cell/can_see_pipes()
return 0 //you can't see the pipe network when inside a cryo cell.
return 0 //you can't see the pipe network when inside a cryo cell.
@@ -86,7 +86,7 @@
qdel(meter)
. = ..()
if(parent && !qdeleted(parent))
if(parent && !QDELETED(parent))
qdel(parent)
parent = null
@@ -193,7 +193,7 @@
/obj/machinery/capture_the_flag/attack_ghost(mob/user)
if(ctf_enabled == FALSE)
return
if(ticker.current_state != GAME_STATE_PLAYING)
if(ticker.current_state < GAME_STATE_PLAYING)
return
if(user.ckey in team_members)
if(user.ckey in recently_dead_ckeys)
@@ -580,7 +580,7 @@
CTF.dead_barricades += src
/obj/effect/ctf/dead_barricade/proc/respawn()
if(!qdeleted(src))
if(!QDELETED(src))
new /obj/structure/barricade/security/ctf(get_turf(src))
qdel(src)
+2 -2
View File
@@ -144,7 +144,7 @@ var/obj/machinery/gateway/centerstation/the_gateway = null
return
if(!detect())
return
if(!awaygate || qdeleted(awaygate))
if(!awaygate || QDELETED(awaygate))
return
if(awaygate.calibrated)
@@ -214,7 +214,7 @@ var/obj/machinery/gateway/centerstation/the_gateway = null
return
if(!active)
return
if(!stationgate || qdeleted(stationgate))
if(!stationgate || QDELETED(stationgate))
return
if(istype(AM, /mob/living/carbon))
var/mob/living/carbon/C = AM
+2
View File
@@ -91,6 +91,8 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
return FALSE
if(!get_cost(O, contr, emag))
return FALSE
if(O.flags & HOLOGRAM)
return FALSE
return TRUE
// Called only once, when the object is actually sold by the datum.
+22 -26
View File
@@ -69,18 +69,6 @@
src << "<span class='danger'>Your previous action was ignored because you've done too many in a second</span>"
return
//Logs all hrefs
if(config && config.log_hrefs && href_logfile)
href_logfile << "<small>[time2text(world.timeofday,"hh:mm")] [src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]<br>"
// Admin PM
if(href_list["priv_msg"])
if (href_list["ahelp_reply"])
cmd_ahelp_reply(href_list["priv_msg"])
return
cmd_admin_pm(href_list["priv_msg"],null)
return
if(href_list["mentor_msg"])
if(config.mentors_mobname_only)
var/mob/M = locate(href_list["mentor_msg"])
@@ -93,6 +81,14 @@
if(config && config.log_hrefs && href_logfile)
href_logfile << "<small>[time2text(world.timeofday,"hh:mm")] [src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]<br>"
// Admin PM
if(href_list["priv_msg"])
if (href_list["ahelp_reply"])
cmd_ahelp_reply(href_list["priv_msg"])
return
cmd_admin_pm(href_list["priv_msg"],null)
return
switch(href_list["_src_"])
if("holder")
hsrc = holder
@@ -257,7 +253,7 @@ var/next_external_rsc = 0
if(holder)
add_admin_verbs()
admin_memo_output("Show")
src << get_message_output("memo")
adminGreet()
if((global.comms_key == "default_pwd" || length(global.comms_key) <= 6) && global.comms_allowed) //It's the default value or less than 6 characters long, but it somehow didn't disable comms.
src << "<span class='danger'>The server's API key is either too short or is the default value! Consider changing it immediately!</span>"
@@ -294,7 +290,7 @@ var/next_external_rsc = 0
findJoinDate()
sync_client_with_db(tdata)
get_message_output("watchlist entry", ckey)
check_ip_intel()
send_resources()
@@ -318,7 +314,7 @@ var/next_external_rsc = 0
if(config && config.autoconvert_notes)
convert_notes_sql(ckey)
src << get_message_output("message", ckey)
if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
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>"
@@ -399,12 +395,6 @@ var/next_external_rsc = 0
if (check_randomizer(connectiontopic))
return
var/watchreason = check_watchlist(sql_ckey)
if(watchreason)
current_watchlist[sql_ckey] = watchreason
message_admins("<font color='red'><B>Notice: </B></font><font color='blue'>[key_name_admin(src)] is on the watchlist and has just connected - Reason: [watchreason]</font>")
// send2irc_adminless_only("Watchlist", "[key_name(src)] is on the watchlist and has just connected - Reason: [watchreason]")
var/sql_ip = sanitizeSQL(src.address)
var/sql_computerid = sanitizeSQL(src.computer_id)
var/sql_admin_rank = sanitizeSQL(admin_rank)
@@ -499,24 +489,24 @@ var/next_external_rsc = 0
var/const/adminckey = "CID-Error"
var/sql_ckey = sanitizeSQL(ckey)
//check to see if we noted them in the last day.
var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id FROM [format_table_name("notes")] WHERE ckey = '[sql_ckey]' AND adminckey = '[adminckey]' AND timestamp + INTERVAL 1 DAY < NOW()")
var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id FROM [format_table_name("messages")] WHERE type = 'note' AND targetckey = '[sql_ckey]' AND adminckey = '[adminckey]' AND timestamp + INTERVAL 1 DAY < NOW()")
if(!query_get_notes.Execute())
var/err = query_get_notes.ErrorMsg()
log_game("SQL ERROR obtaining id from notes table. Error : \[[err]\]\n")
log_game("SQL ERROR obtaining id from messages table. Error : \[[err]\]\n")
return
if (query_get_notes.NextRow())
return
//regardless of above, make sure their last note is not from us, as no point in repeating the same note over and over.
query_get_notes = dbcon.NewQuery("SELECT adminckey FROM [format_table_name("notes")] WHERE ckey = '[sql_ckey]' ORDER BY timestamp DESC LIMIT 1")
query_get_notes = dbcon.NewQuery("SELECT adminckey FROM [format_table_name("messages")] WHERE targetckey = '[sql_ckey]' ORDER BY timestamp DESC LIMIT 1")
if(!query_get_notes.Execute())
var/err = query_get_notes.ErrorMsg()
log_game("SQL ERROR obtaining id from notes table. Error : \[[err]\]\n")
log_game("SQL ERROR obtaining adminckey from notes table. Error : \[[err]\]\n")
return
if (query_get_notes.NextRow())
if (query_get_notes.item[1] == adminckey)
return
add_note(ckey, "Detected as using a cid randomizer.", null, adminckey, 0, null, 0)
create_message("note", sql_ckey, adminckey, "Detected as using a cid randomizer.", null, null, 0, 0)
/client/proc/check_ip_intel()
@@ -584,3 +574,9 @@ var/next_external_rsc = 0
return FALSE
if ("key")
return FALSE
/client/proc/change_view(new_size)
if (isnull(new_size))
CRASH("change_view called without argument.")
view = new_size
+1 -1
View File
@@ -156,7 +156,7 @@ var/global/normal_ooc_colour = OOC_COLOR
usr << "<span class='notice'>Sorry, that function is not enabled on this server.</span>"
return
show_note(usr.ckey, null, 1)
browse_messages(null, usr.ckey, null, 1)
/client/proc/ignore_key(client)
var/client/C = client
+3 -2
View File
@@ -1,6 +1,7 @@
/client/verb/sethotkeys(from_pref = 0 as num)
set name = "Set Hotkeys"
set hidden = 1
set hidden = TRUE
set waitfor = FALSE
set desc = "Used to set mob-specific hotkeys or load hoykey mode from preferences"
var/hotkey_default = "default"
@@ -21,4 +22,4 @@
if(current_setting in default_macros)
winset(src, null, "mainwindow.macro=[hotkey_default] input.focus=true input.background-color=#d3b5b5")
else
winset(src, null, "mainwindow.macro=[hotkey_macro] mapwindow.map.focus=true input.background-color=#e0e0e0")
winset(src, null, "mainwindow.macro=[hotkey_macro] mapwindow.map.focus=true input.background-color=#e0e0e0")
+3
View File
@@ -4,7 +4,10 @@
set hidden = 1
if(!canSuicide())
return
var/oldkey = ckey
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
if(ckey != oldkey)
return
if(!canSuicide())
return
if(confirm == "Yes")
@@ -97,7 +97,7 @@
for(var/obj/item/I in user.held_items)
if(I in hands_nodrop)
I.flags &= ~NODROP
if(phase_underlay && !qdeleted(phase_underlay))
if(phase_underlay && !QDELETED(phase_underlay))
user.underlays -= phase_underlay
qdel(phase_underlay)
phase_underlay = null
@@ -1272,12 +1272,12 @@
/obj/item/clothing/head/helmet/space/hardsuit/flightsuit/proc/toggle_zoom(mob/living/user, force_off = FALSE)
if(zoom || force_off)
user.client.view = world.view
user.client.change_view(world.view)
user << "<span class='boldnotice'>Disabling smart zooming image enhancement...</span>"
zoom = FALSE
return FALSE
else
user.client.view = zoom_range
user.client.change_view(zoom_range)
user << "<span class='boldnotice'>Enabling smart zooming image enhancement!</span>"
zoom = TRUE
return TRUE
+34 -1
View File
@@ -39,10 +39,43 @@
name = "plasma envirosuit helmet"
desc = "A special containment helmet that allows plasma-based lifeforms to exist safely in an oxygenated environment. It is space-worthy, and may be worn in tandem with other EVA gear."
icon_state = "plasmaman-helm"
item_color = "plasma" //needed for the helmet lighting
item_state = "plasmaman-helm"
strip_delay = 80
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 0, fire = 100, acid = 75)
resistance_flags = FIRE_PROOF
var/brightness_on = 4 //luminosity when the light is on
var/on = 0
actions_types = list(/datum/action/item_action/toggle_helmet_light)
/obj/item/clothing/head/helmet/space/plasmaman/attack_self(mob/user)
on = !on
icon_state = "[initial(icon_state)][on ? "-light":""]"
item_state = icon_state
user.update_inv_head() //So the mob overlay updates
if(on)
turn_on(user)
else
turn_off(user)
for(var/X in actions)
var/datum/action/A=X
A.UpdateButtonIcon()
/obj/item/clothing/head/helmet/space/plasmaman/pickup(mob/user)
..()
if(on)
user.AddLuminosity(brightness_on)
SetLuminosity(0)
/obj/item/clothing/head/helmet/space/plasmaman/dropped(mob/user)
..()
if(on)
user.AddLuminosity(-brightness_on)
SetLuminosity(brightness_on)
/obj/item/clothing/head/helmet/space/plasmaman/proc/turn_on/(mob/user)
user.AddLuminosity(brightness_on)
/obj/item/clothing/head/helmet/space/plasmaman/proc/turn_off/(mob/user)
user.AddLuminosity(-brightness_on)
+10
View File
@@ -327,6 +327,16 @@
category = CAT_MISC
/datum/crafting_recipe/flashlight_eyes
name = "Flashlight Eyes"
result = /obj/item/organ/eyes/robotic/flashlight
time = 10
reqs = list(
/obj/item/device/flashlight = 2,
/obj/item/weapon/restraints/handcuffs/cable = 1
)
category = CAT_MISC
/datum/crafting_recipe/chemical_payload
name = "Chemical Payload (C4)"
result = /obj/item/weapon/bombcore/chemical
+1 -1
View File
@@ -37,7 +37,7 @@
/datum/round_event/ghost_role/alien_infestation/spawn_role()
var/list/vents = list()
for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in machines)
if(qdeleted(temp_vent))
if(QDELETED(temp_vent))
continue
if(temp_vent.loc.z == ZLEVEL_STATION && !temp_vent.welded)
var/datum/pipeline/temp_vent_parent = temp_vent.PARENT1
+2 -2
View File
@@ -40,7 +40,7 @@
/datum/round_event/brand_intelligence/tick()
if(!originMachine || qdeleted(originMachine) || originMachine.shut_up || originMachine.wires.is_all_cut()) //if the original vending machine is missing or has it's voice switch flipped
if(!originMachine || QDELETED(originMachine) || originMachine.shut_up || originMachine.wires.is_all_cut()) //if the original vending machine is missing or has it's voice switch flipped
for(var/obj/machinery/vending/saved in infectedMachines)
saved.shoot_inventory = 0
if(originMachine)
@@ -51,7 +51,7 @@
vendingMachines = removeNullsFromList(vendingMachines)
if(!vendingMachines.len) //if every machine is infected
for(var/obj/machinery/vending/upriser in infectedMachines)
if(prob(70) && !qdeleted(upriser))
if(prob(70) && !QDELETED(upriser))
var/mob/living/simple_animal/hostile/mimic/copy/M = new(upriser.loc, upriser, null, 1) // it will delete upriser on creation and override any machine checks
M.faction = list("profit")
M.speak = rampant_speeches.Copy()
+40 -1
View File
@@ -19,6 +19,45 @@
var/obj/item/weapon/storage/backpack/b = locate() in H.contents
new /obj/item/weapon/reagent_containers/food/snacks/candyheart(b)
var/list/valentines = list()
for(var/mob/living/M in player_list)
if(!M.stat && M.client && M.mind)
valentines |= M
while(valentines.len)
var/mob/living/L = pick_n_take(valentines)
if(valentines.len)
var/mob/living/date = pick_n_take(valentines)
forge_valentines_objective(L, date)
forge_valentines_objective(date, L)
else
L << "<span class='warning'><B>You didn't get a date! They're all having fun without you! you'll show them though...</B></span>"
var/datum/objective/martyr/normiesgetout = new
normiesgetout.owner = L.mind
ticker.mode.traitors |= L.mind
L.mind.objectives += normiesgetout
/proc/forge_valentines_objective(mob/living/lover,mob/living/date)
ticker.mode.traitors |= lover.mind
lover.mind.special_role = "valentine"
var/datum/objective/protect/protect_objective = new /datum/objective/protect
protect_objective.owner = lover.mind
protect_objective.target = date.mind
protect_objective.explanation_text = "Protect [date.real_name], your date."
lover.mind.objectives += protect_objective
lover << "<span class='warning'><B>You're on a date with [date]! Protect them at all costs. This takes priority over all other loyalties.</B></span>"
/datum/round_event/valentines/announce()
priority_announce("It's Valentine's Day! Give a valentine to that special someone!")
@@ -126,4 +165,4 @@
"A heart-shaped candy that reads: FACEHUGGER",
"A heart-shaped candy that reads: DOMINATOR",
"A heart-shaped candy that reads: GET TESLA'D")
icon_state = pick("candyheart", "candyheart2", "candyheart3", "candyheart4")
icon_state = pick("candyheart", "candyheart2", "candyheart3", "candyheart4")
+5 -3
View File
@@ -35,6 +35,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
anchored = 1
var/z_original = 0
var/destination
var/notify = TRUE
/obj/effect/immovablerod/New(atom/start, atom/end)
..()
@@ -42,9 +43,10 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
SSaugury.register_doom(src, 2000)
z_original = z
destination = end
notify_ghosts("\A [src] is inbound!",
enter_link="<a href=?src=\ref[src];orbit=1>(Click to orbit)</a>",
source=src, action=NOTIFY_ORBIT)
if(notify)
notify_ghosts("\A [src] is inbound!",
enter_link="<a href=?src=\ref[src];orbit=1>(Click to orbit)</a>",
source=src, action=NOTIFY_ORBIT)
poi_list += src
if(end && end.z==z_original)
walk_towards(src, destination, 1)
+1 -1
View File
@@ -497,7 +497,7 @@
var/list/obj/structure/spacevine/queue_end = list()
for(var/obj/structure/spacevine/SV in growth_queue)
if(qdeleted(SV))
if(QDELETED(SV))
continue
i++
queue_end += SV
@@ -147,3 +147,10 @@
list_reagents = list("nutriment" = 6, "vitamin" = 1)
bitesize = 3
w_class = WEIGHT_CLASS_NORMAL
/obj/item/weapon/reagent_containers/food/snacks/deepfryholder
name = "Deep Fried Foods Holder Obj"
desc = "If you can see this description the code for the deep fryer fucked up."
icon = 'icons/obj/food/food.dmi'
icon_state = ""
bitesize = 2
@@ -0,0 +1,118 @@
/*
April 3rd, 2014 marks the day this machine changed the face of the kitchen on NTStation13
God bless America.
insert ascii eagle on american flag background here
*/
// April 3rd, 2014 marks the day this machine changed the face of the kitchen on NTStation13
// God bless America.
/obj/machinery/deepfryer
name = "deep fryer"
desc = "Deep fried <i>everything</i>."
icon = 'icons/obj/kitchen.dmi'
icon_state = "fryer_off"
density = 1
anchored = 1
use_power = 1
idle_power_usage = 5
container_type = OPENCONTAINER
var/obj/item/frying = null //What's being fried RIGHT NOW?
var/cook_time = 0
/obj/item/weapon/circuitboard/machine/deep_fryer
name = "circuit board (Deep Fryer)"
build_path = /obj/machinery/deepfryer
origin_tech = "programming=1"
req_components = list(/obj/item/weapon/stock_parts/micro_laser = 1)
/obj/machinery/deepfryer/New()
..()
create_reagents(50)
reagents.add_reagent("nutriment", 25)
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/machine/deep_fryer(null)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(null)
RefreshParts()
/obj/machinery/deepfryer/examine()
..()
if(frying)
usr << "You can make out [frying] in the oil."
/obj/machinery/deepfryer/attackby(obj/item/I, mob/user)
if(!reagents.total_volume)
user << "There's nothing to fry with in [src]!"
return
if(istype(I, /obj/item/weapon/reagent_containers/food/snacks/deepfryholder))
user << "<span class='userdanger'>Your cooking skills are not up to the legendary Doublefry technique.</span>"
return
else
if(user.drop_item() && !frying)
user << "<span class='notice'>You put [I] into [src].</span>"
frying = I
frying.forceMove(src)
icon_state = "fryer_on"
/obj/machinery/deepfryer/process()
..()
if(!reagents.total_volume)
return
if(frying)
cook_time++
if(cook_time == 30)
playsound(src.loc, "sound/machines/ding.ogg", 50, 1)
visible_message("[src] dings!")
else if (cook_time == 60)
visible_message("[src] emits an acrid smell!")
/obj/machinery/deepfryer/attack_hand(mob/user)
if(frying)
if(frying.loc == src)
user << "<span class='notice'>You eject [frying] from [src].</span>"
var/obj/item/weapon/reagent_containers/food/snacks/deepfryholder/S = new(get_turf(src))
if(istype(frying, /obj/item/weapon/reagent_containers/))
var/obj/item/weapon/reagent_containers/food = frying
food.reagents.trans_to(S, food.reagents.total_volume)
S.icon = frying.icon
S.overlays = frying.overlays
S.icon_state = frying.icon_state
S.desc = frying.desc
reagents.trans_to(S, 2*(cook_time/15))
switch(cook_time)
if(0 to 15)
S.color = rgb(166,103,54)
S.name = "lightly-fried [frying.name]"
if(16 to 49)
S.color = rgb(103,63,24)
S.name = "fried [frying.name]"
if(50 to 59)
S.color = rgb(63, 23, 4)
S.name = "deep-fried [frying.name]"
if(60 to INFINITY)
S.color = rgb(33,19,9)
S.name = "the physical manifestation of the very concept of fried foods"
S.desc = "A heavily fried...something. Who can tell anymore?"
S.filling_color = S.color
if(istype(frying, /obj/item/weapon/reagent_containers/food/snacks/))
qdel(frying)
else
frying.forceMove(S)
icon_state = "fryer_off"
user.put_in_hands(S)
frying = null
cook_time = 0
return
else if(user.pulling && user.a_intent == "grab" && iscarbon(user.pulling) && reagents.total_volume)
if(user.grab_state < GRAB_AGGRESSIVE)
user << "<span class='warning'>You need a better grip to do that!</span>"
return
var/mob/living/carbon/C = user.pulling
user.visible_message("<span class = 'danger'>[user] dunks [C]'s face in [src]!</span>")
reagents.reaction(C, TOUCH)
C.adjustFireLoss(reagents.total_volume)
reagents.remove_any((reagents.total_volume/2))
C.Weaken(3)
user.changeNext_move(CLICK_CD_MELEE)
..()
+3
View File
@@ -33,6 +33,9 @@
if(istype(O,/obj/machinery))
var/obj/machinery/M = O
M.power_change()
if(holoitem)
O.flags |= HOLOGRAM
return O
+4 -4
View File
@@ -194,16 +194,16 @@
/obj/machinery/computer/holodeck/Destroy()
emergency_shutdown()
..()
return ..()
/obj/machinery/computer/holodeck/emp_act(severity)
emergency_shutdown()
..()
return ..()
/obj/machinery/computer/holodeck/ex_act(severity, target)
emergency_shutdown()
..()
return ..()
/obj/machinery/computer/holodeck/blob_act(obj/structure/blob/B)
emergency_shutdown()
..()
return ..()
+1 -1
View File
@@ -130,7 +130,7 @@
/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/deconstruct(disassembled = TRUE)
if(!disassembled)
prime()
if(!qdeleted(src))
if(!QDELETED(src))
qdel(src)
/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/ex_act(severity)
+1 -1
View File
@@ -130,7 +130,7 @@
awakening = 1
spawn(30)
if(!qdeleted(src))
if(!QDELETED(src))
var/mob/living/simple_animal/hostile/killertomato/K = new /mob/living/simple_animal/hostile/killertomato(get_turf(src.loc))
K.maxHealth += round(seed.endurance / 3)
K.melee_damage_lower += round(seed.potency / 10)
+1 -1
View File
@@ -685,7 +685,7 @@
return
if(alert(user, "This will make [src] self-sustaining but consume [O] forever. Are you sure?", "[name]", "I'm Sure", "Abort") == "Abort" || !user)
return
if(!O || qdeleted(O))
if(!O || QDELETED(O))
return
if(!Adjacent(user))
return
+1 -1
View File
@@ -277,4 +277,4 @@ Janitor
belt = /obj/item/device/pda/janitor
ears = /obj/item/device/radio/headset/headset_srv
uniform = /obj/item/clothing/under/rank/janitor
backpack_contents = list(/obj/item/device/modular_computer/tablet/preset/advanced=1)
backpack_contents = list(/obj/item/device/modular_computer/tablet/preset/advanced=1, /obj/item/soapstone/empty=1)
+16 -10
View File
@@ -1,6 +1,6 @@
/obj/item/soapstone
name = "chisel"
desc = "Leave informative messages for the crew, including the crew of future shifts!\n(Not suitable for engraving on shuttles, off station or on cats. Side effects may include beatings, bannings and orbital bombardment.)"
desc = "Leave informative messages for the crew, including the crew of future shifts!\nEven if out of uses, it can still be used to remove messages.\n(Not suitable for engraving on shuttles, off station or on cats. Side effects may include beatings, bannings and orbital bombardment.)"
icon = 'icons/obj/items.dmi'
icon_state = "soapstone"
throw_speed = 3
@@ -18,6 +18,7 @@
/obj/item/soapstone/New()
. = ..()
random_name()
check_name() // could start empty
/obj/item/soapstone/proc/random_name()
name = pick("soapstone", "chisel", "chalk", "magic marker")
@@ -58,7 +59,7 @@
if(already_message)
our_message = already_message.creator_key == user.ckey
if(!remaining_uses && !our_message)
if(!remaining_uses && !already_message)
// The dull chisel is dull.
user << "<span class='warning'>[src] is [w_dull].</span>"
return
@@ -73,15 +74,13 @@
// Removing our own messages refunds a charge
if((our_message || can_use()) && do_after(user, tool_speed, target=target) && (our_message || can_use()))
if(do_after(user, tool_speed, target=target))
user.visible_message("<span class='notice'>[user] has erased [already_message].</span>", "<span class='notice'>You erased [already_message].</span>")
already_message.persists = FALSE
qdel(already_message)
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
if(our_message)
refund_use()
else
remove_use()
return
var/message = stripped_input(user, "What would you like to [w_engrave]?", "[name] Message")
@@ -115,18 +114,19 @@
return
remaining_uses--
if(!remaining_uses)
non_dull_name = name
name = "[w_dull] [name]"
check_name()
/obj/item/soapstone/proc/refund_use()
if(remaining_uses == -1)
return
var/was_dull = !remaining_uses
remaining_uses++
check_name()
if(was_dull)
/obj/item/soapstone/proc/check_name()
if(remaining_uses)
name = non_dull_name
else
name = "[w_dull] [name]"
/* Persistent engraved messages, etched onto the station turfs to serve
as instructions and/or memes for the next generation of spessmen.
@@ -138,6 +138,9 @@
/obj/item/soapstone/infinite
remaining_uses = -1
/obj/item/soapstone/empty
remaining_uses = 0
/proc/good_chisel_message_location(turf/T)
if(!T)
. = FALSE
@@ -176,6 +179,9 @@
persists = FALSE
qdel(src)
/obj/structure/chisel_message/singularity_pull()
return
/obj/structure/chisel_message/proc/register(mob/user, newmessage)
hidden_message = newmessage
creator_name = user.real_name
+1 -1
View File
@@ -144,7 +144,7 @@ var/list/total_extraction_beacons = list()
icon_state = "subspace_amplifier"
/obj/item/fulton_core/attack_self(mob/user)
if(do_after(user,15,target = user) && !qdeleted(src))
if(do_after(user,15,target = user) && !QDELETED(src))
new /obj/structure/extraction_point(get_turf(user))
qdel(src)
@@ -355,7 +355,7 @@
icon = 'icons/obj/lavaland/dragonboat.dmi'
resistance_flags = LAVA_PROOF | FIRE_PROOF
/obj/vehicle/lavaboat/buckle_mob()
/obj/vehicle/lavaboat/buckle_mob(mob/living/M, force = 0, check_loc = 1)
. = ..()
riding_datum = new/datum/riding/boat
@@ -403,7 +403,7 @@
desc = "This boat moves where you will it, without the need for an oar."
icon_state = "dragon_boat"
/obj/vehicle/lavaboat/dragon/buckle_mob()
/obj/vehicle/lavaboat/dragon/buckle_mob(mob/living/M, force = 0, check_loc = 1)
..()
riding_datum = new/datum/riding/boat/dragon
@@ -831,7 +831,7 @@
blast_range -= round(health_percent * 10) //one additional range for each missing 10% of health
/obj/item/weapon/hierophant_club/update_icon()
icon_state = "hierophant_club[timer <= world.time ? "_ready":""][(beacon && !qdeleted(beacon)) ? "":"_beacon"]"
icon_state = "hierophant_club[timer <= world.time ? "_ready":""][(beacon && !QDELETED(beacon)) ? "":"_beacon"]"
item_state = icon_state
if(ismob(loc))
var/mob/M = loc
@@ -853,7 +853,7 @@
if(!user.is_holding(src)) //you need to hold the staff to teleport
user << "<span class='warning'>You need to hold the club in your hands to [beacon ? "teleport with it":"detach the beacon"]!</span>"
return
if(!beacon || qdeleted(beacon))
if(!beacon || QDELETED(beacon))
if(isturf(user.loc))
user.visible_message("<span class='hierophant_warning'>[user] starts fiddling with [src]'s pommel...</span>", \
"<span class='notice'>You start detaching the hierophant beacon...</span>")
@@ -906,7 +906,7 @@
new /obj/effect/overlay/temp/hierophant/telegraph(source, user)
playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1)
playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1)
if(!do_after(user, 3, target = user) || !user || !beacon || qdeleted(beacon)) //no walking away shitlord
if(!do_after(user, 3, target = user) || !user || !beacon || QDELETED(beacon)) //no walking away shitlord
teleporting = FALSE
if(user)
user.update_action_buttons_icon()
+1 -1
View File
@@ -167,7 +167,7 @@
var/items = list("Survival Capsule and Explorer's Webbing", "Resonator and Advanced Scanner", "Mining Drone", "Extraction and Rescue Kit", "Crusher Kit", "Mining Conscription Kit")
var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in items
if(!selection || !Adjacent(redeemer) || qdeleted(voucher) || voucher.loc != redeemer)
if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer)
return
switch(selection)
if("Survival Capsule and Explorer's Webbing")
+1 -1
View File
@@ -73,7 +73,7 @@ var/global/posibrain_notif_cooldown = 0
return
var/posi_ask = alert("Become a [name]? (Warning, You can no longer be cloned, and all past lives will be forgotten!)","Are you positive?","Yes","No")
if(posi_ask == "No" || qdeleted(src))
if(posi_ask == "No" || QDELETED(src))
return
transfer_personality(user)
+1 -36
View File
@@ -42,13 +42,13 @@
create_internal_organs()
AddAbility(new/obj/effect/proc_holder/alien/nightvisiontoggle(null))
..()
/mob/living/carbon/alien/create_internal_organs()
internal_organs += new /obj/item/organ/brain/alien
internal_organs += new /obj/item/organ/alien/hivenode
internal_organs += new /obj/item/organ/tongue/alien
internal_organs += new /obj/item/organ/eyes/night_vision/alien
..()
/mob/living/carbon/alien/assess_threat() // beepsky won't hunt aliums
@@ -152,40 +152,5 @@ Des: Removes all infected images from the alien.
#undef HEAT_DAMAGE_LEVEL_2
#undef HEAT_DAMAGE_LEVEL_3
/mob/living/carbon/alien/update_sight()
if(!client)
return
if(stat == DEAD)
sight |= SEE_TURFS
sight |= SEE_MOBS
sight |= SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_OBSERVER
return
sight = SEE_MOBS
if(nightvision)
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
else
see_in_dark = 4
see_invisible = SEE_INVISIBLE_LIVING
if(client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
for(var/obj/item/organ/cyberimp/eyes/E in internal_organs)
sight |= E.sight_flags
if(E.dark_view)
see_in_dark = max(see_in_dark, E.dark_view)
if(E.see_invisible)
see_invisible = min(see_invisible, E.see_invisible)
if(see_override)
see_invisible = see_override
/mob/living/carbon/alien/can_hold_items()
return has_fine_manipulation
@@ -286,26 +286,6 @@ Doesn't work on other aliens/AI.*/
user.visible_message("<span class='alertealien'>[user] hurls out the contents of their stomach!</span>")
return
/obj/effect/proc_holder/alien/nightvisiontoggle
name = "Toggle Night Vision"
desc = "Toggles Night Vision"
plasma_cost = 0
has_action = 0 // Has dedicated GUI button already
/obj/effect/proc_holder/alien/nightvisiontoggle/fire(mob/living/carbon/alien/user)
if(!user.nightvision)
user.see_in_dark = 8
user.see_invisible = SEE_INVISIBLE_MINIMUM
user.nightvision = 1
user.hud_used.nightvisionicon.icon_state = "nightvision1"
else if(user.nightvision == 1)
user.see_in_dark = 4
user.see_invisible = 45
user.nightvision = 0
user.hud_used.nightvisionicon.icon_state = "nightvision0"
return 1
/obj/effect/proc_holder/alien/sneak
name = "Sneak"
desc = "Blend into the shadows to stalk your prey."
@@ -141,7 +141,7 @@
recent_queen_death = 1
owner.throw_alert("alien_noqueen", /obj/screen/alert/alien_vulnerable)
spawn(2400) //four minutes
if(qdeleted(src)) //In case the node is deleted
if(QDELETED(src)) //In case the node is deleted
return
recent_queen_death = 0
if(!owner) //In case the xeno is butchered or subjected to surgery after death.
+29 -9
View File
@@ -529,21 +529,34 @@
see_invisible = SEE_INVISIBLE_OBSERVER
return
see_invisible = initial(see_invisible)
see_in_dark = initial(see_in_dark)
sight = initial(sight)
var/obj/item/organ/eyes/E = getorganslot("eye_sight")
if(!E)
update_tint()
else
see_invisible = E.see_invisible
see_in_dark = E.see_in_dark
sight |= E.sight_flags
if(client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
for(var/obj/item/organ/cyberimp/eyes/E in internal_organs)
sight |= E.sight_flags
if(E.dark_view)
see_in_dark = max(see_in_dark,E.dark_view)
if(E.see_invisible)
see_invisible = min(see_invisible, E.see_invisible)
if(glasses)
var/obj/item/clothing/glasses/G = glasses
sight |= G.vision_flags
see_in_dark = max(G.darkness_view, see_in_dark)
if(G.invis_override)
see_invisible = G.invis_override
else
see_invisible = min(G.invis_view, see_invisible)
if(dna)
for(var/X in dna.mutations)
var/datum/mutation/M = X
if(M.name == XRAY)
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_in_dark = max(see_in_dark, 8)
if(see_override)
see_invisible = see_override
@@ -569,6 +582,13 @@
if(wear_mask)
. += wear_mask.tint
var/obj/item/organ/eyes/E = getorganslot("eye_sight")
if(E)
. += E.tint
else
. += INFINITY
//this handles hud updates
/mob/living/carbon/update_damage_hud()
@@ -709,7 +729,7 @@
return 0
/mob/living/carbon/harvest(mob/living/user)
if(qdeleted(src))
if(QDELETED(src))
return
var/organs_amt = 0
for(var/X in internal_organs)
@@ -1,8 +1,12 @@
/mob/living/carbon/get_eye_protection()
var/number = ..()
for(var/obj/item/organ/cyberimp/eyes/EFP in internal_organs)
number += EFP.flash_protect
var/obj/item/organ/eyes/E = getorganslot("eye_sight")
if(!E)
number = INFINITY //Can't get flashed without eyes
else
number += E.flash_protect
return number
/mob/living/carbon/get_ear_protection()
+2 -11
View File
@@ -47,6 +47,8 @@
internal_organs += new /obj/item/organ/lungs()
if(!(NOBLOOD in dna.species.species_traits))
internal_organs += new /obj/item/organ/heart
internal_organs += new dna.species.mutanteyes()
internal_organs += new /obj/item/organ/brain
..()
@@ -764,17 +766,6 @@
if(R)
R.fields["name"] = newname
/mob/living/carbon/human/update_sight()
if(!client)
return
if(stat == DEAD)
sight = (SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_in_dark = 8
see_invisible = SEE_INVISIBLE_OBSERVER
return
dna.species.update_sight(src)
/mob/living/carbon/human/get_total_tint()
. = ..()
if(glasses)
+12 -44
View File
@@ -15,8 +15,6 @@
var/name = null // this is the fluff name. these will be left generic (such as 'Lizardperson' for the lizard race) so servers can change them to whatever
var/roundstart = 0 // can this mob be chosen at roundstart? (assuming the config option is checked?)
var/default_color = "#FFF" // if alien colors are disabled, this is the color that will be used by that race
var/eyes = "eyes" // which eyes the race uses. at the moment, the only types of eyes are "eyes" (regular eyes) and "jelleyes" (three eyes)
var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
var/hair_color = null // this allows races to have specific hair colors... if null, it uses the H's hair/facial hair colors. if "mutcolor", it uses the H's mutant_color
var/hair_alpha = 255 // the alpha used by the hair. 255 is completely solid, 0 is transparent.
@@ -47,9 +45,6 @@
var/damage_overlay_type = "human" //what kind of damage overlays (if any) appear on our species when wounded?
var/fixed_mut_color = "" //to use MUTCOLOR with a fixed color that's independent of dna.feature["mcolor"]
var/invis_sight = SEE_INVISIBLE_LIVING
var/darksight = 2
// species flags. these can be found in flags.dm
var/list/species_traits = list()
@@ -65,6 +60,9 @@
//Flight and floating
var/override_float = 0
//Eyes
var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes
//Citadel snowflake
var/fixed_mut_color2 = ""
var/fixed_mut_color3 = ""
@@ -250,6 +248,13 @@
var/obj/item/bodypart/head/HD = H.get_bodypart("head")
// eyes
var/has_eyes = TRUE
if(!H.getorgan(/obj/item/organ/eyes) && HD)
standing += image("icon"='icons/mob/human_face.dmi', "icon_state" = "eyes_missing", "layer" = -BODY_LAYER)
has_eyes = FALSE
if(!(H.disabilities & HUSK))
// lipstick
if(H.lip_style && (LIPS in species_traits) && HD)
@@ -258,8 +263,8 @@
standing += lips
// eyes
if((EYECOLOR in species_traits) && HD)
var/image/img_eyes = image("icon" = 'icons/mob/human_face.dmi', "icon_state" = "[eyes]", "layer" = -BODY_LAYER)
if((EYECOLOR in species_traits) && HD && has_eyes)
var/image/img_eyes = image("icon" = 'icons/mob/human_face.dmi', "icon_state" = "eyes", "layer" = -BODY_LAYER)
img_eyes.color = "#" + H.eye_color
standing += img_eyes
@@ -867,7 +872,6 @@
hunger_rate = 3 * HUNGER_FACTOR
H.nutrition = max(0, H.nutrition - hunger_rate)
if (H.nutrition > NUTRITION_LEVEL_FULL)
if(H.overeatduration < 600) //capped so people don't take forever to unfat
H.overeatduration++
@@ -901,42 +905,6 @@
else
H.throw_alert("nutrition", /obj/screen/alert/starving)
/datum/species/proc/update_sight(mob/living/carbon/human/H)
H.sight = initial(H.sight)
H.see_in_dark = darksight
H.see_invisible = invis_sight
if(H.client.eye != H)
var/atom/A = H.client.eye
if(A.update_remote_sight(H)) //returns 1 if we override all other sight updates.
return
for(var/obj/item/organ/cyberimp/eyes/E in H.internal_organs)
H.sight |= E.sight_flags
if(E.dark_view)
H.see_in_dark = E.dark_view
if(E.see_invisible)
H.see_invisible = min(H.see_invisible, E.see_invisible)
if(H.glasses)
var/obj/item/clothing/glasses/G = H.glasses
H.sight |= G.vision_flags
H.see_in_dark = max(G.darkness_view, H.see_in_dark)
if(G.invis_override)
H.see_invisible = G.invis_override
else
H.see_invisible = min(G.invis_view, H.see_invisible)
for(var/X in H.dna.mutations)
var/datum/mutation/M = X
if(M.name == XRAY)
H.sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
H.see_in_dark = max(H.see_in_dark, 8)
if(H.see_override) //Override all
H.see_invisible = H.see_override
/datum/species/proc/update_health_hud(mob/living/carbon/human/H)
return 0
@@ -1,7 +1,6 @@
/datum/species/abductor
name = "Abductor"
id = "abductor"
darksight = 3
say_mod = "gibbers"
sexes = 0
species_traits = list(NOBLOOD,NOBREATH,VIRUSIMMUNE,NOGUNS)
@@ -116,6 +116,7 @@ datum/species/canid
//EXOTIC//
//These races will likely include lots of downsides and upsides. Keep them relatively balanced.//
/*
/datum/species/xeno
name = "Xenomorph"
id = "xeno"
@@ -170,7 +171,7 @@ datum/species/canid
toxpwr = 0
acidpwr = 12
/*
/datum/species/yautja
name = "Yautja"
id = "pred"
@@ -4,7 +4,6 @@
id = "jelly"
default_color = "00FF90"
say_mod = "chirps"
eyes = "jelleyes"
species_traits = list(MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE,TOXINLOVER)
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/slime
exotic_blood = "slimejelly"
@@ -99,10 +98,8 @@
name = "Slimeperson"
id = "slime"
default_color = "00FFFF"
darksight = 3
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD,VIRUSIMMUNE, TOXINLOVER)
say_mod = "says"
eyes = "eyes"
hair_color = "mutcolor"
hair_alpha = 150
ignored_by = list(/mob/living/simple_animal/slime)
@@ -131,8 +128,8 @@
/* slime_split = new
slime_split.Grant(C)
swap_body = new
swap_body.Grant(C) */
swap_body.Grant(C)
*/
if(!bodies || !bodies.len)
bodies = list(C)
else
@@ -248,10 +245,10 @@
var/list/data = list()
data["bodies"] = list()
for(var/b in SS.bodies)
if(!b || qdeleted(b) || !isslimeperson(b))
var/mob/living/carbon/human/body = b
if(!body || QDELETED(body) || !isslimeperson(body))
SS.bodies -= b
continue
var/mob/living/carbon/human/body = b
var/list/L = list()
// HTML colors need a # prefix
@@ -311,7 +308,7 @@
var/mob/living/carbon/human/selected = locate(params["ref"])
if(!(selected in SS.bodies))
return
if(!selected || qdeleted(selected) || !isslimeperson(selected))
if(!selected || QDELETED(selected) || !isslimeperson(selected))
SS.bodies -= selected
return
if(M.current == selected)
@@ -2,42 +2,14 @@
// Humans cursed to stay in the darkness, lest their life forces drain. They regain health in shadow and die in light.
name = "???"
id = "shadow"
darksight = 8
invis_sight = SEE_INVISIBLE_MINIMUM
sexes = 0
blacklisted = 1
ignored_by = list(/mob/living/simple_animal/hostile/faithless)
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/shadow
species_traits = list(NOBREATH,NOBLOOD,RADIMMUNE,VIRUSIMMUNE)
dangerous_existence = 1
var/datum/action/innate/shadow/darkvision/vision_toggle
mutanteyes = /obj/item/organ/eyes/night_vision
/datum/action/innate/shadow/darkvision //Darkvision toggle so shadowpeople can actually see where darkness is
name = "Toggle Darkvision"
check_flags = AB_CHECK_CONSCIOUS
background_icon_state = "bg_default"
button_icon_state = "blind"
/datum/action/innate/shadow/darkvision/Activate()
var/mob/living/carbon/human/H = owner
if(H.see_in_dark < 8)
H.see_in_dark = 8
H.see_invisible = SEE_INVISIBLE_MINIMUM
H << "<span class='notice'>You adjust your vision to pierce the darkness.</span>"
else
H.see_in_dark = 2
H.see_invisible = SEE_INVISIBLE_LIVING
H << "<span class='notice'>You adjust your vision to recognize the shadows.</span>"
/datum/species/shadow/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
vision_toggle = new
vision_toggle.Grant(C)
/datum/species/shadow/on_species_loss(mob/living/carbon/C)
. = ..()
if(vision_toggle)
vision_toggle.Remove(C)
/datum/species/shadow/spec_life(mob/living/carbon/human/H)
var/light_amount = 0
@@ -137,7 +137,7 @@ There are several things that need to be remembered:
else if(!(dna && dna.species.nojumpsuit))
// Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY
for(var/obj/item/thing in list(r_store, l_store, wear_id, belt))
for(var/obj/item/thing in list(r_store, l_store, wear_id, belt)) //
dropItemToGround(thing)
apply_overlay(UNIFORM_LAYER)
@@ -576,4 +576,4 @@ generate/load female uniform sprites matching all previously decided variables
observers -= observe
if(!observers.len)
observers = null
break
break
@@ -345,7 +345,7 @@
for(var/obj/item/I in M.held_items)
if(I == pickupTarget)
M.visible_message("<span class='danger'>[src] snatches [pickupTarget] from [M].</span>", "<span class='userdanger'>[src] snatched [pickupTarget]!</span>")
if(M.temporarilyRemoveItemFromInventory(pickupTarget) && !qdeleted(pickupTarget))
if(M.temporarilyRemoveItemFromInventory(pickupTarget) && !QDELETED(pickupTarget))
equip_item(pickupTarget)
else
M.visible_message("<span class='danger'>[src] tried to snatch [pickupTarget] from [M], but failed!</span>", "<span class='userdanger'>[src] tried to grab [pickupTarget]!</span>")
@@ -45,6 +45,7 @@
internal_organs += new /obj/item/organ/heart
internal_organs += new /obj/item/organ/brain
internal_organs += new /obj/item/organ/tongue
internal_organs += new /obj/item/organ/eyes
..()
/mob/living/carbon/monkey/movement_delay()
@@ -301,4 +301,4 @@ var/global/list/limb_icon_cache = list()
remove_overlay(BODYPARTS_LAYER)
overlays_standing[BODYPARTS_LAYER] = limb_icon_cache[icon_render_key]
apply_overlay(BODYPARTS_LAYER)
update_damage_overlays()
update_damage_overlays()
+1 -1
View File
@@ -766,7 +766,7 @@
return 0
/mob/living/proc/harvest(mob/living/user)
if(qdeleted(src))
if(QDELETED(src))
return
if(butcher_results)
for(var/path in butcher_results)
+9 -1
View File
@@ -33,6 +33,7 @@ var/list/ai_list = list()
var/list/connected_robots = list()
var/aiRestorePowerRoutine = 0
var/requires_power = POWER_REQ_ALL
var/can_be_carded = TRUE
//var/list/laws = list()
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list())
var/viewalerts = 0
@@ -790,6 +791,10 @@ var/list/ai_list = list()
if(!mind)
user << "<span class='warning'>No intelligence patterns detected.</span>" //No more magical carding of empty cores, AI RETURN TO BODY!!!11
return
if(!can_be_carded)
user << "<span class='boldwarning'>Transfer failed.</span>"
return
ShutOffDoomsdayDevice()
new /obj/structure/AIcore/deactivated(loc)//Spawns a deactivated terminal at AI location.
ai_restore_power()//So the AI initially has power.
control_disabled = 1//Can't control things remotely if you're stuck in a card!
@@ -881,7 +886,7 @@ var/list/ai_list = list()
malfhacking = 0
clear_alert("hackingapc")
if(!istype(apc) || qdeleted(apc) || apc.stat & BROKEN)
if(!istype(apc) || QDELETED(apc) || apc.stat & BROKEN)
src << "<span class='danger'>Hack aborted. The designated APC no \
longer exists on the power network.</span>"
playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 1)
@@ -902,6 +907,9 @@ var/list/ai_list = list()
exclusive control."
apc.update_icon()
/mob/living/silicon/ai/resist()
return
/mob/living/silicon/ai/spawned/New(loc, datum/ai_laws/L, mob/target_ai)
if(!target_ai)
target_ai = src //cheat! just give... ourselves as the spawned AI, because that's technically correct
+13 -10
View File
@@ -19,17 +19,8 @@
shuttle_caller_list -= src
SSshuttle.autoEvac()
if(nuking)
set_security_level("red")
nuking = FALSE
for(var/obj/item/weapon/pinpointer/P in pinpointer_list)
P.switch_mode_to(TRACK_NUKE_DISK) //Party's over, back to work, everyone
P.nuke_warning = FALSE
ShutOffDoomsdayDevice()
if(doomsday_device)
doomsday_device.timing = FALSE
SSshuttle.clearHostileEnvironment(doomsday_device)
qdel(doomsday_device)
if(explosive)
spawn(10)
explosion(src.loc, 3, 6, 12, 15)
@@ -40,3 +31,15 @@
if(istype(loc, /obj/item/device/aicard))
loc.icon_state = "aicard-404"
/mob/living/silicon/ai/proc/ShutOffDoomsdayDevice()
if(nuking)
set_security_level("red")
nuking = FALSE
for(var/obj/item/weapon/pinpointer/P in pinpointer_list)
P.switch_mode_to(TRACK_NUKE_DISK) //Party's over, back to work, everyone
P.nuke_warning = FALSE
if(doomsday_device)
doomsday_device.timing = FALSE
SSshuttle.clearHostileEnvironment(doomsday_device)
qdel(doomsday_device)
@@ -87,7 +87,7 @@
cameraFollow = null
unset_machine()
if(!eyeobj || !eyeobj.loc || qdeleted(eyeobj))
if(!eyeobj || !eyeobj.loc || QDELETED(eyeobj))
src << "ERROR: Eyeobj not found. Creating new eye..."
eyeobj = new(loc)
eyeobj.ai = src
+1 -1
View File
@@ -19,7 +19,7 @@
// messenging the client
malfhacked(malfhack)
if(!eyeobj || qdeleted(eyeobj) || !eyeobj.loc)
if(!eyeobj || QDELETED(eyeobj) || !eyeobj.loc)
view_core()
if(machine)
@@ -30,4 +30,4 @@
update_icons()
sql_report_cyborg_death(src)
sql_report_death(src)
@@ -136,7 +136,7 @@
bot_patrol()
if(target)
if(qdeleted(target) || !isturf(target.loc))
if(QDELETED(target) || !isturf(target.loc))
target = null
mode = BOT_IDLE
return
@@ -35,7 +35,7 @@
user << "Can't become a drone before the game has started."
return
var/be_drone = alert("Become a drone? (Warning, You can no longer be cloned!)",,"Yes","No")
if(be_drone == "No" || qdeleted(src) || !isobserver(user))
if(be_drone == "No" || QDELETED(src) || !isobserver(user))
return
var/mob/living/simple_animal/drone/D = new drone_type(get_turf(loc))
D.admin_spawned = admin_spawned
@@ -55,11 +55,12 @@
removechains()
/mob/living/simple_animal/hostile/guardian/beam/proc/cleardeletedchains()
if(summonerchain && qdeleted(summonerchain))
if(summonerchain && QDELETED(summonerchain))
summonerchain = null
if(enemychains.len)
for(var/chain in enemychains)
if(!chain || qdeleted(chain))
var/datum/cd = chain
if(!chain || QDELETED(cd))
enemychains -= chain
/mob/living/simple_animal/hostile/guardian/beam/proc/shockallchains()
@@ -48,7 +48,7 @@
casting = 1
icon_state = "[initial(icon_state)][casting]"
if(do_after_mob(src, A, spellcasttime, uninterruptible = 1, progress = 0)) //Break LOS to dodge.
if(qdeleted(src))
if(QDELETED(src))
return
if((A in view(src)))
A.do_attack_animation(A, spellanimation)
@@ -50,7 +50,6 @@
see_invisible = SEE_INVISIBLE_MINIMUM
see_in_dark = 4
var/playable_spider = FALSE
devourable = 1
/mob/living/simple_animal/hostile/poison/giant_spider/Topic(href, href_list)
if(href_list["activate"])
@@ -66,7 +65,7 @@
if(key || !playable_spider)//Someone is in it or the fun police are shutting it down
return 0
var/spider_ask = alert("Become a spider?", "Are you australian?", "Yes", "No")
if(spider_ask == "No" || !src || qdeleted(src))
if(spider_ask == "No" || !src || QDELETED(src))
return 1
if(key)
user << "<span class='notice'>Someone else already took this spider.</span>"
@@ -579,7 +579,7 @@ Difficulty: Very Hard
..()
if(ready_to_deploy)
var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No")
if(be_helper == "Yes" && !qdeleted(src) && isobserver(user))
if(be_helper == "Yes" && !QDELETED(src) && isobserver(user))
var/mob/living/simple_animal/hostile/lightgeist/W = new /mob/living/simple_animal/hostile/lightgeist(get_turf(loc))
W.key = user.key
@@ -706,7 +706,7 @@ Difficulty: Very Hard
/obj/structure/closet/stasis/process()
if(holder_animal)
if(holder_animal.stat == DEAD && !qdeleted(holder_animal))
if(holder_animal.stat == DEAD && !QDELETED(holder_animal))
dump_contents()
holder_animal.gib()
return
@@ -734,7 +734,7 @@ Difficulty: Very Hard
L.disabilities &= ~MUTE
L.status_flags &= ~GODMODE
L.notransform = 0
if(holder_animal && !qdeleted(holder_animal))
if(holder_animal && !QDELETED(holder_animal))
holder_animal.mind.transfer_to(L)
L.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/exit_possession)
if(kill || !isanimal(loc))
@@ -213,7 +213,7 @@ Difficulty: Medium
fire_rain()
icon_state = "dragon"
if(swoop_target && !qdeleted(swoop_target) && swoop_target.z == src.z)
if(swoop_target && !QDELETED(swoop_target) && swoop_target.z == src.z)
tturf = get_turf(swoop_target)
else
tturf = get_turf(src)
@@ -228,7 +228,7 @@ Difficulty: Medium
L.gib()
else
L.adjustBruteLoss(75)
if(L && !qdeleted(L)) // Some mobs are deleted on death
if(L && !QDELETED(L)) // Some mobs are deleted on death
var/throw_dir = get_dir(src, L)
if(L.loc == loc)
throw_dir = pick(alldirs)
@@ -80,7 +80,7 @@ Difficulty: Hard
/mob/living/simple_animal/hostile/megafauna/hierophant/Life()
. = ..()
if(. && spawned_beacon && !qdeleted(spawned_beacon) && !client)
if(. && spawned_beacon && !QDELETED(spawned_beacon) && !client)
if(target || loc == spawned_beacon.loc)
timeout_time = initial(timeout_time)
else
@@ -500,7 +500,7 @@ Difficulty: Hard
if(!currently_seeking)
currently_seeking = TRUE
targetturf = get_turf(target)
while(target && src && !qdeleted(src) && currently_seeking && x && y && targetturf) //can this target actually be sook out
while(target && src && !QDELETED(src) && currently_seeking && x && y && targetturf) //can this target actually be sook out
if(!moving) //we're out of tiles to move, find more and where the target is!
more_previouser_moving_dir = previous_moving_dir
previous_moving_dir = moving_dir
@@ -207,16 +207,7 @@
/obj/effect/proc_holder/spell/targeted/night_vision/cast(list/targets,mob/user = usr)
for(var/mob/living/target in targets)
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.dna.species.invis_sight == SEE_INVISIBLE_LIVING)
H.dna.species.invis_sight = SEE_INVISIBLE_NOLIGHTING
name = "Toggle Nightvision \[ON]"
else
H.dna.species.invis_sight = SEE_INVISIBLE_LIVING
name = "Toggle Nightvision \[OFF]"
else
if(!iscarbon(target)) //Carbons should be toggling their vision via organ, this spell is used as a power for simple mobs
if(target.see_invisible == SEE_INVISIBLE_LIVING)
target.see_invisible = SEE_INVISIBLE_NOLIGHTING
name = "Toggle Nightvision \[ON]"
@@ -224,7 +215,6 @@
target.see_invisible = SEE_INVISIBLE_LIVING
name = "Toggle Nightvision \[OFF]"
/mob/living/simple_animal/hostile/statue/sentience_act()
faction -= "neutral"
+2 -1
View File
@@ -71,4 +71,5 @@
update_client_colour()
if(client)
client.click_intercept = null
client.view = world.view // Resets the client.view in case it was changed.
client.view = world.view // Resets the client.view in case it was changed.
@@ -1381,414 +1381,3 @@
/datum/sprite_accessory/legs/digitigrade_lizard
name = "Digitigrade Legs"
/* tbi eventually idk
/datum/sprite_accessory/legs/digitigrade_mam
name = "Anthro Digitigrade Legs"
icon = 'icons/mob/mam_bodyparts.dmi'
*/
//Human Ears/Tails
/datum/sprite_accessory/ears/fox
name = "Fox"
icon_state = "fox"
hasinner = 0
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/ears/wolf
name = "Wolf"
icon_state = "wolf"
hasinner = 1
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails/human/fox
name = "Fox"
icon_state = "fox"
icon = 'icons/mob/mam_bodyparts.dmi'
extra = 1
/datum/sprite_accessory/tails_animated/human/fox
name = "Fox"
icon_state = "fox"
icon = 'icons/mob/mam_bodyparts.dmi'
extra = 1
/datum/sprite_accessory/tails/human/wolf
name = "Wolf"
icon_state = "wolf"
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails_animated/human/wolf
name = "Wolf"
icon_state = "wolf"
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails/human/catbig
name = "Cat, Big"
icon_state = "catbig"
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails_animated/human/catbig
name = "Cat, Big"
icon_state = "catbig"
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/ears/fennec
name = "Fennec"
icon_state = "fennec"
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails/human/fennec
name = "Fennec"
icon_state = "fennec"
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails_animated/human/fennec
name = "Fennec"
icon_state = "fennec"
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/ears/lab
name = "Dog, Floppy"
icon_state = "lab"
hasinner = 0
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails/human/husky
name = "Husky"
icon_state = "husky"
icon = 'icons/mob/mam_bodyparts.dmi'
extra = 1
/datum/sprite_accessory/tails_animated/human/husky
name = "Husky"
icon_state = "husky"
icon = 'icons/mob/mam_bodyparts.dmi'
extra = 1
/datum/sprite_accessory/ears/murid
name = "Murid"
icon_state = "murid"
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails/human/murid
name = "Murid"
icon_state = "murid"
color_src = 0
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails_animated/human/murid
name = "Murid"
icon_state = "murid"
color_src = 0
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails/human/shark
name = "Shark"
icon_state = "shark"
color_src = 0
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails/human/shark/datashark
name = "datashark"
icon_state = "datashark"
color_src = 0
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails/human/ailurus
name = "ailurus"
icon_state = "ailurus"
color_src = 0
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/ears/squirrel
name = "Squirrel"
icon_state = "squirrel"
hasinner= 1
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails/human/squirrel
name = "Squirrel"
icon_state = "squirrel"
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/tails_animated/human/squirrel
name = "Squirrel"
icon_state = "squirrel"
icon = 'icons/mob/mam_bodyparts.dmi'
//Mammal Bodyparts
/datum/sprite_accessory/mam_ears
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/mam_ears/none
name = "None"
/datum/sprite_accessory/mam_tails
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/mam_tails/none
name = "None"
/datum/sprite_accessory/mam_tails_animated
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/mam_tails_animated/none
name = "None"
//Snouts
/datum/sprite_accessory/snouts/lcanid
name = "Fox, Long"
icon_state = "lcanid"
icon = 'icons/mob/mam_bodyparts.dmi'
extra = 1
/datum/sprite_accessory/snouts/scanid
name = "Fox, Short"
icon_state = "scanid"
icon = 'icons/mob/mam_bodyparts.dmi'
extra = 1
/datum/sprite_accessory/snouts/wolf
name = "Wolf"
icon_state = "wolf"
icon = 'icons/mob/mam_bodyparts.dmi'
extra = 1
/datum/sprite_accessory/snouts/husky
name = "Husky"
icon_state = "husky"
icon = 'icons/mob/mam_bodyparts.dmi'
extra = 1
//Cat, Big
/datum/sprite_accessory/mam_ears/catbig
name = "Cat, Big"
icon_state = "cat"
hasinner = 1
icon = 'icons/mob/mutant_bodyparts.dmi'
/datum/sprite_accessory/mam_tails/catbig
name = "Cat, Big"
icon_state = "catbig"
/datum/sprite_accessory/mam_tails_animated/catbig
name = "Cat, Big"
icon_state = "catbig"
//Wolf
/datum/sprite_accessory/mam_ears/wolf
name = "Wolf"
icon_state = "wolf"
hasinner = 1
/datum/sprite_accessory/mam_tails/wolf
name = "Wolf"
icon_state = "wolf"
/datum/sprite_accessory/mam_tails_animated/wolf
name = "Wolf"
icon_state = "wolf"
//Fox
/datum/sprite_accessory/mam_ears/fox
name = "Fox"
icon_state = "fox"
hasinner = 0
/datum/sprite_accessory/mam_tails/fox
name = "Fox"
icon_state = "fox"
extra = 1
extra_color_src = MUTCOLORS2
/datum/sprite_accessory/mam_tails_animated/fox
name = "Fox"
icon_state = "fox"
extra = 1
extra_color_src = MUTCOLORS2
//Fennec
/datum/sprite_accessory/mam_ears/fennec
name = "Fennec"
icon_state = "fennec"
hasinner = 1
/datum/sprite_accessory/mam_tails/fennec
name = "Fennec"
icon_state = "fennec"
/datum/sprite_accessory/mam_tails_animated/fennec
name = "Fennec"
icon_state = "fennec"
//Lab
/datum/sprite_accessory/mam_ears/lab
name = "Dog, Long"
icon_state = "lab"
/datum/sprite_accessory/mam_tails/lab
name = "Lab"
icon_state = "lab"
/datum/sprite_accessory/mam_tails_animated/lab
name = "Lab"
icon_state = "lab"
//Husky
/datum/sprite_accessory/mam_ears/husky
name = "Husky"
icon_state = "wolf"
hasinner = 1
icon = 'icons/mob/mam_bodyparts.dmi'
extra = 1
/datum/sprite_accessory/mam_tails/husky
name = "Husky"
icon_state = "husky"
extra = 1
/datum/sprite_accessory/mam_tails_animated/husky
name = "Husky"
icon_state = "husky"
extra = 1
//Murid
/datum/sprite_accessory/mam_ears/murid
name = "Murid"
icon_state = "murid"
/datum/sprite_accessory/mam_tails/murid
name = "Murid"
icon_state = "murid"
color_src = 0
/datum/sprite_accessory/mam_tails_animated/murid
name = "Murid"
icon_state = "murid"
color_src = 0
//Shark
/datum/sprite_accessory/mam_tails/shark
name = "Shark"
icon_state = "shark"
color_src = 0
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/mam_tails/shark/datashark
name = "DataShark"
icon_state = "datashark"
color_src = 0
icon = 'icons/mob/mam_bodyparts.dmi'
//Squirrel
/datum/sprite_accessory/mam_ears/squirrel
name = "Squirrel"
icon_state = "squirrel"
hasinner= 1
/datum/sprite_accessory/mam_tails/squirrel
name = "Squirrel"
icon_state = "squirrel"
/datum/sprite_accessory/mam_tails_animated/squirrel
name = "Squirrel"
icon_state = "squirrel"
/datum/sprite_accessory/mam_tails/ailurus
name = "Ailurus"
icon_state = "ailurus"
//Capra
/datum/sprite_accessory/mam_tails/capra
name = "Capra"
icon_state = "capra"
//Hawk
/datum/sprite_accessory/mam_tails/hawk
name = "Hawk"
icon_state = "hawk"
//Mammal Specific Body Markings
/datum/sprite_accessory/mam_body_markings
color_src = MUTCOLORS2
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/mam_body_markings/none
name = "None"
icon_state = "none"
/datum/sprite_accessory/mam_body_markings/belly
name = "Belly"
icon_state = "belly"
gender_specific = 1
/*
/datum/sprite_accessory/mam_body_markings/bellyhandsfeet
name = "Belly, Hands, & Feet"
icon_state = "bellyhandsfeet"
gender_specific = 1
extra = 1
extra_color_src = MUTCOLORS3
*/
//Xeno Dorsal Tubes
/datum/sprite_accessory/xeno_dorsal
icon = 'icons/mob/exotic_bodyparts.dmi'
color_src = 0
/datum/sprite_accessory/xeno_dorsal/none
name = "None"
/datum/sprite_accessory/xeno_dorsal/normal
name = "Dorsal Tubes"
icon_state = "dortubes"
//Xeno Tail
/datum/sprite_accessory/xeno_tail
icon = 'icons/mob/exotic_bodyparts.dmi'
color_src = 0
/datum/sprite_accessory/xeno_tail/none
name = "None"
/datum/sprite_accessory/xeno_tail/normal
name = "Xenomorph Tail"
icon_state = "xeno"
//Xeno Caste Heads
//unused as of October 3, 2016
/datum/sprite_accessory/xeno_head
icon = 'icons/mob/exotic_bodyparts.dmi'
color_src = 0
/datum/sprite_accessory/xeno_head/none
name = "None"
/datum/sprite_accessory/xeno_head/hunter
name = "Hunter"
icon_state = "hunter"
/datum/sprite_accessory/xeno_head/drone
name = "Drone"
icon_state = "drone"
/datum/sprite_accessory/xeno_head/sentinel
name = "Sentinel"
icon_state = "sentinel"
/*
//Slimecoon Parts
/datum/sprite_accessory/slimecoon_ears
icon = 'icons/mob/exotic_bodyparts.dmi'
name = "Slimecoon Ears"
icon_state = "slimecoon"
/datum/sprite_accessory/slimecoon_tail
icon = 'icons/mob/exotic_bodyparts.dmi'
name = "Slimecoon Tail"
icon_state = "slimecoon"
/datum/sprite_accessory/slimecoon_snout
icon = 'icons/mob/exotic_bodyparts.dmi'
name = "Hunter"
icon_state = "slimecoon" */
@@ -118,7 +118,7 @@
D.target = null
D.error = "Connection to quantum relay severed"
..()
return ..()
/obj/item/weapon/circuitboard/machine/ntnet_relay
name = "NTNet Relay (Machine Board)"
@@ -126,4 +126,4 @@
origin_tech = "programming=3;bluespace=3;magnets=2"
req_components = list(
/obj/item/stack/cable_coil = 2,
/obj/item/weapon/stock_parts/subspace/filter = 1)
/obj/item/weapon/stock_parts/subspace/filter = 1)
@@ -141,6 +141,7 @@ var/list/global_modular_computers = list()
/obj/machinery/modular_computer/ex_act(severity)
if(cpu)
cpu.ex_act(severity)
..()
// EMPs are similar to explosions, but don't cause physical damage to the casing. Instead they screw up the components
/obj/machinery/modular_computer/emp_act(severity)
@@ -152,4 +153,4 @@ var/list/global_modular_computers = list()
// "Brute" damage mostly damages the casing.
/obj/machinery/modular_computer/bullet_act(obj/item/projectile/Proj)
if(cpu)
cpu.bullet_act(Proj)
cpu.bullet_act(Proj)
@@ -15,7 +15,7 @@
return 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.all_components[MC_HDD]
var/obj/item/weapon/computer_hardware/hard_drive/RHDD = computer.all_components[MC_HDD]
var/obj/item/weapon/computer_hardware/hard_drive/RHDD = computer.all_components[MC_SDD]
var/obj/item/weapon/computer_hardware/printer/printer = computer.all_components[MC_PRINT]
switch(action)
@@ -24,7 +24,7 @@
open_file = params["name"]
if("PRG_newtextfile")
. = 1
var/newname = sanitize(input(usr, "Enter file name or leave blank to cancel:", "File rename"))
var/newname = stripped_input(usr, "Enter file name or leave blank to cancel:", "File rename", max_length=50)
if(!newname)
return 1
if(!HDD)
@@ -69,7 +69,7 @@
var/datum/computer_file/file = HDD.find_file_by_name(params["name"])
if(!file || !istype(file))
return 1
var/newname = sanitize(input(usr, "Enter new file name:", "File rename", file.filename))
var/newname = stripped_input(usr, "Enter new file name:", "File rename", file.filename, max_length=50)
if(file && newname)
file.filename = newname
if("PRG_edit")
@@ -84,7 +84,7 @@
if(F.do_not_edit && (alert("WARNING: This file is not compatible with editor. Editing it may result in permanently corrupted formatting or damaged data consistency. Edit anyway?", "Incompatible File", "No", "Yes") == "No"))
return 1
// 16384 is the limit for file length in characters. Currently, papers have value of 2048 so this is 8 times as long, since we can't edit parts of the file independently.
var/newtext = sanitize(html_decode(input(usr, "Editing file [open_file]. You may use most tags used in paper formatting:", "Text Editor", F.stored_data) as message|null), 16384)
var/newtext = stripped_multiline_input(usr, "Editing file [open_file]. You may use most tags used in paper formatting:", "Text Editor", html_decode(F.stored_data), 16384, TRUE)
if(!newtext)
return
if(F)
@@ -110,7 +110,7 @@
if(!printer)
error = "Missing Hardware: Your computer does not have required hardware to complete this operation."
return 1
if(!printer.print_text(parse_tags(F.stored_data)))
if(!printer.print_text("<font face=\"[computer.emagged ? CRAYON_FONT : PRINTER_FONT]\">" + prepare_printjob(F.stored_data) + "</font>", open_file))
error = "Hardware error: Printer was unable to print the file. It may be out of paper."
return 1
if("PRG_copytousb")
@@ -132,11 +132,11 @@
var/datum/computer_file/C = F.clone(0)
HDD.store_file(C)
/datum/computer_file/program/filemanager/proc/parse_tags(t)
t = replacetext(t, "\[center\]", "<center>")
t = replacetext(t, "\[/center\]", "</center>")
t = replacetext(t, "\[br\]", "<BR>")
t = replacetext(t, "\n", "<BR>")
t = replacetext(t, "\[b\]", "<B>")
t = replacetext(t, "\[/b\]", "</B>")
t = replacetext(t, "\[i\]", "<I>")
@@ -167,9 +167,14 @@
t = replacetext(t, "\[tr\]", "</td><tr>")
t = replacetext(t, "\[td\]", "<td>")
t = replacetext(t, "\[cell\]", "<td>")
t = replacetext(t, "\[logo\]", "<img src = ntlogo.png>")
t = replacetext(t, "\[tab\]", "&nbsp;&nbsp;&nbsp;&nbsp;")
return t
/datum/computer_file/program/filemanager/proc/prepare_printjob(t) // Additional stuff to parse if we want to print it and make a happy Head of Personnel. Forms FTW.
t = replacetext(t, "\[field\]", "<span class=\"paper_field\"></span>")
t = replacetext(t, "\[sign\]", "<span class=\"paper_field\"></span>")
t = parse_tags(t)
return t
/datum/computer_file/program/filemanager/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state)
@@ -179,7 +184,7 @@
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers)
assets.send(user)
ui = new(user, src, ui_key, "file_manager", "NTOS File Manage", 575, 700, state = state)
ui = new(user, src, ui_key, "file_manager", "NTOS File Manager", 575, 700, state = state)
ui.open()
ui.set_autoupdate(state = 1)
@@ -227,4 +232,4 @@
)))
data["usbfiles"] = usbfiles
return data
return data
@@ -46,8 +46,11 @@
if(stored_card && stored_card2)
user << "<span class='warning'>You try to insert \the [I] into \the [src], but its slots are occupied.</span>"
return FALSE
if(user && !user.transferItemToLoc(I, src))
return FALSE
if(user)
if(!user.transferItemToLoc(I, src))
return FALSE
else
I.forceMove(src)
if(!stored_card)
stored_card = I
@@ -100,4 +103,4 @@
/obj/item/weapon/computer_hardware/card_slot/examine(mob/user)
..()
if(stored_card || stored_card2)
user << "There appears to be something loaded in the card slots."
user << "There appears to be something loaded in the card slots."
@@ -34,6 +34,7 @@
if(paper_title)
P.name = paper_title
P.update_icon()
P.reload_fields()
stored_paper--
P = null
return TRUE
+1 -1
View File
@@ -33,7 +33,7 @@
if (!orbiting.orbiters.len)//we are the last orbit, delete the list
orbiting.orbiters = null
orbiting = null
..()
return ..()
/datum/orbit/proc/Check(turf/targetloc)
if (!orbiter)
+14 -2
View File
@@ -181,6 +181,7 @@
t = replacetext(t, "\[center\]", "<center>")
t = replacetext(t, "\[/center\]", "</center>")
t = replacetext(t, "\[br\]", "<BR>")
t = replacetext(t, "\n", "<BR>")
t = replacetext(t, "\[b\]", "<B>")
t = replacetext(t, "\[/b\]", "</B>")
t = replacetext(t, "\[i\]", "<I>")
@@ -191,7 +192,7 @@
t = replacetext(t, "\[/large\]", "</font>")
t = replacetext(t, "\[sign\]", "<font face=\"[SIGNFONT]\"><i>[user.real_name]</i></font>")
t = replacetext(t, "\[field\]", "<span class=\"paper_field\"></span>")
t = replacetext(t, "\[tab\]", "&nbsp;")
t = replacetext(t, "\[tab\]", "&nbsp;&nbsp;&nbsp;&nbsp;")
if(!iscrayon)
t = replacetext(t, "\[*\]", "<li>")
@@ -226,6 +227,17 @@
return t
/obj/item/weapon/paper/proc/reload_fields() // Useful if you made the paper programicly and want to include fields. Also runs updateinfolinks() for you.
fields = 0
var/laststart = 1
while(1)
var/i = findtext(info, "<span class=\"paper_field\">", laststart)
if(i == 0)
break
laststart = i+1
fields++
updateinfolinks()
/obj/item/weapon/paper/proc/openhelp(mob/user)
user << browse({"<HTML><HEAD><TITLE>Pen Help</TITLE></HEAD>
@@ -256,7 +268,7 @@
if(href_list["write"])
var/id = href_list["write"]
var/t = stripped_multiline_input("Enter what you want to write:", "Write")
var/t = stripped_multiline_input("Enter what you want to write:", "Write", no_trim=TRUE)
if(!t)
return
var/obj/item/i = usr.get_active_held_item() //Check to see if he still got that darn pen, also check if he's using a crayon or pen.
+3 -3
View File
@@ -301,7 +301,7 @@
playsound(loc, O.usesound, 50, 1)
user << "<span class='warning'>You start [anchored ? "unwrenching" : "wrenching"] [src]...</span>"
if(do_after(user, 20*O.toolspeed, target = src))
if(qdeleted(src))
if(QDELETED(src))
return
user << "<span class='notice'>You [anchored ? "unwrench" : "wrench"] [src].</span>"
anchored = !anchored
@@ -325,7 +325,7 @@
user.visible_message("<span class='warning'>[user] starts putting [target] onto the photocopier!</span>", "<span class='notice'>You start putting [target] onto the photocopier...</span>")
if(do_after(user, 20, target = src))
if(!target || qdeleted(target) || qdeleted(src) || !Adjacent(target)) //check if the photocopier/target still exists.
if(!target || QDELETED(target) || QDELETED(src) || !Adjacent(target)) //check if the photocopier/target still exists.
return
if(target == user)
@@ -363,7 +363,7 @@
return 1
/obj/machinery/photocopier/proc/copier_blocked()
if(qdeleted(src))
if(QDELETED(src))
return
if(loc.density)
return 1
+1 -1
View File
@@ -419,7 +419,7 @@ By design, d1 is the smallest direction and d2 is the highest
powernet.remove_cable(src) //remove the cut cable from its powernet
spawn(0) //so we don't rebuild the network X times when singulo/explosion destroys a line of X cables
if(O && !qdeleted(O))
if(O && !QDELETED(O))
var/datum/powernet/newPN = new()// creates a new powernet...
propagate_network(O, newPN)//... and propagates it to the other side of the cable
+1 -1
View File
@@ -140,7 +140,7 @@
/obj/item/weapon/stock_parts/cell/ex_act(severity, target)
..()
if(!qdeleted(src))
if(!QDELETED(src))
switch(severity)
if(2)
if(prob(50))
+1 -1
View File
@@ -384,7 +384,7 @@
/obj/machinery/light/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1)
. = ..()
if(. && !qdeleted(src))
if(. && !QDELETED(src))
if(prob(damage_amount * 5))
break_light_tube()
+1 -1
View File
@@ -100,7 +100,7 @@
tesla_zap(src, 10, power/shock_coeff)
/obj/machinery/power/grounding_rod
name = "Grounding Rod"
name = "grounding rod"
desc = "Keep an area from being fried from Edison's Bane."
icon = 'icons/obj/tesla_engine/tesla_coil.dmi'
icon_state = "grounding_rod0"
+10 -6
View File
@@ -17,8 +17,8 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
/obj/structure/sign,
/obj/machinery/gateway,
/obj/structure/lattice,
/obj/structure/grille))
/obj/structure/grille,
/obj/machinery/the_singularitygen/tesla))
/obj/singularity/energy_ball
name = "energy ball"
desc = "An energy ball."
@@ -147,14 +147,18 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
orbitingball.orbiting_balls -= src
orbitingball.dissipate_strength = orbitingball.orbiting_balls.len
..()
if (!loc && !qdeleted(src))
if (!loc && !QDELETED(src))
qdel(src)
/obj/singularity/energy_ball/proc/dust_mobs(atom/A)
if(istype(A, /mob/living/carbon))
var/mob/living/carbon/C = A
C.dust()
if(!iscarbon(A))
return
for(var/obj/machinery/power/grounding_rod/GR in orange(src, 2))
if(GR.anchored)
return
var/mob/living/carbon/C = A
C.dust()
/proc/tesla_zap(atom/source, zap_range = 3, power, explosive = FALSE)
. = source.dir
+5 -1
View File
@@ -3,4 +3,8 @@
desc = "Makes the wardenclyffe look like a child's plaything when shot with a particle accelerator."
icon = 'icons/obj/tesla_engine/tesla_generator.dmi'
icon_state = "TheSingGen"
creation_type = /obj/singularity/energy_ball
creation_type = /obj/singularity/energy_ball
/obj/machinery/the_singularitygen/tesla/tesla_act(power, explosive = FALSE)
if(explosive)
energy += power
@@ -233,7 +233,7 @@
return
vol_each = min(reagents.total_volume / amount, 50)
var/name = stripped_input(usr,"Name:","Name your pill!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN)
if(!name || !reagents.total_volume || !src || qdeleted(src) || !usr.canUseTopic(src, be_close=TRUE))
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, be_close=TRUE))
return
var/obj/item/weapon/reagent_containers/pill/P
@@ -248,7 +248,7 @@
reagents.trans_to(P,vol_each)
else
var/name = stripped_input(usr, "Name:", "Name your pack!", reagents.get_master_reagent_name(), MAX_NAME_LEN)
if(!name || !reagents.total_volume || !src || qdeleted(src) || !usr.canUseTopic(src, be_close=TRUE))
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, be_close=TRUE))
return
var/obj/item/weapon/reagent_containers/food/condiment/pack/P = new/obj/item/weapon/reagent_containers/food/condiment/pack(src.loc)
@@ -270,7 +270,7 @@
return
vol_each = min(reagents.total_volume / amount, 40)
var/name = stripped_input(usr,"Name:","Name your patch!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN)
if(!name || !reagents.total_volume || !src || qdeleted(src) || !usr.canUseTopic(src, be_close=TRUE))
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, be_close=TRUE))
return
var/obj/item/weapon/reagent_containers/pill/P
@@ -289,7 +289,7 @@
if(condi)
var/name = stripped_input(usr, "Name:","Name your bottle!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN)
if(!name || !reagents.total_volume || !src || qdeleted(src) || !usr.canUseTopic(src, be_close=TRUE))
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, be_close=TRUE))
return
var/obj/item/weapon/reagent_containers/food/condiment/P = new(src.loc)
P.originalname = name
@@ -302,7 +302,7 @@
amount_full = round(reagents.total_volume / 30)
vol_part = reagents.total_volume % 30
var/name = stripped_input(usr, "Name:","Name your bottle!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN)
if(!name || !reagents.total_volume || !src || qdeleted(src) || !usr.canUseTopic(src, be_close=TRUE))
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, be_close=TRUE))
return
var/obj/item/weapon/reagent_containers/glass/bottle/P
@@ -260,7 +260,7 @@
/datum/reagent/medicine/salglu_solution
name = "Saline-Glucose Solution"
id = "salglu_solution"
description = "Has a 33% chance per metabolism cycle to heal brute and burn damage. Can be used as a blood substitute on an IV drip."
description = "Has a 33% chance per metabolism cycle to heal brute and burn damage. Can be used as a blood substitute on an IV drip."
reagent_state = LIQUID
color = "#DCDCDC"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
@@ -269,6 +269,9 @@
if(prob(33))
M.adjustBruteLoss(-0.5*REM, 0)
M.adjustFireLoss(-0.5*REM, 0)
if(iscarbon(M))
var/mob/living/carbon/C = M
C.blood_volume += 0.2
. = 1
..()
@@ -277,7 +280,7 @@
var/mob/living/carbon/human/H = M
if(H.dna && !(NOBLOOD in H.dna.species.species_traits))
var/efficiency = (BLOOD_VOLUME_NORMAL-H.blood_volume)/700 + 0.2//The lower the blood of the patient, the better it is as a blood substitute.
efficiency = min(0.75,efficiency)
efficiency = Clamp(efficiency, 0.1, 0.75)
//As it's designed for an IV drip, make large injections not as effective as repeated small injections.
H.blood_volume += round(efficiency * min(5,reac_volume), 0.1)
..()
@@ -214,7 +214,7 @@
name = "Unholy Water"
id = "unholywater"
description = "Something that shouldn't exist on this plane of existence."
/datum/reagent/fuel/unholywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(method == TOUCH || method == VAPOR)
M.reagents.add_reagent("unholywater", (reac_volume/4))
@@ -379,7 +379,7 @@
H.visible_message("<b>[H]</b> falls to the ground and screams as [H.p_their()] skin bubbles and froths!") //'froths' sounds painful when used with SKIN.
H.Weaken(3, 0)
spawn(30)
if(!H || qdeleted(H))
if(!H || QDELETED(H))
return
var/current_species = H.dna.species.type
@@ -896,6 +896,23 @@
H.wash_cream()
M.clean_blood()
/datum/reagent/space_cleaner/ez_clean
name = "EZ Clean"
id = "ez_clean"
description = "A powerful, acidic cleaner sold by Waffle Co. Affects organic matter while leaving other objects unaffected."
metabolization_rate = 1.5 * REAGENTS_METABOLISM
/datum/reagent/space_cleaner/ez_clean/on_mob_life(mob/living/M)
M.adjustBruteLoss(3.33)
M.adjustFireLoss(3.33)
M.adjustToxLoss(3.33)
..()
/datum/reagent/space_cleaner/ez_clean/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
..()
if((method == TOUCH || method == VAPOR) && !issilicon(M))
M.adjustBruteLoss(1)
M.adjustFireLoss(1)
/datum/reagent/cryptobiolin
name = "Cryptobiolin"
@@ -692,7 +692,7 @@
color = "#3C5133"
metabolization_rate = 0.08 * REAGENTS_METABOLISM
toxpwr = 0.15
/datum/reagent/toxin/anacea/on_mob_life(mob/living/M)
var/remove_amt = 5
if(holder.has_reagent("calomel") || holder.has_reagent("pen_acid"))
@@ -700,7 +700,7 @@
for(var/datum/reagent/medicine/R in M.reagents.reagent_list)
M.reagents.remove_reagent(R.id,remove_amt)
return ..()
//ACID
@@ -214,7 +214,7 @@
name = "Mulligan"
id = "mulligan"
results = list("mulligan" = 1)
required_reagents = list("humanmutationtoxin" = 1, "mutagen" = 1)
required_reagents = list("stablemutationtoxin" = 1, "mutagen" = 1)
////////////////////////////////// VIROLOGY //////////////////////////////////////////
+2 -2
View File
@@ -71,7 +71,7 @@
if(reagents)
for(var/datum/reagent/R in reagents.reagent_list)
R.on_ex_act()
if(!qdeleted(src))
if(!QDELETED(src))
..()
/obj/item/weapon/reagent_containers/fire_act(exposed_temperature, exposed_volume)
@@ -109,7 +109,7 @@
else
visible_message("<span class='notice'>[src] spills its contents all over [target].</span>")
reagents.reaction(target, TOUCH)
if(qdeleted(src))
if(QDELETED(src))
return
reagents.clear_reagents()
@@ -24,7 +24,7 @@ Borg Hypospray
var/bypass_protection = 0 //If the hypospray can go through armor or thick material
var/list/datum/reagents/reagent_list = list()
var/list/reagent_ids = list("dexalin", "kelotane", "bicaridine", "antitoxin", "epinephrine", "spaceacillin")
var/list/reagent_ids = list("dexalin", "kelotane", "bicaridine", "antitoxin", "epinephrine", "spaceacillin", "salglu_solution")
var/accepts_reagent_upgrades = TRUE //If upgrades can increase number of reagents dispensed.
var/list/modes = list() //Basically the inverse of reagent_ids. Instead of having numbers as "keys" and strings as values it has strings as keys and numbers as values.
//Used as list for input() in shakers.
+2 -2
View File
@@ -84,7 +84,7 @@
/obj/structure/reagent_dispensers/fueltank/bullet_act(obj/item/projectile/P)
..()
if(!qdeleted(src)) //wasn't deleted by the projectile's effects.
if(!QDELETED(src)) //wasn't deleted by the projectile's effects.
if(!P.nodamage && ((P.damage_type == BURN) || (P.damage_type == BRUTE)))
var/boom_message = "[key_name_admin(P.firer)] triggered a fueltank explosion via projectile."
bombers += boom_message
@@ -162,7 +162,7 @@
/obj/structure/reagent_dispensers/beerkeg/blob_act(obj/structure/blob/B)
explosion(src.loc,0,3,5,7,10)
if(!qdeleted(src))
if(!QDELETED(src))
qdel(src)

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