Merge remote-tracking branch 'citadel/master' into combat_rework

This commit is contained in:
kevinz000
2020-04-08 04:04:45 -07:00
919 changed files with 148968 additions and 10144 deletions
+2 -2
View File
@@ -25,7 +25,7 @@
to_chat(usr, "You seem to be selecting a mob that doesn't exist anymore.")
return
var/body = "<html><head><title>Options for [M.key]</title></head>"
var/body = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Options for [M.key]</title></head>"
body += "<body>Options panel for <b>[M]</b>"
if(M.client)
body += " played by <b>[M.client]</b> "
@@ -194,7 +194,7 @@
body += "<A href='?_src_=holder;[HrefToken()];tdomeadmin=[REF(M)]'>Thunderdome Admin</A> | "
body += "<A href='?_src_=holder;[HrefToken()];tdomeobserve=[REF(M)]'>Thunderdome Observer</A> | "
body += "<A href='?_src_=holder;[HrefToken()];makementor=[M.ckey]'>Make mentor</A> | "
body += "<A href='?_src_=holder;[HrefToken()];removementor=[M.ckey]'>Remove mentor</A>"
body += "<A href='?_src_=holder;[HrefToken()];removementor=[M.ckey]'>Remove mentor</A> | "
body += "<A href='?_src_=holder;[HrefToken()];makeeligible=[REF(M)]'>Allow reentering round</A>"
body += "<br>"
body += "</body></html>"
+1
View File
@@ -74,6 +74,7 @@ GLOBAL_PROTECT(admin_verbs_admin)
/client/proc/addbunkerbypass,
/client/proc/revokebunkerbypass,
/client/proc/stop_sounds,
/client/proc/mark_datum_mapview,
/client/proc/hide_verbs, /*hides all our adminverbs*/
/client/proc/hide_most_verbs, /*hides all our hideable adminverbs*/
/datum/admins/proc/open_borgopanel
+208
View File
@@ -0,0 +1,208 @@
/client/proc/callproc()
set category = "Debug"
set name = "Advanced ProcCall"
set waitfor = FALSE
callproc_blocking()
/client/proc/callproc_blocking(list/get_retval)
if(!check_rights(R_DEBUG))
return
var/datum/target
var/targetselected = FALSE
var/returnval
switch(alert("Proc owned by something?",,"Yes","No"))
if("Yes")
targetselected = TRUE
var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT, VV_MARKED_DATUM, VV_TEXT_LOCATE, VV_PROCCALL_RETVAL))
if (!value["class"] || !value["value"])
return
target = value["value"]
if(!istype(target))
to_chat(usr, "<span class='danger'>Invalid target.</span>")
return
if("No")
target = null
targetselected = FALSE
var/procpath = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
if(!procpath)
return
//strip away everything but the proc name
var/list/proclist = splittext(procpath, "/")
if (!length(proclist))
return
var/procname = proclist[proclist.len]
var/proctype = ("verb" in proclist) ? "verb" :"proc"
if(targetselected)
if(!hascall(target, procname))
to_chat(usr, "<span class='warning'>Error: callproc(): type [target.type] has no [proctype] named [procpath].</span>")
return
else
procpath = "/[proctype]/[procname]"
if(!text2path(procpath))
to_chat(usr, "<span class='warning'>Error: callproc(): [procpath] does not exist.</span>")
return
var/list/lst = get_callproc_args()
if(!lst)
return
if(targetselected)
if(!target)
to_chat(usr, "<font color='red'>Error: callproc(): owner of proc no longer exists.</font>")
return
var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
log_admin(msg)
message_admins(msg) //Proccall announce removed.
admin_ticket_log(target, msg)
returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc
else
//this currently has no hascall protection. wasn't able to get it working.
log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") //Proccall announce removed.
returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc
SSblackbox.record_feedback("tally", "admin_verb", 1, "Advanced ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(get_retval)
get_retval += returnval
. = get_callproc_returnval(returnval, procname)
if(.)
to_chat(usr, .)
GLOBAL_VAR(AdminProcCaller)
GLOBAL_PROTECT(AdminProcCaller)
GLOBAL_VAR_INIT(AdminProcCallCount, 0)
GLOBAL_PROTECT(AdminProcCallCount)
GLOBAL_VAR(LastAdminCalledTargetRef)
GLOBAL_PROTECT(LastAdminCalledTargetRef)
GLOBAL_VAR(LastAdminCalledTarget)
GLOBAL_PROTECT(LastAdminCalledTarget)
GLOBAL_VAR(LastAdminCalledProc)
GLOBAL_PROTECT(LastAdminCalledProc)
GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention)
GLOBAL_PROTECT(AdminProcCallSpamPrevention)
/proc/WrapAdminProcCall(datum/target, procname, list/arguments)
if(target != GLOBAL_PROC && procname == "Del")
to_chat(usr, "<span class='warning'>Calling Del() is not allowed</span>")
return
if(target != GLOBAL_PROC && !target.CanProcCall(procname))
to_chat(usr, "Proccall on [target.type]/proc/[procname] is disallowed!")
return
var/current_caller = GLOB.AdminProcCaller
var/ckey = usr ? usr.client.ckey : GLOB.AdminProcCaller
if(!ckey)
CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]")
if(current_caller && current_caller != ckey)
if(!GLOB.AdminProcCallSpamPrevention[ckey])
to_chat(usr, "<span class='adminnotice'>Another set of admin called procs are still running, your proc will be run after theirs finish.</span>")
GLOB.AdminProcCallSpamPrevention[ckey] = TRUE
UNTIL(!GLOB.AdminProcCaller)
to_chat(usr, "<span class='adminnotice'>Running your proc</span>")
GLOB.AdminProcCallSpamPrevention -= ckey
else
UNTIL(!GLOB.AdminProcCaller)
GLOB.LastAdminCalledProc = procname
if(target != GLOBAL_PROC)
GLOB.LastAdminCalledTargetRef = "[REF(target)]"
GLOB.AdminProcCaller = ckey //if this runtimes, too bad for you
++GLOB.AdminProcCallCount
. = world.WrapAdminProcCall(target, procname, arguments)
if(--GLOB.AdminProcCallCount == 0)
GLOB.AdminProcCaller = null
//adv proc call this, ya nerds
/world/proc/WrapAdminProcCall(datum/target, procname, list/arguments)
if(target == GLOBAL_PROC)
return call(procname)(arglist(arguments))
else if(target != world)
return call(target, procname)(arglist(arguments))
else
log_admin_private("[key_name(usr)] attempted to call world/proc/[procname] with arguments: [english_list(arguments)]")
/proc/IsAdminAdvancedProcCall()
#ifdef TESTING
return FALSE
#else
return usr && usr.client && GLOB.AdminProcCaller == usr.client.ckey
#endif
/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf)
set category = "Debug"
set name = "Atom ProcCall"
set waitfor = FALSE
if(!check_rights(R_DEBUG))
return
var/procname = input("Proc name, eg: fake_blood","Proc:", null) as text|null
if(!procname)
return
if(!hascall(A,procname))
to_chat(usr, "<span class='warning'>Error: callproc_datum(): type [A.type] has no proc named [procname].</span>")
return
var/list/lst = get_callproc_args()
if(!lst)
return
if(!A || !IsValidSrc(A))
to_chat(usr, "<span class='warning'>Error: callproc_datum(): owner of proc no longer exists.</span>")
return
var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
log_admin(msg)
message_admins(msg)
admin_ticket_log(A, msg)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Atom ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
var/returnval = WrapAdminProcCall(A, procname, lst) // Pass the lst as an argument list to the proc
. = get_callproc_returnval(returnval,procname)
if(.)
to_chat(usr, .)
/client/proc/get_callproc_args()
var/argnum = input("Number of arguments","Number:",0) as num|null
if(isnull(argnum))
return
. = list()
var/list/named_args = list()
while(argnum--)
var/named_arg = input("Leave blank for positional argument. Positional arguments will be considered as if they were added first.", "Named argument") as text|null
var/value = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT))
if (!value["class"])
return
if(named_arg)
named_args[named_arg] = value["value"]
else
. += value["value"]
if(LAZYLEN(named_args))
. += named_args
/client/proc/get_callproc_returnval(returnval,procname)
. = ""
if(islist(returnval))
var/list/returnedlist = returnval
. = "<span class='notice'>"
if(returnedlist.len)
var/assoc_check = returnedlist[1]
if(istext(assoc_check) && (returnedlist[assoc_check] != null))
. += "[procname] returned an associative list:"
for(var/key in returnedlist)
. += "\n[key] = [returnedlist[key]]"
else
. += "[procname] returned a list:"
for(var/elem in returnedlist)
. += "\n[elem]"
else
. = "[procname] returned an empty list"
. += "</span>"
else
. = "<span class='notice'>[procname] returned: [!isnull(returnval) ? returnval : "null"]</span>"
+1 -1
View File
@@ -136,7 +136,7 @@
if(!SSticker.HasRoundStarted())
alert("The game hasn't started yet!")
return
var/list/dat = list("<html><head><title>Round Status</title></head><body><h1><B>Round Status</B></h1>")
var/list/dat = list("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Round Status</title></head><body><h1><B>Round Status</B></h1>")
if(SSticker.mode.replacementmode)
dat += "Former Game Mode: <B>[SSticker.mode.name]</B><BR>"
dat += "Replacement Game Mode: <B>[SSticker.mode.replacementmode.name]</B><BR>"
+1 -1
View File
@@ -45,6 +45,6 @@
SEND_SIGNAL(H, COMSIG_HUMAN_ON_RANDOMIZE)
H.update_body()
H.update_body(TRUE)
H.update_hair()
H.update_body_parts()
+3 -1
View File
@@ -83,7 +83,9 @@
<hr style='background:#000000; border:0; height:1px'>"}
qdel(query_check_unused_rank)
else if(!action)
output += {"<head>
output += {"
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<title>Permissions Panel</title>
<script type='text/javascript' src='search.js'></script>
</head>
+1 -1
View File
@@ -2,7 +2,7 @@
if(!check_rights())
return
log_admin("[key_name(usr)] checked the player panel.")
var/dat = "<html><head><title>Player Panel</title></head>"
var/dat = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Player Panel</title></head>"
//javascript, the part that does most of the work~
dat += {"
+2 -2
View File
@@ -79,7 +79,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
title = "Resolved Tickets"
if(!l2b)
return
var/list/dat = list("<html><head><title>[title]</title></head>")
var/list/dat = list("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>[title]</title></head>")
dat += "<A href='?_src_=holder;[HrefToken()];ahelp_tickets=[state]'>Refresh</A><br><br>"
for(var/I in l2b)
var/datum/admin_help/AH = I
@@ -401,7 +401,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
//Show the ticket panel
/datum/admin_help/proc/TicketPanel()
var/list/dat = list("<html><head><title>Ticket #[id]</title></head>")
var/list/dat = list("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Ticket #[id]</title></head>")
var/ref_src = "[REF(src)]"
dat += "<h4>Admin Help Ticket #[id]: [LinkedReplyName(ref_src)]</h4>"
dat += "<b>State: "
-268
View File
@@ -15,214 +15,6 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Debug Two") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/* 21st Sept 2010
Updated by Skie -- Still not perfect but better!
Stuff you can't do:
Call proc /mob/proc/Dizzy() for some player
Because if you select a player mob as owner it tries to do the proc for
/mob/living/carbon/human/ instead. And that gives a run-time error.
But you can call procs that are of type /mob/living/carbon/human/proc/ for that player.
*/
/client/proc/callproc()
set category = "Debug"
set name = "Advanced ProcCall"
set waitfor = FALSE
if(!check_rights(R_DEBUG))
return
var/datum/target = null
var/targetselected = FALSE
var/returnval = null
if(alert("Proc owned by something?",,"Yes","No") == "Yes")
targetselected = TRUE
var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT))
if (!value["class"] || !value["value"])
return
target = value["value"]
var/procpath = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
if(!procpath)
return
//strip away everything but the proc name
var/list/proclist = splittext(procpath, "/")
if (!length(proclist))
return
var/procname = proclist[proclist.len]
var/proctype = ("verb" in proclist) ? "verb" :"proc"
if(targetselected)
if(!hascall(target, procname))
to_chat(usr, "<span class='warning'>Error: callproc(): type [target.type] has no [proctype] named [procpath].</span>")
return
else
procpath = "/[proctype]/[procname]"
if(!text2path(procpath))
to_chat(usr, "<span class='warning'>Error: callproc(): [procpath] does not exist.</span>")
return
var/list/lst = get_callproc_args()
if(!lst)
return
if(targetselected)
if(!target)
to_chat(usr, "<span class='warning'>Error: callproc(): owner of proc no longer exists.</span>")
return
var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no argument"]."
log_admin(msg)
message_admins(msg)
admin_ticket_log(target, msg)
returnval = WrapAdminProcCall(target, procname, lst)
else
var/msg = "[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no argument"]."
log_admin(msg)
message_admins(msg)
returnval = WrapAdminProcCall(GLOBAL_PROC, procpath, lst) //calling globals needs full qualified name (e.g /proc/foo)
. = get_callproc_returnval(returnval, procname)
if(.)
to_chat(usr, .)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Advanced ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
GLOBAL_VAR(AdminProcCaller)
GLOBAL_PROTECT(AdminProcCaller)
GLOBAL_VAR_INIT(AdminProcCallCount, 0)
GLOBAL_PROTECT(AdminProcCallCount)
GLOBAL_VAR(LastAdminCalledTargetRef)
GLOBAL_PROTECT(LastAdminCalledTargetRef)
GLOBAL_VAR(LastAdminCalledTarget)
GLOBAL_PROTECT(LastAdminCalledTarget)
GLOBAL_VAR(LastAdminCalledProc)
GLOBAL_PROTECT(LastAdminCalledProc)
GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention)
GLOBAL_PROTECT(AdminProcCallSpamPrevention)
/proc/WrapAdminProcCall(datum/target, procname, list/arguments)
if(target != GLOBAL_PROC && procname == "Del")
to_chat(usr, "<span class='warning'>Calling Del() is not allowed</span>")
return
if(target != GLOBAL_PROC && !target.CanProcCall(procname))
to_chat(usr, "Proccall on [target.type]/proc/[procname] is disallowed!")
return
var/current_caller = GLOB.AdminProcCaller
var/ckey = usr ? usr.client.ckey : GLOB.AdminProcCaller
if(!ckey)
CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]")
if(current_caller && current_caller != ckey)
if(!GLOB.AdminProcCallSpamPrevention[ckey])
to_chat(usr, "<span class='adminnotice'>Another set of admin called procs are still running, your proc will be run after theirs finish.</span>")
GLOB.AdminProcCallSpamPrevention[ckey] = TRUE
UNTIL(!GLOB.AdminProcCaller)
to_chat(usr, "<span class='adminnotice'>Running your proc</span>")
GLOB.AdminProcCallSpamPrevention -= ckey
else
UNTIL(!GLOB.AdminProcCaller)
GLOB.LastAdminCalledProc = procname
if(target != GLOBAL_PROC)
GLOB.LastAdminCalledTargetRef = "[REF(target)]"
GLOB.AdminProcCaller = ckey //if this runtimes, too bad for you
++GLOB.AdminProcCallCount
. = world.WrapAdminProcCall(target, procname, arguments)
if(--GLOB.AdminProcCallCount == 0)
GLOB.AdminProcCaller = null
//adv proc call this, ya nerds
/world/proc/WrapAdminProcCall(datum/target, procname, list/arguments)
if(target == GLOBAL_PROC)
return call(procname)(arglist(arguments))
else if(target != world)
return call(target, procname)(arglist(arguments))
else
log_admin_private("[key_name(usr)] attempted to call world/proc/[procname] with arguments: [english_list(arguments)]")
/proc/IsAdminAdvancedProcCall()
#ifdef TESTING
return FALSE
#else
return usr && usr.client && GLOB.AdminProcCaller == usr.client.ckey
#endif
/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf)
set category = "Debug"
set name = "Atom ProcCall"
set waitfor = FALSE
if(!check_rights(R_DEBUG))
return
var/procname = input("Proc name, eg: fake_blood","Proc:", null) as text|null
if(!procname)
return
if(!hascall(A,procname))
to_chat(usr, "<span class='warning'>Error: callproc_datum(): type [A.type] has no proc named [procname].</span>")
return
var/list/lst = get_callproc_args()
if(!lst)
return
if(!A || !IsValidSrc(A))
to_chat(usr, "<span class='warning'>Error: callproc_datum(): owner of proc no longer exists.</span>")
return
var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
log_admin(msg)
message_admins(msg)
admin_ticket_log(A, msg)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Atom ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
var/returnval = WrapAdminProcCall(A, procname, lst) // Pass the lst as an argument list to the proc
. = get_callproc_returnval(returnval,procname)
if(.)
to_chat(usr, .)
/client/proc/get_callproc_args()
var/argnum = input("Number of arguments","Number:",0) as num|null
if(isnull(argnum))
return
. = list()
var/list/named_args = list()
while(argnum--)
var/named_arg = input("Leave blank for positional argument. Positional arguments will be considered as if they were added first.", "Named argument") as text|null
var/value = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT))
if (!value["class"])
return
if(named_arg)
named_args[named_arg] = value["value"]
else
. += value["value"]
if(LAZYLEN(named_args))
. += named_args
/client/proc/get_callproc_returnval(returnval,procname)
. = ""
if(islist(returnval))
var/list/returnedlist = returnval
. = "<span class='notice'>"
if(returnedlist.len)
var/assoc_check = returnedlist[1]
if(istext(assoc_check) && (returnedlist[assoc_check] != null))
. += "[procname] returned an associative list:"
for(var/key in returnedlist)
. += "\n[key] = [returnedlist[key]]"
else
. += "[procname] returned a list:"
for(var/elem in returnedlist)
. += "\n[elem]"
else
. = "[procname] returned an empty list"
. += "</span>"
else
. = "<span class='notice'>[procname] returned: [!isnull(returnval) ? returnval : "null"]</span>"
/client/proc/Cell()
set category = "Debug"
set name = "Air Status in Location"
@@ -343,66 +135,6 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
else
alert("Invalid mob")
/proc/make_types_fancy(var/list/types)
if (ispath(types))
types = list(types)
. = list()
for(var/type in types)
var/typename = "[type]"
var/static/list/TYPES_SHORTCUTS = list(
/obj/effect/decal/cleanable = "CLEANABLE",
/obj/item/radio/headset = "HEADSET",
/obj/item/clothing/head/helmet/space = "SPESSHELMET",
/obj/item/book/manual = "MANUAL",
/obj/item/reagent_containers/food/drinks = "DRINK", //longest paths comes first
/obj/item/reagent_containers/food = "FOOD",
/obj/item/reagent_containers = "REAGENT_CONTAINERS",
/obj/machinery/atmospherics = "ATMOS_MECH",
/obj/machinery/portable_atmospherics = "PORT_ATMOS",
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack = "MECHA_MISSILE_RACK",
/obj/item/mecha_parts/mecha_equipment = "MECHA_EQUIP",
/obj/item/organ = "ORGAN",
/obj/item = "ITEM",
/obj/machinery = "MACHINERY",
/obj/effect = "EFFECT",
/obj = "O",
/datum = "D",
/turf/open = "OPEN",
/turf/closed = "CLOSED",
/turf = "T",
/mob/living/carbon = "CARBON",
/mob/living/simple_animal = "SIMPLE",
/mob/living = "LIVING",
/mob = "M"
)
for (var/tn in TYPES_SHORTCUTS)
if (copytext(typename,1, length("[tn]/")+1)=="[tn]/" /*findtextEx(typename,"[tn]/",1,2)*/ )
typename = TYPES_SHORTCUTS[tn]+copytext(typename,length("[tn]/"))
break
.[typename] = type
/proc/get_fancy_list_of_atom_types()
var/static/list/pre_generated_list
if (!pre_generated_list) //init
pre_generated_list = make_types_fancy(typesof(/atom))
return pre_generated_list
/proc/get_fancy_list_of_datum_types()
var/static/list/pre_generated_list
if (!pre_generated_list) //init
pre_generated_list = make_types_fancy(sortList(typesof(/datum) - typesof(/atom)))
return pre_generated_list
/proc/filter_fancy_list(list/L, filter as text)
var/list/matches = new
for(var/key in L)
var/value = L[key]
if(findtext("[key]", filter) || findtext("[value]", filter))
matches[key] = value
return matches
//TODO: merge the vievars version into this or something maybe mayhaps
/client/proc/cmd_debug_del_all(object as text)
set category = "Debug"
+3 -28
View File
@@ -594,31 +594,6 @@ Traitors and the like can also be revived with the previous role mostly intact.
admin_delete(A)
/client/proc/admin_delete(datum/D)
var/atom/A = D
var/coords = ""
var/jmp_coords = ""
if(istype(A))
var/turf/T = get_turf(A)
if(T)
coords = "at [COORD(T)]"
jmp_coords = "at [ADMIN_COORDJMP(T)]"
else
jmp_coords = coords = "in nullspace"
if (alert(src, "Are you sure you want to delete:\n[D]\n[coords]?", "Confirmation", "Yes", "No") == "Yes")
log_admin("[key_name(usr)] deleted [D] [coords]")
message_admins("[key_name_admin(usr)] deleted [D] [jmp_coords]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Delete") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(isturf(D))
var/turf/T = D
T.ScrapeAway()
else
vv_update_display(D, "deleted", VV_MSG_DELETED)
qdel(D)
if(!QDELETED(D))
vv_update_display(D, "deleted", "")
/client/proc/cmd_admin_list_open_jobs()
set category = "Admin"
set name = "Manage Job Slots"
@@ -934,7 +909,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
id_select += "</select>"
var/dat = {"
<html><head><title>Create Outfit</title></head><body>
<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Create Outfit</title></head><body>
<form name="outfit" action="byond://?src=[REF(src)];[HrefToken()]" method="get">
<input type="hidden" name="src" value="[REF(src)]">
[HrefTokenFormField()]
@@ -1360,7 +1335,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
return
var/list/msg = list()
msg += "<html><head><title>Playtime Report</title></head><body>Playtime:<BR><UL>"
msg += "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Playtime Report</title></head><body>Playtime:<BR><UL>"
for(var/client/C in GLOB.clients)
msg += "<LI> - [key_name_admin(C)]: <A href='?_src_=holder;[HrefToken()];getplaytimewindow=[REF(C.mob)]'>" + C.get_exp_living() + "</a></LI>"
msg += "</UL></BODY></HTML>"
@@ -1377,7 +1352,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
return
var/list/body = list()
body += "<html><head><title>Playtime for [C.key]</title></head><BODY><BR>Playtime:"
body += "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Playtime for [C.key]</title></head><BODY><BR>Playtime:"
body += C.get_exp_report()
body += "<A href='?_src_=holder;[HrefToken()];toggleexempt=[REF(C)]'>Toggle Exempt status</a>"
body += "</BODY></HTML>"
@@ -0,0 +1,24 @@
/client/proc/admin_delete(datum/D)
var/atom/A = D
var/coords = ""
var/jmp_coords = ""
if(istype(A))
var/turf/T = get_turf(A)
if(T)
coords = "at [COORD(T)]"
jmp_coords = "at [ADMIN_COORDJMP(T)]"
else
jmp_coords = coords = "in nullspace"
if (alert(src, "Are you sure you want to delete:\n[D]\n[coords]?", "Confirmation", "Yes", "No") == "Yes")
log_admin("[key_name(usr)] deleted [D] [coords]")
message_admins("[key_name_admin(usr)] deleted [D] [jmp_coords]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Delete") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(isturf(D))
var/turf/T = D
T.ScrapeAway()
else
vv_update_display(D, "deleted", VV_MSG_DELETED)
qdel(D)
if(!QDELETED(D))
vv_update_display(D, "deleted", "")
@@ -0,0 +1,76 @@
#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing )
/proc/debug_variable(name, value, level, datum/D, sanitize = TRUE) //if D is a list, name will be index, and value will be assoc value.
var/header
if(D)
if(islist(D))
var/index = name
if (value)
name = D[name] //name is really the index until this line
else
value = D[name]
header = "<li style='backgroundColor:white'>([VV_HREF_TARGET_1V(D, VV_HK_LIST_EDIT, "E", index)]) ([VV_HREF_TARGET_1V(D, VV_HK_LIST_CHANGE, "C", index)]) ([VV_HREF_TARGET_1V(D, VV_HK_LIST_REMOVE, "-", index)]) "
else
header = "<li style='backgroundColor:white'>([VV_HREF_TARGET_1V(D, VV_HK_BASIC_EDIT, "E", name)]) ([VV_HREF_TARGET_1V(D, VV_HK_BASIC_CHANGE, "C", name)]) ([VV_HREF_TARGET_1V(D, VV_HK_BASIC_MASSEDIT, "M", name)]) "
else
header = "<li>"
var/item
if (isnull(value))
item = "[VV_HTML_ENCODE(name)] = <span class='value'>null</span>"
else if (istext(value))
item = "[VV_HTML_ENCODE(name)] = <span class='value'>\"[VV_HTML_ENCODE(value)]\"</span>"
else if (isicon(value))
#ifdef VARSICON
var/icon/I = icon(value)
var/rnd = rand(1,10000)
var/rname = "tmp[REF(I)][rnd].png"
usr << browse_rsc(I, rname)
item = "[VV_HTML_ENCODE(name)] = (<span class='value'>[value]</span>) <img class=icon src=\"[rname]\">"
#else
item = "[VV_HTML_ENCODE(name)] = /icon (<span class='value'>[value]</span>)"
#endif
else if (isfile(value))
item = "[VV_HTML_ENCODE(name)] = <span class='value'>'[value]'</span>"
else if (istype(value, /datum))
var/datum/DV = value
if ("[DV]" != "[DV.type]") //if the thing as a name var, lets use it.
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [DV] [DV.type]"
else
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [DV.type]"
else if (islist(value))
var/list/L = value
var/list/items = list()
if (L.len > 0 && !(name == "underlays" || name == "overlays" || L.len > (IS_NORMAL_LIST(L) ? VV_NORMAL_LIST_NO_EXPAND_THRESHOLD : VV_SPECIAL_LIST_NO_EXPAND_THRESHOLD)))
for (var/i in 1 to L.len)
var/key = L[i]
var/val
if (IS_NORMAL_LIST(L) && !isnum(key))
val = L[key]
if (isnull(val)) // we still want to display non-null false values, such as 0 or ""
val = key
key = i
items += debug_variable(key, val, level + 1, sanitize = sanitize)
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a><ul>[items.Join()]</ul>"
else
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a>"
else if (name in GLOB.bitfields)
var/list/flags = list()
for (var/i in GLOB.bitfields[name])
if (value & GLOB.bitfields[name][i])
flags += i
item = "[VV_HTML_ENCODE(name)] = [VV_HTML_ENCODE(jointext(flags, ", "))]"
else
item = "[VV_HTML_ENCODE(name)] = <span class='value'>[VV_HTML_ENCODE(value)]</span>"
return "[header][item]</li>"
#undef VV_HTML_ENCODE
@@ -0,0 +1,271 @@
/client/proc/vv_get_class(var_name, var_value)
if(isnull(var_value))
. = VV_NULL
else if(isnum(var_value))
if(var_name in GLOB.bitfields)
. = VV_BITFIELD
else
. = VV_NUM
else if(istext(var_value))
if(findtext(var_value, "\n"))
. = VV_MESSAGE
else
. = VV_TEXT
else if(isicon(var_value))
. = VV_ICON
else if(ismob(var_value))
. = VV_MOB_REFERENCE
else if(isloc(var_value))
. = VV_ATOM_REFERENCE
else if(istype(var_value, /client))
. = VV_CLIENT
else if(istype(var_value, /datum))
. = VV_DATUM_REFERENCE
else if(ispath(var_value))
if(ispath(var_value, /atom))
. = VV_ATOM_TYPE
else if(ispath(var_value, /datum))
. = VV_DATUM_TYPE
else
. = VV_TYPE
else if(islist(var_value))
. = VV_LIST
else if(isfile(var_value))
. = VV_FILE
else
. = VV_NULL
/client/proc/vv_get_value(class, default_class, current_value, list/restricted_classes, list/extra_classes, list/classes, var_name)
. = list("class" = class, "value" = null)
if(!class)
if(!classes)
classes = list (
VV_NUM,
VV_TEXT,
VV_MESSAGE,
VV_ICON,
VV_ATOM_REFERENCE,
VV_DATUM_REFERENCE,
VV_MOB_REFERENCE,
VV_CLIENT,
VV_ATOM_TYPE,
VV_DATUM_TYPE,
VV_TYPE,
VV_FILE,
VV_NEW_ATOM,
VV_NEW_DATUM,
VV_NEW_TYPE,
VV_NEW_LIST,
VV_NULL,
VV_RESTORE_DEFAULT,
VV_TEXT_LOCATE,
VV_PROCCALL_RETVAL,
)
var/markstring
if(!(VV_MARKED_DATUM in restricted_classes))
markstring = "[VV_MARKED_DATUM] (CURRENT: [(istype(holder) && istype(holder.marked_datum))? holder.marked_datum.type : "NULL"])"
classes += markstring
if(restricted_classes)
classes -= restricted_classes
if(extra_classes)
classes += extra_classes
.["class"] = input(src, "What kind of data?", "Variable Type", default_class) as null|anything in classes
if(holder && holder.marked_datum && .["class"] == markstring)
.["class"] = VV_MARKED_DATUM
switch(.["class"])
if(VV_TEXT)
.["value"] = input("Enter new text:", "Text", current_value) as null|text
if(.["value"] == null)
.["class"] = null
return
if(VV_MESSAGE)
.["value"] = input("Enter new text:", "Text", current_value) as null|message
if(.["value"] == null)
.["class"] = null
return
if(VV_NUM)
.["value"] = input("Enter new number:", "Num", current_value) as null|num
if(.["value"] == null)
.["class"] = null
return
if(VV_BITFIELD)
.["value"] = input_bitfield(usr, "Editing bitfield: [var_name]", var_name, current_value)
if(.["value"] == null)
.["class"] = null
return
if(VV_ATOM_TYPE)
.["value"] = pick_closest_path(FALSE)
if(.["value"] == null)
.["class"] = null
return
if(VV_DATUM_TYPE)
.["value"] = pick_closest_path(FALSE, get_fancy_list_of_datum_types())
if(.["value"] == null)
.["class"] = null
return
if(VV_TYPE)
var/type = current_value
var/error = ""
do
type = input("Enter type:[error]", "Type", type) as null|text
if(!type)
break
type = text2path(type)
error = "\nType not found, Please try again"
while(!type)
if(!type)
.["class"] = null
return
.["value"] = type
if(VV_ATOM_REFERENCE)
var/type = pick_closest_path(FALSE)
var/subtypes = vv_subtype_prompt(type)
if(subtypes == null)
.["class"] = null
return
var/list/things = vv_reference_list(type, subtypes)
var/value = input("Select reference:", "Reference", current_value) as null|anything in things
if(!value)
.["class"] = null
return
.["value"] = things[value]
if(VV_DATUM_REFERENCE)
var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types())
var/subtypes = vv_subtype_prompt(type)
if(subtypes == null)
.["class"] = null
return
var/list/things = vv_reference_list(type, subtypes)
var/value = input("Select reference:", "Reference", current_value) as null|anything in things
if(!value)
.["class"] = null
return
.["value"] = things[value]
if(VV_MOB_REFERENCE)
var/type = pick_closest_path(FALSE, make_types_fancy(typesof(/mob)))
var/subtypes = vv_subtype_prompt(type)
if(subtypes == null)
.["class"] = null
return
var/list/things = vv_reference_list(type, subtypes)
var/value = input("Select reference:", "Reference", current_value) as null|anything in things
if(!value)
.["class"] = null
return
.["value"] = things[value]
if(VV_CLIENT)
.["value"] = input("Select reference:", "Reference", current_value) as null|anything in GLOB.clients
if(.["value"] == null)
.["class"] = null
return
if(VV_FILE)
.["value"] = input("Pick file:", "File") as null|file
if(.["value"] == null)
.["class"] = null
return
if(VV_ICON)
.["value"] = input("Pick icon:", "Icon") as null|icon
if(.["value"] == null)
.["class"] = null
return
if(VV_MARKED_DATUM)
.["value"] = holder.marked_datum
if(.["value"] == null)
.["class"] = null
return
if(VV_PROCCALL_RETVAL)
var/list/get_retval = list()
callproc_blocking(get_retval)
.["value"] = get_retval[1] //should have been set in proccall!
if(.["value"] == null)
.["class"] = null
return
if(VV_NEW_ATOM)
var/type = pick_closest_path(FALSE)
if(!type)
.["class"] = null
return
.["type"] = type
var/atom/newguy = new type()
newguy.datum_flags |= DF_VAR_EDITED
.["value"] = newguy
if(VV_NEW_DATUM)
var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types())
if(!type)
.["class"] = null
return
.["type"] = type
var/datum/newguy = new type()
newguy.datum_flags |= DF_VAR_EDITED
.["value"] = newguy
if(VV_NEW_TYPE)
var/type = current_value
var/error = ""
do
type = input("Enter type:[error]", "Type", type) as null|text
if(!type)
break
type = text2path(type)
error = "\nType not found, Please try again"
while(!type)
if(!type)
.["class"] = null
return
.["type"] = type
var/datum/newguy = new type()
if(istype(newguy))
newguy.datum_flags |= DF_VAR_EDITED
.["value"] = newguy
if(VV_NEW_LIST)
.["value"] = list()
.["type"] = /list
if(VV_TEXT_LOCATE)
var/datum/D
do
var/ref = input("Enter reference:", "Reference") as null|text
if(!ref)
break
D = locate(ref)
if(!D)
alert("Invalid ref!")
continue
if(!D.can_vv_mark())
alert("Datum can not be marked!")
continue
while(!D)
.["type"] = D.type
.["value"] = D
@@ -0,0 +1,12 @@
/client/proc/mark_datum(datum/D)
if(!holder)
return
if(holder.marked_datum)
vv_update_display(holder.marked_datum, "marked", "")
holder.marked_datum = D
vv_update_display(D, "marked", VV_MSG_MARKED)
/client/proc/mark_datum_mapview(datum/D as mob|obj|turf|area in view(view))
set category = "Debug"
set name = "Mark Object"
mark_datum(D)
@@ -197,7 +197,7 @@
log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
//not using global lists as vv is a debug function and debug functions should rely on as less things as possible.
/proc/get_all_of_type(var/T, subtypes = TRUE)
var/list/typecache = list()
typecache[T] = 1
@@ -205,19 +205,25 @@
typecache = typecacheof(typecache)
. = list()
if (ispath(T, /mob))
for(var/mob/thing in GLOB.mob_list)
for(var/mob/thing in world)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if (ispath(T, /obj/machinery/door))
for(var/obj/machinery/door/thing in GLOB.airlocks)
for(var/obj/machinery/door/thing in world)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if (ispath(T, /obj/machinery))
for(var/obj/machinery/thing in GLOB.machines)
for(var/obj/machinery/thing in world)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if (ispath(T, /obj/item))
for(var/obj/item/thing in world)
if (typecache[thing.type])
. += thing
CHECK_TICK
@@ -247,7 +253,7 @@
CHECK_TICK
else if (ispath(T, /client))
for(var/client/thing in GLOB.clients)
for(var/client/thing in world)
if (typecache[thing.type])
. += thing
CHECK_TICK
@@ -1,264 +1,12 @@
GLOBAL_LIST_INIT(VVlocked, list("vars", "datum_flags", "client", "virus", "viruses", "cuffed", "last_eaten", "unlock_content", "force_ending"))
GLOBAL_LIST_INIT(VVlocked, list("vars", "datum_flags", "client", "mob")) //Requires DEBUG
GLOBAL_PROTECT(VVlocked)
GLOBAL_LIST_INIT(VVicon_edit_lock, list("icon", "icon_state", "overlays", "underlays", "resize"))
GLOBAL_LIST_INIT(VVicon_edit_lock, list("icon", "icon_state", "overlays", "underlays")) //Requires DEBUG or FUN
GLOBAL_PROTECT(VVicon_edit_lock)
GLOBAL_LIST_INIT(VVckey_edit, list("key", "ckey"))
GLOBAL_LIST_INIT(VVckey_edit, list("key", "ckey")) //Requires DEBUG or SPAWN
GLOBAL_PROTECT(VVckey_edit)
GLOBAL_LIST_INIT(VVpixelmovement, list("step_x", "step_y", "bound_height", "bound_width", "bound_x", "bound_y"))
GLOBAL_LIST_INIT(VVpixelmovement, list("bound_x", "bound_y", "step_x", "step_y", "step_size", "bound_height", "bound_width", "bounds")) //No editing ever.
GLOBAL_PROTECT(VVpixelmovement)
/client/proc/vv_get_class(var/var_name, var/var_value)
if(isnull(var_value))
. = VV_NULL
else if (isnum(var_value))
if (var_name in GLOB.bitfields)
. = VV_BITFIELD
else
. = VV_NUM
else if (istext(var_value))
if (findtext(var_value, "\n"))
. = VV_MESSAGE
else
. = VV_TEXT
else if (isicon(var_value))
. = VV_ICON
else if (ismob(var_value))
. = VV_MOB_REFERENCE
else if (isloc(var_value))
. = VV_ATOM_REFERENCE
else if (istype(var_value, /client))
. = VV_CLIENT
else if (istype(var_value, /datum))
. = VV_DATUM_REFERENCE
else if (ispath(var_value))
if (ispath(var_value, /atom))
. = VV_ATOM_TYPE
else if (ispath(var_value, /datum))
. = VV_DATUM_TYPE
else
. = VV_TYPE
else if (islist(var_value))
. = VV_LIST
else if (isfile(var_value))
. = VV_FILE
else
. = VV_NULL
/client/proc/vv_get_value(class, default_class, current_value, list/restricted_classes, list/extra_classes, list/classes, var_name)
. = list("class" = class, "value" = null)
if (!class)
if (!classes)
classes = list (
VV_NUM,
VV_TEXT,
VV_MESSAGE,
VV_ICON,
VV_ATOM_REFERENCE,
VV_DATUM_REFERENCE,
VV_MOB_REFERENCE,
VV_CLIENT,
VV_ATOM_TYPE,
VV_DATUM_TYPE,
VV_TYPE,
VV_FILE,
VV_NEW_ATOM,
VV_NEW_DATUM,
VV_NEW_TYPE,
VV_NEW_LIST,
VV_NULL,
VV_RESTORE_DEFAULT
)
if(holder && holder.marked_datum && !(VV_MARKED_DATUM in restricted_classes))
classes += "[VV_MARKED_DATUM] ([holder.marked_datum.type])"
if (restricted_classes)
classes -= restricted_classes
if (extra_classes)
classes += extra_classes
.["class"] = input(src, "What kind of data?", "Variable Type", default_class) as null|anything in classes
if (holder && holder.marked_datum && .["class"] == "[VV_MARKED_DATUM] ([holder.marked_datum.type])")
.["class"] = VV_MARKED_DATUM
switch(.["class"])
if (VV_TEXT)
.["value"] = input("Enter new text:", "Text", current_value) as null|text
if (.["value"] == null)
.["class"] = null
return
if (VV_MESSAGE)
.["value"] = input("Enter new text:", "Text", current_value) as null|message
if (.["value"] == null)
.["class"] = null
return
if (VV_NUM)
.["value"] = input("Enter new number:", "Num", current_value) as null|num
if (.["value"] == null)
.["class"] = null
return
if (VV_BITFIELD)
.["value"] = input_bitfield(usr, "Editing bitfield: [var_name]", var_name, current_value)
if (.["value"] == null)
.["class"] = null
return
if (VV_ATOM_TYPE)
.["value"] = pick_closest_path(FALSE)
if (.["value"] == null)
.["class"] = null
return
if (VV_DATUM_TYPE)
.["value"] = pick_closest_path(FALSE, get_fancy_list_of_datum_types())
if (.["value"] == null)
.["class"] = null
return
if (VV_TYPE)
var/type = current_value
var/error = ""
do
type = input("Enter type:[error]", "Type", type) as null|text
if (!type)
break
type = text2path(type)
error = "\nType not found, Please try again"
while(!type)
if (!type)
.["class"] = null
return
.["value"] = type
if (VV_ATOM_REFERENCE)
var/type = pick_closest_path(FALSE)
var/subtypes = vv_subtype_prompt(type)
if (subtypes == null)
.["class"] = null
return
var/list/things = vv_reference_list(type, subtypes)
var/value = input("Select reference:", "Reference", current_value) as null|anything in things
if (!value)
.["class"] = null
return
.["value"] = things[value]
if (VV_DATUM_REFERENCE)
var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types())
var/subtypes = vv_subtype_prompt(type)
if (subtypes == null)
.["class"] = null
return
var/list/things = vv_reference_list(type, subtypes)
var/value = input("Select reference:", "Reference", current_value) as null|anything in things
if (!value)
.["class"] = null
return
.["value"] = things[value]
if (VV_MOB_REFERENCE)
var/type = pick_closest_path(FALSE, make_types_fancy(typesof(/mob)))
var/subtypes = vv_subtype_prompt(type)
if (subtypes == null)
.["class"] = null
return
var/list/things = vv_reference_list(type, subtypes)
var/value = input("Select reference:", "Reference", current_value) as null|anything in things
if (!value)
.["class"] = null
return
.["value"] = things[value]
if (VV_CLIENT)
.["value"] = input("Select reference:", "Reference", current_value) as null|anything in GLOB.clients
if (.["value"] == null)
.["class"] = null
return
if (VV_FILE)
.["value"] = input("Pick file:", "File") as null|file
if (.["value"] == null)
.["class"] = null
return
if (VV_ICON)
.["value"] = input("Pick icon:", "Icon") as null|icon
if (.["value"] == null)
.["class"] = null
return
if (VV_MARKED_DATUM)
.["value"] = holder.marked_datum
if (.["value"] == null)
.["class"] = null
return
if (VV_NEW_ATOM)
var/type = pick_closest_path(FALSE)
if (!type)
.["class"] = null
return
.["type"] = type
var/atom/newguy = new type()
newguy.datum_flags |= DF_VAR_EDITED
.["value"] = newguy
if (VV_NEW_DATUM)
var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types())
if (!type)
.["class"] = null
return
.["type"] = type
var/datum/newguy = new type()
newguy.datum_flags |= DF_VAR_EDITED
.["value"] = newguy
if (VV_NEW_TYPE)
var/type = current_value
var/error = ""
do
type = input("Enter type:[error]", "Type", type) as null|text
if (!type)
break
type = text2path(type)
error = "\nType not found, Please try again"
while(!type)
if (!type)
.["class"] = null
return
.["type"] = type
var/datum/newguy = new type()
if(istype(newguy))
newguy.datum_flags |= DF_VAR_EDITED
.["value"] = newguy
if (VV_NEW_LIST)
.["value"] = list()
.["type"] = /list
/client/proc/vv_parse_text(O, new_var)
if(O && findtext(new_var,"\["))
var/process_vars = alert(usr,"\[] detected in string, process as variables?","Process Variables?","Yes","No")
@@ -372,13 +120,13 @@ GLOBAL_PROTECT(VVpixelmovement)
if(confirm != "Continue")
return
var/is_normal_list = IS_NORMAL_LIST(L)
var/list/names = list()
for (var/i in 1 to L.len)
var/key = L[i]
var/value
if (IS_NORMAL_LIST(L) && !isnum(key))
if (is_normal_list && !isnum(key))
value = L[key]
if (value == null)
value = "null"
@@ -439,10 +187,17 @@ GLOBAL_PROTECT(VVpixelmovement)
assoc_key = L[index]
var/default
var/variable
if (assoc)
variable = L[assoc_key]
else
variable = L[index]
var/old_assoc_value //EXPERIMENTAL - Keep old associated value while modifying key, if any
if(is_normal_list)
if (assoc)
variable = L[assoc_key]
else
variable = L[index]
//EXPERIMENTAL - Keep old associated value while modifying key, if any
var/found = L[variable]
if(!isnull(found))
old_assoc_value = found
//
default = vv_get_class(objectvar, variable)
@@ -504,11 +259,13 @@ GLOBAL_PROTECT(VVpixelmovement)
for(var/V in varsvars)
new_var = replacetext(new_var,"\[[V]]","[O.vars[V]]")
if(assoc)
L[assoc_key] = new_var
else
L[index] = new_var
if(is_normal_list)
if(assoc)
L[assoc_key] = new_var
else
L[index] = new_var
if(!isnull(old_assoc_value) && IS_VALID_ASSOC_KEY(new_var))
L[new_var] = old_assoc_value
if (O)
if (O.vv_edit_var(objectvar, L) == FALSE)
to_chat(src, "Your edit was rejected by the object.")
@@ -527,15 +284,8 @@ GLOBAL_PROTECT(VVpixelmovement)
if(param_var_name in GLOB.VVicon_edit_lock)
if(!check_rights(R_FUN|R_DEBUG))
return FALSE
if(param_var_name in GLOB.VVpixelmovement)
if(!check_rights(R_DEBUG))
return FALSE
var/prompt = alert(usr, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", "ABORT ", "Continue", " ABORT")
if (prompt != "Continue")
return FALSE
return TRUE
/client/proc/modify_variables(atom/O, param_var_name = null, autodetect_class = 0)
if(!check_rights(R_VAREDIT))
return
@@ -567,11 +317,6 @@ GLOBAL_PROTECT(VVpixelmovement)
var_value = O.vars[variable]
if(!vv_varname_lockcheck(variable))
return
if(istype(O, /datum/armor))
var/prompt = alert(src, "Editing this var changes this value on potentially thousands of items that share the same combination of armor values. If you want to edit the armor of just one item, use the \"Modify armor values\" dropdown item", "DANGER", "ABORT ", "Continue", " ABORT")
if (prompt != "Continue")
return
var/default = vv_get_class(variable, var_value)
@@ -635,10 +380,9 @@ GLOBAL_PROTECT(VVpixelmovement)
to_chat(src, "Your edit was rejected by the object.")
return
vv_update_display(O, "varedited", VV_MSG_EDITED)
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_VAR_EDIT, args)
log_world("### VarEdit by [key_name(src)]: [O.type] [variable]=[var_value] => [var_new]")
log_admin("[key_name(src)] modified [original_name]'s [variable] from [html_encode("[var_value]")] to [html_encode("[var_new]")]")
var/msg = "[key_name_admin(src)] modified [original_name]'s [variable] from [var_value] to [var_new]"
message_admins(msg)
admin_ticket_log(O, msg)
return TRUE
return TRUE
+128
View File
@@ -0,0 +1,128 @@
//DO NOT ADD MORE TO THIS FILE.
//Use vv_do_topic() for datums!
/client/proc/view_var_Topic(href, href_list, hsrc)
if( (usr.client != src) || !src.holder || !holder.CheckAdminHref(href, href_list))
return
var/target = GET_VV_TARGET
vv_do_basic(target, href_list, href)
if(istype(target, /datum))
var/datum/D = target
D.vv_do_topic(href_list)
else if(islist(target))
vv_do_list(target, href_list)
if(href_list["Vars"])
debug_variables(locate(href_list["Vars"]))
//Stuff below aren't in dropdowns/etc.
if(check_rights(R_VAREDIT))
//~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records).
if(href_list["rename"])
if(!check_rights(NONE))
return
var/mob/M = locate(href_list["rename"]) in GLOB.mob_list
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
var/new_name = stripped_input(usr,"What would you like to name this mob?","Input a name",M.real_name,MAX_NAME_LEN)
if( !new_name || !M )
return
message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].")
M.fully_replace_character_name(M.real_name,new_name)
vv_update_display(M, "name", new_name)
vv_update_display(M, "real_name", M.real_name || "No real name")
else if(href_list["rotatedatum"])
if(!check_rights(NONE))
return
var/atom/A = locate(href_list["rotatedatum"])
if(!istype(A))
to_chat(usr, "This can only be done to instances of type /atom")
return
switch(href_list["rotatedir"])
if("right")
A.setDir(turn(A.dir, -45))
if("left")
A.setDir(turn(A.dir, 45))
vv_update_display(A, "dir", dir2text(A.dir))
else if(href_list["makehuman"])
if(!check_rights(R_SPAWN))
return
var/mob/living/carbon/monkey/Mo = locate(href_list["makehuman"]) in GLOB.mob_list
if(!istype(Mo))
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/monkey")
return
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
return
if(!Mo)
to_chat(usr, "Mob doesn't exist anymore")
return
holder.Topic(href, list("humanone"=href_list["makehuman"]))
else if(href_list["adjustDamage"] && href_list["mobToDamage"])
if(!check_rights(NONE))
return
var/mob/living/L = locate(href_list["mobToDamage"]) in GLOB.mob_list
if(!istype(L))
return
var/Text = href_list["adjustDamage"]
var/amount = input("Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0) as num
if(!L)
to_chat(usr, "Mob doesn't exist anymore")
return
var/newamt
switch(Text)
if("brute")
L.adjustBruteLoss(amount)
newamt = L.getBruteLoss()
if("fire")
L.adjustFireLoss(amount)
newamt = L.getFireLoss()
if("toxin")
L.adjustToxLoss(amount)
newamt = L.getToxLoss()
if("oxygen")
L.adjustOxyLoss(amount)
newamt = L.getOxyLoss()
if("brain")
L.adjustOrganLoss(ORGAN_SLOT_BRAIN, amount)
newamt = L.getOrganLoss(ORGAN_SLOT_BRAIN)
if("clone")
L.adjustCloneLoss(amount)
newamt = L.getCloneLoss()
if("stamina")
L.adjustStaminaLoss(amount)
newamt = L.getStaminaLoss()
else
to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[L]")
return
if(amount != 0)
var/log_msg = "[key_name(usr)] dealt [amount] amount of [Text] damage to [key_name(L)]"
message_admins("[key_name(usr)] dealt [amount] amount of [Text] damage to [ADMIN_LOOKUPFLW(L)]")
log_admin(log_msg)
admin_ticket_log(L, "<font color='blue'>[log_msg]</font>")
vv_update_display(L, Text, "[newamt]")
//Finally, refresh if something modified the list.
if(href_list["datumrefresh"])
var/datum/DAT = locate(href_list["datumrefresh"])
if(istype(DAT, /datum) || istype(DAT, /client))
debug_variables(DAT)
@@ -0,0 +1,51 @@
//Not using datum.vv_do_topic for very basic/low level debug things, incase the datum's vv_do_topic is runtiming/whatnot.
/client/proc/vv_do_basic(datum/target, href_list)
var/target_var = GET_VV_VAR_TARGET
if(check_rights(R_VAREDIT))
if(target_var)
if(href_list[VV_HK_BASIC_EDIT])
if(!modify_variables(target, target_var, 1))
return
switch(target_var)
if("name")
vv_update_display(target, "name", "[target]")
if("dir")
var/atom/A = target
if(istype(A))
vv_update_display(target, "dir", dir2text(A.dir) || A.dir)
if("ckey")
var/mob/living/L = target
if(istype(L))
vv_update_display(target, "ckey", L.ckey || "No ckey")
if("real_name")
var/mob/living/L = target
if(istype(L))
vv_update_display(target, "real_name", L.real_name || "No real name")
if(href_list[VV_HK_BASIC_CHANGE])
modify_variables(target, target_var, 0)
if(href_list[VV_HK_BASIC_MASSEDIT])
cmd_mass_modify_object_variables(target, target_var)
if(check_rights(R_ADMIN, FALSE))
if(href_list[VV_HK_EXPOSE])
var/value = vv_get_value(VV_CLIENT)
if (value["class"] != VV_CLIENT)
return
var/client/C = value["value"]
if (!C)
return
if(!target)
to_chat(usr, "<span class='warning'>The object you tried to expose to [C] no longer exists (nulled or hard-deled)</span>")
return
message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a <a href='?_src_=vars;datumrefresh=[REF(target)]'>VV window</a>")
log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [target]")
to_chat(C, "[holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window")
C.debug_variables(target)
if(check_rights(R_DEBUG))
if(href_list[VV_HK_DELETE])
usr.client.admin_delete(target)
if (isturf(src)) // show the turf that took its place
usr.client.debug_variables(src)
if(href_list[VV_HK_MARK])
usr.client.mark_datum(target)
if(href_list[VV_HK_CALLPROC])
usr.client.callproc_datum(target)
@@ -0,0 +1,43 @@
//LISTS - CAN NOT DO VV_DO_TOPIC BECAUSE LISTS AREN'T DATUMS :(
/client/proc/vv_do_list(list/target, href_list)
var/target_index = text2num(GET_VV_VAR_TARGET)
if(check_rights(R_VAREDIT))
if(target_index)
if(href_list[VV_HK_LIST_EDIT])
mod_list(target, null, "list", "contents", target_index, autodetect_class = TRUE)
if(href_list[VV_HK_LIST_CHANGE])
mod_list(target, null, "list", "contents", target_index, autodetect_class = FALSE)
if(href_list[VV_HK_LIST_REMOVE])
var/variable = target[target_index]
var/prompt = alert("Do you want to remove item number [target_index] from list?", "Confirm", "Yes", "No")
if (prompt != "Yes")
return
target.Cut(target_index, target_index+1)
log_world("### ListVarEdit by [src]: /list's contents: REMOVED=[html_encode("[variable]")]")
log_admin("[key_name(src)] modified list's contents: REMOVED=[variable]")
message_admins("[key_name_admin(src)] modified list's contents: REMOVED=[variable]")
if(href_list[VV_HK_LIST_ADD])
mod_list_add(target, null, "list", "contents")
if(href_list[VV_HK_LIST_ERASE_DUPES])
uniqueList_inplace(target)
log_world("### ListVarEdit by [src]: /list contents: CLEAR DUPES")
log_admin("[key_name(src)] modified list's contents: CLEAR DUPES")
message_admins("[key_name_admin(src)] modified list's contents: CLEAR DUPES")
if(href_list[VV_HK_LIST_ERASE_NULLS])
listclearnulls(target)
log_world("### ListVarEdit by [src]: /list contents: CLEAR NULLS")
log_admin("[key_name(src)] modified list's contents: CLEAR NULLS")
message_admins("[key_name_admin(src)] modified list's contents: CLEAR NULLS")
if(href_list[VV_HK_LIST_SET_LENGTH])
var/value = vv_get_value(VV_NUM)
if (value["class"] != VV_NUM || value["value"] > max(50000, target.len)) //safety - would rather someone not put an extra 0 and erase the server's memory lmao.
return
target.len = value["value"]
log_world("### ListVarEdit by [src]: /list len: [target.len]")
log_admin("[key_name(src)] modified list's len: [target.len]")
message_admins("[key_name_admin(src)] modified list's len: [target.len]")
if(href_list[VV_HK_LIST_SHUFFLE])
shuffle_inplace(target)
log_world("### ListVarEdit by [src]: /list contents: SHUFFLE")
log_admin("[key_name(src)] modified list's contents: SHUFFLE")
message_admins("[key_name_admin(src)] modified list's contents: SHUFFLE")
@@ -0,0 +1,269 @@
/client/proc/debug_variables(datum/D in world)
set category = "Debug"
set name = "View Variables"
//set src in world
var/static/cookieoffset = rand(1, 9999) //to force cookies to reset after the round.
if(!usr.client || !usr.client.holder) //This is usr because admins can call the proc on other clients, even if they're not admins, to show them VVs.
to_chat(usr, "<span class='danger'>You need to be an administrator to access this.</span>")
return
if(!D)
return
var/islist = islist(D)
if(!islist && !istype(D))
return
var/title = ""
var/refid = REF(D)
var/icon/sprite
var/hash
var/type = islist? /list : D.type
var/no_icon = FALSE
if(istype(D, /atom))
sprite = getFlatIcon(D)
hash = md5(sprite)
if(sprite)
hash = md5(sprite)
src << browse_rsc(sprite, "vv[hash].png")
else
no_icon = TRUE
title = "[D] ([REF(D)]) = [type]"
var/formatted_type = replacetext("[type]", "/", "<wbr>/")
var/sprite_text
if(sprite)
sprite_text = no_icon? "\[NO ICON\]" : "<img src='vv[hash].png'></td><td>"
var/list/header = islist(D)? list("<b>/list</b>") : D.vv_get_header()
var/marked_line
if(holder && holder.marked_datum && holder.marked_datum == D)
marked_line = VV_MSG_MARKED
var/varedited_line
if(!islist && (D.datum_flags & DF_VAR_EDITED))
varedited_line = VV_MSG_EDITED
var/deleted_line
if(!islist && D.gc_destroyed)
deleted_line = VV_MSG_DELETED
var/list/dropdownoptions
if (islist)
dropdownoptions = list(
"---",
"Add Item" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_ADD),
"Remove Nulls" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_ERASE_NULLS),
"Remove Dupes" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_ERASE_DUPES),
"Set len" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_SET_LENGTH),
"Shuffle" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_SHUFFLE),
"Show VV To Player" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_EXPOSE),
"---"
)
for(var/i in 1 to length(dropdownoptions))
var/name = dropdownoptions[i]
var/link = dropdownoptions[name]
dropdownoptions[i] = "<option value[link? "='[link]'":""]>[name]</option>"
else
dropdownoptions = D.vv_get_dropdown()
var/list/names = list()
if(!islist)
for(var/V in D.vars)
names += V
sleep(1)
var/list/variable_html = list()
if(islist)
var/list/L = D
for(var/i in 1 to L.len)
var/key = L[i]
var/value
if(IS_NORMAL_LIST(L) && IS_VALID_ASSOC_KEY(key))
value = L[key]
variable_html += debug_variable(i, value, 0, L)
else
names = sortList(names)
for(var/V in names)
if(D.can_vv_get(V))
variable_html += D.vv_get_var(V)
var/html = {"
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<title>[title]</title>
<style>
body {
font-family: Verdana, sans-serif;
font-size: 9pt;
}
.value {
font-family: "Courier New", monospace;
font-size: 8pt;
}
</style>
</head>
<body onload='selectTextField()' onkeydown='return handle_keydown()' onkeyup='handle_keyup()'>
<script type="text/javascript">
// onload
function selectTextField() {
var filter_text = document.getElementById('filter');
filter_text.focus();
filter_text.select();
var lastsearch = getCookie("[refid][cookieoffset]search");
if (lastsearch) {
filter_text.value = lastsearch;
updateSearch();
}
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca\[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(name)==0) return c.substring(name.length,c.length);
}
return "";
}
// main search functionality
var last_filter = "";
function updateSearch() {
var filter = document.getElementById('filter').value.toLowerCase();
var vars_ol = document.getElementById("vars");
if (filter === last_filter) {
// An event triggered an update but nothing has changed.
return;
} else if (filter.indexOf(last_filter) === 0) {
// The new filter starts with the old filter, fast path by removing only.
var children = vars_ol.childNodes;
for (var i = children.length - 1; i >= 0; --i) {
try {
var li = children\[i];
if (li.innerText.toLowerCase().indexOf(filter) == -1) {
vars_ol.removeChild(li);
}
} catch(err) {}
}
} else {
// Remove everything and put back what matches.
while (vars_ol.hasChildNodes()) {
vars_ol.removeChild(vars_ol.lastChild);
}
for (var i = 0; i < complete_list.length; ++i) {
try {
var li = complete_list\[i];
if (!filter || li.innerText.toLowerCase().indexOf(filter) != -1) {
vars_ol.appendChild(li);
}
} catch(err) {}
}
}
last_filter = filter;
document.cookie="[refid][cookieoffset]search="+encodeURIComponent(filter);
}
// onkeydown
function handle_keydown() {
if(event.keyCode == 116) { //F5 (to refresh properly)
document.getElementById("refresh_link").click();
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
return false;
}
return true;
}
// onkeyup
function handle_keyup() {
updateSearch();
}
// onchange
function handle_dropdown(list) {
var value = list.options\[list.selectedIndex].value;
if (value !== "") {
location.href = value;
}
list.selectedIndex = 0;
document.getElementById('filter').focus();
}
// byjax
function replace_span(what) {
var idx = what.indexOf(':');
document.getElementById(what.substr(0, idx)).innerHTML = what.substr(idx + 1);
}
</script>
<div align='center'>
<table width='100%'>
<tr>
<td width='50%'>
<table align='center' width='100%'>
<tr>
<td>
[sprite_text]
<div align='center'>
[header.Join()]
</div>
</td>
</tr>
</table>
<div align='center'>
<b><font size='1'>[formatted_type]</font></b>
<span id='marked'>[marked_line]</span>
<span id='varedited'>[varedited_line]</span>
<span id='deleted'>[deleted_line]</span>
</div>
</td>
<td width='50%'>
<div align='center'>
<a id='refresh_link' href='?_src_=vars;
datumrefresh=[refid];[HrefToken()]'>Refresh</a>
<form>
<select name="file" size="1"
onchange="handle_dropdown(this)"
onmouseclick="this.focus()">
<option value selected>Select option</option>
[dropdownoptions.Join()]
</select>
</form>
</div>
</td>
</tr>
</table>
</div>
<hr>
<font size='1'>
<b>E</b> - Edit, tries to determine the variable type by itself.<br>
<b>C</b> - Change, asks you for the var type first.<br>
<b>M</b> - Mass modify: changes this variable for all objects of this type.<br>
</font>
<hr>
<table width='100%'>
<tr>
<td width='20%'>
<div align='center'>
<b>Search:</b>
</div>
</td>
<td width='80%'>
<input type='text' id='filter' name='filter_text' value='' style='width:100%;'>
</td>
</tr>
</table>
<hr>
<ol id='vars'>
[variable_html.Join()]
</ol>
<script type='text/javascript'>
var complete_list = \[\];
var lis = document.getElementById("vars").children;
for(var i = lis.length; i--;) complete_list\[i\] = lis\[i\];
</script>
</body>
</html>
"}
src << browse(html, "window=variables[refid];size=475x650")
/client/proc/vv_update_display(datum/D, span, content)
src << output("[span]:[content]", "variables[REF(D)].browser:replace_span")
@@ -22,6 +22,7 @@ GLOBAL_LIST_EMPTY(antagonists)
var/antagpanel_category = "Uncategorized" //Antagpanel will display these together, REQUIRED
var/show_name_in_check_antagonists = FALSE //Will append antagonist name in admin listings - use for categories that share more than one antag type
var/list/blacklisted_quirks = list(/datum/quirk/nonviolent,/datum/quirk/mute) // Quirks that will be removed upon gaining this antag. Pacifist and mute are default.
var/threat = 0 // Amount of threat this antag poses, for dynamic mode
/datum/antagonist/New()
GLOB.antagonists += src
@@ -75,6 +76,7 @@ GLOBAL_LIST_EMPTY(antagonists)
remove_blacklisted_quirks()
if(is_banned(owner.current) && replace_banned)
replace_banned_player()
SEND_SIGNAL(owner.current, COMSIG_MOB_ANTAG_ON_GAIN, src)
/datum/antagonist/proc/is_banned(mob/M)
if(!M)
@@ -237,6 +239,13 @@ GLOBAL_LIST_EMPTY(antagonists)
return H.hijack_speed_override
return hijack_speed
/// Gets our threat level. Defaults to threat var, override for custom stuff like different traitor goals having different threats.
/datum/antagonist/proc/threat()
. = CONFIG_GET(keyed_list/antag_threat)[lowertext(name)]
if(. == null)
return threat
return threat
//This one is created by admin tools for custom objectives
/datum/antagonist/custom
antagpanel_category = "Custom"
@@ -31,4 +31,5 @@
/datum/antagonist/abductee/remove_innate_effects(mob/living/mob_override)
update_abductor_icons_removed(mob_override ? mob_override.mind : owner)
qdel(brain_trauma)
if(!QDELETED(brain_trauma))
qdel(brain_trauma)
@@ -6,6 +6,7 @@
antagpanel_category = "Abductor"
job_rank = ROLE_ABDUCTOR
show_in_antagpanel = FALSE //should only show subtypes
threat = 5
var/datum/team/abductor_team/team
var/sub_role
var/outfit
+2 -2
View File
@@ -3,7 +3,7 @@
roundend_category = "blobs"
antagpanel_category = "Blob"
job_rank = ROLE_BLOB
threat = 20
var/datum/action/innate/blobpop/pop_action
var/starting_points_human_blob = 60
var/point_rate_human_blob = 2
@@ -63,4 +63,4 @@
if(owner && owner.current)
var/mob/camera/blob/B = owner.current
if(istype(B))
. += "(Progress: [B.blobs_legit.len]/[B.blobwincount])"
. += "(Progress: [B.blobs_legit.len]/[B.blobwincount])"
@@ -75,6 +75,7 @@
desc = "A floating, fragile spore."
icon_state = "blobpod"
icon_living = "blobpod"
threat = 0.2
health = 30
maxHealth = 30
verb_say = "psychically pulses"
@@ -6,7 +6,7 @@
roundend_category = "bloodsuckers"
antagpanel_category = "Bloodsucker"
job_rank = ROLE_BLOODSUCKER
threat = 5
// NAME
var/vampname // My Dracula name
var/vamptitle // My Dracula title
@@ -91,10 +91,8 @@
// Refill with Blood
owner.current.blood_volume = max(owner.current.blood_volume,BLOOD_VOLUME_SAFE)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/antagonist/bloodsucker/threat()
return ..()+3*vamplevel
/datum/antagonist/bloodsucker/proc/SelectFirstName()
@@ -13,7 +13,10 @@
var/list/datum/objective/objectives_given = list() // For removal if needed.
var/datum/martial_art/my_kungfu // Hunters know a lil kung fu.
var/bad_dude = FALSE // Every first hunter spawned is a SHIT LORD.
threat = -3
/datum/antagonist/vamphunter/threat()
return bad_dude ? -(..()) : ..()
/datum/antagonist/vamphunter/on_gain()
@@ -19,6 +19,7 @@
var/datum/antagonist/bloodsucker/master // Who made me?
var/list/datum/action/powers = list()// Purchased powers
var/list/datum/objective/objectives_given = list() // For removal if needed.
threat = 1
/datum/antagonist/vassal/can_be_owned(datum/mind/new_owner)
// If we weren't created by a bloodsucker, then we cannot be a vassal (assigned from antag panel)
@@ -95,7 +95,7 @@
H.dna.features = random_features(H.dna.species?.id)
// Apply Appearance
H.update_body() // Outfit and underware, also body.
H.update_body(TRUE) // Outfit and underwear, also body and privates.
//H.update_mutant_bodyparts() // Lizard tails etc
H.update_hair()
H.update_body_parts()
@@ -140,7 +140,7 @@
ADD_TRAIT(H, TRAIT_DISFIGURED, "husk") // NOTE: We are ASSUMING husk. // H.status_flags |= DISFIGURED // Restore "Unknown" disfigurement
H.dna.features = prev_features
// Apply Appearance
H.update_body() // Outfit and underware, also body.
H.update_body(TRUE) // Outfit and underwear, also body and privates.
H.update_hair()
H.update_body_parts() // Body itself, maybe skin color?
cast_effect() // POOF
@@ -5,6 +5,7 @@
var/special_role = ROLE_BROTHER
var/datum/team/brother_team/team
antag_moodlet = /datum/mood_event/focused
threat = 3
/datum/antagonist/brother/create_team(datum/team/brother_team/new_team)
if(!new_team)
@@ -8,6 +8,7 @@
antagpanel_category = "Changeling"
job_rank = ROLE_CHANGELING
antag_moodlet = /datum/mood_event/focused
threat = 10
var/you_are_greet = TRUE
var/give_objectives = TRUE
@@ -6,6 +6,7 @@
unique_name = 1
minbodytemp = 0
unsuitable_atmos_damage = 0
threat = 1
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) //Robotic
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
healable = FALSE
@@ -9,6 +9,7 @@
desc = "The stalwart apparition of a soldier, blazing with crimson flames. It's armed with a gladius and shield."
icon_state = "clockwork_marauder"
mob_biotypes = MOB_HUMANOID
threat = 3
health = 120
maxHealth = 120
force_threshold = 8
@@ -5,6 +5,7 @@
antagpanel_category = "Clockcult"
job_rank = ROLE_SERVANT_OF_RATVAR
antag_moodlet = /datum/mood_event/cult
threat = 3
var/datum/action/innate/hierophant/hierophant_network = new()
var/datum/team/clockcult/clock_team
var/make_team = TRUE //This should be only false for tutorial scarabs
+1
View File
@@ -5,6 +5,7 @@
roundend_category = "cultists"
antagpanel_category = "Cult"
antag_moodlet = /datum/mood_event/cult
threat = 3
var/datum/action/innate/cult/comm/communion = new
var/datum/action/innate/cult/mastervote/vote = new
var/datum/action/innate/cult/blood_magic/magic = new
@@ -349,6 +349,11 @@
brightness_on = 0
actions_types = list()
/obj/item/clothing/head/helmet/space/hardsuit/cult/ComponentInitialize()
. = ..()
AddElement(/datum/element/spellcasting, SPELL_CULT_HELMET, ITEM_SLOT_HEAD)
/obj/item/clothing/suit/space/hardsuit/cult
name = "\improper Nar'Sien hardened armor"
icon_state = "cult_armor"
@@ -359,6 +364,10 @@
armor = list("melee" = 70, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 40, "acid" = 75)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/cult
/obj/item/clothing/suit/space/hardsuit/cult/ComponentInitialize()
. = ..()
AddElement(/datum/element/spellcasting, SPELL_CULT_ARMOR, ITEM_SLOT_OCLOTHING)
/obj/item/sharpener/cult
name = "eldritch whetstone"
desc = "A block, empowered by dark magic. Sharp weapons will be enhanced when used on the stone."
+6 -3
View File
@@ -91,6 +91,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
job_rank = ROLE_DEVIL
//Don't delete upon mind destruction, otherwise soul re-selling will break.
delete_on_mind_deletion = FALSE
threat = 5
var/obligation
var/ban
var/bane
@@ -112,6 +113,9 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/obj/effect/proc_holder/spell/targeted/summon_dancefloor))
var/ascendable = FALSE
/datum/antagonist/devil/threat()
return ..() + form * 10
/datum/antagonist/devil/can_be_owned(datum/mind/new_owner)
. = ..()
return . && (ishuman(new_owner.current) || iscyborg(new_owner.current))
@@ -120,7 +124,6 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
. = ..()
.["Toggle ascendable"] = CALLBACK(src,.proc/admin_toggle_ascendable)
/datum/antagonist/devil/proc/admin_toggle_ascendable(mob/admin)
ascendable = !ascendable
message_admins("[key_name_admin(admin)] set [owner.current] devil ascendable to [ascendable]")
@@ -244,7 +247,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
H.undershirt = "Nude"
H.socks = "Nude"
H.dna.features["mcolor"] = "511" //A deep red
H.regenerate_icons()
H.update_body(TRUE)
else //Did the devil get hit by a staff of transmutation?
owner.current.color = "#501010"
give_appropriate_spells()
@@ -466,7 +469,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
H.undershirt = "Nude"
H.socks = "Nude"
H.dna.features["mcolor"] = "511"
H.regenerate_icons()
H.update_body(TRUE)
if(SOULVALUE >= TRUE_THRESHOLD) //Yes, BOTH this and the above if statement are to run if soulpower is high enough.
var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(targetturf)
A.faction |= "hell"
+2 -1
View File
@@ -62,6 +62,7 @@
name = "Imp"
antagpanel_category = "Devil"
show_in_roundend = FALSE
threat = 10
/datum/antagonist/imp/on_gain()
. = ..()
@@ -71,4 +72,4 @@
var/datum/objective/newobjective = new
newobjective.explanation_text = "Try to get a promotion to a higher devilic rank."
newobjective.owner = owner
objectives += newobjective
objectives += newobjective
@@ -14,6 +14,13 @@
var/static/list/sins = list(SIN_ACEDIA,SIN_GLUTTONY,SIN_GREED,SIN_SLOTH,SIN_WRATH,SIN_ENVY,SIN_PRIDE)
/datum/antagonist/sintouched/threat()
switch(sin)
if(SIN_GLUTTONY,SIN_ENVY)
return 1
else
return 0
/datum/antagonist/sintouched/New()
. = ..()
sin = pick(sins)
@@ -80,4 +87,4 @@
#undef SIN_GREED
#undef SIN_PRIDE
#undef SIN_SLOTH
#undef SIN_WRATH
#undef SIN_WRATH
@@ -59,7 +59,7 @@ new /datum/disease_ability/symptom/powerful/youth
var/stat_block = ""
var/threshold_block = ""
var/category = ""
var/malefit = 0 // used for threat calculation
var/list/symptoms
var/list/actions
@@ -282,6 +282,7 @@ new /datum/disease_ability/symptom/powerful/youth
/datum/disease_ability/symptom/medium/heal
cost = 5
malefit = -1
category = "Symptom (+)"
/datum/disease_ability/symptom/powerful
@@ -291,6 +292,7 @@ new /datum/disease_ability/symptom/powerful/youth
/datum/disease_ability/symptom/powerful/heal
cost = 8
malefit = -1
category = "Symptom (Strong+)"
/******MILD******/
@@ -319,50 +321,61 @@ new /datum/disease_ability/symptom/powerful/youth
/datum/disease_ability/symptom/medium/hallucigen
symptoms = list(/datum/symptom/hallucigen)
malefit = 1
short_desc = "Cause victims to hallucinate."
long_desc = "Cause victims to hallucinate. Decreases stats, especially resistance."
/datum/disease_ability/symptom/medium/choking
symptoms = list(/datum/symptom/choking)
malefit = 1
short_desc = "Cause victims to choke."
long_desc = "Cause victims to choke, threatening asphyxiation. Decreases stats, especially transmissibility."
/datum/disease_ability/symptom/medium/confusion
symptoms = list(/datum/symptom/confusion)
malefit = 1
short_desc = "Cause victims to become confused."
long_desc = "Cause victims to become confused intermittently."
/datum/disease_ability/symptom/medium/vomit
symptoms = list(/datum/symptom/vomit)
malefit = 1
short_desc = "Cause victims to vomit."
long_desc = "Cause victims to vomit. Slightly increases transmissibility. Vomiting also also causes the victims to lose nutrition and removes some toxin damage."
/datum/disease_ability/symptom/medium/voice_change
symptoms = list(/datum/symptom/voice_change)
malefit = 1
short_desc = "Change the voice of victims."
long_desc = "Change the voice of victims, causing confusion in communications."
/datum/disease_ability/symptom/medium/visionloss
symptoms = list(/datum/symptom/visionloss)
malefit = 1
short_desc = "Damage the eyes of victims, eventually causing blindness."
long_desc = "Damage the eyes of victims, eventually causing blindness. Decreases all stats."
/datum/disease_ability/symptom/medium/deafness
malefit = 1
symptoms = list(/datum/symptom/deafness)
/datum/disease_ability/symptom/medium/fever
malefit = 1
symptoms = list(/datum/symptom/fever)
/datum/disease_ability/symptom/medium/shivering
malefit = 1
symptoms = list(/datum/symptom/shivering)
/datum/disease_ability/symptom/medium/headache
symptoms = list(/datum/symptom/headache)
/datum/disease_ability/symptom/medium/nano_boost
malefit = -1
symptoms = list(/datum/symptom/nano_boost)
/datum/disease_ability/symptom/medium/nano_destroy
malefit = 1
symptoms = list(/datum/symptom/nano_destroy)
/datum/disease_ability/symptom/medium/viraladaptation
@@ -374,18 +387,22 @@ new /datum/disease_ability/symptom/powerful/youth
symptoms = list(/datum/symptom/viralevolution)
/datum/disease_ability/symptom/medium/polyvitiligo
malefit = 1
symptoms = list(/datum/symptom/polyvitiligo)
/datum/disease_ability/symptom/medium/disfiguration
malefit = 1
symptoms = list(/datum/symptom/disfiguration)
/datum/disease_ability/symptom/medium/itching
symptoms = list(/datum/symptom/itching)
malefit = 1
short_desc = "Cause victims to itch."
long_desc = "Cause victims to itch, increasing all stats except stealth."
/datum/disease_ability/symptom/medium/heal/weight_loss
symptoms = list(/datum/symptom/weight_loss)
malefit = 1
short_desc = "Cause victims to lose weight."
long_desc = "Cause victims to lose weight, and make it almost impossible for them to gain nutrition from food. Reduced nutrition allows your infection to spread more easily from hosts, especially by sneezing."
@@ -400,12 +417,15 @@ new /datum/disease_ability/symptom/powerful/youth
/******POWERFUL******/
/datum/disease_ability/symptom/powerful/fire
malefit = 1
symptoms = list(/datum/symptom/fire)
/datum/disease_ability/symptom/powerful/flesh_eating
malefit = 1
symptoms = list(/datum/symptom/flesh_eating)
/datum/disease_ability/symptom/powerful/genetic_mutation
malefit = 1
symptoms = list(/datum/symptom/genetic_mutation)
cost = 8
@@ -413,6 +433,7 @@ new /datum/disease_ability/symptom/powerful/youth
symptoms = list(/datum/symptom/inorganic_adaptation)
/datum/disease_ability/symptom/powerful/narcolepsy
malefit = 1
symptoms = list(/datum/symptom/narcolepsy)
/datum/disease_ability/symptom/powerful/youth
@@ -451,4 +472,4 @@ new /datum/disease_ability/symptom/powerful/youth
/datum/disease_ability/symptom/powerful/heal/coma
symptoms = list(/datum/symptom/heal/coma)
short_desc = "Cause victims to fall into a healing coma when hurt."
long_desc = "Cause victims to fall into a healing coma when hurt."
long_desc = "Cause victims to fall into a healing coma when hurt."
@@ -17,6 +17,14 @@
. = ..()
/datum/antagonist/disease/threat()
var/mob/camera/disease/D = owner.current
var/final_threat = 0
for(var/V in D.purchased_abilities)
var/datum/disease_ability/A = V
final_threat += (A.cost/8)*A.malefit
return final_threat*D.hosts
/datum/antagonist/disease/greet()
to_chat(owner.current, "<span class='notice'>You are the [owner.special_role]!</span>")
to_chat(owner.current, "<span class='notice'>Infect members of the crew to gain adaptation points, and spread your infection further.</span>")
+1
View File
@@ -10,6 +10,7 @@
var/datum/outfit/outfit = /datum/outfit/ert/security
var/role = "Security Officer"
var/list/name_source
threat = -5
show_in_antagpanel = FALSE
antag_moodlet = /datum/mood_event/focused
@@ -2,6 +2,7 @@
name = "Emergency Assistant"
show_name_in_check_antagonists = TRUE
show_in_antagpanel = FALSE
threat = -1
var/mission = "Assist the station."
var/datum/outfit/outfit = /datum/outfit/ert/greybois
@@ -73,4 +73,4 @@
antiwelder.name = "compulsion of honor"
antiwelder.desc = "You are unable to hold anything in this hand until you're the last one left!"
antiwelder.icon_state = "bloodhand_right"
H.put_in_hands(antiwelder)
H.put_in_hands(antiwelder)
@@ -8,6 +8,7 @@
job_rank = ROLE_MONKEY
roundend_category = "monkeys"
antagpanel_category = "Monkey"
threat = 3
var/datum/team/monkey/monkey_team
var/monkey_only = TRUE
@@ -81,6 +82,7 @@
/datum/antagonist/monkey/leader
name = "Monkey Leader"
threat = 5
monkey_only = FALSE
/datum/antagonist/monkey/leader/admin_add(datum/mind/new_owner,mob/admin)
@@ -2,5 +2,6 @@
name = "Morph"
show_name_in_check_antagonists = TRUE
show_in_antagpanel = FALSE
threat = 2
//It does nothing! (Besides tracking)
//It does nothing! (Besides tracking)
@@ -1,4 +1,5 @@
/datum/antagonist/nightmare
name = "Nightmare"
show_in_antagpanel = FALSE
show_name_in_check_antagonists = TRUE
show_name_in_check_antagonists = TRUE
threat = 5
+4
View File
@@ -4,10 +4,14 @@
job_rank = ROLE_NINJA
show_name_in_check_antagonists = TRUE
antag_moodlet = /datum/mood_event/focused
threat = 8
var/helping_station = FALSE
var/give_objectives = TRUE
var/give_equipment = TRUE
/datum/antagonist/ninja/threat()
return helping_station ? -(..()) : ..()
/datum/antagonist/ninja/apply_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
update_ninja_icons_added(M)
@@ -3,6 +3,7 @@
name = "Clown Operative"
roundend_category = "clown operatives"
antagpanel_category = "ClownOp"
threat = 7
nukeop_outfit = /datum/outfit/syndicate/clownop
/datum/antagonist/nukeop/clownop/on_gain()
@@ -74,12 +74,6 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS - tc_malus + CEILING(PLAYER_SCALING * actual_players, 1))
CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY))
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(!(mode.storyteller.flags & WAROPS_ALWAYS_ALLOWED))
var/threat_spent = CONFIG_GET(number/dynamic_warops_cost)
mode.spend_threat(threat_spent)
mode.log_threat("Nuke ops spent [threat_spent] on war ops.")
SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1)
qdel(src)
@@ -74,16 +74,15 @@
/obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station)
var/datum/game_mode/nuclear/NM = SSticker.mode
switch(off_station)
if(0)
if(FALSE)
if(istype(NM) && !NM.nuke_team.syndies_escaped())
return CINEMATIC_ANNIHILATION
else
return CINEMATIC_NUKE_WIN
if(1)
if(NUKE_MISS_STATION)
return CINEMATIC_NUKE_MISS
if(2)
else
return CINEMATIC_NUKE_FAR
return CINEMATIC_NUKE_FAR
/obj/machinery/nuclearbomb/proc/disk_check(obj/item/disk/nuclear/D)
if(D.fake)
@@ -387,14 +386,14 @@
if("anchor")
if(auth && yes_code)
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
set_anchor()
set_anchor(usr)
else
playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE)
/obj/machinery/nuclearbomb/proc/set_anchor()
if(isinspace() && !anchored)
to_chat(usr, "<span class='warning'>There is nothing to anchor to!</span>")
/obj/machinery/nuclearbomb/proc/set_anchor(mob/user)
if((istype(get_area(src), /area/space) || isinspace()) && !anchored)
to_chat(user, "<span class='warning'>This is not a suitable platform for anchoring [src]!</span>")
else
anchored = !anchored
@@ -415,11 +414,11 @@
if(safety)
to_chat(usr, "<span class='danger'>The safety is still on.</span>")
return
if(!timing && nuclear_cooldown > world.time)
to_chat(usr, "<span class='danger'>[src]'s timer protocols are currently on cooldown, please stand by.</span>")
return
timing = !timing
if(timing)
if(nuclear_cooldown > world.time)
to_chat(usr, "<span class='danger'>[src]'s timer protocols are currently on cooldown, please stand by.</span>")
return
previous_level = get_security_level()
detonation_timer = world.time + (timer_set * 10)
for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
@@ -480,20 +479,14 @@
GLOB.enter_allowed = FALSE
var/off_station = 0
var/off_station = FALSE
var/turf/bomb_location = get_turf(src)
var/area/A = get_area(bomb_location)
if(bomb_location && is_station_level(bomb_location.z))
if(istype(A, /area/space))
off_station = NUKE_NEAR_MISS
if((bomb_location.x < (128-NUKERANGE)) || (bomb_location.x > (128+NUKERANGE)) || (bomb_location.y < (128-NUKERANGE)) || (bomb_location.y > (128+NUKERANGE)))
off_station = NUKE_NEAR_MISS
if(!bomb_location || !is_station_level(bomb_location.z))
off_station = NUKE_MISS_STATION
else if(bomb_location.onSyndieBase())
off_station = NUKE_SYNDICATE_BASE
else
off_station = NUKE_MISS_STATION
if(off_station < 2)
if(!off_station)
SSshuttle.registerHostileEnvironment(src)
SSshuttle.lockdown = TRUE
@@ -507,7 +500,7 @@
INVOKE_ASYNC(GLOBAL_PROC,.proc/KillEveryoneOnZLevel, z)
/obj/machinery/nuclearbomb/proc/get_cinematic_type(off_station)
if(off_station < 2)
if(!off_station)
return CINEMATIC_SELFDESTRUCT
else
return CINEMATIC_SELFDESTRUCT_MISS
@@ -588,7 +581,7 @@
This is here to make the tiles around the station mininuke change when it's armed.
*/
/obj/machinery/nuclearbomb/selfdestruct/set_anchor()
/obj/machinery/nuclearbomb/selfdestruct/set_anchor(mob/user)
return
/obj/machinery/nuclearbomb/selfdestruct/set_active()
@@ -4,6 +4,7 @@
antagpanel_category = "NukeOp"
job_rank = ROLE_OPERATIVE
antag_moodlet = /datum/mood_event/focused
threat = 10
var/datum/team/nuclear/nuke_team
var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team.
var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint.
@@ -10,6 +10,7 @@
roundend_category = "syndicate mutineers"
antagpanel_category = "Syndicate Mutineers"
job_rank = ROLE_TRAITOR // simply use the traitor preference & jobban settings
threat = 5
var/datum/team/overthrow/team
var/static/list/possible_useful_items
+2 -1
View File
@@ -3,6 +3,7 @@
job_rank = ROLE_TRAITOR
roundend_category = "space pirates"
antagpanel_category = "Pirate"
threat = 5
var/datum/team/pirate/crew
/datum/antagonist/pirate/greet()
@@ -104,4 +105,4 @@
else
parts += "<span class='redtext big'>The pirate crew has failed.</span>"
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
@@ -117,7 +117,7 @@
tinfoil_check = FALSE
/obj/effect/proc_holder/spell/aoe_turf/revenant
clothes_req = 0
clothes_req = NONE
action_icon = 'icons/mob/actions/actions_revenant.dmi'
action_background_icon_state = "bg_revenant"
panel = "Revenant Abilities (Locked)"
@@ -135,7 +135,7 @@
else
name = "[initial(name)] ([cast_amount]E)"
/obj/effect/proc_holder/spell/aoe_turf/revenant/can_cast(mob/living/simple_animal/revenant/user = usr)
/obj/effect/proc_holder/spell/aoe_turf/revenant/can_cast(mob/living/simple_animal/revenant/user = usr, skipcharge = FALSE, silent = FALSE)
if(charge_counter < charge_max)
return FALSE
if(!istype(user)) //Badmins, no. Badmins, don't do it.
@@ -2,6 +2,7 @@
name = "Revenant"
show_in_antagpanel = FALSE
show_name_in_check_antagonists = TRUE
threat = 5
/datum/antagonist/revenant/greet()
owner.announce_objectives()
@@ -7,6 +7,7 @@
antagpanel_category = "Revolution"
job_rank = ROLE_REV
antag_moodlet = /datum/mood_event/revolution
threat = 2
var/hud_type = "rev"
var/datum/team/revolution/rev_team
@@ -148,6 +149,7 @@
/datum/antagonist/rev/head
name = "Head Revolutionary"
hud_type = "rev_head"
threat = 8
var/remove_clumsy = FALSE
var/give_flash = FALSE
var/give_hud = TRUE
+1 -1
View File
@@ -18,7 +18,7 @@
owner.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/presents)
var/obj/effect/proc_holder/spell/targeted/area_teleport/teleport/telespell = new
telespell.clothes_req = 0 //santa robes aren't actually magical.
telespell.clothes_req = NONE //santa robes aren't actually magical.
owner.AddSpell(telespell) //does the station have chimneys? WHO KNOWS!
/datum/antagonist/santa/proc/give_objective()
@@ -3,6 +3,7 @@
show_name_in_check_antagonists = TRUE
var/objective_verb = "Kill"
var/datum/mind/summoner
threat = 10
job_rank = ROLE_ALIEN
show_in_antagpanel = FALSE
@@ -28,4 +29,4 @@
/datum/antagonist/slaughter/laughter
name = "Laughter demon"
objective_verb = "Hug and Tickle"
objective_verb = "Hug and Tickle"
@@ -3,6 +3,7 @@
show_in_antagpanel = FALSE
show_name_in_check_antagonists = TRUE
blacklisted_quirks = list(/datum/quirk/nonviolent) // mutes are allowed
threat = 1
var/greet_message = ""
/datum/antagonist/survivalist/proc/forge_objectives()
@@ -70,6 +70,7 @@
icon_living = "swarmer"
icon_dead = "swarmer_unactivated"
icon_gib = null
threat = 0.5
wander = 0
harm_intent_damage = 5
minbodytemp = 0
@@ -1,5 +1,6 @@
/datum/traitor_class/ai // this one is special, so has no weight
name = "Malfunctioning AI"
threat = 20
/datum/traitor_class/ai/forge_objectives(datum/antagonist/traitor/T)
var/objective_count = 0
@@ -3,7 +3,7 @@
employer = "Donk Corporation"
weight = 0
chaos = 1
cost = 2
threat = 2
/datum/traitor_class/human/assassin/forge_single_objective(datum/antagonist/traitor/T)
.=1
@@ -3,7 +3,7 @@
employer = "The Gorlex Marauders"
weight = 3
chaos = 5
cost = 5
threat = 3
uplink_filters = list(/datum/uplink_item/stealthy_weapons/romerol_kit)
/datum/traitor_class/human/hijack/forge_objectives(datum/antagonist/traitor/T)
@@ -34,7 +34,7 @@
if(is_dynamic)
var/threat_spent = CONFIG_GET(number/dynamic_assassinate_cost)
mode.spend_threat(threat_spent)
mode.log_threat("[T.owner.name] spent [threat_spent] on an assassination target.")
mode.log_threat("[T.owner.name] added [threat_spent] on an assassination target.")
var/list/active_ais = active_ais()
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
var/datum/objective/destroy/destroy_objective = new
@@ -3,7 +3,7 @@
employer = "The Tiger Cooperative"
weight = 2
chaos = 5
cost = 5
threat = 5
uplink_filters = list(/datum/uplink_item/stealthy_weapons/romerol_kit,/datum/uplink_item/bundles_TC/contract_kit)
/datum/traitor_class/human/martyr/forge_objectives(datum/antagonist/traitor/T)
@@ -5,7 +5,7 @@ GLOBAL_LIST_EMPTY(traitor_classes)
var/employer = "The Syndicate"
var/weight = 0
var/chaos = 0
var/cost = 0
var/threat = 0
var/TC = 20
var/list/uplink_filters
@@ -12,6 +12,7 @@
var/datum/traitor_class/traitor_kind
var/datum/contractor_hub/contractor_hub
hijack_speed = 0.5 //10 seconds per hijack stage by default
threat = 5
/datum/antagonist/traitor/New()
..()
@@ -21,11 +22,6 @@
/datum/antagonist/traitor/proc/set_traitor_kind(var/kind)
traitor_kind = GLOB.traitor_classes[kind]
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(traitor_kind.cost)
mode.spend_threat(traitor_kind.cost)
mode.log_threat("[traitor_kind.cost] was spent due to [owner.name] being a [traitor_kind.name].")
/datum/antagonist/traitor/on_gain()
if(owner.current && isAI(owner.current))
@@ -38,7 +34,7 @@
var/list/weights = list()
for(var/C in GLOB.traitor_classes)
var/datum/traitor_class/class = GLOB.traitor_classes[C]
var/weight = (1.5*class.weight)/(0.5+NUM_E**(-chaos_weight*class.chaos)) // just a logistic function
var/weight = LOGISTIC_FUNCTION(1.5*class.weight,chaos_weight,class.chaos,0)
weights[C] = weight
var/choice = pickweightAllowZero(weights)
if(!choice)
@@ -100,6 +96,13 @@
equip(silent)
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE)
/datum/antagonist/traitor/antag_panel_objectives()
. = ..()
if(contractor_hub?.assigned_targets && length(contractor_hub.assigned_targets))
. += "<i><b>Contract Targets</b></i>:<br>"
for(var/datum/mind/M in contractor_hub.assigned_targets)
. += "<b> - </b>[key_name(M, FALSE, TRUE)]<br>"
/datum/antagonist/traitor/apply_innate_effects(mob/living/mob_override)
. = ..()
update_traitor_icons_added()
@@ -294,3 +297,6 @@
/datum/antagonist/traitor/is_gamemode_hero()
return SSticker.mode.name == "traitor"
/datum/antagonist/traitor/threat()
return (..())+traitor_kind.threat
@@ -87,9 +87,9 @@
As is policy we've taken a portion of the station's funds to offset the overall cost.", null, "attention", null, "Nanotrasen Asset Protection")
/datum/syndicate_contract/proc/handleVictimExperience(var/mob/living/M) // They're off to holding - handle the return timer and give some text about what's going on.
addtimer(CALLBACK(src, .proc/returnVictim, M), (60 * 10) * 4) // Ship 'em back - dead or alive... 4 minutes wait.
addtimer(CALLBACK(src, .proc/returnVictim, M), 4 MINUTES) // Ship 'em back - dead or alive... 4 minutes wait.
if(M.stat != DEAD) //Even if they weren't the target, we're still treating them the same.
M.reagents.add_reagent(/datum/reagent/medicine/omnizine, 20) // Heal them up - gets them out of crit/soft crit.
M.reagents.add_reagent(/datum/reagent/medicine/regen_jelly, 20) // Heal them up - gets them out of crit/soft crit. -- now 100% toxinlover friendly!!
M.flash_act()
M.confused += 10
M.blur_eyes(5)
@@ -147,4 +147,4 @@
if(iscarbon(M))
var/mob/living/carbon/C = M
if(C.can_heartattack())
C.set_heartattack(TRUE)
C.set_heartattack(TRUE)
@@ -2,6 +2,7 @@
name = "Wishgranter Avatar"
show_in_antagpanel = FALSE
show_name_in_check_antagonists = TRUE
threat = 20
/datum/antagonist/wishgranter/proc/forge_objectives()
var/datum/objective/hijack/hijack = new
@@ -25,4 +26,4 @@
H.dna.add_mutation(HULK)
H.dna.add_mutation(XRAY)
H.dna.add_mutation(SPACEMUT)
H.dna.add_mutation(TK)
H.dna.add_mutation(TK)
@@ -11,7 +11,6 @@
var/buy_word = "Learn"
var/limit //used to prevent a spellbook_entry from being bought more than X times with one wizard spellbook
var/list/no_coexistance_typecache //Used so you can't have specific spells together
var/dynamic_cost = 0 // How much threat the spell costs to purchase for dynamic.
var/dynamic_requirement = 0 // How high the threat level needs to be for purchasing in dynamic.
/datum/spellbook_entry/New()
@@ -31,10 +30,6 @@
for(var/spell in user.mind.spell_list)
if(is_type_in_typecache(spell, no_coexistance_typecache))
return 0
if(dynamic_cost>0 && istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat < dynamic_cost)
return 0
return 1
/datum/spellbook_entry/proc/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) //return 1 on success
@@ -70,10 +65,6 @@
SSblackbox.record_feedback("nested tally", "wizard_spell_improved", 1, list("[name]", "[aspell.spell_level]"))
return 1
//No same spell found - just learn it
if(dynamic_cost > 0 && istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
mode.spend_threat(dynamic_cost)
mode.log_threat("Wizard spent [dynamic_cost] on [name].")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
user.mind.AddSpell(S)
to_chat(user, "<span class='notice'>You have learned [S.name].</span>")
@@ -97,10 +88,6 @@
if(!S)
S = new spell_type()
var/spell_levels = 0
if(dynamic_cost > 0 && istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
mode.refund_threat(dynamic_cost)
mode.log_threat("Wizard refunded [dynamic_cost] on [name].")
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
if(initial(S.name) == initial(aspell.name))
spell_levels = aspell.spell_level
@@ -117,7 +104,7 @@
dat += " Cooldown:[S.charge_max/10]"
dat += " Cost:[cost]<br>"
dat += "<i>[S.desc][desc]</i><br>"
dat += "[S.clothes_req?"Needs wizard garb":"Can be cast without wizard garb"]<br>"
dat += "[S.clothes_req & SPELL_WIZARD_GARB ? "Needs wizard garb" : "Can be cast without wizard garb"]<br>"
return dat
/datum/spellbook_entry/fireball
@@ -308,7 +295,6 @@
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself."
item_path = /obj/item/gun/magic/staff/change
dynamic_requirement = 60
dynamic_cost = 20
/datum/spellbook_entry/item/staffanimation
name = "Staff of Animation"
@@ -376,7 +362,6 @@
item_path = /obj/item/storage/belt/wands/full
category = "Defensive"
dynamic_requirement = 60
dynamic_cost = 10
/datum/spellbook_entry/item/armor
name = "Mastercrafted Armor Set"
@@ -396,7 +381,6 @@
item_path = /obj/item/antag_spawner/contract
category = "Assistance"
dynamic_requirement = 50
dynamic_cost = 10
/datum/spellbook_entry/item/plasmafist
name = "Plasma Fist"
@@ -424,10 +408,6 @@
category = "Assistance"
dynamic_requirement = 60
/datum/spellbook_entry/item/bloodbottle/New()
..()
dynamic_cost = CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"]
/datum/spellbook_entry/item/hugbottle
name = "Bottle of Tickles"
desc = "A bottle of magically infused fun, the smell of which will \
@@ -443,10 +423,6 @@
category = "Assistance"
dynamic_requirement = 40
/datum/spellbook_entry/item/hugbottle/New()
..()
dynamic_cost = CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"]/3
/datum/spellbook_entry/item/mjolnir
name = "Mjolnir"
desc = "A mighty hammer on loan from Thor, God of Thunder. It crackles with barely contained power."
@@ -522,7 +498,6 @@
/datum/spellbook_entry/summon/guns
name = "Summon Guns"
desc = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill you. Just be careful not to stand still too long!"
dynamic_cost = 10
dynamic_requirement = 60
/datum/spellbook_entry/summon/guns/IsAvailible()
@@ -536,17 +511,11 @@
active = 1
playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1)
to_chat(user, "<span class='notice'>You have cast summon guns!</span>")
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = dynamic_cost
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on summon guns.")
return 1
/datum/spellbook_entry/summon/magic
name = "Summon Magic"
desc = "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time."
dynamic_cost = 10
dynamic_requirement = 60
/datum/spellbook_entry/summon/magic/IsAvailible()
@@ -560,17 +529,11 @@
active = 1
playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1)
to_chat(user, "<span class='notice'>You have cast summon magic!</span>")
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = dynamic_cost
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on summon magic.")
return 1
/datum/spellbook_entry/summon/events
name = "Summon Events"
desc = "Give Murphy's law a little push and replace all events with special wizard ones that will confound and confuse everyone. Multiple castings increase the rate of these events."
dynamic_cost = 20
dynamic_requirement = 60
var/times = 0
@@ -582,11 +545,6 @@
/datum/spellbook_entry/summon/events/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
summonevents()
if(istype(SSticker.mode,/datum/game_mode/dynamic) && times == 0)
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = dynamic_cost
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on summon events.")
times++
playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1)
to_chat(user, "<span class='notice'>You have cast summon events.</span>")
@@ -687,7 +645,7 @@
/obj/item/spellbook/proc/wrap(content)
var/dat = ""
dat +="<html><head><title>Spellbook</title></head>"
dat +="<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Spellbook</title></head>"
dat += {"
<head>
<style type="text/css">
@@ -4,6 +4,7 @@
antagpanel_category = "Wizard"
job_rank = ROLE_WIZARD
antag_moodlet = /datum/mood_event/focused
threat = 30
var/give_objectives = TRUE
var/strip = TRUE //strip before equipping
var/allow_rename = TRUE
+2 -1
View File
@@ -13,6 +13,7 @@
job_rank = ROLE_ALIEN
show_in_antagpanel = FALSE
var/datum/team/xeno/xeno_team
threat = 3
/datum/antagonist/xeno/create_team(datum/team/xeno/new_team)
if(!new_team)
@@ -34,4 +35,4 @@
/mob/living/carbon/alien/mind_initialize()
..()
if(!mind.has_antag_datum(/datum/antagonist/xeno))
mind.add_antag_datum(/datum/antagonist/xeno)
mind.add_antag_datum(/datum/antagonist/xeno)
@@ -179,7 +179,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g
/datum/gas/miasma
id = "miasma"
specific_heat = 0.00001
specific_heat = 20
fusion_power = 50
name = "Miasma"
gas_overlay = "miasma"
@@ -667,7 +667,8 @@
else
set_light(0)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, EMISSIVE_LAYER, EMISSIVE_PLANE, dir)
update_light()
/obj/machinery/airalarm/process()
+1 -1
View File
@@ -208,7 +208,7 @@
else
H.skin_tone = random_skin_tone()
H.update_hair()
H.update_body()
H.update_body() //update_genitals arg FALSE because these don't quite require/have them most times.
if(outfit)
var/static/list/slots = list("uniform", "r_hand", "l_hand", "suit", "shoes", "gloves", "ears", "glasses", "mask", "head", "belt", "r_pocket", "l_pocket", "back", "id", "neck", "backpack_contents", "suit_store")
for(var/slot in slots)
@@ -309,7 +309,7 @@
name = "Summon Servant"
desc = "This spell can be used to call your servant, whenever you need it."
charge_max = 100
clothes_req = 0
clothes_req = NONE
invocation = "JE VES"
invocation_type = "whisper"
range = -1
-38
View File
@@ -164,17 +164,6 @@
/obj/item/shield/riot)
crate_name = "riot shields crate"
/datum/supply_pack/security/armory/riotshotguns
name = "Riot Shotgun Crate"
desc = "For when the greytide gets really uppity. Contains three riot shotguns, seven rubber shot and beanbag shells. Requires Armory access to open."
cost = 6500
contains = list(/obj/item/gun/ballistic/shotgun/riot,
/obj/item/gun/ballistic/shotgun/riot,
/obj/item/gun/ballistic/shotgun/riot,
/obj/item/storage/box/rubbershot,
/obj/item/storage/box/beanbag)
crate_name = "riot shotgun crate"
/datum/supply_pack/security/armory/russian
name = "Russian Surplus Crate"
desc = "Hello Comrade, we have the most modern russian military equipment the black market can offer, for the right price of course. Sadly we couldnt remove the lock so it requires Armory access to open."
@@ -216,23 +205,6 @@
/obj/item/clothing/gloves/combat)
crate_name = "swat crate"
/datum/supply_pack/security/armory/swattasers //Lesser AEG tbh
name = "SWAT tactical tasers Crate"
desc = "Contains two tactical energy gun, these guns are able to tase, disable and lethal as well as hold a seclight. Requires Armory access to open."
cost = 7000
contains = list(/obj/item/gun/energy/e_gun/stun,
/obj/item/gun/energy/e_gun/stun)
crate_name = "swat taser crate"
/datum/supply_pack/security/armory/woodstock
name = "WoodStock Classic Shotguns Crate"
desc = "Contains three rustic, pumpaction shotguns. Requires Armory access to open."
cost = 3000
contains = list(/obj/item/gun/ballistic/shotgun,
/obj/item/gun/ballistic/shotgun,
/obj/item/gun/ballistic/shotgun)
crate_name = "woodstock shotguns crate"
/datum/supply_pack/security/armory/wt550
name = "WT-550 Semi-Auto Rifle Crate"
desc = "Contains two high-powered, semiautomatic rifles chambered in 4.6x30mm. Requires Armory access to open."
@@ -260,13 +232,3 @@
/obj/item/ammo_box/magazine/wt550m9/wtrubber,
/obj/item/ammo_box/magazine/wt550m9/wtrubber)
crate_name = "auto rifle ammo crate"
/datum/supply_pack/security/armory/wt550ammo_special
name = "WT-550 Semi-Auto SMG Special Ammo Crate"
desc = "Contains 2 20-round Armour Piercing and Incendiary magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
cost = 3000
contains = list(/obj/item/ammo_box/magazine/wt550m9/wtap,
/obj/item/ammo_box/magazine/wt550m9/wtap,
/obj/item/ammo_box/magazine/wt550m9/wtic,
/obj/item/ammo_box/magazine/wt550m9/wtic)
crate_name = "auto rifle ammo crate"
+1 -25
View File
@@ -206,30 +206,6 @@
/obj/item/storage/box/mre/menu4/safe)
crate_name = "MRE crate (emergency rations)"
/datum/supply_pack/emergency/syndicate
name = "NULL_ENTRY"
desc = "(#@&^$THIS PACKAGE CONTAINS 30TC WORTH OF SOME RANDOM SYNDICATE GEAR WE HAD LYING AROUND THE WAREHOUSE. GIVE EM HELL, OPERATIVE@&!*() "
hidden = TRUE
cost = 20000
contains = list()
crate_name = "emergency crate"
crate_type = /obj/structure/closet/crate/internals
dangerous = TRUE
/datum/supply_pack/emergency/syndicate/fill(obj/structure/closet/crate/C)
var/crate_value = 30
var/list/uplink_items = get_uplink_items(SSticker.mode)
while(crate_value)
var/category = pick(uplink_items)
var/item = pick(uplink_items[category])
var/datum/uplink_item/I = uplink_items[category][item]
if(!I.surplus_nullcrates || prob(100 - I.surplus_nullcrates))
continue
if(crate_value < I.cost)
continue
crate_value -= I.cost
new I.item(C)
/datum/supply_pack/emergency/plasma_spacesuit
name = "Plasmaman Space Envirosuits"
desc = "Contains two space-worthy envirosuits for Plasmamen. Order now and we'll throw in two free helmets! Requires EVA access to open."
@@ -311,7 +287,7 @@
/datum/supply_pack/emergency/specialops
name = "Special Ops Supplies"
desc = "(*!&@#TOO CHEAP FOR THAT NULL_ENTRY, HUH OPERATIVE? WELL, THIS LITTLE ORDER CAN STILL HELP YOU OUT IN A PINCH. CONTAINS A BOX OF FIVE EMP GRENADES, THREE SMOKEBOMBS, AN INCENDIARY GRENADE, AND A \"SLEEPY PEN\" FULL OF NICE TOXINS!#@*$"
desc = "(*!&@#NEED SOMETHING TO DEAL WITH THE GREYTIDE, HUH OPERATIVE? WELL, THIS LITTLE ORDER CAN HELP YOU OUT IN A PINCH. CONTAINS A BOX OF FIVE EMP GRENADES, THREE SMOKEBOMBS, AN INCENDIARY GRENADE, AND A \"SLEEPY PEN\" FULL OF NICE TOXINS!#@*$"
hidden = TRUE
cost = 2200
contains = list(/obj/item/storage/box/emps,
+1 -1
View File
@@ -152,7 +152,7 @@
/obj/item/instrument/trombone,
/obj/item/instrument/recorder,
/obj/item/instrument/harmonica,
/obj/structure/piano/unanchored)
/obj/structure/musician/piano/unanchored)
crate_type = /obj/structure/closet/crate/wooden
/datum/supply_pack/misc/casinocrate
-29
View File
@@ -108,17 +108,6 @@
/obj/item/clothing/gloves/color/latex/nitrile)
crate_name = "nitrile gloves crate"
/datum/supply_pack/science/nuke_b_gone
name = "Nuke Defusal Kit"
desc = "Contains set of tools to defuse a nuke."
cost = 7500 //Useful for traitors/nukies that fucked up
dangerous = TRUE
hidden = TRUE
contains = list(/obj/item/nuke_core_container/nt,
/obj/item/screwdriver/nuke/nt,
/obj/item/paper/guides/nt/nuke_instructions)
crate_name = "safe defusal kit storage"
/datum/supply_pack/science/plasma
name = "Plasma Assembly Crate"
desc = "Everything you need to burn something to the ground, this contains three plasma assembly sets. Each set contains a plasma tank, igniter, proximity sensor, and timer! Warranty void if exposed to high temperatures. Requires Toxins access to open."
@@ -191,17 +180,6 @@
crate_name = "slime core crate"
crate_type = /obj/structure/closet/crate/secure/science
/datum/supply_pack/science/supermater
name = "Supermatter Extraction Tools Crate"
desc = "Contains a set of tools to extract a sliver of supermatter. Consult your CE today!"
cost = 7500 //Useful for traitors that fucked up
hidden = TRUE
contains = list(/obj/item/nuke_core_container/supermatter,
/obj/item/scalpel/supermatter,
/obj/item/hemostat/supermatter,
/obj/item/paper/guides/antag/supermatter_sliver)
crate_name = "supermatter extraction kit crate"
/datum/supply_pack/science/tablets
name = "Tablet Crate"
desc = "What's a computer? Contains five cargo tablets."
@@ -224,10 +202,3 @@
crate_type = /obj/structure/closet/crate/secure/science
dangerous = TRUE
/datum/supply_pack/science/tech_slugs
name = "Tech Slug Ammo Shells"
desc = "A new type of shell that is able to be made into a few different dangerous types. Contains two boxes of tech slugs, 14 shells in all."
cost = 1700
contains = list(/obj/item/storage/box/techsslug,
/obj/item/storage/box/techsslug)
crate_name = "tech slug crate"
+4
View File
@@ -14,6 +14,10 @@
var/jobbancache = null //Used to cache this client's jobbans to save on DB queries
var/last_message = "" //Contains the last message sent by this client - used to protect against copy-paste spamming.
var/last_message_count = 0 //contins a number of how many times a message identical to last_message was sent.
///How many messages sent in the last 10 seconds
var/total_message_count = 0
///Next tick to reset the total message counter
var/total_count_reset = 0
var/ircreplyamount = 0
/////////
+36
View File
@@ -141,7 +141,43 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
return 0
return 1
/*
* Call back proc that should be checked in all paths where a client can send messages
*
* Handles checking for duplicate messages and people sending messages too fast
*
* The first checks are if you're sending too fast, this is defined as sending
* SPAM_TRIGGER_AUTOMUTE messages in
* 5 seconds, this will start supressing your messages,
* if you send 2* that limit, you also get muted
*
* The second checks for the same duplicate message too many times and mutes
* you for it
*/
/client/proc/handle_spam_prevention(message, mute_type)
//Increment message count
total_message_count += 1
//store the total to act on even after a reset
var/cache = total_message_count
if(total_count_reset <= world.time)
total_message_count = 0
total_count_reset = world.time + (5 SECONDS)
//If they're really going crazy, mute them
if(cache >= SPAM_TRIGGER_AUTOMUTE * 2)
total_message_count = 0
total_count_reset = 0
cmd_admin_mute(src, mute_type, 1)
return 1
//Otherwise just supress the message
else if(cache >= SPAM_TRIGGER_AUTOMUTE)
return 1
if(CONFIG_GET(flag/automute_on) && !holder && last_message == message)
src.last_message_count++
if(src.last_message_count >= SPAM_TRIGGER_AUTOMUTE)
+104 -61
View File
@@ -125,8 +125,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"cock_length" = COCK_SIZE_DEF,
"cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF,
"cock_color" = "fff",
"cock_taur" = FALSE,
"has_balls" = FALSE,
"balls_internal" = FALSE,
"balls_color" = "fff",
"balls_shape" = DEF_BALLS_SHAPE,
"balls_size" = BALLS_SIZE_DEF,
@@ -141,12 +141,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"has_vag" = FALSE,
"vag_shape" = DEF_VAGINA_SHAPE,
"vag_color" = "fff",
"vag_clits" = 1,
"vag_clit_diam" = 0.25,
"has_womb" = FALSE,
"womb_cum_rate" = CUM_RATE,
"womb_cum_mult" = CUM_RATE_MULT,
"womb_efficiency" = CUM_EFFICIENCY,
"balls_visibility" = GEN_VISIBLE_NO_UNDIES,
"breasts_visibility"= GEN_VISIBLE_NO_UNDIES,
"cock_visibility" = GEN_VISIBLE_NO_UNDIES,
"vag_visibility" = GEN_VISIBLE_NO_UNDIES,
"ipc_screen" = "Sunburst",
"ipc_antenna" = "None",
"flavor_text" = "",
@@ -187,6 +186,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/sprint_spacebar = FALSE
var/sprint_toggle = FALSE
var/hud_toggle_flash = TRUE
var/hud_toggle_color = "#ffffff"
var/list/exp = list()
var/list/menuoptions
@@ -418,7 +420,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "</td>"
mutant_category = 0
if("tail_lizard" in pref_species.default_features)
if(pref_species.mutant_bodyparts["tail_lizard"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -431,7 +433,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "</td>"
mutant_category = 0
if("mam_tail" in pref_species.default_features)
if(pref_species.mutant_bodyparts["mam_tail"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -443,7 +445,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("tail_human" in pref_species.default_features)
if(pref_species.mutant_bodyparts["tail_human"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -456,7 +458,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "</td>"
mutant_category = 0
if("meat_type" in pref_species.default_features)
if(pref_species.mutant_bodyparts["meat_type"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -468,7 +470,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("snout" in pref_species.default_features)
if(pref_species.mutant_bodyparts["snout"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -480,7 +482,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("horns" in pref_species.default_features)
if(pref_species.mutant_bodyparts["horns"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -493,7 +495,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
if("frills" in pref_species.default_features)
if(pref_species.mutant_bodyparts["frills"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -506,7 +508,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "</td>"
mutant_category = 0
if("spines" in pref_species.default_features)
if(pref_species.mutant_bodyparts["spines"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -519,7 +521,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "</td>"
mutant_category = 0
if("body_markings" in pref_species.default_features)
if(pref_species.mutant_bodyparts["body_markings"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -531,7 +533,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("mam_body_markings" in pref_species.default_features)
if(pref_species.mutant_bodyparts["mam_body_markings"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -543,7 +545,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
if("mam_ears" in pref_species.default_features)
if(pref_species.mutant_bodyparts["mam_ears"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -556,7 +558,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "</td>"
mutant_category = 0
if("ears" in pref_species.default_features)
if(pref_species.mutant_bodyparts["ears"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -569,7 +571,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "</td>"
mutant_category = 0
if("mam_snouts" in pref_species.default_features)
if(pref_species.mutant_bodyparts["mam_snouts"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -581,7 +583,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("legs" in pref_species.default_features)
if(pref_species.mutant_bodyparts["legs"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -593,7 +595,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("deco_wings" in pref_species.default_features)
if(pref_species.mutant_bodyparts["deco_wings"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -602,7 +604,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=deco_wings;task=input'>[features["deco_wings"]]</a>"
dat += "<span style='border:1px solid #161616; background-color: #[wing_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=wings_color;task=input'>Change</a><BR>"
if("insect_wings" in pref_species.default_features)
if(pref_species.mutant_bodyparts["insect_wings"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -614,7 +616,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("insect_fluff" in pref_species.default_features)
if(pref_species.mutant_bodyparts["insect_fluff"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -625,7 +627,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("taur" in pref_species.default_features)
if(pref_species.mutant_bodyparts["taur"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -633,7 +635,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=taur;task=input'>[features["taur"]]</a>"
if("insect_markings" in pref_species.default_features)
if(pref_species.mutant_bodyparts["insect_markings"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -650,7 +652,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("wings" in pref_species.mutant_bodyparts && GLOB.r_wings_list.len >1)
if(pref_species.mutant_bodyparts["wings"] && GLOB.r_wings_list.len >1)
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -662,7 +664,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("xenohead" in pref_species.default_features)
if(pref_species.mutant_bodyparts["xenohead"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -674,7 +676,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("xenotail" in pref_species.default_features)
if(pref_species.mutant_bodyparts["xenotail"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -686,7 +688,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("xenodorsal" in pref_species.default_features)
if(pref_species.mutant_bodyparts["xenodorsal"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -698,7 +700,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("ipc_screen" in pref_species.default_features)
if(pref_species.mutant_bodyparts["ipc_screen"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -710,7 +712,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += "</td>"
mutant_category = 0
if("ipc_antenna" in pref_species.default_features)
if(pref_species.mutant_bodyparts["ipc_antenna"])
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -761,8 +763,16 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
dat += "<b>Penis Color:</b></a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["cock_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=cock_color;task=input'>Change</a><br>"
dat += "<b>Penis Shape:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_shape;task=input'>[features["cock_shape"]]</a>"
var/tauric_shape = FALSE
if(features["cock_taur"])
var/datum/sprite_accessory/penis/P = GLOB.cock_shapes_list[features["cock_shape"]]
if(P.taur_icon && pref_species.mutant_bodyparts["taur"])
var/datum/sprite_accessory/taur/T = GLOB.taur_list[features["taur"]]
if(T.taur_mode & P.accepted_taurs)
tauric_shape = TRUE
dat += "<b>Penis Shape:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_shape;task=input'>[features["cock_shape"]][tauric_shape ? " (Taur)" : ""]</a>"
dat += "<b>Penis Length:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_length;task=input'>[features["cock_length"]] inch(es)</a>"
dat += "<b>Penis Visibility:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=cock_visibility;task=input'>[features["cock_visibility"]]</a>"
dat += "<b>Has Testicles:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=has_balls'>[features["has_balls"] == TRUE ? "Yes" : "No"]</a>"
if(features["has_balls"])
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
@@ -771,7 +781,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
dat += "<b>Testicles Color:</b></a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["balls_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=balls_color;task=input'>Change</a><br>"
dat += "<b>Testicles showing:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=balls_shape;task=input'>[features["balls_shape"]]</a>"
dat += "<b>Testicles Visibility:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=balls_visibility;task=input'>[features["balls_visibility"]]</a>"
dat += APPEARANCE_CATEGORY_COLUMN
dat += "<h3>Vagina</h3>"
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_vag'>[features["has_vag"] == TRUE ? "Yes" : "No"]</a>"
@@ -783,6 +793,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
dat += "<b>Vagina Color:</b></a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["vag_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=vag_color;task=input'>Change</a><br>"
dat += "<b>Vagina Visibility:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=vag_visibility;task=input'>[features["vag_visibility"]]</a>"
dat += "<b>Has Womb:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=has_womb'>[features["has_womb"] == TRUE ? "Yes" : "No"]</a>"
dat += "</td>"
dat += APPEARANCE_CATEGORY_COLUMN
@@ -796,7 +807,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<b>Color:</b></a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["breasts_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=breasts_color;task=input'>Change</a><br>"
dat += "<b>Cup Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_size;task=input'>[features["breasts_size"]]</a>"
dat += "<b>Breast Shape:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_shape;task=input'>[features["breasts_shape"]]</a>"
dat += "<b>Breasts Shape:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_shape;task=input'>[features["breasts_shape"]]</a>"
dat += "<b>Breasts Visibility:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=breasts_visibility;task=input'>[features["breasts_visibility"]]</a>"
dat += "<b>Lactates:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_producing'>[features["breasts_producing"] == TRUE ? "Yes" : "No"]</a>"
dat += "</td>"
dat += "</td>"
@@ -902,6 +914,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<b>Fit Viewport:</b> <a href='?_src_=prefs;preference=auto_fit_viewport'>[auto_fit_viewport ? "Auto" : "Manual"]</a><br>"
dat += "<b>Sprint Key:</b> <a href='?_src_=prefs;preference=sprint_key'>[sprint_spacebar ? "Space" : "Shift"]</a><br>"
dat += "<b>Toggle Sprint:</b> <a href='?_src_=prefs;preference=sprint_toggle'>[sprint_toggle ? "Enabled" : "Disabled"]</a><br>"
dat += "<b>HUD Button Flashes:</b> <a href='?_src_=prefs;preference=hud_toggle_flash'>[hud_toggle_flash ? "Enabled" : "Disabled"]</a><br>"
dat += "<b>HUD Button Flash Color:</b> <span style='border: 1px solid #161616; background-color: [hud_toggle_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=hud_toggle_color;task=input'>Change</a><br>"
if (CONFIG_GET(flag/maprotation) && CONFIG_GET(flag/tgstyle_maprotation))
var/p_map = preferred_map
@@ -1563,14 +1577,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
pref_species = new newtype()
//let's ensure that no weird shit happens on species swapping.
custom_species = null
if(!("body_markings" in pref_species.default_features))
if(!pref_species.mutant_bodyparts["body_markings"])
features["body_markings"] = "None"
if(!("mam_body_markings" in pref_species.default_features))
if(!pref_species.mutant_bodyparts["mam_body_markings"])
features["mam_body_markings"] = "None"
if("mam_body_markings" in pref_species.default_features)
if(pref_species.mutant_bodyparts["mam_body_markings"])
if(features["mam_body_markings"] == "None")
features["mam_body_markings"] = "Plain"
if("tail_lizard" in pref_species.default_features)
if(pref_species.mutant_bodyparts["tail_lizard"])
features["tail_lizard"] = "Smooth"
if(pref_species.id == "felinid")
features["mam_tail"] = "Cat"
@@ -1604,7 +1618,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
if("mutant_color2")
var/new_mutantcolor = input(user, "Choose your character's secondary alien/mutant color:", "Character Preference") as color|null
var/new_mutantcolor = input(user, "Choose your character's secondary alien/mutant color:", "Character Preference","#"+features["mcolor2"]) as color|null
if(new_mutantcolor)
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
@@ -1615,7 +1629,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
if("mutant_color3")
var/new_mutantcolor = input(user, "Choose your character's tertiary alien/mutant color:", "Character Preference") as color|null
var/new_mutantcolor = input(user, "Choose your character's tertiary alien/mutant color:", "Character Preference","#"+features["mcolor3"]) as color|null
if(new_mutantcolor)
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
@@ -1916,7 +1930,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
//Genital code
if("cock_color")
var/new_cockcolor = input(user, "Penis color:", "Character Preference") as color|null
var/new_cockcolor = input(user, "Penis color:", "Character Preference","#"+features["cock_color"]) as color|null
if(new_cockcolor)
var/temp_hsv = RGBtoHSV(new_cockcolor)
if(new_cockcolor == "#000000")
@@ -1935,12 +1949,28 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("cock_shape")
var/new_shape
new_shape = input(user, "Penis shape:", "Character Preference") as null|anything in GLOB.cock_shapes_list
var/list/hockeys = list()
if(pref_species.mutant_bodyparts["taur"])
var/datum/sprite_accessory/taur/T = GLOB.taur_list[features["taur"]]
for(var/A in GLOB.cock_shapes_list)
var/datum/sprite_accessory/penis/P = GLOB.cock_shapes_list[A]
if(P.taur_icon && T.taur_mode & P.accepted_taurs)
LAZYSET(hockeys, "[A] (Taur)", A)
new_shape = input(user, "Penis shape:", "Character Preference") as null|anything in (GLOB.cock_shapes_list + hockeys)
if(new_shape)
features["cock_taur"] = FALSE
if(hockeys[new_shape])
new_shape = hockeys[new_shape]
features["cock_taur"] = TRUE
features["cock_shape"] = new_shape
if("cock_visibility")
var/n_vis = input(user, "Penis Visibility", "Character Preference") as null|anything in CONFIG_GET(keyed_list/safe_visibility_toggles)
if(n_vis)
features["cock_visibility"] = n_vis
if("balls_color")
var/new_ballscolor = input(user, "Testicle Color:", "Character Preference") as color|null
var/new_ballscolor = input(user, "Testicles Color:", "Character Preference","#"+features["balls_color"]) as color|null
if(new_ballscolor)
var/temp_hsv = RGBtoHSV(new_ballscolor)
if(new_ballscolor == "#000000")
@@ -1950,11 +1980,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
if("balls_shape")
var/new_shape
new_shape = input(user, "Testicle Type:", "Character Preference") as null|anything in GLOB.balls_shapes_list
if(new_shape)
features["balls_shape"] = new_shape
if("balls_visibility")
var/n_vis = input(user, "Testicles Visibility", "Character Preference") as null|anything in CONFIG_GET(keyed_list/safe_visibility_toggles)
if(n_vis)
features["balls_visibility"] = n_vis
if("breasts_size")
var/new_size = input(user, "Breast Size", "Character Preference") as null|anything in CONFIG_GET(keyed_list/breasts_cups_prefs)
@@ -1968,7 +1997,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["breasts_shape"] = new_shape
if("breasts_color")
var/new_breasts_color = input(user, "Breast Color:", "Character Preference") as color|null
var/new_breasts_color = input(user, "Breast Color:", "Character Preference","#"+features["breasts_color"]) as color|null
if(new_breasts_color)
var/temp_hsv = RGBtoHSV(new_breasts_color)
if(new_breasts_color == "#000000")
@@ -1978,6 +2007,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
if("breasts_visibility")
var/n_vis = input(user, "Breasts Visibility", "Character Preference") as null|anything in CONFIG_GET(keyed_list/safe_visibility_toggles)
if(n_vis)
features["breasts_visibility"] = n_vis
if("vag_shape")
var/new_shape
new_shape = input(user, "Vagina Type", "Character Preference") as null|anything in GLOB.vagina_shapes_list
@@ -1985,7 +2019,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["vag_shape"] = new_shape
if("vag_color")
var/new_vagcolor = input(user, "Vagina color:", "Character Preference") as color|null
var/new_vagcolor = input(user, "Vagina color:", "Character Preference","#"+features["vag_color"]) as color|null
if(new_vagcolor)
var/temp_hsv = RGBtoHSV(new_vagcolor)
if(new_vagcolor == "#000000")
@@ -1995,6 +2029,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
if("vag_visibility")
var/n_vis = input(user, "Vagina Visibility", "Character Preference") as null|anything in CONFIG_GET(keyed_list/safe_visibility_toggles)
if(n_vis)
features["vag_visibility"] = n_vis
if("ooccolor")
var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference",ooccolor) as color|null
if(new_ooccolor)
@@ -2075,6 +2114,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(pickedPDASkin)
pda_skin = pickedPDASkin
if("hud_toggle_color")
var/new_toggle_color = input(user, "Choose your HUD toggle flash color:", "Game Preference",hud_toggle_color) as color|null
if(new_toggle_color)
hud_toggle_color = new_toggle_color
else
switch(href_list["preference"])
//CITADEL PREFERENCES EDIT - I can't figure out how to modularize these, so they have to go here. :c -Pooj
@@ -2088,8 +2132,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["has_balls"] = FALSE
if("has_balls")
features["has_balls"] = !features["has_balls"]
if("balls_internal")
features["balls_internal"] = !features["balls_internal"]
if("has_breasts")
features["has_breasts"] = !features["has_breasts"]
if(features["has_breasts"] == FALSE)
@@ -2131,6 +2173,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
toggles ^= MEMBER_PUBLIC
if("gender")
var/chosengender = input(user, "Select your character's gender.", "Gender Selection", gender) as null|anything in list(MALE,FEMALE,"nonbinary","object")
if(!chosengender)
return
switch(chosengender)
if("nonbinary")
chosengender = PLURAL
@@ -2278,6 +2322,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("sprint_toggle")
sprint_toggle = !sprint_toggle
if("hud_toggle_flash")
hud_toggle_flash = !hud_toggle_flash
if("save")
save_preferences()
save_character()
@@ -2389,17 +2437,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character.dna.nameless = character.nameless
character.dna.custom_species = character.custom_species
if("tail_lizard" in pref_species.default_features)
character.dna.species.mutant_bodyparts |= "tail_lizard"
if("mam_tail" in pref_species.default_features)
character.dna.species.mutant_bodyparts |= "mam_tail"
if("xenotail" in pref_species.default_features)
character.dna.species.mutant_bodyparts |= "xenotail"
if("meat_type" in pref_species.default_features)
if(pref_species.mutant_bodyparts["meat_type"])
character.type_of_meat = GLOB.meat_types[features["meat_type"]]
if(("legs" in character.dna.species.mutant_bodyparts) && (character.dna.features["legs"] == "Digitigrade" || character.dna.features["legs"] == "Avian"))
if(character.dna.species.mutant_bodyparts["legs"] && (character.dna.features["legs"] == "Digitigrade" || character.dna.features["legs"] == "Avian"))
pref_species.species_traits |= DIGITIGRADE
else
pref_species.species_traits -= DIGITIGRADE
@@ -2409,6 +2450,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
character.Digitigrade_Leg_Swap(TRUE)
character.give_genitals(TRUE) //character.update_genitals() is already called on genital.update_appearance()
SEND_SIGNAL(character, COMSIG_HUMAN_PREFS_COPIED_TO, src, icon_updates, roundstart_checks)
//let's be sure the character updates
+62 -7
View File
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
#define SAVEFILE_VERSION_MAX 26
#define SAVEFILE_VERSION_MAX 28
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -145,6 +145,20 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(features["meat_type"] == "Inesct")
features["meat_type"] = "Insect"
if(current_version < 27)
var/tennis
S["feature_balls_shape"] >> tennis
if(tennis == "Hidden")
features["balls_visibility"] = GEN_VISIBLE_NEVER
if(current_version < 28)
var/hockey
S["feature_cock_shape"] >> hockey
var/list/malformed_hockeys = list("Taur, Flared" = "Flared", "Taur, Knotted" = "Knotted", "Taur, Tapered" = "Tapered")
if(malformed_hockeys[hockey])
features["cock_shape"] = malformed_hockeys[hockey]
features["cock_taur"] = TRUE
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey)
return
@@ -200,6 +214,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["auto_fit_viewport"] >> auto_fit_viewport
S["sprint_spacebar"] >> sprint_spacebar
S["sprint_toggle"] >> sprint_toggle
S["hud_toggle_flash"] >> hud_toggle_flash
S["hud_toggle_color"] >> hud_toggle_color
S["menuoptions"] >> menuoptions
S["enable_tips"] >> enable_tips
S["tip_delay"] >> tip_delay
@@ -239,6 +255,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport))
sprint_spacebar = sanitize_integer(sprint_spacebar, 0, 1, initial(sprint_spacebar))
sprint_toggle = sanitize_integer(sprint_toggle, 0, 1, initial(sprint_toggle))
hud_toggle_flash = sanitize_integer(hud_toggle_flash, 0, 1, initial(hud_toggle_flash))
hud_toggle_color = sanitize_hexcolor(hud_toggle_color, 6, 1, initial(hud_toggle_color))
ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form))
ghost_orbit = sanitize_inlist(ghost_orbit, GLOB.ghost_orbits, initial(ghost_orbit))
ghost_accs = sanitize_inlist(ghost_accs, GLOB.ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION)
@@ -248,7 +266,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
pda_style = sanitize_inlist(pda_style, GLOB.pda_styles, initial(pda_style))
pda_color = sanitize_hexcolor(pda_color, 6, 1, initial(pda_color))
pda_skin = sanitize_inlist(pda_skin, GLOB.pda_reskins, PDA_SKIN_ALT)
screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake))
damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake))
widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref))
@@ -301,6 +318,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["auto_fit_viewport"], auto_fit_viewport)
WRITE_FILE(S["sprint_spacebar"], sprint_spacebar)
WRITE_FILE(S["sprint_toggle"], sprint_toggle)
WRITE_FILE(S["hud_toggle_flash"], hud_toggle_flash)
WRITE_FILE(S["hud_toggle_color"], hud_toggle_color)
WRITE_FILE(S["menuoptions"], menuoptions)
WRITE_FILE(S["enable_tips"], enable_tips)
WRITE_FILE(S["tip_delay"], tip_delay)
@@ -427,7 +446,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//Citadel code
S["feature_genitals_use_skintone"] >> features["genitals_use_skintone"]
S["feature_exhibitionist"] >> features["exhibitionist"]
S["feature_mcolor2"] >> features["mcolor2"]
S["feature_mcolor3"] >> features["mcolor3"]
S["feature_mam_body_markings"] >> features["mam_body_markings"]
@@ -447,22 +465,25 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["feature_cock_color"] >> features["cock_color"]
S["feature_cock_length"] >> features["cock_length"]
S["feature_cock_diameter"] >> features["cock_diameter"]
S["feature_has_sheath"] >> features["sheath_color"]
S["feature_cock_taur"] >> features["cock_taur"]
S["feature_cock_visibility"] >> features["cock_visibility"]
//balls features
S["feature_has_balls"] >> features["has_balls"]
S["feature_balls_color"] >> features["balls_color"]
S["feature_balls_size"] >> features["balls_size"]
S["feature_balls_shape"] >> features["balls_shape"]
S["feature_balls_visibility"] >> features["balls_visibility"]
//breasts features
S["feature_has_breasts"] >> features["has_breasts"]
S["feature_breasts_size"] >> features["breasts_size"]
S["feature_breasts_shape"] >> features["breasts_shape"]
S["feature_breasts_color"] >> features["breasts_color"]
S["feature_breasts_producing"] >> features["breasts_producing"]
S["feature_breasts_visibility"] >> features["breasts_visibility"]
//vagina features
S["feature_has_vag"] >> features["has_vag"]
S["feature_vag_shape"] >> features["vag_shape"]
S["feature_vag_color"] >> features["vag_color"]
S["feature_vag_visibility"] >> features["vag_visibility"]
//womb features
S["feature_has_womb"] >> features["has_womb"]
//flavor text
@@ -549,14 +570,18 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
var/static/list/B_sizes
if(!B_sizes)
B_sizes = CONFIG_GET(keyed_list/breasts_cups_prefs)
B_sizes = B_sizes.Copy()
var/list/L = CONFIG_GET(keyed_list/breasts_cups_prefs)
B_sizes = L.Copy()
var/static/min_D
if(!min_D)
min_D = CONFIG_GET(number/penis_min_inches_prefs)
var/static/max_D
if(!max_D)
max_D = CONFIG_GET(number/penis_max_inches_prefs)
var/static/safe_visibilities
if(!safe_visibilities)
var/list/L = CONFIG_GET(keyed_list/safe_visibility_toggles)
safe_visibilities = L.Copy()
features["breasts_size"] = sanitize_inlist(features["breasts_size"], B_sizes, BREASTS_SIZE_DEF)
features["cock_length"] = sanitize_integer(features["cock_length"], min_D, max_D, COCK_SIZE_DEF)
@@ -568,6 +593,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
features["cock_color"] = sanitize_hexcolor(features["cock_color"], 3, FALSE, "FFF")
features["balls_color"] = sanitize_hexcolor(features["balls_color"], 3, FALSE, "FFF")
features["vag_color"] = sanitize_hexcolor(features["vag_color"], 3, FALSE, "FFF")
features["breasts_visibility"] = sanitize_inlist(features["breasts_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
features["cock_visibility"] = sanitize_inlist(features["cock_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
features["balls_visibility"] = sanitize_inlist(features["balls_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
features["vag_visibility"] = sanitize_inlist(features["vag_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
features["flavor_text"] = copytext(features["flavor_text"], 1, MAX_FLAVOR_LEN)
@@ -648,6 +678,31 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["feature_insect_markings"] , features["insect_markings"])
WRITE_FILE(S["feature_meat"] , features["meat_type"])
WRITE_FILE(S["feature_has_cock"], features["has_cock"])
WRITE_FILE(S["feature_cock_shape"], features["cock_shape"])
WRITE_FILE(S["feature_cock_color"], features["cock_color"])
WRITE_FILE(S["feature_cock_length"], features["cock_length"])
WRITE_FILE(S["feature_cock_taur"], features["cock_taur"])
WRITE_FILE(S["feature_cock_visibility"], features["cock_visibility"])
WRITE_FILE(S["feature_has_balls"], features["has_balls"])
WRITE_FILE(S["feature_balls_color"], features["balls_color"])
WRITE_FILE(S["feature_balls_size"], features["balls_size"])
WRITE_FILE(S["feature_balls_visibility"], features["balls_visibility"])
WRITE_FILE(S["feature_has_breasts"], features["has_breasts"])
WRITE_FILE(S["feature_breasts_size"], features["breasts_size"])
WRITE_FILE(S["feature_breasts_shape"], features["breasts_shape"])
WRITE_FILE(S["feature_breasts_color"], features["breasts_color"])
WRITE_FILE(S["feature_breasts_producing"], features["breasts_producing"])
WRITE_FILE(S["feature_breasts_visibility"], features["breasts_visibility"])
WRITE_FILE(S["feature_has_vag"], features["has_vag"])
WRITE_FILE(S["feature_vag_shape"], features["vag_shape"])
WRITE_FILE(S["feature_vag_color"], features["vag_color"])
WRITE_FILE(S["feature_vag_visibility"], features["vag_visibility"])
WRITE_FILE(S["feature_has_womb"], features["has_womb"])
//Custom names
for(var/custom_name_id in GLOB.preferences_custom_names)
+1 -1
View File
@@ -273,7 +273,7 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8")
return
var/list/body = list()
body += "<html><head><title>Playtime for [key]</title></head><BODY><BR>Playtime:"
body += "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Playtime for [key]</title></head><BODY><BR>Playtime:"
body += get_exp_report()
body += "</BODY></HTML>"
usr << browse(body.Join(), "window=playerplaytime[ckey];size=550x615")
+1
View File
@@ -24,6 +24,7 @@
w_class = WEIGHT_CLASS_SMALL
armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 30, "acid" = 30)
resistance_flags = FIRE_PROOF | ACID_PROOF
mutantrace_variation = STYLE_MUZZLE
var/voice_unknown = TRUE ///This makes it so that your name shows up as unknown when wearing the mask.
/obj/item/clothing/mask/luchador
@@ -343,3 +343,45 @@
desc = "A bandana made from durathread, you wish it would provide some protection to its wearer, but it's far too thin..."
icon_state = "banddurathread"
/obj/item/clothing/mask/paper
name = "paper mask"
desc = "A neat, circular mask made out of paper."
icon_state = "plainmask"
item_state = "plainmask"
flags_inv = HIDEFACE|HIDEFACIALHAIR
resistance_flags = FLAMMABLE
max_integrity = 100
actions_types = list(/datum/action/item_action/adjust)
/obj/item/clothing/mask/paper/ui_action_click(mob/user)
if(!istype(user) || user.incapacitated())
return
var/list/options = list()
options["Blank"] = "plainmask"
options["Neutral"] = "neutralmask"
options["Eyes"] = "eyemask"
options["Sleeping"] ="sleepingmask"
options["Heart"] = "heartmask"
options["Core"] = "coremask"
options["Plus"] = "plusmask"
options["Square"] ="squaremask"
options["Bullseye"] = "bullseyemask"
options["Vertical"] = "verticalmask"
options["Horizontal"] = "horizontalmask"
options["X"] ="xmask"
options["Bugeyes"] = "bugmask"
options["Double"] = "doublemask"
options["Mark"] = "markmask"
var/choice = input(user,"What symbol would you want on this mask?","Morph Mask") in options
if(src && choice && !user.incapacitated() && in_range(user,src))
icon_state = options[choice]
user.update_inv_wear_mask()
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
to_chat(user, "<span class='notice'>Your paper mask now has a [choice] symbol!</span>")
return 1
+9 -1
View File
@@ -25,7 +25,15 @@
icon_state = "sneakboots"
item_state = "sneakboots"
resistance_flags = FIRE_PROOF | ACID_PROOF
clothing_flags = TRAIT_SILENT_STEP
/obj/item/clothing/shoes/combat/sneakboots/equipped(mob/user, slot)
. = ..()
if(slot == SLOT_SHOES)
ADD_TRAIT(user, TRAIT_SILENT_STEP, SHOES_TRAIT)
/obj/item/clothing/shoes/combat/sneakboots/dropped(mob/user)
. = ..()
REMOVE_TRAIT(user, TRAIT_SILENT_STEP, SHOES_TRAIT)
/obj/item/clothing/shoes/combat/swat //overpowered boots for death squads
name = "\improper SWAT boots"
File diff suppressed because it is too large Load Diff
+6 -1
View File
@@ -422,6 +422,10 @@
heat_protection = HEAD //Uncomment to enable firesuit protection
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
/obj/item/clothing/head/helmet/space/hardsuit/wizard/ComponentInitialize()
. = ..()
AddElement(/datum/element/spellcasting, SPELL_WIZARD_HAT, ITEM_SLOT_HEAD)
/obj/item/clothing/suit/space/hardsuit/wizard
icon_state = "hardsuit-wiz"
name = "gem-encrusted hardsuit"
@@ -436,9 +440,10 @@
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/wizard
mutantrace_variation = STYLE_DIGITIGRADE
/obj/item/clothing/suit/space/hardsuit/wizard/Initialize()
/obj/item/clothing/suit/space/hardsuit/wizard/ComponentInitialize()
. = ..()
AddComponent(/datum/component/anti_magic, TRUE, FALSE, FALSE, ITEM_SLOT_OCLOTHING, INFINITY, FALSE)
AddElement(/datum/element/spellcasting, SPELL_WIZARD_ROBE, ITEM_SLOT_OCLOTHING)
//Medical hardsuit
/obj/item/clothing/head/helmet/space/hardsuit/medical
+27 -11
View File
@@ -9,6 +9,12 @@
equip_delay_other = 50
resistance_flags = FIRE_PROOF | ACID_PROOF
dog_fashion = /datum/dog_fashion/head/blue_wizard
var/magic_flags = SPELL_WIZARD_HAT
/obj/item/clothing/head/wizard/ComponentInitialize()
. = ..()
if(magic_flags)
AddElement(/datum/element/spellcasting, magic_flags, ITEM_SLOT_HEAD)
/obj/item/clothing/head/wizard/red
name = "red wizard hat"
@@ -36,7 +42,7 @@
permeability_coefficient = 1
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
resistance_flags = FLAMMABLE
dog_fashion = /datum/dog_fashion/head/blue_wizard
magic_flags = NONE
/obj/item/clothing/head/wizard/marisa
name = "witch hat"
@@ -50,6 +56,7 @@
icon_state = "magus"
item_state = "magus"
dog_fashion = null
magic_flags = SPELL_WIZARD_HAT|SPELL_CULT_HELMET
/obj/item/clothing/head/wizard/santa
name = "Santa's hat"
@@ -72,6 +79,12 @@
strip_delay = 50
equip_delay_other = 50
resistance_flags = FIRE_PROOF | ACID_PROOF
var/magic_flags = SPELL_WIZARD_ROBE
/obj/item/clothing/suit/wizrobe/ComponentInitialize()
. = ..()
if(magic_flags)
AddElement(/datum/element/spellcasting, magic_flags, ITEM_SLOT_OCLOTHING)
/obj/item/clothing/suit/wizrobe/red
name = "red wizard robe"
@@ -102,13 +115,14 @@
desc = "A set of armored robes that seem to radiate a dark power."
icon_state = "magusblue"
item_state = "magusblue"
magic_flags = SPELL_WIZARD_ROBE|SPELL_CULT_ARMOR
/obj/item/clothing/suit/wizrobe/magusred
name = "\improper Magus robe"
desc = "A set of armored robes that seem to radiate a dark power."
icon_state = "magusred"
item_state = "magusred"
magic_flags = SPELL_WIZARD_ROBE|SPELL_CULT_ARMOR
/obj/item/clothing/suit/wizrobe/santa
name = "Santa's suit"
@@ -117,33 +131,27 @@
item_state = "santa"
/obj/item/clothing/suit/wizrobe/fake
name = "wizard robe"
desc = "A rather dull blue robe meant to mimick real wizard robes."
icon_state = "wizard-fake"
item_state = "wizrobe"
gas_transfer_coefficient = 1
permeability_coefficient = 1
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
resistance_flags = FLAMMABLE
magic_flags = NONE
/obj/item/clothing/head/wizard/marisa/fake
name = "witch hat"
desc = "Strange-looking hat-wear, makes you want to cast fireballs."
icon_state = "marisa"
gas_transfer_coefficient = 1
permeability_coefficient = 1
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
resistance_flags = FLAMMABLE
magic_flags = NONE
/obj/item/clothing/suit/wizrobe/marisa/fake
name = "witch robe"
desc = "Magic is all about the spell power, ZE!"
icon_state = "marisa"
item_state = "marisarobe"
gas_transfer_coefficient = 1
permeability_coefficient = 1
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
resistance_flags = FLAMMABLE
magic_flags = NONE
/obj/item/clothing/suit/wizrobe/paper
name = "papier-mache robe" // no non-latin characters!
@@ -198,6 +206,10 @@
slowdown = 0
resistance_flags = FIRE_PROOF | ACID_PROOF
/obj/item/clothing/suit/space/hardsuit/shielded/wizard/ComponentInitialize()
. = ..()
AddElement(/datum/element/spellcasting, SPELL_WIZARD_HAT, ITEM_SLOT_HEAD)
/obj/item/clothing/head/helmet/space/hardsuit/shielded/wizard
name = "battlemage helmet"
desc = "A suitably impressive helmet.."
@@ -209,6 +221,10 @@
actions_types = null //No inbuilt light
resistance_flags = FIRE_PROOF | ACID_PROOF
/obj/item/clothing/head/helmet/space/hardsuit/shielded/wizard/ComponentInitialize()
. = ..()
AddElement(/datum/element/spellcasting, SPELL_WIZARD_ROBE, ITEM_SLOT_OCLOTHING)
/obj/item/clothing/head/helmet/space/hardsuit/shielded/wizard/attack_self(mob/user)
return
@@ -12,7 +12,6 @@
item_state = "explorer_envirosuit"
item_color = "explorer_envirosuit"
/obj/item/clothing/under/plasmaman/chef
name = "chef's plasma envirosuit"
desc = "A white plasmaman envirosuit designed for cullinary practices. One might question why a member of a species that doesn't need to eat would become a chef."
@@ -69,6 +68,8 @@
item_state = "captain_envirosuit"
item_color = "captain_envirosuit"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95)
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
/obj/item/clothing/under/plasmaman/mime
name = "mime envirosuit"
@@ -97,4 +98,4 @@
H.visible_message("<span class='warning'>[H]'s suit spews out a tonne of space lube!</span>","<span class='warning'>Your suit spews out a tonne of space lube!</span>")
H.ExtinguishMob()
new /obj/effect/particle_effect/foam(loc) //Truely terrifying.
return FALSE
return FALSE
@@ -5,6 +5,8 @@
item_state = "security_envirosuit"
item_color = "security_envirosuit"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95)
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
/obj/item/clothing/under/plasmaman/security/warden
name = "warden plasma envirosuit"
@@ -13,7 +13,6 @@
item_state = "red_suit"
item_color = "red_suit_skirt"
body_parts_covered = CHEST|GROIN|ARMS
can_adjust = FALSE
fitted = FEMALE_UNIFORM_TOP
/obj/item/clothing/under/rank/civilian/curator/treasure_hunter
@@ -37,5 +36,4 @@
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
can_adjust = FALSE
resistance_flags = NONE
-1
View File
@@ -14,7 +14,6 @@
item_state = "lb_suit"
item_color = "director_skirt"
body_parts_covered = CHEST|GROIN|ARMS
can_adjust = FALSE
fitted = FEMALE_UNIFORM_TOP
/obj/item/clothing/under/rank/rnd/research_director/alt
+5 -18
View File
@@ -8,6 +8,11 @@
/*
* Security
*/
/obj/item/clothing/under/rank/security
strip_delay = 50
alt_covers_chest = TRUE
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
/obj/item/clothing/under/rank/security/officer
name = "security jumpsuit"
@@ -16,10 +21,6 @@
item_state = "r_suit"
item_color = "rsecurity"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30)
strip_delay = 50
alt_covers_chest = TRUE
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
/obj/item/clothing/under/rank/security/officer/grey
name = "grey security jumpsuit"
@@ -73,10 +74,6 @@
item_state = "r_suit"
item_color = "rwarden"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30)
strip_delay = 50
alt_covers_chest = TRUE
sensor_mode = 3
random_sensor = FALSE
/obj/item/clothing/under/rank/security/warden/grey
name = "grey security suit"
@@ -114,10 +111,6 @@
item_state = "det"
item_color = "detective"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30)
strip_delay = 50
alt_covers_chest = TRUE
sensor_mode = 3
random_sensor = FALSE
/obj/item/clothing/under/rank/security/detective/skirt
name = "detective's suitskirt"
@@ -135,7 +128,6 @@
icon_state = "greydet"
item_state = "greydet"
item_color = "greydet"
alt_covers_chest = TRUE
/obj/item/clothing/under/rank/security/detective/grey/skirt
name = "noir suitskirt"
@@ -159,9 +151,6 @@
item_color = "rhos"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
strip_delay = 60
alt_covers_chest = TRUE
sensor_mode = 3
random_sensor = FALSE
/obj/item/clothing/under/rank/security/head_of_security/skirt
name = "head of security's jumpskirt"
@@ -203,7 +192,6 @@
icon_state = "hosblueclothes"
item_state = "hosblueclothes"
item_color = "hosblueclothes"
alt_covers_chest = TRUE
/obj/item/clothing/under/rank/security/head_of_security/parade
name = "head of security's parade uniform"
@@ -220,4 +208,3 @@
item_state = "r_suit"
item_color = "hos_parade_fem"
fitted = FEMALE_UNIFORM_TOP
can_adjust = FALSE
+5 -2
View File
@@ -121,7 +121,8 @@
var/activeFor = 0 //How long the event has existed. You don't need to change this.
var/current_players = 0 //Amount of of alive, non-AFK human players on server at the time of event start
var/fakeable = TRUE //Can be faked by fake news event.
var/threat = 0
var/fakeable = TRUE //Can be faked by fake news event.
//Called first before processing.
//Allows you to setup your event, such as randomly
@@ -161,7 +162,9 @@
/datum/round_event/proc/end()
return
// Returns threat; used for dynamic. Used for custom stuff, just returns the threat var by default.
/datum/round_event/proc/threat()
return threat
//Do not override this proc, instead use the appropiate procs.
//This proc will handle the calls to the appropiate procs.
@@ -27,6 +27,7 @@
"How do I vore people?",
"ERP?",
"Not epic bros...")
threat = 5
/datum/round_event/brand_intelligence/announce(fake)
+2 -2
View File
@@ -87,10 +87,10 @@
. = ..()
if(in_range(user, src) || isobserver(user))
if( !(ishuman(user) || isobserver(user) || hasSiliconAccessInArea(user)) )
user << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[stars(message)]</BODY></HTML>", "window=[name]")
user << browse("<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>[name]</TITLE></HEAD><BODY>[stars(message)]</BODY></HTML>", "window=[name]")
onclose(user, "[name]")
else
user << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[message]</BODY></HTML>", "window=[name]")
user << browse("<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>[name]</TITLE></HEAD><BODY>[message]</BODY></HTML>", "window=[name]")
onclose(user, "[name]")
else
. += "<span class='notice'>It is too far away.</span>"

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