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

This commit is contained in:
silicons
2021-07-18 15:12:52 -07:00
159 changed files with 132112 additions and 130447 deletions

View File

@@ -0,0 +1,65 @@
/datum/component/acid
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
var/level = 0
/datum/component/acid/Initialize(acidpwr, acid_volume)
if(!isobj(parent))
return COMPONENT_INCOMPATIBLE
var/obj/O = parent
var/acid_cap = acidpwr * 300
level = min(acidpwr * acid_volume, acid_cap)
START_PROCESSING(SSprocessing, src)
RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/add_acid_overlay)
if(isitem(parent))
RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand)
O.update_icon()
/datum/component/acid/proc/on_attack_hand(datum/source, mob/user)
var/obj/item/I = parent
if(istype(I) && level > 20 && !ismob(I.loc))// so we can still remove the clothes on us that have acid.
var/mob/living/carbon/C = user
if(istype(C))
if(!C.gloves || (!(C.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF))))
to_chat(user, "<span class='warning'>The acid on [I] burns your hand!</span>")
var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage
C.update_damage_overlays()
/datum/component/acid/InheritComponent(datum/component/C, i_am_original, acidpwr, acid_volume)
if(!i_am_original)
return
var/acid_cap = acidpwr * 300
if(level < acid_cap)
if(C)
var/datum/component/acid/other = C
level = min(level + other.level, acid_cap)
else
level = min(level + acidpwr * acid_volume, acid_cap)
/datum/component/acid/Destroy()
STOP_PROCESSING(SSprocessing, src)
var/obj/O = parent
level = 0
O.update_overlays()
return ..()
/datum/component/acid/process()
var/obj/O = parent
if(!istype(O))
qdel(src)
return PROCESS_KILL
if(!(O.resistance_flags & ACID_PROOF))
if(prob(33))
playsound(O.loc, 'sound/items/welder.ogg', 150, 1)
O.take_damage(min(1 + round(sqrt(level)*0.3), 300), BURN, "acid", 0)
level = max(level - (5 + 3*round(sqrt(level))), 0)
if(level <= 0)
qdel(src)
return PROCESS_KILL
else
O.update_icon()
return TRUE
/datum/component/acid/proc/add_acid_overlay(atom/source, list/overlay_list)
overlay_list += GLOB.acid_overlay

View File

@@ -16,7 +16,7 @@
RegisterSignal(L, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_MOVABLE_TELEPORTED, COMSIG_LIVING_GUN_PROCESS_FIRE, COMSIG_MOB_APPLY_DAMAGE), .proc/minor_activity)
/datum/component/activity/proc/log_activity()
historical_activity_levels[world.time] = activity_level
historical_activity_levels["[world.time]"] = activity_level
/datum/component/activity/proc/minor_activity(datum/source)
activity_level += 1

View File

@@ -1,491 +0,0 @@
/datum/component/personal_crafting/Initialize()
if(!ismob(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN, .proc/create_mob_button)
/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/CL)
var/datum/hud/H = user.hud_used
var/obj/screen/craft/C = new()
C.icon = H.ui_style
H.static_inventory += C
if(!CL.prefs.widescreenpref)
C.screen_loc = ui_boxcraft
CL.screen += C
RegisterSignal(C, COMSIG_CLICK, .proc/component_ui_interact)
/datum/component/personal_crafting
var/busy
var/viewing_category = 1
var/viewing_subcategory = 1
var/list/categories = list(
CAT_WEAPONRY = list(
CAT_WEAPON,
CAT_AMMO,
),
CAT_ROBOT = CAT_NONE,
CAT_MISC = list(
CAT_MISCELLANEOUS,
CAT_TOOL,
CAT_FURNITURE,
),
CAT_PRIMAL = CAT_NONE,
CAT_FOOD = list(
CAT_BREAD,
CAT_BURGER,
CAT_CAKE,
CAT_DONUT,
CAT_EGG,
CAT_ICE,
CAT_MEAT,
CAT_MEXICAN,
CAT_MISCFOOD,
CAT_PASTRY,
CAT_PIE,
CAT_PIZZA,
CAT_SEAFOOD,
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
check_contents - takes a recipe and a key-type list and checks if said recipe can be done with available stuff
check_tools - takes recipe, a key-type list, and a user and checks if there are enough tools to do the stuff, checks bugs one level deep
construct_item - takes a recipe and a user, call all the checking procs, calls do_after, checks all the things again, calls del_reqs, creates result, calls CheckParts of said result with argument being list returned by deel_reqs
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
*/
/**
* Check that the contents of the recipe meet the requirements.
*
* user: The /mob that initated the crafting.
* R: The /datum/crafting_recipe being attempted.
* contents: List of items to search for R's reqs.
*/
/datum/component/personal_crafting/proc/check_contents(mob/user, datum/crafting_recipe/R, list/contents)
var/list/item_instances = contents["instances"]
contents = contents["other"]
var/list/requirements_list = list()
// Process all requirements
for(var/requirement_path in R.reqs)
// Check we have the appropriate amount available in the contents list
var/needed_amount = R.reqs[requirement_path]
for(var/content_item_path in contents)
// Right path and not blacklisted
if(!ispath(content_item_path, requirement_path) || R.blacklist.Find(requirement_path))
continue
needed_amount -= contents[content_item_path]
if(needed_amount <= 0)
break
if(needed_amount > 0)
return FALSE
// Store the instances of what we will use for R.check_requirements() for requirement_path
var/list/instances_list = list()
for(var/instance_path in item_instances)
if(ispath(instance_path, requirement_path))
instances_list += item_instances[instance_path]
requirements_list[requirement_path] = instances_list
for(var/requirement_path in R.chem_catalysts)
if(contents[requirement_path] < R.chem_catalysts[requirement_path])
return FALSE
return R.check_requirements(user, requirements_list)
/datum/component/personal_crafting/proc/get_environment(mob/user)
. = list()
for(var/obj/item/I in user.held_items)
. += I
if(!isturf(user.loc))
return
var/list/L = block(get_step(user, SOUTHWEST), get_step(user, NORTHEAST))
for(var/A in L)
var/turf/T = A
if(T.Adjacent(user))
for(var/B in T)
var/atom/movable/AM = B
if(AM.flags_1 & HOLOGRAM_1)
continue
. += AM
for(var/slot in list(SLOT_R_STORE, SLOT_L_STORE))
. += user.get_item_by_slot(slot)
/datum/component/personal_crafting/proc/get_surroundings(mob/user)
. = list()
.["tool_behaviour"] = list()
.["other"] = list()
.["instances"] = list()
for(var/obj/item/I in get_environment(user))
if(I.flags_1 & HOLOGRAM_1)
continue
if(.["instances"][I.type])
.["instances"][I.type] += I
else
.["instances"][I.type] = list(I)
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
.["other"][I.type] += S.amount
else if(I.tool_behaviour)
.["tool_behaviour"] += I.tool_behaviour
.["other"][I.type] += 1
else
if(istype(I, /obj/item/reagent_containers))
var/obj/item/reagent_containers/RC = I
if(RC.is_drainable())
for(var/datum/reagent/A in RC.reagents.reagent_list)
.["other"][A.type] += A.volume
.["other"][I.type] += 1
/datum/component/personal_crafting/proc/check_tools(mob/user, datum/crafting_recipe/R, list/contents)
if(!R.tools.len)
return TRUE
var/list/possible_tools = list()
var/list/present_qualities = list()
present_qualities |= contents["tool_behaviour"]
for(var/obj/item/I in user.contents)
if(istype(I, /obj/item/storage))
for(var/obj/item/SI in I.contents)
possible_tools += SI.type
if(SI.tool_behaviour)
present_qualities.Add(SI.tool_behaviour)
possible_tools += I.type
if(I.tool_behaviour)
present_qualities.Add(I.tool_behaviour)
possible_tools |= contents["other"]
main_loop:
for(var/A in R.tools)
if(A in present_qualities)
continue
else
for(var/I in possible_tools)
if(ispath(I, A))
continue main_loop
return FALSE
return TRUE
/datum/component/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R)
var/list/contents = get_surroundings(user)
var/send_feedback = TRUE
if(check_contents(user, R, contents))
if(check_tools(user, R, contents))
if(do_after(user, R.time, target = user))
contents = get_surroundings(user)
if(!check_contents(user, R, contents))
return ", missing component."
if(!check_tools(user, R, contents))
return ", missing tool."
var/list/parts = del_reqs(R, user)
var/atom/movable/I = new R.result (get_turf(user.loc))
I.CheckParts(parts, R)
if(isitem(I))
if(isfood(I))
var/obj/item/reagent_containers/food/food_result = I
var/total_quality = 0
var/total_items = 0
for(var/obj/item/reagent_containers/food/ingredient in parts)
total_items += 1
total_quality += ingredient.food_quality
if(total_items == 0)
food_result.adjust_food_quality(50)
else
food_result.adjust_food_quality(total_quality / total_items)
user.put_in_hands(I)
if(send_feedback)
SSblackbox.record_feedback("tally", "object_crafted", 1, I.type)
log_craft("[I] crafted by [user] at [loc_name(I.loc)]")
return FALSE
return "."
return ", missing tool."
return ", missing component."
/*Del reqs works like this:
Loop over reqs var of the recipe
Set var amt to the value current cycle req is pointing to, its amount of type we need to delete
Get var/surroundings list of things accessable to crafting by get_environment()
Check the type of the current cycle req
If its reagent then do a while loop, inside it try to locate() reagent containers, inside such containers try to locate needed reagent, if there isnt remove thing from surroundings
If there is enough reagent in the search result then delete the needed amount, create the same type of reagent with the same data var and put it into deletion list
If there isnt enough take all of that reagent from the container, put into deletion list, substract the amt var by the volume of reagent, remove the container from surroundings list and keep searching
While doing above stuff check deletion list if it already has such reagnet, if yes merge instead of adding second one
If its stack check if it has enough amount
If yes create new stack with the needed amount and put in into deletion list, substract taken amount from the stack
If no put all of the stack in the deletion list, substract its amount from amt and keep searching
While doing above stuff check deletion list if it already has such stack type, if yes try to merge them instead of adding new one
If its anything else just locate() in in the list in a while loop, each find --s the amt var and puts the found stuff in deletion loop
Then do a loop over parts var of the recipe
Do similar stuff to what we have done above, but now in deletion list, until the parts conditions are satisfied keep taking from the deletion list and putting it into parts list for return
After its done loop over deletion list and delete all the shit that wasnt taken by parts loop
del_reqs return the list of parts resulting object will receive as argument of CheckParts proc, on the atom level it will add them all to the contents, on all other levels it calls ..() and does whatever is needed afterwards but from contents list already
*/
/datum/component/personal_crafting/proc/del_reqs(datum/crafting_recipe/R, mob/user)
var/list/surroundings
var/list/Deletion = list()
. = list()
var/data
var/amt
main_loop:
for(var/A in R.reqs)
amt = R.reqs[A]
surroundings = get_environment(user)
surroundings -= Deletion
if(ispath(A, /datum/reagent))
var/datum/reagent/RG = new A
var/datum/reagent/RGNT
while(amt > 0)
var/obj/item/reagent_containers/RC = locate() in surroundings
RG = RC.reagents.get_reagent(A)
if(RG)
if(!locate(RG.type) in Deletion)
Deletion += new RG.type()
if(RG.volume > amt)
RG.volume -= amt
data = RG.data
RC.reagents.conditional_update(RC)
RG = locate(RG.type) in Deletion
RG.volume = amt
RG.data += data
continue main_loop
else
surroundings -= RC
amt -= RG.volume
RC.reagents.reagent_list -= RG
RC.reagents.conditional_update(RC)
RGNT = locate(RG.type) in Deletion
RGNT.volume += RG.volume
RGNT.data += RG.data
qdel(RG)
RC.on_reagent_change()
else
surroundings -= RC
else if(ispath(A, /obj/item/stack))
var/obj/item/stack/S
var/obj/item/stack/SD
while(amt > 0)
S = locate(A) in surroundings
if(S.amount >= amt)
if(!locate(S.type) in Deletion)
SD = new S.type()
Deletion += SD
S.use(amt)
SD = locate(S.type) in Deletion
SD.amount += amt
continue main_loop
else
amt -= S.amount
if(!locate(S.type) in Deletion)
Deletion += S
else
data = S.amount
S = locate(S.type) in Deletion
S.add(data)
surroundings -= S
else
var/atom/movable/I
while(amt > 0)
I = locate(A) in surroundings
Deletion += I
surroundings -= I
amt--
var/list/partlist = list(R.parts.len)
for(var/M in R.parts)
partlist[M] = R.parts[M]
for(var/A in R.parts)
if(istype(A, /datum/reagent))
var/datum/reagent/RG = locate(A) in Deletion
if(RG.volume > partlist[A])
RG.volume = partlist[A]
. += RG
Deletion -= RG
continue
else if(istype(A, /obj/item/stack))
var/obj/item/stack/ST = locate(A) in Deletion
if(ST.amount > partlist[A])
ST.amount = partlist[A]
. += ST
Deletion -= ST
continue
else
while(partlist[A] > 0)
var/atom/movable/AM = locate(A) in Deletion
. += AM
Deletion -= AM
partlist[A] -= 1
while(Deletion.len)
var/DL = Deletion[Deletion.len]
Deletion.Cut(Deletion.len)
qdel(DL)
/datum/component/personal_crafting/proc/component_ui_interact(obj/screen/craft/image, location, control, params, user)
if(user == parent)
ui_interact(user)
/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()
data["busy"] = busy
data["category"] = cur_category
data["subcategory"] = cur_subcategory
data["display_craftable_only"] = display_craftable_only
data["display_compact"] = display_compact
var/list/surroundings = get_surroundings(user)
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
craftability["[REF(R)]"] = check_contents(user, 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
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
/datum/component/personal_crafting/ui_act(action, params)
if(..())
return
switch(action)
if("make")
var/datum/crafting_recipe/TR = locate(params["recipe"]) in GLOB.crafting_recipes
ui_interact(usr)
if(busy)
to_chat(usr, "<span class='warning'>You are already making something!</span>")
return
busy = TRUE
var/fail_msg = construct_item(usr, TR)
if(!fail_msg)
to_chat(usr, "<span class='notice'>[TR.name] constructed.</span>")
else
to_chat(usr, "<span class='warning'>Construction failed[fail_msg]</span>")
busy = FALSE
if("toggle_recipes")
display_craftable_only = !display_craftable_only
. = TRUE
if("toggle_compact")
display_compact = !display_compact
. = TRUE
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()
data["name"] = R.name
data["ref"] = "[REF(R)]"
var/req_text = ""
var/tool_text = ""
var/catalyst_text = ""
for(var/a in R.reqs)
//We just need the name, so cheat-typecast to /atom for speed (even tho Reagents are /datum they DO have a "name" var)
//Also these are typepaths so sadly we can't just do "[a]"
var/atom/A = a
req_text += " [R.reqs[A]] [initial(A.name)],"
req_text = replacetext(req_text,",","",-1)
data["req_text"] = req_text
for(var/a in R.chem_catalysts)
var/atom/A = a //cheat-typecast
catalyst_text += " [R.chem_catalysts[A]] [initial(A.name)],"
catalyst_text = replacetext(catalyst_text,",","",-1)
data["catalyst_text"] = catalyst_text
for(var/a in R.tools)
if(ispath(a, /obj/item))
var/obj/item/b = a
tool_text += " [initial(b.name)],"
else
tool_text += " [a],"
tool_text = replacetext(tool_text,",","",-1)
data["tool_text"] = tool_text
return data
//Mind helpers
/datum/mind/proc/teach_crafting_recipe(R)
if(!learned_recipes)
learned_recipes = list()
learned_recipes |= R

View File

@@ -4,6 +4,10 @@
/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/CL)
var/datum/hud/H = user.hud_used
for(var/huds in H.static_inventory)
if(istype(huds, /obj/screen/craft))
return
//We don't want to be stacking multiple crafting huds on relogs
var/obj/screen/craft/C = new()
C.icon = H.ui_style
H.static_inventory += C
@@ -20,7 +24,7 @@
CAT_AMMO,
),
CAT_ROBOT = CAT_NONE,
CAT_MISC = list(
CAT_MISCELLANEOUS = list(
CAT_MISCELLANEOUS,
CAT_TOOL,
CAT_FURNITURE,

View File

@@ -8,7 +8,7 @@
time = 1
reqs = list(/obj/item/stack/sheet/plastic = 1,
/obj/item/stack/sheet/mineral/wood = 1)
category = CAT_MISC
category = CAT_MISCELLANEOUS
subcategory = CAT_TOOL
/datum/crafting_recipe/showercurtain
@@ -18,7 +18,7 @@
/obj/item/stack/rods = 1)
result = /obj/structure/curtain
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/guillotine
name = "Guillotine"
@@ -29,7 +29,7 @@
/obj/item/stack/cable_coil = 10)
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/femur_breaker
name = "Femur Breaker"
@@ -39,7 +39,7 @@
/obj/item/stack/cable_coil = 30)
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
// Blood Sucker stuff //
/datum/crafting_recipe/bloodsucker/blackcoffin
@@ -54,7 +54,7 @@
///obj/item/pipe = 2)
time = 150
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
always_availible = TRUE
/datum/crafting_recipe/bloodsucker/meatcoffin
@@ -66,7 +66,7 @@
/obj/item/restraints/handcuffs/cable = 1)
time = 150
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
always_availible = TRUE
/datum/crafting_recipe/bloodsucker/metalcoffin
@@ -77,7 +77,7 @@
reqs = list(/obj/item/stack/sheet/metal = 5)
time = 100
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
always_availible = TRUE
/datum/crafting_recipe/bloodsucker/vassalrack
@@ -100,7 +100,7 @@
// )
time = 150
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
always_availible = FALSE // Disabled until learned
@@ -117,7 +117,7 @@
)
time = 100
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
always_availible = FALSE // Disabled til learned
/datum/crafting_recipe/furnace
@@ -129,7 +129,7 @@
/obj/item/stack/rods = 2)
tools = list(TOOL_CROWBAR)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/tableanvil
name = "Table Anvil"
@@ -139,7 +139,7 @@
/obj/item/stack/rods = 2)
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/sandvil
name = "Sandstone Anvil"
@@ -148,7 +148,7 @@
reqs = list(/obj/item/stack/sheet/mineral/sandstone = 24)
tools = list(TOOL_CROWBAR)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/basaltblock
name = "Sintered Basalt Block"
@@ -157,7 +157,7 @@
reqs = list(/obj/item/stack/ore/glass/basalt = 50)
tools = list(TOOL_WELDER)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/basaltanvil
name = "Basalt Anvil"
@@ -166,7 +166,7 @@
reqs = list(/obj/item/basaltblock = 5)
tools = list(TOOL_CROWBAR)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
///////////////////
//Tools & Storage//
///////////////////
@@ -177,7 +177,7 @@
time = 1
reqs = list(/obj/item/stack/medical/gauze = 1,
/datum/reagent/space_cleaner/sterilizine = 5)
category = CAT_MISC
category = CAT_MISCELLANEOUS
subcategory = CAT_TOOL
/datum/crafting_recipe/brute_pack
@@ -186,7 +186,7 @@
time = 1
reqs = list(/obj/item/stack/medical/gauze/adv = 1,
/datum/reagent/medicine/styptic_powder = 10)
category = CAT_MISC
category = CAT_MISCELLANEOUS
subcategory = CAT_TOOL
/datum/crafting_recipe/burn_pack
@@ -195,7 +195,7 @@
time = 1
reqs = list(/obj/item/stack/medical/gauze/adv = 1,
/datum/reagent/medicine/silver_sulfadiazine = 10)
category = CAT_MISC
category = CAT_MISCELLANEOUS
subcategory = CAT_TOOL
/datum/crafting_recipe/ghettojetpack
@@ -206,7 +206,7 @@
/obj/item/extinguisher = 1,
/obj/item/pipe = 3,
/obj/item/stack/cable_coil = 30)
category = CAT_MISC
category = CAT_MISCELLANEOUS
subcategory = CAT_TOOL
tools = list(TOOL_WRENCH, TOOL_WELDER, TOOL_WIRECUTTER)
@@ -220,7 +220,7 @@
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/toolboxhammer
name = "Toolbox Hammer"
@@ -231,7 +231,7 @@
/obj/item/stack/rods = 2)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/papersack
name = "Paper Sack"
@@ -239,7 +239,7 @@
time = 10
reqs = list(/obj/item/paper = 5)
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/smallcarton
name = "Small Carton"
@@ -247,7 +247,7 @@
time = 10
reqs = list(/obj/item/stack/sheet/cardboard = 1)
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/bronze_driver
name = "Bronze Plated Screwdriver"
@@ -259,7 +259,7 @@
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/bronze_welder
name = "Bronze Plated Welding Tool"
@@ -271,7 +271,7 @@
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/bronze_wirecutters
name = "Bronze Plated Wirecutters"
@@ -283,7 +283,7 @@
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/bronze_crowbar
name = "Bronze Plated Crowbar"
@@ -295,7 +295,7 @@
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/bronze_wrench
name = "Bronze Plated Wrench"
@@ -307,7 +307,7 @@
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/rcl
name = "Makeshift Rapid Cable Layer"
@@ -316,7 +316,7 @@
tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
reqs = list(/obj/item/stack/sheet/metal = 15)
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/picket_sign
name = "Picket Sign"
@@ -325,7 +325,7 @@
/obj/item/stack/sheet/cardboard = 2)
time = 80
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/electrochromatic_kit
name = "Electrochromatic Kit"
@@ -334,7 +334,7 @@
/obj/item/stack/cable_coil = 1)
time = 5
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/blackmarket_uplink
name = "Black Market Uplink"
@@ -346,7 +346,7 @@
/obj/item/radio = 1,
/obj/item/analyzer = 1)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/heretic/codex
name = "Codex Cicatrix"
@@ -358,7 +358,7 @@
/obj/item/stack/sheet/animalhide/human = 1)
time = 150
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
always_availible = FALSE
////////////
@@ -372,7 +372,21 @@
/obj/item/stack/rods = 8)
time = 100
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/motorized_wheelchair
name = "Hoverchair"
result = /obj/vehicle/ridden/wheelchair/motorized
reqs = list(/obj/item/stack/sheet/plasteel = 10,
/obj/item/stack/rods = 8,
/obj/item/stock_parts/manipulator = 2,
/obj/item/stock_parts/capacitor = 1)
parts = list(/obj/item/stock_parts/manipulator = 2,
/obj/item/stock_parts/capacitor = 1)
tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
time = 200
subcategory = CAT_MISCELLANEOUS
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/skateboard
name = "Skateboard"
@@ -381,7 +395,7 @@
reqs = list(/obj/item/stack/sheet/metal = 5,
/obj/item/stack/rods = 10)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/scooter
name = "Scooter"
@@ -390,7 +404,7 @@
reqs = list(/obj/item/stack/sheet/metal = 5,
/obj/item/stack/rods = 12)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/////////
//Toys///
@@ -401,28 +415,28 @@
reqs = list(/obj/item/light/bulb = 1, /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plastic = 4)
result = /obj/item/toy/sword
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/extendohand
name = "Extendo-Hand"
reqs = list(/obj/item/bodypart/r_arm/robot = 1, /obj/item/clothing/gloves/boxing = 1)
result = /obj/item/extendohand
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/toyneb
name = "Non-Euplastic Blade"
reqs = list(/obj/item/light/tube = 1, /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plastic = 4)
result = /obj/item/toy/sword/cx
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/catgirlplushie
name = "Catgirl Plushie"
reqs = list(/obj/item/toy/plush/hairball = 3)
result = /obj/item/toy/plush/catgirl
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
////////////
//Unsorted//
@@ -436,7 +450,7 @@
reqs = list(/obj/item/stack/sheet/mineral/wood = 1)
result = /obj/item/stick
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/swordhilt
@@ -445,14 +459,14 @@
reqs = list(/obj/item/stack/sheet/mineral/wood = 2)
result = /obj/item/swordhandle
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/blackcarpet
name = "Black Carpet"
reqs = list(/obj/item/stack/tile/carpet = 50, /obj/item/toy/crayon/black = 1)
result = /obj/item/stack/tile/carpet/black/fifty
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/paperframes
name = "Paper Frames"
@@ -460,7 +474,7 @@
time = 10
reqs = list(/obj/item/stack/sheet/mineral/wood = 5, /obj/item/paper = 20)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/naturalpaper
name = "Hand-Pressed Paper"
@@ -469,7 +483,7 @@
tools = list(/obj/item/hatchet)
result = /obj/item/paper_bin/bundlenatural
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/bluespacehonker
name = "Bluespace Bike horn"
@@ -479,7 +493,7 @@
/obj/item/toy/crayon/blue = 1,
/obj/item/bikehorn = 1)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/mousetrap
name = "Mouse Trap"
@@ -488,7 +502,7 @@
reqs = list(/obj/item/stack/sheet/cardboard = 1,
/obj/item/stack/rods = 1)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/flashlight_eyes
name = "Flashlight Eyes"
@@ -499,7 +513,7 @@
/obj/item/restraints/handcuffs/cable = 1
)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/pressureplate
name = "Pressure Plate"
@@ -510,7 +524,7 @@
/obj/item/stack/cable_coil = 2,
/obj/item/assembly/igniter = 1)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/gold_horn
name = "Golden Bike Horn"
@@ -519,7 +533,7 @@
reqs = list(/obj/item/stack/sheet/mineral/bananium = 5,
/obj/item/bikehorn = 1)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/spooky_camera
name = "Camera Obscura"
@@ -529,7 +543,7 @@
/datum/reagent/water/holywater = 10)
parts = list(/obj/item/camera = 1)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/coconut_bong
name = "Coconut Bong"
@@ -538,7 +552,7 @@
/obj/item/reagent_containers/food/snacks/grown/coconut = 1)
time = 70
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
//////////////
//Banners/////
@@ -551,7 +565,7 @@
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/captain/parade = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/engineering_banner
name = "Engitopia Banner"
@@ -560,7 +574,7 @@
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/engineering/engineer = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/cargo_banner
name = "Cargonia Banner"
@@ -569,7 +583,7 @@
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/cargo/tech = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/science_banner
name = "Sciencia Banner"
@@ -578,7 +592,7 @@
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/rnd/scientist = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/medical_banner
name = "Meditopia Banner"
@@ -587,7 +601,7 @@
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/medical/doctor = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/security_banner
name = "Securistan Banner"
@@ -596,4 +610,4 @@
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/security/officer = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS

View File

@@ -72,6 +72,16 @@
category = CAT_WEAPONRY
subcategory = CAT_MELEE
/datum/crafting_recipe/newsbaton
name = "Newspaper Baton"
result = /obj/item/melee/classic_baton/telescopic/newspaper
reqs = list(/obj/item/melee/classic_baton/telescopic = 1,
/obj/item/newspaper = 1,
/obj/item/stack/sticky_tape = 2)
time = 40
category = CAT_WEAPONRY
subcategory = CAT_MELEE
/datum/crafting_recipe/bokken
name = "Training Bokken"
result = /obj/item/melee/bokken

View File

@@ -265,6 +265,7 @@
/// Items embedded/stuck to carbons both check whether they randomly fall out (if applicable), as well as if the target mob and limb still exists.
/// Items harmfully embedded in carbons have an additional check for random pain (if applicable)
/datum/component/embedded/proc/processCarbon()
set waitfor = FALSE
var/mob/living/carbon/victim = parent
if(!victim || !limb) // in case the victim and/or their limbs exploded (say, due to a sticky bomb)

View File

@@ -158,6 +158,7 @@
autolock()
/datum/component/lockon_aiming/proc/autolock()
set waitfor = FALSE
var/mob/M = parent
if(!M.client)
return FALSE

View File

@@ -405,7 +405,7 @@
/mob/living/carbon/human/proc/hardset_dna(ui, list/mutation_index, newreal_name, newblood_type, datum/species/mrace, newfeatures, list/default_mutation_genes)
set waitfor = FALSE
if(newreal_name)
real_name = newreal_name
dna.generate_unique_enzymes()

View File

@@ -24,7 +24,8 @@
else
user_by_item -= source
/datum/element/earhealing/process()
/datum/element/earhealing/proc/do_process()
set waitfor = FALSE
for(var/i in user_by_item)
var/mob/living/carbon/user = user_by_item[i]
if(HAS_TRAIT(user, TRAIT_DEAF))
@@ -35,3 +36,6 @@
ears.deaf = max(ears.deaf - 0.25, (ears.damage < ears.maxHealth ? 0 : 1)) // Do not clear deafness if our ears are too damaged
ears.damage = max(ears.damage - 0.025, 0)
CHECK_TICK
/datum/element/earhealing/process()
do_process()

View File

@@ -59,7 +59,7 @@
var/mob/living/L = AM
if(L.stat == DEAD)
continue
if(light_nutrition_gain)
if(light_nutrition_gain && L.nutrition < NUTRITION_LEVEL_WELL_FED)
L.adjust_nutrition(light_amount * light_nutrition_gain * attached_atoms[AM], NUTRITION_LEVEL_WELL_FED)
if(light_amount > bonus_lum || light_amount < malus_lum)
var/mult = ((light_amount > bonus_lum) ? 1 : -1) * attached_atoms[AM]

View File

@@ -0,0 +1,19 @@
/datum/element/trash
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
/datum/element/trash/Attach(datum/target)
. = ..()
RegisterSignal(target, COMSIG_ITEM_ATTACK, .proc/UseFromHand)
/datum/element/trash/proc/UseFromHand(obj/item/source, mob/living/M, mob/living/user)
if((M == user || user.vore_flags & TRASH_FORCEFEED) && ishuman(user))
var/mob/living/carbon/human/H = user
if(HAS_TRAIT(H, TRAIT_TRASHCAN))
playsound(H.loc,'sound/items/eatfood.ogg', rand(10,50), 1)
if(H.vore_selected)
H.visible_message("<span class='notice'>[H] [H.vore_selected.vore_verb]s the [source] into their [H.vore_selected]</span>",
"<span class='notice'>You [H.vore_selected.vore_verb]s the [source] into your [H.vore_selected]</span>")
source.forceMove(H.vore_selected)
else
H.visible_message("<span class='notice'>[H] consumes the [source].")
qdel(source)

View File

@@ -154,3 +154,11 @@
/datum/quirk/longtimer/on_spawn()
var/mob/living/carbon/C = quirk_holder
C.generate_fake_scars(rand(min_scars, max_scars))
/datum/quirk/trashcan
name = "Trashcan"
desc = "You are able to consume and digest trash."
value = 0
gain_text = "<span class='notice'>You feel like munching on a can of soda.</span>"
lose_text = "<span class='notice'>You no longer feel like you should be eating trash.</span>"
mob_trait = TRAIT_TRASHCAN

View File

@@ -166,6 +166,7 @@
on_pulse(wire, user)
/datum/wires/proc/pulse_color(color, mob/living/user)
set waitfor = FALSE
LAZYINITLIST(current_users)
if(current_users[user])
return FALSE