Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into BlobRefactor
To fixs something?
This commit is contained in:
@@ -407,6 +407,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
|
||||
#define DUMMY_HUMAN_SLOT_ADMIN "admintools"
|
||||
#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation"
|
||||
#define DUMMY_HUMAN_SLOT_HALLUCINATION "dummy_hallucination"
|
||||
#define DUMMY_HUMAN_SLOT_EXAMINER "dummy_examiner"
|
||||
|
||||
#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round
|
||||
//This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
//ids
|
||||
|
||||
#define MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED "MOB_WALK_RUN"
|
||||
#define MOVESPEED_ID_MOB_GRAB_STATE "MOB_GRAB_STATE"
|
||||
#define MOVESPEED_ID_MOB_EQUIPMENT "MOB_EQUIPMENT"
|
||||
#define MOVESPEED_ID_MOB_GRAVITY "MOB_GRAVITY"
|
||||
#define MOVESPEED_ID_CONFIG_SPEEDMOD "MOB_CONFIG_MODIFIER"
|
||||
|
||||
#define MOVESPEED_ID_SLIME_REAGENTMOD "SLIME_REAGENT_MODIFIER"
|
||||
@@ -28,6 +31,7 @@
|
||||
#define MOVESPEED_ID_TARANTULA_WEB "TARANTULA_WEB"
|
||||
|
||||
#define MOVESPEED_ID_LIVING_TURF_SPEEDMOD "LIVING_TURF_SPEEDMOD"
|
||||
#define MOVESPEED_ID_LIVING_LIMBLESS "LIVING_LIMBLESS"
|
||||
|
||||
#define MOVESPEED_ID_CARBON_SOFTCRIT "CARBON_SOFTCRIT"
|
||||
#define MOVESPEED_ID_CARBON_OLDSPEED "CARBON_DEPRECATED_SPEED"
|
||||
@@ -59,15 +63,19 @@
|
||||
#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY"
|
||||
#define MOVESPEED_ID_SHRINK_RAY "SHRUNKEN_SPEED_MODIFIER"
|
||||
|
||||
#define MOVESPEED_ID_TASED_STATUS "TASED"
|
||||
|
||||
#define MOVESPEED_ID_SLAUGHTER "SLAUGHTER"
|
||||
|
||||
#define MOVESPEED_ID_CYBER_THRUSTER "CYBER_IMPLANT_THRUSTER"
|
||||
#define MOVESPEED_ID_JETPACK "JETPACK"
|
||||
|
||||
#define MOVESPEED_ID_SHOVE "SHOVE"
|
||||
|
||||
#define MOVESPEED_ID_MKULTRA "MKULTRA"
|
||||
|
||||
#define MOVESPEED_ID_ELECTROSTAFF "ELECTROSTAFF"
|
||||
#define MOVESPEED_ID_TASED_STATUS "TASED"
|
||||
#define MOVESPEED_ID_ELECTROSTAFF "ELECTROSTAFF"
|
||||
|
||||
#define MOVESPEED_ID_SHOVE "SHOVE"
|
||||
#define MOVESPEED_ID_FAT "FAT"
|
||||
#define MOVESPEED_ID_COLD "COLD"
|
||||
#define MOVESPEED_ID_HUNGRY "HUNGRY"
|
||||
#define MOVESPEED_ID_DAMAGE_SLOWDOWN "DAMAGE"
|
||||
#define MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING "FLYING"
|
||||
@@ -23,6 +23,10 @@ Ask ninjanomnom if they're around
|
||||
|
||||
#define RAD_MOB_MUTATE 1250 // How much stored radiation to check for mutation
|
||||
|
||||
#define RAD_MONKEY_GORILLIZE 1650 // How much stored radiation to check for Harambe time.
|
||||
#define RAD_MOB_GORILLIZE_FACTOR 100
|
||||
#define RAD_MONKEY_GORILLIZE_EXPONENT 0.5
|
||||
|
||||
#define RAD_MOB_VOMIT 2000 // The amount of radiation to check for vomitting
|
||||
#define RAD_MOB_VOMIT_PROB 1 // Chance per tick of vomitting
|
||||
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
// Contains VOREStation based vore description type2type functions
|
||||
// list2text - takes delimiter and returns text
|
||||
// text2list - takes delimiter, and creates list
|
||||
//
|
||||
*/
|
||||
|
||||
// Concatenates a list of strings into a single string. A seperator may optionally be provided.
|
||||
/proc/list2text(list/ls, sep)
|
||||
if (ls.len <= 1) // Early-out code for empty or singleton lists.
|
||||
return ls.len ? ls[1] : ""
|
||||
|
||||
var/l = ls.len // Made local for sanic speed.
|
||||
var/i = 0 // Incremented every time a list index is accessed.
|
||||
|
||||
if (sep <> null)
|
||||
// Macros expand to long argument lists like so: sep, ls[++i], sep, ls[++i], sep, ls[++i], etc...
|
||||
#define S1 sep, ls[++i]
|
||||
#define S4 S1, S1, S1, S1
|
||||
#define S16 S4, S4, S4, S4
|
||||
#define S64 S16, S16, S16, S16
|
||||
|
||||
. = "[ls[++i]]" // Make sure the initial element is converted to text.
|
||||
|
||||
// Having the small concatenations come before the large ones boosted speed by an average of at least 5%.
|
||||
if (l-1 & 0x01) // 'i' will always be 1 here.
|
||||
. = text("[][][]", ., S1) // Append 1 element if the remaining elements are not a multiple of 2.
|
||||
if (l-i & 0x02)
|
||||
. = text("[][][][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4.
|
||||
if (l-i & 0x04)
|
||||
. = text("[][][][][][][][][]", ., S4) // And so on....
|
||||
if (l-i & 0x08)
|
||||
. = text("[][][][][][][][][][][][][][][][][]", ., S4, S4)
|
||||
if (l-i & 0x10)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16)
|
||||
if (l-i & 0x20)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16)
|
||||
if (l-i & 0x40)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64)
|
||||
while (l > i) // Chomp through the rest of the list, 128 elements at a time.
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64)
|
||||
|
||||
#undef S64
|
||||
#undef S16
|
||||
#undef S4
|
||||
#undef S1
|
||||
else
|
||||
// Macros expand to long argument lists like so: ls[++i], ls[++i], ls[++i], etc...
|
||||
#define S1 ls[++i]
|
||||
#define S4 S1, S1, S1, S1
|
||||
#define S16 S4, S4, S4, S4
|
||||
#define S64 S16, S16, S16, S16
|
||||
|
||||
. = "[ls[++i]]" // Make sure the initial element is converted to text.
|
||||
|
||||
if (l-1 & 0x01) // 'i' will always be 1 here.
|
||||
. += S1 // Append 1 element if the remaining elements are not a multiple of 2.
|
||||
if (l-i & 0x02)
|
||||
. = text("[][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4.
|
||||
if (l-i & 0x04)
|
||||
. = text("[][][][][]", ., S4) // And so on...
|
||||
if (l-i & 0x08)
|
||||
. = text("[][][][][][][][][]", ., S4, S4)
|
||||
if (l-i & 0x10)
|
||||
. = text("[][][][][][][][][][][][][][][][][]", ., S16)
|
||||
if (l-i & 0x20)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16)
|
||||
if (l-i & 0x40)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64)
|
||||
while (l > i) // Chomp through the rest of the list, 128 elements at a time.
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64)
|
||||
|
||||
#undef S64
|
||||
#undef S16
|
||||
#undef S4
|
||||
#undef S1
|
||||
|
||||
// Converts a string into a list by splitting the string at each delimiter found. (discarding the seperator)
|
||||
/proc/text2list(text, delimiter="\n")
|
||||
var/delim_len = length(delimiter)
|
||||
if (delim_len < 1)
|
||||
return list(text)
|
||||
|
||||
. = list()
|
||||
var/last_found = 1
|
||||
var/found
|
||||
|
||||
do
|
||||
found = findtext(text, delimiter, last_found, 0)
|
||||
. += copytext(text, last_found, found)
|
||||
last_found = found + delim_len
|
||||
while (found)
|
||||
|
||||
// Returns true if val is from min to max, inclusive.
|
||||
/proc/IsInRange(val, min, max)
|
||||
return (val >= min) && (val <= max)
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
|
||||
/datum/projectile_data
|
||||
var/src_x
|
||||
var/src_y
|
||||
var/time
|
||||
var/distance
|
||||
var/power_x
|
||||
var/power_y
|
||||
var/dest_x
|
||||
var/dest_y
|
||||
|
||||
/datum/projectile_data/New(var/src_x, var/src_y, var/time, var/distance, \
|
||||
var/power_x, var/power_y, var/dest_x, var/dest_y)
|
||||
src.src_x = src_x
|
||||
src.src_y = src_y
|
||||
src.time = time
|
||||
src.distance = distance
|
||||
src.power_x = power_x
|
||||
src.power_y = power_y
|
||||
src.dest_x = dest_x
|
||||
src.dest_y = dest_y
|
||||
|
||||
/proc/projectile_trajectory(src_x, src_y, rotation, angle, power)
|
||||
|
||||
// returns the destination (Vx,y) that a projectile shot at [src_x], [src_y], with an angle of [angle],
|
||||
// rotated at [rotation] and with the power of [power]
|
||||
// Thanks to VistaPOWA for this function
|
||||
|
||||
var/power_x = power * cos(angle)
|
||||
var/power_y = power * sin(angle)
|
||||
var/time = 2* power_y / 10 //10 = g
|
||||
|
||||
var/distance = time * power_x
|
||||
|
||||
var/dest_x = src_x + distance*sin(rotation);
|
||||
var/dest_y = src_y + distance*cos(rotation);
|
||||
|
||||
return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y)
|
||||
@@ -499,10 +499,11 @@ SUBSYSTEM_DEF(vote)
|
||||
modes_to_add -= "traitor" // makes it so that traitor is always available
|
||||
choices.Add(modes_to_add)
|
||||
if("dynamic")
|
||||
var/list/probabilities = CONFIG_GET(keyed_list/storyteller_weight)
|
||||
for(var/T in config.storyteller_cache)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
var/list/probabilities = CONFIG_GET(keyed_list/storyteller_weight)
|
||||
if(probabilities[initial(S.config_tag)] > 0)
|
||||
var/probability = ((initial(S.config_tag) in probabilities) ? probabilities[initial(S.config_tag)] : initial(S.weight))
|
||||
if(probability > 0)
|
||||
choices.Add(initial(S.name))
|
||||
choice_descs.Add(initial(S.desc))
|
||||
if("custom")
|
||||
|
||||
@@ -298,19 +298,15 @@
|
||||
subcategory = CAT_AMMO
|
||||
|
||||
/datum/crafting_recipe/ashen_arrow
|
||||
name = "Bonfire-Hardened Arrow"
|
||||
name = "Fire Hardened Arrow"
|
||||
result = /obj/item/ammo_casing/caseless/arrow/ashen
|
||||
tools = list(/obj/structure/bonfire)
|
||||
tools = list(TOOL_WELDER)
|
||||
time = 30
|
||||
always_availible = FALSE
|
||||
reqs = list(/obj/item/ammo_casing/caseless/arrow = 1)
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_AMMO
|
||||
|
||||
/datum/crafting_recipe/ashen_arrow/welder
|
||||
name = "Welder-Hardened Arrow"
|
||||
tools = list(TOOL_WELDER)
|
||||
|
||||
/datum/crafting_recipe/smartdart
|
||||
name = "Medical smartdart"
|
||||
result = /obj/item/reagent_containers/syringe/dart
|
||||
|
||||
+14
-16
@@ -26,10 +26,10 @@
|
||||
/datum/proc/vv_get_dropdown()
|
||||
. = list()
|
||||
. += "---"
|
||||
.["Call Proc"] = "?_src_=vars;[HrefToken()];proc_call=[REF(src)]"
|
||||
.["Mark Object"] = "?_src_=vars;[HrefToken()];mark_object=[REF(src)]"
|
||||
.["Delete"] = "?_src_=vars;[HrefToken()];delete=[REF(src)]"
|
||||
.["Show VV To Player"] = "?_src_=vars;[HrefToken(TRUE)];expose=[REF(src)]"
|
||||
.["Call Proc"] = "?_src_=vars;[HrefToken()];proc_call=\ref[src]"
|
||||
.["Mark Object"] = "?_src_=vars;[HrefToken()];mark_object=\ref[src]"
|
||||
.["Delete"] = "?_src_=vars;[HrefToken()];delete=\ref[src]"
|
||||
.["Show VV To Player"] = "?_src_=vars;[HrefToken(TRUE)];expose=\ref[src]"
|
||||
|
||||
|
||||
/datum/proc/on_reagent_change(changetype)
|
||||
@@ -54,7 +54,7 @@
|
||||
return
|
||||
|
||||
var/title = ""
|
||||
var/refid = REF(D)
|
||||
var/refid = "\ref[D]"
|
||||
var/icon/sprite
|
||||
var/hash
|
||||
|
||||
@@ -62,8 +62,6 @@
|
||||
if (!islist)
|
||||
type = D.type
|
||||
|
||||
|
||||
|
||||
if(istype(D, /atom))
|
||||
var/atom/AT = D
|
||||
if(AT.icon && AT.icon_state)
|
||||
@@ -410,7 +408,7 @@
|
||||
|
||||
|
||||
/client/proc/vv_update_display(datum/D, span, content)
|
||||
src << output("[span]:[content]", "variables[REF(D)].browser:replace_span")
|
||||
src << output("[span]:[content]", "variables\ref[D].browser:replace_span")
|
||||
|
||||
|
||||
#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing )
|
||||
@@ -423,9 +421,9 @@
|
||||
name = DA[name] //name is really the index until this line
|
||||
else
|
||||
value = DA[name]
|
||||
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];listedit=[REF(DA)];index=[index]'>E</a>) (<a href='?_src_=vars;[HrefToken()];listchange=[REF(DA)];index=[index]'>C</a>) (<a href='?_src_=vars;[HrefToken()];listremove=[REF(DA)];index=[index]'>-</a>) "
|
||||
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];listedit=\ref[DA];index=[index]'>E</a>) (<a href='?_src_=vars;[HrefToken()];listchange=\ref[DA];index=[index]'>C</a>) (<a href='?_src_=vars;[HrefToken()];listremove=\ref[DA];index=[index]'>-</a>) "
|
||||
else
|
||||
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];datumedit=[REF(DA)];varnameedit=[name]'>E</a>) (<a href='?_src_=vars;[HrefToken()];datumchange=[REF(DA)];varnamechange=[name]'>C</a>) (<a href='?_src_=vars;[HrefToken()];datummass=[REF(DA)];varnamemass=[name]'>M</a>) "
|
||||
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];datumedit=\ref[DA];varnameedit=[name]'>E</a>) (<a href='?_src_=vars;[HrefToken()];datumchange=\ref[DA];varnamechange=[name]'>C</a>) (<a href='?_src_=vars;[HrefToken()];datummass=\ref[DA];varnamemass=[name]'>M</a>) "
|
||||
else
|
||||
header = "<li>"
|
||||
|
||||
@@ -440,7 +438,7 @@
|
||||
#ifdef VARSICON
|
||||
var/icon/I = new/icon(value)
|
||||
var/rnd = rand(1,10000)
|
||||
var/rname = "tmp[REF(I)][rnd].png"
|
||||
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
|
||||
@@ -453,9 +451,9 @@
|
||||
else if (istype(value, /datum))
|
||||
var/datum/D = value
|
||||
if ("[D]" != "[D.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> = [D] [D.type]"
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D] [D.type]"
|
||||
else
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D.type]"
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D.type]"
|
||||
|
||||
else if (islist(value))
|
||||
var/list/L = value
|
||||
@@ -473,9 +471,9 @@
|
||||
|
||||
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>"
|
||||
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>"
|
||||
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()
|
||||
@@ -587,7 +585,7 @@
|
||||
var/prompt = alert("Do you want to grant [C] access to view this VV window? (they will not be able to edit or change anything nor open nested vv windows unless they themselves are an admin)", "Confirm", "Yes", "No")
|
||||
if (prompt != "Yes" || !usr.client)
|
||||
return
|
||||
message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a <a href='?_src_=vars;[HrefToken(TRUE)];datumrefresh=[REF(thing)]'>VV window</a>")
|
||||
message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a <a href='?_src_=vars;[HrefToken(TRUE)];datumrefresh=\ref[thing]'>VV window</a>")
|
||||
log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [thing]")
|
||||
to_chat(C, "[usr.client.holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window")
|
||||
C.debug_variables(thing)
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
D.grabbedby(A, 1)
|
||||
if(old_grab_state == GRAB_PASSIVE)
|
||||
D.drop_all_held_items()
|
||||
A.grab_state = GRAB_AGGRESSIVE //Instant agressive grab if on grab intent
|
||||
A.setGrabState(GRAB_AGGRESSIVE) //Instant agressive grab if on grab intent
|
||||
log_combat(A, D, "grabbed", addition="aggressively")
|
||||
D.visible_message("<span class='warning'>[A] violently grabs [D]!</span>", \
|
||||
"<span class='userdanger'>[A] violently grabs you!</span>")
|
||||
@@ -185,7 +185,7 @@
|
||||
D.SetSleeping(400)
|
||||
restraining = FALSE
|
||||
if(A.grab_state < GRAB_NECK)
|
||||
A.grab_state = GRAB_NECK
|
||||
A.setGrabState(GRAB_NECK)
|
||||
else
|
||||
restraining = FALSE
|
||||
return FALSE
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
log_combat(A, D, "grabbed", addition="aggressively")
|
||||
D.visible_message("<span class='warning'>[A] violently grabs [D]!</span>", \
|
||||
"<span class='userdanger'>[A] violently grabs you!</span>")
|
||||
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
|
||||
A.setGrabState(GRAB_AGGRESSIVE) //Instant aggressive grab
|
||||
else
|
||||
log_combat(A, D, "grabbed", addition="passively")
|
||||
A.grab_state = GRAB_PASSIVE
|
||||
A.setGrabState(GRAB_PASSIVE)
|
||||
if(4)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
atk_verb = "headbutts"
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
D.grabbedby(A, 1)
|
||||
if(old_grab_state == GRAB_PASSIVE)
|
||||
D.drop_all_held_items()
|
||||
A.grab_state = GRAB_AGGRESSIVE //Instant agressive grab if on grab intent
|
||||
A.setGrabState(GRAB_AGGRESSIVE) //Instant agressive grab if on grab intent
|
||||
log_combat(A, D, "grabbed", addition="aggressively")
|
||||
D.visible_message("<span class='warning'>[A] violently grabs [D]!</span>", \
|
||||
"<span class='userdanger'>[A] violently grabs you!</span>")
|
||||
|
||||
@@ -106,9 +106,9 @@
|
||||
|
||||
/datum/quirk/musician/on_spawn()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/obj/item/instrument/guitar/guitar = new(get_turf(H))
|
||||
H.put_in_hands(guitar)
|
||||
H.equip_to_slot(guitar, SLOT_IN_BACKPACK)
|
||||
var/obj/item/choice_beacon/music/B = new(get_turf(H))
|
||||
H.put_in_hands(B)
|
||||
H.equip_to_slot(B, SLOT_IN_BACKPACK)
|
||||
var/obj/item/musicaltuner/musicaltuner = new(get_turf(H))
|
||||
H.put_in_hands(musicaltuner)
|
||||
H.equip_to_slot(musicaltuner, SLOT_IN_BACKPACK)
|
||||
|
||||
@@ -514,39 +514,6 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
/client/proc/ResetAmbiencePlayed()
|
||||
played = FALSE
|
||||
|
||||
/atom/proc/has_gravity(turf/T)
|
||||
if(!T || !isturf(T))
|
||||
T = get_turf(src)
|
||||
|
||||
if(!T)
|
||||
return 0
|
||||
|
||||
var/list/forced_gravity = list()
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_HAS_GRAVITY, T, forced_gravity)
|
||||
if(!forced_gravity.len)
|
||||
SEND_SIGNAL(T, COMSIG_TURF_HAS_GRAVITY, src, forced_gravity)
|
||||
if(forced_gravity.len)
|
||||
var/max_grav
|
||||
for(var/i in forced_gravity)
|
||||
max_grav = max(max_grav, i)
|
||||
if(max_grav)
|
||||
return max_grav
|
||||
|
||||
if(isspaceturf(T)) // Turf never has gravity
|
||||
return 0
|
||||
|
||||
var/area/A = get_area(T)
|
||||
if(A.has_gravity) // Areas which always has gravity
|
||||
return A.has_gravity
|
||||
else
|
||||
// There's a gravity generator on our z level
|
||||
if(GLOB.gravity_generators["[T.z]"])
|
||||
var/max_grav = 0
|
||||
for(var/obj/machinery/gravity_generator/main/G in GLOB.gravity_generators["[T.z]"])
|
||||
max_grav = max(G.setting,max_grav)
|
||||
return max_grav
|
||||
return SSmapping.level_trait(T.z, ZTRAIT_GRAVITY)
|
||||
|
||||
/area/proc/setup(a_name)
|
||||
name = a_name
|
||||
power_equip = FALSE
|
||||
|
||||
@@ -918,3 +918,49 @@ Proc for attack log creation, because really why not
|
||||
if(!(material_flags & MATERIAL_NO_EFFECTS))
|
||||
custom_material.on_applied(src, materials[custom_material] * multiplier * material_modifier, material_flags)
|
||||
custom_materials[custom_material] += materials[x] * multiplier
|
||||
|
||||
/**
|
||||
* Returns true if this atom has gravity for the passed in turf
|
||||
*
|
||||
* Sends signals COMSIG_ATOM_HAS_GRAVITY and COMSIG_TURF_HAS_GRAVITY, both can force gravity with
|
||||
* the forced gravity var
|
||||
*
|
||||
* Gravity situations:
|
||||
* * No gravity if you're not in a turf
|
||||
* * No gravity if this atom is in is a space turf
|
||||
* * Gravity if the area it's in always has gravity
|
||||
* * Gravity if there's a gravity generator on the z level
|
||||
* * Gravity if the Z level has an SSMappingTrait for ZTRAIT_GRAVITY
|
||||
* * otherwise no gravity
|
||||
*/
|
||||
/atom/proc/has_gravity(turf/T)
|
||||
if(!T || !isturf(T))
|
||||
T = get_turf(src)
|
||||
|
||||
if(!T)
|
||||
return 0
|
||||
|
||||
var/list/forced_gravity = list()
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_HAS_GRAVITY, T, forced_gravity)
|
||||
if(!forced_gravity.len)
|
||||
SEND_SIGNAL(T, COMSIG_TURF_HAS_GRAVITY, src, forced_gravity)
|
||||
if(forced_gravity.len)
|
||||
var/max_grav
|
||||
for(var/i in forced_gravity)
|
||||
max_grav = max(max_grav, i)
|
||||
return max_grav
|
||||
|
||||
if(isspaceturf(T)) // Turf never has gravity
|
||||
return 0
|
||||
|
||||
var/area/A = get_area(T)
|
||||
if(A.has_gravity) // Areas which always has gravity
|
||||
return A.has_gravity
|
||||
else
|
||||
// There's a gravity generator on our z level
|
||||
if(GLOB.gravity_generators["[T.z]"])
|
||||
var/max_grav = 0
|
||||
for(var/obj/machinery/gravity_generator/main/G in GLOB.gravity_generators["[T.z]"])
|
||||
max_grav = max(G.setting,max_grav)
|
||||
return max_grav
|
||||
return SSmapping.level_trait(T.z, ZTRAIT_GRAVITY)
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
return FALSE
|
||||
// Are we trying to pull something we are already pulling? Then enter grab cycle and end.
|
||||
if(AM == pulling)
|
||||
grab_state = state
|
||||
setGrabState(state)
|
||||
if(istype(AM,/mob/living))
|
||||
var/mob/living/AMob = AM
|
||||
AMob.grabbedby(src)
|
||||
@@ -142,7 +142,7 @@
|
||||
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
|
||||
pulling = AM
|
||||
AM.pulledby = src
|
||||
grab_state = state
|
||||
setGrabState(state)
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
log_combat(src, M, "grabbed", addition="passive grab")
|
||||
@@ -155,7 +155,7 @@
|
||||
pulling.pulledby = null
|
||||
var/mob/living/ex_pulled = pulling
|
||||
pulling = null
|
||||
grab_state = 0
|
||||
setGrabState(0)
|
||||
if(isliving(ex_pulled))
|
||||
var/mob/living/L = ex_pulled
|
||||
L.update_mobility()// mob gets up if it was lyng down in a chokehold
|
||||
@@ -563,6 +563,11 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/// Updates the grab state of the movable
|
||||
/// This exists to act as a hook for behaviour
|
||||
/atom/movable/proc/setGrabState(newstate)
|
||||
grab_state = newstate
|
||||
|
||||
/obj/item/proc/do_pickup_animation(atom/target)
|
||||
set waitfor = FALSE
|
||||
if(!istype(loc, /turf))
|
||||
|
||||
@@ -377,6 +377,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
qdel(src)
|
||||
item_flags &= ~IN_INVENTORY
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user)
|
||||
user.update_equipment_speed_mods()
|
||||
|
||||
// called just as an item is picked up (loc is not yet changed)
|
||||
/obj/item/proc/pickup(mob/user)
|
||||
@@ -422,6 +423,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
if(item_action_slot_check(slot, user, A)) //some items only give their actions buttons when in a specific slot.
|
||||
A.Grant(user)
|
||||
item_flags |= IN_INVENTORY
|
||||
user.update_equipment_speed_mods()
|
||||
|
||||
//sometimes we only want to grant the item's action if it's equipped in a specific slot.
|
||||
/obj/item/proc/item_action_slot_check(slot, mob/user, datum/action/A)
|
||||
|
||||
@@ -226,7 +226,6 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
. = ..()
|
||||
if(new_overlays)
|
||||
set_new_overlays()
|
||||
. += new_alert ? current_overlays[PDA_OVERLAY_ALERT] : current_overlays[PDA_OVERLAY_SCREEN]
|
||||
var/screen_state = new_alert ? current_overlays[PDA_OVERLAY_ALERT] : current_overlays[PDA_OVERLAY_SCREEN]
|
||||
var/mutable_appearance/overlay = mutable_appearance(icon, screen_state)
|
||||
overlay.pixel_x = overlays_x_offset
|
||||
|
||||
@@ -289,3 +289,29 @@
|
||||
item_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
|
||||
/obj/item/choice_beacon/music
|
||||
name = "instrument delivery beacon"
|
||||
desc = "Summon your tool of art."
|
||||
icon_state = "gangtool-red"
|
||||
|
||||
/obj/item/choice_beacon/music/generate_display_names()
|
||||
var/static/list/instruments
|
||||
if(!instruments)
|
||||
instruments = list()
|
||||
var/list/templist = list(/obj/item/instrument/violin,
|
||||
/obj/item/instrument/piano_synth,
|
||||
/obj/item/instrument/guitar,
|
||||
/obj/item/instrument/eguitar,
|
||||
/obj/item/instrument/glockenspiel,
|
||||
/obj/item/instrument/accordion,
|
||||
/obj/item/instrument/trumpet,
|
||||
/obj/item/instrument/saxophone,
|
||||
/obj/item/instrument/trombone,
|
||||
/obj/item/instrument/recorder,
|
||||
/obj/item/instrument/harmonica
|
||||
)
|
||||
for(var/V in templist)
|
||||
var/atom/A = V
|
||||
instruments[initial(A.name)] = A
|
||||
return instruments
|
||||
|
||||
@@ -283,6 +283,7 @@
|
||||
if(!C.legcuffed && C.get_num_legs(FALSE) >= 2) //beartrap can't cuff your leg if there's already a beartrap or legcuffs, or you don't have two legs.
|
||||
C.legcuffed = src
|
||||
forceMove(C)
|
||||
C.update_equipment_speed_mods()
|
||||
C.update_inv_legcuffed()
|
||||
SSblackbox.record_feedback("tally", "handcuffs", 1, type)
|
||||
else if(isanimal(L))
|
||||
|
||||
@@ -51,43 +51,37 @@
|
||||
item_state = "knight_hospitaller"
|
||||
// CITADEL CHANGES ENDS HERE
|
||||
|
||||
/obj/item/holybeacon
|
||||
/obj/item/choice_beacon/holy
|
||||
name = "armaments beacon"
|
||||
desc = "Contains a set of armaments for the chaplain."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "gangtool-red"
|
||||
item_state = "radio"
|
||||
|
||||
/obj/item/holybeacon/attack_self(mob/user)
|
||||
if(user.mind && (user.mind.isholy) && !GLOB.holy_armor_type)
|
||||
beacon_armor(user)
|
||||
/obj/item/choice_beacon/holy/canUseBeacon(mob/living/user)
|
||||
if(user.mind && user.mind.isholy)
|
||||
return ..()
|
||||
else
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 40, 1)
|
||||
return FALSE
|
||||
|
||||
/obj/item/holybeacon/proc/beacon_armor(mob/living/L)
|
||||
var/list/holy_armor_list = typesof(/obj/item/storage/box/holy)
|
||||
var/list/display_names = list()
|
||||
for(var/V in holy_armor_list)
|
||||
var/atom/A = V
|
||||
display_names += list(initial(A.name) = A)
|
||||
/obj/item/choice_beacon/holy/generate_display_names()
|
||||
var/static/list/holy_item_list
|
||||
if(!holy_item_list)
|
||||
holy_item_list = list()
|
||||
var/list/templist = typesof(/obj/item/storage/box/holy)
|
||||
for(var/V in templist)
|
||||
var/atom/A = V
|
||||
holy_item_list[initial(A.name)] = A
|
||||
return holy_item_list
|
||||
|
||||
var/choice = input(L,"What holy armor kit would you like to order?","Holy Armor Theme") as null|anything in display_names
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T || QDELETED(src) || !choice || !CHECK_MOBILITY(L, MOBILITY_USE) || !in_range(L, src) || GLOB.holy_armor_type)
|
||||
/obj/item/choice_beacon/holy/spawn_option(obj/choice,mob/living/M)
|
||||
if(!GLOB.holy_armor_type)
|
||||
..()
|
||||
playsound(src, 'sound/effects/pray_chaplain.ogg', 40, 1)
|
||||
SSblackbox.record_feedback("tally", "chaplain_armor", 1, "[choice]")
|
||||
GLOB.holy_armor_type = choice
|
||||
else
|
||||
to_chat(M, "<span class='warning'>A selection has already been made. Self-Destructing...</span>")
|
||||
return
|
||||
|
||||
var/index = display_names.Find(choice)
|
||||
var/A = holy_armor_list[index]
|
||||
|
||||
GLOB.holy_armor_type = A
|
||||
var/holy_armor_box = new A(T)
|
||||
|
||||
SSblackbox.record_feedback("tally", "chaplain_armor", 1, "[choice]")
|
||||
|
||||
if(holy_armor_box)
|
||||
qdel(src)
|
||||
L.put_in_hands(holy_armor_box)
|
||||
|
||||
/obj/item/storage/box/holy
|
||||
name = "Templar Kit"
|
||||
|
||||
|
||||
@@ -296,7 +296,7 @@
|
||||
if(!iscarbon(user))
|
||||
target.LAssailant = null
|
||||
else
|
||||
target.LAssailant = user
|
||||
target.LAssailant = WEAKREF(user)
|
||||
cooldown_check = world.time + cooldown
|
||||
user.adjustStaminaLossBuffered(getweight())//CIT CHANGE - makes swinging batons cost stamina
|
||||
else
|
||||
|
||||
@@ -12,6 +12,95 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
attack_verb = list("warned", "cautioned", "smashed")
|
||||
|
||||
/obj/item/choice_beacon
|
||||
name = "choice beacon"
|
||||
desc = "Hey, why are you viewing this?!! Please let Centcom know about this odd occurance."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "gangtool-blue"
|
||||
item_state = "radio"
|
||||
|
||||
/obj/item/choice_beacon/attack_self(mob/user)
|
||||
if(canUseBeacon(user))
|
||||
generate_options(user)
|
||||
|
||||
/obj/item/choice_beacon/proc/generate_display_names() // return the list that will be used in the choice selection. entries should be in (type.name = type) fashion. see choice_beacon/hero for how this is done.
|
||||
return list()
|
||||
|
||||
/obj/item/choice_beacon/proc/canUseBeacon(mob/living/user)
|
||||
if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return TRUE
|
||||
else
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 40, 1)
|
||||
return FALSE
|
||||
|
||||
/obj/item/choice_beacon/proc/generate_options(mob/living/M)
|
||||
var/list/display_names = generate_display_names()
|
||||
if(!display_names.len)
|
||||
return
|
||||
var/choice = input(M,"Which item would you like to order?","Select an Item") as null|anything in display_names
|
||||
if(!choice || !M.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
|
||||
spawn_option(display_names[choice],M)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/choice_beacon/proc/spawn_option(obj/choice,mob/living/M)
|
||||
var/obj/new_item = new choice()
|
||||
var/obj/structure/closet/supplypod/bluespacepod/pod = new()
|
||||
pod.explosionSize = list(0,0,0,0)
|
||||
new_item.forceMove(pod)
|
||||
var/msg = "<span class='danger'>After making your selection, you notice a strange target on the ground. It might be best to step back!</span>"
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(H.ears, /obj/item/radio/headset))
|
||||
msg = "You hear something crackle in your ears for a moment before a voice speaks. \"Please stand by for a message from Central Command. Message as follows: <span class='bold'>Item request received. Your package is inbound, please stand back from the landing site.</span> Message ends.\""
|
||||
to_chat(M, msg)
|
||||
|
||||
new /obj/effect/abstract/DPtarget(get_turf(src), pod)
|
||||
|
||||
/obj/item/choice_beacon/hero
|
||||
name = "heroic beacon"
|
||||
desc = "To summon heroes from the past to protect the future."
|
||||
|
||||
/obj/item/choice_beacon/hero/generate_display_names()
|
||||
var/static/list/hero_item_list
|
||||
if(!hero_item_list)
|
||||
hero_item_list = list()
|
||||
var/list/templist = typesof(/obj/item/storage/box/hero) //we have to convert type = name to name = type, how lovely!
|
||||
for(var/V in templist)
|
||||
var/atom/A = V
|
||||
hero_item_list[initial(A.name)] = A
|
||||
return hero_item_list
|
||||
|
||||
|
||||
/obj/item/storage/box/hero
|
||||
name = "Courageous Tomb Raider - 1940's."
|
||||
|
||||
/obj/item/storage/box/hero/PopulateContents()
|
||||
new /obj/item/clothing/head/fedora/curator(src)
|
||||
new /obj/item/clothing/suit/curator(src)
|
||||
new /obj/item/clothing/under/rank/curator/treasure_hunter(src)
|
||||
new /obj/item/clothing/shoes/workboots/mining(src)
|
||||
new /obj/item/melee/curator_whip(src)
|
||||
|
||||
/obj/item/storage/box/hero/astronaut
|
||||
name = "First Man on the Moon - 1960's."
|
||||
|
||||
/obj/item/storage/box/hero/astronaut/PopulateContents()
|
||||
new /obj/item/clothing/suit/space/nasavoid(src)
|
||||
new /obj/item/clothing/head/helmet/space/nasavoid(src)
|
||||
new /obj/item/tank/internals/emergency_oxygen/double(src)
|
||||
new /obj/item/gps(src)
|
||||
|
||||
/obj/item/storage/box/hero/scottish
|
||||
name = "Braveheart, the Scottish rebel - 1300's."
|
||||
|
||||
/obj/item/storage/box/hero/scottish/PopulateContents()
|
||||
new /obj/item/clothing/under/kilt(src)
|
||||
new /obj/item/claymore/weak/ceremonial(src)
|
||||
new /obj/item/toy/crayon/spraycan(src)
|
||||
new /obj/item/clothing/shoes/sandal(src)
|
||||
|
||||
/obj/item/skub
|
||||
desc = "It's skub."
|
||||
name = "skub"
|
||||
|
||||
@@ -314,3 +314,9 @@
|
||||
desc = "This one is rusted."
|
||||
force = 30
|
||||
armour_penetration = 15
|
||||
|
||||
/obj/item/claymore/weak/ceremonial
|
||||
desc = "A rusted claymore, once at the heart of a powerful scottish clan struck down and oppressed by tyrants, it has been passed down the ages as a symbol of defiance."
|
||||
force = 15
|
||||
block_chance = 30
|
||||
armour_penetration = 5
|
||||
@@ -1333,7 +1333,7 @@
|
||||
/obj/item/storage/box/beakers/bluespace=1,\
|
||||
/obj/item/storage/box/beakers/variety=1,\
|
||||
/obj/item/storage/box/material=1,\
|
||||
/obj/item/storage/belt/medical/surgery_belt_adv
|
||||
/obj/item/storage/belt/medical/surgery_belt_adv=1
|
||||
)
|
||||
generate_items_inside(items_inside, src)
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
/obj/item/melee/baton/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Right click attack while in combat mode to disarm instead of stun.</span>"
|
||||
. += "<span class='notice'>Right click attack while in combat mode or attack while in disarm intent to disarm instead of stun.</span>"
|
||||
|
||||
/obj/item/melee/baton/get_cell()
|
||||
. = cell
|
||||
@@ -149,6 +149,8 @@
|
||||
|
||||
//return TRUE to interrupt attack chain.
|
||||
/obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, disarming = FALSE)
|
||||
if(user.a_intent == INTENT_DISARM)
|
||||
disarming = TRUE //override if they're in disarm intent.
|
||||
if(iscyborg(M) || !isliving(M)) //can't baton cyborgs
|
||||
return FALSE
|
||||
if(status && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
icon_door = "black"
|
||||
|
||||
/obj/structure/closet/wardrobe/chaplain_black/PopulateContents()
|
||||
new /obj/item/holybeacon(src)
|
||||
new /obj/item/choice_beacon/holy(src)
|
||||
new /obj/item/clothing/accessory/pocketprotector/cosmetology(src)
|
||||
new /obj/item/clothing/under/rank/chaplain(src)
|
||||
new /obj/item/clothing/shoes/sneakers/black(src)
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
var/do_knockdown = !is_A_facing_B(target,owner) || owner.alpha <= 0 || istype(owner.loc, /obj/structure/closet)
|
||||
// CAUSES: Target has their back to me, I'm invisible, or I'm in a Closet
|
||||
// Step One: Heatseek toward Target's Turf
|
||||
addtimer(CALLBACK(owner, .proc/_walk, 0), 2 SECONDS)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/_walk, owner, 0), 2 SECONDS)
|
||||
target.playsound_local(get_turf(owner), 'sound/bloodsucker/lunge_warn.ogg', 60, FALSE, pressure_affected = FALSE) // target-only telegraphing
|
||||
owner.playsound_local(owner, 'sound/bloodsucker/lunge_warn.ogg', 60, FALSE, pressure_affected = FALSE) // audio feedback to the user
|
||||
if(do_mob(owner, owner, 7, TRUE, TRUE))
|
||||
|
||||
@@ -56,7 +56,10 @@
|
||||
/obj/item/clothing/shoes/magboots/advance/debug
|
||||
|
||||
/obj/item/clothing/shoes/magboots/advance/debug/Initialize()
|
||||
attack_self(src)
|
||||
. = ..()
|
||||
var/mob/living/L = loc
|
||||
if(istype(L))
|
||||
attack_self(L)
|
||||
|
||||
/obj/item/clothing/shoes/magboots/paramedic
|
||||
desc = "A pair of magboots decked in colors matching the equipment of an emergency medical technician."
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
/obj/item/reagent_containers/food/snacks/snowcones/blue
|
||||
name = "bluecherry snowcone"
|
||||
desc = "Bluecherry syrup drizzled over a snowball in a paper cup, how rare!"
|
||||
icon_state = "blue_sc"
|
||||
icon_state = "red_sc"
|
||||
list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/bluecherryjelly = 5)
|
||||
tastes = list("ice" = 1, "water" = 1, "blue" = 5, "cherries" = 5)
|
||||
foodtype = FRUIT
|
||||
@@ -148,7 +148,7 @@
|
||||
/obj/item/reagent_containers/food/snacks/snowcones/red
|
||||
name = "cherry snowcone"
|
||||
desc = "Cherry syrup drizzled over a snowball in a paper cup."
|
||||
icon_state = "red_sc"
|
||||
icon_state = "blue_sc"
|
||||
list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/cherryjelly = 5)
|
||||
tastes = list("ice" = 1, "water" = 1, "red" = 5, "cherries" = 5)
|
||||
foodtype = FRUIT
|
||||
@@ -223,7 +223,7 @@
|
||||
tastes = list("ice" = 1, "water" = 1, "cola" = 5)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/snowcones/spacemountainwind
|
||||
name = "Space Mountain Wind snowcone"
|
||||
name = "\improper Space Mountain Wind snowcone"
|
||||
desc = "Space Mountain Wind drizzled over a snowball in a paper cup."
|
||||
icon_state = "kiwi_sc"
|
||||
list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/spacemountainwind = 5)
|
||||
|
||||
@@ -201,10 +201,10 @@
|
||||
/obj/item/reagent_containers/food/snacks/donut/jelly/choco
|
||||
name = "chocolate jelly donut"
|
||||
desc = "Goes great with a glass of warm milk."
|
||||
icon_state = "jelly_choc"
|
||||
icon_state = "jelly_choco"
|
||||
bonus_reagents = list(/datum/reagent/consumable/hot_coco = 3, /datum/reagent/consumable/sprinkles = 1, /datum/reagent/consumable/nutriment/vitamin = 1) //the coco reagent is just bitter.
|
||||
tastes = list("jelly" = 1, "donut" = 4, "bitterness" = 1)
|
||||
decorated_icon = "jelly_choc_sprinkles"
|
||||
decorated_icon = "jelly_choco_sprinkles"
|
||||
filling_color = "#4F230D"
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/donut/jelly/blumpkin
|
||||
|
||||
@@ -349,10 +349,11 @@
|
||||
set_pin_data(IC_OUTPUT, 2, H.desc)
|
||||
|
||||
if(istype(H, /mob/living))
|
||||
var/mob/living/M = H
|
||||
var/msg = M.examine()
|
||||
var/mob/living/carbon/human/D = generate_or_wait_for_human_dummy(DUMMY_HUMAN_SLOT_EXAMINER)
|
||||
var/msg = H.examine(D)
|
||||
if(msg)
|
||||
set_pin_data(IC_OUTPUT, 2, msg)
|
||||
unset_busy_human_dummy(DUMMY_HUMAN_SLOT_EXAMINER)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 3, H.x-T.x)
|
||||
set_pin_data(IC_OUTPUT, 4, H.y-T.y)
|
||||
|
||||
@@ -2,16 +2,13 @@
|
||||
//returns TRUE if this mob has sufficient access to use this object
|
||||
/obj/proc/allowed(mob/M)
|
||||
//check if it doesn't require any access at all
|
||||
if(src.check_access(null))
|
||||
if(check_access(null))
|
||||
return TRUE
|
||||
if(!M)
|
||||
return FALSE
|
||||
if(hasSiliconAccessInArea(M))
|
||||
if(ispAI(M))
|
||||
return FALSE
|
||||
return TRUE //AI can do whatever it wants
|
||||
if(IsAdminGhost(M))
|
||||
//Access can't stop the abuse
|
||||
return TRUE
|
||||
else if(istype(M) && SEND_SIGNAL(M, COMSIG_MOB_ALLOWED, src))
|
||||
return TRUE //AI, robots and adminghosts can do whatever they want
|
||||
else if(SEND_SIGNAL(M, COMSIG_MOB_ALLOWED, src))
|
||||
return TRUE
|
||||
else if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
l_pocket = /obj/item/laser_pointer
|
||||
accessory = /obj/item/clothing/accessory/pocketprotector/full
|
||||
backpack_contents = list(
|
||||
/obj/item/melee/curator_whip = 1,
|
||||
/obj/item/choice_beacon/hero = 1,
|
||||
/obj/item/soapstone = 1,
|
||||
/obj/item/barcodescanner = 1
|
||||
)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
QDEL_LIST(stomach_contents)
|
||||
QDEL_LIST(bodyparts)
|
||||
QDEL_LIST(implants)
|
||||
hand_bodyparts = null //Just references out bodyparts, don't need to delete twice.
|
||||
remove_from_all_data_huds()
|
||||
QDEL_NULL(dna)
|
||||
GLOB.carbon_list -= src
|
||||
@@ -411,16 +412,16 @@
|
||||
else
|
||||
if(I == handcuffed)
|
||||
handcuffed.forceMove(drop_location())
|
||||
handcuffed.dropped(src)
|
||||
handcuffed = null
|
||||
I.dropped(src)
|
||||
if(buckled && buckled.buckle_requires_restraints)
|
||||
buckled.unbuckle_mob(src)
|
||||
update_handcuffed()
|
||||
return
|
||||
if(I == legcuffed)
|
||||
legcuffed.forceMove(drop_location())
|
||||
legcuffed.dropped()
|
||||
legcuffed = null
|
||||
I.dropped(src)
|
||||
update_inv_legcuffed()
|
||||
return
|
||||
else
|
||||
|
||||
@@ -1,15 +1,3 @@
|
||||
/mob/living/carbon/movement_delay()
|
||||
. = ..()
|
||||
. += grab_state * 3 //can't go fast while grabbing something.
|
||||
|
||||
if(!get_leg_ignore()) //ignore the fact we lack legs
|
||||
var/leg_amount = get_num_legs()
|
||||
. += 6 - 3*leg_amount //the fewer the legs, the slower the mob
|
||||
if(!leg_amount)
|
||||
. += 6 - 3*get_num_arms() //crawling is harder with fewer arms
|
||||
if(legcuffed)
|
||||
. += legcuffed.slowdown
|
||||
|
||||
/mob/living/carbon/slip(knockdown_amount, obj/O, lube)
|
||||
if(movement_type & FLYING && !(lube & FLYING_DOESNT_HELP))
|
||||
return FALSE
|
||||
|
||||
@@ -948,6 +948,22 @@
|
||||
if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
|
||||
visible_message("<span class='warning'>[src.name] regains their grip on \the [active_item]!</span>", "<span class='warning'>You regain your grip on \the [active_item]</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
/mob/living/carbon/human/updatehealth()
|
||||
. = ..()
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN))
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN)
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING)
|
||||
return
|
||||
var/stambufferinfluence = (bufferedstam*(100/stambuffer))*0.2 //CIT CHANGE - makes stamina buffer influence movedelay
|
||||
var/health_deficiency = ((100 + stambufferinfluence) - health + (getStaminaLoss()*0.75))//CIT CHANGE - reduces the impact of staminaloss and makes stamina buffer influence it
|
||||
if(health_deficiency >= 40)
|
||||
add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 75), blacklisted_movetypes = FLOATING|FLYING)
|
||||
add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 25), movetypes = FLOATING)
|
||||
else
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN)
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING)
|
||||
|
||||
/mob/living/carbon/human/do_after_coefficent()
|
||||
. = ..()
|
||||
. *= physiology.do_after_speed
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
/mob/living/carbon/human/movement_delay()
|
||||
. = ..()
|
||||
if(dna && dna.species)
|
||||
. += dna.species.movement_delay(src)
|
||||
if (m_intent == MOVE_INTENT_WALK && HAS_TRAIT(src, TRAIT_SPEEDY_STEP))
|
||||
. -= 1.5
|
||||
|
||||
/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube)
|
||||
if(HAS_TRAIT(src, TRAIT_NOSLIPALL))
|
||||
|
||||
@@ -145,6 +145,12 @@
|
||||
|
||||
return not_handled //For future deeper overrides
|
||||
|
||||
/mob/living/carbon/human/equipped_speed_mods()
|
||||
. = ..()
|
||||
for(var/sloties in get_all_slots())
|
||||
var/obj/item/thing = sloties
|
||||
. += thing?.slowdown
|
||||
|
||||
/mob/living/carbon/human/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE)
|
||||
var/index = get_held_index_of_item(I)
|
||||
. = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should.
|
||||
|
||||
@@ -1296,12 +1296,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(H.overeatduration < 100)
|
||||
to_chat(H, "<span class='notice'>You feel fit again!</span>")
|
||||
REMOVE_TRAIT(H, TRAIT_FAT, OBESITY)
|
||||
H.remove_movespeed_modifier(MOVESPEED_ID_FAT)
|
||||
H.update_inv_w_uniform()
|
||||
H.update_inv_wear_suit()
|
||||
else
|
||||
if(H.overeatduration >= 100)
|
||||
to_chat(H, "<span class='danger'>You suddenly feel blubbery!</span>")
|
||||
ADD_TRAIT(H, TRAIT_FAT, OBESITY)
|
||||
H.add_movespeed_modifier(MOVESPEED_ID_FAT, multiplicative_slowdown = 1.5)
|
||||
H.update_inv_w_uniform()
|
||||
H.update_inv_wear_suit()
|
||||
|
||||
@@ -1352,6 +1354,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
to_chat(H, "<span class='notice'>You no longer feel vigorous.</span>")
|
||||
H.metabolism_efficiency = 1
|
||||
|
||||
//Hunger slowdown for if mood isn't enabled
|
||||
if(CONFIG_GET(flag/disable_human_mood))
|
||||
if(!HAS_TRAIT(H, TRAIT_NOHUNGER))
|
||||
var/hungry = (500 - H.nutrition) / 5 //So overeat would be 100 and default level would be 80
|
||||
if(hungry >= 70)
|
||||
H.add_movespeed_modifier(MOVESPEED_ID_HUNGRY, override = TRUE, multiplicative_slowdown = (hungry / 50))
|
||||
else
|
||||
H.remove_movespeed_modifier(MOVESPEED_ID_HUNGRY)
|
||||
|
||||
switch(H.nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fat)
|
||||
@@ -1401,59 +1412,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.hair_style = "Bald"
|
||||
H.update_hair()
|
||||
|
||||
////////////////
|
||||
// MOVE SPEED //
|
||||
////////////////
|
||||
|
||||
/datum/species/proc/movement_delay(mob/living/carbon/human/H)
|
||||
. = 0 //We start at 0.
|
||||
var/flight = 0 //Check for flight and flying items
|
||||
var/gravity = 0
|
||||
if(H.movement_type & FLYING)
|
||||
flight = 1
|
||||
|
||||
gravity = H.has_gravity()
|
||||
|
||||
if (H.m_intent == MOVE_INTENT_WALK && HAS_TRAIT(H, TRAIT_SPEEDY_STEP))
|
||||
. -= 1.5
|
||||
|
||||
if(!HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN) && gravity)
|
||||
if(H.wear_suit)
|
||||
. += H.wear_suit.slowdown
|
||||
if(H.shoes)
|
||||
. += H.shoes.slowdown
|
||||
if(H.back)
|
||||
. += H.back.slowdown
|
||||
for(var/obj/item/I in H.held_items)
|
||||
if(I.item_flags & SLOWS_WHILE_IN_HAND)
|
||||
. += I.slowdown
|
||||
var/stambufferinfluence = (H.bufferedstam*(100/H.stambuffer))*0.2 //CIT CHANGE - makes stamina buffer influence movedelay
|
||||
var/health_deficiency = ((100 + stambufferinfluence) - H.health + (H.getStaminaLoss()*0.75))//CIT CHANGE - reduces the impact of staminaloss on movement speed and makes stamina buffer influence movedelay
|
||||
if(health_deficiency >= 40)
|
||||
if(flight)
|
||||
. += ((health_deficiency-39) / 75) // CIT CHANGE - adds -39 to health deficiency penalty to make the transition to low health movement a little less jarring
|
||||
else
|
||||
. += ((health_deficiency-39) / 25) // CIT CHANGE - ditto
|
||||
if(CONFIG_GET(flag/disable_human_mood))
|
||||
var/hungry = (500 - H.nutrition) / 5 //So overeat would be 100 and default level would be 80
|
||||
if((hungry >= 70) && !flight) //Being hungry will still allow you to use a flightsuit/wings.
|
||||
. += hungry / 50
|
||||
|
||||
//Moving in high gravity is very slow (Flying too)
|
||||
if(gravity > STANDARD_GRAVITY)
|
||||
var/grav_force = min(gravity - STANDARD_GRAVITY,3)
|
||||
. += 1 + grav_force
|
||||
|
||||
if(HAS_TRAIT(H, TRAIT_FAT))
|
||||
. += (1.5 - flight)
|
||||
if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
|
||||
. += (BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR
|
||||
return .
|
||||
|
||||
//////////////////
|
||||
// ATTACK PROCS //
|
||||
//////////////////
|
||||
|
||||
//////////////////
|
||||
// ATTACK PROCS //
|
||||
//////////////////
|
||||
@@ -2070,6 +2028,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold")
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "hot", /datum/mood_event/hot)
|
||||
|
||||
H.remove_movespeed_modifier(MOVESPEED_ID_COLD)
|
||||
|
||||
var/burn_damage
|
||||
var/firemodifier = H.fire_stacks / 50
|
||||
if (H.on_fire)
|
||||
@@ -2085,6 +2045,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold)
|
||||
//Sorry for the nasty oneline but I don't want to assign a variable on something run pretty frequently
|
||||
H.add_movespeed_modifier(MOVESPEED_ID_COLD, override = TRUE, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR))
|
||||
switch(H.bodytemperature)
|
||||
if(200 to BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
H.apply_damage(COLD_DAMAGE_LEVEL_1*coldmod*H.physiology.cold_mod, BURN)
|
||||
@@ -2094,6 +2056,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.apply_damage(COLD_DAMAGE_LEVEL_3*coldmod*H.physiology.cold_mod, BURN)
|
||||
|
||||
else
|
||||
H.remove_movespeed_modifier(MOVESPEED_ID_COLD)
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold")
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
|
||||
|
||||
|
||||
@@ -30,9 +30,10 @@
|
||||
|
||||
/mob/living/carbon/monkey/handle_mutations_and_radiation()
|
||||
if(radiation)
|
||||
if(radiation > RAD_MOB_MUTATE && prob((radiation - RAD_MOB_MUTATE) / 25))
|
||||
gorillize()
|
||||
return
|
||||
if(radiation > RAD_MONKEY_GORILLIZE)
|
||||
if(prob((((radiation - RAD_MONKEY_GORILLIZE + RAD_MOB_GORILLIZE_FACTOR)/RAD_MOB_GORILLIZE_FACTOR)^RAD_MONKEY_GORILLIZE_EXPONENT) - 1))
|
||||
gorillize()
|
||||
return
|
||||
if(radiation > RAD_MOB_KNOCKDOWN && prob(RAD_MOB_KNOCKDOWN_PROB))
|
||||
if(!recoveringstam)
|
||||
emote("collapse")
|
||||
|
||||
@@ -441,7 +441,7 @@
|
||||
to_chat(user, "You cannot send IC messages (muted).")
|
||||
return FALSE
|
||||
else if(!params)
|
||||
var/custom_emote = stripped_multiline_input("Choose an emote to display.", "Custom Emote", null, MAX_MESSAGE_LEN)
|
||||
var/custom_emote = stripped_multiline_input(user, "Choose an emote to display.", "Custom Emote", null, MAX_MESSAGE_LEN)
|
||||
if(custom_emote && !check_invalid(user, custom_emote))
|
||||
var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable")
|
||||
switch(type)
|
||||
|
||||
@@ -295,7 +295,7 @@
|
||||
if(!iscarbon(src))
|
||||
M.LAssailant = null
|
||||
else
|
||||
M.LAssailant = usr
|
||||
M.LAssailant = WEAKREF(usr)
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
//Share diseases that are spread by touch
|
||||
@@ -727,6 +727,7 @@
|
||||
return name
|
||||
|
||||
/mob/living/update_gravity(has_gravity,override = 0)
|
||||
. = ..()
|
||||
if(!SSticker.HasRoundStarted())
|
||||
return
|
||||
if(has_gravity)
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
return 0
|
||||
if(user.voremode && user.grab_state == GRAB_AGGRESSIVE)
|
||||
return 0
|
||||
user.grab_state++
|
||||
user.setGrabState(user.grab_state + 1)
|
||||
switch(user.grab_state)
|
||||
if(GRAB_AGGRESSIVE)
|
||||
var/add_log = ""
|
||||
|
||||
@@ -152,4 +152,17 @@
|
||||
if(CHECK_MOBILITY(src, MOBILITY_MOVE) && !intentionalresting && canstand_involuntary && iscarbon(src) && client?.prefs?.autostand)//CIT CHANGE - adds autostanding as a preference
|
||||
addtimer(CALLBACK(src, .proc/resist_a_rest, TRUE), 0) //CIT CHANGE - ditto
|
||||
|
||||
// Movespeed mods based on arms/legs quantity
|
||||
if(!get_leg_ignore())
|
||||
var/limbless_slowdown = 0
|
||||
// These checks for <2 should be swapped out for something else if we ever end up with a species with more than 2
|
||||
if(has_legs < 2)
|
||||
limbless_slowdown += 6 - (has_legs * 3)
|
||||
if(!has_legs && has_arms < 2)
|
||||
limbless_slowdown += 6 - (has_arms * 3)
|
||||
if(limbless_slowdown)
|
||||
add_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=limbless_slowdown, movetypes=GROUND)
|
||||
else
|
||||
remove_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE)
|
||||
|
||||
return mobility_flags
|
||||
|
||||
@@ -1004,3 +1004,28 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
end_multicam()
|
||||
|
||||
/mob/living/silicon/ai/verb/ai_cryo()
|
||||
set name = "AI Cryogenic Stasis"
|
||||
set desc = "Puts the current AI personality into cryogenic stasis, freeing the space for another."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(incapacitated())
|
||||
return
|
||||
switch(alert("Would you like to enter cryo? This will ghost you. Remember to AHELP before cryoing out of important roles, even with no admins online.",,"Yes.","No."))
|
||||
if("Yes.")
|
||||
src.ghostize(FALSE, penalize = TRUE)
|
||||
var/announce_rank = "Artificial Intelligence,"
|
||||
if(GLOB.announcement_systems.len)
|
||||
// Sends an announcement the AI has cryoed.
|
||||
var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems)
|
||||
announcer.announce("CRYOSTORAGE", src.real_name, announce_rank, list())
|
||||
new /obj/structure/AIcore/latejoin_inactive(loc)
|
||||
if(src.mind)
|
||||
//Handle job slot/tater cleanup.
|
||||
if(src.mind.assigned_role == "AI")
|
||||
SSjob.FreeRole("AI")
|
||||
src.mind.special_role = null
|
||||
qdel(src)
|
||||
else
|
||||
return
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
layer = BELOW_MOB_LAYER
|
||||
var/obj/item/instrument/piano_synth/internal_instrument
|
||||
silicon_privileges = PRIVILEDGES_PAI
|
||||
var/datum/element/mob_holder/current_mob_holder //because only a few of their chassis can be actually held.
|
||||
|
||||
var/network = "ss13"
|
||||
var/obj/machinery/camera/current = null
|
||||
@@ -142,6 +141,11 @@
|
||||
ALM.Grant(src)
|
||||
emitter_next_use = world.time + 10 SECONDS
|
||||
|
||||
/mob/living/silicon/pai/ComponentInitialize()
|
||||
. = ..()
|
||||
if(possible_chassis[chassis])
|
||||
AddElement(/datum/element/mob_holder, chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', ITEM_SLOT_HEAD)
|
||||
|
||||
/mob/living/silicon/pai/Life()
|
||||
if(hacking)
|
||||
process_hack()
|
||||
@@ -302,11 +306,11 @@
|
||||
/obj/item/paicard/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
user.set_machine(src)
|
||||
if(pai.encryptmod == TRUE)
|
||||
if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
pai.radio.attackby(W, user, params)
|
||||
else if(istype(W, /obj/item/encryptionkey))
|
||||
pai.radio.attackby(W, user, params)
|
||||
var/encryption_key_stuff = W.tool_behaviour == TOOL_SCREWDRIVER || istype(W, /obj/item/encryptionkey)
|
||||
if(!encryption_key_stuff)
|
||||
return
|
||||
if(pai?.encryptmod)
|
||||
pai.radio.attackby(W, user, params)
|
||||
else
|
||||
to_chat(user, "Encryption Key ports not configured.")
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
var/list/choices = list("Preset - Basic", "Preset - Dynamic")
|
||||
if(CONFIG_GET(flag/pai_custom_holoforms))
|
||||
choices += "Custom"
|
||||
var/old_chassis = chassis
|
||||
var/choicetype = input(src, "What type of chassis do you want to use?") as null|anything in choices
|
||||
if(!choicetype)
|
||||
return FALSE
|
||||
@@ -95,10 +96,11 @@
|
||||
dynamic_chassis = choice
|
||||
resist_a_rest(FALSE, TRUE)
|
||||
update_icon()
|
||||
current_mob_holder?.Detach(src)
|
||||
current_mob_holder = null
|
||||
if(possible_chassis[old_chassis])
|
||||
var/datum/element/mob_holder/M = SSdcs.GetElement(/datum/element/mob_holder, old_chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', ITEM_SLOT_HEAD)
|
||||
M.Detach(src)
|
||||
if(possible_chassis[chassis])
|
||||
current_mob_holder = AddElement(/datum/element/mob_holder, chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', ITEM_SLOT_HEAD)
|
||||
AddElement(/datum/element/mob_holder, chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', ITEM_SLOT_HEAD)
|
||||
to_chat(src, "<span class='boldnotice'>You switch your holochassis projection composite to [chassis]</span>")
|
||||
|
||||
/mob/living/silicon/pai/lay_down()
|
||||
|
||||
@@ -181,7 +181,7 @@
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
data["locked"] = locked
|
||||
data["siliconUser"] = hasSiliconAccessInArea(usr)
|
||||
data["siliconUser"] = hasSiliconAccessInArea(user)
|
||||
data["mode"] = mode ? mode_name[mode] : "Ready"
|
||||
data["modeStatus"] = ""
|
||||
switch(mode)
|
||||
|
||||
@@ -275,7 +275,7 @@
|
||||
H.dna.add_mutation(DWARFISM)
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/damaged/legioninfested/Initialize()
|
||||
var/type = pickweight(list("Miner" = 66, "Ashwalker" = 10, "Golem" = 10,"Clown" = 10, pick(list("Shadow", "YeOlde","Operative", "Cultist", "Lavaknight")) = 4)) //CIT CHANGE: Lavaknights
|
||||
var/type = pickweight(list("Miner" = 45, "Ashwalker" = 10, "Golem" = 10,"Clown" = 10, pick(list("Shadow", "YeOlde","Operative", "Cultist", "Lavaknight")) = 4, "Assistant" = 20, "Beelegion" = 1))
|
||||
switch(type)
|
||||
if("Miner")
|
||||
mob_species = pickweight(list(/datum/species/human = 70, /datum/species/lizard = 26, /datum/species/fly = 2, /datum/species/plasmaman = 2))
|
||||
@@ -374,13 +374,47 @@
|
||||
l_pocket = /obj/item/melee/cultblade/dagger
|
||||
glasses = /obj/item/clothing/glasses/hud/health/night/cultblind
|
||||
backpack_contents = list(/obj/item/reagent_containers/glass/beaker/unholywater = 1, /obj/item/cult_shift = 1, /obj/item/flashlight/flare/culttorch = 1, /obj/item/stack/sheet/runed_metal = 15)
|
||||
if("Lavaknight") //START OF CIT CHANGE
|
||||
if("Lavaknight")
|
||||
uniform = /obj/item/clothing/under/assistantformal
|
||||
mask = /obj/item/clothing/mask/breath
|
||||
shoes = /obj/item/clothing/shoes/sneakers/black
|
||||
r_pocket = /obj/item/melee/transforming/energy/sword/cx/broken
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/lavaknight
|
||||
suit_store = /obj/item/tank/internals/oxygen
|
||||
id = /obj/item/card/id/knight //END OF CIT CHANGE
|
||||
id = /obj/item/card/id/knight
|
||||
id_job = "Knight"
|
||||
if("Assistant")
|
||||
uniform = /obj/item/clothing/under/color/grey
|
||||
belt = /obj/item/tank/internals/emergency_oxygen
|
||||
mask = /obj/item/clothing/mask/gas
|
||||
ears = /obj/item/radio/headset
|
||||
gloves = /obj/item/clothing/gloves/color/fyellow
|
||||
id = /obj/item/card/id/silver/reaper //looks cool and has a fancy name but only a 1% chance
|
||||
back = /obj/item/storage/backpack
|
||||
backpack_contents = list(/obj/item/stack/cable_coil = 12, /obj/item/assembly/flash = 1, /obj/item/storage/fancy/donut_box = 1, /obj/item/storage/fancy/cigarettes/cigpack_shadyjims = 1, /obj/item/lighter = 1)
|
||||
if(prob(99))
|
||||
id = /obj/item/card/id
|
||||
id_job = "Assisant"
|
||||
if(prob(95))
|
||||
head = /obj/item/clothing/head/hardhat/red
|
||||
if(prob(5))
|
||||
gloves = /obj/item/clothing/gloves/color/yellow
|
||||
if(prob(10))
|
||||
back = /obj/item/twohanded/spear
|
||||
backpack_contents = null
|
||||
if(prob(90))
|
||||
r_pocket = /obj/item/kitchen/knife
|
||||
if(prob(60))
|
||||
l_pocket = /obj/item/soap/homemade
|
||||
if("Beelegion")
|
||||
uniform = /obj/item/clothing/under/color/yellow
|
||||
suit = /obj/item/clothing/suit/hooded/bee_costume
|
||||
shoes = /obj/item/clothing/shoes/sneakers/yellow
|
||||
gloves = /obj/item/clothing/gloves/color/yellow
|
||||
ears = /obj/item/radio/headset
|
||||
belt = /obj/item/storage/belt/fannypack/yellow
|
||||
id_job = "Assisant"
|
||||
id = /obj/item/card/id
|
||||
l_pocket = /obj/item/reagent_containers/food/drinks/soda_cans/buzz_fuzz
|
||||
mask = /obj/item/clothing/mask/rat/bee
|
||||
. = ..()
|
||||
|
||||
@@ -186,12 +186,13 @@
|
||||
if(M.stat == DEAD) // our victim died
|
||||
if(!client)
|
||||
if(!rabid && !attacked)
|
||||
if(M.LAssailant && M.LAssailant != M)
|
||||
var/mob/living/carbon/their_attacker = M.getLAssailant()
|
||||
if(their_attacker != M)
|
||||
if(prob(50))
|
||||
if(!(M.LAssailant in Friends))
|
||||
Friends[M.LAssailant] = 1
|
||||
if(!(their_attacker in Friends))
|
||||
Friends[their_attacker] = 1
|
||||
else
|
||||
++Friends[M.LAssailant]
|
||||
++Friends[their_attacker]
|
||||
else
|
||||
to_chat(src, "<i>This subject does not have a strong enough life energy anymore...</i>")
|
||||
|
||||
|
||||
@@ -70,7 +70,8 @@
|
||||
|
||||
var/colour = "grey"
|
||||
var/coretype = /obj/item/slime_extract/grey
|
||||
var/list/slime_mutation[4]
|
||||
var/list/slime_mutation
|
||||
var/static/list/color_mutation_cache = list()
|
||||
|
||||
var/static/list/slime_colours = list("rainbow", "grey", "purple", "metal", "orange",
|
||||
"blue", "dark blue", "dark purple", "yellow", "silver", "pink", "red",
|
||||
@@ -84,6 +85,7 @@
|
||||
|
||||
|
||||
/mob/living/simple_animal/slime/Initialize(mapload, new_colour="grey", new_is_adult=FALSE)
|
||||
initialize_mutations()
|
||||
var/datum/action/innate/slime/feed/F = new
|
||||
F.Grant(src)
|
||||
|
||||
@@ -108,10 +110,16 @@
|
||||
AC.Remove(src)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/slime/proc/initialize_mutations()
|
||||
var/list/cached = color_mutation_cache[colour]
|
||||
if(!cached)
|
||||
cached = color_mutation_cache[colour] = mutation_table(colour)
|
||||
slime_mutation = cached
|
||||
|
||||
/mob/living/simple_animal/slime/proc/set_colour(new_colour)
|
||||
colour = new_colour
|
||||
update_name()
|
||||
slime_mutation = mutation_table(colour)
|
||||
initialize_mutations()
|
||||
var/sanitizedcolour = replacetext(colour, " ", "")
|
||||
coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]")
|
||||
regenerate_icons()
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
GLOB.all_clockwork_mobs -= src
|
||||
GLOB.mob_directory -= tag
|
||||
focus = null
|
||||
LAssailant = null
|
||||
movespeed_modification = null
|
||||
for (var/alert in alerts)
|
||||
clear_alert(alert, TRUE)
|
||||
if(observers && observers.len)
|
||||
@@ -949,3 +951,28 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
/mob/setMovetype(newval)
|
||||
. = ..()
|
||||
update_movespeed(FALSE)
|
||||
|
||||
/mob/proc/getLAssailant()
|
||||
return LAssailant?.resolve()
|
||||
|
||||
/// Updates the grab state of the mob and updates movespeed
|
||||
/mob/setGrabState(newstate)
|
||||
. = ..()
|
||||
if(grab_state == GRAB_PASSIVE)
|
||||
remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE, update=TRUE)
|
||||
else
|
||||
add_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=grab_state*3, blacklisted_movetypes=FLOATING)
|
||||
|
||||
/mob/proc/update_equipment_speed_mods()
|
||||
var/speedies = equipped_speed_mods()
|
||||
if(!speedies)
|
||||
remove_movespeed_modifier(MOVESPEED_ID_MOB_EQUIPMENT, update=TRUE)
|
||||
else
|
||||
add_movespeed_modifier(MOVESPEED_ID_MOB_EQUIPMENT, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=speedies, blacklisted_movetypes=FLOATING)
|
||||
|
||||
/// Gets the combined speed modification of all worn items
|
||||
/// Except base mob type doesnt really wear items
|
||||
/mob/proc/equipped_speed_mods()
|
||||
for(var/obj/item/I in held_items)
|
||||
if(I.item_flags & SLOWS_WHILE_IN_HAND)
|
||||
. += I.slowdown
|
||||
|
||||
@@ -80,8 +80,8 @@
|
||||
var/list/faction = list("neutral") //A list of factions that this mob is currently in, for hostile mob targetting, amongst other things
|
||||
var/move_on_shuttle = 1 // Can move on the shuttle.
|
||||
|
||||
//The last mob/living/carbon to push/drag/grab this mob (mostly used by slimes friend recognition)
|
||||
var/mob/living/carbon/LAssailant = null
|
||||
/// The last mob/living/carbon to push/drag/grab this mob (mostly used by slimes friend recognition)
|
||||
var/datum/weakref/LAssailant
|
||||
|
||||
var/list/obj/user_movement_hooks //Passes movement in client/Move() to these!
|
||||
|
||||
|
||||
@@ -249,8 +249,12 @@
|
||||
/mob/proc/slip(s_amount, w_amount, obj/O, lube)
|
||||
return
|
||||
|
||||
/mob/proc/update_gravity()
|
||||
return
|
||||
/mob/proc/update_gravity(has_gravity, override=FALSE)
|
||||
var/speed_change = max(0, has_gravity - STANDARD_GRAVITY)
|
||||
if(!speed_change)
|
||||
remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAVITY, update=TRUE)
|
||||
else
|
||||
add_movespeed_modifier(MOVESPEED_ID_MOB_GRAVITY, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=speed_change, blacklisted_movetypes=FLOATING)
|
||||
|
||||
//bodypart selection - Cyberboss
|
||||
//8 toggles through head - eyes - mouth
|
||||
|
||||
@@ -37,8 +37,7 @@
|
||||
var/mindrain = 200
|
||||
var/maxdrain = 400
|
||||
|
||||
var/stunforce = 140 //Same as stunbaton, adjustable.
|
||||
|
||||
var/stunforce = 100
|
||||
|
||||
/obj/item/clothing/gloves/space_ninja/Touch(atom/A,proximity)
|
||||
if(!candrain || draining)
|
||||
|
||||
@@ -22,7 +22,7 @@ Contents:
|
||||
/obj/item/clothing/mask/gas/space_ninja/handle_speech(datum/source, list/speech_args)
|
||||
var/message = speech_args[SPEECH_MESSAGE]
|
||||
if(message[1] != "*")
|
||||
var/list/temp_message = text2list(message, " ")
|
||||
var/list/temp_message = splittext(message, " ")
|
||||
var/list/pick_list = list()
|
||||
for(var/i in 1 to temp_message.len)
|
||||
pick_list += i
|
||||
@@ -32,7 +32,7 @@ Contents:
|
||||
continue
|
||||
temp_message[H] = ninjaspeak(temp_message[H])
|
||||
pick_list -= H
|
||||
message = list2text(temp_message, " ")
|
||||
message = temp_message.Join(" ")
|
||||
|
||||
//The Alternate speech mod is now the main one.
|
||||
message = replacetext(message, "l", "r")
|
||||
|
||||
@@ -264,7 +264,6 @@ They *could* go in their appropriate files, but this is supposed to be modular
|
||||
electrocute_act(15, H)
|
||||
|
||||
DefaultCombatKnockdown(G.stunforce)
|
||||
adjustStaminaLoss(G.stunforce*0.1, affected_zone = (istype(H) ? H.zone_selected : BODY_ZONE_CHEST))
|
||||
apply_effect(EFFECT_STUTTER, G.stunforce)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_MINOR_SHOCK)
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
reagents.reaction(target, TOUCH)
|
||||
|
||||
else if(bartender_check(target) && thrown)
|
||||
visible_message("<span class='notice'>[src] lands onto the [target.name] without spilling a single drop.</span>")
|
||||
visible_message("<span class='notice'>[src] lands without spilling a single drop.</span>")
|
||||
transform = initial(transform)
|
||||
addtimer(CALLBACK(src, .proc/ForceResetRotation), 1)
|
||||
|
||||
@@ -153,11 +153,10 @@
|
||||
log_reagent("SPLASH - [src] object SplashReagents() onto [target] at [T] ([AREACOORD(T)])[throwerstring] - [reagents.log_list()]")
|
||||
visible_message("<span class='notice'>[src] spills its contents all over [target].</span>")
|
||||
reagents.reaction(target, TOUCH)
|
||||
reagents.clear_reagents()
|
||||
if(QDELETED(src))
|
||||
return
|
||||
|
||||
reagents.clear_reagents()
|
||||
|
||||
//melts plastic beakers
|
||||
/obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M)
|
||||
reagents.expose_temperature(1000)
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
else
|
||||
target.visible_message("<span class='danger'>[user] has placed [target] in [src].</span>", "<span class='userdanger'>[user] has placed [target] in [src].</span>")
|
||||
log_combat(user, target, "stuffed", addition="into [src]")
|
||||
target.LAssailant = user
|
||||
target.LAssailant = WEAKREF(user)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/disposal/proc/can_stuff_mob_in(mob/living/target, mob/living/user, pushing = FALSE)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
rogue_types = list(/datum/nanite_program/toxic, /datum/nanite_program/nerve_decay)
|
||||
|
||||
/datum/nanite_program/adrenaline/on_trigger()
|
||||
host_mob.do_adrenaline(-10, TRUE, TRUE, FALSE, TRUE, list(/datum/reagent/medicine/stimulants = 1.5), "<span class='notice'>You feel a sudden surge of energy!</span>", FALSE, FALSE, FALSE)
|
||||
host_mob.do_adrenaline(50, TRUE, TRUE, FALSE, TRUE, list(), "<span class='notice'>You feel a sudden surge of energy!</span>", 25)
|
||||
|
||||
/datum/nanite_program/hardening
|
||||
name = "Dermal Hardening"
|
||||
|
||||
@@ -236,7 +236,7 @@
|
||||
if(X.monkeys >= 1)
|
||||
var/mob/living/carbon/monkey/food = new /mob/living/carbon/monkey(remote_eye.loc, TRUE, owner)
|
||||
if (!QDELETED(food))
|
||||
food.LAssailant = C
|
||||
food.LAssailant = WEAKREF(C)
|
||||
X.monkeys --
|
||||
to_chat(owner, "<span class='notice'>[X] now has [X.monkeys] monkey(s) left.</span>")
|
||||
else
|
||||
@@ -474,7 +474,7 @@
|
||||
if(X.monkeys >= 1)
|
||||
var/mob/living/carbon/monkey/food = new /mob/living/carbon/monkey(T, TRUE, C)
|
||||
if (!QDELETED(food))
|
||||
food.LAssailant = C
|
||||
food.LAssailant = WEAKREF(C)
|
||||
X.monkeys--
|
||||
X.monkeys = round(X.monkeys, 0.1) //Prevents rounding errors
|
||||
to_chat(C, "<span class='notice'>[X] now has [X.monkeys] monkey(s) stored.</span>")
|
||||
|
||||
@@ -190,17 +190,21 @@
|
||||
name = "CuraDrobe"
|
||||
desc = "A lowstock vendor only capable of vending clothing for curators and librarians."
|
||||
icon_state = "curadrobe"
|
||||
product_ads = "Our clothes are endorsed by treasure hunters everywhere!"
|
||||
product_ads = "Glasses for your eyes and literature for your soul, Curadrobe has it all!; Impress & enthrall your library guests with Curadrobe's extended line of pens!"
|
||||
vend_reply = "Thank you for using the CuraDrobe!"
|
||||
products = list(/obj/item/clothing/head/fedora/curator = 2,
|
||||
/obj/item/clothing/suit/curator = 2,
|
||||
products = list(/obj/item/pen = 4,
|
||||
/obj/item/pen/red = 2,
|
||||
/obj/item/pen/blue = 2,
|
||||
/obj/item/pen/fourcolor = 1,
|
||||
/obj/item/pen/fountain = 2,
|
||||
/obj/item/clothing/accessory/pocketprotector = 2,
|
||||
/obj/item/clothing/under/rank/curator/skirt = 2,
|
||||
/obj/item/clothing/under/gimmick/rank/captain/suit/skirt = 2,
|
||||
/obj/item/clothing/under/gimmick/rank/head_of_personnel/suit/skirt = 2,
|
||||
/obj/item/clothing/under/rank/curator/treasure_hunter = 2,
|
||||
/obj/item/clothing/shoes/workboots/mining = 2,
|
||||
/obj/item/storage/backpack/satchel/explorer = 2,
|
||||
/obj/item/storage/bag/books = 2)
|
||||
/obj/item/storage/backpack/satchel/explorer = 1,
|
||||
/obj/item/clothing/glasses/regular = 2,
|
||||
/obj/item/clothing/glasses/regular/jamjar = 1,
|
||||
/obj/item/storage/bag/books = 1)
|
||||
refill_canister = /obj/item/vending_refill/wardrobe/curator_wardrobe
|
||||
|
||||
/obj/item/vending_refill/wardrobe/curator_wardrobe
|
||||
@@ -327,7 +331,7 @@
|
||||
icon_state = "chapdrobe"
|
||||
product_ads = "Are you being bothered by cultists or pesky revenants? Then come and dress like the holy man!;Clothes for men of the cloth!"
|
||||
vend_reply = "Thank you for using the ChapDrobe!"
|
||||
products = list(/obj/item/holybeacon = 1,
|
||||
products = list(/obj/item/choice_beacon/holy = 1,
|
||||
/obj/item/storage/backpack/cultpack = 2,
|
||||
/obj/item/clothing/accessory/pocketprotector/cosmetology = 2,
|
||||
/obj/item/clothing/under/rank/chaplain = 2,
|
||||
@@ -415,7 +419,7 @@
|
||||
req_access = list(ACCESS_CAPTAIN)
|
||||
vend_reply = "A wonderful day to you, great leader."
|
||||
products = list(/obj/item/clothing/suit/hooded/wintercoat/captain = 1,
|
||||
/obj/item/storage/backpack/captain = 1,
|
||||
/obj/item/storage/backpack/captain = 1,
|
||||
/obj/item/storage/backpack/satchel/cap = 1,
|
||||
/obj/item/storage/backpack/duffelbag/captain = 1,
|
||||
/obj/item/clothing/neck/cloak/cap = 1,
|
||||
@@ -436,4 +440,3 @@
|
||||
/obj/item/vending_refill/wardrobe/cap_wardrobe
|
||||
machine_name = "Captain's Wardrobe"
|
||||
icon_state = "refill_caps"
|
||||
|
||||
@@ -161,6 +161,8 @@
|
||||
SSbellies.belly_list -= src
|
||||
if(owner?.vore_organs)
|
||||
owner.vore_organs -= src
|
||||
if(owner.vore_selected == src)
|
||||
owner.vore_selected = null
|
||||
owner = null
|
||||
. = ..()
|
||||
|
||||
@@ -413,7 +415,7 @@
|
||||
if("em")
|
||||
raw_messages = examine_messages
|
||||
|
||||
var/messages = list2text(raw_messages,delim)
|
||||
var/messages = raw_messages.Join(delim)
|
||||
return messages
|
||||
|
||||
// The next function sets the messages on the belly, from human-readable var
|
||||
@@ -422,7 +424,7 @@
|
||||
/obj/belly/proc/set_messages(var/raw_text, var/type, var/delim = "\n\n")
|
||||
ASSERT(type == "smo" || type == "smi" || type == "dmo" || type == "dmp" || type == "em")
|
||||
|
||||
var/list/raw_list = text2list(html_encode(raw_text),delim)
|
||||
var/list/raw_list = splittext(html_encode(raw_text),delim)
|
||||
if(raw_list.len > 10)
|
||||
raw_list.Cut(11)
|
||||
testing("[owner] tried to set [lowertext(name)] with 11+ messages")
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
swallow_time = istype(prey, /mob/living/carbon/human) ? belly.human_prey_swallow_time : belly.nonhuman_prey_swallow_time
|
||||
|
||||
//Timer and progress bar
|
||||
if(!do_after(user, swallow_time, prey))
|
||||
if(!do_after(user, swallow_time, TRUE, prey))
|
||||
return FALSE // Prey escaped (or user disabled) before timer expired.
|
||||
|
||||
if(!prey.Adjacent(user)) //double check'd just in case they moved during the timer and the do_mob didn't fail for whatever reason
|
||||
|
||||
@@ -574,7 +574,7 @@
|
||||
if(new_bulge == 0) //Disable.
|
||||
selected.bulge_size = 0
|
||||
to_chat(user,"<span class='notice'>Your stomach will not be seen on examine.</span>")
|
||||
else if (!IsInRange(new_bulge,25,200))
|
||||
else if (!ISINRANGE(new_bulge,25,200))
|
||||
selected.bulge_size = 0.25 //Set it to the default.
|
||||
to_chat(user,"<span class='notice'>Invalid size.</span>")
|
||||
else if(new_bulge)
|
||||
|
||||
Reference in New Issue
Block a user