Merge remote-tracking branch 'citadel/master' into mobility_flags
This commit is contained in:
@@ -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
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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!"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user