This commit is contained in:
DJSnapshot
2014-02-04 15:10:13 -08:00
519 changed files with 31380 additions and 24560 deletions
+3
View File
@@ -58,6 +58,9 @@ var/savefile/Banlist
CMinutes = (world.realtime / 10) / 60
return 1
/hook/startup/proc/loadBans()
return LoadBans()
/proc/LoadBans()
Banlist = new("data/banlist.bdb")
+22 -11
View File
@@ -581,7 +581,8 @@ var/global/floorIsLava = 0
<A href='?src=\ref[src];secretsfun=gravanomalies'>Spawn a gravitational anomaly (aka lagitational anomolag)</A><BR>
<A href='?src=\ref[src];secretsfun=timeanomalies'>Spawn wormholes</A><BR>
<A href='?src=\ref[src];secretsfun=goblob'>Spawn blob</A><BR>
<A href='?src=\ref[src];secretsfun=aliens'>Trigger an Alien infestation</A><BR>
<A href='?src=\ref[src];secretsfun=aliens'>Trigger a Xenomorph infestation</A><BR>
<A href='?src=\ref[src];secretsfun=borers'>Trigger a Cortical Borer infestation</A><BR>
<A href='?src=\ref[src];secretsfun=alien_silent'>Spawn an Alien silently</A><BR>
<A href='?src=\ref[src];secretsfun=spiders'>Trigger a Spider infestation</A><BR>
<A href='?src=\ref[src];secretsfun=spaceninja'>Send in a space ninja</A><BR>
@@ -695,7 +696,7 @@ var/global/floorIsLava = 0
/datum/admins/proc/toggleooc()
set category = "Server"
set desc="Toggle dis bitch"
set desc="Globally Toggles OOC"
set name="Toggle OOC"
ooc_allowed = !( ooc_allowed )
if (ooc_allowed)
@@ -706,6 +707,20 @@ var/global/floorIsLava = 0
message_admins("[key_name_admin(usr)] toggled OOC.", 1)
feedback_add_details("admin_verb","TOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggledsay()
set category = "Server"
set desc="Globally Toggles DSAY"
set name="Toggle DSAY"
dsay_allowed = !( dsay_allowed )
if (dsay_allowed)
world << "<B>Deadchat has been globally enabled!</B>"
else
world << "<B>Deadchat has been globally disabled!</B>"
log_admin("[key_name(usr)] toggled deadchat.")
message_admins("[key_name_admin(usr)] toggled deadchat.", 1)
feedback_add_details("admin_verb","TDSAY") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc
/datum/admins/proc/toggleoocdead()
set category = "Server"
set desc="Toggle dis bitch"
@@ -966,7 +981,11 @@ var/global/floorIsLava = 0
if(!chosen)
return
new chosen(usr.loc)
if(ispath(chosen,/turf))
var/turf/T = get_turf(usr.loc)
T.ChangeTurf(chosen)
else
new chosen(usr.loc)
log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])")
feedback_add_details("admin_verb","SA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -1014,14 +1033,6 @@ var/global/floorIsLava = 0
message_admins("\blue [key_name_admin(usr)] toggled guests game entering [guests_allowed?"":"dis"]allowed.", 1)
feedback_add_details("admin_verb","TGU") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/unjobban_panel()
set name = "Unjobban Panel"
set category = "Admin"
if (src.holder)
src.holder.unjobbanpanel()
feedback_add_details("admin_verb","UJBP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/datum/admins/proc/output_ai_laws()
var/ai_number = 0
for(var/mob/living/silicon/S in mob_list)
+6 -2
View File
@@ -11,6 +11,10 @@
/proc/investigate_subject2file(var/subject)
return file("[INVESTIGATE_DIR][subject].html")
/hook/startup/proc/resetInvestigate()
investigate_reset()
return 1
/proc/investigate_reset()
if(fdel(INVESTIGATE_DIR)) return 1
return 0
@@ -22,12 +26,12 @@
F << "<small>[time2text(world.timeofday,"hh:mm")] \ref[src] ([x],[y],[z])</small> || [src] [message]<br>"
//ADMINVERBS
/client/proc/investigate_show( subject in list("hrefs","notes","singulo") )
/client/proc/investigate_show( subject in list("hrefs","notes","singulo","telesci") )
set name = "Investigate"
set category = "Admin"
if(!holder) return
switch(subject)
if("singulo") //general one-round-only stuff
if("singulo", "telesci") //general one-round-only stuff
var/F = investigate_subject2file(subject)
if(!F)
src << "<font color='red'>Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed.</font>"
+4
View File
@@ -53,6 +53,10 @@ var/list/admin_ranks = list() //list of all ranks with associated rights
#endif
/hook/startup/proc/loadAdmins()
load_admins()
return 1
/proc/load_admins()
//clear the datums references
admin_datums.Cut()
+28 -10
View File
@@ -55,6 +55,7 @@ var/list/admin_verbs_admin = list(
/client/proc/secrets,
/datum/admins/proc/toggleooc, /*toggles ooc on/off for everyone*/
/datum/admins/proc/toggleoocdead, /*toggles ooc on/off for everyone who is dead*/
/datum/admins/proc/toggledsay, /*toggles dsay on/off for everyone*/
/client/proc/game_panel, /*game panel, allows to change game-mode etc*/
/client/proc/cmd_admin_say, /*admin-only ooc chat*/
/datum/admins/proc/PlayerNotes,
@@ -65,17 +66,19 @@ var/list/admin_verbs_admin = list(
/client/proc/cmd_admin_rejuvenate,
/client/proc/toggleattacklogs,
/client/proc/toggledebuglogs,
/client/proc/toggleghostwriters,
/datum/admins/proc/show_skills,
/client/proc/check_customitem_activity,
/client/proc/man_up,
/client/proc/global_man_up,
/client/proc/response_team // Response Teams admin verb
/client/proc/response_team, // Response Teams admin verb
/client/proc/toggle_antagHUD_use,
/client/proc/toggle_antagHUD_restrictions,
/client/proc/allow_character_respawn /* Allows a ghost to respawn */
)
var/list/admin_verbs_ban = list(
/client/proc/unban_panel,
/client/proc/jobbans,
/client/proc/unjobban_panel,
// /client/proc/DB_ban_panel
/client/proc/jobbans
)
var/list/admin_verbs_sounds = list(
/client/proc/play_local_sound,
@@ -127,6 +130,7 @@ var/list/admin_verbs_debug = list(
/client/proc/cmd_admin_list_open_jobs,
/client/proc/Debug2,
/client/proc/kill_air,
/client/proc/ZASSettings,
/client/proc/cmd_debug_make_powernets,
/client/proc/kill_airgroup,
/client/proc/debug_controller,
@@ -139,7 +143,9 @@ var/list/admin_verbs_debug = list(
/client/proc/restart_controller,
/client/proc/enable_debug_verbs,
/client/proc/callproc,
/client/proc/toggledebuglogs
/client/proc/toggledebuglogs,
/client/proc/SDQL_query,
/client/proc/SDQL2_query
)
var/list/admin_verbs_possess = list(
/proc/possess,
@@ -356,14 +362,11 @@ var/list/admin_verbs_mod = list(
if(mob.invisibility == INVISIBILITY_OBSERVER)
mob.invisibility = initial(mob.invisibility)
mob << "\red <b>Invisimin off. Invisibility reset.</b>"
mob.icon_state = "ghost"
mob.icon = 'icons/mob/human.dmi'
mob.update_icons()
mob.alpha = max(mob.alpha + 100, 255)
else
mob.invisibility = INVISIBILITY_OBSERVER
mob << "\blue <b>Invisimin on. You are now as invisible as a ghost.</b>"
mob.icon_state = "ghost"
mob.icon = 'icons/mob/mob.dmi'
mob.alpha = max(mob.alpha - 100, 0)
/client/proc/player_panel()
@@ -724,6 +727,21 @@ var/list/admin_verbs_mod = list(
usr << "You now won't get attack log messages"
/client/proc/toggleghostwriters()
set name = "Toggle ghost writers"
set category = "Server"
if(!holder) return
if(config)
if(config.cult_ghostwriter)
config.cult_ghostwriter = 0
src << "<b>Disallowed ghost writers.</b>"
message_admins("Admin [key_name_admin(usr)] has disabled ghost writers.", 1)
else
config.cult_ghostwriter = 1
src << "<b>Enabled ghost writers.</b>"
message_admins("Admin [key_name_admin(usr)] has enabled ghost writers.", 1)
/client/proc/toggledebuglogs()
set name = "Toggle Debug Log Messages"
set category = "Preferences"
+4 -9
View File
@@ -50,6 +50,10 @@ DEBUG
jobban_loadbanfile()
*/
/hook/startup/proc/loadJobBans()
jobban_loadbanfile()
return 1
/proc/jobban_loadbanfile()
if(config.ban_legacy_system)
var/savefile/S=new("data/job_full.ban")
@@ -101,15 +105,6 @@ DEBUG
text2file(formatted_log,"data/ban_unban_log.txt")
/proc/jobban_updatelegacybans()
if(!jobban_runonce)
log_admin("Updating jobbanfile!")
// Updates bans.. Or fixes them. Either way.
for(var/T in jobban_keylist)
if(!T) continue
jobban_runonce++ //don't run this update again
/proc/jobban_remove(X)
for (var/i = 1; i <= length(jobban_keylist); i++)
if( findtext(jobban_keylist[i], "[X]") )
+1 -1
View File
@@ -2,7 +2,7 @@
/datum/admins/proc/create_mob(var/mob/user)
if (!create_mob_html)
var/mobjs = null
mobjs = dd_list2text(typesof(/mob), ";")
mobjs = list2text(typesof(/mob), ";")
create_mob_html = file2text('html/create_object.html')
create_mob_html = replacetext(create_mob_html, "null /* object types */", "\"[mobjs]\"")
+2 -2
View File
@@ -3,7 +3,7 @@
/datum/admins/proc/create_object(var/mob/user)
if (!create_object_html)
var/objectjs = null
objectjs = dd_list2text(typesof(/obj), ";")
objectjs = list2text(typesof(/obj), ";")
create_object_html = file2text('html/create_object.html')
create_object_html = replacetext(create_object_html, "null /* object types */", "\"[objectjs]\"")
@@ -21,7 +21,7 @@
if (!quick_create_object_html)
var/objectjs = null
objectjs = dd_list2text(typesof(path), ";")
objectjs = list2text(typesof(path), ";")
quick_create_object_html = file2text('html/create_object.html')
quick_create_object_html = replacetext(quick_create_object_html, "null /* object types */", "\"[objectjs]\"")
+1 -1
View File
@@ -2,7 +2,7 @@
/datum/admins/proc/create_turf(var/mob/user)
if (!create_turf_html)
var/turfjs = null
turfjs = dd_list2text(typesof(/turf), ";")
turfjs = list2text(typesof(/turf), ";")
create_turf_html = file2text('html/create_object.html')
create_turf_html = replacetext(create_turf_html, "null /* object types */", "\"[turfjs]\"")
-2
View File
@@ -479,7 +479,6 @@
dat += "<td><A HREF='?src=\ref[src];traitor=\ref[M]'>Show Objective</A></td></tr>"
dat += "</table>"
/*
if(ticker.mode.ninjas.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Ninjas</B></td><td></td><td></td></tr>"
for(var/datum/mind/ninja in ticker.mode.ninjas)
@@ -491,7 +490,6 @@
else
dat += "<tr><td><i>Ninja not found!</i></td></tr>"
dat += "</table>"
*/
if(ticker.mode.cult.len)
dat += "<br><table cellspacing=5><tr><td><B>Cultists</B></td><td></td></tr>"
+34 -21
View File
@@ -511,17 +511,17 @@
jobs += "</tr><tr align='center'>"
counter = 0
if(jobban_isbanned(M, "Internal Affairs Agent"))
if(jobban_isbanned(M, "Internal Affairs Agent"))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Internal Affairs Agent;jobban4=\ref[M]'><font color=red>Internal Affairs Agent</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Internal Affairs Agent;jobban4=\ref[M]'>Internal Affairs Agent</a></td>"
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Internal Affairs Agent;jobban4=\ref[M]'>Internal Affairs Agent</a></td>"
jobs += "</tr></table>"
//Non-Human (Green)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='ccffcc'><th colspan='[length(nonhuman_positions)]'><a href='?src=\ref[src];jobban3=nonhumandept;jobban4=\ref[M]'>Non-human Positions</a></th></tr><tr align='center'>"
jobs += "<tr bgcolor='ccffcc'><th colspan='[length(nonhuman_positions)+1]'><a href='?src=\ref[src];jobban3=nonhumandept;jobban4=\ref[M]'>Non-human Positions</a></th></tr><tr align='center'>"
for(var/jobPos in nonhuman_positions)
if(!jobPos) continue
var/datum/job/job = job_master.GetJob(jobPos)
@@ -539,11 +539,15 @@
counter = 0
//pAI isn't technically a job, but it goes in here.
if(jobban_isbanned(M, "pAI"))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=pAI;jobban4=\ref[M]'><font color=red>pAI</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=pAI;jobban4=\ref[M]'>pAI</a></td>"
if(jobban_isbanned(M, "AntagHUD"))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=AntagHUD;jobban4=\ref[M]'><font color=red>AntagHUD</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=AntagHUD;jobban4=\ref[M]'>AntagHUD</a></td>"
jobs += "</tr></table>"
//Antagonist (Orange)
@@ -614,11 +618,24 @@
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=infested monkey;jobban4=\ref[M]'>[replacetext("Infested Monkey", " ", "&nbsp")]</a></td>"
*/
jobs += "</tr></table>"
//Other races (BLUE, because I have no idea what other color to make this)
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='ccccff'><th colspan='1'>Other Races</th></tr><tr align='center'>"
if(jobban_isbanned(M, "Dionaea"))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Dionaea;jobban4=\ref[M]'><font color=red>Dionaea</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Dionaea;jobban4=\ref[M]'>Dionaea</a></td>"
jobs += "</tr></table>"
body = "<body>[jobs]</body>"
dat = "<tt>[header][body]</tt>"
usr << browse(dat, "window=jobban2;size=800x450")
usr << browse(dat, "window=jobban2;size=800x490")
return
//JOBBAN'S INNARDS
@@ -787,7 +804,11 @@
if (ismob(M))
if(!check_if_greater_rights_than(M.client))
return
M << "\red You have been kicked from the server"
var/reason = input("Please enter reason")
if(!reason)
M << "\red You have been kicked from the server"
else
M << "\red You have been kicked from the server: [reason]"
log_admin("[key_name(usr)] booted [key_name(M)].")
message_admins("\blue [key_name_admin(usr)] booted [key_name_admin(M)].", 1)
//M.client = null
@@ -887,19 +908,6 @@
if("Cancel")
return
else if(href_list["unjobbanf"])
if(!check_rights(R_BAN)) return
var/banfolder = href_list["unjobbanf"]
Banlist.cd = "/base/[banfolder]"
var/key = Banlist["key"]
if(alert(usr, "Are you sure you want to unban [key]?", "Confirmation", "Yes", "No") == "Yes")
if (RemoveBanjob(banfolder))
unjobbanpanel()
else
alert(usr,"This ban has already been lifted / does not exist.","Error","Ok")
unjobbanpanel()
else if(href_list["mute"])
if(!check_rights(R_MOD,0) && !check_rights(R_ADMIN)) return
@@ -1598,7 +1606,7 @@
alert("Select fewer object types, (max 5)")
return
else if(length(removed_paths))
alert("Removed:\n" + dd_list2text(removed_paths, "\n"))
alert("Removed:\n" + list2text(removed_paths, "\n"))
var/list/offset = text2list(href_list["offset"],",")
var/number = dd_range(1, 100, text2num(href_list["object_count"]))
@@ -1769,7 +1777,12 @@
log_admin("[key_name(usr)] spawned an alien infestation", 1)
message_admins("\blue [key_name_admin(usr)] attempted an alien infestation", 1)
new /datum/event/alien_infestation
if("borers")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","Borers")
log_admin("[key_name(usr)] spawned a cortical borer infestation.", 1)
message_admins("\blue [key_name_admin(usr)] spawned a cortical borer infestation.", 1)
new /datum/event/borer_infestation
if("power")
feedback_inc("admin_secrets_fun_used",1)
+497
View File
@@ -0,0 +1,497 @@
//Structured Datum Query Language. Basically SQL meets BYOND objects.
//Note: For use in BS12, need text_starts_with proc, and to modify the action on select to use BS12's object edit command(s).
/client/proc/SDQL_query(query_text as message)
set category = "Admin"
if(!check_rights(R_DEBUG)) //Shouldn't happen... but just to be safe.
message_admins("\red ERROR: Non-admin [usr.key] attempted to execute a SDQL query!")
log_admin("Non-admin [usr.key] attempted to execute a SDQL query!")
var/list/query_list = SDQL_tokenize(query_text)
if(query_list.len < 2)
if(query_list.len > 0)
usr << "\red SDQL: Too few discrete tokens in query \"[query_text]\". Please check your syntax and try again."
return
if(!(lowertext(query_list[1]) in list("select", "delete", "update")))
usr << "\red SDQL: Unknown query type: \"[query_list[1]]\" in query \"[query_text]\". Please check your syntax and try again."
return
var/list/types = list()
var/i
for(i = 2; i <= query_list.len; i += 2)
types += query_list[i]
if(i + 1 >= query_list.len || query_list[i + 1] != ",")
break
i++
var/list/from = list()
if(i <= query_list.len)
if(lowertext(query_list[i]) in list("from", "in"))
for(i++; i <= query_list.len; i += 2)
from += query_list[i]
if(i + 1 >= query_list.len || query_list[i + 1] != ",")
break
i++
if(from.len < 1)
from += "world"
var/list/set_vars = list()
if(lowertext(query_list[1]) == "update")
if(i <= query_list.len && lowertext(query_list[i]) == "set")
for(i++; i <= query_list.len; i++)
if(i + 2 <= query_list.len && query_list[i + 1] == "=")
set_vars += query_list[i]
set_vars[query_list[i]] = query_list[i + 2]
else
usr << "\red SDQL: Invalid set parameter in query \"[query_text]\". Please check your syntax and try again."
return
i += 3
if(i >= query_list.len || query_list[i] != ",")
break
if(set_vars.len < 1)
usr << "\red SDQL: Invalid or missing set in query \"[query_text]\". Please check your syntax and try again."
return
var/list/where = list()
if(i <= query_list.len && lowertext(query_list[i]) == "where")
where = query_list.Copy(i + 1)
var/list/from_objs = list()
if("world" in from)
from_objs += world
else
for(var/f in from)
if(copytext(f, 1, 2) == "'" || copytext(f, 1, 2) == "\"")
from_objs += locate(copytext(f, 2, length(f)))
else if(copytext(f, 1, 2) != "/")
from_objs += locate(f)
else
var/f2 = text2path(f)
if(text_starts_with(f, "/mob"))
for(var/mob/m in world)
if(istype(m, f2))
from_objs += m
else if(text_starts_with(f, "/turf/space"))
for(var/turf/space/m in world)
if(istype(m, f2))
from_objs += m
else if(text_starts_with(f, "/turf/simulated"))
for(var/turf/simulated/m in world)
if(istype(m, f2))
from_objs += m
else if(text_starts_with(f, "/turf/unsimulated"))
for(var/turf/unsimulated/m in world)
if(istype(m, f2))
from_objs += m
else if(text_starts_with(f, "/turf"))
for(var/turf/m in world)
if(istype(m, f2))
from_objs += m
else if(text_starts_with(f, "/area"))
for(var/area/m in world)
if(istype(m, f2))
from_objs += m
else if(text_starts_with(f, "/obj/item"))
for(var/obj/item/m in world)
if(istype(m, f2))
from_objs += m
else if(text_starts_with(f, "/obj/machinery"))
for(var/obj/machinery/m in world)
if(istype(m, f2))
from_objs += m
else if(text_starts_with(f, "/obj"))
for(var/obj/m in world)
if(istype(m, f2))
from_objs += m
else if(text_starts_with(f, "/atom"))
for(var/atom/m in world)
if(istype(m, f2))
from_objs += m
/*
else
for(var/datum/m in world)
if(istype(m, f2))
from_objs += m
*/
var/list/objs = list()
for(var/from_obj in from_objs)
if("*" in types)
objs += from_obj:contents
else
for(var/f in types)
if(copytext(f, 1, 2) == "'" || copytext(f, 1, 2) == "\"")
objs += locate(copytext(f, 2, length(f))) in from_obj
else if(copytext(f, 1, 2) != "/")
objs += locate(f) in from_obj
else
var/f2 = text2path(f)
if(text_starts_with(f, "/mob"))
for(var/mob/m in from_obj)
if(istype(m, f2))
objs += m
else if(text_starts_with(f, "/turf/space"))
for(var/turf/space/m in from_obj)
if(istype(m, f2))
objs += m
else if(text_starts_with(f, "/turf/simulated"))
for(var/turf/simulated/m in from_obj)
if(istype(m, f2))
objs += m
else if(text_starts_with(f, "/turf/unsimulated"))
for(var/turf/unsimulated/m in from_obj)
if(istype(m, f2))
objs += m
else if(text_starts_with(f, "/turf"))
for(var/turf/m in from_obj)
if(istype(m, f2))
objs += m
else if(text_starts_with(f, "/area"))
for(var/area/m in from_obj)
if(istype(m, f2))
objs += m
else if(text_starts_with(f, "/obj/item"))
for(var/obj/item/m in from_obj)
if(istype(m, f2))
objs += m
else if(text_starts_with(f, "/obj/machinery"))
for(var/obj/machinery/m in from_obj)
if(istype(m, f2))
objs += m
else if(text_starts_with(f, "/obj"))
for(var/obj/m in from_obj)
if(istype(m, f2))
objs += m
else if(text_starts_with(f, "/atom"))
for(var/atom/m in from_obj)
if(istype(m, f2))
objs += m
else
for(var/datum/m in from_obj)
if(istype(m, f2))
objs += m
for(var/datum/t in objs)
var/currently_false = 0
for(i = 1, i - 1 < where.len, i++)
var/v = where[i++]
var/compare_op = where[i++]
if(!(compare_op in list("==", "=", "<>", "<", ">", "<=", ">=", "!=")))
usr << "\red SDQL: Unknown comparison operator [compare_op] in where clause following [v] in query \"[query_text]\". Please check your syntax and try again."
return
var/j
for(j = i, j <= where.len, j++)
if(lowertext(where[j]) in list("and", "or", ";"))
break
if(!currently_false)
var/value = SDQL_text2value(t, v)
var/result = SDQL_evaluate(t, where.Copy(i, j))
switch(compare_op)
if("=", "==")
currently_false = !(value == result)
if("!=", "<>")
currently_false = !(value != result)
if("<")
currently_false = !(value < result)
if(">")
currently_false = !(value > result)
if("<=")
currently_false = !(value <= result)
if(">=")
currently_false = !(value >= result)
if(j > where.len || lowertext(where[j]) == ";")
break
else if(lowertext(where[j]) == "or")
if(currently_false)
currently_false = 0
else
break
i = j
if(currently_false)
objs -= t
usr << "\blue SQDL Query: [query_text]"
message_admins("[usr] executed SDQL query: \"[query_text]\".")
/*
for(var/t in types)
usr << "Type: [t]"
for(var/t in from)
usr << "From: [t]"
for(var/t in set_vars)
usr << "Set: [t] = [set_vars[t]]"
if(where.len)
var/where_str = ""
for(var/t in where)
where_str += "[t] "
usr << "Where: [where_str]"
usr << "From objects:"
for(var/datum/t in from_objs)
usr << t
usr << "Objects:"
for(var/datum/t in objs)
usr << t
*/
switch(lowertext(query_list[1]))
if("delete")
for(var/datum/t in objs)
del t
if("update")
for(var/datum/t in objs)
objs[t] = list()
for(var/v in set_vars)
if(v in t.vars)
objs[t][v] = SDQL_text2value(t, set_vars[v])
for(var/datum/t in objs)
for(var/v in objs[t])
t.vars[v] = objs[t][v]
if("select")
var/text = ""
for(var/datum/t in objs)
if(istype(t, /atom))
var/atom/a = t
if(a.x)
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t] at ([a.x], [a.y], [a.z])<br>"
else if(a.loc && a.loc.x)
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])<br>"
else
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t]<br>"
else
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t]<br>"
//text += "[t]<br>"
usr << browse(text, "window=sdql_result")
/client/Topic(href,href_list[],hsrc)
if(href_list["SDQL_select"])
debug_variables(locate(href_list["SDQL_select"]))
..()
/proc/SDQL_evaluate(datum/object, list/equation)
if(equation.len == 0)
return null
else if(equation.len == 1)
return SDQL_text2value(object, equation[1])
else if(equation[1] == "!")
return !SDQL_evaluate(object, equation.Copy(2))
else if(equation[1] == "-")
return -SDQL_evaluate(object, equation.Copy(2))
else
usr << "\red SDQL: Sorry, equations not yet supported :("
return null
/proc/SDQL_text2value(datum/object, text)
if(text2num(text) != null)
return text2num(text)
else if(text == "null")
return null
else if(copytext(text, 1, 2) == "'" || copytext(text, 1, 2) == "\"" )
return copytext(text, 2, length(text))
else if(copytext(text, 1, 2) == "/")
return text2path(text)
else
if(findtext(text, "."))
var/split = findtext(text, ".")
var/v = copytext(text, 1, split)
if((v in object.vars) && istype(object.vars[v], /datum))
return SDQL_text2value(object.vars[v], copytext(text, split + 1))
else
return null
else
if(text in object.vars)
return object.vars[text]
else
return null
/proc/text_starts_with(text, start)
if(copytext(text, 1, length(start) + 1) == start)
return 1
else
return 0
/proc/SDQL_tokenize(query_text)
var/list/whitespace = list(" ", "\n", "\t")
var/list/single = list("(", ")", ",", "+", "-")
var/list/multi = list(
"=" = list("", "="),
"<" = list("", "=", ">"),
">" = list("", "="),
"!" = list("", "="))
var/word = ""
var/list/query_list = list()
var/len = length(query_text)
for(var/i = 1, i <= len, i++)
var/char = copytext(query_text, i, i + 1)
if(char in whitespace)
if(word != "")
query_list += word
word = ""
else if(char in single)
if(word != "")
query_list += word
word = ""
query_list += char
else if(char in multi)
if(word != "")
query_list += word
word = ""
var/char2 = copytext(query_text, i + 1, i + 2)
if(char2 in multi[char])
query_list += "[char][char2]"
i++
else
query_list += char
else if(char == "'")
if(word != "")
usr << "\red SDQL: You have an error in your SDQL syntax, unexpected ' in query: \"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again."
return null
word = "'"
for(i++, i <= len, i++)
char = copytext(query_text, i, i + 1)
if(char == "'")
if(copytext(query_text, i + 1, i + 2) == "'")
word += "'"
i++
else
break
else
word += char
if(i > len)
usr << "\red SDQL: You have an error in your SDQL syntax, unmatched ' in query: \"<font color=gray>[query_text]</font>\". Please check your syntax, and try again."
return null
query_list += "[word]'"
word = ""
else if(char == "\"")
if(word != "")
usr << "\red SDQL: You have an error in your SDQL syntax, unexpected \" in query: \"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again."
return null
word = "\""
for(i++, i <= len, i++)
char = copytext(query_text, i, i + 1)
if(char == "\"")
if(copytext(query_text, i + 1, i + 2) == "'")
word += "\""
i++
else
break
else
word += char
if(i > len)
usr << "\red SDQL: You have an error in your SDQL syntax, unmatched \" in query: \"<font color=gray>[query_text]</font>\". Please check your syntax, and try again."
return null
query_list += "[word]\""
word = ""
else
word += char
if(word != "")
query_list += word
return query_list
+426
View File
@@ -0,0 +1,426 @@
/client/proc/SDQL2_query(query_text as message)
set category = "Admin"
if(!check_rights(R_DEBUG)) //Shouldn't happen... but just to be safe.
message_admins("\red ERROR: Non-admin [usr.key] attempted to execute a SDQL query!")
log_admin("Non-admin [usr.key] attempted to execute a SDQL query!")
if(!query_text || length(query_text) < 1)
return
//world << query_text
var/list/query_list = SDQL2_tokenize(query_text)
if(!query_list || query_list.len < 1)
return
var/list/query_tree = SDQL_parse(query_list)
if(query_tree.len < 1)
return
var/list/from_objs = list()
var/list/select_types = list()
switch(query_tree[1])
if("explain")
SDQL_testout(query_tree["explain"])
return
if("call")
if("on" in query_tree)
select_types = query_tree["on"]
else
return
if("select", "delete", "update")
select_types = query_tree[query_tree[1]]
from_objs = SDQL_from_objs(query_tree["from"])
var/list/objs = list()
for(var/type in select_types)
var/char = copytext(type, 1, 2)
if(char == "/" || char == "*")
for(var/from in from_objs)
objs += SDQL_get_all(type, from)
else if(char == "'" || char == "\"")
objs += locate(copytext(type, 2, length(type)))
if("where" in query_tree)
var/objs_temp = objs
objs = list()
for(var/datum/d in objs_temp)
if(SDQL_expression(d, query_tree["where"]))
objs += d
//usr << "Query: [query_text]"
message_admins("[usr] executed SDQL query: \"[query_text]\".")
switch(query_tree[1])
if("delete")
for(var/datum/d in objs)
del d
if("select")
var/text = ""
for(var/datum/t in objs)
if(istype(t, /atom))
var/atom/a = t
if(a.x)
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t] at ([a.x], [a.y], [a.z])<br>"
else if(a.loc && a.loc.x)
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])<br>"
else
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t]<br>"
else
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t]<br>"
usr << browse(text, "window=SDQL-result")
if("update")
if("set" in query_tree)
var/list/set_list = query_tree["set"]
for(var/datum/d in objs)
var/list/vals = list()
for(var/v in set_list)
if(v in d.vars)
vals += v
vals[v] = SDQL_expression(d, set_list[v])
if(istype(d, /turf))
for(var/v in vals)
if(v == "x" || v == "y" || v == "z")
continue
d.vars[v] = vals[v]
else
for(var/v in vals)
d.vars[v] = vals[v]
/proc/SDQL_parse(list/query_list)
var/datum/SDQL_parser/parser = new(query_list)
var/list/query_tree = parser.parse()
del(parser)
return query_tree
/proc/SDQL_testout(list/query_tree, indent = 0)
var/spaces = ""
for(var/s = 0, s < indent, s++)
spaces += " "
for(var/item in query_tree)
if(istype(item, /list))
world << "[spaces]("
SDQL_testout(item, indent + 1)
world << "[spaces])"
else
world << "[spaces][item]"
if(!isnum(item) && query_tree[item])
if(istype(query_tree[item], /list))
world << "[spaces] ("
SDQL_testout(query_tree[item], indent + 2)
world << "[spaces] )"
else
world << "[spaces] [query_tree[item]]"
/proc/SDQL_from_objs(list/tree)
if("world" in tree)
return list(world)
var/list/out = list()
for(var/type in tree)
var/char = copytext(type, 1, 2)
if(char == "/")
out += SDQL_get_all(type, world)
else if(char == "'" || char == "\"")
out += locate(copytext(type, 2, length(type)))
return out
/proc/SDQL_get_all(type, location)
var/list/out = list()
if(type == "*")
for(var/datum/d in location)
out += d
return out
type = text2path(type)
if(ispath(type, /mob))
for(var/mob/d in location)
if(istype(d, type))
out += d
else if(ispath(type, /turf))
for(var/turf/d in location)
if(istype(d, type))
out += d
else if(ispath(type, /obj))
for(var/obj/d in location)
if(istype(d, type))
out += d
else if(ispath(type, /area))
for(var/area/d in location)
if(istype(d, type))
out += d
else if(ispath(type, /atom))
for(var/atom/d in location)
if(istype(d, type))
out += d
else
for(var/datum/d in location)
if(istype(d, type))
out += d
return out
/proc/SDQL_expression(datum/object, list/expression, start = 1)
var/result = 0
var/val
for(var/i = start, i <= expression.len, i++)
var/op = ""
if(i > start)
op = expression[i]
i++
var/list/ret = SDQL_value(object, expression, i)
val = ret["val"]
i = ret["i"]
if(op != "")
switch(op)
if("+")
result += val
if("-")
result -= val
if("*")
result *= val
if("/")
result /= val
if("&")
result &= val
if("|")
result |= val
if("^")
result ^= val
if("=", "==")
result = (result == val)
if("!=", "<>")
result = (result != val)
if("<")
result = (result < val)
if("<=")
result = (result <= val)
if(">")
result = (result > val)
if(">=")
result = (result >= val)
if("and", "&&")
result = (result && val)
if("or", "||")
result = (result || val)
else
usr << "\red SDQL2: Unknown op [op]"
result = null
else
result = val
return result
/proc/SDQL_value(datum/object, list/expression, start = 1)
var/i = start
var/val = null
if(i > expression.len)
return list("val" = null, "i" = i)
if(istype(expression[i], /list))
val = SDQL_expression(object, expression[i])
else if(expression[i] == "!")
var/list/ret = SDQL_value(object, expression, i + 1)
val = !ret["val"]
i = ret["i"]
else if(expression[i] == "~")
var/list/ret = SDQL_value(object, expression, i + 1)
val = ~ret["val"]
i = ret["i"]
else if(expression[i] == "-")
var/list/ret = SDQL_value(object, expression, i + 1)
val = -ret["val"]
i = ret["i"]
else if(expression[i] == "null")
val = null
else if(isnum(expression[i]))
val = expression[i]
else if(copytext(expression[i], 1, 2) in list("'", "\""))
val = copytext(expression[i], 2, length(expression[i]))
else
val = SDQL_var(object, expression, i)
i = expression.len
return list("val" = val, "i" = i)
/proc/SDQL_var(datum/object, list/expression, start = 1)
if(expression[start] in object.vars)
if(start < expression.len && expression[start + 1] == ".")
return SDQL_var(object.vars[expression[start]], expression[start + 2])
else
return object.vars[expression[start]]
else
return null
/proc/SDQL2_tokenize(query_text)
var/list/whitespace = list(" ", "\n", "\t")
var/list/single = list("(", ")", ",", "+", "-", ".")
var/list/multi = list(
"=" = list("", "="),
"<" = list("", "=", ">"),
">" = list("", "="),
"!" = list("", "="))
var/word = ""
var/list/query_list = list()
var/len = length(query_text)
for(var/i = 1, i <= len, i++)
var/char = copytext(query_text, i, i + 1)
if(char in whitespace)
if(word != "")
query_list += word
word = ""
else if(char in single)
if(word != "")
query_list += word
word = ""
query_list += char
else if(char in multi)
if(word != "")
query_list += word
word = ""
var/char2 = copytext(query_text, i + 1, i + 2)
if(char2 in multi[char])
query_list += "[char][char2]"
i++
else
query_list += char
else if(char == "'")
if(word != "")
usr << "\red SDQL2: You have an error in your SDQL syntax, unexpected ' in query: \"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again."
return null
word = "'"
for(i++, i <= len, i++)
char = copytext(query_text, i, i + 1)
if(char == "'")
if(copytext(query_text, i + 1, i + 2) == "'")
word += "'"
i++
else
break
else
word += char
if(i > len)
usr << "\red SDQL2: You have an error in your SDQL syntax, unmatched ' in query: \"<font color=gray>[query_text]</font>\". Please check your syntax, and try again."
return null
query_list += "[word]'"
word = ""
else if(char == "\"")
if(word != "")
usr << "\red SDQL2: You have an error in your SDQL syntax, unexpected \" in query: \"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again."
return null
word = "\""
for(i++, i <= len, i++)
char = copytext(query_text, i, i + 1)
if(char == "\"")
if(copytext(query_text, i + 1, i + 2) == "'")
word += "\""
i++
else
break
else
word += char
if(i > len)
usr << "\red SDQL2: You have an error in your SDQL syntax, unmatched \" in query: \"<font color=gray>[query_text]</font>\". Please check your syntax, and try again."
return null
query_list += "[word]\""
word = ""
else
word += char
if(word != "")
query_list += word
return query_list
+531
View File
@@ -0,0 +1,531 @@
//I'm pretty sure that this is a recursive [s]descent[/s] ascent parser.
//Spec
//////////
//
// query : select_query | delete_query | update_query | call_query | explain
// explain : 'EXPLAIN' query
//
// select_query : 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
// delete_query : 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
// update_query : 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression]
// call_query : 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]]
//
// select_list : select_item [',' select_list]
// select_item : '*' | select_function | object_type
// select_function : count_function
// count_function : 'COUNT' '(' '*' ')' | 'COUNT' '(' object_types ')'
//
// from_list : from_item [',' from_list]
// from_item : 'world' | object_type
//
// call_function : <function name> ['(' [arguments] ')']
// arguments : expression [',' arguments]
//
// object_type : <type path> | string
//
// assignments : assignment, [',' assignments]
// assignment : <variable name> '=' expression
// variable : <variable name> | <variable name> '.' variable
//
// bool_expression : expression comparitor expression [bool_operator bool_expression]
// expression : ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
// unary_expression : unary_operator ( unary_expression | value | '(' expression ')' )
// comparitor : '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
// value : variable | string | number | 'null'
// unary_operator : '!' | '-' | '~'
// binary_operator : comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^'
// bool_operator : 'AND' | '&&' | 'OR' | '||'
//
// string : ''' <some text> ''' | '"' <some text > '"'
// number : <some digits>
//
//////////
/datum/SDQL_parser
var/query_type
var/error = 0
var/list/query
var/list/tree
var/list/select_functions = list("count")
var/list/boolean_operators = list("and", "or", "&&", "||")
var/list/unary_operators = list("!", "-", "~")
var/list/binary_operators = list("+", "-", "/", "*", "&", "|", "^")
var/list/comparitors = list("=", "==", "!=", "<>", "<", "<=", ">", ">=")
/datum/SDQL_parser/New(query_list)
query = query_list
/datum/SDQL_parser/proc/parse_error(error_message)
error = 1
usr << "\red SQDL2 Parsing Error: [error_message]"
return query.len + 1
/datum/SDQL_parser/proc/parse()
tree = list()
query(1, tree)
if(error)
return list()
else
return tree
/datum/SDQL_parser/proc/token(i)
if(i <= query.len)
return query[i]
else
return null
/datum/SDQL_parser/proc/tokens(i, num)
if(i + num <= query.len)
return query.Copy(i, i + num)
else
return null
/datum/SDQL_parser/proc/tokenl(i)
return lowertext(token(i))
/datum/SDQL_parser/proc
//query: select_query | delete_query | update_query
query(i, list/node)
query_type = tokenl(i)
switch(query_type)
if("select")
select_query(i, node)
if("delete")
delete_query(i, node)
if("update")
update_query(i, node)
if("call")
call_query(i, node)
if("explain")
node += "explain"
node["explain"] = list()
query(i + 1, node["explain"])
// select_query: 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
select_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
node += "select"
node["select"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
return i
//delete_query: 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
delete_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
node += "delete"
node["delete"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
return i
//update_query: 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression]
update_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
node += "update"
node["update"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) != "set")
i = parse_error("UPDATE has misplaced SET")
var/list/set_assignments = list()
i = assignments(i + 1, set_assignments)
node += "set"
node["set"] = set_assignments
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
return i
//call_query: 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]]
call_query(i, list/node)
var/list/func = list()
i = call_function(i + 1, func)
node += "call"
node["call"] = func
if(tokenl(i) != "on")
return i
var/list/select = list()
i = select_list(i + 1, select)
node += "on"
node["on"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
return i
//select_list: select_item [',' select_list]
select_list(i, list/node)
i = select_item(i, node)
if(token(i) == ",")
i = select_list(i + 1, node)
return i
//from_list: from_item [',' from_list]
from_list(i, list/node)
i = from_item(i, node)
if(token(i) == ",")
i = from_list(i + 1, node)
return i
//assignments: assignment, [',' assignments]
assignments(i, list/node)
i = assignment(i, node)
if(token(i) == ",")
i = assignments(i + 1, node)
return i
//select_item: '*' | select_function | object_type
select_item(i, list/node)
if(token(i) == "*")
node += "*"
i++
else if(tokenl(i) in select_functions)
i = select_function(i, node)
else
i = object_type(i, node)
return i
//from_item: 'world' | object_type
from_item(i, list/node)
if(token(i) == "world")
node += "world"
i++
else
i = object_type(i, node)
return i
//bool_expression: expression [bool_operator bool_expression]
bool_expression(i, list/node)
var/list/bool = list()
i = expression(i, bool)
node[++node.len] = bool
if(tokenl(i) in boolean_operators)
i = bool_operator(i, node)
i = bool_expression(i, node)
return i
//assignment: <variable name> '=' expression
assignment(i, list/node)
node += token(i)
if(token(i + 1) == "=")
var/varname = token(i)
node[varname] = list()
i = expression(i + 2, node[varname])
else
parse_error("Assignment expected, but no = found")
return i
//variable: <variable name> | <variable name> '.' variable
variable(i, list/node)
var/list/L = list(token(i))
node[++node.len] = L
if(token(i + 1) == ".")
L += "."
i = variable(i + 2, L)
else
i++
return i
//object_type: <type path> | string
object_type(i, list/node)
if(copytext(token(i), 1, 2) == "/")
node += token(i)
else
i = string(i, node)
return i + 1
//comparitor: '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
comparitor(i, list/node)
if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">="))
node += token(i)
else
parse_error("Unknown comparitor [token(i)]")
return i + 1
//bool_operator: 'AND' | '&&' | 'OR' | '||'
bool_operator(i, list/node)
if(tokenl(i) in list("and", "or", "&&", "||"))
node += token(i)
else
parse_error("Unknown comparitor [token(i)]")
return i + 1
//string: ''' <some text> ''' | '"' <some text > '"'
string(i, list/node)
if(copytext(token(i), 1, 2) in list("'", "\""))
node += token(i)
else
parse_error("Expected string but found '[token(i)]'")
return i + 1
//call_function: <function name> ['(' [arguments] ')']
call_function(i, list/node)
parse_error("Sorry, function calls aren't available yet")
return i
//select_function: count_function
select_function(i, list/node)
parse_error("Sorry, function calls aren't available yet")
return i
//expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
expression(i, list/node)
if(token(i) in unary_operators)
i = unary_expression(i, node)
else if(token(i) == "(")
var/list/expr = list()
i = expression(i + 1, expr)
if(token(i) != ")")
parse_error("Missing ) at end of expression.")
else
i++
node[++node.len] = expr
else
i = value(i, node)
if(token(i) in binary_operators)
i = binary_operator(i, node)
i = expression(i, node)
else if(token(i) in comparitors)
i = binary_operator(i, node)
var/list/rhs = list()
i = expression(i, rhs)
node[++node.len] = rhs
return i
//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' )
unary_expression(i, list/node)
if(token(i) in unary_operators)
var/list/unary_exp = list()
unary_exp += token(i)
i++
if(token(i) in unary_operators)
i = unary_expression(i, unary_exp)
else if(token(i) == "(")
var/list/expr = list()
i = expression(i + 1, expr)
if(token(i) != ")")
parse_error("Missing ) at end of expression.")
else
i++
unary_exp[++unary_exp.len] = expr
else
i = value(i, unary_exp)
node[++node.len] = unary_exp
else
parse_error("Expected unary operator but found '[token(i)]'")
return i
//binary_operator: comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^'
binary_operator(i, list/node)
if(token(i) in (binary_operators + comparitors))
node += token(i)
else
parse_error("Unknown binary operator [token(i)]")
return i + 1
//value: variable | string | number | 'null'
value(i, list/node)
if(token(i) == "null")
node += "null"
i++
else if(isnum(text2num(token(i))))
node += text2num(token(i))
i++
else if(copytext(token(i), 1, 2) in list("'", "\""))
i = string(i, node)
else
i = variable(i, node)
return i
/*EXPLAIN SELECT * WHERE 42 = 6 * 9 OR val = - 5 == 7*/
+4 -4
View File
@@ -55,7 +55,7 @@
//get message text, limit it's length.and clean/escape html
if(!msg)
msg = input(src,"Message:", "Private message to [C.key]") as text|null
msg = input(src,"Message:", "Private message to [key_name(C, 0, holder ? 1 : 0)]") as text|null
if(!msg) return
if(!C)
@@ -80,10 +80,10 @@
//mod PMs are maroon
//PMs sent from admins and mods display their rank
if(holder)
if( holder.rights & R_MOD )
recieve_color = "maroon"
else
if( holder.rights & R_ADMIN )
recieve_color = "red"
else
recieve_color = "maroon"
send_pm_type = holder.rank + " "
recieve_pm_type = holder.rank
+1 -1
View File
@@ -10,7 +10,7 @@
log_admin("[key_name(src)] : [msg]")
if(check_rights(R_ADMIN,0))
msg = "<span class='admin'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> (<a href='?_src_=holder;adminplayerobservejump=\ref[mob]'>JMP</A>): <span class='message'>[msg]</span></span>"
msg = "<span class='adminsay'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> (<a href='?_src_=holder;adminplayerobservejump=\ref[mob]'>JMP</A>): <span class='message'>[msg]</span></span>"
for(var/client/C in admins)
if(R_ADMIN & C.holder.rights)
C << msg
+6 -6
View File
@@ -975,14 +975,14 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
switch(input("Which list?") in list("Players","Admins","Mobs","Living Mobs","Dead Mobs", "Clients"))
if("Players")
usr << dd_list2text(player_list,",")
usr << list2text(player_list,",")
if("Admins")
usr << dd_list2text(admins,",")
usr << list2text(admins,",")
if("Mobs")
usr << dd_list2text(mob_list,",")
usr << list2text(mob_list,",")
if("Living Mobs")
usr << dd_list2text(living_mob_list,",")
usr << list2text(living_mob_list,",")
if("Dead Mobs")
usr << dd_list2text(dead_mob_list,",")
usr << list2text(dead_mob_list,",")
if("Clients")
usr << dd_list2text(clients,",")
usr << list2text(clients,",")
+125 -3
View File
@@ -221,6 +221,128 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
message_admins("\blue [key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].", 1)
return 1
/*
Allow admins to set players to be able to respawn/bypass 30 min wait, without the admin having to edit variables directly
Ccomp's first proc.
*/
/client/proc/get_ghosts(var/notify = 0,var/what = 2)
// what = 1, return ghosts ass list.
// what = 2, return mob list
var/list/mobs = list()
var/list/ghosts = list()
var/list/sortmob = sortAtom(mob_list) // get the mob list.
/var/any=0
for(var/mob/dead/observer/M in sortmob)
mobs.Add(M) //filter it where it's only ghosts
any = 1 //if no ghosts show up, any will just be 0
if(!any)
if(notify)
src << "There doesn't appear to be any ghosts for you to select."
return
for(var/mob/M in mobs)
var/name = M.name
ghosts[name] = M //get the name of the mob for the popup list
if(what==1)
return ghosts
else
return mobs
/client/proc/allow_character_respawn()
set category = "Special Verbs"
set name = "Allow player to respawn"
set desc = "Let's the player bypass the 30 minute wait to respawn or allow them to re-enter their corpse."
if(!holder)
src << "Only administrators may use this command."
var/list/ghosts= get_ghosts(1,1)
var/target = input("Please, select a ghost!", "COME BACK TO LIFE!", null, null) as null|anything in ghosts
if(!target)
src << "Hrm, appears you didn't select a ghost" // Sanity check, if no ghosts in the list we don't want to edit a null variable and cause a runtime error.
return
var/mob/dead/observer/G = ghosts[target]
if(G.has_enabled_antagHUD && config.antag_hud_restricted)
var/response = alert(src, "Are you sure you wish to allow this individual to play?","Ghost has used AntagHUD","Yes","No")
if(response == "No") return
G.timeofdeath=-19999 /* time of death is checked in /mob/verb/abandon_mob() which is the Respawn verb.
timeofdeath is used for bodies on autopsy but since we're messing with a ghost I'm pretty sure
there won't be an autopsy.
*/
G.has_enabled_antagHUD = 2
G.can_reenter_corpse = 1
G:show_message(text("\blue <B>You may now respawn. You should roleplay as if you learned nothing about the round during your time with the dead.</B>"), 1)
log_admin("[key_name(usr)] allowed [key_name(G)] to bypass the 30 minute respawn limit")
message_admins("Admin [key_name_admin(usr)] allowed [key_name_admin(G)] to bypass the 30 minute respawn limit", 1)
/client/proc/toggle_antagHUD_use()
set category = "Server"
set name = "Toggle antagHUD usage"
set desc = "Toggles antagHUD usage for observers"
if(!holder)
src << "Only administrators may use this command."
var/action=""
if(config.antag_hud_allowed)
for(var/mob/dead/observer/g in get_ghosts())
if(!g.client.holder) //Remove the verb from non-admin ghosts
g.verbs -= /mob/dead/observer/verb/toggle_antagHUD
if(g.antagHUD)
g.antagHUD = 0 // Disable it on those that have it enabled
g.has_enabled_antagHUD = 2 // We'll allow them to respawn
g << "\red <B>The Administrator has disabled AntagHUD </B>"
config.antag_hud_allowed = 0
src << "\red <B>AntagHUD usage has been disabled</B>"
action = "disabled"
else
for(var/mob/dead/observer/g in get_ghosts())
if(!g.client.holder) // Add the verb back for all non-admin ghosts
g.verbs += /mob/dead/observer/verb/toggle_antagHUD
g << "\blue <B>The Administrator has enabled AntagHUD </B>" // Notify all observers they can now use AntagHUD
config.antag_hud_allowed = 1
action = "enabled"
src << "\blue <B>AntagHUD usage has been enabled</B>"
log_admin("[key_name(usr)] has [action] antagHUD usage for observers")
message_admins("Admin [key_name_admin(usr)] has [action] antagHUD usage for observers", 1)
/client/proc/toggle_antagHUD_restrictions()
set category = "Server"
set name = "Toggle antagHUD Restrictions"
set desc = "Restricts players that have used antagHUD from being able to join this round."
if(!holder)
src << "Only administrators may use this command."
var/action=""
if(config.antag_hud_restricted)
for(var/mob/dead/observer/g in get_ghosts())
g << "\blue <B>The administrator has lifted restrictions on joining the round if you use AntagHUD</B>"
action = "lifted restrictions"
config.antag_hud_restricted = 0
src << "\blue <B>AntagHUD restrictions have been lifted</B>"
else
for(var/mob/dead/observer/g in get_ghosts())
g << "\red <B>The administrator has placed restrictions on joining the round if you use AntagHUD</B>"
g << "\red <B>Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions </B>"
g.antagHUD = 0
g.has_enabled_antagHUD = 0
action = "placed restrictions"
config.antag_hud_restricted = 1
src << "\red <B>AntagHUD restrictions have been enabled</B>"
log_admin("[key_name(usr)] has [action] on joining the round if they use AntagHUD")
message_admins("Admin [key_name_admin(usr)] has [action] on joining the round if they use AntagHUD", 1)
/*
If a guy was gibbed and you want to revive him, this is a good way to do so.
Works kind of like entering the game with a new character. Character receives a new mind if they didn't have one.
@@ -325,9 +447,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(record_found)//Pull up their name from database records if they did have a mind.
new_character.dna = new()//Let's first give them a new DNA.
new_character.dna.unique_enzymes = record_found.fields["b_dna"]//Enzymes are based on real name but we'll use the record for conformity.
new_character.dna.struc_enzymes = record_found.fields["enzymes"]//This is the default of enzymes so I think it's safe to go with.
new_character.dna.uni_identity = record_found.fields["identity"]//DNA identity is carried over.
updateappearance(new_character,new_character.dna.uni_identity)//Now we configure their appearance based on their unique identity, same as with a DNA machine or somesuch.
new_character.dna.SE = record_found.fields["enzymes"]//This is the default of enzymes so I think it's safe to go with.
new_character.dna.UpdateSE()
new_character.UpdateAppearance(record_found.fields["identity"])//Now we configure their appearance based on their unique identity, same as with a DNA machine or somesuch.
else//If they have no records, we just do a random DNA for them, based on their random appearance/savefile.
new_character.dna.ready_dna(new_character)
+1 -1
View File
@@ -124,7 +124,7 @@ var/global/sent_strike_team = 0
/mob/living/carbon/human/proc/equip_death_commando(leader_selected = 0)
var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src)
R.set_frequency(1441)
R.set_frequency(1341)
equip_to_slot_or_del(R, slot_l_ear)
if (leader_selected == 0)
equip_to_slot_or_del(new /obj/item/clothing/under/color/green(src), slot_w_uniform)
+14 -1
View File
@@ -45,6 +45,7 @@
visible_message("\red <b>SPLAT!</b>")
M.splat()
playsound(target.loc, 'sound/effects/snap.ogg', 50, 1)
layer = MOB_LAYER - 0.2
armed = 0
update_icon()
pulse(0)
@@ -112,4 +113,16 @@
/obj/item/device/assembly/mousetrap/armed
icon_state = "mousetraparmed"
armed = 1
armed = 1
/obj/item/device/assembly/mousetrap/verb/hide_under()
set src in oview(1)
set name = "Hide"
set category = "Object"
if(usr.stat)
return
layer = TURF_LAYER+0.2
usr << "<span class='notice'>You hide [src].</span>"
+2 -2
View File
@@ -31,11 +31,11 @@
s.start()
if(entersmoke)
var/datum/effect/effect/system/harmless_smoke_spread/s = new /datum/effect/effect/system/harmless_smoke_spread
var/datum/effect/effect/system/smoke_spread/s = new /datum/effect/effect/system/smoke_spread
s.set_up(4, 1, src, 0)
s.start()
if(exitsmoke)
var/datum/effect/effect/system/harmless_smoke_spread/s = new /datum/effect/effect/system/harmless_smoke_spread
var/datum/effect/effect/system/smoke_spread/s = new /datum/effect/effect/system/smoke_spread
s.set_up(4, 1, dest, 0)
s.start()
+8 -5
View File
@@ -251,14 +251,21 @@
'nano/css/icons.css',
'nano/templates/chem_dispenser.tmpl',
'nano/templates/cryo.tmpl',
'nano/templates/geoscanner.tmpl',
'nano/templates/dna_modifier.tmpl',
'nano/templates/telescience_console.tmpl',
'nano/templates/pda.tmpl',
'nano/templates/smes.tmpl',
'nano/templates/uplink.tmpl',
'nano/images/uiBackground.png',
'nano/images/uiIcons16.png',
'nano/images/uiIcons24.png',
'nano/images/uiBackground-Syndicate.png',
'nano/images/uiLinkPendingIcon.gif',
'nano/images/uiMaskBackground.png',
'nano/images/uiNoticeBackground.jpg',
'nano/images/uiTitleFluff.png',
'nano/images/uiTitleFluff-Syndicate.png',
'html/search.js',
'html/panels.css',
'icons/pda_icons/pda_atmos.png',
@@ -298,9 +305,5 @@
'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/xenoarch_icons/chart1.jpg',
'icons/xenoarch_icons/chart2.jpg',
'icons/xenoarch_icons/chart3.jpg',
'icons/xenoarch_icons/chart4.jpg'
'icons/spideros_icons/sos_14.png'
)
+78 -4
View File
@@ -44,6 +44,8 @@ datum/preferences
var/be_special = 0 //Special role selection
var/UI_style = "Midnight"
var/toggles = TOGGLES_DEFAULT
var/UI_style_color = "#ffffff"
var/UI_style_alpha = 255
//character preferences
var/real_name //our character's name
@@ -243,10 +245,14 @@ datum/preferences
dat += "<br>"
dat += "<b>UI Style:</b> <a href='?_src_=prefs;preference=ui'><b>[UI_style]</b></a><br>"
dat += "<b>Custom UI</b>(recommended for White UI):<br>"
dat += "-Color: <a href='?_src_=prefs;preference=UIcolor'><b>[UI_style_color]</b></a> <table style='display:inline;' bgcolor='[UI_style_color]'><tr><td>__</td></tr></table><br>"
dat += "-Alpha(transparence): <a href='?_src_=prefs;preference=UIalpha'><b>[UI_style_alpha]</b></a><br>"
dat += "<b>Play admin midis:</b> <a href='?_src_=prefs;preference=hear_midis'><b>[(toggles & SOUND_MIDI) ? "Yes" : "No"]</b></a><br>"
dat += "<b>Play lobby music:</b> <a href='?_src_=prefs;preference=lobby_music'><b>[(toggles & SOUND_LOBBY) ? "Yes" : "No"]</b></a><br>"
dat += "<b>Ghost ears:</b> <a href='?_src_=prefs;preference=ghost_ears'><b>[(toggles & CHAT_GHOSTEARS) ? "Nearest Creatures" : "All Speech"]</b></a><br>"
dat += "<b>Ghost sight:</b> <a href='?_src_=prefs;preference=ghost_sight'><b>[(toggles & CHAT_GHOSTSIGHT) ? "Nearest Creatures" : "All Emotes"]</b></a><br>"
dat += "<b>Ghost radio:</b> <a href='?_src_=prefs;preference=ghost_radio'><b>[(toggles & CHAT_GHOSTRADIO) ? "Nearest Speakers" : "All Chatter"]</b></a><br>"
if(config.allow_Metadata)
dat += "<b>OOC Notes:</b> <a href='?_src_=prefs;preference=metadata;task=input'> Edit </a><br>"
@@ -264,6 +270,7 @@ datum/preferences
//dat += "Skin pattern: <a href='byond://?src=\ref[user];preference=skin_style;task=input'>Adjust</a><br>"
dat += "Needs Glasses: <a href='?_src_=prefs;preference=disabilities'><b>[disabilities == 0 ? "No" : "Yes"]</b></a><br>"
dat += "Limbs: <a href='byond://?src=\ref[user];preference=limbs;task=input'>Adjust</a><br>"
dat += "Internal Organs: <a href='byond://?src=\ref[user];preference=organs;task=input'>Adjust</a><br>"
//display limbs below
var/ind = 0
@@ -288,6 +295,10 @@ datum/preferences
organ_name = "left hand"
if("r_hand")
organ_name = "right hand"
if("heart")
organ_name = "heart"
if("eyes")
organ_name = "eyes"
if(status == "cyborg")
++ind
@@ -299,6 +310,24 @@ datum/preferences
if(ind > 1)
dat += ", "
dat += "\tAmputated [organ_name]"
else if(status == "mechanical")
++ind
if(ind > 1)
dat += ", "
dat += "\tMechanical [organ_name]"
else if(status == "assisted")
++ind
if(ind > 1)
dat += ", "
switch(organ_name)
if("heart")
dat += "\tPacemaker-assisted [organ_name]"
if("voicebox") //on adding voiceboxes for speaking skrell/similar replacements
dat += "\tSurgically altered [organ_name]"
if("eyes")
dat += "\tRetinal overlayed [organ_name]"
else
dat += "\tMechanically assisted [organ_name]"
if(!ind)
dat += "\[...\]<br><br>"
else
@@ -1087,6 +1116,28 @@ datum/preferences
if(second_limb)
organ_data[second_limb] = "cyborg"
if("organs")
var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Heart", "Eyes")
if(!organ_name) return
var/organ = null
switch(organ_name)
if("Heart")
organ = "heart"
if("Eyes")
organ = "eyes"
var/new_state = input(user, "What state do you wish the organ to be in?") as null|anything in list("Normal","Assisted","Mechanical")
if(!new_state) return
switch(new_state)
if("Normal")
organ_data[organ] = null
if("Assisted")
organ_data[organ] = "assisted"
if("Mechanical")
organ_data[organ] = "mechanical"
if("skin_style")
var/skin_style_name = input(user, "Select a new skin style") as null|anything in list("default1", "default2", "default3")
if(!skin_style_name) return
@@ -1111,9 +1162,21 @@ datum/preferences
UI_style = "Orange"
if("Orange")
UI_style = "old"
if("old")
UI_style = "White"
else
UI_style = "Midnight"
if("UIcolor")
var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!") as color|null
if(!UI_style_color_new) return
UI_style_color = UI_style_color_new
if("UIalpha")
var/UI_style_alpha_new = input(user, "Select a new alpha(transparence) parametr for UI, between 50 and 255") as num
if(!UI_style_alpha_new | !(UI_style_alpha_new <= 255 && UI_style_alpha_new >= 50)) return
UI_style_alpha = UI_style_alpha_new
if("be_special")
var/num = text2num(href_list["num"])
be_special ^= (1<<num)
@@ -1137,6 +1200,9 @@ datum/preferences
if("ghost_sight")
toggles ^= CHAT_GHOSTSIGHT
if("ghost_radio")
toggles ^= CHAT_GHOSTRADIO
if("save")
save_preferences()
save_character()
@@ -1206,19 +1272,27 @@ datum/preferences
character.skills = skills
// Destroy/cyborgize organs
for(var/name in organ_data)
var/datum/organ/external/O = character.organs_by_name[name]
if(!O) continue
var/datum/organ/internal/I = character.internal_organs_by_name[name]
var/status = organ_data[name]
if(status == "amputated")
O.amputated = 1
O.status |= ORGAN_DESTROYED
O.destspawn = 1
else if(status == "cyborg")
if(status == "cyborg")
O.status |= ORGAN_ROBOT
if(status == "assisted")
I.mechassist()
else if(status == "mechanical")
I.mechanize()
else continue
if(underwear > underwear_m.len || underwear < 1)
underwear = 1 //I'm sure this is 100% unnecessary, but I'm paranoid... sue me.
underwear = 0 //I'm sure this is 100% unnecessary, but I'm paranoid... sue me. //HAH NOW NO MORE MAGIC CLONING UNDIES
character.underwear = underwear
if(backbag > 4 || backbag < 1)
+8 -2
View File
@@ -1,5 +1,5 @@
#define SAVEFILE_VERSION_MIN 8
#define SAVEFILE_VERSION_MAX 10
#define SAVEFILE_VERSION_MAX 11
//handles converting savefiles to new formats
//MAKE SURE YOU KEEP THIS UP TO DATE!
@@ -54,14 +54,18 @@
S["be_special"] >> be_special
S["default_slot"] >> default_slot
S["toggles"] >> toggles
S["UI_style_color"] >> UI_style_color
S["UI_style_alpha"] >> UI_style_alpha
//Sanitize
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
UI_style = sanitize_inlist(UI_style, list("Midnight","Orange","old"), initial(UI_style))
UI_style = sanitize_inlist(UI_style, list("White", "Midnight","Orange","old"), initial(UI_style))
be_special = sanitize_integer(be_special, 0, 65535, initial(be_special))
default_slot = sanitize_integer(default_slot, 1, MAX_SAVE_SLOTS, initial(default_slot))
toggles = sanitize_integer(toggles, 0, 65535, initial(toggles))
UI_style_color = sanitize_hexcolor(UI_style_color, initial(UI_style_color))
UI_style_alpha = sanitize_integer(UI_style_alpha, 0, 255, initial(UI_style_alpha))
return 1
@@ -80,6 +84,8 @@
S["be_special"] << be_special
S["default_slot"] << default_slot
S["toggles"] << toggles
S["UI_style_color"] << UI_style_color
S["UI_style_alpha"] << UI_style_alpha
return 1
+52 -3
View File
@@ -17,14 +17,23 @@
prefs.save_preferences()
feedback_add_details("admin_verb","TGS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_ghost_radio()
set name = "Enable/Disable GhostRadio"
set category = "Preferences"
set desc = ".Toggle between hearing all radio chatter, or only from nearby speakers"
prefs.toggles ^= CHAT_GHOSTRADIO
src << "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTRADIO) ? "hear all radio chat in the world" : "only hear from nearby speakers"]."
prefs.save_preferences()
feedback_add_details("admin_verb","TGR")
/client/proc/toggle_hear_radio()
set name = "Show/Hide RadioChatter"
set category = "Preferences"
set desc = "Toggle seeing radiochatter from nearby radios and speakers"
set desc = "Toggle seeing radiochatter from radios and speakers"
if(!holder) return
prefs.toggles ^= CHAT_RADIO
prefs.save_preferences()
usr << "You will [(prefs.toggles & CHAT_RADIO) ? "now" : "no longer"] see radio chatter from nearby radios or speakers"
usr << "You will [(prefs.toggles & CHAT_RADIO) ? "now" : "no longer"] see radio chatter from radios or speakers"
feedback_add_details("admin_verb","THR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/toggleadminhelpsound()
@@ -107,10 +116,12 @@
set desc = "Toggles seeing Local OutOfCharacter chat"
prefs.toggles ^= CHAT_LOOC
prefs.save_preferences()
src << "You will [(prefs.toggles & CHAT_LOOC) ? "now" : "no longer"] see messages on the LOOC channel."
feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/Toggle_Soundscape() //All new ambience should be added here so it works with this verb until someone better at things comes up with a fix that isn't awful
set name = "Hear/Silence Ambience"
set category = "Preferences"
@@ -135,4 +146,42 @@
prefs.be_special ^= role_flag
prefs.save_preferences()
src << "You will [(prefs.be_special & role_flag) ? "now" : "no longer"] be considered for [role] events (where possible)."
feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/change_ui()
set name = "Change UI"
set category = "Preferences"
set desc = "Configure your user interface"
if(!ishuman(usr))
usr << "This only for human"
return
var/UI_style_new = input(usr, "Select a style, we recommend White for customization") in list("White", "Midnight", "Orange", "old")
if(!UI_style_new) return
var/UI_style_alpha_new = input(usr, "Select a new alpha(transparence) parametr for UI, between 50 and 255") as num
if(!UI_style_alpha_new | !(UI_style_alpha_new <= 255 && UI_style_alpha_new >= 50)) return
var/UI_style_color_new = input(usr, "Choose your UI color, dark colors are not recommended!") as color|null
if(!UI_style_color_new) return
//update UI
var/list/icons = usr.hud_used.adding + usr.hud_used.other +usr.hud_used.hotkeybuttons
icons.Add(usr.zone_sel)
for(var/obj/screen/I in icons)
if(I.color && I.alpha)
I.icon = ui_style2icon(UI_style_new)
I.color = UI_style_color_new
I.alpha = UI_style_alpha_new
if(alert("Like it? Save changes?",,"Yes", "No") == "Yes")
prefs.UI_style = UI_style_new
prefs.UI_style_alpha = UI_style_alpha_new
prefs.UI_style_color = UI_style_color_new
prefs.save_preferences()
usr << "UI was saved"
+1 -1
View File
@@ -28,7 +28,7 @@
return ..()
//Ears: currently only used for headsets and earmuffs
//Ears: headsets, earmuffs and tiny objects
/obj/item/clothing/ears
name = "ears"
w_class = 1.0
+6
View File
@@ -73,6 +73,12 @@
holder.icon_state = "hudxeno"
else if(foundVirus)
holder.icon_state = "hudill"
else if(patient.has_brain_worms())
var/mob/living/simple_animal/borer/B = patient.has_brain_worms()
if(B.controlling)
holder.icon_state = "hudbrainworm"
else
holder.icon_state = "hudhealthy"
else
holder.icon_state = "hudhealthy"
C.images += holder
+1
View File
@@ -19,6 +19,7 @@
var/candrain = 0
var/mindrain = 200
var/maxdrain = 400
species_restricted = null
/*
This runs the gamut of what ninja gloves can do
+12 -12
View File
@@ -1,6 +1,6 @@
/obj/item/clothing/head/soft
name = "cargo cap"
desc = "It's a baseball hat in a tasteless yellow colour."
desc = "It's a baseball hat in a tasteless yellow color."
icon_state = "cargosoft"
flags = FPRINT|TABLEPASS|HEADCOVERSEYES
item_state = "helmet"
@@ -29,49 +29,49 @@
/obj/item/clothing/head/soft/red
name = "red cap"
desc = "It's a baseball hat in a tasteless red colour."
desc = "It's a baseball hat in a tasteless red color."
icon_state = "redsoft"
item_color = "red"
/obj/item/clothing/head/soft/blue
name = "blue cap"
desc = "It's a baseball hat in a tasteless blue colour."
desc = "It's a baseball hat in a tasteless blue color."
icon_state = "bluesoft"
item_color = "blue"
/obj/item/clothing/head/soft/green
name = "green cap"
desc = "It's a baseball hat in a tasteless green colour."
desc = "It's a baseball hat in a tasteless green color."
icon_state = "greensoft"
item_color = "green"
/obj/item/clothing/head/soft/yellow
name = "yellow cap"
desc = "It's a baseball hat in a tasteless yellow colour."
desc = "It's a baseball hat in a tasteless yellow color."
icon_state = "yellowsoft"
item_color = "yellow"
/obj/item/clothing/head/soft/grey
name = "grey cap"
desc = "It's a baseball hat in a tasteful grey colour."
desc = "It's a baseball hat in a tasteful grey color."
icon_state = "greysoft"
item_color = "grey"
/obj/item/clothing/head/soft/orange
name = "orange cap"
desc = "It's a baseball hat in a tasteless orange colour."
desc = "It's a baseball hat in a tasteless orange color."
icon_state = "orangesoft"
item_color = "orange"
/obj/item/clothing/head/soft/mime
name = "white cap"
desc = "It's a baseball hat in a tasteless white colour."
desc = "It's a baseball hat in a tasteless white color."
icon_state = "mimesoft"
item_color = "mime"
/obj/item/clothing/head/soft/purple
name = "purple cap"
desc = "It's a baseball hat in a tasteless purple colour."
desc = "It's a baseball hat in a tasteless purple color."
icon_state = "purplesoft"
item_color = "purple"
@@ -83,12 +83,12 @@
/obj/item/clothing/head/soft/sec
name = "security cap"
desc = "It's baseball hat in tasteful red colour."
desc = "It's baseball hat in tasteful red color."
icon_state = "secsoft"
item_color = "sec"
/obj/item/clothing/head/soft/sec/corp
name = "corporate security cap"
desc = "It's baseball hat in corpotate colours."
desc = "It's baseball hat in corporate colors."
icon_state = "corpsoft"
item_color = "corp"
item_color = "corp"
+1 -1
View File
@@ -129,7 +129,7 @@
/obj/item/clothing/shoes/swimmingfins
desc = "Help you swim good."
name = "swimming fins"
icon_state = "flippers"
icon_state = "flipperfeet"
flags = NOSLIP
slowdown = SHOES_SLOWDOWN+1
species_restricted = null
+47 -1
View File
@@ -213,4 +213,50 @@
examine()
set src in view()
..()
..()
//Species-specific Syndicate rigs.
/obj/item/clothing/head/helmet/space/rig/syndi/tajara
icon_state = "rig0-syndie-taj"
item_state = "syndie_helm"
item_color = "syndie-taj"
species_restricted = list("Tajaran")
/obj/item/clothing/suit/space/rig/syndi/tajara
item_state = "syndie_hardsuit"
icon_state = "rig-syndie-taj"
species_restricted = list("Tajaran")
/obj/item/clothing/head/helmet/space/rig/syndi/unathi
icon_state = "rig0-syndie-unathi"
item_state = "syndie_helm"
item_color = "syndie-unathi"
species_restricted = list("Unathi")
/obj/item/clothing/suit/space/rig/syndi/unathi
item_state = "syndie_hardsuit"
icon_state = "rig-syndie-unathi"
species_restricted = list("Unathi")
/obj/item/clothing/head/helmet/space/rig/syndi/skrell
icon_state = "rig0-syndie-skrell"
item_state = "syndie_helm"
item_color = "syndie-skrell"
species_restricted = list("Skrell")
/obj/item/clothing/suit/space/rig/syndi/skrell
item_state = "syndie_hardsuit"
icon_state = "rig-syndie-skrell"
species_restricted = list("Skrell")
/obj/item/clothing/head/helmet/space/rig/syndi/human
icon_state = "rig0-syndie-human"
item_state = "syndie_helm"
item_color = "syndie-human"
species_restricted = list("Human")
/obj/item/clothing/suit/space/rig/syndi/human
item_state = "syndie_hardsuit"
icon_state = "rig-syndie-human"
species_restricted = list("Human")
+3 -2
View File
@@ -6,17 +6,18 @@
allowed = list(/obj/item/weapon/cell)
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 25)
siemens_coefficient = 0.2
species_restricted = null
/obj/item/clothing/suit/space/space_ninja
name = "ninja suit"
desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
icon_state = "s-ninja"
item_state = "s-ninja_suit"
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/cell)
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/weapon/cell)
slowdown = 0
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0.2
species_restricted = null //Workaround for spawning alien ninja without internals.
//Important parts of the suit.
var/mob/living/carbon/affecting = null//The wearer.
+7 -2
View File
@@ -25,6 +25,10 @@
if(on) user.SetLuminosity(user.luminosity + brightness_on)
else user.SetLuminosity(user.luminosity - brightness_on)
if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user
H.update_inv_head()
pickup(mob/user)
if(on)
user.SetLuminosity(user.luminosity + brightness_on)
@@ -90,7 +94,7 @@
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.6
var/obj/machinery/camera/camera
species_restricted = list("exclude","Vox")
/obj/item/clothing/head/helmet/space/rig/syndi/attack_self(mob/user)
if(camera)
..(user)
@@ -116,6 +120,7 @@
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs)
siemens_coefficient = 0.6
species_restricted = list("exclude","Vox")
//Wizard Rig
@@ -179,7 +184,7 @@
//Atmospherics Rig (BS12)
/obj/item/clothing/head/helmet/space/rig/atmos
desc = "A special helmet designed for work in a hazardou, low pressure environments. Has reduced radiation shielding and protective plating to allow for greater mobility."
desc = "A special helmet designed for work in a hazardous, low pressure environments. Has reduced radiation shielding and protective plating to allow for greater mobility."
name = "atmospherics hardsuit helmet"
icon_state = "rig0-atmos"
item_state = "atmos_helm"
+3
View File
@@ -77,6 +77,9 @@
allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy,/obj/item/weapon/gun/projectile,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder)
armor = list(melee = 50, bullet = 10, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0)
/obj/item/clothing/suit/storage/det_suit/black
icon_state = "detective2"
//Forensics
/obj/item/clothing/suit/storage/forensics
name = "jacket"
+1 -1
View File
@@ -5,7 +5,7 @@
item_state = "labcoat"
blood_overlay_type = "coat"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen)
allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper)
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0)
verb/toggle()
@@ -257,15 +257,6 @@
item_state = "neocoat"
flags = FPRINT | TABLEPASS
//actual suits
/obj/item/clothing/suit/creamsuit
name = "cream suit"
desc = "A cream coloured, genteel suit."
icon_state = "creamsuit"
item_state = "creamsuit"
flags = FPRINT | TABLEPASS
//stripper
/obj/item/clothing/under/stripper/stripper_pink
+12
View File
@@ -35,6 +35,12 @@
icon_state = "amp"
siemens_coefficient = 0.8
/obj/item/clothing/head/wizard/cap
name = "Gentlemans Cap"
desc = "A checkered gray flat cap woven together with the rarest of threads."
icon_state = "gentcap"
siemens_coefficient = 0.8
/obj/item/clothing/suit/wizrobe
name = "wizard robe"
desc = "A magnificant, gem-lined robe that seems to radiate power."
@@ -79,6 +85,12 @@
icon_state = "psyamp"
item_state = "psyamp"
/obj/item/clothing/suit/wizrobe/gentlecoat
name = "Gentlemans Coat"
desc = "A heavy threaded twead gray jacket. For a different sort of Gentleman."
icon_state = "gentlecoat"
item_state = "gentlecoat"
/obj/item/clothing/suit/wizrobe/fake
name = "wizard robe"
desc = "A rather dull, blue robe meant to mimick real wizard robes."
@@ -10,6 +10,24 @@
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0)
flags = FPRINT | TABLEPASS
/obj/item/clothing/under/rank/research_director/rdalt
desc = "A dress suit and slacks stained with hard work and dedication to science. Perhaps other things as well, but mostly hard work and dedication."
name = "head researcher uniform"
icon_state = "rdalt"
item_state = "rdalt"
item_color = "rdalt"
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0)
flags = FPRINT | TABLEPASS
/obj/item/clothing/under/rank/research_director/dress_rd
name = "research director dress uniform"
desc = "Feminine fashion for the style concious RD. Its fabric provides minor protection from biological contaminants."
icon_state = "dress_rd"
item_color = "dress_rd"
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0)
flags = FPRINT | TABLEPASS
/obj/item/clothing/under/rank/scientist
desc = "It's made of a special fiber that provides minor protection against biohazards. It has markings that denote the wearer as a scientist."
name = "scientist's jumpsuit"
@@ -71,6 +71,22 @@
flags = FPRINT | TABLEPASS
siemens_coefficient = 0.9
/obj/item/clothing/under/det/black
icon_state = "detective2"
item_color = "detective2"
/obj/item/clothing/under/det/slob
icon_state = "polsuit"
item_color = "polsuit"
/obj/item/clothing/under/det/slob/verb/rollup()
set name = "Roll suit sleeves"
set category = "Object"
set src in usr
item_color = item_color == "polsuit" ? "polsuit_rolled" : "polsuit"
if (ishuman(loc))
var/mob/living/carbon/human/H = loc
H.update_inv_w_uniform(1)
/obj/item/clothing/head/det_hat
name = "hat"
@@ -80,6 +96,10 @@
armor = list(melee = 50, bullet = 5, laser = 25,energy = 10, bomb = 0, bio = 0, rad = 0)
siemens_coefficient = 0.9
/obj/item/clothing/head/det_hat/black
icon_state = "detective2"
/*
* Head of Security
*/
+8 -6
View File
@@ -138,6 +138,13 @@
item_state = "psysuit"
item_color = "psysuit"
/obj/item/clothing/under/gentlesuit
name = "Gentlemans Suit"
desc = "A silk black shirt with a white tie and a matching gray vest and slacks. Feels proper."
icon_state = "gentlesuit"
item_state = "gentlesuit"
item_color = "gentlesuit"
/obj/item/clothing/under/gimmick/rank/captain/suit
name = "captain's suit"
desc = "A green suit and yellow necktie. Exemplifies authority."
@@ -285,11 +292,6 @@
icon_state = "dress_saloon"
item_color = "dress_saloon"
/obj/item/clothing/under/dress/dress_rd
name = "research director dress uniform"
desc = "Feminine fashion for the style concious RD."
icon_state = "dress_rd"
item_color = "dress_rd"
/obj/item/clothing/under/dress/dress_cap
name = "captain dress uniform"
@@ -358,7 +360,7 @@
flags_inv = HIDESHOES
/obj/item/clothing/under/wedding/bride_white
name = "orange wedding dress"
name = "silky wedding dress"
desc = "A white wedding gown made from the finest silk."
icon_state = "bride_white"
item_color = "bride_white"
+71 -14
View File
@@ -478,6 +478,7 @@
siemens_coefficient = 0.30
permeability_coefficient = 0.01
item_color="white"
species_restricted = list("exclude","Unathi")
/obj/item/clothing/gloves/fluff/walter_brooks_1 //botanistpower: Walter Brooks
name = "mittens"
@@ -493,12 +494,6 @@
icon = 'icons/obj/custom_items.dmi'
icon_state = "chal_appara_1"
/obj/item/clothing/gloves/fluff/ashley_rifler_1 //Vinceluk: Ashley Rifler
name = "Purple Glove"
desc = "A single, purple glove. Initials A.R. are written on the inside of it."
icon = 'icons/obj/custom_items.dmi'
icon_state = "ashley_rifler_1"
//////////// Eye Wear ////////////
/obj/item/clothing/glasses/meson/fluff/book_berner_1 //asanadas: Book Berner
@@ -590,14 +585,6 @@
icon = 'icons/obj/custom_items.dmi'
icon_state = "labcoat_pink_open"
/obj/item/clothing/suit/storage/det_suit/fluff/graycoat //vinceluk: Seth Sealis
name = "gray coat"
desc = "Old, worn out coat. It's seen better days."
icon = 'icons/obj/custom_items.dmi'
icon_state = "graycoat"
item_state = "graycoat"
item_color = "graycoat"
/obj/item/clothing/suit/storage/det_suit/fluff/leatherjack //atomicdog92: Seth Sealis
name = "leather jacket"
desc = "A black leather coat, popular amongst punks, greasers, and other galactic scum."
@@ -746,6 +733,15 @@
item_state = "wyatt_uniform"
item_color = "wyatt_uniform"
////// Black Dress - Lillian Amsel - PapaDrow
/obj/item/clothing/under/fluff/lillian_amsel_1
name = "Black Dress"
desc = "A knee-length, dark gray and black dress made of a soft, velvety material."
icon = 'icons/obj/custom_items.dmi'
icon_state = "lillian_dress"
item_state = "lillian_dress"
item_color = "lillian_dress"
//////////// Masks ////////////
/*
@@ -836,6 +832,15 @@
flags = FPRINT|TABLEPASS
w_class = 1
////// Apollon Pendant - Michael Guess - Dragor23
/obj/item/clothing/mask/michael_guess_1
name = "Apollon Pendant"
desc = "A pendant with the form of a sacrificial tripod, used in acient greece. It's a symbol of the Olympian Apollon, a god associated with oracles, poetry, the sun and healing."
icon = 'icons/obj/custom_items.dmi'
icon_state = "michael_guess_1"
flags = FPRINT|TABLEPASS
w_class = 1
slot_flags = SLOT_MASK
//////////// Shoes ////////////
/obj/item/clothing/shoes/magboots/fluff/susan_harris_1 //sniperyeti: Susan Harris
@@ -860,6 +865,7 @@
desc = "Made of a special fiber that gives special protection against biohazards. Has a cross on the chest denoting that the wearer is trained medical personnel and short sleeves."
icon = 'icons/obj/custom_items.dmi'
icon_state = "medical_short"
item_state = "medical_short"
item_color = "medical_short"
/obj/item/clothing/suit/storage/labcoat/fluff/red
@@ -919,3 +925,54 @@
if(istype(A, /obj/item/ammo_magazine))
flick("leamas-reloading",src)
..()
///// Custom Items coded by Iamgoofball are Below /////
/obj/item/weapon/storage/belt/medical/fluff/nashi_belt
name = "rainbow medical belt"
desc = "A somewhat-worn, modified, rainbow belt."
icon = 'icons/obj/custom_items.dmi'
icon_state = "nashi_belt"
item_state = "fluff_rbelt"
New()
..()
new /obj/item/weapon/reagent_containers/glass/bottle/fluff/nashi_bottle(src, 14, "Bicaridine")
new /obj/item/weapon/reagent_containers/glass/bottle/fluff/nashi_bottle(src, 15, "Dermaline")
new /obj/item/weapon/reagent_containers/glass/bottle/fluff/nashi_bottle(src, 16, "Dylovene")
new /obj/item/weapon/reagent_containers/glass/bottle/fluff/nashi_bottle(src, 17, "Dexalin Plus")
new /obj/item/weapon/reagent_containers/glass/bottle/fluff/nashi_bottle(src, 18, "Tricordrazine")
new /obj/item/weapon/reagent_containers/syringe/(src)
new /obj/item/device/healthanalyzer(src)
/obj/item/weapon/reagent_containers/glass/bottle/fluff/nashi_bottle
icon = 'icons/obj/chemical.dmi'
flags = FPRINT | TABLEPASS //Starting them with lids on them. Safety first!
New(loc, var/color, var/labeled)
..()
name = "[labeled] bottle"
desc = "A small bottle. Contains [labeled]"
icon_state = "bottle[color]"
/obj/item/weapon/reagent_containers/food/drinks/flask/fluff/yuri_kornienkovich_flask
name = "Yuri's Flask"
desc = "An old gold plated flask. Nothing noteworthy about it besides it being gold and the red star on the worn out leather around it. There is also an engraving on the cap that is rather hard to see but it looks like \"Kornienkovich\" "
icon = 'icons/obj/custom_items.dmi'
icon_state = "yuri_kornienkovich_flask"
/obj/item/clothing/under/fluff/mai_yang_dress // Mai Yang's pretty pretty dress.
name = "White Cheongsam"
desc = "It is a white cheongsam dress."
icon = 'icons/obj/custom_items.dmi'
icon_state = "mai_yang"
item_state = "mai_yang"
item_color = "mai_yang"
/obj/item/clothing/under/fluff/sakura_hokkaido_kimono
name = "Sakura Kimono"
desc = "A pale-pink, nearly white, kimono with a red and gold obi. There is a embroidered design of cherry blossom flowers covering the kimono."
icon = 'icons/obj/custom_items.dmi'
icon_state = "sakura_hokkaido_kimono"
item_state = "sakura_hokkaido_kimono"
item_color = "sakura_hokkaido_kimono"
+18 -1
View File
@@ -57,6 +57,23 @@
del(C)
ok = M.equip_if_possible(I, slot_wear_id, 0) //if 1, last argument deletes on fail
break
else if(istype(Item,/obj/item/weapon/storage/belt))
if(M.ckey == "jakksergal" && M.real_name == "Nashi Ra'hal" && M.mind.role_alt_title && M.mind.role_alt_title != "Nurse" && M.mind.role_alt_title != "Chemist")
ok = 1
del(Item)
goto skip
var/obj/item/weapon/storage/belt/medical/fluff/nashi_belt/I = Item
if(istype(M.belt,/obj/item/weapon/storage/belt))
for(var/obj/item/weapon/storage/belt/B in M)
del(B)
M.belt=null
ok = M.equip_if_possible(I, slot_belt, 0)
break
if(istype(M.belt,/obj/item/device/pda))
for(var/obj/item/device/pda/Pda in M)
M.belt=null
M.equip_if_possible(Pda, slot_l_store, 0)
ok = M.equip_if_possible(I, slot_belt, 0)
else if(istype(M.back,/obj/item/weapon/storage) && M.back:contents.len < M.back:storage_slots) // Try to place it in something on the mob's back
Item.loc = M.back
ok = 1
@@ -70,4 +87,4 @@
skip:
if (ok == 0) // Finally, since everything else failed, place it on the ground
Item.loc = get_turf(M.loc)
Item.loc = get_turf(M.loc)
+2 -2
View File
@@ -118,7 +118,7 @@
switch(fermenting_item.type)
if(/obj/item/weapon/reagent_containers/food/drinks/flour) //Flour is still flour
var/obj/item/weapon/reagent_containers/food/drinks/beer/B = new(src)
var/obj/item/weapon/reagent_containers/food/drinks/cans/beer/B = new(src)
output += B
else
error = 1
@@ -178,7 +178,7 @@
return //Not done yet.
switch(destilling_item.type)
if(/obj/item/weapon/reagent_containers/food/drinks/beer) //Flour is still flour
if(/obj/item/weapon/reagent_containers/food/drinks/cans/beer) //Flour is still flour
var/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka/V = new(src)
output += V
else
@@ -4,6 +4,7 @@
var/track_blood = 0
var/list/feet_blood_DNA
var/track_blood_type
var/feet_blood_color
/obj/item/clothing/gloves
var/transfer_blood = 0
+4 -4
View File
@@ -70,6 +70,7 @@
return
if(istype(A,/obj/machinery/computer/forensic_scanning)) //breaks shit.
return
if(istype(A,/obj/item/weapon/f_card))
user << "The scanner displays on the screen: \"ERROR 43: Object on Excluded Object List.\""
flick("forensic0",src)
@@ -77,9 +78,8 @@
add_fingerprint(user)
//Special case for blood splaters.
if (istype(A, /obj/effect/decal/cleanable/blood) || istype(A, /obj/effect/rune))
//Special case for blood splatters, runes and gibs.
if (istype(A, /obj/effect/decal/cleanable/blood) || istype(A, /obj/effect/rune) || istype(A, /obj/effect/decal/cleanable/blood/gibs))
if(!isnull(A.blood_DNA))
for(var/blood in A.blood_DNA)
user << "\blue Blood type: [A.blood_DNA[blood]]\nDNA: [blood]"
@@ -178,4 +178,4 @@
sum_list[3] = A.blood_DNA ? A.blood_DNA.Copy() : null
sum_list[4] = "\The [A] in \the [get_area(A)]"
stored["\ref [A]"] = sum_list
return 0
return 0
+126 -91
View File
@@ -32,10 +32,14 @@ log transactions
var/obj/item/weapon/card/held_card
var/editing_security_level = 0
var/view_screen = NO_SCREEN
var/datum/effect/effect/system/spark_spread/spark_system
/obj/machinery/atm/New()
..()
machine_id = "[station_name()] RT #[num_financial_terminals++]"
spark_system = new /datum/effect/effect/system/spark_spread
spark_system.set_up(5, 0, src)
spark_system.attach(src)
/obj/machinery/atm/process()
if(stat & NOPOWER)
@@ -60,6 +64,23 @@ log transactions
/obj/machinery/atm/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/weapon/card))
if(emagged > 0)
//prevent inserting id into an emagged ATM
user << "\red \icon[src] CARD READER ERROR. This system has been compromised!"
return
else if(istype(I,/obj/item/weapon/card/emag))
//short out the machine, shoot sparks, spew money!
emagged = 1
spark_system.start()
spawn_money(rand(100,500),src.loc)
//we don't want to grief people by locking their id in an emagged ATM
release_held_id(user)
//display a message to the user
var/response = pick("Initiating withdraw. Have a nice day!", "CRITICAL ERROR: Activating cash chamber panic siphon.","PIN Code accepted! Emptying account balance.", "Jackpot!")
user << "\red \icon[src] The [src] beeps: \"[response]\""
return
var/obj/item/weapon/card/id/idcard = I
if(!held_card)
usr.drop_item()
@@ -94,7 +115,7 @@ log transactions
/obj/machinery/atm/attack_hand(mob/user as mob)
if(istype(user, /mob/living/silicon))
user << "\red Artificial unit recognized. Artificial units do not currently receive monetary compensation, as per NanoTrasen regulation #1005."
user << "\red \icon[src] Artificial unit recognized. Artificial units do not currently receive monetary compensation, as per NanoTrasen regulation #1005."
return
if(get_dist(src,user) <= 1)
@@ -102,84 +123,88 @@ log transactions
var/dat = "<h1>NanoTrasen Automatic Teller Machine</h1>"
dat += "For all your monetary needs!<br>"
dat += "<i>This terminal is</i> [machine_id]. <i>Report this code when contacting NanoTrasen IT Support</i><br/>"
dat += "Card: <a href='?src=\ref[src];choice=insert_card'>[held_card ? held_card.name : "------"]</a><br><br>"
if(ticks_left_locked_down > 0)
dat += "<span class='alert'>Maximum number of pin attempts exceeded! Access to this ATM has been temporarily disabled.</span>"
else if(authenticated_account)
if(authenticated_account.suspended)
dat += "\red<b>Access to this account has been suspended, and the funds within frozen.</b>"
else
switch(view_screen)
if(CHANGE_SECURITY_LEVEL)
dat += "Select a new security level for this account:<br><hr>"
var/text = "Zero - Either the account number or card is required to access this account. EFTPOS transactions will require a card and ask for a pin, but not verify the pin is correct."
if(authenticated_account.security_level != 0)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=0'>[text]</a>"
dat += "[text]<hr>"
text = "One - An account number and pin must be manually entered to access this account and process transactions."
if(authenticated_account.security_level != 1)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=1'>[text]</a>"
dat += "[text]<hr>"
text = "Two - In addition to account number and pin, a card is required to access this account and process transactions."
if(authenticated_account.security_level != 2)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=2'>[text]</a>"
dat += "[text]<hr><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a>"
if(VIEW_TRANSACTION_LOGS)
dat += "<b>Transaction logs</b><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a>"
dat += "<table border=1 style='width:100%'>"
dat += "<tr>"
dat += "<td><b>Date</b></td>"
dat += "<td><b>Time</b></td>"
dat += "<td><b>Target</b></td>"
dat += "<td><b>Purpose</b></td>"
dat += "<td><b>Value</b></td>"
dat += "<td><b>Source terminal ID</b></td>"
dat += "</tr>"
for(var/datum/transaction/T in authenticated_account.transaction_log)
dat += "<tr>"
dat += "<td>[T.date]</td>"
dat += "<td>[T.time]</td>"
dat += "<td>[T.target_name]</td>"
dat += "<td>[T.purpose]</td>"
dat += "<td>$[T.amount]</td>"
dat += "<td>[T.source_terminal]</td>"
dat += "</tr>"
dat += "</table>"
if(TRANSFER_FUNDS)
dat += "<b>Account balance:</b> $[authenticated_account.money]<br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a><br><br>"
dat += "<form name='transfer' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='transfer'>"
dat += "Target account number: <input type='text' name='target_acc_number' value='' style='width:200px; background-color:white;'><br>"
dat += "Funds to transfer: <input type='text' name='funds_amount' value='' style='width:200px; background-color:white;'><br>"
dat += "Transaction purpose: <input type='text' name='purpose' value='Funds transfer' style='width:200px; background-color:white;'><br>"
dat += "<input type='submit' value='Transfer funds'><br>"
dat += "</form>"
else
dat += "Welcome, <b>[authenticated_account.owner_name].</b><br/>"
dat += "<b>Account balance:</b> $[authenticated_account.money]"
dat += "<form name='withdrawal' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='withdrawal'>"
dat += "<input type='text' name='funds_amount' value='' style='width:200px; background-color:white;'><input type='submit' value='Withdraw funds'><br>"
dat += "</form>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=1'>Change account security level</a><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=2'>Make transfer</a><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=3'>View transaction log</a><br>"
dat += "<A href='?src=\ref[src];choice=balance_statement'>Print balance statement</a><br>"
dat += "<A href='?src=\ref[src];choice=logout'>Logout</a><br>"
if(emagged > 0)
dat += "Card: <span style='color: red;'>LOCKED</span><br><br><span style='color: red;'>Unauthorized terminal access detected! This ATM has been locked. Please contact NanoTrasen IT Support.</span>"
else
dat += "<form name='atm_auth' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='attempt_auth'>"
dat += "<b>Account:</b> <input type='text' id='account_num' name='account_num' style='width:250px; background-color:white;'><br>"
dat += "<b>PIN:</b> <input type='text' id='account_pin' name='account_pin' style='width:250px; background-color:white;'><br>"
dat += "<input type='submit' value='Submit'><br>"
dat += "</form>"
dat += "Card: <a href='?src=\ref[src];choice=insert_card'>[held_card ? held_card.name : "------"]</a><br><br>"
if(ticks_left_locked_down > 0)
dat += "<span class='alert'>Maximum number of pin attempts exceeded! Access to this ATM has been temporarily disabled.</span>"
else if(authenticated_account)
if(authenticated_account.suspended)
dat += "\red<b>Access to this account has been suspended, and the funds within frozen.</b>"
else
switch(view_screen)
if(CHANGE_SECURITY_LEVEL)
dat += "Select a new security level for this account:<br><hr>"
var/text = "Zero - Either the account number or card is required to access this account. EFTPOS transactions will require a card and ask for a pin, but not verify the pin is correct."
if(authenticated_account.security_level != 0)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=0'>[text]</a>"
dat += "[text]<hr>"
text = "One - An account number and pin must be manually entered to access this account and process transactions."
if(authenticated_account.security_level != 1)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=1'>[text]</a>"
dat += "[text]<hr>"
text = "Two - In addition to account number and pin, a card is required to access this account and process transactions."
if(authenticated_account.security_level != 2)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=2'>[text]</a>"
dat += "[text]<hr><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a>"
if(VIEW_TRANSACTION_LOGS)
dat += "<b>Transaction logs</b><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a>"
dat += "<table border=1 style='width:100%'>"
dat += "<tr>"
dat += "<td><b>Date</b></td>"
dat += "<td><b>Time</b></td>"
dat += "<td><b>Target</b></td>"
dat += "<td><b>Purpose</b></td>"
dat += "<td><b>Value</b></td>"
dat += "<td><b>Source terminal ID</b></td>"
dat += "</tr>"
for(var/datum/transaction/T in authenticated_account.transaction_log)
dat += "<tr>"
dat += "<td>[T.date]</td>"
dat += "<td>[T.time]</td>"
dat += "<td>[T.target_name]</td>"
dat += "<td>[T.purpose]</td>"
dat += "<td>$[T.amount]</td>"
dat += "<td>[T.source_terminal]</td>"
dat += "</tr>"
dat += "</table>"
if(TRANSFER_FUNDS)
dat += "<b>Account balance:</b> $[authenticated_account.money]<br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a><br><br>"
dat += "<form name='transfer' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='transfer'>"
dat += "Target account number: <input type='text' name='target_acc_number' value='' style='width:200px; background-color:white;'><br>"
dat += "Funds to transfer: <input type='text' name='funds_amount' value='' style='width:200px; background-color:white;'><br>"
dat += "Transaction purpose: <input type='text' name='purpose' value='Funds transfer' style='width:200px; background-color:white;'><br>"
dat += "<input type='submit' value='Transfer funds'><br>"
dat += "</form>"
else
dat += "Welcome, <b>[authenticated_account.owner_name].</b><br/>"
dat += "<b>Account balance:</b> $[authenticated_account.money]"
dat += "<form name='withdrawal' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='withdrawal'>"
dat += "<input type='text' name='funds_amount' value='' style='width:200px; background-color:white;'><input type='submit' value='Withdraw funds'><br>"
dat += "</form>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=1'>Change account security level</a><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=2'>Make transfer</a><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=3'>View transaction log</a><br>"
dat += "<A href='?src=\ref[src];choice=balance_statement'>Print balance statement</a><br>"
dat += "<A href='?src=\ref[src];choice=logout'>Logout</a><br>"
else
dat += "<form name='atm_auth' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='attempt_auth'>"
dat += "<b>Account:</b> <input type='text' id='account_num' name='account_num' style='width:250px; background-color:white;'><br>"
dat += "<b>PIN:</b> <input type='text' id='account_pin' name='account_pin' style='width:250px; background-color:white;'><br>"
dat += "<input type='submit' value='Submit'><br>"
dat += "</form>"
user << browse(dat,"window=atm;size=550x650")
else
@@ -322,20 +347,18 @@ log transactions
else
playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
if("insert_card")
if(held_card)
held_card.loc = src.loc
authenticated_account = null
if(ishuman(usr) && !usr.get_active_hand())
usr.put_in_hands(held_card)
held_card = null
if(!held_card)
//this might happen if the user had the browser window open when somebody emagged it
if(emagged > 0)
usr << "\red \icon[src] The ATM card reader rejected your ID because this machine has been sabotaged!"
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id))
usr.drop_item()
I.loc = src
held_card = I
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id))
usr.drop_item()
I.loc = src
held_card = I
release_held_id(usr)
if("logout")
authenticated_account = null
//usr << browse(null,"window=atm")
@@ -366,4 +389,16 @@ log transactions
T.time = worldtime2text()
authenticated_account.transaction_log.Add(T)
view_screen = NO_SCREEN
view_screen = NO_SCREEN
// put the currently held id on the ground or in the hand of the user
/obj/machinery/atm/proc/release_held_id(mob/living/carbon/human/human_user as mob)
if(!held_card)
return
held_card.loc = src.loc
authenticated_account = null
if(ishuman(human_user) && !human_user.get_active_hand())
human_user.put_in_hands(held_card)
held_card = null
+1 -1
View File
@@ -103,7 +103,7 @@ var/global/economy_init = 0
create_department_account("Vendor")
vendor_account = department_accounts["Vendor"]
current_date_string = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], 2557"
current_date_string = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], [game_year]"
economy_init = 1
return 1
+38
View File
@@ -0,0 +1,38 @@
//Cortical borer spawn event - care of RobRichards1997 with minor editing by Zuhayr.
/datum/event/borer_infestation
oneShot = 1
/datum/event/borer_infestation
announceWhen = 400
var/spawncount = 1
var/successSpawn = 0 //So we don't make a command report if nothing gets spawned.
/datum/event/borer_infestation/setup()
announceWhen = rand(announceWhen, announceWhen + 50)
spawncount = rand(1, 3)
/datum/event/borer_infestation/announce()
if(successSpawn)
command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert")
world << sound('sound/AI/aliens.ogg')
/datum/event/borer_infestation/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world)
if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network)
//Stops cortical borers getting stuck in small networks. See: Security, Virology
if(temp_vent.network.normal_members.len > 50)
vents += temp_vent
var/list/candidates = get_alien_candidates()
while(spawncount > 0 && vents.len && candidates.len)
var/obj/vent = pick_n_take(vents)
var/client/C = pick_n_take(candidates)
var/mob/living/simple_animal/borer/new_borer = new(vent.loc)
new_borer.key = C.key
spawncount--
successSpawn = 1
+2 -2
View File
@@ -30,8 +30,8 @@
continue
var/datum/disease/dnaspread/D = new
D.strain_data["name"] = H.real_name
D.strain_data["UI"] = H.dna.uni_identity
D.strain_data["SE"] = H.dna.struc_enzymes
D.strain_data["UI"] = H.dna.UI
D.strain_data["SE"] = H.dna.SE
D.carrier = 1
D.holder = H
D.affected_mob = H
+2 -1
View File
@@ -94,7 +94,8 @@
if(ai.aiPDA != P && ai.aiPDA != src)
ai.show_message("<i>Intercepted message from <b>[sender]</b></i> (Unknown / spam?) <i>to <b>[P:owner]</b>: [message]</i>")
P.tnote += "<i><b>&larr; From [sender] (Unknown / spam?):</b></i><br>[message]<br>"
//Commented out because we don't send messages like this anymore. Instead it will just popup in their chat window.
//P.tnote += "<i><b>&larr; From [sender] (Unknown / spam?):</b></i><br>[message]<br>"
if (!P.silent)
playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1)
+2 -2
View File
@@ -34,10 +34,10 @@
H.apply_effect((rand(40,70)),IRRADIATE,0)
if (prob(75))
randmutb(H) // Applies bad mutation
domutcheck(H,null,1)
domutcheck(H,null,MUTCHK_FORCED)
else
randmutg(H) // Applies good mutation
domutcheck(H,null,1)
domutcheck(H,null,MUTCHK_FORCED)
for(var/mob/living/carbon/monkey/M in living_mob_list)
+9 -4
View File
@@ -4,11 +4,16 @@
return
/proc/send2mainirc(var/msg)
if(config.use_irc_bot && config.main_irc && config.irc_bot_host)
ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [config.main_irc] [msg]")
if(config.main_irc)
send2irc(config.main_irc, msg)
return
/proc/send2adminirc(var/msg)
if(config.use_irc_bot && config.admin_irc && config.irc_bot_host)
ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [config.admin_irc] [msg]")
if(config.admin_irc)
send2irc(config.admin_irc, msg)
return
/hook/startup/proc/ircNotify()
send2mainirc("Server starting up on [config.server? "byond://[config.server]" : "byond://[world.address]:[world.port]"]")
return 1
+2 -2
View File
@@ -57,7 +57,7 @@ proc/NewStutter(phrase,stunned)
split_phrase[index] = word
return sanitize(dd_list2text(split_phrase," "))
return sanitize(list2text(split_phrase," "))
proc/Stagger(mob/M,d) //Technically not a filter, but it relates to drunkenness.
step(M, pick(d,turn(d,90),turn(d,-90)))
@@ -78,6 +78,6 @@ proc/Ellipsis(original_msg, chance = 50)
else
new_words += w
new_msg = dd_list2text(new_words," ")
new_msg = list2text(new_words," ")
return new_msg
+34 -1
View File
@@ -33,6 +33,15 @@ I said no!
)
result = /obj/item/weapon/reagent_containers/food/snacks/boiledegg
/datum/recipe/dionaroast
reagents = list("radium" = 5)
items = list(
/obj/item/weapon/holder/diona,
/obj/item/weapon/reagent_containers/food/snacks/grown/apple
)
result = /obj/item/weapon/reagent_containers/food/snacks/dionaroast
/*
/datum/recipe/bananaphone
reagents = list("psilocybin" = 5) //Trippin' balls, man.
@@ -477,6 +486,15 @@ I said no!
)
result = /obj/item/weapon/reagent_containers/food/snacks/popcorn
/datum/recipe/cookie
reagents = list("milk" = 5, "flour" = 5)
items = list(
/obj/item/weapon/reagent_containers/food/snacks/egg,
/obj/item/weapon/reagent_containers/food/snacks/chocolatebar,
)
result = /obj/item/weapon/reagent_containers/food/snacks/cookie
/datum/recipe/fortunecookie
reagents = list("flour" = 5)
items = list(
@@ -1142,4 +1160,19 @@ I said no!
/datum/recipe/cracker
reagents = list("flour" = 5, "sodiumchloride" = 1)
result = /obj/item/weapon/reagent_containers/food/snacks/cracker
result = /obj/item/weapon/reagent_containers/food/snacks/cracker
/datum/recipe/stuffing
reagents = list("water" = 5, "sodiumchloride" = 1, "blackpepper" = 1)
items = list(
/obj/item/weapon/reagent_containers/food/snacks/sliceable/bread,
)
result = /obj/item/weapon/reagent_containers/food/snacks/stuffing
/datum/recipe/tofurkey
items = list(
/obj/item/weapon/reagent_containers/food/snacks/tofu,
/obj/item/weapon/reagent_containers/food/snacks/tofu,
/obj/item/weapon/reagent_containers/food/snacks/stuffing,
)
result = /obj/item/weapon/reagent_containers/food/snacks/tofurkey
+2 -1
View File
@@ -99,8 +99,9 @@
new /obj/item/weapon/book/manual/engineering_particle_accelerator(src)
new /obj/item/weapon/book/manual/engineering_hacking(src)
new /obj/item/weapon/book/manual/engineering_guide(src)
new /obj/item/weapon/book/manual/atmospipes(src)
new /obj/item/weapon/book/manual/engineering_singularity_safety(src)
new /obj/item/weapon/book/manual/robotics_cyborgs(src)
new /obj/item/weapon/book/manual/evaguide(src)
update_icon()
/obj/structure/bookcase/manuals/research_and_development
+115
View File
@@ -0,0 +1,115 @@
/obj/structure/closet/crate/secure/loot
name = "abandoned crate"
desc = "What could be inside?"
icon_state = "securecrate"
icon_opened = "securecrateopen"
icon_closed = "securecrate"
var/code = null
var/lastattempt = null
var/attempts = 3
locked = 1
var/min = 1
var/max = 10
/obj/structure/closet/crate/secure/loot/New()
..()
code = rand(min,max)
var/loot = rand(1,30)
switch(loot)
if(1)
new/obj/item/weapon/reagent_containers/food/drinks/bottle/rum(src)
new/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus(src)
new/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey(src)
new/obj/item/weapon/lighter/zippo(src)
if(2)
new/obj/item/weapon/pickaxe/drill(src)
new/obj/item/device/taperecorder(src)
new/obj/item/clothing/suit/space(src)
new/obj/item/clothing/head/helmet/space(src)
if(3)
return
if(4)
new/obj/item/weapon/reagent_containers/glass/beaker/bluespace(src)
if(5 to 6)
for(var/i = 0, i < 10, i++)
new/obj/item/weapon/ore/diamond(src)
if(7)
return
if(8)
return
if(9)
for(var/i = 0, i < 3, i++)
new/obj/machinery/hydroponics(src)
if(10)
for(var/i = 0, i < 3, i++)
new/obj/item/weapon/reagent_containers/glass/beaker/noreact(src)
if(11 to 12)
for(var/i = 0, i < 9, i++)
new/obj/item/bluespace_crystal(src)
if(13)
new/obj/item/weapon/melee/classic_baton(src)
if(14)
return
if(15)
new/obj/item/clothing/under/chameleon(src)
for(var/i = 0, i < 7, i++)
new/obj/item/clothing/tie/horrible(src)
if(16)
new/obj/item/clothing/under/shorts(src)
new/obj/item/clothing/under/shorts/red(src)
new/obj/item/clothing/under/shorts/blue(src)
//Dummy crates start here.
if(17 to 29)
return
//Dummy crates end here.
if(30)
new/obj/item/weapon/melee/baton(src)
/obj/structure/closet/crate/secure/loot/attack_hand(mob/user as mob)
if(locked)
user << "<span class='notice'>The crate is locked with a Deca-code lock.</span>"
var/input = input(usr, "Enter digit from [min] to [max].", "Deca-Code Lock", "") as num
if(in_range(src, user))
input = Clamp(input, 0, 10)
if (input == code)
user << "<span class='notice'>The crate unlocks!</span>"
locked = 0
else if (input == null || input > max || input < min)
user << "<span class='notice'>You leave the crate alone.</span>"
else
user << "<span class='warning'>A red light flashes.</span>"
lastattempt = input
attempts--
if (attempts == 0)
user << "<span class='danger'>The crate's anti-tamper system activates!</span>"
var/turf/T = get_turf(src.loc)
explosion(T, 0, 0, 0, 1)
del(src)
return
else
user << "<span class='notice'>You attempt to interact with the device using a hand gesture, but it appears this crate is from before the DECANECT came out.</span>"
return
else
return ..()
/obj/structure/closet/crate/secure/loot/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(locked)
if (istype(W, /obj/item/weapon/card/emag))
user << "<span class='notice'>The crate unlocks!</span>"
locked = 0
if (istype(W, /obj/item/device/multitool))
user << "<span class='notice'>DECA-CODE LOCK REPORT:</span>"
if (attempts == 1)
user << "<span class='warning'>* Anti-Tamper Bomb will activate on next failed access attempt.</span>"
else
user << "<span class='notice'>* Anti-Tamper Bomb will activate after [src.attempts] failed access attempts.</span>"
if (lastattempt == null)
user << "<span class='notice'> has been made to open the crate thus far.</span>"
return
// hot and cold
if (code > lastattempt)
user << "<span class='notice'>* Last access attempt lower than expected code.</span>"
else
user << "<span class='notice'>* Last access attempt higher than expected code.</span>"
else ..()
else ..()
+24
View File
@@ -298,9 +298,25 @@
new /obj/item/stack/sheet/mineral/clown(output.loc)
else
on = 0
if (selected_glass == 1 && selected_gold == 0 && selected_silver == 0 && selected_diamond == 0 && selected_plasma == 1 && selected_uranium == 0 && selected_iron == 0 && selected_clown == 0)
if (ore_glass > 0 && ore_plasma > 0)
ore_glass--;
ore_plasma--;
new /obj/item/stack/sheet/glass/plasmaglass(output.loc)
else
on = 0
if (selected_glass == 1 && selected_gold == 0 && selected_silver == 0 && selected_diamond == 0 && selected_plasma == 1 && selected_uranium == 0 && selected_iron == 1 && selected_clown == 0)
if (ore_glass > 0 && ore_plasma > 0 && ore_iron > 0)
ore_glass--;
ore_iron--;
ore_plasma--;
new /obj/item/stack/sheet/glass/plasmarglass(output.loc)
else
on = 0
continue
//THESE TWO ARE CODED FOR URIST TO USE WHEN HE GETS AROUND TO IT.
//They were coded on 18 Feb 2012. If you're reading this in 2015, then firstly congratulations on the world not ending on 21 Dec 2012 and secondly, Urist is apparently VERY lazy. ~Errorage
//Iamgoofball here, this comment I'm typing right now was made in 11/1/2013. If you're reading this in 2020, then please let me know if the world has gone into a nuclear apocalypse. Also Urist has been tried and hung for how lazy he was. That and he was jaywalking.
/*if (selected_glass == 0 && selected_gold == 0 && selected_silver == 0 && selected_diamond == 1 && selected_plasma == 0 && selected_uranium == 1 && selected_iron == 0 && selected_clown == 0)
if (ore_uranium >= 2 && ore_diamond >= 1)
ore_uranium -= 2
@@ -380,34 +396,42 @@
if (O)
if (istype(O,/obj/item/weapon/ore/iron))
ore_iron++;
O.loc = null
del(O)
continue
if (istype(O,/obj/item/weapon/ore/glass))
ore_glass++;
O.loc = null
del(O)
continue
if (istype(O,/obj/item/weapon/ore/diamond))
ore_diamond++;
O.loc = null
del(O)
continue
if (istype(O,/obj/item/weapon/ore/plasma))
ore_plasma++
O.loc = null
del(O)
continue
if (istype(O,/obj/item/weapon/ore/gold))
ore_gold++
O.loc = null
del(O)
continue
if (istype(O,/obj/item/weapon/ore/silver))
ore_silver++
O.loc = null
del(O)
continue
if (istype(O,/obj/item/weapon/ore/uranium))
ore_uranium++
O.loc = null
del(O)
continue
if (istype(O,/obj/item/weapon/ore/clown))
ore_clown++
O.loc = null
del(O)
continue
O.loc = src.output.loc
+38
View File
@@ -42,6 +42,10 @@
dat += text("Reinforced Glass: [machine.ore_rglass] <A href='?src=\ref[src];release=rglass'>Release</A><br>")
if(machine.ore_plasma)
dat += text("Plasma: [machine.ore_plasma] <A href='?src=\ref[src];release=plasma'>Release</A><br>")
if(machine.ore_plasmaglass)
dat += text("Plasma Glass: [machine.ore_plasmaglass] <A href='?src=\ref[src];release=plasmaglass'>Release</A><br>")
if(machine.ore_plasmarglass)
dat += text("Reinforced Plasma Glass: [machine.ore_plasmarglass] <A href='?src=\ref[src];release=plasmarglass'>Release</A><br>")
if(machine.ore_gold)
dat += text("Gold: [machine.ore_gold] <A href='?src=\ref[src];release=gold'>Release</A><br>")
if(machine.ore_silver)
@@ -83,6 +87,18 @@
G.amount = machine.ore_plasma
G.loc = machine.output.loc
machine.ore_plasma = 0
if ("plasmaglass")
if (machine.ore_plasmaglass > 0)
var/obj/item/stack/sheet/glass/plasmaglass/G = new /obj/item/stack/sheet/glass/plasmaglass
G.amount = machine.ore_plasmaglass
G.loc = machine.output.loc
machine.ore_plasmaglass = 0
if ("plasmarglass")
if (machine.ore_plasmarglass > 0)
var/obj/item/stack/sheet/glass/plasmarglass/G = new /obj/item/stack/sheet/glass/plasmarglass
G.amount = machine.ore_plasmarglass
G.loc = machine.output.loc
machine.ore_plasmarglass = 0
if ("uranium")
if (machine.ore_uranium > 0)
var/obj/item/stack/sheet/mineral/uranium/G = new /obj/item/stack/sheet/mineral/uranium
@@ -195,6 +211,8 @@
var/ore_silver = 0;
var/ore_diamond = 0;
var/ore_plasma = 0;
var/ore_plasmaglass = 0;
var/ore_plasmarglass = 0;
var/ore_iron = 0;
var/ore_uranium = 0;
var/ore_clown = 0;
@@ -255,6 +273,14 @@
ore_uranium+= O:amount
del(O)
continue
if (istype(O,/obj/item/stack/sheet/glass/plasmaglass))
ore_plasmaglass+= O:amount
del(O)
continue
if (istype(O,/obj/item/stack/sheet/glass/plasmarglass))
ore_plasmarglass+= O:amount
del(O)
continue
if (istype(O,/obj/item/stack/sheet/glass))
ore_glass+= O:amount
del(O)
@@ -349,6 +375,18 @@
G.loc = output.loc
ore_rglass -= stack_amt
return
if (ore_plasmaglass >= stack_amt)
var/obj/item/stack/sheet/glass/plasmaglass/G = new /obj/item/stack/sheet/glass/plasmaglass
G.amount = stack_amt
G.loc = output.loc
ore_plasmaglass -= stack_amt
return
if (ore_plasmarglass >= stack_amt)
var/obj/item/stack/sheet/glass/plasmarglass/G = new /obj/item/stack/sheet/glass/plasmarglass
G.amount = stack_amt
G.loc = output.loc
ore_plasmarglass -= stack_amt
return
if (ore_plasteel >= stack_amt)
var/obj/item/stack/sheet/plasteel/G = new /obj/item/stack/sheet/plasteel
G.amount = stack_amt
File diff suppressed because it is too large Load Diff
+72
View File
@@ -0,0 +1,72 @@
var/list/name_to_mineral
proc/SetupMinerals()
name_to_mineral = list()
for(var/type in typesof(/mineral) - /mineral)
var/mineral/new_mineral = new type
if(!new_mineral.name)
continue
name_to_mineral[new_mineral.name] = new_mineral
return 1
mineral
///What am I called?
var/name
var/display_name
///How much ore?
var/result_amount
///Does this type of deposit spread?
var/spread = 1
///Chance of spreading in any direction
var/spread_chance
///Path to the resultant ore.
var/ore
New()
. = ..()
if(!display_name)
display_name = name
mineral/uranium
name = "Uranium"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/uranium
mineral/iron
name = "Iron"
result_amount = 5
spread_chance = 25
ore = /obj/item/weapon/ore/iron
mineral/diamond
name = "Diamond"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/diamond
mineral/gold
name = "Gold"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/gold
mineral/silver
name = "Silver"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/silver
mineral/plasma
name = "Plasma"
result_amount = 5
spread_chance = 25
ore = /obj/item/weapon/ore/plasma
mineral/clown
display_name = "Bananium"
name = "Clown"
result_amount = 3
spread = 0
ore = /obj/item/weapon/ore/clown
+1 -1
View File
@@ -4,7 +4,7 @@
name = "Rock"
icon = 'icons/obj/mining.dmi'
icon_state = "ore2"
var/datum/geosample/geological_data
var/datum/geosample/geologic_data
/obj/item/weapon/ore/uranium
name = "Uranium ore"
+35
View File
@@ -0,0 +1,35 @@
/*
Creature-level abilities.
*/
/var/global/list/ability_verbs = list( )
/*
Example ability:
/client/proc/test_ability()
set category = "Ability"
set name = "Test ability"
set desc = "An ability for testing."
// Check if the client has a mob and if the mob is valid and alive.
if(!mob || !istype(mob,/mob/living) || mob.stat)
src << "\red You must be corporeal and alive to do that."
return 0
//Handcuff check.
if(mob.restrained())
src << "\red You cannot do this while restrained."
return 0
if(istype(mob,/mob/living/carbon))
var/mob/living/carbon/M = mob
if(M.handcuffed)
src << "\red You cannot do this while cuffed."
return 0
src << "\blue You perform an ability."
*/
+328 -21
View File
@@ -16,13 +16,18 @@
var/started_as_observer //This variable is set to 1 when you enter the game as an observer.
//If you died in the game and are a ghsot - this will remain as null.
//Note that this is not a reliable way to determine if admins started as observers, since they change mobs a lot.
var/has_enabled_antagHUD = 0
var/medHUD = 0
var/antagHUD = 0
universal_speak = 1
var/atom/movable/following = null
/mob/dead/observer/New(mob/body)
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
see_invisible = SEE_INVISIBLE_OBSERVER
see_in_dark = 100
verbs += /mob/dead/observer/proc/dead_tele
stat = DEAD
var/turf/T
@@ -87,12 +92,129 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body
Works together with spawning an observer, noted above.
*/
/mob/dead/observer/Life()
..()
if(!loc) return
if(!client) return 0
if(client.images.len)
for(var/image/hud in client.images)
if(copytext(hud.icon_state,1,4) == "hud")
client.images.Remove(hud)
if(antagHUD)
var/list/target_list = list()
for(var/mob/living/target in oview(src))
if( target.mind&&(target.mind.special_role||issilicon(target)) )
target_list += target
if(target_list.len)
assess_targets(target_list, src)
if(medHUD)
process_medHUD(src)
// Direct copied from medical HUD glasses proc, used to determine what health bar to put over the targets head.
/mob/dead/proc/RoundHealth(var/health)
switch(health)
if(100 to INFINITY)
return "health100"
if(70 to 100)
return "health80"
if(50 to 70)
return "health60"
if(30 to 50)
return "health40"
if(18 to 30)
return "health25"
if(5 to 18)
return "health10"
if(1 to 5)
return "health1"
if(-99 to 0)
return "health0"
else
return "health-100"
return "0"
// Pretty much a direct copy of Medical HUD stuff, except will show ill if they are ill instead of also checking for known illnesses.
/mob/dead/proc/process_medHUD(var/mob/M)
var/client/C = M.client
var/image/holder
for(var/mob/living/carbon/human/patient in oview(M))
var/foundVirus = 0
if(patient.virus2.len)
foundVirus = 1
if(!C) return
holder = patient.hud_list[HEALTH_HUD]
if(patient.stat == 2)
holder.icon_state = "hudhealth-100"
else
holder.icon_state = "hud[RoundHealth(patient.health)]"
C.images += holder
holder = patient.hud_list[STATUS_HUD]
if(patient.stat == 2)
holder.icon_state = "huddead"
else if(patient.status_flags & XENO_HOST)
holder.icon_state = "hudxeno"
else if(foundVirus)
holder.icon_state = "hudill"
else if(patient.has_brain_worms())
var/mob/living/simple_animal/borer/B = patient.has_brain_worms()
if(B.controlling)
holder.icon_state = "hudbrainworm"
else
holder.icon_state = "hudhealthy"
else
holder.icon_state = "hudhealthy"
C.images += holder
/mob/dead/proc/assess_targets(list/target_list, mob/dead/observer/U)
var/icon/tempHud = 'icons/mob/hud.dmi'
for(var/mob/living/target in target_list)
if(iscarbon(target))
switch(target.mind.special_role)
if("traitor","Syndicate")
U.client.images += image(tempHud,target,"hudsyndicate")
if("Revolutionary")
U.client.images += image(tempHud,target,"hudrevolutionary")
if("Head Revolutionary")
U.client.images += image(tempHud,target,"hudheadrevolutionary")
if("Cultist")
U.client.images += image(tempHud,target,"hudcultist")
if("Changeling")
U.client.images += image(tempHud,target,"hudchangeling")
if("Wizard","Fake Wizard")
U.client.images += image(tempHud,target,"hudwizard")
if("Hunter","Sentinel","Drone","Queen")
U.client.images += image(tempHud,target,"hudalien")
if("Death Commando")
U.client.images += image(tempHud,target,"huddeathsquad")
if("Ninja")
U.client.images += image(tempHud,target,"hudninja")
else//If we don't know what role they have but they have one.
U.client.images += image(tempHud,target,"hudunknown1")
else//If the silicon mob has no law datum, no inherent laws, or a law zero, add them to the hud.
var/mob/living/silicon/silicon_target = target
if(!silicon_target.laws||(silicon_target.laws&&(silicon_target.laws.zeroth||!silicon_target.laws.inherent.len))||silicon_target.mind.special_role=="traitor")
if(isrobot(silicon_target))//Different icons for robutts and AI.
U.client.images += image(tempHud,silicon_target,"hudmalborg")
else
U.client.images += image(tempHud,silicon_target,"hudmalai")
return 1
/mob/proc/ghostize(var/can_reenter_corpse = 1)
if(key)
var/mob/dead/observer/ghost = new(src) //Transfer safety to observer spawning proc.
ghost.can_reenter_corpse = can_reenter_corpse
ghost.timeofdeath = src.timeofdeath //BS12 EDIT
ghost.key = key
if(!ghost.client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
ghost.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
return ghost
/*
@@ -170,7 +292,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(mind.current.key && copytext(mind.current.key,1,2)!="@") //makes sure we don't accidentally kick any clients
usr << "<span class='warning'>Another consciousness is in your body...It is resisting you.</span>"
return
if(mind.current.ajourn && mind.current.stat != DEAD) //check if the corpse is astral-journeying (it's client ghosted using a cultist rune).
if(mind.current.ajourn && mind.current.stat != DEAD) //check if the corpse is astral-journeying (it's client ghosted using a cultist rune).
var/obj/effect/rune/R = locate() in mind.current.loc //whilst corpse is alive, we can only reenter the body if it's on the rune
if(!(R && R.word1 == cultwords["hell"] && R.word2 == cultwords["travel"] && R.word3 == cultwords["self"])) //astral journeying rune
usr << "<span class='warning'>The astral cord that ties your body and your spirit has been severed. You are likely to wander the realm beyond until your body is finally dead and thus reunited with you.</span>"
@@ -179,6 +301,45 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
mind.current.key = key
return 1
/mob/dead/observer/verb/toggle_medHUD()
set category = "Ghost"
set name = "Toggle MedicHUD"
set desc = "Toggles Medical HUD allowing you to see how everyone is doing"
if(!client)
return
if(medHUD)
medHUD = 0
src << "\blue <B>Medical HUD Disabled</B>"
else
medHUD = 1
src << "\blue <B>Medical HUD Enabled</B>"
/mob/dead/observer/verb/toggle_antagHUD()
set category = "Ghost"
set name = "Toggle AntagHUD"
set desc = "Toggles AntagHUD allowing you to see who is the antagonist"
if(!config.antag_hud_allowed && !client.holder)
src << "\red Admins have disabled this for this round."
return
if(!client)
return
var/mob/dead/observer/M = src
if(jobban_isbanned(M, "AntagHUD"))
src << "\red <B>You have been banned from using this feature</B>"
return
if(config.antag_hud_restricted && !M.has_enabled_antagHUD &&!client.holder)
var/response = alert(src, "If you turn this on, you will not be able to take any part in the round.","Are you sure you want to turn this feature on?","Yes","No")
if(response == "No") return
M.can_reenter_corpse = 0
if(!M.has_enabled_antagHUD && !client.holder)
M.has_enabled_antagHUD = 1
if(M.antagHUD)
M.antagHUD = 0
src << "\blue <B>AntagHUD Disabled</B>"
else
M.antagHUD = 1
src << "\blue <B>AntagHUD Enabled</B>"
/mob/dead/observer/proc/dead_tele()
set category = "Ghost"
set name = "Teleport"
@@ -208,27 +369,30 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Follow" // "Haunt"
set desc = "Follow and haunt a mob."
if(istype(usr, /mob/dead/observer))
var/list/mobs = getmobs()
var/input = input("Please, select a mob!", "Haunt", null, null) as null|anything in mobs
var/mob/target = mobs[input]
if(target && target != usr)
following = target
spawn(0)
var/turf/pos = get_turf(src)
while(src.loc == pos)
var/list/mobs = getmobs()
var/input = input("Please, select a mob!", "Haunt", null, null) as null|anything in mobs
var/mob/target = mobs[input]
ManualFollow(target)
var/turf/T = get_turf(target)
if(!T)
break
if(following != target)
break
if(!client)
break
src.loc = T
pos = src.loc
sleep(15)
following = null
// This is the ghost's follow verb with an argument
/mob/dead/observer/proc/ManualFollow(var/atom/movable/target)
if(target && target != src)
if(following && following == target)
return
following = target
src << "\blue Now following [target]"
spawn(0)
var/turf/pos = get_turf(src)
while(loc == pos && target && following == target && client)
var/turf/T = get_turf(target)
if(!T)
break
// To stop the ghost flickering.
if(loc != T)
loc = T
pos = loc
sleep(15)
following = null
/mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
@@ -280,6 +444,58 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set hidden = 1
src << "\red You are dead! You have no mind to store memory!"
/mob/dead/observer/verb/analyze_air()
set name = "Analyze Air"
set category = "Ghost"
if(!istype(usr, /mob/dead/observer)) return
// Shamelessly copied from the Gas Analyzers
if (!( istype(usr.loc, /turf) ))
return
var/datum/gas_mixture/environment = usr.loc.return_air()
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
src << "\blue <B>Results:</B>"
if(abs(pressure - ONE_ATMOSPHERE) < 10)
src << "\blue Pressure: [round(pressure,0.1)] kPa"
else
src << "\red Pressure: [round(pressure,0.1)] kPa"
if(total_moles)
var/o2_concentration = environment.oxygen/total_moles
var/n2_concentration = environment.nitrogen/total_moles
var/co2_concentration = environment.carbon_dioxide/total_moles
var/plasma_concentration = environment.toxins/total_moles
var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+plasma_concentration)
if(abs(n2_concentration - N2STANDARD) < 20)
src << "\blue Nitrogen: [round(n2_concentration*100)]% ([round(environment.nitrogen,0.01)] moles)"
else
src << "\red Nitrogen: [round(n2_concentration*100)]% ([round(environment.nitrogen,0.01)] moles)"
if(abs(o2_concentration - O2STANDARD) < 2)
src << "\blue Oxygen: [round(o2_concentration*100)]% ([round(environment.oxygen,0.01)] moles)"
else
src << "\red Oxygen: [round(o2_concentration*100)]% ([round(environment.oxygen,0.01)] moles)"
if(co2_concentration > 0.01)
src << "\red CO2: [round(co2_concentration*100)]% ([round(environment.carbon_dioxide,0.01)] moles)"
else
src << "\blue CO2: [round(co2_concentration*100)]% ([round(environment.carbon_dioxide,0.01)] moles)"
if(plasma_concentration > 0.01)
src << "\red Plasma: [round(plasma_concentration*100)]% ([round(environment.toxins,0.01)] moles)"
if(unknown_concentration > 0.01)
src << "\red Unknown: [round(unknown_concentration*100)]% ([round(unknown_concentration*total_moles,0.01)] moles)"
src << "\blue Temperature: [round(environment.temperature-T0C,0.1)]&deg;C"
src << "\blue Heat Capacity: [round(environment.heat_capacity(),0.1)]"
/mob/dead/observer/verb/toggle_darkness()
set name = "Toggle Darkness"
set category = "Ghost"
@@ -293,6 +509,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Become mouse"
set category = "Ghost"
if(config.disable_player_mice)
src << "<span class='warning'>Spawning as a mouse is currently disabled.</span>"
return
var/mob/dead/observer/M = usr
if(config.antag_hud_restricted && M.has_enabled_antagHUD == 1)
src << "<span class='warning'>antagHUD restrictions prevent you from spawning in as a mouse.</span>"
return
var/timedifference = world.time - client.time_died_as_mouse
if(client.time_died_as_mouse && timedifference <= mouse_respawn_time * 600)
var/timedifference_text
@@ -300,6 +525,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
src << "<span class='warning'>You may only spawn again as a mouse more than [mouse_respawn_time] minutes after your death. You have [timedifference_text] left.</span>"
return
var/response = alert(src, "Are you -sure- you want to become a mouse?","Are you sure you want to squeek?","Squeek!","Nope!")
if(response != "Squeek!") return //Hit the wrong key...again.
//find a viable mouse candidate
var/mob/living/simple_animal/mouse/host
var/obj/machinery/atmospherics/unary/vent_pump/vent_found
@@ -314,6 +543,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
src << "<span class='warning'>Unable to find any unwelded vents to spawn mice at.</span>"
if(host)
if(config.uneducated_mice)
host.universal_understand = 0
host.ckey = src.ckey
host << "<span class='info'>You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent.</span>"
@@ -326,3 +557,79 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
dat += data_core.get_manifest()
src << browse(dat, "window=manifest;size=370x420;can_close=1")
//Used for drawing on walls with blood puddles as a spooky ghost.
/mob/dead/verb/bloody_doodle()
set category = "Ghost"
set name = "Write in blood"
set desc = "If the round is sufficiently spooky, write a short message in blood on the floor or a wall. Remember, no IC in OOC or OOC in IC."
if(!(config.cult_ghostwriter))
src << "\red That verb is not currently permitted."
return
if (!src.stat)
return
if (usr != src)
return 0 //something is terribly wrong
var/ghosts_can_write
if(ticker.mode.name == "cult")
var/datum/game_mode/cult/C = ticker.mode
if(C.cult.len > config.cult_ghostwriter_req_cultists)
ghosts_can_write = 1
if(!ghosts_can_write)
src << "\red The veil is not thin enough for you to do that."
return
var/list/choices = list()
for(var/obj/effect/decal/cleanable/blood/B in view(1,src))
if(B.amount > 0)
choices += B
if(!choices.len)
src << "<span class = 'warning'>There is no blood to use nearby.</span>"
return
var/obj/effect/decal/cleanable/blood/choice = input(src,"What blood would you like to use?") in null|choices
var/direction = input(src,"Which way?","Tile selection") as anything in list("Here","North","South","East","West")
var/turf/simulated/T = src.loc
if (direction != "Here")
T = get_step(T,text2dir(direction))
if (!istype(T))
src << "<span class='warning'>You cannot doodle there.</span>"
return
if(!choice || choice.amount == 0 || !(src.Adjacent(choice)))
return
var/doodle_color = (choice.basecolor) ? choice.basecolor : "#A10808"
var/num_doodles = 0
for (var/obj/effect/decal/cleanable/blood/writing/W in T)
num_doodles++
if (num_doodles > 4)
src << "<span class='warning'>There is no space to write on!</span>"
return
var/max_length = 50
var/message = stripped_input(src,"Write a message. It cannot be longer than [max_length] characters.","Blood writing", "")
if (message)
if (length(message) > max_length)
message += "-"
src << "<span class='warning'>You ran out of blood to write with!</span>"
var/obj/effect/decal/cleanable/blood/writing/W = new(T)
W.basecolor = doodle_color
W.update_icon()
W.message = message
W.add_hiddenprint(src)
W.visible_message("\red Invisible fingers crudely paint something in blood on [T]...")
+3 -3
View File
@@ -1,5 +1,5 @@
/mob/dead/observer/say(var/message)
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
message = sanitize(copytext(message, 1, MAX_MESSAGE_LEN))
if (!message)
return
@@ -18,7 +18,7 @@
/mob/dead/observer/emote(var/act, var/type, var/message)
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
message = sanitize(copytext(message, 1, MAX_MESSAGE_LEN))
if(!message)
return
@@ -62,4 +62,4 @@
M.show_message("<span class='game'><i>You hear muffled speech... you can almost make out some words...</i></span>", 2)
// M.show_message("<span class='game'><i>[stutter(message)]</i></span>", 2)
playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)
*/
*/
+11 -1
View File
@@ -36,11 +36,15 @@
M.show_message(message)
// Type 1 (Visual) emotes are sent to anyone in view of the item
if (m_type & 1)
for (var/mob/O in viewers(src, null))
O.show_message(message, m_type)
// Type 2 (Audible) emotes are sent to anyone in hear range
// of the *LOCATION* -- this is important for pAIs to be heard
else if (m_type & 2)
for (var/mob/O in hearers(src.loc, null))
for (var/mob/O in hearers(get_turf(src), null))
O.show_message(message, m_type)
/mob/proc/emote_dead(var/message)
@@ -53,6 +57,12 @@
src << "\red You have deadchat muted."
return
if(!src.client.holder)
if(!dsay_allowed)
src << "\red Deadchat is globally muted"
return
var/input
if(!message)
input = copytext(sanitize(input(src, "Choose an emote to display.") as text|null), 1, MAX_MESSAGE_LEN)
+7 -11
View File
@@ -6,7 +6,7 @@
var/name = "an unknown language" // Fluff name of language if any.
var/desc = "A language." // Short description for 'Check Languages'.
var/speech_verb = "says" // 'says', 'hisses', 'farts'.
var/colour = "say_quote" // CSS style to use for strings in this language.
var/colour = "body" // CSS style to use for strings in this language.
var/key = "x" // Character used to speak in language eg. :o for Unathi.
var/flags = 0 // Various language flags.
var/native // If set, non-native speakers will have trouble speaking.
@@ -54,6 +54,7 @@
/datum/language/human
name = "Sol Common"
desc = "A bastardized hybrid of informal English and elements of Mandarin Chinese; the common language of the Sol system."
colour = "rough"
key = "1"
flags = RESTRICTED
@@ -62,35 +63,30 @@
name = "Tradeband"
desc = "Maintained by the various trading cartels in major systems, this elegant, structured language is used for bartering and bargaining."
speech_verb = "enunciates"
colour = "say_quote"
key = "2"
/datum/language/gutter
name = "Gutter"
desc = "Much like Standard, this crude pidgin tongue descended from numerous languages and serves as Tradeband for criminal elements."
speech_verb = "growls"
colour = "rough"
key = "3"
// Language handling.
/mob/proc/add_language(var/language)
for(var/datum/language/L in languages)
if(L && L.name == language)
return 0
var/datum/language/new_language = all_languages[language]
if(!istype(new_language,/datum/language))
if(!istype(new_language) || new_language in languages)
return 0
languages += new_language
languages.Add(new_language)
return 1
/mob/proc/remove_language(var/rem_language)
for(var/datum/language/L in languages)
if(L && L.name == rem_language)
languages -= L
return 1
languages.Remove(all_languages[rem_language])
return 0
@@ -31,6 +31,10 @@
continue
no_queen = 0
if(src.has_brain_worms())
src << "<span class='warning'>We cannot perform this ability at the present time!</span>"
return
if(no_queen)
adjustToxLoss(-500)
src << "\green You begin to evolve!"
@@ -128,7 +128,7 @@
breath = loc.remove_air(breath_moles)
// Handle chem smoke effect -- Doohl
for(var/obj/effect/effect/chem_smoke/smoke in view(1, src))
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
if(smoke.reagents.total_volume)
smoke.reagents.reaction(src, INGEST)
spawn(5)
@@ -103,7 +103,7 @@
breath = loc.remove_air(breath_moles)
// Handle chem smoke effect -- Doohl
for(var/obj/effect/effect/chem_smoke/smoke in view(1, src))
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
if(smoke.reagents.total_volume)
smoke.reagents.reaction(src, INGEST)
spawn(5)
@@ -27,6 +27,8 @@
proc/request_player()
for(var/mob/dead/observer/O in player_list)
if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
continue
if(jobban_isbanned(O, "pAI"))
continue
if(O.client)
+1 -94
View File
@@ -221,99 +221,6 @@
// ++++ROCKDTBEN++++ MOB PROCS //END
/mob/living/carbon/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null) // -- TLE -- Merged by Carn
if(stat)
src << "You must be conscious to do this!"
return
if(lying)
src << "You can't vent crawl while you're stunned!"
return
if(vent_found) // one was passed in, probably from vent/AltClick()
if(vent_found.welded)
src << "That vent is welded shut."
return
if(!vent_found.Adjacent(src))
return // don't even acknowledge that
else
for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
if(!v.welded)
if(v.Adjacent(src))
vent_found = v
if(!vent_found)
src << "You'll need a non-welded vent to crawl into!"
return
if(!vent_found.network || !vent_found.network.normal_members.len)
src << "This vent is not connected to anything."
return
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
if(temp_vent.welded)
continue
if(temp_vent in loc)
continue
var/turf/T = get_turf(temp_vent)
if(!T || T.z != loc.z)
continue
var/i = 1
var/index = "[T.loc.name]\[[i]\]"
while(index in vents)
i++
index = "[T.loc.name]\[[i]\]"
vents[index] = temp_vent
if(!vents.len)
src << "\red There are no available vents to travel to, they could be welded."
return
var/obj/selection = input("Select a destination.", "Duct System") as null|anything in sortAssoc(vents)
if(!selection) return
if(!vent_found.Adjacent(src))
src << "Never mind, you left."
return
for(var/obj/item/carried_item in contents)//If the monkey got on objects.
if( !istype(carried_item, /obj/item/weapon/implant) && !istype(carried_item, /obj/item/clothing/mask/facehugger) )//If it's not an implant or a facehugger
src << "\red You can't be carrying items or have items equipped when vent crawling!"
return
if(isslime(src))
var/mob/living/carbon/slime/S = src
if(S.Victim)
src << "\red You'll have to let [S.Victim] go or finish eating \him first."
return
var/obj/machinery/atmospherics/unary/vent_pump/target_vent = vents[selection]
if(!target_vent)
return
for(var/mob/O in viewers(src, null))
O.show_message(text("<B>[src] scrambles into the ventillation ducts!</B>"), 1)
loc = target_vent
var/travel_time = round(get_dist(loc, target_vent.loc) / 2)
spawn(travel_time)
if(!target_vent) return
for(var/mob/O in hearers(target_vent,null))
O.show_message("You hear something squeezing through the ventilation ducts.",2)
sleep(travel_time)
if(!target_vent) return
if(target_vent.welded) //the vent can be welded while alien scrolled through the list or travelled.
target_vent = vent_found //travel back. No additional time required.
src << "\red The vent you were heading to appears to be welded."
loc = target_vent.loc
var/area/new_area = get_area(loc)
if(new_area)
new_area.Entered(src)
/mob/living/carbon/clean_blood()
. = ..()
if(ishuman(src))
@@ -532,7 +439,7 @@
B.host_brain << "\red <B><FONT size=3>Horrific, burning agony lances through you, ripping a soundless scream from your trapped mind!</FONT></B>"
//Check for brain worms in head.
/mob/living/carbon/proc/has_brain_worms()
/mob/proc/has_brain_worms()
for(var/I in contents)
if(istype(I,/mob/living/simple_animal/borer))
@@ -20,7 +20,10 @@
E.droplimb(1,1)
flick("gibbed-h", animation)
hgibs(loc, viruses, dna)
if(species)
hgibs(loc, viruses, dna, species.flesh_color, species.blood_color)
else
hgibs(loc, viruses, dna)
spawn(15)
if(animation) del(animation)
@@ -243,7 +243,7 @@
if(!key && brain_op_stage != 4 && stat != DEAD)
msg += "<span class='deadsay'>[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely</span>\n"
else if(!client && brain_op_stage != 4 && stat != DEAD)
msg += "[t_He] [t_has] a vacant, braindead stare...\n"
msg += "[t_He] [t_has] suddenly fallen asleep.\n"
var/list/wound_flavor_text = list()
var/list/is_destroyed = list()
+77 -84
View File
@@ -40,11 +40,6 @@
if(!species)
set_species()
if(species.language)
var/datum/language/L = all_languages[species.language]
if(L)
languages += L
var/datum/reagents/R = new/datum/reagents(1000)
reagents = R
R.my_atom = src
@@ -776,6 +771,14 @@
if(istype(usr,/mob/living/silicon/robot))
var/mob/living/silicon/robot/U = usr
R.fields[text("com_[counter]")] = text("Made by [U.name] ([U.modtype] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]<BR>[t1]")
if (href_list["lookitem"])
var/obj/item/I = locate(href_list["lookitem"])
I.examine()
if (href_list["lookmob"])
var/mob/M = locate(href_list["lookmob"])
M.examine()
..()
return
@@ -1019,17 +1022,21 @@
O.status &= ~ORGAN_BROKEN
O.status &= ~ORGAN_BLEEDING
O.status &= ~ORGAN_SPLINTED
O.status &= ~ORGAN_CUT_AWAY
O.status &= ~ORGAN_ATTACHABLE
if (!O.amputated)
O.status &= ~ORGAN_DESTROYED
O.destspawn = 0
O.wounds.Cut()
O.heal_damage(1000,1000,1,1)
var/datum/organ/external/head/h = organs_by_name["head"]
h.disfigured = 0
vessel.add_reagent("blood",560-vessel.total_volume)
fixblood()
if(species && !(species.flags & NO_BLOOD))
vessel.add_reagent("blood",560-vessel.total_volume)
fixblood()
for (var/obj/item/weapon/organ/head/H in world)
if(H.brainmob)
if(H.brainmob.real_name == src.real_name)
@@ -1100,6 +1107,7 @@
return 0 //already bloodied with this blood. Cannot add more.
blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
src.update_inv_gloves() //handles bloody hands overlays and updating
verbs += /mob/living/carbon/human/proc/bloody_doodle
return 1 //we applied blood to the item
/mob/living/carbon/human/clean_blood()
@@ -1108,83 +1116,7 @@
del(feet_blood_DNA)
return 1
mob/living/carbon/human/yank_out_object()
set category = "Object"
set name = "Yank out object"
set desc = "Remove an embedded item at the cost of bleeding and pain."
set src in view(1)
if(!isliving(usr) || usr.next_move > world.time)
return
usr.next_move = world.time + 20
if(usr.stat == 1)
usr << "You are unconcious and cannot do that!"
return
if(usr.restrained())
usr << "You are restrained and cannot do that!"
return
var/list/valid_objects = list()
var/datum/organ/external/affected = null
var/mob/living/carbon/human/S = src
var/mob/living/carbon/human/U = usr
var/self = null
if(S == U)
self = 1 // Removing object from yourself.
valid_objects = get_visible_implants(1)
if(!valid_objects.len)
if(self)
src << "You have nothing stuck in your wounds that is large enough to remove without surgery."
else
U << "[src] has nothing stuck in their wounds that is large enough to remove without surgery."
return
var/obj/item/weapon/selection = input("What do you want to yank out?", "Embedded objects") in valid_objects
for(var/datum/organ/external/organ in organs) //Grab the organ holding the implant.
for(var/obj/item/weapon/O in organ.implants)
if(O == selection)
affected = organ
if(self)
src << "<span class='warning'>You attempt to get a good grip on the [selection] in your [affected.display_name] with bloody fingers.</span>"
else
U << "<span class='warning'>You attempt to get a good grip on the [selection] in [S]'s [affected.display_name] with bloody fingers.</span>"
if(istype(U,/mob/living/carbon/human/)) U.bloody_hands(S)
if(!do_after(U, 80))
return
if(!selection || !affected || !S || !U)
return
if(self)
visible_message("<span class='warning'><b>[src] rips [selection] out of their [affected.display_name] in a welter of blood.</b></span>","<span class='warning'><b>You rip [selection] out of your [affected] in a welter of blood.</b></span>")
else
visible_message("<span class='warning'><b>[usr] rips [selection] out of [src]'s [affected.display_name] in a welter of blood.</b></span>","<span class='warning'><b>[usr] rips [selection] out of your [affected] in a welter of blood.</b></span>")
selection.loc = get_turf(src)
affected.implants -= selection
shock_stage+=10
for(var/obj/item/weapon/O in pinned)
if(O == selection)
pinned -= O
if(!pinned.len)
anchored = 0
if(prob(10)) //I'M SO ANEMIC I COULD JUST -DIE-.
var/datum/wound/internal_bleeding/I = new (15)
affected.wounds += I
custom_pain("Something tears wetly in your [affected] as [selection] is pulled free!", 1)
return 1
/mob/living/carbon/human/proc/get_visible_implants(var/class = 0)
/mob/living/carbon/human/get_visible_implants(var/class = 0)
var/list/visible_implants = list()
for(var/datum/organ/external/organ in src.organs)
@@ -1257,8 +1189,14 @@ mob/living/carbon/human/yank_out_object()
if(species && (species.name && species.name == new_species))
return
if(species && species.language)
remove_language(species.language)
species = all_species[new_species]
if(species.language)
add_language(species.language)
spawn(0)
update_icons()
@@ -1266,3 +1204,58 @@ mob/living/carbon/human/yank_out_object()
return 1
else
return 0
/mob/living/carbon/human/proc/bloody_doodle()
set category = "IC"
set name = "Write in blood"
set desc = "Use blood on your hands to write a short message on the floor or a wall, murder mystery style."
if (src.stat)
return
if (usr != src)
return 0 //something is terribly wrong
if (!bloody_hands)
verbs -= /mob/living/carbon/human/proc/bloody_doodle
if (src.gloves)
src << "<span class='warning'>Your [src.gloves] are getting in the way.</span>"
return
var/turf/simulated/T = src.loc
if (!istype(T)) //to prevent doodling out of mechs and lockers
src << "<span class='warning'>You cannot reach the floor.</span>"
return
var/direction = input(src,"Which way?","Tile selection") as anything in list("Here","North","South","East","West")
if (direction != "Here")
T = get_step(T,text2dir(direction))
if (!istype(T))
src << "<span class='warning'>You cannot doodle there.</span>"
return
var/num_doodles = 0
for (var/obj/effect/decal/cleanable/blood/writing/W in T)
num_doodles++
if (num_doodles > 4)
src << "<span class='warning'>There is no space to write on!</span>"
return
var/max_length = bloody_hands * 30 //tweeter style
var/message = stripped_input(src,"Write a message. It cannot be longer than [max_length] characters.","Blood writing", "")
if (message)
var/used_blood_amount = round(length(message) / 30, 1)
bloody_hands = max(0, bloody_hands - used_blood_amount) //use up some blood
if (length(message) > max_length)
message += "-"
src << "<span class='warning'>You ran out of blood to write with!</span>"
var/obj/effect/decal/cleanable/blood/writing/W = new(T)
W.basecolor = (hand_blood_color) ? hand_blood_color : "#A10808"
W.update_icon()
W.message = message
W.add_fingerprint(src)
@@ -180,7 +180,7 @@ This function restores the subjects blood to max.
/mob/living/carbon/human/proc/restore_blood()
var/blood_volume = vessel.get_reagent_amount("blood")
vessel.add_reagent("blood",560.0-blood_volume)
/*
This function restores all organs.
@@ -245,20 +245,11 @@ This function restores all organs.
if( (damage > (10*W.w_class)) && ( (sharp && !ismob(W.loc)) || prob(damage/W.w_class) ) )
organ.implants += W
visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
src.verbs += /mob/proc/yank_out_object
W.add_blood(src)
if(ismob(W.loc))
var/mob/living/H = W.loc
H.drop_item()
W.loc = src
else if(istype(used_weapon,/obj/item/projectile)) //We don't want to use the actual projectile item, so we spawn some shrapnel.
if(prob(75) && damagetype == BRUTE)
var/obj/item/projectile/P = used_weapon
var/obj/item/weapon/shard/shrapnel/S = new()
S.name = "[P.name] shrapnel"
S.desc = "[S.desc] It looks like it was fired from [P.shot_from]."
S.loc = src
organ.implants += S
visible_message("<span class='danger'>The projectile sticks in the wound!</span>")
S.add_blood(src)
return 1
@@ -88,6 +88,19 @@ emp_act
return
//END TASER NERF
var/datum/organ/external/organ = get_organ(check_zone(def_zone))
var/armor = checkarmor(organ, "bullet")
if((P.embed && prob(20 + max(P.damage - armor, -10))) && P.damage_type == BRUTE)
var/obj/item/weapon/shard/shrapnel/SP = new()
(SP.name) = "[P.name] shrapnel"
(SP.desc) = "[SP.desc] It looks like it was fired from [P.shot_from]."
(SP.loc) = organ
organ.implants += SP
visible_message("<span class='danger'>The projectile sticks in the wound!</span>")
src.verbs += /mob/proc/yank_out_object
SP.add_blood(src)
return (..(P , def_zone))
@@ -122,6 +135,16 @@ emp_act
protection += C.armor[type]
return protection
/mob/living/carbon/human/proc/check_head_coverage()
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform)
for(var/bp in body_parts)
if(!bp) continue
if(bp && istype(bp ,/obj/item/clothing))
var/obj/item/clothing/C = bp
if(C.body_parts_covered & HEAD)
return 1
return 0
/mob/living/carbon/human/proc/check_shields(var/damage = 0, var/attack_text = "the attack")
if(l_hand && istype(l_hand, /obj/item/weapon))//Current base is the prob(50-d/3)
@@ -159,6 +182,9 @@ emp_act
for(var/datum/organ/external/O in organs)
if(O.status & ORGAN_DESTROYED) continue
O.emp_act(severity)
for(var/datum/organ/internal/I in O.internal_organs)
if(I.robotic == 0) continue
I.emp_act(severity)
..()
@@ -170,14 +196,14 @@ emp_act
target_zone = user.zone_sel.selecting
if(!target_zone)
visible_message("\red <B>[user] misses [src] with \the [I]!")
return
return 0
var/datum/organ/external/affecting = get_organ(target_zone)
if (!affecting)
return
return 0
if(affecting.status & ORGAN_DESTROYED)
user << "What [affecting.display_name]?"
return
return 0
var/hit_area = affecting.display_name
if((user != src) && check_shields(I.force, "the [I.name]"))
@@ -194,7 +220,7 @@ emp_act
var/obj/item/weapon/card/emag/emag = I
emag.uses--
affecting.sabotaged = 1
return
return 1
if(I.attack_verb.len)
visible_message("\red <B>[src] has been [pick(I.attack_verb)] in the [hit_area] with [I.name] by [user]!</B>")
@@ -249,6 +275,7 @@ emp_act
if(bloody)
bloody_body(src)
return 1
/mob/living/carbon/human/proc/bloody_hands(var/mob/living/source, var/amount = 2)
if (gloves)
@@ -21,7 +21,7 @@
var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup
var/age = 30 //Player's age (pure fluff)
var/b_type = "A+" //Player's bloodtype (Not currently used, just character fluff)
var/b_type = "A+" //Player's bloodtype
var/underwear = 1 //Which underwear the player wants
var/backbag = 2 //Which backpack type the player has chosen. Nothing, Satchel or Backpack.
@@ -56,3 +56,4 @@
var/xylophone = 0 //For the spoooooooky xylophone cooldown
var/mob/remoteview_target = null
var/hand_blood_color
@@ -1,6 +1,9 @@
/mob/living/carbon/human/movement_delay()
var/tally = 0
if(species && species.flags & IS_SLOW)
tally = 7
if (istype(loc, /turf/space)) return -1 // It's hard to be slowed down in space by... anything
handle_embedded_objects() //Moving with objects stuck in you can cause bad times.
@@ -81,20 +81,20 @@
if (W == wear_suit)
if(s_store)
u_equip(s_store)
drop_from_inventory(s_store)
if(W)
success = 1
wear_suit = null
update_inv_wear_suit()
else if (W == w_uniform)
if (r_store)
u_equip(r_store)
drop_from_inventory(r_store)
if (l_store)
u_equip(l_store)
drop_from_inventory(l_store)
if (wear_id)
u_equip(wear_id)
drop_from_inventory(wear_id)
if (belt)
u_equip(belt)
drop_from_inventory(belt)
w_uniform = null
success = 1
update_inv_w_uniform()
+62 -22
View File
@@ -242,7 +242,7 @@
var/rads = radiation/25
radiation -= rads
nutrition += rads
heal_overall_damage(rads,rads)
adjustBruteLoss(-(rads))
adjustOxyLoss(-(rads))
adjustToxLoss(-(rads))
updatehealth()
@@ -359,7 +359,7 @@
if(!block)
for(var/obj/effect/effect/chem_smoke/smoke in view(1, src))
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
if(smoke.reagents.total_volume)
smoke.reagents.reaction(src, INGEST)
spawn(5)
@@ -866,7 +866,15 @@
*/
proc/handle_chemicals_in_body()
if(reagents) reagents.metabolize(src)
if(reagents)
var/alien = 0 //Not the best way to handle it, but neater than checking this for every single reagent proc.
if(species && species.name == "Diona")
alien = 1
else if(species && species.name == "Vox")
alien = 2
reagents.metabolize(src,alien)
var/total_plasmaloss = 0
for(var/obj/item/I in src)
if(I.contaminated)
@@ -885,12 +893,15 @@
nutrition += light_amount
traumatic_shock -= light_amount
if(nutrition > 500)
nutrition = 500
if(light_amount > 2) //if there's enough light, heal
heal_overall_damage(1,1)
adjustToxLoss(-1)
adjustOxyLoss(-1)
if(species.flags & IS_PLANT)
if(nutrition > 500)
nutrition = 500
if(light_amount >= 3) //if there's enough light, heal
adjustBruteLoss(-(light_amount))
adjustToxLoss(-(light_amount))
adjustOxyLoss(-(light_amount))
//TODO: heal wounds, heal broken limbs.
if(dna && dna.mutantrace == "shadow")
var/light_amount = 0
if(isturf(loc))
@@ -960,6 +971,9 @@
var/datum/organ/internal/liver/liver = internal_organs["liver"]
liver.process()
var/datum/organ/internal/eyes/eyes = internal_organs["eyes"]
eyes.process()
updatehealth()
return //TODO: DEFERRED
@@ -1178,6 +1192,13 @@
see_in_dark = 8
if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO
if(healths) healths.icon_state = "health7" //DEAD healthmeter
if(client)
if(client.view != world.view)
if(locate(/obj/item/weapon/gun/energy/sniperrifle, contents))
var/obj/item/weapon/gun/energy/sniperrifle/s = locate() in src
if(s.zoom)
s.zoom()
else
sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_in_dark = species.darksight
@@ -1259,7 +1280,7 @@
if(2) healths.icon_state = "health7"
else
//switch(health - halloss)
switch(100 - traumatic_shock)
switch(100 - ((species && species.flags & NO_PAIN) ? 0 : traumatic_shock))
if(100 to INFINITY) healths.icon_state = "health0"
if(80 to 100) healths.icon_state = "health1"
if(60 to 80) healths.icon_state = "health2"
@@ -1335,10 +1356,6 @@
if(!O.up && tinted_weldhelh)
client.screen += global_hud.darkMask
if(eye_stat > 20)
if(eye_stat > 30) client.screen += global_hud.darkMask
else client.screen += global_hud.vimpaired
if(machine)
if(!machine.check_eye(src)) reset_view(null)
else
@@ -1423,7 +1440,7 @@
handle_shock()
..()
if(status_flags & GODMODE) return 0 //godmode
if(analgesic) return // analgesic avoids all traumatic shock temporarily
if(analgesic || (species && species.flags & NO_PAIN)) return // analgesic avoids all traumatic shock temporarily
if(health < config.health_threshold_softcrit)// health 0 makes you immediately collapse
shock_stage = max(shock_stage, 61)
@@ -1433,7 +1450,7 @@
else if(health < config.health_threshold_softcrit)
shock_stage = max(shock_stage, 61)
else
shock_stage = min(shock_stage, 100)
shock_stage = min(shock_stage, 160)
shock_stage = max(shock_stage-1, 0)
return
@@ -1450,19 +1467,33 @@
if (shock_stage >= 60)
if(shock_stage == 60) emote("me",1,"'s body becomes limp.")
if (prob(2))
src << "<font color='red'><b>"+pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!")
Weaken(20)
if(shock_stage >= 80)
if (prob(5))
Stun(20)
lying = 1
src << "<font color='red'><b>"+pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!")
Weaken(20)
if(shock_stage == 80)
src << "<font color='red'><b>"+pick("You see a light at the end of the tunnel!", "You feel like you could die any moment now.", "You're about to lose consciousness.")
if(shock_stage >= 120)
if (prob(2))
src << "<font color='red'><b>"+pick("You black out!", "You feel like you could die any moment now.", "You're about to lose consciousness.")
Paralyse(5)
if(shock_stage > 80)
Paralyse(rand(15,28))
if(shock_stage == 150)
emote("me",1,"can no longer stand, collapsing!")
Weaken(20)
if(shock_stage >= 150)
Weaken(20)
proc/handle_pulse()
if(life_tick % 5) return pulse //update pulse every 5 life ticks (~1 tick/sec, depending on server load)
if(species && species.flags & NO_BLOOD) return PULSE_NONE //No blood, no pulse.
if(stat == DEAD)
return PULSE_NONE //that's it, you're dead, nothing can influence your pulse
@@ -1485,6 +1516,15 @@
if(temp <= PULSE_FAST && temp >= PULSE_NONE)
temp++
break
for(var/datum/reagent/R in reagents.reagent_list) //To avoid using fakedeath
if(R.id in heartstopper)
temp = PULSE_NONE
break
for(var/datum/reagent/R in reagents.reagent_list) //Conditional heart-stoppage
if(R.id in cheartstopper)
if(R.volume >= R.overdose)
temp = PULSE_NONE
break
return temp
+1 -2
View File
@@ -12,7 +12,7 @@
if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
temp_message[H] = ninjaspeak(temp_message[H])
pick_list -= H
message = dd_list2text(temp_message, " ")
message = list2text(temp_message, " ")
message = replacetext(message, "o", "¤")
message = replacetext(message, "p", "þ")
message = replacetext(message, "l", "£")
@@ -71,4 +71,3 @@
/mob/living/carbon/human/proc/GetSpecialVoice()
return special_voice
@@ -123,7 +123,6 @@ Please contact me on #coderbus IRC. ~Carn x
//////////////////////////////////
/mob/living/carbon/human
var/list/overlays_lying[TOTAL_LAYERS]
var/list/overlays_standing[TOTAL_LAYERS]
var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed
var/icon/race_icon
@@ -137,28 +136,32 @@ Please contact me on #coderbus IRC. ~Carn x
update_hud() //TODO: remove the need for this
overlays.Cut()
if(lying) //can't be cloaked when lying. (for now)
icon = lying_icon
for(var/image/I in overlays_lying)
overlays += I
var/stealth = 0
//cloaking devices. //TODO: get rid of this :<
for(var/obj/item/weapon/cloaking_device/S in list(l_hand,r_hand,belt,l_store,r_store))
if(S.active)
stealth = 1
break
if(stealth)
icon = 'icons/mob/human.dmi'
icon_state = "body_cloaked"
var/image/I = overlays_standing[L_HAND_LAYER]
if(istype(I)) overlays += I
I = overlays_standing[R_HAND_LAYER]
if(istype(I)) overlays += I
else
var/stealth = 0
//cloaking devices. //TODO: get rid of this :<
for(var/obj/item/weapon/cloaking_device/S in list(l_hand,r_hand,belt,l_store,r_store))
if(S.active)
stealth = 1
break
if(stealth)
icon = 'icons/mob/human.dmi'
icon_state = "body_cloaked"
var/image/I = overlays_standing[L_HAND_LAYER]
if(istype(I)) overlays += I
I = overlays_standing[R_HAND_LAYER]
if(istype(I)) overlays += I
else
icon = stand_icon
for(var/image/I in overlays_standing)
overlays += I
icon = stand_icon
for(var/image/I in overlays_standing)
overlays += I
if(lying)
var/matrix/M = matrix()
M.Turn(90)
M.Translate(1,-6)
src.transform = M
else
var/matrix/M = matrix()
src.transform = M
var/global/list/damage_icon_parts = list()
proc/get_damage_icon_part(damage_state, body_part)
@@ -188,10 +191,8 @@ proc/get_damage_icon_part(damage_state, body_part)
previous_damage_appearance = damage_appearance
var/icon/standing = new /icon('icons/mob/dam_human.dmi', "00")
var/icon/lying = new /icon('icons/mob/dam_human.dmi', "00-2")
var/image/standing_image = new /image("icon" = standing)
var/image/lying_image = new /image("icon" = lying)
// blend the individual damage states with our icons
@@ -204,19 +205,14 @@ proc/get_damage_icon_part(damage_state, body_part)
standing_image.overlays += DI
DI = get_damage_icon_part("[O.damage_state]-2", "[O.icon_name]2")
lying_image.overlays += DI
overlays_standing[DAMAGE_LAYER] = standing_image
overlays_lying[DAMAGE_LAYER] = lying_image
if(update_icons) update_icons()
//BASE MOB SPRITE
/mob/living/carbon/human/proc/update_body(var/update_icons=1)
if(stand_icon) del(stand_icon)
if(lying_icon) del(lying_icon)
var/husk_color_mod = rgb(96,88,80)
var/hulk_color_mod = rgb(48,224,40)
@@ -252,9 +248,6 @@ proc/get_damage_icon_part(damage_state, body_part)
else
temp = part.get_icon()
if(part.status & ORGAN_ROBOT)
temp.GrayScale()
if(part.status & ORGAN_DEAD)
temp.ColorTone(necrosis_color_mod)
temp.SetIntensity(0.7)
@@ -316,8 +309,6 @@ proc/get_damage_icon_part(damage_state, body_part)
if(!fat && !skeleton)
stand_icon.Blend(new /icon('icons/mob/human.dmi', "underwear[underwear]_[g]_s"), ICON_OVERLAY)
lying_icon = stand_icon.MakeLying()
if(update_icons)
update_icons()
@@ -328,7 +319,6 @@ proc/get_damage_icon_part(damage_state, body_part)
//HAIR OVERLAY
/mob/living/carbon/human/proc/update_hair(var/update_icons=1)
//Reset our hair
overlays_lying[HAIR_LAYER] = null
overlays_standing[HAIR_LAYER] = null
var/datum/organ/external/head/head_organ = get_organ("head")
@@ -343,33 +333,25 @@ proc/get_damage_icon_part(damage_state, body_part)
//base icons
var/icon/face_standing = new /icon('icons/mob/human_face.dmi',"bald_s")
var/icon/face_lying = new /icon('icons/mob/human_face.dmi',"bald_l")
if(f_style)
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style]
if(facial_hair_style && src.species.name in facial_hair_style.species_allowed)
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
var/icon/facial_l = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_l")
if(facial_hair_style.do_colouration)
facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
facial_l.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
face_standing.Blend(facial_s, ICON_OVERLAY)
face_lying.Blend(facial_l, ICON_OVERLAY)
if(h_style && !(head && (head.flags & BLOCKHEADHAIR)))
var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
if(hair_style && src.species.name in hair_style.species_allowed)
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
var/icon/hair_l = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_l")
if(hair_style.do_colouration)
hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
hair_l.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
face_standing.Blend(hair_s, ICON_OVERLAY)
face_lying.Blend(hair_l, ICON_OVERLAY)
overlays_lying[HAIR_LAYER] = image(face_lying)
overlays_standing[HAIR_LAYER] = image(face_standing)
if(update_icons) update_icons()
@@ -379,7 +361,6 @@ proc/get_damage_icon_part(damage_state, body_part)
if(FAT in mutations)
fat = "fat"
var/image/lying = image("icon" = 'icons/effects/genetics.dmi')
var/image/standing = image("icon" = 'icons/effects/genetics.dmi')
var/add_image = 0
var/g = "m"
@@ -388,29 +369,22 @@ proc/get_damage_icon_part(damage_state, body_part)
switch(mut)
if(HULK)
if(fat)
lying.underlays += "hulk_[fat]_l"
standing.underlays += "hulk_[fat]_s"
else
lying.underlays += "hulk_[g]_l"
standing.underlays += "hulk_[g]_s"
add_image = 1
if(COLD_RESISTANCE)
lying.underlays += "fire[fat]_l"
standing.underlays += "fire[fat]_s"
add_image = 1
if(TK)
lying.underlays += "telekinesishead[fat]_l"
standing.underlays += "telekinesishead[fat]_s"
add_image = 1
if(LASER)
lying.overlays += "lasereyes_l"
standing.overlays += "lasereyes_s"
add_image = 1
if(add_image)
overlays_lying[MUTATIONS_LAYER] = lying
overlays_standing[MUTATIONS_LAYER] = standing
else
overlays_lying[MUTATIONS_LAYER] = null
overlays_standing[MUTATIONS_LAYER] = null
if(update_icons) update_icons()
@@ -433,10 +407,8 @@ proc/get_damage_icon_part(damage_state, body_part)
if(dna)
switch(dna.mutantrace)
if("golem","slime","shadow","adamantine")
overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace][fat]_[gender]_l")
overlays_standing[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace][fat]_[gender]_s")
else
overlays_lying[MUTANTRACE_LAYER] = null
overlays_standing[MUTANTRACE_LAYER] = null
if(!dna || !(dna.mutantrace in list("golem","metroid")))
@@ -448,12 +420,10 @@ proc/get_damage_icon_part(damage_state, body_part)
//Call when target overlay should be added/removed
/mob/living/carbon/human/update_targeted(var/update_icons=1)
if (targeted_by && target_locked)
overlays_lying[TARGETED_LAYER] = target_locked
overlays_standing[TARGETED_LAYER] = target_locked
else if (!targeted_by && target_locked)
del(target_locked)
if (!targeted_by)
overlays_lying[TARGETED_LAYER] = null
overlays_standing[TARGETED_LAYER] = null
if(update_icons) update_icons()
@@ -495,27 +465,22 @@ proc/get_damage_icon_part(damage_state, body_part)
w_uniform.screen_loc = ui_iclothing
var/t_color = w_uniform.item_color
if(!t_color) t_color = icon_state
var/image/lying = image("icon_state" = "[t_color]_l")
var/image/standing = image("icon_state" = "[t_color]_s")
lying.icon = 'icons/mob/uniform.dmi'
standing.icon = 'icons/mob/uniform.dmi'
standing.icon = ((w_uniform.icon_override) ? w_uniform.icon_override : 'icons/mob/uniform.dmi')
if(w_uniform.blood_DNA)
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "uniformblood2")
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "uniformblood")
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "uniformblood")
bloodsies.color = w_uniform.blood_color
standing.overlays += bloodsies
if(w_uniform:hastie) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE.
var/tie_color = w_uniform:hastie.item_color
if(!tie_color) tie_color = w_uniform:hastie.icon_state
lying.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]2")
standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]")
overlays_lying[UNIFORM_LAYER] = lying
overlays_standing[UNIFORM_LAYER] = standing
else
overlays_lying[UNIFORM_LAYER] = null
overlays_standing[UNIFORM_LAYER] = null
// Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY
for( var/obj/item/thing in list(r_store, l_store, wear_id, belt) ) //
@@ -534,13 +499,10 @@ proc/get_damage_icon_part(damage_state, body_part)
if(wear_id)
wear_id.screen_loc = ui_id //TODO
if(w_uniform && w_uniform:displays_id)
overlays_lying[ID_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "id2")
overlays_standing[ID_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "id")
else
overlays_lying[ID_LAYER] = null
overlays_standing[ID_LAYER] = null
else
overlays_lying[ID_LAYER] = null
overlays_standing[ID_LAYER] = null
if(update_icons) update_icons()
@@ -548,57 +510,49 @@ proc/get_damage_icon_part(damage_state, body_part)
if(gloves)
var/t_state = gloves.item_state
if(!t_state) t_state = gloves.icon_state
var/image/lying = image("icon" = 'icons/mob/hands.dmi', "icon_state" = "[t_state]2")
var/image/standing = image("icon" = 'icons/mob/hands.dmi', "icon_state" = "[t_state]")
var/image/standing = image("icon" = ((gloves.icon_override) ? gloves.icon_override : 'icons/mob/hands.dmi'), "icon_state" = "[t_state]")
if(gloves.blood_DNA)
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands2")
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands")
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands")
bloodsies.color = gloves.blood_color
standing.overlays += bloodsies
gloves.screen_loc = ui_gloves
overlays_lying[GLOVES_LAYER] = lying
overlays_standing[GLOVES_LAYER] = standing
else
if(blood_DNA)
overlays_lying[GLOVES_LAYER] = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands2")
overlays_standing[GLOVES_LAYER] = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands")
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands")
bloodsies.color = hand_blood_color
overlays_standing[GLOVES_LAYER] = bloodsies
else
overlays_lying[GLOVES_LAYER] = null
overlays_standing[GLOVES_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_glasses(var/update_icons=1)
if(glasses)
overlays_lying[GLASSES_LAYER] = image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]2")
overlays_standing[GLASSES_LAYER] = image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]")
overlays_standing[GLASSES_LAYER] = image("icon" = ((glasses.icon_override) ? glasses.icon_override : 'icons/mob/eyes.dmi'), "icon_state" = "[glasses.icon_state]")
else
overlays_lying[GLASSES_LAYER] = null
overlays_standing[GLASSES_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_ears(var/update_icons=1)
if(l_ear || r_ear)
if(l_ear)
overlays_lying[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[l_ear.icon_state]2")
overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[l_ear.icon_state]")
overlays_standing[EARS_LAYER] = image("icon" = ((l_ear.icon_override) ? l_ear.icon_override : 'icons/mob/ears.dmi'), "icon_state" = "[l_ear.icon_state]")
if(r_ear)
overlays_lying[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[r_ear.icon_state]2")
overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[r_ear.icon_state]")
overlays_standing[EARS_LAYER] = image("icon" = ((r_ear.icon_override) ? r_ear.icon_override : 'icons/mob/ears.dmi'), "icon_state" = "[r_ear.icon_state]")
else
overlays_lying[EARS_LAYER] = null
overlays_standing[EARS_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_shoes(var/update_icons=1)
if(shoes)
var/image/lying = image("icon" = 'icons/mob/feet.dmi', "icon_state" = "[shoes.icon_state]2")
var/image/standing = image("icon" = 'icons/mob/feet.dmi', "icon_state" = "[shoes.icon_state]")
var/image/standing = image("icon" = ((shoes.icon_override) ? shoes.icon_override : 'icons/mob/feet.dmi'), "icon_state" = "[shoes.icon_state]")
if(shoes.blood_DNA)
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "shoeblood2")
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "shoeblood")
overlays_lying[SHOES_LAYER] = lying
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "shoeblood")
bloodsies.color = shoes.blood_color
standing.overlays += bloodsies
overlays_standing[SHOES_LAYER] = standing
else
overlays_lying[SHOES_LAYER] = null
overlays_standing[SHOES_LAYER] = null
if(update_icons) update_icons()
@@ -606,11 +560,9 @@ proc/get_damage_icon_part(damage_state, body_part)
if(s_store)
var/t_state = s_store.item_state
if(!t_state) t_state = s_store.icon_state
overlays_lying[SUIT_STORE_LAYER] = image("icon" = 'icons/mob/belt_mirror.dmi', "icon_state" = "[t_state]2")
overlays_standing[SUIT_STORE_LAYER] = image("icon" = 'icons/mob/belt_mirror.dmi', "icon_state" = "[t_state]")
s_store.screen_loc = ui_sstore1 //TODO
else
overlays_lying[SUIT_STORE_LAYER] = null
overlays_standing[SUIT_STORE_LAYER] = null
if(update_icons) update_icons()
@@ -618,21 +570,17 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/update_inv_head(var/update_icons=1)
if(head)
head.screen_loc = ui_head //TODO
var/image/lying
var/image/standing
if(istype(head,/obj/item/clothing/head/kitty))
lying = image("icon" = head:mob2)
standing = image("icon" = head:mob)
else
lying = image("icon" = 'icons/mob/head.dmi', "icon_state" = "[head.icon_state]2")
standing = image("icon" = 'icons/mob/head.dmi', "icon_state" = "[head.icon_state]")
standing = image("icon" = ((head.icon_override) ? head.icon_override : 'icons/mob/head.dmi'), "icon_state" = "[head.icon_state]")
if(head.blood_DNA)
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood2")
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood")
overlays_lying[HEAD_LAYER] = lying
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood")
bloodsies.color = head.blood_color
standing.overlays += bloodsies
overlays_standing[HEAD_LAYER] = standing
else
overlays_lying[HEAD_LAYER] = null
overlays_standing[HEAD_LAYER] = null
if(update_icons) update_icons()
@@ -641,10 +589,8 @@ proc/get_damage_icon_part(damage_state, body_part)
belt.screen_loc = ui_belt //TODO
var/t_state = belt.item_state
if(!t_state) t_state = belt.icon_state
overlays_lying[BELT_LAYER] = image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[t_state]2")
overlays_standing[BELT_LAYER] = image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[t_state]")
overlays_standing[BELT_LAYER] = image("icon" = ((belt.icon_override) ? belt.icon_override : 'icons/mob/belt.dmi'), "icon_state" = "[t_state]")
else
overlays_lying[BELT_LAYER] = null
overlays_standing[BELT_LAYER] = null
if(update_icons) update_icons()
@@ -652,8 +598,7 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/update_inv_wear_suit(var/update_icons=1)
if( wear_suit && istype(wear_suit, /obj/item/clothing/suit) ) //TODO check this
wear_suit.screen_loc = ui_oclothing //TODO
var/image/lying = image("icon" = 'icons/mob/suit.dmi', "icon_state" = "[wear_suit.icon_state]2")
var/image/standing = image("icon" = 'icons/mob/suit.dmi', "icon_state" = "[wear_suit.icon_state]")
var/image/standing = image("icon" = ((wear_suit.icon_override) ? wear_suit.icon_override : 'icons/mob/suit.dmi'), "icon_state" = "[wear_suit.icon_state]")
if( istype(wear_suit, /obj/item/clothing/suit/straight_jacket) )
drop_from_inventory(handcuffed)
@@ -662,16 +607,15 @@ proc/get_damage_icon_part(damage_state, body_part)
if(wear_suit.blood_DNA)
var/obj/item/clothing/suit/S = wear_suit
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[S.blood_overlay_type]blood2")
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[S.blood_overlay_type]blood")
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[S.blood_overlay_type]blood")
bloodsies.color = wear_suit.blood_color
standing.overlays += bloodsies
overlays_lying[SUIT_LAYER] = lying
overlays_standing[SUIT_LAYER] = standing
update_tail_showing(0)
else
overlays_lying[SUIT_LAYER] = null
overlays_standing[SUIT_LAYER] = null
update_tail_showing(0)
@@ -687,15 +631,13 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/update_inv_wear_mask(var/update_icons=1)
if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/tie) ) )
wear_mask.screen_loc = ui_mask //TODO
var/image/lying = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state]2")
var/image/standing = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state]")
var/image/standing = image("icon" = ((wear_mask.icon_override) ? wear_mask.icon_override : 'icons/mob/mask.dmi'), "icon_state" = "[wear_mask.icon_state]")
if( !istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA )
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "maskblood2")
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "maskblood")
overlays_lying[FACEMASK_LAYER] = lying
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "maskblood")
bloodsies.color = wear_mask.blood_color
standing.overlays += bloodsies
overlays_standing[FACEMASK_LAYER] = standing
else
overlays_lying[FACEMASK_LAYER] = null
overlays_standing[FACEMASK_LAYER] = null
if(update_icons) update_icons()
@@ -703,10 +645,8 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/update_inv_back(var/update_icons=1)
if(back)
back.screen_loc = ui_back //TODO
overlays_lying[BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]2")
overlays_standing[BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]")
overlays_standing[BACK_LAYER] = image("icon" = ((back.icon_override) ? back.icon_override : 'icons/mob/back.dmi'), "icon_state" = "[back.icon_state]")
else
overlays_lying[BACK_LAYER] = null
overlays_standing[BACK_LAYER] = null
if(update_icons) update_icons()
@@ -723,16 +663,13 @@ proc/get_damage_icon_part(damage_state, body_part)
drop_r_hand()
drop_l_hand()
stop_pulling() //TODO: should be handled elsewhere
overlays_lying[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff2")
overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1")
else
overlays_lying[HANDCUFF_LAYER] = null
overlays_standing[HANDCUFF_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1)
if(legcuffed)
overlays_lying[LEGCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff2")
overlays_standing[LEGCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff1")
if(src.m_intent != "walk")
src.m_intent = "walk"
@@ -740,7 +677,6 @@ proc/get_damage_icon_part(damage_state, body_part)
src.hud_used.move_intent.icon_state = "walking"
else
overlays_lying[LEGCUFF_LAYER] = null
overlays_standing[LEGCUFF_LAYER] = null
if(update_icons) update_icons()
@@ -769,12 +705,10 @@ proc/get_damage_icon_part(damage_state, body_part)
if(update_icons) update_icons()
/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1)
overlays_lying[TAIL_LAYER] = null
overlays_standing[TAIL_LAYER] = null
if(species.tail && species.flags & HAS_TAIL)
if(!wear_suit || !(wear_suit.flags_inv & HIDEJUMPSUIT) && !istype(wear_suit, /obj/item/clothing/suit/space))
overlays_lying[TAIL_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_l")
overlays_standing[TAIL_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s")
if(update_icons)
@@ -52,7 +52,7 @@
if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
temp_message[H] = ninjaspeak(temp_message[H])
pick_list -= H
message = dd_list2text(temp_message, " ")
message = list2text(temp_message, " ")
message = replacetext(message, "o", "¤")
message = replacetext(message, "p", "þ")
message = replacetext(message, "l", "£")
+74 -6
View File
@@ -2,14 +2,68 @@
Tiny babby plant critter plus procs.
*/
//Helper object for picking dionaea (and other creatures) up.
/obj/item/weapon/holder
name = "holder"
desc = "You shouldn't ever see this."
/obj/item/weapon/holder/diona
name = "diona nymph"
desc = "It's a tiny plant critter."
icon = 'icons/obj/objects.dmi'
icon_state = "nymph"
slot_flags = SLOT_HEAD
origin_tech = "magnets=3;biotech=5"
/obj/item/weapon/holder/New()
..()
processing_objects.Add(src)
/obj/item/weapon/holder/Del()
//Hopefully this will stop the icon from remaining on human mobs.
if(istype(loc,/mob/living))
var/mob/living/A = src.loc
src.loc = null
A.update_icons()
processing_objects.Remove(src)
..()
/obj/item/weapon/holder/process()
if(!loc) return
if(istype(loc,/turf) || !(contents.len))
for(var/mob/M in contents)
M.loc = get_turf(src)
del(src)
/obj/item/weapon/holder/attackby(obj/item/weapon/W as obj, mob/user as mob)
for(var/mob/M in src.contents)
M.attackby(W,user)
//Mob defines.
/mob/living/carbon/monkey/diona
name = "diona nymph"
voice_name = "diona nymph"
speak_emote = list("chirrups")
ico = "nymph"
icon_state = "nymph1"
var/list/donors = list()
var/ready_evolve = 0
/mob/living/carbon/monkey/diona/attack_hand(mob/living/carbon/human/M as mob)
//Let people pick the little buggers up.
if(M.a_intent == "help")
var/obj/item/weapon/holder/diona/D = new(loc)
src.loc = D
D.name = loc.name
D.attack_hand(M)
M << "You scoop up [src]."
src << "[M] scoops you up."
return
..()
/mob/living/carbon/monkey/diona/New()
..()
@@ -64,17 +118,28 @@
set name = "Evolve"
set desc = "Grow to a more complex form."
if(!is_alien_whitelisted(src, "Diona") && config.usealienwhitelist)
src << alert("You are currently not whitelisted to play as a full diona.")
return 0
if(donors.len < 5)
src << "You are not yet ready for your growth..."
return
if(reagents.get_reagent_amount("nutriment") < 5)
if(nutrition < 400)
src << "You have not yet consumed enough to grow..."
return
src.visible_message("\red [src] begins to shift and quiver, and erupts in a shower of shed bark and twigs!","\red You begin to shift and quiver, then erupt in a shower of shed bark and twigs, attaining your adult form!")
var/mob/living/carbon/human/adult = new(loc)
var/mob/living/carbon/human/adult = new(get_turf(src.loc))
adult.set_species("Diona")
if(istype(loc,/obj/item/weapon/holder/diona))
var/obj/item/weapon/holder/diona/L = loc
src.loc = L.loc
del(L)
for(var/datum/language/L in languages)
adult.add_language(L.name)
adult.regenerate_icons()
@@ -118,8 +183,11 @@
if(donors.len == 5)
ready_evolve = 1
src << "\green You feel ready to move on to your next stage of growth."
else if(donors.len == 3)
else if(donors.len == 2)
universal_understand = 1
src << "\green You feel your awareness expand, and realize you know how to understand the creatures around you."
else if(donors.len == 4)
universal_speak = 1
src << "\green You feel your awareness expand, and realize you know how to speak to the meat-creatures around you."
src << "\green You feel your awareness expand, and realize you know how to speak with the creatures around you."
else
src << "\green The blood seeps into your small form, and you draw out the echoes of memories and personality from it, working them into your budding mind."
src << "\green The blood seeps into your small form, and you draw out the echoes of memories and personality from it, working them into your budding mind."
+12 -6
View File
@@ -13,13 +13,16 @@
set invisibility = 0
set background = 1
if (monkeyizing) return
if (update_muts)
update_muts=0
domutcheck(src,null,MUTCHK_FORCED)
..()
var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE
if(loc)
environment = loc.return_air()
if (stat != DEAD) //still breathing
if (stat != DEAD && !istype(src,/mob/living/carbon/monkey/diona)) //still breathing
//First, resolve location and get a breath
if(air_master.current_cycle%4==2)
//Only try to take a breath every 4 seconds, unless suffocating
@@ -67,8 +70,11 @@
G.process()
if(!client && stat == CONSCIOUS)
if(prob(33) && canmove && isturf(loc))
if(prob(33) && canmove && isturf(loc) && !pulledby) //won't move if being pulled
step(src, pick(cardinal))
if(prob(1))
emote(pick("scratch","jump","roll","tail"))
@@ -250,7 +256,7 @@
block = 1
if(!block)
for(var/obj/effect/effect/chem_smoke/smoke in view(1, src))
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
if(smoke.reagents.total_volume)
smoke.reagents.reaction(src, INGEST)
spawn(5)
@@ -434,7 +440,7 @@
proc/handle_chemicals_in_body()
if(istype(src,/mob/living/carbon/monkey/diona)) //Filthy check. Dionaea nymphs need light or they get sad.
if(alien) //Diona nymphs are the only alien monkey currently.
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
if(isturf(loc)) //else, there's considered to be no light
var/turf/T = loc
@@ -449,11 +455,11 @@
if(nutrition > 500)
nutrition = 500
if(light_amount > 2) //if there's enough light, heal
heal_overall_damage(1,1)
adjustBruteLoss(-1)
adjustToxLoss(-1)
adjustOxyLoss(-1)
if(reagents) reagents.metabolize(src)
if(reagents) reagents.metabolize(src,alien)
if (drowsyness)
drowsyness--
+30 -17
View File
@@ -10,29 +10,32 @@
var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
var/greaterform = "Human" // Used when humanizing a monkey.
var/ico = "monkey" // Used when updating icons.
var/uni_append = "12C4E2" // Small appearance modifier for different species.
icon_state = "monkey1"
//var/uni_append = "12C4E2" // Small appearance modifier for different species.
var/list/uni_append = list(0x12C,0x4E2) // Same as above for DNA2.
var/update_muts = 1 // Monkey gene must be set at start.
var/alien = 0 //Used for reagent metabolism.
/mob/living/carbon/monkey/tajara
name = "farwa"
voice_name = "farwa"
speak_emote = list("mews")
ico = "tajkey"
uni_append = "0A0E00"
icon_state = "tajkey1"
uni_append = list(0x0A0,0xE00) // 0A0E00
/mob/living/carbon/monkey/skrell
name = "neaera"
voice_name = "neaera"
speak_emote = list("squicks")
ico = "skrellkey"
uni_append = "01CC92"
icon_state = "skrellkey1"
uni_append = list(0x01C,0xC92) // 01CC92
/mob/living/carbon/monkey/unathi
name = "stok"
voice_name = "stok"
speak_emote = list("hisses")
ico = "stokkey"
uni_append = "044C5D"
icon_state = "stokkey1"
uni_append = list(0x044,0xC5D) // 044C5D
/mob/living/carbon/monkey/New()
var/datum/reagents/R = new/datum/reagents(1000)
@@ -48,16 +51,25 @@
gender = pick(MALE, FEMALE)
dna = new /datum/dna( null )
dna.real_name = real_name
dna.uni_identity = "00600200A00E0110148FC01300B009"
dna.struc_enzymes = "43359156756131E13763334D1C369012032164D4FE4CD61544B6C03F251B6C60A42821D26BA3B0FD6"
dna.ResetSE()
dna.ResetUI()
//dna.uni_identity = "00600200A00E0110148FC01300B009"
//dna.struc_enzymes = "43359156756131E13763334D1C369012032164D4FE4CD61544B6C03F251B6C60A42821D26BA3B0FD6"
dna.unique_enzymes = md5(name)
//////////blah
var/gendervar
if (gender == MALE)
gendervar = add_zero2(num2hex((rand(1,2049)),1), 3)
else
gendervar = add_zero2(num2hex((rand(2051,4094)),1), 3)
dna.uni_identity += "[gendervar][uni_append]"
// We're a monkey
dna.SetSEState(MONKEYBLOCK, 1)
// Fix gender
dna.SetUIState(DNA_UI_GENDER, gender != MALE, 1)
// Set the blocks to uni_append, if needed.
if(uni_append.len>0)
for(var/b=1;b<=uni_append.len;b++)
dna.SetUIValue(DNA_UI_LENGTH-(uni_append.len-b),uni_append[b], 1)
dna.UpdateUI()
update_muts=1
..()
update_icons()
return
@@ -86,6 +98,7 @@
/mob/living/carbon/monkey/diona/New()
..()
alien = 1
gender = NEUTER
dna.mutantrace = "plant"
greaterform = "Diona"
@@ -28,25 +28,25 @@
update_hud()
lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again
overlays.Cut()
for(var/image/I in overlays_standing)
overlays += I
if(lying)
icon_state = ico + "0"
for(var/image/I in overlays_lying)
overlays += I
var/matrix/M = matrix()
M.Turn(90)
M.Translate(1,-6)
src.transform = M
else
icon_state = ico + "1"
for(var/image/I in overlays_standing)
overlays += I
var/matrix/M = matrix()
src.transform = M
////////
/mob/living/carbon/monkey/update_inv_wear_mask(var/update_icons=1)
if( wear_mask && istype(wear_mask, /obj/item/clothing/mask) )
overlays_lying[M_MASK_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "[wear_mask.icon_state]2")
overlays_standing[M_MASK_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "[wear_mask.icon_state]")
wear_mask.screen_loc = ui_monkey_mask
else
overlays_lying[M_MASK_LAYER] = null
overlays_standing[M_MASK_LAYER] = null
if(update_icons) update_icons()
@@ -77,11 +77,9 @@
/mob/living/carbon/monkey/update_inv_back(var/update_icons=1)
if(back)
overlays_lying[M_BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]2")
overlays_standing[M_BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]")
back.screen_loc = ui_monkey_back
else
overlays_lying[M_BACK_LAYER] = null
overlays_standing[M_BACK_LAYER] = null
if(update_icons) update_icons()
@@ -91,10 +89,8 @@
drop_r_hand()
drop_l_hand()
stop_pulling()
overlays_lying[M_HANDCUFF_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "handcuff2")
overlays_standing[M_HANDCUFF_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "handcuff1")
else
overlays_lying[M_HANDCUFF_LAYER] = null
overlays_standing[M_HANDCUFF_LAYER] = null
if(update_icons) update_icons()
@@ -106,12 +102,10 @@
//Call when target overlay should be added/removed
/mob/living/carbon/monkey/update_targeted(var/update_icons=1)
if (targeted_by && target_locked)
overlays_lying[TARGETED_LAYER] = target_locked
overlays_standing[TARGETED_LAYER] = target_locked
else if (!targeted_by && target_locked)
del(target_locked)
if (!targeted_by)
overlays_lying[TARGETED_LAYER] = null
overlays_standing[TARGETED_LAYER] = null
if(update_icons) update_icons()
+12 -8
View File
@@ -5,20 +5,24 @@
/mob/living/carbon/proc/updateshock()
src.traumatic_shock = \
1 * src.getOxyLoss() + \
0.5 * src.getToxLoss() + \
2.5 * src.getFireLoss() + \
1.5 * src.getBruteLoss() + \
2 * src.getCloneLoss() + \
1 * src.halloss
0.7 * src.getToxLoss() + \
1.5 * src.getFireLoss() + \
1.2 * src.getBruteLoss() + \
1.7 * src.getCloneLoss() + \
2 * src.halloss
if(reagents.has_reagent("alkysine"))
src.traumatic_shock -= 10
if(reagents.has_reagent("inaprovaline"))
src.traumatic_shock -= 25
if(reagents.has_reagent("synaptizine"))
src.traumatic_shock -= 40
if(reagents.has_reagent("paracetamol"))
src.traumatic_shock -= 50
if(reagents.has_reagent("tramadol"))
src.traumatic_shock -= 80 // make synaptizine function as good painkiller
src.traumatic_shock -= 80
if(reagents.has_reagent("oxycodone"))
src.traumatic_shock -= 200 // make synaptizine function as good painkiller
src.traumatic_shock -= 200
if(src.slurring)
src.traumatic_shock -= 20
if(src.analgesic)
@@ -35,7 +39,7 @@
else if(organ.status & ORGAN_BROKEN || organ.open)
src.traumatic_shock += 30
if(organ.status & ORGAN_SPLINTED)
src.traumatic_shock -= 20
src.traumatic_shock -= 25
if(src.traumatic_shock < 0)
src.traumatic_shock = 0
+26 -5
View File
@@ -37,6 +37,11 @@
var/flags = 0 // Various specific features.
var/list/abilities = list() // For species-derived or admin-given powers
var/blood_color = "#A10808" //Red.
var/flesh_color = "#FFC896" //Pink.
/datum/species/human
name = "Human"
language = "Sol Common"
@@ -44,6 +49,9 @@
flags = HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR
//If you wanted to add a species-level ability:
/*abilities = list(/client/proc/test_ability)*/
/datum/species/unathi
name = "Unathi"
icobase = 'icons/mob/human_races/r_lizard.dmi'
@@ -63,7 +71,9 @@
heat_level_2 = 480 //Default 400
heat_level_3 = 1100 //Default 1000
flags = WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL
flesh_color = "#34AF10"
/datum/species/tajaran
name = "Tajaran"
@@ -85,7 +95,9 @@
primitive = /mob/living/carbon/monkey/tajara
flags = WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL
flesh_color = "#AFA59E"
/datum/species/skrell
name = "Skrell"
@@ -94,7 +106,9 @@
language = "Skrellian"
primitive = /mob/living/carbon/monkey/skrell
flags = WHITELISTED | HAS_LIPS | HAS_UNDERWEAR
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR
flesh_color = "#8CD7A3"
/datum/species/vox
name = "Vox"
@@ -112,7 +126,10 @@
eyes = "vox_eyes_s"
breath_type = "nitrogen"
flags = NO_SCAN
flags = NO_SCAN | NO_BLOOD
blood_color = "#2299FC"
flesh_color = "#808D11"
/datum/species/diona
name = "Diona"
@@ -134,4 +151,8 @@
heat_level_2 = 3000
heat_level_3 = 4000
flags = WHITELISTED | NO_BREATHE | REQUIRE_LIGHT | NON_GENDERED | NO_SCAN | IS_PLANT | RAD_ABSORB
flags = IS_WHITELISTED | NO_BREATHE | REQUIRE_LIGHT | NO_SCAN | IS_PLANT | RAD_ABSORB | NO_BLOOD | IS_SLOW | NO_PAIN
blood_color = "#004400"
flesh_color = "#907E4A"
+103 -4
View File
@@ -280,7 +280,6 @@
blinded = 0
eye_blind = 0
eye_blurry = 0
eye_stat = 0
ear_deaf = 0
ear_damage = 0
heal_overall_damage(getBruteLoss(), getFireLoss())
@@ -435,6 +434,13 @@
var/mob/living/L = usr
//Getting out of someone's inventory.
if(istype(src.loc,/obj/item/weapon/holder))
var/obj/item/weapon/holder/H = src.loc
src.loc = get_turf(src.loc)
del(H)
return
//Resisting control by an alien mind.
if(istype(src.loc,/mob/living/simple_animal/borer))
var/mob/living/simple_animal/borer/B = src.loc
@@ -620,9 +626,10 @@
for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink
O.show_message("\red <B>[CM] manages to remove the handcuffs!</B>", 1)
CM << "\blue You successfully remove \the [CM.handcuffed]."
CM.handcuffed.loc = usr.loc
CM.drop_from_inventory(CM.handcuffed)
CM.handcuffed = null
CM.update_inv_handcuffed()
else if(CM.legcuffed && CM.canmove && (CM.last_special <= world.time))
CM.next_move = world.time + 100
CM.last_special = world.time + 100
@@ -658,7 +665,7 @@
for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink
O.show_message("\red <B>[CM] manages to remove the legcuffs!</B>", 1)
CM << "\blue You successfully remove \the [CM.legcuffed]."
CM.legcuffed.loc = usr.loc
CM.drop_from_inventory(CM.legcuffed)
CM.legcuffed = null
CM.update_inv_legcuffed()
@@ -667,4 +674,96 @@
set category = "IC"
resting = !resting
src << "\blue You are now [resting ? "resting" : "getting up"]"
src << "\blue You are now [resting ? "resting" : "getting up"]"
/mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null) // -- TLE -- Merged by Carn
if(stat)
src << "You must be conscious to do this!"
return
if(lying)
src << "You can't vent crawl while you're stunned!"
return
if(vent_found) // one was passed in, probably from vent/AltClick()
if(vent_found.welded)
src << "That vent is welded shut."
return
if(!vent_found.Adjacent(src))
return // don't even acknowledge that
else
for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
if(!v.welded)
if(v.Adjacent(src))
vent_found = v
if(!vent_found)
src << "You'll need a non-welded vent to crawl into!"
return
if(!vent_found.network || !vent_found.network.normal_members.len)
src << "This vent is not connected to anything."
return
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
if(temp_vent.welded)
continue
if(temp_vent in loc)
continue
var/turf/T = get_turf(temp_vent)
if(!T || T.z != loc.z)
continue
var/i = 1
var/index = "[T.loc.name]\[[i]\]"
while(index in vents)
i++
index = "[T.loc.name]\[[i]\]"
vents[index] = temp_vent
if(!vents.len)
src << "\red There are no available vents to travel to, they could be welded."
return
var/obj/selection = input("Select a destination.", "Duct System") as null|anything in sortAssoc(vents)
if(!selection) return
if(!vent_found.Adjacent(src))
src << "Never mind, you left."
return
for(var/obj/item/carried_item in contents)//If the monkey got on objects.
if( !istype(carried_item, /obj/item/weapon/implant) && !istype(carried_item, /obj/item/clothing/mask/facehugger) )//If it's not an implant or a facehugger
src << "\red You can't be carrying items or have items equipped when vent crawling!"
return
if(isslime(src))
var/mob/living/carbon/slime/S = src
if(S.Victim)
src << "\red You'll have to let [S.Victim] go or finish eating \him first."
return
var/obj/machinery/atmospherics/unary/vent_pump/target_vent = vents[selection]
if(!target_vent)
return
for(var/mob/O in viewers(src, null))
O.show_message(text("<B>[src] scrambles into the ventillation ducts!</B>"), 1)
loc = target_vent
var/travel_time = round(get_dist(loc, target_vent.loc) / 2)
spawn(travel_time)
if(!target_vent) return
for(var/mob/O in hearers(target_vent,null))
O.show_message("You hear something squeezing through the ventilation ducts.",2)
sleep(travel_time)
if(!target_vent) return
if(target_vent.welded) //the vent can be welded while alien scrolled through the list or travelled.
target_vent = vent_found //travel back. No additional time required.
src << "\red The vent you were heading to appears to be welded."
loc = target_vent.loc
var/area/new_area = get_area(loc)
if(new_area)
new_area.Entered(src)
+11 -4
View File
@@ -108,7 +108,7 @@ var/list/department_radio_keys = list(
if(client.prefs.muted & MUTE_IC)
src << "\red You cannot speak in IC (muted)."
return
if (src.client.handle_spam_prevention(message,MUTE_IC))
if (src.client.handle_spam_prevention(message, MUTE_IC))
return
// Mute disability
@@ -173,7 +173,7 @@ var/list/department_radio_keys = list(
if(src.stunned > 2 || (traumatic_shock > 61 && prob(50)))
message_mode = null //Stunned people shouldn't be able to physically turn on their radio/hold down the button to speak into it
message = capitalize(message)
message = capitalize(trim_left(message))
if (!message)
return
@@ -302,6 +302,7 @@ var/list/department_radio_keys = list(
var/list/listening
listening = get_mobs_in_view(message_range, src)
var/list/onscreen = get_mobs_in_view(7, src)
for(var/mob/M in player_list)
if (!M.client)
continue //skip monkeys and leavers
@@ -372,14 +373,17 @@ var/list/department_radio_keys = list(
M:show_message("<span class='notice'>[src] talks into [used_radios.len ? used_radios[1] : "radio"]</span>")
var/rendered = null
if (length(heard_a))
var/message_a = say_quote(message,speaking)
if (italics)
message_a = "<i>[message_a]</i>"
var/message_ghost = "<b>[message_a]</b>" // bold so ghosts know the person is in view.
rendered = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] <span class='message'>[message_a]</span></span>"
for (var/M in heard_a)
var/rendered_ghost = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] <span class='message'>[message_ghost]</span></span>"
for (var/mob/M in heard_a)
if(hascall(M,"show_message"))
var/deaf_message = ""
var/deaf_type = 1
@@ -388,7 +392,10 @@ var/list/department_radio_keys = list(
else
deaf_message = "<span class='notice'>You cannot hear yourself!</span>"
deaf_type = 2 // Since you should be able to hear yourself without looking
M:show_message(rendered, 2, deaf_message, deaf_type)
if (M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && M in onscreen)
M:show_message(rendered_ghost, 2, deaf_message, deaf_type)
else
M:show_message(rendered, 2, deaf_message, deaf_type)
M << speech_bubble
if (length(heard_b))
+4
View File
@@ -95,6 +95,7 @@ var/list/ai_list = list()
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
/mob/living/silicon/ai/proc/toggle_camera_light)
if(!safety)//Only used by AIize() to successfully spawn an AI.
if (!B)//If there is no player/brain inside.
new/obj/structure/AIcore/deactivated(loc)//New empty terminal.
@@ -338,9 +339,12 @@ var/list/ai_list = list()
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
checklaws()
//Uncomment this line of code if you are enabling the AI Vocal (VOX) announcements.
/*
if(href_list["say_word"])
play_vox_word(href_list["say_word"], null, src)
return
*/
if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
var/L = text2num(href_list["lawi"])
+12 -2
View File
@@ -14,6 +14,13 @@
return 1
return ..()
// These Verbs are commented out since we've disabled the AI vocal (VOX) announcements.
// If you re-enable them there is 3 lines in ai.dm Topic() that you need to uncomment as well.
// just search for VOX in there.
/*
var/announcing_vox = 0 // Stores the time of the last announcement
var/const/VOX_CHANNEL = 200
var/const/VOX_DELAY = 100 // 10 seconds
@@ -61,7 +68,7 @@ var/const/VOX_PATH = "sound/vox/"
if(!message || announcing_vox > world.time)
return
var/list/words = stringsplit(trim(message), " ")
var/list/words = text2list(trim(message), " ")
var/list/incorrect_words = list()
if(words.len > 30)
@@ -127,4 +134,7 @@ var/const/VOX_PATH = "sound/vox/"
for(var/file in vox_files)
// src << "Downloading [file]"
var/sound/S = sound("[VOX_PATH][file]")
src << browse_rsc(S)
src << browse_rsc(S)
*/
@@ -80,6 +80,12 @@
holder.icon_state = "hudxeno"
else if(foundVirus)
holder.icon_state = "hudill"
else if(patient.has_brain_worms())
var/mob/living/simple_animal/borer/B = patient.has_brain_worms()
if(B.controlling)
holder.icon_state = "hudbrainworm"
else
holder.icon_state = "hudhealthy"
else
holder.icon_state = "hudhealthy"
client.images += holder
+2 -1
View File
@@ -4,6 +4,7 @@
icon_state = "shadow"
robot_talk_understand = 0
emote_type = 2 // pAIs emotes are heard, not seen, so they can be seen through a container (eg. person)
var/network = "SS13"
var/obj/machinery/camera/current = null
@@ -268,4 +269,4 @@
pai.key = src.key
card.setPersonality(pai)
*/
*/
@@ -13,6 +13,10 @@ var/datum/paiController/paiController // Global handler for pAI candidates
var/ready = 0
/hook/startup/proc/paiControllerSetup()
paiController = new /datum/paiController()
return 1
/datum/paiController
var/list/pai_candidates = list()
@@ -191,6 +195,8 @@ var/datum/paiController/paiController // Global handler for pAI candidates
proc/requestRecruits()
for(var/mob/dead/observer/O in player_list)
if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
continue
if(jobban_isbanned(O, "pAI"))
continue
if(asked.Find(O.key))
@@ -124,11 +124,11 @@
/obj/item/broken_device
name = "broken component"
icon = 'icons/robot_component.dmi'
icon = 'icons/obj/robot_component.dmi'
icon_state = "broken"
/obj/item/robot_parts/robot_component
icon = 'icons/robot_component.dmi'
icon = 'icons/obj/robot_component.dmi'
icon_state = "working"
construction_time = 200
construction_cost = list("metal"=5000)
@@ -214,4 +214,4 @@
if(H.emagged && prob(5))
user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1)
src.add_fingerprint(user)
return
return
@@ -275,8 +275,11 @@
if(Entry[1] == src.ckey && Entry[2] == src.real_name) //They're in the list? Custom sprite time, var and icon change required
custom_sprite = 1
icon = 'icons/mob/custom-synthetic.dmi'
if(icon_state == "robot")
icon_state = "[src.ckey]-Standard"
/mob/living/silicon/robot/verb/Namepick()
set category = "Robot Commands"
if(custom_name)
return 0
@@ -1161,6 +1164,9 @@
var/turf/tile = loc
if(isturf(tile))
tile.clean_blood()
if (istype(tile, /turf/simulated))
var/turf/simulated/S = tile
S.dirt = 0
for(var/A in tile)
if(istype(A, /obj/effect))
if(istype(A, /obj/effect/rune) || istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/overlay))
@@ -169,7 +169,7 @@
New()
..()
src.modules += new /obj/item/weapon/reagent_containers/food/drinks/beer(src)
src.modules += new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
src.modules += new /obj/item/weapon/reagent_containers/food/condiment/enzyme(src)
src.modules += new /obj/item/weapon/pen/robopen(src)
@@ -185,7 +185,7 @@
src.modules += new /obj/item/weapon/tray/robotray(src)
src.modules += new /obj/item/weapon/reagent_containers/food/drinks/shaker(src)
src.emag = new /obj/item/weapon/reagent_containers/food/drinks/beer(src)
src.emag = new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
var/datum/reagents/R = new/datum/reagents(50)
src.emag.reagents = R
@@ -80,7 +80,7 @@
//smoke, water and steam calms us down
var/calming = 0
var/list/calmers = list(/obj/effect/effect/chem_smoke, \
var/list/calmers = list(/obj/effect/effect/smoke/chem, \
/obj/effect/effect/water, \
/obj/effect/effect/foam, \
/obj/effect/effect/steam, \

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