Merge remote-tracking branch 'upstream/master' into qdelFixes

Conflicts:
	code/modules/mob/living/silicon/robot/robot.dm
This commit is contained in:
xxalpha
2015-08-31 08:52:30 +01:00
168 changed files with 3564 additions and 2510 deletions
+5 -1
View File
@@ -48,7 +48,11 @@ var/global/floorIsLava = 0
body += "<A href='?_src_=holder;jobban2=\ref[M]'>Jobban</A> | "
body += "<A href='?_src_=holder;appearanceban=\ref[M]'>Identity Ban</A> | "
body += "<A href='?_src_=holder;shownoteckey=[M.ckey]'>Notes</A> | "
body += "<A href='?_src_=holder;watchlist=\ref[M]'>Watchlist Flag</A> "
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> "
if(M.client)
body += "| <A href='?_src_=holder;sendtoprison=\ref[M]'>Prison</A> | "
+3 -1
View File
@@ -22,7 +22,7 @@
F << "<small>[time_stamp()] \ref[src] ([x],[y],[z])</small> || [src] [message]<br>"
//ADMINVERBS
/client/proc/investigate_show( subject in list("hrefs","notes","ntsl","singulo","wires","telesci", "gravity", "records", "cargo", "supermatter", "atmos", "experimentor", "kudzu") )
/client/proc/investigate_show( subject in list("hrefs","notes","watchlist","ntsl","singulo","wires","telesci", "gravity", "records", "cargo", "supermatter", "atmos", "experimentor", "kudzu") )
set name = "Investigate"
set category = "Admin"
if(!holder) return
@@ -46,3 +46,5 @@
return
if("notes")
show_note()
if("watchlist")
watchlist_show()
+7 -7
View File
@@ -19,7 +19,7 @@
var/sql_ckey = sanitizeSQL(src.ckey)
switch(task)
if("Write")
var/DBQuery/query_memocheck = dbcon.NewQuery("SELECT ckey FROM [format_table_name("memo")] WHERE (ckey = '[sql_ckey]')")
var/DBQuery/query_memocheck = dbcon.NewQuery("SELECT ckey FROM [format_table_name("memo")] WHERE ckey = '[sql_ckey]'")
if(!query_memocheck.Execute())
var/err = query_memocheck.ErrorMsg()
log_game("SQL ERROR obtaining ckey from memo table. Error : \[[err]\]\n")
@@ -27,7 +27,7 @@
if(query_memocheck.NextRow())
src << "You already have set a memo."
return
var/memotext = input(src,"Write your Memo","Memo") as text|null
var/memotext = input(src,"Write your Memo","Memo") as message
if(!memotext)
return
memotext = sanitizeSQL(memotext)
@@ -56,20 +56,20 @@
if(!target_ckey)
return
var/target_sql_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_memofind = dbcon.NewQuery("SELECT ckey, memotext FROM [format_table_name("memo")] WHERE (ckey = '[target_sql_ckey]')")
var/DBQuery/query_memofind = dbcon.NewQuery("SELECT memotext FROM [format_table_name("memo")] WHERE ckey = '[target_sql_ckey]'")
if(!query_memofind.Execute())
var/err = query_memofind.ErrorMsg()
log_game("SQL ERROR obtaining ckey, memotext from memo table. Error : \[[err]\]\n")
log_game("SQL ERROR obtaining memotext from memo table. Error : \[[err]\]\n")
return
if(query_memofind.NextRow())
var/old_memo = query_memofind.item[2]
var/new_memo = input("Input new memo", "New Memo", "[old_memo]", null) as null|text
var/old_memo = query_memofind.item[1]
var/new_memo = input("Input new memo", "New Memo", "[old_memo]", null) as message
if(!new_memo)
return
new_memo = sanitizeSQL(new_memo)
var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from<br>[old_memo]<br>to<br>[new_memo]<hr>"
edit_text = sanitizeSQL(edit_text)
var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("memo")] SET memotext = '[new_memo]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE (ckey = '[target_sql_ckey]')")
var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("memo")] SET memotext = '[new_memo]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE ckey = '[target_sql_ckey]'")
if(!update_query.Execute())
var/err = update_query.ErrorMsg()
log_game("SQL ERROR editing memo. Error : \[[err]\]\n")
+5 -3
View File
@@ -3,13 +3,14 @@
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
if(!target_ckey)
var/new_ckey = ckey(input(usr,"Who would you like to add a note for?","Enter a ckey",null) as text|null)
var/new_ckey = ckey(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 notes table. Error : \[[err]\]\n")
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
return
if(!query_find_ckey.NextRow())
usr << "<span class='redtext'>[new_ckey] has not been seen before, you can only add notes to known players.</span>"
@@ -147,7 +148,8 @@
var/search
output += "<center><a href='?_src_=holder;addnoteempty=1'>\[Add Note\]</a></center>"
output += ruler
index = sanitizeSQL(index)
if(!isnum(index))
index = sanitizeSQL(index)
switch(index)
if(1)
search = "^."
+49 -66
View File
@@ -443,15 +443,14 @@
mins = minutes - CMinutes
mins = input(usr,"How long (in minutes)? (Default: 1440)","Ban time",mins ? mins : 1440) as num|null
if(!mins) return
mins = min(525599,mins)
minutes = CMinutes + mins
duration = GetExp(minutes)
reason = input(usr,"Reason?","reason",reason2) as text|null
reason = input(usr,"Please State Reason","Reason",reason2) as message
if(!reason) return
if("No")
temp = 0
duration = "Perma"
reason = input(usr,"Reason?","reason",reason2) as text|null
reason = input(usr,"Please State Reason","Reason",reason2) as message
if(!reason) return
log_admin("[key_name(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [duration]")
@@ -497,7 +496,7 @@
else switch(alert("Appearance ban [M.ckey]?",,"Yes","No", "Cancel"))
if("Yes")
var/reason = input(usr,"Reason?","reason","Metafriender") as text|null
var/reason = input(usr,"Please State Reason","Reason") as message
if(!reason)
return
ban_unban_log_save("[key_name(usr)] appearance banned [key_name(M)]. reason: [reason]")
@@ -505,7 +504,7 @@
feedback_inc("ban_appearance",1)
DB_ban_record(BANTYPE_APPEARANCE, M, -1, reason)
appearance_fullban(M, "[reason]; By [usr.ckey] on [time2text(world.realtime)]")
add_note(M.ckey, "Appearance banned - [reason]", null, usr, 0)
add_note(M.ckey, "Appearance banned - [reason]", null, usr.ckey, 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>"
@@ -905,7 +904,7 @@
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
if(!mins)
return
var/reason = input(usr,"Reason?","Please State Reason","") as text|null
var/reason = input(usr,"Please State Reason","Reason") as message
if(!reason)
return
@@ -921,7 +920,7 @@
msg = job
else
msg += ", [job]"
add_note(M.ckey, "Banned from [msg] - [reason]", null, usr, 0)
add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 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 jobbanned by [usr.client.ckey] from: [msg].</BIG></span>"
M << "<span class='boldannounce'>The reason is: [reason]</span>"
@@ -929,7 +928,7 @@
href_list["jobban2"] = 1 // lets it fall through and refresh
return 1
if("No")
var/reason = input(usr,"Reason?","Please State Reason","") as text|null
var/reason = input(usr,"Please State Reason","Reason") as message
if(reason)
var/msg
for(var/job in notbannedlist)
@@ -941,7 +940,7 @@
jobban_fullban(M, job, "[reason]; By [usr.ckey] on [time2text(world.realtime)]")
if(!msg) msg = job
else msg += ", [job]"
add_note(M.ckey, "Banned from [msg] - [reason]", null, usr, 0)
add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 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 jobbanned by [usr.client.ckey] from: [msg].</BIG></span>"
M << "<span class='boldannounce'>The reason is: [reason]</span>"
@@ -1065,8 +1064,7 @@
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
if(!mins)
return
if(mins >= 525600) mins = 525599
var/reason = input(usr,"Reason?","reason","Griefer") as text|null
var/reason = input(usr,"Please State Reason","Reason") as message
if(!reason)
return
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins)
@@ -1086,7 +1084,7 @@
del(M.client)
//qdel(M) // See no reason why to delete mob. Important stuff can be lost. And ban can be lifted before round ends.
if("No")
var/reason = input(usr,"Reason?","reason","Griefer") as text|null
var/reason = input(usr,"Please State Reason","Reason") as message
if(!reason)
return
switch(alert(usr,"IP ban?",,"Yes","No","Cancel"))
@@ -1126,61 +1124,46 @@
unjobbanpanel()
//Watchlist
else if(href_list["watchlist"])
if(!check_rights(R_ADMIN)) return
var/mob/M = locate(href_list["watchlist"])
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
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(!ismob(M))
usr << "This can only be used on instances of type /mob"
return
if(!M.ckey)
usr << "This mob has no ckey"
return
var/sql_ckey = sanitizeSQL(M.ckey)
var/DBQuery/query = dbcon.NewQuery("SELECT ckey FROM [format_table_name("watch")] WHERE (ckey = '[sql_ckey]')")
query.Execute()
if(query.NextRow())
switch(alert(usr, "[sql_ckey] is already on the watchlist, do you want to:", "Ckey already flagged", "Remove", "Edit reason", "Cancel"))
if("Cancel")
return
if("Remove")
var/DBQuery/query_watchdel = dbcon.NewQuery("DELETE FROM [format_table_name("watch")] WHERE ckey = '[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 [key_name_admin(M)] from the watchlist")
message_admins("[key_name_admin(usr)] has removed [key_name_admin(M)] from the watchlist", 1)
if("Edit reason")
var/DBQuery/query_reason = dbcon.NewQuery("SELECT ckey, reason FROM [format_table_name("watch")] WHERE (ckey = '[sql_ckey]')")
query_reason.Execute()
if(query_reason.NextRow())
var/watch_reason = query_reason.item[2]
var/new_reason = input("Insert new reason", "New Reason", "[watch_reason]", null) as null|text
new_reason = sanitizeSQL(new_reason)
if(!new_reason)
return
var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("watch")] SET reason = '[new_reason]' WHERE (ckey = '[sql_ckey]')")
if(!update_query.Execute())
var/err = update_query.ErrorMsg()
log_game("SQL ERROR during edit watch entry reason. Error : \[[err]\]\n")
return
log_admin("[key_name(usr)] has edited [sql_ckey]'s reason from [watch_reason] to [new_reason]",1)
message_admins("[key_name_admin(usr)] has edited [sql_ckey]'s reason from [watch_reason] to [new_reason]",1)
else
var/reason = input(usr,"Reason?","reason","Metagaming") as text|null
if(!reason)
return
reason = sanitizeSQL(reason)
var/DBQuery/query_watchadd = dbcon.NewQuery("INSERT INTO [format_table_name("watch")] (ckey, reason) VALUES ('[sql_ckey]', '[reason]')")
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 [key_name_admin(M)] to the watchlist - Reason: [reason]")
message_admins("[key_name_admin(usr)] has added [key_name_admin(M)] to the watchlist - Reason: [reason]", 1)
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
+2 -2
View File
@@ -1,7 +1,7 @@
/*
HOW DO I LOG RUNTIMES?
Firstly, start dreamdeamon if it isn't already running. Then select "world>Log Session" (or press the F3 key)
navigate the popup window to the data/logs/runtime/ folder from where your tgstation .dmb is located.
navigate the popup window to the data/logs/runtimes/ folder from where your tgstation .dmb is located.
(you may have to make this folder yourself)
OPTIONAL: you can select the little checkbox down the bottom to make dreamdeamon save the log everytime you
@@ -44,7 +44,7 @@
set desc = "Retrieve any session logfiles saved by dreamdeamon."
set category = null
var/path = browse_files("data/logs/runtime/")
var/path = browse_files("data/logs/runtimes/")
if(!path)
return
+1 -1
View File
@@ -171,7 +171,7 @@
return .(O.vars[variable])
if("text")
var/new_value = input("Enter new text:","Text",O.vars[variable]) as text|null
var/new_value = input("Enter new text:","Text",O.vars[variable]) as message|null
if(new_value == null) return
var/process_vars = 0
+4 -4
View File
@@ -49,7 +49,7 @@ var/list/VVckey_edit = list("key", "ckey")
switch(class)
if("text")
var_value = input("Enter new text:","Text") as null|text
var_value = input("Enter new text:","Text") as null|message
if("num")
var_value = input("Enter new number:","Num") as null|num
@@ -106,7 +106,7 @@ var/list/VVckey_edit = list("key", "ckey")
switch(class)
if("text")
var_value = input("Enter new text:","Text") as text
var_value = input("Enter new text:","Text") as message
if("num")
var_value = input("Enter new number:","Num") as num
@@ -302,7 +302,7 @@ var/list/VVckey_edit = list("key", "ckey")
return
if("text")
new_var = input("Enter new text:","Text") as text
new_var = input("Enter new text:","Text") as message
if(findtext(new_var,"\["))
var/process_vars = alert(usr,"\[] detected in string, process as variables?","Process Variables?","Yes","No")
@@ -557,7 +557,7 @@ var/list/VVckey_edit = list("key", "ckey")
return .(O.vars[variable])
if("text")
var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|text
var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|message
if(var_new==null) return
if(findtext(var_new,"\["))
+118
View File
@@ -0,0 +1,118 @@
/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())
usr << "<span class='redtext'>[new_ckey] has not been seen before, you can only add known players.</span>"
return
else
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)
/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
+12 -3
View File
@@ -25,6 +25,13 @@
var/const/WIRE_RADIO_RECEIVE = 8 //Allows Pulsed(1) to call Activate()
var/const/WIRE_RADIO_PULSE = 16 //Allows Pulse(1) to send a radio message
/obj/item/device/assembly/Destroy()
qdel(connected)
connected = null
qdel(holder)
holder = null
return ..()
/obj/item/device/assembly/proc/holder_movement() //Called when the holder is moved
return
@@ -51,10 +58,12 @@
//Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs
/obj/item/device/assembly/proc/pulsed(radio = 0)
if(holder && (wires & WIRE_RECEIVE))
activate()
if(wires & WIRE_RECEIVE)
spawn(0)
activate()
if(radio && (wires & WIRE_RADIO_RECEIVE))
activate()
spawn(0)
activate()
return 1
+146
View File
@@ -0,0 +1,146 @@
/obj/item/device/assembly/control
name = "blast door controller"
desc = "A small electronic device able to control a blast door remotely."
icon_state = "control"
origin_tech = "magnets=1;programming=2"
attachable = 1
var/id = null
var/can_change_id = 0
/obj/item/device/assembly/control/examine(mob/user)
..()
if(id)
user << "It's channel ID is '[id]'."
/obj/item/device/assembly/control/activate()
cooldown = 1
var/openclose
for(var/obj/machinery/door/poddoor/M in machines)
if(M.id == src.id)
if(openclose == null)
openclose = M.density
spawn(0)
if(M)
if(openclose) M.open()
else M.close()
return
sleep(10)
cooldown = 0
/obj/item/device/assembly/control/airlock
name = "airlock controller"
desc = "A small electronic device able to control an airlock remotely."
id = "badmin" // Set it to null for MEGAFUN.
var/specialfunctions = OPEN
/*
Bitflag, 1= open (OPEN)
2= idscan (IDSCAN)
4= bolts (BOLTS)
8= shock (SHOCK)
16= door safties (SAFE)
*/
/obj/item/device/assembly/control/airlock/activate()
cooldown = 1
for(var/obj/machinery/door/airlock/D in airlocks)
if(D.id_tag == src.id)
if(specialfunctions & OPEN)
spawn(0)
if(D)
if(D.density) D.open()
else D.close()
return
if(specialfunctions & IDSCAN)
D.aiDisabledIdScanner = !D.aiDisabledIdScanner
if(specialfunctions & BOLTS)
if(!D.isWireCut(4) && D.hasPower())
D.locked = !D.locked
D.update_icon()
if(specialfunctions & SHOCK)
D.secondsElectrified = D.secondsElectrified ? 0 : -1
if(specialfunctions & SAFE)
D.safe = !D.safe
sleep(10)
cooldown = 0
/obj/item/device/assembly/control/massdriver
name = "mass driver controller"
desc = "A small electronic device able to control a mass driver."
/obj/item/device/assembly/control/massdriver/activate()
cooldown = 1
for(var/obj/machinery/door/poddoor/M in machines)
if (M.id == src.id)
spawn( 0 )
M.open()
return
sleep(10)
for(var/obj/machinery/mass_driver/M in machines)
if(M.id == src.id)
M.drive()
sleep(60)
for(var/obj/machinery/door/poddoor/M in machines)
if (M.id == src.id)
spawn( 0 )
M.close()
return
sleep(10)
cooldown = 0
/obj/item/device/assembly/control/igniter
name = "ignition controller"
desc = "A remote controller for a mounted igniter."
/obj/item/device/assembly/control/igniter/activate()
cooldown = 1
for(var/obj/machinery/sparker/M in machines)
if (M.id == src.id)
spawn( 0 )
M.ignite()
for(var/obj/machinery/igniter/M in machines)
if(M.id == src.id)
M.use_power(50)
M.on = !M.on
M.icon_state = "igniter[M.on]"
sleep(30)
cooldown = 0
/obj/item/device/assembly/control/flasher
name = "flasher controller"
desc = "A remote controller for a mounted flasher."
/obj/item/device/assembly/control/flasher/activate()
cooldown = 1
for(var/obj/machinery/flasher/M in machines)
if(M.id == src.id)
spawn(0)
M.flash()
sleep(50)
cooldown = 0
/obj/item/device/assembly/control/crematorium
name = "crematorium controller"
desc = "An evil-looking remote controller for a crematorium."
/obj/item/device/assembly/control/crematorium/activate()
cooldown = 1
for (var/obj/structure/bodycontainer/crematorium/C in crematoriums)
if (C.id == id)
C.cremate(usr)
sleep(50)
cooldown = 0
+4 -5
View File
@@ -234,11 +234,10 @@ var/next_external_rsc = 0
while (query_cid.NextRow())
related_accounts_cid += "[query_cid.item[1]], "
var/DBQuery/query_watch = dbcon.NewQuery("SELECT ckey, reason FROM [format_table_name("watch")] WHERE (ckey = '[sql_ckey]')")
query_watch.Execute()
if(query_watch.NextRow())
message_admins("<font color='red'><B>Notice: </B></font><font color='blue'>[key_name_admin(src)] is flagged for watching and has just connected - Reason: [query_watch.item[2]]</font>")
send2irc_adminless_only("Watchlist", "[key_name(src)] is flagged for watching and has just connected - Reason: [query_watch.item[2]]")
var/watchreason = check_watchlist(sql_ckey)
if(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/admin_rank = "Player"
if (src.holder && src.holder.rank)
+1 -1
View File
@@ -105,7 +105,7 @@
/obj/item/clothing/suit/armor/laserproof/IsReflect(def_zone)
if(!(def_zone in list("chest", "groin"))) //If not shot where ablative is covering you, you don't get the reflection bonus!
hit_reflect_chance = 0
return 0
if (prob(hit_reflect_chance))
return 1
+1 -5
View File
@@ -7,7 +7,6 @@
/datum/round_event/brand_intelligence
announceWhen = 21
endWhen = 1000 //Ends when all vending machines are subverted anyway.
var/list/obj/machinery/vending/vendingMachines = list()
var/list/obj/machinery/vending/infectedMachines = list()
var/obj/machinery/vending/originMachine
@@ -28,11 +27,9 @@
for(var/obj/machinery/vending/V in machines)
if(V.z != 1) continue
vendingMachines.Add(V)
if(!vendingMachines.len)
kill()
return
originMachine = pick(vendingMachines)
vendingMachines.Remove(originMachine)
originMachine.shut_up = 0
@@ -48,7 +45,7 @@
originMachine.visible_message("[originMachine] beeps and seems lifeless.")
kill()
return
vendingMachines = removeNullsFromList(vendingMachines)
if(!vendingMachines.len) //if every machine is infected
for(var/obj/machinery/vending/upriser in infectedMachines)
if(prob(70) && !upriser.gc_destroyed)
@@ -62,7 +59,6 @@
kill()
return
if(IsMultiple(activeFor, 4))
var/obj/machinery/vending/rebel = pick(vendingMachines)
vendingMachines.Remove(rebel)
+5
View File
@@ -121,6 +121,11 @@
var/attacher = "UNKNOWN"
var/datum/wires/explosive/gibtonite/wires
/obj/item/weapon/twohanded/required/gibtonite/Destroy()
qdel(wires)
wires = null
return ..()
/obj/item/weapon/twohanded/required/gibtonite/attackby(obj/item/I, mob/user, params)
if(!wires && istype(I, /obj/item/device/assembly/igniter))
user.visible_message("[user] attaches [I] to [src].", "<span class='notice'>You attach [I] to [src].</span>")
+3 -1
View File
@@ -293,7 +293,9 @@
/mob/living/carbon/human/interactive/Life()
..()
if(isnotfunc()) return
if(isnotfunc())
walk(src,0)
return
if(a_intent != "disarm")
a_intent = "disarm"
//---------------------------
@@ -73,7 +73,19 @@ In all, this is a lot like the monkey code. /N
/mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M)
if(..())
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
adjustBruteLoss(damage)
switch(M.melee_damage_type)
if(BRUTE)
adjustBruteLoss(damage)
if(BURN)
adjustFireLoss(damage)
if(TOX)
adjustToxLoss(damage)
if(OXY)
adjustOxyLoss(damage)
if(CLONE)
adjustCloneLoss(damage)
if(STAMINA)
adjustStaminaLoss(damage)
updatehealth()
/mob/living/carbon/alien/attack_slime(mob/living/simple_animal/slime/M)
@@ -14,7 +14,6 @@
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/humanoid/New()
create_reagents(1000)
AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null))
..()
@@ -10,8 +10,6 @@
/mob/living/carbon/alien/humanoid/queen/New()
create_reagents(100)
//there should only be one queen
for(var/mob/living/carbon/alien/humanoid/queen/Q in living_mob_list)
if(Q == src) continue
@@ -24,5 +24,5 @@
/mob/living/carbon/alien/larva/update_transform() //All this is handled in update_icons()
return update_icons()
/mob/living/carbon/larva/update_inv_handcuffed()
/mob/living/carbon/alien/larva/update_inv_handcuffed()
return
@@ -8,10 +8,6 @@
var/alert = null
has_limbs = 0
/mob/living/carbon/brain/New()
create_reagents(1000)
..()
/mob/living/carbon/brain/Destroy()
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
if(stat!=DEAD) //If not dead.
+10 -3
View File
@@ -1,3 +1,7 @@
/mob/living/carbon/New()
create_reagents(1000)
..()
/mob/living/carbon/prepare_huds()
..()
prepare_data_huds()
@@ -74,9 +78,9 @@
. = ..()
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1.0)
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1.0, override = 0)
shock_damage *= siemens_coeff
if (shock_damage<1)
if(shock_damage<1 && !override)
return 0
take_overall_damage(0,shock_damage)
//src.burn_skin(shock_damage)
@@ -95,7 +99,10 @@
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
Stun(3)
Weaken(3)
return shock_damage
if(override)
return override
else
return shock_damage
/mob/living/carbon/swap_hand()
@@ -14,7 +14,6 @@
/mob/living/carbon/human/New()
create_reagents(1000)
verbs += /mob/living/proc/mob_sleep
verbs += /mob/living/proc/lay_down
//initialise organs
@@ -270,7 +269,7 @@
spreadFire(AM)
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1.0, safety = 0)
/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1.0, safety = 0, override = 0)
if(!safety)
if(gloves)
var/obj/item/clothing/gloves/G = gloves
@@ -280,8 +279,7 @@
heart_attack = 0
if(stat == CONSCIOUS)
src << "<span class='notice'>You feel your heart beating again!</span>"
. = ..(shock_damage,source,siemens_coeff)
. = ..(shock_damage,source,siemens_coeff,safety,override)
if(.)
electrocution_animation(40)
@@ -389,7 +389,7 @@ emp_act
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/obj/item/organ/limb/affecting = get_organ(ran_zone(dam_zone))
var/armor = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor)
apply_damage(damage, M.melee_damage_type, affecting, armor)
updatehealth()
@@ -13,7 +13,6 @@
unique_name = 1
/mob/living/carbon/monkey/New()
create_reagents(1000)
verbs += /mob/living/proc/mob_sleep
verbs += /mob/living/proc/lay_down
@@ -155,7 +154,19 @@
/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M)
if(..())
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
adjustBruteLoss(damage)
switch(M.melee_damage_type)
if(BRUTE)
adjustBruteLoss(damage)
if(BURN)
adjustFireLoss(damage)
if(TOX)
adjustToxLoss(damage)
if(OXY)
adjustOxyLoss(damage)
if(CLONE)
adjustCloneLoss(damage)
if(STAMINA)
adjustStaminaLoss(damage)
updatehealth()
@@ -138,7 +138,9 @@
mmi = null
if(connected_ai)
connected_ai.connected_robots -= src
qdel(wires)
qdel(module)
wires = null
module = null
camera = null
cell = null
+13 -1
View File
@@ -386,7 +386,19 @@
/mob/living/silicon/attack_animal(mob/living/simple_animal/M)
if(..())
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
adjustBruteLoss(damage)
switch(M.melee_damage_type)
if(BRUTE)
adjustBruteLoss(damage)
if(BURN)
adjustFireLoss(damage)
if(TOX)
adjustToxLoss(damage)
if(OXY)
adjustOxyLoss(damage)
if(CLONE)
adjustCloneLoss(damage)
if(STAMINA)
adjustStaminaLoss(damage)
updatehealth()
/mob/living/silicon/attack_paw(mob/living/user)
@@ -0,0 +1,529 @@
////Deactivated swarmer shell////
/obj/item/unactivated_swarmer
name = "unactivated swarmer"
desc = "A currently unactivated swarmer. Swarmers can self activate at any time, it would be wise to immediately dispose of this."
icon = 'icons/mob/swarmer.dmi'
icon_state = "swarmer_unactivated"
/obj/item/unactivated_swarmer/New()
notify_ghosts("An unactivated swarmer has been created in [get_area(src)]! <a href=?src=\ref[src];ghostjoin=1>(Click to enter)</a>")
..()
/obj/item/unactivated_swarmer/Topic(href, href_list)
if(href_list["ghostjoin"])
var/mob/dead/observer/ghost = usr
if(istype(ghost))
attack_ghost(ghost)
/obj/item/unactivated_swarmer/attack_ghost(mob/user)
var/be_swarmer = alert("Become a swarmer? (Warning, You can no longer be cloned!)",,"Yes","No")
if(be_swarmer == "No")
return
if(qdeleted(src))
user << "Swarmer has been occupied by someone else."
return
var/mob/living/simple_animal/hostile/swarmer/S = new /mob/living/simple_animal/hostile/swarmer(get_turf(loc))
S.key = user.key
qdel(src)
////The Mob itself////
/mob/living/simple_animal/hostile/swarmer
name = "Swarmer"
unique_name = 1
icon = 'icons/mob/swarmer.dmi'
desc = "A robot of unknown design, they seek only to consume materials and replicate themselves indefinitely."
speak_emote = list("tones")
health = 40
maxHealth = 40
status_flags = CANPUSH
icon_state = "swarmer"
icon_living = "swarmer"
icon_dead = "swarmer_unactivated"
icon_gib = null
wander = 0
harm_intent_damage = 5
minbodytemp = 0
maxbodytemp = 500
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
unsuitable_atmos_damage = 0
melee_damage_lower = 15
melee_damage_upper = 15
melee_damage_type = STAMINA
ignored_damage_types = list(BRUTE = 0, BURN = 0, TOX = 1, CLONE = 1, STAMINA = 1, OXY = 1)
languages = SWARMER
environment_smash = 0
attacktext = "shocks"
attack_sound = 'sound/effects/EMPulse.ogg'
friendly = "pinches"
speed = 0
faction = list("swarmer")
AIStatus = AI_OFF
projectiletype = /obj/item/projectile/beam/disabler
pass_flags = PASSTABLE | PASSMOB
ventcrawler = 2
ranged = 1
projectiletype = /obj/item/projectile/beam/disabler
ranged_cooldown_cap = 2
projectilesound = 'sound/weapons/taser2.ogg'
var/resources = 0 //Resource points, generated by consuming metal/glass
/mob/living/simple_animal/hostile/swarmer/Login()
..()
src << "<b>You are a swarmer, a weapon of a long dead civilization. Until further orders from your original masters are received, you must continue to consume and replicate.</b>"
src << "<b>Ctrl + Click provides most of your swarmer specific interactions, such as cannibalizing metal or glass, destroying the environment, or teleporting mobs away from you."
src << "<b>Objectives:</b>"
src << "1. Consume resources and replicate until there are no more resources left."
src << "2. Ensure that the station is fit for invasion at a later date, do not perform actions that would render it dangerous or inhospitable."
src << "3. Biological resources will be harvested at a later date, do not harm them."
/mob/living/simple_animal/hostile/swarmer/New()
..()
verbs -= /mob/living/verb/pulled
/mob/living/simple_animal/hostile/swarmer/Stat()
..()
if(statpanel("Status"))
stat("Resources:",resources)
/mob/living/simple_animal/hostile/swarmer/death(gibbed)
..(gibbed)
new /obj/effect/decal/cleanable/robot_debris(src.loc)
ghostize()
qdel(src)
/mob/living/simple_animal/hostile/swarmer/emp_act()
if(health > 1)
health = 1
..()
health = 0
/mob/living/simple_animal/hostile/swarmer/CanPass(atom/movable/O)
if(istype(O, /obj/item/projectile/beam/disabler))//Allows for swarmers to fight as a group without wasting their shots hitting each other
return 1
if(isswarmer(O))
return 1
..()
////CTRL CLICK FOR SWARMERS AND SWARMER_ACT()'S////
/mob/living/simple_animal/hostile/swarmer/CtrlClickOn(atom/A)
face_atom(A)
if(!isturf(loc))
return
if(next_move > world.time)
return
if(!A.Adjacent(src))
return
A.swarmer_act(src)
return
/atom/proc/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S.DisIntegrate(src)
/obj/item/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S.Integrate(src)
/obj/item/weapon/gun/swarmer_act()//Stops you from eating the entire armory
return
/turf/simulated/floor/swarmer_act()//ex_act() on turf calls it on its contents, this is to prevent attacking mobs by DisIntegrate()'ing the floor
return
/obj/machinery/atmospherics/swarmer_act()
return
/obj/structure/disposalpipe/swarmer_act()
return
/obj/machinery/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S.DismantleMachine(src)
/obj/machinery/light/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S.DisIntegrate(src)
/obj/machinery/door/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S.DisIntegrate(src)
/obj/machinery/camera/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S.DisIntegrate(src)
deactivate(S, 0)
/obj/machinery/particle_accelerator/control_box/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S.DisIntegrate(src)
/obj/machinery/field/generator/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S.DisIntegrate(src)
/obj/machinery/gravity_generator/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S.DisIntegrate(src)
/obj/machinery/vending/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)//It's more visually interesting than dismantling the machine
S.DisIntegrate(src)
/obj/machinery/turretid/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S.DisIntegrate(src)
/obj/machinery/chem_dispenser/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S << "<span class='warning'>The volatile chemicals in this machine would destroy us. Aborting.</span>"
/obj/machinery/nuclearbomb/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S << "<span class='warning'>This device's destruction would result in the extermination of everything in the area. Aborting.</span>"
/obj/machinery/dominator/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S << "<span class='warning'>This device is attempting to corrupt our entire network; attempting to interact with it is too risky. Aborting.</span>"
/obj/structure/reagent_dispensers/fueltank/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S << "<span class='warning'>Destroying this object would cause a chain reaction. Aborting.</span>"
/obj/structure/cable/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S << "<span class='warning'>Disrupting the power grid would bring no benefit to us. Aborting.</span>"
/obj/machinery/portable_atmospherics/canister/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S << "<span class='warning'>An inhospitable area may be created as a result of destroying this object. Aborting.</span>"
/obj/machinery/power/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S << "<span class='warning'>Disrupting the power grid would bring no benefit to us. Aborting.</span>"
/obj/machinery/gateway/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S << "<span class='warning'>This bluespace source will be important to us later. Aborting.</span>"
/turf/simulated/wall/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
if(locate(/turf/space) in range(1, src))
S << "<span class='warning'>Destroying this object has the potential to cause a hull breach. Aborting.</span>"
return
..()
/obj/structure/window/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
if(locate(/turf/space) in range(1, src))
S << "<span class='warning'>Destroying this object has the potential to cause a hull breach. Aborting.</span>"
return
..()
/obj/item/stack/cable_coil/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)//Wiring would be too effective as a resource
S << "<span class='warning'>This object does not contain enough materials to work with.</span>"
/obj/machinery/porta_turret/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S << "<span class='warning'>Attempting to dismantle this machine would result in an immediate counterattack. Aborting.</span>"
/mob/living/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S.DisperseTarget(src)
/mob/living/simple_animal/slime/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S << "<span class='warning'>This biological resource is somehow resisting our bluespace transceiver. Aborting.</span>"
////END CTRL CLICK FOR SWARMERS////
/mob/living/simple_animal/hostile/swarmer/proc/Fabricate(var/atom/fabrication_object,var/fabrication_cost = 0)
if(!isturf(loc))
src << "<span class='warning'>This is not a suitable location for fabrication. We need more space.</span>"
if(resources >= fabrication_cost)
resources -= fabrication_cost
else
src << "<span class='warning'>You do not have the necessary resources to fabricate this object.</span>"
return 0
new fabrication_object(loc)
return 1
/mob/living/simple_animal/hostile/swarmer/proc/Integrate(var/obj/item/target)
if(resources >= 100)
src << "<span class='warning'>We cannot hold more materials!</span>"
return
if((target.materials[MAT_METAL]) || (target.materials[MAT_GLASS]))
resources++
do_attack_animation(target)
changeNext_move(CLICK_CD_MELEE)
if(istype(target, /obj/item/stack))
var/obj/item/stack/S = target
S.use(1)
if(S.amount)
return
qdel(target)
else
src << "<span class='warning'>\the [target] is incompatible with our internal matter recycler.</span>"
return
/mob/living/simple_animal/hostile/swarmer/proc/DisIntegrate(var/atom/movable/target)
new /obj/effect/effect/sparks(get_turf(target))
do_attack_animation(target)
changeNext_move(CLICK_CD_MELEE)
target.ex_act(3)
return
/mob/living/simple_animal/hostile/swarmer/proc/DisperseTarget(var/mob/living/target)
if(target != src)
src << "<span class='info'>Attempting to remove this being from our presence.</span>"
if(src.z != ZLEVEL_STATION)
src << "<span class='warning'>Our bluespace transceiver cannot locate a viable bluespace link, our teleportation abilities are useless in this area.</span>"
return
if(do_mob(src, target, 30))
var/cycle
for(cycle=0,cycle<100,cycle++)
var/random_location = locate(rand(37,202),rand(75,192),ZLEVEL_STATION)//Drunk dial a turf in the general ballpark of the station
if(istype(random_location, /turf/simulated/floor))
var/turf/simulated/floor/F = random_location
if(F.air)
var/datum/gas_mixture/A = F.air
if(A.oxygen >= 16 && !A.toxins && A.carbon_dioxide < 10 && !A.trace_gases.len)//Can most things breathe in this location?
if((A.temperature > 270) && (A.temperature < 360))//Not too hot, not too cold
var/pressure = A.return_pressure()
if((pressure > 20) && (pressure < 550))//Account for crushing pressure or vaccuums
if(ishuman(target))//If we're getting rid of a human, slap some zipties on them to keep them away from us a little longer
var/obj/item/weapon/restraints/handcuffs/cable/zipties/Z = new /obj/item/weapon/restraints/handcuffs/cable/zipties(src)
var/mob/living/carbon/human/H = target
Z.apply_cuffs(H, src)
do_teleport(target, F, 0)
playsound(src,'sound/effects/sparks4.ogg',50,1)
break
return
/mob/living/simple_animal/hostile/swarmer/proc/DismantleMachine(var/obj/machinery/target)
do_attack_animation(target)
src << "<span class='info'>We begin to dismantle this machine. We will need to be uninterrupted.</span>"
new /obj/effect/effect/sparks(get_turf(target))
if(do_mob(src, target, 100))
src << "<span class='info'>Dismantling complete.</span>"
var/obj/item/stack/sheet/metal/M = new /obj/item/stack/sheet/metal(target.loc)
M.amount = 5
for(var/obj/item/I in target.component_parts)
I.loc = M.loc
new /obj/effect/effect/sparks(get_turf(target))
target.dropContents()
if(istype(target, /obj/machinery/computer))
var/obj/machinery/computer/C = target
if(C.circuit)
C.circuit.loc = M.loc
qdel(target)
/obj/effect/swarmer //Default destroyable object for swarmer constructions
name = "swarmer construction"
desc = "Debug swarmer item, this shouldn't be here. Yell at a coder."
gender = NEUTER
icon = 'icons/mob/swarmer.dmi'
icon_state = "ui_light"
luminosity = 1
var/health = 30
/obj/effect/swarmer/proc/TakeDamage(damage)
health -= damage
if(health <= 0)
qdel(src)
/obj/effect/swarmer/bullet_act(obj/item/projectile/Proj)
if(Proj.damage)
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
TakeDamage(Proj.damage)
..()
/obj/effect/swarmer/attackby(obj/item/weapon/I, mob/living/user, params)
if(istype(I, /obj/item/weapon))
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
TakeDamage(I.force)
return
/obj/effect/swarmer/ex_act()
qdel(src)
return
/obj/effect/swarmer/blob_act()
qdel(src)
return
/obj/effect/swarmer/attack_animal(mob/living/user)
if(isanimal(user))
var/mob/living/simple_animal/S = user
S.do_attack_animation(src)
user.changeNext_move(CLICK_CD_MELEE)
if(S.melee_damage_type == BRUTE || S.melee_damage_type == BURN)
TakeDamage(rand(S.melee_damage_lower, S.melee_damage_upper))
return
/mob/living/simple_animal/hostile/swarmer/proc/CreateTrap()
set name = "Create trap"
set category = "Swarmer"
set desc = "Creates a simple trap that will non-lethally electrocute anything that steps on it. Costs 5 resources"
if(/obj/effect/swarmer/trap in loc)
src << "<span class='warning'>There is already a trap here. Aborting.</span>"
return
Fabricate(/obj/effect/swarmer/trap, 5)
return
/obj/effect/swarmer/trap
name = "swarmer trap"
desc = "A quickly assembled electric trap. Will not retain its form if damaged enough."
icon_state = "trap"
luminosity = 1
health = 10
/obj/effect/swarmer/trap/Crossed(var/atom/movable/AM)
if(isliving(AM))
var/mob/living/L = AM
if(!istype(L, /mob/living/simple_animal/hostile/swarmer))
L.electrocute_act(0, src, 1, 1)
qdel(src)
..()
/mob/living/simple_animal/hostile/swarmer/proc/CreateBarricade()
set name = "Create barricade"
set category = "Swarmer"
set desc = "Creates a barricade that will stop anything but swarmers and disabler beams from passing through."
if(/obj/effect/swarmer/blockade in loc)
src << "<span class='warning'>There is already a blockade here. Aborting.</span>"
return
Fabricate(/obj/effect/swarmer/blockade, 5)
return
/obj/effect/swarmer/blockade
name = "swarmer blockade"
desc = "A quickly assembled energy blockade. Will not retain its form if damaged enough, but disabler beams and swarmers pass right through."
icon_state = "barricade"
luminosity = 1
health = 50
density = 1
anchored = 1
/obj/effect/swarmer/blockade/CanPass(atom/movable/O)
if(isswarmer(O))
return 1
if(istype(O, /obj/item/projectile/beam/disabler))
return 1
/mob/living/simple_animal/hostile/swarmer/proc/CreateSwarmer()
set name = "Replicate"
set category = "Swarmer"
set desc = "Creates a shell for a new swarmer. Swarmers will self activate."
src << "<span class='info'>We are attempting to replicate ourselves. We will need to stand still until the process is complete.</span>"
if(resources < 50)
src << "<span class='warning'>We do not have the resources for this!</span>"
return
if(!isturf(loc))
src << "<span class='warning'>This is not a suitable location for replicating ourselves. We need more room.</span>"
return
if(do_mob(src, src, 100))
if(Fabricate(/obj/item/unactivated_swarmer, 50))
playsound(loc,'sound/items/poster_being_created.ogg',50, 1, -1)
/mob/living/simple_animal/hostile/swarmer/proc/RepairSelf()
set name = "Self Repair"
set category = "Swarmer"
set desc = "Attempts to repair damage to our body. You will have to remain motionless until repairs are complete."
if(!isturf(loc))
return
src << "<span class='info'>Attempting to repair damage to our body, stand by...</span>"
if(do_mob(src, src, 100))
adjustBruteLoss(-100)
src << "<span class='info'>We successfully repaired ourselves.</span>"
/mob/living/simple_animal/hostile/swarmer/proc/ToggleLight()
if(!luminosity)
SetLuminosity(3)
else
SetLuminosity(0)
/mob/living/simple_animal/hostile/swarmer/proc/ContactSwarmers()
var/message = input(src, "Announce to other swarmers", "Swarmer contact")
if(message)
for(var/mob/M in mob_list)
if(isswarmer(M) || (M in dead_mob_list))
M << "<B>Swarm communication - </b> [src] states: [message]"
////HUD NONSENSE////
/obj/screen/swarmer
icon = 'icons/mob/swarmer.dmi'
/obj/screen/swarmer/FabricateTrap
icon_state = "ui_trap"
name = "Create trap"
desc = "Creates a trap that will nonlethally shock any non-swarmer that attempts to cross it. (Costs 5 resources)"
/obj/screen/swarmer/FabricateTrap/Click()
if(isswarmer(usr))
var/mob/living/simple_animal/hostile/swarmer/S = usr
S.CreateTrap()
/obj/screen/swarmer/Barricade
icon_state = "ui_barricade"
name = "Create barricade"
desc = "Creates a destructible barricade that will stop any non swarmer from passing it. Also allows disabler beams to pass through. (Costs 5 resources)"
/obj/screen/swarmer/Barricade/Click()
if(isswarmer(usr))
var/mob/living/simple_animal/hostile/swarmer/S = usr
S.CreateBarricade()
/obj/screen/swarmer/Replicate
icon_state = "ui_replicate"
name = "Replicate"
desc = "Creates a another of our kind. (Costs 50 resources)"
/obj/screen/swarmer/Replicate/Click()
if(isswarmer(usr))
var/mob/living/simple_animal/hostile/swarmer/S = usr
S.CreateSwarmer()
/obj/screen/swarmer/RepairSelf
icon_state = "ui_self_repair"
name = "Repair self"
desc = "Repairs damage to our body."
/obj/screen/swarmer/RepairSelf/Click()
if(isswarmer(usr))
var/mob/living/simple_animal/hostile/swarmer/S = usr
S.RepairSelf()
/obj/screen/swarmer/ToggleLight
icon_state = "ui_light"
name = "Toggle light"
desc = "Toggles our inbuilt light on or off."
/obj/screen/swarmer/ToggleLight/Click()
if(isswarmer(usr))
var/mob/living/simple_animal/hostile/swarmer/S = usr
S.ToggleLight()
/obj/screen/swarmer/ContactSwarmers
icon_state = "ui_contact_swarmers"
name = "Contact swarmers"
desc = "Sends a message to all other swarmers, should they exist."
/obj/screen/swarmer/ContactSwarmers/Click()
if(isswarmer(usr))
var/mob/living/simple_animal/hostile/swarmer/S = usr
S.ContactSwarmers()
/datum/hud/proc/swarmer_hud(ui_style = 'icons/mob/screen_midnight.dmi')
adding = list()
var/obj/screen/using
using = new /obj/screen/swarmer/FabricateTrap()
using.screen_loc = ui_rhand
adding += using
using = new /obj/screen/swarmer/Barricade()
using.screen_loc = ui_lhand
adding += using
using = new /obj/screen/swarmer/Replicate()
using.screen_loc = ui_zonesel
adding += using
using = new /obj/screen/swarmer/RepairSelf()
using.screen_loc = ui_storage1
adding += using
using = new /obj/screen/swarmer/ToggleLight()
using.screen_loc = ui_back
adding += using
using = new /obj/screen/swarmer/ContactSwarmers()
using.screen_loc = ui_inventory
adding += using
mymob.client.screen = list()
mymob.client.screen += mymob.client.void
mymob.client.screen += adding
@@ -16,6 +16,7 @@
attack_sound = 'sound/weapons/punch1.ogg'
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
healable = 0
faction = list("cult")
flying = 1
unique_name = 1
@@ -24,6 +24,7 @@
wander = 0
speed = 0
ventcrawler = 2
healable = 0
density = 0
pass_flags = PASSTABLE | PASSMOB
sight = (SEE_TURFS | SEE_OBJS)
@@ -11,6 +11,7 @@
icon_dead = "basic"
health = 15
maxHealth = 15
healable = 0
melee_damage_lower = 2
melee_damage_upper = 3
attacktext = "claws"
@@ -16,6 +16,7 @@
speed = -1
maxHealth = 50000
health = 50000
healable = 0
harm_intent_damage = 70
melee_damage_lower = 68
@@ -20,6 +20,7 @@
minbodytemp = 0
maxHealth = 150
health = 150
healable = 0
environment_smash = 1
melee_damage_lower = 20
melee_damage_upper = 20
@@ -12,6 +12,7 @@
invisibility = INVISIBILITY_OBSERVER
health = 25
maxHealth = 25
healable = 0
see_invisible = SEE_INVISIBLE_OBSERVER
languages = ALL
response_help = "passes through"
@@ -7,6 +7,7 @@
icon_living = "shade"
maxHealth = 50
health = 50
healable = 0
speak_emote = list("hisses")
emote_hear = list("wails.","screeches.")
response_help = "puts their hand through"
@@ -34,6 +34,9 @@
var/minbodytemp = 250
var/maxbodytemp = 350
//Healable by medical stacks? Defaults to yes.
var/healable = 1
//Atmos effect - Yes, you can make creatures that require plasma or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage
var/list/atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) //Leaving something at 0 means it's off - has no maximum
var/unsuitable_atmos_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
@@ -41,6 +44,8 @@
//LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly
var/melee_damage_lower = 0
var/melee_damage_upper = 0
var/melee_damage_type = BRUTE //Damage type of a simple mob's melee attack, should it do damage.
var/list/ignored_damage_types = list(BRUTE = 0, BURN = 0, TOX = 0, CLONE = 0, STAMINA = 1, OXY = 0) //Set 0 to receive that damage type, 1 to ignore
var/attacktext = "attacks"
var/attack_sound = null
var/friendly = "nuzzles" //If the mob does no damage with it's attack
@@ -253,7 +258,7 @@
/mob/living/simple_animal/attack_animal(mob/living/simple_animal/M)
if(..())
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
attack_threshold_check(damage)
attack_threshold_check(damage,M.melee_damage_type)
return 1
/mob/living/simple_animal/bullet_act(obj/item/projectile/Proj)
@@ -263,8 +268,21 @@
Proj.on_hit(src)
return 0
/mob/living/simple_animal/adjustBruteLoss(amount)
if(!ignored_damage_types[BRUTE])
..()
/mob/living/simple_animal/adjustFireLoss(amount)
adjustBruteLoss(amount)
if(!ignored_damage_types[BURN])
adjustBruteLoss(amount)
/mob/living/simple_animal/adjustToxLoss(amount)
if(!ignored_damage_types[TOX])
..(amount)
/mob/living/simple_animal/adjustCloneLoss(amount)
if(!ignored_damage_types[CLONE])
..(amount)
/mob/living/simple_animal/adjustStaminaLoss(amount)
return
@@ -334,8 +352,8 @@
attack_threshold_check(damage)
return 1
/mob/living/simple_animal/proc/attack_threshold_check(damage)
if(damage <= force_threshold)
/mob/living/simple_animal/proc/attack_threshold_check(damage, damagetype = BRUTE)
if(damage <= force_threshold || ignored_damage_types[damagetype])
visible_message("<span class='warning'>[src] looks unharmed.</span>")
else
adjustBruteLoss(damage)
@@ -346,29 +364,6 @@
if(O.flags & NOBLUDGEON)
return
if(istype(O, /obj/item/stack/medical))
user.changeNext_move(CLICK_CD_MELEE)
if(stat != DEAD)
var/obj/item/stack/medical/MED = O
if(health < maxHealth)
if(MED.amount >= 1)
if(MED.heal_brute >= 1)
adjustBruteLoss(-MED.heal_brute)
MED.amount -= 1
if(MED.amount <= 0)
qdel(MED)
visible_message("<span class='notice'>[user] applies [MED] on [src].</span>")
return
else
user << "<span class='notice'>[MED] won't help at all.</span>"
return
else
user << "<span class='notice'>[src] is at full health.</span>"
return
else
user << "<span class='notice'>[src] is dead, medical items won't bring it back to life.</span>"
return
if((butcher_results) && (stat == DEAD))
user.changeNext_move(CLICK_CD_MELEE)
var/sharpness = is_sharp(O)
@@ -23,6 +23,7 @@
attacktext = "wildly tears into"
maxHealth = 200
health = 200
healable = 0
environment_smash = 1
melee_damage_lower = 30
melee_damage_upper = 30
@@ -24,6 +24,7 @@
maxHealth = 150
health = 150
healable = 0
gender = NEUTER
nutrition = 700
+5
View File
@@ -125,6 +125,11 @@
return 1
return 0
/proc/isswarmer(A)
if(istype(A, /mob/living/simple_animal/hostile/swarmer))
return 1
return 0
/proc/islimb(A)
if(istype(A, /obj/item/organ/limb))
return 1
+9 -16
View File
@@ -153,11 +153,12 @@
if(occupier)
malfvacate(1)
qdel(wires)
wires = null
if(cell)
qdel(cell)
if(terminal)
disconnect_terminal()
..()
return ..()
/obj/machinery/power/apc/proc/make_terminal()
// create a terminal object at the same position as original turf loc
@@ -398,7 +399,7 @@
user.visible_message(\
"[user.name] has removed the power control board from [src.name]!",\
"<span class='notice'>You remove the power control board.</span>")
new /obj/item/weapon/module/power_control(loc)
new /obj/item/weapon/electronics/apc(loc)
else if (opened!=2) //cover isn't removed
opened = 0
update_icon()
@@ -496,7 +497,7 @@
else if (istype(W, /obj/item/weapon/wirecutters) && terminal && opened && has_electronics!=2)
terminal.dismantle(user)
else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && !((stat & BROKEN) || malfhack))
else if (istype(W, /obj/item/weapon/electronics/apc) && opened && has_electronics==0 && !((stat & BROKEN) || malfhack))
user.visible_message("[user.name] inserts the power control board into [src].", \
"<span class='notice'>You start to insert the power control board into the frame...</span>")
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
@@ -505,7 +506,7 @@
has_electronics = 1
user << "<span class='notice'>You place the power control board inside the frame.</span>"
qdel(W)
else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && ((stat & BROKEN) || malfhack))
else if (istype(W, /obj/item/weapon/electronics/apc) && opened && has_electronics==0 && ((stat & BROKEN) || malfhack))
user << "<span class='warning'>You cannot put the board inside, the frame is damaged!</span>"
return
else if (istype(W, /obj/item/weapon/weldingtool) && opened && has_electronics==0 && !terminal)
@@ -525,13 +526,13 @@
"[user.name] has cut [src] apart with [W].",\
"<span class='notice'>You disassembled the broken APC frame.</span>")
else
new /obj/item/apc_frame(loc)
new /obj/item/wallframe/apc(loc)
user.visible_message(\
"[user.name] has cut [src] from the wall with [W].",\
"<span class='notice'>You cut the APC frame from the wall.</span>")
qdel(src)
return
else if (istype(W, /obj/item/apc_frame) && opened && emagged)
else if (istype(W, /obj/item/wallframe/apc) && opened && emagged)
emagged = 0
if (opened==2)
opened = 1
@@ -540,7 +541,7 @@
"<span class='notice'>You replace the damaged APC frontal panel with a new one.</span>")
qdel(W)
update_icon()
else if (istype(W, /obj/item/apc_frame) && opened && ((stat & BROKEN) || malfhack))
else if (istype(W, /obj/item/wallframe/apc) && opened && ((stat & BROKEN) || malfhack))
if (has_electronics)
user << "<span class='warning'>You cannot repair this APC until you remove the electronics still inside!</span>"
return
@@ -1232,15 +1233,7 @@
#undef APC_UPDATE_ICON_COOLDOWN
/*Power module, used for APC construction*/
/obj/item/weapon/module
icon = 'icons/obj/module.dmi'
icon_state = "std_module"
w_class = 2.0
item_state = "electronic"
flags = CONDUCT
/obj/item/weapon/module/power_control
/obj/item/weapon/electronics/apc
name = "power control module"
icon_state = "power_mod"
desc = "Heavy-duty switching circuits for power control."
+10 -56
View File
@@ -11,61 +11,20 @@
/obj/item/light_fixture_frame
/obj/item/wallframe/light_fixture
name = "light fixture frame"
desc = "Used for building lights."
icon = 'icons/obj/lighting.dmi'
icon_state = "tube-construct-item"
flags = CONDUCT
var/fixture_type = "tube"
var/obj/machinery/light/newlight = null
var/sheets_refunded = 2
result_path = /obj/machinery/light_construct
inverse = 1
/obj/item/light_fixture_frame/attackby(obj/item/weapon/W, mob/user, params)
if (istype(W, /obj/item/weapon/wrench))
new /obj/item/stack/sheet/metal( get_turf(src.loc), sheets_refunded )
qdel(src)
return
..()
/obj/item/light_fixture_frame/proc/try_build(turf/on_wall)
if (get_dist(on_wall,usr)>1)
return
var/ndir = get_dir(usr,on_wall)
if (!(ndir in cardinal))
return
var/turf/loc = get_turf(usr)
if (!istype(loc, /turf/simulated/floor))
usr << "<span class='warning'>[src.name] cannot be placed on this spot!</span>"
return
usr << "<span class='notice'>You begin attaching [src] to the wall...</span>"
playsound(src.loc, 'sound/machines/click.ogg', 75, 1)
var/constrdir = usr.dir
var/constrloc = usr.loc
if (!do_after(usr, 30, target = src))
return
switch(fixture_type)
if("bulb")
newlight = new /obj/machinery/light_construct/small(constrloc)
if("tube")
newlight = new /obj/machinery/light_construct(constrloc)
newlight.dir = constrdir
newlight.fingerprints = src.fingerprints
newlight.fingerprintshidden = src.fingerprintshidden
newlight.fingerprintslast = src.fingerprintslast
usr.visible_message("[usr.name] attaches [src] to the wall.", \
"<span class='notice'>You attach [src] to the wall.</span>")
qdel(src)
/obj/item/light_fixture_frame/small
/obj/item/wallframe/light_fixture/small
name = "small light fixture frame"
desc = "Used for building small lights."
icon = 'icons/obj/lighting.dmi'
icon_state = "bulb-construct-item"
flags = CONDUCT
fixture_type = "bulb"
sheets_refunded = 1
result_path = /obj/machinery/light_construct/small
materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT)
/obj/machinery/light_construct
name = "light fixture frame"
@@ -79,10 +38,10 @@
var/sheets_refunded = 2
var/obj/machinery/light/newlight = null
/obj/machinery/light_construct/New()
/obj/machinery/light_construct/New(loc, ndir, building)
..()
if (fixture_type == "bulb")
icon_state = "bulb-construct-stage1"
if(building)
dir = ndir
/obj/machinery/light_construct/examine(mob/user)
..()
@@ -172,12 +131,7 @@
/obj/machinery/light_construct/small
name = "small light fixture frame"
desc = "A small light fixture under construction."
icon = 'icons/obj/lighting.dmi'
icon_state = "bulb-construct-stage1"
anchored = 1
layer = 5
stage = 1
fixture_type = "bulb"
sheets_refunded = 1
+2 -1
View File
@@ -181,7 +181,8 @@
user << "<span class='warning'>Turn off \the [src] first!</span>"
return
switch(state)
if(0 && !isinspace())
if(0)
if(isinspace()) return
state = 1
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
user.visible_message("[user.name] secures [src.name] to the floor.", \
@@ -100,7 +100,8 @@ field_generator power level display
return
else if(istype(W, /obj/item/weapon/wrench))
switch(state)
if(0 && !isinspace())
if(0)
if(isinspace()) return
state = 1
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
user.visible_message("[user.name] secures [src.name] to the floor.", \
@@ -29,7 +29,9 @@
/obj/machinery/particle_accelerator/control_box/Destroy()
if(active)
toggle_power()
..()
qdel(wires)
wires = null
return ..()
/obj/machinery/particle_accelerator/control_box/attack_hand(mob/user)
if(construction_state >= 3)
+2 -2
View File
@@ -255,7 +255,7 @@
return 1
if(!tracker)
if(istype(W, /obj/item/weapon/tracker_electronics))
if(istype(W, /obj/item/weapon/electronics/tracker))
if(!user.drop_item())
return
tracker = 1
@@ -264,7 +264,7 @@
return 1
else
if(istype(W, /obj/item/weapon/crowbar))
new /obj/item/weapon/tracker_electronics(src.loc)
new /obj/item/weapon/electronics/tracker(src.loc)
tracker = 0
user.visible_message("[user] takes out the electronics from the solar assembly.", "<span class='notice'>You take out the electronics from the solar assembly.</span>")
return 1
+2 -6
View File
@@ -76,9 +76,5 @@
// Tracker Electronic
/obj/item/weapon/tracker_electronics
name = "tracker electronics"
icon = 'icons/obj/doors/door_assembly.dmi'
icon_state = "door_electronics"
w_class = 2.0
/obj/item/weapon/electronics/tracker
name = "tracker electronics"
-9
View File
@@ -208,15 +208,6 @@
if(!compressor)
stat |= BROKEN
// THIS MAKES IT WORK!!!!!
// OLD FIX . Dunno how other engines handle this but this is how it should work: Turbine and compressor should be
// treated as walls to avoid conductivity and gas spread. This was the problem of the original turbine which was just
// a machinery - it didn't block the gas passage.
// /obj/machinery/power/turbine/CanPass(atom/movable/mover, turf/target, height=0)
// return !density
/obj/machinery/power/turbine/RefreshParts()
var/P = 0
for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
+1 -10
View File
@@ -4,10 +4,6 @@
#define REM REAGENTS_EFFECT_MULTIPLIER
//The reaction procs must ALWAYS set src = null, this detaches the proc from the object (the reagent)
//so that it can continue working when the reagent is deleted while the proc is still active.
//Various reagents
//Toxin & acid reagents
//Hydroponics stuff
@@ -37,23 +33,18 @@
/datum/reagent/proc/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
if(!istype(M))
return 0
var/datum/reagent/self = src
src = null
if(method == VAPOR) //smoke, foam, spray
if(M.reagents)
var/modifier = Clamp((1 - touch_protection), 0, 1)
var/amount = round(volume*modifier, 0.1)
if(amount >= 1)
M.reagents.add_reagent(self.id, amount)
M.reagents.add_reagent(id, amount)
return 1
/datum/reagent/proc/reaction_obj(obj/O, volume)
src = null
return
/datum/reagent/proc/reaction_turf(turf/T, volume)
src = null
return
/datum/reagent/proc/on_mob_life(mob/living/M)
@@ -324,7 +324,6 @@
/datum/reagent/consumable/cornoil/reaction_turf(turf/simulated/T, reac_volume)
if (!istype(T))
return
src = null
if(reac_volume >= 3)
T.MakeSlippery()
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
@@ -381,7 +380,6 @@
color = "#FFFFFF" // rgb: 0, 0, 0
/datum/reagent/consumable/flour/reaction_turf(turf/T, reac_volume)
src = null
if(!istype(T, /turf/space))
var/obj/effect/decal/cleanable/reagentdecal = new/obj/effect/decal/cleanable/flour(T)
reagentdecal.reagents.add_reagent("flour", reac_volume)
@@ -173,13 +173,36 @@
if(method == INGEST)
M.adjustToxLoss(0.5*reac_volume)
if(show_message)
M << "<span class='notice'>You probably shouldn't have eaten that. Maybe you should of splashed it on, or applied a patch?</span>"
M << "<span class='notice'>You probably shouldn't have eaten that. Maybe you should have splashed it on, or applied a patch?</span>"
..()
/datum/reagent/medicine/silver_sulfadiazine/on_mob_life(mob/living/M)
M.adjustFireLoss(-2*REM)
..()
/datum/reagent/medicine/oxandrolone
name = "Oxandrolone"
id = "oxandrolone"
description = "Stimulates healing of severe burns. If you have more than 50 burn damage, it heals 2 units; otherwise, 0.5. If overdosed it will exacerbate existing burns, causing burn and brute damage."
reagent_state = LIQUID
color = "#f7ffa5"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
overdose_threshold = 25
/datum/reagent/medicine/oxandrolone/on_mob_life(mob/living/M)
if(M.getFireLoss() > 50)
M.adjustFireLoss(-2*REM)
else
M.adjustFireLoss(-0.5*REM)
..()
return
/datum/reagent/medicine/oxandrolone/overdose_process(mob/living/M)
M.adjustFireLoss(2.5*REM) // it's going to be healing either 2 or 0.5
M.adjustBruteLoss(0.5*REM)
..()
return
/datum/reagent/medicine/styptic_powder
name = "Styptic Powder"
id = "styptic_powder"
@@ -6,10 +6,8 @@
color = "#C80000" // rgb: 200, 0, 0
/datum/reagent/blood/reaction_mob(mob/M, method=TOUCH, reac_volume)
var/datum/reagent/blood/self = src
src = null
if(self.data && self.data["viruses"])
for(var/datum/disease/D in self.data["viruses"])
if(data && data["viruses"])
for(var/datum/disease/D in data["viruses"])
if(D.spread_flags & SPECIAL || D.spread_flags & NON_CONTAGIOUS)
continue
@@ -28,7 +26,7 @@
src.data["cloneable"] = 0 //On mix, consider the genetic sampling unviable for pod cloning, or else we won't know who's even getting cloned, etc
if(src.data["viruses"] || data["viruses"])
var/list/mix1 = src.data["viruses"]
var/list/mix1 = data["viruses"]
var/list/mix2 = data["viruses"]
// Stop issues with the list changing during mixing.
@@ -51,39 +49,36 @@
/datum/reagent/blood/reaction_turf(turf/simulated/T, reac_volume)//splash the blood all over the place
if(!istype(T))
return
var/datum/reagent/blood/self = src
src = null
if(reac_volume < 3)
return
//var/datum/disease/D = self.data["virus"]
if(!self.data["donor"] || istype(self.data["donor"], /mob/living/carbon/human))
if(!data["donor"] || istype(data["donor"], /mob/living/carbon/human))
var/obj/effect/decal/cleanable/blood/blood_prop = locate() in T //find some blood here
if(!blood_prop) //first blood!
blood_prop = new(T)
blood_prop.blood_DNA[self.data["blood_DNA"]] = self.data["blood_type"]
blood_prop.blood_DNA[data["blood_DNA"]] = data["blood_type"]
for(var/datum/disease/D in self.data["viruses"])
for(var/datum/disease/D in data["viruses"])
var/datum/disease/newVirus = D.Copy(1)
blood_prop.viruses += newVirus
newVirus.holder = blood_prop
else if(istype(self.data["donor"], /mob/living/carbon/monkey))
else if(istype(data["donor"], /mob/living/carbon/monkey))
var/obj/effect/decal/cleanable/blood/blood_prop = locate() in T
if(!blood_prop)
blood_prop = new(T)
blood_prop.blood_DNA["Non-Human DNA"] = "A+"
for(var/datum/disease/D in self.data["viruses"])
for(var/datum/disease/D in data["viruses"])
var/datum/disease/newVirus = D.Copy(1)
blood_prop.viruses += newVirus
newVirus.holder = blood_prop
else if(istype(self.data["donor"], /mob/living/carbon/alien))
else if(istype(data["donor"], /mob/living/carbon/alien))
var/obj/effect/decal/cleanable/xenoblood/blood_prop = locate() in T
if(!blood_prop)
blood_prop = new(T)
blood_prop.blood_DNA["UNKNOWN DNA STRUCTURE"] = "X*"
for(var/datum/disease/D in self.data["viruses"])
for(var/datum/disease/D in data["viruses"])
var/datum/disease/newVirus = D.Copy(1)
blood_prop.viruses += newVirus
newVirus.holder = blood_prop
@@ -96,13 +91,11 @@
color = "#C81040" // rgb: 200, 16, 64
/datum/reagent/vaccine/reaction_mob(mob/M, method=TOUCH, reac_volume)
var/datum/reagent/vaccine/self = src
src = null
if(islist(self.data) && method == INGEST)
if(islist(data) && method == INGEST)
for(var/datum/disease/D in M.viruses)
if(D.GetDiseaseID() in self.data)
if(D.GetDiseaseID() in data)
D.cure()
M.resistances |= self.data
M.resistances |= data
/datum/reagent/vaccine/on_merge(list/data)
if(istype(data))
@@ -122,7 +115,6 @@
/datum/reagent/water/reaction_turf(turf/simulated/T, reac_volume)
if (!istype(T)) return
var/CT = cooling_temperature
src = null
if(reac_volume >= 10)
T.MakeSlippery()
@@ -143,8 +135,6 @@
*/
/datum/reagent/water/reaction_obj(obj/O, reac_volume)
src = null
if(istype(O,/obj/item))
var/obj/item/Item = O
Item.extinguish()
@@ -250,7 +240,6 @@
/datum/reagent/lube/reaction_turf(turf/simulated/T, reac_volume)
if (!istype(T)) return
src = null
if(reac_volume >= 1)
T.MakeSlippery(2)
@@ -384,7 +373,6 @@
color = "#13BC5E" // rgb: 19, 188, 94
/datum/reagent/aslimetoxin/reaction_mob(mob/M, method=TOUCH, reac_volume)
src = null
if(method != TOUCH)
M.ForceContractDisease(new /datum/disease/transformation/slime(0))
@@ -466,7 +454,6 @@
color = "#1C1300" // rgb: 30, 20, 0
/datum/reagent/carbon/reaction_turf(turf/T, reac_volume)
src = null
if(!istype(T, /turf/space))
new /obj/effect/decal/cleanable/dirt(T)
@@ -542,7 +529,6 @@
return
/datum/reagent/radium/reaction_turf(turf/T, reac_volume)
src = null
if(reac_volume >= 3)
if(!istype(T, /turf/space))
var/obj/effect/decal/cleanable/reagentdecal = new/obj/effect/decal/cleanable/greenglow(T)
@@ -587,7 +573,6 @@
..()
/datum/reagent/uranium/reaction_turf(turf/T, reac_volume)
src = null
if(reac_volume >= 3)
if(!istype(T, /turf/space))
var/obj/effect/decal/cleanable/reagentdecal = new/obj/effect/decal/cleanable/greenglow(T)
@@ -715,7 +700,6 @@
color = "#535E66" // rgb: 83, 94, 102
/datum/reagent/nanites/reaction_mob(mob/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
src = null
if(method==PATCH || method==INGEST || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection))))
M.ForceContractDisease(new /datum/disease/transformation/robot(0))
@@ -726,7 +710,6 @@
color = "#535E66" // rgb: 83, 94, 102
/datum/reagent/xenomicrobes/reaction_mob(mob/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
src = null
if(method==PATCH || method==INGEST || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection))))
M.ContractDisease(new /datum/disease/transformation/xeno(0))
@@ -7,7 +7,6 @@
color = "#673910" // rgb: 103, 57, 16
/datum/reagent/thermite/reaction_turf(turf/T, reac_volume)
src = null
if(reac_volume >= 1 && istype(T, /turf/simulated/wall))
var/turf/simulated/wall/Wall = T
if(istype(Wall, /turf/simulated/wall/r_wall))
@@ -33,7 +33,6 @@
return
if(!istype(M) || !M.dna)
return //No robots, AIs, aliens, Ians or other mobs should be affected by this.
src = null
if((method==VAPOR && prob(min(33, reac_volume))) || method==INGEST || method == PATCH)
randmuti(M)
if(prob(98))
@@ -66,12 +65,11 @@
return
/datum/reagent/toxin/plasma/reaction_obj(obj/O, reac_volume)
src = null
if((!O) || (!reac_volume)) return 0
if((!O) || (!reac_volume))
return 0
O.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C, reac_volume)
/datum/reagent/toxin/plasma/reaction_turf(turf/simulated/T, reac_volume)
src = null
if(istype(T))
T.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C, reac_volume)
return
@@ -189,7 +187,6 @@
SV.on_chem_effect(src)
/datum/reagent/toxin/plantbgone/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
src = null
if(method == VAPOR)
if(iscarbon(M))
var/mob/living/carbon/C = M
@@ -212,7 +209,6 @@
toxpwr = 1
/datum/reagent/toxin/pestkiller/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
src = null
if(method == VAPOR)
if(iscarbon(M))
var/mob/living/carbon/C = M
@@ -639,7 +635,6 @@
/datum/reagent/toxin/acid/reaction_turf(turf/T, reac_volume)
if (!istype(T))
return
src = null
reac_volume = round(reac_volume,0.1)
for(var/obj/O in T)
O.acid_act(acidpwr, reac_volume)
@@ -116,6 +116,12 @@
required_reagents = list("sodium" = 1, "phenol" = 1, "carbon" = 1, "oxygen" = 1, "sacid" = 1)
result_amount = 5
/datum/chemical_reaction/oxandrolone
name = "Oxandrolone"
id = "oxandrolone"
result = "oxandrolone"
required_reagents = list("carbon" = 3, "phenol" = 1, "hydrogen" = 1, "oxygen" = 1)
result_amount = 6
/datum/chemical_reaction/salbutamol
name = "Salbutamol"
@@ -246,7 +246,7 @@
/datum/chemical_reaction/slimestabilizer/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/weapon/slimestabilizer/P = new /obj/item/weapon/slimestabilizer
var/obj/item/slimepotion/stabilizer/P = new /obj/item/slimepotion/stabilizer
P.loc = get_turf(holder.my_atom)
@@ -363,7 +363,7 @@
/datum/chemical_reaction/slimepsteroid/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/weapon/slimesteroid/P = new /obj/item/weapon/slimesteroid
var/obj/item/slimepotion/steroid/P = new /obj/item/slimepotion/steroid
P.loc = get_turf(holder.my_atom)
/datum/chemical_reaction/slimejam
@@ -406,7 +406,7 @@
/datum/chemical_reaction/slimemutator/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/weapon/slimemutator/P = new /obj/item/weapon/slimemutator
var/obj/item/slimepotion/mutator/P = new /obj/item/slimepotion/mutator
P.loc = get_turf(holder.my_atom)
/datum/chemical_reaction/slimebloodlust
@@ -484,7 +484,7 @@
/datum/chemical_reaction/slimepotion2/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/slimepotion2/P = new /obj/item/slimepotion2
var/obj/item/slimepotion/sentience/P = new /obj/item/slimepotion/sentience
P.loc = get_turf(holder.my_atom)
//Adamantine
@@ -547,7 +547,7 @@
/datum/chemical_reaction/slimepsteroid2/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/weapon/slimesteroid2/P = new /obj/item/weapon/slimesteroid2
var/obj/item/slimepotion/enhancer/P = new /obj/item/slimepotion/enhancer
P.loc = get_turf(holder.my_atom)
//Sepia
@@ -133,6 +133,12 @@
icon_state = "pill5"
list_reagents = list("sal_acid" = 24)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/oxandrolone
name = "oxandrolone pill"
desc = "Used to stimulate burn healing."
icon_state = "pill5"
list_reagents = list("oxandrolone" = 24)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/insulin
name = "insulin pill"
@@ -111,7 +111,7 @@
id = "power control"
build_type = AUTOLATHE
materials = list(MAT_METAL = 100, MAT_GLASS = 100)
build_path = /obj/item/weapon/module/power_control
build_path = /obj/item/weapon/electronics/apc
category = list("initial", "Electronics")
/datum/design/airlock_board
@@ -119,7 +119,7 @@
id = "airlock_board"
build_type = AUTOLATHE
materials = list(MAT_METAL = 50, MAT_GLASS = 50)
build_path = /obj/item/weapon/airlock_electronics
build_path = /obj/item/weapon/electronics/airlock
category = list("initial", "Electronics")
/datum/design/firelock_board
@@ -127,7 +127,7 @@
id = "firelock_board"
build_type = AUTOLATHE
materials = list(MAT_METAL = 50, MAT_GLASS = 50)
build_path = /obj/item/weapon/firelock_board
build_path = /obj/item/weapon/electronics/firelock
category = list("initial", "Electronics")
/datum/design/airalarm_electronics
@@ -135,7 +135,7 @@
id = "airalarm_electronics"
build_type = AUTOLATHE
materials = list(MAT_METAL = 50, MAT_GLASS = 50)
build_path = /obj/item/weapon/airalarm_electronics
build_path = /obj/item/weapon/electronics/airalarm
category = list("initial", "Electronics")
/datum/design/firealarm_electronics
@@ -143,7 +143,7 @@
id = "firealarm_electronics"
build_type = AUTOLATHE
materials = list(MAT_METAL = 50, MAT_GLASS = 50)
build_path = /obj/item/weapon/firealarm_electronics
build_path = /obj/item/weapon/electronics/firealarm
category = list("initial", "Electronics")
/datum/design/pipe_painter
@@ -383,7 +383,7 @@
id = "camera_assembly"
build_type = AUTOLATHE
materials = list(MAT_METAL = 400, MAT_GLASS = 250)
build_path = /obj/item/weapon/camera_assembly
build_path = /obj/item/wallframe/camera
category = list("initial", "Construction")
/datum/design/newscaster_frame
@@ -391,7 +391,7 @@
id = "newscaster_frame"
build_type = AUTOLATHE
materials = list(MAT_METAL = 14000, MAT_GLASS = 8000)
build_path = /obj/item/newscaster_frame
build_path = /obj/item/wallframe/newscaster
category = list("initial", "Construction")
/datum/design/syringe
+2 -1
View File
@@ -703,7 +703,8 @@
R.realProc = realProc
R.revealed = TRUE
dupes |= R
R.throw_at(pick(oview(7,get_turf(src))),10,1)
spawn()
R.throw_at(pick(oview(7,get_turf(src))),10,1)
counter = 0
spawn(rand(10,100))
for(counter = 1; counter <= dupes.len; counter++)
+5
View File
@@ -20,6 +20,11 @@
..()
wires = new(src)
/obj/machinery/r_n_d/Destroy()
qdel(wires)
wires = null
return ..()
/obj/machinery/r_n_d/proc/shock(mob/user, prb)
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
return 0
@@ -11,12 +11,12 @@
throwforce = 0
throw_speed = 3
throw_range = 6
origin_tech = "biotech=4"
origin_tech = "biotech=3"
var/Uses = 1 // uses before it goes inert
var/enhanced = 0 //has it been enhanced before?
/obj/item/slime_extract/attackby(obj/item/O, mob/user)
if(istype(O, /obj/item/weapon/slimesteroid2))
if(istype(O, /obj/item/slimepotion/steroid))
if(enhanced == 1)
user << "<span class='warning'>This extract has already been enhanced!</span>"
return ..()
@@ -120,15 +120,26 @@
name = "rainbow slime extract"
icon_state = "rainbow slime extract"
////Pet Slime Creation///
////Slime-derived potions///
/obj/item/slimepotion
name = "slime potion"
desc = "A hard yet gelatinous capsule excreted by a slime, containing mysterious substances."
w_class = 1
origin_tech = "biotech=4"
/obj/item/slimepotion/afterattack(obj/item/weapon/reagent_containers/target, mob/user , proximity)
if (istype(target))
user << "<span class='notice'>You cannot transfer [src] to [target]! It appears the potion must be given directly to a slime to absorb.</span>" // le fluff faec
return
/obj/item/slimepotion/docility
name = "docility potion"
desc = "A potent chemical mix that nullifies a slime's hunger, causing it to become docile and tame."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle19"
/obj/item/slimepotion/attack(mob/living/simple_animal/slime/M, mob/user)
/obj/item/slimepotion/docility/attack(mob/living/simple_animal/slime/M, mob/user)
if(!isslime(M))
user << "<span class='warning'>The potion only works on slimes!</span>"
return ..()
@@ -139,7 +150,7 @@
M.docile = 1
M.nutrition = 700
M <<"<span class='warning'>You absorb the potion and feel your intense desire to feed melt away.</span>"
user <<"<span class='notice'>You feed the slime the potion, removing it's hunger and calming it.</span>"
user <<"<span class='notice'>You feed the slime the potion, removing its hunger and calming it.</span>"
var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN)
if (!newname)
@@ -148,15 +159,16 @@
M.real_name = newname
qdel(src)
/obj/item/slimepotion2
/obj/item/slimepotion/sentience
name = "sentience potion"
desc = "A miraculous chemical mix that can raise the intelligence of creatures to human levels."
desc = "A miraculous chemical mix that can raise the intelligence of creatures to human levels. Unlike normal slime potions, it can be absorbed by any nonsentient being."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle19"
origin_tech = "biotech=5"
var/list/not_interested = list()
var/being_used = 0
/obj/item/slimepotion2/afterattack(mob/living/M, mob/user)
/obj/item/slimepotion/sentience/afterattack(mob/living/M, mob/user)
if(being_used || !ismob(M))
return
if(!isanimal(M) || M.ckey) //only works on animals that aren't player controlled
@@ -166,7 +178,7 @@
user << "<span class='warning'>[M] is dead!</span>"
return..()
user << "<span class='notice'>You begin to apply the potion to [M]...</span>"
user << "<span class='notice'>You offer the sentience potion to [M]...</span>"
being_used = 1
var/list/candidates = get_candidates(BE_ALIEN, ALIEN_AFK_BRACKET)
@@ -203,26 +215,26 @@
M.key = C.key
M.languages |= HUMAN
M.faction -= "neutral"
M << "<span class='warning'>All at once it makes sense, you know what you are and who you are! Self awareness is yours!</span>"
M << "<span class='warning'>All at once it makes sense: you know what you are and who you are! Self awareness is yours!</span>"
M << "<span class='userdanger'>You are grateful to be self aware and owe [user] a great debt. Serve [user], and assist them in completing their goals at any cost.</span>"
user << "<span class='notice'>[M] is suddenly attentive and aware. It worked!</span>"
user << "<span class='notice'>[M] accepts the potion and suddenly becomes attentive and aware. It worked!</span>"
qdel(src)
else
user << "<span class='notice'>[M] looks interested for a moment, but then looks back down. Maybe you should try again later...</span>"
user << "<span class='notice'>[M] looks interested for a moment, but then looks back down. Maybe you should try again later.</span>"
being_used = 0
..()
/obj/item/weapon/slimesteroid
/obj/item/slimepotion/steroid
name = "slime steroid"
desc = "A potent chemical mix that will cause a slime to generate more extract."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle16"
/obj/item/weapon/slimesteroid/attack(mob/living/simple_animal/slime/M, mob/user)
/obj/item/slimepotion/steroid/attack(mob/living/simple_animal/slime/M, mob/user)
if(!isslime(M))//If target is not a slime.
user << "<span class='warning'>The steroid only works on baby slimes!</span>"
return ..()
if(M.is_adult) //Can't tame adults
if(M.is_adult) //Can't steroidify adults
user << "<span class='warning'>Only baby slimes can use the steroid!</span>"
return..()
if(M.stat)
@@ -236,14 +248,7 @@
M.cores = 3
qdel(src)
/obj/item/weapon/slimesteroid3
name = "slime steroid"
desc = "A potent chemical mix that will cause a slime to generate more extract."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle16"
/obj/item/weapon/slimesteroid2
/obj/item/slimepotion/enhancer
name = "extract enhancer"
desc = "A potent chemical mix that will give a slime extract three uses."
icon = 'icons/obj/chemical.dmi'
@@ -263,13 +268,13 @@
qdel(src)*/
/obj/item/weapon/slimestabilizer
/obj/item/slimepotion/stabilizer
name = "slime stabilizer"
desc = "A potent chemical mix that will reduce the chance of a slime mutating."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle15"
/obj/item/weapon/slimestabilizer/attack(mob/living/simple_animal/slime/M, mob/user)
/obj/item/slimepotion/stabilizer/attack(mob/living/simple_animal/slime/M, mob/user)
if(!isslime(M))
user << "<span class='warning'>The stabilizer only works on slimes!</span>"
return ..()
@@ -284,13 +289,13 @@
M.mutation_chance = Clamp(M.mutation_chance-15,0,100)
qdel(src)
/obj/item/weapon/slimemutator
/obj/item/slimepotion/mutator
name = "slime mutator"
desc = "A potent chemical mix that will increase the chance of a slime mutating."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle3"
/obj/item/weapon/slimemutator/attack(mob/living/simple_animal/slime/M, mob/user)
/obj/item/slimepotion/mutator/attack(mob/living/simple_animal/slime/M, mob/user)
if(!isslime(M))
user << "<span class='warning'>The mutator only works on slimes!</span>"
return ..()