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

This commit is contained in:
kevinz000
2020-02-13 00:39:20 -07:00
481 changed files with 10666 additions and 9059 deletions
+72
View File
@@ -549,6 +549,70 @@
cooldown = world.time
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
/datum/action/item_action/removeAPCs
name = "Relinquish APC"
desc = "Let go of an APC, relinquish control back to the station."
icon_icon = 'icons/obj/implants.dmi'
button_icon_state = "hijackx"
/datum/action/item_action/removeAPCs/Trigger()
var/list/areas = list()
for (var/area/a in owner.siliconaccessareas)
areas[a.name] = a
var/removeAPC = input("Select an APC to remove:","Remove APC Control",1) as null|anything in areas
if (!removeAPC)
return
var/area/area = areas[removeAPC]
var/obj/machinery/power/apc/apc = area.get_apc()
if (!apc || !(area in owner.siliconaccessareas))
return
apc.hijacker = null
apc.update_icon()
apc.set_hijacked_lighting()
owner.toggleSiliconAccessArea(area)
/datum/action/item_action/accessAPCs
name = "Access APC Interface"
desc = "Open the APC's interface."
icon_icon = 'icons/obj/implants.dmi'
button_icon_state = "hijacky"
/datum/action/item_action/accessAPCs/Trigger()
var/list/areas = list()
for (var/area/a in owner.siliconaccessareas)
areas[a.name] = a
var/accessAPC = input("Select an APC to access:","Access APC Interface",1) as null|anything in areas
if (!accessAPC)
return
var/area/area = areas[accessAPC]
var/obj/machinery/power/apc/apc = area.get_apc()
if (!apc || !(area in owner.siliconaccessareas))
return
apc.ui_interact(owner)
/datum/action/item_action/stealthmodetoggle
name = "Toggle Stealth Mode"
desc = "Toggles the stealth mode on the hijack implant."
icon_icon = 'icons/obj/implants.dmi'
button_icon_state = "hijackz"
/datum/action/item_action/stealthmodetoggle/Trigger()
var/obj/item/implant/hijack/H = target
if (!istype(H))
return
if (H.stealthcooldown > world.time)
to_chat(owner,"<span class='warning'>The hijack implant's stealth mode toggle is still rebooting!</span>")
return
H.stealthmode = !H.stealthmode
for (var/area/area in H.imp_in.siliconaccessareas)
var/obj/machinery/power/apc/apc = area.get_apc()
if (apc)
apc.set_hijacked_lighting()
apc.update_icon()
H.stealthcooldown = world.time + 15 SECONDS
H.toggle_eyes()
to_chat(owner,"<span class='notice'>You toggle the hijack implant's stealthmode [H.stealthmode ? "on" : "off"].</span>")
/datum/action/item_action/flash
name = "Flash"
@@ -761,3 +825,11 @@
target.layer = old_layer
target.plane = old_plane
current_button.appearance_cache = target.appearance
/proc/get_action_of_type(mob/M, var/action_type)
if(!M.actions || !ispath(action_type, /datum/action))
return
for(var/datum/action/A in M.actions)
if(istype(A, action_type))
return A
return
+86 -99
View File
@@ -16,41 +16,43 @@
var/viewing_category = 1 //typical powergamer starting on the Weapons tab
var/viewing_subcategory = 1
var/list/categories = list(
CAT_WEAPONRY,
CAT_ROBOT,
CAT_MISC,
CAT_PRIMAL,
CAT_FOOD,
CAT_CLOTHING)
var/list/subcategories = list(
list( //Weapon subcategories
CAT_WEAPON,
CAT_AMMO),
CAT_NONE, //Robot subcategories
CAT_NONE, //Misc subcategories
CAT_NONE, //Tribal subcategories
list( //Food subcategories
CAT_BREAD,
CAT_BURGER,
CAT_CAKE,
CAT_EGG,
CAT_FISH,
CAT_ICE, //Called Frozen
CAT_MEAT,
CAT_MISCFOOD,
CAT_PASTRY,
CAT_PIE,
CAT_PIZZA,
CAT_SALAD,
CAT_SANDWICH,
CAT_SOUP,
CAT_SPAGHETTI),
CAT_NONE) //Clothing subcategories
CAT_WEAPONRY = list(
CAT_WEAPON,
CAT_AMMO,
),
CAT_ROBOT = CAT_NONE,
CAT_MISC = CAT_NONE,
CAT_PRIMAL = CAT_NONE,
CAT_FOOD = list(
CAT_BREAD,
CAT_BURGER,
CAT_CAKE,
CAT_EGG,
CAT_FISH,
CAT_ICE,
CAT_MEAT,
CAT_MISCFOOD,
CAT_PASTRY,
CAT_PIE,
CAT_PIZZA,
CAT_SALAD,
CAT_SANDWICH,
CAT_SOUP,
CAT_SPAGHETTI,
),
CAT_DRINK = CAT_NONE,
CAT_CLOTHING = CAT_NONE,
)
var/cur_category = CAT_NONE
var/cur_subcategory = CAT_NONE
var/datum/action/innate/crafting/button
var/display_craftable_only = FALSE
var/display_compact = TRUE
/* This is what procs do:
get_environment - gets a list of things accessable for crafting by user
get_surroundings - takes a list of things and makes a list of key-types to values-amounts of said type in the list
@@ -60,6 +62,9 @@
del_reqs - takes recipe and a user, loops over the recipes reqs var and tries to find everything in the list make by get_environment and delete it/add to parts list, then returns the said list
*/
/datum/component/personal_crafting/proc/check_contents(datum/crafting_recipe/R, list/contents)
contents = contents["other"]
main_loop:
@@ -77,11 +82,11 @@
continue main_loop
else
continue
return 0
return FALSE
for(var/A in R.chem_catalysts)
if(contents[A] < R.chem_catalysts[A])
return 0
return 1
return FALSE
return TRUE
/datum/component/personal_crafting/proc/get_environment(mob/user)
. = list()
@@ -307,43 +312,65 @@
/datum/component/personal_crafting/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.not_incapacitated_turf_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
cur_category = categories[1]
if(islist(categories[cur_category]))
var/list/subcats = categories[cur_category]
cur_subcategory = subcats[1]
else
cur_subcategory = CAT_NONE
ui = new(user, src, ui_key, "personal_crafting", "Crafting Menu", 700, 800, master_ui, state)
ui.open()
/datum/component/personal_crafting/ui_data(mob/user)
var/list/data = list()
var/list/subs = list()
var/cur_subcategory = CAT_NONE
var/cur_category = categories[viewing_category]
if (islist(subcategories[viewing_category]))
subs = subcategories[viewing_category]
cur_subcategory = subs[viewing_subcategory]
data["busy"] = busy
data["prev_cat"] = categories[prev_cat()]
data["prev_subcat"] = subs[prev_subcat()]
data["category"] = cur_category
data["subcategory"] = cur_subcategory
data["next_cat"] = categories[next_cat()]
data["next_subcat"] = subs[next_subcat()]
data["display_craftable_only"] = display_craftable_only
data["display_compact"] = display_compact
var/list/surroundings = get_surroundings(user)
var/list/can_craft = list()
var/list/cant_craft = list()
var/list/craftability = list()
for(var/rec in GLOB.crafting_recipes)
var/datum/crafting_recipe/R = rec
if(!R.always_availible && !(R.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this.
continue
if((R.category != cur_category) || (R.subcategory != cur_subcategory))
continue
if(check_contents(R, surroundings))
can_craft += list(build_recipe_data(R))
craftability["[REF(R)]"] = check_contents(R, surroundings)
data["craftability"] = craftability
return data
/datum/component/personal_crafting/ui_static_data(mob/user)
var/list/data = list()
var/list/crafting_recipes = list()
for(var/rec in GLOB.crafting_recipes)
var/datum/crafting_recipe/R = rec
if(R.name == "") //This is one of the invalid parents that sneaks in
continue
if(!R.always_availible && !(R.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this.
continue
if(isnull(crafting_recipes[R.category]))
crafting_recipes[R.category] = list()
if(R.subcategory == CAT_NONE)
crafting_recipes[R.category] += list(build_recipe_data(R))
else
cant_craft += list(build_recipe_data(R))
data["can_craft"] = can_craft
data["cant_craft"] = cant_craft
if(isnull(crafting_recipes[R.category][R.subcategory]))
crafting_recipes[R.category][R.subcategory] = list()
crafting_recipes[R.category]["has_subcats"] = TRUE
crafting_recipes[R.category][R.subcategory] += list(build_recipe_data(R))
data["crafting_recipes"] = crafting_recipes
return data
@@ -361,60 +388,21 @@
else
to_chat(usr, "<span class='warning'>Construction failed[fail_msg]</span>")
busy = FALSE
if("forwardCat") //Meow
viewing_category = next_cat(FALSE)
. = TRUE
if("backwardCat")
viewing_category = prev_cat(FALSE)
. = TRUE
if("forwardSubCat")
viewing_subcategory = next_subcat()
. = TRUE
if("backwardSubCat")
viewing_subcategory = prev_subcat()
. = TRUE
if("toggle_recipes")
display_craftable_only = !display_craftable_only
. = TRUE
if("toggle_compact")
display_compact = !display_compact
. = TRUE
//Next works nicely with modular arithmetic
/datum/component/personal_crafting/proc/next_cat(readonly = TRUE)
if (!readonly)
viewing_subcategory = 1
. = viewing_category % categories.len + 1
/datum/component/personal_crafting/proc/next_subcat()
if(islist(subcategories[viewing_category]))
var/list/subs = subcategories[viewing_category]
. = viewing_subcategory % subs.len + 1
//Previous can go fuck itself
/datum/component/personal_crafting/proc/prev_cat(readonly = TRUE)
if (!readonly)
viewing_subcategory = 1
if(viewing_category == categories.len)
. = viewing_category-1
else
. = viewing_category % categories.len - 1
if(. <= 0)
. = categories.len
/datum/component/personal_crafting/proc/prev_subcat()
if(islist(subcategories[viewing_category]))
var/list/subs = subcategories[viewing_category]
if(viewing_subcategory == subs.len)
. = viewing_subcategory-1
else
. = viewing_subcategory % subs.len - 1
if(. <= 0)
. = subs.len
else
. = null
if("set_category")
if(!isnull(params["category"]))
cur_category = params["category"]
if(!isnull(params["subcategory"]))
if(params["subcategory"] == "0")
cur_subcategory = ""
else
cur_subcategory = params["subcategory"]
. = TRUE
/datum/component/personal_crafting/proc/build_recipe_data(datum/crafting_recipe/R)
var/list/data = list()
@@ -455,4 +443,3 @@
if(!learned_recipes)
learned_recipes = list()
learned_recipes |= R
@@ -1,10 +1,3 @@
/datum/crafting_recipe/bonearmor
name = "Bone Armor"
result = /obj/item/clothing/suit/armor/bone
time = 30
reqs = list(/obj/item/stack/sheet/bone = 6)
category = CAT_PRIMAL
/datum/crafting_recipe/bonetalisman
name = "Bone Talisman"
result = /obj/item/clothing/accessory/talisman
@@ -29,13 +22,6 @@
/obj/item/stack/sheet/sinew = 1)
category = CAT_PRIMAL
/datum/crafting_recipe/skullhelm
name = "Skull Helmet"
result = /obj/item/clothing/head/helmet/skull
time = 30
reqs = list(/obj/item/stack/sheet/bone = 4)
category = CAT_PRIMAL
/datum/crafting_recipe/goliathcloak
name = "Goliath Cloak"
result = /obj/item/clothing/suit/hooded/cloak/goliath
@@ -62,13 +48,6 @@
/obj/item/stack/sheet/sinew = 2)
category = CAT_PRIMAL
/datum/crafting_recipe/bonedagger
name = "Bone Dagger"
result = /obj/item/kitchen/knife/combat/bone
time = 20
reqs = list(/obj/item/stack/sheet/bone = 2)
category = CAT_PRIMAL
/datum/crafting_recipe/bonespear
name = "Bone Spear"
result = /obj/item/twohanded/bonespear
@@ -56,7 +56,7 @@
/obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector,
/obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/dropper,
/obj/item/implanter, /obj/item/screwdriver, /obj/item/weldingtool/mini,
/obj/item/firing_pin, /obj/item/gun/ballistic/automatic/pistol
/obj/item/firing_pin, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/automatic/magrifle/pistol
))
/datum/component/storage/concrete/pockets/shoes/clown/Initialize()
+3 -2
View File
@@ -25,6 +25,7 @@ GLOBAL_LIST_EMPTY(uplinks)
var/unlock_code
var/failsafe_code
var/datum/ui_state/checkstate
var/debug = FALSE
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20, datum/ui_state/_checkstate)
if(!isitem(parent))
@@ -152,7 +153,7 @@ GLOBAL_LIST_EMPTY(uplinks)
if(I.restricted_roles.len)
var/is_inaccessible = 1
for(var/R in I.restricted_roles)
if(R == user.mind.assigned_role)
if(R == user.mind.assigned_role || debug)
is_inaccessible = 0
if(is_inaccessible)
continue
@@ -294,4 +295,4 @@ GLOBAL_LIST_EMPTY(uplinks)
if(!T)
return
explosion(T,1,2,3)
qdel(parent) //Alternatively could brick the uplink.
qdel(parent) //Alternatively could brick the uplink.
@@ -448,9 +448,11 @@
symptom_delay_max = 1
passive_message = "<span class='notice'>Your skin glows faintly for a moment.</span>"
var/cellular_damage = FALSE
threshold_desc = "<b>Transmission 6:</b> Additionally heals cellular damage and toxin lovers.<br>\
<b>Resistance 7:</b> Increases healing speed."
threshold_desc = list(
"Transmission 6" = "Additionally heals cellular damage and toxin lovers.",
"Resistance 7" = "Increases healing speed.",
)
/datum/symptom/heal/radiation/Start(datum/disease/advance/A)
if(!..())
return
+184
View File
@@ -0,0 +1,184 @@
/datum/element/mob_holder
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
id_arg_index = 2
var/worn_state
var/alt_worn
var/right_hand
var/left_hand
var/inv_slots
var/proctype //if present, will be invoked on headwear generation.
/datum/element/mob_holder/Attach(datum/target, _worn_state, _alt_worn, _right_hand, _left_hand, _inv_slots = NONE, _proctype)
. = ..()
if(!isliving(target))
return ELEMENT_INCOMPATIBLE
worn_state = _worn_state
alt_worn = _alt_worn
right_hand = _right_hand
left_hand = _left_hand
inv_slots = _inv_slots
proctype = _proctype
RegisterSignal(target, COMSIG_CLICK_ALT, .proc/mob_try_pickup)
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine)
/datum/element/mob_holder/Detach(datum/source, force)
. = ..()
UnregisterSignal(source, COMSIG_CLICK_ALT)
UnregisterSignal(source, COMSIG_PARENT_EXAMINE)
/datum/element/mob_holder/proc/on_examine(mob/living/source, mob/user, list/examine_list)
if(ishuman(user) && !istype(source.loc, /obj/item/clothing/head/mob_holder))
examine_list += "<span class='notice'>Looks like [source.p_they(TRUE)] can be picked up with <b>Alt+Click</b>!</span>"
/datum/element/mob_holder/proc/mob_try_pickup(mob/living/source, mob/user)
if(!ishuman(user) || !user.Adjacent(source) || user.incapacitated())
return FALSE
if(user.get_active_held_item())
to_chat(user, "<span class='warning'>Your hands are full!</span>")
return FALSE
if(source.buckled)
to_chat(user, "<span class='warning'>[src] is buckled to something!</span>")
return FALSE
if(source == user)
to_chat(user, "<span class='warning'>You can't pick yourself up.</span>")
return FALSE
source.visible_message("<span class='warning'>[user] starts picking up [source].</span>", \
"<span class='userdanger'>[user] starts picking you up!</span>")
if(!do_after(user, 20, target = source) || source.buckled)
return FALSE
source.visible_message("<span class='warning'>[user] picks up [source]!</span>", \
"<span class='userdanger'>[user] picks you up!</span>")
to_chat(user, "<span class='notice'>You pick [src] up.</span>")
source.drop_all_held_items()
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(source), source, worn_state, alt_worn, right_hand, left_hand, inv_slots)
if(proctype)
INVOKE_ASYNC(src, proctype, source, holder, user)
user.put_in_hands(holder)
return TRUE
/datum/element/mob_holder/proc/drone_worn_icon(mob/living/simple_animal/drone/D, obj/item/clothing/head/mob_holder/holder, mob/user)
var/new_state = "[D.visualAppearence]_hat"
holder.item_state = new_state
holder.icon_state = new_state
//The item itself,
/obj/item/clothing/head/mob_holder
name = "bugged mob"
desc = "Yell at coderbrush."
icon = null
alternate_worn_icon = 'icons/mob/animals_held.dmi'
righthand_file = 'icons/mob/animals_held_rh.dmi'
lefthand_file = 'icons/mob/animals_held_lh.dmi'
icon_state = ""
w_class = WEIGHT_CLASS_BULKY
var/mob/living/held_mob
/obj/item/clothing/head/mob_holder/Initialize(mapload, mob/living/target, worn_state, alt_worn, right_hand, left_hand, slots = NONE)
. = ..()
if(target)
assimilate(target)
if(alt_worn)
alternate_worn_icon = alt_worn
if(worn_state)
item_state = worn_state
icon_state = worn_state
if(left_hand)
lefthand_file = left_hand
if(right_hand)
righthand_file = right_hand
slot_flags = slots
/obj/item/clothing/head/mob_holder/proc/assimilate(mob/living/target)
target.setDir(SOUTH)
held_mob = target
target.forceMove(src)
var/image/I = new //work around to retain the same appearance to the mob idependently from inhands/worn states.
I.appearance = target.appearance
I.override = TRUE
add_overlay(I)
name = target.name
desc = target.desc
switch(target.mob_size)
if(MOB_SIZE_TINY)
w_class = WEIGHT_CLASS_TINY
if(MOB_SIZE_SMALL)
w_class = WEIGHT_CLASS_NORMAL
if(MOB_SIZE_LARGE)
w_class = WEIGHT_CLASS_HUGE
RegisterSignal(src, COMSIG_CLICK_SHIFT, .proc/examine_held_mob)
/obj/item/clothing/head/mob_holder/Destroy()
if(held_mob)
release()
return ..()
/obj/item/clothing/head/mob_holder/proc/examine_held_mob(datum/source, mob/user)
held_mob.ShiftClick(user)
return COMPONENT_DENY_EXAMINATE
/obj/item/clothing/head/mob_holder/Exited(atom/movable/AM, atom/newloc)
. = ..()
if(AM == held_mob)
held_mob.reset_perspective()
held_mob = null
qdel(src)
/obj/item/clothing/head/mob_holder/Entered(atom/movable/AM, atom/newloc)
. = ..()
if(AM != held_mob)
var/destination = loc
if(isliving(loc)) //the mob is held or worn, drop things on the floor
destination = get_turf(loc)
AM.forceMove(destination)
/obj/item/clothing/head/mob_holder/dropped()
. = ..()
if(held_mob && isturf(loc))//don't release on soft-drops
release()
/obj/item/clothing/head/mob_holder/proc/release()
if(held_mob)
var/mob/living/L = held_mob
held_mob = null
L.forceMove(get_turf(L))
L.reset_perspective()
L.setDir(SOUTH)
qdel(src)
/obj/item/clothing/head/mob_holder/relaymove(mob/user)
return
/obj/item/clothing/head/mob_holder/container_resist()
if(isliving(loc))
var/mob/living/L = loc
L.visible_message("<span class='warning'>[src] escapes from [L]!</span>", "<span class='warning'>[src] escapes your grip!</span>")
release()
/obj/item/clothing/head/mob_holder/assume_air(datum/gas_mixture/env)
var/atom/location = loc
if(!loc)
return //null
var/turf/T = get_turf(loc)
while(location != T)
location = location.loc
if(ismob(location))
return location.loc.assume_air(env)
return loc.assume_air(env)
/obj/item/clothing/head/mob_holder/remove_air(amount)
var/atom/location = loc
if(!loc)
return //null
var/turf/T = get_turf(loc)
while(location != T)
location = location.loc
if(ismob(location))
return location.loc.remove_air(amount)
return loc.remove_air(amount)
+5 -1
View File
@@ -1,6 +1,6 @@
/datum/element/wuv //D'awwwww
element_flags = ELEMENT_BESPOKE
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
id_arg_index = 2
//the for the me emote proc call when petted.
var/pet_emote
@@ -30,6 +30,10 @@
RegisterSignal(target, COMSIG_MOB_ATTACK_HAND, .proc/on_attack_hand)
/datum/element/wuv/Detach(datum/source, force)
. = ..()
UnregisterSignal(source, COMSIG_MOB_ATTACK_HAND)
/datum/element/wuv/proc/on_attack_hand(datum/source, mob/user)
var/mob/living/L = source
+1
View File
@@ -458,6 +458,7 @@
var/list/allowed_types = list(
/datum/objective/assassinate,
/datum/objective/assassinate/once,
/datum/objective/maroon,
/datum/objective/debrain,
/datum/objective/protect,
@@ -201,51 +201,52 @@
/datum/mood_event/vampcandle
description = "<span class='umbra'>Something is making your mind feel... loose...</span>\n"
mood_change = -10
mood_change = -15
timeout = 1 MINUTES
/datum/mood_event/drankblood_bad
description = "<span class='boldwarning'>I drank the blood of a lesser creature. Disgusting.</span>\n"
mood_change = -4
timeout = 900
timeout = 8 MINUTES
/datum/mood_event/drankblood_dead
description = "<span class='boldwarning'>I drank dead blood. I am better than this.</span>\n"
mood_change = -7
timeout = 900
timeout = 10 MINUTES
/datum/mood_event/drankblood_synth
description = "<span class='boldwarning'>I drank synthetic blood. What is wrong with me?</span>\n"
mood_change = -7
timeout = 900
timeout = 15 MINUTES
/datum/mood_event/drankkilled
description = "<span class='boldwarning'>I drank from my victim until they died. I feel...less human.</span>\n"
mood_change = -12
timeout = 6000
timeout = 25 MINUTES
/datum/mood_event/madevamp
description = "<span class='boldwarning'>A soul has been cursed to undeath by my own hand.</span>\n"
mood_change = -10
timeout = 10000
timeout = 30 MINUTES
/datum/mood_event/vampatefood
description = "<span class='boldwarning'>Mortal nourishment no longer sustains me. I feel unwell.</span>\n"
mood_change = -6
timeout = 1000
timeout = 10 MINUTES
/datum/mood_event/daylight_1
description = "<span class='boldwarning'>I slept poorly in a makeshift coffin during the day.</span>\n"
mood_change = -3
timeout = 1000
timeout = 10 MINUTES
/datum/mood_event/nanite_sadness
description = "<span class='warning robot'>+++++++HAPPINESS SUPPRESSION+++++++</span>\n"
mood_change = -7
/datum/mood_event/daylight_2
description = "<span class='boldwarning'>I have been scorched by the unforgiving rays of the sun.</span>\n"
mood_change = -6
timeout = 1200
timeout = 15 MINUTES
/datum/mood_event/nanite_sadness
description = "<span class='warning robot'>+++++++HAPPINESS SUPPRESSION+++++++</span>\n"
mood_change = -7
/datum/mood_event/nanite_sadness/add_effects(message)
description = "<span class='warning robot'>+++++++[message]+++++++</span>\n"
+41 -18
View File
@@ -91,11 +91,11 @@
desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are."
icon_state = "asleep"
/datum/status_effect/no_combat_mode/
/datum/status_effect/no_combat_mode
id = "no_combat_mode"
blocks_combatmode = TRUE
alert_type = null
status_type = STATUS_EFFECT_REPLACE
blocks_combatmode = TRUE
/datum/status_effect/no_combat_mode/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration))
@@ -124,31 +124,54 @@
icon = 'icons/mob/actions/bloodsucker.dmi'
icon_state = "power_mez"
/datum/status_effect/no_combat_mode/electrode
/datum/status_effect/electrode
id = "tased"
var/slowdown = 1.5
var/slowdown_priority = 50 //to make sure the stronger effect overrides
var/affect_crawl = FALSE
var/nextmove_modifier = 1
var/stamdmg_per_ds = 1 //a 20 duration would do 20 stamdmg, disablers do 24 or something
var/last_tick = 0 //fastprocess processing speed is a goddamn sham, don't trust it.
/datum/status_effect/no_combat_mode/electrode/on_creation(mob/living/new_owner, set_duration)
/datum/status_effect/electrode/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration)) //TODO, figure out how to grab from subtype
duration = set_duration
. = ..()
last_tick = world.time
if(iscarbon(owner))
var/mob/living/carbon/C = owner
if(C.combatmode)
C.toggle_combat_mode(TRUE)
C.add_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]", TRUE, priority = slowdown_priority, override = TRUE, multiplicative_slowdown = slowdown, blacklisted_movetypes = affect_crawl? NONE : CRAWLING)
/datum/status_effect/electrode/on_remove()
if(iscarbon(owner))
var/mob/living/carbon/C = owner
C.remove_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]")
. = ..()
/datum/status_effect/electrode/tick()
var/diff = world.time - last_tick
if(owner)
owner.adjustStaminaLoss(max(0, stamdmg_per_ds * diff)) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
last_tick = world.time
/datum/status_effect/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
return nextmove_modifier
/datum/status_effect/electrode/no_combat_mode
id = "tased_strong"
slowdown = 8
slowdown_priority = 100
nextmove_modifier = 2
blocks_combatmode = TRUE
/datum/status_effect/electrode/no_combat_mode/on_creation(mob/living/new_owner, set_duration)
. = ..()
if(iscarbon(owner))
var/mob/living/carbon/C = owner
if(C.combatmode)
C.toggle_combat_mode(TRUE)
C.add_movespeed_modifier(MOVESPEED_ID_TASED_STATUS, TRUE, override = TRUE, multiplicative_slowdown = 8)
/datum/status_effect/no_combat_mode/electrode/on_remove()
if(iscarbon(owner))
var/mob/living/carbon/C = owner
C.remove_movespeed_modifier(MOVESPEED_ID_TASED_STATUS)
. = ..()
/datum/status_effect/no_combat_mode/electrode/tick()
if(owner)
owner.adjustStaminaLoss(5) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
/datum/status_effect/no_combat_mode/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
return 2
//OTHER DEBUFFS
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
+1
View File
@@ -8,6 +8,7 @@
var/gain_text
var/lose_text
var/medical_record_text //This text will appear on medical records for the trait. Not yet implemented
var/antag_removal_text // Text will be given to the quirk holder if they get an antag that has it blacklisted.
var/mood_quirk = FALSE //if true, this quirk affects mood and is unavailable if moodlets are disabled
var/mob_trait //if applicable, apply and remove this mob trait
var/mob/living/quirk_holder
+8 -13
View File
@@ -6,6 +6,7 @@
value = -2
gain_text = "<span class='danger'>You feel your vigor slowly fading away.</span>"
lose_text = "<span class='notice'>You feel vigorous again.</span>"
antag_removal_text = "Your antagonistic nature has removed your blood deficiency."
medical_record_text = "Patient requires regular treatment for blood loss due to low production of blood."
/datum/quirk/blooddeficiency/on_process()
@@ -38,6 +39,8 @@
var/obj/item/heirloom
var/where
GLOBAL_LIST_EMPTY(family_heirlooms)
/datum/quirk/family_heirloom/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
var/obj/item/heirloom_type
@@ -76,6 +79,7 @@
/obj/item/lighter,
/obj/item/dice/d20)
heirloom = new heirloom_type(get_turf(quirk_holder))
GLOB.family_heirlooms += heirloom
var/list/slots = list(
"in your left pocket" = SLOT_L_STORE,
"in your right pocket" = SLOT_R_STORE,
@@ -140,9 +144,8 @@
/datum/quirk/nearsighted/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
var/obj/item/clothing/glasses/regular/glasses = new(get_turf(H))
H.put_in_hands(glasses)
H.equip_to_slot(glasses, SLOT_GLASSES)
H.regenerate_icons() //this is to remove the inhand icon, which persists even if it's not in their hands
if(!H.equip_to_slot_if_possible(glasses, SLOT_GLASSES))
H.put_in_hands(glasses)
/datum/quirk/nyctophobia
name = "Nyctophobia"
@@ -188,11 +191,7 @@
gain_text = "<span class='danger'>You feel repulsed by the thought of violence!</span>"
lose_text = "<span class='notice'>You think you can defend yourself again.</span>"
medical_record_text = "Patient is unusually pacifistic and cannot bring themselves to cause physical harm."
/datum/quirk/nonviolent/on_process()
if(quirk_holder.mind && LAZYLEN(quirk_holder.mind.antag_datums))
to_chat(quirk_holder, "<span class='boldannounce'>Your antagonistic nature has caused you to renounce your pacifism.</span>")
qdel(src)
antag_removal_text = "Your antagonistic nature has caused you to renounce your pacifism."
/datum/quirk/paraplegic
name = "Paraplegic"
@@ -355,6 +354,7 @@
gain_text = "<span class='danger'>You find yourself unable to speak!</span>"
lose_text = "<span class='notice'>You feel a growing strength in your vocal chords.</span>"
medical_record_text = "Functionally mute, patient is unable to use their voice in any capacity."
antag_removal_text = "Your antagonistic nature has caused your voice to be heard."
var/datum/brain_trauma/severe/mute/mute
/datum/quirk/mute/add()
@@ -366,11 +366,6 @@
var/mob/living/carbon/human/H = quirk_holder
H?.cure_trauma_type(mute, TRAUMA_RESILIENCE_ABSOLUTE)
/datum/quirk/mute/on_process()
if(quirk_holder.mind && LAZYLEN(quirk_holder.mind.antag_datums))
to_chat(quirk_holder, "<span class='boldannounce'>Your antagonistic nature has caused your voice to be heard.</span>")
qdel(src)
/datum/quirk/unstable
name = "Unstable"
desc = "Due to past troubles, you are unable to recover your sanity if you lose it. Be very careful managing your mood!"
+1 -1
View File
@@ -52,7 +52,7 @@
/datum/wires/airlock/interactable(mob/user)
var/obj/machinery/door/airlock/A = holder
if(!issilicon(user) && A.isElectrified() && A.shock(user, 100))
if(!A.hasSiliconAccessInArea(user) && A.isElectrified() && A.shock(user, 100))
return FALSE
if(A.panel_open)
return TRUE
+1 -1
View File
@@ -12,7 +12,7 @@
/datum/wires/vending/interactable(mob/user)
var/obj/machinery/vending/V = holder
if(!issilicon(user) && V.seconds_electrified && V.shock(user, 100))
if(!V.hasSiliconAccessInArea(user) && V.seconds_electrified && V.shock(user, 100))
return FALSE
if(V.panel_open)
return TRUE