Merge branch 'master' into upstream-merge-30117
This commit is contained in:
@@ -49,6 +49,10 @@
|
||||
open_machine()
|
||||
|
||||
|
||||
/obj/machinery/vr_sleeper/container_resist(mob/living/user)
|
||||
open_machine()
|
||||
|
||||
|
||||
/obj/machinery/vr_sleeper/Destroy()
|
||||
open_machine()
|
||||
cleanup_vr_human()
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
if(M.client)
|
||||
body += " played by <b>[M.client]</b> "
|
||||
body += "\[<A href='?_src_=holder;editrights=rank;ckey=[M.ckey]'>[M.client.holder ? M.client.holder.rank : "Player"]</A>\]"
|
||||
if(config.use_exp_tracking)
|
||||
body += "\[<A href='?_src_=holder;getplaytimewindow=\ref[M]'>" + M.client.get_exp_living() + "</a>\]"
|
||||
|
||||
if(isnewplayer(M))
|
||||
body += " <B>Hasn't Entered Game</B> "
|
||||
|
||||
@@ -61,6 +61,7 @@ GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin())
|
||||
/client/proc/cmd_admin_local_narrate, /*sends text to all mobs within view of atom*/
|
||||
/client/proc/cmd_admin_create_centcom_report,
|
||||
/client/proc/cmd_change_command_name,
|
||||
/client/proc/cmd_admin_check_player_exp, /* shows players by playtime */
|
||||
/client/proc/toggle_antag_hud, /*toggle display of the admin antag hud*/
|
||||
/client/proc/toggle_AI_interact, /*toggle admin ability to interact with machines as an AI*/
|
||||
/client/proc/customiseSNPC, /* Customise any interactive crewmembers in the world */
|
||||
@@ -260,6 +261,8 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
verbs += GLOB.admin_verbs_poll
|
||||
if(rights & R_SOUNDS)
|
||||
verbs += GLOB.admin_verbs_sounds
|
||||
if(config.invoke_youtubedl)
|
||||
verbs += /client/proc/play_web_sound
|
||||
if(rights & R_SPAWN)
|
||||
verbs += GLOB.admin_verbs_spawn
|
||||
|
||||
@@ -282,6 +285,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
/client/proc/stealth,
|
||||
GLOB.admin_verbs_poll,
|
||||
GLOB.admin_verbs_sounds,
|
||||
/client/proc/play_web_sound,
|
||||
GLOB.admin_verbs_spawn,
|
||||
/*Debug verbs added by "show debug verbs"*/
|
||||
/client/proc/Cell,
|
||||
|
||||
10
code/modules/admin/admin_verbs.dm.rej
Normal file
10
code/modules/admin/admin_verbs.dm.rej
Normal file
@@ -0,0 +1,10 @@
|
||||
diff a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm (rejected hunks)
|
||||
@@ -663,7 +664,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, AVerbsHideable())
|
||||
|
||||
if(!holder)
|
||||
return
|
||||
-
|
||||
+
|
||||
if(has_antag_hud())
|
||||
toggle_antag_hud()
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
return 0
|
||||
|
||||
/proc/jobban_buildcache(client/C)
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
if(C && istype(C))
|
||||
C.jobbancache = list()
|
||||
var/datum/DBQuery/query_jobban_build_cache = SSdbcore.NewQuery("SELECT job, reason FROM [format_table_name("ban")] WHERE ckey = '[sanitizeSQL(C.ckey)]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
descmax = sanitizeSQL(descmax)
|
||||
else if(descmax == null)
|
||||
return
|
||||
sql_option_list += list(list("text" = "'[option]'", "minval" = "'[minval]'", "maxval" = "'[maxval]'", "descmin" = "'[descmin]'", "descmid" = "'[descmid]'", "descmax" = "'[descmax]'", "default_display_in_results" = "'[default_percentage_calc]'"))
|
||||
sql_option_list += list(list("text" = "'[option]'", "minval" = "'[minval]'", "maxval" = "'[maxval]'", "descmin" = "'[descmin]'", "descmid" = "'[descmid]'", "descmax" = "'[descmax]'", "default_percentage_calc" = "'[default_percentage_calc]'"))
|
||||
switch(alert(" ",,"Add option","Finish", "Cancel"))
|
||||
if("Add option")
|
||||
add_option = 1
|
||||
|
||||
@@ -389,7 +389,7 @@
|
||||
for(var/datum/mind/N in SSticker.mode.syndicates)
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
else
|
||||
@@ -418,20 +418,20 @@
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[N]'>[N.name]([N.key])</a><i>Head Revolutionary body destroyed!</i></td>"
|
||||
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
for(var/datum/mind/N in SSticker.mode.revolutionaries)
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "</table><table cellspacing=5><tr><td><B>Target(s)</B></td><td></td><td><B>Location</B></td></tr>"
|
||||
for(var/datum/mind/N in SSticker.mode.get_living_heads())
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
var/turf/mob_loc = get_turf(M)
|
||||
@@ -449,13 +449,13 @@
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[N]'>[N.name]([N.key])</a><i>Gang Boss body destroyed!</i></td>"
|
||||
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Boss)</b>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Boss)</b>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
for(var/datum/mind/N in G.gangsters)
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
@@ -464,7 +464,7 @@
|
||||
for(var/datum/mind/changeling in SSticker.mode.changelings)
|
||||
var/mob/M = changeling.current
|
||||
if(M)
|
||||
dat += "<tr><td>[M.mind.changeling.changelingID] as <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td>[M.mind.changeling.changelingID] as <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
@@ -478,7 +478,7 @@
|
||||
for(var/datum/mind/wizard in SSticker.mode.wizards)
|
||||
var/mob/M = wizard.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
@@ -492,7 +492,7 @@
|
||||
for(var/datum/mind/apprentice in SSticker.mode.apprentices)
|
||||
var/mob/M = apprentice.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
@@ -506,7 +506,7 @@
|
||||
for(var/datum/mind/N in SSticker.mode.cult)
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[N.has_antag_datum(ANTAG_DATUM_CULT_MASTER) ? "<i><font color=red> \[Master\]</font></i>" : ""][M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[N.has_antag_datum(ANTAG_DATUM_CULT_MASTER) ? "<i><font color=red> \[Master\]</font></i>" : ""][M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "</table>"
|
||||
@@ -516,7 +516,7 @@
|
||||
for(var/datum/mind/N in SSticker.mode.servants_of_ratvar)
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "</table>"
|
||||
@@ -526,7 +526,7 @@
|
||||
for(var/datum/mind/traitor in SSticker.mode.traitors)
|
||||
var/mob/M = traitor.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
@@ -540,7 +540,7 @@
|
||||
for(var/datum/mind/abductor in SSticker.mode.abductors)
|
||||
var/mob/M = abductor.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
@@ -553,7 +553,7 @@
|
||||
for(var/datum/mind/abductee in E.abductee_minds)
|
||||
var/mob/M = abductee.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
@@ -569,7 +569,7 @@
|
||||
var/mob/M = devil.current
|
||||
var/datum/antagonist/devil/devilinfo = devil.has_antag_datum(ANTAG_DATUM_DEVIL)
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name] : [devilinfo.truename]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name] : [devilinfo.truename]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
dat += "<td><A HREF='?_src_=holder;admincheckdevilinfo=\ref[M]'>Show all devil info</A></td></tr>"
|
||||
@@ -584,7 +584,7 @@
|
||||
var/datum/mind/sintouched = X
|
||||
var/mob/M = sintouched.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
else
|
||||
@@ -606,7 +606,7 @@
|
||||
for(var/datum/mind/blob in blob_minds)
|
||||
var/mob/M = blob.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
else
|
||||
@@ -622,7 +622,7 @@
|
||||
for(var/datum/mind/eek in mode.ape_infectees)
|
||||
var/mob/M = eek.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
else
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
SSblackbox.add_details("admin_secrets_fun_used","Traitor All ([objective])")
|
||||
for(var/mob/living/H in GLOB.player_list)
|
||||
if(!(ishuman(H)||istype(H, /mob/living/silicon/))) continue
|
||||
if(H.stat == 2 || !H.client || !H.mind || ispAI(H)) continue
|
||||
if(H.stat == DEAD || !H.client || !H.mind || ispAI(H)) continue
|
||||
if(is_special_character(H)) continue
|
||||
H.mind.add_antag_datum(ANTAG_DATUM_TRAITOR_CUSTOM)
|
||||
var/datum/antagonist/traitor/traitordatum = H.mind.has_antag_datum(ANTAG_DATUM_TRAITOR) //original datum self deletes
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
secret = 0
|
||||
else
|
||||
return
|
||||
var/datum/DBQuery/query_create_message = SSdbcore.NewQuery("INSERT INTO [format_table_name("messages")] (type, targetckey, adminckey, text, timestamp, server, secret) VALUES ('[type]', '[target_ckey]', '[admin_ckey]', '[text]', '[timestamp]', '[server]', '[secret]')")
|
||||
var/datum/DBQuery/query_create_message = SSdbcore.NewQuery("INSERT INTO [format_table_name("messages")] (type, targetckey, adminckey, text, timestamp, server, server_ip, server_port, round_id, secret) VALUES ('[type]', '[target_ckey]', '[admin_ckey]', '[text]', '[timestamp]', '[server]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]','[secret]')")
|
||||
if(!query_create_message.warn_execute())
|
||||
return
|
||||
if(logged)
|
||||
|
||||
@@ -22,6 +22,24 @@
|
||||
else if(href_list["stickyban"])
|
||||
stickyban(href_list["stickyban"],href_list)
|
||||
|
||||
else if(href_list["getplaytimewindow"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
var/mob/M = locate(href_list["getplaytimewindow"]) in GLOB.mob_list
|
||||
if(!M)
|
||||
to_chat(usr, "<span class='danger'>ERROR: Mob not found.</span>")
|
||||
return
|
||||
cmd_show_exp_panel(M.client)
|
||||
|
||||
else if(href_list["toggleexempt"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
var/client/C = locate(href_list["toggleexempt"]) in GLOB.clients
|
||||
if(!C)
|
||||
to_chat(usr, "<span class='danger'>ERROR: Client not found.</span>")
|
||||
return
|
||||
toggle_exempt_status(C)
|
||||
|
||||
else if(href_list["makeAntag"])
|
||||
if (!SSticker.mode)
|
||||
to_chat(usr, "<span class='danger'>Not until the round starts!</span>")
|
||||
@@ -1597,11 +1615,13 @@
|
||||
var/mob/living/L = M
|
||||
var/status
|
||||
switch (M.stat)
|
||||
if (0)
|
||||
if (CONSCIOUS)
|
||||
status = "Alive"
|
||||
if (1)
|
||||
status = "<font color='orange'><b>Unconscious</b></font>"
|
||||
if (2)
|
||||
if(SOFT_CRIT)
|
||||
status = "<font color='orange'><b>Dying</b></font>"
|
||||
if(UNCONSCIOUS)
|
||||
status = "<font color='orange'><b>[L.InCritical() ? "Unconscious and Dying" : "Unconscious"]</b></font>"
|
||||
if(DEAD)
|
||||
status = "<font color='red'><b>Dead</b></font>"
|
||||
health_description = "Status = [status]"
|
||||
health_description += "<BR>Oxy: [L.getOxyLoss()] - Tox: [L.getToxLoss()] - Fire: [L.getFireLoss()] - Brute: [L.getBruteLoss()] - Clone: [L.getCloneLoss()] - Brain: [L.getBrainLoss()] - Stamina: [L.getStaminaLoss()]"
|
||||
|
||||
@@ -36,7 +36,11 @@
|
||||
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.client.prefs.toggles & SOUND_MIDI)
|
||||
var/user_vol = M.client.chatOutput.adminMusicVolume
|
||||
if(user_vol)
|
||||
admin_sound.volume = vol * (user_vol / 100)
|
||||
SEND_SOUND(M, admin_sound)
|
||||
admin_sound.volume = vol
|
||||
|
||||
SSblackbox.add_details("admin_verb","Play Global Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -52,6 +56,62 @@
|
||||
playsound(get_turf(src.mob), S, 50, 0, 0)
|
||||
SSblackbox.add_details("admin_verb","Play Local Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/play_web_sound()
|
||||
set category = "Fun"
|
||||
set name = "Play Internet Sound"
|
||||
if(!check_rights(R_SOUNDS))
|
||||
return
|
||||
|
||||
if(!config.invoke_youtubedl)
|
||||
to_chat(src, "<span class='boldwarning'>Youtube-dl was not configured, action unavailable</span>") //Check config.txt for the INVOKE_YOUTUBEDL value
|
||||
return
|
||||
|
||||
var/web_sound_input = input("Enter content URL (supported sites only, leave blank to stop playing)", "Play Internet Sound via youtube-dl") as text|null
|
||||
if(istext(web_sound_input))
|
||||
var/web_sound_url = ""
|
||||
var/pitch
|
||||
if(length(web_sound_input))
|
||||
|
||||
web_sound_input = trim(web_sound_input)
|
||||
var/static/regex/html_protocol_regex = regex("https?://")
|
||||
if(findtext(web_sound_input, ":") && !findtext(web_sound_input, html_protocol_regex))
|
||||
to_chat(src, "<span class='boldwarning'>Non-http(s) URIs are not allowed.</span>")
|
||||
to_chat(src, "<span class='warning'>For youtube-dl shortcuts like ytsearch: please use the appropriate full url from the website.</span>")
|
||||
return
|
||||
var/shell_scrubbed_input = shell_url_scrub(web_sound_input)
|
||||
var/list/output = world.shelleo("[config.invoke_youtubedl] --format \"bestaudio\[ext=aac]/bestaudio\[ext=mp3]/bestaudio\[ext=m4a]\" --get-url \"[shell_scrubbed_input]\"")
|
||||
var/errorlevel = output[SHELLEO_ERRORLEVEL]
|
||||
var/stdout = output[SHELLEO_STDOUT]
|
||||
var/stderr = output[SHELLEO_STDERR]
|
||||
if(!errorlevel)
|
||||
var/static/regex/content_url_regex = regex("https?://\\S+")
|
||||
if(content_url_regex.Find(stdout))
|
||||
web_sound_url = content_url_regex.match
|
||||
|
||||
if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
|
||||
pitch = pick(0.5, 0.7, 0.8, 0.85, 0.9, 0.95, 1.1, 1.2, 1.4, 1.6, 2.0, 2.5)
|
||||
to_chat(src, "You feel the Honkmother messing with your song...")
|
||||
|
||||
log_admin("[key_name(src)] played web sound: [web_sound_input]")
|
||||
message_admins("[key_name(src)] played web sound: [web_sound_input]")
|
||||
else
|
||||
to_chat(src, "<span class='boldwarning'>Youtube-dl URL retrieval FAILED:</span>")
|
||||
to_chat(src, "<span class='warning'>[stderr]</span>")
|
||||
|
||||
else //pressed ok with blank
|
||||
log_admin("[key_name(src)] stopped web sound")
|
||||
message_admins("[key_name(src)] stopped web sound")
|
||||
web_sound_url = " "
|
||||
|
||||
if(web_sound_url)
|
||||
for(var/m in GLOB.player_list)
|
||||
var/mob/M = m
|
||||
var/client/C = M.client
|
||||
if((C.prefs.toggles & SOUND_MIDI) && C.chatOutput && !C.chatOutput.broken && C.chatOutput.loaded)
|
||||
C.chatOutput.sendMusic(web_sound_url, pitch)
|
||||
|
||||
SSblackbox.add_details("admin_verb","Play Internet Sound")
|
||||
|
||||
/client/proc/set_round_end_sound(S as sound)
|
||||
set category = "Fun"
|
||||
set name = "Set Round End Sound"
|
||||
@@ -75,4 +135,7 @@
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.client)
|
||||
SEND_SOUND(M, sound(null))
|
||||
var/client/C = M.client
|
||||
if(C && C.chatOutput && !C.chatOutput.broken && C.chatOutput.loaded)
|
||||
C.chatOutput.sendMusic(" ")
|
||||
SSblackbox.add_details("admin_verb","Stop All Playing Sounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,25 @@
|
||||
diff a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm (rejected hunks)
|
||||
@@ -1214,7 +1214,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
|
||||
/client/proc/cmd_admin_check_player_exp() //Allows admins to determine who the newer players are.
|
||||
set category = "Admin"
|
||||
- set name = "Check Player Playtime"
|
||||
+ set name = "Player Playtime"
|
||||
if(!check_rights(R_ADMIN))
|
||||
@@ -1246,7 +1246,8 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
to_chat(usr, "<span class='danger'>ERROR: Client not found.</span>")
|
||||
return
|
||||
|
||||
- C.set_db_player_flags()
|
||||
+ if(!C.set_db_player_flags())
|
||||
+ to_chat(usr, "<span class='danger'>ERROR: Unable read player flags from database. Please check logs.</span>")
|
||||
var/dbflags = C.prefs.db_flags
|
||||
var/newstate = FALSE
|
||||
if(dbflags & DB_FLAG_EXEMPT)
|
||||
@@ -1254,6 +1255,8 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
else
|
||||
newstate = TRUE
|
||||
|
||||
- message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]")
|
||||
- log_admin("[key_name(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name(C)]")
|
||||
- C.update_flag_db(DB_FLAG_EXEMPT, newstate)
|
||||
\ No newline at end of file
|
||||
+ if(C.update_flag_db(DB_FLAG_EXEMPT, newstate))
|
||||
+ to_chat(usr, "<span class='danger'>ERROR: Unable to update player flags. Please check logs.</span>")
|
||||
+ else
|
||||
+ message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]")
|
||||
+ log_admin("[key_name(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name(C)]")
|
||||
\ No newline at end of file
|
||||
|
||||
@@ -222,6 +222,7 @@ Pipelines + Other Objects -> Pipe network
|
||||
build_network()
|
||||
|
||||
/obj/machinery/atmospherics/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
deconstruct(FALSE)
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
var/running_bob_anim = FALSE
|
||||
|
||||
var/escape_in_progress = FALSE
|
||||
var/message_cooldown
|
||||
var/breakout_time = 0.5
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/Initialize()
|
||||
. = ..()
|
||||
@@ -219,7 +221,9 @@
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/relaymove(mob/user)
|
||||
container_resist(user)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/open_machine(drop = 0)
|
||||
if(!state_open && !panel_open)
|
||||
@@ -239,16 +243,17 @@
|
||||
return occupant
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/container_resist(mob/living/user)
|
||||
if(escape_in_progress)
|
||||
to_chat(user, "<span class='notice'>You are already trying to exit (This will take around 30 seconds)</span>")
|
||||
return
|
||||
escape_in_progress = TRUE
|
||||
to_chat(user, "<span class='notice'>You struggle inside the cryotube, kicking the release with your foot... (This will take around 30 seconds.)</span>")
|
||||
audible_message("<span class='notice'>You hear a thump from [src].</span>")
|
||||
if(do_after(user, 300))
|
||||
if(occupant == user) // Check they're still here.
|
||||
open_machine()
|
||||
escape_in_progress = FALSE
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the glass of [src]!</span>", \
|
||||
"<span class='notice'>You struggle inside [src], kicking the release with your foot... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a thump from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src )
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/examine(mob/user)
|
||||
..()
|
||||
@@ -303,30 +308,47 @@
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_data()
|
||||
var/list/data = list()
|
||||
data["isOperating"] = on
|
||||
data["hasOccupant"] = occupant ? 1 : 0
|
||||
data["hasOccupant"] = occupant ? TRUE : FALSE
|
||||
data["isOpen"] = state_open
|
||||
data["autoEject"] = autoeject
|
||||
|
||||
var/list/occupantData = list()
|
||||
data["occupant"] = list()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
occupantData["name"] = mob_occupant.name
|
||||
occupantData["stat"] = mob_occupant.stat
|
||||
occupantData["health"] = mob_occupant.health
|
||||
occupantData["maxHealth"] = mob_occupant.maxHealth
|
||||
occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD
|
||||
occupantData["bruteLoss"] = mob_occupant.getBruteLoss()
|
||||
occupantData["oxyLoss"] = mob_occupant.getOxyLoss()
|
||||
occupantData["toxLoss"] = mob_occupant.getToxLoss()
|
||||
occupantData["fireLoss"] = mob_occupant.getFireLoss()
|
||||
occupantData["bodyTemperature"] = mob_occupant.bodytemperature
|
||||
data["occupant"] = occupantData
|
||||
data["occupant"]["name"] = mob_occupant.name
|
||||
switch(mob_occupant.stat)
|
||||
if(CONSCIOUS)
|
||||
data["occupant"]["stat"] = "Conscious"
|
||||
data["occupant"]["statstate"] = "good"
|
||||
if(SOFT_CRIT)
|
||||
data["occupant"]["stat"] = "Conscious"
|
||||
data["occupant"]["statstate"] = "average"
|
||||
if(UNCONSCIOUS)
|
||||
data["occupant"]["stat"] = "Unconscious"
|
||||
data["occupant"]["statstate"] = "average"
|
||||
if(DEAD)
|
||||
data["occupant"]["stat"] = "Dead"
|
||||
data["occupant"]["statstate"] = "bad"
|
||||
data["occupant"]["health"] = round(mob_occupant.health, 1)
|
||||
data["occupant"]["maxHealth"] = mob_occupant.maxHealth
|
||||
data["occupant"]["minHealth"] = HEALTH_THRESHOLD_DEAD
|
||||
data["occupant"]["bruteLoss"] = round(mob_occupant.getBruteLoss(), 1)
|
||||
data["occupant"]["oxyLoss"] = round(mob_occupant.getOxyLoss(), 1)
|
||||
data["occupant"]["toxLoss"] = round(mob_occupant.getToxLoss(), 1)
|
||||
data["occupant"]["fireLoss"] = round(mob_occupant.getFireLoss(), 1)
|
||||
data["occupant"]["bodyTemperature"] = round(mob_occupant.bodytemperature, 1)
|
||||
if(mob_occupant.bodytemperature < 225)
|
||||
data["occupant"]["temperaturestatus"] = "good"
|
||||
else if(mob_occupant.bodytemperature < 273.15)
|
||||
data["occupant"]["temperaturestatus"] = "average"
|
||||
else
|
||||
data["occupant"]["temperaturestatus"] = "bad"
|
||||
|
||||
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
data["cellTemperature"] = round(air1.temperature)
|
||||
data["cellTemperature"] = round(air1.temperature, 1)
|
||||
|
||||
data["isBeakerLoaded"] = beaker ? 1 : 0
|
||||
data["isBeakerLoaded"] = beaker ? TRUE : FALSE
|
||||
var beakerContents = list()
|
||||
if(beaker && beaker.reagents && beaker.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
||||
|
||||
@@ -120,6 +120,7 @@
|
||||
return 1
|
||||
|
||||
/obj/machinery/meter/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
new /obj/item/pipe_meter(loc)
|
||||
qdel(src)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
during December to Feburary, so we should try to be frugal with the next shipment.<br><br><b>November 20th</b><br>Final shipment from central for the next few months. Going outside
|
||||
for more than 10-15 minutes without losing feeling in your fingers is difficult. We've finally gotten a signal on the radio, it's mostly some weird static though. One of the researchers is trying to decypher it.
|
||||
<br><br><b>December 10th</b><br>Signal has gotten much stronger, it almost seems like it's coming from under us according to what the researcher managed to decypher. We're waiting from the go from central before investigating.<br><br>
|
||||
<i>The rest of the paper seems to be a mixture of scribbles and smudged ink.</i> "}
|
||||
<i>The rest of the paper seems to be a mixture of scribbles and smudged ink.</i>"}
|
||||
|
||||
/obj/item/paper/fluff/awaymissions/snowdin/log2
|
||||
name = "Activity Log"
|
||||
@@ -41,7 +41,7 @@
|
||||
<b>September 20th</b><br>Another shipment arrival, standard shit. Our radios have been picking up a weird signal during the nights recently, we've sent the transcripts over to the northern
|
||||
base to be decyphered. Probably some drunk russians or something equally stupid.<br><br><b>November 24th</b><br>We've lost communications with the northern base after recieving the last
|
||||
shipment of supplies. The snow has really kicked up recently, shits almost like a constant blizzard right now. Maybe it'll drop down soon so we can get a word in.<br><br>
|
||||
<i>The rest of the paper seems to be a mixture of scribbles and smudged ink.</i> "}
|
||||
<i>The rest of the paper seems to be a mixture of scribbles and smudged ink.</i>"}
|
||||
|
||||
/obj/item/paper/fluff/awaymissions/snowdin/secnotice
|
||||
name = "Security Notice"
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
B.deity_name = "Narsie"
|
||||
B.icon_state = "melted"
|
||||
B.item_state = "melted"
|
||||
B.lefthand_file = 'icons/mob/inhands/misc/books_lefthand.dmi'
|
||||
B.righthand_file = 'icons/mob/inhands/misc/books_righthand.dmi'
|
||||
new /obj/item/paper/fluff/awaymissions/stationcollision/safehint_paper_bible(B)
|
||||
new /obj/item/pen(B)
|
||||
qdel(src)
|
||||
|
||||
@@ -811,7 +811,7 @@
|
||||
/obj/item/reagent_containers/glass/bottle/magnitis,
|
||||
/obj/item/reagent_containers/glass/bottle/pierrot_throat,
|
||||
/obj/item/reagent_containers/glass/bottle/brainrot,
|
||||
/obj/item/reagent_containers/glass/bottle/hullucigen_virion,
|
||||
/obj/item/reagent_containers/glass/bottle/hallucigen_virion,
|
||||
/obj/item/reagent_containers/glass/bottle/anxiety,
|
||||
/obj/item/reagent_containers/glass/bottle/beesease,
|
||||
/obj/item/storage/box/syringes,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* // Can't be bothered to maintain this, mostly just memes anyway.
|
||||
/datum/supply_pack/misc/vidyacon
|
||||
name = "Vidya-Con Surplus Crate"
|
||||
cost = 3250
|
||||
@@ -30,4 +31,4 @@ datum/supply_pack/misc/reenactor
|
||||
/obj/item/clothing/under/officeruniform,/obj/item/clothing/head/naziofficer,/obj/item/clothing/suit/officercoat,
|
||||
/obj/item/clothing/head/panzer,
|
||||
/obj/item/clothing/suit/russofurcoat,/obj/item/clothing/head/russofurhat,/obj/item/clothing/under/soviet)
|
||||
crate_name = "historical reanactor crate"
|
||||
crate_name = "historical reanactor crate" */
|
||||
|
||||
@@ -361,35 +361,34 @@ GLOBAL_LIST(external_rsc_urls)
|
||||
holder.owner = null
|
||||
GLOB.admins -= src
|
||||
if (!GLOB.admins.len && SSticker.IsRoundInProgress()) //Only report this stuff if we are currently playing.
|
||||
if(!GLOB.admins.len) //Apparently the admin logging out is no longer an admin at this point, so we have to check this towards 0 and not towards 1. Awell.
|
||||
var/cheesy_message = pick(
|
||||
"I have no admins online!",\
|
||||
"I'm all alone... :(",\
|
||||
"I'm feeling lonely. :(",\
|
||||
"I'm so lonely. :(",\
|
||||
"Why does nobody love me? :(",\
|
||||
"I want a man. :(",\
|
||||
"Where has everyone gone?",\
|
||||
"I need a hug. :(",\
|
||||
"Someone come hold me. :(",\
|
||||
"I need someone on me :(",\
|
||||
"What happened? Where has everyone gone?",\
|
||||
"My nipples are so stiff, but Zelda ain't here. :(",\
|
||||
"Leon senpai, play more Spessmans. :(",\
|
||||
"If only Serdy were here...",\
|
||||
"Panic bunker can't keep my love for you out.",\
|
||||
"Cebu needs to Awoo herself back into my heart.",\
|
||||
"I don't even have a Turry to snuggle viciously here.",\
|
||||
"MOM, WHERE ARE YOU??? D:",\
|
||||
"It's a beautiful day outside. Birds are singing, flowers are blooming. On days like this...kids like you...SHOULD BE BURNING IN HELL.",\
|
||||
"Sometimes when I have sex, I think about putting an entire peanut butter and jelly sandwich in the VCR.",\
|
||||
"Oh good, no-one around to watch me lick Goofball's nipples. :D",\
|
||||
"I've replaced Beepsky with a fidget spinner, glory be autism abuse.",\
|
||||
"i shure hop dere are no PRED arund!!!!",\
|
||||
"NO PRED CAN eVER CATCH MI"\
|
||||
)
|
||||
var/cheesy_message = pick(
|
||||
"I have no admins online!",\
|
||||
"I'm all alone... :(",\
|
||||
"I'm feeling lonely. :(",\
|
||||
"I'm so lonely. :(",\
|
||||
"Why does nobody love me? :(",\
|
||||
"I want a man. :(",\
|
||||
"Where has everyone gone?",\
|
||||
"I need a hug. :(",\
|
||||
"Someone come hold me. :(",\
|
||||
"I need someone on me :(",\
|
||||
"What happened? Where has everyone gone?",\
|
||||
"My nipples are so stiff, but Zelda ain't here. :(",\
|
||||
"Leon senpai, play more Spessmans. :(",\
|
||||
"If only Serdy were here...",\
|
||||
"Panic bunker can't keep my love for you out.",\
|
||||
"Cebu needs to Awoo herself back into my heart.",\
|
||||
"I don't even have a Turry to snuggle viciously here.",\
|
||||
"MOM, WHERE ARE YOU??? D:",\
|
||||
"It's a beautiful day outside. Birds are singing, flowers are blooming. On days like this...kids like you...SHOULD BE BURNING IN HELL.",\
|
||||
"Sometimes when I have sex, I think about putting an entire peanut butter and jelly sandwich in the VCR.",\
|
||||
"Oh good, no-one around to watch me lick Goofball's nipples. :D",\
|
||||
"I've replaced Beepsky with a fidget spinner, glory be autism abuse.",\
|
||||
"i shure hop dere are no PRED arund!!!!",\
|
||||
"NO PRED CAN eVER CATCH MI"\
|
||||
)
|
||||
|
||||
send2irc("Server", "[cheesy_message] (No admins online)")
|
||||
send2irc("Server", "[cheesy_message] (No admins online)")
|
||||
|
||||
GLOB.ahelp_tickets.ClientLogout(src)
|
||||
GLOB.directory -= ckey
|
||||
@@ -447,7 +446,7 @@ GLOBAL_LIST(external_rsc_urls)
|
||||
|
||||
new_player = 1
|
||||
account_join_date = sanitizeSQL(findJoinDate())
|
||||
var/datum/DBQuery/query_add_player = SSdbcore.NewQuery("INSERT INTO [format_table_name("player")] (`ckey`, `firstseen`, `lastseen`, `ip`, `computerid`, `lastadminrank`, `accountjoindate`) VALUES ('[sql_ckey]', Now(), Now(), INET_ATON('[sql_ip]'), '[sql_computerid]', '[sql_admin_rank]', [account_join_date ? "'[account_join_date]'" : "NULL"])")
|
||||
var/datum/DBQuery/query_add_player = SSdbcore.NewQuery("INSERT INTO [format_table_name("player")] (`ckey`, `firstseen`, `firstseen_round_id`, `lastseen`, `lastseen_round_id`, `ip`, `computerid`, `lastadminrank`, `accountjoindate`) VALUES ('[sql_ckey]', Now(), '[GLOB.round_id]', Now(), '[GLOB.round_id]', INET_ATON('[sql_ip]'), '[sql_computerid]', '[sql_admin_rank]', [account_join_date ? "'[account_join_date]'" : "NULL"])")
|
||||
if(!query_add_player.Execute())
|
||||
return
|
||||
if(!account_join_date)
|
||||
@@ -473,12 +472,12 @@ GLOBAL_LIST(external_rsc_urls)
|
||||
if(query_datediff.NextRow())
|
||||
account_age = text2num(query_datediff.item[1])
|
||||
if(!new_player)
|
||||
var/datum/DBQuery/query_log_player = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET lastseen = Now(), ip = INET_ATON('[sql_ip]'), computerid = '[sql_computerid]', lastadminrank = '[sql_admin_rank]', accountjoindate = [account_join_date ? "'[account_join_date]'" : "NULL"] WHERE ckey = '[sql_ckey]'")
|
||||
var/datum/DBQuery/query_log_player = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET lastseen = Now(), lastseen_round_id = '[GLOB.round_id]', ip = INET_ATON('[sql_ip]'), computerid = '[sql_computerid]', lastadminrank = '[sql_admin_rank]', accountjoindate = [account_join_date ? "'[account_join_date]'" : "NULL"] WHERE ckey = '[sql_ckey]'")
|
||||
if(!query_log_player.Execute())
|
||||
return
|
||||
if(!account_join_date)
|
||||
account_join_date = "Error"
|
||||
var/datum/DBQuery/query_log_connection = SSdbcore.NewQuery("INSERT INTO `[format_table_name("connection_log")]` (`id`,`datetime`,`server_ip`,`server_port`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')),'[world.port]','[sql_ckey]',INET_ATON('[sql_ip]'),'[sql_computerid]')")
|
||||
var/datum/DBQuery/query_log_connection = SSdbcore.NewQuery("INSERT INTO `[format_table_name("connection_log")]` (`id`,`datetime`,`server_ip`,`server_port`,`round_id`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')),'[world.port]','[GLOB.round_id]','[sql_ckey]',INET_ATON('[sql_ip]'),'[sql_computerid]')")
|
||||
query_log_connection.Execute()
|
||||
if(new_player)
|
||||
player_age = -1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
14
code/modules/client/preferences.dm.rej
Normal file
14
code/modules/client/preferences.dm.rej
Normal file
@@ -0,0 +1,14 @@
|
||||
diff a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm (rejected hunks)
|
||||
@@ -130,12 +130,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
menuoptions = list()
|
||||
return
|
||||
|
||||
-/datum/preferences/vv_edit_var(var_name, var_value)
|
||||
- var/static/list/banned_edits = list("exp")
|
||||
- if(var_name in banned_edits)
|
||||
- return FALSE
|
||||
- return ..()
|
||||
-
|
||||
/datum/preferences/proc/ShowChoices(mob/user)
|
||||
if(!user || !user.client)
|
||||
return
|
||||
@@ -144,6 +144,9 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, togglemidis)()
|
||||
else
|
||||
to_chat(usr, "You will no longer hear sounds uploaded by admins")
|
||||
usr.stop_sound_channel(CHANNEL_ADMIN)
|
||||
var/client/C = usr.client
|
||||
if(C && C.chatOutput && !C.chatOutput.broken && C.chatOutput.loaded)
|
||||
C.chatOutput.sendMusic(" ")
|
||||
SSblackbox.add_details("preferences_verb","Toggle Hearing Midis|[usr.client.prefs.toggles & SOUND_MIDI]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/datum/verbs/menu/Settings/Sound/togglemidis/Get_checked(client/C)
|
||||
return C.prefs.toggles & SOUND_MIDI
|
||||
@@ -230,6 +233,9 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggleprayersounds)()
|
||||
set category = "Preferences"
|
||||
set desc = "Stop Current Sounds"
|
||||
SEND_SOUND(usr, sound(null))
|
||||
var/client/C = usr.client
|
||||
if(C && C.chatOutput && !C.chatOutput.broken && C.chatOutput.loaded)
|
||||
C.chatOutput.sendMusic(" ")
|
||||
SSblackbox.add_details("preferences_verb","Stop Self Sounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
var/flash_protect = 0 //What level of bright light protection item has. 1 = Flashers, Flashes, & Flashbangs | 2 = Welding | -1 = OH GOD WELDING BURNT OUT MY RETINAS
|
||||
var/tint = 0 //Sets the item's level of visual impairment tint, normally set to the same as flash_protect
|
||||
var/up = 0 //but separated to allow items to protect but not impair vision, like space helmets
|
||||
var/visor_flags = 0 //flags_1 that are added/removed when an item is adjusted up/down
|
||||
var/visor_flags = 0 //flags that are added/removed when an item is adjusted up/down
|
||||
var/visor_flags_inv = 0 //same as visor_flags, but for flags_inv
|
||||
var/visor_flags_cover = 0 //same as above, but for flags_cover
|
||||
//what to toggle when toggled with weldingvisortoggle()
|
||||
@@ -193,7 +193,6 @@
|
||||
var/invis_view = SEE_INVISIBLE_LIVING
|
||||
var/invis_override = 0 //Override to allow glasses to set higher than normal see_invis
|
||||
var/lighting_alpha
|
||||
var/emagged = FALSE
|
||||
var/list/icon/current = list() //the current hud icons
|
||||
var/vision_correction = 0 //does wearing these glasses correct some of our vision defects?
|
||||
strip_delay = 20
|
||||
@@ -475,6 +474,8 @@ BLIND // can't see anything
|
||||
permeability_coefficient = 0.01
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50, fire = 80, acid = 70)
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
|
||||
dynamic_hair_suffix = ""
|
||||
dynamic_fhair_suffix = ""
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
|
||||
heat_protection = HEAD
|
||||
@@ -783,7 +784,7 @@ BLIND // can't see anything
|
||||
A.UpdateButtonIcon()
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/proc/visor_toggling() //handles all the actual toggling of flags_1
|
||||
/obj/item/clothing/proc/visor_toggling() //handles all the actual toggling of flags
|
||||
up = !up
|
||||
flags_1 ^= visor_flags
|
||||
flags_inv ^= visor_flags_inv
|
||||
|
||||
@@ -125,17 +125,18 @@
|
||||
desc = "A pair of kitty ears. Meow!"
|
||||
icon_state = "kitty"
|
||||
color = "#999999"
|
||||
dynamic_hair_suffix = ""
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/kitty
|
||||
|
||||
/obj/item/clothing/head/kitty/equipped(mob/user, slot)
|
||||
if(user && slot == slot_head)
|
||||
/obj/item/clothing/head/kitty/equipped(mob/living/carbon/human/user, slot)
|
||||
if(ishuman(user) && slot == slot_head)
|
||||
update_icon(user)
|
||||
user.update_inv_head() //Color might have been changed by update_icon.
|
||||
..()
|
||||
|
||||
/obj/item/clothing/head/kitty/update_icon(mob/living/carbon/human/user)
|
||||
if(istype(user))
|
||||
if(ishuman(user))
|
||||
add_atom_colour("#[user.hair_color]", FIXED_COLOUR_PRIORITY)
|
||||
|
||||
/obj/item/clothing/head/kitty/genuine
|
||||
@@ -151,7 +152,7 @@
|
||||
flags_inv = 0
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
|
||||
brightness_on = 1 //luminosity when on
|
||||
dynamic_hair_suffix = ""
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/reindeer
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ Contains:
|
||||
name = "officer's beret"
|
||||
desc = "An armored beret commonly used by special operations officers. Uses advanced force field technology to protect the head from space."
|
||||
icon_state = "beret_badge"
|
||||
dynamic_hair_suffix = "+generic"
|
||||
dynamic_fhair_suffix = "+generic"
|
||||
flags_1 = STOPSPRESSUREDMAGE_1
|
||||
flags_inv = 0
|
||||
armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100)
|
||||
|
||||
@@ -280,6 +280,7 @@
|
||||
body_parts_covered = HEAD
|
||||
flags_1 = THICKMATERIAL_1
|
||||
flags_inv = HIDEHAIR|HIDEEARS
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
/obj/item/clothing/suit/hooded/bloated_human //OH MY GOD WHAT HAVE YOU DONE!?!?!?
|
||||
name = "bloated human suit"
|
||||
|
||||
@@ -555,7 +555,10 @@
|
||||
name = "Pressure Plate"
|
||||
result = /obj/item/device/pressure_plate
|
||||
time = 5
|
||||
reqs = list(/obj/item/stack/sheet/plasteel = 1, /obj/item/stack/tile/plasteel = 1, /obj/item/stack/cable_coil = 2)
|
||||
reqs = list(/obj/item/stack/sheet/metal = 1,
|
||||
/obj/item/stack/tile/plasteel = 1,
|
||||
/obj/item/stack/cable_coil = 2,
|
||||
/obj/item/device/assembly/igniter = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
//AI laws
|
||||
for(var/mob/living/silicon/ai/M in GLOB.living_mob_list)
|
||||
M.laws_sanity_check()
|
||||
if(M.stat != 2 && M.see_in_dark != 0)
|
||||
if(M.stat != DEAD && M.see_in_dark != 0)
|
||||
if(prob(replaceLawsetChance))
|
||||
M.laws.pick_weighted_lawset()
|
||||
|
||||
|
||||
@@ -16,4 +16,5 @@
|
||||
//sound not longer matches the text, but an audible warning is probably good
|
||||
|
||||
/datum/round_event/radiation_storm/start()
|
||||
SSweather.run_weather("radiation storm",ZLEVEL_STATION)
|
||||
SSweather.run_weather("radiation storm",ZLEVEL_STATION)
|
||||
make_maint_all_access()
|
||||
|
||||
@@ -759,7 +759,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list(
|
||||
people += H
|
||||
if(person) //Basic talk
|
||||
var/image/speech_overlay = image('icons/mob/talk.dmi', person, "default0", layer = ABOVE_MOB_LAYER)
|
||||
var/message = target.compose_message(person,understood_language,pick(speak_messages),null,person.get_spans())
|
||||
var/message = target.compose_message(person,understood_language,pick(speak_messages),null,person.get_spans(),face_name = TRUE)
|
||||
feedback_details += "Type: Talk, Source: [person.real_name], Message: [message]"
|
||||
to_chat(target, message)
|
||||
if(target.client)
|
||||
@@ -771,7 +771,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list(
|
||||
for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
|
||||
humans += H
|
||||
person = pick(humans)
|
||||
var/message = target.compose_message(person,understood_language,pick(radio_messages),"1459",person.get_spans())
|
||||
var/message = target.compose_message(person,understood_language,pick(radio_messages),"1459",person.get_spans(),face_name = TRUE)
|
||||
feedback_details += "Type: Radio, Source: [person.real_name], Message: [message]"
|
||||
to_chat(target, message)
|
||||
qdel(src)
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
/obj/machinery/gibber/container_resist(mob/living/user)
|
||||
go_out()
|
||||
|
||||
/obj/machinery/gibber/relaymove(mob/living/user)
|
||||
go_out()
|
||||
|
||||
/obj/machinery/gibber/attack_hand(mob/user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
@@ -225,4 +228,4 @@
|
||||
|
||||
if(M.loc == input_plate)
|
||||
M.forceMove(src)
|
||||
M.gib()
|
||||
M.gib()
|
||||
|
||||
@@ -142,69 +142,55 @@
|
||||
user.set_machine(src)
|
||||
interact(user)
|
||||
|
||||
/*******************
|
||||
* SmartFridge Menu
|
||||
********************/
|
||||
|
||||
/obj/machinery/smartfridge/interact(mob/user)
|
||||
if(stat)
|
||||
return FALSE
|
||||
|
||||
var/dat = "<TT><b>Select an item:</b><br>"
|
||||
/obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "smartvend", name, 440, 550, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
if (contents.len == 0)
|
||||
dat += "<font color = 'red'>No product loaded!</font>"
|
||||
else
|
||||
var/listofitems = list()
|
||||
for (var/atom/movable/O in contents)
|
||||
if (listofitems[O.name])
|
||||
listofitems[O.name]++
|
||||
else
|
||||
listofitems[O.name] = 1
|
||||
sortList(listofitems)
|
||||
/obj/machinery/smartfridge/ui_data(mob/user)
|
||||
. = list()
|
||||
|
||||
for (var/O in listofitems)
|
||||
if(listofitems[O] <= 0)
|
||||
continue
|
||||
var/N = listofitems[O]
|
||||
var/itemName = url_encode(O)
|
||||
dat += "<FONT color = 'blue'><B>[capitalize(O)]</B>:"
|
||||
dat += " [N] </font>"
|
||||
dat += "<a href='byond://?src=\ref[src];vend=[itemName];amount=1'>Vend</A> "
|
||||
if(N > 5)
|
||||
dat += "(<a href='byond://?src=\ref[src];vend=[itemName];amount=5'>x5</A>)"
|
||||
if(N > 10)
|
||||
dat += "(<a href='byond://?src=\ref[src];vend=[itemName];amount=10'>x10</A>)"
|
||||
if(N > 25)
|
||||
dat += "(<a href='byond://?src=\ref[src];vend=[itemName];amount=25'>x25</A>)"
|
||||
if(N > 1)
|
||||
dat += "(<a href='?src=\ref[src];vend=[itemName];amount=[N]'>All</A>)"
|
||||
var/listofitems = list()
|
||||
for (var/I in src)
|
||||
var/atom/movable/O = I
|
||||
if (listofitems[O.name])
|
||||
listofitems[O.name]["amount"]++
|
||||
else
|
||||
listofitems[O.name] = list("name" = O.name, "type" = O.type, "amount" = 1)
|
||||
sortList(listofitems)
|
||||
|
||||
dat += "<br>"
|
||||
.["contents"] = listofitems
|
||||
.["name"] = name
|
||||
.["isdryer"] = FALSE
|
||||
|
||||
dat += "</TT>"
|
||||
user << browse("<HEAD><TITLE>[src] supplies</TITLE></HEAD><TT>[dat]</TT>", "window=smartfridge")
|
||||
onclose(user, "smartfridge")
|
||||
return dat
|
||||
|
||||
/obj/machinery/smartfridge/Topic(var/href, var/list/href_list)
|
||||
if(..())
|
||||
/obj/machinery/smartfridge/ui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
usr.set_machine(src)
|
||||
switch(action)
|
||||
if("Release")
|
||||
var/desired = 0
|
||||
|
||||
var/N = href_list["vend"]
|
||||
var/amount = text2num(href_list["amount"])
|
||||
if (params["amount"])
|
||||
desired = text2num(params["amount"])
|
||||
else
|
||||
desired = input("How many items?", "How many items would you like to take out?", 1) as null|num
|
||||
|
||||
var/i = amount
|
||||
for(var/obj/O in contents)
|
||||
if(i <= 0)
|
||||
break
|
||||
if(O.name == N)
|
||||
O.loc = src.loc
|
||||
i--
|
||||
if(QDELETED(src) || QDELETED(usr) || !usr.Adjacent(src)) // Sanity checkin' in case stupid stuff happens while we wait for input()
|
||||
return FALSE
|
||||
|
||||
|
||||
updateUsrDialog()
|
||||
for(var/obj/item/O in src)
|
||||
if(desired <= 0)
|
||||
break
|
||||
if(O.name == params["name"])
|
||||
O.forceMove(drop_location())
|
||||
desired--
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
// ----------------------------
|
||||
@@ -240,20 +226,35 @@
|
||||
/obj/machinery/smartfridge/drying_rack/default_deconstruction_crowbar(obj/item/crowbar/C, ignore_panel = 1)
|
||||
..()
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/interact(mob/user)
|
||||
var/dat = ..()
|
||||
if(dat)
|
||||
dat += "<br>"
|
||||
dat += "<a href='byond://?src=\ref[src];dry=1'>Toggle Drying</A> "
|
||||
user << browse("<HEAD><TITLE>[src] supplies</TITLE></HEAD><TT>[dat]</TT>", "window=smartfridge")
|
||||
onclose(user, "smartfridge")
|
||||
/obj/machinery/smartfridge/drying_rack/ui_data(mob/user)
|
||||
. = list()
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/Topic(href, list/href_list)
|
||||
..()
|
||||
if(href_list["dry"])
|
||||
toggle_drying(FALSE)
|
||||
updateUsrDialog()
|
||||
update_icon()
|
||||
var/listofitems = list()
|
||||
for (var/I in src)
|
||||
var/atom/movable/O = I
|
||||
|
||||
if (listofitems[O.name])
|
||||
listofitems[O.name]["amount"]++
|
||||
else
|
||||
listofitems[O.name] = list("name" = O.name, "type" = O.type, "amount" = 1)
|
||||
sortList(listofitems)
|
||||
|
||||
.["contents"] = listofitems
|
||||
.["name"] = name
|
||||
.["isdryer"] = TRUE
|
||||
.["verb"] = "Take"
|
||||
.["drying"] = drying
|
||||
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/ui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
switch(action)
|
||||
if("Dry")
|
||||
toggle_drying(FALSE)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/power_change()
|
||||
if(powered() && anchored)
|
||||
|
||||
@@ -13,6 +13,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
var/cookieSent = FALSE // Has the client sent a cookie for analysis
|
||||
var/broken = FALSE
|
||||
var/list/connectionHistory //Contains the connection history passed from chat cookie
|
||||
var/adminMusicVolume = 100 //This is for the Play Global Sound verb
|
||||
|
||||
/datum/chatOutput/New(client/C)
|
||||
owner = C
|
||||
@@ -79,6 +80,9 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
if("analyzeClientData")
|
||||
data = analyzeClientData(arglist(params))
|
||||
|
||||
if("setMusicVolume")
|
||||
data = setMusicVolume(arglist(params))
|
||||
|
||||
if(data)
|
||||
ehjax_send(data = data)
|
||||
|
||||
@@ -120,6 +124,16 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
data = json_encode(data)
|
||||
C << output("[data]", "[window]:ehjaxCallback")
|
||||
|
||||
/datum/chatOutput/proc/sendMusic(music, pitch)
|
||||
var/list/music_data = list("adminMusic" = url_encode(url_encode(music)))
|
||||
if(pitch)
|
||||
music_data["musicRate"] = pitch
|
||||
ehjax_send(data = music_data)
|
||||
|
||||
/datum/chatOutput/proc/setMusicVolume(volume = "")
|
||||
if(volume)
|
||||
adminMusicVolume = Clamp(text2num(volume), 0, 100)
|
||||
|
||||
//Sends client connection details to the chat to handle and save
|
||||
/datum/chatOutput/proc/sendClientData()
|
||||
//Get dem deets
|
||||
|
||||
@@ -101,7 +101,7 @@ a.popt {text-decoration: none;}
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
#options a {
|
||||
#options .optionsCell {
|
||||
background: #ddd;
|
||||
height: 30px;
|
||||
padding: 5px 0;
|
||||
@@ -111,7 +111,7 @@ a.popt {text-decoration: none;}
|
||||
line-height: 28px;
|
||||
border-top: 1px solid #b4b4b4;
|
||||
}
|
||||
#options a:hover {background: #ccc;}
|
||||
#options .optionsCell:hover {background: #ccc;}
|
||||
#options .toggle {
|
||||
width: 40px;
|
||||
background: #ccc;
|
||||
@@ -121,7 +121,7 @@ a.popt {text-decoration: none;}
|
||||
}
|
||||
#options .sub {clear: both; display: none; width: 160px;}
|
||||
#options .sub.scroll {overflow-y: scroll;}
|
||||
#options .sub a {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;}
|
||||
#options .sub.optionsCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;}
|
||||
#options .sub span {
|
||||
display: block;
|
||||
line-height: 30px;
|
||||
@@ -136,6 +136,13 @@ a.popt {text-decoration: none;}
|
||||
line-height: 30px;
|
||||
float: right;
|
||||
}
|
||||
#options .sub input {
|
||||
position: absolute;
|
||||
padding: 7px 5px;
|
||||
width: 121px;
|
||||
line-height: 30px;
|
||||
float: left;
|
||||
}
|
||||
#options .decreaseFont {border-top: 0;}
|
||||
|
||||
/* POPUPS */
|
||||
|
||||
@@ -28,17 +28,19 @@
|
||||
<span class="ms" id="pingMs">--ms</span>
|
||||
</div>
|
||||
<div id="options">
|
||||
<a href="#" class="toggle" id="toggleOptions" title="Options"><i class="icon-cog"></i></a>
|
||||
<a href="#" class="optionsCell toggle" id="toggleOptions" title="Options"><i class="icon-cog"></i></a>
|
||||
<div class="sub" id="subOptions">
|
||||
<a href="#" class="decreaseFont" id="decreaseFont"><span>Decrease font size</span> <i class="icon-font">-</i></a>
|
||||
<a href="#" class="increaseFont" id="increaseFont"><span>Increase font size</span> <i class="icon-font">+</i></a>
|
||||
<a href="#" class="togglePing" id="togglePing"><span>Toggle ping display</span> <i class="icon-circle"></i></a>
|
||||
<a href="#" class="highlightTerm" id="highlightTerm"><span>Highlight string</span> <i class="icon-tag"></i></a>
|
||||
<a href="#" class="saveLog" id="saveLog"><span>Save chat log</span> <i class="icon-save"></i></a>
|
||||
<a href="#" class="clearMessages" id="clearMessages"><span>Clear all messages</span> <i class="icon-eraser"></i></a>
|
||||
<a href="#" class="optionsCell decreaseFont" id="decreaseFont"><span>Decrease font size</span> <i class="icon-font">-</i></a>
|
||||
<a href="#" class="optionsCell increaseFont" id="increaseFont"><span>Increase font size</span> <i class="icon-font">+</i></a>
|
||||
<a href="#" class="optionsCell togglePing" id="togglePing"><span>Toggle ping display</span> <i class="icon-circle"></i></a>
|
||||
<a href="#" class="optionsCell highlightTerm" id="highlightTerm"><span>Highlight string</span> <i class="icon-tag"></i></a>
|
||||
<a href="#" class="optionsCell saveLog" id="saveLog"><span>Save chat log</span> <i class="icon-save"></i></a>
|
||||
<a href="#" class="optionsCell clearMessages" id="clearMessages"><span>Clear all messages</span> <i class="icon-eraser"></i></a>
|
||||
<span class="optionsCell" id="musicVolumeSpan"><input type="range" class="hidden" id="musicVolume"><span id="musicVolumeText">Admin music volume</span><i class="icon-music"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<audio class="hidden" id="adminMusic" autoplay></audio>
|
||||
<script type="text/javascript" src="browserOutput.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -61,8 +61,17 @@ var opts = {
|
||||
'clientDataLimit': 5,
|
||||
'clientData': [],
|
||||
|
||||
//Admin music volume update
|
||||
'volumeUpdateDelay': 5000, //Time from when the volume updates to data being sent to the server
|
||||
'volumeUpdating': false, //True if volume update function set to fire
|
||||
'updatedVolume': 0, //The volume level that is sent to the server
|
||||
|
||||
};
|
||||
|
||||
function clamp(val, min, max) {
|
||||
return Math.max(min, Math.min(val, max))
|
||||
}
|
||||
|
||||
function outerHTML(el) {
|
||||
var wrap = document.createElement('div');
|
||||
wrap.appendChild(el.cloneNode(true));
|
||||
@@ -95,6 +104,15 @@ function linkify(text) {
|
||||
});
|
||||
}
|
||||
|
||||
function byondDecode(message) {
|
||||
// Basically we url_encode twice server side so we can manually read the encoded version and actually do UTF-8.
|
||||
// The replace for + is because FOR SOME REASON, BYOND replaces spaces with a + instead of %20, and a plus with %2b.
|
||||
// Marvelous.
|
||||
message = message.replace(/\+/g, "%20");
|
||||
message = decoder(message);
|
||||
return message;
|
||||
}
|
||||
|
||||
//Actually turns the highlight term match into appropriate html
|
||||
function addHighlightMarkup(match) {
|
||||
var extra = '';
|
||||
@@ -176,11 +194,7 @@ function output(message, flag) {
|
||||
if (flag !== 'internal')
|
||||
opts.lastPang = Date.now();
|
||||
|
||||
// Basically we url_encode twice server side so we can manually read the encoded version and actually do UTF-8.
|
||||
// The replace for + is because FOR SOME REASON, BYOND replaces spaces with a + instead of %20, and a plus with %2b.
|
||||
// Marvelous.
|
||||
message = message.replace(/\+/g, "%20")
|
||||
message = decoder(message)
|
||||
message = byondDecode(message)
|
||||
|
||||
//The behemoth of filter-code (for Admin message filters)
|
||||
//Note: This is proooobably hella inefficient
|
||||
@@ -423,7 +437,22 @@ function ehjaxCallback(data) {
|
||||
var firebugEl = document.createElement('script');
|
||||
firebugEl.src = 'https://getfirebug.com/firebug-lite-debug.js';
|
||||
document.body.appendChild(firebugEl);
|
||||
}
|
||||
} else if (data.adminMusic) {
|
||||
if (typeof data.adminMusic === 'string') {
|
||||
var adminMusic = byondDecode(data.adminMusic);
|
||||
adminMusic = adminMusic.match(/https?:\/\/\S+/) || '';
|
||||
if (data.musicRate) {
|
||||
var newRate = Number(data.musicRate);
|
||||
if(newRate) {
|
||||
$('#adminMusic').prop('defaultPlaybackRate', newRate);
|
||||
}
|
||||
} else {
|
||||
$('#adminMusic').prop('defaultPlaybackRate', 1.0);
|
||||
}
|
||||
$('#adminMusic').prop('src', adminMusic);
|
||||
$('#adminMusic').trigger("play");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,6 +475,13 @@ function toggleWasd(state) {
|
||||
opts.wasd = (state == 'on' ? true : false);
|
||||
}
|
||||
|
||||
function sendVolumeUpdate() {
|
||||
opts.volumeUpdating = false;
|
||||
if(opts.updatedVolume) {
|
||||
runByond('?_src_=chat&proc=setMusicVolume¶m[volume]='+opts.updatedVolume);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* DOM READY
|
||||
@@ -486,6 +522,7 @@ $(function() {
|
||||
'spingDisabled': getCookie('pingdisabled'),
|
||||
'shighlightTerms': getCookie('highlightterms'),
|
||||
'shighlightColor': getCookie('highlightcolor'),
|
||||
'smusicVolume': getCookie('musicVolume'),
|
||||
};
|
||||
|
||||
if (savedConfig.sfontSize) {
|
||||
@@ -517,6 +554,14 @@ $(function() {
|
||||
opts.highlightColor = savedConfig.shighlightColor;
|
||||
internalOutput('<span class="internal boldnshit">Loaded highlight color of: '+savedConfig.shighlightColor+'</span>', 'internal');
|
||||
}
|
||||
if (savedConfig.smusicVolume) {
|
||||
var newVolume = clamp(savedConfig.smusicVolume, 0, 100);
|
||||
$('#adminMusic').prop('volume', newVolume / 100);
|
||||
$('#musicVolume').val(newVolume);
|
||||
opts.updatedVolume = newVolume;
|
||||
sendVolumeUpdate();
|
||||
internalOutput('<span class="internal boldnshit">Loaded music volume of: '+savedConfig.smusicVolume+'</span>', 'internal');
|
||||
}
|
||||
|
||||
(function() {
|
||||
var dataCookie = getCookie('connData');
|
||||
@@ -835,6 +880,26 @@ $(function() {
|
||||
opts.messageCount = 0;
|
||||
});
|
||||
|
||||
$('#musicVolumeSpan').hover(function() {
|
||||
$('#musicVolumeText').addClass('hidden');
|
||||
$('#musicVolume').removeClass('hidden');
|
||||
}, function() {
|
||||
$('#musicVolume').addClass('hidden');
|
||||
$('#musicVolumeText').removeClass('hidden');
|
||||
});
|
||||
|
||||
$('#musicVolume').change(function() {
|
||||
var newVolume = $('#musicVolume').val();
|
||||
newVolume = clamp(newVolume, 0, 100);
|
||||
$('#adminMusic').prop('volume', newVolume / 100);
|
||||
setCookie('musicVolume', newVolume, 365);
|
||||
opts.updatedVolume = newVolume;
|
||||
if(!opts.volumeUpdating) {
|
||||
setTimeout(sendVolumeUpdate, opts.volumeUpdateDelay);
|
||||
opts.volumeUpdating = true;
|
||||
}
|
||||
});
|
||||
|
||||
$('img.icon').error(iconError);
|
||||
|
||||
|
||||
|
||||
@@ -120,17 +120,15 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/structure/holohoop/CanPass(atom/movable/mover, turf/target)
|
||||
if (isitem(mover) && mover.throwing)
|
||||
var/obj/item/I = mover
|
||||
if(istype(I, /obj/item/projectile))
|
||||
return
|
||||
/obj/structure/holohoop/hitby(atom/movable/AM)
|
||||
if (isitem(AM) && !istype(AM,/obj/item/projectile))
|
||||
if(prob(50))
|
||||
I.forceMove(get_turf(src))
|
||||
visible_message("<span class='warning'>Swish! [I] lands in [src].</span>")
|
||||
AM.forceMove(get_turf(src))
|
||||
visible_message("<span class='warning'>Swish! [AM] lands in [src].</span>")
|
||||
return
|
||||
else
|
||||
visible_message("<span class='danger'>[I] bounces off of [src]'s rim!</span>")
|
||||
return 0
|
||||
visible_message("<span class='danger'>[AM] bounces off of [src]'s rim!</span>")
|
||||
return ..()
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
/obj/structure/beebox
|
||||
name = "apiary"
|
||||
desc = "Dr Miles Manners is just your average wasp-themed super hero by day, but by night he becomes DR BEES!"
|
||||
desc = "Dr. Miles Manners is just your average wasp-themed super hero by day, but by night he becomes DR. BEES!"
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
icon_state = "beebox"
|
||||
anchored = TRUE
|
||||
@@ -45,9 +45,7 @@
|
||||
/obj/structure/beebox/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
bees.Cut()
|
||||
bees = null
|
||||
honeycombs.Cut()
|
||||
honeycombs = null
|
||||
queen_bee = null
|
||||
return ..()
|
||||
|
||||
@@ -151,7 +149,7 @@
|
||||
honey_frames += HF
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There's no room for any more frames in the apiary!</span>")
|
||||
|
||||
return
|
||||
if(istype(I, /obj/item/wrench))
|
||||
if(default_unfasten_wrench(user, I, time = 20))
|
||||
return
|
||||
@@ -187,6 +185,9 @@
|
||||
to_chat(user, "<span class='warning'>The queen bee disappeared! Disappearing bees have been in the news lately...</span>")
|
||||
|
||||
qdel(qb)
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
|
||||
/obj/structure/beebox/attack_hand(mob/user)
|
||||
@@ -203,8 +204,10 @@
|
||||
bees = TRUE
|
||||
if(bees)
|
||||
visible_message("<span class='danger'>[user] disturbs the bees!</span>")
|
||||
else
|
||||
visible_message("<span class='danger'>[user] disturbs the [name] to no effect!</span>")
|
||||
else
|
||||
var/option = alert(user, "What action do you wish to perform?","Apiary","Remove a Honey Frame","Remove the Queen Bee")
|
||||
var/option = alert(user, "What action do you wish to perform?","Apiary","Remove a Honey Frame","Remove the Queen Bee", "Cancel")
|
||||
if(!Adjacent(user))
|
||||
return
|
||||
switch(option)
|
||||
@@ -244,3 +247,13 @@
|
||||
QB.loc = get_turf(src)
|
||||
visible_message("<span class='notice'>[user] removes the queen from the apiary.</span>")
|
||||
queen_bee = null
|
||||
|
||||
/obj/structure/beebox/deconstruct(disassembled = TRUE)
|
||||
new /obj/item/stack/sheet/mineral/wood (loc, 20)
|
||||
for(var/mob/living/simple_animal/hostile/poison/bees/B in bees)
|
||||
if(B.loc == src)
|
||||
B.loc = get_turf(src)
|
||||
for(var/obj/item/honey_frame/HF in honey_frames)
|
||||
if(HF.loc == src)
|
||||
HF.loc = get_turf(src)
|
||||
qdel(src)
|
||||
@@ -72,7 +72,7 @@
|
||||
break
|
||||
else //If the player has ghosted from his corpse before blood was drawn, his ckey is no longer attached to the mob, so we need to match up the cloned player through the mind key
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(mind && M.mind && ckey(M.mind.key) == ckey(mind.key) && M.ckey && M.client && M.stat == 2 && !M.suiciding)
|
||||
if(mind && M.mind && ckey(M.mind.key) == ckey(mind.key) && M.ckey && M.client && M.stat == DEAD && !M.suiciding)
|
||||
if(isobserver(M))
|
||||
var/mob/dead/observer/O = M
|
||||
if(!O.can_reenter_corpse)
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
name = "weed spray"
|
||||
icon_state = "weedspray"
|
||||
item_state = "spray"
|
||||
item_state = "spraycan"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
volume = 100
|
||||
container_type = OPENCONTAINER_1
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
@@ -248,7 +248,7 @@
|
||||
if(istype(src, /obj/machinery/hydroponics/soil))
|
||||
add_atom_colour(rgb(255, 175, 0), FIXED_COLOUR_PRIORITY)
|
||||
else
|
||||
overlays += mutable_appearance('icons/obj/hydroponics/equipment.dmi', "gaia_blessing")
|
||||
add_overlay(mutable_appearance('icons/obj/hydroponics/equipment.dmi', "gaia_blessing"))
|
||||
set_light(3)
|
||||
|
||||
update_icon_hoses()
|
||||
@@ -915,9 +915,11 @@
|
||||
name = "soil"
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
icon_state = "soil"
|
||||
circuit = null
|
||||
density = FALSE
|
||||
use_power = NO_POWER_USE
|
||||
unwrenchable = 0
|
||||
flags_1 = NODECONSTRUCT_1
|
||||
unwrenchable = FALSE
|
||||
|
||||
/obj/machinery/hydroponics/soil/update_icon_hoses()
|
||||
return // Has no hoses
|
||||
|
||||
279
code/modules/jobs/job_exp.dm
Normal file
279
code/modules/jobs/job_exp.dm
Normal file
@@ -0,0 +1,279 @@
|
||||
GLOBAL_LIST_EMPTY(exp_to_update)
|
||||
GLOBAL_PROTECT(exp_to_update)
|
||||
|
||||
|
||||
// Procs
|
||||
/datum/job/proc/required_playtime_remaining(client/C)
|
||||
if(!C)
|
||||
return 0
|
||||
if(!config.use_exp_tracking)
|
||||
return 0
|
||||
if(!exp_requirements || !exp_type)
|
||||
return 0
|
||||
if(!job_is_xp_locked(src.title))
|
||||
return 0
|
||||
if(config.use_exp_restrictions_admin_bypass && check_rights(R_ADMIN, FALSE, C.mob))
|
||||
return 0
|
||||
var/isexempt = C.prefs.db_flags & DB_FLAG_EXEMPT
|
||||
if(isexempt)
|
||||
return 0
|
||||
var/my_exp = C.calc_exp_type(get_exp_req_type())
|
||||
var/job_requirement = get_exp_req_amount()
|
||||
if(my_exp >= job_requirement)
|
||||
return 0
|
||||
else
|
||||
return (job_requirement - my_exp)
|
||||
|
||||
/datum/job/proc/get_exp_req_amount()
|
||||
if(title in GLOB.command_positions)
|
||||
if(config.use_exp_restrictions_heads_hours)
|
||||
return config.use_exp_restrictions_heads_hours * 60
|
||||
return exp_requirements
|
||||
|
||||
/datum/job/proc/get_exp_req_type()
|
||||
if(title in GLOB.command_positions)
|
||||
if(config.use_exp_restrictions_heads_department && exp_type_department)
|
||||
return exp_type_department
|
||||
return exp_type
|
||||
|
||||
/proc/job_is_xp_locked(jobtitle)
|
||||
if(!config.use_exp_restrictions_heads && jobtitle in GLOB.command_positions)
|
||||
return FALSE
|
||||
if(!config.use_exp_restrictions_other && !(jobtitle in GLOB.command_positions))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/client/proc/calc_exp_type(exptype)
|
||||
var/list/explist = prefs.exp.Copy()
|
||||
var/amount = 0
|
||||
var/list/typelist = GLOB.exp_jobsmap[exptype]
|
||||
if(!typelist)
|
||||
return -1
|
||||
for(var/job in typelist["titles"])
|
||||
if(job in explist)
|
||||
amount += explist[job]
|
||||
return amount
|
||||
|
||||
/client/proc/get_exp_report()
|
||||
if(!config.use_exp_tracking)
|
||||
return "Tracking is disabled in the server configuration file."
|
||||
var/list/play_records = prefs.exp
|
||||
if(!play_records.len)
|
||||
set_exp_from_db()
|
||||
play_records = prefs.exp
|
||||
if(!play_records.len)
|
||||
return "[key] has no records."
|
||||
var/return_text = list()
|
||||
return_text += "<UL>"
|
||||
var/list/exp_data = list()
|
||||
for(var/category in SSjob.name_occupations)
|
||||
if(play_records[category])
|
||||
exp_data[category] = text2num(play_records[category])
|
||||
else
|
||||
exp_data[category] = 0
|
||||
for(var/category in GLOB.exp_specialmap)
|
||||
if(play_records[category])
|
||||
exp_data[category] = text2num(play_records[category])
|
||||
else
|
||||
exp_data[category] = 0
|
||||
if(prefs.db_flags & DB_FLAG_EXEMPT)
|
||||
return_text += "<LI>Exempt (all jobs auto-unlocked)</LI>"
|
||||
|
||||
for(var/dep in exp_data)
|
||||
if(exp_data[dep] > 0)
|
||||
if(exp_data[EXP_TYPE_LIVING] > 0)
|
||||
var/percentage = num2text(round(exp_data[dep]/exp_data[EXP_TYPE_LIVING]*100))
|
||||
return_text += "<LI>[dep] [get_exp_format(exp_data[dep])] ([percentage]%)</LI>"
|
||||
else
|
||||
return_text += "<LI>[dep] [get_exp_format(exp_data[dep])] </LI>"
|
||||
if(config.use_exp_restrictions_admin_bypass && check_rights(R_ADMIN, 0, mob))
|
||||
return_text += "<LI>Admin (all jobs auto-unlocked)</LI>"
|
||||
return_text += "</UL>"
|
||||
var/list/jobs_locked = list()
|
||||
var/list/jobs_unlocked = list()
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
if(job.exp_requirements && job.exp_type)
|
||||
if(!job_is_xp_locked(job.title))
|
||||
continue
|
||||
else if(!job.required_playtime_remaining(mob.client))
|
||||
jobs_unlocked += job.title
|
||||
else
|
||||
var/xp_req = job.get_exp_req_amount()
|
||||
jobs_locked += "[job.title] [get_exp_format(text2num(calc_exp_type(job.get_exp_req_type())))] / [get_exp_format(xp_req)] as [job.get_exp_req_type()])"
|
||||
if(jobs_unlocked.len)
|
||||
return_text += "<BR><BR>Jobs Unlocked:<UL><LI>"
|
||||
return_text += jobs_unlocked.Join("</LI><LI>")
|
||||
return_text += "</LI></UL>"
|
||||
if(jobs_locked.len)
|
||||
return_text += "<BR><BR>Jobs Not Unlocked:<UL><LI>"
|
||||
return_text += jobs_locked.Join("</LI><LI>")
|
||||
return_text += "</LI></UL>"
|
||||
return return_text
|
||||
|
||||
|
||||
/client/proc/get_exp_living()
|
||||
if(!prefs.exp)
|
||||
return "No data"
|
||||
var/exp_living = text2num(prefs.exp[EXP_TYPE_LIVING])
|
||||
return get_exp_format(exp_living)
|
||||
|
||||
/proc/get_exp_format(expnum)
|
||||
if(expnum > 60)
|
||||
return num2text(round(expnum / 60)) + "h"
|
||||
else if(expnum > 0)
|
||||
return num2text(expnum) + "m"
|
||||
else
|
||||
return "0h"
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/update_exp(mins, ann = FALSE)
|
||||
if(!SSdbcore.Connect())
|
||||
return -1
|
||||
for(var/client/L in GLOB.clients)
|
||||
if(L.is_afk())
|
||||
continue
|
||||
addtimer(CALLBACK(L,/client/proc/update_exp_list,mins,ann),10)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/update_exp_db()
|
||||
SSdbcore.MassInsert(format_table_name("role_time"),GLOB.exp_to_update,TRUE)
|
||||
LAZYCLEARLIST(GLOB.exp_to_update)
|
||||
|
||||
//resets a client's exp to what was in the db.
|
||||
/client/proc/set_exp_from_db()
|
||||
if(!config.use_exp_tracking)
|
||||
return -1
|
||||
if(!SSdbcore.Connect())
|
||||
return -1
|
||||
var/datum/DBQuery/exp_read = SSdbcore.NewQuery("SELECT job, minutes FROM [format_table_name("role_time")] WHERE ckey = '[sanitizeSQL(ckey)]'")
|
||||
if(!exp_read.Execute())
|
||||
return -1
|
||||
var/list/play_records = list()
|
||||
while(exp_read.NextRow())
|
||||
play_records[exp_read.item[1]] = text2num(exp_read.item[2])
|
||||
|
||||
for(var/rtype in SSjob.name_occupations)
|
||||
if(!play_records[rtype])
|
||||
play_records[rtype] = 0
|
||||
for(var/rtype in GLOB.exp_specialmap)
|
||||
if(!play_records[rtype])
|
||||
play_records[rtype] = 0
|
||||
|
||||
prefs.exp = play_records
|
||||
|
||||
|
||||
//updates player db flags
|
||||
/client/proc/update_flag_db(newflag, state = FALSE)
|
||||
|
||||
if(!SSdbcore.Connect())
|
||||
return -1
|
||||
|
||||
if(!set_db_player_flags())
|
||||
return -1
|
||||
|
||||
if((prefs.db_flags & newflag) && !state)
|
||||
prefs.db_flags &= ~newflag
|
||||
else
|
||||
prefs.db_flags |= newflag
|
||||
|
||||
var/datum/DBQuery/flag_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET flags = '[prefs.db_flags]' WHERE ckey='[sanitizeSQL(ckey)]'")
|
||||
|
||||
if(!flag_update.Execute())
|
||||
return -1
|
||||
|
||||
|
||||
/client/proc/update_exp_list(minutes, announce_changes = FALSE)
|
||||
if(!config.use_exp_tracking)
|
||||
return -1
|
||||
if(!SSdbcore.Connect())
|
||||
return -1
|
||||
var/datum/DBQuery/exp_read = SSdbcore.NewQuery("SELECT job, minutes FROM [format_table_name("role_time")] WHERE ckey = '[sanitizeSQL(ckey)]'")
|
||||
if(!exp_read.Execute())
|
||||
return -1
|
||||
var/list/play_records = list()
|
||||
while(exp_read.NextRow())
|
||||
play_records[exp_read.item[1]] = text2num(exp_read.item[2])
|
||||
|
||||
for(var/rtype in SSjob.name_occupations)
|
||||
if(!play_records[rtype])
|
||||
play_records[rtype] = 0
|
||||
for(var/rtype in GLOB.exp_specialmap)
|
||||
if(!play_records[rtype])
|
||||
play_records[rtype] = 0
|
||||
var/list/old_records = play_records.Copy()
|
||||
if(isliving(mob))
|
||||
if(mob.stat != DEAD)
|
||||
var/rolefound = FALSE
|
||||
play_records[EXP_TYPE_LIVING] += minutes
|
||||
if(announce_changes)
|
||||
to_chat(src,"<span class='notice'>You got: [minutes] Living EXP!</span>")
|
||||
if(mob.mind.assigned_role)
|
||||
for(var/job in SSjob.name_occupations)
|
||||
if(mob.mind.assigned_role == job)
|
||||
rolefound = TRUE
|
||||
play_records[job] += minutes
|
||||
if(announce_changes)
|
||||
to_chat(src,"<span class='notice'>You got: [minutes] [job] EXP!</span>")
|
||||
if(!rolefound)
|
||||
for(var/role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL])
|
||||
if(mob.mind.assigned_role == role)
|
||||
rolefound = TRUE
|
||||
play_records[role] += minutes
|
||||
if(announce_changes)
|
||||
to_chat(mob,"<span class='notice'>You got: [minutes] [role] EXP!</span>")
|
||||
if(mob.mind.special_role && !mob.mind.var_edited)
|
||||
var/trackedrole = mob.mind.special_role
|
||||
var/gangrole = lookforgangrole(mob.mind.special_role)
|
||||
if(gangrole)
|
||||
trackedrole = gangrole
|
||||
play_records[trackedrole] += minutes
|
||||
if(announce_changes)
|
||||
to_chat(src,"<span class='notice'>You got: [minutes] [trackedrole] EXP!</span>")
|
||||
if(!rolefound)
|
||||
play_records["Unknown"] += minutes
|
||||
else
|
||||
play_records[EXP_TYPE_GHOST] += minutes
|
||||
if(announce_changes)
|
||||
to_chat(src,"<span class='notice'>You got: [minutes] Ghost EXP!</span>")
|
||||
else if(isobserver(mob))
|
||||
play_records[EXP_TYPE_GHOST] += minutes
|
||||
if(announce_changes)
|
||||
to_chat(src,"<span class='notice'>You got: [minutes] Ghost EXP!</span>")
|
||||
else if(minutes) //Let "refresh" checks go through
|
||||
return
|
||||
prefs.exp = play_records
|
||||
|
||||
for(var/jtype in play_records)
|
||||
if(play_records[jtype] != old_records[jtype])
|
||||
LAZYINITLIST(GLOB.exp_to_update)
|
||||
GLOB.exp_to_update.Add(list(list(
|
||||
"job" = "'[sanitizeSQL(jtype)]'",
|
||||
"ckey" = "'[sanitizeSQL(ckey)]'",
|
||||
"minutes" = play_records[jtype])))
|
||||
addtimer(CALLBACK(SSblackbox,/datum/controller/subsystem/blackbox/proc/update_exp_db),20,TIMER_OVERRIDE|TIMER_UNIQUE)
|
||||
|
||||
|
||||
//ALWAYS call this at beginning to any proc touching player flags, or your database admin will probably be mad
|
||||
/client/proc/set_db_player_flags()
|
||||
if(!SSdbcore.Connect())
|
||||
return FALSE
|
||||
|
||||
var/datum/DBQuery/flags_read = SSdbcore.NewQuery("SELECT flags FROM [format_table_name("player")] WHERE ckey='[ckey]'")
|
||||
|
||||
if(!flags_read.Execute())
|
||||
return FALSE
|
||||
|
||||
if(flags_read.NextRow())
|
||||
prefs.db_flags = text2num(flags_read.item[1])
|
||||
else if(isnull(prefs.db_flags))
|
||||
prefs.db_flags = 0 //This PROBABLY won't happen, but better safe than sorry.
|
||||
return TRUE
|
||||
|
||||
//Since each gang is tracked as a different antag type, records need to be generalized or you get up to 57 different possible records
|
||||
/proc/lookforgangrole(rolecheck)
|
||||
if(findtext(rolecheck,"Gangster"))
|
||||
return "Gangster"
|
||||
else if(findtext(rolecheck,"Gang Boss"))
|
||||
return "Gang Boss"
|
||||
else if(findtext(rolecheck,"Gang Lieutenant"))
|
||||
return "Gang Lieutenant"
|
||||
else
|
||||
return FALSE
|
||||
108
code/modules/jobs/job_exp.dm.rej
Normal file
108
code/modules/jobs/job_exp.dm.rej
Normal file
@@ -0,0 +1,108 @@
|
||||
diff a/code/modules/jobs/job_exp.dm b/code/modules/jobs/job_exp.dm (rejected hunks)
|
||||
@@ -140,15 +140,12 @@ GLOBAL_PROTECT(exp_to_update)
|
||||
//resets a client's exp to what was in the db.
|
||||
/client/proc/set_exp_from_db()
|
||||
if(!config.use_exp_tracking)
|
||||
- return
|
||||
+ return -1
|
||||
if(!SSdbcore.Connect())
|
||||
return -1
|
||||
var/datum/DBQuery/exp_read = SSdbcore.NewQuery("SELECT job, minutes FROM [format_table_name("role_time")] WHERE ckey = '[sanitizeSQL(ckey)]'")
|
||||
if(!exp_read.Execute())
|
||||
- var/err = exp_read.ErrorMsg()
|
||||
- log_sql("SQL ERROR during exp_update_client read. Error : \[[err]\]\n")
|
||||
- message_admins("SQL ERROR during exp_update_client read. Error : \[[err]\]\n")
|
||||
- return
|
||||
+ return -1
|
||||
var/list/play_records = list()
|
||||
while(exp_read.NextRow())
|
||||
play_records[exp_read.item[1]] = text2num(exp_read.item[2])
|
||||
@@ -172,42 +169,24 @@ GLOBAL_PROTECT(exp_to_update)
|
||||
if(!set_db_player_flags())
|
||||
return -1
|
||||
|
||||
- var/datum/DBQuery/flag_read = SSdbcore.NewQuery("SELECT flags FROM [format_table_name("player")] WHERE ckey='[sanitizeSQL(ckey)]'")
|
||||
-
|
||||
- if(!flag_read.Execute())
|
||||
- var/err = flag_read.ErrorMsg()
|
||||
- log_sql("SQL ERROR during player flags read. Error : \[[err]\]\n")
|
||||
- message_admins("SQL ERROR during player flags read. Error : \[[err]\]\n")
|
||||
- return
|
||||
-
|
||||
- var/playerflags = null
|
||||
- if(flag_read.NextRow())
|
||||
- playerflags = text2num(flag_read.item[1])
|
||||
-
|
||||
- if((playerflags & newflag) && !state)
|
||||
+ if((prefs.db_flags & newflag) && !state)
|
||||
prefs.db_flags &= ~newflag
|
||||
else
|
||||
prefs.db_flags |= newflag
|
||||
|
||||
var/datum/DBQuery/flag_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET flags = '[prefs.db_flags]' WHERE ckey='[sanitizeSQL(ckey)]'")
|
||||
|
||||
-
|
||||
if(!flag_update.Execute())
|
||||
- var/err = flag_update.ErrorMsg()
|
||||
- log_sql("SQL ERROR during exp_exempt update. Error : \[[err]\]\n")
|
||||
- message_admins("SQL ERROR during exp_exempt update. Error : \[[err]\]\n")
|
||||
- return
|
||||
+ return -1
|
||||
+
|
||||
|
||||
/client/proc/update_exp_list(minutes, announce_changes = FALSE)
|
||||
if(!config.use_exp_tracking)
|
||||
- return
|
||||
+ return -1
|
||||
if(!SSdbcore.Connect())
|
||||
return -1
|
||||
var/datum/DBQuery/exp_read = SSdbcore.NewQuery("SELECT job, minutes FROM [format_table_name("role_time")] WHERE ckey = '[sanitizeSQL(ckey)]'")
|
||||
if(!exp_read.Execute())
|
||||
- var/err = exp_read.ErrorMsg()
|
||||
- log_sql("SQL ERROR during exp_update_client read. Error : \[[err]\]\n")
|
||||
- message_admins("SQL ERROR during exp_update_client read. Error : \[[err]\]\n")
|
||||
return -1
|
||||
var/list/play_records = list()
|
||||
while(exp_read.NextRow())
|
||||
@@ -241,9 +220,13 @@ GLOBAL_PROTECT(exp_to_update)
|
||||
if(announce_changes)
|
||||
to_chat(mob,"<span class='notice'>You got: [minutes] [role] EXP!</span>")
|
||||
if(mob.mind.special_role && !mob.mind.var_edited)
|
||||
- play_records[mob.mind.special_role] += minutes
|
||||
+ var/trackedrole = mob.mind.special_role
|
||||
+ var/gangrole = lookforgangrole(mob.mind.special_role)
|
||||
+ if(gangrole)
|
||||
+ trackedrole = gangrole
|
||||
+ play_records[trackedrole] += minutes
|
||||
if(announce_changes)
|
||||
- to_chat(src,"<span class='notice'>You got: [minutes] [mob.mind.special_role] EXP!</span>")
|
||||
+ to_chat(src,"<span class='notice'>You got: [minutes] [trackedrole] EXP!</span>")
|
||||
if(!rolefound)
|
||||
play_records["Unknown"] += minutes
|
||||
else
|
||||
@@ -276,11 +259,21 @@ GLOBAL_PROTECT(exp_to_update)
|
||||
var/datum/DBQuery/flags_read = SSdbcore.NewQuery("SELECT flags FROM [format_table_name("player")] WHERE ckey='[ckey]'")
|
||||
|
||||
if(!flags_read.Execute())
|
||||
- var/err = flags_read.ErrorMsg()
|
||||
- log_sql("SQL ERROR during player flags read. Error : \[[err]\]\n")
|
||||
- message_admins("SQL ERROR during player flags read. Error : \[[err]\]\n")
|
||||
return FALSE
|
||||
|
||||
if(flags_read.NextRow())
|
||||
prefs.db_flags = text2num(flags_read.item[1])
|
||||
+ else if(isnull(prefs.db_flags))
|
||||
+ prefs.db_flags = 0 //This PROBABLY won't happen, but better safe than sorry.
|
||||
return TRUE
|
||||
+
|
||||
+//Since each gang is tracked as a different antag type, records need to be generalized or you get up to 57 different possible records
|
||||
+/proc/lookforgangrole(rolecheck)
|
||||
+ if(findtext(rolecheck,"Gangster"))
|
||||
+ return "Gangster"
|
||||
+ else if(findtext(rolecheck,"Gang Boss"))
|
||||
+ return "Gang Boss"
|
||||
+ else if(findtext(rolecheck,"Gang Lieutenant"))
|
||||
+ return "Gang Lieutenant"
|
||||
+ else
|
||||
+ return FALSE
|
||||
\ No newline at end of file
|
||||
@@ -13,6 +13,8 @@ Captain
|
||||
selection_color = "#ccccff"
|
||||
req_admin_notify = 1
|
||||
minimal_player_age = 14
|
||||
exp_requirements = 180
|
||||
exp_type = EXP_TYPE_CREW
|
||||
|
||||
outfit = /datum/outfit/job/captain
|
||||
|
||||
@@ -64,6 +66,9 @@ Head of Personnel
|
||||
selection_color = "#ddddff"
|
||||
req_admin_notify = 1
|
||||
minimal_player_age = 10
|
||||
exp_requirements = 180
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_type_department = EXP_TYPE_SUPPLY
|
||||
|
||||
outfit = /datum/outfit/job/hop
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@ Chief Engineer
|
||||
selection_color = "#ffeeaa"
|
||||
req_admin_notify = 1
|
||||
minimal_player_age = 7
|
||||
exp_requirements = 180
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_type_department = EXP_TYPE_ENGINEERING
|
||||
|
||||
outfit = /datum/outfit/job/ce
|
||||
|
||||
@@ -72,6 +75,8 @@ Station Engineer
|
||||
spawn_positions = 5
|
||||
supervisors = "the chief engineer"
|
||||
selection_color = "#fff5cc"
|
||||
exp_requirements = 60
|
||||
exp_type = EXP_TYPE_CREW
|
||||
|
||||
outfit = /datum/outfit/job/engineer
|
||||
|
||||
@@ -127,6 +132,8 @@ Atmospheric Technician
|
||||
spawn_positions = 2
|
||||
supervisors = "the chief engineer"
|
||||
selection_color = "#fff5cc"
|
||||
exp_requirements = 60
|
||||
exp_type = EXP_TYPE_CREW
|
||||
|
||||
outfit = /datum/outfit/job/atmos
|
||||
|
||||
|
||||
@@ -43,6 +43,11 @@
|
||||
|
||||
var/outfit = null
|
||||
|
||||
var/exp_requirements = 0
|
||||
|
||||
var/exp_type = ""
|
||||
var/exp_type_department = ""
|
||||
|
||||
//Only override this proc
|
||||
//H is usually a human unless an /equip override transformed it
|
||||
/datum/job/proc/after_spawn(mob/living/H, mob/M)
|
||||
|
||||
@@ -14,6 +14,9 @@ Chief Medical Officer
|
||||
selection_color = "#ffddf0"
|
||||
req_admin_notify = 1
|
||||
minimal_player_age = 7
|
||||
exp_requirements = 180
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_type_department = EXP_TYPE_MEDICAL
|
||||
|
||||
outfit = /datum/outfit/job/cmo
|
||||
|
||||
@@ -91,6 +94,8 @@ Chemist
|
||||
spawn_positions = 2
|
||||
supervisors = "the chief medical officer"
|
||||
selection_color = "#ffeef0"
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_requirements = 60
|
||||
|
||||
outfit = /datum/outfit/job/chemist
|
||||
|
||||
@@ -125,6 +130,8 @@ Geneticist
|
||||
spawn_positions = 2
|
||||
supervisors = "the chief medical officer and research director"
|
||||
selection_color = "#ffeef0"
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_requirements = 60
|
||||
|
||||
outfit = /datum/outfit/job/geneticist
|
||||
|
||||
@@ -159,6 +166,8 @@ Virologist
|
||||
spawn_positions = 1
|
||||
supervisors = "the chief medical officer"
|
||||
selection_color = "#ffeef0"
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_requirements = 60
|
||||
|
||||
outfit = /datum/outfit/job/virologist
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@ Research Director
|
||||
selection_color = "#ffddff"
|
||||
req_admin_notify = 1
|
||||
minimal_player_age = 7
|
||||
exp_type_department = EXP_TYPE_SCIENCE
|
||||
exp_requirements = 180
|
||||
exp_type = EXP_TYPE_CREW
|
||||
|
||||
outfit = /datum/outfit/job/rd
|
||||
|
||||
@@ -68,6 +71,8 @@ Scientist
|
||||
spawn_positions = 3
|
||||
supervisors = "the research director"
|
||||
selection_color = "#ffeeff"
|
||||
exp_requirements = 60
|
||||
exp_type = EXP_TYPE_CREW
|
||||
|
||||
outfit = /datum/outfit/job/scientist
|
||||
|
||||
@@ -101,6 +106,8 @@ Roboticist
|
||||
spawn_positions = 2
|
||||
supervisors = "research director"
|
||||
selection_color = "#ffeeff"
|
||||
exp_requirements = 60
|
||||
exp_type = EXP_TYPE_CREW
|
||||
|
||||
outfit = /datum/outfit/job/roboticist
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@ Head of Security
|
||||
selection_color = "#ffdddd"
|
||||
req_admin_notify = 1
|
||||
minimal_player_age = 14
|
||||
exp_requirements = 300
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_type_department = EXP_TYPE_SECURITY
|
||||
|
||||
outfit = /datum/outfit/job/hos
|
||||
|
||||
@@ -71,6 +74,8 @@ Warden
|
||||
supervisors = "the head of security"
|
||||
selection_color = "#ffeeee"
|
||||
minimal_player_age = 7
|
||||
exp_requirements = 300
|
||||
exp_type = EXP_TYPE_CREW
|
||||
|
||||
outfit = /datum/outfit/job/warden
|
||||
|
||||
@@ -121,6 +126,8 @@ Detective
|
||||
supervisors = "the head of security"
|
||||
selection_color = "#ffeeee"
|
||||
minimal_player_age = 7
|
||||
exp_requirements = 300
|
||||
exp_type = EXP_TYPE_CREW
|
||||
|
||||
outfit = /datum/outfit/job/detective
|
||||
|
||||
@@ -169,6 +176,8 @@ Security Officer
|
||||
supervisors = "the head of security, and the head of your assigned department (if applicable)"
|
||||
selection_color = "#ffeeee"
|
||||
minimal_player_age = 7
|
||||
exp_requirements = 300
|
||||
exp_type = EXP_TYPE_CREW
|
||||
|
||||
outfit = /datum/outfit/job/security
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ AI
|
||||
supervisors = "your laws"
|
||||
req_admin_notify = 1
|
||||
minimal_player_age = 30
|
||||
exp_requirements = 180
|
||||
exp_type = EXP_TYPE_CREW
|
||||
|
||||
/datum/job/ai/equip(mob/living/carbon/human/H)
|
||||
return H.AIize(FALSE)
|
||||
@@ -44,6 +46,8 @@ Cyborg
|
||||
supervisors = "your laws and the AI" //Nodrak
|
||||
selection_color = "#ddffdd"
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 120
|
||||
exp_type = EXP_TYPE_CREW
|
||||
|
||||
/datum/job/cyborg/equip(mob/living/carbon/human/H)
|
||||
return H.Robotize(FALSE, FALSE)
|
||||
|
||||
@@ -59,6 +59,26 @@ GLOBAL_LIST_INIT(nonhuman_positions, list(
|
||||
"Cyborg",
|
||||
"pAI"))
|
||||
|
||||
GLOBAL_LIST_INIT(exp_jobsmap, list(
|
||||
EXP_TYPE_CREW = list("titles" = command_positions | engineering_positions | medical_positions | science_positions | supply_positions | security_positions | civilian_positions | list("AI","Cyborg")), // crew positions
|
||||
EXP_TYPE_COMMAND = list("titles" = command_positions),
|
||||
EXP_TYPE_ENGINEERING = list("titles" = engineering_positions),
|
||||
EXP_TYPE_MEDICAL = list("titles" = medical_positions),
|
||||
EXP_TYPE_SCIENCE = list("titles" = science_positions),
|
||||
EXP_TYPE_SUPPLY = list("titles" = supply_positions),
|
||||
EXP_TYPE_SECURITY = list("titles" = security_positions),
|
||||
EXP_TYPE_SILICON = list("titles" = list("AI","Cyborg")),
|
||||
EXP_TYPE_SERVICE = list("titles" = civilian_positions),
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(exp_specialmap, list(
|
||||
EXP_TYPE_LIVING = list(), // all living mobs
|
||||
EXP_TYPE_ANTAG = list(),
|
||||
EXP_TYPE_SPECIAL = list("Lifebringer","Ash Walker","Exile","Servant Golem","Free Golem","Hermit","Translocated Vet","Escaped Prisoner","Hotel Staff","SuperFriend","Space Syndicate","Ancient Crew","Space Doctor","Space Bartender","Beach Bum","Skeleton","Zombie","Space Bar Patron","Lavaland Syndicate","Ghost Role"), // Ghost roles
|
||||
EXP_TYPE_GHOST = list() // dead people, observers
|
||||
))
|
||||
GLOBAL_PROTECT(exp_jobsmap)
|
||||
GLOBAL_PROTECT(exp_specialmap)
|
||||
|
||||
/proc/guest_jobbans(job)
|
||||
return ((job in GLOB.command_positions) || (job in GLOB.nonhuman_positions) || (job in GLOB.security_positions))
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
name = "\improper Codex Gigas"
|
||||
desc = "A book documenting the nature of devils."
|
||||
icon_state ="demonomicon"
|
||||
lefthand_file = 'icons/mob/inhands/misc/books_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/books_righthand.dmi'
|
||||
throw_speed = 1
|
||||
throw_range = 10
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
|
||||
@@ -419,7 +419,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
|
||||
var/sqlauthor = sanitizeSQL(scanner.cache.author)
|
||||
var/sqlcontent = sanitizeSQL(scanner.cache.dat)
|
||||
var/sqlcategory = sanitizeSQL(upload_category)
|
||||
var/datum/DBQuery/query_library_upload = SSdbcore.NewQuery("INSERT INTO [format_table_name("library")] (author, title, content, category, ckey, datetime) VALUES ('[sqlauthor]', '[sqltitle]', '[sqlcontent]', '[sqlcategory]', '[usr.ckey]', Now())")
|
||||
var/datum/DBQuery/query_library_upload = SSdbcore.NewQuery("INSERT INTO [format_table_name("library")] (author, title, content, category, ckey, datetime, round_id_created) VALUES ('[sqlauthor]', '[sqltitle]', '[sqlcontent]', '[sqlcategory]', '[usr.ckey]', Now(), '[GLOB.round_id]')")
|
||||
if(!query_library_upload.Execute())
|
||||
alert("Database error encountered uploading to Archive")
|
||||
return
|
||||
|
||||
@@ -480,6 +480,8 @@
|
||||
icon = 'icons/obj/vehicles.dmi'
|
||||
icon_state = "oar"
|
||||
item_state = "oar"
|
||||
lefthand_file = 'icons/mob/inhands/misc/lavaland_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/lavaland_righthand.dmi'
|
||||
desc = "Not to be confused with the kind Research hassles you for."
|
||||
force = 12
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
@@ -835,6 +837,8 @@
|
||||
desc = "The ability to fill the emergency shuttle with lava. What more could you want out of life?"
|
||||
icon_state = "staffofstorms"
|
||||
item_state = "staffofstorms"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
slot_flags = SLOT_BACK
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
@@ -1008,6 +1012,7 @@
|
||||
slot_flags = SLOT_BACK
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 15
|
||||
attack_verb = list("clubbed", "beat", "pummeled")
|
||||
hitsound = 'sound/weapons/sonic_jackhammer.ogg'
|
||||
actions_types = list(/datum/action/item_action/vortex_recall, /datum/action/item_action/toggle_unfriendly_fire)
|
||||
var/cooldown_time = 20 //how long the cooldown between non-melee ranged attacks is
|
||||
@@ -1024,6 +1029,21 @@
|
||||
..()
|
||||
to_chat(user, "<span class='hierophant_warning'>The[beacon ? " beacon is not currently":"re is a beacon"] attached.</span>")
|
||||
|
||||
/obj/item/hierophant_club/suicide_act(mob/living/user)
|
||||
say("Xverwpsgexmrk...")
|
||||
user.visible_message("<span class='suicide'>[user] holds [src] into the air! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
new/obj/effect/temp_visual/hierophant/telegraph(get_turf(user))
|
||||
playsound(user,'sound/machines/airlockopen.ogg', 75, TRUE)
|
||||
user.visible_message("<span class='hierophant_warning'>[user] fades out, leaving their belongings behind!</span>")
|
||||
for(var/obj/item/I in user)
|
||||
if(I != src)
|
||||
user.dropItemToGround(I)
|
||||
for(var/turf/T in RANGE_TURFS(1, user))
|
||||
var/obj/effect/temp_visual/hierophant/blast/B = new(T, user, TRUE)
|
||||
B.damage = 0
|
||||
user.dropItemToGround(src) //Drop us last, so it goes on top of their stuff
|
||||
qdel(user)
|
||||
|
||||
/obj/item/hierophant_club/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
..()
|
||||
var/turf/T = get_turf(target)
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/mob/dead/new_player/Login()
|
||||
if(config.use_exp_tracking)
|
||||
client.set_exp_from_db()
|
||||
client.set_db_player_flags()
|
||||
if(!mind)
|
||||
mind = new /datum/mind(key)
|
||||
mind.active = 1
|
||||
|
||||
9
code/modules/mob/dead/new_player/login.dm.rej
Normal file
9
code/modules/mob/dead/new_player/login.dm.rej
Normal file
@@ -0,0 +1,9 @@
|
||||
diff a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm (rejected hunks)
|
||||
@@ -1,5 +1,6 @@
|
||||
/mob/dead/new_player/Login()
|
||||
- client.update_exp_client(0, 0)
|
||||
+ if(config.use_exp_tracking)
|
||||
+ client.update_exp_client(0, 0)
|
||||
if(!mind)
|
||||
mind = new /datum/mind(key)
|
||||
mind.active = 1
|
||||
@@ -307,6 +307,8 @@
|
||||
return 0
|
||||
if(!job.player_old_enough(src.client))
|
||||
return 0
|
||||
if(job.required_playtime_remaining(client))
|
||||
return 0
|
||||
if(config.enforce_human_authority && !client.prefs.pref_species.qualifies_for_rank(rank, client.prefs.features))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -96,6 +96,20 @@
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/tails/human/kitsune
|
||||
name = "Kitsune"
|
||||
icon_state = "kitsune"
|
||||
extra = 1
|
||||
extra_color_src = MUTCOLORS2
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/tails_animated/human/kitsune
|
||||
name = "Kitsune"
|
||||
icon_state = "kitsune"
|
||||
extra = 1
|
||||
extra_color_src = MUTCOLORS2
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/ears/lab
|
||||
name = "Dog, Floppy"
|
||||
icon_state = "lab"
|
||||
@@ -119,6 +133,33 @@
|
||||
color_src = 0
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/ears/human/otie
|
||||
name = "Otusian"
|
||||
icon_state = "otie"
|
||||
hasinner= 1
|
||||
|
||||
/datum/sprite_accessory/tails/human/otie
|
||||
name = "Otusian"
|
||||
icon_state = "otie"
|
||||
|
||||
/datum/sprite_accessory/tails_animated/human/otie
|
||||
name = "Otusian"
|
||||
icon_state = "otie"
|
||||
|
||||
/datum/sprite_accessory/ears/human/skunk
|
||||
name = "skunk"
|
||||
icon_state = "skunk"
|
||||
|
||||
/datum/sprite_accessory/tails/human/skunk
|
||||
name = "skunk"
|
||||
icon_state = "skunk"
|
||||
color_src = 0
|
||||
|
||||
/datum/sprite_accessory/tails_animated/human/skunk
|
||||
name = "skunk"
|
||||
icon_state = "skunk"
|
||||
color_src = 0
|
||||
|
||||
/datum/sprite_accessory/tails/human/shark
|
||||
name = "Shark"
|
||||
icon_state = "shark"
|
||||
@@ -198,6 +239,16 @@
|
||||
**************** Snouts *******************
|
||||
*******************************************/
|
||||
|
||||
/datum/sprite_accessory/snouts/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/snouts/bird
|
||||
name = "Beak"
|
||||
icon_state = "bird"
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/snouts/lcanid
|
||||
name = "Fox, Long"
|
||||
icon_state = "lcanid"
|
||||
@@ -347,6 +398,31 @@
|
||||
icon_state = "husky"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_ears/kangaroo
|
||||
name = "kangaroo"
|
||||
icon_state = "kangaroo"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_tails/kangaroo
|
||||
name = "kangaroo"
|
||||
icon_state = "kangaroo"
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/kangaroo
|
||||
name = "kangaroo"
|
||||
icon_state = "kangaroo"
|
||||
|
||||
/datum/sprite_accessory/mam_tails/kitsune
|
||||
name = "Kitsune"
|
||||
icon_state = "kitsune"
|
||||
extra = 1
|
||||
extra_color_src = MUTCOLORS2
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/kitsune
|
||||
name = "Kitsune"
|
||||
icon_state = "kitsune"
|
||||
extra = 1
|
||||
extra_color_src = MUTCOLORS2
|
||||
|
||||
/datum/sprite_accessory/mam_ears/lab
|
||||
name = "Dog, Long"
|
||||
icon_state = "lab"
|
||||
@@ -386,6 +462,22 @@
|
||||
name = "Otusian"
|
||||
icon_state = "otie"
|
||||
|
||||
/datum/sprite_accessory/mam_ears/skunk
|
||||
name = "skunk"
|
||||
icon_state = "skunk"
|
||||
|
||||
/datum/sprite_accessory/mam_tails/skunk
|
||||
name = "skunk"
|
||||
icon_state = "skunk"
|
||||
color_src = 0
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/skunk
|
||||
name = "skunk"
|
||||
icon_state = "skunk"
|
||||
color_src = 0
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_tails/shark
|
||||
name = "Shark"
|
||||
icon_state = "shark"
|
||||
@@ -396,17 +488,6 @@
|
||||
icon_state = "shark"
|
||||
color_src = 0
|
||||
|
||||
/datum/sprite_accessory/mam_tails/shark/datashark
|
||||
name = "DataShark"
|
||||
icon_state = "datashark"
|
||||
color_src = 0
|
||||
// ckeys_allowed = list("rubyflamewing")
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/shark/datashark
|
||||
name = "DataShark"
|
||||
icon_state = "datashark"
|
||||
color_src = 0
|
||||
|
||||
/datum/sprite_accessory/mam_tails/shepherd
|
||||
name = "Shepherd"
|
||||
icon_state = "shepherd"
|
||||
@@ -445,31 +526,18 @@
|
||||
name = "Wolf"
|
||||
icon_state = "wolf"
|
||||
|
||||
/datum/sprite_accessory/mam_tails/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_ears/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails/rabbit
|
||||
name = "Rabbit"
|
||||
icon_state = "rabbit"
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/rabbit
|
||||
name = "Rabbit"
|
||||
icon_state = "rabbit"
|
||||
|
||||
/datum/sprite_accessory/mam_ears/rabbit
|
||||
name = "Rabbit"
|
||||
icon_state = "rabbit"
|
||||
hasinner= 1
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/******************************************
|
||||
************ Body Markings ****************
|
||||
@@ -586,21 +654,14 @@
|
||||
color_src = MUTCOLORS2
|
||||
gender_specific = 1
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
extra = 1
|
||||
extra2 = 1
|
||||
icon = 'icons/mob/mam_body_markings.dmi'
|
||||
gender_specific = 1
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/xeno
|
||||
/datum/sprite_accessory/mam_body_markings/xeno
|
||||
name = "Xeno"
|
||||
icon_state = "xeno"
|
||||
color_src = MUTCOLORS2
|
||||
extra_color_src = MUTCOLORS3
|
||||
gender_specific = 1
|
||||
|
||||
|
||||
/******************************************
|
||||
************ Taur Bodies ******************
|
||||
*******************************************/
|
||||
@@ -712,7 +773,6 @@
|
||||
icon = 'icons/mob/xeno_parts_greyscale.dmi'
|
||||
|
||||
//Xeno Caste Heads
|
||||
//unused as of October 3, 2016
|
||||
/datum/sprite_accessory/xeno_head
|
||||
icon = 'icons/mob/xeno_parts_greyscale.dmi'
|
||||
|
||||
@@ -740,17 +800,67 @@
|
||||
icon_state = "warrior"
|
||||
icon = 'icons/mob/xeno_parts_greyscale.dmi'
|
||||
|
||||
// *** Snooooow flaaaaake ***
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
extra_color_src = MUTCOLORS2
|
||||
extra2_color_src = MUTCOLORS3
|
||||
gender_specific = 1
|
||||
|
||||
/datum/sprite_accessory/mam_tails/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_ears/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails/shark/datashark
|
||||
name = "DataShark"
|
||||
icon_state = "datashark"
|
||||
color_src = 0
|
||||
// ckeys_allowed = list("rubyflamewing")
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/shark/datashark
|
||||
name = "DataShark"
|
||||
icon_state = "datashark"
|
||||
color_src = 0
|
||||
|
||||
/*
|
||||
//Slimecoon Parts
|
||||
/datum/sprite_accessory/slimecoon_ears
|
||||
icon = 'icons/mob/exotic_bodyparts.dmi'
|
||||
name = "Slimecoon Ears"
|
||||
icon_state = "slimecoon"
|
||||
/datum/sprite_accessory/slimecoon_tail
|
||||
icon = 'icons/mob/exotic_bodyparts.dmi'
|
||||
name = "Slimecoon Tail"
|
||||
icon_state = "slimecoon"
|
||||
/datum/sprite_accessory/slimecoon_snout
|
||||
icon = 'icons/mob/exotic_bodyparts.dmi'
|
||||
name = "Hunter"
|
||||
icon_state = "slimecoon" */
|
||||
//Till I get my snowflake only ckey lock, these are locked-locked :D
|
||||
|
||||
/datum/sprite_accessory/mam_ears/sabresune
|
||||
name = "sabresune"
|
||||
icon_state = "sabresune"
|
||||
extra = 1
|
||||
extra_color_src = MUTCOLORS3
|
||||
locked = TRUE
|
||||
|
||||
/datum/sprite_accessory/mam_tails/sabresune
|
||||
name = "sabresune"
|
||||
icon_state = "sabresune"
|
||||
extra = 1
|
||||
locked = TRUE
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/sabresune
|
||||
name = "sabresune"
|
||||
icon_state = "sabresune"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/sabresune
|
||||
name = "Sabresune"
|
||||
icon_state = "sabresune"
|
||||
color_src = MUTCOLORS2
|
||||
extra = 0
|
||||
extra2 = 0
|
||||
locked = TRUE
|
||||
*/
|
||||
|
||||
@@ -309,9 +309,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
if(SSticker.HasRoundStarted())
|
||||
for(var/datum/gang/G in SSticker.mode.gangs)
|
||||
if(G.is_dominating)
|
||||
stat(null, "[G.name] Gang Takeover: [max(G.domination_time_remaining(), 0)]")
|
||||
if(istype(SSticker.mode, /datum/game_mode/blob))
|
||||
var/datum/game_mode/blob/B = SSticker.mode
|
||||
if(B.message_sent)
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
initial_language_holder = /datum/language_holder/alien
|
||||
bubble_icon = "alien"
|
||||
type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
|
||||
var/nightvision = 1
|
||||
|
||||
var/obj/item/card/id/wear_id = null // Fix for station bounced radios -- Skie
|
||||
var/has_fine_manipulation = 0
|
||||
@@ -32,7 +31,7 @@
|
||||
|
||||
var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|queen)( \\(\\d+\\))?")
|
||||
devourable = TRUE
|
||||
|
||||
|
||||
/mob/living/carbon/alien/Initialize()
|
||||
verbs += /mob/living/proc/mob_sleep
|
||||
verbs += /mob/living/proc/lay_down
|
||||
|
||||
@@ -610,50 +610,94 @@
|
||||
if(!client)
|
||||
return
|
||||
|
||||
if(stat == UNCONSCIOUS && health <= HEALTH_THRESHOLD_CRIT)
|
||||
if(health <= HEALTH_THRESHOLD_CRIT)
|
||||
var/severity = 0
|
||||
switch(health)
|
||||
if(-20 to -10) severity = 1
|
||||
if(-30 to -20) severity = 2
|
||||
if(-40 to -30) severity = 3
|
||||
if(-50 to -40) severity = 4
|
||||
if(-60 to -50) severity = 5
|
||||
if(-70 to -60) severity = 6
|
||||
if(-80 to -70) severity = 7
|
||||
if(-90 to -80) severity = 8
|
||||
if(-95 to -90) severity = 9
|
||||
if(-INFINITY to -95) severity = 10
|
||||
if(-20 to -10)
|
||||
severity = 1
|
||||
if(-30 to -20)
|
||||
severity = 2
|
||||
if(-40 to -30)
|
||||
severity = 3
|
||||
if(-50 to -40)
|
||||
severity = 4
|
||||
if(-50 to -40)
|
||||
severity = 5
|
||||
if(-60 to -50)
|
||||
severity = 6
|
||||
if(-70 to -60)
|
||||
severity = 7
|
||||
if(-90 to -70)
|
||||
severity = 8
|
||||
if(-95 to -90)
|
||||
severity = 9
|
||||
if(-INFINITY to -95)
|
||||
severity = 10
|
||||
if(!InFullCritical())
|
||||
var/visionseverity = 4
|
||||
switch(health)
|
||||
if(-8 to -4)
|
||||
visionseverity = 5
|
||||
if(-12 to -8)
|
||||
visionseverity = 6
|
||||
if(-16 to -12)
|
||||
visionseverity = 7
|
||||
if(-20 to -16)
|
||||
visionseverity = 8
|
||||
if(-24 to -20)
|
||||
visionseverity = 9
|
||||
if(-INFINITY to -24)
|
||||
visionseverity = 10
|
||||
overlay_fullscreen("critvision", /obj/screen/fullscreen/crit/vision, visionseverity)
|
||||
else
|
||||
clear_fullscreen("critvision")
|
||||
overlay_fullscreen("crit", /obj/screen/fullscreen/crit, severity)
|
||||
else
|
||||
clear_fullscreen("crit")
|
||||
if(oxyloss)
|
||||
var/severity = 0
|
||||
switch(oxyloss)
|
||||
if(10 to 20) severity = 1
|
||||
if(20 to 25) severity = 2
|
||||
if(25 to 30) severity = 3
|
||||
if(30 to 35) severity = 4
|
||||
if(35 to 40) severity = 5
|
||||
if(40 to 45) severity = 6
|
||||
if(45 to INFINITY) severity = 7
|
||||
overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity)
|
||||
else
|
||||
clear_fullscreen("oxy")
|
||||
clear_fullscreen("critvision")
|
||||
|
||||
//Fire and Brute damage overlay (BSSR)
|
||||
var/hurtdamage = getBruteLoss() + getFireLoss() + damageoverlaytemp
|
||||
if(hurtdamage)
|
||||
var/severity = 0
|
||||
switch(hurtdamage)
|
||||
if(5 to 15) severity = 1
|
||||
if(15 to 30) severity = 2
|
||||
if(30 to 45) severity = 3
|
||||
if(45 to 70) severity = 4
|
||||
if(70 to 85) severity = 5
|
||||
if(85 to INFINITY) severity = 6
|
||||
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
|
||||
else
|
||||
clear_fullscreen("brute")
|
||||
//Oxygen damage overlay
|
||||
if(oxyloss)
|
||||
var/severity = 0
|
||||
switch(oxyloss)
|
||||
if(10 to 20)
|
||||
severity = 1
|
||||
if(20 to 25)
|
||||
severity = 2
|
||||
if(25 to 30)
|
||||
severity = 3
|
||||
if(30 to 35)
|
||||
severity = 4
|
||||
if(35 to 40)
|
||||
severity = 5
|
||||
if(40 to 45)
|
||||
severity = 6
|
||||
if(45 to INFINITY)
|
||||
severity = 7
|
||||
overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity)
|
||||
else
|
||||
clear_fullscreen("oxy")
|
||||
|
||||
//Fire and Brute damage overlay (BSSR)
|
||||
var/hurtdamage = getBruteLoss() + getFireLoss() + damageoverlaytemp
|
||||
if(hurtdamage)
|
||||
var/severity = 0
|
||||
switch(hurtdamage)
|
||||
if(5 to 15)
|
||||
severity = 1
|
||||
if(15 to 30)
|
||||
severity = 2
|
||||
if(30 to 45)
|
||||
severity = 3
|
||||
if(45 to 70)
|
||||
severity = 4
|
||||
if(70 to 85)
|
||||
severity = 5
|
||||
if(85 to INFINITY)
|
||||
severity = 6
|
||||
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
|
||||
else
|
||||
clear_fullscreen("brute")
|
||||
|
||||
/mob/living/carbon/update_health_hud(shown_health_amount)
|
||||
if(!client || !hud_used)
|
||||
@@ -688,20 +732,19 @@
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
if(stat != DEAD)
|
||||
if(health<= HEALTH_THRESHOLD_DEAD)
|
||||
if(health <= HEALTH_THRESHOLD_DEAD)
|
||||
death()
|
||||
return
|
||||
if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
|
||||
if(stat == CONSCIOUS)
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
update_canmove()
|
||||
if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_FULLCRIT)
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
else
|
||||
if(stat == UNCONSCIOUS)
|
||||
if(health <= HEALTH_THRESHOLD_CRIT)
|
||||
stat = SOFT_CRIT
|
||||
else
|
||||
stat = CONSCIOUS
|
||||
resting = 0
|
||||
adjust_blindness(-1)
|
||||
update_canmove()
|
||||
adjust_blindness(-1)
|
||||
update_canmove()
|
||||
update_damage_hud()
|
||||
update_health_hud()
|
||||
med_hud_set_status()
|
||||
|
||||
@@ -255,6 +255,8 @@
|
||||
else if(check_zone(M.zone_selected) == "head")
|
||||
M.visible_message("<span class='notice'>[M] gives [src] a pat on the head to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You give [src] a pat on the head to make [p_them()] feel better!</span>")
|
||||
if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || (dna.features["tail_human"] != "None") || ("mam_tail" in dna.species.mutant_bodyparts)))
|
||||
emote("wag") //lewd
|
||||
else
|
||||
M.visible_message("<span class='notice'>[M] hugs [src] to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>")
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/mob/living/carbon/movement_delay()
|
||||
var/FP
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
var/obj/item/device/flightpack/F = C.get_flightpack()
|
||||
if(istype(F) && F.flight)
|
||||
FP = 1
|
||||
var/FP = FALSE
|
||||
var/obj/item/device/flightpack/F = get_flightpack()
|
||||
if(istype(F) && F.flight)
|
||||
FP = TRUE
|
||||
. = ..(FP)
|
||||
if(!FP)
|
||||
. += grab_state * 1 //Flightpacks are too powerful to be slowed too much by the weight of a corpse.
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
if(!appears_dead)
|
||||
if(stat == UNCONSCIOUS)
|
||||
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
|
||||
else if(InCritical())
|
||||
msg += "[t_His] breathing is shallow and labored.\n"
|
||||
|
||||
if(digitalcamo)
|
||||
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner.\n"
|
||||
|
||||
@@ -613,7 +613,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
|
||||
//Check for dresscode violations
|
||||
if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/syndi) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi))
|
||||
threatcount += 3
|
||||
threatcount += 6
|
||||
|
||||
//Check for nonhuman scum
|
||||
if(dna && dna.species.id && !(dna.species.id in list("human" , "lizard", "mammal", "avian", "aquatic", "insect")))
|
||||
@@ -643,6 +643,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
update_hair()
|
||||
|
||||
/mob/living/carbon/human/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_THREE)
|
||||
for(var/obj/item/hand in held_items)
|
||||
if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && dropItemToGround(hand))
|
||||
@@ -651,7 +652,6 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
rad_act(current_size * 3)
|
||||
if(mob_negates_gravity())
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/proc/do_cpr(mob/living/carbon/C)
|
||||
CHECK_DNA_AND_SPECIES(C)
|
||||
|
||||
@@ -105,9 +105,6 @@
|
||||
/mob/living/carbon/human/IsAdvancedToolUser()
|
||||
return 1//Humans can use guns and such
|
||||
|
||||
/mob/living/carbon/human/InCritical()
|
||||
return (health <= HEALTH_THRESHOLD_CRIT && stat == UNCONSCIOUS)
|
||||
|
||||
/mob/living/carbon/human/reagent_check(datum/reagent/R)
|
||||
return dna.species.handle_chemicals(R,src)
|
||||
// if it returns 0, it will run the usual on_mob_life for that reagent. otherwise, it will stop after running handle_chemicals for the species.
|
||||
|
||||
@@ -87,17 +87,23 @@
|
||||
/// SNPC voice handling
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/loadVoice()
|
||||
var/savefile/S = new /savefile("data/npc_saves/snpc.sav")
|
||||
S["knownStrings"] >> knownStrings
|
||||
|
||||
var/json_file = file("data/npc_saves/snpc.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
knownStrings = json["knownStrings"]
|
||||
if(isnull(knownStrings))
|
||||
knownStrings = list()
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/saveVoice()
|
||||
if(voice_saved)
|
||||
return
|
||||
var/savefile/S = new /savefile("data/npc_saves/snpc.sav")
|
||||
WRITE_FILE(S["knownStrings"], knownStrings)
|
||||
var/json_file = file("data/npc_saves/snpc.json")
|
||||
var/list/file_data = list()
|
||||
file_data["knownStrings"] = knownStrings
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
//botPool funcs
|
||||
/mob/living/carbon/human/interactive/proc/takeDelegate(mob/living/carbon/human/interactive/from,doReset=TRUE)
|
||||
@@ -284,7 +290,7 @@
|
||||
//job specific favours
|
||||
switch(myjob.title)
|
||||
if("Assistant")
|
||||
favoured_types = list(/obj/item/clothing, /obj/item/weapon)
|
||||
favoured_types = list(/obj/item/clothing, /obj/item)
|
||||
if("Captain","Head of Personnel")
|
||||
favoured_types = list(/obj/item/clothing, /obj/item/stamp/captain, /obj/item/disk/nuclear)
|
||||
if("Cook")
|
||||
@@ -296,14 +302,14 @@
|
||||
functions += "bartend"
|
||||
restrictedJob = 1
|
||||
if("Station Engineer","Chief Engineer","Atmospheric Technician")
|
||||
favoured_types = list(/obj/item/stack, /obj/item/weapon, /obj/item/clothing)
|
||||
favoured_types = list(/obj/item/stack, /obj/item, /obj/item/clothing)
|
||||
if("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Geneticist")
|
||||
favoured_types = list(/obj/item/reagent_containers/glass/beaker, /obj/item/storage/firstaid, /obj/item/stack/medical, /obj/item/reagent_containers/syringe)
|
||||
functions += "healpeople"
|
||||
if("Research Director","Scientist","Roboticist")
|
||||
favoured_types = list(/obj/item/reagent_containers/glass/beaker, /obj/item/stack, /obj/item/reagent_containers)
|
||||
if("Head of Security","Warden","Security Officer","Detective")
|
||||
favoured_types = list(/obj/item/clothing, /obj/item/weapon, /obj/item/restraints)
|
||||
favoured_types = list(/obj/item/clothing, /obj/item, /obj/item/restraints)
|
||||
if("Janitor")
|
||||
favoured_types = list(/obj/item/mop, /obj/item/reagent_containers/glass/bucket, /obj/item/reagent_containers/spray/cleaner, /obj/effect/decal/cleanable)
|
||||
functions += "dojanitor"
|
||||
@@ -313,7 +319,7 @@
|
||||
if("Mime")
|
||||
functions -= "chatter"
|
||||
if("Botanist")
|
||||
favoured_types = list(/obj/machinery/hydroponics, /obj/item/reagent_containers, /obj/item/weapon)
|
||||
favoured_types = list(/obj/machinery/hydroponics, /obj/item/reagent_containers, /obj/item)
|
||||
functions += "botany"
|
||||
restrictedJob = 1
|
||||
else
|
||||
@@ -633,7 +639,7 @@
|
||||
insert_into_backpack() // dump random item into backpack to make space
|
||||
//---------ITEMS
|
||||
if(isitem(TARGET))
|
||||
if(istype(TARGET, /obj/item/weapon))
|
||||
if(istype(TARGET, /obj/item))
|
||||
var/obj/item/W = TARGET
|
||||
if(W.force >= best_force || prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/2))
|
||||
if(!get_item_for_held_index(1) || !get_item_for_held_index(2))
|
||||
@@ -1473,7 +1479,7 @@
|
||||
foundFav = 1
|
||||
return
|
||||
if(!foundFav)
|
||||
if(istype(test, /obj/item/weapon))
|
||||
if(istype(test, /obj/item))
|
||||
var/obj/item/R = test
|
||||
if(R.force > 2) // make sure we don't equip any non-weaponlike items, ie bags and stuff
|
||||
if(!best)
|
||||
@@ -1498,7 +1504,7 @@
|
||||
if(istype(A, /obj/item/gun)) // guns are for shooting, not throwing.
|
||||
continue
|
||||
if(prob(robustness))
|
||||
if(istype(A, /obj/item/weapon))
|
||||
if(istype(A, /obj/item))
|
||||
var/obj/item/W = A
|
||||
if(W.throwforce > 19) // Only throw worthwile stuff, no more lobbing wrenches at wenches
|
||||
npcDrop(W,1)
|
||||
@@ -1612,4 +1618,4 @@
|
||||
TRAITS |= TRAIT_ROBUST
|
||||
TRAITS |= TRAIT_SMART
|
||||
faction += "bot_power"
|
||||
..()
|
||||
..()
|
||||
@@ -147,7 +147,7 @@
|
||||
. = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should.
|
||||
if(!. || !I)
|
||||
return
|
||||
if(index && dna.species.mutanthands)
|
||||
if(index && !QDELETED(src) && dna.species.mutanthands) //hand freed, fill with claws, skip if we're getting deleted.
|
||||
put_in_hand(new dna.species.mutanthands(), index)
|
||||
if(I == wear_suit)
|
||||
if(s_store && invdrop)
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
|
||||
if((wear_suit && (wear_suit.flags_1 & STOPSPRESSUREDMAGE_1)) && (head && (head.flags_1 & STOPSPRESSUREDMAGE_1)))
|
||||
return ONE_ATMOSPHERE
|
||||
if(ismob(loc))
|
||||
return ONE_ATMOSPHERE
|
||||
else
|
||||
return pressure
|
||||
|
||||
@@ -242,6 +244,9 @@
|
||||
|
||||
if(dna && (RESISTCOLD in dna.species.species_traits))
|
||||
return 1
|
||||
|
||||
if(ismob(loc))
|
||||
return 1 //because lazy and being inside somemone insulates you from space
|
||||
|
||||
temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K.
|
||||
var/thermal_protection_flags = get_cold_protection_flags(temperature)
|
||||
|
||||
@@ -1198,6 +1198,8 @@
|
||||
. += (1.5 - flight)
|
||||
if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
. += (BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR
|
||||
if(H.stat == SOFT_CRIT)
|
||||
. = max(SOFTCRIT_MIN_SLOWDOWN, . + SOFTCRIT_ADD_SLOWDOWN) //regardless of how fast you are, you move at a maximum of SOFTCRIT_MIN_SLOWDOWN while in softcrit
|
||||
return .
|
||||
|
||||
//////////////////
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1
|
||||
liked_food = MEAT | FRIED
|
||||
disliked_food = TOXIC
|
||||
|
||||
/datum/species/mammal/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -24,12 +26,14 @@
|
||||
say_mod = "chirps"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("snout", "wings", "taur", "mam_tail", "mam_body_markings")
|
||||
mutant_bodyparts = list("snout", "wings", "taur", "mam_tail", "mam_body_markings", "taur")
|
||||
default_features = list("snout" = "Sharp", "wings" = "None", "taur" = "None", "mam_body_markings" = "Hawk")
|
||||
attack_verb = "peck"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1
|
||||
liked_food = MEAT | FRUIT
|
||||
disliked_food = TOXIC
|
||||
|
||||
/datum/species/avian/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -44,12 +48,14 @@
|
||||
id = "aquatic"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("mam_tail", "mam_body_markings", "mam_ears")
|
||||
mutant_bodyparts = list("mam_tail", "mam_body_markings", "mam_ears", "taur")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF","mam_tail" = "shark", "mam_body_markings" = "None", "mam_ears" = "None")
|
||||
attack_verb = "bite"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1
|
||||
liked_food = MEAT
|
||||
disliked_food = TOXIC
|
||||
|
||||
/datum/species/aquatic/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -64,12 +70,14 @@
|
||||
id = "insect"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("mam_body_markings", "mam_ears", "mam_tail")
|
||||
mutant_bodyparts = list("mam_body_markings", "mam_ears", "mam_tail", "taur")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_body_markings" = "moth", "mam_tail" = "None", "mam_ears" = "None")
|
||||
attack_verb = "flutter" //wat?
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1
|
||||
liked_food = MEAT | FRUIT
|
||||
disliked_food = TOXIC
|
||||
|
||||
/datum/species/insect/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -98,6 +106,7 @@
|
||||
exotic_bloodtype = "L"
|
||||
damage_overlay_type = "xeno"
|
||||
roundstart = 1
|
||||
liked_food = MEAT
|
||||
|
||||
//Praise the Omnissiah, A challange worthy of my skills - HS
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
damage_overlay_type = ""
|
||||
var/datum/action/innate/regenerate_limbs/regenerate_limbs
|
||||
toxic_food = NONE
|
||||
liked_food = NONE
|
||||
liked_food = MEAT
|
||||
|
||||
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
|
||||
if(regenerate_limbs)
|
||||
|
||||
@@ -95,24 +95,30 @@
|
||||
|
||||
if(I == head)
|
||||
head = null
|
||||
head_update(I)
|
||||
if(!QDELETED(src))
|
||||
head_update(I)
|
||||
else if(I == back)
|
||||
back = null
|
||||
update_inv_back()
|
||||
if(!QDELETED(src))
|
||||
update_inv_back()
|
||||
else if(I == wear_mask)
|
||||
wear_mask = null
|
||||
wear_mask_update(I, toggle_off = 1)
|
||||
if(!QDELETED(src))
|
||||
wear_mask_update(I, toggle_off = 1)
|
||||
if(I == wear_neck)
|
||||
wear_neck = null
|
||||
update_inv_neck(I)
|
||||
if(!QDELETED(src))
|
||||
update_inv_neck(I)
|
||||
else if(I == handcuffed)
|
||||
handcuffed = null
|
||||
if(buckled && buckled.buckle_requires_restraints)
|
||||
buckled.unbuckle_mob(src)
|
||||
update_handcuffed()
|
||||
if(!QDELETED(src))
|
||||
update_handcuffed()
|
||||
else if(I == legcuffed)
|
||||
legcuffed = null
|
||||
update_inv_legcuffed()
|
||||
if(!QDELETED(src))
|
||||
update_inv_legcuffed()
|
||||
|
||||
//handle stuff to update when a mob equips/unequips a mask.
|
||||
/mob/living/proc/wear_mask_update(obj/item/clothing/C, toggle_off = 1)
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
return
|
||||
if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
|
||||
return
|
||||
if(istype(loc, /obj/item/device/dogborg/sleeper))
|
||||
return
|
||||
if(ismob(loc))
|
||||
return
|
||||
var/datum/gas_mixture/environment
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
..()
|
||||
|
||||
//These have to be after the parent new to ensure that the monkey
|
||||
//bodyparts are actually created before we try to equip things to
|
||||
//bodyparts are actually created before we try to equip things to
|
||||
//those slots
|
||||
if(relic_hat)
|
||||
equip_to_slot_or_del(new relic_hat, slot_head)
|
||||
@@ -42,32 +42,32 @@
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/punpun/proc/Read_Memory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Punpun.sav")
|
||||
S["ancestor_name"] >> ancestor_name
|
||||
S["ancestor_chain"] >> ancestor_chain
|
||||
S["relic_hat"] >> relic_hat
|
||||
S["relic_mask"] >> relic_mask
|
||||
var/json_file = file("data/npc_saves/Punpun.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
ancestor_name = json["ancestor_name"]
|
||||
ancestor_chain = json["ancestor_chain"]
|
||||
relic_hat = json["relic_hat"]
|
||||
relic_mask = json["relic_hat"]
|
||||
|
||||
/mob/living/carbon/monkey/punpun/proc/Write_Memory(dead, gibbed)
|
||||
var/savefile/S = new /savefile("data/npc_saves/Punpun.sav")
|
||||
var/json_file = file("data/npc_saves/Punpun.json")
|
||||
var/list/file_data = list()
|
||||
if(gibbed)
|
||||
WRITE_FILE(S["ancestor_name"], null)
|
||||
WRITE_FILE(S["ancestor_chain"], 1)
|
||||
WRITE_FILE(S["relic_hat"], null)
|
||||
WRITE_FILE(S["relic_mask"], null)
|
||||
return
|
||||
file_data["ancestor_name"] = null
|
||||
file_data["ancestor_chain"] = null
|
||||
file_data["relic_hat"] = null
|
||||
file_data["relic_mask"] = null
|
||||
if(dead)
|
||||
WRITE_FILE(S["ancestor_name"], ancestor_name)
|
||||
WRITE_FILE(S["ancestor_chain"], ancestor_chain + 1)
|
||||
if(!ancestor_name) //new monkey name this round
|
||||
WRITE_FILE(S["ancestor_name"], name)
|
||||
if(head)
|
||||
WRITE_FILE(S["relic_hat"], head.type)
|
||||
else
|
||||
WRITE_FILE(S["relic_hat"], null)
|
||||
if(wear_mask)
|
||||
WRITE_FILE(S["relic_mask"], wear_mask.type)
|
||||
else
|
||||
WRITE_FILE(S["relic_mask"], null)
|
||||
file_data["ancestor_name"] = ancestor_name
|
||||
file_data["ancestor_chain"] = ancestor_chain + 1
|
||||
file_data["relic_hat"] = head ? head.type : null
|
||||
file_data["relic_mask"] = wear_mask ? wear_mask.type : null
|
||||
if(!ancestor_name)
|
||||
file_data["ancestor_name"] = name
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(json_file))
|
||||
if(!dead)
|
||||
memory_saved = 1
|
||||
memory_saved = 1
|
||||
@@ -229,8 +229,8 @@
|
||||
/mob/living/verb/succumb(whispered as null)
|
||||
set hidden = 1
|
||||
if (InCritical())
|
||||
src.log_message("Has [whispered ? "whispered his final words" : "succumbed to death"] with [round(health, 0.1)] points of health!", INDIVIDUAL_ATTACK_LOG)
|
||||
src.adjustOxyLoss(src.health - HEALTH_THRESHOLD_DEAD)
|
||||
log_message("Has [whispered ? "whispered his final words" : "succumbed to death"] while in [InFullCritical() ? "hard":"soft"] critical with [round(health, 0.1)] points of health!", INDIVIDUAL_ATTACK_LOG)
|
||||
adjustOxyLoss(health - HEALTH_THRESHOLD_DEAD)
|
||||
updatehealth()
|
||||
if(!whispered)
|
||||
to_chat(src, "<span class='notice'>You have given up life and succumbed to death.</span>")
|
||||
@@ -241,7 +241,10 @@
|
||||
return 1
|
||||
|
||||
/mob/living/proc/InCritical()
|
||||
return (health < HEALTH_THRESHOLD_CRIT && health > HEALTH_THRESHOLD_DEAD && stat == UNCONSCIOUS)
|
||||
return (health <= HEALTH_THRESHOLD_CRIT && (stat == SOFT_CRIT || stat == UNCONSCIOUS))
|
||||
|
||||
/mob/living/proc/InFullCritical()
|
||||
return (health <= HEALTH_THRESHOLD_FULLCRIT && stat == UNCONSCIOUS)
|
||||
|
||||
//This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually
|
||||
//affects them once clothing is factored in. ~Errorage
|
||||
@@ -471,31 +474,31 @@
|
||||
if(MOVE_INTENT_WALK)
|
||||
. += config.walk_speed
|
||||
|
||||
/mob/living/proc/makeTrail(turf/T)
|
||||
/mob/living/proc/makeTrail(turf/target_turf)
|
||||
if(!has_gravity())
|
||||
return
|
||||
var/blood_exists = 0
|
||||
var/blood_exists = FALSE
|
||||
|
||||
for(var/obj/effect/decal/cleanable/trail_holder/C in src.loc) //checks for blood splatter already on the floor
|
||||
blood_exists = 1
|
||||
if (isturf(src.loc))
|
||||
for(var/obj/effect/decal/cleanable/trail_holder/C in loc) //checks for blood splatter already on the floor
|
||||
blood_exists = TRUE
|
||||
if(isturf(loc))
|
||||
var/trail_type = getTrail()
|
||||
if(trail_type)
|
||||
var/brute_ratio = round(getBruteLoss()/maxHealth, 0.1)
|
||||
var/brute_ratio = round(getBruteLoss() / maxHealth, 0.1)
|
||||
if(blood_volume && blood_volume > max(BLOOD_VOLUME_NORMAL*(1 - brute_ratio * 0.25), 0))//don't leave trail if blood volume below a threshold
|
||||
blood_volume = max(blood_volume - max(1, brute_ratio * 2), 0) //that depends on our brute damage.
|
||||
var/newdir = get_dir(T, src.loc)
|
||||
if(newdir != src.dir)
|
||||
newdir = newdir | src.dir
|
||||
var/newdir = get_dir(target_turf, loc)
|
||||
if(newdir != dir)
|
||||
newdir = newdir | dir
|
||||
if(newdir == 3) //N + S
|
||||
newdir = NORTH
|
||||
else if(newdir == 12) //E + W
|
||||
newdir = EAST
|
||||
if((newdir in GLOB.cardinals) && (prob(50)))
|
||||
newdir = turn(get_dir(T, src.loc), 180)
|
||||
newdir = turn(get_dir(target_turf, loc), 180)
|
||||
if(!blood_exists)
|
||||
new /obj/effect/decal/cleanable/trail_holder(src.loc)
|
||||
for(var/obj/effect/decal/cleanable/trail_holder/TH in src.loc)
|
||||
new /obj/effect/decal/cleanable/trail_holder(loc)
|
||||
for(var/obj/effect/decal/cleanable/trail_holder/TH in loc)
|
||||
if((!(newdir in TH.existing_dirs) || trail_type == "trails_1" || trail_type == "trails_2") && TH.existing_dirs.len <= 16) //maximum amount of overlays is 16 (all light & heavy directions filled)
|
||||
TH.existing_dirs += newdir
|
||||
TH.add_overlay(image('icons/effects/blood.dmi', trail_type, dir = newdir))
|
||||
@@ -560,7 +563,7 @@
|
||||
|
||||
// climbing out of a gut
|
||||
if(attempt_vr(src,"vore_process_resist",args)) return TRUE
|
||||
|
||||
|
||||
//Breaking out of a container (Locker, sleeper, cryo...)
|
||||
else if(isobj(loc))
|
||||
var/obj/C = loc
|
||||
@@ -687,6 +690,7 @@
|
||||
who.equip_to_slot(what, where, TRUE)
|
||||
|
||||
/mob/living/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_SIX)
|
||||
throw_at(S,14,3, spin=1)
|
||||
else
|
||||
@@ -946,13 +950,14 @@
|
||||
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
|
||||
//Robots, animals and brains have their own version so don't worry about them
|
||||
/mob/living/proc/update_canmove()
|
||||
var/ko = IsKnockdown() || IsUnconscious() || stat || (status_flags & FAKEDEATH)
|
||||
var/ko = IsKnockdown() || IsUnconscious() || (stat && (stat != SOFT_CRIT || pulledby)) || (status_flags & FAKEDEATH)
|
||||
var/move_and_fall = stat == SOFT_CRIT && !pulledby
|
||||
var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK
|
||||
var/buckle_lying = !(buckled && !buckled.buckle_lying)
|
||||
var/has_legs = get_num_legs()
|
||||
var/has_arms = get_num_arms()
|
||||
var/ignore_legs = get_leg_ignore()
|
||||
if(ko || resting || has_status_effect(STATUS_EFFECT_STUN) || chokehold)
|
||||
if(ko || resting || move_and_fall || IsStun() || chokehold)
|
||||
drop_all_held_items()
|
||||
unset_machine()
|
||||
if(pulling)
|
||||
@@ -965,7 +970,7 @@
|
||||
else if(!lying)
|
||||
if(resting)
|
||||
fall()
|
||||
else if(ko || (!has_legs && !ignore_legs) || chokehold)
|
||||
else if(ko || move_and_fall || (!has_legs && !ignore_legs) || chokehold)
|
||||
fall(forced = 1)
|
||||
canmove = !(ko || resting || has_status_effect(STATUS_EFFECT_STUN) || has_status_effect(/datum/status_effect/freon) || chokehold || buckled || (!has_legs && !ignore_legs && !has_arms))
|
||||
density = !lying
|
||||
|
||||
@@ -75,3 +75,5 @@
|
||||
var/datum/riding/riding_datum
|
||||
|
||||
var/datum/language/selected_default_language
|
||||
|
||||
var/last_words //used for database logging
|
||||
|
||||
@@ -145,16 +145,18 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
|
||||
var/succumbed = FALSE
|
||||
|
||||
if(message_mode == MODE_WHISPER)
|
||||
var/fullcrit = InFullCritical()
|
||||
if((InCritical() && !fullcrit) || message_mode == MODE_WHISPER)
|
||||
message_range = 1
|
||||
spans |= SPAN_ITALICS
|
||||
message_mode = MODE_WHISPER
|
||||
log_talk(src,"[key_name(src)] : [message]",LOGWHISPER)
|
||||
if(in_critical)
|
||||
if(fullcrit)
|
||||
var/health_diff = round(-HEALTH_THRESHOLD_DEAD + health)
|
||||
// If we cut our message short, abruptly end it with a-..
|
||||
var/message_len = length(message)
|
||||
message = copytext(message, 1, health_diff) + "[message_len > health_diff ? "-.." : "..."]"
|
||||
message = Ellipsis(message, 10, 1)
|
||||
last_words = message
|
||||
message_mode = MODE_WHISPER_CRIT
|
||||
succumbed = TRUE
|
||||
else
|
||||
@@ -164,7 +166,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
if(!message)
|
||||
return
|
||||
|
||||
spans += get_spans()
|
||||
spans |= get_spans()
|
||||
|
||||
if(language)
|
||||
var/datum/language/L = GLOB.language_datum_instances[language]
|
||||
@@ -295,10 +297,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
|
||||
/mob/living/proc/get_message_mode(message)
|
||||
var/key = copytext(message, 1, 2)
|
||||
if(key == ";")
|
||||
return MODE_HEADSET
|
||||
else if(key == "#")
|
||||
if(key == "#")
|
||||
return MODE_WHISPER
|
||||
else if(key == ";")
|
||||
return MODE_HEADSET
|
||||
else if(length(message) > 2 && (key in GLOB.department_radio_prefixes))
|
||||
var/key_symbol = lowertext(copytext(message, 2, 3))
|
||||
return GLOB.department_radio_keys[key_symbol]
|
||||
@@ -384,6 +386,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
|
||||
/mob/living/proc/radio(message, message_mode, list/spans, language)
|
||||
switch(message_mode)
|
||||
if(MODE_WHISPER)
|
||||
return ITALICS
|
||||
if(MODE_R_HAND)
|
||||
for(var/obj/item/r_hand in get_held_items_for_side("r", all = TRUE))
|
||||
if (r_hand)
|
||||
|
||||
@@ -465,7 +465,7 @@
|
||||
set category = "AI Commands"
|
||||
set name = "Access Robot Control"
|
||||
set desc = "Wirelessly control various automatic robots."
|
||||
if(stat == 2)
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
|
||||
if(control_disabled)
|
||||
@@ -585,7 +585,7 @@
|
||||
cameraFollow = null
|
||||
var/cameralist[0]
|
||||
|
||||
if(stat == 2)
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
@@ -629,7 +629,7 @@
|
||||
set category = "AI Commands"
|
||||
set name = "AI Status"
|
||||
|
||||
if(stat == 2)
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
var/list/ai_emotions = list("Very Happy", "Happy", "Neutral", "Unsure", "Confused", "Sad", "BSOD", "Blank", "Problems?", "Awesome", "Facepalm", "Friend Computer", "Dorfy", "Blue Glow", "Red Glow")
|
||||
var/emote = input("Please, select a status!", "AI Status", null, null) in ai_emotions
|
||||
@@ -652,7 +652,7 @@
|
||||
set desc = "Change the default hologram available to AI to something else."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(stat == 2)
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
var/input
|
||||
switch(alert("Would you like to select a hologram based on a crew member, an animal, or switch to a unique avatar?",,"Crew Member","Unique","Animal"))
|
||||
@@ -774,7 +774,7 @@
|
||||
set desc = "Allows you to change settings of your radio."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(stat == 2)
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
|
||||
to_chat(src, "Accessing Subspace Transceiver control...")
|
||||
@@ -790,7 +790,7 @@
|
||||
set desc = "Modify the default radio setting for your automatic announcements."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(stat == 2)
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
set_autosay()
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
set category = "AI Commands"
|
||||
set name = "Toggle Camera Acceleration"
|
||||
|
||||
if(usr.stat == 2)
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
acceleration = !acceleration
|
||||
to_chat(usr, "Camera acceleration has been toggled [acceleration ? "on" : "off"].")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/mob/living/silicon/ai/proc/show_laws_verb()
|
||||
set category = "AI Commands"
|
||||
set name = "Show Laws"
|
||||
if(usr.stat == 2)
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
src.show_laws()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/silicon/ai/say(message, language)
|
||||
if(parent && istype(parent) && parent.stat != 2) //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
|
||||
if(parent && istype(parent) && parent.stat != DEAD) //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
|
||||
parent.say(message, language)
|
||||
return
|
||||
..(message)
|
||||
@@ -71,7 +71,7 @@
|
||||
set desc = "Display a list of vocal words to announce to the crew."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(usr.stat == 2)
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
|
||||
var/dat = "Here is a list of words you can type into the 'Announcement' button to create sentences to vocally announce to everyone on the same level at you.<BR> \
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
if(temp)
|
||||
left_part = temp
|
||||
else if(src.stat == 2) // Show some flavor text if the pAI is dead
|
||||
else if(src.stat == DEAD) // Show some flavor text if the pAI is dead
|
||||
left_part = "<b><font color=red><3E>Rr<52>R <20>a<EFBFBD><61> <20><>Rr<52><72><EFBFBD><EFBFBD>o<EFBFBD></font></b>"
|
||||
right_part = "<pre>Program index hash not found</pre>"
|
||||
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
var/d_hud = DATA_HUD_DIAGNOSTIC //There is only one kind of diag hud
|
||||
|
||||
var/law_change_counter = 0
|
||||
var/obj/machinery/camera/builtInCamera = null
|
||||
var/updating = FALSE //portable camera camerachunk update
|
||||
var/obj/machinery/camera/builtInCamera = null
|
||||
var/updating = FALSE //portable camera camerachunk update
|
||||
|
||||
/mob/living/silicon/Initialize()
|
||||
. = ..()
|
||||
. = ..()
|
||||
GLOB.silicon_mobs += src
|
||||
var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC]
|
||||
diag_hud.add_to_hud(src)
|
||||
@@ -56,7 +56,7 @@
|
||||
/mob/living/silicon/Destroy()
|
||||
radio = null
|
||||
aicamera = null
|
||||
QDEL_NULL(builtInCamera)
|
||||
QDEL_NULL(builtInCamera)
|
||||
GLOB.silicon_mobs -= src
|
||||
return ..()
|
||||
|
||||
@@ -310,7 +310,7 @@
|
||||
else //For department channels, if any, given by the internal radio.
|
||||
for(var/key in GLOB.department_radio_keys)
|
||||
if(GLOB.department_radio_keys[key] == Autochan)
|
||||
radiomod = key
|
||||
radiomod = ":" + key
|
||||
break
|
||||
|
||||
to_chat(src, "<span class='notice'>Automatic announcements [Autochan == "None" ? "will not use the radio." : "set to [Autochan]."]</span>")
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
desc = "A security robot. He looks less than thrilled."
|
||||
icon = 'icons/mob/aibots.dmi'
|
||||
icon_state = "ed2090"
|
||||
density = TRUE
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
anchored = FALSE
|
||||
health = 100
|
||||
maxHealth = 100
|
||||
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
@@ -59,7 +59,7 @@
|
||||
shot_delay = 6//Longer shot delay because JESUS CHRIST
|
||||
check_records = 0//Don't actively target people set to arrest
|
||||
arrest_type = 1//Don't even try to cuff
|
||||
bot_core.req_access = list(ACCESS_MAINT_TUNNELS, ACCESS_THEATRE)
|
||||
bot_core.req_access = list(ACCESS_MAINT_TUNNELS, ACCESS_THEATRE)
|
||||
arrest_type = 1
|
||||
if((lasercolor == "b") && (name == "\improper ED-209 Security Robot"))//Picks a name if there isn't already a custome one
|
||||
name = pick("BLUE BALLER","SANIC","BLUE KILLDEATH MURDERBOT")
|
||||
@@ -83,7 +83,7 @@
|
||||
..()
|
||||
target = null
|
||||
oldtarget_name = null
|
||||
anchored = FALSE
|
||||
anchored = FALSE
|
||||
walk_to(src,0)
|
||||
last_found = world.time
|
||||
set_weapon()
|
||||
@@ -153,7 +153,7 @@ Auto Patrol[]"},
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/judgement_criteria()
|
||||
var/final = FALSE
|
||||
var/final = FALSE
|
||||
if(idcheck)
|
||||
final = final|JUDGE_IDCHECK
|
||||
if(check_records)
|
||||
@@ -201,7 +201,7 @@ Auto Patrol[]"},
|
||||
set_weapon()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/bullet_act(obj/item/projectile/Proj)
|
||||
if(istype(Proj , /obj/item/projectile/beam/laser)||istype(Proj, /obj/item/projectile/bullet))
|
||||
if(istype(Proj , /obj/item/projectile/beam/laser)||istype(Proj, /obj/item/projectile/bullet))
|
||||
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
|
||||
if(!Proj.nodamage && Proj.damage < src.health)
|
||||
retaliate(Proj.firer)
|
||||
@@ -254,7 +254,7 @@ Auto Patrol[]"},
|
||||
stun_attack(target)
|
||||
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = TRUE
|
||||
anchored = TRUE
|
||||
target_lastloc = target.loc
|
||||
return
|
||||
|
||||
@@ -288,7 +288,7 @@ Auto Patrol[]"},
|
||||
|
||||
if(BOT_ARREST)
|
||||
if(!target)
|
||||
anchored = FALSE
|
||||
anchored = FALSE
|
||||
mode = BOT_IDLE
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
@@ -303,7 +303,7 @@ Auto Patrol[]"},
|
||||
return
|
||||
else
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = FALSE
|
||||
anchored = FALSE
|
||||
|
||||
if(BOT_START_PATROL)
|
||||
look_for_perp()
|
||||
@@ -317,7 +317,7 @@ Auto Patrol[]"},
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/back_to_idle()
|
||||
anchored = FALSE
|
||||
anchored = FALSE
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
last_found = world.time
|
||||
@@ -325,7 +325,7 @@ Auto Patrol[]"},
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action) //ensure bot quickly responds
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/back_to_hunt()
|
||||
anchored = FALSE
|
||||
anchored = FALSE
|
||||
frustration = 0
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action) //ensure bot quickly responds
|
||||
@@ -335,7 +335,7 @@ Auto Patrol[]"},
|
||||
/mob/living/simple_animal/bot/ed209/proc/look_for_perp()
|
||||
if(disabled)
|
||||
return
|
||||
anchored = FALSE
|
||||
anchored = FALSE
|
||||
threatlevel = 0
|
||||
var/judgement_criteria = judgement_criteria()
|
||||
for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
|
||||
@@ -464,7 +464,7 @@ Auto Patrol[]"},
|
||||
new /obj/effect/temp_visual/emp(loc)
|
||||
var/list/mob/living/carbon/targets = new
|
||||
for(var/mob/living/carbon/C in view(12,src))
|
||||
if(C.stat==2)
|
||||
if(C.stat==DEAD)
|
||||
continue
|
||||
targets += C
|
||||
if(targets.len)
|
||||
@@ -476,7 +476,7 @@ Auto Patrol[]"},
|
||||
emagged = 2
|
||||
set_weapon()
|
||||
shootAt(toshoot)
|
||||
emagged = FALSE
|
||||
emagged = FALSE
|
||||
set_weapon()
|
||||
else
|
||||
shootAt(toshoot)
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
oldpatient = user
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/process_scan(mob/living/carbon/human/H)
|
||||
if(H.stat == 2)
|
||||
if(H.stat == DEAD)
|
||||
return
|
||||
|
||||
if((H == oldpatient) && (world.time < last_found + 200))
|
||||
|
||||
@@ -28,3 +28,6 @@
|
||||
. = ..()
|
||||
var/newcolor = rgb(rand(0, 255), rand(0, 255), rand(0, 255))
|
||||
add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY)
|
||||
|
||||
/mob/living/simple_animal/butterfly/bee_friendly()
|
||||
return TRUE //treaty signed at the Beeneeva convention
|
||||
|
||||
@@ -113,14 +113,17 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Runtime.sav")
|
||||
S["family"] >> family
|
||||
|
||||
var/json_file = file("data/npc_saves/Runtime.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
family = json["family"]
|
||||
if(isnull(family))
|
||||
family = list()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Write_Memory(dead)
|
||||
var/savefile/S = new /savefile("data/npc_saves/Runtime.sav")
|
||||
var/json_file = file("data/npc_saves/Runtime.json")
|
||||
family = list()
|
||||
if(!dead)
|
||||
for(var/mob/living/simple_animal/pet/cat/kitten/C in children)
|
||||
@@ -130,7 +133,8 @@
|
||||
family[C.type] += 1
|
||||
else
|
||||
family[C.type] = 1
|
||||
WRITE_FILE(S["family"], family)
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(family))
|
||||
memory_saved = 1
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Deploy_The_Cats()
|
||||
@@ -271,4 +275,4 @@
|
||||
..()
|
||||
if(L.a_intent == INTENT_HARM && L.reagents && !stat)
|
||||
L.reagents.add_reagent("nutriment", 0.4)
|
||||
L.reagents.add_reagent("vitamin", 0.4)
|
||||
L.reagents.add_reagent("vitamin", 0.4)
|
||||
@@ -328,33 +328,37 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/proc/Read_Memory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Ian.sav")
|
||||
S["age"] >> age
|
||||
S["record_age"] >> record_age
|
||||
S["saved_head"] >> saved_head
|
||||
|
||||
var/json_file = file("data/npc_saves/Ian.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
age = json["age"]
|
||||
record_age = json["record_age"]
|
||||
saved_head = json["saved_head"]
|
||||
if(isnull(age))
|
||||
age = 0
|
||||
if(isnull(record_age))
|
||||
record_age = 1
|
||||
|
||||
if(saved_head)
|
||||
place_on_head(new saved_head)
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/proc/Write_Memory(dead)
|
||||
var/savefile/S = new /savefile("data/npc_saves/Ian.sav")
|
||||
var/json_file = file("data/npc_saves/Ian.json")
|
||||
var/list/file_data = list()
|
||||
if(!dead)
|
||||
WRITE_FILE(S["age"], age + 1)
|
||||
file_data["age"] = age + 1
|
||||
if((age + 1) > record_age)
|
||||
WRITE_FILE(S["record_age"], record_age + 1)
|
||||
file_data["record_age"] = record_age + 1
|
||||
if(inventory_head)
|
||||
WRITE_FILE(S["saved_head"], inventory_head.type)
|
||||
file_data["saved_head"] = inventory_head.type
|
||||
else
|
||||
WRITE_FILE(S["age"], 0)
|
||||
WRITE_FILE(S["saved_head"], null)
|
||||
file_data["age"] = 0
|
||||
file_data["saved_head"] = null
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
memory_saved = 1
|
||||
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/Life()
|
||||
..()
|
||||
|
||||
@@ -565,4 +569,4 @@
|
||||
emote("me", 1, "yaps happily!")
|
||||
else
|
||||
if(M && stat != DEAD) // Same check here, even though emote checks it as well (poor form to check it only in the help case)
|
||||
emote("me", 1, "growls!")
|
||||
emote("me", 1, "growls!")
|
||||
@@ -15,6 +15,10 @@
|
||||
/mob/living/simple_animal/drone/verb/toggle_light()
|
||||
set category = "Drone"
|
||||
set name = "Toggle drone light"
|
||||
|
||||
if(stat == DEAD)
|
||||
to_chat(src, "<span class='warning'>There's no light in your life... by that I mean you're dead.</span>")
|
||||
return
|
||||
if(light_on)
|
||||
set_light(0)
|
||||
else
|
||||
|
||||
@@ -24,11 +24,17 @@
|
||||
butcher_results = list()
|
||||
gold_core_spawnable = 2
|
||||
|
||||
/mob/living/simple_animal/pet/penguin/emperor/shamebrero
|
||||
name = "Shamebrero penguin."
|
||||
desc = "Shameful of all he surveys."
|
||||
icon_state = "penguin_shamebrero"
|
||||
icon_living = "penguin_shamebrero"
|
||||
|
||||
/mob/living/simple_animal/pet/penguin/baby
|
||||
speak = list("gah", "noot noot", "noot!", "noot", "squeee!", "noo!")
|
||||
name = "Penguin chick"
|
||||
real_name = "penguin"
|
||||
desc = "Can't fly and can barely waddles, but the prince of all chicks."
|
||||
desc = "Can't fly and barely waddles, yet the prince of all chicks."
|
||||
icon_state = "penguin_baby"
|
||||
icon_living = "penguin_baby"
|
||||
icon_dead = "penguin_baby_dead"
|
||||
|
||||
@@ -57,7 +57,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/med_hud_set_health()
|
||||
if(summoner)
|
||||
if(!QDELETED(summoner))
|
||||
var/image/holder = hud_list[HEALTH_HUD]
|
||||
holder.icon_state = "hud[RoundHealth(summoner)]"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "A Perfectly Generic Boss Placeholder"
|
||||
desc = ""
|
||||
robust_searching = 1
|
||||
stat_attack = 1
|
||||
stat_attack = UNCONSCIOUS
|
||||
status_flags = 0
|
||||
a_intent = INTENT_HARM
|
||||
gender = NEUTER
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
speed = 0
|
||||
maxHealth = 80
|
||||
health = 80
|
||||
stat_attack = 1
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = 1
|
||||
|
||||
harm_intent_damage = 10
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
faction = list("creature")
|
||||
robust_searching = 1
|
||||
stat_attack = 2
|
||||
stat_attack = DEAD
|
||||
obj_damage = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
speak_emote = list("squeaks")
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
var/ranged_message = "fires" //Fluff text for ranged mobs
|
||||
var/ranged_cooldown = 0 //What the current cooldown on ranged attacks is, generally world.time + ranged_cooldown_time
|
||||
var/ranged_cooldown_time = 30 //How long, in deciseconds, the cooldown of ranged attacks is
|
||||
var/ranged_telegraph = "prepares to fire at *TARGET*!" //A message shown when the mob prepares to fire; use *TARGET* if you want to show the target's name
|
||||
var/ranged_telegraph_sound //A sound played when the mob prepares to fire
|
||||
var/ranged_telegraph_time = 0 //In deciseconds, how long between the telegraph and ranged shot
|
||||
var/ranged_ignores_vision = FALSE //if it'll fire ranged attacks even if it lacks vision on its target, only works with environment smash
|
||||
var/check_friendly_fire = 0 // Should the ranged mob check for friendlies when shooting
|
||||
var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat.
|
||||
@@ -43,8 +46,8 @@
|
||||
var/search_objects_timer_id //Timer for regaining our old search_objects value after being attacked
|
||||
var/search_objects_regain_time = 30 //the delay between being attacked and gaining our old search_objects value back
|
||||
var/list/wanted_objects = list() //A typecache of objects types that will be checked against to attack, should we have search_objects enabled
|
||||
var/stat_attack = 0 //Mobs with stat_attack to 1 will attempt to attack things that are unconscious, Mobs with stat_attack set to 2 will attempt to attack the dead.
|
||||
var/stat_exclusive = 0 //Mobs with this set to 1 will exclusively attack things defined by stat_attack, stat_attack 2 means they will only attack corpses
|
||||
var/stat_attack = CONSCIOUS //Mobs with stat_attack to UNCONSCIOUS will attempt to attack things that are unconscious, Mobs with stat_attack set to 2 will attempt to attack the dead.
|
||||
var/stat_exclusive = FALSE //Mobs with this set to TRUE will exclusively attack things defined by stat_attack, stat_attack 2 means they will only attack corpses
|
||||
var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction
|
||||
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
|
||||
var/atom/targets_from = null //all range/attack/etc. calculations should be done from this atom, defaults to the mob itself, useful for Vehicles and such
|
||||
@@ -171,7 +174,7 @@
|
||||
var/mob/living/L = the_target
|
||||
var/faction_check = faction_check_mob(L)
|
||||
if(robust_searching)
|
||||
if(L.stat > stat_attack || L.stat != stat_attack && stat_exclusive == 1)
|
||||
if(L.stat > stat_attack || L.stat != stat_attack && stat_exclusive)
|
||||
return 0
|
||||
if(faction_check && !attack_same || !faction_check && attack_same == 2)
|
||||
return 0
|
||||
@@ -232,7 +235,14 @@
|
||||
var/target_distance = get_dist(targets_from,target)
|
||||
if(ranged) //We ranged? Shoot at em
|
||||
if(!target.Adjacent(targets_from) && ranged_cooldown <= world.time) //But make sure they're not in range for a melee attack and our range attack is off cooldown
|
||||
OpenFire(target)
|
||||
if(!ranged_telegraph_time || client)
|
||||
OpenFire(target)
|
||||
else
|
||||
if(ranged_telegraph)
|
||||
visible_message("<span class='danger'>[src] [replacetext(ranged_telegraph, "*TARGET*", "[target]")]</span>")
|
||||
if(ranged_telegraph_sound)
|
||||
playsound(src, ranged_telegraph_sound, 75, FALSE)
|
||||
addtimer(CALLBACK(src, .proc/OpenFire, target), ranged_telegraph_time)
|
||||
if(!Process_Spacemove()) //Drifting
|
||||
walk(src,0)
|
||||
return 1
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
pixel_x = -16
|
||||
layer = LARGE_MOB_LAYER
|
||||
speed = 10
|
||||
stat_attack = 1
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = 1
|
||||
var/hopping = FALSE
|
||||
var/hop_cooldown = 0 //Strictly for player controlled leapers
|
||||
|
||||
@@ -277,19 +277,24 @@ Difficulty: Very Hard
|
||||
WriteMemory()
|
||||
|
||||
/obj/machinery/smartfridge/black_box/proc/WriteMemory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Blackbox.sav")
|
||||
var/json_file = file("data/npc_saves/Blackbox.json")
|
||||
stored_items = list()
|
||||
|
||||
for(var/obj/O in (contents-component_parts))
|
||||
stored_items += O.type
|
||||
|
||||
WRITE_FILE(S["stored_items"], stored_items)
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = stored_items
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
memory_saved = TRUE
|
||||
|
||||
/obj/machinery/smartfridge/black_box/proc/ReadMemory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Blackbox.sav")
|
||||
S["stored_items"] >> stored_items
|
||||
|
||||
var/json_file = file("data/npc_saves/Blackbox.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
stored_items = json["data"]
|
||||
if(isnull(stored_items))
|
||||
stored_items = list()
|
||||
|
||||
@@ -782,4 +787,4 @@ Difficulty: Very Hard
|
||||
#undef ACTIVATE_WEAPON
|
||||
#undef ACTIVATE_MAGIC
|
||||
|
||||
#undef MEDAL_PREFIX
|
||||
#undef MEDAL_PREFIX
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user