mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 14:39:58 +01:00
Merge branch 'master' of https://github.com/tgstation/-tg-station into ReagentReactionRuntimeFix
Conflicts: code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm icons/obj/assemblies/new_assemblies.dmi
This commit is contained in:
@@ -48,9 +48,13 @@ 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)
|
||||
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
|
||||
@@ -508,9 +512,12 @@ var/global/floorIsLava = 0
|
||||
message_admins("<font color='blue'>[usr.key] has started the game.</font>")
|
||||
feedback_add_details("admin_verb","SN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return 1
|
||||
else if (ticker.current_state == GAME_STATE_STARTUP)
|
||||
usr << "<font color='red'>Error: Start Now: Game is in startup, please wait until it has finished.</font>"
|
||||
else
|
||||
usr << "<font color='red'>Error: Start Now: Game has already started.</font>"
|
||||
return 0
|
||||
|
||||
return 0
|
||||
|
||||
/datum/admins/proc/toggleenter()
|
||||
set category = "Server"
|
||||
@@ -805,3 +812,15 @@ var/global/floorIsLava = 0
|
||||
qdel(frommob)
|
||||
|
||||
return 1
|
||||
|
||||
/client/proc/adminGreet(logout)
|
||||
if(ticker && ticker.current_state == GAME_STATE_PLAYING)
|
||||
var/string
|
||||
if(logout && config && config.announce_admin_logout)
|
||||
string = pick(
|
||||
"Admin logout: [key_name(src)]")
|
||||
else if(!logout && config && config.announce_admin_login && (prefs.toggles & ANNOUNCE_LOGIN))
|
||||
string = pick(
|
||||
"Admin login: [key_name(src)]")
|
||||
if(string)
|
||||
message_admins("[string]")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//admin verb groups - They can overlap if you so wish. Only one of each verb will exist in the verbs list regardless
|
||||
var/list/admin_verbs_default = list(
|
||||
/client/proc/toggleadminhelpsound, /*toggles whether we hear a sound when adminhelps/PMs are used*/
|
||||
/client/proc/toggleannouncelogin, /*toggles if an admin's login is announced during a round*/
|
||||
/client/proc/deadmin_self, /*destroys our own admin datum so we can play as a regular player*/
|
||||
/client/proc/cmd_admin_say, /*admin-only ooc chat*/
|
||||
/client/proc/hide_verbs, /*hides all our adminverbs*/
|
||||
|
||||
@@ -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
@@ -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[3]
|
||||
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
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
|
||||
//Manifolds
|
||||
for (var/obj/machinery/atmospherics/pipe/manifold/pipe in world)
|
||||
if (!pipe.node1 || !pipe.node2 || !pipe.node3)
|
||||
if (!pipe.NODE1 || !pipe.NODE2 || !pipe.NODE3)
|
||||
usr << "Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])"
|
||||
|
||||
//Pipes
|
||||
for (var/obj/machinery/atmospherics/pipe/simple/pipe in world)
|
||||
if (!pipe.node1 || !pipe.node2)
|
||||
if (!pipe.NODE1 || !pipe.NODE2)
|
||||
usr << "Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])"
|
||||
|
||||
/client/proc/powerdebug()
|
||||
|
||||
@@ -120,7 +120,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
/client/proc/get_callproc_args()
|
||||
var/argnum = input("Number of arguments","Number:",0) as num|null
|
||||
if(!argnum && (argnum!=0)) return
|
||||
|
||||
|
||||
var/list/lst = list()
|
||||
//TODO: make a list to store whether each argument was initialised as null.
|
||||
//Reason: So we can abort the proccall if say, one of our arguments was a mob which no longer exists
|
||||
@@ -1100,6 +1100,10 @@ var/global/list/g_fancy_list_of_types = null
|
||||
for(var/path in SSgarbage.didntgc)
|
||||
dat += "[path] - [SSgarbage.didntgc[path]] times<BR>"
|
||||
|
||||
dat += "<B>List of paths that did not return a qdel hint in Destroy()</B><BR><BR>"
|
||||
for(var/path in SSgarbage.noqdelhint)
|
||||
dat += "[path]<BR>"
|
||||
|
||||
usr << browse(dat, "window=dellog")
|
||||
|
||||
|
||||
@@ -1127,7 +1131,7 @@ var/global/list/g_fancy_list_of_types = null
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/box(M), slot_in_backpack)
|
||||
|
||||
M.equip_to_slot_or_del(new /obj/item/ammo_box/a357(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/combat/nanites(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/flashbangs(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/device/flashlight(M), slot_in_backpack)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,"\["))
|
||||
|
||||
@@ -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
|
||||
@@ -51,10 +51,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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,197 @@
|
||||
/obj/item/device/assembly/flash
|
||||
name = "flash"
|
||||
desc = "A powerful and versatile flashbulb device, with applications ranging from disorienting attackers to acting as visual receptors in robot production."
|
||||
icon_state = "flash"
|
||||
item_state = "flashtool"
|
||||
throwforce = 0
|
||||
w_class = 1
|
||||
origin_tech = "magnets=2;combat=1"
|
||||
|
||||
crit_fail = 0 //Is the flash burnt out?
|
||||
var/times_used = 0 //Number of times it's been used.
|
||||
var/last_used = 0 //last world.time it was used.
|
||||
|
||||
|
||||
/obj/item/device/assembly/flash/update_icon(var/flash = 0)
|
||||
overlays.Cut()
|
||||
attached_overlays = list()
|
||||
if(crit_fail)
|
||||
overlays += "flashburnt"
|
||||
attached_overlays += "flashburnt"
|
||||
|
||||
if(flash)
|
||||
overlays += "flash-f"
|
||||
attached_overlays += "flash-f"
|
||||
spawn(5)
|
||||
update_icon()
|
||||
if(holder)
|
||||
holder.update_icon()
|
||||
|
||||
/obj/item/device/assembly/flash/proc/clown_check(mob/living/carbon/human/user)
|
||||
if(user.disabilities & CLUMSY && prob(50))
|
||||
flash_carbon(user, user, 15, 0)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/device/assembly/flash/activate()
|
||||
if(!try_use_flash())
|
||||
return 0
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("<span class='disarm'>[src] emits a blinding light!</span>")
|
||||
for(var/mob/living/carbon/M in viewers(3, null))
|
||||
flash_carbon(M, null, 2, 0)
|
||||
|
||||
|
||||
/obj/item/device/assembly/flash/proc/burn_out() //Made so you can override it if you want to have an invincible flash from R&D or something.
|
||||
crit_fail = 1
|
||||
update_icon()
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("The [src.name] burns out!")
|
||||
|
||||
|
||||
/obj/item/device/assembly/flash/proc/flash_recharge(interval=10)
|
||||
if(prob(times_used * 3)) //The more often it's used in a short span of time the more likely it will burn out
|
||||
burn_out()
|
||||
return 0
|
||||
|
||||
var/deciseconds_passed = world.time - last_used
|
||||
for(var/seconds = deciseconds_passed/10, seconds>=interval, seconds-=interval) //get 1 charge every interval
|
||||
times_used--
|
||||
|
||||
last_used = world.time
|
||||
times_used = max(0, times_used) //sanity
|
||||
return 1
|
||||
|
||||
/obj/item/device/assembly/flash/proc/try_use_flash(mob/user = null)
|
||||
flash_recharge(10)
|
||||
|
||||
if(crit_fail)
|
||||
return 0
|
||||
|
||||
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
|
||||
update_icon(1)
|
||||
times_used++
|
||||
|
||||
if(user && !clown_check(user))
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/device/assembly/flash/proc/flash_carbon(mob/living/carbon/M, mob/user = null, power = 5, targeted = 1)
|
||||
add_logs(user, M, "flashed", src)
|
||||
if(user && targeted)
|
||||
if(M.weakeyes)
|
||||
M.Weaken(3) //quick weaken bypasses eye protection but has no eye flash
|
||||
if(M.flash_eyes(1, 1))
|
||||
M.confused += power
|
||||
terrible_conversion_proc(M, user)
|
||||
M.Stun(1)
|
||||
visible_message("<span class='disarm'>[user] blinds [M] with the flash!</span>")
|
||||
user << "<span class='danger'>You blind [M] with the flash!</span>"
|
||||
M << "<span class='userdanger'>[user] blinds you with the flash!</span>"
|
||||
if(M.weakeyes)
|
||||
M.Stun(2)
|
||||
M.visible_message("<span class='disarm'>[M] gasps and shields their eyes!</span>", "<span class='userdanger'>You gasp and shields your eyes!</span>")
|
||||
else
|
||||
visible_message("<span class='disarm'>[user] fails to blind [M] with the flash!</span>")
|
||||
user << "<span class='warning'>You fail to blind [M] with the flash!</span>"
|
||||
M << "<span class='danger'>[user] fails to blind you with the flash!</span>"
|
||||
else
|
||||
if(M.flash_eyes())
|
||||
M.confused += power
|
||||
|
||||
/obj/item/device/assembly/flash/attack(mob/living/M, mob/user)
|
||||
if(!try_use_flash(user))
|
||||
return 0
|
||||
|
||||
if(iscarbon(M))
|
||||
flash_carbon(M, user, 5, 1)
|
||||
return 1
|
||||
|
||||
else if(issilicon(M))
|
||||
add_logs(user, M, "flashed", src)
|
||||
update_icon(1)
|
||||
M.Weaken(rand(5,10))
|
||||
user.visible_message("<span class='disarm'>[user] overloads [M]'s sensors with the flash!</span>", "<span class='danger'>You overload [M]'s sensors with the flash!</span>")
|
||||
return 1
|
||||
|
||||
user.visible_message("<span class='disarm'>[user] fails to blind [M] with the flash!</span>", "<span class='warning'>You fail to blind [M] with the flash!</span>")
|
||||
|
||||
|
||||
/obj/item/device/assembly/flash/attack_self(mob/living/carbon/user, flag = 0, emp = 0)
|
||||
if(holder)
|
||||
return 0
|
||||
if(!try_use_flash(user))
|
||||
return 0
|
||||
user.visible_message("<span class='disarm'>[user]'s flash emits a blinding light!</span>", "<span class='danger'>Your flash emits a blinding light!</span>")
|
||||
for(var/mob/living/carbon/M in oviewers(3, null))
|
||||
flash_carbon(M, user, 1, 0)
|
||||
|
||||
|
||||
/obj/item/device/assembly/flash/emp_act(severity)
|
||||
if(!try_use_flash())
|
||||
return 0
|
||||
for(var/mob/living/carbon/M in viewers(3, null))
|
||||
flash_carbon(M, null, 10, 0)
|
||||
burn_out()
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/device/assembly/flash/proc/terrible_conversion_proc(mob/M, mob/user)
|
||||
if(ishuman(M) && ishuman(user) && M.stat != DEAD)
|
||||
if(user.mind && (user.mind in ticker.mode.head_revolutionaries))
|
||||
if(M.client)
|
||||
if(M.stat == CONSCIOUS)
|
||||
M.mind_initialize() //give them a mind datum if they don't have one.
|
||||
var/resisted
|
||||
if(!isloyal(M))
|
||||
if(user.mind in ticker.mode.head_revolutionaries)
|
||||
if(ticker.mode.add_revolutionary(M.mind))
|
||||
times_used -- //Flashes less likely to burn out for headrevs when used for conversion
|
||||
else
|
||||
resisted = 1
|
||||
else
|
||||
resisted = 1
|
||||
|
||||
if(resisted)
|
||||
user << "<span class='warning'>This mind seems resistant to the flash!</span>"
|
||||
else
|
||||
user << "<span class='warning'>They must be conscious before you can convert them!</span>"
|
||||
else
|
||||
user << "<span class='warning'>This mind is so vacant that it is not susceptible to influence!</span>"
|
||||
|
||||
|
||||
/obj/item/device/assembly/flash/cyborg
|
||||
origin_tech = null
|
||||
|
||||
/obj/item/device/assembly/flash/cyborg/attack(mob/living/M, mob/user)
|
||||
..()
|
||||
cyborg_flash_animation(user)
|
||||
|
||||
/obj/item/device/assembly/flash/cyborg/attack_self(mob/user)
|
||||
..()
|
||||
cyborg_flash_animation(user)
|
||||
|
||||
/obj/item/device/assembly/flash/cyborg/attackby(obj/item/weapon/W, mob/user, params)
|
||||
return
|
||||
|
||||
/obj/item/device/assembly/flash/cyborg/proc/cyborg_flash_animation(mob/living/user)
|
||||
var/atom/movable/overlay/animation = new(user.loc)
|
||||
animation.layer = user.layer + 1
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = user
|
||||
flick("blspell", animation)
|
||||
sleep(5)
|
||||
qdel(animation)
|
||||
|
||||
|
||||
/obj/item/device/assembly/flash/memorizer
|
||||
name = "memorizer"
|
||||
desc = "If you see this, you're not likely to remember it any time soon."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "memorizer"
|
||||
item_state = "nullrod"
|
||||
|
||||
/obj/item/device/assembly/flash/handheld //this is now the regular pocket flashes
|
||||
@@ -0,0 +1,105 @@
|
||||
/obj/item/device/assembly/health
|
||||
name = "health sensor"
|
||||
desc = "Used for scanning and monitoring health."
|
||||
icon_state = "health"
|
||||
materials = list(MAT_METAL=800, MAT_GLASS=200)
|
||||
origin_tech = "magnets=1;biotech=1"
|
||||
attachable = 1
|
||||
secured = 0
|
||||
|
||||
var/scanning = 0
|
||||
var/health_scan
|
||||
var/alarm_health = 0
|
||||
|
||||
|
||||
|
||||
/obj/item/device/assembly/health/activate()
|
||||
if(!..()) return 0//Cooldown check
|
||||
toggle_scan()
|
||||
return 0
|
||||
|
||||
/obj/item/device/assembly/health/toggle_secure()
|
||||
secured = !secured
|
||||
if(secured && scanning)
|
||||
SSobj.processing |= src
|
||||
else
|
||||
scanning = 0
|
||||
SSobj.processing.Remove(src)
|
||||
update_icon()
|
||||
return secured
|
||||
|
||||
/obj/item/device/assembly/health/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/device/multitool))
|
||||
if(alarm_health == 0)
|
||||
alarm_health = -90
|
||||
user.show_message("You toggle [src] to \"detect death\" mode.")
|
||||
else
|
||||
alarm_health = 0
|
||||
user.show_message("You toggle [src] to \"detect critical state\" mode.")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/device/assembly/health/process()
|
||||
if(!scanning || !secured)
|
||||
return
|
||||
|
||||
var/atom/A = src
|
||||
if(connected && connected.holder)
|
||||
A = connected.holder
|
||||
|
||||
for(A, A && !ismob(A), A=A.loc);
|
||||
// like get_turf(), but for mobs.
|
||||
var/mob/living/M = A
|
||||
|
||||
if(M)
|
||||
health_scan = M.health
|
||||
if(health_scan <= alarm_health)
|
||||
pulse()
|
||||
audible_message("\icon[src] *beep* *beep*", "*beep* *beep*")
|
||||
toggle_scan()
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/device/assembly/health/proc/toggle_scan()
|
||||
if(!secured) return 0
|
||||
scanning = !scanning
|
||||
if(scanning)
|
||||
SSobj.processing |= src
|
||||
else
|
||||
SSobj.processing.Remove(src)
|
||||
return
|
||||
|
||||
/obj/item/device/assembly/health/interact(mob/user as mob)//TODO: Change this to the wires thingy
|
||||
if(!secured)
|
||||
user.show_message("<span class='warning'>The [name] is unsecured!</span>")
|
||||
return 0
|
||||
var/dat = text("<TT><B>Health Sensor</B> <A href='?src=\ref[src];scanning=1'>[scanning?"On":"Off"]</A>")
|
||||
if(scanning && health_scan)
|
||||
dat += "<BR>Health: [health_scan]"
|
||||
user << browse(dat, "window=hscan")
|
||||
onclose(user, "hscan")
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/assembly/health/Topic(href, href_list)
|
||||
..()
|
||||
if(!ismob(usr))
|
||||
return
|
||||
|
||||
var/mob/user = usr
|
||||
|
||||
if(!user.canUseTopic(user))
|
||||
usr << browse(null, "window=hscan")
|
||||
onclose(usr, "hscan")
|
||||
return
|
||||
|
||||
if(href_list["scanning"])
|
||||
toggle_scan()
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=hscan")
|
||||
return
|
||||
|
||||
attack_self(user)
|
||||
return
|
||||
@@ -21,7 +21,7 @@
|
||||
attach(A2,user)
|
||||
name = "[A.name]-[A2.name] assembly"
|
||||
update_icon()
|
||||
feedback_add_details("assembly_made","[type]")
|
||||
feedback_add_details("assembly_made","[A.name]-[A2.name]")
|
||||
|
||||
/obj/item/device/assembly_holder/proc/attach(obj/item/device/assembly/A, mob/user)
|
||||
if(!A.remove_item_from_storage(src))
|
||||
@@ -41,10 +41,17 @@
|
||||
overlays += "[a_left.icon_state]_left"
|
||||
for(var/O in a_left.attached_overlays)
|
||||
overlays += "[O]_l"
|
||||
|
||||
if(a_right)
|
||||
src.overlays += "[a_right.icon_state]_right"
|
||||
var/list/images = list()
|
||||
images += image(icon, icon_state = "[a_right.icon_state]_left")
|
||||
for(var/O in a_right.attached_overlays)
|
||||
overlays += "[O]_r"
|
||||
images += image(icon, icon_state = "[O]_l")
|
||||
var/matrix = matrix(-1, 0, 0, 0, 1, 0)
|
||||
for(var/image/I in images)
|
||||
I.transform = matrix
|
||||
overlays += I
|
||||
|
||||
if(master)
|
||||
master.update_icon()
|
||||
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
sparks.set_up(2, 0, src)
|
||||
sparks.attach(src)
|
||||
|
||||
/obj/item/device/assembly/igniter/Destroy()
|
||||
qdel(sparks)
|
||||
sparks = null
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/device/assembly/igniter/activate()
|
||||
if(!..()) return 0//Cooldown check
|
||||
|
||||
@@ -223,4 +223,4 @@
|
||||
if(previous)
|
||||
previous.next = null
|
||||
master.last = previous
|
||||
..()
|
||||
return ..()
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
icon_state = "mousetrap"
|
||||
materials = list(MAT_METAL=100)
|
||||
origin_tech = "combat=1"
|
||||
attachable = 1
|
||||
var/armed = 0
|
||||
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
/obj/item/assembly/shock_kit/Destroy()
|
||||
qdel(part1)
|
||||
qdel(part2)
|
||||
..()
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/assembly/shock_kit/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(istype(W, /obj/item/weapon/wrench))
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
/obj/item/device/assembly/signaler/Destroy()
|
||||
if(radio_controller)
|
||||
radio_controller.remove_object(src,frequency)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/device/assembly/signaler/activate()
|
||||
if(cooldown > 0) return 0
|
||||
|
||||
@@ -129,6 +129,7 @@ var/next_external_rsc = 0
|
||||
if(holder)
|
||||
add_admin_verbs()
|
||||
admin_memo_output("Show")
|
||||
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>"
|
||||
|
||||
@@ -183,6 +184,7 @@ var/next_external_rsc = 0
|
||||
//////////////
|
||||
/client/Del()
|
||||
if(holder)
|
||||
adminGreet(1)
|
||||
holder.owner = null
|
||||
admins -= src
|
||||
directory -= ckey
|
||||
@@ -234,11 +236,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)
|
||||
@@ -323,20 +324,6 @@ var/next_external_rsc = 0
|
||||
'icons/pda_icons/pda_scanner.png',
|
||||
'icons/pda_icons/pda_signaler.png',
|
||||
'icons/pda_icons/pda_status.png',
|
||||
'icons/spideros_icons/sos_1.png',
|
||||
'icons/spideros_icons/sos_2.png',
|
||||
'icons/spideros_icons/sos_3.png',
|
||||
'icons/spideros_icons/sos_4.png',
|
||||
'icons/spideros_icons/sos_5.png',
|
||||
'icons/spideros_icons/sos_6.png',
|
||||
'icons/spideros_icons/sos_7.png',
|
||||
'icons/spideros_icons/sos_8.png',
|
||||
'icons/spideros_icons/sos_9.png',
|
||||
'icons/spideros_icons/sos_10.png',
|
||||
'icons/spideros_icons/sos_11.png',
|
||||
'icons/spideros_icons/sos_12.png',
|
||||
'icons/spideros_icons/sos_13.png',
|
||||
'icons/spideros_icons/sos_14.png',
|
||||
'icons/stamp_icons/large_stamp-clown.png',
|
||||
'icons/stamp_icons/large_stamp-deny.png',
|
||||
'icons/stamp_icons/large_stamp-ok.png',
|
||||
|
||||
@@ -345,8 +345,8 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set
|
||||
|
||||
if(user.client)
|
||||
if(user.client.holder)
|
||||
dat += "<b>Adminhelp Sound:</b> "
|
||||
dat += "<a href='?_src_=prefs;preference=hear_adminhelps'>[(toggles & SOUND_ADMINHELP)?"On":"Off"]</a><br>"
|
||||
dat += "<b>Adminhelp Sound:</b> <a href='?_src_=prefs;preference=hear_adminhelps'>[(toggles & SOUND_ADMINHELP)?"On":"Off"]</a><br>"
|
||||
dat += "<b>Announce Login:</b> <a href='?_src_=prefs;preference=announce_login'>[(toggles & ANNOUNCE_LOGIN)?"On":"Off"]</a><br>"
|
||||
|
||||
if(unlock_content || check_rights_for(user.client, R_ADMIN))
|
||||
dat += "<b>OOC:</b> <span style='border: 1px solid #161616; background-color: [ooccolor ? ooccolor : normal_ooc_colour];'> </span> <a href='?_src_=prefs;preference=ooccolor;task=input'>Change</a><br>"
|
||||
@@ -955,6 +955,8 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set
|
||||
|
||||
if("hear_adminhelps")
|
||||
toggles ^= SOUND_ADMINHELP
|
||||
if("announce_login")
|
||||
toggles ^= ANNOUNCE_LOGIN
|
||||
|
||||
if("ui")
|
||||
switch(UI_style)
|
||||
|
||||
@@ -64,6 +64,16 @@
|
||||
usr << "You will [(prefs.toggles & SOUND_ADMINHELP) ? "now" : "no longer"] hear a sound when adminhelps arrive."
|
||||
feedback_add_details("admin_verb","AHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/toggleannouncelogin()
|
||||
set name = "Do/Don't Announce Login"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggle if you want an announcement to admins when you login during a round"
|
||||
if(!holder) return
|
||||
prefs.toggles ^= ANNOUNCE_LOGIN
|
||||
prefs.save_preferences()
|
||||
usr << "You will [(prefs.toggles & ANNOUNCE_LOGIN) ? "now" : "no longer"] have an announcement to other admins when you login."
|
||||
feedback_add_details("admin_verb","TAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/deadchat()
|
||||
set name = "Show/Hide Deadchat"
|
||||
set category = "Preferences"
|
||||
|
||||
@@ -149,6 +149,13 @@ BLIND // can't see anything
|
||||
|
||||
permeability_coefficient = 0.50
|
||||
slowdown = SHOES_SLOWDOWN
|
||||
var/blood_state = BLOOD_STATE_NOT_BLOODY
|
||||
var/list/bloody_shoes = list(BLOOD_STATE_HUMAN = 0,BLOOD_STATE_XENO = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
|
||||
|
||||
/obj/item/clothing/shoes/clean_blood()
|
||||
..()
|
||||
bloody_shoes = list(BLOOD_STATE_HUMAN = 0,BLOOD_STATE_XENO = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
|
||||
blood_state = BLOOD_STATE_NOT_BLOODY
|
||||
|
||||
/obj/item/proc/negates_gravity()
|
||||
return 0
|
||||
|
||||
@@ -188,12 +188,14 @@
|
||||
..()
|
||||
|
||||
/obj/item/clothing/glasses/thermal/syndi //These are now a traitor item, concealed as mesons. -Pete
|
||||
name = "Optical Meson Scanner"
|
||||
desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition."
|
||||
icon_state = "meson"
|
||||
name = "Chameleon Thermals"
|
||||
desc = "A pair of thermal optic goggles with an onboard chameleon generator. Toggle to disguise."
|
||||
origin_tech = "magnets=3;syndicate=4"
|
||||
flash_protect = -1
|
||||
|
||||
/obj/item/clothing/glasses/thermal/syndi/attack_self(mob/user)
|
||||
chameleon(user)
|
||||
|
||||
/obj/item/clothing/glasses/thermal/monocle
|
||||
name = "Thermoncle"
|
||||
desc = "A monocle thermal."
|
||||
@@ -230,3 +232,55 @@
|
||||
icon_state = "redglasses"
|
||||
item_state = "redglasses"
|
||||
|
||||
|
||||
/obj/item/clothing/glasses/proc/chameleon(var/mob/user)
|
||||
var/input_glasses = input(user, "Choose a piece of eyewear to disguise as.", "Choose glasses style.") as null|anything in list("Sunglasses", "Medical HUD", "Mesons", "Science Goggles", "Glasses", "Security Sunglasses","Eyepatch","Welding","Gar")
|
||||
|
||||
if(user && src in user.contents)
|
||||
switch(input_glasses)
|
||||
if("Sunglasses")
|
||||
desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks many flashes."
|
||||
name = "sunglasses"
|
||||
icon_state = "sun"
|
||||
item_state = "sunglasses"
|
||||
if("Medical HUD")
|
||||
name = "Health Scanner HUD"
|
||||
desc = "A heads-up display that scans the humans in view and provides accurate data about their health status."
|
||||
icon_state = "healthhud"
|
||||
item_state = "healthhud"
|
||||
if("Mesons")
|
||||
name = "Optical Meson Scanner"
|
||||
desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition."
|
||||
icon_state = "meson"
|
||||
item_state = "meson"
|
||||
if("Science Goggles")
|
||||
name = "Science Goggles"
|
||||
desc = "A pair of snazzy goggles used to protect against chemical spills."
|
||||
icon_state = "purple"
|
||||
item_state = "glasses"
|
||||
if("Glasses")
|
||||
name = "Prescription Glasses"
|
||||
desc = "Made by Nerd. Co."
|
||||
icon_state = "glasses"
|
||||
item_state = "glasses"
|
||||
if("Security Sunglasses")
|
||||
name = "HUDSunglasses"
|
||||
desc = "Sunglasses with a HUD."
|
||||
icon_state = "sunhud"
|
||||
item_state = "sunglasses"
|
||||
if("Eyepatch")
|
||||
name = "eyepatch"
|
||||
desc = "Yarr."
|
||||
icon_state = "eyepatch"
|
||||
item_state = "eyepatch"
|
||||
if("Welding")
|
||||
name = "welding goggles"
|
||||
desc = "Protects the eyes from welders; approved by the mad scientist association."
|
||||
icon_state = "welding-g"
|
||||
item_state = "welding-g"
|
||||
if("Gar")
|
||||
desc = "Just who the hell do you think I am?!"
|
||||
name = "gar glasses"
|
||||
icon_state = "gar"
|
||||
item_state = "gar"
|
||||
|
||||
|
||||
@@ -46,6 +46,15 @@
|
||||
icon_state = "securityhud"
|
||||
hud_type = DATA_HUD_SECURITY_ADVANCED
|
||||
|
||||
/obj/item/clothing/glasses/hud/security/chameleon
|
||||
name = "Chamleon Security HUD"
|
||||
desc = "A stolen security HUD integrated with Syndicate chameleon technology. Toggle to disguise the HUD. Provides flash protection."
|
||||
flash_protect = 1
|
||||
|
||||
/obj/item/clothing/glasses/hud/security/chameleon/attack_self(mob/user)
|
||||
chameleon(user)
|
||||
|
||||
|
||||
/obj/item/clothing/glasses/hud/security/sunglasses/eyepatch
|
||||
name = "Eyepatch HUD"
|
||||
desc = "A heads-up display that connects directly to the optical nerve of the user, replacing the need for that useless eyeball."
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
can_toggle = 1
|
||||
toggle_cooldown = 20
|
||||
active_sound = 'sound/items/WEEOO1.ogg'
|
||||
|
||||
|
||||
/obj/item/clothing/head/helmet/justice/escape
|
||||
name = "alarm helmet"
|
||||
desc = "WEEEEOOO. WEEEEEOOO. STOP THAT MONKEY. WEEEOOOO."
|
||||
|
||||
@@ -62,6 +62,16 @@
|
||||
put_on_delay = 50
|
||||
burn_state = -1 //Won't burn in fires
|
||||
|
||||
/obj/item/clothing/shoes/galoshes/dry
|
||||
name = "absorbent galoshes"
|
||||
desc = "A pair of orange rubber boots, designed to prevent slipping on wet surfaces while also drying them."
|
||||
icon_state = "galoshes_dry"
|
||||
|
||||
/obj/item/clothing/shoes/galoshes/dry/step_action()
|
||||
var/turf/simulated/t_loc = get_turf(src)
|
||||
if(istype(t_loc) && t_loc.wet)
|
||||
t_loc.MakeDry(TURF_WET_WATER)
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes
|
||||
desc = "The prankster's standard-issue clowning shoes. Damn, they're huge!"
|
||||
name = "clown shoes"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
/obj/item/clothing/head/helmet/space/chronos/Destroy()
|
||||
dropped()
|
||||
..()
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/chronos
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
/obj/item/clothing/suit/space/chronos/Destroy()
|
||||
dropped()
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/suit/space/chronos/emp_act(severity)
|
||||
var/mob/living/carbon/human/user = src.loc
|
||||
@@ -216,5 +216,5 @@
|
||||
holder.remote_control = null
|
||||
if(holder.client && (holder.client.eye == src))
|
||||
holder.client.eye = holder
|
||||
..()
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
var/basestate = "hardsuit"
|
||||
var/brightness_on = 4 //luminosity when on
|
||||
var/on = 0
|
||||
var/obj/item/clothing/suit/space/hardsuit/suit
|
||||
item_color = "engineering" //Determines used sprites: hardsuit[on]-[color] and hardsuit[on]-[color]2 (lying down sprite)
|
||||
action_button_name = "Toggle Helmet Light"
|
||||
flags = BLOCKHAIR | STOPSPRESSUREDMAGE | THICKMATERIAL | NODROP
|
||||
|
||||
@@ -40,7 +40,7 @@ Contains:
|
||||
desc = "That's not red paint. That's real blood."
|
||||
icon_state = "deathsquad"
|
||||
item_state = "deathsquad"
|
||||
armor = list(melee = 50, bullet = 40, laser = 30, energy = 50, bomb = 50, bio = 100, rad = 100)
|
||||
armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100)
|
||||
strip_delay = 130
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
|
||||
unacidable = 1
|
||||
@@ -55,7 +55,7 @@ Contains:
|
||||
icon_state = "deathsquad"
|
||||
item_state = "swat_suit"
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank/internals)
|
||||
armor = list(melee = 50, bullet = 40, laser = 30,energy = 50, bomb = 50, bio = 100, rad = 100)
|
||||
armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100)
|
||||
slowdown = 1
|
||||
strip_delay = 130
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
|
||||
@@ -68,7 +68,7 @@ Contains:
|
||||
icon_state = "beret_badge"
|
||||
flags = STOPSPRESSUREDMAGE
|
||||
flags_inv = 0
|
||||
armor = list(melee = 50, bullet = 40, laser = 30, energy = 50, bomb = 50, bio = 100, rad = 100)
|
||||
armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100)
|
||||
strip_delay = 130
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
|
||||
unacidable = 1
|
||||
@@ -83,7 +83,7 @@ Contains:
|
||||
flags_inv = 0
|
||||
w_class = 3
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank/internals)
|
||||
armor = list(melee = 50, bullet = 40, laser = 30,energy = 50, bomb = 50, bio = 100, rad = 100)
|
||||
armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100)
|
||||
slowdown = 1
|
||||
strip_delay = 130
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
item_state = "bio_suit"
|
||||
body_parts_covered = CHEST|GROIN|LEGS|ARMS
|
||||
flags_inv = HIDEJUMPSUIT
|
||||
allowed = list(/obj/item/weapon/disk, /obj/item/weapon/stamp, /obj/item/weapon/reagent_containers/food/drinks/flask, /obj/item/weapon/melee, /obj/item/weapon/storage/lockbox/medal, /obj/item/device/flash/handheld, /obj/item/weapon/storage/box/matches, /obj/item/weapon/lighter, /obj/item/clothing/mask/cigarette, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/tank/internals/emergency_oxygen)
|
||||
allowed = list(/obj/item/weapon/disk, /obj/item/weapon/stamp, /obj/item/weapon/reagent_containers/food/drinks/flask, /obj/item/weapon/melee, /obj/item/weapon/storage/lockbox/medal, /obj/item/device/assembly/flash/handheld, /obj/item/weapon/storage/box/matches, /obj/item/weapon/lighter, /obj/item/clothing/mask/cigarette, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/tank/internals/emergency_oxygen)
|
||||
|
||||
//Chaplain
|
||||
/obj/item/clothing/suit/hooded/chaplain_hoodie
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
/obj/item/clothing/suit/hooded/Destroy()
|
||||
qdel(hood)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/suit/hooded/proc/MakeHood()
|
||||
if(!hood)
|
||||
@@ -90,7 +90,6 @@
|
||||
user << "Alt-click on [src] to toggle the [togglename]."
|
||||
|
||||
//Hardsuit toggle code
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/New()
|
||||
MakeHelmet()
|
||||
if(!jetpack)
|
||||
@@ -98,15 +97,24 @@
|
||||
verbs -= /obj/item/clothing/suit/space/hardsuit/verb/Jetpack_Rockets
|
||||
..()
|
||||
/obj/item/clothing/suit/space/hardsuit/Destroy()
|
||||
qdel(helmet)
|
||||
if(helmet)
|
||||
helmet.suit = null
|
||||
qdel(helmet)
|
||||
qdel(jetpack)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/Destroy()
|
||||
if(suit)
|
||||
suit.helmet = null
|
||||
qdel(suit)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/proc/MakeHelmet()
|
||||
if(!helmettype)
|
||||
return
|
||||
if(!helmet)
|
||||
var/obj/item/clothing/head/helmet/space/hardsuit/W = new helmettype(src)
|
||||
W.suit = src
|
||||
helmet = W
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/ui_action_click()
|
||||
@@ -121,7 +129,7 @@
|
||||
..()
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/proc/RemoveHelmet()
|
||||
if(!helmettype)
|
||||
if(!helmet)
|
||||
return
|
||||
suittoggled = 0
|
||||
if(ishuman(helmet.loc))
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
reagents.reaction(C, INGEST)
|
||||
reagents.trans_to(C, reagents.total_volume)
|
||||
C.visible_message("<span class='danger'>[user] has smothered \the [C] with \the [src]!</span>", "<span class='userdanger'>[user] has smothered you with \the [src]!</span>", "<span class='italics'>You hear some struggling and muffled cries of surprise.</span>")
|
||||
var/reagentlist = pretty_string_from_reagent_list(A.reagents)
|
||||
log_game("[key_name(user)] smothered [key_name(A)] with a damp rag containing [reagentlist]")
|
||||
log_attack("[key_name(user)] smothered [key_name(A)] with a damp rag containing [reagentlist]")
|
||||
else
|
||||
reagents.reaction(C, TOUCH)
|
||||
reagents.clear_reagents()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
color = "#aa77aa"
|
||||
icon_state = "vinefloor"
|
||||
broken_states = list()
|
||||
ignoredirt = 1
|
||||
|
||||
|
||||
//All of this shit is useless for vines
|
||||
@@ -324,7 +323,7 @@
|
||||
SetOpacity(0)
|
||||
if(buckled_mob)
|
||||
unbuckle_mob()
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/effect/spacevine/proc/on_chem_effect(datum/reagent/R)
|
||||
var/override = 0
|
||||
@@ -424,7 +423,7 @@
|
||||
|
||||
/obj/effect/spacevine_controller/Destroy()
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/effect/spacevine_controller/proc/spawn_spacevine_piece(turf/location, obj/effect/spacevine/parent, list/muts)
|
||||
var/obj/effect/spacevine/SV = new(location)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
endWhen = rand(25, 100)
|
||||
for(var/obj/machinery/atmospherics/components/unary/vent_scrubber/temp_vent in machines)
|
||||
if(temp_vent.loc.z == ZLEVEL_STATION && !temp_vent.welded)
|
||||
var/datum/pipeline/temp_vent_parent = temp_vent.parents["p1"]
|
||||
var/datum/pipeline/temp_vent_parent = temp_vent.PARENT1
|
||||
if(temp_vent_parent.other_atmosmch.len > 20)
|
||||
vents += temp_vent
|
||||
if(!vents.len)
|
||||
|
||||
@@ -78,4 +78,4 @@
|
||||
M.color = initial(M.color)
|
||||
message += "...</span>"
|
||||
M << message
|
||||
..()
|
||||
return ..()
|
||||
@@ -107,6 +107,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
/obj/effect/hallucination/simple/Destroy()
|
||||
if(target.client) target.client.images.Remove(current_image)
|
||||
active = 0
|
||||
return ..()
|
||||
|
||||
#define FAKE_FLOOD_EXPAND_TIME 30
|
||||
#define FAKE_FLOOD_MAX_RADIUS 7
|
||||
@@ -160,7 +161,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
if(target.client) target.client.images.Remove(flood_images)
|
||||
target = null
|
||||
qdel(flood_images)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/effect/hallucination/simple/xeno
|
||||
image_icon = 'icons/mob/alien.dmi'
|
||||
@@ -188,19 +189,20 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
if(!U.welded)
|
||||
pump = U
|
||||
break
|
||||
xeno = new(pump.loc,target)
|
||||
sleep(10)
|
||||
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
|
||||
xeno.throw_at(target,7,1, spin = 0, diagonals_first = 1)
|
||||
sleep(10)
|
||||
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
|
||||
xeno.throw_at(pump,7,1, spin = 0, diagonals_first = 1)
|
||||
sleep(10)
|
||||
var/xeno_name = xeno.name
|
||||
target << "<span class='notice'>[xeno_name] begins climbing into the ventilation system...</span>"
|
||||
sleep(10)
|
||||
qdel(xeno)
|
||||
target << "<span class='notice'>[xeno_name] scrambles into the ventilation ducts!</span>"
|
||||
if(pump)
|
||||
xeno = new(pump.loc,target)
|
||||
sleep(10)
|
||||
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
|
||||
xeno.throw_at(target,7,1, spin = 0, diagonals_first = 1)
|
||||
sleep(10)
|
||||
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
|
||||
xeno.throw_at(pump,7,1, spin = 0, diagonals_first = 1)
|
||||
sleep(10)
|
||||
var/xeno_name = xeno.name
|
||||
target << "<span class='notice'>[xeno_name] begins climbing into the ventilation system...</span>"
|
||||
sleep(10)
|
||||
qdel(xeno)
|
||||
target << "<span class='notice'>[xeno_name] scrambles into the ventilation ducts!</span>"
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/hallucination/singularity_scare
|
||||
|
||||
@@ -223,7 +223,7 @@
|
||||
if(contents)
|
||||
for(var/atom/movable/something in contents)
|
||||
something.loc = get_turf(src)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/attack_animal(mob/M)
|
||||
if(isanimal(M))
|
||||
|
||||
@@ -305,7 +305,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/berries/glow/Destroy()
|
||||
if(istype(loc,/mob))
|
||||
loc.AddLuminosity(round(-potency / 5,1))
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/berries/glow/pickup(mob/user)
|
||||
src.SetLuminosity(0)
|
||||
@@ -1208,7 +1208,7 @@ obj/item/weapon/reagent_containers/food/snacks/grown/shell/eggy/add_juice()
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/Destroy()
|
||||
if(istype(loc,/mob))
|
||||
loc.AddLuminosity(round(-potency / 10,1))
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/pickup(mob/user)
|
||||
SetLuminosity(0)
|
||||
|
||||
@@ -1339,21 +1339,29 @@
|
||||
if(parent)
|
||||
mutations = parent.mutations
|
||||
|
||||
/obj/item/seeds/kudzuseed/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] swallows the pack of kudzu seeds! It looks like \he's trying to commit suicide..</span>")
|
||||
plant(user)
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/seeds/kudzuseed/harvest()
|
||||
var/list/prod = ..()
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/grown/kudzupod/K in prod)
|
||||
K.mutations = mutations
|
||||
|
||||
/obj/item/seeds/kudzuseed/attack_self(mob/user)
|
||||
/obj/item/seeds/kudzuseed/proc/plant(mob/user)
|
||||
if(istype(user.loc,/turf/space))
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
user << "<span class='notice'>You plant the kudzu. You monster.</span>"
|
||||
message_admins("Kudzu planted by [key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) at ([T.x],[T.y],[T.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>(JMP)</a>)",0,1)
|
||||
investigate_log("was planted by [key_name(user)] at ([T.x],[T.y],[T.z])","kudzu")
|
||||
new /obj/effect/spacevine_controller(user.loc, mutations, potency, production)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/seeds/kudzuseed/attack_self(mob/user)
|
||||
plant(user)
|
||||
user << "<span class='notice'>You plant the kudzu. You monster.</span>"
|
||||
|
||||
/obj/item/seeds/kudzuseed/get_analyzer_text()
|
||||
var/list/mut_text = list()
|
||||
var/text_string = ""
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
new /obj/item/weapon/ore/diamond(src)
|
||||
if(21 to 25)
|
||||
for(var/i = 0, i < 5, i++)
|
||||
new /obj/item/weapon/contraband/poster(src)
|
||||
new /obj/item/weapon/poster/contraband(src)
|
||||
if(26 to 30)
|
||||
for(var/i = 0, i < 3, i++)
|
||||
new /obj/item/weapon/reagent_containers/glass/beaker/noreact(src)
|
||||
|
||||
@@ -573,6 +573,7 @@
|
||||
/**********************Facehugger toy**********************/
|
||||
|
||||
/obj/item/clothing/mask/facehugger/toy
|
||||
item_state = "facehugger_inactive"
|
||||
desc = "A toy often used to play pranks on other miners by putting it in their beds. It takes a bit to recharge after latching onto something."
|
||||
throwforce = 0
|
||||
real = 0
|
||||
|
||||
@@ -509,7 +509,6 @@ var/global/list/rockTurfEdgeCache
|
||||
icon_state = "asteroid"
|
||||
icon_plating = "asteroid"
|
||||
var/dug = 0 //0 = has not yet been dug, 1 = has already been dug
|
||||
ignoredirt = 1
|
||||
|
||||
/turf/simulated/floor/plating/asteroid/airless
|
||||
oxygen = 0.01
|
||||
@@ -603,6 +602,12 @@ var/global/list/rockTurfEdgeCache
|
||||
icon_state = "asteroid_dug"
|
||||
return
|
||||
|
||||
/turf/simulated/floor/plating/asteroid/singularity_act()
|
||||
return
|
||||
|
||||
/turf/simulated/floor/plating/asteroid/singularity_pull(S, current_size)
|
||||
return
|
||||
|
||||
/turf/proc/updateMineralOverlays()
|
||||
src.overlays.Cut()
|
||||
|
||||
|
||||
@@ -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>")
|
||||
@@ -131,7 +136,7 @@
|
||||
return
|
||||
|
||||
if(wires && !primed)
|
||||
if(istype(I, /obj/item/weapon/wirecutters) || istype(I, /obj/item/device/multitool) || istype(I, /obj/item/device/assembly/signaler))
|
||||
if(wires.IsInteractionTool(I))
|
||||
wires.Interact(user)
|
||||
return
|
||||
|
||||
@@ -326,7 +331,9 @@
|
||||
flick("coin_[cmineral]_flip", src)
|
||||
icon_state = "coin_[cmineral]_[coinflip]"
|
||||
playsound(user.loc, 'sound/items/coinflip.ogg', 50, 1)
|
||||
if(do_after(user, 15, target = src))
|
||||
var/oldloc = loc
|
||||
sleep(15)
|
||||
if(loc == oldloc && user && !user.incapacitated())
|
||||
user.visible_message("[user] has flipped [src]. It lands on [coinflip].", \
|
||||
"<span class='notice'>You flip [src]. It lands on [coinflip].</span>", \
|
||||
"<span class='italics'>You hear the clattering of loose change.</span>")
|
||||
@@ -14,10 +14,6 @@
|
||||
/mob/camera/experience_pressure_difference()
|
||||
return
|
||||
|
||||
/mob/camera/Destroy()
|
||||
..()
|
||||
qdel(src)
|
||||
|
||||
/mob/camera/Login()
|
||||
..()
|
||||
update_interface()
|
||||
@@ -69,7 +69,7 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi
|
||||
qdel(ghostimage)
|
||||
ghostimage = null
|
||||
updateallghostimages()
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/mob/dead/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
return 1
|
||||
|
||||
@@ -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"
|
||||
//---------------------------
|
||||
|
||||
@@ -1,91 +1,6 @@
|
||||
//Travel through pools of blood. Slaughter Demon powers for everyone!
|
||||
|
||||
#define BLOODCRAWL 1
|
||||
#define BLOODCRAWL_EAT 2
|
||||
|
||||
/mob/living/proc/phaseout(obj/effect/decal/cleanable/B)
|
||||
var/mob/living/kidnapped = null
|
||||
var/turf/mobloc = get_turf(src.loc)
|
||||
var/turf/bloodloc = get_turf(B.loc)
|
||||
if(Adjacent(bloodloc))
|
||||
src.notransform = TRUE
|
||||
spawn(0)
|
||||
src.visible_message("[src] sinks into the pool of blood.")
|
||||
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, 1, -1)
|
||||
var/obj/effect/dummy/slaughter/holder = PoolOrNew(/obj/effect/dummy/slaughter,mobloc)
|
||||
src.ExtinguishMob()
|
||||
if(src.buckled)
|
||||
src.buckled.unbuckle_mob()
|
||||
if(src.pulling && src.bloodcrawl == BLOODCRAWL_EAT)
|
||||
if(istype(src.pulling, /mob/living))
|
||||
var/mob/living/victim = src.pulling
|
||||
if(victim.stat == CONSCIOUS)
|
||||
src.visible_message("[victim] kicks free of the [src] at the last second!")
|
||||
else
|
||||
victim.loc = holder
|
||||
src.visible_message("<span class='warning'><B>The [src] drags [victim] into the pool of blood!</B>")
|
||||
kidnapped = victim
|
||||
src.loc = holder
|
||||
src.holder = holder
|
||||
if(kidnapped)
|
||||
src << "<B>You begin to feast on [kidnapped]. You can not move while you are doing this.</B>"
|
||||
playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1)
|
||||
sleep(30)
|
||||
playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1)
|
||||
sleep(30)
|
||||
playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1)
|
||||
sleep(30)
|
||||
src << "<B>You devour [kidnapped]. Your health is fully restored.</B>"
|
||||
src.adjustBruteLoss(-1000)
|
||||
src.adjustFireLoss(-1000)
|
||||
src.adjustOxyLoss(-1000)
|
||||
src.adjustToxLoss(-1000)
|
||||
kidnapped.ghostize()
|
||||
qdel(kidnapped)
|
||||
src.notransform = 0
|
||||
|
||||
/mob/living/proc/phasein(obj/effect/decal/cleanable/B)
|
||||
if(src.notransform)
|
||||
src << "<B>Finish eating first!</B>"
|
||||
else
|
||||
src.loc = B.loc
|
||||
src.client.eye = src
|
||||
src.visible_message("<span class='warning'><B>The [src] rises out of the pool of blood!</B>")
|
||||
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
|
||||
qdel(src.holder)
|
||||
src.holder = null
|
||||
|
||||
/obj/effect/decal/cleanable/blood/CtrlClick(mob/living/user)
|
||||
..()
|
||||
if(user.bloodcrawl)
|
||||
if(user.holder)
|
||||
user.phasein(src)
|
||||
else
|
||||
user.phaseout(src)
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/trail_holder/CtrlClick(mob/living/user)
|
||||
..()
|
||||
if(user.bloodcrawl)
|
||||
if(user.holder)
|
||||
user.phasein(src)
|
||||
else
|
||||
user.phaseout(src)
|
||||
|
||||
|
||||
|
||||
/turf/CtrlClick(var/mob/living/user)
|
||||
..()
|
||||
if(user.bloodcrawl)
|
||||
for(var/obj/effect/decal/cleanable/B in src.contents)
|
||||
if(istype(B, /obj/effect/decal/cleanable/blood) || istype(B, /obj/effect/decal/cleanable/trail_holder))
|
||||
if(user.holder)
|
||||
user.phasein(B)
|
||||
break
|
||||
else
|
||||
user.phaseout(B)
|
||||
break
|
||||
|
||||
/obj/effect/dummy/slaughter //Can't use the wizard one, blocked by jaunt/slow
|
||||
name = "water"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
@@ -113,3 +28,59 @@ obj/effect/dummy/slaughter/relaymove(mob/user, direction)
|
||||
|
||||
/obj/effect/dummy/slaughter/Destroy()
|
||||
return QDEL_HINT_PUTINPOOL
|
||||
|
||||
|
||||
/mob/living/proc/phaseout(obj/effect/decal/cleanable/B)
|
||||
var/mob/living/kidnapped = null
|
||||
var/turf/mobloc = get_turf(src.loc)
|
||||
src.notransform = TRUE
|
||||
spawn(0)
|
||||
src.visible_message("[src] sinks into the pool of blood.")
|
||||
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, 1, -1)
|
||||
var/obj/effect/dummy/slaughter/holder = PoolOrNew(/obj/effect/dummy/slaughter,mobloc)
|
||||
src.ExtinguishMob()
|
||||
if(src.buckled)
|
||||
src.buckled.unbuckle_mob()
|
||||
if(src.pulling && src.bloodcrawl == BLOODCRAWL_EAT)
|
||||
if(istype(src.pulling, /mob/living))
|
||||
var/mob/living/victim = src.pulling
|
||||
if(victim.stat == CONSCIOUS)
|
||||
src.visible_message("[victim] kicks free of the [src] at the last second!")
|
||||
else
|
||||
victim.loc = holder
|
||||
src.visible_message("<span class='warning'><B>The [src] drags [victim] into the pool of blood!</B>")
|
||||
kidnapped = victim
|
||||
src.loc = holder
|
||||
src.holder = holder
|
||||
if(kidnapped)
|
||||
src << "<B>You begin to feast on [kidnapped]. You can not move while you are doing this.</B>"
|
||||
playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1)
|
||||
sleep(30)
|
||||
playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1)
|
||||
sleep(30)
|
||||
playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1)
|
||||
sleep(30)
|
||||
if(kidnapped)
|
||||
src << "<B>You devour [kidnapped]. Your health is fully restored.</B>"
|
||||
src.adjustBruteLoss(-1000)
|
||||
src.adjustFireLoss(-1000)
|
||||
src.adjustOxyLoss(-1000)
|
||||
src.adjustToxLoss(-1000)
|
||||
kidnapped.ghostize()
|
||||
qdel(kidnapped)
|
||||
else
|
||||
src << "<B>You happily devour...nothing? Your meal vanished at some point!</B>"
|
||||
src.notransform = 0
|
||||
|
||||
/mob/living/proc/phasein(obj/effect/decal/cleanable/B)
|
||||
if(src.notransform)
|
||||
src << "<B>Finish eating first!</B>"
|
||||
return 0
|
||||
|
||||
src.loc = B.loc
|
||||
src.client.eye = src
|
||||
src.visible_message("<span class='warning'><B>The [src] rises out of the pool of blood!</B>")
|
||||
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
|
||||
qdel(src.holder)
|
||||
src.holder = null
|
||||
return 1
|
||||
@@ -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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/alien/humanoid/emote(act)
|
||||
/mob/living/carbon/alien/humanoid/emote(act,m_type=1,message = null)
|
||||
|
||||
var/param = null
|
||||
if (findtext(act, "-", 1, null))
|
||||
@@ -7,8 +7,6 @@
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
var/muzzled = is_muzzled()
|
||||
var/m_type = 1
|
||||
var/message
|
||||
|
||||
switch(act) //Alphabetical please
|
||||
if ("deathgasp","deathgasps")
|
||||
@@ -25,6 +23,10 @@
|
||||
message = "<span class='name'>[src]</span> hisses."
|
||||
m_type = 2
|
||||
|
||||
if ("me")
|
||||
..()
|
||||
return
|
||||
|
||||
if ("moan","moans")
|
||||
message = "<span class='name'>[src]</span> moans!"
|
||||
m_type = 2
|
||||
|
||||
@@ -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
|
||||
@@ -77,17 +75,3 @@
|
||||
icon_state = "queen_s"
|
||||
pixel_x = -16
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
|
||||
/mob/living/carbon/alien/humanoid/queen/large/update_icons()
|
||||
update_hud() //TODO: remove the need for this to be here
|
||||
overlays.Cut()
|
||||
if(stat == DEAD)
|
||||
icon_state = "queen_dead"
|
||||
else if((stat == UNCONSCIOUS && !sleeping) || weakened)
|
||||
icon_state = "queen_l"
|
||||
else if(sleeping || lying || resting)
|
||||
icon_state = "queen_sleep"
|
||||
else
|
||||
icon_state = "queen_s"
|
||||
for(var/image/I in overlays_standing)
|
||||
overlays += I
|
||||
|
||||
@@ -50,4 +50,29 @@
|
||||
if(lying > 0)
|
||||
lying = 90 //Anything else looks retarded
|
||||
..()
|
||||
update_icons()
|
||||
update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/queen/large/update_icons()
|
||||
update_hud() //TODO: remove the need for this to be here
|
||||
overlays.Cut()
|
||||
if(stat == DEAD)
|
||||
icon_state = "queen_dead"
|
||||
else if((stat == UNCONSCIOUS && !sleeping) || weakened)
|
||||
icon_state = "queen_l"
|
||||
else if(sleeping || lying || resting)
|
||||
icon_state = "queen_sleep"
|
||||
else
|
||||
icon_state = "queen_s"
|
||||
for(var/image/I in overlays_standing)
|
||||
overlays += I
|
||||
|
||||
/mob/living/carbon/alien/humanoid/queen/large/update_inv_l_hand()
|
||||
remove_overlay(L_HAND_LAYER)
|
||||
if(handcuffed)
|
||||
drop_l_hand()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/queen/large/update_inv_r_hand()
|
||||
remove_overlay(R_HAND_LAYER)
|
||||
if(handcuffed)
|
||||
drop_r_hand()
|
||||
|
||||
@@ -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
|
||||
@@ -73,15 +73,17 @@
|
||||
/obj/item/organ/internal/alien/plasmavessel/on_life()
|
||||
//If there are alien weeds on the ground then heal if needed or give some plasma
|
||||
if(locate(/obj/structure/alien/weeds) in owner.loc)
|
||||
if(owner.health >= owner.maxHealth - owner.getCloneLoss())
|
||||
if(owner.health >= owner.maxHealth)
|
||||
owner.adjustPlasma(plasma_rate)
|
||||
else
|
||||
var/mod = 1
|
||||
var/heal_amt = heal_rate
|
||||
if(!isalien(owner))
|
||||
mod = 0.2
|
||||
owner.adjustBruteLoss(-heal_rate*mod)
|
||||
owner.adjustFireLoss(-heal_rate*mod)
|
||||
owner.adjustOxyLoss(-heal_rate*mod)
|
||||
heal_amt *= 0.2
|
||||
owner.adjustPlasma(plasma_rate*0.5)
|
||||
owner.adjustBruteLoss(-heal_amt)
|
||||
owner.adjustFireLoss(-heal_amt)
|
||||
owner.adjustOxyLoss(-heal_amt)
|
||||
owner.adjustCloneLoss(-heal_amt)
|
||||
|
||||
/obj/item/organ/internal/alien/plasmavessel/Insert(mob/living/carbon/M, special = 0)
|
||||
..()
|
||||
|
||||
@@ -3,16 +3,20 @@
|
||||
if(.)
|
||||
playsound(loc, "hiss", 25, 1, 1) //erp just isn't the same without sound feedback
|
||||
|
||||
/mob/living/proc/alien_talk(message)
|
||||
/mob/living/proc/alien_talk(message, shown_name = name)
|
||||
log_say("[key_name(src)] : [message]")
|
||||
message = trim(message)
|
||||
if(!message) return
|
||||
|
||||
var/message_a = say_quote(message)
|
||||
var/rendered = "<i><span class='game say'>Hivemind, <span class='name'>[name]</span> <span class='message'>[message_a]</span></span></i>"
|
||||
var/message_a = say_quote(message, get_spans())
|
||||
var/rendered = "<i><span class='alien'>Hivemind, <span class='name'>[shown_name]</span> <span class='message'>[message_a]</span></span></i>"
|
||||
for(var/mob/S in player_list)
|
||||
if((!S.stat && S.hivecheck()) || (S in dead_mob_list))
|
||||
S << rendered
|
||||
|
||||
/mob/living/carbon/alien/humanoid/queen/alien_talk(message, shown_name = name)
|
||||
shown_name = "<FONT size = 3>[shown_name]</FONT>"
|
||||
..(message, shown_name)
|
||||
|
||||
/mob/living/carbon/hivecheck()
|
||||
return getorgan(/obj/item/organ/internal/alien/hivenode)
|
||||
|
||||
@@ -187,7 +187,6 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
else
|
||||
target.visible_message("<span class='danger'>[src] violates [target]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] violates [target]'s face!</span>")
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/GoActive()
|
||||
if(stat == DEAD || stat == CONSCIOUS)
|
||||
@@ -196,20 +195,10 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
stat = CONSCIOUS
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
/* for(var/mob/living/carbon/alien/alien in world)
|
||||
var/image/activeIndicator = image('icons/mob/alien.dmi', loc = src, icon_state = "facehugger_active")
|
||||
activeIndicator.override = 1
|
||||
if(alien && alien.client)
|
||||
alien.client.images += activeIndicator */
|
||||
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/GoIdle()
|
||||
if(stat == DEAD || stat == UNCONSCIOUS)
|
||||
return
|
||||
|
||||
/* RemoveActiveIndicators() */
|
||||
|
||||
stat = UNCONSCIOUS
|
||||
icon_state = "[initial(icon_state)]_inactive"
|
||||
|
||||
@@ -221,15 +210,12 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
/* RemoveActiveIndicators() */
|
||||
|
||||
icon_state = "[initial(icon_state)]_dead"
|
||||
item_state = "facehugger_inactive"
|
||||
stat = DEAD
|
||||
|
||||
visible_message("<span class='danger'>[src] curls up into a ball!</span>")
|
||||
|
||||
return
|
||||
|
||||
/proc/CanHug(mob/living/M)
|
||||
if(!istype(M))
|
||||
return 0
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
if(brainmob)
|
||||
qdel(brainmob)
|
||||
brainmob = null
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/device/mmi/examine(mob/user)
|
||||
..()
|
||||
|
||||
@@ -8,16 +8,12 @@
|
||||
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.
|
||||
death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
|
||||
ghostize() //Ghostize checks for key so nothing else is necessary.
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/brain/update_canmove()
|
||||
if(in_contents_of(/obj/mecha)) canmove = 1
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
if(brainmob)
|
||||
qdel(brainmob)
|
||||
brainmob = null
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/internal/brain/alien
|
||||
name = "alien brain"
|
||||
|
||||
@@ -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()
|
||||
@@ -572,4 +579,7 @@ var/const/GALOSHES_DONT_HELP = 4
|
||||
var/obj/item/organ/internal/alien/plasmavessel/vessel = getorgan(/obj/item/organ/internal/alien/plasmavessel)
|
||||
if(vessel)
|
||||
stat(null, "Plasma Stored: [vessel.storedPlasma]/[vessel.max_plasma]")
|
||||
if(locate(/obj/item/device/assembly/health) in src)
|
||||
stat(null, "Health: [health]")
|
||||
|
||||
add_abilities_to_panel()
|
||||
@@ -111,6 +111,11 @@
|
||||
else
|
||||
message = "<B>[src]</B> makes a noise."
|
||||
|
||||
if ("me")
|
||||
if(!silent)
|
||||
..()
|
||||
return
|
||||
|
||||
if ("nod","nods")
|
||||
message = "<B>[src]</B> nods."
|
||||
m_type = 1
|
||||
|
||||
+57
-44
@@ -1,45 +1,58 @@
|
||||
/mob/living/carbon/monkey/examine(mob/user)
|
||||
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n"
|
||||
|
||||
if (src.handcuffed)
|
||||
msg += "It is \icon[src.handcuffed] handcuffed!\n"
|
||||
if (src.head)
|
||||
msg += "It has \icon[src.head] \a [src.head] on its head. \n"
|
||||
if (src.wear_mask)
|
||||
msg += "It has \icon[src.wear_mask] \a [src.wear_mask] on its face.\n"
|
||||
if (src.l_hand)
|
||||
msg += "It has \icon[src.l_hand] \a [src.l_hand] in its left hand.\n"
|
||||
if (src.r_hand)
|
||||
msg += "It has \icon[src.r_hand] \a [src.r_hand] in its right hand.\n"
|
||||
if (src.back)
|
||||
msg += "It has \icon[src.back] \a [src.back] on its back.\n"
|
||||
if (src.stat == DEAD)
|
||||
msg += "<span class='deadsay'>It is limp and unresponsive, with no signs of life.</span>\n"
|
||||
else
|
||||
msg += "<span class='warning'>"
|
||||
if (src.getBruteLoss())
|
||||
if (src.getBruteLoss() < 30)
|
||||
msg += "It has minor bruising.\n"
|
||||
else
|
||||
msg += "<B>It has severe bruising!</B>\n"
|
||||
if (src.getFireLoss())
|
||||
if (src.getFireLoss() < 30)
|
||||
msg += "It has minor burns.\n"
|
||||
else
|
||||
msg += "<B>It has severe burns!</B>\n"
|
||||
|
||||
if (src.fire_stacks > 0)
|
||||
msg += "It's covered in something flammable.\n"
|
||||
if (src.fire_stacks < 0)
|
||||
msg += "It's soaked in water.\n"
|
||||
|
||||
if (src.stat == UNCONSCIOUS)
|
||||
msg += "It isn't responding to anything around it; it seems to be asleep.\n"
|
||||
msg += "</span>"
|
||||
|
||||
if (src.digitalcamo)
|
||||
msg += "It is moving its body in an unnatural and blatantly unsimian manner.\n"
|
||||
|
||||
msg += "*---------*</span>"
|
||||
|
||||
/mob/living/carbon/examine(mob/user)
|
||||
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n"
|
||||
|
||||
if (handcuffed)
|
||||
msg += "It is \icon[src.handcuffed] handcuffed!\n"
|
||||
if (head)
|
||||
msg += "It has \icon[src.head] \a [src.head] on its head. \n"
|
||||
if (wear_mask)
|
||||
msg += "It has \icon[src.wear_mask] \a [src.wear_mask] on its face.\n"
|
||||
if (l_hand)
|
||||
msg += "It has \icon[src.l_hand] \a [src.l_hand] in its left hand.\n"
|
||||
if (r_hand)
|
||||
msg += "It has \icon[src.r_hand] \a [src.r_hand] in its right hand.\n"
|
||||
if (back)
|
||||
msg += "It has \icon[src.back] \a [src.back] on its back.\n"
|
||||
if (stat == DEAD)
|
||||
msg += "<span class='deadsay'>It is limp and unresponsive, with no signs of life.</span>\n"
|
||||
else
|
||||
msg += "<span class='warning'>"
|
||||
var/temp = getBruteLoss()
|
||||
if(temp)
|
||||
if (temp < 30)
|
||||
msg += "It has minor bruising.\n"
|
||||
else
|
||||
msg += "<B>It has severe bruising!</B>\n"
|
||||
|
||||
temp = getFireLoss()
|
||||
if(temp)
|
||||
if (temp < 30)
|
||||
msg += "It has minor burns.\n"
|
||||
else
|
||||
msg += "<B>It has severe burns!</B>\n"
|
||||
|
||||
temp = getCloneLoss()
|
||||
if(temp)
|
||||
if(getCloneLoss() < 30)
|
||||
msg += "It is slightly deformed.\n"
|
||||
else
|
||||
msg += "<b>It is severely deformed.</b>\n"
|
||||
|
||||
if(getBrainLoss() > 60)
|
||||
msg += "It seems to be clumsy and unable to think.\n"
|
||||
|
||||
if(fire_stacks > 0)
|
||||
msg += "It's covered in something flammable.\n"
|
||||
if(fire_stacks < 0)
|
||||
msg += "It's soaked in water.\n"
|
||||
|
||||
if(stat == UNCONSCIOUS)
|
||||
msg += "It isn't responding to anything around it; it seems to be asleep.\n"
|
||||
msg += "</span>"
|
||||
|
||||
if (digitalcamo)
|
||||
msg += "It is moving its body in an unnatural and blatantly unsimian manner.\n"
|
||||
|
||||
msg += "*---------*</span>"
|
||||
|
||||
user << msg
|
||||
@@ -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,7 +279,11 @@
|
||||
heart_attack = 0
|
||||
if(stat == CONSCIOUS)
|
||||
src << "<span class='notice'>You feel your heart beating again!</span>"
|
||||
return ..(shock_damage,source,siemens_coeff)
|
||||
. = ..(shock_damage,source,siemens_coeff,safety,override)
|
||||
if(.)
|
||||
electrocution_animation(40)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/human/Topic(href, href_list)
|
||||
if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
|
||||
@@ -801,4 +804,30 @@
|
||||
H.bloody_hands = 0
|
||||
H.bloody_hands_mob = null
|
||||
H.update_inv_gloves()
|
||||
update_icons() //apply the now updated overlays to the mob
|
||||
update_icons() //apply the now updated overlays to the mob
|
||||
|
||||
|
||||
|
||||
//Turns a mob black, flashes a skeleton overlay
|
||||
//Just like a cartoon!
|
||||
/mob/living/carbon/human/proc/electrocution_animation(anim_duration)
|
||||
//Handle mutant parts if possible
|
||||
if(dna && dna.species)
|
||||
dna.species.handle_mutant_bodyparts(src,"black")
|
||||
dna.species.handle_hair(src,"black")
|
||||
dna.species.update_color(src,"black")
|
||||
overlays += "electrocuted_base"
|
||||
spawn(anim_duration)
|
||||
if(src)
|
||||
if(dna && dna.species)
|
||||
dna.species.handle_mutant_bodyparts(src)
|
||||
dna.species.handle_hair(src)
|
||||
dna.species.update_color(src)
|
||||
overlays -= "electrocuted_base"
|
||||
|
||||
else //or just do a generic animation
|
||||
var/list/viewing = list()
|
||||
for(var/mob/M in viewers(src))
|
||||
if(M.client)
|
||||
viewing += M.client
|
||||
flick_overlay(image(icon,src,"electrocuted_generic",MOB_LAYER+1), viewing, anim_duration)
|
||||
@@ -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()
|
||||
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
return shoes && shoes.negates_gravity()
|
||||
|
||||
/mob/living/carbon/human/Move(NewLoc, direct)
|
||||
. = ..()
|
||||
. = ..()
|
||||
if(dna)
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
HM.on_move(src, NewLoc)
|
||||
@@ -55,5 +55,23 @@
|
||||
if(!has_gravity(loc))
|
||||
return
|
||||
var/obj/item/clothing/shoes/S = shoes
|
||||
|
||||
//Bloody footprints
|
||||
var/turf/T = get_turf(src)
|
||||
if(S.bloody_shoes && S.bloody_shoes[S.blood_state])
|
||||
var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T
|
||||
if(oldFP && oldFP.blood_state == S.blood_state)
|
||||
return
|
||||
else
|
||||
//No oldFP or it's a different kind of blood
|
||||
S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state]-BLOOD_LOSS_PER_STEP)
|
||||
var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T)
|
||||
FP.blood_state = S.blood_state
|
||||
FP.entered_dirs |= dir
|
||||
FP.bloodiness = S.bloody_shoes[S.blood_state]
|
||||
FP.update_icon()
|
||||
update_inv_shoes()
|
||||
//End bloody footprints
|
||||
|
||||
S.step_action()
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point
|
||||
#define HEAT_DAMAGE_LEVEL_2 3 //Amount of damage applied when your body temperature passes the 400K point
|
||||
#define HEAT_DAMAGE_LEVEL_3 8 //Amount of damage applied when your body temperature passes the 460K point and you are on fire
|
||||
#define HEAT_DAMAGE_LEVEL_3 10 //Amount of damage applied when your body temperature passes the 460K point and you are on fire
|
||||
|
||||
#define COLD_DAMAGE_LEVEL_1 0.5 //Amount of damage applied when your body temperature just passes the 260.15k safety point
|
||||
#define COLD_DAMAGE_LEVEL_2 1.5 //Amount of damage applied when your body temperature passes the 200K point
|
||||
@@ -123,7 +123,7 @@
|
||||
if(thermal_protection >= FIRE_SUIT_MAX_TEMP_PROTECT)
|
||||
bodytemperature += 11
|
||||
else
|
||||
bodytemperature += BODYTEMP_HEATING_MAX
|
||||
bodytemperature += (BODYTEMP_HEATING_MAX + (fire_stacks * 12))
|
||||
|
||||
|
||||
/mob/living/carbon/human/IgniteMob()
|
||||
|
||||
@@ -118,24 +118,35 @@
|
||||
else
|
||||
return "[id]"
|
||||
|
||||
/datum/species/proc/update_color(mob/living/carbon/human/H)
|
||||
/datum/species/proc/update_color(mob/living/carbon/human/H, forced_colour)
|
||||
H.remove_overlay(SPECIES_LAYER)
|
||||
|
||||
var/image/standing
|
||||
|
||||
var/g = (H.gender == FEMALE) ? "f" : "m"
|
||||
|
||||
if(MUTCOLORS in specflags)
|
||||
if((MUTCOLORS in specflags) || use_skintones)
|
||||
var/image/spec_base
|
||||
var/icon_state_string = "[id]_"
|
||||
if(sexes)
|
||||
icon_state_string += "[g]_s"
|
||||
|
||||
if(use_skintones)
|
||||
if(sexes)
|
||||
icon_state_string = "[H.skin_tone]_[g]_s"
|
||||
else
|
||||
icon_state_string = "[H.skin_tone]_s"
|
||||
else
|
||||
icon_state_string += "_s"
|
||||
if(sexes)
|
||||
icon_state_string += "[g]_s"
|
||||
else
|
||||
icon_state_string += "_s"
|
||||
|
||||
spec_base = image("icon" = 'icons/mob/human.dmi', "icon_state" = icon_state_string, "layer" = -SPECIES_LAYER)
|
||||
|
||||
spec_base.color = "#[H.dna.features["mcolor"]]"
|
||||
if(!forced_colour && !use_skintones)
|
||||
spec_base.color = "#[H.dna.features["mcolor"]]"
|
||||
else
|
||||
spec_base.color = forced_colour
|
||||
|
||||
standing = spec_base
|
||||
|
||||
if(standing)
|
||||
@@ -143,7 +154,7 @@
|
||||
|
||||
H.apply_overlay(SPECIES_LAYER)
|
||||
|
||||
/datum/species/proc/handle_hair(mob/living/carbon/human/H)
|
||||
/datum/species/proc/handle_hair(mob/living/carbon/human/H, forced_colour)
|
||||
H.remove_overlay(HAIR_LAYER)
|
||||
|
||||
var/datum/sprite_accessory/S
|
||||
@@ -156,13 +167,17 @@
|
||||
|
||||
img_facial_s = image("icon" = S.icon, "icon_state" = "[S.icon_state]_s", "layer" = -HAIR_LAYER)
|
||||
|
||||
if(hair_color)
|
||||
if(hair_color == "mutcolor")
|
||||
img_facial_s.color = "#" + H.dna.features["mcolor"]
|
||||
if(!forced_colour)
|
||||
if(hair_color)
|
||||
if(hair_color == "mutcolor")
|
||||
img_facial_s.color = "#" + H.dna.features["mcolor"]
|
||||
else
|
||||
img_facial_s.color = "#" + hair_color
|
||||
else
|
||||
img_facial_s.color = "#" + hair_color
|
||||
img_facial_s.color = "#" + H.facial_hair_color
|
||||
else
|
||||
img_facial_s.color = "#" + H.facial_hair_color
|
||||
img_facial_s.color = forced_colour
|
||||
|
||||
img_facial_s.alpha = hair_alpha
|
||||
|
||||
standing += img_facial_s
|
||||
@@ -184,13 +199,16 @@
|
||||
|
||||
img_hair_s = image("icon" = S.icon, "icon_state" = "[S.icon_state]_s", "layer" = -HAIR_LAYER)
|
||||
|
||||
if(hair_color)
|
||||
if(hair_color == "mutcolor")
|
||||
img_hair_s.color = "#" + H.dna.features["mcolor"]
|
||||
if(!forced_colour)
|
||||
if(hair_color)
|
||||
if(hair_color == "mutcolor")
|
||||
img_hair_s.color = "#" + H.dna.features["mcolor"]
|
||||
else
|
||||
img_hair_s.color = "#" + hair_color
|
||||
else
|
||||
img_hair_s.color = "#" + hair_color
|
||||
img_hair_s.color = "#" + H.hair_color
|
||||
else
|
||||
img_hair_s.color = "#" + H.hair_color
|
||||
img_hair_s.color = forced_colour
|
||||
img_hair_s.alpha = hair_alpha
|
||||
|
||||
standing += img_hair_s
|
||||
@@ -246,7 +264,7 @@
|
||||
|
||||
return
|
||||
|
||||
/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H)
|
||||
/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour)
|
||||
var/list/bodyparts_to_add = mutant_bodyparts.Copy()
|
||||
var/list/relevent_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
var/list/standing = list()
|
||||
@@ -359,18 +377,21 @@
|
||||
I = image("icon" = 'icons/mob/mutant_bodyparts.dmi', "icon_state" = icon_string, "layer" =- layer)
|
||||
|
||||
if(!(H.disabilities & HUSK))
|
||||
switch(S.color_src)
|
||||
if(MUTCOLORS)
|
||||
I.color = "#[H.dna.features["mcolor"]]"
|
||||
if(HAIR)
|
||||
if(hair_color == "mutcolor")
|
||||
if(!forced_colour)
|
||||
switch(S.color_src)
|
||||
if(MUTCOLORS)
|
||||
I.color = "#[H.dna.features["mcolor"]]"
|
||||
else
|
||||
I.color = "#[H.hair_color]"
|
||||
if(FACEHAIR)
|
||||
I.color = "#[H.facial_hair_color]"
|
||||
if(EYECOLOR)
|
||||
I.color = "#[H.eye_color]"
|
||||
if(HAIR)
|
||||
if(hair_color == "mutcolor")
|
||||
I.color = "#[H.dna.features["mcolor"]]"
|
||||
else
|
||||
I.color = "#[H.hair_color]"
|
||||
if(FACEHAIR)
|
||||
I.color = "#[H.facial_hair_color]"
|
||||
if(EYECOLOR)
|
||||
I.color = "#[H.eye_color]"
|
||||
else
|
||||
I.color = forced_colour
|
||||
standing += I
|
||||
|
||||
if(S.hasinner)
|
||||
|
||||
@@ -53,7 +53,6 @@ Please contact me on #coderbus IRC. ~Carnie x
|
||||
*/
|
||||
|
||||
/mob/living/carbon/human/proc/update_base_icon_state()
|
||||
//var/race = dna ? dna.mutantrace : null
|
||||
if(dna)
|
||||
base_icon_state = dna.species.update_base_icon_state(src)
|
||||
else
|
||||
@@ -68,7 +67,6 @@ Please contact me on #coderbus IRC. ~Carnie x
|
||||
//UPDATES OVERLAYS FROM OVERLAYS_STANDING
|
||||
//TODO: Remove all instances where this proc is called. It used to be the fastest way to swap between standing/lying.
|
||||
/mob/living/carbon/human/update_icons()
|
||||
|
||||
update_hud() //TODO: remove the need for this
|
||||
|
||||
if(overlays.len != overlays_standing.len)
|
||||
@@ -79,7 +77,6 @@ Please contact me on #coderbus IRC. ~Carnie x
|
||||
|
||||
update_transform()
|
||||
|
||||
|
||||
//DAMAGE OVERLAYS
|
||||
//constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists
|
||||
/mob/living/carbon/human/update_damage_overlays()
|
||||
@@ -123,14 +120,9 @@ Please contact me on #coderbus IRC. ~Carnie x
|
||||
/mob/living/carbon/human/proc/update_body()
|
||||
remove_overlay(BODY_LAYER)
|
||||
|
||||
update_base_icon_state()
|
||||
|
||||
if(dna)
|
||||
base_icon_state = dna.species.update_base_icon_state(src)
|
||||
else
|
||||
update_base_icon_state()
|
||||
|
||||
icon_state = "[base_icon_state]_s"
|
||||
|
||||
if(dna) // didn't want to have a duplicate if(dna) here, but due to the ordering of the code this was the only way
|
||||
dna.species.handle_body(src)
|
||||
|
||||
/mob/living/carbon/human/update_fire()
|
||||
@@ -370,7 +362,15 @@ Please contact me on #coderbus IRC. ~Carnie x
|
||||
standing = image("icon"='icons/mob/feet.dmi', "icon_state"="[shoes.icon_state]", "layer"=-layer2use)
|
||||
overlays_standing[SHOES_LAYER] = standing
|
||||
|
||||
//Bloody shoes
|
||||
var/obj/item/clothing/shoes/S = shoes
|
||||
var/bloody = 0
|
||||
if(shoes.blood_DNA)
|
||||
bloody = 1
|
||||
else
|
||||
bloody = S.bloody_shoes[BLOOD_STATE_HUMAN]
|
||||
|
||||
if(bloody)
|
||||
standing.overlays += image("icon"='icons/effects/blood.dmi', "icon_state"="shoeblood")
|
||||
|
||||
apply_overlay(SHOES_LAYER)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/monkey/emote(act)
|
||||
/mob/living/carbon/monkey/emote(act,m_type=1,message = null)
|
||||
|
||||
var/param = null
|
||||
if (findtext(act, "-", 1, null))
|
||||
@@ -6,10 +6,7 @@
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
|
||||
var/muzzled = is_muzzled()
|
||||
var/m_type = 1
|
||||
var/message
|
||||
|
||||
switch(act) //Ooh ooh ah ah keep this alphabetical ooh ooh ah ah!
|
||||
if ("deathgasp","deathgasps")
|
||||
@@ -21,15 +18,19 @@
|
||||
message = "<B>[src]</B> gnarls and shows its teeth.."
|
||||
m_type = 2
|
||||
|
||||
if ("paw")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flails its paw."
|
||||
m_type = 1
|
||||
if ("me")
|
||||
..()
|
||||
return
|
||||
|
||||
if ("moan","moans")
|
||||
message = "<B>[src]</B> moans!"
|
||||
m_type = 2
|
||||
|
||||
if ("paw")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flails its paw."
|
||||
m_type = 1
|
||||
|
||||
if ("roar","roars")
|
||||
if (!muzzled)
|
||||
message = "<B>[src]</B> roars."
|
||||
@@ -67,7 +68,7 @@
|
||||
src << "Help for monkey emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, dance, deathgasp, drool, flap, frown, gasp, gnarl, giggle, glare-(none)/mob, grin, jump, laugh, look, me, moan, nod, paw, point-(atom), roar, roll, scream, scratch, screech, shake, shiver, sigh, sign-#, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tail, tremble, twitch, twitch_s, wave whimper, wink, yawn"
|
||||
|
||||
else
|
||||
..(act)
|
||||
..()
|
||||
|
||||
if ((message && src.stat == 0))
|
||||
if(src.client)
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
set invisibility = 0
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
if(digitalinvis)
|
||||
handle_diginvis() //AI becomes unable to see mob
|
||||
|
||||
if (notransform)
|
||||
return
|
||||
if(!loc)
|
||||
@@ -66,6 +69,14 @@
|
||||
/mob/living/proc/handle_chemicals_in_body()
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_diginvis()
|
||||
if(!digitaldisguise)
|
||||
src.digitaldisguise = image(loc = src)
|
||||
src.digitaldisguise.override = 1
|
||||
for(var/mob/living/silicon/ai/AI in player_list)
|
||||
AI.client.images |= src.digitaldisguise
|
||||
|
||||
|
||||
/mob/living/proc/handle_blood()
|
||||
return
|
||||
|
||||
|
||||
@@ -839,7 +839,7 @@ Sorry Giacom. Please don't be mad :(
|
||||
|
||||
else if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
|
||||
var/obj/machinery/atmospherics/components/unary/cryo_cell/C = loc
|
||||
var/datum/gas_mixture/G = C.airs["a1"]
|
||||
var/datum/gas_mixture/G = C.AIR1
|
||||
|
||||
if(G.total_moles() < 10)
|
||||
loc_temp = environment.temperature
|
||||
@@ -883,7 +883,7 @@ Sorry Giacom. Please don't be mad :(
|
||||
return 0
|
||||
if(invisibility || alpha == 0)//cloaked
|
||||
return 0
|
||||
if(digitalcamo)
|
||||
if(digitalcamo || digitalinvis)
|
||||
return 0
|
||||
|
||||
// Now, are they viewable by a camera? (This is last because it's the most intensive check)
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
if(!on_fire)
|
||||
return 1
|
||||
if(fire_stacks > 0)
|
||||
adjust_fire_stacks(-0.2) //the fire is slowly consumed
|
||||
adjust_fire_stacks(-0.1) //the fire is slowly consumed
|
||||
else
|
||||
ExtinguishMob()
|
||||
return
|
||||
@@ -145,7 +145,7 @@
|
||||
location.hotspot_expose(700, 50, 1)
|
||||
|
||||
/mob/living/fire_act()
|
||||
adjust_fire_stacks(0.5)
|
||||
adjust_fire_stacks(3)
|
||||
IgniteMob()
|
||||
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ var/list/ai_list = list()
|
||||
shuttle_caller_list -= src
|
||||
SSshuttle.autoEvac()
|
||||
qdel(eyeobj) // No AI, no Eye
|
||||
..()
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/silicon/ai/verb/pick_icon()
|
||||
@@ -300,9 +300,8 @@ var/list/ai_list = list()
|
||||
onclose(src, "airoster")
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_call_shuttle()
|
||||
if(src.stat == DEAD)
|
||||
src << "You can't call the shuttle because you are dead!"
|
||||
return
|
||||
if(stat == 2)
|
||||
return //won't work if dead
|
||||
if(istype(usr,/mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/AI = src
|
||||
if(AI.control_disabled)
|
||||
@@ -330,6 +329,8 @@ var/list/ai_list = list()
|
||||
set name = "Toggle Floor Bolts"
|
||||
if(!isturf(loc)) // if their location isn't a turf
|
||||
return // stop
|
||||
if(stat == 2)
|
||||
return //won't work if dead
|
||||
anchored = !anchored // Toggles the anchor
|
||||
|
||||
src << "[anchored ? "<b>You are now anchored.</b>" : "<b>You are now unanchored.</b>"]"
|
||||
@@ -340,9 +341,8 @@ var/list/ai_list = list()
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_cancel_call()
|
||||
set category = "Malfunction"
|
||||
if(src.stat == 2)
|
||||
src << "You can't send the shuttle back because you are dead!"
|
||||
return
|
||||
if(stat == 2)
|
||||
return //won't work if dead
|
||||
if(istype(usr,/mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/AI = src
|
||||
if(AI.control_disabled)
|
||||
@@ -507,8 +507,7 @@ var/list/ai_list = list()
|
||||
set name = "Access Robot Control"
|
||||
set desc = "Wirelessly control various automatic robots."
|
||||
if(stat == 2)
|
||||
src << "<span class='danger'>Critical error. System offline.</span>"
|
||||
return
|
||||
return //won't work if dead
|
||||
|
||||
if(control_disabled)
|
||||
src << "Wireless communication is disabled."
|
||||
@@ -623,9 +622,8 @@ var/list/ai_list = list()
|
||||
cameraFollow = null
|
||||
var/cameralist[0]
|
||||
|
||||
if(usr.stat == 2)
|
||||
usr << "You can't change your camera network because you are dead!"
|
||||
return
|
||||
if(stat == 2)
|
||||
return //won't work if dead
|
||||
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
|
||||
@@ -668,9 +666,8 @@ var/list/ai_list = list()
|
||||
set category = "AI Commands"
|
||||
set name = "AI Status"
|
||||
|
||||
if(usr.stat == 2)
|
||||
usr <<"You cannot change your emotional status because you are dead!"
|
||||
return
|
||||
if(stat == 2)
|
||||
return //won't work if dead
|
||||
var/list/ai_emotions = list("Very Happy", "Happy", "Neutral", "Unsure", "Confused", "Sad", "BSOD", "Blank", "Problems?", "Awesome", "Facepalm", "Friend Computer", "Dorfy", "Blue Glow", "Red Glow")
|
||||
var/emote = input("Please, select a status!", "AI Status", null, null) in ai_emotions
|
||||
for (var/obj/machinery/M in machines) //change status
|
||||
@@ -693,6 +690,8 @@ var/list/ai_list = list()
|
||||
set desc = "Change the default hologram available to AI to something else."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(stat == 2)
|
||||
return //won't work if dead
|
||||
var/input
|
||||
if(alert("Would you like to select a hologram based on a crew member or switch to unique avatar?",,"Crew Member","Unique")=="Crew Member")
|
||||
|
||||
@@ -788,6 +787,8 @@ var/list/ai_list = list()
|
||||
set desc = "Allows you to change settings of your radio."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(stat == 2)
|
||||
return //won't work if dead
|
||||
src << "Accessing Subspace Transceiver control..."
|
||||
if (radio)
|
||||
radio.interact(src)
|
||||
@@ -801,6 +802,8 @@ var/list/ai_list = list()
|
||||
set desc = "Modify the default radio setting for your automatic announcements."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(stat == 2)
|
||||
return //won't work if dead
|
||||
set_autosay()
|
||||
|
||||
/mob/living/silicon/ai/attack_slime(mob/living/simple_animal/slime/user)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
else
|
||||
icon_state = "ai_dead"
|
||||
|
||||
anchored = 0 //unbolt floorbolts
|
||||
update_canmove()
|
||||
if(src.eyeobj)
|
||||
src.eyeobj.setLoc(get_turf(src))
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
/mob/camera/aiEye/Destroy()
|
||||
ai = null
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/atom/proc/move_camera_by_click()
|
||||
if(istype(usr, /mob/living/silicon/ai))
|
||||
@@ -100,5 +100,7 @@
|
||||
set category = "AI Commands"
|
||||
set name = "Toggle Camera Acceleration"
|
||||
|
||||
if(usr.stat == 2)
|
||||
return //won't work if dead
|
||||
acceleration = !acceleration
|
||||
usr << "Camera acceleration has been toggled [acceleration ? "on" : "off"]."
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/obj/structure/Destroy()
|
||||
if(ticker)
|
||||
cameranet.updateVisibility(src)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/structure/New()
|
||||
..()
|
||||
@@ -38,7 +38,7 @@
|
||||
/obj/effect/Destroy()
|
||||
if(ticker)
|
||||
cameranet.updateVisibility(src)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/effect/New()
|
||||
..()
|
||||
@@ -94,6 +94,6 @@
|
||||
/obj/machinery/camera/Destroy()
|
||||
cameranet.cameras -= src
|
||||
cameranet.removeCamera(src)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
#undef BORG_CAMERA_BUFFER
|
||||
@@ -2,6 +2,8 @@
|
||||
/mob/living/silicon/ai/proc/show_laws_verb()
|
||||
set category = "AI Commands"
|
||||
set name = "Show Laws"
|
||||
if(usr.stat == 2)
|
||||
return //won't work if dead
|
||||
src.show_laws()
|
||||
|
||||
/mob/living/silicon/ai/show_laws(everyone = 0)
|
||||
|
||||
@@ -69,6 +69,8 @@ var/const/VOX_DELAY = 600
|
||||
set desc = "Display a list of vocal words to announce to the crew."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(usr.stat == 2)
|
||||
return //won't work if dead
|
||||
|
||||
var/dat = "Here is a list of words you can type into the 'Announcement' button to create sentences to vocally announce to everyone on the same level at you.<BR> \
|
||||
<UL><LI>You can also click on the word to preview it.</LI>\
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
return
|
||||
if(!gibbed)
|
||||
emote("deathgasp")
|
||||
locked = 0 //unlock cover
|
||||
stat = DEAD
|
||||
update_canmove()
|
||||
if(camera)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/mob/living/silicon/robot/verb/cmd_show_laws()
|
||||
set category = "Robot Commands"
|
||||
set name = "Show Laws"
|
||||
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
show_laws()
|
||||
|
||||
/mob/living/silicon/robot/show_laws(everyone = 0)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
var/custom_name = ""
|
||||
designation = "Default" //used for displaying the prefix & getting the current module of cyborg
|
||||
has_limbs = 1
|
||||
var/magpulse = 0
|
||||
|
||||
//Hud stuff
|
||||
|
||||
@@ -36,6 +37,7 @@
|
||||
|
||||
var/opened = 0
|
||||
var/emagged = 0
|
||||
var/emag_cooldown = 0
|
||||
var/wiresexposed = 0
|
||||
var/locked = 1
|
||||
var/list/req_access = list(access_robotics)
|
||||
@@ -138,7 +140,13 @@
|
||||
mmi = null
|
||||
if(connected_ai)
|
||||
connected_ai.connected_robots -= src
|
||||
..()
|
||||
qdel(wires)
|
||||
qdel(module)
|
||||
wires = null
|
||||
module = null
|
||||
camera = null
|
||||
cell = null
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/silicon/robot/proc/pick_module()
|
||||
@@ -213,6 +221,7 @@
|
||||
animation_length = 45
|
||||
modtype = "Eng"
|
||||
feedback_inc("cyborg_engineering",1)
|
||||
magpulse = 1
|
||||
|
||||
if("Janitor")
|
||||
module = new /obj/item/weapon/robot_module/janitor(src)
|
||||
@@ -255,6 +264,8 @@
|
||||
/mob/living/silicon/robot/verb/cmd_robot_alerts()
|
||||
set category = "Robot Commands"
|
||||
set name = "Show Alerts"
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
robot_alerts()
|
||||
|
||||
//for borg hotkeys, here module refers to borg inv slot, not core module
|
||||
@@ -462,7 +473,7 @@
|
||||
user << "<span class='notice'>You insert the power cell.</span>"
|
||||
update_icons()
|
||||
|
||||
else if (istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/device/multitool) || istype(W, /obj/item/device/assembly/signaler))
|
||||
else if (wires.IsInteractionTool(W))
|
||||
if (wiresexposed)
|
||||
wires.Interact(user)
|
||||
else
|
||||
@@ -570,11 +581,26 @@
|
||||
user << "<span class='warning'>The cover is already unlocked!</span>"
|
||||
return
|
||||
if(opened)//Cover is open
|
||||
if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice
|
||||
if((world.time - 100) < emag_cooldown)
|
||||
return
|
||||
|
||||
var/ai_is_antag = 0
|
||||
if(connected_ai && connected_ai.mind)
|
||||
if(connected_ai.mind.special_role)
|
||||
ai_is_antag = (connected_ai.mind.special_role == "malfunction") || (connected_ai.mind.special_role == "traitor")
|
||||
if(ai_is_antag)
|
||||
user << "<span class='notice'>You emag [src]'s interface.</span>"
|
||||
src << "<span class='danger'>ALERT: Foreign software execution prevented.</span>"
|
||||
connected_ai << "<span class='danger'>ALERT: Cyborg unit \[[src]] successfuly defended against subversion.</span>"
|
||||
log_game("[key_name(user)] attempted to emag cyborg [key_name(src)] slaved to traitor AI [connected_ai].")
|
||||
emag_cooldown = world.time
|
||||
return
|
||||
|
||||
if(wiresexposed)
|
||||
user << "<span class='warning'>You must close the cover first!</span>"
|
||||
return
|
||||
else
|
||||
emag_cooldown = world.time
|
||||
sleep(6)
|
||||
SetEmagged(1)
|
||||
SetLockdown(1) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown
|
||||
@@ -613,6 +639,8 @@
|
||||
set category = "Robot Commands"
|
||||
set name = "Unlock Cover"
|
||||
set desc = "Unlocks your own cover if it is locked. You can not lock it again. A human will have to lock it for you."
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
if(locked)
|
||||
switch(alert("You can not lock your cover again, are you sure?\n (You can still ask for a human to lock it)", "Unlock Own Cover", "Yes", "No"))
|
||||
if("Yes")
|
||||
@@ -862,9 +890,6 @@
|
||||
var/turf/tile = loc
|
||||
if(isturf(tile))
|
||||
tile.clean_blood()
|
||||
if (istype(tile, /turf/simulated/floor))
|
||||
var/turf/simulated/floor/F = tile
|
||||
F.dirt = 0
|
||||
for(var/A in tile)
|
||||
if(istype(A, /obj/effect))
|
||||
if(is_cleanable(A))
|
||||
@@ -981,12 +1006,17 @@
|
||||
set category = "Robot Commands"
|
||||
set name = "State Laws"
|
||||
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
checklaws()
|
||||
|
||||
/mob/living/silicon/robot/verb/set_automatic_say_channel() //Borg version of setting the radio for autosay messages.
|
||||
set name = "Set Auto Announce Mode"
|
||||
set desc = "Modify the default radio setting for stating your laws."
|
||||
set category = "Robot Commands"
|
||||
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
set_autosay()
|
||||
|
||||
/mob/living/silicon/robot/proc/control_headlamp()
|
||||
@@ -1054,7 +1084,7 @@
|
||||
new /obj/item/robot_parts/head(T)
|
||||
var/b
|
||||
for(b=0, b!=2, b++)
|
||||
var/obj/item/device/flash/handheld/F = new /obj/item/device/flash/handheld(T)
|
||||
var/obj/item/device/assembly/flash/handheld/F = new /obj/item/device/assembly/flash/handheld(T)
|
||||
F.burn_out()
|
||||
if (cell) //Sanity check.
|
||||
cell.loc = T
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
var/obj/item/emag = null
|
||||
var/list/storages = list()
|
||||
|
||||
/obj/item/weapon/robot_module/Destroy()
|
||||
modules.Cut()
|
||||
emag = null
|
||||
storages.Cut()
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/robot_module/emp_act(severity)
|
||||
if(modules)
|
||||
for(var/obj/O in modules)
|
||||
@@ -34,7 +40,7 @@
|
||||
|
||||
|
||||
/obj/item/weapon/robot_module/New()
|
||||
modules += new /obj/item/device/flash/cyborg(src)
|
||||
modules += new /obj/item/device/assembly/flash/cyborg(src)
|
||||
emag = new /obj/item/toy/sword(src)
|
||||
emag.name = "Placeholder Emag Item"
|
||||
return
|
||||
|
||||
@@ -13,3 +13,13 @@
|
||||
tally = speed
|
||||
|
||||
return tally+config.robot_delay
|
||||
|
||||
/mob/living/silicon/robot/mob_negates_gravity()
|
||||
return magpulse
|
||||
|
||||
/mob/living/silicon/robot/mob_has_gravity()
|
||||
return ..() || mob_negates_gravity()
|
||||
|
||||
/mob/living/silicon/robot/experience_pressure_difference(pressure_difference, direction)
|
||||
if(!magpulse)
|
||||
return ..()
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
if(istype(src, /mob/living/silicon))
|
||||
var/mob/living/silicon/S = src
|
||||
desig = trim_left(S.designation + " " + S.job)
|
||||
var/message_a = say_quote(message)
|
||||
var/message_a = say_quote(message, get_spans())
|
||||
var/rendered = "<i><span class='game say'>Robotic Talk, <span class='name'>[name]</span> <span class='message'>[message_a]</span></span></i>"
|
||||
for(var/mob/M in player_list)
|
||||
if(M.binarycheck() || (M in dead_mob_list))
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
|
||||
var/law_change_counter = 0
|
||||
|
||||
/mob/living/silicon/Destroy()
|
||||
radio = null
|
||||
aicamera = null
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/contents_explosion(severity, target)
|
||||
return
|
||||
|
||||
@@ -381,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
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
ventcrawler = 2
|
||||
mob_size = MOB_SIZE_TINY
|
||||
gold_core_spawnable = 2
|
||||
|
||||
/mob/living/simple_animal/butterfly/New()
|
||||
..()
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
gold_core_spawnable = 2
|
||||
|
||||
//RUNTIME IS ALIVE! SQUEEEEEEEE~
|
||||
/mob/living/simple_animal/pet/cat/Runtime
|
||||
@@ -31,6 +32,7 @@
|
||||
gender = FEMALE
|
||||
var/turns_since_scan = 0
|
||||
var/mob/living/simple_animal/mouse/movement_target
|
||||
gold_core_spawnable = 0
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/Life()
|
||||
//MICE!
|
||||
@@ -69,6 +71,7 @@
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Proc
|
||||
name = "Proc"
|
||||
gold_core_spawnable = 0
|
||||
|
||||
/mob/living/simple_animal/pet/cat/kitten
|
||||
name = "kitten"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
ventcrawler = 2
|
||||
var/obj/item/inventory_head
|
||||
var/obj/item/inventory_mask
|
||||
gold_core_spawnable = 2
|
||||
|
||||
/mob/living/simple_animal/crab/Life()
|
||||
..()
|
||||
@@ -40,4 +41,5 @@
|
||||
desc = "It's Coffee, the other pet!"
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "stomps"
|
||||
response_harm = "stomps"
|
||||
gold_core_spawnable = 0
|
||||
@@ -29,6 +29,7 @@
|
||||
var/obj/item/inventory_head
|
||||
var/obj/item/inventory_back
|
||||
var/facehugger
|
||||
gold_core_spawnable = 2
|
||||
|
||||
/mob/living/simple_animal/pet/dog/pug
|
||||
name = "\improper pug"
|
||||
@@ -39,6 +40,7 @@
|
||||
icon_living = "pug"
|
||||
icon_dead = "pug_dead"
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/pug = 3)
|
||||
gold_core_spawnable = 2
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/New()
|
||||
..()
|
||||
@@ -275,7 +277,9 @@
|
||||
return valid
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/proc/update_corgi_fluff()
|
||||
switch(src.inventory_head.type)
|
||||
if(!inventory_head)
|
||||
return
|
||||
switch(inventory_head.type)
|
||||
if(/obj/item/clothing/head/helmet)
|
||||
name = "Sergeant [real_name]"
|
||||
desc = "The ever-loyal, the ever-vigilant."
|
||||
@@ -388,6 +392,7 @@
|
||||
response_help = "pets"
|
||||
response_disarm = "bops"
|
||||
response_harm = "kicks"
|
||||
gold_core_spawnable = 0
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/Life()
|
||||
..()
|
||||
@@ -511,6 +516,7 @@
|
||||
response_harm = "kicks"
|
||||
var/turns_since_scan = 0
|
||||
var/puppies = 0
|
||||
gold_core_spawnable = 0
|
||||
|
||||
//Lisa already has a cute bow!
|
||||
/mob/living/simple_animal/pet/dog/corgi/Lisa/Topic(href, href_list)
|
||||
@@ -532,7 +538,7 @@
|
||||
dir = i
|
||||
sleep(1)
|
||||
|
||||
/mob/living/simple_animal/pet/pug/Life()
|
||||
/mob/living/simple_animal/pet/dog/pug/Life()
|
||||
..()
|
||||
|
||||
if(!stat && !resting && !buckled)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
wander = 0
|
||||
speed = 0
|
||||
ventcrawler = 2
|
||||
healable = 0
|
||||
density = 0
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
sight = (SEE_TURFS | SEE_OBJS)
|
||||
@@ -79,7 +80,7 @@
|
||||
|
||||
/mob/living/simple_animal/drone/Destroy()
|
||||
qdel(access_card) //Otherwise it ends up on the floor!
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/drone/Login()
|
||||
..()
|
||||
|
||||
@@ -25,11 +25,14 @@
|
||||
melee_damage_upper = 2
|
||||
environment_smash = 0
|
||||
stop_automated_movement_when_pulled = 1
|
||||
var/datum/reagents/udder = null
|
||||
var/obj/udder/udder = null
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/New()
|
||||
udder = new(50)
|
||||
udder.my_atom = src
|
||||
udder = new()
|
||||
..()
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/Destroy()
|
||||
qdel(udder)
|
||||
udder = null
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/Life()
|
||||
@@ -43,15 +46,11 @@
|
||||
enemies = list()
|
||||
LoseTarget()
|
||||
src.visible_message("<span class='notice'>[src] calms down.</span>")
|
||||
|
||||
if(stat == CONSCIOUS)
|
||||
if(udder && prob(5))
|
||||
udder.add_reagent("milk", rand(5, 10))
|
||||
|
||||
udder.generateMilk()
|
||||
if(locate(/obj/effect/spacevine) in loc)
|
||||
var/obj/effect/spacevine/SV = locate(/obj/effect/spacevine) in loc
|
||||
SV.eat(src)
|
||||
|
||||
if(!pulledby)
|
||||
for(var/direction in shuffle(list(1,2,4,8,5,6,9,10)))
|
||||
var/step = get_step(src, direction)
|
||||
@@ -70,18 +69,12 @@
|
||||
var/obj/effect/spacevine/SV = locate(/obj/effect/spacevine) in loc
|
||||
SV.eat(src)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/attackby(obj/item/O, mob/user, params)
|
||||
if(stat == CONSCIOUS && istype(O, /obj/item/weapon/reagent_containers/glass))
|
||||
user.visible_message("[user] milks [src] using \the [O].", "<span class='notice'>You milk [src] using \the [O].</span>")
|
||||
var/obj/item/weapon/reagent_containers/glass/G = O
|
||||
var/transfered = udder.trans_id_to(G, "milk", rand(5,10))
|
||||
if(G.reagents.total_volume >= G.volume)
|
||||
user << "<span class='warning'>[O] is full!</span>"
|
||||
if(!transfered)
|
||||
user << "<span class='warning'>The udder is dry! Wait a bit longer...</span>"
|
||||
udder.milkAnimal(O, user)
|
||||
else
|
||||
..()
|
||||
|
||||
//cow
|
||||
/mob/living/simple_animal/cow
|
||||
name = "cow"
|
||||
@@ -104,30 +97,28 @@
|
||||
attacktext = "kicks"
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
health = 50
|
||||
var/datum/reagents/udder = null
|
||||
var/obj/udder/udder = null
|
||||
gold_core_spawnable = 2
|
||||
|
||||
/mob/living/simple_animal/cow/New()
|
||||
udder = new(50)
|
||||
udder.my_atom = src
|
||||
udder = new()
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/cow/Destroy()
|
||||
qdel(udder)
|
||||
udder = null
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/cow/attackby(obj/item/O, mob/user, params)
|
||||
if(stat == CONSCIOUS && istype(O, /obj/item/weapon/reagent_containers/glass))
|
||||
user.visible_message("[user] milks [src] using \the [O].", "<span class='notice'>You milk [src] using \the [O].</span>")
|
||||
var/obj/item/weapon/reagent_containers/glass/G = O
|
||||
var/transfered = udder.trans_id_to(G, "milk", rand(5,10))
|
||||
if(G.reagents.total_volume >= G.volume)
|
||||
user << "<span class='danger'>[O] is full.</span>"
|
||||
if(!transfered)
|
||||
user << "<span class='danger'>The udder is dry. Wait a bit longer...</span>"
|
||||
udder.milkAnimal(O, user)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/cow/Life()
|
||||
. = ..()
|
||||
if(stat == CONSCIOUS)
|
||||
if(udder && prob(5))
|
||||
udder.add_reagent("milk", rand(5, 10))
|
||||
udder.generateMilk()
|
||||
|
||||
/mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M)
|
||||
if(!stat && M.a_intent == "disarm" && icon_state != icon_dead)
|
||||
@@ -169,6 +160,7 @@
|
||||
var/amount_grown = 0
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
mob_size = MOB_SIZE_TINY
|
||||
gold_core_spawnable = 2
|
||||
|
||||
/mob/living/simple_animal/chick/New()
|
||||
..()
|
||||
@@ -219,6 +211,7 @@ var/global/chicken_count = 0
|
||||
var/list/feedMessages = list("It clucks happily.","It clucks happily.")
|
||||
var/list/layMessage = list("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")
|
||||
var/list/validColors = list("brown","black","white")
|
||||
gold_core_spawnable = 2
|
||||
|
||||
/mob/living/simple_animal/chicken/New()
|
||||
..()
|
||||
@@ -274,3 +267,29 @@ var/global/chicken_count = 0
|
||||
qdel(src)
|
||||
else
|
||||
SSobj.processing.Remove(src)
|
||||
|
||||
/obj/udder
|
||||
|
||||
/obj/udder/New()
|
||||
reagents = new(50)
|
||||
reagents.my_atom = src
|
||||
reagents.add_reagent("milk", 20)
|
||||
|
||||
/obj/udder/proc/generateMilk()
|
||||
if(prob(5))
|
||||
reagents.add_reagent("milk", rand(5, 10))
|
||||
|
||||
/obj/udder/proc/milkAnimal(obj/O, mob/user)
|
||||
var/obj/item/weapon/reagent_containers/glass/G = O
|
||||
if(G.reagents.total_volume >= G.volume)
|
||||
user << "<span class='danger'>[O] is full.</span>"
|
||||
return
|
||||
var/transfered = reagents.trans_id_to(G, "milk", rand(5,10))
|
||||
if(transfered)
|
||||
user.visible_message("[user] milks [src] using \the [O].", "<span class='notice'>You milk [src] using \the [O].</span>")
|
||||
else
|
||||
user << "<span class='danger'>The udder is dry. Wait a bit longer...</span>"
|
||||
|
||||
/obj/udder/Destroy()
|
||||
qdel(reagents)
|
||||
..()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user