Conflict fixes

This commit is contained in:
Artur
2020-04-14 09:27:54 +03:00
720 changed files with 148595 additions and 8360 deletions
+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>"
+2 -3
View File
@@ -1732,9 +1732,8 @@
var/mob/M = locate(href_list["makeeligible"])
if(!ismob(M))
to_chat(usr, "this can only be used on instances of type /mob.")
var/datum/element/ghost_role_eligibility/eli = SSdcs.GetElement(list(/datum/element/ghost_role_eligibility))
if(M.ckey in eli.timeouts)
eli.timeouts -= M.ckey
if(M.ckey in GLOB.client_ghost_timeouts)
GLOB.client_ghost_timeouts -= M.ckey
else if(href_list["sendtoprison"])
if(!check_rights(R_ADMIN))
+1 -1
View File
@@ -23,8 +23,8 @@
/datum/borgpanel/New(to_user, mob/living/silicon/robot/to_borg)
if(!istype(to_borg))
CRASH("Borg panel is only available for borgs")
qdel(src)
CRASH("Borg panel is only available for borgs")
user = CLIENT_FROM_VAR(to_user)
-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"
-25
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"
@@ -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")
@@ -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)
@@ -92,10 +92,8 @@
M.cut_overlays()
M.regenerate_icons()
/obj/item/clothing/suit/armor/abductor/vest/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
DeactivateStealth()
/obj/item/clothing/suit/armor/abductor/vest/IsReflect()
/obj/item/clothing/suit/armor/abductor/vest/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
. = ..()
DeactivateStealth()
/obj/item/clothing/suit/armor/abductor/vest/ui_action_click()
@@ -493,7 +491,7 @@
user.do_attack_animation(L)
if(L.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK))
if(L.run_block(src, 0, "[user]'s [src]", ATTACK_TYPE_MELEE, 0, user, check_zone(user.zone_selected)) & BLOCK_SUCCESS)
playsound(L, 'sound/weapons/genhit.ogg', 50, TRUE)
return FALSE
@@ -209,7 +209,6 @@
open_machine()
SendBack(H)
return "<span class='bad'>Specimen braindead - disposed.</span>"
return "<span class='bad'>ERROR</span>"
/obj/machinery/abductor/experiment/proc/SendBack(mob/living/carbon/human/H)
@@ -8,7 +8,7 @@
desc = "Dash somewhere with supernatural speed. Those nearby may be knocked away, stunned, or left empty-handed."
button_icon_state = "power_speed"
bloodcost = 6
cooldown = 50
cooldown = 120
target_range = 15
power_activates_immediately = TRUE
message_Trigger = ""//"Whom will you subvert to your will?"
@@ -64,7 +64,7 @@
to_chat(owner, "<span class='warning'>Your victim's eyes are glazed over. They cannot perceive you.</span>")
return FALSE
// Check: Target See Me? (behind wall)
if(!(target in view(target_range, get_turf(owner))))
if(!(target in viewers(target_range, get_turf(owner))))
// Sub-Check: GET CLOSER
//if (!(owner in range(target_range, get_turf(target)))
// if (display_error)
@@ -90,48 +90,56 @@
/datum/action/bloodsucker/targeted/mesmerize/proc/ContinueTarget(atom/A)
var/mob/living/carbon/target = A
var/mob/living/user = owner
var/mob/living/L = owner
var/cancontinue=CheckCanTarget(target)
var/cancontinue = CheckCanTarget(target)
if(!cancontinue)
success = FALSE
target.remove_status_effect(STATUS_EFFECT_MESMERIZE)
user.remove_status_effect(STATUS_EFFECT_MESMERIZE)
L.remove_status_effect(STATUS_EFFECT_MESMERIZE)
DeactivatePower()
DeactivateRangedAbility()
StartCooldown()
to_chat(user, "<span class='warning'>[target] has escaped your gaze!</span>")
to_chat(L, "<span class='warning'>[target] has escaped your gaze!</span>")
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
/datum/action/bloodsucker/targeted/mesmerize/FireTargetedPower(atom/A)
// set waitfor = FALSE <---- DONT DO THIS!We WANT this power to hold up ClickWithPower(), so that we can unlock the power when it's done.
var/mob/living/carbon/target = A
var/mob/living/user = owner
var/mob/living/L = owner
L.face_atom(A)
if(!istype(target))
return
success = TRUE
var/power_time = 138 + level_current * 12
target.apply_status_effect(STATUS_EFFECT_MESMERIZE, 30)
L.apply_status_effect(STATUS_EFFECT_MESMERIZE, 30)
RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/ContinueTarget)
// 5 second windup
addtimer(CALLBACK(src, .proc/apply_effects, L, target, power_time), 6 SECONDS)
ADD_TRAIT(target, TRAIT_COMBAT_MODE_LOCKED, src)
ADD_TRAIT(L, TRAIT_COMBAT_MODE_LOCKED, src)
if(istype(target))
success = TRUE
var/power_time = 138 + level_current * 12
target.apply_status_effect(STATUS_EFFECT_MESMERIZE, 30)
user.apply_status_effect(STATUS_EFFECT_MESMERIZE, 30)
RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/ContinueTarget)
/datum/action/bloodsucker/targeted/mesmerize/proc/apply_effects(aggressor, victim, power_time)
var/mob/living/carbon/target = victim
var/mob/living/L = aggressor
if(!success)
return
PowerActivatedSuccessfully() // blood & cooldown only altered if power activated successfully - less "fuck you"-y
target.apply_status_effect(STATUS_EFFECT_MESMERIZE, power_time)
REMOVE_TRAIT(L, TRAIT_COMBAT_MODE_LOCKED, src)
target.face_atom(L)
target.Stun(power_time)
to_chat(L, "<span class='notice'>[target] is fixed in place by your hypnotic gaze.</span>")
target.next_move = world.time + power_time // <--- Use direct change instead. We want an unmodified delay to their next move // target.changeNext_move(power_time) // check click.dm
target.notransform = TRUE // <--- Fuck it. We tried using next_move, but they could STILL resist. We're just doing a hard freeze.
spawn(power_time)
if(istype(target) && success)
target.notransform = FALSE
REMOVE_TRAIT(target, TRAIT_COMBAT_MODE_LOCKED, src)
if(istype(L) && target.stat == CONSCIOUS && (target in view(10, get_turf(L)))) // They Woke Up! (Notice if within view)
to_chat(L, "<span class='warning'>[target] has snapped out of their trance.</span>")
// 3 second windup
sleep(30)
if(success)
PowerActivatedSuccessfully() // blood & cooldown only altered if power activated successfully - less "fuck you"-y
target.face_atom(user)
target.apply_status_effect(STATUS_EFFECT_MESMERIZE, power_time) // pretty much purely cosmetic
target.Stun(power_time)
to_chat(user, "<span class='notice'>[target] is fixed in place by your hypnotic gaze.</span>")
target.next_move = world.time + power_time // <--- Use direct change instead. We want an unmodified delay to their next move // target.changeNext_move(power_time) // check click.dm
target.notransform = TRUE // <--- Fuck it. We tried using next_move, but they could STILL resist. We're just doing a hard freeze.
spawn(power_time)
if(istype(target) && success)
target.notransform = FALSE
// They Woke Up! (Notice if within view)
if(istype(user) && target.stat == CONSCIOUS && (target in view(10, get_turf(user))) )
to_chat(user, "<span class='warning'>[target] has snapped out of their trance.</span>")
/datum/action/bloodsucker/targeted/mesmerize/ContinueActive(mob/living/user, mob/living/target)
return ..() && CheckCanUse() && CheckCanTarget(target)
@@ -31,6 +31,7 @@
var/isabsorbing = 0
var/islinking = 0
var/geneticpoints = 10
var/maxgeneticpoints = 10
var/purchasedpowers = list()
var/mimicing = ""
var/canrespec = 0
@@ -98,17 +99,24 @@
to_chat(H, "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself.")
H.dna.remove_mutation(CLOWNMUT)
/datum/antagonist/changeling/proc/reset_properties()
/datum/antagonist/changeling/proc/reset_properties(hardReset = FALSE)
changeling_speak = 0
chosen_sting = null
geneticpoints = initial(geneticpoints)
geneticpoints = maxgeneticpoints
sting_range = initial(sting_range)
chem_storage = initial(chem_storage)
chem_recharge_rate = initial(chem_recharge_rate)
chem_charges = min(chem_charges, chem_storage)
chem_recharge_slowdown = initial(chem_recharge_slowdown)
mimicing = ""
if (hardReset)
chem_storage = initial(chem_storage)
chem_recharge_rate = initial(chem_recharge_rate)
geneticpoints = initial(geneticpoints)
maxgeneticpoints = initial(maxgeneticpoints)
chem_charges = min(chem_charges, chem_storage)
/datum/antagonist/changeling/proc/remove_changeling_powers()
if(ishuman(owner.current) || ismonkey(owner.current))
reset_properties()
@@ -287,7 +295,6 @@
prof.name_list[slot] = I.name
prof.appearance_list[slot] = I.appearance
prof.flags_cover_list[slot] = I.flags_cover
prof.item_color_list[slot] = I.item_color
prof.item_state_list[slot] = I.item_state
prof.exists_list[slot] = 1
else
@@ -503,7 +510,6 @@
var/list/appearance_list = list()
var/list/flags_cover_list = list()
var/list/exists_list = list()
var/list/item_color_list = list()
var/list/item_state_list = list()
var/underwear
@@ -526,7 +532,6 @@
newprofile.appearance_list = appearance_list.Copy()
newprofile.flags_cover_list = flags_cover_list.Copy()
newprofile.exists_list = exists_list.Copy()
newprofile.item_color_list = item_color_list.Copy()
newprofile.item_state_list = item_state_list.Copy()
newprofile.underwear = underwear
newprofile.undershirt = undershirt
@@ -28,8 +28,7 @@
action.Remove(user)
return
/obj/effect/proc_holder/changeling/Click()
var/mob/user = usr
/obj/effect/proc_holder/changeling/Trigger(mob/user)
if(!user || !user.mind || !user.mind.has_antag_datum(/datum/antagonist/changeling))
return
try_to_sting(user)
@@ -96,6 +96,7 @@
to_chat(user, "<span class='boldnotice'>[target] was one of us. We have absorbed their power.</span>")
target_ling.remove_changeling_powers()
changeling.geneticpoints += round(target_ling.geneticpoints/2)
changeling.maxgeneticpoints += round(target_ling.geneticpoints/2)
target_ling.geneticpoints = 0
target_ling.canrespec = 0
changeling.chem_storage += round(target_ling.chem_storage/2)
@@ -441,23 +441,23 @@
var/remaining_uses //Set by the changeling ability.
/obj/item/shield/changeling/Initialize()
/obj/item/shield/changeling/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT)
if(ismob(loc))
loc.visible_message("<span class='warning'>The end of [loc.name]\'s hand inflates rapidly, forming a huge shield-like mass!</span>", "<span class='warning'>We inflate our hand into a strong shield.</span>", "<span class='italics'>You hear organic matter ripping and tearing!</span>")
/obj/item/shield/changeling/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(remaining_uses < 1)
/obj/item/shield/changeling/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
block_return[BLOCK_RETURN_BLOCK_CAPACITY] = (block_return[BLOCK_RETURN_BLOCK_CAPACITY] || 0) + remaining_uses
return ..()
/obj/item/shield/changeling/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
. = ..()
if(--remaining_uses < 1)
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
H.visible_message("<span class='warning'>With a sickening crunch, [H] reforms [H.p_their()] shield into an arm!</span>", "<span class='notice'>We assimilate our shield into our body</span>", "<span class='italics>You hear organic matter ripping and tearing!</span>")
qdel(src)
return 0
else
remaining_uses--
return ..()
/***************************************\
|*********SPACE SUIT + HELMET***********|
@@ -3,8 +3,7 @@
desc = "Stabby stabby."
var/sting_icon = null
/obj/effect/proc_holder/changeling/sting/Click()
var/mob/user = usr
/obj/effect/proc_holder/changeling/sting/Trigger(mob/user)
if(!user || !user.mind)
return
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
@@ -74,8 +73,7 @@
action_icon_state = "ling_sting_transform"
action_background_icon_state = "bg_ling"
/obj/effect/proc_holder/changeling/sting/transformation/Click()
var/mob/user = usr
/obj/effect/proc_holder/changeling/sting/transformation/Trigger(mob/user)
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
if(changeling.chosen_sting)
unset_sting(user)
@@ -279,9 +279,15 @@
sigil_name = "Vitality Matrix"
var/revive_cost = 150
var/sigil_active = FALSE
var/min_drain_health = -INFINITY
var/can_dust = TRUE
var/animation_number = 3 //each cycle increments this by 1, at 4 it produces an animation and resets
var/static/list/damage_heal_order = list(CLONE, TOX, BURN, BRUTE, OXY) //we heal damage in this order
/obj/effect/clockwork/sigil/vitality/neutered
min_drain_health = 20
can_dust = FALSE
/obj/effect/clockwork/sigil/vitality/examine(mob/user)
. = ..()
if(is_servant_of_ratvar(user) || isobserver(user))
@@ -306,7 +312,7 @@
animation_number++
if(!is_servant_of_ratvar(L))
var/vitality_drained = 0
if(L.stat == DEAD && !consumed_vitality)
if(L.stat == DEAD && !consumed_vitality && can_dust)
consumed_vitality = TRUE //Prevent the target from being consumed multiple times
vitality_drained = L.maxHealth
var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src))
@@ -318,7 +324,7 @@
if(!L.dropItemToGround(W))
qdel(W)
L.dust()
else
else if(L.health > min_drain_health)
if(!GLOB.ratvar_awakens && L.stat == CONSCIOUS)
vitality_drained = L.adjustToxLoss(1, forced = TRUE)
else
@@ -35,7 +35,7 @@
var/span_for_name = "heavy_brass"
var/span_for_message = "brass"
/datum/action/innate/hierophant/IsAvailable()
/datum/action/innate/hierophant/IsAvailable(silent = FALSE)
if(!is_servant_of_ratvar(owner))
return FALSE
return ..()
@@ -12,7 +12,7 @@
var/obj/item/clockwork/weapon/weapon_type //The type of weapon to create
var/obj/item/clockwork/weapon/weapon
/datum/action/innate/call_weapon/IsAvailable()
/datum/action/innate/call_weapon/IsAvailable(silent = FALSE)
if(!is_servant_of_ratvar(owner))
qdel(src)
return
@@ -127,7 +127,6 @@
icon = 'icons/obj/clothing/clockwork_garb.dmi'
icon_state = "clockwork_gauntlets"
item_state = "clockwork_gauntlets"
item_color = null //So they don't wash.
strip_delay = 50
equip_delay_other = 30
body_parts_covered = ARMS
@@ -36,6 +36,24 @@
speed_multiplier = 0
no_cost = TRUE
/obj/item/clockwork/slab/traitor
var/spent = FALSE
/obj/item/clockwork/slab/traitor/check_uplink_validity()
return !spent
/obj/item/clockwork/slab/traitor/attack_self(mob/living/user)
if(!is_servant_of_ratvar(user) && !spent)
to_chat(user, "<span class='userdanger'>You press your hand onto [src], golden tendrils of light latching onto you. Was this the best of ideas?</span>")
if(add_servant_of_ratvar(user, FALSE, FALSE, /datum/antagonist/clockcult/neutered/traitor))
spent = TRUE
// Add some (5 KW) power so they don't suffer for 100 ticks
GLOB.clockwork_power += 5000
// This intentionally does not use adjust_clockwork_power.
else
to_chat(user, "<span class='userdanger'>[src] falls dark. It appears you weren't worthy.</span>")
return ..()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/clockwork/slab/debug/attack_hand(mob/living/user)
if(!is_servant_of_ratvar(user))
@@ -103,8 +121,8 @@
. = ..()
addtimer(CALLBACK(src, .proc/check_on_mob, user), 1) //dropped is called before the item is out of the slot, so we need to check slightly later
/obj/item/clockwork/slab/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
. = list()
/obj/item/clockwork/slab/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(isinhands && item_state && inhand_overlay)
var/mutable_appearance/M = mutable_appearance(icon_file, "slab_[inhand_overlay]")
. += M
@@ -232,7 +232,7 @@
background_icon_state = "bg_clock"
buttontooltipstyle = "clockcult"
/datum/action/innate/eminence/IsAvailable()
/datum/action/innate/eminence/IsAvailable(silent = FALSE)
if(!iseminence(owner))
qdel(src)
return
@@ -283,7 +283,7 @@
desc = "Initiates a mass recall, warping all servants to the Ark after a short delay. This can only be used once."
button_icon_state = "Spatial Gateway"
/datum/action/innate/eminence/mass_recall/IsAvailable()
/datum/action/innate/eminence/mass_recall/IsAvailable(silent = FALSE)
. = ..()
if(.)
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
@@ -30,6 +30,7 @@ Applications: 8 servants, 3 caches, and 100 CV
var/primary_component
var/important = FALSE //important scripture will be italicized in the slab's interface
var/sort_priority = 1 //what position the scripture should have in a list of scripture. Should be based off of component costs/reqs, but you can't initial() lists.
var/requires_full_power = FALSE //requires the user to be a full, non neutered servant of ratvar
//messages for offstation scripture recital, courtesy ratvar's generals(and neovgre)
var/static/list/neovgre_penalty = list("Go to the station.", "Useless.", "Don't waste time.", "Pathetic.", "Wasteful.")
@@ -77,6 +78,9 @@ Applications: 8 servants, 3 caches, and 100 CV
/datum/clockwork_scripture/proc/can_recite() //If the words can be spoken
if(!invoker || !slab || invoker.get_active_held_item() != slab)
return FALSE
if(!is_servant_of_ratvar(invoker, requires_full_power))
to_chat(invoker, "<span class='warning'>You aren't strongly connected enough to Ratvar to invoke this!</span>")
return FALSE
if(!invoker.can_speak_vocal())
to_chat(invoker, "<span class='warning'>You are unable to speak the words of the scripture!</span>")
return FALSE
@@ -236,18 +240,21 @@ Applications: 8 servants, 3 caches, and 100 CV
return FALSE
return TRUE
/datum/clockwork_scripture/create_object/proc/get_spawn_path(mob/user)
return object_path
/datum/clockwork_scripture/create_object/scripture_effects()
if(creator_message && observer_message)
invoker.visible_message(observer_message, creator_message)
else if(creator_message)
to_chat(invoker, creator_message)
var/obj/O = new object_path (get_turf(invoker))
var/to_spawn = get_spawn_path(invoker)
var/obj/O = new to_spawn(get_turf(invoker))
O.ratvar_act() //update the new object so it gets buffed if ratvar is alive
if(isitem(O) && put_object_in_hands)
invoker.put_in_hands(O)
return TRUE
//Used specifically to create construct shells.
/datum/clockwork_scripture/create_object/construct
put_object_in_hands = FALSE
@@ -88,7 +88,7 @@
sort_priority = 4
quickbind = TRUE
quickbind_desc = "Creates a Sigil of Submission, which will convert non-Servants that remain on it."
requires_full_power = TRUE
//Kindle: Charges the slab with blazing energy. It can be released to stun and silence a target.
/datum/clockwork_scripture/ranged_ability/kindle
@@ -211,6 +211,7 @@
quickbind = TRUE
quickbind_desc = "Returns you to Reebe."
var/client_color
requires_full_power = TRUE
/datum/clockwork_scripture/abscond/check_special_requirements()
if(is_reebe(invoker.z))
@@ -50,7 +50,6 @@
return FALSE
return ..()
//Vitality Matrix: Creates a sigil which will drain health from nonservants and can use that health to heal or even revive servants.
/datum/clockwork_scripture/create_object/vitality_matrix
descname = "Trap, Damage to Healing"
@@ -77,6 +76,10 @@
return FALSE
return ..()
/datum/clockwork_scripture/create_object/vitality_matrix/get_spawn_path(mob/user)
if(!is_servant_of_ratvar(user, TRUE))
return /obj/effect/clockwork/sigil/vitality/neutered
return ..()
//Judicial Visor: Creates a judicial visor, which can smite an area.
/datum/clockwork_scripture/create_object/judicial_visor
@@ -150,7 +153,7 @@
/obj/item/clothing/head/helmet/space,
/obj/item/clothing/shoes/magboots)) //replace this only if ratvar is up
/datum/action/innate/clockwork_armaments/IsAvailable()
/datum/action/innate/clockwork_armaments/IsAvailable(silent = FALSE)
if(!is_servant_of_ratvar(owner))
qdel(src)
return
@@ -5,15 +5,27 @@
antagpanel_category = "Clockcult"
job_rank = ROLE_SERVANT_OF_RATVAR
antag_moodlet = /datum/mood_event/cult
var/datum/action/innate/hierophant/hierophant_network = new
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
var/neutered = FALSE //can not use round ending, gibbing, converting, or similar things with unmatched round impact
var/ignore_eligibility_check = FALSE
var/ignore_holy_water = FALSE
/datum/antagonist/clockcult/silent
silent = TRUE
show_in_antagpanel = FALSE //internal
/datum/antagonist/clockcult/neutered
neutered = TRUE
/datum/antagonist/clockcult/neutered/traitor
ignore_eligibility_check = TRUE
ignore_holy_water = TRUE
show_in_roundend = FALSE
make_team = FALSE
/datum/antagonist/clockcult/Destroy()
qdel(hierophant_network)
return ..()
@@ -38,7 +50,7 @@
/datum/antagonist/clockcult/can_be_owned(datum/mind/new_owner)
. = ..()
if(.)
if(. && !ignore_eligibility_check)
. = is_eligible_servant(new_owner.current)
/datum/antagonist/clockcult/greet()
+12 -5
View File
@@ -17,7 +17,7 @@
qdel(X)
..()
/datum/action/innate/cult/blood_magic/IsAvailable()
/datum/action/innate/cult/blood_magic/IsAvailable(silent = FALSE)
if(!iscultist(owner))
return FALSE
return ..()
@@ -118,7 +118,7 @@
hand_magic = null
..()
/datum/action/innate/cult/blood_spell/IsAvailable()
/datum/action/innate/cult/blood_spell/IsAvailable(silent = FALSE)
if(!iscultist(owner) || owner.incapacitated() || !charges)
return FALSE
return ..()
@@ -439,7 +439,7 @@
"<span class='userdanger'>A feeling of warmth washes over you, rays of holy light surround your body and protect you from the flash of light!</span>")
else // cult doesn't stun any longer when halos are out, instead it does burn damage + knockback!
var/datum/antagonist/cult/user_antag = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(user_antag.cult_team.cult_ascendent)
if(user_antag.cult_team?.cult_ascendent)
if(!iscultist(L))
L.adjustFireLoss(20)
if(L.move_resist < MOVE_FORCE_STRONG)
@@ -577,7 +577,9 @@
var/turf/T = get_turf(target)
if(istype(target, /obj/item/stack/sheet/metal))
var/obj/item/stack/sheet/candidate = target
if(candidate.use(50))
if(!iscultist(user, TRUE))
to_chat(user, "<span class='warning'>You are not strongly connected enough to Nar'sie to use make constructs...</span>")
else if(candidate.use(50))
uses--
to_chat(user, "<span class='warning'>A dark cloud emanates from your hand and swirls around the metal, twisting it into a construct shell!</span>")
new /obj/structure/constructshell(T)
@@ -600,7 +602,9 @@
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
else if(istype(target,/mob/living/silicon/robot))
var/mob/living/silicon/robot/candidate = target
if(candidate.mmi)
if(!iscultist(user, TRUE))
to_chat(user, "<span class='warning'>You are not strongly connected enough to Nar'sie to use make constructs...</span>")
else if(candidate.mmi)
user.visible_message("<span class='danger'>A dark cloud emanates from [user]'s hand and swirls around [candidate]!</span>")
playsound(T, 'sound/machines/airlock_alien_prying.ogg', 80, 1)
var/prev_color = candidate.color
@@ -656,6 +660,7 @@
C.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), SLOT_WEAR_SUIT)
C.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult/alt(user), SLOT_SHOES)
C.equip_to_slot_or_del(new /obj/item/storage/backpack/cultpack(user), SLOT_BACK)
C.equip_to_slot_or_del(new /obj/item/clothing/gloves/fingerless/pugilist/hungryghost(user), SLOT_GLOVES)
if(C == user)
qdel(src) //Clears the hands
C.put_in_hands(new /obj/item/melee/cultblade(user))
@@ -819,6 +824,8 @@
if("Blood Beam (500)")
if(uses < 500)
to_chat(user, "<span class='cultitalic'>You need 500 charges to perform this rite.</span>")
else if(!iscultist(user, TRUE))
to_chat(user, "<span class='warning'>You are not strongly connected to Nar'sie enough to use something of this power.</span>")
else
var/obj/rite = new /obj/item/blood_beam()
uses -= 500
+21 -9
View File
@@ -11,15 +11,27 @@
var/datum/action/innate/cult/blood_magic/magic = new
job_rank = ROLE_CULTIST
var/ignore_implant = FALSE
var/make_team = TRUE
var/give_equipment = FALSE
var/datum/team/cult/cult_team
var/neutered = FALSE //can not use round ending, gibbing, converting, or similar things with unmatched round impact
var/ignore_eligibility_checks = FALSE
var/ignore_holy_water = FALSE
/datum/antagonist/cult/neutered
neutered = TRUE
/datum/antagonist/cult/neutered/traitor
ignore_eligibility_checks = TRUE
ignore_holy_water = TRUE
show_in_roundend = FALSE
make_team = FALSE
/datum/antagonist/cult/get_team()
return cult_team
/datum/antagonist/cult/create_team(datum/team/cult/new_team)
if(!new_team)
if(!new_team && make_team)
//todo remove this and allow admin buttons to create more than one cult
for(var/datum/antagonist/cult/H in GLOB.antagonists)
if(!H.owner)
@@ -30,12 +42,12 @@
cult_team = new /datum/team/cult
cult_team.setup_objectives()
return
if(!istype(new_team))
if(make_team && !istype(new_team))
stack_trace("Wrong team type passed to [type] initialization.")
cult_team = new_team
/datum/antagonist/cult/proc/add_objectives()
objectives |= cult_team.objectives
objectives |= cult_team?.objectives
/datum/antagonist/cult/Destroy()
QDEL_NULL(communion)
@@ -44,7 +56,7 @@
/datum/antagonist/cult/can_be_owned(datum/mind/new_owner)
. = ..()
if(. && !ignore_implant)
if(. && !ignore_implant && !ignore_eligibility_checks)
. = is_convertable_to_cult(new_owner.current,cult_team)
/datum/antagonist/cult/greet()
@@ -62,7 +74,7 @@
SSticker.mode.update_cult_icons_added(owner)
current.log_message("has been converted to the cult of Nar'Sie!", LOG_ATTACK, color="#960000")
if(cult_team.blood_target && cult_team.blood_target_image && current.client)
if(cult_team?.blood_target && cult_team.blood_target_image && current.client)
current.client.images += cult_team.blood_target_image
@@ -105,13 +117,13 @@
current = mob_override
current.faction |= "cult"
current.grant_language(/datum/language/narsie)
if(!cult_team.cult_master)
if(!cult_team?.cult_master)
vote.Grant(current)
communion.Grant(current)
if(ishuman(current))
magic.Grant(current)
current.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
if(cult_team.cult_risen)
if(cult_team?.cult_risen)
cult_team.rise(current)
if(cult_team.cult_ascendent)
cult_team.ascend(current)
@@ -144,7 +156,7 @@
owner.current.visible_message("<span class='deconversion_message'>[owner.current] looks like [owner.current.p_theyve()] just reverted to [owner.current.p_their()] old faith!</span>", null, null, null, owner.current)
to_chat(owner.current, "<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of the Geometer and all your memories as her servant.</span>")
owner.current.log_message("has renounced the cult of Nar'Sie!", LOG_ATTACK, color="#960000")
if(cult_team.blood_target && cult_team.blood_target_image && owner.current.client)
if(cult_team?.blood_target && cult_team.blood_target_image && owner.current.client)
owner.current.client.images -= cult_team.blood_target_image
. = ..()
@@ -206,7 +218,7 @@
throwing.Grant(current)
current.update_action_buttons_icon()
current.apply_status_effect(/datum/status_effect/cult_master)
if(cult_team.cult_risen)
if(cult_team?.cult_risen)
cult_team.rise(current)
if(cult_team.cult_ascendent)
cult_team.ascend(current)
+26 -14
View File
@@ -6,7 +6,7 @@
buttontooltipstyle = "cult"
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
/datum/action/innate/cult/IsAvailable()
/datum/action/innate/cult/IsAvailable(silent = FALSE)
if(!iscultist(owner))
return FALSE
return ..()
@@ -51,7 +51,7 @@
name = "Spiritual Communion"
desc = "Conveys a message from the spirit realm that all cultists can hear."
/datum/action/innate/cult/comm/spirit/IsAvailable()
/datum/action/innate/cult/comm/spirit/IsAvailable(silent = FALSE)
if(iscultist(owner.mind.current))
return TRUE
@@ -72,9 +72,9 @@
name = "Assert Leadership"
button_icon_state = "cultvote"
/datum/action/innate/cult/mastervote/IsAvailable()
/datum/action/innate/cult/mastervote/IsAvailable(silent = FALSE)
var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(!C || C.cult_team.cult_vote_called || !ishuman(owner))
if(!C?.cult_team || C.cult_team.cult_vote_called || !ishuman(owner))
return FALSE
return ..()
@@ -82,6 +82,9 @@
var/choice = alert(owner, "The mantle of leadership is heavy. Success in this role requires an expert level of communication and experience. Are you sure?",, "Yes", "No")
if(choice == "Yes" && IsAvailable())
var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(!C.cult_team)
to_chat(owner, "<span class='cult bold'>Do you not alreaady lead yourself?</span>")
return
pollCultists(owner,C.cult_team)
/proc/pollCultists(var/mob/living/Nominee,datum/team/cult/team) //Cult Master Poll
@@ -137,7 +140,7 @@
to_chat(B.current,"<span class='cultlarge'>[Nominee] has won the cult's support and is now their master. Follow [Nominee.p_their()] orders to the best of your ability!</span>")
return TRUE
/datum/action/innate/cult/master/IsAvailable()
/datum/action/innate/cult/master/IsAvailable(silent = FALSE)
if(!owner.mind || !owner.mind.has_antag_datum(/datum/antagonist/cult/master) || GLOB.cult_narsie)
return 0
return ..()
@@ -151,6 +154,9 @@
var/datum/antagonist/cult/antag = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(!antag)
return
if(!antag.cult_team)
to_chat(owner, "<span class='cult bold'>You have no team. You are alone.</span>")
return
for(var/i in 1 to 4)
chant(i)
var/list/destinations = list()
@@ -220,9 +226,9 @@
CM.attached_action = src
..()
/datum/action/innate/cult/master/cultmark/IsAvailable()
/datum/action/innate/cult/master/cultmark/IsAvailable(silent = FALSE)
if(cooldown > world.time)
if(!CM.active)
if(!CM.active && !silent)
to_chat(owner, "<span class='cultlarge'><b>You need to wait [DisplayTimeText(cooldown - world.time)] before you can mark another target!</b></span>")
return FALSE
return ..()
@@ -261,7 +267,10 @@
return FALSE
var/datum/antagonist/cult/C = caller.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(!C.cult_team)
to_chat(ranged_ability_user, "<span class='cultlarge'>What is the point of marking a target for yourself?</span>")
remove_ranged_ability()
return
if(target in view(7, get_turf(ranged_ability_user)))
if(C.cult_team.blood_target)
to_chat(ranged_ability_user, "<span class='cult'>The cult has already designated a target!</span>")
@@ -299,7 +308,7 @@
name = "Mark a Blood Target for the Cult"
desc = "Marks a target for the entire cult to track."
/datum/action/innate/cult/master/cultmark/ghost/IsAvailable()
/datum/action/innate/cult/master/cultmark/ghost/IsAvailable(silent = FALSE)
if(istype(owner, /mob/dead/observer) && iscultist(owner.mind.current))
return TRUE
else
@@ -313,7 +322,7 @@
var/cooldown = 0
var/base_cooldown = 600
/datum/action/innate/cult/ghostmark/IsAvailable()
/datum/action/innate/cult/ghostmark/IsAvailable(silent = FALSE)
if(istype(owner, /mob/dead/observer) && iscultist(owner.mind.current))
return TRUE
else
@@ -330,8 +339,11 @@
/datum/action/innate/cult/ghostmark/Activate()
var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(!C.cult_team)
to_chat(owner, "<span class='cultbold'>You are alone. You do not have a team.</span>")
return
if(C.cult_team.blood_target)
if(cooldown>world.time)
if(cooldown > world.time)
reset_blood_target(C.cult_team)
to_chat(owner, "<span class='cultbold'>You have cleared the cult's blood target!</span>")
deltimer(C.cult_team.blood_target_reset_timer)
@@ -339,7 +351,7 @@
else
to_chat(owner, "<span class='cultbold'>The cult has already designated a target!</span>")
return
if(cooldown>world.time)
if(cooldown > world.time)
to_chat(owner, "<span class='cultbold'>You aren't ready to place another blood mark yet!</span>")
return
target = owner.orbiting?.parent || get_turf(owner)
@@ -389,11 +401,11 @@
PM.attached_action = src
..()
/datum/action/innate/cult/master/pulse/IsAvailable()
/datum/action/innate/cult/master/pulse/IsAvailable(silent = FALSE)
if(!owner.mind || !owner.mind.has_antag_datum(/datum/antagonist/cult/master))
return FALSE
if(cooldown > world.time)
if(!PM.active)
if(!PM.active && !silent)
to_chat(owner, "<span class='cultlarge'><b>You need to wait [DisplayTimeText(cooldown - world.time)] before you can pulse again!</b></span>")
return FALSE
return ..()
+65 -38
View File
@@ -6,6 +6,21 @@
throw_range = 5
w_class = WEIGHT_CLASS_SMALL
/obj/item/tome/traitor
var/spent = FALSE
/obj/item/tome/traitor/check_uplink_validity()
return !spent
/obj/item/tome/traitor/attack_self(mob/living/user)
if(!iscultist(user) && !spent)
to_chat(user, "<span class='userdanger'>You press your hand onto [src], sinister tendrils of corrupted magic swirling around you. Was this the best of ideas?</span>")
if(user.mind.add_antag_datum(/datum/antagonist/cult/neutered/traitor))
spent = TRUE
else
to_chat(user, "<span class='userdanger'>[src] falls dark. It appears you weren't worthy.</span>")
return ..()
/obj/item/melee/cultblade/dagger
name = "ritual dagger"
desc = "A strange dagger said to be used by sinister groups for \"preparing\" a corpse before sacrificing it to their dark gods."
@@ -162,24 +177,20 @@
jaunt.Remove(user)
user.update_icons()
/obj/item/twohanded/required/cult_bastard/IsReflect()
if(spinning)
/obj/item/twohanded/required/cult_bastard/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(spinning && is_energy_reflectable_projectile(object) && (attack_type & ATTACK_TYPE_PROJECTILE))
playsound(src, pick('sound/weapons/effects/ric1.ogg', 'sound/weapons/effects/ric2.ogg', 'sound/weapons/effects/ric3.ogg', 'sound/weapons/effects/ric4.ogg', 'sound/weapons/effects/ric5.ogg'), 100, 1)
return TRUE
else
..()
/obj/item/twohanded/required/cult_bastard/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT
if(prob(final_block_chance))
if(attack_type == PROJECTILE_ATTACK)
if(attack_type & ATTACK_TYPE_PROJECTILE)
owner.visible_message("<span class='danger'>[owner] deflects [attack_text] with [src]!</span>")
playsound(src, pick('sound/weapons/effects/ric1.ogg', 'sound/weapons/effects/ric2.ogg', 'sound/weapons/effects/ric3.ogg', 'sound/weapons/effects/ric4.ogg', 'sound/weapons/effects/ric5.ogg'), 100, 1)
return TRUE
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT
else
playsound(src, 'sound/weapons/parry.ogg', 75, 1)
owner.visible_message("<span class='danger'>[owner] parries [attack_text] with [src]!</span>")
return TRUE
return FALSE
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
return BLOCK_NONE
/obj/item/twohanded/required/cult_bastard/afterattack(atom/target, mob/user, proximity, click_parameters)
. = ..()
@@ -211,7 +222,7 @@
phasein = /obj/effect/temp_visual/dir_setting/cult/phase
phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out
/datum/action/innate/dash/cult/IsAvailable()
/datum/action/innate/dash/cult/IsAvailable(silent = FALSE)
if(iscultist(holder) && current_charges)
return TRUE
else
@@ -231,7 +242,7 @@
sword = bastard
holder = user
/datum/action/innate/cult/spin2win/IsAvailable()
/datum/action/innate/cult/spin2win/IsAvailable(silent = FALSE)
if(iscultist(holder) && cooldown <= world.time)
return TRUE
else
@@ -353,6 +364,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"
@@ -363,6 +379,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."
@@ -414,7 +434,13 @@
user.adjustBruteLoss(25)
user.dropItemToGround(src, TRUE)
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(current_charges)
block_return[BLOCK_RETURN_NORMAL_BLOCK_CHANCE] = 100
block_return[BLOCK_RETURN_BLOCK_CAPACITY] = (block_return[BLOCK_RETURN_BLOCK_CAPACITY] || 0) + current_charges
return ..()
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(current_charges)
owner.visible_message("<span class='danger'>\The [attack_text] is deflected in a burst of blood-red sparks!</span>")
current_charges--
@@ -422,11 +448,11 @@
if(!current_charges)
owner.visible_message("<span class='danger'>The runed shield around [owner] suddenly disappears!</span>")
owner.update_inv_wear_suit()
return 1
return 0
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
return BLOCK_NONE
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/worn_overlays(isinhands, icon_file, style_flags = NONE)
. = list()
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands && current_charges)
. += mutable_appearance('icons/effects/cult_effects.dmi', "shield-cult", MOB_LAYER + 0.01)
@@ -498,7 +524,7 @@
var/static/curselimit = 0
/obj/item/shuttle_curse/attack_self(mob/living/user)
if(!iscultist(user))
if(!iscultist(user, TRUE))
user.dropItemToGround(src, TRUE)
user.DefaultCombatKnockdown(100)
to_chat(user, "<span class='warning'>A powerful force shoves you away from [src]!</span>")
@@ -725,19 +751,19 @@
playsound(T, 'sound/effects/glassbr3.ogg', 100)
qdel(src)
/obj/item/twohanded/cult_spear/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
/obj/item/twohanded/cult_spear/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(wielded)
final_block_chance *= 2
if(prob(final_block_chance))
if(attack_type == PROJECTILE_ATTACK)
if(attack_type & ATTACK_TYPE_PROJECTILE)
owner.visible_message("<span class='danger'>[owner] deflects [attack_text] with [src]!</span>")
playsound(src, pick('sound/weapons/effects/ric1.ogg', 'sound/weapons/effects/ric2.ogg', 'sound/weapons/effects/ric3.ogg', 'sound/weapons/effects/ric4.ogg', 'sound/weapons/effects/ric5.ogg'), 100, 1)
return TRUE
return BLOCK_SUCCESS | BLOCK_SHOULD_REDIRECT | BLOCK_REDIRECTED | BLOCK_PHYSICAL_EXTERNAL
else
playsound(src, 'sound/weapons/parry.ogg', 100, 1)
owner.visible_message("<span class='danger'>[owner] parries [attack_text] with [src]!</span>")
return TRUE
return FALSE
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
return BLOCK_NONE
/datum/action/innate/cult/spear
name = "Bloody Bond"
@@ -936,10 +962,18 @@
hitsound = 'sound/weapons/smash.ogg'
var/illusions = 2
/obj/item/shield/mirror/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
/obj/item/shield/mirror/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
block_return[BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE] = max(block_return[BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE] || null, final_block_chance)
return ..()
/obj/item/shield/mirror/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(iscultist(owner))
if(istype(hitby, /obj/item/projectile))
var/obj/item/projectile/P = hitby
if(istype(object, /obj/item/projectile) && (attack_type == ATTACK_TYPE_PROJECTILE))
if(is_energy_reflectable_projectile(object))
if(prob(final_block_chance))
return BLOCK_SUCCESS | BLOCK_SHOULD_REDIRECT | BLOCK_PHYSICAL_EXTERNAL | BLOCK_REDIRECTED
return BLOCK_NONE //To avoid reflection chance double-dipping with block chance
var/obj/item/projectile/P = object
if(P.damage >= 30)
var/turf/T = get_turf(owner)
T.visible_message("<span class='warning'>The sheer force from [P] shatters the mirror shield!</span>")
@@ -947,11 +981,9 @@
playsound(T, 'sound/effects/glassbr3.ogg', 100)
owner.DefaultCombatKnockdown(25)
qdel(src)
return FALSE
if(P.is_reflectable)
return FALSE //To avoid reflection chance double-dipping with block chance
return BLOCK_NONE
. = ..()
if(.)
if(. & BLOCK_SUCCESS)
playsound(src, 'sound/weapons/parry.ogg', 100, 1)
if(illusions > 0)
illusions--
@@ -966,7 +998,7 @@
E.Copy_Parent(owner, 70, 10)
E.GiveTarget(owner)
E.Goto(owner, owner.movement_delay(), E.minimum_distance)
return TRUE
return
else
if(prob(50))
var/mob/living/simple_animal/hostile/illusion/H = new(owner.loc)
@@ -975,7 +1007,7 @@
H.GiveTarget(owner)
H.move_to_delay = owner.movement_delay()
to_chat(owner, "<span class='danger'><b>[src] betrays you!</b></span>")
return FALSE
return BLOCK_NONE
/obj/item/shield/mirror/proc/readd()
illusions++
@@ -983,11 +1015,6 @@
var/mob/living/holder = loc
to_chat(holder, "<span class='cult italic'>The shield's illusions are back at full strength!</span>")
/obj/item/shield/mirror/IsReflect()
if(prob(block_chance))
return TRUE
return FALSE
/obj/item/shield/mirror/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
var/turf/T = get_turf(hit_atom)
var/datum/thrownthing/D = throwingdatum
+5 -2
View File
@@ -59,6 +59,9 @@ This file contains the cult dagger and rune list code
rune_to_scribe = GLOB.rune_types[entered_rune_name]
if(!rune_to_scribe)
return
if(!iscultist(user, initial(rune_to_scribe.requires_full_power)))
to_chat(user, "<span class='warning'>You aren't strongly connected enough to Nar'sie to do draw this.</span>")
return
if(initial(rune_to_scribe.req_keyword))
chosen_keyword = stripped_input(user, "Enter a keyword for the new rune.", "Words of Power")
if(!chosen_keyword)
@@ -84,8 +87,8 @@ This file contains the cult dagger and rune list code
to_chat(user, "<span class='cultlarge'>Only one ritual site remains - it must be reserved for the final summoning!</span>")
return
if(ispath(rune_to_scribe, /obj/effect/rune/narsie))
var/datum/objective/eldergod/summon_objective = locate() in user_antag.cult_team.objectives
var/datum/objective/sacrifice/sac_objective = locate() in user_antag.cult_team.objectives
var/datum/objective/eldergod/summon_objective = locate() in user_antag.cult_team?.objectives
var/datum/objective/sacrifice/sac_objective = locate() in user_antag.cult_team?.objectives
if(!summon_objective)
to_chat(user, "<span class='warning'>Nar'Sie does not wish to be summoned!</span>")
return
@@ -14,7 +14,7 @@
var/obj/effect/temp_visual/cult/rune_spawn/rune_center_type
var/rune_color
/datum/action/innate/cult/create_rune/IsAvailable()
/datum/action/innate/cult/create_rune/IsAvailable(silent = FALSE)
if(!rune_type || cooldown > world.time)
return FALSE
return ..()
+11
View File
@@ -32,6 +32,7 @@ Runes can either be invoked by one's self or with many different cultists. Each
var/scribe_delay = 40 //how long the rune takes to create
var/scribe_damage = 0.1 //how much damage you take doing it
var/requires_full_power = FALSE //requires full power to draw or invoke
var/invoke_damage = 0 //how much damage invokers take when invoking it
var/construct_invoke = TRUE //if constructs can invoke it
@@ -185,6 +186,7 @@ structure_check() searches for nearby cultist structures required for the invoca
color = RUNE_COLOR_OFFER
req_cultists = 1
rune_in_use = FALSE
requires_full_power = TRUE
/obj/effect/rune/convert/do_invoke_glow()
return
@@ -458,6 +460,7 @@ structure_check() searches for nearby cultist structures required for the invoca
pixel_y = -32
scribe_delay = 500 //how long the rune takes to create
scribe_damage = 40.1 //how much damage you take doing it
requires_full_power = TRUE
var/used = FALSE
/obj/effect/rune/narsie/Initialize(mapload, set_keyword)
@@ -482,6 +485,9 @@ structure_check() searches for nearby cultist structures required for the invoca
fail_invoke()
return
var/datum/antagonist/cult/user_antag = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(!user_antag.cult_team)
to_chat(user, "<span class='cultlarge'>You can't seem to make the arcane links to your fellows that you'd need to use this.</span>")
return
var/datum/objective/eldergod/summon_objective = locate() in user_antag.cult_team.objectives
var/area/place = get_area(src)
if(!(place in summon_objective.summon_spots))
@@ -812,6 +818,7 @@ structure_check() searches for nearby cultist structures required for the invoca
invoke_damage = 10
construct_invoke = FALSE
color = RUNE_COLOR_DARKRED
requires_full_power = TRUE
var/mob/living/affecting = null
var/ghost_limit = 3
var/ghosts = 0
@@ -942,6 +949,7 @@ structure_check() searches for nearby cultist structures required for the invoca
color = RUNE_COLOR_DARKRED
req_cultists = 3
scribe_delay = 100
requires_full_power = TRUE
/obj/effect/rune/apocalypse/invoke(var/list/invokers)
if(rune_in_use)
@@ -950,6 +958,9 @@ structure_check() searches for nearby cultist structures required for the invoca
var/area/place = get_area(src)
var/mob/living/user = invokers[1]
var/datum/antagonist/cult/user_antag = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(!user_antag.cult_team)
to_chat(user, "<span class='cultlarge'>You can't seem to make the arcane links to your fellows that you'd need to use this.</span>")
return
var/datum/objective/eldergod/summon_objective = locate() in user_antag.cult_team.objectives
if(summon_objective.summon_spots.len <= 1)
to_chat(user, "<span class='cultlarge'>Only one ritual site remains - it must be reserved for the final summoning!</span>")
@@ -12,12 +12,7 @@
var/obj/item/r_hand = get_item_for_held_index(2)
if(r_hand)
var/r_state = r_hand.item_state
if(!r_state)
r_state = r_hand.icon_state
var/mutable_appearance/r_hand_overlay = r_hand.build_worn_icon(state = r_state, default_layer = DEVIL_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE)
var/mutable_appearance/r_hand_overlay = r_hand.build_worn_icon(default_layer = DEVIL_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE)
hands_overlays += r_hand_overlay
@@ -28,12 +23,7 @@
client.screen |= r_hand
if(l_hand)
var/l_state = l_hand.item_state
if(!l_state)
l_state = l_hand.icon_state
var/mutable_appearance/l_hand_overlay = l_hand.build_worn_icon(state = l_state, default_layer = DEVIL_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE)
var/mutable_appearance/l_hand_overlay = l_hand.build_worn_icon(default_layer = DEVIL_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE)
hands_overlays += l_hand_overlay
@@ -414,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)
@@ -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.
+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()
+61 -2
View File
@@ -179,8 +179,8 @@
/obj/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
if(resistance_flags & INDESTRUCTIBLE)
return FALSE
for(var/mob/living/L in contents)
if(!issilicon(L) && !isbrain(L))
for(var/mob/living/L in GetAllContents())
if(!ispAI(L) && !isbrain(L))
to_chat(S, "<span class='warning'>An organism has been detected inside this object. Aborting.</span>")
return FALSE
return ..()
@@ -416,6 +416,57 @@
to_chat(S, "<span class='warning'>Destroying this object would cause a catastrophic chain reaction. Aborting.</span>")
return FALSE
/obj/machinery/ore_silo/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
to_chat(S, "<span class='warning'>Destroying this object, however tempting it's, will disrupt the research development that may serve for our masters in the future. Aborting.</span>")
return FALSE
/obj/machinery/rnd/server/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
to_chat(S, "<span class='warning'>Destroying this object, will disrupt the research development that may serve for our masters in the future. Aborting.</span>")
return FALSE
/obj/machinery/pool/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) //pool's closed, but not.
to_chat(S, "<span class='warning'>The pool must not be closed, it will provide healthy fun for our masters in the future. Aborting.</span>")
return FALSE
/obj/structure/pool/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
to_chat(S, "<span class='warning'>The pool must not be closed, it will provide healthy fun for our masters in the future. Aborting.</span>")
return FALSE
/obj/structure/holosign/barrier/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
var/static/list/lazy_typecache = typecacheof(list(/obj/structure/holosign/barrier/engineering, /obj/structure/holosign/barrier/firelock, /obj/structure/holosign/barrier/atmos, /obj/structure/holosign/barrier/combifan))
if(lazy_typecache[type])
to_chat(S, "<span class='warning'>Destroying this holographic barrier may not benefit us. Aborting.</span>")
return FALSE
return ..()
/obj/machinery/dominator/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
to_chat(S, "<span class='warning'>This advanced piece of technology may be of use for our masters in the future. Aborting.</span>")
return FALSE
/obj/machinery/computer/bsa_control/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
to_chat(S, "<span class='warning'>This advanced piece of technology may be of use for our masters in the future. Aborting.</span>")
return FALSE
/obj/machinery/bsa/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
to_chat(S, "<span class='warning'>This advanced piece of technology may be of use for our masters in the future. Aborting.</span>")
return FALSE
/obj/machinery/dna_vault/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
to_chat(S, "<span class='warning'>This advanced piece of technology may be of use for our masters in the future. Aborting.</span>")
return FALSE
/obj/structure/filler/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
to_chat(S, "<span class='warning'>This advanced piece of technology may be of use for our masters in the future. Aborting.</span>")
return FALSE
/obj/machinery/computer/sat_control/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
to_chat(S, "<span class='warning'>Destroying this object will lower the station shielding against space debris. Aborting.</span>")
return FALSE
/obj/machinery/satellite/meteor_shield/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
to_chat(S, "<span class='warning'>Destroying this object will lower the station shielding against space debris. Aborting.</span>")
return FALSE
////END CTRL CLICK FOR SWARMERS////
/mob/living/simple_animal/hostile/swarmer/proc/Fabricate(atom/fabrication_object,fabrication_cost = 0)
@@ -429,6 +480,14 @@
return new fabrication_object(loc)
/mob/living/simple_animal/hostile/swarmer/proc/Integrate(atom/movable/target)
if(isobj(target))
var/obj/O = target
if(O.resistance_flags & INDESTRUCTIBLE)
return FALSE
for(var/mob/living/L in GetAllContents())
if(!ispAI(L) && !isbrain(L))
to_chat(src, "<span class='warning'>An organism has been detected inside this object. Aborting.</span>")
return FALSE
var/resource_gain = target.IntegrateAmount()
if(resources + resource_gain > max_resources)
to_chat(src, "<span class='warning'>We cannot hold more materials!</span>")
@@ -1,10 +1,10 @@
/datum/round_event_control/spawn_swarmer
name = "Spawn Swarmer Shell"
typepath = /datum/round_event/spawn_swarmer
weight = 0
max_occurrences = 0
weight = 7
max_occurrences = 1 //Only once okay fam
earliest_start = 30 MINUTES
min_players = 15
min_players = 35
gamemode_blacklist = list("dynamic")
@@ -38,8 +38,8 @@
weights[C] = weight
var/choice = pickweightAllowZero(weights)
if(!choice)
choice = GLOB.traitor_classes[TRAITOR_HUMAN]
set_traitor_kind(pickweightAllowZero(weights))
choice = GLOB.traitor_classes[TRAITOR_HUMAN] // it's an "easter egg"
set_traitor_kind(choice)
traitor_kind.weight *= 0.8 // less likely this round
SSticker.mode.traitors += owner
owner.special_role = special_role
@@ -43,7 +43,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
else
owner_AI = owner
/datum/action/innate/ai/IsAvailable()
/datum/action/innate/ai/IsAvailable(silent = FALSE)
. = ..()
if(owner_AI && owner_AI.malf_cooldown > world.time)
return FALSE
@@ -89,7 +89,7 @@
/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), 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)
@@ -31,12 +31,12 @@
/obj/item/soulstone/pickup(mob/living/user)
..()
if(!iscultist(user) && !iswizard(user) && !usability)
if(!iscultist(user, TRUE) && !iswizard(user) && !usability)
to_chat(user, "<span class='danger'>An overwhelming feeling of dread comes over you as you pick up the soulstone. It would be wise to be rid of this quickly.</span>")
/obj/item/soulstone/examine(mob/user)
. = ..()
if(usability || iscultist(user) || iswizard(user) || isobserver(user))
if(usability || iscultist(user, TRUE) || iswizard(user) || isobserver(user))
if (old_shard)
. += "<span class='cult'>A soulstone, used to capture a soul, either from dead humans or from freed shades.</span>"
else
@@ -53,7 +53,7 @@
//////////////////////////////Capturing////////////////////////////////////////////////////////
/obj/item/soulstone/attack(mob/living/carbon/human/M, mob/living/user)
if(!iscultist(user) && !iswizard(user) && !usability)
if(!iscultist(user, TRUE) && !iswizard(user) && !usability)
user.Unconscious(100)
to_chat(user, "<span class='userdanger'>Your body is wracked with debilitating pain!</span>")
return
@@ -74,7 +74,7 @@
/obj/item/soulstone/attack_self(mob/living/user)
if(!in_range(src, user))
return
if(!iscultist(user) && !iswizard(user) && !usability)
if(!iscultist(user, TRUE) && !iswizard(user) && !usability)
user.Unconscious(100)
to_chat(user, "<span class='userdanger'>Your body is wracked with debilitating pain!</span>")
return
@@ -103,7 +103,7 @@
/obj/structure/constructshell/examine(mob/user)
. = ..()
if(iscultist(user) || iswizard(user) || user.stat == DEAD)
if(iscultist(user, TRUE) || iswizard(user) || user.stat == DEAD)
. += "<span class='cult'>A construct shell, used to house bound souls from a soulstone.</span>"
. += "<span class='cult'>Placing a soulstone with a soul into this shell allows you to produce your choice of the following:</span>"
. += "<span class='cult'>An <b>Artificer</b>, which can produce <b>more shells and soulstones</b>, as well as fortifications.</span>"
@@ -113,7 +113,7 @@
/obj/structure/constructshell/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/soulstone))
var/obj/item/soulstone/SS = O
if(!iscultist(user) && !iswizard(user) && !SS.usability)
if(!iscultist(user, TRUE) && !iswizard(user) && !SS.usability)
to_chat(user, "<span class='danger'>An overwhelming feeling of dread comes over you as you attempt to place the soulstone into the shell. It would be wise to be rid of this quickly.</span>")
user.Dizzy(30)
return
@@ -145,7 +145,7 @@
if("VICTIM")
var/mob/living/carbon/human/T = target
var/datum/antagonist/cult/C = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(C && C.cult_team.is_sacrifice_target(T.mind))
if(C && C.cult_team?.is_sacrifice_target(T.mind))
if(iscultist(user))
to_chat(user, "<span class='cult'><b>\"This soul is mine.</b></span> <span class='cultlarge'>SACRIFICE THEM!\"</span>")
else
@@ -104,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
+1 -1
View File
@@ -312,7 +312,7 @@
if(holder)
holder.update_icon()
/obj/item/assembly/flash/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
/obj/item/assembly/flash/shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
activate()
return ..()
@@ -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"
@@ -84,7 +84,6 @@
/obj/machinery/atmospherics/components/proc/nullifyPipenet(datum/pipeline/reference)
if(!reference)
CRASH("nullifyPipenet(null) called by [type] on [COORD(src)]")
return
var/i = parents.Find(reference)
reference.other_airs -= airs[i]
reference.other_atmosmch -= src
@@ -168,4 +167,4 @@
/obj/machinery/atmospherics/components/analyzer_act(mob/living/user, obj/item/I)
atmosanalyzer_scan(airs, user, src)
atmosanalyzer_scan(airs, user, src)
@@ -131,7 +131,6 @@
var/datum/pipeline/P = returnPipenet(A)
if(!P)
CRASH("null.addMember() called by [type] on [COORD(src)]")
return
P.addMember(A, src)
@@ -208,7 +207,7 @@
/datum/pipeline/proc/return_air()
. = other_airs + air
if(null in .)
stack_trace("[src] has one or more null gas mixtures, which may cause bugs. Null mixtures will not be considered in reconcile_air().")
stack_trace("[src]([REF(src)]) has one or more null gas mixtures, which may cause bugs. Null mixtures will not be considered in reconcile_air().")
return removeNullsFromList(.)
/datum/pipeline/proc/reconcile_air()
@@ -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
@@ -488,7 +488,6 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
if (isnull(A)) //If theres no supplypod bay mapped into centcom, throw an error
to_chat(holder.mob, "No /area/centcom/supplypod/loading/one (or /two or /three or /four) in the world! You can make one yourself (then refresh) for now, but yell at a mapper to fix this, today!")
CRASH("No /area/centcom/supplypod/loading/one (or /two or /three or /four) has been mapped into the centcom z-level!")
return
orderedArea = list()
if (!isemptylist(A.contents)) //Go through the area passed into the proc, and figure out the top left and bottom right corners by calculating max and min values
var/startX = A.contents[1].x //Create the four values (we do it off a.contents[1] so they have some sort of arbitrary initial value. They should be overwritten in a few moments)
+1 -1
View File
@@ -309,7 +309,7 @@
/datum/export/gear/combatgloves
cost = 80
unit_name = "combat gloves"
export_types = list(/obj/item/clothing/gloves/combat, /obj/item/clothing/gloves/rapid, /obj/item/clothing/gloves/krav_maga)
export_types = list(/obj/item/clothing/gloves/combat, /obj/item/clothing/gloves/fingerless/pugilist/rapid, /obj/item/clothing/gloves/krav_maga)
include_subtypes = TRUE
/datum/export/gear/bonegloves
+25 -1
View File
@@ -112,7 +112,7 @@
/datum/export/glasswork_lens
cost = 1800
unit_name = "small glass lens"
export_types = list(/obj/item/lens)
export_types = list(/obj/item/glasswork/glass_base/lens)
/datum/export/glasswork_spouty
cost = 1200
@@ -131,3 +131,27 @@
unit_name = "large flask"
export_types = list(/obj/item/reagent_containers/glass/beaker/flask/large)
include_subtypes = FALSE
/datum/export/glasswork_teaplate
cost = 1200
unit_name = "tea gear"
export_types = list(/obj/item/tea_plate)
include_subtypes = FALSE
/datum/export/glasswork_teacup
cost = 1800
unit_name = "tea gear"
export_types = list(/obj/item/tea_cup)
include_subtypes = FALSE
/datum/export/glasswork_laserpointer
cost = 2600
unit_name = "hand made laserpointer"
export_types = list(/obj/item/laser_pointer/blue/handmade)
include_subtypes = FALSE
/datum/export/glasswork_glasses
cost = 5000
unit_name = "hand made glasses"
export_types = list(/obj/item/glasswork/glasses)
include_subtypes = FALSE
+1 -1
View File
@@ -287,7 +287,7 @@
/datum/export/weapon/gloves
cost = 90
unit_name = "star struck gloves"
export_types = list(/obj/item/clothing/gloves/rapid)
export_types = list(/obj/item/clothing/gloves/fingerless/pugilist/rapid)
/datum/export/weapon/l6
cost = 500
+1 -1
View File
@@ -287,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
+36 -2
View File
@@ -529,7 +529,7 @@ GLOBAL_LIST_EMPTY(asset_datums)
"pill21" = 'icons/UI_Icons/Pills/pill21.png',
"pill22" = 'icons/UI_Icons/Pills/pill22.png',
)
/datum/asset/simple/IRV
assets = list(
"jquery-ui.custom-core-widgit-mouse-sortable-min.js" = 'html/IRV/jquery-ui.custom-core-widgit-mouse-sortable-min.js',
@@ -704,9 +704,43 @@ GLOBAL_LIST_EMPTY(asset_datums)
Insert(initial(D.id), I)
return ..()
/datum/asset/spritesheet/vending
name = "vending"
/datum/asset/spritesheet/vending/register()
for(var/k in GLOB.vending_products)
var/atom/item = k
if(!ispath(item, /atom))
continue
var/icon_file = initial(item.icon)
var/icon_state = initial(item.icon_state)
var/icon/I
var/icon_states_list = icon_states(icon_file)
if(icon_state in icon_states_list)
I = icon(icon_file, icon_state, SOUTH)
var/c = initial(item.color)
if(!isnull(c) && c != "#FFFFFF")
I.Blend(c, ICON_MULTIPLY)
else
var/icon_states_string
for(var/an_icon_state in icon_states_list)
if(!icon_states_string)
icon_states_string = "[json_encode(an_icon_state)](\ref[an_icon_state])"
else
icon_states_string += ", [json_encode(an_icon_state)](\ref[an_icon_state])"
stack_trace("[item] does not have a valid icon state, icon=[icon_file], icon_state=[json_encode(icon_state)](\ref[icon_state]), icon_states=[icon_states_string]")
I = icon('icons/turf/floors.dmi', "", SOUTH)
var/imgid = replacetext(replacetext("[item]", "/obj/item/", ""), "/", "-")
Insert(imgid, I)
return ..()
/datum/asset/simple/genetics
assets = list(
"dna_discovered.gif" = 'html/dna_discovered.gif',
"dna_undiscovered.gif" = 'html/dna_undiscovered.gif',
"dna_extra.gif" = 'html/dna_extra.gif'
)
)
+27 -8
View File
@@ -125,6 +125,7 @@ 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_color" = "fff",
"balls_shape" = DEF_BALLS_SHAPE,
@@ -762,7 +763,14 @@ 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>"
@@ -1610,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")
@@ -1621,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")
@@ -1922,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")
@@ -1941,8 +1949,19 @@ 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")
@@ -1951,7 +1970,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["cock_visibility"] = n_vis
if("balls_color")
var/new_ballscolor = input(user, "Testicles 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")
@@ -1978,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")
@@ -2000,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")
+11 -1
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 27
#define SAVEFILE_VERSION_MAX 28
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -151,6 +151,14 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
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
@@ -457,6 +465,7 @@ 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_cock_taur"] >> features["cock_taur"]
S["feature_cock_visibility"] >> features["cock_visibility"]
//balls features
S["feature_has_balls"] >> features["has_balls"]
@@ -673,6 +682,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
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"])
+1 -9
View File
@@ -219,14 +219,13 @@
if(isitem(target))
var/obj/item/I = target
I.item_state = initial(picked_item.item_state)
I.item_color = initial(picked_item.item_color)
var/obj/item/clothing/CL = target
var/obj/item/clothing/PCL = new picked_item
if(istype(CL) && istype(PCL))
CL.flags_cover = PCL.flags_cover
CL.flags_inv = PCL.flags_inv
CL.mutantrace_variation = PCL.mutantrace_variation
CL.alternate_worn_icon = PCL.alternate_worn_icon
CL.mob_overlay_icon = PCL.mob_overlay_icon
qdel(PCL)
target.icon = initial(picked_item.icon)
@@ -238,7 +237,6 @@
P.desc = initial(picked_item.desc)
P.icon_state = initial(picked_item.icon_state)
P.item_state = initial(picked_item.item_state)
P.item_color = initial(picked_item.item_color)
P.overlays_offsets = initial(picked_item.overlays_offsets)
P.set_new_overlays()
P.update_icon()
@@ -269,7 +267,6 @@
name = "black jumpsuit"
icon_state = "black"
item_state = "bl_suit"
item_color = "black"
desc = "It's a plain jumpsuit. It has a small dial on the wrist."
sensor_mode = SENSOR_OFF //Hey who's this guy on the Syndicate Shuttle??
random_sensor = FALSE
@@ -284,7 +281,6 @@
desc = "A tough jumpsuit woven from alloy threads. It can take on the appearance of other jumpsuits."
icon_state = "engine"
item_state = "engi_suit"
item_color = "engine"
/obj/item/clothing/under/chameleon/Initialize()
. = ..()
@@ -394,7 +390,6 @@
name = "grey cap"
desc = "It's a baseball hat in a tasteful grey colour."
icon_state = "greysoft"
item_color = "grey"
resistance_flags = NONE
armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
@@ -494,7 +489,6 @@
/obj/item/clothing/shoes/chameleon
name = "black shoes"
icon_state = "black"
item_color = "black"
desc = "A pair of black shoes."
permeability_coefficient = 0.05
resistance_flags = NONE
@@ -520,7 +514,6 @@
/obj/item/clothing/shoes/chameleon/noslip
name = "black shoes"
icon_state = "black"
item_color = "black"
desc = "A pair of black shoes."
clothing_flags = NOSLIP
@@ -639,7 +632,6 @@
desc = "A neosilk clip-on tie."
icon = 'icons/obj/clothing/neck.dmi'
icon_state = "blacktie"
item_color = "blacktie"
resistance_flags = NONE
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
+2 -195
View File
@@ -3,6 +3,7 @@
resistance_flags = FLAMMABLE
max_integrity = 200
integrity_failure = 0.4
block_priority = BLOCK_PRIORITY_CLOTHING
var/damaged_clothes = 0 //similar to machine's BROKEN stat and structure's broken var
var/flash_protect = 0 //What level of bright light protection item has. 1 = Flashers, Flashes, & Flashbangs | 2 = Welding | -1 = OH GOD WELDING BURNT OUT MY RETINAS
var/tint = 0 //Sets the item's level of visual impairment tint, normally set to the same as flash_protect
@@ -46,25 +47,12 @@
//Add a "exclude" string to do the opposite, making it only only species listed that can't wear it.
//You append this to clothing objects.
//Polychrome stuff:
var/hasprimary = FALSE //These vars allow you to choose which overlays a clothing has
var/hassecondary = FALSE
var/hastertiary = FALSE
var/primary_color = "#FFFFFF" //RGB in hexcode
var/secondary_color = "#FFFFFF"
var/tertiary_color = "#808080"
//No idea what this is but eh -tori
var/force_alternate_icon = FALSE
/obj/item/clothing/Initialize()
. = ..()
if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE))
actions_types += /datum/action/item_action/toggle_voice_box
if(ispath(pocket_storage_component_path))
LoadComponent(pocket_storage_component_path)
if(hasprimary | hassecondary | hastertiary) //Checks if polychrome is enabled
update_icon() //Applies the overlays and default colors onto the clothes on spawn.
/obj/item/clothing/MouseDrop(atom/over_object)
. = ..()
@@ -149,8 +137,6 @@
how_cool_are_your_threads += "Adding or removing items from [src] makes no noise.\n"
how_cool_are_your_threads += "</span>"
. += how_cool_are_your_threads.Join()
if(hasprimary | hassecondary | hastertiary) //Checks if polychrome is enabled
. += "<span class='notice'>Alt-click to recolor it.</span>"
/obj/item/clothing/obj_break(damage_flag)
if(!damaged_clothes)
@@ -189,178 +175,11 @@ BLIND // can't see anything
/proc/generate_female_clothing(index,t_color,icon,type)
var/icon/female_clothing_icon = icon("icon"=icon, "icon_state"=t_color)
var/icon/female_s = icon("icon"='icons/mob/uniform.dmi', "icon_state"="[(type == FEMALE_UNIFORM_FULL) ? "female_full" : "female_top"]")
var/icon/female_s = icon("icon"='icons/mob/clothing/uniform.dmi', "icon_state"="[(type == FEMALE_UNIFORM_FULL) ? "female_full" : "female_top"]")
female_clothing_icon.Blend(female_s, ICON_MULTIPLY)
female_clothing_icon = fcopy_rsc(female_clothing_icon)
GLOB.female_clothing_icons[index] = female_clothing_icon
/obj/item/clothing/under/verb/toggle()
set name = "Adjust Suit Sensors"
set category = "Object"
set src in usr
var/mob/M = usr
if (istype(M, /mob/dead/))
return
if (!can_use(M))
return
if(src.has_sensor == LOCKED_SENSORS)
to_chat(usr, "The controls are locked.")
return 0
if(src.has_sensor == BROKEN_SENSORS)
to_chat(usr, "The sensors have shorted out!")
return 0
if(src.has_sensor <= NO_SENSORS)
to_chat(usr, "This suit does not have any sensors.")
return 0
var/list/modes = list("Off", "Binary vitals", "Exact vitals", "Tracking beacon")
var/switchMode = input("Select a sensor mode:", "Suit Sensor Mode", modes[sensor_mode + 1]) in modes
if(get_dist(usr, src) > 1)
to_chat(usr, "<span class='warning'>You have moved too far away!</span>")
return
sensor_mode = modes.Find(switchMode) - 1
if (src.loc == usr)
switch(sensor_mode)
if(0)
to_chat(usr, "<span class='notice'>You disable your suit's remote sensing equipment.</span>")
if(1)
to_chat(usr, "<span class='notice'>Your suit will now only report whether you are alive or dead.</span>")
if(2)
to_chat(usr, "<span class='notice'>Your suit will now only report your exact vital lifesigns.</span>")
if(3)
to_chat(usr, "<span class='notice'>Your suit will now report your exact vital lifesigns as well as your coordinate position.</span>")
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
if(H.w_uniform == src)
H.update_suit_sensors()
/obj/item/clothing/under/CtrlClick(mob/user)
. = ..()
if (!(item_flags & IN_INVENTORY))
return
if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if(has_sensor == LOCKED_SENSORS)
to_chat(user, "The controls are locked.")
return
if(has_sensor == BROKEN_SENSORS)
to_chat(user, "The sensors have shorted out!")
return
if(has_sensor <= NO_SENSORS)
to_chat(user, "This suit does not have any sensors.")
return
sensor_mode = SENSOR_COORDS
to_chat(user, "<span class='notice'>Your suit will now report your exact vital lifesigns as well as your coordinate position.</span>")
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.w_uniform == src)
H.update_suit_sensors()
/obj/item/clothing/under/AltClick(mob/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if(attached_accessory)
remove_accessory(user)
else
rolldown()
// Polychrome stuff:
if(hasprimary | hassecondary | hastertiary)
var/choice = input(user,"polychromic thread options", "Clothing Recolor") as null|anything in list("[hasprimary ? "Primary Color" : ""]", "[hassecondary ? "Secondary Color" : ""]", "[hastertiary ? "Tertiary Color" : ""]") //generates a list depending on the enabled overlays
switch(choice) //Lets the list's options actually lead to something
if("Primary Color")
var/primary_color_input = input(usr,"","Choose Primary Color",primary_color) as color|null //color input menu, the "|null" adds a cancel button to it.
if(primary_color_input) //Checks if the color selected is NULL, rejects it if it is NULL.
primary_color = sanitize_hexcolor(primary_color_input, desired_format=6, include_crunch=1) //formats the selected color properly
update_icon() //updates the item icon
user.regenerate_icons() //updates the worn icon. Probably a bad idea, but it works.
if("Secondary Color")
var/secondary_color_input = input(usr,"","Choose Secondary Color",secondary_color) as color|null
if(secondary_color_input)
secondary_color = sanitize_hexcolor(secondary_color_input, desired_format=6, include_crunch=1)
update_icon()
user.regenerate_icons()
if("Tertiary Color")
var/tertiary_color_input = input(usr,"","Choose Tertiary Color",tertiary_color) as color|null
if(tertiary_color_input)
tertiary_color = sanitize_hexcolor(tertiary_color_input, desired_format=6, include_crunch=1)
update_icon()
user.regenerate_icons()
return TRUE
/obj/item/clothing/neck/AltClick(mob/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
// Polychrome stuff:
if(hasprimary | hassecondary | hastertiary)
var/choice = input(user,"polychromic thread options", "Clothing Recolor") as null|anything in list("[hasprimary ? "Primary Color" : ""]", "[hassecondary ? "Secondary Color" : ""]", "[hastertiary ? "Tertiary Color" : ""]") //generates a list depending on the enabled overlays
switch(choice) //Lets the list's options actually lead to something
if("Primary Color")
var/primary_color_input = input(usr,"","Choose Primary Color",primary_color) as color|null //color input menu, the "|null" adds a cancel button to it.
if(primary_color_input) //Checks if the color selected is NULL, rejects it if it is NULL.
primary_color = sanitize_hexcolor(primary_color_input, desired_format=6, include_crunch=1) //formats the selected color properly
update_icon() //updates the item icon
user.regenerate_icons() //updates the worn icon. Probably a bad idea, but it works.
if("Secondary Color")
var/secondary_color_input = input(usr,"","Choose Secondary Color",secondary_color) as color|null
if(secondary_color_input)
secondary_color = sanitize_hexcolor(secondary_color_input, desired_format=6, include_crunch=1)
update_icon()
user.regenerate_icons()
if("Tertiary Color")
var/tertiary_color_input = input(usr,"","Choose Tertiary Color",tertiary_color) as color|null
if(tertiary_color_input)
tertiary_color = sanitize_hexcolor(tertiary_color_input, desired_format=6, include_crunch=1)
update_icon()
user.regenerate_icons()
return TRUE
/obj/item/clothing/under/verb/jumpsuit_adjust()
set name = "Adjust Jumpsuit Style"
set category = null
set src in usr
rolldown()
/obj/item/clothing/under/proc/rolldown()
if(!can_use(usr))
return
if(!can_adjust)
to_chat(usr, "<span class='warning'>You cannot wear this suit any differently!</span>")
return
if(toggle_jumpsuit_adjust())
to_chat(usr, "<span class='notice'>You adjust the suit to wear it more casually.</span>")
else
to_chat(usr, "<span class='notice'>You adjust the suit back to normal.</span>")
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
H.update_inv_w_uniform()
H.update_body()
/obj/item/clothing/under/proc/toggle_jumpsuit_adjust()
adjusted = !adjusted
if(adjusted)
if(fitted != FEMALE_UNIFORM_TOP)
fitted = NO_FEMALE_UNIFORM
if(!alt_covers_chest) // for the special snowflake suits that expose the chest when adjusted
body_parts_covered &= ~CHEST
else
fitted = initial(fitted)
if(!alt_covers_chest)
body_parts_covered |= CHEST
return adjusted
/obj/item/clothing/proc/weldingvisortoggle(mob/user) //proc to toggle welding visors on helmets, masks, goggles, etc.
if(!can_use(user))
return FALSE
@@ -440,15 +259,3 @@ BLIND // can't see anything
return FALSE
return TRUE
/obj/item/clothing/update_overlays() // Polychrome stuff
. = ..()
if(hasprimary) //Checks if the overlay is enabled
var/mutable_appearance/primary_overlay = mutable_appearance(icon, "[item_color]-primary", color = primary_color) //Automagically picks overlays
. += primary_overlay //Applies the coloured overlay onto the item sprite. but NOT the mob sprite.
if(hassecondary)
var/mutable_appearance/secondary_overlay = mutable_appearance(icon, "[item_color]-secondary", color = secondary_color)
. += secondary_overlay
if(hastertiary)
var/mutable_appearance/tertiary_overlay = mutable_appearance(icon, "[item_color]-tertiary", color = tertiary_color)
. += tertiary_overlay
+4 -4
View File
@@ -132,7 +132,7 @@
name = "prescription night vision goggles"
desc = "NVGs but for those with nearsightedness."
vision_correction = 1
/obj/item/clothing/glasses/night/syndicate
name = "combat night vision goggles"
desc = "See everything, without fear."
@@ -346,11 +346,11 @@
add_atom_colour("#[user.eye_color]", FIXED_COLOUR_PRIORITY)
colored_before = TRUE
/obj/item/clothing/glasses/sunglasses/blindfold/white/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
. = list()
/obj/item/clothing/glasses/sunglasses/blindfold/white/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands && ishuman(loc) && !colored_before)
var/mob/living/carbon/human/H = loc
var/mutable_appearance/M = mutable_appearance('icons/mob/eyes.dmi', "blindfoldwhite")
var/mutable_appearance/M = mutable_appearance('icons/mob/clothing/eyes.dmi', "blindfoldwhite")
M.appearance_flags |= RESET_COLOR
M.color = "#[H.eye_color]"
. += M
@@ -1,7 +1,7 @@
/obj/item/clothing/glasses/phantomthief
name = "suspicious paper mask"
desc = "A cheap, Syndicate-branded paper face mask. They'll never see it coming."
alternate_worn_icon = 'icons/mob/mask.dmi'
mob_overlay_icon = 'icons/mob/clothing/mask.dmi'
icon = 'icons/obj/clothing/masks.dmi'
icon_state = "s-ninja"
item_state = "s-ninja"
+2 -2
View File
@@ -26,8 +26,8 @@
user.visible_message("<span class='suicide'>\the [src] are forcing [user]'s hands around [user.p_their()] neck! It looks like the gloves are possessed!</span>")
return OXYLOSS
/obj/item/clothing/gloves/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
. = list()
/obj/item/clothing/gloves/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves")
+6 -41
View File
@@ -1,3 +1,6 @@
/obj/item/clothing/gloves/color
dying_key = DYE_REGISTRY_GLOVES
/obj/item/clothing/gloves/color/yellow
desc = "These gloves will protect the wearer from electric shock."
name = "insulated gloves"
@@ -5,7 +8,6 @@
item_state = "ygloves"
siemens_coefficient = 0
permeability_coefficient = 0.05
item_color="yellow"
resistance_flags = NONE
var/can_be_cut = 1
@@ -16,7 +18,6 @@
item_state = "ygloves"
siemens_coefficient = 1 //Set to a default of 1, gets overridden in New()
permeability_coefficient = 0.05
item_color="yellow"
resistance_flags = NONE
var/can_be_cut = 1
@@ -70,21 +71,14 @@
name = "black gloves"
icon_state = "black"
item_state = "blackgloves"
item_color="black"
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
resistance_flags = NONE
var/can_be_cut = 1
var/can_be_cut = TRUE
strip_mod = 1.2
/obj/item/clothing/gloves/color/black/hos
item_color = "hosred" //Exists for washing machines. Is not different from black gloves in any way.
/obj/item/clothing/gloves/color/black/ce
item_color = "chief" //Exists for washing machines. Is not different from black gloves in any way.
/obj/item/clothing/gloves/color/black/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/wirecutters))
if(can_be_cut && icon_state == initial(icon_state))//only if not dyed
@@ -99,15 +93,12 @@
desc = "A pair of gloves, they don't look special in any way."
icon_state = "orange"
item_state = "orangegloves"
item_color="orange"
/obj/item/clothing/gloves/color/red
name = "red gloves"
desc = "A pair of gloves, they don't look special in any way."
icon_state = "red"
item_state = "redgloves"
item_color = "red"
/obj/item/clothing/gloves/color/red/insulated
name = "insulated gloves"
@@ -121,68 +112,48 @@
desc = "A pair of gloves, they don't look special in any way."
icon_state = "rainbow"
item_state = "rainbowgloves"
item_color = "rainbow"
/obj/item/clothing/gloves/color/rainbow/clown
item_color = "clown"
/obj/item/clothing/gloves/color/blue
name = "blue gloves"
desc = "A pair of gloves, they don't look special in any way."
icon_state = "blue"
item_state = "bluegloves"
item_color="blue"
/obj/item/clothing/gloves/color/purple
name = "purple gloves"
desc = "A pair of gloves, they don't look special in any way."
icon_state = "purple"
item_state = "purplegloves"
item_color="purple"
/obj/item/clothing/gloves/color/green
name = "green gloves"
desc = "A pair of gloves, they don't look special in any way."
icon_state = "green"
item_state = "greengloves"
item_color="green"
/obj/item/clothing/gloves/color/grey
name = "grey gloves"
desc = "A pair of gloves, they don't look special in any way."
icon_state = "gray"
item_state = "graygloves"
item_color="grey"
/obj/item/clothing/gloves/color/grey/rd
item_color = "director" //Exists for washing machines. Is not different from gray gloves in any way.
/obj/item/clothing/gloves/color/grey/hop
item_color = "hop" //Exists for washing machines. Is not different from gray gloves in any way.
/obj/item/clothing/gloves/color/light_brown
name = "light brown gloves"
desc = "A pair of gloves, they don't look special in any way."
icon_state = "lightbrown"
item_state = "lightbrowngloves"
item_color="light brown"
/obj/item/clothing/gloves/color/brown
name = "brown gloves"
desc = "A pair of gloves, they don't look special in any way."
icon_state = "brown"
item_state = "browngloves"
item_color="brown"
/obj/item/clothing/gloves/color/brown/cargo
item_color = "cargo" //Exists for washing machines. Is not different from brown gloves in any way.
/obj/item/clothing/gloves/color/captain
desc = "Regal blue gloves, with a nice gold trim, a diamond anti-shock coating, and an integrated thermal barrier. Swanky."
name = "captain's gloves"
icon_state = "captain"
item_state = "egloves"
item_color = "captain"
siemens_coefficient = 0
permeability_coefficient = 0.05
cold_protection = HANDS
@@ -199,7 +170,6 @@
item_state = "lgloves"
siemens_coefficient = 0.3
permeability_coefficient = 0.01
item_color="mime"
transfer_prints = TRUE
resistance_flags = NONE
var/carrytrait = TRAIT_QUICK_CARRY
@@ -207,18 +177,17 @@
/obj/item/clothing/gloves/color/latex/equipped(mob/user, slot)
..()
if(slot == SLOT_GLOVES)
ADD_TRAIT(user, carrytrait, CLOTHING_TRAIT)
ADD_TRAIT(user, carrytrait, GLOVE_TRAIT)
/obj/item/clothing/gloves/color/latex/dropped(mob/user)
..()
REMOVE_TRAIT(user, carrytrait, CLOTHING_TRAIT)
REMOVE_TRAIT(user, carrytrait, GLOVE_TRAIT)
/obj/item/clothing/gloves/color/latex/nitrile
name = "nitrile gloves"
desc = "Pricy sterile gloves that are stronger than latex. Transfers advanced paramedical knowledge to the wearer via the use of nanochips."
icon_state = "nitrile"
item_state = "nitrilegloves"
item_color = "cmo"
transfer_prints = FALSE
carrytrait = TRAIT_QUICKER_CARRY
@@ -236,7 +205,3 @@
desc = "These look pretty fancy."
icon_state = "white"
item_state = "wgloves"
item_color="white"
/obj/item/clothing/gloves/color/white/redcoat
item_color = "redcoat" //Exists for washing machines. Is not different from white gloves in any way.
+130 -51
View File
@@ -4,7 +4,6 @@
desc = "Plain black gloves without fingertips for the hard working."
icon_state = "fingerless"
item_state = "fingerless"
item_color = null //So they don't wash.
transfer_prints = TRUE
strip_delay = 40
equip_delay_other = 20
@@ -12,6 +11,135 @@
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
strip_mod = 0.9
/obj/item/clothing/gloves/fingerless/pugilist
name = "armwraps"
desc = "A series of armwraps. Makes you pretty keen to start punching people."
icon_state = "armwraps"
item_state = "armwraps"
body_parts_covered = ARMS
cold_protection = ARMS
strip_delay = 300 //you can't just yank them off
///Extra damage through the punch.
var/enhancement = 0 //it's a +0 to your punches because it isn't magical
///Main trait added by the gloves to the user on wear.
var/inherited_trait = TRAIT_NOGUNS //what are you, dishonoroable?
///Secondary trait added by the gloves to the user on wear.
var/secondary_trait = TRAIT_FEARLESS //what are you, a coward?
/obj/item/clothing/gloves/fingerless/pugilist/equipped(mob/user, slot)
. = ..()
if(slot == SLOT_GLOVES)
if(ishuman(user))
var/mob/living/carbon/human/H = user
ADD_TRAIT(H, TRAIT_PUGILIST, GLOVE_TRAIT)
ADD_TRAIT(H, inherited_trait, GLOVE_TRAIT)
ADD_TRAIT(H, secondary_trait, GLOVE_TRAIT)
H.dna.species.punchdamagehigh += enhancement
H.dna.species.punchdamagelow += enhancement
/obj/item/clothing/gloves/fingerless/pugilist/dropped(mob/user)
REMOVE_TRAIT(user, TRAIT_PUGILIST, GLOVE_TRAIT)
REMOVE_TRAIT(user, inherited_trait, GLOVE_TRAIT)
REMOVE_TRAIT(user, secondary_trait, GLOVE_TRAIT)
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.dna.species.punchdamagehigh = initial(H.dna.species.punchdamagehigh)
H.dna.species.punchdamagelow = initial(H.dna.species.punchdamagelow)
return ..()
/obj/item/clothing/gloves/fingerless/pugilist/chaplain
name = "armwraps of unyielding resolve"
desc = "A series of armwraps, soaked in holy water. Makes you pretty keen to smite evil magic users."
resistance_flags = FIRE_PROOF | ACID_PROOF
enhancement = 1 //It is not magic that makes you punch harder, but force of will. Trust me.
secondary_trait = TRAIT_ANTIMAGIC
var/chaplain_spawnable = TRUE
/obj/item/clothing/gloves/fingerless/pugilist/chaplain/Initialize()
. = ..()
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
/obj/item/clothing/gloves/fingerless/pugilist/magic
name = "armwraps of mighty fists"
desc = "A series of armwraps. Makes you pretty keen to go adventuring and punch dragons."
resistance_flags = FIRE_PROOF | ACID_PROOF //magic items are harder to damage with energy this is a dnd joke okay?
enhancement = 1 //They're +1!
/obj/item/clothing/gloves/fingerless/pugilist/hungryghost
name = "armwraps of the hungry ghost"
desc = "A series of blackened, bloodstained armwraps stitched with strange geometric symbols. Makes you pretty keen to commit horrible acts against the living through bloody carnage."
icon_state = "narsiearmwraps"
item_state = "narsiearmwraps"
resistance_flags = FIRE_PROOF | ACID_PROOF
armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 35, "rad" = 0, "fire" = 50, "acid" = 50)
enhancement = 3
secondary_trait = TRAIT_KI_VAMPIRE
/obj/item/clothing/gloves/fingerless/pugilist/brassmountain
name = "armbands of the brass mountain"
desc = "A series of scolding hot brass armbands. Makes you pretty keen to bring the light to the unenlightened through unmitigated violence."
icon_state = "ratvararmwraps"
item_state = "ratvararmwraps"
resistance_flags = FIRE_PROOF | ACID_PROOF
armor = list("melee" = 10, "bullet" = 0, "laser" = -10, "energy" = 0, "bomb" = 0, "bio" = 35, "rad" = 0, "fire" = 50, "acid" = 50)
enhancement = 4 //The artifice of Ratvar is unmatched except when it is.
secondary_trait = TRAIT_STRONG_GRABBER
/obj/item/clothing/gloves/fingerless/pugilist/rapid
name = "Bands of the North Star"
desc = "The armbands of a deadly martial artist. Makes you pretty keen to put an end to evil in an extremely violent manner."
icon_state = "rapid"
item_state = "rapid"
enhancement = 10 //omae wa mou shindeiru
var/warcry = "AT"
secondary_trait = TRAIT_NOSOFTCRIT //basically extra health
/obj/item/clothing/gloves/fingerless/pugilist/rapid/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, GLOVE_TRAIT)
/obj/item/clothing/gloves/fingerless/pugilist/rapid/Touch(atom/target, proximity = TRUE)
if(!isliving(target))
return
var/mob/living/M = loc
M.changeNext_move(CLICK_CD_RAPID)
if(warcry)
M.say("[warcry]", ignore_spam = TRUE, forced = TRUE)
return FALSE
/obj/item/clothing/gloves/fingerless/pugilist/rapid/AltClick(mob/user)
var/input = stripped_input(user,"What do you want your battlecry to be? Max length of 6 characters.", ,"", 7)
if(input)
warcry = input
/obj/item/clothing/gloves/fingerless/pugilist/rapid/hug
name = "Hugs of the North Star"
desc = "The armbands of a humble friend. Makes you pretty keen to go let everyone know how much you appreciate them!"
warcry = "owo" //Shouldn't ever come into play
enhancement = 0
secondary_trait = TRAIT_PACIFISM //You are only here to hug and be friends!
/obj/item/clothing/gloves/fingerless/pugilist/rapid/hug/Touch(mob/target, proximity = TRUE)
if(!isliving(target))
return
var/mob/living/M = loc
if(M.a_intent != INTENT_HELP)
return FALSE
if(target.stat != CONSCIOUS) //Can't hug people who are dying/dead
return FALSE
else
M.changeNext_move(CLICK_CD_RAPID)
return FALSE
/obj/item/clothing/gloves/fingerless/pugilist/rapid/hug/AltClick(mob/user)
return FALSE
/obj/item/clothing/gloves/botanic_leather
name = "botanist's leather gloves"
desc = "These leather gloves protect against thorns, barbs, prickles, spikes and other harmful objects of floral origin. They're also quite warm."
@@ -48,7 +176,6 @@
desc = "For when you're expecting to get slapped on the wrist. Offers modest protection to your arms."
icon_state = "bracers"
item_state = "bracers"
item_color = null //So they don't wash.
transfer_prints = TRUE
strip_delay = 40
equip_delay_other = 20
@@ -59,54 +186,6 @@
resistance_flags = NONE
armor = list("melee" = 15, "bullet" = 35, "laser" = 35, "energy" = 20, "bomb" = 35, "bio" = 35, "rad" = 35, "fire" = 0, "acid" = 0)
/obj/item/clothing/gloves/rapid
name = "Gloves of the North Star"
desc = "Just looking at these fills you with an urge to beat the shit out of people. Violently."
icon_state = "rapid"
item_state = "rapid"
transfer_prints = TRUE
var/warcry = "AT"
/obj/item/clothing/gloves/rapid/Touch(mob/living/target,proximity = TRUE)
if(!istype(target))
return
var/mob/living/M = loc
M.changeNext_move(CLICK_CD_RAPID)
M.adjustStaminaLoss(-3.5) // used to be -2 with some comment about stamina buffer management but *shrug -hatterhat
if(warcry)
M.say("[warcry]", ignore_spam = TRUE, forced = "north star warcry")
.= FALSE
/obj/item/clothing/gloves/rapid/attack_self(mob/user)
var/input = stripped_input(user,"What do you want your battlecry to be? Max length of 6 characters.", ,"", 7)
if(input)
warcry = input
/obj/item/clothing/gloves/rapid/hug
name = "Hugs of the North Star"
desc = "Just looking at these fills you with an urge to hug the shit out of people. In a very friendly manner."
warcry = "owo" //Shouldn't ever come into play
/obj/item/clothing/gloves/rapid/hug/Touch(mob/living/target,proximity = TRUE)
if(!istype(target))
return
var/mob/living/M = loc
if(M.a_intent == INTENT_HELP)
if(target.health >= 0 && !HAS_TRAIT(target, TRAIT_FAKEDEATH)) //Can't hug people who are dying/dead
if(target.on_fire || target.lying) //No spamming extinguishing, helping them up, or other non-hugging/patting help interactions
return
else
M.changeNext_move(CLICK_CD_RAPID)
. = FALSE
/obj/item/clothing/gloves/rapid/hug/attack_self(mob/user)
return FALSE
/obj/item/clothing/gloves/thief
name = "black gloves"
desc = "Gloves made with completely frictionless, insulated cloth, easier to steal from people with."
@@ -117,4 +196,4 @@
strip_delay = 80
transfer_prints = FALSE
strip_mod = 5
strip_silence = TRUE
strip_silence = TRUE
+2 -2
View File
@@ -48,8 +48,8 @@
/obj/item/clothing/head/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
. = list()
/obj/item/clothing/head/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet")
-7
View File
@@ -5,7 +5,6 @@
name = "white beanie"
desc = "A stylish beanie. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their heads."
icon_state = "beanie" //Default white
item_color = "beanie"
/obj/item/clothing/head/beanie/black
name = "black beanie"
@@ -52,33 +51,27 @@
/obj/item/clothing/head/beanie/christmas
name = "christmas beanie"
icon_state = "beaniechristmas"
item_color = "beaniechristmas"
/obj/item/clothing/head/beanie/striped
name = "striped beanie"
icon_state = "beaniestriped"
item_color = "beaniestriped"
/obj/item/clothing/head/beanie/stripedred
name = "red striped beanie"
icon_state = "beaniestripedred"
item_color = "beaniestripedred"
/obj/item/clothing/head/beanie/stripedblue
name = "blue striped beanie"
icon_state = "beaniestripedblue"
item_color = "beaniestripedblue"
/obj/item/clothing/head/beanie/stripedgreen
name = "green striped beanie"
icon_state = "beaniestripedgreen"
item_color = "beaniestripedgreen"
/obj/item/clothing/head/beanie/durathread
name = "durathread beanie"
desc = "A beanie made from durathread, its resilient fibres provide some protection to the wearer."
icon_state = "beaniedurathread"
item_color = null
armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50)
+14 -14
View File
@@ -7,7 +7,7 @@
light_color = "#FFCC66"
var/power_on = 0.8
var/on = FALSE
item_color = "yellow" //Determines used sprites: hardhat[on]_[item_color] and hardhat[on]_[item_color]2 (lying down sprite)
var/hat_type = "yellow" //Determines used sprites: hardhat[on]_[hat_type] and hardhat[on]_[hat_type]2 (lying down sprite)
armor = list("melee" = 15, "bullet" = 5, "laser" = 20,"energy" = 10, "bomb" = 20, "bio" = 10, "rad" = 20, "fire" = 100, "acid" = 50)
flags_inv = 0
actions_types = list(/datum/action/item_action/toggle_helmet_light)
@@ -33,8 +33,8 @@
update_icon()
/obj/item/clothing/head/hardhat/update_icon_state()
icon_state = "hardhat[on]_[item_color]"
item_state = "hardhat[on]_[item_color]"
icon_state = "hardhat[on]_[hat_type]"
item_state = "hardhat[on]_[hat_type]"
/obj/item/clothing/head/hardhat/proc/turn_on(mob/user)
set_light(brightness_on, power_on)
@@ -45,13 +45,13 @@
/obj/item/clothing/head/hardhat/orange
icon_state = "hardhat0_orange"
item_state = "hardhat0_orange"
item_color = "orange"
hat_type = "orange"
dog_fashion = null
/obj/item/clothing/head/hardhat/red
icon_state = "hardhat0_red"
item_state = "hardhat0_red"
item_color = "red"
hat_type = "red"
dog_fashion = null
name = "firefighter helmet"
clothing_flags = STOPSPRESSUREDAMAGE
@@ -63,7 +63,7 @@
/obj/item/clothing/head/hardhat/white
icon_state = "hardhat0_white"
item_state = "hardhat0_white"
item_color = "white"
hat_type = "white"
clothing_flags = STOPSPRESSUREDAMAGE
heat_protection = HEAD
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
@@ -74,13 +74,13 @@
/obj/item/clothing/head/hardhat/dblue
icon_state = "hardhat0_dblue"
item_state = "hardhat0_dblue"
item_color = "dblue"
hat_type = "dblue"
dog_fashion = null
/obj/item/clothing/head/hardhat/atmos
icon_state = "hardhat0_atmos"
item_state = "hardhat0_atmos"
item_color = "atmos"
hat_type = "atmos"
dog_fashion = null
name = "atmospheric technician's firefighting helmet"
desc = "A firefighter's helmet, able to keep the user cool in any situation."
@@ -124,12 +124,12 @@
playsound(src, 'sound/mecha/mechmove03.ogg', 50, TRUE) //Visors don't just come from nothing
update_icon()
/obj/item/clothing/head/hardhat/weldhat/worn_overlays(isinhands, icon_file, style_flags = NONE)
/obj/item/clothing/head/hardhat/weldhat/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
. += mutable_appearance('icons/mob/head.dmi', "weldhelmet")
. += mutable_appearance('icons/mob/clothing/head.dmi', "weldhelmet")
if(!up)
. += mutable_appearance('icons/mob/head.dmi', "weldvisor")
. += mutable_appearance('icons/mob/clothing/head.dmi', "weldvisor")
/obj/item/clothing/head/hardhat/weldhat/update_overlays()
. = ..()
@@ -139,14 +139,14 @@
/obj/item/clothing/head/hardhat/weldhat/orange
icon_state = "hardhat0_orange"
item_state = "hardhat0_orange"
item_color = "orange"
hat_type = "orange"
/obj/item/clothing/head/hardhat/weldhat/white
desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight AND welding shield!" //This bulb is not smaller
icon_state = "hardhat0_white"
item_state = "hardhat0_white"
brightness_on = 4 //Boss always takes the best stuff
item_color = "white"
hat_type = "white"
clothing_flags = STOPSPRESSUREDAMAGE
heat_protection = HEAD
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
@@ -156,4 +156,4 @@
/obj/item/clothing/head/hardhat/weldhat/dblue
icon_state = "hardhat0_dblue"
item_state = "hardhat0_dblue"
item_color = "dblue"
hat_type = "dblue"
-1
View File
@@ -364,7 +364,6 @@
name = "durathread beret"
desc = "A beret made from durathread, its resilient fibres provide some protection to the wearer."
icon_state = "beretdurathread"
item_color = null
armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50)
#undef DRILL_DEFAULT
-2
View File
@@ -372,14 +372,12 @@
name = "Telegram cap"
desc = "A bright red cap warn by hotel staff. Or people who want to be a singing telegram"
icon_state = "telegram"
item_color = "telegram"
dog_fashion = /datum/dog_fashion/head/telegram
/obj/item/clothing/head/colour
name = "Singer cap"
desc = "A light white hat that has bands of color. Just makes you want to sing and dance!"
icon_state = "colour"
item_color = "colour"
dog_fashion = /datum/dog_fashion/head/colour
/obj/item/clothing/head/christmashat
+10 -17
View File
@@ -42,7 +42,6 @@
desc = "You put the cake on your head. Brilliant."
icon_state = "hardhat0_cakehat"
item_state = "hardhat0_cakehat"
item_color = "cakehat"
hitsound = 'sound/weapons/tap.ogg'
flags_inv = HIDEEARS|HIDEHAIR
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
@@ -114,7 +113,6 @@
desc = "A jack o' lantern! Believed to ward off evil spirits."
icon_state = "hardhat0_pumpkin"
item_state = "hardhat0_pumpkin"
item_color = "pumpkin"
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
brightness_on = 2 //luminosity when on
@@ -151,7 +149,6 @@
desc = "Some fake antlers and a very fake red nose."
icon_state = "hardhat0_reindeer"
item_state = "hardhat0_reindeer"
item_color = "reindeer"
flags_inv = 0
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
brightness_on = 1 //luminosity when on
@@ -187,14 +184,15 @@
/obj/item/clothing/head/wig
name = "wig"
desc = "A bunch of hair without a head attached."
icon_state = ""
item_state = "pwig"
icon = 'icons/mob/human_face.dmi' // default icon for all hairs
icon_state = "hair_vlong"
flags_inv = HIDEHAIR
color = "#000"
var/hair_style = "Very Long Hair"
var/hair_color = "#000"
/obj/item/clothing/head/wig/Initialize(mapload)
. = ..()
icon_state = "" //Shitty hack that i dont know if it is even neccesary to deal with the vendor stack exception
update_icon()
/obj/item/clothing/head/wig/update_icon_state()
@@ -202,29 +200,24 @@
if(!S)
icon = 'icons/obj/clothing/hats.dmi'
icon_state = "pwig"
else
icon = S.icon
icon_state = S.icon_state
/obj/item/clothing/head/wig/update_overlays()
/obj/item/clothing/head/wig/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
var/datum/sprite_accessory/S = GLOB.hair_styles_list[hair_style]
if(S)
var/mutable_appearance/M = mutable_appearance(S.icon, S.icon_state, color = hair_color)
M.appearance_flags |= RESET_COLOR
. += M
/obj/item/clothing/head/wig/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
. = list()
if(!isinhands)
var/datum/sprite_accessory/S = GLOB.hair_styles_list[hair_style]
if(!S)
return
var/mutable_appearance/M = mutable_appearance(S.icon, S.icon_state,layer = -HAIR_LAYER)
M.appearance_flags |= RESET_COLOR
M.color = hair_color
M.color = color
. += M
/obj/item/clothing/head/wig/random/Initialize(mapload)
hair_style = pick(GLOB.hair_styles_list - "Bald") //Don't want invisible wig
hair_color = "#[random_short_color()]"
color = "#[random_short_color()]"
. = ..()
/obj/item/clothing/head/bronze
+17 -17
View File
@@ -3,14 +3,14 @@
desc = "It's a baseball hat in a tasteless yellow colour."
icon_state = "cargosoft"
item_state = "helmet"
item_color = "cargo"
var/soft_type = "cargo"
dog_fashion = /datum/dog_fashion/head/cargo_tech
var/flipped = 0
/obj/item/clothing/head/soft/dropped(mob/user)
icon_state = "[item_color]soft"
icon_state = "[soft_type]soft"
flipped = FALSE
return ..()
@@ -33,10 +33,10 @@
if(!user.incapacitated())
src.flipped = !src.flipped
if(src.flipped)
icon_state = "[item_color]soft_flipped"
icon_state = "[soft_type]soft_flipped"
to_chat(user, "<span class='notice'>You flip the hat backwards.</span>")
else
icon_state = "[item_color]soft"
icon_state = "[soft_type]soft"
to_chat(user, "<span class='notice'>You flip the hat back in normal position.</span>")
usr.update_inv_head() //so our mob-overlays update
@@ -48,77 +48,77 @@
name = "red cap"
desc = "It's a baseball hat in a tasteless red colour."
icon_state = "redsoft"
item_color = "red"
soft_type = "red"
dog_fashion = null
/obj/item/clothing/head/soft/blue
name = "blue cap"
desc = "It's a baseball hat in a tasteless blue colour."
icon_state = "bluesoft"
item_color = "blue"
soft_type = "blue"
dog_fashion = null
/obj/item/clothing/head/soft/green
name = "green cap"
desc = "It's a baseball hat in a tasteless green colour."
icon_state = "greensoft"
item_color = "green"
soft_type = "green"
dog_fashion = null
/obj/item/clothing/head/soft/yellow
name = "yellow cap"
desc = "It's a baseball hat in a tasteless yellow colour."
icon_state = "yellowsoft"
item_color = "yellow"
soft_type = "yellow"
dog_fashion = null
/obj/item/clothing/head/soft/grey
name = "grey cap"
desc = "It's a baseball hat in a tasteful grey colour."
icon_state = "greysoft"
item_color = "grey"
soft_type = "grey"
dog_fashion = null
/obj/item/clothing/head/soft/orange
name = "orange cap"
desc = "It's a baseball hat in a tasteless orange colour."
icon_state = "orangesoft"
item_color = "orange"
soft_type = "orange"
dog_fashion = null
/obj/item/clothing/head/soft/mime
name = "white cap"
desc = "It's a baseball hat in a tasteless white colour."
icon_state = "mimesoft"
item_color = "mime"
soft_type = "mime"
dog_fashion = null
/obj/item/clothing/head/soft/purple
name = "purple cap"
desc = "It's a baseball hat in a tasteless purple colour."
icon_state = "purplesoft"
item_color = "purple"
soft_type = "purple"
dog_fashion = null
/obj/item/clothing/head/soft/black
name = "black cap"
desc = "It's a baseball hat in a tasteless black colour."
icon_state = "blacksoft"
item_color = "black"
soft_type = "black"
dog_fashion = null
/obj/item/clothing/head/soft/rainbow
name = "rainbow cap"
desc = "It's a baseball hat in a bright rainbow of colors."
icon_state = "rainbowsoft"
item_color = "rainbow"
soft_type = "rainbow"
dog_fashion = null
/obj/item/clothing/head/soft/sec
name = "security cap"
desc = "It's a robust baseball hat in tasteful red colour."
icon_state = "secsoft"
item_color = "sec"
soft_type = "sec"
armor = list("melee" = 30, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 50)
strip_delay = 60
dog_fashion = null
@@ -127,14 +127,14 @@
name = "EMT cap"
desc = "It's a baseball hat with a dark turquoise color and a reflective cross on the top."
icon_state = "emtsoft"
item_color = "emt"
soft_type = "emt"
dog_fashion = null
/obj/item/clothing/head/soft/baseball
name = "baseball cap"
desc = "It's a robust baseball hat, this one belongs to syndicate major league team."
icon_state = "baseballsoft"
item_color = "baseballsoft"
soft_type = "baseballsoft"
item_state = "baseballsoft"
flags_inv = HIDEEYES|HIDEFACE
armor = list("melee" = 35, "bullet" = 35, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 90)
+2 -2
View File
@@ -28,8 +28,8 @@
/obj/item/clothing/mask/proc/handle_speech()
/obj/item/clothing/mask/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
. = list()
/obj/item/clothing/mask/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
if(body_parts_covered & HEAD)
if(damaged_clothes)
+1
View File
@@ -68,6 +68,7 @@
clothing_flags = ALLOWINTERNALS
icon_state = "clown"
item_state = "clown_hat"
dye_color = "clown"
flags_cover = MASKCOVERSEYES
resistance_flags = FLAMMABLE
actions_types = list(/datum/action/item_action/adjust)
+42 -1
View File
@@ -132,7 +132,6 @@
/obj/item/clothing/mask/cowmask
name = "Cow mask with a builtin voice modulator."
desc = "A rubber cow mask,"
icon = 'icons/mob/mask.dmi'
icon_state = "cowmask"
item_state = "cowmask"
clothing_flags = VOICEBOX_TOGGLABLE
@@ -343,3 +342,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
+24 -65
View File
@@ -6,8 +6,8 @@
strip_delay = 40
equip_delay_other = 40
/obj/item/clothing/neck/worn_overlays(isinhands = FALSE, icon_flag, style_flags = NONE)
. = list()
/obj/item/clothing/neck/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
if(body_parts_covered & HEAD)
if(damaged_clothes)
@@ -21,35 +21,29 @@
icon = 'icons/obj/clothing/neck.dmi'
icon_state = "bluetie"
item_state = "" //no inhands
item_color = "bluetie"
w_class = WEIGHT_CLASS_SMALL
/obj/item/clothing/neck/tie/blue
name = "blue tie"
icon_state = "bluetie"
item_color = "bluetie"
/obj/item/clothing/neck/tie/red
name = "red tie"
icon_state = "redtie"
item_color = "redtie"
/obj/item/clothing/neck/tie/black
name = "black tie"
icon_state = "blacktie"
item_color = "blacktie"
/obj/item/clothing/neck/tie/horrible
name = "horrible tie"
desc = "A neosilk clip-on tie. This one is disgusting."
icon_state = "horribletie"
item_color = "horribletie"
/obj/item/clothing/neck/stethoscope
name = "stethoscope"
desc = "An outdated medical apparatus for listening to the sounds of the human body. It also makes you look like you know what you're doing."
icon_state = "stethoscope"
item_color = "stethoscope"
/obj/item/clothing/neck/stethoscope/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] puts \the [src] to [user.p_their()] chest! It looks like [user.p_they()] wont hear much!</span>")
@@ -94,7 +88,6 @@
name = "white scarf"
icon_state = "scarf"
desc = "A stylish scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks."
item_color = "scarf"
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/neck/scarf/black
@@ -148,12 +141,10 @@
/obj/item/clothing/neck/scarf/zebra
name = "zebra scarf"
icon_state = "zebrascarf"
item_color = "zebrascarf"
/obj/item/clothing/neck/scarf/christmas
name = "christmas scarf"
icon_state = "christmasscarf"
item_color = "christmasscarf"
//The three following scarves don't have the scarf subtype
//This is because Ian can equip anything from that subtype
@@ -161,17 +152,14 @@
/obj/item/clothing/neck/stripedredscarf
name = "striped red scarf"
icon_state = "stripedredscarf"
item_color = "stripedredscarf"
/obj/item/clothing/neck/stripedgreenscarf
name = "striped green scarf"
icon_state = "stripedgreenscarf"
item_color = "stripedgreenscarf"
/obj/item/clothing/neck/stripedbluescarf
name = "striped blue scarf"
icon_state = "stripedbluescarf"
item_color = "stripedbluescarf"
///////////
//COLLARS//
@@ -181,57 +169,44 @@
name = "pet collar"
desc = "It's for pets. Though you probably could wear it yourself, you'd doubtless be the subject of ridicule. It seems to be made out of a polychromic material."
icon_state = "petcollar"
item_color = "petcollar"
alternate_worn_icon = 'icons/mob/neck.dmi' //Because, as it appears, the item itself is normally not directly aware of its worn overlays, so this is about the easiest way, without adding a new var.
hasprimary = TRUE
primary_color = "#00BBBB"
pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/collar
var/poly_states = 1
var/poly_colors = list("#00BBBB")
var/tagname = null
var/treat_path = /obj/item/reagent_containers/food/snacks/cookie
/obj/item/clothing/neck/petcollar/Initialize()
. = ..()
if(treat_path)
new treat_path(src)
/obj/item/clothing/neck/petcollar/ComponentInitialize()
. = ..()
if(!poly_states)
return
AddElement(/datum/element/polychromic, poly_colors, poly_states)
/obj/item/clothing/neck/petcollar/attack_self(mob/user)
tagname = stripped_input(user, "Would you like to change the name on the tag?", "Name your new pet", "Spot", MAX_NAME_LEN)
name = "[initial(name)] - [tagname]"
/obj/item/clothing/neck/petcollar/worn_overlays(isinhands, icon_file, style_flags = NONE)
. = ..()
if(hasprimary | hassecondary | hastertiary)
if(!isinhands) //prevents the worn sprites from showing up if you're just holding them
if(hasprimary) //checks if overlays are enabled
var/mutable_appearance/primary_worn = mutable_appearance(alternate_worn_icon, "[item_color]-primary") //automagical sprite selection
primary_worn.color = primary_color //colors the overlay
. += primary_worn //adds the overlay onto the buffer list to draw on the mob sprite
if(hassecondary)
var/mutable_appearance/secondary_worn = mutable_appearance(alternate_worn_icon, "[item_color]-secondary")
secondary_worn.color = secondary_color
. += secondary_worn
if(hastertiary)
var/mutable_appearance/tertiary_worn = mutable_appearance(alternate_worn_icon, "[item_color]-tertiary")
tertiary_worn.color = tertiary_color
. += tertiary_worn
/obj/item/clothing/neck/petcollar/leather
name = "leather pet collar"
icon_state = "leathercollar"
item_color = "leathercollar"
hasprimary = TRUE
hassecondary = TRUE
primary_color = "#222222"
secondary_color = "#888888"
poly_states = 2
poly_colors = list("#222222", "#888888")
/obj/item/clothing/neck/petcollar/choker
desc = "Quite fashionable... if you're somebody who's just read their first BDSM-themed erotica novel."
name = "choker"
icon_state = "choker"
item_color = "choker"
hasprimary = TRUE
primary_color = "#222222"
poly_colors = list("#222222")
/obj/item/clothing/neck/petcollar/locked
name = "locked collar"
desc = "A collar that has a small lock on it to keep it from being removed."
pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/collar/locked
treat_path = /obj/item/key/collar
var/lock = FALSE
/obj/item/clothing/neck/petcollar/locked/attackby(obj/item/K, mob/user, params)
@@ -253,34 +228,19 @@
/obj/item/clothing/neck/petcollar/locked/leather
name = "leather pet collar"
icon_state = "leathercollar"
item_color = "leathercollar"
hasprimary = TRUE
hassecondary = TRUE
primary_color = "#222222"
secondary_color = "#888888"
poly_states = 2
poly_colors = list("#222222", "#888888")
/obj/item/clothing/neck/petcollar/locked/choker
name = "choker"
desc = "Quite fashionable... if you're somebody who's just read their first BDSM-themed erotica novel."
icon_state = "choker"
item_color = "choker"
hasprimary = TRUE
primary_color = "#222222"
poly_colors = list("#222222")
/obj/item/key/collar
name = "Collar Key"
desc = "A key for a tiny lock on a collar or bag."
/obj/item/clothing/neck/petcollar/Initialize()
. = ..()
new /obj/item/reagent_containers/food/snacks/cookie(src)
/obj/item/clothing/neck/petcollar/locked/Initialize()
. = ..()
new /obj/item/key/collar(src)
//////////////
//DOPE BLING//
//////////////
@@ -290,7 +250,6 @@
desc = "Damn, it feels good to be a gangster."
icon = 'icons/obj/clothing/neck.dmi'
icon_state = "bling"
item_color = "bling"
//////////////////////////////////
//VERY SUPER BADASS NECKERCHIEFS//
@@ -304,7 +263,7 @@ obj/item/clothing/neck/neckerchief
/obj/item/clothing/neck/neckerchief/worn_overlays(isinhands)
. = ..()
if(!isinhands)
var/mutable_appearance/realOverlay = mutable_appearance('icons/mob/mask.dmi', icon_state)
var/mutable_appearance/realOverlay = mutable_appearance('icons/mob/clothing/mask.dmi', icon_state)
realOverlay.pixel_y = -3
. += realOverlay
+3 -3
View File
@@ -49,8 +49,8 @@
last_bloodtype = blood_dna[blood_dna[blood_dna.len]]//trust me this works
last_blood_DNA = blood_dna[blood_dna.len]
/obj/item/clothing/shoes/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
. = list()
/obj/item/clothing/shoes/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
var/bloody = FALSE
if(blood_DNA)
@@ -61,7 +61,7 @@
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedshoe")
if(bloody)
var/file2use = style_flags & STYLE_DIGITIGRADE ? 'icons/mob/feet_digi.dmi' : 'icons/effects/blood.dmi'
var/file2use = style_flags & STYLE_DIGITIGRADE ? 'icons/mob/clothing/feet_digi.dmi' : 'icons/effects/blood.dmi'
. += mutable_appearance(file2use, "shoeblood", color = blood_DNA_to_color())
/obj/item/clothing/shoes/equipped(mob/user, slot)
+2 -34
View File
@@ -1,9 +1,9 @@
/obj/item/clothing/shoes/sneakers
dying_key = DYE_REGISTRY_SNEAKERS
/obj/item/clothing/shoes/sneakers/black
name = "black shoes"
icon_state = "black"
item_color = "black"
desc = "A pair of black shoes."
cold_protection = FEET
@@ -11,80 +11,49 @@
heat_protection = FEET
max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT
/obj/item/clothing/shoes/sneakers/black/redcoat
item_color = "redcoat" //Exists for washing machines. Is not different from black shoes in any way.
/obj/item/clothing/shoes/sneakers/brown
name = "brown shoes"
desc = "A pair of brown shoes."
icon_state = "brown"
item_color = "brown"
/obj/item/clothing/shoes/sneakers/brown/captain
item_color = "captain" //Exists for washing machines. Is not different from brown shoes in any way.
/obj/item/clothing/shoes/sneakers/brown/hop
item_color = "hop" //Exists for washing machines. Is not different from brown shoes in any way.
/obj/item/clothing/shoes/sneakers/brown/ce
item_color = "chief" //Exists for washing machines. Is not different from brown shoes in any way.
/obj/item/clothing/shoes/sneakers/brown/rd
item_color = "director" //Exists for washing machines. Is not different from brown shoes in any way.
/obj/item/clothing/shoes/sneakers/brown/cmo
item_color = "medical" //Exists for washing machines. Is not different from brown shoes in any way.
/obj/item/clothing/shoes/sneakers/brown/qm
item_color = "cargo" //Exists for washing machines. Is not different from brown shoes in any way.
/obj/item/clothing/shoes/sneakers/blue
name = "blue shoes"
icon_state = "blue"
item_color = "blue"
/obj/item/clothing/shoes/sneakers/green
name = "green shoes"
icon_state = "green"
item_color = "green"
/obj/item/clothing/shoes/sneakers/yellow
name = "yellow shoes"
icon_state = "yellow"
item_color = "yellow"
/obj/item/clothing/shoes/sneakers/purple
name = "purple shoes"
icon_state = "purple"
item_color = "purple"
/obj/item/clothing/shoes/sneakers/brown
name = "brown shoes"
icon_state = "brown"
item_color = "brown"
/obj/item/clothing/shoes/sneakers/red
name = "red shoes"
desc = "Stylish red shoes."
icon_state = "red"
item_color = "red"
/obj/item/clothing/shoes/sneakers/white
name = "white shoes"
icon_state = "white"
permeability_coefficient = 0.01
item_color = "white"
/obj/item/clothing/shoes/sneakers/rainbow
name = "rainbow shoes"
desc = "Very gay shoes."
icon_state = "rain_bow"
item_color = "rainbow"
/obj/item/clothing/shoes/sneakers/orange
name = "orange shoes"
icon_state = "orange"
item_color = "orange"
/obj/item/clothing/shoes/sneakers/orange/attack_self(mob/user)
if (src.chained)
@@ -120,5 +89,4 @@
to_chat(c, "<span class='warning'>You need help taking these off!</span>")
return
return ..()
+96 -4
View File
@@ -4,7 +4,6 @@
/obj/item/clothing/shoes/sneakers/mime
name = "mime shoes"
icon_state = "mime"
item_color = "mime"
/obj/item/clothing/shoes/combat //basic syndicate combat boots for nuke ops and mob corpses
name = "combat boots"
@@ -124,7 +123,6 @@
icon_state = "jackboots"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
item_color = "hosred"
strip_delay = 50
equip_delay_other = 50
resistance_flags = NONE
@@ -181,7 +179,6 @@
name = "\improper Nar'Sien invoker boots"
desc = "A pair of boots worn by the followers of Nar'Sie."
icon_state = "cult"
item_color = "cult"
cold_protection = FEET
min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT
heat_protection = FEET
@@ -227,7 +224,6 @@
name = "jump boots"
desc = "A specialized pair of combat boots with a built-in propulsion system for rapid foward movement."
icon_state = "jetboots"
item_color = "hosred"
resistance_flags = FIRE_PROOF
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
actions_types = list(/datum/action/item_action/bhop)
@@ -381,3 +377,99 @@
name = "black cowboy boots"
desc = "A pair of black cowboy boots, pretty easy to scuff up."
icon_state = "cowboyboots_black"
/obj/item/clothing/shoes/wallwalkers
name = "wall walking boots"
desc = "Contrary to popular belief, these do not allow you to walk on walls. Through bluespace magic stolen from an organisation that hoards technology, they simply allow you to slip through the atoms that make up anything, but only while walking, for safety reasons. As well as this, they unfortunately cause minor breath loss as the majority of atoms in your lungs are sucked out into any solid object you walk through. Make sure not to overuse them."
icon_state = "walkboots"
var/walkcool = 0
var/wallcharges = 4
var/newlocobject = null
/obj/item/clothing/shoes/wallwalkers/equipped(mob/user,slot)
. = ..()
if(slot == SLOT_SHOES)
RegisterSignal(user, COMSIG_MOB_CLIENT_MOVE,.proc/intercept_user_move)
/obj/item/clothing/shoes/wallwalkers/dropped(mob/user)
. = ..()
UnregisterSignal(user, COMSIG_MOB_CLIENT_MOVE)
/obj/item/clothing/shoes/wallwalkers/attackby(obj/item/W, mob/user, params)
. = ..()
if(!istype(W, /obj/item/bluespacerecharge))
return
var/obj/item/bluespacerecharge/ER = W
if(ER.uses)
wallcharges += ER.uses
to_chat(user, "<span class='notice'>You charged the bluespace crystal in the [src]. It now has [wallcharges] charges left.</span>")
ER.uses = 0
ER.icon_state = "[initial(ER.icon_state)]0"
else
to_chat(user, "<span class='warning'>[ER] has no crystal on it.</span>")
/obj/item/clothing/shoes/wallwalkers/examine(mob/user)
. = ..()
. += "<span class='warning'>It has [wallcharges] charges left.</span>"
/obj/item/clothing/shoes/wallwalkers/proc/intercept_user_move(mob/living/m, client/client, dir, newloc, oldloc)
if (walkcool >= world.time || m.m_intent != MOVE_INTENT_WALK || wallcharges <= 0)
return
walkcool = world.time + m.movement_delay()
var/issolid = FALSE
var/turf/K = newloc
if (istype(K))
if (K.density)
issolid = TRUE
if (!issolid)
for (var/atom/T in newloc) //stuff on the new turf
if (!T.CanPass(m,newloc) && T != m)
issolid = TRUE
newlocobject = T
break
if (!issolid)
for (var/atom/T in oldloc) //directional shit on the old turf
if (!T.CanPass(m,newloc) && T != m && T != newlocobject)
issolid = TRUE
break
newlocobject = null //stopping structures from using two charges because of how shitty the canpass code is
m.forceMove(newloc)
if (!issolid)
return
m.adjustOxyLoss(rand(5,13))
if (prob(15))
m.adjustBruteLoss(rand(4,7))
to_chat(m,"<span class='warning'>You feel as if travelling through the solid object left something behind and it hurts!</span>")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(5, 1, oldloc)
s.start()
flash_lighting_fx(3, 3, LIGHT_COLOR_ORANGE)
wallcharges--
/obj/item/bluespacerecharge
name = "bluespace crystal recharging device"
desc = "A small cell with two prongs lazily jabbed into it. It looks like it's made for replacing the crystals in bluespace devices."
icon = 'icons/obj/module.dmi'
icon_state = "bluespace_charge"
item_flags = NOBLUDGEON
w_class = WEIGHT_CLASS_TINY
var/uses = 6
/obj/item/bluespacerecharge/examine(mob/user)
. = ..()
if(uses)
. += "<span class='notice'>It can add up to [uses] charges to compatible devices.</span>"
else
. += "<span class='warning'>The crystal is gone.</span>"
/obj/item/bluespacerecharge/attackby(obj/item/I, mob/user, params)
..()
if(!istype(I, /obj/item/stack/ore/bluespace_crystal) || uses)
return
var/obj/item/stack/ore/bluespace_crystal/B = I
if (B.amount < 10)
return
uses += 3
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
B.use(10)
icon_state = initial(icon_state)
@@ -321,7 +321,7 @@
check_flags = AB_CHECK_CONSCIOUS //|AB_CHECK_INSIDE
var/obj/item/clothing/suit/space/chronos/chronosuit = null
/datum/action/innate/chrono_teleport/IsAvailable()
/datum/action/innate/chrono_teleport/IsAvailable(silent = FALSE)
return (chronosuit && chronosuit.activated && chronosuit.camera && !chronosuit.teleporting)
/datum/action/innate/chrono_teleport/Activate()
+54 -44
View File
@@ -10,7 +10,7 @@
var/brightness_on = 4 //luminosity when on
var/on = FALSE
var/obj/item/clothing/suit/space/hardsuit/suit
item_color = "engineering" //Determines used sprites: hardsuit[on]-[color] and hardsuit[on]-[color]2 (lying down sprite)
var/hardsuit_type = "engineering" //Determines used sprites: hardsuit[on]-[type]
actions_types = list(/datum/action/item_action/toggle_helmet_light)
var/rad_count = 0
@@ -30,16 +30,14 @@
/obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user)
on = !on
icon_state = "[basestate][on]-[item_color]"
user.update_inv_head() //so our mob-overlays update
if(on)
set_light(brightness_on)
else
set_light(0)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/clothing/head/helmet/space/hardsuit/update_icon_state()
icon_state = "[basestate][on]-[hardsuit_type]"
/obj/item/clothing/head/helmet/space/hardsuit/dropped(mob/user)
..()
@@ -103,6 +101,7 @@
actions_types = list(/datum/action/item_action/toggle_helmet)
var/helmettype = /obj/item/clothing/head/helmet/space/hardsuit
var/obj/item/tank/jetpack/suit/jetpack = null
var/hardsuit_type
/obj/item/clothing/suit/space/hardsuit/Initialize()
@@ -169,7 +168,7 @@
icon_state = "hardsuit0-engineering"
item_state = "eng_helm"
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 100, "acid" = 75)
item_color = "engineering"
hardsuit_type = "engineering"
resistance_flags = FIRE_PROOF
/obj/item/clothing/suit/space/hardsuit/engine
@@ -188,7 +187,7 @@
desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has thermal shielding."
icon_state = "hardsuit0-atmospherics"
item_state = "atmo_helm"
item_color = "atmospherics"
hardsuit_type = "atmospherics"
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 25, "fire" = 100, "acid" = 75)
heat_protection = HEAD //Uncomment to enable firesuit protection
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
@@ -209,7 +208,7 @@
desc = "An advanced helmet designed for work in a hazardous, low pressure environment. Shines with a high polish."
icon_state = "hardsuit0-white"
item_state = "ce_helm"
item_color = "white"
hardsuit_type = "white"
armor = list("melee" = 40, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 90)
heat_protection = HEAD
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
@@ -231,7 +230,7 @@
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has reinforced plating for wildlife encounters and dual floodlights."
icon_state = "hardsuit0-mining"
item_state = "mining_helm"
item_color = "mining"
hardsuit_type = "mining"
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF
heat_protection = HEAD
@@ -267,7 +266,7 @@
alt_desc = "A dual-mode advanced helmet designed for work in special operations. It is in combat mode. Property of Gorlex Marauders."
icon_state = "hardsuit1-syndi"
item_state = "syndie_helm"
item_color = "syndi"
hardsuit_type = "syndi"
armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90)
on = FALSE
var/obj/item/clothing/suit/space/hardsuit/syndi/linkedsuit = null
@@ -276,7 +275,7 @@
visor_flags = STOPSPRESSUREDAMAGE
/obj/item/clothing/head/helmet/space/hardsuit/syndi/update_icon_state()
icon_state = "hardsuit[on]-[item_color]"
icon_state = "hardsuit[on]-[hardsuit_type]"
/obj/item/clothing/head/helmet/space/hardsuit/syndi/Initialize()
. = ..()
@@ -332,7 +331,7 @@
linkedsuit.clothing_flags &= ~STOPSPRESSUREDAMAGE
linkedsuit.cold_protection &= ~(CHEST | GROIN | LEGS | FEET | ARMS | HANDS)
linkedsuit.icon_state = "hardsuit[on]-[item_color]"
linkedsuit.icon_state = "hardsuit[on]-[hardsuit_type]"
linkedsuit.update_icon()
user.update_inv_wear_suit()
user.update_inv_w_uniform()
@@ -344,7 +343,7 @@
alt_desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in combat mode. Property of Gorlex Marauders."
icon_state = "hardsuit1-syndi"
item_state = "syndie_hardsuit"
item_color = "syndi"
hardsuit_type = "syndi"
w_class = WEIGHT_CLASS_NORMAL
armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90)
allowed = list(/obj/item/gun, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
@@ -358,7 +357,7 @@
desc = "An elite version of the syndicate helmet, with improved armour and fireproofing. It is in EVA mode. Property of Gorlex Marauders."
alt_desc = "An elite version of the syndicate helmet, with improved armour and fireproofing. It is in combat mode. Property of Gorlex Marauders."
icon_state = "hardsuit0-syndielite"
item_color = "syndielite"
hardsuit_type = "syndielite"
armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 25, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100)
heat_protection = HEAD
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
@@ -375,7 +374,7 @@
desc = "An elite version of the syndicate hardsuit, with improved armour and fireproofing. It is in travel mode."
alt_desc = "An elite version of the syndicate hardsuit, with improved armour and fireproofing. It is in combat mode."
icon_state = "hardsuit0-syndielite"
item_color = "syndielite"
hardsuit_type = "syndielite"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite
armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 25, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100)
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
@@ -394,7 +393,7 @@
alt_desc = "A dual-mode advanced helmet designed for any crime-fighting situation. It is in combat mode."
icon_state = "hardsuit1-owl"
item_state = "s_helmet"
item_color = "owl"
hardsuit_type = "owl"
visor_flags_inv = 0
visor_flags = 0
on = FALSE
@@ -405,7 +404,7 @@
alt_desc = "A dual-mode advanced hardsuit designed for any crime-fighting situation. It is in combat mode."
icon_state = "hardsuit1-owl"
item_state = "s_suit"
item_color = "owl"
hardsuit_type = "owl"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/owl
mutantrace_variation = STYLE_DIGITIGRADE
@@ -416,12 +415,16 @@
desc = "A bizarre gem-encrusted helmet that radiates magical energies."
icon_state = "hardsuit0-wiz"
item_state = "wiz_helm"
item_color = "wiz"
hardsuit_type = "wiz"
resistance_flags = FIRE_PROOF | ACID_PROOF //No longer shall our kind be foiled by lone chemists with spray bottles!
armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100)
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 +439,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
@@ -446,7 +450,7 @@
desc = "A special helmet designed for work in a hazardous, low pressure environment. Built with lightweight materials for extra comfort, but does not protect the eyes from intense light."
icon_state = "hardsuit0-medical"
item_state = "medical_helm"
item_color = "medical"
hardsuit_type = "medical"
flash_protect = 0
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75)
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
@@ -479,7 +483,7 @@
name = "prototype hardsuit helmet"
desc = "A prototype helmet designed for research in a hazardous, low pressure environment. Scientific data flashes across the visor."
icon_state = "hardsuit0-rd"
item_color = "rd"
hardsuit_type = "rd"
resistance_flags = ACID_PROOF | FIRE_PROOF
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80)
@@ -521,7 +525,7 @@
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor."
icon_state = "hardsuit0-sec"
item_state = "sec_helm"
item_color = "sec"
hardsuit_type = "sec"
armor = list("melee" = 35, "bullet" = 15, "laser" = 30,"energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75)
/obj/item/clothing/suit/space/hardsuit/security
@@ -542,7 +546,7 @@
name = "head of security's hardsuit helmet"
desc = "A special bulky helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor."
icon_state = "hardsuit0-hos"
item_color = "hos"
hardsuit_type = "hos"
armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95)
/obj/item/clothing/suit/space/hardsuit/security/hos
@@ -591,7 +595,7 @@
icon_state = "hardsuit0-clown"
item_state = "hardsuit0-clown"
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 30)
item_color = "clown"
hardsuit_type = "clown"
/obj/item/clothing/suit/space/hardsuit/clown
name = "cosmohonk hardsuit"
@@ -617,7 +621,7 @@
icon_state = "hardsuit0-ancient"
item_state = "anc_helm"
armor = list("melee" = 30, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 75)
item_color = "ancient"
hardsuit_type = "ancient"
resistance_flags = FIRE_PROOF
/obj/item/clothing/suit/space/hardsuit/ancient
@@ -653,7 +657,7 @@
icon_state = "hardsuit0-ancient"
item_state = "anc_helm"
armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
item_color = "ancient"
hardsuit_type = "ancient"
brightness_on = 16
flash_protect = 5 //We will not be flash by bombs
tint = 1
@@ -715,7 +719,7 @@
name = "soviet hardhelmet"
desc = "Crafted with the pride of the proletariat. The vengeful gaze of the visor roots out all fascists and capitalists."
item_state = "rig0-soviet"
item_color = "soviet"
hardsuit_type = "soviet"
icon_state = "rig0-soviet"
armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 75)
mutantrace_variation = NONE
@@ -757,7 +761,13 @@
if(!allowed)
allowed = GLOB.advanced_hardsuit_allowed
/obj/item/clothing/suit/space/hardsuit/shielded/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
/obj/item/clothing/suit/space/hardsuit/shielded/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(current_charges > 0)
block_return[BLOCK_RETURN_NORMAL_BLOCK_CHANCE] = 100
block_return[BLOCK_RETURN_BLOCK_CAPACITY] = (block_return[BLOCK_RETURN_BLOCK_CAPACITY] || 0) + current_charges
return ..()
/obj/item/clothing/suit/space/hardsuit/shielded/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
recharge_cooldown = world.time + recharge_delay
if(current_charges > 0)
var/datum/effect_system/spark_spread/s = new
@@ -771,8 +781,8 @@
owner.visible_message("[owner]'s shield overloads!")
shield_state = "broken"
owner.update_inv_wear_suit()
return 1
return 0
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
return BLOCK_NONE
/obj/item/clothing/suit/space/hardsuit/shielded/Destroy()
STOP_PROCESSING(SSobj, src)
@@ -790,7 +800,7 @@
var/mob/living/carbon/human/C = loc
C.update_inv_wear_suit()
/obj/item/clothing/suit/space/hardsuit/shielded/worn_overlays(isinhands, icon_file, style_flags = NONE)
/obj/item/clothing/suit/space/hardsuit/shielded/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
var/file2use = style_flags & STYLE_ALL_TAURIC ? 'modular_citadel/icons/mob/64x32_effects.dmi' : 'icons/effects/effects.dmi'
@@ -806,7 +816,7 @@
desc = "Standard issue hardsuit for playing capture the flag."
icon_state = "ert_medical"
item_state = "ert_medical"
item_color = "ert_medical"
hardsuit_type = "ert_medical"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf
armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95)
slowdown = 0
@@ -820,7 +830,7 @@
name = "red shielded hardsuit"
icon_state = "ert_security"
item_state = "ert_security"
item_color = "ert_security"
hardsuit_type = "ert_security"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/red
shield_state = "shield-red"
shield_on = "shield-red"
@@ -837,20 +847,20 @@
desc = "Standard issue hardsuit helmet for playing capture the flag."
icon_state = "hardsuit0-ert_medical"
item_state = "hardsuit0-ert_medical"
item_color = "ert_medical"
hardsuit_type = "ert_medical"
armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95)
/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/red
icon_state = "hardsuit0-ert_security"
item_state = "hardsuit0-ert_security"
item_color = "ert_security"
hardsuit_type = "ert_security"
/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/blue
name = "shielded hardsuit helmet"
desc = "Standard issue hardsuit helmet for playing capture the flag."
icon_state = "hardsuit0-ert_commander"
item_state = "hardsuit0-ert_commander"
item_color = "ert_commander"
hardsuit_type = "ert_commander"
//////Syndicate Version
@@ -859,7 +869,7 @@
desc = "An advanced hardsuit with built in energy shielding."
icon_state = "hardsuit1-syndi"
item_state = "syndie_hardsuit"
item_color = "syndi"
hardsuit_type = "syndi"
armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100)
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi
@@ -875,7 +885,7 @@
desc = "An advanced hardsuit helmet with built in energy shielding."
icon_state = "hardsuit1-syndi"
item_state = "syndie_helm"
item_color = "syndi"
hardsuit_type = "syndi"
armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100)
///SWAT version
@@ -884,7 +894,7 @@
desc = "An advanced hardsuit favored by commandos for use in special operations."
icon_state = "deathsquad"
item_state = "swat_suit"
item_color = "syndi"
hardsuit_type = "syndi"
max_charges = 4
current_charges = 4
recharge_delay = 15
@@ -899,7 +909,7 @@
desc = "A tactical helmet with built in energy shielding."
icon_state = "deathsquad"
item_state = "deathsquad"
item_color = "syndi"
hardsuit_type = "syndi"
armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
strip_delay = 130
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
@@ -914,7 +924,7 @@
desc = "A helmet designed with both form and function in mind, it protects the user against physical trauma and hazardous conditions while also having polychromic light strips."
icon_state = "knight_cydonia"
item_state = "knight_yellow"
item_color = null
hardsuit_type = null
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | LAVA_PROOF
heat_protection = HEAD
@@ -947,7 +957,7 @@
. = ..()
. += mutable_appearance(icon, "knight_cydonia_overlay", color = energy_color)
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER)
@@ -978,7 +988,7 @@
. = ..()
. += mutable_appearance(icon, "knight_cydonia_overlay", color = energy_color)
/obj/item/clothing/suit/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
/obj/item/clothing/suit/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER)
@@ -174,7 +174,7 @@ Contains:
desc = "Standard issue command helmet for the ERT."
icon_state = "hardsuit0-ert_commander"
item_state = "hardsuit0-ert_commander"
item_color = "ert_commander"
hardsuit_type = "ert_commander"
armor = list("melee" = 65, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80)
strip_delay = 130
brightness_on = 7
@@ -201,7 +201,7 @@ Contains:
desc = "Standard issue security helmet for the ERT."
icon_state = "hardsuit0-ert_security"
item_state = "hardsuit0-ert_security"
item_color = "ert_security"
hardsuit_type = "ert_security"
/obj/item/clothing/suit/space/hardsuit/ert/sec
desc = "Standard issue security suit for the ERT."
@@ -214,7 +214,7 @@ Contains:
desc = "Standard issue engineer helmet for the ERT."
icon_state = "hardsuit0-ert_engineer"
item_state = "hardsuit0-ert_engineer"
item_color = "ert_engineer"
hardsuit_type = "ert_engineer"
/obj/item/clothing/suit/space/hardsuit/ert/engi
desc = "Standard issue engineer suit for the ERT."
@@ -227,7 +227,7 @@ Contains:
desc = "Standard issue medical helmet for the ERT."
icon_state = "hardsuit0-ert_medical"
item_state = "hardsuit0-ert_medical"
item_color = "ert_medical"
hardsuit_type = "ert_medical"
/obj/item/clothing/suit/space/hardsuit/ert/med
desc = "Standard issue medical suit for the ERT."
@@ -243,7 +243,7 @@ Contains:
desc = "Red alert command helmet for the ERT. This one is more armored than its standard version."
icon_state = "hardsuit0-ert_commander-alert"
item_state = "hardsuit0-ert_commander-alert"
item_color = "ert_commander-alert"
hardsuit_type = "ert_commander-alert"
armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
brightness_on = 8
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -263,7 +263,7 @@ Contains:
desc = "Red alert security helmet for the ERT. This one is more armored than its standard version."
icon_state = "hardsuit0-ert_security-alert"
item_state = "hardsuit0-ert_security-alert"
item_color = "ert_security-alert"
hardsuit_type = "ert_security-alert"
/obj/item/clothing/suit/space/hardsuit/ert/alert/sec
desc = "Red alert security suit for the ERT. This one is more armored than its standard version."
@@ -276,7 +276,7 @@ Contains:
desc = "Red alert engineer helmet for the ERT. This one is more armored than its standard version."
icon_state = "hardsuit0-ert_engineer-alert"
item_state = "hardsuit0-ert_engineer-alert"
item_color = "ert_engineer-alert"
hardsuit_type = "ert_engineer-alert"
/obj/item/clothing/suit/space/hardsuit/ert/alert/engi
desc = "Red alert engineer suit for the ERT. This one is more armored than its standard version."
@@ -289,7 +289,7 @@ Contains:
desc = "Red alert medical helmet for the ERT. This one is more armored than its standard version."
icon_state = "hardsuit0-ert_medical-alert"
item_state = "hardsuit0-ert_medical-alert"
item_color = "ert_medical-alert"
hardsuit_type = "ert_medical-alert"
/obj/item/clothing/suit/space/hardsuit/ert/alert/med
desc = "Red alert medical suit for the ERT. This one is more armored than its standard version."
@@ -320,7 +320,6 @@ Contains:
icon_state = "cespace_helmet"
item_state = "nothing"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0)
item_color = "engineering"
resistance_flags = FIRE_PROOF
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
actions_types = list()
@@ -391,7 +390,7 @@ Contains:
desc = "A helmet worn by those who deal with paranormal threats for a living."
icon_state = "hardsuit0-prt"
item_state = "hardsuit0-prt"
item_color = "knight_grey"
hardsuit_type = "knight_grey"
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
actions_types = list()
resistance_flags = FIRE_PROOF
@@ -456,7 +455,8 @@ Contains:
armor = list("melee" = 5, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 0, "acid" = 0)
strip_delay = 65
/obj/item/clothing/suit/space/fragile/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
/obj/item/clothing/suit/space/fragile/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
. = ..()
if(!torn && prob(50) && damage >= 5)
to_chat(owner, "<span class='warning'>[src] tears from the damage, breaking the air-tight seal!</span>")
clothing_flags &= ~STOPSPRESSUREDAMAGE
@@ -67,7 +67,7 @@
var/datum/action/A=X
A.UpdateButtonIcon()
/obj/item/clothing/head/helmet/space/plasmaman/worn_overlays(isinhands, icon_file, style_flags = NONE)
/obj/item/clothing/head/helmet/space/plasmaman/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands && on)
. += mutable_appearance(icon_file, light_overlay)
+2 -1
View File
@@ -1,6 +1,7 @@
/obj/item/clothing/suit
icon = 'icons/obj/clothing/suits.dmi'
name = "suit"
block_priority = BLOCK_PRIORITY_WEAR_SUIT
var/fire_resist = T0C+100
allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
@@ -11,7 +12,7 @@
var/suittoggled = FALSE
mutantrace_variation = STYLE_DIGITIGRADE
/obj/item/clothing/suit/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
/obj/item/clothing/suit/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
if(damaged_clothes)
+6 -5
View File
@@ -173,12 +173,13 @@
armor = list("melee" = 10, "bullet" = 10, "laser" = 60, "energy" = 50, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/hit_reflect_chance = 40
var/list/protected_zones = list(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_GROIN)
/obj/item/clothing/suit/armor/laserproof/IsReflect(def_zone)
if(!(def_zone in list(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_GROIN))) //If not shot where ablative is covering you, you don't get the reflection bonus!
return 0
if (prob(hit_reflect_chance))
return 1
/obj/item/clothing/suit/armor/laserproof/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(def_zone in protected_zones)
if(prob(hit_reflect_chance))
return BLOCK_SHOULD_REDIRECT | BLOCK_REDIRECTED | BLOCK_SUCCESS | BLOCK_PHYSICAL_INTERNAL
return ..()
/obj/item/clothing/suit/armor/vest/det_suit
name = "detective's armor vest"
+11
View File
@@ -91,3 +91,14 @@
heat_protection = HEAD
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF | GOLIATH_RESISTANCE
/obj/item/clothing/neck/cloak/polychromic
name = "polychromic cloak"
desc = "For when you want to show off your horrible colour coordination skills."
icon_state = "polyce"
item_state = "qmcloak"
var/list/poly_colors = list("#FFFFFF", "#FFFFFF", "#808080")
/obj/item/clothing/neck/cloak/polychromic/ComponentInitialize()
. = ..()
AddElement(/datum/element/polychromic, poly_colors, 3)
+4 -65
View File
@@ -973,73 +973,12 @@
name = "polychromic winter coat"
icon_state = "coatpoly"
item_state = "coatpoly"
item_color = "coatpoly"
hoodtype = /obj/item/clothing/head/hooded/winterhood/polychromic
hasprimary = TRUE
hassecondary = TRUE
hastertiary = TRUE
primary_color = "#6A6964"
secondary_color = "#C4B8A6"
tertiary_color = "#0000FF"
/obj/item/clothing/suit/hooded/wintercoat/ComponentInitialize()
. = ..()
AddElement(/datum/element/polychromic, list("#6A6964", "#C4B8A6", "#0000FF"), 3)
/obj/item/clothing/head/hooded/winterhood/polychromic
icon_state = "winterhood_poly"
item_color = "winterhood_poly"
item_state = "winterhood_poly"
/obj/item/clothing/head/hooded/winterhood/polychromic/worn_overlays(isinhands, icon_file, style_flags = NONE) //this is where the main magic happens.
. = ..()
if(suit.hasprimary | suit.hassecondary)
if(!isinhands) //prevents the worn sprites from showing up if you're just holding them
if(suit.hasprimary) //checks if overlays are enabled
var/mutable_appearance/primary_worn = mutable_appearance(icon_file, "[item_color]-primary") //automagical sprite selection
primary_worn.color = suit.primary_color //colors the overlay
. += primary_worn //adds the overlay onto the buffer list to draw on the mob sprite.
if(suit.hassecondary)
var/mutable_appearance/secondary_worn = mutable_appearance(icon_file, "[item_color]-secondary")
secondary_worn.color = suit.secondary_color
. += secondary_worn
/obj/item/clothing/suit/hooded/wintercoat/polychromic/worn_overlays(isinhands, icon_file, style_flags = NONE) //this is where the main magic happens.
. = ..()
if(hasprimary | hassecondary | hastertiary)
if(!isinhands) //prevents the worn sprites from showing up if you're just holding them
if(hasprimary) //checks if overlays are enabled
var/mutable_appearance/primary_worn = mutable_appearance(icon_file, "[item_color]-primary[suittoggled ? "_t" : ""]") //automagical sprite selection
primary_worn.color = primary_color //colors the overlay
. += primary_worn //adds the overlay onto the buffer list to draw on the mob sprite.
if(hassecondary)
var/mutable_appearance/secondary_worn = mutable_appearance(icon_file, "[item_color]-secondary[suittoggled ? "_t" : ""]")
secondary_worn.color = secondary_color
. += secondary_worn
if(hastertiary)
var/mutable_appearance/tertiary_worn = mutable_appearance(icon_file, "[item_color]-tertiary[suittoggled ? "_t" : ""]")
tertiary_worn.color = tertiary_color
. += tertiary_worn
/obj/item/clothing/suit/hooded/wintercoat/AltClick(mob/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if(hasprimary | hassecondary | hastertiary)
var/choice = input(user,"polychromic thread options", "Clothing Recolor") as null|anything in list("[hasprimary ? "Primary Color" : ""]", "[hassecondary ? "Secondary Color" : ""]", "[hastertiary ? "Tertiary Color" : ""]") //generates a list depending on the enabled overlays
switch(choice) //Lets the list's options actually lead to something
if("Primary Color")
var/primary_color_input = input(usr,"","Choose Primary Color",primary_color) as color|null //color input menu, the "|null" adds a cancel button to it.
if(primary_color_input) //Checks if the color selected is NULL, rejects it if it is NULL.
primary_color = sanitize_hexcolor(primary_color_input, desired_format=6, include_crunch=1) //formats the selected color properly
update_icon() //updates the item icon
user.regenerate_icons() //updates the worn icon. Probably a bad idea, but it works.
if("Secondary Color")
var/secondary_color_input = input(usr,"","Choose Secondary Color",secondary_color) as color|null
if(secondary_color_input)
secondary_color = sanitize_hexcolor(secondary_color_input, desired_format=6, include_crunch=1)
update_icon()
user.regenerate_icons()
if("Tertiary Color")
var/tertiary_color_input = input(usr,"","Choose Tertiary Color",tertiary_color) as color|null
if(tertiary_color_input)
tertiary_color = sanitize_hexcolor(tertiary_color_input, desired_format=6, include_crunch=1)
update_icon()
user.regenerate_icons()
return TRUE
+30 -30
View File
@@ -36,8 +36,8 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
actions_types = list(/datum/action/item_action/toggle)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
hit_reaction_chance = 50 // Only on the chest yet blocks all attacks?
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
var/hit_reaction_chance = 50
/obj/item/clothing/suit/armor/reactive/attack_self(mob/user)
active = !(active)
@@ -62,6 +62,14 @@
item_state = "reactiveoff"
reactivearmor_cooldown = world.time + 200
/obj/item/clothing/suit/armor/reactive/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(!active)
return BLOCK_NONE
return block_action(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
/obj/item/clothing/suit/armor/reactive/proc/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
return BLOCK_NONE
//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
/obj/item/clothing/suit/armor/reactive/teleport
name = "reactive teleport armor"
@@ -71,18 +79,15 @@
var/rad_amount_before = 120
reactivearmor_cooldown_duration = 100
/obj/item/clothing/suit/armor/reactive/teleport/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
. = FALSE
if(!active)
return
/obj/item/clothing/suit/armor/reactive/teleport/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(prob(hit_reaction_chance))
var/mob/living/carbon/human/H = owner
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive teleport system is still recharging! It fails to teleport [H]!</span>")
return
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text], shutting itself off in the process!</span>")
playsound(get_turf(owner),'sound/magic/blink.ogg', 100, 1)
var/list/turfs = new/list()
playsound(get_turf(owner), 'sound/magic/blink.ogg', 100, 1)
var/list/turfs = new
var/turf/old = get_turf(src)
for(var/turf/T in orange(tele_range, H))
if(T.density)
@@ -101,7 +106,9 @@
radiation_pulse(old, rad_amount_before)
radiation_pulse(src, rad_amount)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return TRUE
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_PASSTHROUGH
return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT | BLOCK_TARGET_DODGED
return BLOCK_NONE
//Fire
@@ -109,9 +116,7 @@
name = "reactive incendiary armor"
desc = "An experimental suit of armor with a reactive sensor array rigged to a flame emitter. For the stylish pyromaniac."
/obj/item/clothing/suit/armor/reactive/fire/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
/obj/item/clothing/suit/armor/reactive/fire/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive incendiary armor on [owner] activates, but fails to send out flames as it is still recharging its flame jets!</span>")
@@ -124,8 +129,8 @@
C.IgniteMob()
owner.fire_stacks = -20
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
return BLOCK_SUCCESS | BLOCK_PHYSICAL_INTERNAL
return BLOCK_NONE
//Stealth
@@ -134,9 +139,7 @@
reactivearmor_cooldown_duration = 65
desc = "An experimental suit of armor that renders the wearer invisible on detection of imminent harm, and creates a decoy that runs away from the owner. You can't fight what you can't see."
/obj/item/clothing/suit/armor/reactive/stealth/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
/obj/item/clothing/suit/armor/reactive/stealth/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive stealth system on [owner] activates, but is still recharging its holographic emitters!</span>")
@@ -150,7 +153,8 @@
spawn(40)
owner.alpha = initial(owner.alpha)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return BLOCK_SUCCESS | BLOCK_PHYSICAL_INTERNAL
return BLOCK_NONE
//Tesla
@@ -175,9 +179,7 @@
if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item?
user.flags_1 |= TESLA_IGNORE_1
/obj/item/clothing/suit/armor/reactive/tesla/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return FALSE
/obj/item/clothing/suit/armor/reactive/tesla/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
@@ -196,7 +198,8 @@
M.adjustFireLoss(legacy_dmg)
playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return TRUE
return BLOCK_SUCCESS | BLOCK_PHYSICAL_INTERNAL
return NONE
//Repulse
@@ -205,9 +208,7 @@
reactivearmor_cooldown_duration = 20
desc = "An experimental suit of armor that violently throws back attackers."
/obj/item/clothing/suit/armor/reactive/repulse/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
/obj/item/clothing/suit/armor/reactive/repulse/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The repulse generator is still recharging!</span>")
@@ -234,7 +235,8 @@
AM.throw_at(throwtarget,10,1)
safety--
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return BLOCK_SUCCESS | BLOCK_PHYSICAL_INTERNAL
return BLOCK_NONE
/obj/item/clothing/suit/armor/reactive/table
name = "reactive table armor"
@@ -242,9 +244,7 @@
desc = "If you can't beat the memes, embrace them."
var/tele_range = 10
/obj/item/clothing/suit/armor/reactive/table/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
/obj/item/clothing/suit/armor/reactive/table/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(prob(hit_reaction_chance))
var/mob/living/carbon/human/H = owner
if(world.time < reactivearmor_cooldown)
@@ -270,8 +270,8 @@
H.forceMove(picked)
new /obj/structure/table(get_turf(owner))
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
return BLOCK_SUCCESS | BLOCK_PHYSICAL_INTERNAL
return BLOCK_NONE
/obj/item/clothing/suit/armor/reactive/table/emp_act()
return
+14 -10
View File
@@ -6,7 +6,7 @@
var/hoodtype = /obj/item/clothing/head/hooded/winterhood //so the chaplain hoodie or other hoodies can override this
/obj/item/clothing/suit/hooded/New()
MakeHood()
hood = MakeHelmet()
..()
/obj/item/clothing/suit/hooded/Destroy()
@@ -14,11 +14,15 @@
qdel(hood)
hood = null
/obj/item/clothing/suit/hooded/proc/MakeHood()
/obj/item/clothing/suit/proc/MakeHelmet(obj/item/clothing/head/H)
SEND_SIGNAL(src, COMSIG_SUIT_MADE_HELMET, H)
return H
/obj/item/clothing/suit/hooded/MakeHelmet(obj/item/clothing/head/hooded/H)
if(!hood)
var/obj/item/clothing/head/hooded/W = new hoodtype(src)
W.suit = src
hood = W
H = new hoodtype(src)
H.suit = src
return ..()
/obj/item/clothing/suit/hooded/ui_action_click()
ToggleHood()
@@ -125,7 +129,7 @@
//Hardsuit toggle code
/obj/item/clothing/suit/space/hardsuit/Initialize()
MakeHelmet()
helmet = MakeHelmet()
. = ..()
/obj/item/clothing/suit/space/hardsuit/Destroy()
@@ -140,13 +144,13 @@
suit.helmet = null
return ..()
/obj/item/clothing/suit/space/hardsuit/proc/MakeHelmet()
/obj/item/clothing/suit/space/hardsuit/MakeHelmet(obj/item/clothing/head/helmet/space/hardsuit/H)
if(!helmettype)
return
if(!helmet)
var/obj/item/clothing/head/helmet/space/hardsuit/W = new helmettype(src)
W.suit = src
helmet = W
H = new helmettype(src)
H.suit = src
return ..()
/obj/item/clothing/suit/space/hardsuit/ui_action_click()
..()
+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

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