diff --git a/code/__DEFINES/_globals.dm b/code/__DEFINES/_globals.dm index 6e1e5ba352e..3e5b67e53e9 100644 --- a/code/__DEFINES/_globals.dm +++ b/code/__DEFINES/_globals.dm @@ -47,6 +47,12 @@ /// Create a typed list global that is initialized as an empty list #define GLOBAL_LIST_EMPTY_TYPED(X, Typepath) GLOBAL_LIST_INIT_TYPED(X, Typepath, list()) +/// Create an alist global with an initializer expression +#define GLOBAL_ALIST_INIT(X, InitValue) GLOBAL_RAW(/alist/##X); GLOBAL_MANAGED(X, InitValue) + +// Create an alist global that is initialized as an empty list +#define GLOBAL_ALIST_EMPTY(X) GLOBAL_ALIST_INIT(X, alist()) + /// Create a typed global with an initializer expression #define GLOBAL_DATUM_INIT(X, Typepath, InitValue) GLOBAL_RAW(Typepath/##X); GLOBAL_MANAGED(X, InitValue) diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 5bf3d604d6a..54e40b96d94 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -9,7 +9,7 @@ // /datum signals /// when a component is added to a datum: (/datum/component) #define COMSIG_COMPONENT_ADDED "component_added" -/// before a component is removed from a datum because of RemoveComponent: (/datum/component) +/// before a component is removed from a datum because of ClearFromParent: (/datum/component) #define COMSIG_COMPONENT_REMOVING "component_removing" /// before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation #define COMSIG_PARENT_PREQDELETED "parent_preqdeleted" diff --git a/code/__DEFINES/dcs/flags.dm b/code/__DEFINES/dcs/flags.dm index 100e572fb47..37b961c07f1 100644 --- a/code/__DEFINES/dcs/flags.dm +++ b/code/__DEFINES/dcs/flags.dm @@ -1,4 +1,4 @@ -/// Return this from `/datum/component/Initialize` or `datum/component/OnTransfer` to have the component be deleted if it's applied to an incorrect type. +/// Return this from `/datum/component/Initialize` or `/datum/component/OnTransfer` or `/datum/component/on_source_add` to have the component be deleted if it's applied to an incorrect type. /// `parent` must not be modified if this is to be returned. /// This will be noted in the runtime logs #define COMPONENT_INCOMPATIBLE 1 @@ -16,7 +16,7 @@ /// You would need it if you are doing something like removing the target from a processing list. #define ELEMENT_DETACH (1 << 0) /** - * Only elements created with the same arguments given after `id_arg_index` share an element instance + * Only elements created with the same arguments given after `argument_hash_start_idx` share an element instance * The arguments are the same when the text and number values are the same and all other values have the same ref */ #define ELEMENT_BESPOKE (1 << 1) @@ -31,8 +31,17 @@ #define COMPONENT_DUPE_ALLOWED 1 /// new component is deleted #define COMPONENT_DUPE_UNIQUE 2 +/** + * Component uses source tracking to manage adding and removal logic. + * Add a source/spawn to/the component by using AddComponentFrom(source, component_type, args...) + * Removing the last source will automatically remove the component from the parent. + * Arguments will be passed to on_source_add(source, args...); ensure that Initialize and on_source_add have the same signature. + */ +#define COMPONENT_DUPE_SOURCES 3 /// old component is given the initialization args of the new #define COMPONENT_DUPE_UNIQUE_PASSARGS 4 +/// each component of the same type is consulted as to whether the duplicate should be allowed +#define COMPONENT_DUPE_SELECTIVE 5 // Update flags for [/atom/proc/update_appearance] /// Update the atom's name diff --git a/code/__DEFINES/dcs/helpers.dm b/code/__DEFINES/dcs/helpers.dm index b13aee56179..e8ed2513d6f 100644 --- a/code/__DEFINES/dcs/helpers.dm +++ b/code/__DEFINES/dcs/helpers.dm @@ -6,6 +6,8 @@ #define SEND_GLOBAL_SIGNAL(sigtype, arguments...) ( SEND_SIGNAL(SSdcs, sigtype, ##arguments) ) +/// Signifies that this proc is used to handle signals. +/// Every proc you pass to RegisterSignal must have this. #define SIGNAL_HANDLER SHOULD_NOT_SLEEP(TRUE) /// A wrapper for _AddElement that allows us to pretend we're using normal named arguments @@ -15,3 +17,10 @@ /// A wrapper for _AddComponent that allows us to pretend we're using normal named arguments #define AddComponent(arguments...) _AddComponent(list(##arguments)) + +/// A wrapper for _AddComonent that passes in a source. +/// Necessary if dupe_mode is set to COMPONENT_DUPE_SOURCES. +#define AddComponentFrom(source, arguments...) _AddComponent(list(##arguments), source) + +/// A wrapper for _LoadComponent that allows us to pretend we're using normal named arguments +#define LoadComponent(arguments...) _LoadComponent(list(##arguments)) diff --git a/code/__DEFINES/dcs/signals/signals_reagents.dm b/code/__DEFINES/dcs/signals/signals_reagents.dm new file mode 100644 index 00000000000..c4a7436e51d --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_reagents.dm @@ -0,0 +1,21 @@ + +///from base of [/datum/reagent/proc/expose_atom]: (/mob/living, reac_volume, methods, show_message, touch_protection, /mob/eye/blob) // ovemind arg is only used by blob reagents. +#define COMSIG_REAGENT_EXPOSE_MOB "reagent_expose_mob" + +///from base of [/datum/reagents/proc/add_reagent]: (/datum/reagent, amount, reagtemp, data, no_react) +#define COMSIG_REAGENTS_NEW_REAGENT "reagents_new_reagent" +///from base of [/datum/reagents/proc/add_reagent]: (/datum/reagent, amount, reagtemp, data, no_react) +#define COMSIG_REAGENTS_ADD_REAGENT "reagents_add_reagent" +///from base of [/datum/reagents/proc/del_reagent]: (/datum/reagent) +#define COMSIG_REAGENTS_DEL_REAGENT "reagents_del_reagent" +///from base of [/datum/reagents/proc/remove_reagent]: (/datum/reagent, amount) +#define COMSIG_REAGENTS_REM_REAGENT "reagents_rem_reagent" +///from base of [/datum/reagents/proc/clear_reagents]: () +#define COMSIG_REAGENTS_CLEAR_REAGENTS "reagents_clear_reagents" +///from base of [/datum/reagents/proc/handle_reactions]: (num_reactions) +#define COMSIG_REAGENTS_REACTED "reagents_reacted" + +///from base of [/datum/reagents/proc/update_total()] +#define COMSIG_REAGENTS_HOLDER_UPDATED "reagents_update_total" +///from base of [/datum/reagents/proc/set_temperature]: (new_temp, old_temp) +#define COMSIG_REAGENTS_TEMP_CHANGE "reagents_temp_change" diff --git a/code/__DEFINES/liquids.dm b/code/__DEFINES/liquids.dm index 0d68cde5451..a20480c6293 100644 --- a/code/__DEFINES/liquids.dm +++ b/code/__DEFINES/liquids.dm @@ -91,7 +91,3 @@ GLOBAL_LIST_INIT(liquid_blacklist, list( )) - -///from base of [/datum/reagents/proc/del_reagent]: (/datum/reagent) -#define COMSIG_REAGENTS_DEL_REAGENT "reagents_del_reagent" -#define COMSIG_REAGENTS_EXPOSE_TEMPERATURE "reagents_expose_temperature" diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm index 7825769cb92..1f02f26e9fd 100644 --- a/code/__DEFINES/movespeed_modification.dm +++ b/code/__DEFINES/movespeed_modification.dm @@ -49,7 +49,6 @@ #define MOVESPEED_ID_SEPIA "SEPIA" -#define MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD "MONKEY_REAGENT_SPEEDMOD" #define MOVESPEED_ID_MONKEY_TEMPERATURE_SPEEDMOD "MONKEY_TEMPERATURE_SPEEDMOD" #define MOVESPEED_ID_MONKEY_HEALTH_SPEEDMOD "MONKEY_HEALTH_SPEEDMOD" diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm index 29f482a51b5..381d6860192 100644 --- a/code/__DEFINES/obj_flags.dm +++ b/code/__DEFINES/obj_flags.dm @@ -14,6 +14,9 @@ #define BLOCK_Z_IN_DOWN (1<<10) // Should this object block z falling from above? #define BLOCK_Z_IN_UP (1<<11) // Should this object block z uprise from below? #define IGNORE_SINK (1<<12) +#define BLOCKS_CONSTRUCTION (1<<13) //! Does this object prevent things from being built on it? For things that might change density. +#define BLOCKS_CONSTRUCTION_DIR (1<<14) //! Does this object prevent same-direction things from being built on it? +#define IGNORE_DENSITY (1<<15) //! Can we ignore density when building on this object? (for example, directional windows and grilles) // If you add new ones, be sure to add them to /obj/Initialize as well for complete mapping support @@ -56,3 +59,8 @@ /// use on color subtypes for clothes, so the unit test for crafting doesn't scream at you. #define CRAFTING_TEST_EXCLUDE (1<<0) + +/// Flags for specifically what kind of items to get in get_equipped_items +#define INCLUDE_POCKETS (1<<0) +#define INCLUDE_ACCESSORIES (1<<1) +#define INCLUDE_HELD (1<<2) diff --git a/code/__DEFINES/qualities.dm b/code/__DEFINES/qualities.dm new file mode 100644 index 00000000000..7d46f24684b --- /dev/null +++ b/code/__DEFINES/qualities.dm @@ -0,0 +1,40 @@ +// For recipe and crafting quality defines + +#define BLACKSMITH_QUALITY_SPOILED -8 // Spoil bars and crude smithing skill +#define BLACKSMITH_QUALITY_AWFUL -5 // Shit bars and crude skill +#define BLACKSMITH_QUALITY_CRUDE -2 +#define BLACKSMITH_QUALITY_ROUGH -1 +#define BLACKSMITH_QUALITY_COMPETENT 0 +#define BLACKSMITH_QUALITY_FINE 2 +#define BLACKSMITH_QUALITY_FLAWLESS 5 +#define BLACKSMITH_QUALITY_LEGENDARY 8 + +//Smelting quality results +#define SMELTERY_QUALITY_SPOIL 1 +#define SMELTERY_QUALITY_POOR 2 +#define SMELTERY_QUALITY_NORMAL 3 +#define SMELTERY_QUALITY_GOOD 4 +#define SMELTERY_QUALITY_GREAT 5 +#define SMELTERY_QUALITY_EXCELLENT 6 + +#define SMELTING_DENOMINATOR 21 + +//Food and reagent qualities for cooking +#define COOK_QUALITY_NORMAL 1 +#define COOK_QUALITY_NICE 2 +#define COOK_QUALITY_GOOD 3 +#define COOK_QUALITY_VERYGOOD 4 + +/// Labels for food quality +GLOBAL_ALIST_INIT(food_quality_description, alist( + COOK_QUALITY_NORMAL = "okay", + COOK_QUALITY_NICE = "nice", + COOK_QUALITY_GOOD = "good", + COOK_QUALITY_VERYGOOD = "very good", +)) + +// Stardew Valley-style qualities +#define CROP_QUALITY_REGULAR 1 +#define CROP_QUALITY_SILVER 2 +#define CROP_QUALITY_GOLD 3 +#define CROP_QUALITY_DIAMOND 4 diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index 3eee3288189..9fd4ada7968 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -38,13 +38,10 @@ /// Used for direct snorting of reagents #define SNORT (1<<5) - -//defines passed through to the on_reagent_change proc -#define DEL_REAGENT 1 // reagent deleted (fully cleared) -#define ADD_REAGENT 2 // reagent added -#define REM_REAGENT 3 // reagent removed (may still exist) -#define CLEAR_REAGENTS 4 // all reagents were cleared -#define REACT_REAGENTS 5 // a reaction occured +///The smallest amount of volume allowed - prevents tiny numbers +#define CHEMICAL_VOLUME_MINIMUM 0.001 +///The maximum temperature a reagent holder can attain +#define CHEMICAL_MAXIMUM_TEMPERATURE 99999 #define MIMEDRINK_SILENCE_DURATION 30 //ends up being 60 seconds given 1 tick every 2 seconds //used by chem masters and pill presses diff --git a/code/__DEFINES/roguetown.dm b/code/__DEFINES/roguetown.dm index c527374471b..5941090fbd3 100644 --- a/code/__DEFINES/roguetown.dm +++ b/code/__DEFINES/roguetown.dm @@ -155,13 +155,6 @@ GLOBAL_LIST_EMPTY(job_respawn_delays) #define M_SILVER M_IRON*3 // one silver bar #define M_GOLD M_IRON*5 // one gold bar -// Skill costs - a rarity value add, items requiring a high skill to produce are rarer and has more intrinsic value. So craftsmen can make a profit. -#define SKILL_1 2 -#define SKILL_2 4 -#define SKILL_3 6 -#define SKILL_4 8 -#define SKILL_5 10 - // Work costs - valued VERY low compared to raw materials, this is a problem but at least its systemic and visible now and can be adjusted. Very rough, time to gather stuff, refine it etc etc as well as crafting time itself. #define W_MINOR 2 // Less than 10 seconds of work #define W_MODERATE W_MINOR * 3 // Less than 1 minute of work, high skill required diff --git a/code/__DEFINES/skills.dm b/code/__DEFINES/skills.dm index ef5c974f4f1..8f190685370 100644 --- a/code/__DEFINES/skills.dm +++ b/code/__DEFINES/skills.dm @@ -18,21 +18,3 @@ // Gets the reference for the skill type that was given #define GetSkillRef(A) (SSskills.all_skills[A]) - -//Blacksmith resultant skills -#define BLACKSMITH_LEVEL_MIN -10 -#define BLACKSMITH_LEVEL_SPOIL -2 // Spoil bars and crude smithing skill -#define BLACKSMITH_LEVEL_AWFUL -1 // Shit bars and crude skill -#define BLACKSMITH_LEVEL_CRUDE 0 -#define BLACKSMITH_LEVEL_ROUGH 1 -#define BLACKSMITH_LEVEL_COMPETENT 2 -#define BLACKSMITH_LEVEL_FINE 3 -#define BLACKSMITH_LEVEL_FLAWLESS 4 -#define BLACKSMITH_LEVEL_LEGENDARY 5 -#define BLACKSMITH_LEVEL_MAX 10 - -//Smelting quality results -#define SMELTERY_LEVEL_SPOIL 0 -#define SMELTERY_LEVEL_POOR 1 -#define SMELTERY_LEVEL_NORMAL 2 // Average, same as it always was -#define SMELTERY_LEVEL_GOOD 3 diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 3ebd905dea8..37358aac3d6 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -167,6 +167,7 @@ #define FIRE_PRIORITY_RESEARCH 10 #define FIRE_PRIORITY_VIS 10 #define FIRE_PRIORITY_AMBIENCE 10 +#define FIRE_PRIORITY_PARTICLE_SPEWERS 10 #define FIRE_PRIORITY_GARBAGE 15 #define FIRE_PRIORITY_INCONE 19 #define FIRE_PRIORITY_MOUSECHARGE 20 diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm index 4db63816e8f..c37f2d163a6 100644 --- a/code/__DEFINES/tools.dm +++ b/code/__DEFINES/tools.dm @@ -27,6 +27,3 @@ // If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY, // tool sound is only played when op is started. If not, it's played twice. #define MIN_TOOL_SOUND_DELAY 20 - - -#define TOOL_USAGE_TONGS (1<<0) diff --git a/code/__DEFINES/traits/definitions.dm b/code/__DEFINES/traits/definitions.dm index b8b86950510..93194f14d1a 100644 --- a/code/__DEFINES/traits/definitions.dm +++ b/code/__DEFINES/traits/definitions.dm @@ -514,7 +514,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NOEMBED "noembed" /// Can't be teleported #define TRAIT_NO_TELEPORT "no-teleport" //you just can't +/// Item is too hot to pick up by hands, must use tongs. #define TRAIT_NEEDS_QUENCH "Needs Quenching" +/// Item has been recently smelted and should give XP when retrieved +#define TRAIT_NEWLY_SMELTED "newly_smelted" /// Properly wielded two handed item #define TRAIT_WIELDED "wielded" /// The items needs two hands to be carried @@ -530,3 +533,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// This object has sound debugging tools attached to it #define TRAIT_SOUND_DEBUGGED "sound_debugged" +/// Generic atom traits +/// Stops someone from splashing their reagent_container on an object with this trait +#define TRAIT_DO_NOT_SPLASH "do_not_splash" diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index 93c5e99f09b..c2129d4a2ef 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -83,6 +83,7 @@ #define VV_HK_TRIGGER_EXPLOSION "explode" #define VV_HK_AUTO_RENAME "auto_rename" #define VV_HK_ADD_AI "add_ai" +#define VV_HK_ADJUST_ANIMATIONS "adjust_animations" // /obj #define VV_HK_OSAY "osay" diff --git a/code/__HELPERS/turfs.dm b/code/__HELPERS/turfs.dm index 2368c48cd81..7ec35a62610 100644 --- a/code/__HELPERS/turfs.dm +++ b/code/__HELPERS/turfs.dm @@ -90,3 +90,26 @@ LAZYSET(modifiers, ICON_X, "[(click_turf_px - click_turf.pixel_x) + ((click_turf_x - click_turf.x) * 32)]") LAZYSET(modifiers, ICON_Y, "[(click_turf_py - click_turf.pixel_y) + ((click_turf_y - click_turf.y) * 32)]") return click_turf + +/** + * Checks whether the target turf is in a valid state to accept a directional construction + * such as windows or railings. + * + * Returns FALSE if the target turf cannot accept a directional construction. + * Returns TRUE otherwise. + * + * Arguments: + * * dest_turf - The destination turf to check for existing directional constructions + * * test_dir - The prospective dir of some atom you'd like to put on this turf. + * * is_fulltile - Whether the thing you're attempting to move to this turf takes up the entire tile or whether it supports multiple movable atoms on its tile. + */ +/proc/valid_build_direction(turf/dest_turf, test_dir, is_fulltile = FALSE) + if(!dest_turf) + return FALSE + for(var/obj/turf_content in dest_turf) + if(turf_content.obj_flags & BLOCKS_CONSTRUCTION_DIR) + if(is_fulltile) // for making it so fulltile things can't be built over directional things--a special case + return FALSE + if(turf_content.dir == test_dir) + return FALSE + return TRUE diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 50bb4158c86..54ce64f5872 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -26,6 +26,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_EMOTEMUTE " = TRAIT_EMOTEMUTE, "TRAIT_DEAF" = TRAIT_DEAF, "TRAIT_HUSK" = TRAIT_HUSK, + "TRAIT_DO_NOT_SPLASH" = TRAIT_DO_NOT_SPLASH, "TRAIT_DUMB" = TRAIT_DUMB, "TRAIT_MONKEYLIKE" = TRAIT_MONKEYLIKE, "TRAIT_PACIFISM" = TRAIT_PACIFISM, diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 489bdb620ef..d6401dc3e4a 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -194,7 +194,7 @@ adf = round(adf * 0.6) user.changeNext_move(adf) - for(var/obj/item/clothing/worn_thing in get_equipped_items(include_pockets = TRUE))//checks clothing worn by src. + for(var/obj/item/clothing/worn_thing in get_equipped_items(INCLUDE_POCKETS))//checks clothing worn by src. // Things that are supposed to be worn, being held = cannot block if(isclothing(worn_thing)) if(worn_thing in held_items) diff --git a/code/controllers/subsystem/dcs.dm b/code/controllers/subsystem/dcs.dm index ca6768e45bf..946a01530ff 100644 --- a/code/controllers/subsystem/dcs.dm +++ b/code/controllers/subsystem/dcs.dm @@ -29,7 +29,7 @@ PROCESSING_SUBSYSTEM_DEF(dcs) var/datum/element/eletype = arguments[1] var/list/fullid = list("[eletype]") var/list/named_arguments = list() - for(var/i in initial(eletype.id_arg_index) to length(arguments)) + for(var/i in initial(eletype.argument_hash_start_idx) to length(arguments)) var/key = arguments[i] var/value if(istext(key)) diff --git a/code/controllers/subsystem/merchant.dm b/code/controllers/subsystem/merchant.dm index 9aa35ba32fa..3c8bbd66f87 100644 --- a/code/controllers/subsystem/merchant.dm +++ b/code/controllers/subsystem/merchant.dm @@ -107,8 +107,8 @@ SUBSYSTEM_DEF(merchant) if(output) var/list/all_requirements = list() - if(recipe.req_bar) - all_requirements[recipe.req_bar] = recipe.num_of_materials + if(recipe.required_material) + all_requirements[recipe.required_material] = recipe.num_of_materials if(length(recipe.additional_items)) for(var/item in recipe.additional_items) diff --git a/code/controllers/subsystem/processing/particle_spewers.dm b/code/controllers/subsystem/processing/particle_spewers.dm new file mode 100644 index 00000000000..ce2fa703684 --- /dev/null +++ b/code/controllers/subsystem/processing/particle_spewers.dm @@ -0,0 +1,7 @@ +/// Processing subsystem used by particle spewers. +/// Low-priority background subsystem bc they're not exactly the most performant thing. +PROCESSING_SUBSYSTEM_DEF(particle_spewers) + name = "Particle Spewer Processing" + wait = 0.1 SECONDS + priority = FIRE_PRIORITY_PARTICLE_SPEWERS + stat_tag = "PSP" diff --git a/code/controllers/subsystem/skills.dm b/code/controllers/subsystem/skills.dm index 69ce0103c5a..559a8ff523d 100644 --- a/code/controllers/subsystem/skills.dm +++ b/code/controllers/subsystem/skills.dm @@ -10,8 +10,23 @@ SUBSYSTEM_DEF(skills) ///Dictionary of skill.type || skill ref var/list/all_skills = list() ///Static assoc list of levels (ints) - strings - var/list/level_names = list(span_info("Weak"), span_info("Average"), span_biginfo("Skilled"), span_biginfo("Expert"), "Master", span_greentext("Legendary"))//This list is already in the right order, due to indexing - + var/list/level_names = list( + span_info("Weak"), \ + span_info("Average"), \ + span_biginfo("Skilled"), \ + span_biginfo("Expert"), \ + "Master", \ + span_greentext("Legendary"))//This list is already in the right order, due to indexing + /// All level plain names without span + var/static/alist/level_names_plain = alist( + SKILL_LEVEL_NONE = "None", + SKILL_LEVEL_NOVICE = "Weak", + SKILL_LEVEL_APPRENTICE = "Average", + SKILL_LEVEL_JOURNEYMAN = "Skilled", + SKILL_LEVEL_EXPERT = "Expert", + SKILL_LEVEL_MASTER = "Master", + SKILL_LEVEL_LEGENDARY = "Legendary", + ) /datum/controller/subsystem/skills/Initialize(timeofday) InitializeSkills() diff --git a/code/controllers/subsystem/storyteller.dm b/code/controllers/subsystem/storyteller.dm index a7243efae39..3241b15cb6e 100644 --- a/code/controllers/subsystem/storyteller.dm +++ b/code/controllers/subsystem/storyteller.dm @@ -1563,7 +1563,7 @@ SUBSYSTEM_DEF(gamemode) var/mob/living/carbon/human/human_mob = client.mob current_valid_humans += human_mob record_round_statistic(STATS_TOTAL_POPULATION) - for(var/obj/item/clothing/neck/current_item in human_mob.get_equipped_items(TRUE)) + for(var/obj/item/clothing/neck/current_item in human_mob.get_equipped_items(INCLUDE_POCKETS)) if(current_item.type in list(/obj/item/clothing/neck/psycross, /obj/item/clothing/neck/psycross/silver, /obj/item/clothing/neck/psycross/gold)) record_round_statistic(STATS_PSYCROSS_USERS) break diff --git a/code/datums/ai/behaviours/resist.dm b/code/datums/ai/behaviours/resist.dm index 40d7759700c..c02ea15bd4e 100644 --- a/code/datums/ai/behaviours/resist.dm +++ b/code/datums/ai/behaviours/resist.dm @@ -1,5 +1,15 @@ -/datum/ai_behavior/resist/perform(delta_time, datum/ai_controller/controller) +/datum/ai_behavior/resist/perform(seconds_per_tick, datum/ai_controller/controller) . = ..() var/mob/living/living_pawn = controller.pawn - living_pawn.resist() + living_pawn.execute_resist() finish_action(controller, TRUE) + +/datum/ai_behavior/resist/finish_action(datum/ai_controller/controller, succeeded, ...) + . = ..() + var/mob/living/living_pawn = controller.pawn + if(QDELETED(living_pawn)) + return + if(SHOULD_RESIST(living_pawn)) + living_pawn.ai_controller.set_blackboard_key(BB_RESISTING, TRUE) + else + living_pawn.ai_controller.set_blackboard_key(BB_RESISTING, FALSE) diff --git a/code/datums/ai/subtrees/generic_resist.dm b/code/datums/ai/subtrees/generic_resist.dm index 52f6f605272..3d9e73115a8 100644 --- a/code/datums/ai/subtrees/generic_resist.dm +++ b/code/datums/ai/subtrees/generic_resist.dm @@ -7,20 +7,3 @@ if(SHOULD_RESIST(living_pawn) && SPT_PROB(75, seconds_per_tick)) controller.queue_behavior(/datum/ai_behavior/resist) //BRO IM ON FUCKING FIRE BRO return SUBTREE_RETURN_FINISH_PLANNING //IM NOT DOING ANYTHING ELSE BUT EXTINGUISH MYSELF, GOOD GOD HAVE MERCY. - -/datum/ai_behavior/resist/perform(seconds_per_tick, datum/ai_controller/controller) - var/mob/living/living_pawn = controller.pawn - living_pawn.ai_controller.set_blackboard_key(BB_RESISTING, TRUE) - living_pawn.execute_resist() - finish_action(controller, TRUE) - return TRUE - -/datum/ai_behavior/resist/finish_action(datum/ai_controller/controller, succeeded, ...) - . = ..() - var/mob/living/living_pawn = controller.pawn - if(QDELETED(living_pawn)) - return - if(SHOULD_RESIST(living_pawn)) - living_pawn.ai_controller.set_blackboard_key(BB_RESISTING, TRUE) - else - living_pawn.ai_controller.set_blackboard_key(BB_RESISTING, FALSE) diff --git a/code/datums/brewing_recipes/_base.dm b/code/datums/brewing_recipes/_base.dm index 037ae98309b..b88026cba0c 100644 --- a/code/datums/brewing_recipes/_base.dm +++ b/code/datums/brewing_recipes/_base.dm @@ -86,11 +86,8 @@ // Create quality calculator with the calculated quality var/datum/quality_calculator/brewing/brew_calc = new( - base_qual = 0, mat_qual = quality, skill_qual = brewing_skill, - perf_qual = 0, - diff_mod = 0, components = 1, fresh = 0, // Freshness already factored into quality calculation recipe_mod = quality_modifier @@ -112,7 +109,7 @@ var/total_freshness = 0 var/ingredient_count = 0 var/highest_food_quality = 0 - var/highest_input_reagent_quality = 0 + var/highest_input_recipe_quality = 0 var/total_reagent_volume = 0 // Calculate average freshness and find highest quality food ingredient from crops @@ -141,8 +138,7 @@ for(var/datum/reagent/R in keg.reagents.reagent_list) if(R.volume > 0) total_reagent_volume += R.volume - if(R.recipe_quality) - highest_input_reagent_quality = max(highest_input_reagent_quality, R.recipe_quality) + highest_input_recipe_quality = max(highest_input_recipe_quality, R.get_recipe_quality()) // Calculate average freshness var/average_freshness = (ingredient_count > 0) ? (total_freshness / ingredient_count) : 0 @@ -154,21 +150,18 @@ // Use the quality calculator to determine final quality (matching cooking system) var/datum/quality_calculator/brewing/brew_calc = new( - base_qual = 0, - mat_qual = max(highest_food_quality, highest_input_reagent_quality), // Use the higher of food or reagent quality + mat_qual = max(highest_food_quality, highest_input_recipe_quality), // Use the higher of food or reagent quality skill_qual = brewing_skill, - perf_qual = 0, - diff_mod = 0, components = 1, fresh = average_freshness, recipe_mod = quality_modifier, - reagent_qual = highest_input_reagent_quality + reagent_qual = highest_input_recipe_quality ) var/final_quality = brew_calc.calculate_final_quality() qdel(brew_calc) - return CLAMP(final_quality, 1, 4) + return CLAMP(final_quality, COOK_QUALITY_NORMAL, COOK_QUALITY_VERYGOOD) /datum/brewing_recipe/proc/generate_html(mob/user) var/client/client = user diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index d6f1b439829..f165b5cb629 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -27,6 +27,9 @@ /// Make sure you also implement PostTransfer for any post transfer handling var/can_transfer = FALSE + /// A lazy list of the sources for this component + var/list/sources + /** * Create a new component. * Additional arguments are passed to `Initialize()` @@ -141,6 +144,28 @@ /datum/component/proc/UnregisterFromParent() return +/** + * Called when the component has a new source registered. + * Return COMPONENT_INCOMPATIBLE to signal that the source is incompatible and should not be added + */ +/datum/component/proc/on_source_add(source, ...) + SHOULD_CALL_PARENT(TRUE) + if(dupe_mode != COMPONENT_DUPE_SOURCES) + return COMPONENT_INCOMPATIBLE + LAZYOR(sources, source) + +/** + * Called when the component has a source removed. + * You probably want to call parent after you do your logic because at the end of this we qdel if we have no sources remaining! + */ +/datum/component/proc/on_source_remove(source) + SHOULD_CALL_PARENT(TRUE) + if(dupe_mode != COMPONENT_DUPE_SOURCES) + CRASH("Component '[type]' does not use sources but is trying to remove a source") + LAZYREMOVE(sources, source) + if(!LAZYLEN(sources)) + qdel(src) + /** * Register to listen for a signal from the passed in target * @@ -246,6 +271,18 @@ /datum/component/proc/InheritComponent(datum/component/C, i_am_original) return +/** + * Called on a component when a component of the same type was added to the same parent with [COMPONENT_DUPE_SELECTIVE] + * + * See [/datum/component/var/dupe_mode] + * + * `C`'s type will always be the same of the called component + * + * return TRUE if you are absorbing the component, otherwise FALSE if you are fine having it exist as a duplicate component + */ +/datum/component/proc/CheckDupeComponent(datum/component/C, ...) + return + /** * Callback Just before this component is transferred * @@ -308,7 +345,7 @@ */ /datum/proc/GetComponent(datum/component/c_type) RETURN_TYPE(c_type) - if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED) + if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED || initial(c_type.dupe_mode) == COMPONENT_DUPE_SELECTIVE) stack_trace("GetComponent was called to get a component of which multiple copies could be on an object. This can easily break and should be changed. Type: \[[c_type]\]") var/list/dc = datum_components if(!dc) @@ -327,20 +364,20 @@ */ /datum/proc/GetExactComponent(datum/component/c_type) RETURN_TYPE(c_type) - if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED) + var/initial_type_mode = c_type::dupe_mode + if(initial_type_mode == COMPONENT_DUPE_ALLOWED || initial_type_mode == COMPONENT_DUPE_SELECTIVE) stack_trace("GetComponent was called to get a component of which multiple copies could be on an object. This can easily break and should be changed. Type: \[[c_type]\]") - var/list/dc = datum_components - if(!dc) + var/list/all_components = datum_components + if(!all_components) return null - var/datum/component/C = dc[c_type] - if(C) - if(length(C)) - var/list/components = C - C = components[1] - if(C.type == c_type) - return C + var/datum/component/potential_component + if(length(all_components)) + potential_component = all_components[c_type] + if(potential_component?.type == c_type) + return potential_component return null + /** * Get all components of a given type that are attached to this datum * @@ -357,64 +394,114 @@ /** * Creates an instance of `new_type` in the datum and attaches to it as parent - * Sends the `COMSIG_COMPONENT_ADDED` signal to the datum - * Returns the component that was created. Or the old component in a dupe situation where `COMPONENT_DUPE_UNIQUE` was set - * If this tries to add an component to an incompatible type, the component will be deleted and the result will be `null`. This is very unperformant, try not to do it + * + * Sends the [COMSIG_COMPONENT_ADDED] signal to the datum + * + * Returns the component that was created. Or the old component in a dupe situation where [COMPONENT_DUPE_UNIQUE] was set + * + * If this tries to add a component to an incompatible type, the component will be deleted and the result will be `null`. This is very unperformant, try not to do it + * * Properly handles duplicate situations based on the `dupe_mode` var */ -/datum/proc/_AddComponent(list/raw_args) - var/new_type = raw_args[1] - var/datum/component/nt = new_type - var/dm = initial(nt.dupe_mode) - var/dt = initial(nt.dupe_type) - - var/datum/component/old_comp - var/datum/component/new_comp - - if(ispath(nt)) - if(nt == /datum/component) - CRASH("[nt] attempted instantiation!") +/datum/proc/_AddComponent(list/raw_args, source) + var/original_type = raw_args[1] + var/datum/component/component_type = original_type + + if(QDELING(src)) + CRASH("Attempted to add a new component of type \[[component_type]\] to a qdeleting parent of type \[[type]\]!") + + var/dupe_mode = initial(component_type.dupe_mode) + var/dupe_type = initial(component_type.dupe_type) + var/uses_sources = (dupe_mode == COMPONENT_DUPE_SOURCES) + if(uses_sources && !source) + CRASH("Attempted to add a sourced component of type '[component_type]' to '[type]' without a source!") + else if(!uses_sources && source) + CRASH("Attempted to add a normal component of type '[component_type]' to '[type]' with a source!") + + var/datum/component/old_component + var/datum/component/new_component + + if(ispath(component_type)) + if(component_type == /datum/component) + CRASH("[component_type] attempted instantiation!") else - new_comp = nt - nt = new_comp.type + new_component = component_type + component_type = new_component.type raw_args[1] = src - - if(dm != COMPONENT_DUPE_ALLOWED) - if(!dt) - old_comp = GetExactComponent(nt) + if(dupe_mode != COMPONENT_DUPE_ALLOWED && dupe_mode != COMPONENT_DUPE_SELECTIVE) + if(!dupe_type) + old_component = GetExactComponent(component_type) else - old_comp = GetComponent(dt) - if(old_comp) - switch(dm) + old_component = GetComponent(dupe_type) + + if(old_component) + switch(dupe_mode) if(COMPONENT_DUPE_UNIQUE) - if(!new_comp) - new_comp = new nt(raw_args) - if(!QDELETED(new_comp)) - old_comp.InheritComponent(new_comp, TRUE) - QDEL_NULL(new_comp) + if(!new_component) + new_component = new component_type(raw_args) + if(!QDELETED(new_component)) + old_component.InheritComponent(new_component, TRUE) + QDEL_NULL(new_component) + if(COMPONENT_DUPE_HIGHLANDER) - if(!new_comp) - new_comp = new nt(raw_args) - if(!QDELETED(new_comp)) - new_comp.InheritComponent(old_comp, FALSE) - QDEL_NULL(old_comp) + if(!new_component) + new_component = new component_type(raw_args) + if(!QDELETED(new_component)) + new_component.InheritComponent(old_component, FALSE) + QDEL_NULL(old_component) + if(COMPONENT_DUPE_UNIQUE_PASSARGS) - if(!new_comp) + if(!new_component) var/list/arguments = raw_args.Copy(2) arguments.Insert(1, null, TRUE) - old_comp.InheritComponent(arglist(arguments)) + old_component.InheritComponent(arglist(arguments)) else - old_comp.InheritComponent(new_comp, TRUE) - else if(!new_comp) - new_comp = new nt(raw_args) // There's a valid dupe mode but there's no old component, act like normal - else if(!new_comp) - new_comp = new nt(raw_args) // Dupes are allowed, act like normal + old_component.InheritComponent(new_component, TRUE) + + if(COMPONENT_DUPE_SOURCES) + if(source in old_component.sources) + return old_component // source already registered, no work to do + + if(old_component.on_source_add(arglist(list(source) + raw_args.Copy(2))) == COMPONENT_INCOMPATIBLE) + stack_trace("incompatible source added to a [old_component.type]. Args: [json_encode(raw_args)]") + return null + + else if(!new_component) + new_component = new component_type(raw_args) // There's a valid dupe mode but there's no old component, act like normal + + else if(dupe_mode == COMPONENT_DUPE_SELECTIVE) + var/list/arguments = raw_args.Copy() + arguments[1] = new_component + var/make_new_component = TRUE + for(var/datum/component/existing_component as anything in GetComponents(original_type)) + if(existing_component.CheckDupeComponent(arglist(arguments))) + make_new_component = FALSE + QDEL_NULL(new_component) + break + if(!new_component && make_new_component) + new_component = new component_type(raw_args) + + else if(!new_component) + new_component = new component_type(raw_args) // Dupes are allowed, act like normal + + if(!old_component && !QDELETED(new_component)) // Nothing related to duplicate components happened and the new component is healthy + if(uses_sources) // add the sources to the new component + new_component.on_source_add(arglist(list(source) + raw_args.Copy(2))) + SEND_SIGNAL(src, COMSIG_COMPONENT_ADDED, new_component) + return new_component + + return old_component - if(!old_comp && !QDELETED(new_comp)) // Nothing related to duplicate components happened and the new component is healthy - SEND_SIGNAL(src, COMSIG_COMPONENT_ADDED, new_comp) - return new_comp - return old_comp +/** + * Removes a component source from this datum + */ +/datum/proc/RemoveComponentSource(source, datum/component/component_type) + if(ispath(component_type)) + component_type = GetExactComponent(component_type) + if(!component_type) + return + component_type.on_source_remove(source) /** * Get existing component of type, or create it and return a reference to it @@ -425,15 +512,16 @@ * * component_type The typepath of the component to create or return * * ... additional arguments to be passed when creating the component if it does not exist */ -/datum/proc/LoadComponent(component_type, ...) - . = GetComponent(component_type) +/datum/proc/_LoadComponent(list/arguments) + . = GetComponent(arguments[1]) if(!.) - return _AddComponent(args) + return _AddComponent(arguments) /** * Removes the component from parent, ends up with a null parent + * Used as a helper proc by the component transfer proc, does not clean up the component like Destroy does */ -/datum/component/proc/RemoveComponent() +/datum/component/proc/ClearFromParent() if(!parent) return var/datum/old_parent = parent @@ -454,7 +542,7 @@ if(!target || target.parent == src) return if(target.parent) - target.RemoveComponent() + target.ClearFromParent() target.parent = src var/result = target.PostTransfer() switch(result) diff --git a/code/datums/components/augments/augment_datums/skills.dm b/code/datums/components/augments/augment_datums/skills.dm index 3811decc64e..9ba4c2dd8a5 100644 --- a/code/datums/components/augments/augment_datums/skills.dm +++ b/code/datums/components/augments/augment_datums/skills.dm @@ -73,7 +73,7 @@ /datum/augment/skill/smithing_optimizer name = "smithing precision optimizer" desc = "Enhances hammer control and metal working precision." - skill_changes = list(/datum/skill/craft/blacksmithing = 1, /datum/skill/craft/smelting = 1) + skill_changes = list(/datum/skill/craft/blacksmithing = 1) engineering_difficulty = SKILL_LEVEL_JOURNEYMAN installation_time = 15 SECONDS diff --git a/code/datums/components/container_craft/_container_craft.dm b/code/datums/components/container_craft/_container_craft.dm index 2055731eedb..09e4f1f73d7 100644 --- a/code/datums/components/container_craft/_container_craft.dm +++ b/code/datums/components/container_craft/_container_craft.dm @@ -39,13 +39,15 @@ on_craft_finished = success RegisterSignal(parent, COMSIG_STORAGE_CLOSED, PROC_REF(async_start)) RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(async_start)) - if(temperature_listener) - RegisterSignal(parent, COMSIG_REAGENTS_EXPOSE_TEMPERATURE, PROC_REF(async_start)) + if(temperature_listener && isatom(parent)) + var/atom/parent_atom = parent + RegisterSignal(parent_atom.reagents, COMSIG_REAGENTS_TEMP_CHANGE, PROC_REF(async_start)) /** * Asynchronously start crafting */ /datum/component/container_craft/proc/async_start(datum/source, mob/user) + SIGNAL_HANDLER INVOKE_ASYNC(src, PROC_REF(attempt_crafts), source, user) /** diff --git a/code/datums/components/container_craft/recipes/_base.dm b/code/datums/components/container_craft/recipes/_base.dm index a4af467e8dd..612ba5daadd 100644 --- a/code/datums/components/container_craft/recipes/_base.dm +++ b/code/datums/components/container_craft/recipes/_base.dm @@ -353,7 +353,7 @@ GLOBAL_LIST_INIT(container_craft_to_singleton, init_container_crafts()) var/total_freshness = 0 var/ingredient_count = 0 var/highest_food_quality = 0 - var/highest_reagent_quality = 0 + var/highest_recipe_quality = 0 var/total_reagent_volume = 0 // Calculate average freshness and find highest quality ingredient @@ -364,7 +364,7 @@ GLOBAL_LIST_INIT(container_craft_to_singleton, init_container_crafts()) if(istype(food_item, /obj/item/reagent_containers/food/snacks)) var/obj/item/reagent_containers/food/snacks/F = food_item total_freshness += max(0, (F.warming + F.rotprocess)) - highest_food_quality = max(highest_food_quality, F.recipe_quality ) + highest_food_quality = max(highest_food_quality, F.recipe_quality) // Check reagent qualities in the crafter container if(crafter.reagents && crafter.reagents.reagent_list) @@ -372,7 +372,7 @@ GLOBAL_LIST_INIT(container_craft_to_singleton, init_container_crafts()) if(R.volume > 0) total_reagent_volume += R.volume // Weight the reagent quality by its volume - highest_reagent_quality = max(highest_reagent_quality, R.recipe_quality) + highest_recipe_quality = max(highest_recipe_quality, R.get_recipe_quality()) // Calculate average freshness var/average_freshness = (ingredient_count > 0) ? (total_freshness / ingredient_count) : 0 @@ -396,7 +396,7 @@ GLOBAL_LIST_INIT(container_craft_to_singleton, init_container_crafts()) food_item.warming = min(5 MINUTES, average_freshness) // Calculate final quality based on ingredients, skill, and recipe - apply_food_quality(food_item, cooking_skill, highest_food_quality, highest_reagent_quality, average_freshness) + apply_food_quality(food_item, cooking_skill, highest_food_quality, highest_recipe_quality, average_freshness) SEND_SIGNAL(crafter, COMSIG_TRY_STORAGE_INSERT, created_output, null, null, TRUE, TRUE) after_craft(created_output, crafter, initiator, found_optional_requirements, found_optional_wildcards, found_optional_reagents, removing_items) @@ -407,20 +407,17 @@ GLOBAL_LIST_INIT(container_craft_to_singleton, init_container_crafts()) * * @param cooking_skill The cooking skill level of the crafter * @param ingredient_quality The highest quality food ingredient used - * @param reagent_quality The highest quality reagent used + * @param recipe_quality The highest quality reagent used * @param freshness The average freshness of ingredients */ -/datum/container_craft/proc/apply_food_quality(obj/item/reagent_containers/food/snacks/food_item, cooking_skill, ingredient_quality, reagent_quality, freshness) +/datum/container_craft/proc/apply_food_quality(obj/item/reagent_containers/food/snacks/food_item, cooking_skill, ingredient_quality, recipe_quality, freshness) var/datum/quality_calculator/cooking/cook_calc = new( - base_qual = 0, - mat_qual = max(ingredient_quality, reagent_quality), // Use the higher of food or reagent quality + mat_qual = max(ingredient_quality, recipe_quality), // Use the higher of food or reagent quality skill_qual = cooking_skill, - perf_qual = 0, - diff_mod = 0, components = 1, fresh = freshness, recipe_mod = quality_modifier, - reagent_qual = reagent_quality // Pass reagent quality separately if needed + reagent_qual = recipe_quality // Pass reagent quality separately if needed ) cook_calc.apply_quality_to_item(food_item) qdel(cook_calc) diff --git a/code/datums/components/container_craft/recipes/cooking_pot/_cooking_pot.dm b/code/datums/components/container_craft/recipes/cooking_pot/_cooking_pot.dm index 8db39f285c7..2c8e2976b60 100644 --- a/code/datums/components/container_craft/recipes/cooking_pot/_cooking_pot.dm +++ b/code/datums/components/container_craft/recipes/cooking_pot/_cooking_pot.dm @@ -74,7 +74,7 @@ var/total_freshness = 0 var/ingredient_count = 0 var/highest_food_quality = 0 - var/highest_input_reagent_quality = 0 + var/highest_input_recipe_quality = 0 var/total_reagent_volume = 0 // Calculate average freshness and find highest quality food ingredient @@ -85,21 +85,21 @@ if(istype(food_item, /obj/item/reagent_containers/food/snacks)) var/obj/item/reagent_containers/food/snacks/F = food_item total_freshness += max(0, (F.warming + F.rotprocess)) - highest_food_quality = max(highest_food_quality, F.recipe_quality ) + highest_food_quality = max(highest_food_quality, F.recipe_quality) // Also check reagents in the food items if(food_item.reagents && food_item.reagents.reagent_list) for(var/datum/reagent/R in food_item.reagents.reagent_list) if(R.volume > 0) total_reagent_volume += R.volume - highest_input_reagent_quality = max(highest_input_reagent_quality, R.recipe_quality) + highest_input_recipe_quality = max(highest_input_recipe_quality, R.get_recipe_quality()) // Check reagent qualities already in the crafter container (like the water) if(crafter.reagents && crafter.reagents.reagent_list) for(var/datum/reagent/R in crafter.reagents.reagent_list) if(R.volume > 0) total_reagent_volume += R.volume - highest_input_reagent_quality = max(highest_input_reagent_quality, R.recipe_quality) + highest_input_recipe_quality = max(highest_input_recipe_quality, R.get_recipe_quality()) // Calculate average freshness var/average_freshness = (ingredient_count > 0) ? (total_freshness / ingredient_count) : 0 @@ -109,21 +109,18 @@ // Use the quality calculator to determine final quality var/datum/quality_calculator/cooking/cook_calc = new( - base_qual = 0, - mat_qual = max(highest_food_quality, highest_input_reagent_quality), // Use the higher of food or reagent quality + mat_qual = max(highest_food_quality, highest_input_recipe_quality), // Use the higher of food or reagent quality skill_qual = cooking_skill, - perf_qual = 0, - diff_mod = 0, components = 1, fresh = average_freshness, recipe_mod = quality_modifier, - reagent_qual = highest_input_reagent_quality + reagent_qual = highest_input_recipe_quality ) var/final_quality = cook_calc.calculate_final_quality() qdel(cook_calc) - return CLAMP(final_quality, 1, 4) + return CLAMP(final_quality, COOK_QUALITY_NORMAL, COOK_QUALITY_VERYGOOD) /datum/container_craft/cooking/after_craft(atom/created_output, obj/item/crafter, mob/initiator, list/found_optional_requirements, list/found_optional_wildcards, list/found_optional_reagents, list/removing_items) . = ..() @@ -151,8 +148,8 @@ extra_taste += " and [ingredient.name]" found_product.name += extra_string found_product.taste_description += extra_taste - found_product.add_data("custom_name", found_product.name) - found_product.add_data("custom_tastes", found_product.taste_description) + LAZYADDASSOC(found_product.data, "custom_name", found_product.name) + LAZYADDASSOC(found_product.data, "custom_tastes", found_product.taste_description) // Optionally modify reagent properties based on quality apply_quality_effects_to_reagent(found_product) @@ -166,6 +163,8 @@ if(!reagent) return + var/reagent_quality = reagent.get_recipe_quality() + /* // Modify reagent properties based on quality switch(reagent.recipe_quality) if(1) // Poor quality @@ -181,11 +180,13 @@ if(4) // Premium quality // Premium quality is much more effective reagent.metabolization_rate *= 0.75 // Metabolizes much slower (very effective) - + */ // Update description to reflect quality - var/quality_desc = reagent.get_recipe_quality_desc() - if(reagent.description && !findtext(reagent.description, quality_desc)) - reagent.description += " This appears to be [quality_desc]." + + // GLOB.food_quality_description[quality] + var/quality_desc = GLOB.food_quality_description[reagent_quality] + if(quality_desc && !findtext(reagent.description, quality_desc)) + reagent.description += " The [lowertext(reagent.name)] is of [quality_desc] quality." /datum/container_craft/cooking/extra_html() var/html diff --git a/code/datums/components/unusual_effects/_spawning_component.dm b/code/datums/components/unusual_effects/_spawning_component.dm index f1972173d47..41624cfe0b9 100644 --- a/code/datums/components/unusual_effects/_spawning_component.dm +++ b/code/datums/components/unusual_effects/_spawning_component.dm @@ -5,7 +5,7 @@ appearance_flags = RESET_ALPHA | RESET_COLOR | RESET_TRANSFORM | KEEP_APART | TILE_BOUND mouse_opacity = MOUSE_OPACITY_TRANSPARENT icon = 'icons/effects/particles/particle.dmi' - icon_state = "dot" + icon_state = "none" underlays = null overlays = null @@ -14,7 +14,7 @@ ///the unusual_description grabbed into the actual handler itself only needed when used as an unusual var/unusual_description = "teehee" ///the duration we last - var/duration = 0.7 SECONDS + var/duration = 0 ///the spawn intervals in game ticks var/spawn_interval = 1 ///particles still in the process of animating @@ -28,7 +28,7 @@ ///the dmi location of the particle var/icon_file = 'icons/effects/particles/particle.dmi' ///the icon_state given to the objects - var/particle_state = "dot" + var/particle_state = "none" ///current process count var/count = 0 ///equipped offset ie hats go to 32 if set to 32 will also reset to height changes @@ -50,9 +50,13 @@ var/particle_blending = BLEND_DEFAULT /// our animate_holder var/datum/animate_holder/animate_holder + /// If the effect is currently paused. + var/paused = FALSE /datum/component/particle_spewer/Initialize(duration = 0, spawn_interval = 0, offset_x = 0, offset_y = 0, icon_file, particle_state, equipped_offset = 0, burst_amount = 0, lifetime = 0, random_bursts = 0) . = ..() + if(!isatom(parent)) + return COMPONENT_INCOMPATIBLE if(icon_file) src.icon_file = icon_file if(particle_state) @@ -79,45 +83,55 @@ animate_holder.animates_self = FALSE adjust_animate_steps() - if(processes) - START_PROCESSING(SSfastprocess, src) + update_processing() RegisterSignal(source_object, COMSIG_ITEM_EQUIPPED, PROC_REF(handle_equip_offsets)) RegisterSignal(source_object, COMSIG_ITEM_POST_UNEQUIP, PROC_REF(reset_offsets)) + RegisterSignal(source_object, COMSIG_MOVABLE_MOVED, PROC_REF(update_processing)) if(lifetime) QDEL_IN(src, lifetime) /datum/component/particle_spewer/Destroy(force) - . = ..() UnregisterSignal(source_object, list( COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_POST_UNEQUIP, + COMSIG_MOVABLE_MOVED, )) - - STOP_PROCESSING(SSfastprocess, src) + STOP_PROCESSING(SSparticle_spewers, src) QDEL_LIST(living_particles) QDEL_LIST(dead_particles) source_object = null QDEL_NULL(animate_holder) + return ..() -/datum/component/particle_spewer/process() +/datum/component/particle_spewer/process(seconds_per_tick) + if(!get_turf(source_object) || paused) + return PROCESS_KILL if(spawn_interval != 1) count++ if(count < spawn_interval) return count = 0 - if(isturf(source_object.loc)) - spawn_particles() + spawn_particles() + +/datum/component/particle_spewer/proc/update_processing() + SIGNAL_HANDLER + if(paused || QDELETED(src) || QDELETED(source_object) || !processes || !get_turf(source_object)) + STOP_PROCESSING(SSparticle_spewers, src) + else + START_PROCESSING(SSparticle_spewers, src) /datum/component/particle_spewer/proc/spawn_particles(atom/movable/mover, turf/target) + if(paused) + return var/burstees = burst_amount if(random_bursts) burstees = rand(1, burst_amount) + var/turf/spawn_loc = get_turf(source_object) for(var/i = 0 to burstees) //create and assign particle its stuff - var/obj/effect/abstract/particle/spawned - spawned = new(get_turf(source_object)) + var/obj/effect/abstract/particle/spawned = new(spawn_loc) if(offsets) spawned.pixel_x = offset_x spawned.pixel_y = offset_y @@ -172,3 +186,13 @@ /obj/item/debug_particle_holder/Initialize(mapload) . = ..() AddComponent(/datum/component/particle_spewer, 2 SECONDS) + +/datum/component/particle_spewer/vv_get_dropdown() + . = ..() + VV_DROPDOWN_OPTION("", "---------") + VV_DROPDOWN_OPTION(VV_HK_ADJUST_ANIMATIONS, "Adjust Animations") + +/datum/component/particle_spewer/vv_do_topic(list/href_list) + . = ..() + if(href_list[VV_HK_ADJUST_ANIMATIONS] && check_rights(R_VAREDIT)) + animate_holder.ui_interact(usr) diff --git a/code/datums/components/unusual_effects/sparkle.dm b/code/datums/components/unusual_effects/sparkle.dm index 40bd45f64e6..41282fe3d81 100644 --- a/code/datums/components/unusual_effects/sparkle.dm +++ b/code/datums/components/unusual_effects/sparkle.dm @@ -1,4 +1,6 @@ /datum/component/particle_spewer/sparkle + + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS icon_file = 'icons/effects/particles/special_particles.dmi' particle_state = "sparkle" @@ -17,6 +19,19 @@ spawn_interval = 0.2 SECONDS burst_amount = 2 +/datum/component/particle_spewer/sparkle/InheritComponent(datum/component/particle_spewer/sparkle/new_comp, i_am_original, shine_more) + if(!i_am_original) + return + src.shine_more = shine_more + if(shine_more) + duration = 1.1 SECONDS + spawn_interval = 0.2 SECONDS + burst_amount = 2 + else + duration = initial(duration) + spawn_interval = initial(spawn_interval) + burst_amount = initial(burst_amount) + /datum/component/particle_spewer/sparkle/animate_particle(obj/effect/abstract/particle/spawned) var/matrix/first = matrix() spawned.pixel_x += rand(-12, 12) // can be anywhere in the tile bounds @@ -40,3 +55,11 @@ QDEL_IN(spawned, duration) +/datum/component/particle_spewer/sparkle/turf_only + +/datum/component/particle_spewer/sparkle/turf_only/update_processing() + if(isturf(source_object.loc)) + paused = FALSE + else + paused = TRUE + ..() diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 348f9e67788..773032b1dd8 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -46,6 +46,3 @@ . = list() if(("name" in vars) && !isatom(src)) . += "[vars["name"]]
" - -/datum/proc/on_reagent_change(changetype) - return diff --git a/code/datums/elements/_element.dm b/code/datums/elements/_element.dm index 1abff1c0c3e..98bed59c370 100644 --- a/code/datums/elements/_element.dm +++ b/code/datums/elements/_element.dm @@ -7,8 +7,17 @@ /datum/element /// Option flags for element behaviour var/element_flags = NONE - - var/id_arg_index = 1 + /** + * The index of the first attach argument to consider for duplicate elements + * + * All arguments from this index onwards (1 based) are hashed into the key to determine + * if this is a new unique element or one already exists + * + * Is only used when flags contains [ELEMENT_BESPOKE] + * + * This is infinity so you must explicitly set this + */ + var/argument_hash_start_idx = 1 /// Activates the functionality defined by the element on the given target datum /datum/element/proc/Attach(datum/target) diff --git a/code/datums/elements/ai_flee_when_hurt.dm b/code/datums/elements/ai_flee_when_hurt.dm index 840d73dd130..b7a7a49117a 100644 --- a/code/datums/elements/ai_flee_when_hurt.dm +++ b/code/datums/elements/ai_flee_when_hurt.dm @@ -3,7 +3,7 @@ */ /datum/element/ai_flee_while_injured element_flags = ELEMENT_BESPOKE - id_arg_index = 2 + argument_hash_start_idx = 2 /// Health value to end fleeing if at or above var/stop_fleeing_at /// Health value to start fleeing if at or below diff --git a/code/datums/elements/appearance/update_icon_updates_onmob.dm b/code/datums/elements/appearance/update_icon_updates_onmob.dm index ab28e8d7d0f..99d1e9800c9 100644 --- a/code/datums/elements/appearance/update_icon_updates_onmob.dm +++ b/code/datums/elements/appearance/update_icon_updates_onmob.dm @@ -2,7 +2,7 @@ //Very good name, I know /datum/element/update_icon_updates_onmob element_flags = ELEMENT_BESPOKE - id_arg_index = 2 + argument_hash_start_idx = 2 ///The ITEM_SLOT_X flags to update on the parent mob. (Ex: ITEM_SLOT_HANDS|ITEM_SLOT_FEET) var/update_flags = NONE diff --git a/code/datums/elements/connect_loc.dm b/code/datums/elements/connect_loc.dm index 79f13befd34..42e0d473bc6 100644 --- a/code/datums/elements/connect_loc.dm +++ b/code/datums/elements/connect_loc.dm @@ -2,7 +2,7 @@ /// When the object moves, it will unhook the signal and rehook it to the new object. /datum/element/connect_loc element_flags = ELEMENT_BESPOKE - id_arg_index = 2 + argument_hash_start_idx = 2 /// An assoc list of signal -> procpath to register to the loc this object is on. var/list/connections diff --git a/code/datums/elements/divine_intervention.dm b/code/datums/elements/divine_intervention.dm index 68c29181e6d..f85f90bf326 100644 --- a/code/datums/elements/divine_intervention.dm +++ b/code/datums/elements/divine_intervention.dm @@ -1,6 +1,6 @@ /datum/element/divine_intervention element_flags = ELEMENT_BESPOKE - id_arg_index = 2 + argument_hash_start_idx = 2 var/datum/stress_event/stress_event var/datum/patron/patron var/allows_pantheon diff --git a/code/datums/elements/hat_wearer.dm b/code/datums/elements/hat_wearer.dm index d1bbade9093..8cf80755372 100644 --- a/code/datums/elements/hat_wearer.dm +++ b/code/datums/elements/hat_wearer.dm @@ -3,7 +3,7 @@ */ /datum/element/hat_wearer element_flags = ELEMENT_BESPOKE - id_arg_index = 2 + argument_hash_start_idx = 2 ///offsets of hats we will wear var/list/offsets diff --git a/code/datums/elements/mob_overlay_effect.dm b/code/datums/elements/mob_overlay_effect.dm index b47721e0ebe..973f1fa9de0 100644 --- a/code/datums/elements/mob_overlay_effect.dm +++ b/code/datums/elements/mob_overlay_effect.dm @@ -4,7 +4,7 @@ ///mob_overlay_effect component. adds and removes /datum/element/mob_overlay_effect element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH - id_arg_index = 2 + argument_hash_start_idx = 2 var/y_offset = 0 var/mask_y_offset = 0 diff --git a/code/datums/elements/noisy_movement.dm b/code/datums/elements/noisy_movement.dm index 7d16518d20f..da28d5344c7 100644 --- a/code/datums/elements/noisy_movement.dm +++ b/code/datums/elements/noisy_movement.dm @@ -1,6 +1,6 @@ /datum/element/noisy_movement element_flags = ELEMENT_BESPOKE - id_arg_index = 2 + argument_hash_start_idx = 2 var/movement_sound var/volume diff --git a/code/datums/elements/relay_attackers.dm b/code/datums/elements/relay_attackers.dm index 2912aad33bf..70ee4a9d2f2 100644 --- a/code/datums/elements/relay_attackers.dm +++ b/code/datums/elements/relay_attackers.dm @@ -57,7 +57,7 @@ var/obj/item/hit_item = hit_atom if(!hit_item.throwforce) return - var/mob/thrown_by = hit_item.thrownby + var/mob/thrown_by = hit_item.thrownby?.resolve() if(!ismob(thrown_by)) return relay_attacker(target, thrown_by, hit_item.throwforce) diff --git a/code/datums/elements/visual_quality.dm b/code/datums/elements/visual_quality.dm new file mode 100644 index 00000000000..9f92973d8b3 --- /dev/null +++ b/code/datums/elements/visual_quality.dm @@ -0,0 +1,48 @@ + +/** + * Stardew Valley-style qualities that modify visuals of an item. + * Attaches a star to the item when picked up and shiny particles if high enough quality. + * Quality defines can be found in qualities.dm +*/ +/datum/element/visual_quality + element_flags = ELEMENT_BESPOKE + argument_hash_start_idx = 2 + /// Determines which star overlay and whether sparkles are applied + var/quality + /// Overlay to apply to the item when picked + var/mutable_appearance/quality_overlay + +/datum/element/visual_quality/Attach(datum/target, quality) + . = ..() + if(!isitem(target)) + return ELEMENT_INCOMPATIBLE + + var/obj/item/target_item = target + src.quality = quality + + var/list/quality_icons = list( + null, // CROP_QUALITY_REGULAR has no overlay + "silver", // CROP_QUALITY_SILVER + "gold", // CROP_QUALITY_GOLD + "diamond", // CROP_QUALITY_DIAMOND + ) + if(quality && quality <= length(quality_icons) && quality_icons[quality]) + quality_overlay = mutable_appearance('icons/effects/crop_quality.dmi', quality_icons[quality]) + RegisterSignal(target, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(update_overlay_on_signal)) + target_item.update_appearance(UPDATE_OVERLAYS) + + if(quality >= CROP_QUALITY_GOLD) // I'd rather be shiny + target_item.AddComponent(/datum/component/particle_spewer/sparkle/turf_only) + +/datum/element/visual_quality/Detach(datum/source, ...) + UnregisterSignal(source, COMSIG_ATOM_UPDATE_OVERLAYS) + qdel(source.GetComponent(/datum/component/particle_spewer/sparkle/turf_only)) + . = ..() + +/datum/element/visual_quality/proc/update_overlay_on_signal(obj/item/source, list/overlays) + SIGNAL_HANDLER + + if(!quality_overlay || !ismob(source.loc)) + return + + overlays += quality_overlay diff --git a/code/datums/liquids/liquid_effect.dm b/code/datums/liquids/liquid_effect.dm index a1c9034ecc1..7213f7c4eb7 100644 --- a/code/datums/liquids/liquid_effect.dm +++ b/code/datums/liquids/liquid_effect.dm @@ -314,7 +314,7 @@ var/liquid_state_template = liquid_state_messages["[liquid_group.group_overlay_state]"] - examine_list += "
" + examine_list += "
" if(examiner.can_see_reagents()) examine_list += "
" diff --git a/code/datums/materials/_base.dm b/code/datums/materials/_base.dm index 94f05fad371..386e8968cf6 100644 --- a/code/datums/materials/_base.dm +++ b/code/datums/materials/_base.dm @@ -21,4 +21,5 @@ var/hardness var/can_be_molded = FALSE + /// What ingot does this material form var/obj/item/ingot/ingot_type diff --git a/code/datums/migrants/waves/dwarven_company.dm b/code/datums/migrants/waves/dwarven_company.dm index a145aa78b5d..025069f38b5 100644 --- a/code/datums/migrants/waves/dwarven_company.dm +++ b/code/datums/migrants/waves/dwarven_company.dm @@ -34,7 +34,6 @@ /datum/skill/craft/blacksmithing = 2, /datum/skill/craft/armorsmithing = 2, /datum/skill/craft/weaponsmithing = 2, - /datum/skill/craft/smelting = 2, /datum/skill/craft/engineering = 1, /datum/skill/craft/traps = 2, /datum/skill/misc/reading = 2, @@ -87,7 +86,6 @@ /datum/skill/craft/blacksmithing = 4, /datum/skill/craft/armorsmithing = 2, /datum/skill/craft/weaponsmithing = 4, - /datum/skill/craft/smelting = 3, /datum/skill/craft/engineering = 3, /datum/skill/craft/traps = 2, /datum/skill/misc/reading = 2, @@ -157,7 +155,6 @@ /datum/skill/craft/blacksmithing = 4, /datum/skill/craft/armorsmithing = 4, /datum/skill/craft/weaponsmithing = 2, - /datum/skill/craft/smelting = 3, /datum/skill/craft/engineering = 3, /datum/skill/craft/traps = 2, /datum/skill/misc/reading = 2, diff --git a/code/datums/migrants/waves/heartfelt_wave.dm b/code/datums/migrants/waves/heartfelt_wave.dm index bd7822b8ccf..8aab4431394 100644 --- a/code/datums/migrants/waves/heartfelt_wave.dm +++ b/code/datums/migrants/waves/heartfelt_wave.dm @@ -319,7 +319,7 @@ /datum/skill/misc/climbing = 3, /datum/skill/misc/athletics = 2, /datum/skill/labor/mining = 2, - /datum/skill/craft/smelting = 4, + /datum/skill/craft/blacksmithing = 1, /datum/skill/misc/reading = 2, /datum/skill/craft/bombs= 4, ) diff --git a/code/datums/molten_materials/_base.dm b/code/datums/molten_materials/_base.dm index 33454387cd3..0ecd1a3ba66 100644 --- a/code/datums/molten_materials/_base.dm +++ b/code/datums/molten_materials/_base.dm @@ -2,15 +2,24 @@ name = "Molten " metabolization_rate = REAGENTS_METABOLISM * 4 + base_recipe_quality = SMELTERY_QUALITY_NORMAL var/datum/material/largest_metal -/datum/reagent/molten_metal/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0) +/datum/reagent/molten_metal/on_new(list/incoming_data) . = ..() - if(method & INGEST) + RegisterSignal(holder, COMSIG_REAGENTS_TEMP_CHANGE, PROC_REF(on_temp_change)) + +/datum/reagent/molten_metal/Destroy() + UnregisterSignal(holder, COMSIG_REAGENTS_TEMP_CHANGE) + return ..() + +/datum/reagent/molten_metal/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume, show_message = TRUE, touch_protection = 0) + . = ..() + if(methods & INGEST) for(var/datum/material_trait/trait as anything in initial(largest_metal.traits)) var/datum/material_trait/new_trait = GLOB.material_traits[trait] - new_trait.on_consume(M, reac_volume) + new_trait.on_consume(exposed_mob, reac_volume) /datum/reagent/molten_metal/on_mob_life(mob/living/carbon/M) . = ..() @@ -25,27 +34,12 @@ if(!length(incoming_data)) return - var/list/materials = list() - for(var/datum/material/material as anything in incoming_data) - if(!ispath(material)) - continue - materials |= material - - if(length(materials) == 1) - var/datum/material/material_type = materials[1] - name = "Molten [initial(material_type.name)]" - else - name = "Molten Metals" - - data = incoming_data try_metal_merge() - find_largest_metal() /datum/reagent/molten_metal/on_merge(list/incoming_data) . = ..() if(!length(incoming_data)) return - name = "Molten Metals" for(var/datum/material/material as anything in incoming_data) if(!ispath(material)) @@ -54,15 +48,13 @@ data[material] += incoming_data[material] try_metal_merge() - find_largest_metal() -/datum/reagent/molten_metal/on_temp_change(chem_temp) - . = ..() - if(!chem_temp) +/datum/reagent/molten_metal/proc/on_temp_change(datum/source, new_temp, old_temp) + SIGNAL_HANDLER + if(new_temp < old_temp) return - try_metal_merge() - find_largest_metal() + try_metal_merge() /datum/reagent/molten_metal/proc/try_metal_merge() for(var/datum/molten_recipe/recipe as anything in GLOB.molten_recipes) @@ -79,14 +71,20 @@ data |= material data[material] += recipe.output[material] * multiplier - if(length(data) == 1) - var/datum/material/material_type = data[1] - name = "Molten [initial(material_type.name)]" + var/name_found = FALSE + for(var/datum/material/material_type as anything in data) + if(!ispath(material_type)) + continue + if(!name_found) + name = "Molten [initial(material_type.name)]" + name_found = TRUE + else + name = "Molten Metals" + break find_largest_metal() /datum/reagent/molten_metal/proc/find_largest_metal() - var/largest for(var/datum/material/material as anything in data) if(!ispath(material)) diff --git a/code/datums/quality/_base_quality_manager.dm b/code/datums/quality/_base_quality_manager.dm index a017045aa82..bfb52db27e0 100644 --- a/code/datums/quality/_base_quality_manager.dm +++ b/code/datums/quality/_base_quality_manager.dm @@ -1,12 +1,3 @@ -#define QUALITY_LEVEL_SPOILED "-10" -#define QUALITY_LEVEL_AWFUL "-5" -#define QUALITY_LEVEL_CRUDE "-2" -#define QUALITY_LEVEL_ROUGH "-1" -#define QUALITY_LEVEL_COMPETENT "0" -#define QUALITY_LEVEL_FINE "2" -#define QUALITY_LEVEL_FLAWLESS "5" -#define QUALITY_LEVEL_LEGENDARY "8" - /proc/create_quality_item(obj/item/base_item, datum/quality_calculator/calculator) if(!calculator || !base_item) return base_item @@ -16,50 +7,28 @@ /datum/quality_calculator var/name = "Generic Quality" - var/base_quality = 0 var/material_quality = 0 - var/reagent_quality = 0 var/skill_quality = 0 - var/performance_quality = 0 - var/difficulty_modifier = 0 var/num_components = 1 + var/reagent_quality = 0 + + /// AList of Quality descriptors - generalized now so we can give them better modifiers + var/alist/quality_descriptors = alist() - // Quality descriptors - generalized now so we can give them better modifiers - var/list/quality_descriptors = list( - QUALITY_LEVEL_SPOILED = list("name_prefix" = "ruined", "modifier" = 0.3), - QUALITY_LEVEL_AWFUL = list("name_prefix" = "awful", "modifier" = 0.5), - QUALITY_LEVEL_CRUDE = list("name_prefix" = "crude", "modifier" = 0.8), - QUALITY_LEVEL_ROUGH = list("name_prefix" = "rough", "modifier" = 0.9), - QUALITY_LEVEL_COMPETENT = list("name_prefix" = "", "modifier" = 1.0), - QUALITY_LEVEL_FINE = list("name_prefix" = "fine", "modifier" = 1.1), - QUALITY_LEVEL_FLAWLESS = list("name_prefix" = "flawless", "modifier" = 1.2), - QUALITY_LEVEL_LEGENDARY = list("name_prefix" = "masterwork", "modifier" = 1.3) - ) - -/datum/quality_calculator/New(base_qual = 0, mat_qual = 0, skill_qual = 0, perf_qual = 0, diff_mod = 0, components = 1, reagent_qual = 0) - base_quality = base_qual +/datum/quality_calculator/New(mat_qual = 0, skill_qual = 0, components = 1, reagent_qual = 0) material_quality = mat_qual skill_quality = skill_qual - performance_quality = perf_qual - difficulty_modifier = diff_mod num_components = max(1, components) reagent_quality = reagent_qual /datum/quality_calculator/proc/calculate_final_quality() - // Average out component-based qualities - var/avg_material = floor(material_quality / num_components) - var/avg_skill = floor(skill_quality / num_components) - var/avg_performance = floor(performance_quality / num_components) - - var/final_quality = base_quality + avg_material + avg_skill + avg_performance - difficulty_modifier - - return final_quality + return /datum/quality_calculator/proc/get_quality_tier(quality_value) - var/best_tier = text2num(QUALITY_LEVEL_SPOILED) + var/best_tier for(var/tier in quality_descriptors) - if(quality_value >= text2num(tier) && text2num(tier) > best_tier) - best_tier = text2num(tier) + if(quality_value >= tier && (isnull(best_tier) || tier > best_tier)) + best_tier = tier return best_tier /datum/quality_calculator/proc/get_quality_data(quality_value = null) @@ -67,88 +36,40 @@ quality_value = calculate_final_quality() var/tier = get_quality_tier(quality_value) - return quality_descriptors[num2text(tier)] - -/datum/quality_calculator/proc/apply_quality_to_item(obj/item/target, track_masterworks = FALSE) - var/final_quality = calculate_final_quality() - var/list/quality_data = get_quality_data(final_quality) + return quality_descriptors[tier] - if(!quality_data || !quality_data["modifier"]) +/datum/quality_calculator/proc/apply_quality_to_item(obj/item/target, track_creation = FALSE, quality_override) + if(!target) return FALSE - var/modifier = quality_data["modifier"] - var/name_prefix = quality_data["name_prefix"] + var/final_quality = quality_override ? quality_override : calculate_final_quality() + var/list/quality_data = get_quality_data(final_quality) + if(!quality_data) + return FALSE // Apply name prefix + var/name_prefix = quality_data["name_prefix"] + if(islist(name_prefix)) + name_prefix = pick(name_prefix) if(name_prefix && name_prefix != "") target.name = "[name_prefix] [target.name]" - // Apply basic modifiers - target.modify_max_integrity(target.max_integrity * modifier, can_break = FALSE) + // Apply description prefix + var/description_prefix = quality_data["description"] + if(islist(description_prefix)) + description_prefix = pick(description_prefix) + if(description_prefix && description_prefix != "") + target.desc += "\n[description_prefix]" + + // Apply sellprice modifier + var/modifier = quality_data["price_modifier"] if(target.sellprice) target.sellprice *= modifier - // Track masterworks if enabled - if(track_masterworks && final_quality >= text2num(QUALITY_LEVEL_LEGENDARY)) - record_round_statistic(STATS_MASTERWORKS_FORGED, 1) - - apply_specialized_modifiers(target, modifier) - - return TRUE - - -/datum/quality_calculator/proc/apply_specialized_modifiers(obj/item/target, modifier) - // Lockpicks - make them better at their job - if(istype(target, /obj/item/lockpick)) - var/obj/item/lockpick/L = target - L.picklvl = modifier - - // Weapons - else if(istype(target, /obj/item/weapon)) - var/obj/item/weapon/W = target - var/datum/component/two_handed/twohanded = W.GetComponent(/datum/component/two_handed) - if(twohanded) - twohanded.modify_base_force(multiplicative_modifier = modifier) - else - W.force *= modifier - if(W.throwforce) - W.throwforce *= modifier - if(W.blade_int) - W.blade_int *= modifier - W.max_blade_int *= modifier - // if(W.armor_penetration) - // W.armor_penetration *= modifier - // if(W.wdefense) - // W.wdefense *= modifier - - // Special handling for axes and pick-axes - better at woodcutting - if(istype(target, /obj/item/weapon/axe/iron) || istype(target, /obj/item/weapon/pick/paxe)) - var/obj/item/weapon/A = target - A.axe_cut += (A.force * modifier) * 0.5 // Add half of modified damage as axe_cut - - // Special handling for picks - better at mining - if(istype(target, /obj/item/weapon/pick)) - var/obj/item/weapon/pick/P = target - P.pickmult *= modifier - - // Crossbows - modify damage multiplier - else if(istype(target, /obj/item/gun/ballistic/revolver/grenadelauncher)) - var/obj/item/gun/ballistic/revolver/grenadelauncher/R = target - R.damfactor = modifier - - // Bear traps - modify trap damage - else if(istype(target, /obj/item/restraints/legcuffs/beartrap)) - var/obj/item/restraints/legcuffs/beartrap/B = target - B.trap_damage *= modifier - - // Clothing/Armor - else if(istype(target, /obj/item/clothing)) - var/obj/item/clothing/C = target - // if(C.damage_deflection) - // C.damage_deflection *= modifier - if(C.integrity_failure) - C.integrity_failure /= modifier - // if(C.armor) - // C.armor = C.armor.multiplymodifyAllRatings(modifier) - // if(C.equip_delay_self) - // C.equip_delay_self *= modifier + if(track_creation) + track_item_creation(target, final_quality) + + return quality_data // cheeky way to send quality_data list to child proc calls + +/datum/quality_calculator/proc/track_item_creation(obj/item/target, final_quality) + return diff --git a/code/datums/quality/blacksmithing.dm b/code/datums/quality/blacksmithing.dm index 6ed22439780..55e22e342fa 100644 --- a/code/datums/quality/blacksmithing.dm +++ b/code/datums/quality/blacksmithing.dm @@ -1,27 +1,114 @@ + /datum/quality_calculator/blacksmithing name = "Blacksmithing Quality" - var/minigame_success = 0 + quality_descriptors = alist( + BLACKSMITH_QUALITY_SPOILED = list("name_prefix" = "ruined", "modifier" = 0.3), + BLACKSMITH_QUALITY_AWFUL = list("name_prefix" = "awful", "modifier" = 0.5), + BLACKSMITH_QUALITY_CRUDE = list("name_prefix" = "crude", "modifier" = 0.8), + BLACKSMITH_QUALITY_ROUGH = list("name_prefix" = "rough", "modifier" = 0.9), + BLACKSMITH_QUALITY_COMPETENT = list("name_prefix" = "", "modifier" = 1.0), + BLACKSMITH_QUALITY_FINE = list("name_prefix" = "fine", "modifier" = 1.1), + BLACKSMITH_QUALITY_FLAWLESS = list("name_prefix" = "flawless", "modifier" = 1.2), + BLACKSMITH_QUALITY_LEGENDARY = list("name_prefix" = "masterwork", "modifier" = 1.3) + ) + + var/performance_quality = 0 + var/difficulty_modifier = 0 + var/minigame_plays = 0 + var/skill_randomization = 0 + +/datum/quality_calculator/blacksmithing/New(mat_qual = 0, skill_qual = 0, components = 1, reagent_qual = 0, perf_qual = 0, diff_mod = 0, mini_play = 1) + ..() + performance_quality = perf_qual + difficulty_modifier = diff_mod + minigame_plays = mini_play + skill_randomization = rand(0, 0.5) // just a healthy amount of randomization + +// REMINDERS: +// skill ranges from 0 to 6 +// performance ranges from 0 to 100 (100 is perfect) +// material ranges from 1 to 6 (3 is regular) +// smithing scales from -10 to 10 (0 is regular) +// Tier differences are between 2 and 3 (for positive ones) /datum/quality_calculator/blacksmithing/calculate_final_quality() + var/avg_skill = skill_quality / minigame_plays + avg_skill = min(avg_skill + skill_randomization, SKILL_LEVEL_LEGENDARY) // just a healthy amount of randomization var/avg_material = floor(material_quality / num_components) + var/avg_performance = performance_quality / minigame_plays + + /* Explanations for factors and their scaling + * Skill (MAJOR): Essentially the base quality for each skill level + * Material (MAJOR): Good materials is just as important as skill + * Performance (MINOR): Good performance can push items up a tier + * Difficulty (MINOR) : Makes harder recipes have lower qualities in general + */ + var/skill_component = (avg_skill / 6) * (-BLACKSMITH_QUALITY_SPOILED + BLACKSMITH_QUALITY_FLAWLESS) + var/material_component = ((avg_material - SMELTERY_QUALITY_NORMAL) / SMELTERY_QUALITY_NORMAL) * 6 + var/performance_component = (avg_performance / 100) * 3 + var/difficulty_penalty = difficulty_modifier * 0.3 + + var/final_quality = skill_component + material_component + performance_component - difficulty_penalty + final_quality += BLACKSMITH_QUALITY_SPOILED - // Skill factor (0 to 1) - var/skill_factor = skill_quality / 6 - var/performance_factor = min(1.2, minigame_success / 100) + return clamp(final_quality, BLACKSMITH_QUALITY_SPOILED, BLACKSMITH_QUALITY_LEGENDARY) - // --- FORGIVING WEIGHTS --- - var/skill_component = skill_factor * 3.0 // Max +3.0 - var/material_component = avg_material * 1.5 // Max +6.0 - var/performance_component = performance_factor * 3.0 // Max +3.6 (120 score) +/datum/quality_calculator/blacksmithing/apply_quality_to_item(obj/item/target, track_creation) + . = ..() + if(!.) + return - var/hit_penalty = floor(performance_quality * 0.5) - var/difficulty_penalty = floor(difficulty_modifier * 0.3) + var/list/quality_data = . - var/raw_quality = skill_component + material_component + performance_component - hit_penalty - difficulty_penalty + var/modifier = quality_data["modifier"] + // Apply basic modifiers + target.modify_max_integrity(target.max_integrity * modifier, can_break = FALSE) + if(target.sellprice) + target.sellprice *= modifier - var/final_quality = raw_quality - if(raw_quality > skill_quality) - var/excess = raw_quality - skill_quality - final_quality = skill_quality + (excess * 0.8) // High retention (80%) + // Lockpicks - make them better at their job + if(istype(target, /obj/item/lockpick)) + var/obj/item/lockpick/L = target + L.picklvl = modifier + // Weapons + else if(istype(target, /obj/item/weapon)) + var/obj/item/weapon/W = target + var/datum/component/two_handed/twohanded = W.GetComponent(/datum/component/two_handed) + if(twohanded) + twohanded.modify_base_force(multiplicative_modifier = modifier) + else + W.force *= modifier + if(W.throwforce) + W.throwforce *= modifier + if(W.blade_int) + W.blade_int *= modifier + W.max_blade_int *= modifier + + // Special handling for axes and pick-axes - better at woodcutting + if(istype(target, /obj/item/weapon/axe/iron) || istype(target, /obj/item/weapon/pick/paxe)) + var/obj/item/weapon/A = target + A.axe_cut += (A.force * modifier) * 0.5 // Add half of modified damage as axe_cut + + // Special handling for picks - better at mining + if(istype(target, /obj/item/weapon/pick)) + var/obj/item/weapon/pick/P = target + P.pickmult *= modifier + + // Crossbows - modify damage multiplier + else if(istype(target, /obj/item/gun/ballistic/revolver/grenadelauncher)) + var/obj/item/gun/ballistic/revolver/grenadelauncher/R = target + R.damfactor = modifier + + // Bear traps - modify trap damage + else if(istype(target, /obj/item/restraints/legcuffs/beartrap)) + var/obj/item/restraints/legcuffs/beartrap/B = target + B.trap_damage *= modifier + + // In order to preserve material quality information for smelting + var/avg_material = floor(material_quality / num_components) + target.set_quality(avg_material) - return clamp(round(final_quality), -10, 8) +/datum/quality_calculator/blacksmithing/track_item_creation(obj/item/target, final_quality) + // Track masterworks if enabled + if(final_quality >= BLACKSMITH_QUALITY_LEGENDARY) + record_round_statistic(STATS_MASTERWORKS_FORGED, 1) diff --git a/code/datums/quality/brewing.dm b/code/datums/quality/brewing.dm index 0f7e215001d..82fc40e2ffe 100644 --- a/code/datums/quality/brewing.dm +++ b/code/datums/quality/brewing.dm @@ -1,9 +1,9 @@ /datum/quality_calculator/brewing name = "Brewing Quality" - quality_descriptors = list( - "-1" = list( - "name_prefix" = list("spoiled", "rancid", "failed", "putrid", "foul"), + quality_descriptors = alist( + -1 = list( + "brew_prefix" = list("spoiled", "rancid", "failed", "putrid", "foul"), "description" = list( "This brew has gone terribly wrong.", "The smell alone is enough to make you gag.", @@ -13,13 +13,13 @@ ), "price_modifier" = 0.2 ), - "0" = list( - "name_prefix" = "", + 0 = list( + "brew_prefix" = "", "description" = "", "price_modifier" = 0.8 ), - "1" = list( - "name_prefix" = list("weak", "watery", "poor", "substandard"), + 1 = list( + "brew_prefix" = list("weak", "watery", "poor", "substandard"), "description" = list( "This brew appears poorly made with an unpleasant aroma.", "The color is off and it smells strange.", @@ -27,13 +27,13 @@ ), "price_modifier" = 0.6 ), - "2" = list( - "name_prefix" = "", + 2 = list( + "brew_prefix" = "", "description" = "This appears to be a standard quality brew.", "price_modifier" = 1.0 ), - "3" = list( - "name_prefix" = list("fine", "quality", "well-crafted", "premium"), + 3 = list( + "brew_prefix" = list("fine", "quality", "well-crafted", "premium"), "description" = list( "This brew has an excellent aroma and rich color.", "The craftsmanship is evident in every sip.", @@ -41,8 +41,8 @@ ), "price_modifier" = 1.4 ), - "4" = list( - "name_prefix" = list("masterful", "exquisite", "artisan", "legendary", "perfect"), + 4 = list( + "brew_prefix" = list("masterful", "exquisite", "artisan", "legendary", "perfect"), "description" = list( "This is a masterfully crafted brew with perfect clarity and an intoxicating bouquet.", "This represents the pinnacle of brewing artistry.", @@ -57,7 +57,7 @@ var/recipe_quality_modifier = 1.0 var/aging_bonus = 0 -/datum/quality_calculator/brewing/New(base_qual = 0, mat_qual = 0, skill_qual = 0, perf_qual = 0, diff_mod = 0, components = 1, reagent_qual = 0, fresh = 0, recipe_mod = 1.0, aging_bonus = 0) +/datum/quality_calculator/brewing/New(mat_qual = 0, skill_qual = 0, components = 1, reagent_qual = 0, fresh = 0, recipe_mod = 1.0, aging_bonus = 0) freshness = fresh recipe_quality_modifier = recipe_mod src.aging_bonus = aging_bonus @@ -79,81 +79,31 @@ // Apply skill cap and absolute maximum var/skill_cap = 1 + brewing_skill - return min(4, min(skill_cap, final_quality)) + return min(COOK_QUALITY_VERYGOOD, min(skill_cap, final_quality)) -/datum/quality_calculator/brewing/get_quality_tier(quality_value) - var/best_tier = -1 - for(var/tier_str in quality_descriptors) - var/tier = text2num(tier_str) - if(quality_value >= tier && tier > best_tier) - best_tier = tier - return best_tier - -/datum/quality_calculator/brewing/get_quality_data(quality_value = null) - if(isnull(quality_value)) - quality_value = calculate_final_quality() - - var/tier = get_quality_tier(quality_value) - var/tier_str = num2text(tier) - return quality_descriptors[tier_str] - -/datum/quality_calculator/brewing/apply_quality_to_item(obj/item/target, track_masterworks = FALSE) - if(!istype(target, /obj/item/reagent_containers/glass/bottle)) +/datum/quality_calculator/brewing/apply_quality_to_item(obj/item/reagent_containers/glass/bottle/bottle, track_creation) + if(!istype(bottle)) return FALSE - var/final_quality = calculate_final_quality() - var/list/quality_data = get_quality_data(final_quality) - - if(!quality_data) - return FALSE + . = ..() + if(!.) + return - var/name_prefix = quality_data["name_prefix"] - if(islist(name_prefix)) - var/list/names = name_prefix - name_prefix = pick(names) - - var/description_prefix = quality_data["description"] - if(islist(description_prefix)) - var/list/names = description_prefix - description_prefix = pick(names) + var/list/quality_data = . // Apply name prefix - if(name_prefix && name_prefix != "") - target.name = "[name_prefix] [target.name]" - - // Apply description prefix - if(description_prefix && description_prefix != "") - target.desc += "\n[description_prefix]" - - apply_brewing_quality_modifiers(target, quality_data) - - // Track masterworks if enabled (quality 4) - if(track_masterworks && final_quality >= 4) - record_round_statistic(STATS_MASTERWORKS_FORGED, 1) // TODO! Make this an actual unique brewing type - - return TRUE - -/datum/quality_calculator/brewing/proc/apply_brewing_quality_modifiers(obj/item/reagent_containers/glass/bottle/bottle, list/quality_data) - // Apply name prefix - var/name_prefix = quality_data["name_prefix"] - if(name_prefix && name_prefix != "") - if(islist(name_prefix)) - name_prefix = pick(name_prefix) + var/brew_prefix = quality_data["brew_prefix"] + if(islist(brew_prefix)) + brew_prefix = pick(brew_prefix) + if(brew_prefix && brew_prefix != "") // Insert the prefix before "bottle of" var/bottle_pos = findtext(bottle.name, " bottle of ") if(bottle_pos) - bottle.name = copytext(bottle.name, 1, bottle_pos) + " [name_prefix] bottle of " + copytext(bottle.name, bottle_pos + 11) + bottle.name = copytext(bottle.name, 1, bottle_pos) + " [brew_prefix] bottle of " + copytext(bottle.name, bottle_pos + 11) else - bottle.name = "[name_prefix] [bottle.name]" - - // Apply description - var/description = quality_data["description"] - if(description && description != "") - if(islist(description)) - description = pick(description) - bottle.desc += " [description]" + bottle.name = "[brew_prefix] [bottle.name]" - // Apply price modifier - var/price_modifier = quality_data["price_modifier"] - if(price_modifier && bottle.sellprice) - bottle.sellprice = round(bottle.sellprice * price_modifier) +/datum/quality_calculator/brewing/track_item_creation(obj/item/target, final_quality) + // Track masterworks if enabled (quality 4) + if(final_quality >= COOK_QUALITY_VERYGOOD) + record_round_statistic(STATS_MASTERWORKS_FORGED, 1) // TODO! Make this an actual unique brewing type diff --git a/code/datums/quality/cooking.dm b/code/datums/quality/cooking.dm index d5308d30e4a..d7f65bf8e9a 100644 --- a/code/datums/quality/cooking.dm +++ b/code/datums/quality/cooking.dm @@ -1,8 +1,8 @@ /datum/quality_calculator/cooking name = "Cooking Quality" - quality_descriptors = list( - "-1" = list( + quality_descriptors = alist( + -1 = list( "name_prefix" = list("unappealing", "sloppy", "failed", "woeful", "soggy", "bland"), "description" = list( "It is made without love or care.", @@ -15,25 +15,25 @@ "eat_effect" = null, "tastes" = list("blandness" = 1) ), - "0" = list( + 0 = list( "name_prefix" = "", "description" = "", "eat_effect" = null, "tastes" = null ), - "1" = list( + 1 = list( "name_prefix" = "", "description" = "", "eat_effect" = null, "tastes" = null ), - "2" = list( + 2 = list( "name_prefix" = list("tasty", "well-made", "appealing"), "description" = "It looks good.", "eat_effect" = /datum/status_effect/buff/foodbuff, "tastes" = null ), - "3" = list( + 3 = list( "name_prefix" = list("fine", "tasty", "well-made", "appealing", "appetising", "savory", "flavorful"), "description" = list( "It looks tasty.", @@ -47,7 +47,7 @@ "eat_effect" = /datum/status_effect/buff/foodbuff, "tastes" = null ), - "4" = list( + 4 = list( "name_prefix" = list("masterful", "exquisite", "perfected", "gourmet", "delicious"), "description" = list( "It looks perfect.", @@ -64,12 +64,11 @@ var/freshness = 0 var/recipe_quality_modifier = 1.0 -/datum/quality_calculator/cooking/New(base_qual = 0, mat_qual = 0, skill_qual = 0, perf_qual = 0, diff_mod = 0, components = 1, reagent_qual = 0, fresh = 0, recipe_mod = 1.0) +/datum/quality_calculator/cooking/New(mat_qual = 0, skill_qual = 0, components = 1, reagent_qual = 0, fresh = 0, recipe_mod = 1.0) freshness = fresh recipe_quality_modifier = recipe_mod ..() - /datum/quality_calculator/cooking/calculate_final_quality() var/cooking_skill = skill_quality var/ingredient_quality = material_quality @@ -86,70 +85,20 @@ // Apply skill cap and absolute maximum var/skill_cap = 1 + cooking_skill - return min(4, min(skill_cap, final_quality)) - -/datum/quality_calculator/cooking/get_quality_tier(quality_value) - var/best_tier = -1 - for(var/tier_str in quality_descriptors) - var/tier = text2num(tier_str) - if(quality_value >= tier && tier > best_tier) - best_tier = tier - return best_tier - -/datum/quality_calculator/cooking/get_quality_data(quality_value = null) - if(isnull(quality_value)) - quality_value = calculate_final_quality() + return min(COOK_QUALITY_VERYGOOD, min(skill_cap, final_quality)) - var/tier = get_quality_tier(quality_value) - var/tier_str = num2text(tier) - return quality_descriptors[tier_str] - -/datum/quality_calculator/cooking/apply_quality_to_item(obj/item/target, track_masterworks = FALSE) - if(!istype(target, /obj/item/reagent_containers/food/snacks)) +/datum/quality_calculator/cooking/apply_quality_to_item(obj/item/reagent_containers/food/snacks/food_item, track_creation) + if(!istype(food_item)) return FALSE - var/final_quality = calculate_final_quality() - var/list/quality_data = get_quality_data(final_quality) - - if(!quality_data) - return FALSE - - var/name_prefix = quality_data["name_prefix"] - var/description_prefix = quality_data["description"] - // Apply name prefix - if(name_prefix && name_prefix != "") - target.name = "[name_prefix] [target.name]" - - // Apply description prefix - if(description_prefix && description_prefix != "") - target.desc += "\n[description_prefix]" - - apply_cooking_quality_modifiers(target, quality_data) + . = ..() + if(!.) + return - // Track masterworks if enabled (quality 4) - if(track_masterworks && final_quality >= 4) - record_round_statistic(STATS_MASTERWORKS_FORGED, 1) // TODO! Make this an actual unique type - - return TRUE + var/list/quality_data = . -/datum/quality_calculator/cooking/proc/apply_cooking_quality_modifiers(obj/item/reagent_containers/food/snacks/food_item, list/quality_data) // Clear previous effect food_item.eat_effect = null - - // Apply name prefix - var/name_prefix = quality_data["name_prefix"] - if(name_prefix && name_prefix != "") - if(islist(name_prefix)) - name_prefix = pick(name_prefix) - food_item.name = "[name_prefix] [initial(food_item.name)]" - - // Apply description - var/description = quality_data["description"] - if(description && description != "") - if(islist(description)) - description = pick(description) - food_item.desc = "[initial(food_item.desc)] [description]" - // Apply eat effect var/eat_effect = quality_data["eat_effect"] if(eat_effect) @@ -162,3 +111,8 @@ food_item.tastes = list() for(var/taste in tastes) food_item.tastes[taste] = tastes[taste] + +/datum/quality_calculator/cooking/track_item_creation(obj/item/target, final_quality) + // Track masterworks if enabled (quality 4) + if(final_quality >= COOK_QUALITY_VERYGOOD) + record_round_statistic(STATS_MASTERWORKS_FORGED, 1) // TODO! Make this an actual unique type diff --git a/code/datums/quality/metallurgy.dm b/code/datums/quality/metallurgy.dm index 02e494cbd81..2aa466d4251 100644 --- a/code/datums/quality/metallurgy.dm +++ b/code/datums/quality/metallurgy.dm @@ -1,24 +1,25 @@ + /datum/quality_calculator/metallurgy name = "Metallurgy Quality" - quality_descriptors = list( - "-1" = list( + quality_descriptors = alist( + SMELTERY_QUALITY_SPOIL = list( "name_prefix" = "awful", "description" = "", ), - "0" = list( + SMELTERY_QUALITY_POOR = list( "name_prefix" = "", "description" = "", ), - "1" = list( + SMELTERY_QUALITY_NORMAL = list( "name_prefix" = "", "description" = "", ), - "2" = list( + SMELTERY_QUALITY_GOOD = list( "name_prefix" = list("refined", "processed"), "description" = "It shows signs of careful refinement.", ), - "3" = list( + SMELTERY_QUALITY_GREAT = list( "name_prefix" = list("high-grade", "superior", "fine"), "description" = list( "It gleams with exceptional purity.", @@ -26,7 +27,7 @@ "It radiates quality craftsmanship." ), ), - "4" = list( + SMELTERY_QUALITY_EXCELLENT = list( "name_prefix" = list("pristine", "flawless", "legendary"), "description" = list( "It represents the pinnacle of metallurgical perfection.", @@ -37,78 +38,35 @@ ) /datum/quality_calculator/metallurgy/calculate_final_quality() - var/skill_factor = skill_quality / 8 // Smaller impact than others - var/material_factor = material_quality * 0.1 // Minor factor - var/reagent_factor = reagent_quality * 0.9 // Major factor - - var/final_quality = material_factor + skill_factor + reagent_factor - return max(-1, CEILING(min(4, final_quality), 1)) - -/datum/quality_calculator/metallurgy/apply_quality_to_item(obj/item/target, track_masterworks = FALSE) + /* SHOULD MATCH CALCULATIONS OF SMELTERS + RANDOMLY PICKED NUMBER ACCORDING TO SMELTER SKILL: + NO SKILL: between 10 and 30 + NOVICE: between 25 and 30 + APPRENTICE: between 40 and 50 + JOURNEYMAN: between 55 and 75 + EXPERT: between 70 and 100 + MASTER: between 85 and 125 + LEGENDARY: between 100 and 150 + PICKED NUMBER GETS DIVIDED BY SMELTING_DENOMINATOR. + */ + var/skill_factor = (rand(skill_quality*15 + 10, max(30, skill_quality*25)) / SMELTING_DENOMINATOR) + var/material_factor = (material_quality - SMELTERY_QUALITY_SPOIL) * 0.5 + + var/final_quality = floor(material_factor + skill_factor) + + return clamp(final_quality, SMELTERY_QUALITY_SPOIL, SMELTERY_QUALITY_EXCELLENT) + +/datum/quality_calculator/metallurgy/apply_quality_to_item(obj/item/target, track_creation, quality_override) if(!target) return FALSE - var/final_quality = calculate_final_quality() - var/list/quality_data = get_quality_data(final_quality) - - if(!quality_data) - return FALSE - - var/name_prefix = quality_data["name_prefix"] - if(islist(name_prefix)) - var/list/names = name_prefix - name_prefix = pick(names) + if(!quality_override) + quality_override = calculate_final_quality() + quality_override = clamp(quality_override, SMELTERY_QUALITY_SPOIL, SMELTERY_QUALITY_EXCELLENT) - var/description_prefix = quality_data["description"] - if(islist(description_prefix)) - var/list/names = description_prefix - description_prefix = pick(names) - // Apply name prefix - if(name_prefix && name_prefix != "") - target.name = "[name_prefix] [target.name]" + . = ..(target, track_creation, quality_override) + target.set_quality(quality_override) - // Apply description prefix - if(description_prefix && description_prefix != "") - target.desc += "\n[description_prefix]" - - - target.set_quality(final_quality) - - if(track_masterworks && final_quality >= 4) +/datum/quality_calculator/metallurgy/track_item_creation(obj/item/target, final_quality) + if(final_quality >= SMELTERY_QUALITY_EXCELLENT) record_round_statistic(STATS_MASTERWORKS_FORGED, 1) - - return TRUE - -/datum/quality_calculator/metallurgy/proc/apply_smelt_to_ingot(obj/item/target, final_quality = 0, track_masterworks = FALSE) - if(!target) - return FALSE - final_quality = max(-1, CEILING(min(4, final_quality), 1)) - - var/list/quality_data = get_quality_data(final_quality) - - if(!quality_data) - return FALSE - - var/name_prefix = quality_data["name_prefix"] - if(islist(name_prefix)) - var/list/names = name_prefix - name_prefix = pick(names) - var/description_prefix = quality_data["description"] - if(islist(description_prefix)) - var/list/names = description_prefix - description_prefix = pick(names) - // Apply name prefix - if(name_prefix && name_prefix != "") - target.name = "[name_prefix] [target.name]" - - // Apply description prefix - if(description_prefix && description_prefix != "") - target.desc += "\n[description_prefix]" - - - target.set_quality(final_quality) - - if(track_masterworks && final_quality >= 4) - record_round_statistic(STATS_MASTERWORKS_FORGED, 1) - - return TRUE diff --git a/code/datums/quirks/boon/backstory.dm b/code/datums/quirks/boon/backstory.dm index d008c0d9b79..d372f93fd7d 100644 --- a/code/datums/quirks/boon/backstory.dm +++ b/code/datums/quirks/boon/backstory.dm @@ -304,12 +304,6 @@ granted_skill = /datum/skill/craft/traps stat_penalty = STATKEY_SPD -/datum/backstory/craft/smelter - name = "Apprentice Smelter" - desc = "You worked the furnace, turning ore into metal." - granted_skill = /datum/skill/craft/smelting - stat_penalty = STATKEY_PER - /datum/backstory/craft/bombmaker name = "Powder Maker" desc = "You crafted explosives, a dangerous trade." diff --git a/code/datums/skills/craft.dm b/code/datums/skills/craft.dm index 4714e8c400c..a0deeabb82b 100644 --- a/code/datums/skills/craft.dm +++ b/code/datums/skills/craft.dm @@ -31,13 +31,6 @@ "...CLANG! Clang! Clang... you feel the weight of the hammer reverberate up your arm, past your shoulder, through your spine... the hits march to the drums of your heart. you feel attuned to the metal." ) -/datum/skill/craft/smelting - name = "Smelting" - desc = "Smelting is a skill that represents your character's ability to smelt metal into ingots. The higher your skill in Smelting, the better the ingots you create, which affect the quality of the resulting item." - dreams = list( - "...the heat brings warmth to you on this dreary night. your feet ache, and your arms remain sore - but the stress of the day melts away, along with the snow around you - becoming just another distant memory." - ) - /datum/skill/craft/carpentry name = "Carpentry" desc = "Carpentry is a skill that represents your character's ability to craft wooden items. The higher your skill in Carpentry, the faster you can create wooden items and buildings." diff --git a/code/datums/status_effects/rogue/debuff.dm b/code/datums/status_effects/rogue/debuff.dm index dddfdd0f7f9..2d6c99fdbf9 100644 --- a/code/datums/status_effects/rogue/debuff.dm +++ b/code/datums/status_effects/rogue/debuff.dm @@ -511,8 +511,7 @@ /datum/status_effect/debuff/stinky_person/on_remove() . = ..() - var/datum/component/stinky_component = GetComponent(/datum/component/rot/stinky_person) - stinky_component?.RemoveComponent() + qdel(GetComponent(/datum/component/rot/stinky_person)) /datum/status_effect/debuff/tainted_lux id = "tainted_lux" diff --git a/code/game/gamemodes/personal_objectives/abyssor/take_bath.dm b/code/game/gamemodes/personal_objectives/abyssor/take_bath.dm index 4400019219a..e2cf667b7f9 100644 --- a/code/game/gamemodes/personal_objectives/abyssor/take_bath.dm +++ b/code/game/gamemodes/personal_objectives/abyssor/take_bath.dm @@ -21,7 +21,7 @@ return var/amulet_found = FALSE - for(var/obj/item/clothing/neck/current_item in owner.current.get_equipped_items(TRUE)) + for(var/obj/item/clothing/neck/current_item in owner.current.get_equipped_items(INCLUDE_POCKETS)) if(current_item.type in list(/obj/item/clothing/neck/psycross/silver/divine/abyssor)) amulet_found = TRUE diff --git a/code/game/gamemodes/personal_objectives/necra/hear_cries.dm b/code/game/gamemodes/personal_objectives/necra/hear_cries.dm index f97e92d5caa..1918d4fe856 100644 --- a/code/game/gamemodes/personal_objectives/necra/hear_cries.dm +++ b/code/game/gamemodes/personal_objectives/necra/hear_cries.dm @@ -36,7 +36,7 @@ return var/amulet_found = FALSE - for(var/obj/item/clothing/neck/current_item in user.get_equipped_items(TRUE)) + for(var/obj/item/clothing/neck/current_item in user.get_equipped_items(INCLUDE_POCKETS)) if(current_item.type in list(/obj/item/clothing/neck/psycross/silver/divine/necra)) amulet_found = TRUE diff --git a/code/game/machinery/anvil.dm b/code/game/machinery/anvil.dm index 1a0419c5fd6..e54319cf883 100644 --- a/code/game/machinery/anvil.dm +++ b/code/game/machinery/anvil.dm @@ -2,281 +2,245 @@ icon = 'icons/roguetown/misc/forge.dmi' name = "anvil" icon_state = "anvil" - var/hott = 0 - var/obj/item/ingot/hingot max_integrity = 2000 density = TRUE damage_deflection = 25 climbable = TRUE - var/previous_material_quality = 0 - var/cool_time = 30 SECONDS var/smithing = FALSE // Is a minigame currently active? var/obj/item/working_material // Reference to the material being worked var/always_perfect = FALSE // Debug/admin flag +/obj/machinery/anvil/Destroy() + if(working_material) + working_material.forceMove(drop_location()) + . = ..() + /obj/machinery/anvil/crafted icon_state = "caveanvil" /obj/machinery/anvil/examine(mob/user) . = ..() - if(hingot) - . += hingot.examine() - if(hott) - . += "[hingot] is too hot to touch." + if(working_material) + . += span_info("[src] has \a [working_material.name] on it.") + if(working_material.currecipe) + . += span_warning("It is currently being worked on to become \a [working_material.currecipe.name].") + if(HAS_TRAIT(working_material, TRAIT_NEEDS_QUENCH)) + . += span_warning("[working_material] is too hot to touch.") /obj/machinery/anvil/attack_hand_secondary(mob/user, list/modifiers) - if(hingot) - return hingot.attack_hand_secondary(user, modifiers) - . = ..() + if(working_material && !smithing) + return working_material.attack_hand_secondary(user, modifiers) + return ..() -/obj/machinery/anvil/attackby(obj/item/W, mob/living/user, list/modifiers) - if(istype(W, /obj/item/weapon/tongs)) - var/obj/item/weapon/tongs/T = W - if(smithing) - to_chat(user, "[src] is currently being worked on!") - return - if(hingot) - if(T.held_item && istype(T.held_item, /obj/item/ingot)) - if(hingot.currecipe && hingot.currecipe.needed_item && istype(T.held_item, hingot.currecipe.needed_item)) - hingot.currecipe.item_added(user) - qdel(T.held_item) - T.held_item = null - T.update_appearance(UPDATE_ICON_STATE) - update_appearance(UPDATE_OVERLAYS) - return - else - hingot.forceMove(T) - T.held_item = hingot - hingot = null - T.update_appearance(UPDATE_ICON_STATE) - update_appearance(UPDATE_OVERLAYS) - return - else - if(T.held_item && istype(T.held_item, /obj/item/ingot)) - T.held_item.forceMove(src) - hingot = T.held_item - T.held_item = null - hott = T.hott - if(hott) - START_PROCESSING(SSmachines, src) - T.update_appearance(UPDATE_ICON_STATE) - update_appearance(UPDATE_OVERLAYS) +/obj/machinery/anvil/attackby(obj/item/attacking_item, mob/living/user, list/modifiers) + if(smithing) + to_chat(user, span_warning("[src] is currently being worked on!")) + return TRUE + + // TODO: REWRITE TONGS INTERACTIONS USING interact_with_atom() + var/actual_attacking_item = attacking_item + var/obj/item/weapon/tongs/tongs_used + if(istype(attacking_item, /obj/item/weapon/tongs)) + tongs_used = attacking_item + if(tongs_used.held_item) + actual_attacking_item = tongs_used.held_item + + if(try_place_item(actual_attacking_item, user)) + return TRUE + + if(working_material) + if(istype(attacking_item, /obj/item/weapon/hammer)) + . = TRUE + user.changeNext_move(CLICK_CD_MELEE) + if(!HAS_TRAIT(working_material, TRAIT_NEEDS_QUENCH)) + if(working_material.currecipe) + to_chat(user, span_warning("[working_material] has gone too cold to continue working on it.")) + else + return working_material.attackby(attacking_item, user, modifiers) + + if(!working_material.currecipe) + if(!choose_recipe(user)) + return working_material.attackby(attacking_item, user, modifiers) + if(!working_material.currecipe.is_recipe_available(user)) return - - if(istype(W, /obj/item/ingot)) - if(!hingot) - W.forceMove(src) - hingot = W - hott = 0 - update_appearance(UPDATE_OVERLAYS) + // Start the minigame instead of direct hammering + start_minigame(user, attacking_item) return - if(istype(W, /obj/item/weapon/hammer)) - var/obj/item/weapon/hammer/hammer = W - user.changeNext_move(CLICK_CD_MELEE) - if(!hingot) - return - if(!hott) - to_chat(user, "The bar has gone too cold to continue working on it.") - return - if(smithing) - to_chat(user, "Already working on this!") - return - if(!hingot.currecipe) - if(!choose_recipe(user)) - return - if(has_world_trait(/datum/world_trait/delver)) - if(!has_recipe_unlocked(user.key, hingot.currecipe.type)) - return + if(tongs_used && !tongs_used.held_item) + tongs_used.set_held_item(working_material) + return TRUE - // Start the minigame instead of direct hammering - start_minigame(user, hammer) - return + . = ..() - if(hingot && hingot.currecipe && hingot.currecipe.needed_item && istype(W, hingot.currecipe.needed_item)) - hingot.currecipe.item_added(user) - if(istype(W, /obj/item/ingot)) - var/obj/item/ingot/I = W - hingot.currecipe.material_quality += I.recipe_quality - previous_material_quality = I.recipe_quality - else - hingot.currecipe.material_quality += previous_material_quality - hingot.currecipe.num_of_materials += 1 - qdel(W) - return +/obj/machinery/anvil/attack_hand(mob/living/user, list/modifiers) + if(smithing) + to_chat(user, span_warning("[src] is currently being worked on!")) + return TRUE + if(working_material) + return working_material.attack_hand(user, modifiers) + return ..() + +/obj/machinery/anvil/proc/try_place_item(obj/item/item, mob/living/user) + if(working_material?.currecipe?.item_added(item, user)) + return TRUE + + if(!working_material) + if(HAS_TRAIT(item, TRAIT_NEEDS_QUENCH) || item.melting_material || item.anvilrepair) + set_working_material(item) + return TRUE - if(W.anvilrepair) - user.visible_message("[user] places \a [W] on the anvil.") - W.forceMove(src.loc) - return - ..() + return FALSE /obj/machinery/anvil/proc/start_minigame(mob/living/user, obj/item/weapon/hammer/hammer) - if(!hingot || !hingot.currecipe) + if(!working_material || !working_material.currecipe) return - smithing = TRUE - working_material = hingot + if(!working_material.currecipe.can_advance(user)) + shake_camera(user, 1, 1) + playsound(src, 'sound/items/bsmithfail.ogg', 100, FALSE) + return - var/difficulty_modifier = hingot.currecipe.craftdiff + smithing = TRUE - var/datum/anvil_challenge/challenge = new(src, hingot.currecipe, user, difficulty_modifier) + var/datum/anvil_challenge/challenge = new(src, working_material.currecipe, user) if(!challenge) smithing = FALSE - working_material = null return - -/obj/machinery/anvil/proc/process_minigame_result(quality_score, mob/living/user, total_fail) - if(!hingot || !hingot.currecipe) +/obj/machinery/anvil/proc/process_minigame_result(quality_score, mob/living/user) + if(!working_material || !working_material.currecipe) return - var/datum/anvil_recipe/recipe = hingot.currecipe - var/breakthrough = quality_score >= 80 - if(total_fail) - quality_score = 0 - var/success = recipe.advance(user, breakthrough, quality_score) - + var/datum/anvil_recipe/recipe = working_material.currecipe + + if(quality_score >= 15) // Did you even try? + var/recipe_skill = recipe.appro_skill + var/amt2raise = user.STAINT // It would be impossible to level up otherwise + var/boon = user.get_learning_boon(recipe_skill) + if(user.get_skill_level(recipe_skill) < 3) + amt2raise /= 2 // Let's not get out of hand it's for lower levels with high chances of failure + user.mind.add_sleep_experience(recipe_skill, amt2raise * boon, FALSE) + else if(HAS_TRAIT(user, TRAIT_MALUMFIRE))// Sanity, no expert blacksmith has lower skill than 3, for if admins manually add the trait or blacksmith vampire thralls + user.mind.add_sleep_experience(recipe_skill, amt2raise, FALSE) + + // Breakthrough system for RNG success + if(quality_score != 100) + var/obj/item/weapon/hammer/hammer = user.get_active_held_item() + var/total_chance = user.get_skill_level(recipe_skill) * user.STAPER/10 + if(istype(hammer)) + total_chance += (1 / hammer.toolspeed) + if(prob((1 + total_chance))) + user.flash_fullscreen("whiteflash") + quality_score = 100 + + var/success = recipe.advance(user, quality_score) if(!success) - shake_camera(user, 1, 1) - playsound(src, 'sound/items/bsmithfail.ogg', 100, FALSE) - - if(success) - var/skill_boost = 0 - if(quality_score >= 80) - skill_boost = quality_score * 2 - recipe.numberofbreakthroughs++ - else if(quality_score >= 60) - skill_boost = quality_score * 1.5 - else if(quality_score >= 40) - skill_boost = quality_score - else if(quality_score >= 20) - skill_boost = quality_score * 0.5 + return - recipe.skill_quality += skill_boost + if(quality_score >= 80) + user.visible_message(span_deadsay("[user] deftly strikes the bar!")) + var/datum/effect_system/spark_spread/sparks = new() + var/turf/front = get_turf(src) + sparks.set_up(1, 1, front) + sparks.start() + else if(quality_score >= 40) + user.visible_message(span_info("[user] strikes the bar!")) + else + user.visible_message(span_warning("[user] fumbles the bar!")) if(recipe.progress >= 100 && !length(recipe.additional_items) && !recipe.needed_item) complete_recipe(user, quality_score) - working_material = null - /obj/machinery/anvil/proc/complete_recipe(mob/living/user, quality_score) - if(!hingot || !hingot.currecipe) + if(!working_material || !working_material.currecipe) return - var/datum/anvil_recipe/recipe = hingot.currecipe - var/obj/item/I = new recipe.created_item(loc) - - I.OnCrafted(user.dir, user) - - var/skill_level = 0 - if(user) - skill_level = user.get_skill_level(recipe.appro_skill) - - recipe.handle_creation(I, quality_score, skill_level) - SEND_SIGNAL(user, COMSIG_ITEM_FORGED) + var/datum/anvil_recipe/recipe = working_material.currecipe + var/obj/item/output_item_path = recipe.created_item + SEND_SIGNAL(user, COMSIG_ITEM_FORGED, recipe.created_item) record_featured_stat(FEATURED_STATS_SMITHS, user) - record_featured_object_stat(FEATURED_STATS_FORGED_ITEMS, I.name) + record_featured_object_stat(FEATURED_STATS_FORGED_ITEMS, initial(output_item_path.name)) - for(var/i in 1 to recipe.createditem_extra) - var/obj/item/extra = new recipe.created_item(loc) - extra.OnCrafted(user.dir, user) - recipe.handle_creation(extra, quality_score, skill_level) + recipe.handle_creation(loc, user) - user?.visible_message(span_info("[user] finishes crafting [I]!")) - - qdel(hingot) - hingot = null - update_appearance(UPDATE_OVERLAYS) + user?.visible_message(span_info("[user] finishes crafting \the [initial(output_item_path.name)]!")) + qdel(working_material) /obj/machinery/anvil/proc/choose_recipe(mob/living/user) - if(!hingot || !hott) + if(!working_material || !HAS_TRAIT(working_material, TRAIT_NEEDS_QUENCH) || working_material.currecipe) return var/list/valid_types = list() - for(var/datum/anvil_recipe/R as anything in GLOB.anvil_recipes) - if(IS_ABSTRACT(R)) + for(var/datum/anvil_recipe/recipe_instance as anything in GLOB.anvil_recipes) + var/datum/recipe_type = recipe_instance.type // necessary typecasting of type for macro + if(IS_ABSTRACT(recipe_type)) + continue + if(!recipe_instance.is_recipe_available(user)) + continue + if(!istype(working_material, recipe_instance.required_material)) continue - if(has_world_trait(/datum/world_trait/delver)) - if(!has_recipe_unlocked(user.key, R)) - continue - - if(istype(hingot, R.req_bar)) - if(!valid_types.Find(R.i_type)) - valid_types += R.i_type + var/recipe_category = recipe_instance.category + if(!valid_types[recipe_category]) + valid_types[recipe_category] = list() + valid_types[recipe_category] += recipe_instance if(!length(valid_types)) return - var/i_type_choice + var/category_choice if(length(valid_types) == 1) - i_type_choice = valid_types[1] + category_choice = valid_types[1] else - i_type_choice = browser_input_list(user, "Choose a category", "Anvil", valid_types) - if(!i_type_choice) + category_choice = browser_input_list(user, "Choose a category", "Anvil", valid_types) + if(!category_choice) return - var/list/appro_recipe = list() - for(var/datum/anvil_recipe/R as anything in GLOB.anvil_recipes) - if(IS_ABSTRACT(R)) - continue - if(R.i_type == i_type_choice && istype(hingot, R::req_bar)) - appro_recipe += R - - for(var/datum/anvil_recipe/R as anything in appro_recipe) - if(!R::req_bar) - appro_recipe -= R - if(!istype(hingot, R::req_bar)) - appro_recipe -= R - - if(length(appro_recipe)) - var/datum/chosen_recipe - chosen_recipe = browser_input_list(user, "Choose what to start working on:", "Anvil", sortNames(appro_recipe.Copy())) - if(!hingot.currecipe && chosen_recipe) - hingot.currecipe = new chosen_recipe.type(hingot) - hingot.currecipe.material_quality += hingot.recipe_quality - previous_material_quality = hingot.recipe_quality - return TRUE + var/list/chosen_category = valid_types[category_choice] + if(!length(chosen_category)) + return - return FALSE + var/list/final_recipe_list = list() + for(var/datum/anvil_recipe/recipe_instance as anything in chosen_category) + var/modified_name = "[recipe_instance.name]" + if(recipe_instance.output_amount > 1) + modified_name += " ([recipe_instance.output_amount]x)" + final_recipe_list["[modified_name] \[[uppertext(SSskills.level_names_plain[recipe_instance.craftdiff])]\]"] = recipe_instance + + var/datum/chosen_recipe = browser_input_list(user, "Choose what to start working on:", "Anvil", sortList(final_recipe_list)) + + chosen_recipe = final_recipe_list[chosen_recipe] + if(!working_material.currecipe && chosen_recipe) + working_material.currecipe = new chosen_recipe.type(working_material) + return TRUE + +/obj/machinery/anvil/proc/set_working_material(obj/item/new_material) + if(!QDELETED(working_material)) + UnregisterSignal(working_material, list(\ + SIGNAL_ADDTRAIT(TRAIT_NEEDS_QUENCH), SIGNAL_REMOVETRAIT(TRAIT_NEEDS_QUENCH), \ + COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED)) + working_material = new_material + if(working_material) + working_material.forceMove(src) + RegisterSignal(working_material, list(SIGNAL_ADDTRAIT(TRAIT_NEEDS_QUENCH), SIGNAL_REMOVETRAIT(TRAIT_NEEDS_QUENCH)), PROC_REF(update_overlay_upon_signal)) + RegisterSignal(working_material, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED), PROC_REF(unset_material_on_signal)) + update_appearance(UPDATE_OVERLAYS) -/obj/machinery/anvil/attack_hand(mob/user, list/modifiers) - if(smithing) - to_chat(user, "[src] is currently being worked on!") - return - if(hingot) - if(hott) - to_chat(user, "It's too hot to handle with your hands.") - return - else - var/obj/item/I = hingot - hingot = null - I.loc = user.loc - user.put_in_active_hand(I) - update_appearance(UPDATE_OVERLAYS) - -/obj/machinery/anvil/process() - if(hott) - if(world.time > hott + cool_time) - hott = 0 - STOP_PROCESSING(SSmachines, src) - else - STOP_PROCESSING(SSmachines, src) +/obj/machinery/anvil/proc/update_overlay_upon_signal(datum/source, trait) + SIGNAL_HANDLER update_appearance(UPDATE_OVERLAYS) +/obj/machinery/anvil/proc/unset_material_on_signal(datum/source, trait) + SIGNAL_HANDLER + set_working_material(null) + /obj/machinery/anvil/update_overlays() . = ..() - if(!hingot) - return - var/obj/item/I = hingot - I.pixel_x = I.base_pixel_x - I.pixel_y = I.base_pixel_y - var/mutable_appearance/M = new /mutable_appearance(I) - if(hott) - M.filters += filter(type="color", color = list(3,0,0,1, 0,2.7,0,0.4, 0,0,1,0, 0,0,0,1)) - M.transform *= 0.5 - M.pixel_y = 5 - M.pixel_x = 3 - . += M + if(working_material) + var/mutable_appearance/M = new /mutable_appearance(working_material) + M.transform *= 0.5 + M.pixel_y = 4 + M.pixel_x = 3 + . += M diff --git a/code/game/machinery/artificer_table.dm b/code/game/machinery/artificer_table.dm index e326b49742f..d6820ecfa7a 100644 --- a/code/game/machinery/artificer_table.dm +++ b/code/game/machinery/artificer_table.dm @@ -130,7 +130,7 @@ material.artrecipe.advance(I, user) if(material && material.artrecipe && material.artrecipe.hammered && istype(I, material.artrecipe.needed_item)) - material.artrecipe.item_added(user) + material.artrecipe.item_added(I, user) qdel(I) return diff --git a/code/game/machinery/forge.dm b/code/game/machinery/forge.dm index b3d8ada0a29..fc9d382d111 100644 --- a/code/game/machinery/forge.dm +++ b/code/game/machinery/forge.dm @@ -10,20 +10,20 @@ climbable = TRUE climb_time = 0 -/obj/machinery/light/fueled/forge/attackby(obj/item/W, mob/living/user, list/modifiers) - if(istype(W, /obj/item/weapon/tongs) && on) - var/obj/item/weapon/tongs/T = W - if(T.held_item) - var/tyme = world.time - T.hott = tyme - T.proxy_heat(150, 1500) - addtimer(CALLBACK(T, TYPE_PROC_REF(/obj/item/weapon/tongs, make_unhot), tyme), 100) - T.update_appearance(UPDATE_ICON_STATE) - user.visible_message("[user] heats the bar.") - if(istype(W, /obj/item/weapon/tongs/stone)) - W.take_damage(1, BRUTE, "blunt") +/obj/machinery/light/fueled/forge/attackby(obj/item/attacking_item, mob/living/user, list/modifiers) + if(!on) + return ..() + // TODO: REWRITE TONGS INTERACTIONS USING interact_with_atom() + if(istype(attacking_item, /obj/item/weapon/tongs)) + var/obj/item/weapon/tongs/tongs = attacking_item + if(tongs.held_item) + tongs.heat_held_item(source = "tongs", duration = 30 SECONDS, incoming = 150, max_heat = 1500) + user.visible_message(span_info("[user] heats [tongs.held_item] with [tongs].")) + if(istype(attacking_item, /obj/item/weapon/tongs/stone)) + attacking_item.take_damage(1, BRUTE, BLUNT) return TRUE - if(istype(W, /obj/item/storage/crucible) && on) - user.visible_message("[user] places the [W] onto [src].") - W.forceMove(get_turf(src)) + if(istype(attacking_item, /obj/item/storage/crucible)) + user.visible_message("[user] places [attacking_item] onto [src].") + user.transferItemToLoc(attacking_item, get_turf(src), silent = TRUE) + return TRUE return ..() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index d816b555590..ad4ae03d65d 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -105,7 +105,8 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e var/list/attack_verb //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]" var/list/species_exception = null // list() of species types, if a species cannot put items in a certain slot, but species type is in list, it will be able to wear that item - var/mob/thrownby = null + ///A weakref to the mob who threw the item + var/datum/weakref/thrownby = null //I cannot verbally describe how much I hate this var mouse_drag_pointer = MOUSE_ACTIVE_POINTER //the icon to indicate this object is being dragged @@ -118,6 +119,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e var/sharpness = IS_BLUNT var/tool_behaviour = NONE + ///How fast does the tool work var/toolspeed = 1 var/block_chance = 0 @@ -232,8 +234,6 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e var/last_used = 0 - // Boolean sanity var for smelteries to avoid runtimes. Is this is a bar smelted through ore for exp gain? - var/smelted = FALSE // Can this be used against a training dummy to learn skills? Prevents dumb exploits. var/istrainable = FALSE @@ -264,8 +264,6 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e var/melt_amount = 0 ///our current in progress slapcraft var/datum/orderless_slapcraft/in_progress_slapcraft - ///these are flags of what tools can interact with this atom useful to stop hard coding interactions - var/tool_flags = NONE var/list/attunement_values ///this is in KG @@ -275,11 +273,13 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e /// Artificers Recipe var/datum/artificer_recipe/artrecipe + /// Current anvil/forging recipe + var/datum/anvil_recipe/currecipe /// angle of the icon, these are used for attack animations var/icon_angle = 50 // most of our icons are angled ///the processing quality we have - var/recipe_quality = 1 + var/recipe_quality // Lock related @@ -293,14 +293,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e var/toggle_state // Needed for grandmaster/martyr weapons, might be shitcode, might be usable for the future, *shrug, it works /obj/item/proc/set_quality(quality) - recipe_quality = clamp(quality, 0, 4) - update_appearance(UPDATE_OVERLAYS) - if(recipe_quality >= 3) // gold tier and above - AddComponent(/datum/component/particle_spewer/sparkle) - else - var/datum/component/particle_spewer = GetComponent(/datum/component/particle_spewer/sparkle) - if(particle_spewer) - particle_spewer.RemoveComponent() + recipe_quality = quality /obj/item/update_overlays() . = ..() @@ -312,19 +305,6 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e pic.color = get_detail_color() . += pic - // Add quality overlay to the food item - if(recipe_quality <= 0 || !ismob(loc)) - return - var/list/quality_icons = list( - null, // Regular has no overlay - // "bronze", - "silver", - "gold", - "diamond", - ) - if(recipe_quality <= length(quality_icons) && quality_icons[recipe_quality]) - . += mutable_appearance('icons/effects/crop_quality.dmi', quality_icons[recipe_quality]) - /** * Handles adding components to the item. Added in Initialize() * @@ -511,6 +491,8 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e embedded_mob.simple_remove_embedded_object(src) if(artrecipe) QDEL_NULL(artrecipe) + if(currecipe) + QDEL_NULL(currecipe) if(istype(loc, /obj/machinery/artificer_table)) var/obj/machinery/artificer_table/A = loc A.material = null @@ -680,7 +662,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e return if(HAS_TRAIT(src, TRAIT_NEEDS_QUENCH)) - to_chat(user, "[src] is too hot to touch.") + to_chat(user, span_warning("[src] is too hot to handle with your hands!")) return if(resistance_flags & ON_FIRE) @@ -1044,7 +1026,9 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e return hit_atom.hitby(src, 0, itempush, throwingdatum=throwingdatum, damage_type = src.damage_type) /obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE) - thrownby = thrower + if(HAS_TRAIT(src, TRAIT_NODROP)) + return + thrownby = WEAKREF(thrower) callback = CALLBACK(src, PROC_REF(after_throw), callback) //replace their callback with our own . = ..(target, range, speed, thrower, spin, diagonals_first, callback, force) @@ -1512,6 +1496,8 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e /obj/item/examine(mob/user) . = ..() + if(currecipe) + . += span_warning("It is currently being worked on to become \a [currecipe.name].") if(!get_precursor_data(src)) return var/alch_skill = user.get_skill_level(/datum/skill/craft/alchemy) diff --git a/code/game/objects/items/crucible.dm b/code/game/objects/items/crucible.dm index 5174b53e430..d62ce513ac2 100644 --- a/code/game/objects/items/crucible.dm +++ b/code/game/objects/items/crucible.dm @@ -9,8 +9,6 @@ grid_width = 32 grid_height = 64 - tool_flags = TOOL_USAGE_TONGS - var/crucible_temperature = 300 var/list/melting_pot = list() @@ -25,10 +23,14 @@ color = pick("#766f8c", "#565c5c", "#8d3a2d", "#4f3524") START_PROCESSING(SSobj, src) +/obj/item/storage/crucible/create_reagents(max_vol, flags) + . = ..() + RegisterSignal(reagents, COMSIG_REAGENTS_HOLDER_UPDATED, PROC_REF(on_reagent_change)) + /obj/item/storage/crucible/examine(mob/user) . = ..() if(crucible_temperature) - . += "The crucible is around [crucible_temperature - 271.3]C" + . += "The crucible is around [crucible_temperature - T0C]C" if(length(melting_pot)) for(var/obj/item/atom in melting_pot) var/datum/material/material = atom.melting_material @@ -36,7 +38,9 @@ var/datum/reagent/molten_metal/metal = reagents.get_reagent(/datum/reagent/molten_metal) if(!metal) return - for(var/datum/material/material in metal.data) + for(var/datum/material/material as anything in metal.data) + if(!ispath(material)) + continue var/tag = "Molten" if(reagents.chem_temp < material.melting_point) tag = "Hardened" @@ -44,7 +48,7 @@ var/reagent_color = initial(material.color) . += "It contains [UNIT_FORM_STRING(total_volume)] of [tag] [initial(material.name)]." -/obj/item/storage/crucible/process() +/obj/item/storage/crucible/process(delta_time) var/obj/machinery/light/fueled/smelter/smelter = loc var/obj/machinery/light/fueled/light = locate(/obj/machinery/light/fueled) in get_turf(src) if(istype(smelter) && smelter?.on) @@ -74,14 +78,10 @@ if(crucible_temperature < initial(material.melting_point)) melting_pot -= item continue - melting_pot |= item - melting_pot[item] += 5 + melting_pot[item] += 5 * delta_time if(melting_pot[item] >= melty) melt_item(item) - if(reagents?.total_volume) - update_appearance(UPDATE_OVERLAYS) - /obj/item/storage/crucible/get_temperature() return crucible_temperature @@ -119,11 +119,10 @@ material = initial(ingot.melting_material) melty = 100 - data |= material data[material] = melty // Get quality from the item - var/item_quality = 1 + var/item_quality = SMELTERY_QUALITY_NORMAL if(istype(item, /obj/item/ore)) var/obj/item/ore/ore_item = item item_quality = ore_item.recipe_quality @@ -139,6 +138,9 @@ reagents.add_reagent(/datum/reagent/molten_metal, melty, data, crucible_temperature) melting_pot -= item qdel(item) + +/obj/item/storage/crucible/proc/on_reagent_change(datum/reagents/holder, ...) + SIGNAL_HANDLER update_appearance(UPDATE_OVERLAYS) /obj/item/storage/crucible/random/Initialize() @@ -151,13 +153,14 @@ /datum/material/copper = 18, /datum/material/tin = 2 ) - var/temperature = 1500 crucible_temperature = 1500 /obj/item/storage/crucible/test_crucible/Initialize() . = ..() - reagents.add_reagent(/datum/reagent/molten_metal, 20, data = material_data_to_add, reagtemp = 4000) - update_appearance(UPDATE_OVERLAYS) + var/total_volume = 0 + for(var/i in material_data_to_add) + total_volume += material_data_to_add[i] + reagents.add_reagent(/datum/reagent/molten_metal, total_volume, data = material_data_to_add, reagtemp = 4000) /obj/item/storage/crucible/test_crucible/bar material_data_to_add = list( diff --git a/code/game/objects/items/cup.dm b/code/game/objects/items/cup.dm index afc0682e9ed..81a188026f3 100644 --- a/code/game/objects/items/cup.dm +++ b/code/game/objects/items/cup.dm @@ -269,7 +269,8 @@ // If someone got hit- wound them with the glass shard if(ishuman(hit_atom)) var/mob/living/carbon/victim = hit_atom - var/obj/item/bodypart/affecting = victim.get_bodypart(check_zone(thrownby.zone_selected)) + var/mob/thrown_by = thrownby?.resolve() + var/obj/item/bodypart/affecting = victim.get_bodypart(check_zone(thrown_by.zone_selected)) if(!affecting) affecting = victim.get_bodypart(pickweight(list(BODY_ZONE_HEAD = 1, BODY_ZONE_CHEST = 1, BODY_ZONE_L_ARM = 4, BODY_ZONE_R_ARM = 4, BODY_ZONE_L_LEG = 4, BODY_ZONE_R_LEG = 4))) affecting.add_embedded_object(bottleshard) diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index aa84219a208..175f5842baf 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -201,10 +201,12 @@ diceroll(user, TRUE) /obj/item/dice/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - diceroll(thrownby, TRUE) + var/mob/thrown_by = thrownby?.resolve() + if(thrown_by) + diceroll(thrown_by) . = ..() -/obj/item/dice/proc/diceroll(mob/user, var/shown) +/obj/item/dice/proc/diceroll(mob/user, shown) result = roll(sides) if(rigged != DICE_NOT_RIGGED && result != rigged_value) if(rigged == DICE_BASICALLY_RIGGED) diff --git a/code/game/objects/items/natural.dm b/code/game/objects/items/natural.dm index 132fa130a0c..cb6a6a6b4d4 100644 --- a/code/game/objects/items/natural.dm +++ b/code/game/objects/items/natural.dm @@ -7,7 +7,6 @@ grid_width = 32 grid_height = 32 var/bundletype = null - var/quality = SMELTERY_LEVEL_NORMAL // To not ruin blacksmith recipes /obj/item/natural/attackby(obj/item/W, mob/living/user, list/modifiers) if(istype(W, /obj/item/natural/bundle)) diff --git a/code/game/objects/items/natural/stones.dm b/code/game/objects/items/natural/stones.dm index ace045de4ce..98ad194cbcd 100644 --- a/code/game/objects/items/natural/stones.dm +++ b/code/game/objects/items/natural/stones.dm @@ -292,7 +292,7 @@ GLOBAL_LIST_INIT(stone_personality_descs, list( var/work_time = (4 SECONDS - (skill_level * 5)) if(istype(W, /obj/item/weapon/chisel)) var/obj/item/weapon/chisel/chisel = W - work_time *= chisel.time_multiplier + work_time *= chisel.toolspeed playsound(src, pick('sound/combat/hits/onrock/onrock (1).ogg', 'sound/combat/hits/onrock/onrock (2).ogg', 'sound/combat/hits/onrock/onrock (3).ogg', 'sound/combat/hits/onrock/onrock (4).ogg'), 100) user.visible_message("[user] begins chiseling [src] into blocks.") var/stone_amount = rand(1, max(round(skill_level)/2, 1)) @@ -407,7 +407,7 @@ GLOBAL_LIST_INIT(stone_personality_descs, list( var/work_time = (10 SECONDS - (skill_level * 5)) if(istype(W, /obj/item/weapon/chisel)) var/obj/item/weapon/chisel/chisel = W - work_time *= chisel.time_multiplier + work_time *= chisel.toolspeed playsound(src, pick('sound/combat/hits/onrock/onrock (1).ogg', 'sound/combat/hits/onrock/onrock (2).ogg', 'sound/combat/hits/onrock/onrock (3).ogg', 'sound/combat/hits/onrock/onrock (4).ogg'), 100) user.visible_message("[user] begins chiseling a part of [src] off.") if(do_after(user, work_time)) diff --git a/code/game/objects/items/natural/wood.dm b/code/game/objects/items/natural/wood.dm index 70f4330f90b..bacb203c5f1 100644 --- a/code/game/objects/items/natural/wood.dm +++ b/code/game/objects/items/natural/wood.dm @@ -18,7 +18,6 @@ obj_flags = CAN_BE_HIT w_class = WEIGHT_CLASS_HUGE metalizer_result = /obj/item/rotation_contraption/water_pipe - var/quality = SMELTERY_LEVEL_NORMAL // For it not to ruin recipes that need it var/lumber = /obj/item/grown/log/tree/small //These are solely for lumberjack calculations var/lumber_alt var/lumber_amount = 1 diff --git a/code/game/objects/items/ore.dm b/code/game/objects/items/ore.dm index 2fa480187cd..617870eda0b 100644 --- a/code/game/objects/items/ore.dm +++ b/code/game/objects/items/ore.dm @@ -6,27 +6,24 @@ resistance_flags = FIRE_PROOF grid_width = 32 grid_height = 32 - melt_amount = 120 + melt_amount = 100 + recipe_quality = SMELTERY_QUALITY_NORMAL var/atom/mill_result // What this ore becomes when milled - var/mill_yield_bonus = 0 // Extra yield from milling /obj/item/ore/set_quality(quality) . = ..() // Quality affects melt amount var/quality_multiplier = 1.0 switch(recipe_quality) - if(2) + if(SMELTERY_QUALITY_GOOD) quality_multiplier = 1.15 - if(3) + if(SMELTERY_QUALITY_GREAT) quality_multiplier = 1.3 - if(4) - quality_multiplier = 1.5 + if(SMELTERY_QUALITY_EXCELLENT) + quality_multiplier = 1.45 melt_amount = round(initial(melt_amount) * quality_multiplier) - // Update mill yield bonus - mill_yield_bonus = (recipe_quality - 1) * 0.2 - /obj/item/ore/gold name = "raw gold" icon_state = "oregold1" @@ -136,49 +133,31 @@ grid_width = 64 grid_height = 32 melt_amount = 100 - var/datum/anvil_recipe/currecipe + recipe_quality = SMELTERY_QUALITY_NORMAL /obj/item/ingot/examine() . += ..() - if(currecipe) - . += span_warning("It is currently being worked on to become [currecipe.get_display_name()].") /obj/item/ingot/Initialize(mapload, smelt_quality) . = ..() if(smelt_quality) recipe_quality = smelt_quality - smelted = TRUE - var/datum/quality_calculator/metallurgy/metal_calc = new() - metal_calc.apply_smelt_to_ingot(src, recipe_quality, TRUE) - qdel(metal_calc) - -/obj/item/ingot/attackby(obj/item/I, mob/user, list/modifiers) - if(!istype(I, /obj/item/weapon/tongs)) - return ..() - var/obj/item/weapon/tongs/T = I - if(!T.held_item) - if(item_flags & IN_STORAGE) - if(!SEND_SIGNAL(loc, COMSIG_TRY_STORAGE_TAKE, src, user.loc, TRUE)) - return ..() - forceMove(T) - T.held_item = src - T.hott = null - T.update_appearance(UPDATE_ICON_STATE) + var/datum/quality_calculator/metallurgy/metal_calc = new() + metal_calc.apply_quality_to_item(src, TRUE, recipe_quality) + qdel(metal_calc) /obj/item/ingot/attack_hand_secondary(mob/user, list/modifiers) if(currecipe) - to_chat(user, span_notice("You begin canceling the recipe of [currecipe.get_display_name()].")) + to_chat(user, span_notice("You begin canceling the recipe of \the [currecipe.name].")) if(do_after(user, 5 SECONDS, src, display_over_user = TRUE)) - currecipe = null + QDEL_NULL(currecipe) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN . = ..() /obj/item/ingot/Destroy() - if(currecipe) - QDEL_NULL(currecipe) if(istype(loc, /obj/machinery/anvil)) var/obj/machinery/anvil/A = loc - A.hingot = null + A.working_material = null A.update_appearance(UPDATE_OVERLAYS) return ..() diff --git a/code/game/objects/items/ore_dust.dm b/code/game/objects/items/ore_dust.dm index f2ca10887da..ab1fa88c446 100644 --- a/code/game/objects/items/ore_dust.dm +++ b/code/game/objects/items/ore_dust.dm @@ -10,10 +10,6 @@ if(melting_material) color = initial(melting_material.color) -/obj/item/ore/dust/set_quality(quality) - ..() - mill_yield_bonus = (recipe_quality - 1) * 0.3 - /obj/item/ore/dust/gold name = "gold dust" desc = "Fine particles of gold ore." diff --git a/code/game/objects/items/plate.dm b/code/game/objects/items/plate.dm index 54e14a09147..58982ae9048 100644 --- a/code/game/objects/items/plate.dm +++ b/code/game/objects/items/plate.dm @@ -45,7 +45,7 @@ cloth_check.reagents.remove_all(1) dirty = FALSE update_appearance(UPDATE_OVERLAYS) - AddComponent(/datum/component/particle_spewer/sparkle) + AddComponent(/datum/component/particle_spewer/sparkle/turf_only) user.nobles_seen_servant_work() fork_usages = 0 cleaned = TRUE diff --git a/code/game/objects/items/pouring_mould.dm b/code/game/objects/items/pouring_mould.dm index a754a833ece..7908e089055 100644 --- a/code/game/objects/items/pouring_mould.dm +++ b/code/game/objects/items/pouring_mould.dm @@ -7,18 +7,18 @@ var/filling_icon_state = "" var/atom/output_atom - var/required_metal + var/required_metal_amount var/fufilled_metal = 0 - var/datum/material/required_material var/datum/material/filling_metal var/cooling = FALSE var/cooling_progress = 0 - var/cooling_bonus = 1 + var/cooling_multiplier = 1 - // Quality tracking variables - var/total_quality_points = 0 // Sum of (amount * quality) for weighted average - var/average_quality = 0 // Current weighted average quality + /// Average quality weighted by molten metal reagent amount + var/average_quality = 0 + /// Average skill level of pourers weighted by molten metal reagent amount + var/average_skill = 0 /obj/item/mould/Initialize() . = ..() @@ -38,18 +38,20 @@ if(fufilled_metal) var/reagent_color = initial(filling_metal.color) - . += "[src] has [UNIT_FORM_STRING(fufilled_metal)] of Molten [initial(filling_metal.name)] out of [UNIT_FORM_STRING(required_metal)]." + . += "[src] has [UNIT_FORM_STRING(fufilled_metal)] of Molten [initial(filling_metal.name)] out of [UNIT_FORM_STRING(required_metal_amount)]." if(average_quality > 0) . += "The metal quality appears to be [average_quality]." else - . += "[src] requires [UNIT_FORM_STRING(required_metal)] of Molten Metal to form." + . += "[src] requires [UNIT_FORM_STRING(required_metal_amount)] of Molten Metal to form." -/obj/item/mould/attackby(obj/item/I, mob/living/user, list/modifiers) +/obj/item/mould/attackby(obj/item/attacking_item, mob/living/user, list/modifiers) . = ..() - if(!istype(I, /obj/item/storage/crucible)) + if(!istype(attacking_item, /obj/item/storage/crucible)) + return + if(cooling) return - var/obj/item/storage/crucible/crucible = I + var/obj/item/storage/crucible/crucible = attacking_item var/datum/reagent/molten_metal/metal = crucible.reagents.get_reagent(/datum/reagent/molten_metal) if(!metal) return @@ -79,21 +81,17 @@ if(!(filling_metal in metal.data)) return + if(cooling) + return var/metal_amount = metal.data[filling_metal] - if(metal_amount > required_metal - fufilled_metal) - metal_amount = required_metal - fufilled_metal + if(metal_amount > required_metal_amount - fufilled_metal) + metal_amount = required_metal_amount - fufilled_metal - var/pour_quality = metal.recipe_quality - - // Update weighted average quality - if(fufilled_metal > 0) - // Calculate new weighted average: (old_total + new_contribution) / new_total_amount - total_quality_points += metal_amount * pour_quality - average_quality = total_quality_points / (fufilled_metal + metal_amount) - else - // First pour - set initial quality - total_quality_points = metal_amount * pour_quality - average_quality = pour_quality + var/pour_quality = metal.get_recipe_quality() + var/user_skill_level = user.get_skill_level(/datum/skill/craft/blacksmithing, TRUE) + var/new_metal_ratio = metal_amount / (fufilled_metal + metal_amount) + average_quality = LERP(average_quality, pour_quality, new_metal_ratio) + average_skill = LERP(average_skill, user_skill_level, new_metal_ratio) metal.data[filling_metal] -= metal_amount if(!metal.data[filling_metal]) @@ -102,10 +100,14 @@ if(!QDELETED(metal)) metal.find_largest_metal() + var/boon = user.get_learning_boon(/datum/skill/craft/blacksmithing) + var/amt2raise = user.STAINT * 2 // Smelting is already a timesink, this is justified to accelerate levelling + amt2raise *= (metal_amount / required_metal_amount) + if(amt2raise > 0) + user.adjust_experience(/datum/skill/craft/blacksmithing, amt2raise * boon, FALSE) + fufilled_metal += metal_amount - update_appearance(UPDATE_OVERLAYS) - crucible.update_appearance(UPDATE_OVERLAYS) - if(fufilled_metal >= required_metal) + if(fufilled_metal >= required_metal_amount) start_cooling() /obj/item/mould/update_overlays() @@ -116,14 +118,14 @@ icon, filling_icon_state, color = initial(filling_metal.color), - alpha = (255 * (fufilled_metal / required_metal)), + alpha = (255 * (fufilled_metal / required_metal_amount)), appearance_flags = RESET_COLOR | KEEP_APART, ) var/mutable_appearance/MA = emissive_appearance(icon, filling_icon_state) if(cooling) MA.alpha = 255 * round((1 - (cooling_progress / 100)),0.1) else - MA.alpha = 255 * (fufilled_metal / required_metal) + MA.alpha = 255 * (fufilled_metal / required_metal_amount) . += MA /obj/item/mould/proc/start_cooling() @@ -131,38 +133,39 @@ START_PROCESSING(SSobj, src) /obj/item/mould/process() - cooling_progress += 7.5 * cooling_bonus + cooling_progress += 7.5 * cooling_multiplier update_appearance(UPDATE_OVERLAYS) if(cooling_progress >= 100) STOP_PROCESSING(SSobj, src) create_item() +/obj/item/mould/proc/on_reagent_change(datum/reagents/holder, ...) + SIGNAL_HANDLER + update_appearance(UPDATE_OVERLAYS) + /obj/item/mould/proc/create_item() if(output_atom) var/obj/item/new_item = new output_atom(get_turf(src)) - if(average_quality > 0) - var/datum/quality_calculator/metallurgy/metal_calc = new( - base_qual = 0, - mat_qual = average_quality, // Use the stored weighted average quality - skill_qual = 1, // Could add blacksmithing skill here but I'd need to track from start of the process - perf_qual = 0, - diff_mod = 0, - components = 1 - ) - metal_calc.apply_quality_to_item(new_item, TRUE) - qdel(metal_calc) + var/datum/quality_calculator/metallurgy/metal_calc = new( + mat_qual = average_quality, // Use the stored weighted average quality + skill_qual = average_skill + ) + metal_calc.apply_quality_to_item(new_item, TRUE) + qdel(metal_calc) + + reset_state() +/obj/item/mould/proc/reset_state() // Reset all variables fufilled_metal = 0 filling_metal = null cooling = FALSE cooling_progress = 0 - total_quality_points = 0 average_quality = 0 + average_skill = 0 update_appearance(UPDATE_OVERLAYS) - /obj/item/mould/ingot name = "ingot mould" desc = "A clay mould for making metal ingots." @@ -170,41 +173,23 @@ icon_state = "ingot-mold" filling_icon_state = "ingot-mold-color" - required_metal = 100 + required_metal_amount = 100 grid_width = 64 grid_height = 32 /obj/item/mould/ingot/create_item() - var/atom/to_create - to_create = initial(filling_metal.ingot_type) - if(filling_metal.ingot_type == /obj/item/ingot/blacksteel) + output_atom = initial(filling_metal.ingot_type) + if(output_atom == /obj/item/ingot/blacksteel) record_round_statistic(STATS_BLACKSTEEL_SMELTED) - var/obj/item/new_item = new to_create(get_turf(src)) - - if(average_quality > 0) - var/datum/quality_calculator/metallurgy/metal_calc = new( - base_qual = 0, - mat_qual = average_quality, - skill_qual = 1, - perf_qual = 0, - diff_mod = 0, - components = 1 - ) - metal_calc.apply_quality_to_item(new_item, TRUE) - qdel(metal_calc) + . = ..() - // Reset all variables - fufilled_metal = 0 - filling_metal = null - cooling = FALSE - cooling_progress = 0 - total_quality_points = 0 - average_quality = 0 - update_appearance(UPDATE_OVERLAYS) +/obj/item/mould/ingot/reset_state() + . = ..() + output_atom = null /obj/item/mould/ingot/advanced name = "advanced ingot mould" desc = "An ingot mould that utilizes water for faster cooling." - cooling_bonus = 2 + cooling_multiplier = 2 diff --git a/code/game/objects/items/tools/chisel.dm b/code/game/objects/items/tools/chisel.dm index 503b5d26c74..f47615f7119 100644 --- a/code/game/objects/items/tools/chisel.dm +++ b/code/game/objects/items/tools/chisel.dm @@ -25,7 +25,6 @@ grid_width = 32 melt_amount = 50 melting_material = /datum/material/steel - var/time_multiplier = 1 /datum/intent/chisel name = "chisel" @@ -41,9 +40,9 @@ /obj/item/weapon/chisel/iron name = "iron chisel" smeltresult = /obj/item/ingot/iron - time_multiplier = 1.1 + toolspeed = 1.1 /obj/item/weapon/chisel/bronze name = "bronze chisel" smeltresult = /obj/item/ingot/bronze - time_multiplier = 1.2 + toolspeed = 1.2 diff --git a/code/game/objects/items/tools/farmtools.dm b/code/game/objects/items/tools/farmtools.dm index 0ec91add9e9..379938121b4 100644 --- a/code/game/objects/items/tools/farmtools.dm +++ b/code/game/objects/items/tools/farmtools.dm @@ -12,7 +12,7 @@ experimental_onback = TRUE experimental_onhip = TRUE smeltresult = /obj/item/ingot/copper - time_multiplier = 0.5 + toolspeed = 0.5 /obj/item/weapon/sickle/copper name = "copper sickle" diff --git a/code/game/objects/items/tools/gravetools.dm b/code/game/objects/items/tools/gravetools.dm index 4d8d35d70dd..233030eb72f 100644 --- a/code/game/objects/items/tools/gravetools.dm +++ b/code/game/objects/items/tools/gravetools.dm @@ -30,7 +30,6 @@ max_blade_int = 100 grid_width = 32 grid_height = 96 - var/time_multiplier = 1 //multipler to do_after times /obj/item/weapon/shovel/pre_attack(atom/A, mob/living/user, list/modifiers) . = ..() @@ -116,7 +115,7 @@ if(istype(T, /turf/open/floor/dirt)) var/turf/open/floor/dirt/D = T user.visible_message("[user] starts digging an irrigation channel.", "You start digging an irrigation channel.") - if(!do_after(user, 5 SECONDS * time_multiplier, D)) + if(!do_after(user, 5 SECONDS * toolspeed, D)) return new /obj/structure/irrigation_channel(D) return TRUE @@ -242,7 +241,7 @@ slot_flags = ITEM_SLOT_HIP w_class = WEIGHT_CLASS_NORMAL grid_height = 64 - time_multiplier = 2 + toolspeed = 2 smeltresult = null /obj/item/weapon/shovel/small/getonmobprop(tag) diff --git a/code/game/objects/items/tools/hammer.dm b/code/game/objects/items/tools/hammer.dm index 32b4e1da9e0..0534b820533 100644 --- a/code/game/objects/items/tools/hammer.dm +++ b/code/game/objects/items/tools/hammer.dm @@ -18,19 +18,8 @@ grid_width = 32 grid_height = 64 - var/time_multiplier = 1 var/no_spark = FALSE //for hammers that shouldn't make sparks on impact -/obj/proc/unbreak() - return - -/atom/proc/onanvil() - if(!isturf(src.loc)) - return FALSE - for(var/obj/machinery/anvil/T in src.loc) - return TRUE - return FALSE - /obj/structure var/hammer_repair @@ -39,16 +28,17 @@ return ..() if(!isliving(user) || !user.mind || user.cmode) return ..() - var/obj/O = attacked_atom var/datum/mind/blacksmith_mind = user.mind - var/repair_percent = 0.025 // 2.5% Repairing per hammer smack + var/repair_percent = 0.05 // 5% Repairing per hammer smack /// Repairing is MUCH better with an anvil! - if(locate(/obj/machinery/anvil) in O.loc) - repair_percent *= 2 // Double the repair amount if we're using an anvil + if(locate(/obj/machinery/anvil) in attacked_atom.loc) + repair_percent *= 1.5 + if(HAS_TRAIT(attacked_atom, TRAIT_NEEDS_QUENCH)) + repair_percent *= 1.5 - if(isbodypart(O)) + if(isbodypart(attacked_atom)) . = TRUE - var/obj/item/bodypart/attacked_prosthetic = O + var/obj/item/bodypart/attacked_prosthetic = attacked_atom if(!attacked_prosthetic.anvilrepair || !isturf(attacked_prosthetic.loc)) return if(attacked_prosthetic.get_integrity() >= attacked_prosthetic.max_integrity && attacked_prosthetic.brute_dam == 0 && attacked_prosthetic.burn_dam == 0 && attacked_prosthetic.wounds == null && attacked_prosthetic.bodypart_disabled == BODYPART_NOT_DISABLED) //A mouthful @@ -81,25 +71,29 @@ attacked_prosthetic.take_damage(attacked_prosthetic.max_integrity * 0.1, BRUTE, "blunt") return - if(isitem(O)) + if(isitem(attacked_atom)) . = TRUE - var/obj/item/attacked_item = O - if(!attacked_item.anvilrepair || !attacked_item.max_integrity || attacked_item.obj_broken || (attacked_item.get_integrity() >= attacked_item.max_integrity) || !isturf(attacked_item.loc)) + var/obj/item/attacked_item = attacked_atom + if(!attacked_item.anvilrepair || !attacked_item.max_integrity || attacked_item.obj_broken || (attacked_item.get_integrity() >= attacked_item.max_integrity)) to_chat(user, span_warning("[attacked_item] cannot be repaired any further.")) return + if(!attacked_item.ontable() && !istype(attacked_atom.loc, /obj/machinery/anvil)) + to_chat(user, span_warning("I should put [attacked_item] on a table or an anvil first.")) + return + if(user.get_skill_level(attacked_item.anvilrepair) <= 0) if(prob(30)) repair_percent = 0.01 else repair_percent = 0 else - repair_percent *= user.get_skill_level(attacked_item.anvilrepair, TRUE) + repair_percent *= 1 + (user.get_skill_level(attacked_item.anvilrepair, TRUE) / 10) playsound(src,'sound/items/bsmithfail.ogg', 40, FALSE) if(repair_percent) var/amt2raise = floor(user.STAINT * 0.25) - attacked_item.repair_damage( attacked_item.max_integrity * repair_percent) + attacked_item.repair_damage(attacked_item.max_integrity * repair_percent) if(repair_percent == 0.01) // If an inexperienced repair attempt has been successful to_chat(user, span_warning("You fumble your way into slightly repairing [attacked_item].")) else @@ -110,9 +104,9 @@ attacked_item.take_damage(attacked_item.max_integrity * 0.1, BRUTE, "blunt") return - if(isstructure(O)) + if(isstructure(attacked_atom)) . = TRUE - var/obj/structure/attacked_structure = O + var/obj/structure/attacked_structure = attacked_atom if(!attacked_structure.hammer_repair || !attacked_structure.max_integrity || attacked_structure.obj_broken) to_chat(user, span_warning("[attacked_structure] cannot be repaired any further.")) return @@ -150,7 +144,7 @@ icon_state = "hammer_s" experimental_onhip = FALSE experimental_onback = FALSE - time_multiplier = 0.8 + toolspeed = 0.8 melt_amount = 50 melting_material = /datum/material/steel @@ -165,7 +159,7 @@ experimental_onback = FALSE smeltresult = /obj/item/fertilizer/ash max_integrity = INTEGRITY_WORST - time_multiplier = 1.2 + toolspeed = 1.2 no_spark = TRUE /obj/item/weapon/hammer/wood/getonmobprop(tag) @@ -185,7 +179,7 @@ force = DAMAGE_HAMMER - 2 max_integrity = INTEGRITY_POOR melting_material = /datum/material/copper - time_multiplier = 1.1 + toolspeed = 1.1 no_spark = TRUE /obj/item/weapon/hammer/sledgehammer @@ -224,7 +218,7 @@ force_wielded = DAMAGE_HAMMER_WIELD + 10 max_integrity = INTEGRITY_STRONGEST melting_material = /datum/material/steel - time_multiplier = 1.5 //it's for crushing skulls not nails + toolspeed = 1.5 //it's for crushing skulls not nails /obj/item/weapon/hammer/sledgehammer/war/malum name = "forgefiend" diff --git a/code/game/objects/items/tools/tongs.dm b/code/game/objects/items/tools/tongs.dm index 42c4e5aab18..98692ec72b6 100644 --- a/code/game/objects/items/tools/tongs.dm +++ b/code/game/objects/items/tools/tongs.dm @@ -13,56 +13,100 @@ grid_width = 32 grid_height = 96 var/obj/item/held_item = null - var/hott = 0 + +/obj/item/weapon/tongs/Initialize(mapload) + . = ..() + AddElement(/datum/element/update_icon_updates_onmob) /obj/item/weapon/tongs/examine(mob/user) . = ..() - if(hott) - . += "The tip is hot to the touch." + if(held_item) + . += span_info("[src] is holding \a [held_item.name].") + if(HAS_TRAIT(held_item, TRAIT_NEEDS_QUENCH)) + . += span_warning("The tip is hot to the touch.") + +/obj/item/weapon/tongs/Destroy() + place_item_to_atom(drop_location()) + . = ..() /obj/item/weapon/tongs/get_temperature() - if(hott) + if(held_item && HAS_TRAIT(held_item, TRAIT_NEEDS_QUENCH)) return 150+T0C return ..() /obj/item/weapon/tongs/fire_act(added, maxstacks) . = ..() - hott = world.time - update_appearance(UPDATE_ICON_STATE) - addtimer(CALLBACK(src, PROC_REF(make_unhot), world.time), 30 SECONDS) + heat_held_item(source = "fire_act", duration = 10 SECONDS) /obj/item/weapon/tongs/update_icon_state() . = ..() if(!held_item) icon_state = initial(icon_state) else - icon_state = "[initial(icon_state)]i[hott ? "1" : "0"]" - -/obj/item/weapon/tongs/proc/proxy_heat(incoming, max_heat) + var/hot_status = HAS_TRAIT(held_item, TRAIT_NEEDS_QUENCH) + icon_state = "[initial(icon_state)]i[hot_status ? "1" : "0"]" + +/** + * Attempts to heat up the held item. Returns TRUE if successful, FALSE otherwise + * + * Arguments: + * source - the source that TRAIT_NEEDS_QUENCH is applied from + * duration - the time that TRAIT_NEEDS_QUENCH is applied for + * incoming - Value of added temperature. Currently only used for crucibles. + * max_heat - Value of the maximum that can be heated up to. Currently only used for crucibles. + */ +/obj/item/weapon/tongs/proc/heat_held_item(source, duration, incoming, max_heat) + if(!held_item) + return FALSE if(istype(held_item, /obj/item/storage/crucible)) var/obj/item/storage/crucible/crucible = held_item crucible.crucible_temperature = min(crucible.crucible_temperature + incoming, max_heat) + return TRUE + if(duration) + held_item.add_quench_requirement(source, duration) + return TRUE + return FALSE + +/obj/item/weapon/tongs/proc/set_held_item(obj/item/new_held_item) + if(!QDELETED(held_item)) + UnregisterSignal(held_item, list(\ + SIGNAL_ADDTRAIT(TRAIT_NEEDS_QUENCH), SIGNAL_REMOVETRAIT(TRAIT_NEEDS_QUENCH), \ + COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED)) + held_item = new_held_item + if(held_item) + held_item.forceMove(src) + RegisterSignal(held_item, list(SIGNAL_ADDTRAIT(TRAIT_NEEDS_QUENCH), SIGNAL_REMOVETRAIT(TRAIT_NEEDS_QUENCH)), PROC_REF(update_icon_state_upon_signal)) + RegisterSignal(held_item, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED), PROC_REF(unset_item_on_signal)) + update_appearance(UPDATE_ICON_STATE) -/obj/item/weapon/tongs/proc/make_unhot(input) - if(hott == input) - hott = 0 +/obj/item/weapon/tongs/proc/unset_item_on_signal(datum/source) + SIGNAL_HANDLER + set_held_item(null) + +/obj/item/weapon/tongs/proc/update_icon_state_upon_signal(datum/source, trait) + SIGNAL_HANDLER update_appearance(UPDATE_ICON_STATE) -///Places the ingot on the atom, this can be either a turf or a table +/// Places the ingot on the atom, this can be either a turf or a table /obj/item/weapon/tongs/proc/place_item_to_atom(atom/A, mob/user) - if(held_item?.tong_interaction(A, user)) + if(!held_item) + return + + if(user && held_item.tong_interaction(A, user)) return - if(held_item && (isturf(A) || istype(A, /obj/structure/table))) + if(isturf(A) || istype(A, /obj/structure/table)) held_item.forceMove(get_turf(A)) - held_item = null - hott = 0 - update_appearance(UPDATE_ICON_STATE) - else if(held_item) - to_chat(user, "Cannot place [held_item] here!") + else + to_chat(user, span_warning("Cannot place [held_item] here!")) /obj/item/weapon/tongs/attack_self(mob/user, list/modifiers) + . = ..() place_item_to_atom(get_turf(user), user) +/obj/item/weapon/tongs/equipped(mob/user, slot, initial) + . = ..() + place_item_to_atom(get_turf(src), user) + /obj/item/weapon/tongs/dropped(mob/user) . = ..() place_item_to_atom(get_turf(src), user) @@ -74,21 +118,26 @@ place_item_to_atom(get_turf(A), user) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN -/obj/item/weapon/tongs/pre_attack(obj/item/A, mob/living/user, list/modifiers) - if(held_item?.tong_interaction(A, user)) +// TODO: REWRITE TONGS INTERACTIONS USING interact_with_atom() +/obj/item/weapon/tongs/pre_attack(obj/item/attacked_item, mob/living/user, list/modifiers) + if(held_item?.tong_interaction(attacked_item, user)) return TRUE - if(!istype(A)) + if(!istype(attacked_item)) return ..() - if(A.tool_flags & TOOL_USAGE_TONGS || HAS_TRAIT(A, TRAIT_NEEDS_QUENCH)) - if(!held_item) - user.visible_message("[user] picks up [A] with [src].") - held_item = A - A.forceMove(src) - update_appearance(UPDATE_ICON_STATE) - return TRUE - return ..() + if(held_item) + return ..() + + if(istype(attacked_item, /obj/item/storage/crucible)) + . = TRUE + else if(HAS_TRAIT(attacked_item, TRAIT_NEEDS_QUENCH)) + . = TRUE + else if(attacked_item.melting_material || attacked_item.anvilrepair || attacked_item.smeltresult) + . = TRUE + if(.) + user.visible_message(span_info("[user] picks up [attacked_item] with [src].")) + set_held_item(attacked_item) /obj/item/weapon/tongs/getonmobprop(tag) . = ..() @@ -107,5 +156,6 @@ anvilrepair = null max_integrity = INTEGRITY_WORST / 5 +/// Called in pre_attack of tongs, used for items held by tongs. Return TRUE to stop attack chain early. /atom/proc/tong_interaction(atom/target, mob/user) return FALSE diff --git a/code/game/objects/items/waterskins.dm b/code/game/objects/items/waterskins.dm index 2f9e45b32ba..995c1805ff8 100644 --- a/code/game/objects/items/waterskins.dm +++ b/code/game/objects/items/waterskins.dm @@ -48,9 +48,9 @@ . = ..() filtered_reagents = typecacheof(filtered_reagents) -/obj/item/reagent_containers/glass/bottle/waterskin/purifier/on_reagent_change(changetype) - . = ..() - cleanwater() +// Still uses COMSIG_REAGENTS_HOLDER_UPDATED signal but it's good enough +/obj/item/reagent_containers/glass/bottle/waterskin/purifier/on_reagent_change(datum/reagents/holder, ...) + INVOKE_ASYNC(src, PROC_REF(cleanwater)) /obj/item/reagent_containers/glass/bottle/waterskin/purifier/proc/cleanwater() // If there is dirty water inside the device, clean it! diff --git a/code/game/objects/items/weapons/rogueweapon.dm b/code/game/objects/items/weapons/rogueweapon.dm index 30883058abc..cc54ac0725f 100644 --- a/code/game/objects/items/weapons/rogueweapon.dm +++ b/code/game/objects/items/weapons/rogueweapon.dm @@ -38,10 +38,9 @@ if(!destroy_message) destroy_message = span_warning("[pick("[src] is broken!", "[src] is useless!", "[src] is destroyed!")]") - if(ispath(weapon_special)) - weapon_special = new weapon_special() - - if(randomize_blade_int) +/obj/item/weapon/equipped(mob/user, slot, initial) + . = ..() + if(initial && randomize_blade_int) update_integrity(max_integrity + rand(-(max_integrity * 0.2), 0), FALSE) /obj/item/weapon/Destroy(force) @@ -51,17 +50,16 @@ /obj/item/weapon/attack_hand(mob/user) if(is_species(user, /datum/species/werewolf)) //slop fix - return TRUE - . = ..() + return FALSE -/obj/item/weapon/pickup(mob/user) - . = ..() if(HAS_TRAIT(user, TRAIT_RAVOX_CURSE) && prob(33)) var/mob/living/carbon/human/H = user to_chat(H, span_warning("The idea repulses me!")) H.cursed_freak_out() H.Paralyze(4 SECONDS) - return + return FALSE + + . = ..() /obj/item/weapon/get_examine_string(mob/user, thats = FALSE) return "[thats? "That's ":""][get_examine_name(user)]" diff --git a/code/game/objects/lighting/smelter.dm b/code/game/objects/lighting/smelter.dm index 59fcd2623c3..7c8652523b0 100644 --- a/code/game/objects/lighting/smelter.dm +++ b/code/game/objects/lighting/smelter.dm @@ -11,151 +11,171 @@ climb_offset = 10 on = TRUE temperature_change = 80 - var/list/ore = list() - var/maxore = 1 - var/cooking = 0 - var/actively_smelting = FALSE // Are we currently smelting? - var/max_crucible_temperature = 1850 fueluse = 30 MINUTES crossfire = FALSE -/obj/machinery/light/fueled/smelter/attackby(obj/item/W, mob/living/user, list/modifiers) - if(istype(W, /obj/item/weapon/tongs)) - if(!actively_smelting) // Prevents an exp gain exploit. - Foxtrot - var/obj/item/weapon/tongs/T = W - if(ore.len && !T.held_item) - var/obj/item/I = ore[ore.len] - ore -= I - I.forceMove(T) - T.held_item = I - if(user.mind && isliving(user) && T.held_item?:smeltresult) // Prevents an exploit with coal and runtimes with everything else - if(!istype(T.held_item, /obj/item/ore) && T.held_item?:smelted) // Burning items to ash won't level smelting. - var/mob/living/L = user - var/boon = user.get_learning_boon(/datum/skill/craft/smelting) - var/amt2raise = L.STAINT*2 // Smelting is already a timesink, this is justified to accelerate levelling - if(amt2raise > 0) - user.adjust_experience(/datum/skill/craft/smelting, amt2raise * boon, FALSE) - SEND_SIGNAL(user, COMSIG_ITEM_SMELTED) - user.visible_message("[user] retrieves [I] from [src].") - if(on) - var/tyme = world.time - T.hott = tyme - T.proxy_heat(150, max_crucible_temperature) - addtimer(CALLBACK(T, TYPE_PROC_REF(/obj/item/weapon/tongs, make_unhot), tyme), 50) - if(istype(T, /obj/item/weapon/tongs/stone)) - T.take_damage(1, BRUTE, "blunt") - T.update_appearance(UPDATE_ICON_STATE) - return + var/list/contained_items = list() + /// How many items can we contain? + var/max_contained_items = 1 + /// How many crucibles can we contain? + var/max_crucible_amount = 1 + /// How long has the furnace been smelting for? Resets when adding an item. + var/smelting_progress = 0 + /// How high smelting_progress needs to reach before smelting an ore + var/smelting_threshold = 20 + var/max_crucible_temperature = 1850 - for(var/obj/item/storage/crucible/crucible in contents) - user.visible_message("[user] starts removing a crucible from [src]!", "You start removing a crucible from [src]!") - if(!do_after(user, 1.5 SECONDS, src)) - return - crucible.forceMove(T) - T.held_item = crucible - T.update_appearance(UPDATE_ICON_STATE) - return - if(on) - to_chat(user, "Nothing to retrieve from inside.") - return // Safety for not smelting our tongs +/obj/machinery/light/fueled/smelter/examine(mob/user, params) + . = ..() + . += span_info("It can hold up to [max_contained_items] items.") + if(length(contents) && Adjacent(user)) + . += span_notice("Peeking inside, you can see:") + for(var/obj/item/item as anything in contents) + . += span_info("- [item]") + +/obj/machinery/light/fueled/smelter/attackby(obj/item/attacking_item, mob/living/user, list/modifiers) + if(istype(attacking_item, /obj/item/weapon/tongs)) + var/obj/item/weapon/tongs/tongs = attacking_item + if(tongs.held_item) + try_add_item(tongs.held_item, user, tongs) else - to_chat(user, "\The [src] is currently smelting. Wait for it to finish, or douse it with water to retrieve items from it.") - return + try_retrieve_item(user, tongs) + return TRUE - if(W.firefuel) - if(alert(usr, "Fuel \the [src] with [W]?", "VANDERLIN", "Fuel", "Smelt") == "Fuel") + if(attacking_item.firefuel) + if(alert(usr, "Fuel \the [src] with [attacking_item]?", "VANDERLIN", "Fuel", "Smelt") == "Fuel") return ..() - if(istype(W, /obj/item/storage/crucible)) - W.forceMove(src) - user.visible_message("Loads a crucible into [src].", "You load a crucible into [src].") - return ..() + if(try_add_item(attacking_item, user)) + return TRUE - if(W.smeltresult) - if(ore.len < maxore) - if(!(W in user.held_items) || !user.temporarilyRemoveItemFromInventory(W)) - return - W.forceMove(src) - ore += W - if(!isliving(user) || !user.mind) - ore[W] = SMELTERY_LEVEL_SPOIL - else - var/smelter_exp = user.get_skill_level(/datum/skill/craft/smelting) // 0 to 6 - if(smelter_exp < 6) - ore[W] = floor(rand(smelter_exp*15, max(63, smelter_exp*25))/25) // Math explained below - else - ore[W] = floor(min(3, smelter_exp)) // Guarantees a return of 3 no matter how extra experience past 3000 you have. - /* - RANDOMLY PICKED NUMBER ACCORDING TO SMELTER SKILL: - NO SKILL: between 00 and 63 - WEAK: between 15 and 63 - AVERAGE: between 30 and 63 - SKILLED: between 45 and 75 - EXPERT: between 60 and 100 - MASTER: between 75 and 125 - LEGENDARY: between 90 and 150 - - PICKED NUMBER GETS DIVIDED BY 25 AND ROUNDED DOWN TO CLOSEST INTEGER. - RESULT DETERMINES QUALITY OF BAR. SEE code/__DEFINES/skills.dm - 0 = SPOILED - 1 = POOR - 2 = NORMAL - 3 = GOOD - */ - user.visible_message("[user] puts something in \the [src].") - cooking = 0 - return - else - to_chat(user, "\The [W.name] [W.smeltresult? "can" : "can't"] be smelted, but \the [src] is full.") - else - if(!W.firefuel && !istype(W, /obj/item/flint) && !istype(W, /obj/item/flashlight/flare/torch) && !istype(W, /obj/item/ore/coal)) - to_chat(user, "\The [W.name] cannot be smelted.") return ..() -// Gaining experience from just retrieving bars with your hands would be a hard-to-patch exploit. -/obj/machinery/light/fueled/smelter/attack_hand(mob/user, list/modifiers) - if(on) - to_chat(user, "It's too hot to retrieve bars with your hands.") - return - if(ore.len) - var/obj/item/I = ore[ore.len] - ore -= I - I.loc = user.loc - user.put_in_active_hand(I) - user.visible_message("[user] retrieves \the [I] from \the [src].") - else - return ..() +/obj/machinery/light/fueled/smelter/proc/try_retrieve_item(mob/user, obj/item/weapon/tongs/tongs_used) + . = FALSE + var/obj/item/retrieved_item + if(length(contained_items)) + retrieved_item = contained_items[contained_items.len] + if(tongs_used) + tongs_used.set_held_item(retrieved_item) + if(on) + tongs_used.heat_held_item(source = "smelter", duration = 20 SECONDS, incoming = 150, max_heat = max_crucible_temperature) + if(istype(tongs_used, /obj/item/weapon/tongs/stone)) + tongs_used.take_damage(1, BRUTE, BLUNT) + else + if(on) + to_chat(user, span_warning("It's too hot to retrieve items with your hands.")) + return + user.put_in_hands(retrieved_item) + user.visible_message(span_info("[user] retrieves [retrieved_item] from [src].")) + contained_items -= retrieved_item + . = TRUE + + if(tongs_used && !tongs_used.held_item) + for(var/obj/item/storage/crucible/crucible in contents) + user.visible_message("[user] starts removing a crucible from [src]!", "You start removing a crucible from [src].") + if(!do_after(user, 1.5 SECONDS, src)) + return + tongs_used.set_held_item(crucible) + retrieved_item = crucible + . = TRUE + if(.) + if(HAS_TRAIT(retrieved_item, TRAIT_NEWLY_SMELTED)) + var/mob/living/living_user = user + var/boon = living_user.get_learning_boon(/datum/skill/craft/blacksmithing) + var/amt2raise = living_user.STAINT*2 // Smelting is already a timesink, this is justified to accelerate levelling + if(amt2raise > 0) + living_user.adjust_experience(/datum/skill/craft/blacksmithing, amt2raise * boon, FALSE) + SEND_SIGNAL(living_user, COMSIG_ITEM_SMELTED) + REMOVE_TRAIT(retrieved_item, TRAIT_NEWLY_SMELTED, TRAIT_GENERIC) + +/obj/machinery/light/fueled/smelter/proc/try_add_item(obj/item/smelting_item, mob/living/user, obj/item/weapon/tongs/tongs_used) + if(!istype(user)) + return FALSE + + if(istype(smelting_item, /obj/item/storage/crucible)) + var/crucible_count = 0 + for(var/obj/item/storage/crucible/crucible in contents) + crucible_count++ + if(crucible_count >= max_crucible_amount) + to_chat(user, span_warning("[src] cannot hold any more crucibles!")) + return FALSE + smelting_item.forceMove(src) + user.visible_message("[user] loads [smelting_item] into [src].", "You load [smelting_item] into [src].") + return TRUE + + if(!tongs_used && !user.is_holding(smelting_item)) // necessary due to menu popup in attackby() + return FALSE + if(!smelting_item.smeltresult) + to_chat(user, span_warning("[smelting_item] cannot be smelted directly.")) + return FALSE + if(length(contained_items) >= max_contained_items) + to_chat(user, span_warning("[src] is full!")) + return FALSE + + smelting_item.forceMove(src) + contained_items[smelting_item] = SMELTERY_QUALITY_SPOIL + var/smelter_exp = user?.get_skill_level(/datum/skill/craft/blacksmithing, TRUE) // 0 to 6 + contained_items[smelting_item] = clamp(floor(rand(smelter_exp*15 + 10, max(30, smelter_exp*25))/SMELTING_DENOMINATOR), SMELTERY_QUALITY_SPOIL, SMELTERY_QUALITY_EXCELLENT) // Math explained below + /* + RANDOMLY PICKED NUMBER ACCORDING TO SMELTER SKILL: + NO SKILL: between 10 and 30 + NOVICE: between 25 and 30 + APPRENTICE: between 40 and 50 + JOURNEYMAN: between 55 and 75 + EXPERT: between 70 and 100 + MASTER: between 85 and 125 + LEGENDARY: between 100 and 150 + + PICKED NUMBER GETS DIVIDED BY SMELTING_DENOMINATOR AND ROUNDED DOWN TO CLOSEST INTEGER. + RESULT DETERMINES QUALITY OF BAR. SEE code/__DEFINES/qualities.dm + 1 = SPOILED + 2 = POOR + 3 = NORMAL + 4 = GOOD + 5 = GREAT + 6 = EXCELLENT + */ + user.visible_message(span_warning("[user] puts something in \the [src].")) + smelting_progress = 0 + return TRUE + +/obj/machinery/light/fueled/smelter/attack_hand(mob/user, list/modifiers) + if(try_retrieve_item(user)) + return TRUE + return ..() /obj/machinery/light/fueled/smelter/process() - ..() - if(maxore > 1) - return - if(!on) + . = ..() + if(!on || !length(contained_items)) return - if(!length(ore)) + if(smelting_progress < smelting_threshold) + smelting_progress++ + playsound(src.loc,'sound/misc/smelter_sound.ogg', 50, FALSE) return - if(cooking < 20) - cooking++ - playsound(src,'sound/misc/smelter_sound.ogg', 50, FALSE) - actively_smelting = TRUE - return - if(cooking == 20) - for(var/obj/item/I in ore) - if(I.smeltresult) - var/obj/item/R = new I.smeltresult(src, ore[I]) - ore -= I - ore += R - qdel(I) - playsound(src,'sound/misc/smelter_fin.ogg', 100, FALSE) - visible_message(span_notice("[src] finished smelting.")) - cooking = 21 - actively_smelting = FALSE + + if(smelting_progress == smelting_threshold) + handle_smelting() + +/obj/machinery/light/fueled/smelter/proc/handle_smelting() + var/list/valid_xp_smelts = typecacheof(list(/obj/item/ore, /obj/item/ingot, /obj/item/natural/glass)) // prevent ash from giving smelting xp + for(var/obj/item/item_to_smelt in contained_items) + if(!item_to_smelt.smeltresult) + continue + var/obj/item/smelted = new item_to_smelt.smeltresult(src, contained_items[item_to_smelt]) + contained_items -= item_to_smelt + qdel(item_to_smelt) + contained_items += smelted + if(is_type_in_typecache(smelted, valid_xp_smelts)) + ADD_TRAIT(smelted, TRAIT_NEWLY_SMELTED, TRAIT_GENERIC) + playsound(src,'sound/misc/smelter_fin.ogg', 100, FALSE) + visible_message(span_notice("[src] finishes smelting.")) + smelting_progress = smelting_threshold + 1 /obj/machinery/light/fueled/smelter/burn_out() - cooking = 0 - actively_smelting = FALSE - ..() + smelting_progress = 0 + . = ..() /obj/machinery/light/fueled/smelter/great icon = 'icons/roguetown/misc/forge.dmi' @@ -165,74 +185,72 @@ base_state = "smelter" anchored = TRUE density = TRUE - maxore = 4 + max_contained_items = 4 fueluse = 5 MINUTES climbable = FALSE max_crucible_temperature = 2000 -/obj/machinery/light/fueled/smelter/great/process() - ..() - if(on) - if(ore.len) - if(cooking < 30) - cooking++ - playsound(src,'sound/misc/smelter_sound.ogg', 50, FALSE) - actively_smelting = TRUE - else - if(cooking == 30) - var/alloy //moving each alloy to it's own var allows for possible additions later - var/steelalloy - var/bronzealloy - var/blacksteelalloy - - for(var/obj/item/I in ore) - if(I.smeltresult == /obj/item/ore/coal) - steelalloy = steelalloy + 1 - if(I.smeltresult == /obj/item/ingot/iron) - steelalloy = steelalloy + 2 - if(I.smeltresult == /obj/item/ingot/tin) - bronzealloy = bronzealloy + 1 - if(I.smeltresult == /obj/item/ingot/copper) - bronzealloy = bronzealloy + 2 - if(I.smeltresult == /obj/item/ingot/silver) - blacksteelalloy = blacksteelalloy + 1 - if(I.smeltresult == /obj/item/ingot/steel) - blacksteelalloy = blacksteelalloy + 2 - - if(steelalloy == 7) - maxore = 3 - alloy = /obj/item/ingot/steel_slag - else if(bronzealloy == 7) - alloy = /obj/item/ingot/bronze - else if(blacksteelalloy == 7) - alloy = /obj/item/ingot/blacksteel - maxore = 2 - else - alloy = null - if(alloy) - // The smelting quality of all ores added together, divided by the number of ores, and then rounded to the lowest integer (this isn't done until after the for loop) - var/floor_mean_quality = SMELTERY_LEVEL_SPOIL - var/ore_deleted = 0 - for(var/obj/item/I in ore) - floor_mean_quality += ore[I] - ore_deleted += 1 - ore -= I - qdel(I) - floor_mean_quality = floor(floor_mean_quality/ore_deleted) - for(var/i in 1 to maxore) - var/obj/item/R = new alloy(src, floor_mean_quality) - if(alloy == /obj/item/ingot/blacksteel) - record_round_statistic(STATS_BLACKSTEEL_SMELTED) - ore += R - else - for(var/obj/item/I in ore) - if(I.smeltresult) - var/obj/item/R = new I.smeltresult(src, ore[I]) - ore -= I - ore += R - qdel(I) - maxore = initial(maxore) - playsound(src,'sound/misc/smelter_fin.ogg', 100, FALSE) - visible_message("\The [src] finished smelting.") - cooking = 31 - actively_smelting = FALSE +/obj/machinery/light/fueled/smelter/great/handle_smelting() + // Alloy recipes should probably be datumized in the future + var/alloy + var/steelalloy + var/bronzealloy + var/blacksteelalloy + + for(var/obj/item/item_to_smelt in contained_items) + var/smelt_result = item_to_smelt.smeltresult + if(smelt_result == /obj/item/ore/coal) + steelalloy = steelalloy + 1 + if(smelt_result == /obj/item/ore/coal/charcoal) + steelalloy = steelalloy + 1 + if(smelt_result == /obj/item/ingot/iron) + steelalloy = steelalloy + 2 + if(smelt_result == /obj/item/ingot/tin) + bronzealloy = bronzealloy + 1 + if(smelt_result == /obj/item/ingot/copper) + bronzealloy = bronzealloy + 2 + if(smelt_result == /obj/item/ingot/silver) + blacksteelalloy = blacksteelalloy + 1 + if(smelt_result == /obj/item/ingot/steel) + blacksteelalloy = blacksteelalloy + 2 + + if(steelalloy == 7) + max_contained_items = 3 + alloy = /obj/item/ingot/steel_slag + else if(bronzealloy == 7) + alloy = /obj/item/ingot/bronze + else if(blacksteelalloy == 7) + alloy = /obj/item/ingot/blacksteel + max_contained_items = 2 + + if(alloy) + var/floor_mean_quality = 0 + var/ore_deleted = 0 + for(var/obj/item/item in contained_items) + floor_mean_quality += contained_items[item] + ore_deleted++ + contained_items -= item + qdel(item) + floor_mean_quality = floor(floor_mean_quality/ore_deleted) + for(var/i in 1 to max_contained_items) + var/obj/item/result = new alloy(src, floor_mean_quality) + if(alloy == /obj/item/ingot/blacksteel) + record_round_statistic(STATS_BLACKSTEEL_SMELTED) + contained_items += result + ADD_TRAIT(result, TRAIT_NEWLY_SMELTED, TRAIT_GENERIC) + else + var/list/valid_xp_smelts = typecacheof(list(/obj/item/ore, /obj/item/ingot, /obj/item/natural/glass)) // prevent ash from giving smelting xp + for(var/obj/item/item in contained_items) + if(!item.smeltresult) + continue + var/obj/item/result = new item.smeltresult(src, contained_items[item]) + contained_items -= item + qdel(item) + contained_items += result + if(is_type_in_typecache(result, valid_xp_smelts)) + ADD_TRAIT(result, TRAIT_NEWLY_SMELTED, TRAIT_GENERIC) + + max_contained_items = initial(max_contained_items) + playsound(src,'sound/misc/smelter_fin.ogg', 100, FALSE) + visible_message(span_notice("\The [src] finished smelting.")) + smelting_progress = smelting_threshold + 1 diff --git a/code/game/objects/structures/hole.dm b/code/game/objects/structures/hole.dm index 95b76b6abe6..f705e450358 100644 --- a/code/game/objects/structures/hole.dm +++ b/code/game/objects/structures/hole.dm @@ -139,7 +139,7 @@ if(attacking_shovel.heldclod) playsound(src,'sound/items/empty_shovel.ogg', 100, TRUE) if(stage == 3) //close grave - if(!do_after(user, 5 SECONDS * attacking_shovel.time_multiplier, src)) //can't have nice things can we + if(!do_after(user, 5 SECONDS * attacking_shovel.toolspeed, src)) //can't have nice things can we return stage = 4 climb_offset = 10 @@ -169,7 +169,7 @@ if(under_turf && our_turf && isopenturf(under_turf)) playsound(src,'sound/items/dig_shovel.ogg', 100, TRUE) user.visible_message("[user] starts digging out the bottom of [src]", "I start digging out the bottom of [src].") - if(!do_after(user, 10 SECONDS * attacking_shovel.time_multiplier, src)) + if(!do_after(user, 10 SECONDS * attacking_shovel.toolspeed, src)) return TRUE attacking_shovel.heldclod = new(attacking_shovel) attacking_shovel.update_appearance(UPDATE_ICON_STATE) @@ -195,7 +195,7 @@ else stage++ if(stage == 4) - if(!do_after(user, 5 SECONDS * attacking_shovel.time_multiplier, src)) // WE CANT HAVE NICE THINGS CAN WE + if(!do_after(user, 5 SECONDS * attacking_shovel.toolspeed, src)) // WE CANT HAVE NICE THINGS CAN WE return stage = 3 climb_offset = 0 diff --git a/code/game/objects/structures/irrigation_channel.dm b/code/game/objects/structures/irrigation_channel.dm index 23b589569d0..4962ddf4581 100644 --- a/code/game/objects/structures/irrigation_channel.dm +++ b/code/game/objects/structures/irrigation_channel.dm @@ -116,14 +116,14 @@ var/obj/item/weapon/shovel/shovel = I if(!shovel.heldclod) user.visible_message("[user] starts digging a trench.", "I start digging a trench.") - if(!do_after(user, 10 SECONDS * shovel.time_multiplier, src)) + if(!do_after(user, 10 SECONDS * shovel.toolspeed, src)) return new /obj/structure/trench(get_turf(src)) qdel(src) return TRUE user.visible_message("[user] starts filling [src].", "You start filling [src].") - if(!do_after(user, 4 SECONDS * shovel.time_multiplier, src)) + if(!do_after(user, 4 SECONDS * shovel.toolspeed, src)) return QDEL_NULL(shovel.heldclod) shovel.update_appearance(UPDATE_OVERLAYS) diff --git a/code/game/objects/structures/metallurgy/metal_connectors/channel_drain.dm b/code/game/objects/structures/metallurgy/metal_connectors/channel_drain.dm index 049d4e4b83a..b419d0d2e28 100644 --- a/code/game/objects/structures/metallurgy/metal_connectors/channel_drain.dm +++ b/code/game/objects/structures/metallurgy/metal_connectors/channel_drain.dm @@ -30,7 +30,7 @@ . = ..() if(target_mould) . += "There is \a [target_mould] positioned beneath the drain." - var/fill_percent = round((target_mould.fufilled_metal / target_mould.required_metal) * 100, 1) + var/fill_percent = round((target_mould.fufilled_metal / target_mould.required_metal_amount) * 100, 1) . += "The mould is [fill_percent]% filled." else . += "There is no mould beneath the drain." @@ -61,7 +61,7 @@ if(mould.cooling) continue - if(mould.fufilled_metal >= mould.required_metal) + if(mould.fufilled_metal >= mould.required_metal_amount) continue target_mould = mould @@ -95,19 +95,14 @@ return metal_to_drain = target_mould.filling_metal var/available_metal = channel_metal.data[metal_to_drain] - var/needed_metal = target_mould.required_metal - target_mould.fufilled_metal + var/needed_metal = target_mould.required_metal_amount - target_mould.fufilled_metal var/amount_to_drain = min(drain_rate, available_metal, needed_metal) if(amount_to_drain <= 0) return - var/drain_quality = channel_metal.recipe_quality + var/drain_quality = channel_metal.get_recipe_quality() - if(target_mould.fufilled_metal > 0) - target_mould.total_quality_points += amount_to_drain * drain_quality - target_mould.average_quality = target_mould.total_quality_points / (target_mould.fufilled_metal + amount_to_drain) - else - target_mould.total_quality_points = amount_to_drain * drain_quality - target_mould.average_quality = drain_quality + target_mould.average_quality = LERP(target_mould.average_quality, drain_quality, amount_to_drain / (target_mould.fufilled_metal + amount_to_drain)) channel_metal.data[metal_to_drain] -= amount_to_drain if(channel_metal.data[metal_to_drain] <= 0) @@ -118,7 +113,7 @@ target_mould.fufilled_metal += amount_to_drain target_mould.update_appearance(UPDATE_OVERLAYS) - if(target_mould.fufilled_metal >= target_mould.required_metal) + if(target_mould.fufilled_metal >= target_mould.required_metal_amount) target_mould.start_cooling() target_mould = null for(var/obj/structure/metal_channel/channel_update in channel.info?.channels) diff --git a/code/game/rotational_objects/orphan_smasher.dm b/code/game/rotational_objects/orphan_smasher.dm index 19e4d7274d1..c711ffff65e 100644 --- a/code/game/rotational_objects/orphan_smasher.dm +++ b/code/game/rotational_objects/orphan_smasher.dm @@ -216,8 +216,8 @@ var/list/materials = list() - materials |= first.req_bar - materials[first.req_bar]++ + materials |= first.required_material + materials[first.required_material]++ for(var/atom/atom_path as anything in first.additional_items) materials |= atom_path @@ -239,7 +239,7 @@ material_copy -= listed_atom.type var/atom/new_atom - for(var/i in 1 to current.createditem_extra + 1) + for(var/i in 1 to current.output_amount) new_atom = new current.created_item(get_turf(bin)) new_atom.update_integrity(new_atom.max_integrity, update_atom = FALSE) SEND_SIGNAL(bin, COMSIG_TRY_STORAGE_INSERT, new_atom, null, TRUE, TRUE) diff --git a/code/game/turfs/open/water.dm b/code/game/turfs/open/water.dm index 6843d9dc46d..588b7d147b5 100644 --- a/code/game/turfs/open/water.dm +++ b/code/game/turfs/open/water.dm @@ -193,7 +193,7 @@ if(!shovel.heldclod) return user.visible_message("[user] starts filling in [src].", "I start filling in [src].") - if(!do_after(user, 10 SECONDS * shovel.time_multiplier, src)) + if(!do_after(user, 10 SECONDS * shovel.toolspeed, src)) return QDEL_NULL(shovel.heldclod) shovel.update_appearance(UPDATE_ICON_STATE) @@ -822,10 +822,6 @@ taste_description = "salt" color = "#3e7459" -/datum/reagent/water/salty/reaction_mob(mob/living/L, method=TOUCH, reac_volume) - if(method & INGEST) // Make sure you DRANK the salty water before losing hydration - ..() - /datum/reagent/water/salty/on_mob_life(mob/living/carbon/M) if(ishuman(M)) var/mob/living/carbon/human/H = M diff --git a/code/modules/antagonists/villain/maniac/_maniac.dm b/code/modules/antagonists/villain/maniac/_maniac.dm index fd6eb225548..fded144b2e0 100644 --- a/code/modules/antagonists/villain/maniac/_maniac.dm +++ b/code/modules/antagonists/villain/maniac/_maniac.dm @@ -138,9 +138,7 @@ GLOBAL_VAR_INIT(maniac_highlander, 0) // THERE CAN ONLY BE ONE! dreamer.set_patron(/datum/patron/inhumen/zizo) dreamer.cmode_music = old_cm dreamer.remove_stat_modifier("[type]") - var/datum/component/themesong = dreamer.GetComponent(/datum/component/theme_music) - if(themesong) - themesong.RemoveComponent() + qdel(dreamer.GetComponent(/datum/component/theme_music)) phy.bleed_mod *= 2 UnregisterSignal(dreamer, COMSIG_LIVING_DEATH) var/client/client = dreamer?.client diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 67371c26ce7..913fe3efe65 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -570,9 +570,7 @@ BLIND // can't see anything if(proper_drying && !C.has_stress_type(/datum/stress_event/washed_cloth)) C.add_stress(/datum/stress_event/washed_cloth) proper_drying = FALSE - var/datum/component/particle_spewer = GetComponent(/datum/component/particle_spewer/sparkle) - if(particle_spewer) - particle_spewer.RemoveComponent() + qdel(GetComponent(/datum/component/particle_spewer/sparkle)) if(wet.use_water(0.7)) if(HAS_TRAIT(C, TRAIT_NOBLE_BLOOD) && wet.water_stacks == 0) diff --git a/code/modules/clothing/ring/misc.dm b/code/modules/clothing/ring/misc.dm index ac5715d896d..285c9099a7d 100644 --- a/code/modules/clothing/ring/misc.dm +++ b/code/modules/clothing/ring/misc.dm @@ -187,9 +187,7 @@ /obj/item/clothing/ring/active/nomag/demagicify() . = ..() - var/datum/component/magcom = GetComponent(/datum/component/anti_magic) - if(magcom) - magcom.RemoveComponent() + qdel(GetComponent(/datum/component/anti_magic)) // ................... Ring of Protection ....................... (rare treasure, not for purchase) /obj/item/clothing/ring/gold/protection diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index df1e4da0e36..d310607a39d 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -137,9 +137,6 @@ polished = 2 if(HAS_TRAIT(user, TRAIT_NOBLE_BLOOD)) user.add_stress(/datum/stress_event/noble_polishing_shoe) - var/datum/component/particle_spewer = GetComponent(/datum/component/particle_spewer/sparkle) - if(particle_spewer) - qdel(particle_spewer) AddComponent(/datum/component/particle_spewer/sparkle, shine_more = TRUE) addtimer(CALLBACK(src, PROC_REF(lose_shine)), 10 SECONDS) to_chat(user, ("You polished the [name].")) @@ -156,7 +153,5 @@ /obj/item/clothing/shoes/proc/lose_shine() if(polished == 1 || polished == 2) - var/datum/component/particle_spewer = GetComponent(/datum/component/particle_spewer/sparkle) - if(particle_spewer) - qdel(particle_spewer) + qdel(GetComponent(/datum/component/particle_spewer/sparkle)) polished = 0 diff --git a/code/modules/cooking/NeuFood.dm b/code/modules/cooking/NeuFood.dm index 5cbf4e5e7e4..be56dd2dea6 100644 --- a/code/modules/cooking/NeuFood.dm +++ b/code/modules/cooking/NeuFood.dm @@ -230,7 +230,7 @@ cloth_check.reagents.remove_all(1) dirty = FALSE update_appearance(UPDATE_OVERLAYS) - AddComponent(/datum/component/particle_spewer/sparkle) + AddComponent(/datum/component/particle_spewer/sparkle/turf_only) user.nobles_seen_servant_work() usages = 0 cleaned = TRUE @@ -259,9 +259,7 @@ usages +=1 if(usages >= max_usages && !dirty) dirty = TRUE - var/datum/component/particle_spewer = GetComponent(/datum/component/particle_spewer/sparkle) - if(particle_spewer) - qdel(particle_spewer) + qdel(GetComponent(/datum/component/particle_spewer/sparkle/turf_only)) update_appearance(UPDATE_OVERLAYS) playsound(src, 'sound/misc/eat.ogg', rand(30, 60), TRUE) user.visible_message(span_info("[user] eats from [src]."), \ diff --git a/code/modules/crafting/anvil_recipes/_anvil_recipe.dm b/code/modules/crafting/anvil_recipes/_anvil_recipe.dm index 1df19979094..9858aaeeb2b 100644 --- a/code/modules/crafting/anvil_recipes/_anvil_recipe.dm +++ b/code/modules/crafting/anvil_recipes/_anvil_recipe.dm @@ -1,149 +1,137 @@ /datum/anvil_recipe abstract_type = /datum/anvil_recipe var/name + /// Category of crafted item. Will determine how it shows up in menus. var/category = "Misc" - var/list/additional_items = list() // List of the object(s) we need to complete this recipe. - var/material_quality = 0 // Quality of the bar(s) used. Accumulated per added ingot. - var/num_of_materials = 1 // Total number of materials used. Quality divided among them. - var/skill_quality = 0 // Accumulated per hit based on calculations, will decide final result. - var/appro_skill = /datum/skill/craft/blacksmithing // The skill that will be taken into account when crafting. - var/atom/req_bar // The material of the ingot we need to craft. - var/atom/created_item // The item created when the recipe is fulfilled. Takes an object path as argument, NEVER USE A LIST. - var/createditem_extra = 0 // How many EXTRA units this recipe will create. At 1, this creates 2 copies. - var/craftdiff = 0 // Difficulty of craft. Affects final item quality and chance to advance steps. - var/needed_item // What item(s) we need to add to proceed to the next step. Draws from the list on var/additional_items. - var/needed_item_text // Name of the object we need to slap on the anvil to proceed to the next step. - var/progress = 0 // 0 to 100%, percentage of completion on this step of crafting (or overall if no extra items required) - var/i_type // Category of crafted item. Will determine how it shows on the crafting menu window. - var/recipe_name // This is what will be shown when you - var/numberofhits = 0 // Increased every time you hit the bar, the more you have to hit the bar the less quality of the product. - var/numberofbreakthroughs = 0 // How many good hits we got on the metal, advances recipes 50% faster, reduces number of hits total, and restores bar_health - var/datum/parent // The ingot we're currently working on. + /// Quality of the bar(s) used. Accumulated per added ingot. + var/material_quality = 0 + /// Total number of materials (with quality) used. Quality divided among them. + var/num_of_materials = 1 + /// The skill that will be taken into account when crafting. + var/appro_skill = /datum/skill/craft/blacksmithing + /// The typepath of the materialwe need to start the recipe. + var/atom/required_material + /// The item created when the recipe is fulfilled. SHOULD BE A TYPEPATH + var/atom/created_item + /// How much of the item does this recipe create? + var/output_amount = 1 + /// Difficulty of craft. Affects difficulty of minigame and amount of minigames. + var/craftdiff = 0 + /// List of the object(s) we need to complete this recipe. + var/list/additional_items + /// What item we need to add to proceed to the next step. Draws from the list on var/additional_items. + var/obj/item/needed_item + /// 0 to 100%, percentage of completion on this step of crafting (or overall if no extra items required) + var/progress = 0 + /// Based on the performance of each minigame attempt. + var/accumulated_quality = 0 + /// Based on skill level of everyone who worked on this recipe. + var/skill_quality + /// Increased each time the minigame is played. Used to average accumulated_quality and skill_quality. + var/numberofhits = 0 + /// The item that the recipe currently applies to + var/datum/parent var/rotations_required = 1 + /// Set to FALSE if needs to be learned first + var/always_available = TRUE /datum/anvil_recipe/New(datum/P, ...) parent = P + if(parent) + process_parent(parent) . = ..() /datum/anvil_recipe/Destroy(force, ...) - additional_items.Cut() + LAZYNULL(additional_items) parent = null - req_bar = null + required_material = null created_item = null return ..() -/datum/anvil_recipe/proc/advance(mob/user, breakthrough = FALSE, quality_score = 0) - var/moveup = 1 - var/proab = 0 // Probability to not spoil the bar - var/skill_level = user.get_skill_level(appro_skill) +/datum/anvil_recipe/proc/process_parent(parent) + if(isitem(parent)) + material_quality += parent:recipe_quality +/datum/anvil_recipe/proc/can_advance(mob/user) if(progress == 100) - to_chat(user, "It's ready.") - user.visible_message("[user] strikes the bar!") + to_chat(user, span_info("It's ready.")) return FALSE if(needed_item) - to_chat(user, "Now it's time to add a [needed_item_text].") - user.visible_message("[user] strikes the bar!") + to_chat(user, span_notice("Now it's time to add \a [needed_item.name].")) return FALSE - if(!skill_level) - proab = 40 - else if(skill_level < 4) - proab = 40 + (skill_level * 15) // More gradual increase - else - proab = 100 - - proab -= craftdiff // Crafting difficulty subtracts from your chance - var/quality_bonus = 0 - if(quality_score > 0) - if(quality_score >= 80) - quality_bonus = 40 // Excellent performance almost guarantees success - else if(quality_score >= 60) - quality_bonus = 25 - else if(quality_score >= 40) - quality_bonus = 15 - else if(quality_score >= 20) - quality_bonus = 5 - if(skill_level < craftdiff) - quality_bonus = FLOOR(quality_bonus * 0.50, 1) - proab = min(proab + quality_bonus, 100) + return TRUE - if(has_world_trait(/datum/world_trait/delver)) - proab = 100 - - // Roll the dice to see if the hit actually causes progress - if(prob(proab) && quality_score > 0) - moveup += round((min(50, skill_level * 12)) * (breakthrough ? 1.5 : 1)) - moveup += quality_bonus - moveup -= craftdiff - progress = min(progress + max(0, moveup), 100) - numberofhits++ - else - moveup = 0 - numberofhits++ - - // This step is finished, check if more items are needed - if(progress == 100 && additional_items.len) - needed_item = pick(additional_items) - var/obj/item/I = new needed_item() - needed_item_text = I.name - qdel(I) - additional_items -= needed_item - progress = 0 - - if(!moveup) - if(!prob(proab)) // Roll again for consequences - user.visible_message("[user] strikes poorly!") - skill_quality -= 0.5 - return FALSE - else - user.visible_message("[user] almost fumbles but recovers!") - return FALSE - else - if(user.mind && isliving(user)) - var/mob/living/L = user - var/amt2raise = L.STAINT // It would be impossible to level up otherwise - var/boon = user.get_learning_boon(appro_skill) - if(amt2raise > 0) - if(!HAS_TRAIT(user, TRAIT_MALUMFIRE)) - skill_quality += (rand(skill_level*6, skill_level*15) * moveup) // Lesser quality for self-learned non-professional smiths by trade - if(skill_level < 3) // Non-blacksmith jobs can't level past 3. Ever. - user.mind.add_sleep_experience(appro_skill, floor(amt2raise * boon), FALSE) - else - skill_quality += (rand(skill_level*8, skill_level*17) * moveup) - if(skill_level < 3) - amt2raise /= 2 // Let's not get out of hand it's for lower levels with high chances of failure - user.mind.add_sleep_experience(appro_skill, amt2raise * boon, FALSE) - else // Sanity, no expert blacksmith has lower skill than 3, for if admins manually add the trait or blacksmith vampire thralls - user.mind.add_sleep_experience(appro_skill, amt2raise, FALSE) - - if(breakthrough) - user.visible_message("[user] deftly strikes the bar!") +// Keep this simple, we can do the math and randomization in quality_manager +/datum/anvil_recipe/proc/advance(mob/user, quality_score = 0) + if(!can_advance(user)) + return FALSE + + numberofhits++ + accumulated_quality += quality_score + var/skill_level_to_add = user.get_skill_level(appro_skill) + skill_quality += skill_level_to_add + + var/progress_to_add = 100 + switch(craftdiff) + if(0) + progress_to_add /= 2 + if(1) + progress_to_add /= 2 + if(2) + progress_to_add /= 3 + if(3) + progress_to_add /= 3 + if(4) + progress_to_add /= 4 + if(5) + progress_to_add /= 4 + if(6) + progress_to_add /= 5 + // Progress scales based on additional_items to prevent multi-item recipes from taking too long + progress_to_add *= LAZYLEN(additional_items)+1 + progress += progress_to_add + + if(progress >= 100) + if(length(additional_items)) + needed_item = pick_n_take(additional_items) + to_chat(user, span_notice("Now it's time to add \a [needed_item.name].")) + progress = 0 else - user.visible_message("[user] strikes the bar!") - return TRUE + to_chat(user, span_info("It's ready.")) -/datum/anvil_recipe/proc/item_added(mob/user) - needed_item = null - user.visible_message("[user] adds a [needed_item_text].") - needed_item_text = null + return TRUE +/datum/anvil_recipe/proc/item_added(obj/item/added_item, mob/user) + if(!needed_item) + return FALSE + if(!istype(added_item, needed_item)) + return FALSE + user.visible_message(span_info("[user] adds \a [added_item.name].")) + if(istype(added_item, /obj/item/ingot)) + material_quality += added_item.recipe_quality + num_of_materials++ + qdel(added_item) + needed_item = null + return TRUE -/datum/anvil_recipe/proc/handle_creation(obj/item/I, minigame_success = 30,skill_level = 0) +/datum/anvil_recipe/proc/handle_creation(atom/output_location, mob/user) var/datum/quality_calculator/blacksmithing/quality_calc = new( - base_qual = 0, mat_qual = material_quality, - skill_qual = skill_level, // Pass the success score here - perf_qual = numberofhits, + skill_qual = skill_quality, + components = num_of_materials, + perf_qual = accumulated_quality, diff_mod = craftdiff, - components = num_of_materials + mini_play = numberofhits ) - quality_calc.minigame_success = minigame_success - quality_calc.apply_quality_to_item(I, TRUE) - I.add_quench_requirement() - addtimer(CALLBACK(I, TYPE_PROC_REF(/obj/item, remove_quench)), 60 SECONDS) + for(var/i in 1 to output_amount) + var/obj/item/output_item = new created_item(output_location) + output_item.OnCrafted(user.dir, user) + quality_calc.apply_quality_to_item(output_item, TRUE) + output_item.add_quench_requirement("recipe_creation", 60 SECONDS) + qdel(quality_calc) /datum/anvil_recipe/proc/show_menu(mob/user) @@ -200,7 +188,7 @@

Steps

"} - html += "[icon2html(new req_bar, user)] Start with [initial(req_bar.name)] on an anvil.
" + html += "[icon2html(new required_material, user)] Start with [initial(required_material.name)] on an anvil.
" html += "Hammer the material.
" for(var/atom/path as anything in additional_items) html += "[icon2html(new path, user)] then add [initial(path.name)]
" @@ -212,7 +200,7 @@
"} - html += "and then you get
[icon2html(new created_item, user)]
[createditem_extra + 1] [initial(created_item.name)]\s
" + html += "and then you get
[icon2html(new created_item, user)]
[output_amount] [initial(created_item.name)]\s
" html += {"
@@ -222,5 +210,12 @@ "} return html -/datum/anvil_recipe/proc/get_display_name() - return recipe_name || name +/datum/anvil_recipe/proc/is_recipe_available(mob/user) + if(has_world_trait(/datum/world_trait/delver)) + if(!has_recipe_unlocked(user.key, type)) + return FALSE + + if(!always_available && !(type in user?.mind?.learned_recipes)) + return FALSE + + return TRUE diff --git a/code/modules/crafting/anvil_recipes/armor.dm b/code/modules/crafting/anvil_recipes/armor.dm index 8ef6310d529..37d6dff0df9 100644 --- a/code/modules/crafting/anvil_recipes/armor.dm +++ b/code/modules/crafting/anvil_recipes/armor.dm @@ -1,6 +1,5 @@ /datum/anvil_recipe/armor appro_skill = /datum/skill/craft/armorsmithing - i_type = "Armor" craftdiff = 1 abstract_type = /datum/anvil_recipe/armor category = "Armor" @@ -14,41 +13,36 @@ /datum/anvil_recipe/armor/copper abstract_type = /datum/anvil_recipe/armor/copper craftdiff = 0 // for starters - req_bar = /obj/item/ingot/copper + required_material = /obj/item/ingot/copper /////////////////////////////////////////////// // COPPER ARMOR /datum/anvil_recipe/armor/copper/cuirass name = "Copper heart protector" - recipe_name = "a simple armor piece for the chest" created_item = /obj/item/clothing/armor/cuirass/copperchest /datum/anvil_recipe/armor/copper/bracers name = "Copper bracers" - recipe_name = "a pair of Copper bracers" created_item = /obj/item/clothing/wrists/bracers/copper /datum/anvil_recipe/armor/copper/mask name = "Copper mask" - recipe_name = "a mask of copper" created_item = /obj/item/clothing/face/facemask/copper // NECK ARMOR /datum/anvil_recipe/armor/copper/gorget name = "Copper neck protector" - recipe_name = "a neck protector" created_item = /obj/item/clothing/neck/gorget/copper // HELMETS /datum/anvil_recipe/armor/copper/cap name = "Lamellar cap" - recipe_name = "a copper cap" created_item = /obj/item/clothing/head/helmet/coppercap ////////////////////////////////////////////////////////////////////////////////////////////// // --------- BRONZE ----------- /datum/anvil_recipe/armor/bronze - req_bar = /obj/item/ingot/bronze + required_material = /obj/item/ingot/bronze craftdiff = 1 abstract_type = /datum/anvil_recipe/armor/bronze /////////////////////////////////////////////// @@ -57,8 +51,7 @@ /datum/anvil_recipe/armor/bronze/brigandine name = "Abyssal Robe (+Bronze Bar, +Cloth)" - recipe_name = "an abyssal robe" - req_bar = /obj/item/ingot/bronze + required_material = /obj/item/ingot/bronze additional_items = list(/obj/item/ingot/bronze, /obj/item/natural/cloth) created_item = /obj/item/clothing/armor/brigandine/abyssor craftdiff = 3 @@ -67,8 +60,7 @@ /datum/anvil_recipe/armor/bronze/gorget name = "Bronze Gorget" - recipe_name = "a bronze gorget" - req_bar = /obj/item/ingot/bronze + required_material = /obj/item/ingot/bronze created_item = /obj/item/clothing/neck/gorget/hoplite craftdiff = 0 @@ -77,8 +69,7 @@ /datum/anvil_recipe/armor/bronze/helmet name = "Abyssor Helmet (+Bronze Bar)" - recipe_name = "an abyssor helmet" - req_bar = /obj/item/ingot/bronze + required_material = /obj/item/ingot/bronze additional_items = list(/obj/item/ingot/bronze) created_item = /obj/item/clothing/head/helmet/heavy/necked/abyssor craftdiff = 3 @@ -86,7 +77,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////// // --------- IRON ----------- /datum/anvil_recipe/armor/iron - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron craftdiff = 1 abstract_type = /datum/anvil_recipe/armor/iron /////////////////////////////////////////////// @@ -94,226 +85,191 @@ // IRON ARMOR /datum/anvil_recipe/armor/iron/splint name = "Two splint Armors (+2 cured leather)" - recipe_name = "durable light armor" additional_items = list(/obj/item/natural/hide/cured, /obj/item/natural/hide/cured) created_item = /obj/item/clothing/armor/leather/splint - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/armor/iron/splintpants name = "two splint trousers (+3 cured leather)" //two items per bar since is mostly leather + iron bits, ideal for cheaper armors - recipe_name = "durable light armor" additional_items = list(/obj/item/natural/hide/cured, /obj/item/natural/hide/cured, /obj/item/natural/hide/cured) created_item = /obj/item/clothing/pants/trou/leather/splint - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/armor/iron/mailleboots name = "two chainmail boots (+2 cured leather)" - recipe_name = "durable light armor" additional_items = list(/obj/item/natural/hide/cured, /obj/item/natural/hide/cured) created_item = /obj/item/clothing/shoes/boots/armor/ironmaille - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/armor/iron/cuirass name = "Iron Cuirass" - recipe_name = "an iron cuirass" created_item = /obj/item/clothing/armor/cuirass/iron /datum/anvil_recipe/armor/iron/chausses name = "Iron Plate Chausses" - recipe_name = "a pair of iron Plate Chausses" created_item = /obj/item/clothing/pants/platelegs/iron /datum/anvil_recipe/armor/iron/platemask - name = "2x Iron Face Masks" - recipe_name = "a Face Mask" + name = "Iron Face Masks" created_item = /obj/item/clothing/face/facemask - createditem_extra = 1 + output_amount = 2 craftdiff = 0 // IRON CHAIN ARMOR /datum/anvil_recipe/armor/iron/chainmail name = "Iron Maille" - recipe_name = "an iron maille shirt" created_item = /obj/item/clothing/armor/chainmail/iron /datum/anvil_recipe/armor/iron/chainkini name = "Iron Chainkini (+fur)" - recipe_name = "Fur skirt and maille chest holder" additional_items = list(/obj/item/natural/fur) created_item = /obj/item/clothing/armor/amazon_chainkini /datum/anvil_recipe/armor/iron/hauberk name = "Iron Hauberk (+Bar)" - recipe_name = "a Hauberk" additional_items = list(/obj/item/ingot/iron) created_item = /obj/item/clothing/armor/chainmail/hauberk/iron /datum/anvil_recipe/armor/iron/chainleg name = "Iron Chain Chausses" - recipe_name = "a pair of Chain Chausses" created_item = /obj/item/clothing/pants/chainlegs/iron /datum/anvil_recipe/armor/iron/chainkilt name = "Iron Chain Kilt" - recipe_name = "a short Chain Kilt" created_item = /obj/item/clothing/pants/chainlegs/kilt/iron /datum/anvil_recipe/armor/iron/chainglove - name = "2x Iron Chain Gauntlets" - recipe_name = "two pairs of Chain Gauntlets" + name = "Iron Chain Gauntlets" created_item = /obj/item/clothing/gloves/chain/iron - createditem_extra = 1 + output_amount = 2 // IRON NECK ARMOR /datum/anvil_recipe/armor/iron/gorget name = "Iron Gorget" - recipe_name = "a gorget" created_item = /obj/item/clothing/neck/gorget /datum/anvil_recipe/armor/iron/chaincoif name = "Iron Chain Coif" - recipe_name = "a Chain Coif" created_item = /obj/item/clothing/neck/chaincoif/iron /datum/anvil_recipe/armor/iron/highcollier name = "Iron High Collier" - recipe_name = "a High Collier" created_item = /obj/item/clothing/neck/highcollier/iron craftdiff = 1 /datum/anvil_recipe/armor/iron/highcollier_renegade name = "Iron Renegade Collar (+Hide)" - recipe_name = "a renegade collar" additional_items = list(/obj/item/natural/hide) created_item = /obj/item/clothing/neck/highcollier/iron/renegadecollar craftdiff = 1 /datum/anvil_recipe/armor/iron/chainglove - name = "2x Iron Chain Gauntlets" - recipe_name = "two pairs of Chain Gauntlets" - req_bar = /obj/item/ingot/iron + name = "Iron Chain Gauntlets" + required_material = /obj/item/ingot/iron created_item = /obj/item/clothing/gloves/chain/iron - createditem_extra = 1 + output_amount = 2 craftdiff = 0 /datum/anvil_recipe/armor/iron/igauntlets name = "Iron Plate Gauntlets" - recipe_name = "a pair of Plate Gauntlets" created_item = /obj/item/clothing/gloves/plate/iron /datum/anvil_recipe/armor/iron/ijackchain - name = "2x Iron Jack Chains" - recipe_name = "two pairs of Jack Chains" + name = "Iron Jack Chains" created_item = /obj/item/clothing/wrists/bracers/ironjackchain - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/armor/iron/ibracers name = "Iron Plate Vambraces" - recipe_name = "a pair of Plate Vambraces" created_item = /obj/item/clothing/wrists/bracers/iron /datum/anvil_recipe/armor/iron/chainmail name = "Iron Haubergeon" - recipe_name = "a Haubergeon" - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron created_item = /obj/item/clothing/armor/chainmail/iron /datum/anvil_recipe/armor/iron/hauberk name = "Hauberk (+Bar)" - recipe_name = "a Hauberk" - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron additional_items = list(/obj/item/ingot/iron) created_item = /obj/item/clothing/armor/chainmail/hauberk/iron /datum/anvil_recipe/armor/iron/cuirass name = "Iron Cuirass" - recipe_name = "a cuirass" - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron created_item = /obj/item/clothing/armor/cuirass/iron craftdiff = 0 /datum/anvil_recipe/armor/iron/platefull name = "Iron Plate Armor (+Bar x3)" - recipe_name = "a full set of Full-Plate Armor" - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron additional_items = list(/obj/item/ingot/iron,/obj/item/ingot/iron,/obj/item/ingot/iron) created_item = /obj/item/clothing/armor/plate/full/iron craftdiff = 2 /datum/anvil_recipe/armor/iron/platefull_shadow name = "Iron Plate Shadow Armor (+Bar x3)" - recipe_name = "a full set of Full-Plate Shadow Armor" - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron additional_items = list(/obj/item/ingot/iron,/obj/item/ingot/iron,/obj/item/ingot/iron) created_item = /obj/item/clothing/armor/cuirass/iron/shadowplate craftdiff = 2 /datum/anvil_recipe/armor/iron/halfplate name = "Iron Half-plate (+Bar x2)" - recipe_name = "a Half-Plate Armor" - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron additional_items = list(/obj/item/ingot/iron,/obj/item/ingot/iron) created_item = /obj/item/clothing/armor/plate/iron craftdiff = 1 /datum/anvil_recipe/armor/iron/platehelmet name = "Iron Plate Helmet (+Bar)" - recipe_name = "a heavy iron helmet" additional_items = list(/obj/item/ingot/iron) created_item = /obj/item/clothing/head/helmet/heavy/ironplate craftdiff = 1 /datum/anvil_recipe/armor/iron/barred_helmet name = "Barred Helmet (+Bar)" - recipe_name = "a heavy iron helmet" additional_items = list(/obj/item/ingot/iron) created_item = /obj/item/clothing/head/helmet/townwatch/gatemaster craftdiff = 1 /datum/anvil_recipe/armor/iron/winged_helmet name = "Winged Helmet" - recipe_name = "an iron helmet" created_item = /obj/item/clothing/head/helmet/winged craftdiff = 1 /datum/anvil_recipe/armor/iron/horned_helmet name = "Horned Helmet" - recipe_name = "an iron helmet" created_item = /obj/item/clothing/head/helmet/horned craftdiff = 1 /datum/anvil_recipe/armor/steel/bastion_helm name = "Bastion helm (+Bar X2)" - recipe_name = "a heavy steel bastion helmet" additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel) created_item = /obj/item/clothing/head/helmet/heavy/necked craftdiff = 2 /datum/anvil_recipe/armor/steel/pegasusknighthelm name = "Coifed Helmet (+Cloth)" - recipe_name = "a pegasus knight's helmet" additional_items = list(/obj/item/natural/cloth) created_item = /obj/item/clothing/head/helmet/pegasusknight craftdiff = 2 /datum/anvil_recipe/armor/steel/crusader_helm name = "Crusader helm (+Bar X2)" - recipe_name = "a heavy steel crusader helmet" additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel) created_item = /obj/item/clothing/head/helmet/heavy/crusader craftdiff = 2 /datum/anvil_recipe/armor/steel/totod_crusader_helm name = "Totod Crusader helm (+Bar X2)" - recipe_name = "a heavy steel totod crusader helmet" additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel) created_item = /obj/item/clothing/head/helmet/heavy/crusader/t craftdiff = 2 /datum/anvil_recipe/armor/steel/skullmet_helm name = "Skullmet helm (+Bone X2)" - recipe_name = "A creacher skull covering a steel helmet." additional_items = list(/obj/item/alch/bone, /obj/item/alch/bone) created_item = /obj/item/clothing/head/helmet/medium/decorated/skullmet craftdiff = 3 @@ -321,73 +277,61 @@ /datum/anvil_recipe/armor/steel/rousskull_helm name = "Rous Skull helm (+Bone X2)" - recipe_name = "A rous skull covering a steel helmet." additional_items = list(/obj/item/alch/bone, /obj/item/alch/bone) created_item = /obj/item/clothing/head/helmet/medium/decorated/rousskullmet craftdiff = 3 /datum/anvil_recipe/armor/iron/cage_helmet name = "feldsher's cage" - recipe_name = "a cage helmet" created_item = /obj/item/clothing/head/helmet/feld craftdiff = 1 /datum/anvil_recipe/armor/iron/pothelmet name = "Pot Helmet" - recipe_name = "a sturdy iron helmet" created_item = /obj/item/clothing/head/helmet/ironpot /datum/anvil_recipe/armor/iron/lakkariancap name = "Crowned Cap (+ Gold Bar)" - recipe_name = "a sturdy lakkarian cap" created_item = /obj/item/clothing/head/helmet/ironpot/lakkariancap additional_items = list(/obj/item/ingot/gold) /datum/anvil_recipe/armor/iron/nasal_helmet name = "Nasal helmet" - recipe_name = "a Nasal helmet" created_item = /obj/item/clothing/head/helmet/nasal /datum/anvil_recipe/armor/iron/skullcap name = "x2 Skullcap" - recipe_name = "Two skullcaps" created_item = /obj/item/clothing/head/helmet/skullcap - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/armor/iron/helmetkettle name = "Iron Kettle Helmet" - recipe_name = "a Kettle Helmet" created_item = /obj/item/clothing/head/helmet/kettle/iron /datum/anvil_recipe/armor/iron/helmetslitkettle name = "Slitted Iron Kettle Helmet" - recipe_name = "a slitted kettle helmets" created_item = /obj/item/clothing/head/helmet/kettle/slit/iron /datum/anvil_recipe/armor/iron/helmetsall name = "Iron Sallet" - recipe_name = "a Sallet" created_item = /obj/item/clothing/head/helmet/sallet/iron /datum/anvil_recipe/armor/iron/helmetsallv name = "Visored Iron Sallet (+Bar)" - recipe_name = "a Visored Sallet" - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron additional_items = list(/obj/item/ingot/iron) created_item = /obj/item/clothing/head/helmet/visored/sallet/iron craftdiff = 2 /datum/anvil_recipe/armor/iron/eoran_sallet name = "Eoran Sallet (+Bar)" - recipe_name = "an Eoran Sallet" - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron additional_items = list(/obj/item/ingot/iron) created_item = /obj/item/clothing/head/helmet/sallet/eoran craftdiff = 2 /datum/anvil_recipe/armor/iron/helmetknight name = "Iron Knight's helmet (+Bar)" - recipe_name = "a Knight's Helmet" additional_items = list(/obj/item/ingot/iron) created_item = (/obj/item/clothing/head/helmet/visored/knight/iron) craftdiff = 2 @@ -395,111 +339,94 @@ // IRON PLATE ARMOR /datum/anvil_recipe/armor/iron/halfplate name = "Iron Half-plate (+Bar x2)" - recipe_name = "a Half-Plate Armor" additional_items = list(/obj/item/ingot/iron,/obj/item/ingot/iron) created_item = /obj/item/clothing/armor/plate/iron /datum/anvil_recipe/armor/iron/platefull name = "Iron Plate Armor (+Bar x3)" - recipe_name = "a full set of Full-Plate Armor" additional_items = list(/obj/item/ingot/iron,/obj/item/ingot/iron,/obj/item/ingot/iron) created_item = /obj/item/clothing/armor/plate/full/iron craftdiff = 2 /datum/anvil_recipe/armor/iron/platehelmet name = "Iron Plate Helmet (+Bar)" - recipe_name = "a heavy iron helmet" additional_items = list(/obj/item/ingot/iron) created_item = /obj/item/clothing/head/helmet/heavy/ironplate craftdiff = 2 /datum/anvil_recipe/armor/iron/bevor name = "Iron Bevor" - recipe_name = "a Bevor" - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron created_item = /obj/item/clothing/neck/bevor/iron /datum/anvil_recipe/armor/iron/platebootlight name = "Light Plate Boots" - recipe_name = "a pair of Light Plate Boots" created_item = /obj/item/clothing/shoes/boots/armor/light /datum/anvil_recipe/armor/iron/town_watch_helmet name = "Town Watch helmet" - recipe_name = "a Town Watch helmet" - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron created_item = /obj/item/clothing/head/helmet/townwatch craftdiff = 1 /datum/anvil_recipe/armor/iron/town_watch_helmet_alt name = "Town Watch helmet (alt)" - recipe_name = "a Town Watch helmet" - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron created_item = /obj/item/clothing/head/helmet/townwatch/alt craftdiff = 1 /datum/anvil_recipe/armor/iron/skullcap name = "Skullcap" - recipe_name = "a skullcap" created_item = /obj/item/clothing/head/helmet/skullcap /datum/anvil_recipe/armor/iron/grenzelhoft_skullcap name = "Grenzelhoft Plume helmet" additional_items = list(/obj/item/natural/feather) - recipe_name = "a grenzelhoft plume helmet" created_item = /obj/item/clothing/head/helmet/skullcap/grenzelhoft /datum/anvil_recipe/armor/iron/splint name = "Two splint Armors (+2 cured leather)" - recipe_name = "durable light armor" additional_items = list(/obj/item/natural/hide/cured, /obj/item/natural/hide/cured) created_item = /obj/item/clothing/armor/leather/splint - createditem_extra = 1 + output_amount = 2 /////////////////////////////////////////////// // --------- STEEL ----------- /datum/anvil_recipe/armor/steel - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel abstract_type = /datum/anvil_recipe/armor/steel craftdiff = 2 /////////////////////////////////////////////// // STEEL ARMOR /datum/anvil_recipe/armor/steel/jackchain - name = "2x Jack Chains" - recipe_name = "two pairs of Jack Chains" + name = "Jack Chains" created_item = /obj/item/clothing/wrists/bracers/jackchain - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/armor/steel/platemask name = "Steel Mask" - recipe_name = "a Face Mask" created_item = /obj/item/clothing/face/facemask/steel /datum/anvil_recipe/armor/steel/steppemask name = "Steppe War Mask" - recipe_name = "a Face Mask" created_item = /obj/item/clothing/face/facemask/steel/steppe /datum/anvil_recipe/armor/steel/maskbeast name = "Steppe Beast Mask" - recipe_name = "a Face Mask" created_item = /obj/item/clothing/face/facemask/steel/steppebeast /datum/anvil_recipe/armor/steel/cuirass name = "Steel Cuirass" - recipe_name = "a Cuirass" created_item = /obj/item/clothing/armor/cuirass /datum/anvil_recipe/armor/steel/brigadine name = "Brigandine (+Bar x2, +Cloth)" - recipe_name = "a Brigandine" additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel, /obj/item/natural/cloth) created_item = /obj/item/clothing/armor/brigandine craftdiff = 3 /* /datum/anvil_recipe/armor/steel/brigadine name = "Captain's brigandine (+Bar x2, +Cloth)" - recipe_name = "a premium Brigandine" additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel, /obj/item/natural/cloth) created_item = /obj/item/clothing/armor/brigandine/captain craftdiff = 6 @@ -507,20 +434,17 @@ /datum/anvil_recipe/armor/steel/helmetbuc name = "Great Helm" - recipe_name = "a Bucket Helmet" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel created_item = (/obj/item/clothing/head/helmet/heavy/bucket) /* /datum/anvil_recipe/armor/steel/sinistar name = "Sinistar Helmet (+Steel Bar)" - recipe_name = "a graggarite helmet" created_item = /obj/item/clothing/head/helmet/heavy/sinistar additional_items = list(/obj/item/ingot/steel) */ /datum/anvil_recipe/armor/iron/shadow_plate_gauntlets name = "Shadow Plate Gauntlets" - recipe_name = "a pair of Shadow Plate Gauntlets" created_item = /obj/item/clothing/gloves/chain/iron/shadowgauntlets craftdiff = 3 @@ -530,110 +454,92 @@ /datum/anvil_recipe/armor/steel/templar/helmet_noc name = "Noc Helmet (+Silver Bar)" - recipe_name = "a noc helmet" created_item = /obj/item/clothing/head/helmet/heavy/necked/noc additional_items = list(/obj/item/ingot/silver) /datum/anvil_recipe/armor/steel/templar/gold_helmet name = "Gold Helmet (+Gold Bar)" - recipe_name = "a golden helmet" created_item = /obj/item/clothing/head/helmet/heavy/bucket/gold additional_items = list(/obj/item/ingot/gold) /datum/anvil_recipe/armor/steel/templar/helmet_astrata name = "Astratan Helmet (+Gold Bar)" - recipe_name = "an astratan helmet" created_item = /obj/item/clothing/head/helmet/heavy/necked/astrata additional_items = list(/obj/item/ingot/gold) /datum/anvil_recipe/armor/steel/templar/helmet_necra name = "Necran Helmet (+Iron Bar)" - recipe_name = "a necran helmet" created_item = /obj/item/clothing/head/helmet/heavy/necked/necra additional_items = list(/obj/item/ingot/iron) /datum/anvil_recipe/armor/steel/templar/helmet_dendor name = "Dendor Helmet (+Small Log)" - recipe_name = "a dendorian helmet" created_item = /obj/item/clothing/head/helmet/heavy/necked/dendorhelm additional_items = list(/obj/item/grown/log/tree/small) /datum/anvil_recipe/armor/steel/templar/helmet_pestra name = "Pestran Helmet (+Iron Bar)" - recipe_name = "a pestran helmet" created_item = /obj/item/clothing/head/helmet/heavy/necked/pestrahelm additional_items = list(/obj/item/ingot/iron) /datum/anvil_recipe/armor/steel/templar/helmet_malum name = "Malum Helmet (+Iron Bar)" - recipe_name = "a malumite helmet" created_item = /obj/item/clothing/head/helmet/heavy/necked/malumhelm additional_items = list(/obj/item/ingot/iron) /datum/anvil_recipe/armor/steel/templar/helmet_ravox name = "Ravox Helmet (+Iron Bar)" - recipe_name = "a ravoxian helmet" created_item = /obj/item/clothing/head/helmet/heavy/necked/ravox additional_items = list(/obj/item/ingot/iron) /datum/anvil_recipe/armor/steel/templar/helmet_xylix name = "Xylix Helmet (+Iron Bar)" - recipe_name = "a xylixian helmet" created_item = /obj/item/clothing/head/helmet/heavy/necked/xylix additional_items = list(/obj/item/ingot/iron) /datum/anvil_recipe/armor/steel/chainleg name = "Chain Chausses" - recipe_name = "a pair of Chain Chausses" created_item = /obj/item/clothing/pants/chainlegs /datum/anvil_recipe/armor/steel/chainkilt_steel name = "Chain Kilt" - recipe_name = "a long Chain Kilt" created_item = /obj/item/clothing/pants/chainlegs/kilt /datum/anvil_recipe/armor/steel/haubergeon name = "Haubergeon" - recipe_name = "a Haubergeon" created_item = /obj/item/clothing/armor/chainmail /datum/anvil_recipe/armor/steel/chainglove - name = "2x Chain Gauntlets" - recipe_name = "two pairs of Chain Gauntlets" + name = "Chain Gauntlets" created_item = /obj/item/clothing/gloves/chain - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/armor/steel/hauberk name = "Hauberk (+Bar)" - recipe_name = "a Hauberk" additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/clothing/armor/chainmail/hauberk craftdiff = 3 /datum/anvil_recipe/armor/steel/scalemail name = "Scalemail (+Bar)" - recipe_name = "a Scalemail" additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/clothing/armor/medium/scale craftdiff = 3 /datum/anvil_recipe/armor/steel/scalemail/steppe name = "Lamellar (+Bar, +cured hide)" - recipe_name = "Steel Lamellar" additional_items = list(/obj/item/ingot/steel,/obj/item/natural/hide/cured) created_item = /obj/item/clothing/armor/medium/scale/steppe craftdiff = 3 /datum/anvil_recipe/armor/steel/surcoat name = "Armored Surcoat (+Bar)" - recipe_name = "an Armored Surcoat" additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/clothing/armor/medium/surcoat craftdiff = 3 /datum/anvil_recipe/armor/steel/surcoat/heartfelt name = "Armored Heartfelt Surcoat (+Bar)" - recipe_name = "an Armored Heartfeltian Surcoat" additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/clothing/armor/medium/surcoat/heartfelt craftdiff = 4 @@ -641,117 +547,97 @@ // STEEL NECK ARMOR /datum/anvil_recipe/armor/steel/bevor name = "Bevor" - recipe_name = "a Bevor" created_item = /obj/item/clothing/neck/bevor /datum/anvil_recipe/armor/steel/chaincoif name = "Chain Coif" - recipe_name = "a Chain Coif" created_item = /obj/item/clothing/neck/chaincoif /datum/anvil_recipe/armor/steel/highcolleir name = "High Collier" - recipe_name = "a High Collier" created_item = /obj/item/clothing/neck/highcollier craftdiff = 3 // STEEL HELMETS /datum/anvil_recipe/armor/steel/nasal_helmet name = "x2 Nasal helmet" - recipe_name = "Two nasal helmets" created_item = /obj/item/clothing/head/helmet/nasal craftdiff = 1 - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/armor/steel/gallowglass name = "Gallowglass Helmet" - recipe_name = "Gallowglass Helm" created_item = /obj/item/clothing/head/helmet/gallowglass craftdiff = 1 /datum/anvil_recipe/armor/steel/coppergate name = "Coppergate helmet" - recipe_name = "coppergate helmet" created_item = /obj/item/clothing/head/helmet/coppergate craftdiff = 1 /datum/anvil_recipe/armor/steel/helmetbuc name = "Great Helm" - recipe_name = "a Bucket Helmet" created_item = (/obj/item/clothing/head/helmet/heavy/bucket) /datum/anvil_recipe/armor/steel/helmetkettle name = "x2 Kettle Helmet" - recipe_name = "Two kettle helmets" created_item = /obj/item/clothing/head/helmet/kettle - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/armor/steel/helmetslitkettle name = "Slitted Kettle Helmet" - recipe_name = "a slitted kettle helmets" created_item = /obj/item/clothing/head/helmet/kettle/slit /datum/anvil_recipe/armor/steel/froghelmet name = "Frog Helmet" - recipe_name = "a frog helmet" created_item = (/obj/item/clothing/head/helmet/heavy/frog) /datum/anvil_recipe/armor/steel/helmetsall name = "Sallet" - recipe_name = "a Sallet" created_item = /obj/item/clothing/head/helmet/sallet /datum/anvil_recipe/armor/steel/elven_sallet name = "Elven Guardian Sallet (+Gold bar)" additional_items = list(/obj/item/ingot/gold) - recipe_name = "a Sallet" created_item = /obj/item/clothing/head/helmet/sallet/elven /datum/anvil_recipe/armor/steel/elven_cuirass name = "Elven Guardian Cuirass (+Gold bar)" additional_items = list(/obj/item/ingot/gold) - recipe_name = "a cuirass" created_item = /obj/item/clothing/armor/cuirass/rare/elven /datum/anvil_recipe/armor/steel/helmetsall_zalad name = "Kulah Khud" - recipe_name = "a Zalad Sallet" created_item = /obj/item/clothing/head/helmet/sallet/zalad /datum/anvil_recipe/armor/steel/bascinet name = "Bascinet" - recipe_name = "a bascinet" created_item = /obj/item/clothing/head/helmet/bascinet /datum/anvil_recipe/armor/steel/bascinet/steppe name = "Steppe Bascinet" - recipe_name = "a bascinet" created_item = /obj/item/clothing/head/helmet/bascinet/steppe /datum/anvil_recipe/armor/steel/spangenhelm name = "Spangenhelm" - recipe_name = "a nasal helm with built in eye protection" created_item = /obj/item/clothing/head/helmet/heavy/viking craftdiff = 3 /datum/anvil_recipe/armor/steel/helmetknight name = "Knight's helmet (+Bar)" - recipe_name = "a Knight's Helmet" additional_items = list(/obj/item/ingot/steel) created_item = (/obj/item/clothing/head/helmet/visored/knight) craftdiff = 3 /datum/anvil_recipe/armor/steel/helmetsallv name = "Visored sallet (+Bar)" - recipe_name = "a Visored Sallet" additional_items = list(/obj/item/ingot/steel) created_item = (/obj/item/clothing/head/helmet/visored/sallet) craftdiff = 3 /datum/anvil_recipe/armor/steel/hounskull name = "Hounskull Helmet (+Bar x2)" - recipe_name = "a Hounskull Helmet" additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel) created_item = (/obj/item/clothing/head/helmet/visored/hounskull) craftdiff = 4 @@ -759,21 +645,18 @@ /* /datum/anvil_recipe/armor/steel/warden_helm name = "Warden Helmet (+Bar)" - recipe_name = "a Warden's Helmet" additional_items = list(/obj/item/ingot/steel) created_item = (/obj/item/clothing/head/helmet/visored/warden) craftdiff = 6 /datum/anvil_recipe/armor/steel/royal_knight_helm name = "Royal Knight Helmet (+Bar x2)" - recipe_name = "a royal knight's Helmet" additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel) created_item = (/obj/item/clothing/head/helmet/visored/royalknight) craftdiff = 6 /datum/anvil_recipe/armor/steel/captain_helm name = "Captain's Helmet (+Bar x2)" - recipe_name = "a captain's Helmet" additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel) created_item = (/obj/item/clothing/head/helmet/visored/captain) craftdiff = 6 @@ -782,13 +665,11 @@ // STEEL DECORATED HELMS /datum/anvil_recipe/armor/steel/decoratedbascinet name = "Decorated Bascinet (+Cloth)" - recipe_name = "a decorated bascinet" additional_items = list(/obj/item/natural/cloth) created_item = /obj/item/clothing/head/helmet/heavy/decorated/bascinet /datum/anvil_recipe/armor/steel/decorativecoppergate name = "Decorated Coppergate helmet (+Gold)" - recipe_name = "decorative coppergate helmet" additional_items = list(/obj/item/ingot/gold) created_item = /obj/item/clothing/head/helmet/decorativecoppergate craftdiff = 1 @@ -818,14 +699,12 @@ /datum/anvil_recipe/armor/steel/halfplate_decrorated name = "Decorated Half-plate (+Steel Bar x2, + Gold Bar)" - recipe_name = "a decorated Half-Plate Armor" additional_items = list(/obj/item/ingot/steel,/obj/item/ingot/steel, /obj/item/ingot/gold) created_item = /obj/item/clothing/armor/plate/decorated craftdiff = 4 /datum/anvil_recipe/armor/steel/halfplate_decrorated_corset name = "Decorated Half-plate With Corset (+Steel Bar x2, + Gold Bar, + Silk x3)" - recipe_name = "a decorated Half-Plate Armor with Corset" additional_items = list(/obj/item/ingot/steel,/obj/item/ingot/steel, /obj/item/ingot/gold, /obj/item/natural/silk, /obj/item/natural/silk, /obj/item/natural/silk) created_item = /obj/item/clothing/armor/plate/decorated/corset craftdiff = 4 @@ -833,39 +712,33 @@ // STEEL PLATE ARMOR /datum/anvil_recipe/armor/steel/halfplate name = "Steel Half-plate (+Bar x2)" - recipe_name = "a Half-Plate Armor" additional_items = list(/obj/item/ingot/steel,/obj/item/ingot/steel) created_item = /obj/item/clothing/armor/plate craftdiff = 3 /datum/anvil_recipe/armor/steel/platefull name = "Plate Armor (+Bar x3)" - recipe_name = "a Full-Plate Armor" additional_items = list(/obj/item/ingot/steel,/obj/item/ingot/steel,/obj/item/ingot/steel) created_item = /obj/item/clothing/armor/plate/full craftdiff = 4 /datum/anvil_recipe/armor/steel/platebracer name = "Plate Vambraces" - recipe_name = "Plate Vambraces" created_item = /obj/item/clothing/wrists/bracers craftdiff = 4 /datum/anvil_recipe/armor/steel/plateleg name = "Plate Chausses" - recipe_name = "a pair of Plate Chausses" created_item = /obj/item/clothing/pants/platelegs craftdiff = 4 /datum/anvil_recipe/armor/steel/plateglove name = "Plate Gauntlets" - recipe_name = "a pair of Plate Gauntlets" created_item = /obj/item/clothing/gloves/plate craftdiff = 4 /datum/anvil_recipe/armor/steel/plateboot name = "Plated boots" - recipe_name = "some Plated Boots" created_item = /obj/item/clothing/shoes/boots/armor craftdiff = 4 @@ -876,25 +749,21 @@ /datum/anvil_recipe/armor/steel/steam/helm name = "Steamknight helm (+Bar, +Bronze cog)" - recipe_name = "a steam powered helmet" additional_items = list(/obj/item/ingot/steel, /obj/item/gear/metal/bronze) created_item = /obj/item/clothing/head/helmet/heavy/steam /datum/anvil_recipe/armor/steel/steam/gauntlets name = "Steamknight gauntlets (+Bronze cog)" - recipe_name = "a pair of steam powered gauntlets" additional_items = list(/obj/item/gear/metal/bronze) created_item = /obj/item/clothing/gloves/plate/steam /datum/anvil_recipe/armor/steel/steam/body name = "Steamknight plate (+Bar x2, +Bronze cog x3)" - recipe_name = "a pair of steam powered gauntlets" additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel, /obj/item/gear/metal/bronze, /obj/item/gear/metal/bronze, /obj/item/gear/metal/bronze) created_item = /obj/item/clothing/armor/steam /datum/anvil_recipe/armor/steel/steam/boots name = "Steamknight plate boots (+Bronze cog)" - recipe_name = "a pair of steam powered gauntlets" additional_items = list(/obj/item/gear/metal/bronze) created_item = /obj/item/clothing/shoes/boots/armor/steam */ @@ -980,60 +849,51 @@ /datum/anvil_recipe/armor/steel/captain_plate_pants name = "Captain Plate Chausses (+Bar)" - recipe_name = "a pair of Premium Plate Chausses" additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/clothing/pants/platelegs/captain craftdiff = 6 /datum/anvil_recipe/armor/steel/matthios_plate_pants name = "Matthiosan Plate Chausses (+Bar)" - recipe_name = "a pair of Matthiosan Plate Chausses" additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/clothing/pants/platelegs/matthios craftdiff = 6 /datum/anvil_recipe/armor/steel/graggarite_plate_pants name = "Graggarite Plate Chausses (+Bar)" - recipe_name = "a pair of Graggarite Plate Chausses" additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/clothing/pants/platelegs/graggar craftdiff = 6 /datum/anvil_recipe/armor/steel/matthios_plate name = "Matthiosan Plate Armor (+Bar x3)" - recipe_name = "a Full-Plate matthiosan Armor" additional_items = list(/obj/item/ingot/steel,/obj/item/ingot/steel,/obj/item/ingot/steel) created_item = /obj/item/clothing/armor/plate/full/matthios craftdiff = 6 /datum/anvil_recipe/armor/steel/graggar_plate name = "Graggarite Plate Armor (+Bar x3)" - recipe_name = "a Full-Plate Graggarite Armor" additional_items = list(/obj/item/ingot/steel,/obj/item/ingot/steel,/obj/item/ingot/steel) created_item = /obj/item/clothing/armor/plate/full/graggar craftdiff = 6 /datum/anvil_recipe/armor/steel/matthios_plate_gauntlets name = "Matthiosan Plate Gauntlets" - recipe_name = "a pair of matthiosan Plate gauntlets" created_item = /obj/item/clothing/gloves/plate/matthios craftdiff = 6 /datum/anvil_recipe/armor/steel/graggar_plate_gauntlets name = "Graggarite Plate Gauntlets" - recipe_name = "a pair of graggarite Plate gauntlets" created_item = /obj/item/clothing/gloves/plate/graggar craftdiff = 6 /datum/anvil_recipe/armor/steel/matthios_plate_boots name = "Matthiosan Plate Boots" - recipe_name = "a pair of matthios Plate gauntlets" created_item = /obj/item/clothing/shoes/boots/armor/matthios craftdiff = 6 /datum/anvil_recipe/armor/steel/graggar_plate_boots name = "Graggarite Plate Boots" - recipe_name = "a pair of graggar Plate boots" created_item = /obj/item/clothing/shoes/boots/armor/graggar craftdiff = 6 @@ -1042,7 +902,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////// // --------- SILVER ----------- /datum/anvil_recipe/armor/silver - req_bar = /obj/item/ingot/silver + required_material = /obj/item/ingot/silver craftdiff = 3 // harder to work with. mostly jewelry abstract_type = /datum/anvil_recipe/armor/silver /////////////////////////////////////////////// @@ -1050,39 +910,33 @@ // --------- SILVER ----------- /datum/anvil_recipe/armor/silver/bascinet name = "Silver Bascinet (+Steel Bar x2)" - recipe_name = "a silver bascinet" additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel) created_item = /obj/item/clothing/head/helmet/visored/silver /datum/anvil_recipe/armor/silver/armet name = "Silver Armet (+Steel Bar x2)" - recipe_name = "a silver bascinet" additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel) created_item = /obj/item/clothing/head/helmet/visored/silver/armet /datum/anvil_recipe/armor/silver/plateleg name = "Silver Plate Chausses (+Steel Bar x2)" - recipe_name = "a pair of Silver Plate Chausses" additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel) created_item = /obj/item/clothing/pants/platelegs/silver /datum/anvil_recipe/armor/silver/platefull name = "Silver Plate Armor (+Silver Bar, +Steel Bar x3)" - recipe_name = "a Full-Plate Silver Armor" additional_items = list(/obj/item/ingot/silver, /obj/item/ingot/steel, /obj/item/ingot/steel, /obj/item/ingot/steel) created_item = /obj/item/clothing/armor/plate/full/silver craftdiff = 4 /datum/anvil_recipe/armor/silver/gauntlet name = "Silver Gauntlets" - recipe_name = "a pair of Silver Gauntlets" additional_items = list(/obj/item/ingot/silver) created_item = /obj/item/clothing/gloves/plate/silver craftdiff = 4 /datum/anvil_recipe/armor/silver/boots name = "Silver Boots" - recipe_name = "a pair of Silver Boots" additional_items = list(/obj/item/ingot/silver) created_item = /obj/item/clothing/shoes/boots/armor/silver craftdiff = 4 @@ -1090,7 +944,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////// // --------- GOLD ----------- /datum/anvil_recipe/armor/gold - req_bar = /obj/item/ingot/gold + required_material = /obj/item/ingot/gold craftdiff = 3 // harder to work with. mostly jewelry abstract_type = /datum/anvil_recipe/armor/gold /////////////////////////////////////////////// @@ -1102,7 +956,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////// // --------- BLACKSTEEL ----------- /datum/anvil_recipe/armor/blacksteel - req_bar = /obj/item/ingot/blacksteel + required_material = /obj/item/ingot/blacksteel craftdiff = 4 // this is the good stuff abstract_type = /datum/anvil_recipe/armor/blacksteel /////////////////////////////////////////////// @@ -1241,41 +1095,41 @@ /datum/anvil_recipe/armor/anklets name = "golden anklets" - req_bar = /obj/item/ingot/gold + required_material = /obj/item/ingot/gold created_item = /obj/item/clothing/shoes/anklets craftdiff = 2 /datum/anvil_recipe/armor/holysee_plate name = "holy silver plate" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed additional_items = list(/obj/item/ingot/silverblessed, /obj/item/ingot/silverblessed) created_item = /obj/item/clothing/armor/plate/full/holysee craftdiff = 4 /datum/anvil_recipe/armor/holysee_chausses name = "holy silver chausses" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed additional_items = list(/obj/item/ingot/silverblessed) created_item = /obj/item/clothing/pants/platelegs/holysee craftdiff = 3 /datum/anvil_recipe/armor/holysee_bascinet name = "holy silver bascinet" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed additional_items = list(/obj/item/ingot/silver) created_item = /obj/item/clothing/head/helmet/heavy/holysee craftdiff = 3 /datum/anvil_recipe/armor/naledi_mask name = "war scholar's mask" - req_bar = /obj/item/ingot/gold + required_material = /obj/item/ingot/gold created_item = /obj/item/clothing/face/lordmask/naledi craftdiff = 3 /datum/anvil_recipe/armor/sojourner_mask name = "sojourner's mask" - req_bar = /obj/item/ingot/gold + required_material = /obj/item/ingot/gold additional_items = list(/obj/item/ingot/gold) created_item = /obj/item/clothing/face/lordmask/naledi/sojourner craftdiff = 4 @@ -1283,147 +1137,147 @@ /datum/anvil_recipe/armor/xylixhelm name = "xylixian helmet" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel created_item = /obj/item/clothing/head/helmet/heavy/xylixhelm craftdiff = 3 /datum/anvil_recipe/armor/astratahelm name = "astrata helmet" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel created_item = /obj/item/clothing/head/helmet/heavy/astratahelm craftdiff = 3 /datum/anvil_recipe/armor/nochelm name = "noc helmet" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel created_item = /obj/item/clothing/head/helmet/heavy/nochelm craftdiff = 3 /datum/anvil_recipe/armor/necrahelm name = "necra helmet" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel created_item = /obj/item/clothing/head/helmet/heavy/necrahelm craftdiff = 3 /datum/anvil_recipe/armor/dendorhelm name = "dendor helmet" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel created_item = /obj/item/clothing/head/helmet/heavy/dendorhelm craftdiff = 3 /datum/anvil_recipe/armor/abyssorgreathelm name = "abyssorite helmet" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel created_item = /obj/item/clothing/head/helmet/heavy/abyssorgreathelm craftdiff = 3 /datum/anvil_recipe/armor/ravoxhelm name = "justice eagle" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel created_item = /obj/item/clothing/head/helmet/heavy/ravoxhelm craftdiff = 3 /datum/anvil_recipe/armor/volfplate name = "volf-face helm" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel created_item = /obj/item/clothing/head/helmet/heavy/volfplate craftdiff = 3 /datum/anvil_recipe/armor/volfplate_puritan name = "volfskulle bascinet" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/clothing/head/helmet/heavy/volfplate/puritan craftdiff = 4 /datum/anvil_recipe/armor/atgervi_hauberk name = "vagarian hauberk" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/clothing/armor/chainmail/hauberk/atgervi craftdiff = 3 /datum/anvil_recipe/armor/atgervi_claws name = "beast claws" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel created_item = /obj/item/clothing/gloves/plate/atgervi craftdiff = 3 /datum/anvil_recipe/armor/atgervi_helmet name = "owl helmet" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel created_item = /obj/item/clothing/head/helmet/bascinet/atgervi craftdiff = 3 /datum/anvil_recipe/armor/psydonboots name = "crown of psydonian thorns" - req_bar = /obj/item/ingot/blacksteel + required_material = /obj/item/ingot/blacksteel created_item = /obj/item/clothing/head/helmet/blacksteel/psythorns craftdiff = 3 /datum/anvil_recipe/armor/hauberk name = "fluted hauberk" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel created_item = /obj/item/clothing/armor/chainmail/hauberk/fluted craftdiff = 3 /datum/anvil_recipe/armor/blessedsilver/psychestplate name = "Psydonic Chestplate (+1 Cured Leather)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed additional_items = list(/obj/item/natural/hide/cured) created_item = /obj/item/clothing/armor/cuirass/psydon /datum/anvil_recipe/armor/blessedsilver/psycuirass name = "Psydonic Cuirass (+2 Cured Leather)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed additional_items = list(/obj/item/natural/hide/cured, /obj/item/natural/hide/cured) created_item = /obj/item/clothing/armor/cuirass/ornate /datum/anvil_recipe/armor/blessedsilver/armetpsy name = "Psydonic Armet" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed created_item = /obj/item/clothing/head/helmet/heavy/psydonhelm /datum/anvil_recipe/armor/blessedsilver/helmsallpsy name = "Psydonic Sallet (+1 Blessed Silver)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed created_item = /obj/item/clothing/head/helmet/heavy/psysallet /datum/anvil_recipe/armor/blessedsilver/helmbucketpsy name = "Psydonic Bucket Helm (+1 Blessed Silver)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed created_item = /obj/item/clothing/head/helmet/heavy/psybucket /datum/anvil_recipe/armor/blessedsilver/helmetabso name = "Psydonian Conical Helm (+2 Blessed Silver)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed additional_items = list(/obj/item/ingot/silverblessed, /obj/item/ingot/silverblessed) created_item = /obj/item/clothing/head/helmet/heavy/absolver /datum/anvil_recipe/armor/blessedsilver/psyhalfplate name = "Psydonic Half-Plate (+Psydonic Cuirass, +1 Blessed Silver, +2 Cured Leather)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed additional_items = list(/obj/item/clothing/armor/cuirass/ornate, /obj/item/ingot/silverblessed, /obj/item/natural/hide/cured, /obj/item/natural/hide/cured) created_item = /obj/item/clothing/armor/plate/fluted/ornate /datum/anvil_recipe/armor/blessedsilver/psyfullplate name = "Psydonic Full-Plate (+Psydonic Half-Plate, +1 Blessed Silver, +2 Cured Leather)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed additional_items = list(/obj/item/clothing/armor/plate/fluted/ornate, /obj/item/ingot/silverblessed, /obj/item/natural/hide/cured, /obj/item/natural/hide/cured) created_item = /obj/item/clothing/armor/plate/fluted/ornate /datum/anvil_recipe/armor/blessedsilver/psyfullplatealt name = "Psydonic Full-Plate, Hauberked (+Psydonic Hauberk, +2 Blessed Silver, +2 Cured Leather)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed additional_items = list(/obj/item/clothing/armor/chainmail/hauberk/fluted, /obj/item/ingot/silverblessed, /obj/item/ingot/silverblessed, /obj/item/natural/hide/cured, /obj/item/natural/hide/cured) created_item = /obj/item/clothing/armor/plate/fluted/ornate /datum/anvil_recipe/armor/blessedsilver/psydonmask name = "Psydonic Mask" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed created_item = /obj/item/clothing/face/facemask/psydonmask /datum/anvil_recipe/armor/blessedsilver/psydonic_gloves name = "Psydonic Chain Gloves" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed created_item = /obj/item/clothing/gloves/chain/psydon diff --git a/code/modules/crafting/anvil_recipes/minigame.dm b/code/modules/crafting/anvil_recipes/minigame.dm index bc33c867690..47b9334aea1 100644 --- a/code/modules/crafting/anvil_recipes/minigame.dm +++ b/code/modules/crafting/anvil_recipes/minigame.dm @@ -1,3 +1,6 @@ +#define BASE_NUMBER_NOTES 5 +#define EASY_DIFFICULTY_THRESHOLD 3 + /datum/anvil_challenge var/start_time var/completed = FALSE @@ -8,7 +11,9 @@ var/atom/movable/screen/anvil_hud/anvil_hud var/datum/anvil_recipe/selected_recipe var/obj/machinery/anvil/host_anvil + /// Scale from 1 to 7. Higher difficulty results in faster notes and harder-to-click notes var/difficulty = 1 + /// Scale from 0 to 100 based on accuracy. var/success = 100 var/off_time = 0 var/notes_left = 0 @@ -23,14 +28,12 @@ src.user = user selected_recipe = end_product_recipe - var/user_skill = user.get_skill_level(end_product_recipe.appro_skill) - if(user_skill < end_product_recipe.craftdiff) - difficulty_modifier *= 2 - - difficulty = difficulty_modifier - notes_left = max(5, round(difficulty_modifier * 2)) + var/recipe_difficulty = selected_recipe.craftdiff + difficulty_modifier + notes_left = BASE_NUMBER_NOTES + recipe_difficulty total_notes = notes_left + // If skill level matches recipe difficulty, minigame by default should only contain easy notes + difficulty = clamp(ceil(recipe_difficulty - user.get_skill_level(selected_recipe.appro_skill) + EASY_DIFFICULTY_THRESHOLD + difficulty_modifier), 1, 7) if(isdwarf(user) && difficulty > 1) difficulty-- @@ -98,10 +101,12 @@ var/list/modifiers = params2list(params) var/list/click_list = list() - if(LAZYACCESS(modifiers, RIGHT_CLICK)) - click_list |= RIGHT_CLICK if(LAZYACCESS(modifiers, LEFT_CLICK)) click_list |= LEFT_CLICK + if(LAZYACCESS(modifiers, RIGHT_CLICK)) + click_list |= RIGHT_CLICK + if(LAZYACCESS(modifiers, MIDDLE_CLICK)) + click_list |= MIDDLE_CLICK if(LAZYACCESS(modifiers, ALT_CLICKED)) click_list |= ALT_CLICKED if(LAZYACCESS(modifiers, CTRL_CLICKED)) @@ -115,7 +120,6 @@ if((REALTIMEOFDAY > lower_range) && (REALTIMEOFDAY < upper_range)) anvil_presses -= anvil_presses[choice] user.balloon_alert(user, "Great Hit!") - playsound(host_anvil, pick('sound/items/bsmith1.ogg','sound/items/bsmith2.ogg','sound/items/bsmith3.ogg','sound/items/bsmith4.ogg'), 100, FALSE) // for(var/mob/player as anything in GLOB.player_list) // if(!is_in_zweb(player.z, host_anvil.z)) @@ -128,7 +132,6 @@ // continue // player.playsound_local(player_turf, null, 100, 1, get_rand_frequency(), falloff_exponent = 5, S = far_smith_sound) - else if(REALTIMEOFDAY > anvil_presses[choice] + 0.2 SECONDS + average_ping) off_time += REALTIMEOFDAY - (anvil_presses[choice] + 0.2 SECONDS + average_ping) @@ -142,6 +145,7 @@ anvil_presses -= choice note_pixels_moved -= choice anvil_hud.pop_note(choice, good_hit) + playsound(host_anvil, pick('sound/items/bsmith1.ogg','sound/items/bsmith2.ogg','sound/items/bsmith3.ogg','sound/items/bsmith4.ogg'), 100, FALSE) if(!length(anvil_presses)) if(!notes_left) end_minigame() @@ -178,16 +182,14 @@ host_anvil.smithing = FALSE if(completed) - var/smithlevel = user.get_skill_level(selected_recipe.appro_skill) if(host_anvil.always_perfect) - failed_notes = 0 - off_time = 0 success = 100 + else + // Calculate quality score based on performance + success = min(max(0, round(success - ((100 * (failed_notes / total_notes)) + 1 * (off_time * 2)))), \ + 100) - // Calculate quality score based on performance - success = max(smithlevel * 5, round(success - ((100 * (failed_notes / total_notes)) + 1 * (off_time * 2)) +((smithlevel * 5) - 15))) - - host_anvil.process_minigame_result(success, user, (failed_notes == total_notes)) + host_anvil.process_minigame_result(success, user) host_anvil = null @@ -233,9 +235,10 @@ var/timer /atom/movable/screen/hud_note/proc/generate_click_type(difficulty) - difficulty = min(6, difficulty) + difficulty = min(7, difficulty) switch(rand(1,difficulty)) + // EASY NOTES if(1) click_requirements = list(LEFT_CLICK) icon_state = "note" @@ -243,15 +246,19 @@ click_requirements = list(RIGHT_CLICK) icon_state = "note-right" if(3) + click_requirements = list(MIDDLE_CLICK) + icon_state = "note-middle" + // HARD NOTES + if(4) click_requirements = list(LEFT_CLICK, ALT_CLICKED) icon_state = "note-alt" - if(4) + if(5) click_requirements = list(RIGHT_CLICK, ALT_CLICKED) icon_state = "note-right-alt" - if(5) + if(6) click_requirements = list(LEFT_CLICK, CTRL_CLICKED) icon_state = "note-ctrl" - if(6) + if(7) click_requirements = list(RIGHT_CLICK, CTRL_CLICKED) icon_state = "note-right-ctrl" @@ -265,3 +272,6 @@ if(!length(copied_checks)) return TRUE return FALSE + +#undef BASE_NUMBER_NOTES +#undef EASY_DIFFICULTY_THRESHOLD diff --git a/code/modules/crafting/anvil_recipes/slag.dm b/code/modules/crafting/anvil_recipes/slag.dm index 25d799fe8f9..b8746cb03e1 100644 --- a/code/modules/crafting/anvil_recipes/slag.dm +++ b/code/modules/crafting/anvil_recipes/slag.dm @@ -1,12 +1,15 @@ /datum/anvil_recipe/slag appro_skill = /datum/skill/craft/blacksmithing - i_type = "Slag" abstract_type = /datum/anvil_recipe/slag category = "Slag" +/datum/anvil_recipe/slag/handle_creation(obj/item/recipe_output, obj/item/initial_material) + var/average_performance = accumulated_quality / numberofhits + if(average_performance >= 40) // Did you even try? + recipe_output.set_quality(initial_material.recipe_quality) + /datum/anvil_recipe/slag/steel name = "Steel Ingot" - recipe_name = "a steel ingot" - req_bar = /obj/item/ingot/steel_slag + required_material = /obj/item/ingot/steel_slag created_item = /obj/item/ingot/steel craftdiff = 2 diff --git a/code/modules/crafting/anvil_recipes/tools.dm b/code/modules/crafting/anvil_recipes/tools.dm index 39111a4dcf6..33418f56294 100644 --- a/code/modules/crafting/anvil_recipes/tools.dm +++ b/code/modules/crafting/anvil_recipes/tools.dm @@ -1,5 +1,4 @@ /datum/anvil_recipe/tools - i_type = "Utilities" abstract_type = /datum/anvil_recipe/tools appro_skill = /datum/skill/craft/blacksmithing // already in parent just in here so people know category = "Tools" @@ -8,65 +7,59 @@ /datum/anvil_recipe/tools/tin craftdiff = 0 // for starters - req_bar = /obj/item/ingot/tin + required_material = /obj/item/ingot/tin abstract_type = /datum/anvil_recipe/tools/tin /////////////////////////////////////////////// /datum/anvil_recipe/tools/tin/platter - name = "2x Platters (tin)" + name = "Platters (tin)" created_item = /obj/item/plate/pewter - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/tools/tin/spoon - name = "2x Spoons (tin)" + name = "Spoons (tin)" created_item = /obj/item/kitchen/spoon/pewter - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/tools/tin/fork - name = "2x Forks (tin)" + name = "Forks (tin)" created_item = /obj/item/kitchen/fork/pewter - createditem_extra = 1 + output_amount = 2 // --------- COPPER ----------- /datum/anvil_recipe/tools/copper craftdiff = 0 // for starters - req_bar = /obj/item/ingot/copper + required_material = /obj/item/ingot/copper abstract_type = /datum/anvil_recipe/tools/copper /////////////////////////////////////////////// /datum/anvil_recipe/tools/copper/hoe name = "Copper Hoe (+Stick x2)" - recipe_name = "a gardening Hoe" additional_items = list(/obj/item/grown/log/tree/stick,/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/hoe/copper /datum/anvil_recipe/tools/copper/sickle name = "Copper Sickle (+Stick)" - recipe_name = "a Sickle" additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/sickle/copper /datum/anvil_recipe/tools/copper/pitchfork name = "Copper Pitchfork (+Stick x2)" - recipe_name = "a Pitchfork" additional_items = list(/obj/item/grown/log/tree/stick,/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/pitchfork/copper /datum/anvil_recipe/tools/copper/pick name = "Copper Pick (+Stick)" - recipe_name = "a digging Pick" additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/pick/copper /datum/anvil_recipe/tools/copper/lamptern name = "Copper Lamptern" - recipe_name = "a Lamptern" created_item = /obj/item/flashlight/flare/torch/lantern/copper /datum/anvil_recipe/tools/copper/hammer name = "Copper Hammer (+Stick)" - recipe_name = "a blacksmithing Hammer" additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/hammer/copper @@ -75,16 +68,15 @@ created_item = /obj/item/reagent_containers/glass/bucket/pot/copper /datum/anvil_recipe/tools/copper/platter - name = "2x Platters (copper)" - recipe_name = "a platter" + name = "Platters (copper)" created_item = /obj/item/plate/copper - createditem_extra = 1 + output_amount = 2 // --------- BRONZE ----------- /datum/anvil_recipe/tools/bronze craftdiff = 1 - req_bar = /obj/item/ingot/bronze + required_material = /obj/item/ingot/bronze abstract_type = /datum/anvil_recipe/tools/bronze /////////////////////////////////////////////// @@ -93,158 +85,136 @@ created_item = /obj/item/weapon/chisel/bronze /datum/anvil_recipe/tools/bronze/cogbronze - name = "3x Bronze Cog" - recipe_name = "three Cogs" + name = "Bronze Cog" appro_skill = /datum/skill/craft/engineering // To train engineering created_item = /obj/item/gear/metal/bronze craftdiff = 1 - createditem_extra = 2 + output_amount = 3 // --------- IRON ----------- /datum/anvil_recipe/tools/iron craftdiff = 1 - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron abstract_type = /datum/anvil_recipe/tools/iron /////////////////////////////////////////////// /datum/anvil_recipe/tools/iron/syringe name = "Infusion Syringe" - recipe_name = "infusion syringe" created_item = /obj/item/reagent_containers/syringe /datum/anvil_recipe/tools/iron/keyring - name = "3x Keyrings" - recipe_name = "three Keyrings" + name = "Keyrings" created_item = /obj/item/storage/keyring - createditem_extra = 2 + output_amount = 3 craftdiff = 0 /datum/anvil_recipe/tools/iron/locks - name = "3x Custom Locks" - recipe_name = "three Locks" + name = "Custom Locks" appro_skill = /datum/skill/craft/engineering // To train engineering created_item = /obj/item/customlock - createditem_extra = 2 + output_amount = 3 craftdiff = 0 /datum/anvil_recipe/tools/iron/lockpicks - name = "3x Lockpicks" - recipe_name = "three Lockpicks" + name = "Lockpicks" created_item = /obj/item/lockpick - createditem_extra = 2 + output_amount = 3 craftdiff = 1 /datum/anvil_recipe/tools/iron/lockpickring - name = "3x Lockpickrings" - recipe_name = "three Lockpickrings" + name = "Lockpickrings" created_item = /obj/item/lockpickring - createditem_extra = 2 + output_amount = 3 craftdiff = 0 /datum/anvil_recipe/tools/iron/blankeys - name = "3x Blank Custom Keys" - recipe_name = "three Blank Keys" + name = "Blank Custom Keys" appro_skill = /datum/skill/craft/engineering // To train engineering created_item = /obj/item/key/custom - createditem_extra = 2 + output_amount = 3 craftdiff = 0 /datum/anvil_recipe/tools/iron/chains - name = "3x Chains" - recipe_name = "three lengths of Chain" + name = "Chains" created_item = /obj/item/rope/chain - createditem_extra = 2 + output_amount = 3 craftdiff = 0 /datum/anvil_recipe/tools/iron/lamptern name = "Iron Lamptern" - recipe_name = "a Lamptern" created_item = /obj/item/flashlight/flare/torch/lantern /datum/anvil_recipe/tools/iron/cogiron - name = "2x Iron Cog" - recipe_name = "two Cogs" + name = "Iron Cog" appro_skill = /datum/skill/craft/engineering // To train engineering created_item = /obj/item/gear/metal/iron craftdiff = 1 - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/tools/iron/hammer name = "Hammer (+Stick)" - recipe_name = "a blacksmithing Hammer" additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/hammer/iron /datum/anvil_recipe/tools/iron/hoe name = "Hoe (+Stick x2)" - recipe_name = "a gardening Hoe" additional_items = list(/obj/item/grown/log/tree/stick,/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/hoe /datum/anvil_recipe/tools/iron/mantrap name = "Mantrap" - recipe_name = "a mantrap" created_item = /obj/item/restraints/legcuffs/beartrap/crafted /datum/anvil_recipe/tools/iron/fishinghooks - name = "3x Fishing hooks" + name = "Fishing hooks" created_item = /obj/item/fishing/hook/iron - createditem_extra = 2 + output_amount = 3 craftdiff = 0 /datum/anvil_recipe/tools/iron/pick name = "Pick (+Stick)" - recipe_name = "a digging Pick" additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/pick /datum/anvil_recipe/tools/iron/pitchfork name = "Pitchfork (+Stick x2)" - recipe_name = "a Pitchfork" additional_items = list(/obj/item/grown/log/tree/stick,/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/pitchfork /datum/anvil_recipe/tools/iron/sewingneedle - name = "3x Sewing Needles" - recipe_name = "three Sewing Needles" + name = "Sewing Needles" created_item = /obj/item/needle - createditem_extra = 2 // They can be refilled with fiber now + output_amount = 3 // They can be refilled with fiber now /datum/anvil_recipe/tools/iron/shovel name = "Shovel (+Stick x2)" - recipe_name = "a Shovel" additional_items = list(/obj/item/grown/log/tree/stick,/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/shovel /datum/anvil_recipe/tools/iron/sickle name = "Sickle (+Stick)" - recipe_name = "a Sickle" additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/sickle /datum/anvil_recipe/tools/iron/tongs name = "Tongs" - recipe_name = "a pair of Tongs" created_item = /obj/item/weapon/tongs /datum/anvil_recipe/tools/iron/torch - name = "5x Iron Torches (+Coal)" - recipe_name = "five Torches" + name = "Iron Torches (+Coal)" additional_items = list(/obj/item/ore/coal) created_item = /obj/item/flashlight/flare/torch/metal - createditem_extra = 4 + output_amount = 5 craftdiff = 0 /datum/anvil_recipe/tools/iron/pote name = "Cooking pot (iron)" - recipe_name = "a cooking pot" created_item = /obj/item/reagent_containers/glass/bucket/pot craftdiff = 1 /datum/anvil_recipe/tools/iron/headhook name = "Iron Headhook (+Fibers x2)" - recipe_name = "An iron headhook" additional_items = list(/obj/item/natural/fibers = 2) created_item = /obj/item/storage/hip/headhook craftdiff = 3 @@ -254,29 +224,25 @@ created_item = /obj/item/weapon/chisel/iron /datum/anvil_recipe/tools/iron/spoon - name = "2x Spoons (iron)" - recipe_name = "a Spoon" + name = "Spoons (iron)" created_item = /obj/item/kitchen/spoon/iron - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/tools/iron/fork - name = "2x Forks (iron)" - recipe_name = "a Fork" + name = "Forks (iron)" created_item = /obj/item/kitchen/fork/iron - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/tools/iron/cups - name = "3x Metal Cups" - recipe_name = "three drinking Cups" + name = "Metal Cups" created_item = /obj/item/reagent_containers/glass/cup - createditem_extra = 2 + output_amount = 3 craftdiff = 0 /datum/anvil_recipe/tools/iron/dice_cups - name = "3x Metal Dice Cups" - recipe_name = "three Dice Cups" + name = "Metal Dice Cups" created_item = /obj/item/dice_cup - createditem_extra = 2 + output_amount = 3 craftdiff = 0 /datum/anvil_recipe/tools/iron/scissors @@ -285,7 +251,6 @@ /datum/anvil_recipe/tools/iron/frypan name = "Pan" - recipe_name = "a Frypan" created_item = /obj/item/cooking/pan craftdiff = 0 @@ -298,17 +263,16 @@ /datum/anvil_recipe/tools/steel craftdiff = 2 - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel abstract_type = /datum/anvil_recipe/tools/steel /////////////////////////////////////////////// /datum/anvil_recipe/tools/steel/cogstee - name = "3x Steel Cogs" - recipe_name = "three Cogs" + name = "Steel Cogs" appro_skill = /datum/skill/craft/engineering // To train engineering created_item = /obj/item/gear/metal/steel craftdiff = 1 - createditem_extra = 2 + output_amount = 3 /datum/anvil_recipe/tools/steel/scissors name = "Steel Scissors" @@ -316,20 +280,17 @@ /datum/anvil_recipe/tools/steel/pick name = "Steel Pick (+Stick)" - recipe_name = "a digging Pick" additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/pick/steel /datum/anvil_recipe/tools/steel/gobletsteel - name = "3x Goblets" - recipe_name = "three Goblets" + name = "Goblets" created_item = /obj/item/reagent_containers/glass/cup/steel - createditem_extra = 2 + output_amount = 3 craftdiff = 1 /datum/anvil_recipe/tools/steel/chisel name = "Steel Chisel" - recipe_name = "a Chisel" created_item = /obj/item/weapon/chisel craftdiff = 1 @@ -337,31 +298,29 @@ /datum/anvil_recipe/tools/silver craftdiff = 3 - req_bar = /obj/item/ingot/silver + required_material = /obj/item/ingot/silver abstract_type = /datum/anvil_recipe/tools/silver /////////////////////////////////////////////// /datum/anvil_recipe/tools/silver/gobletsilver - name = "3x Silver Goblets" - recipe_name = "three Goblets" + name = "Silver Goblets" created_item = /obj/item/reagent_containers/glass/cup/silver - createditem_extra = 2 + output_amount = 3 craftdiff = 2 /datum/anvil_recipe/tools/silver/carafesilver name = "Silver Carafe" - recipe_name = "Silver Carafe" created_item = /obj/item/reagent_containers/glass/carafe/silver /datum/anvil_recipe/tools/silver/platter - name = "2x Platters (silver)" + name = "Platters (silver)" created_item = /obj/item/plate/silver craftdiff = 2 /datum/anvil_recipe/tools/silver/servantbell name = "x3 Service Bells" created_item = /obj/item/servant_bell - createditem_extra = 2 + output_amount = 3 craftdiff = 3 @@ -369,23 +328,21 @@ /datum/anvil_recipe/tools/gold craftdiff = 3 - req_bar = /obj/item/ingot/gold + required_material = /obj/item/ingot/gold abstract_type = /datum/anvil_recipe/tools/gold /////////////////////////////////////////////// /datum/anvil_recipe/tools/gold/gobletgold - name = "3x Golden Goblets" - recipe_name = "three Goblets" + name = "Golden Goblets" created_item = /obj/item/reagent_containers/glass/cup/golden - createditem_extra = 2 + output_amount = 3 craftdiff = 2 /datum/anvil_recipe/tools/gold/carafegold name = "Golden Carafe" - recipe_name = "Golden Carafe" created_item = /obj/item/reagent_containers/glass/carafe/gold /datum/anvil_recipe/tools/gold/platter - name = "2x Platters (gold)" + name = "Platters (gold)" created_item = /obj/item/plate/gold craftdiff = 2 diff --git a/code/modules/crafting/anvil_recipes/valuables.dm b/code/modules/crafting/anvil_recipes/valuables.dm index 8d8fc4ca60a..cfe9cabd100 100644 --- a/code/modules/crafting/anvil_recipes/valuables.dm +++ b/code/modules/crafting/anvil_recipes/valuables.dm @@ -1,6 +1,5 @@ /datum/anvil_recipe/valuables appro_skill = /datum/skill/craft/blacksmithing - i_type = "Valuables" abstract_type = /datum/anvil_recipe/valuables category = "Valuables" @@ -8,27 +7,24 @@ /datum/anvil_recipe/valuables/gold_mask name = "Golden Half Mask" - recipe_name = "a golden half mask" - req_bar = /obj/item/ingot/gold + required_material = /obj/item/ingot/gold created_item = /obj/item/clothing/face/lordmask craftdiff = 2 /datum/anvil_recipe/valuables/gold_mask_left name = "Golden Half Mask (Left)" - recipe_name = "a golden half mask" - req_bar = /obj/item/ingot/gold + required_material = /obj/item/ingot/gold created_item = /obj/item/clothing/face/lordmask/l craftdiff = 2 /datum/anvil_recipe/valuables/iron - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron abstract_type = /datum/anvil_recipe/valuables/iron craftdiff = 1 /////////////////////////////////////////////// /datum/anvil_recipe/valuables/iron/statue name = "Iron Statue" - recipe_name = "a Statue" created_item = /obj/item/statue/iron // --------- STEEL ----------- @@ -36,487 +32,411 @@ /datum/anvil_recipe/valuables/rontzs name = "Silver Face Mask" - recipe_name = "a silver face mask" - req_bar = /obj/item/ingot/silver + required_material = /obj/item/ingot/silver created_item = /obj/item/clothing/face/facemask/silver craftdiff = 2 /datum/anvil_recipe/valuables/steel abstract_type = /datum/anvil_recipe/valuables/steel - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel craftdiff = 2 /////////////////////////////////////////////// /datum/anvil_recipe/valuables/steel/statue name = "Steel Statue" - recipe_name = "a Statue" created_item = /obj/item/statue/steel // --------- SILVER ----------- /datum/anvil_recipe/valuables/silver abstract_type = /datum/anvil_recipe/valuables/silver - req_bar = /obj/item/ingot/silver + required_material = /obj/item/ingot/silver craftdiff = 3 /////////////////////////////////////////////// /datum/anvil_recipe/valuables/silver/statue name = "Silver Statue" - recipe_name = "a Statue" created_item = /obj/item/statue/silver /datum/anvil_recipe/valuables/silver/volf name = "Silver Volf Bust (+Silver Bar)" - recipe_name = "a Silver Volf Bust" additional_items = list(/obj/item/ingot/silver) created_item = /obj/item/statue/silver/volf /datum/anvil_recipe/valuables/silver/urn name = "Silver Urn (+Silver Bar)" - recipe_name = "a Silver Urn" additional_items = list(/obj/item/ingot/silver) created_item = /obj/item/statue/silver/urn /datum/anvil_recipe/valuables/silver/vasefancy name = "Fancy Silver Vase (+Silver Bar)" - recipe_name = "a Fancy Silver Vase" additional_items = list(/obj/item/ingot/silver) created_item = /obj/item/statue/silver/vasefancy /datum/anvil_recipe/valuables/silver/finger name = "Silver Middle Finger (+2 Silver Bar)" - recipe_name = "a Silver Middle Finger " additional_items = list(/obj/item/ingot/silver/, /obj/item/ingot/silver) created_item = /obj/item/statue/silver/finger /datum/anvil_recipe/valuables/silver/bust name = "Silver Bust" - recipe_name = "a Silver Bust" created_item = /obj/item/statue/silver/bust /datum/anvil_recipe/valuables/silver/vase name = "Silver Vase" - recipe_name = "a Silver Vase" created_item = /obj/item/statue/silver/vase /datum/anvil_recipe/valuables/silver/totem name = "Silver Totem" - recipe_name = "a Silver Totem" created_item = /obj/item/statue/silver/totem /datum/anvil_recipe/valuables/silver/teapot name = "Silver Teapot" - recipe_name = "a Silver Teapot" created_item = /obj/item/reagent_containers/glass/carafe/teapot/silver /datum/anvil_recipe/valuables/silver/obelisk name = "Silver Obelisk" - recipe_name = "a Silver Obelisk" created_item = /obj/item/statue/silver/obelisk /datum/anvil_recipe/valuables/silver/tablet name = "Silver Tablet" - recipe_name = "a Silver Tablet" created_item = /obj/item/statue/silver/tablet /datum/anvil_recipe/valuables/silver/comb - name = "2x Silver Combs" - recipe_name = "two Silver Combs" + name = "Silver Combs" created_item = /obj/item/statue/silver/comb - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/silver/figurine - name = "2x Silver Figurines" - recipe_name = "two Silver Figurines" + name = "Silver Figurines" created_item = /obj/item/statue/silver/figurine - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/silver/cameo - name = "2x Silver Cameo's" - recipe_name = "two Silver Cameo's" + name = "Silver Cameo's" created_item = /obj/item/statue/silver/cameo - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/silver/fish - name = "2x Silver Fish" - recipe_name = "two Silver Fish" + name = "Silver Fish" created_item = /obj/item/statue/silver/fish - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/silver/rings - name = "3x Silver Rings" - recipe_name = "three Rings" + name = "Silver Rings" created_item = /obj/item/clothing/ring/silver - createditem_extra = 2 + output_amount = 3 /datum/anvil_recipe/valuables/silver/diadem name = "Silver Diadem" - recipe_name = "a Silver Diadem" created_item = /obj/item/clothing/head/crown/circlet/silverdiadem /datum/anvil_recipe/valuables/silver/nosechain - name = "2x Silver Nosechain's" - recipe_name = "two Silver Nosechains" + name = "Silver Nosechain's" created_item = /obj/item/clothing/face/facemask/silvernosechain - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/silver/faceveil name = "Silver Face Veil" - recipe_name = "a Silver Veil" created_item = /obj/item/clothing/face/facemask/silverveil /datum/anvil_recipe/valuables/silver/headdress name = "Ziliquae Headdress" - recipe_name = "a Ziliquae Headdress" created_item = /obj/item/clothing/head/crown/circlet/silverheaddress /datum/anvil_recipe/valuables/silver/sbracelet - name = "2x Silver Bracelets" - recipe_name = "two Silver Bracelets" + name = "Silver Bracelets" created_item = /obj/item/clothing/wrists/silverbracelet - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/silver/amulet - name = "2x Silver Amulets" - recipe_name = "two Silver Amulets" + name = "Silver Amulets" created_item = /obj/item/clothing/neck/silveramulet - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/silver/dorpels name = "Silver Dorpel Ring" - recipe_name = "a Silver Dorpel Ring" additional_items = list(/obj/item/gem/diamond) created_item = /obj/item/clothing/ring/silver/dorpel craftdiff = 4 /datum/anvil_recipe/valuables/silver/blortzs name = "Silver Blortz Ring" - recipe_name = "a Silver Blortz Ring" additional_items = list(/obj/item/gem/blue) created_item = /obj/item/clothing/ring/silver/blortz craftdiff = 4 /datum/anvil_recipe/valuables/silver/saffiras name = "Silver Saffira Ring" - recipe_name = "a Silver Saffira Ring" additional_items = list(/obj/item/gem/violet) created_item = /obj/item/clothing/ring/silver/saffira craftdiff = 4 /datum/anvil_recipe/valuables/silver/gemeralds name = "Silver Gemerald Ring" - recipe_name = "a Silver Gemerald Ring" additional_items = list(/obj/item/gem/green) created_item = /obj/item/clothing/ring/silver/gemerald craftdiff = 4 /datum/anvil_recipe/valuables/silver/topers name = "Silver Toper Ring" - recipe_name = "a Silver Toper Ring" additional_items = list(/obj/item/gem/yellow) created_item = /obj/item/clothing/ring/silver/toper craftdiff = 4 /datum/anvil_recipe/valuables/silver/rontzs name = "Silver Rontz Ring" - recipe_name = "a Silver Rontz Ring" additional_items = list(/obj/item/gem/red) created_item = /obj/item/clothing/ring/silver/rontz craftdiff = 4 /datum/anvil_recipe/valuables/silver/maker_ring name = "Maker's guild ring" - recipe_name = "a silver maker's guild ring" created_item = /obj/item/clothing/ring/silver/makers_guild craftdiff = 6 // --------- GOLD ----------- /datum/anvil_recipe/valuables/gold - req_bar = /obj/item/ingot/gold + required_material = /obj/item/ingot/gold abstract_type = /datum/anvil_recipe/valuables/gold craftdiff = 4 ////////////////////////////////////////////// /datum/anvil_recipe/valuables/gold/statue name = "Golden Statue" - recipe_name = "a Statue" created_item = /obj/item/statue/gold /datum/anvil_recipe/valuables/gold/bust name = "Golden Bust" - recipe_name = "a Golden Bust" created_item = /obj/item/statue/gold/bust /datum/anvil_recipe/valuables/gold/finger name = "Golden Middle Finger (2+ Gold Bars)" - recipe_name = "a Golden Middle Finger" additional_items = list(/obj/item/ingot/gold/, /obj/item/ingot/gold) created_item = /obj/item/statue/gold/finger /datum/anvil_recipe/valuables/gold/volf name = "Golden Volf Bust (+ Gold Bar)" - recipe_name = "a Golden Volf Bust" additional_items = list(/obj/item/ingot/gold) created_item = /obj/item/statue/gold/volf /datum/anvil_recipe/valuables/gold/urn name = "Gold Urn (+ Gold Bar)" - recipe_name = "a Golden Urn" additional_items = list(/obj/item/ingot/gold) created_item = /obj/item/statue/gold/urn /datum/anvil_recipe/valuables/gold/vasefancy name = "Fancy Gold Vase (+ Gold Bar)" - recipe_name = "a Fancy Golden Vase" additional_items = list(/obj/item/ingot/gold) created_item = /obj/item/statue/gold/vasefancy /datum/anvil_recipe/valuables/gold/vase name = "Gold Vase" - recipe_name = "a Golden Vase" created_item = /obj/item/statue/gold/vase /datum/anvil_recipe/valuables/gold/obelisk name = "Gold Obelisk" - recipe_name = "a Golden Obelisk" created_item = /obj/item/statue/gold/obelisk /datum/anvil_recipe/valuables/gold/totem name = "Gold Totem" - recipe_name = "a Golden Totem" created_item = /obj/item/statue/gold/totem /datum/anvil_recipe/valuables/gold/teapot name = "Golden Teapot" - recipe_name = "a Golden Teapot" created_item = /obj/item/reagent_containers/glass/carafe/teapot/gold /datum/anvil_recipe/valuables/gold/tablet name = "Golden Tablet" - recipe_name = "a Golden Tablet" created_item = /obj/item/statue/gold/tablet /datum/anvil_recipe/valuables/gold/cameo - name = "2x Golden Cameos" - recipe_name = "two Gold Cameos" + name = "Golden Cameos" created_item = /obj/item/statue/gold/cameo - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/gold/comb - name = "2x Gold Combs" - recipe_name = "two Gold Combs" + name = "Gold Combs" created_item = /obj/item/statue/gold/comb - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/gold/figurine - name = "2x Gold Figurines" - recipe_name = "two Gold Figurines" + name = "Gold Figurines" created_item = /obj/item/statue/gold/figurine - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/gold/bracelet - name = "2x Gold Bracelets" - recipe_name = "two Gold Bracelets" + name = "Gold Bracelets" created_item = /obj/item/clothing/wrists/goldbracelet - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/gold/amulet - name = "2x Gold Amulets" - recipe_name = "two Gold Amulets" + name = "Gold Amulets" created_item = /obj/item/clothing/neck/goldamulet - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/gold/fish - name = "2x Golden Fish Figurines" - recipe_name = "two Gold Fish Figurines" + name = "Golden Fish Figurines" created_item = /obj/item/statue/gold/fish - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/gold/circulet name = "Golden Circlet" - recipe_name = "a golden circlet" created_item = /obj/item/clothing/head/crown/circlet /datum/anvil_recipe/valuables/gold/rings - name = "3x Gold Rings" - recipe_name = "three Rings" // For the Elven kings under the sky... + name = "Gold Rings" created_item = /obj/item/clothing/ring/gold - createditem_extra = 2 + output_amount = 3 /datum/anvil_recipe/valuables/gold/diadem name = "Gold Diadem" - recipe_name = "a Gold Diadem" created_item = /obj/item/clothing/head/crown/circlet/golddiadem /datum/anvil_recipe/valuables/gold/nosechain - name = "2x Gold Nosechain's" - recipe_name = "two Silver Nosechains" + name = "Gold Nosechain's" created_item = /obj/item/clothing/face/facemask/goldnosechain - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/gold/faceveil name = "Golden Face Veil" - recipe_name = "a Golden Veil" created_item = /obj/item/clothing/face/facemask/goldveil /datum/anvil_recipe/valuables/gold/headdress name = "Zenarii Headdress" - recipe_name = "a Zenarii Headdress" created_item = /obj/item/clothing/head/crown/circlet/goldheaddress /datum/anvil_recipe/valuables/gold/dorpel name = "Golden Dorpel Ring" - recipe_name = "a Golden Dorpel Ring" additional_items = list(/obj/item/gem/diamond) created_item = /obj/item/clothing/ring/gold/dorpel craftdiff = 5 /datum/anvil_recipe/valuables/gold/blortz name = "Golden Blortz Ring" - recipe_name = "a Golden Blortz Ring" additional_items = list(/obj/item/gem/blue) created_item = /obj/item/clothing/ring/gold/blortz craftdiff = 5 /datum/anvil_recipe/valuables/gold/saffira name = "Golden Saffira Ring" - recipe_name = "a Golden Saffira Ring" additional_items = list(/obj/item/gem/violet) created_item = /obj/item/clothing/ring/gold/saffira craftdiff = 5 /datum/anvil_recipe/valuables/gold/gemerald name = "Golden Gemerald Ring" - recipe_name = "a Golden Gemerald Ring" additional_items = list(/obj/item/gem/green) created_item = /obj/item/clothing/ring/gold/gemerald craftdiff = 5 /datum/anvil_recipe/valuables/gold/toper name = "Golden Toper Ring" - recipe_name = "a Golden Toper Ring" additional_items = list(/obj/item/gem/yellow) created_item = /obj/item/clothing/ring/gold/toper craftdiff = 5 /datum/anvil_recipe/valuables/gold/rontz name = "Golden Rontz Ring" - recipe_name = "a Golden Rontz Ring" additional_items = list(/obj/item/gem/red) created_item = /obj/item/clothing/ring/gold/rontz craftdiff = 5 /datum/anvil_recipe/valuables/gold/mercator_ring name = "Golden Mercator Ring" - recipe_name = "a Golden Mercator Ring" created_item = /obj/item/clothing/ring/gold/guild_mercator craftdiff = 6 /datum/anvil_recipe/valuables/gold/sparrow_crown name = "Champion's circlet" - recipe_name = "worthy of a champion" created_item = /obj/item/clothing/head/crown/sparrowcrown craftdiff = 6 /datum/anvil_recipe/valuables/signet name = "Signet Ring" - req_bar = /obj/item/ingot/gold + required_material = /obj/item/ingot/gold craftdiff = SKILL_LEVEL_EXPERT created_item = /obj/item/clothing/ring/signet /datum/anvil_recipe/valuables/signet/silver name = "Blessed Silver Signet Ring" craftdiff = SKILL_LEVEL_MASTER - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed created_item = /obj/item/clothing/ring/signet/silver /datum/anvil_recipe/valuables/signet/silver/inq name = "Blessed Silver Signet Ring" craftdiff = SKILL_LEVEL_MASTER - req_bar = /obj/item/ingot/silverblessed/bullion + required_material = /obj/item/ingot/silverblessed/bullion created_item = /obj/item/clothing/ring/signet/silver // --------- BRONZE ----------- /datum/anvil_recipe/valuables/bronze - req_bar = /obj/item/ingot/bronze + required_material = /obj/item/ingot/bronze abstract_type = /datum/anvil_recipe/valuables/bronze craftdiff = 1 ////////////////////////////////////////////// /datum/anvil_recipe/valuables/bronze/statue name = "Bronze Statue" - recipe_name = "a Bronze Statue" created_item = /obj/item/statue/bronze /datum/anvil_recipe/valuables/bronze/bust name = "Bronze Bust" - recipe_name = "a Bronze Bust" created_item = /obj/item/statue/bronze/bust /datum/anvil_recipe/valuables/bronze/volf name = "Bronze Volf Bust (+ Bronze Bar)" - recipe_name = "a Bronze Volf Bust" additional_items = list(/obj/item/ingot/bronze) created_item = /obj/item/statue/bronze/volf /datum/anvil_recipe/valuables/bronze/urn name = "Bronze Urn (+ Bronze Bar)" - recipe_name = "a Bronze Urn" additional_items = list(/obj/item/ingot/bronze) created_item = /obj/item/statue/bronze/urn /datum/anvil_recipe/valuables/bronze/vasefancy name = "Fancy Bronze Vase (+ Bronze Bar)" - recipe_name = "a Fancy Bronze Vase" additional_items = list(/obj/item/ingot/bronze) created_item = /obj/item/statue/bronze/vasefancy /datum/anvil_recipe/valuables/bronze/vase name = "Bronze Vase" - recipe_name = "a Bronze Vase" created_item = /obj/item/statue/bronze/vase /datum/anvil_recipe/valuables/bronze/obelisk name = "Bronze Obelisk" - recipe_name = "a Bronze Obelisk" created_item = /obj/item/statue/bronze/obelisk /datum/anvil_recipe/valuables/bronze/totem name = "Bronze Totem" - recipe_name = "a Bronze Totem" created_item = /obj/item/statue/bronze/totem /datum/anvil_recipe/valuables/bronze/teapot name = "Bronze Teapot" - recipe_name = "a Bronze Teapot" created_item = /obj/item/reagent_containers/glass/carafe/teapot/bronze /datum/anvil_recipe/valuables/bronze/tablet name = "Bronze Tablet" - recipe_name = "a Bronze Tablet" created_item = /obj/item/statue/bronze/tablet /datum/anvil_recipe/valuables/bronze/cameo - name = "2x Bronze Cameos" - recipe_name = "two Bronze Cameos" + name = "Bronze Cameos" created_item = /obj/item/statue/bronze/cameo - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/bronze/comb - name = "2x Bronze Combs" - recipe_name = "two Bronze Combs" + name = "Bronze Combs" created_item = /obj/item/statue/bronze/comb - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/bronze/figurine - name = "2x Bronze Figurines" - recipe_name = "two Bronze Figurines" + name = "Bronze Figurines" created_item = /obj/item/statue/bronze/figurine - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/valuables/bronze/fish - name = "2x Bronze Fish Figurines" - recipe_name = "two bronze Fish Figurines" + name = "Bronze Fish Figurines" created_item = /obj/item/statue/bronze/fish - createditem_extra = 1 + output_amount = 2 diff --git a/code/modules/crafting/anvil_recipes/weapons.dm b/code/modules/crafting/anvil_recipes/weapons.dm index 69e54e603a7..a8731e8fcef 100644 --- a/code/modules/crafting/anvil_recipes/weapons.dm +++ b/code/modules/crafting/anvil_recipes/weapons.dm @@ -1,6 +1,5 @@ /datum/anvil_recipe/weapons appro_skill = /datum/skill/craft/weaponsmithing - i_type = "Weapons" abstract_type = /datum/anvil_recipe/weapons category = "Weapons" @@ -10,80 +9,72 @@ //honestly the only tin "weapon" that comes to mind would be lead bullets /datum/anvil_recipe/weapons/tin abstract_type = /datum/anvil_recipe/weapons/tin - req_bar = /obj/item/ingot/tin + required_material = /obj/item/ingot/tin craftdiff = 0 //////////////////////////////////// /datum/anvil_recipe/weapons/tin/lead_bullet //guys how are you making LEAD bullets out of TIN? - name = "4x Lead Bullets" - recipe_name = "a handful of lead bullets." + name = "Lead Bullets" created_item = /obj/item/ammo_casing/caseless/bullet craftdiff = 1 - createditem_extra = 3 + output_amount = 4 /datum/anvil_recipe/weapons/tin/grenade_shell - name = "2x Grenade shells" - recipe_name = "Grenade Casings" + name = "Grenade shells" created_item = /obj/item/ammo_casing/caseless/grenadeshell craftdiff = 3 - createditem_extra = 1 + output_amount = 2 ///jokes on you whoever said lead bullets were the only tin weapon, may I introduce the pipe casing. ////////////////////////////////////////////////////////////////////////////////////////////// // --------- COPPER ----------- /datum/anvil_recipe/weapons/copper abstract_type = /datum/anvil_recipe/weapons/copper - req_bar = /obj/item/ingot/copper + required_material = /obj/item/ingot/copper craftdiff = 0 /////////////////////////////////////////////// /datum/anvil_recipe/weapons/copper/caxe name = "Copper Hatchet (+Bar)" - recipe_name = "an Axe" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/copper) created_item = /obj/item/weapon/axe/copper /datum/anvil_recipe/weapons/copper/cbludgeon name = "Copper Bludgeon (+Stick)" - recipe_name = "a Bludgeon" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/mace/bludgeon/copper /datum/anvil_recipe/weapons/copper/cdagger - name = "x2 Copper Daggers" - recipe_name = "a couple Daggers" + name = "Copper Daggers" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/copper - createditem_extra = 1 + output_amount = 2 //datum/anvil_recipe/weapons/copper/cmace // name = "Mace (2)" // recipe_name = "a Mace" // appro_skill = /datum/skill/craft/weaponsmithing -// req_bar = /obj/item/ingot/copper +// required_material = /obj/item/ingot/copper // additional_items = list(/obj/item/ingot/copper) // created_item = (/obj/item/weapon/mace/coppermace) // craftdiff = 0 /datum/anvil_recipe/weapons/copper/cmesser name = "Copper Messer (+Stick)" - recipe_name = "a Messer" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/sword/coppermesser /datum/anvil_recipe/weapons/copper/cspears - name = "2x Copper Javelins (+Small Log)" - recipe_name = "two Spears" + name = "Copper Javelins (+Small Log)" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/polearm/spear/stone/copper - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/weapons/copper/cfalx name = "Copper Falx (+Bar)" - recipe_name = "a great copper sword" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/copper) created_item = /obj/item/weapon/sword/long/rider/copper @@ -91,7 +82,7 @@ // --------- BRONZE ----------- /datum/anvil_recipe/weapons/bronze abstract_type = /datum/anvil_recipe/weapons/bronze - req_bar = /obj/item/ingot/bronze + required_material = /obj/item/ingot/bronze craftdiff = 1 /////////////////////////////////////////////// @@ -151,14 +142,14 @@ created_item = /obj/item/weapon/mace/elvenclub/bronze /datum/anvil_recipe/weapons/bronze/dagger - name = "2x Bronze Daggers" + name = "Bronze Daggers" created_item = /obj/item/weapon/knife/dagger/bronze - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/weapons/bronze/throwingdagger - name = "3x Bronze Throwing Daggers" + name = "Bronze Throwing Daggers" created_item = /obj/item/weapon/knife/throwingknife/bronze - createditem_extra = 2 + output_amount = 3 /datum/anvil_recipe/weapons/bronze/ji name = "Bronze Dagger-Ax (+ Small Log)" @@ -168,46 +159,41 @@ // --------- IRON ------------ Middle Tier, what most disgusting Men at Arms have /datum/anvil_recipe/weapons/iron abstract_type = /datum/anvil_recipe/weapons/iron - req_bar = /obj/item/ingot/iron + required_material = /obj/item/ingot/iron craftdiff = 1 /////////////////////////////////////////////// /datum/anvil_recipe/weapons/iron/arrows - name = "5x Arrows (+Plank)" - recipe_name = "five Arrows" + name = "Arrows (+Plank)" appro_skill = /datum/skill/craft/engineering additional_items = list(/obj/item/natural/wood/plank) created_item = /obj/item/ammo_casing/caseless/arrow - createditem_extra = 4 - i_type = "Ammo" + output_amount = 5 + category = "Ammo" craftdiff = 0 /datum/anvil_recipe/weapons/iron/bolts - name = "5x Crossbow Bolts (+Plank)" - recipe_name = "five Crossbow Bolts" + name = "Crossbow Bolts (+Plank)" appro_skill = /datum/skill/craft/engineering additional_items = list(/obj/item/natural/wood/plank) created_item = /obj/item/ammo_casing/caseless/bolt - createditem_extra = 4 - i_type = "Ammo" + output_amount = 5 + category = "Ammo" /datum/anvil_recipe/weapons/iron/axe_iron name = "Iron Axe (+Stick)" - recipe_name = "an Axe" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/axe/iron /datum/anvil_recipe/weapons/iron/nsapo name = "Iron Kasuyu (+Stick)" - recipe_name = "an Iron Kasuyu Axe" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/axe/iron/nsapo /datum/anvil_recipe/weapons/iron/bardiche name = "Bardiche (+Bar, +Small Log)" - recipe_name = "a Bardiche" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/iron,/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/polearm/halberd/bardiche @@ -215,21 +201,18 @@ /datum/anvil_recipe/weapons/iron/assegai name = "Iron Assegai (+ Small Log)" - recipe_name = "an Iron Assegai" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/polearm/spear/assegai /datum/anvil_recipe/weapons/iron/woodcutter name = "Woodcutter Axe (+Small Log)" - recipe_name = "a great axe for woodcutters" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/polearm/halberd/bardiche/woodcutter /datum/anvil_recipe/weapons/iron/warcutter name = "Footman War Axe (+Bar, +Small Log)" - recipe_name = "a war greataxe" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/iron,/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/polearm/halberd/bardiche/warcutter @@ -237,111 +220,95 @@ /datum/anvil_recipe/weapons/iron/greataxe name = "Greataxe (+Bar, +Small log)" - additional_items = list(/obj/item/grown/log/tree/small, /obj/item/ingot/iron,) - recipe_name = "a Greataxe with a single blade." + additional_items = list(/obj/item/grown/log/tree/small, /obj/item/ingot/iron) appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/greataxe craftdiff = 3 /datum/anvil_recipe/weapons/iron/dagger_iron - name = "Dagger x2" - recipe_name = "a couple Daggers" + name = "Dagger" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/dagger - createditem_extra = 1 + output_amount = 2 craftdiff = 0 // To train with /datum/anvil_recipe/weapons/iron/njora - name = "2x Iron Seme's" - recipe_name = "a Iron Seme" + name = "Iron Seme's" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/dagger/njora - createditem_extra = 1 + output_amount = 2 craftdiff = 0 /datum/anvil_recipe/weapons/iron/kukri name = "Iron Kukri" - recipe_name = "a Iron Kukri" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/hunting/kukri/iron /datum/anvil_recipe/weapons/iron/aruval name = "Iron Aruval (+2 Iron Bar)" - recipe_name = "a Iron Aruval" additional_items = list(/obj/item/ingot/iron, /obj/item/ingot/iron) appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/long/aruval/iron /datum/anvil_recipe/weapons/iron/dadao name = "Iron Dadao (+1 Iron Bar)" - recipe_name = "a Iron Dadao" additional_items = list(/obj/item/ingot/iron) appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/sabre/dadao/iron /datum/anvil_recipe/weapons/iron/ji name = "Iron Dagger-Ax (+ Small Log)" - recipe_name = "a Iron Dagger-Ax" additional_items = list(/obj/item/grown/log/tree/small) appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/polearm/spear/billhook/ji/iron /datum/anvil_recipe/weapons/iron/wodao name = "Iron Wo Dao" - recipe_name = "a Iron Wo Dao" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/scimitar/wodao/iron /datum/anvil_recipe/weapons/iron/urumi name = "Iron Urumi (+1 Iron Bar)" - recipe_name = "a Iron Urumi" additional_items = list(/obj/item/ingot/iron) appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/whip/urumi/iron /datum/anvil_recipe/weapons/iron/lakkarikhopesh name = "Iron Khopesh" - recipe_name = "a Iron Khopesh" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/scimitar/lakkarikhopesh/iron /datum/anvil_recipe/weapons/iron/sengese name = "Iron Sengese" - recipe_name = "a Iron Sengese" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/scimitar/sengese/iron /datum/anvil_recipe/weapons/iron/jile - name = "2x Iron Jile Daggers" - recipe_name = "a Iron Jile" + name = "Iron Jile Daggers" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/dagger/jile - createditem_extra = 1 + output_amount = 2 craftdiff = 0 /datum/anvil_recipe/weapons/iron/dagger_iron - name = "3x Villager Knives" - recipe_name = "three peasantry knives" + name = "Villager Knives" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/villager - createditem_extra = 2 + output_amount = 3 craftdiff = 0 /datum/anvil_recipe/weapons/iron/cleaver name = "Cleaver" - recipe_name = "a Cleaver" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/cleaver /datum/anvil_recipe/weapons/iron/flail_iron name = "Militia flail (+Chain, +Stick)" - recipe_name = "a militia flail" additional_items = list(/obj/item/rope/chain, /obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/flail/militia /datum/anvil_recipe/weapons/iron/lucerne name = "Lucerne (+Bar, +Small Log)" - recipe_name = "a Lucerne" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/iron,/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/polearm/eaglebeak/lucerne @@ -349,99 +316,84 @@ /datum/anvil_recipe/weapons/iron/sledgehammer name = "Sledgehammer (+Small Log)" - recipe_name = "a big hammer" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/hammer/sledgehammer /datum/anvil_recipe/weapons/iron/mace_iron name = "Iron Mace (+Stick)" - recipe_name = "a Mace" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/mace /datum/anvil_recipe/weapons/iron/rungu name = "Iron Rungu (+Stick)" - recipe_name = "an Iron Rungu" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/mace/rungu /datum/anvil_recipe/weapons/iron/ibludgeon name = "Iron Bludgeon (+Stick)" - recipe_name = "a Bludgeon" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/mace/bludgeon /datum/anvil_recipe/weapons/iron/warhammer name = "Iron Warhammer (+1 Stick)" - recipe_name = "a Warhammer" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/mace/warhammer /datum/anvil_recipe/weapons/iron/messer_iron name = "Messer" - recipe_name = "a Messer" created_item = /obj/item/weapon/sword/scimitar/messer /datum/anvil_recipe/weapons/iron/spear_iron - name = "2x Spears (+Small Log)" - recipe_name = "a couple Spears" + name = "Spears (+Small Log)" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/polearm/spear - createditem_extra = 1 + output_amount = 2 /datum/anvil_recipe/weapons/iron/shortsword_iron name = "Short Sword" - recipe_name = "a Short Sword" created_item = /obj/item/weapon/sword/short/iron /datum/anvil_recipe/weapons/iron/ida name = "Ida" - recipe_name= "an Iron Ida" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/short/iron/ida /datum/anvil_recipe/weapons/iron/shotel name = "Shotel (+Iron Bar)" - recipe_name= "an Iron Shotel" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/iron,) created_item = /obj/item/weapon/sword/long/shotel/iron /datum/anvil_recipe/weapons/iron/shishpar name = "Iron Shishpar (+ Iron Bar)" - recipe_name = "a Iron Shishpar" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/iron) created_item = /obj/item/weapon/mace/shishpar /datum/anvil_recipe/weapons/iron/sword_iron name = "Sword" - recipe_name = "a Sword" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/iron craftdiff = 0 /datum/anvil_recipe/weapons/iron/sword_iron name = "Estoc" - recipe_name = "a Duelist Sword" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/rapier/ironestoc /datum/anvil_recipe/weapons/iron/kaskara name = "Iron Kaskara" - recipe_name = "a Iron Kaskara" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/kaskara/iron /datum/anvil_recipe/weapons/iron/towershield name = "Tower Shield (+Small Log)" - recipe_name = "a Tower Shield" appro_skill = /datum/skill/craft/armorsmithing additional_items = list(/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/shield/tower @@ -449,13 +401,11 @@ /datum/anvil_recipe/weapons/iron/ironbuckler name = "Iron Buckler" - recipe_name = "a small Shield" appro_skill = /datum/skill/craft/armorsmithing created_item = /obj/item/weapon/shield/tower/buckleriron /datum/anvil_recipe/weapons/iron/warclub name = "Warclub (+Small Log)" - recipe_name = "a Warclub" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/mace/goden @@ -463,7 +413,6 @@ /datum/anvil_recipe/weapons/iron/zweihander name = "Zweihander (+Bar x2)" - recipe_name = "a Zweihander" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/iron, /obj/item/ingot/iron) created_item = /obj/item/weapon/sword/long/greatsword/zwei @@ -471,7 +420,6 @@ /datum/anvil_recipe/weapons/iron/claymore name = "Iron Claymore (+Bar x2)" - recipe_name = "a Iron Claymore" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/iron, /obj/item/ingot/iron) created_item = /obj/item/weapon/sword/long/greatsword/claymore/iron @@ -479,7 +427,6 @@ /datum/anvil_recipe/weapons/iron/elvenclub name = "Elven Warclub" - recipe_name = "a Warclub" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/mace/elvenclub craftdiff = 2 @@ -487,72 +434,62 @@ // --------- STEEL ------------ Fancy gear for Knights /datum/anvil_recipe/weapons/steel abstract_type = /datum/anvil_recipe/weapons/steel - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel craftdiff = 2 /////////////////////////////////////////////// /datum/anvil_recipe/weapons/steel/short_sword name = "Steel Short Sword" - recipe_name = "a Steel Short Sword" created_item = /obj/item/weapon/sword/short /datum/anvil_recipe/weapons/steel/assegai name = "Steel Assegai (+ Small Log)" - recipe_name = "a Steel Assegai" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/polearm/spear/assegai/steel /datum/anvil_recipe/weapons/steel/aruval name = "Steel Aruval (+2 Steel Bar)" - recipe_name = "a Steel Aruval" additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel) appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/long/aruval /datum/anvil_recipe/weapons/steel/dadao name = "Steel Dadao (+1 Steel Bar)" - recipe_name = "a Steel Dadao" additional_items = list(/obj/item/ingot/steel) appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/sabre/dadao /datum/anvil_recipe/weapons/steel/ji name = "Steel Dagger-Ax (+ Small Log)" - recipe_name = "a Steel Dagger-Ax" additional_items = list(/obj/item/grown/log/tree/small) appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/polearm/spear/billhook/ji /datum/anvil_recipe/weapons/steel/wodao name = "Steel Wo Dao" - recipe_name = "a Steel Wo Dao" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/scimitar/wodao /datum/anvil_recipe/weapons/steel/urumi name = "Steel Urumi (+1 Steel Bar)" - recipe_name = "a Steel Urumi" additional_items = list(/obj/item/ingot/steel) appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/whip/urumi /datum/anvil_recipe/weapons/steel/lakkarikhopesh name = "Steel Khopesh" - recipe_name = "a Steel Khopesh" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/scimitar/lakkarikhopesh /datum/anvil_recipe/weapons/steel/sengese name = "Steel Sengese" - recipe_name = "a Steel Sengese" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/scimitar/sengese /datum/anvil_recipe/weapons/steel/axe_steel name = "Steel Axe (+Stick)" - recipe_name = "an Axe" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/axe/steel @@ -560,7 +497,6 @@ /datum/anvil_recipe/weapons/steel/greataxe name = "Greataxe (+Bar, +Small log)" additional_items = list(/obj/item/grown/log/tree/small, /obj/item/ingot/steel) - recipe_name = "a Greataxe with a single blade." appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/greataxe/steel craftdiff = 4 @@ -568,21 +504,18 @@ /datum/anvil_recipe/weapons/steel/doubleheaded_greataxe name = "Double-headed Greataxe (+Bar x2), (+Small log)" additional_items = list(/obj/item/grown/log/tree/small, /obj/item/ingot/steel, /obj/item/ingot/steel) - recipe_name = "a Greataxe with two blades." appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/greataxe/steel/doublehead craftdiff = 5 /datum/anvil_recipe/weapons/steel/nsapo name = "Steel Kasuyu (+Stick)" - recipe_name = "an Steel Kasuyu Axe" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/axe/steel/nsapo /datum/anvil_recipe/weapons/steel/rungu name = "Steel Rungu (+Stick)" - recipe_name = "an Steel Rungu" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/mace/steel/rungu @@ -590,30 +523,26 @@ /datum/anvil_recipe/weapons/steel/sledgehammer name = "Steel Sledgehammer (+Small Log)" - recipe_name = "a big Sledgehammer" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/hammer/sledgehammer/war /datum/anvil_recipe/weapons/steel/njora - name = "2x Steel Seme's" - recipe_name = "a Steel Seme" + name = "Steel Seme's" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/dagger/steel/njora - createditem_extra = 1 + output_amount = 2 craftdiff = 1 /datum/anvil_recipe/weapons/steel/jile - name = "2x Steel Jile Daggers" - recipe_name = "a Steel Jile" + name = "Steel Jile Daggers" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/dagger/steel/jile - createditem_extra = 1 + output_amount = 2 craftdiff = 1 /datum/anvil_recipe/weapons/steel/battleaxe name = "Battle Axe (+Bar)" - recipe_name = "a Battle Axe" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/weapon/axe/battle @@ -621,7 +550,6 @@ /datum/anvil_recipe/weapons/steel/billhook name = "Billhook (+Small Log)" - recipe_name = "a Billhook" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/polearm/spear/billhook @@ -629,67 +557,57 @@ /datum/anvil_recipe/weapons/steel/cutlass_steel name = "Cutlass" - recipe_name = "a Cutlass" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/sabre/cutlass /datum/anvil_recipe/weapons/steel/shotel name = "Steel Shotel (+ Steel Bar)" - recipe_name = "a Steel Shotel" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/weapon/sword/long/shotel /datum/anvil_recipe/weapons/steel/shishpar name = "Steel Shishpar (+ Steel Bar)" - recipe_name = "a Steel Shishpar" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/weapon/mace/steel/shishpar /datum/anvil_recipe/weapons/steel/ida name = "Steel Ida" - recipe_name = "a Steel Ida" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/short/ida /datum/anvil_recipe/weapons/steel/kaskara // I FORGOT TO INCLUDE IT name = "Steel Kaskara" - recipe_name = "a Steel Kaskara" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/kaskara /datum/anvil_recipe/weapons/steel/kukri name = "Steel Kukri" - recipe_name = "a Steel Kukri" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/hunting/kukri /datum/anvil_recipe/weapons/steel/knuckles name = "Knuckles" - recipe_name = "a Steel Knuckles" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knuckles /datum/anvil_recipe/weapons/steel/dagger_steel - name = "2x Steel Daggers" - recipe_name = "a couple Daggers" + name = "Steel Daggers" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/dagger/steel - createditem_extra = 1 + output_amount = 2 craftdiff = 1 /datum/anvil_recipe/weapons/steel/stiletto - name = "2x Steel Stilettos" - recipe_name = "a couple Daggers" + name = "Steel Stilettos" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/dagger/steel/stiletto - createditem_extra = 1 + output_amount = 2 craftdiff = 1 /datum/anvil_recipe/weapons/steel/decsaber name = "Decorated Sabre (+Gold Bar)" - recipe_name = "a Decorated Sabre" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/gold) created_item = /obj/item/weapon/sword/sabre/dec @@ -697,7 +615,6 @@ /datum/anvil_recipe/weapons/steel/decsword name = "Decorated Sword (+Gold Bar)" - recipe_name = "a Decorated Sword" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/gold) created_item = /obj/item/weapon/sword/decorated @@ -705,7 +622,6 @@ /datum/anvil_recipe/weapons/steel/decrapier name = "Decorated Rapier (+Gold Bar)" - recipe_name = "a Decorated Rapier" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/gold) created_item = /obj/item/weapon/sword/rapier/dec @@ -713,7 +629,6 @@ /datum/anvil_recipe/weapons/steel/nimcha name = "Nimcha (+Gold Bar)" - recipe_name = "a Nimcha" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/gold) created_item = /obj/item/weapon/sword/rapier/nimcha @@ -721,7 +636,6 @@ /datum/anvil_recipe/weapons/steel/eaglebeak name = "Eagle's Beak (+Bar, +Small Log)" - recipe_name = "an Eagle's Beak" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel, /obj/item/grown/log/tree/small) created_item = /obj/item/weapon/polearm/eaglebeak @@ -729,13 +643,11 @@ /datum/anvil_recipe/weapons/steel/flail_steel name = "Steel Flail (+Chain, +Stick)" - recipe_name = "a Flail" additional_items = list(/obj/item/rope/chain, /obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/flail/sflail /datum/anvil_recipe/weapons/steel/grandmace name = "Grand Mace (+Bar, +Small Log)" - recipe_name = "a Grand Mace" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/small, /obj/item/ingot/steel) created_item = /obj/item/weapon/mace/goden/steel @@ -743,7 +655,6 @@ /datum/anvil_recipe/weapons/steel/greatsword name = "Greatsword (+Bar x2)" - recipe_name = "a Greatsword" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel) created_item = /obj/item/weapon/sword/long/greatsword @@ -751,7 +662,6 @@ /datum/anvil_recipe/weapons/steel/flamberge name = "Flamberge (+Bar x3)" - recipe_name = "a Flamberge" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel, /obj/item/ingot/steel) created_item = /obj/item/weapon/sword/long/greatsword/flamberge @@ -759,7 +669,6 @@ /datum/anvil_recipe/weapons/steel/claymore name = "Steel Claymore (+Bar x2)" - recipe_name = "a Steel Claymore" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel, /obj/item/ingot/steel) created_item = /obj/item/weapon/sword/long/greatsword/claymore @@ -779,7 +688,7 @@ /datum/anvil_recipe/weapons/gold abstract_type = /datum/anvil_recipe/weapons/gold - req_bar = /obj/item/ingot/gold + required_material = /obj/item/ingot/gold craftdiff = 5 /datum/anvil_recipe/weapons/gold/noble_sword_scabbard @@ -795,7 +704,6 @@ /datum/anvil_recipe/weapons/steel/halberd name = "Halberd (+Bar, +Small Log)" - recipe_name = "a Halberd" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel,/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/polearm/halberd @@ -803,13 +711,11 @@ /datum/anvil_recipe/weapons/steel/huntknife name = "Hunting Knife" - recipe_name = "a Hunting Knife" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/hunting /datum/anvil_recipe/weapons/steel/kiteshield name = "Kite Shield (+Bar, +Hide)" - recipe_name = "a Kite Shield" appro_skill = /datum/skill/craft/armorsmithing additional_items = list(/obj/item/ingot/steel,/obj/item/natural/hide) created_item = /obj/item/weapon/shield/tower/metal @@ -817,7 +723,6 @@ /datum/anvil_recipe/weapons/steel/longsword name = "Longsword (+Bar)" - recipe_name = "a Longsword" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/weapon/sword/long @@ -825,21 +730,18 @@ /datum/anvil_recipe/weapons/steel/mace_steel name = "Steel Mace (+Bar)" - recipe_name = "a Mace" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/weapon/mace/steel /datum/anvil_recipe/weapons/steel/swarhammer name = "Steel Warhammer (+Bar)" - recipe_name = "a Warhammer" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/weapon/mace/warhammer/steel /datum/anvil_recipe/weapons/steel/peasant_flail name = "Peasant Flail (+Chain, +Small Log)" - recipe_name = "a two-handed flail" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/rope/chain, /obj/item/grown/log/tree/small) created_item = /obj/item/weapon/flail/peasant @@ -847,7 +749,6 @@ /datum/anvil_recipe/weapons/iron/chain_whip name = "Chain Whip (+chain)" - recipe_name = "a whip made from chains" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/rope/chain) created_item = /obj/item/weapon/whip/chain @@ -855,7 +756,6 @@ /datum/anvil_recipe/weapons/steel/paxe name = "Pick-Axe (+Bar, +Stick)" - recipe_name = "a Pick that is also an Axe" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel, /obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/pick/paxe @@ -863,37 +763,31 @@ /datum/anvil_recipe/weapons/steel/rapier_steel name = "Rapier" - recipe_name = "a Rapier" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/rapier /datum/anvil_recipe/weapons/steel/saber_steel name = "Sabre" - recipe_name = "a Sabre" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/sabre /datum/anvil_recipe/weapons/steel/sword_steel name = "Arming Sword" - recipe_name = "a Sword" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/arming /datum/anvil_recipe/weapons/steel/scimitar_steel name = "Scimitar" - recipe_name = "a Zalad Sword" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/scimitar /datum/anvil_recipe/weapons/steel/falchion name = "Falchion" - recipe_name = "a heavy one handed sword" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/scimitar/falchion /datum/anvil_recipe/weapons/steel/elvenclub name = "Steel Elven Warclub (+Bar)" - recipe_name = "a Steel Elven Warclub" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/weapon/mace/elvenclub/steel @@ -902,52 +796,45 @@ /datum/anvil_recipe/weapons/silver abstract_type = /datum/anvil_recipe/weapons/silver - req_bar = /obj/item/ingot/silver + required_material = /obj/item/ingot/silver craftdiff = 4 /////////////////////////////////////////////// /datum/anvil_recipe/weapons/silver/dagger name = "Silver Dagger" - recipe_name = "a Silver Dagger" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/knife/dagger/silver craftdiff = 3 /datum/anvil_recipe/weapons/silver/silver_whip name = "Silver Whip (+2 Cured Hide)" - recipe_name = "a whip made modified with silver" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/natural/hide/cured,/obj/item/natural/hide/cured) created_item = /obj/item/weapon/whip/silver /datum/anvil_recipe/weapons/silver/urumi name = "Silver Urumi (+1 Silver Bar)" - recipe_name = "a Silver Urumi" additional_items = list(/obj/item/ingot/silver) appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/whip/urumi/silver /datum/anvil_recipe/weapons/silver/sword_silver name = "Silver Sword" - recipe_name = "a Silver Sword" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/silver /datum/anvil_recipe/weapons/silver/sengese name = "Silver Sengese" - recipe_name = "a Silver Sengese" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/scimitar/sengese/silver /datum/anvil_recipe/weapons/silver/rapier_silver name = "Silver Rapier" - recipe_name = "a Silver Rapier" appro_skill = /datum/skill/craft/weaponsmithing created_item = /obj/item/weapon/sword/rapier/silver /datum/anvil_recipe/weapons/silver/forgotten name = "Forgotten Blade (+Steel Bar)" - recipe_name = "a Forgotten Blade" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/steel) created_item = /obj/item/weapon/sword/long/forgotten @@ -960,126 +847,113 @@ /datum/anvil_recipe/weapons/silver/rungu name = "Silver Rungu (+ Stick)" - recipe_name = "a Silver Rungu" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/grown/log/tree/stick) created_item = /obj/item/weapon/mace/rungu/silver /datum/anvil_recipe/weapons/silver/gada name = "Regal Gada (+1 Gold bar)" - recipe_name = "a Regal Gada" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/gold) created_item = /obj/item/weapon/mace/gada /datum/anvil_recipe/weapons/silver/elvenclub name = "Regal Elven Club (+1 Gold bar)" - recipe_name = "a Silver Elven Warclub" appro_skill = /datum/skill/craft/weaponsmithing additional_items = list(/obj/item/ingot/gold) created_item = /obj/item/weapon/mace/elvenclub/silver /datum/anvil_recipe/weapons/psy/axe name = "Psydonian War Axe (+1 B. Silver, +1 Stick)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed craftdiff = 3 created_item = /obj/item/weapon/axe/psydon additional_items = list(/obj/item/ingot/silverblessed, /obj/item/grown/log/tree/stick) - i_type = "Weapons" + /datum/anvil_recipe/weapons/psy/mace name = "Psydonian Mace (+1 B. Silver, +1 Stick)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed craftdiff = 3 created_item = /obj/item/weapon/mace/goden/psydon additional_items = list(/obj/item/ingot/silverblessed, /obj/item/grown/log/tree/stick) - i_type = "Weapons" + /datum/anvil_recipe/weapons/psy/spear name = "Psydonian Spear (+1 Small Log)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed craftdiff = 3 created_item = /obj/item/weapon/polearm/spear/psydon additional_items = list(/obj/item/grown/log/tree/small) - i_type = "Weapons" + /datum/anvil_recipe/weapons/psy/dagger name = "Psydonian Dagger" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed craftdiff = 3 created_item = /obj/item/weapon/knife/dagger/silver/psydon - i_type = "Weapons" /datum/anvil_recipe/weapons/psy/shortsword name = "Psydonian Shortsword" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed craftdiff = 3 created_item = /obj/item/weapon/sword/short/psy - i_type = "Weapons" /datum/anvil_recipe/weapons/psy/katar name = "Psydonian Katar" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed craftdiff = 3 created_item = /obj/item/weapon/katar/psydon - i_type = "Weapons" /datum/anvil_recipe/weapons/psy/knuckles name = "Psydonian Knuckles" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed craftdiff = 3 created_item = /obj/item/weapon/knuckles/psydon - i_type = "Weapons" /datum/anvil_recipe/weapons/psy/cudgel name = "Psydonian Handmace" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed craftdiff = 3 created_item = /obj/item/weapon/mace/cudgel/psy - i_type = "Weapons" /datum/anvil_recipe/weapons/psy/halberd name = "Psydonian Halberd (+1 B. Silver, +1 Small Log)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed craftdiff = 3 created_item = /obj/item/weapon/polearm/halberd/psydon additional_items = list(/obj/item/ingot/silverblessed, /obj/item/grown/log/tree/small) - i_type = "Weapons" /datum/anvil_recipe/weapons/psy/gsword name = "Psydonian Greatsword (+1 B. Silver)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed craftdiff = 3 created_item = /obj/item/weapon/sword/long/greatsword/psydon additional_items = list(/obj/item/ingot/silverblessed) - i_type = "Weapons" /datum/anvil_recipe/weapons/psy/sword name = "Psydonian Sword" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed craftdiff = 3 created_item = /obj/item/weapon/sword/long/psydon - i_type = "Weapons" /datum/anvil_recipe/weapons/psy/whip name = "Psydonian Whip (+2 Cured Leather)" - req_bar = /obj/item/ingot/silverblessed + required_material = /obj/item/ingot/silverblessed craftdiff = 3 created_item = /obj/item/weapon/whip/psydon additional_items = list(/obj/item/natural/hide/cured, /obj/item/natural/hide/cured) - i_type = "Weapons" /datum/anvil_recipe/weapons/atgervi_shield name = "kite shield" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel additional_items = list(/obj/item/grown/log/tree) created_item = /obj/item/weapon/shield/atgervi - i_type = "Shields" + category = "Shields" craftdiff = 2 /datum/anvil_recipe/weapons/atgervi_axe name = "Bearded axe (+1 Small log)" - req_bar = /obj/item/ingot/steel + required_material = /obj/item/ingot/steel additional_items = list(/obj/item/grown/log/tree/small) created_item = /obj/item/weapon/axe/steel/atgervi - i_type = "Weapons" craftdiff = 3 /datum/anvil_recipe/weapons/mace/cane/noble @@ -1087,4 +961,3 @@ craftdiff = 3 additional_items = list(/obj/item/ingot/gold, /obj/item/grown/log/tree) created_item = /obj/item/weapon/mace/cane/noble - i_type = "Weapons" diff --git a/code/modules/crafting/artificer/_base.dm b/code/modules/crafting/artificer/_base.dm index 82e1b06a4dc..b3bb4860652 100644 --- a/code/modules/crafting/artificer/_base.dm +++ b/code/modules/crafting/artificer/_base.dm @@ -52,7 +52,7 @@ user.visible_message(span_warning("[user] hammers the contraption.")) return -/datum/artificer_recipe/proc/item_added(mob/user) +/datum/artificer_recipe/proc/item_added(obj/item/added_item, mob/user) user.visible_message(span_info("[user] adds [initial(needed_item.name)].")) if(istype(needed_item, /obj/item/natural/wood/plank)) playsound(user, 'sound/misc/wood_saw.ogg', 100, TRUE) diff --git a/code/modules/crafting/blueprinting/_base_blueprint_object.dm b/code/modules/crafting/blueprinting/_base_blueprint_object.dm index 8ad32c567b1..7f9a431325b 100644 --- a/code/modules/crafting/blueprinting/_base_blueprint_object.dm +++ b/code/modules/crafting/blueprinting/_base_blueprint_object.dm @@ -5,6 +5,7 @@ icon = 'icons/effects/alphacolors.dmi' icon_state = "white" alpha = 0 // Keep parent invisible + plane = ABOVE_LIGHTING_PLANE invisibility = 100 /// on_hover still triggers on no alpha objects anchored = TRUE density = FALSE diff --git a/code/modules/crafting/quality_of_crafting/carving.dm b/code/modules/crafting/quality_of_crafting/carving.dm new file mode 100644 index 00000000000..ef75d2649f8 --- /dev/null +++ b/code/modules/crafting/quality_of_crafting/carving.dm @@ -0,0 +1,1246 @@ + +// -------------------------- Gems ------------------------------ // + +// jade // + +/datum/repeatable_crafting_recipe/crafting/jade + abstract_type = /datum/repeatable_crafting_recipe/crafting/jade + requirements = list( + /obj/item/gem/jade = 1, + ) + tool_usage = list( + /obj/item/weapon/knife = list("starts to carve out the raw joapstone", "start to carve the raw joapstone") + ) + attacked_atom = /obj/item/gem/jade + starting_atom = /obj/item/weapon/knife + output_amount = 1 + craftdiff = 1 + subtypes_allowed = TRUE + +/datum/repeatable_crafting_recipe/crafting/jade/cutgem + name = "cut joapstone gem" + output = /obj/item/carvedgem/jade/cutgem + craftdiff = 0 + +/datum/repeatable_crafting_recipe/crafting/jade/fork + name = "joapstone fork" + output = /obj/item/carvedgem/jade/fork + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/jade/spoon + name = "joapstone spoon" + output = /obj/item/carvedgem/jade/spoon + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/jade/cameo + name = "joapstone cameo" + output = /obj/item/carvedgem/jade/cameo + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/jade/bowl + name = "joapstone bowl" + output = /obj/item/reagent_containers/glass/bowl/jade + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/jade/cup + name = "joapstone cup" + output = /obj/item/reagent_containers/glass/cup/jade + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/jade/platter + name = "joapstone platter" + output = /obj/item/plate/jade + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/jade/ring + name = "joapstone ring" + output = /obj/item/clothing/ring/jade + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/jade/amulet + name = "joapstone amulet" + output = /obj/item/clothing/neck/jadeamulet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/jade/vase + name = "joapstone vase" + output = /obj/item/carvedgem/jade/vase + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/jade/figurine + name = "joapstone figurine" + output = /obj/item/carvedgem/jade/figurine + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/jade/fish + name = "joapstone fish figurine" + output = /obj/item/carvedgem/jade/fish + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/jade/tablet + name = "joapstone tablet" + output = /obj/item/carvedgem/jade/tablet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/jade/teapot + name = "joapstone teapot" + output = /obj/item/reagent_containers/glass/carafe/teapot/jade + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/jade/bust + name = "joapstone bust" + output = /obj/item/carvedgem/jade/bust + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/jade/fancyvase + name = "fancy joapstone vase" + output = /obj/item/carvedgem/jade/fancyvase + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/jade/comb + name = "joapstone comb" + output = /obj/item/carvedgem/jade/comb + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/jade/duck + name = "joapstone duck" + output = /obj/item/carvedgem/jade/duck + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/jade/bracelet + name = "joapstone bracelets" + output = /obj/item/clothing/wrists/gem/jadebracelet + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/jade/circlet + name = "joapstone circlet" + output = /obj/item/clothing/head/crown/circlet/jade + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/jade/fancycup + name = "fancy joapstone cup" + output = /obj/item/reagent_containers/glass/cup/jadefancy + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/jade/mask + name = "joapstone mask" + output = /obj/item/clothing/face/jademask + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/jade/urn + name = "joapstone urn" + output = /obj/item/carvedgem/jade/urn + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/jade/statue + name = "joapstone statue" + output = /obj/item/carvedgem/jade/statue + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/jade/obelisk + name = "joapstone obelisk" + output = /obj/item/carvedgem/jade/obelisk + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/jade/wyrm + name = "joapstone wyrm" + output = /obj/item/carvedgem/jade/wyrm + craftdiff = 5 + + +/datum/repeatable_crafting_recipe/crafting/jade/kukri + name = "joapstone kukri" + output = /obj/item/weapon/knife/stone/kukri + craftdiff = 5 + +// shell // + +/datum/repeatable_crafting_recipe/crafting/shell + abstract_type = /datum/repeatable_crafting_recipe/crafting/shell + requirements = list( + /obj/item/carvedgem/shell/rawshell = 1, + ) + tool_usage = list( + /obj/item/weapon/knife = list("starts to carve out the clam shell", "start to carve out the clam shell") + ) + attacked_atom = /obj/item/carvedgem/shell/rawshell + starting_atom = /obj/item/weapon/knife + output_amount = 1 + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/shell/openclam + name = "opened clam" + output = list ( + /obj/item/carvedgem/shell/openoyster, + /obj/item/carvedgem/rose/rawrose + ) + + requirements = list( + /obj/item/gem/oyster = 1 + ) + tool_usage = list( + /obj/item/weapon/knife = list("starts to pry open the clam shell", "pry open the clam shell") + ) + attacked_atom = /obj/item/gem/oyster + starting_atom = /obj/item/weapon/knife + output_amount = 1 + craftdiff = 0 + +/datum/repeatable_crafting_recipe/crafting/shell/rawshell + + name = "2x clam shells " + output = /obj/item/carvedgem/shell/rawshell + requirements = list( + /obj/item/carvedgem/shell/openoyster = 1 + ) + tool_usage = list( + /obj/item/weapon/knife = list("starts to pull apart the clam shell", "pull apart the clam shell") + ) + attacked_atom = /obj/item/carvedgem/shell/openoyster + starting_atom = /obj/item/weapon/knife + output_amount = 2 + craftdiff = 0 + +/datum/repeatable_crafting_recipe/crafting/shell/cutgem + name = "polished clam shell" + output = /obj/item/carvedgem/shell/cutgem + craftdiff = 0 + +/datum/repeatable_crafting_recipe/crafting/shell/fork + name = "shell fork" + output = /obj/item/carvedgem/shell/fork + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/shell/spoon + name = "shell spoon" + output = /obj/item/carvedgem/shell/spoon + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/shell/cameo + name = "shell cameo" + output = /obj/item/carvedgem/shell/cameo + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/shell/bowl + name = "shell bowl" + output = /obj/item/reagent_containers/glass/bowl/shell + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/shell/cup + name = "shell cup" + output = /obj/item/reagent_containers/glass/cup/shell + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/shell/platter + name = "shell platter" + output = /obj/item/plate/shell + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/shell/ring + name = "shell ring" + output = /obj/item/clothing/ring/shell + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/shell/teapot + name = "shell teapot" + output = /obj/item/reagent_containers/glass/carafe/teapot/shell + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/shell/amulet + name = "shell amulet" + output = /obj/item/clothing/neck/shellamulet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/shell/figurine + name = "shell figurine" + output = /obj/item/carvedgem/shell/figurine + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/shell/tablet + name = "shell tablet" + output = /obj/item/carvedgem/shell/tablet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/shell/fish + name = "shell fish figurine" + output = /obj/item/carvedgem/shell/fish + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/shell/vase + name = "shell vase" + output = /obj/item/carvedgem/shell/vase + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/shell/bust + name = "shell bust" + output = /obj/item/carvedgem/shell/bust + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/shell/circlet + name = "shell circlet" + output = /obj/item/clothing/head/crown/circlet/shell + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/shell/bracelet + name = "shell bracelets" + output = /obj/item/clothing/wrists/gem/shellbracelet + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/shell/fancycup + name = "fancy shell cup" + output = /obj/item/reagent_containers/glass/cup/shellfancy + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/shell/fancyvase + name = "fancy shell vase" + output = /obj/item/carvedgem/shell/fancyvase + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/shell/comb + name = "shell comb" + output = /obj/item/carvedgem/shell/comb + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/shell/duck + name = "shell duck" + output = /obj/item/carvedgem/shell/duck + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/shell/mask + name = "shell mask" + output = /obj/item/clothing/face/shellmask + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/shell/urn + name = "shell urn" + output = /obj/item/carvedgem/shell/urn + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/shell/statue + name = "shell statue" + output = /obj/item/carvedgem/shell/statue + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/shell/obelisk + name = "shell obelisk" + output = /obj/item/carvedgem/shell/obelisk + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/shell/turtle + name = "turtle carving" + output = /obj/item/carvedgem/shell/turtle + craftdiff = 5 + +/datum/repeatable_crafting_recipe/crafting/shell/rungu + name = "shell rungu" + output = /obj/item/weapon/mace/cudgel/shellrungu + craftdiff = 5 + +// rose // + +/datum/repeatable_crafting_recipe/crafting/rose + abstract_type = /datum/repeatable_crafting_recipe/crafting/rose + requirements = list( + /obj/item/carvedgem/rose/rawrose = 1, + ) + tool_usage = list( + /obj/item/weapon/knife = list("carves the rosellusk pearl", "carve the rosellusk pearl") + ) + attacked_atom = /obj/item/carvedgem/rose/rawrose + starting_atom = /obj/item/weapon/knife + output_amount = 1 + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/rose/cutgem + name = "rosellusk pearl" + output = /obj/item/carvedgem/rose/cutgem + requirements = list( + /obj/item/carvedgem/rose/rawrose = 1, + ) + tool_usage = list( + /obj/item/weapon/knife = list("refines the rosellusk pearl", "refine the rosellusk pearl") + ) + attacked_atom = /obj/item/carvedgem/rose/rawrose + starting_atom = /obj/item/weapon/knife + output_amount = 1 + craftdiff = 0 + +/datum/repeatable_crafting_recipe/crafting/rose/spoon + name = "rosellusk spoon" + output = /obj/item/carvedgem/rose/spoon + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/rose/fork + name = "rosellusk fork" + output = /obj/item/carvedgem/rose/fork + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/rose/cup + name = "rosellusk cup" + output = /obj/item/reagent_containers/glass/cup/rose + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/rose/bowl + name = "rosellusk bowl" + output = /obj/item/reagent_containers/glass/bowl/rose + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/rose/cameo + name = "rosellusk cameo" + output = /obj/item/carvedgem/rose/cameo + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/rose/figurine + name = "rosellusk figurine" + output = /obj/item/carvedgem/rose/figurine + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/rose/fish + name = "rosellusk fish figurine" + output = /obj/item/carvedgem/rose/fish + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/rose/vase + name = "rosellusk vase" + output = /obj/item/carvedgem/rose/vase + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/rose/tablet + name = "rosellusk tablet" + output = /obj/item/carvedgem/rose/tablet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/rose/teapot + name = "rosellusk teapot" + output = /obj/item/reagent_containers/glass/carafe/teapot/rose + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/rose/ring + name = "rosellusk ring" + output = /obj/item/clothing/ring/rose + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/rose/amulet + name = "rosellusk amulet" + output = /obj/item/clothing/neck/roseamulet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/rose/platter + name = "rosellusk platter" + output = /obj/item/plate/rose + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/rose/bust + name = "rosellusk bust" + output = /obj/item/carvedgem/rose/bust + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/rose/fancyvase + name = "fancy rosellusk vase" + output = /obj/item/carvedgem/rose/fancyvase + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/rose/comb + name = "rosellusk comb" + output = /obj/item/carvedgem/rose/comb + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/rose/duck + name = "rosellusk duck" + output = /obj/item/carvedgem/rose/duck + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/rose/bracelet + name = "rosellusk bracelets" + output = /obj/item/clothing/wrists/gem/rosebracelet + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/rose/circlet + name = "rosellusk circlet" + output = /obj/item/clothing/head/crown/circlet/rose + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/rose/fancycup + name = "fancy rosellusk cup" + output = /obj/item/reagent_containers/glass/cup/rosefancy + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/rose/urn + name = "rosellusk urn" + output = /obj/item/carvedgem/rose/urn + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/rose/statue + name = "rosellusk statue" + output = /obj/item/carvedgem/rose/statue + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/rose/obelisk + name = "rosellusk obelisk" + output = /obj/item/carvedgem/rose/obelisk + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/rose/mask + name = "rosellusk mask" + output = /obj/item/clothing/face/rosemask + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/rose/flower + name = "rosellusk flower carving" + output = /obj/item/carvedgem/rose/flower + craftdiff = 5 + +/datum/repeatable_crafting_recipe/crafting/rose/carp + name = "rosellusk carp statue" + output = /obj/item/carvedgem/rose/carp + craftdiff = 5 + +// onyxa // + +/datum/repeatable_crafting_recipe/crafting/onyxa + abstract_type = /datum/repeatable_crafting_recipe/crafting/onyxa + requirements = list( + /obj/item/gem/onyxa = 1, + ) + tool_usage = list( + /obj/item/weapon/knife = list("carves out the onyxa", "carve out the onyxa") + ) + attacked_atom = /obj/item/gem/onyxa + starting_atom = /obj/item/weapon/knife + output_amount = 1 + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/onyxa/cutgem + name = "cut onyxa gem" + output = /obj/item/carvedgem/onyxa/cutgem + craftdiff = 0 + +/datum/repeatable_crafting_recipe/crafting/onyxa/fork + name = "onyxa fork" + output = /obj/item/carvedgem/onyxa/fork + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/onyxa/spoon + name = "onyxa spoon" + output = /obj/item/carvedgem/onyxa/spoon + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/onyxa/cameo + name = "onyxa cameo" + output = /obj/item/carvedgem/onyxa/cameo + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/onyxa/cup + name = "onyxa cup" + output = /obj/item/reagent_containers/glass/cup/onyxa + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/onyxa/bowl + name = "onyxa bowl" + output = /obj/item/reagent_containers/glass/bowl/onyxa + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/onyxa/figurine + name = "onyxa figurine" + output = /obj/item/carvedgem/onyxa/figurine + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/onyxa/fish + name = "onyxa fish figurine" + output = /obj/item/carvedgem/onyxa/fish + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/onyxa/vase + name = "onyxa vase" + output = /obj/item/carvedgem/onyxa/vase + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/onyxa/tablet + name = "onyxa tablet" + output = /obj/item/carvedgem/onyxa/tablet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/onyxa/teapot + name = "onyxa teapot" + output = /obj/item/reagent_containers/glass/carafe/teapot/onyxa + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/onyxa/ring + name = "onyxa ring" + output = /obj/item/clothing/ring/onyxa + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/onyxa/amulet + name = "onyxa amulet" + output = /obj/item/clothing/neck/onyxaamulet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/onyxa/platter + name = "onyxa platter" + output = /obj/item/plate/onyxa + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/onyxa/bust + name = "onyxa bust" + output = /obj/item/carvedgem/onyxa/bust + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/onyxa/fancyvase + name = "fancy onyxa vase" + output = /obj/item/carvedgem/onyxa/fancyvase + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/onyxa/comb + name = "onyxa comb" + output = /obj/item/carvedgem/onyxa/comb + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/onyxa/duck + name = "onyxa duck" + output = /obj/item/carvedgem/onyxa/duck + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/onyxa/fancycup + name = "fancy onyxa cup" + output = /obj/item/reagent_containers/glass/cup/onyxafancy + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/onyxa/bracelet + name = "onyxa bracelets" + output = /obj/item/clothing/wrists/gem/onyxabracelet + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/onyxa/circlet + name = "onyxa circlet" + output = /obj/item/clothing/head/crown/circlet/onyxa + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/onyxa/mask + name = "onyxa mask" + output = /obj/item/clothing/face/onyxamask + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/onyxa/urn + name = "onyxa urn" + output = /obj/item/carvedgem/onyxa/urn + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/onyxa/statue + name = "onyxa statue" + output = /obj/item/carvedgem/onyxa/statue + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/onyxa/obelisk + name = "onyxa obelisk" + output = /obj/item/carvedgem/onyxa/obelisk + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/onyxa/urn + name = "onyxa urn" + output = /obj/item/carvedgem/onyxa/urn + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/onyxa/spider + name = "onyxa spider statue" + output = /obj/item/carvedgem/onyxa/spider + craftdiff = 5 + +/datum/repeatable_crafting_recipe/crafting/onyxa/snake + name = "onyxa snake statue" + output = /obj/item/carvedgem/onyxa/snake + craftdiff = 5 + +// ceruleabaster // + +/datum/repeatable_crafting_recipe/crafting/turq + abstract_type = /datum/repeatable_crafting_recipe/crafting/turq + requirements = list( + /obj/item/gem/turq = 1, + ) + tool_usage = list( + /obj/item/weapon/knife = list("carves out the raw ceruleabaster", "carve out the raw ceruleabaster") + ) + attacked_atom = /obj/item/gem/turq + starting_atom = /obj/item/weapon/knife + output_amount = 1 + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/turq/cutgem + name = "cut ceruleabaster gem" + output = /obj/item/carvedgem/turq/cutgem + craftdiff = 0 + +/datum/repeatable_crafting_recipe/crafting/turq/fork + name = "ceruleabaster fork" + output = /obj/item/carvedgem/turq/fork + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/turq/spoon + name = "ceruleabaster spoon" + output = /obj/item/carvedgem/turq/spoon + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/turq/cameo + name = "ceruleabaster cameo" + output = /obj/item/carvedgem/turq/cameo + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/turq/bowl + name = "ceruleabaster bowl" + output = /obj/item/reagent_containers/glass/bowl/turq + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/turq/cup + name = "ceruleabaster cup" + output = /obj/item/reagent_containers/glass/cup/turq + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/turq/figurine + name = "ceruleabaster figurine" + output = /obj/item/carvedgem/turq/figurine + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/turq/fish + name = "ceruleabaster fish figurine" + output = /obj/item/carvedgem/turq/fish + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/turq/vase + name = "ceruleabaster vase" + output = /obj/item/carvedgem/turq/vase + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/turq/amulet + name = "ceruleabaster amulet" + output = /obj/item/clothing/neck/turqamulet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/turq/tablet + name = "ceruleabaster tablet" + output = /obj/item/carvedgem/turq/tablet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/turq/ring + name = "ceruleabaster ring" + output = /obj/item/clothing/ring/turq + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/turq/platter + name = "ceruleabaster platter" + output = /obj/item/plate/turq + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/turq/bracelet + name = "ceruleabaster bracelets" + output = /obj/item/clothing/wrists/gem/turqbracelet + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/turq/circlet + name = "ceruleabaster circlet" + output = /obj/item/clothing/head/crown/circlet/turq + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/turq/fancycup + name = "fancy ceruleabaster cup" + output = /obj/item/reagent_containers/glass/cup/turqfancy + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/turq/fancyvase + name = "fancy ceruleabaster vase" + output = /obj/item/carvedgem/turq/fancyvase + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/turq/bust + name = "ceruleabaster bust" + output = /obj/item/carvedgem/turq/bust + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/turq/comb + name = "ceruleabaster comb" + output = /obj/item/carvedgem/turq/comb + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/turq/duck + name = "ceruleabaster duck" + output = /obj/item/carvedgem/turq/duck + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/turq/urn + name = "ceruleabaster urn" + output = /obj/item/carvedgem/turq/urn + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/turq/statue + name = "ceruleabaster statue" + output = /obj/item/carvedgem/turq/statue + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/turq/obelisk + name = "ceruleabaster obelisk" + output = /obj/item/carvedgem/turq/obelisk + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/turq/mask + name = "ceruleabaster mask" + output = /obj/item/clothing/face/turqmask + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/turq/ka + name = "ceruleabaster ka statue" + output = /obj/item/carvedgem/turq/ka + craftdiff = 5 + +/datum/repeatable_crafting_recipe/crafting/turq/scarab + name = "ceruleabaster scarab" + output = /obj/item/carvedgem/turq/scarab + craftdiff = 5 + +// aoetal // + +/datum/repeatable_crafting_recipe/crafting/coral + abstract_type = /datum/repeatable_crafting_recipe/crafting/coral + requirements = list( + /obj/item/gem/coral = 1, + ) + tool_usage = list( + /obj/item/weapon/knife = list("carves out the raw aoetal", "carve out the raw aoetal") + ) + attacked_atom = /obj/item/gem/coral + starting_atom = /obj/item/weapon/knife + output_amount = 1 + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/coral/cutgem + name = "cut aoetal gem" + output = /obj/item/carvedgem/coral/cutgem + craftdiff = 0 + +/datum/repeatable_crafting_recipe/crafting/coral/fork + name = "aoetal fork" + output = /obj/item/carvedgem/coral/fork + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/coral/spoon + name = "aoetal spoon" + output = /obj/item/carvedgem/coral/spoon + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/coral/cameo + name = "aoetal cameo" + output = /obj/item/carvedgem/coral/cameo + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/coral/cup + name = "aoetal cup" + output = /obj/item/reagent_containers/glass/cup/coral + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/coral/bowl + name = "aoetal bowl" + output = /obj/item/reagent_containers/glass/bowl/coral + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/coral/figurine + name = "aoetal figurine" + output = /obj/item/carvedgem/coral/figurine + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/coral/fish + name = "aoetal fish figurine" + output = /obj/item/carvedgem/coral/fish + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/coral/vase + name = "aoetal vase" + output = /obj/item/carvedgem/coral/vase + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/coral/tablet + name = "aoetal tablet" + output = /obj/item/carvedgem/coral/tablet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/coral/teapot + name = "aoetal teapot" + output = /obj/item/reagent_containers/glass/carafe/teapot/coral + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/coral/platter + name = "aoetal platter" + output = /obj/item/plate/coral + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/coral/amulet + name = "aoetal amulet" + output = /obj/item/clothing/neck/coralamulet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/coral/ring + name = "aoetal ring" + output = /obj/item/clothing/ring/coral + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/coral/bust + name = "aoetal bust" + output = /obj/item/carvedgem/coral/bust + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/coral/fancyvase + name = "fancy aoetal vase" + output = /obj/item/carvedgem/coral/fancyvase + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/coral/comb + name = "aoetal comb" + output = /obj/item/carvedgem/coral/comb + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/coral/duck + name = "aoetal duck" + output = /obj/item/carvedgem/coral/duck + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/coral/fancycup + name = "fancy aoetal cup" + output = /obj/item/reagent_containers/glass/cup/coralfancy + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/coral/circlet + name = "aoetal circlet" + output = /obj/item/clothing/head/crown/circlet/coral + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/coral/bracelet + name = "aoetal bracelets" + output = /obj/item/clothing/wrists/gem/coralbracelet + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/coral/mask + name = "aoetal mask" + output = /obj/item/clothing/face/coralmask + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/coral/statue + name = "aoetal statue" + output = /obj/item/carvedgem/coral/statue + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/coral/urn + name = "aoetal urn" + output = /obj/item/carvedgem/coral/urn + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/coral/obelisk + name = "aoetal obelisk" + output = /obj/item/carvedgem/coral/obelisk + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/coral/jaw + name = "shark jaw statue" + output = /obj/item/carvedgem/coral/jaw + craftdiff = 5 + +/datum/repeatable_crafting_recipe/crafting/coral/shark + name = "aoetal shark statue" + output = /obj/item/carvedgem/coral/shark + craftdiff = 5 + +// petriamber // + +/datum/repeatable_crafting_recipe/crafting/amber + abstract_type = /datum/repeatable_crafting_recipe/crafting/amber + requirements = list( + /obj/item/gem/amber = 1, + ) + tool_usage = list( + /obj/item/weapon/knife = list("carves out the raw petriamber", "carve out the raw petriamber") + ) + attacked_atom = /obj/item/gem/amber + starting_atom = /obj/item/weapon/knife + output_amount = 1 + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/amber/cutgem + name = "cut petriamber gem" + output = /obj/item/carvedgem/amber/cutgem + craftdiff = 0 + +/datum/repeatable_crafting_recipe/crafting/amber/spoon + name = "petriamber spoon" + output = /obj/item/carvedgem/amber/spoon + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/amber/fork + name = "petriamber fork" + output = /obj/item/carvedgem/amber/fork + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/amber/cameo + name = "petriamber cameo" + output = /obj/item/carvedgem/amber/cameo + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/amber/bowl + name = "petriamber bowl" + output = /obj/item/reagent_containers/glass/bowl/amber + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/amber/cup + name = "petriamber cup" + output = /obj/item/reagent_containers/glass/cup/amber + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/amber/figurine + name = "petriamber figurine" + output = /obj/item/carvedgem/amber/figurine + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/amber/fish + name = "petriamber fish figurine" + output = /obj/item/carvedgem/amber/fish + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/amber/tablet + name = "petriamber tablet" + output = /obj/item/carvedgem/amber/tablet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/amber/vase + name = "petriamber vase" + output = /obj/item/carvedgem/amber/vase + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/amber/teapot + name = "petriamber teapot" + output = /obj/item/reagent_containers/glass/carafe/teapot/amber + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/amber/platter + name = "petriamber platter" + output = /obj/item/plate/amber + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/amber/ring + name = "petriamber ring" + output = /obj/item/clothing/ring/amber + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/amber/amulet + name = "petriamber amulet" + output = /obj/item/clothing/neck/amberamulet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/amber/bracelet + name = "petriamber bracelets" + output = /obj/item/clothing/wrists/gem/amberbracelet + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/amber/circlet + name = "petriamber circlet" + output = /obj/item/clothing/head/crown/circlet/amber + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/amber/fancycup + name = "fancy petriamber cup" + output = /obj/item/reagent_containers/glass/cup/amberfancy + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/amber/fancyvase + name = "fancy petriamber vase" + output = /obj/item/carvedgem/amber/fancyvase + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/amber/bust + name = "petriamber bust" + output = /obj/item/carvedgem/amber/bust + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/amber/comb + name = "petriamber comb" + output = /obj/item/carvedgem/amber/comb + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/amber/duck + name = "petriamber duck" + output = /obj/item/carvedgem/amber/duck + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/amber/mask + name = "petriamber mask" + output = /obj/item/clothing/face/ambermask + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/amber/obelisk + name = "petriamber obelisk" + output = /obj/item/carvedgem/amber/obelisk + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/amber/urn + name = "petriamber urn" + output = /obj/item/carvedgem/amber/urn + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/amber/statue + name = "petriamber statue" + output = /obj/item/carvedgem/amber/statue + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/amber/beaver + name = "petriamber beaver statue" + output = /obj/item/carvedgem/amber/beaver + craftdiff = 5 + +/datum/repeatable_crafting_recipe/crafting/amber/sun + name = "petriamber sun carving" + output = /obj/item/carvedgem/amber/sun + craftdiff = 5 + +// opaloise // + +/datum/repeatable_crafting_recipe/crafting/opal + abstract_type = /datum/repeatable_crafting_recipe/crafting/opal + requirements = list( + /obj/item/gem/opal = 1, + ) + tool_usage = list( + /obj/item/weapon/knife = list("carves out the raw opaloise", "carve out the raw opaloise") + ) + attacked_atom = /obj/item/gem/opal + starting_atom = /obj/item/weapon/knife + output_amount = 1 + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/opal/cutgem + name = "cut opaloise gem" + output = /obj/item/carvedgem/opal/cutgem + craftdiff = 0 + +/datum/repeatable_crafting_recipe/crafting/opal/spoon + name = "opaloise spoon" + output = /obj/item/carvedgem/opal/spoon + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/opal/fork + name = "opaloise fork" + output = /obj/item/carvedgem/opal/fork + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/opal/cameo + name = "opaloise cameo" + output = /obj/item/carvedgem/opal/cameo + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/opal/bowl + name = "opaloise bowl" + output = /obj/item/reagent_containers/glass/bowl/opal + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/opal/cup + name = "opaloise cup" + output = /obj/item/reagent_containers/glass/cup/opal + craftdiff = 1 + +/datum/repeatable_crafting_recipe/crafting/opal/teapot + name = "opaloise teapot" + output = /obj/item/reagent_containers/glass/carafe/teapot/opal + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/opal/platter + name = "opaloise platter" + output = /obj/item/plate/opal + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/opal/ring + name = "opaloise ring" + output = /obj/item/clothing/ring/opal + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/opal/amulet + name = "opaloise amulet" + output = /obj/item/clothing/neck/opalamulet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/opal/figurine + name = "opaloise figurine" + output = /obj/item/carvedgem/opal/figurine + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/opal/fish + name = "opaloise fish figurine" + output = /obj/item/carvedgem/opal/fish + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/opal/vase + name = "opaloise vase" + output = /obj/item/carvedgem/opal/vase + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/opal/tablet + name = "opaloise tablet" + output = /obj/item/carvedgem/opal/tablet + craftdiff = 2 + +/datum/repeatable_crafting_recipe/crafting/opal/bracelet + name = "opaloise bracelets" + output = /obj/item/clothing/wrists/gem/opalbracelet + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/opal/circlet + name = "opaloise circlet" + output = /obj/item/clothing/head/crown/circlet/opal + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/opal/fancycup + name = "fancy opaloise cup" + output = /obj/item/reagent_containers/glass/cup/opalfancy + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/opal/bust + name = "opaloise bust" + output = /obj/item/carvedgem/opal/bust + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/opal/fancyvase + name = "fancy opaloise vase" + output = /obj/item/carvedgem/opal/fancyvase + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/opal/comb + name = "opaloise comb" + output = /obj/item/carvedgem/opal/comb + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/opal/duck + name = "opaloise duck" + output = /obj/item/carvedgem/opal/duck + craftdiff = 3 + +/datum/repeatable_crafting_recipe/crafting/opal/mask + name = "opaloise mask" + output = /obj/item/clothing/face/opalmask + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/opal/obelisk + name = "opaloise obelisk" + output = /obj/item/carvedgem/opal/obelisk + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/opal/urn + name = "opaloise urn" + output = /obj/item/carvedgem/opal/urn + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/opal/statue + name = "opaloise statue" + output = /obj/item/carvedgem/opal/statue + craftdiff = 4 + +/datum/repeatable_crafting_recipe/crafting/opal/crab + name = "opaloise crab sculpture" + output = /obj/item/carvedgem/opal/crab + craftdiff = 5 + +/datum/repeatable_crafting_recipe/crafting/opal/knife + name = "opaloise knife" + output = /obj/item/weapon/knife/stone/opal + craftdiff = 5 diff --git a/code/modules/crafting/quality_of_crafting/cooking/cooking_base.dm b/code/modules/crafting/quality_of_crafting/cooking/cooking_base.dm index 3bb23a5ae6a..163dd3e11ae 100644 --- a/code/modules/crafting/quality_of_crafting/cooking/cooking_base.dm +++ b/code/modules/crafting/quality_of_crafting/cooking/cooking_base.dm @@ -123,11 +123,8 @@ /datum/repeatable_crafting_recipe/cooking/proc/apply_food_quality(obj/item/reagent_containers/food/snacks/food_item, cooking_skill, ingredient_quality, freshness) var/datum/quality_calculator/cooking/cook_calc = new( - base_qual = 0, mat_qual = ingredient_quality, skill_qual = cooking_skill, - perf_qual = 0, - diff_mod = 0, components = 1, fresh = freshness, recipe_mod = quality_modifier diff --git a/code/modules/crafting/quality_of_crafting/crafting.dm b/code/modules/crafting/quality_of_crafting/crafting.dm index 8631de1bdda..5c4597c13eb 100644 --- a/code/modules/crafting/quality_of_crafting/crafting.dm +++ b/code/modules/crafting/quality_of_crafting/crafting.dm @@ -883,1248 +883,3 @@ ) attacked_atom = /obj/item/natural/cloth starting_atom = /obj/item/weapon/knife - -// -------------------------- Gems ------------------------------ // - -// jade // - -/datum/repeatable_crafting_recipe/crafting/jade - abstract_type = /datum/repeatable_crafting_recipe/crafting/jade - requirements = list( - /obj/item/gem/jade = 1, - ) - tool_usage = list( - /obj/item/weapon/knife = list("starts to carve out the raw joapstone", "start to carve the raw joapstone") - ) - attacked_atom = /obj/item/gem/jade - starting_atom = /obj/item/weapon/knife - output_amount = 1 - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/jade/cutgem - name = "cut joapstone gem" - output = /obj/item/carvedgem/jade/cutgem - craftdiff = 0 - -/datum/repeatable_crafting_recipe/crafting/jade/fork - name = "joapstone fork" - output = /obj/item/carvedgem/jade/fork - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/jade/spoon - name = "joapstone spoon" - output = /obj/item/carvedgem/jade/spoon - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/jade/cameo - name = "joapstone cameo" - output = /obj/item/carvedgem/jade/cameo - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/jade/bowl - name = "joapstone bowl" - output = /obj/item/reagent_containers/glass/bowl/jade - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/jade/cup - name = "joapstone cup" - output = /obj/item/reagent_containers/glass/cup/jade - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/jade/platter - name = "joapstone platter" - output = /obj/item/plate/jade - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/jade/ring - name = "joapstone ring" - output = /obj/item/clothing/ring/jade - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/jade/amulet - name = "joapstone amulet" - output = /obj/item/clothing/neck/jadeamulet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/jade/vase - name = "joapstone vase" - output = /obj/item/carvedgem/jade/vase - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/jade/figurine - name = "joapstone figurine" - output = /obj/item/carvedgem/jade/figurine - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/jade/fish - name = "joapstone fish figurine" - output = /obj/item/carvedgem/jade/fish - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/jade/tablet - name = "joapstone tablet" - output = /obj/item/carvedgem/jade/tablet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/jade/teapot - name = "joapstone teapot" - output = /obj/item/reagent_containers/glass/carafe/teapot/jade - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/jade/bust - name = "joapstone bust" - output = /obj/item/carvedgem/jade/bust - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/jade/fancyvase - name = "fancy joapstone vase" - output = /obj/item/carvedgem/jade/fancyvase - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/jade/comb - name = "joapstone comb" - output = /obj/item/carvedgem/jade/comb - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/jade/duck - name = "joapstone duck" - output = /obj/item/carvedgem/jade/duck - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/jade/bracelet - name = "joapstone bracelets" - output = /obj/item/clothing/wrists/gem/jadebracelet - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/jade/circlet - name = "joapstone circlet" - output = /obj/item/clothing/head/crown/circlet/jade - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/jade/fancycup - name = "fancy joapstone cup" - output = /obj/item/reagent_containers/glass/cup/jadefancy - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/jade/mask - name = "joapstone mask" - output = /obj/item/clothing/face/jademask - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/jade/urn - name = "joapstone urn" - output = /obj/item/carvedgem/jade/urn - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/jade/statue - name = "joapstone statue" - output = /obj/item/carvedgem/jade/statue - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/jade/obelisk - name = "joapstone obelisk" - output = /obj/item/carvedgem/jade/obelisk - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/jade/wyrm - name = "joapstone wyrm" - output = /obj/item/carvedgem/jade/wyrm - craftdiff = 5 - - -/datum/repeatable_crafting_recipe/crafting/jade/kukri - name = "joapstone kukri" - output = /obj/item/weapon/knife/stone/kukri - craftdiff = 5 - -// shell // - -/datum/repeatable_crafting_recipe/crafting/shell - abstract_type = /datum/repeatable_crafting_recipe/crafting/shell - requirements = list( - /obj/item/carvedgem/shell/rawshell = 1, - ) - tool_usage = list( - /obj/item/weapon/knife = list("starts to carve out the clam shell", "start to carve out the clam shell") - ) - attacked_atom = /obj/item/carvedgem/shell/rawshell - starting_atom = /obj/item/weapon/knife - output_amount = 1 - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/shell/openclam - name = "opened clam" - output = list ( - /obj/item/carvedgem/shell/openoyster, - /obj/item/carvedgem/rose/rawrose - ) - - requirements = list( - /obj/item/gem/oyster = 1 - ) - tool_usage = list( - /obj/item/weapon/knife = list("starts to pry open the clam shell", "pry open the clam shell") - ) - attacked_atom = /obj/item/gem/oyster - starting_atom = /obj/item/weapon/knife - output_amount = 1 - craftdiff = 0 - -/datum/repeatable_crafting_recipe/crafting/shell/rawshell - - name = "2x clam shells " - output = /obj/item/carvedgem/shell/rawshell - requirements = list( - /obj/item/carvedgem/shell/openoyster = 1 - ) - tool_usage = list( - /obj/item/weapon/knife = list("starts to pull apart the clam shell", "pull apart the clam shell") - ) - attacked_atom = /obj/item/carvedgem/shell/openoyster - starting_atom = /obj/item/weapon/knife - output_amount = 2 - craftdiff = 0 - -/datum/repeatable_crafting_recipe/crafting/shell/cutgem - name = "polished clam shell" - output = /obj/item/carvedgem/shell/cutgem - craftdiff = 0 - -/datum/repeatable_crafting_recipe/crafting/shell/fork - name = "shell fork" - output = /obj/item/carvedgem/shell/fork - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/shell/spoon - name = "shell spoon" - output = /obj/item/carvedgem/shell/spoon - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/shell/cameo - name = "shell cameo" - output = /obj/item/carvedgem/shell/cameo - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/shell/bowl - name = "shell bowl" - output = /obj/item/reagent_containers/glass/bowl/shell - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/shell/cup - name = "shell cup" - output = /obj/item/reagent_containers/glass/cup/shell - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/shell/platter - name = "shell platter" - output = /obj/item/plate/shell - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/shell/ring - name = "shell ring" - output = /obj/item/clothing/ring/shell - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/shell/teapot - name = "shell teapot" - output = /obj/item/reagent_containers/glass/carafe/teapot/shell - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/shell/amulet - name = "shell amulet" - output = /obj/item/clothing/neck/shellamulet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/shell/figurine - name = "shell figurine" - output = /obj/item/carvedgem/shell/figurine - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/shell/tablet - name = "shell tablet" - output = /obj/item/carvedgem/shell/tablet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/shell/fish - name = "shell fish figurine" - output = /obj/item/carvedgem/shell/fish - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/shell/vase - name = "shell vase" - output = /obj/item/carvedgem/shell/vase - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/shell/bust - name = "shell bust" - output = /obj/item/carvedgem/shell/bust - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/shell/circlet - name = "shell circlet" - output = /obj/item/clothing/head/crown/circlet/shell - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/shell/bracelet - name = "shell bracelets" - output = /obj/item/clothing/wrists/gem/shellbracelet - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/shell/fancycup - name = "fancy shell cup" - output = /obj/item/reagent_containers/glass/cup/shellfancy - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/shell/fancyvase - name = "fancy shell vase" - output = /obj/item/carvedgem/shell/fancyvase - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/shell/comb - name = "shell comb" - output = /obj/item/carvedgem/shell/comb - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/shell/duck - name = "shell duck" - output = /obj/item/carvedgem/shell/duck - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/shell/mask - name = "shell mask" - output = /obj/item/clothing/face/shellmask - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/shell/urn - name = "shell urn" - output = /obj/item/carvedgem/shell/urn - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/shell/statue - name = "shell statue" - output = /obj/item/carvedgem/shell/statue - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/shell/obelisk - name = "shell obelisk" - output = /obj/item/carvedgem/shell/obelisk - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/shell/turtle - name = "turtle carving" - output = /obj/item/carvedgem/shell/turtle - craftdiff = 5 - -/datum/repeatable_crafting_recipe/crafting/shell/rungu - name = "shell rungu" - output = /obj/item/weapon/mace/cudgel/shellrungu - craftdiff = 5 - -// rose // - -/datum/repeatable_crafting_recipe/crafting/rose - abstract_type = /datum/repeatable_crafting_recipe/crafting/rose - requirements = list( - /obj/item/carvedgem/rose/rawrose = 1, - ) - tool_usage = list( - /obj/item/weapon/knife = list("carves the rosellusk pearl", "carve the rosellusk pearl") - ) - attacked_atom = /obj/item/carvedgem/rose/rawrose - starting_atom = /obj/item/weapon/knife - output_amount = 1 - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/rose/cutgem - name = "rosellusk pearl" - output = /obj/item/carvedgem/rose/cutgem - requirements = list( - /obj/item/carvedgem/rose/rawrose = 1, - ) - tool_usage = list( - /obj/item/weapon/knife = list("refines the rosellusk pearl", "refine the rosellusk pearl") - ) - attacked_atom = /obj/item/carvedgem/rose/rawrose - starting_atom = /obj/item/weapon/knife - output_amount = 1 - craftdiff = 0 - -/datum/repeatable_crafting_recipe/crafting/rose/spoon - name = "rosellusk spoon" - output = /obj/item/carvedgem/rose/spoon - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/rose/fork - name = "rosellusk fork" - output = /obj/item/carvedgem/rose/fork - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/rose/cup - name = "rosellusk cup" - output = /obj/item/reagent_containers/glass/cup/rose - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/rose/bowl - name = "rosellusk bowl" - output = /obj/item/reagent_containers/glass/bowl/rose - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/rose/cameo - name = "rosellusk cameo" - output = /obj/item/carvedgem/rose/cameo - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/rose/figurine - name = "rosellusk figurine" - output = /obj/item/carvedgem/rose/figurine - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/rose/fish - name = "rosellusk fish figurine" - output = /obj/item/carvedgem/rose/fish - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/rose/vase - name = "rosellusk vase" - output = /obj/item/carvedgem/rose/vase - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/rose/tablet - name = "rosellusk tablet" - output = /obj/item/carvedgem/rose/tablet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/rose/teapot - name = "rosellusk teapot" - output = /obj/item/reagent_containers/glass/carafe/teapot/rose - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/rose/ring - name = "rosellusk ring" - output = /obj/item/clothing/ring/rose - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/rose/amulet - name = "rosellusk amulet" - output = /obj/item/clothing/neck/roseamulet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/rose/platter - name = "rosellusk platter" - output = /obj/item/plate/rose - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/rose/bust - name = "rosellusk bust" - output = /obj/item/carvedgem/rose/bust - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/rose/fancyvase - name = "fancy rosellusk vase" - output = /obj/item/carvedgem/rose/fancyvase - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/rose/comb - name = "rosellusk comb" - output = /obj/item/carvedgem/rose/comb - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/rose/duck - name = "rosellusk duck" - output = /obj/item/carvedgem/rose/duck - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/rose/bracelet - name = "rosellusk bracelets" - output = /obj/item/clothing/wrists/gem/rosebracelet - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/rose/circlet - name = "rosellusk circlet" - output = /obj/item/clothing/head/crown/circlet/rose - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/rose/fancycup - name = "fancy rosellusk cup" - output = /obj/item/reagent_containers/glass/cup/rosefancy - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/rose/urn - name = "rosellusk urn" - output = /obj/item/carvedgem/rose/urn - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/rose/statue - name = "rosellusk statue" - output = /obj/item/carvedgem/rose/statue - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/rose/obelisk - name = "rosellusk obelisk" - output = /obj/item/carvedgem/rose/obelisk - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/rose/mask - name = "rosellusk mask" - output = /obj/item/clothing/face/rosemask - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/rose/flower - name = "rosellusk flower carving" - output = /obj/item/carvedgem/rose/flower - craftdiff = 5 - -/datum/repeatable_crafting_recipe/crafting/rose/carp - name = "rosellusk carp statue" - output = /obj/item/carvedgem/rose/carp - craftdiff = 5 - -// onyxa // - -/datum/repeatable_crafting_recipe/crafting/onyxa - abstract_type = /datum/repeatable_crafting_recipe/crafting/onyxa - requirements = list( - /obj/item/gem/onyxa = 1, - ) - tool_usage = list( - /obj/item/weapon/knife = list("carves out the onyxa", "carve out the onyxa") - ) - attacked_atom = /obj/item/gem/onyxa - starting_atom = /obj/item/weapon/knife - output_amount = 1 - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/onyxa/cutgem - name = "cut onyxa gem" - output = /obj/item/carvedgem/onyxa/cutgem - craftdiff = 0 - -/datum/repeatable_crafting_recipe/crafting/onyxa/fork - name = "onyxa fork" - output = /obj/item/carvedgem/onyxa/fork - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/onyxa/spoon - name = "onyxa spoon" - output = /obj/item/carvedgem/onyxa/spoon - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/onyxa/cameo - name = "onyxa cameo" - output = /obj/item/carvedgem/onyxa/cameo - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/onyxa/cup - name = "onyxa cup" - output = /obj/item/reagent_containers/glass/cup/onyxa - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/onyxa/bowl - name = "onyxa bowl" - output = /obj/item/reagent_containers/glass/bowl/onyxa - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/onyxa/figurine - name = "onyxa figurine" - output = /obj/item/carvedgem/onyxa/figurine - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/onyxa/fish - name = "onyxa fish figurine" - output = /obj/item/carvedgem/onyxa/fish - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/onyxa/vase - name = "onyxa vase" - output = /obj/item/carvedgem/onyxa/vase - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/onyxa/tablet - name = "onyxa tablet" - output = /obj/item/carvedgem/onyxa/tablet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/onyxa/teapot - name = "onyxa teapot" - output = /obj/item/reagent_containers/glass/carafe/teapot/onyxa - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/onyxa/ring - name = "onyxa ring" - output = /obj/item/clothing/ring/onyxa - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/onyxa/amulet - name = "onyxa amulet" - output = /obj/item/clothing/neck/onyxaamulet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/onyxa/platter - name = "onyxa platter" - output = /obj/item/plate/onyxa - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/onyxa/bust - name = "onyxa bust" - output = /obj/item/carvedgem/onyxa/bust - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/onyxa/fancyvase - name = "fancy onyxa vase" - output = /obj/item/carvedgem/onyxa/fancyvase - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/onyxa/comb - name = "onyxa comb" - output = /obj/item/carvedgem/onyxa/comb - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/onyxa/duck - name = "onyxa duck" - output = /obj/item/carvedgem/onyxa/duck - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/onyxa/fancycup - name = "fancy onyxa cup" - output = /obj/item/reagent_containers/glass/cup/onyxafancy - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/onyxa/bracelet - name = "onyxa bracelets" - output = /obj/item/clothing/wrists/gem/onyxabracelet - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/onyxa/circlet - name = "onyxa circlet" - output = /obj/item/clothing/head/crown/circlet/onyxa - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/onyxa/mask - name = "onyxa mask" - output = /obj/item/clothing/face/onyxamask - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/onyxa/urn - name = "onyxa urn" - output = /obj/item/carvedgem/onyxa/urn - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/onyxa/statue - name = "onyxa statue" - output = /obj/item/carvedgem/onyxa/statue - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/onyxa/obelisk - name = "onyxa obelisk" - output = /obj/item/carvedgem/onyxa/obelisk - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/onyxa/urn - name = "onyxa urn" - output = /obj/item/carvedgem/onyxa/urn - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/onyxa/spider - name = "onyxa spider statue" - output = /obj/item/carvedgem/onyxa/spider - craftdiff = 5 - -/datum/repeatable_crafting_recipe/crafting/onyxa/snake - name = "onyxa snake statue" - output = /obj/item/carvedgem/onyxa/snake - craftdiff = 5 - -// ceruleabaster // - -/datum/repeatable_crafting_recipe/crafting/turq - abstract_type = /datum/repeatable_crafting_recipe/crafting/turq - requirements = list( - /obj/item/gem/turq = 1, - ) - tool_usage = list( - /obj/item/weapon/knife = list("carves out the raw ceruleabaster", "carve out the raw ceruleabaster") - ) - attacked_atom = /obj/item/gem/turq - starting_atom = /obj/item/weapon/knife - output_amount = 1 - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/turq/cutgem - name = "cut ceruleabaster gem" - output = /obj/item/carvedgem/turq/cutgem - craftdiff = 0 - -/datum/repeatable_crafting_recipe/crafting/turq/fork - name = "ceruleabaster fork" - output = /obj/item/carvedgem/turq/fork - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/turq/spoon - name = "ceruleabaster spoon" - output = /obj/item/carvedgem/turq/spoon - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/turq/cameo - name = "ceruleabaster cameo" - output = /obj/item/carvedgem/turq/cameo - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/turq/bowl - name = "ceruleabaster bowl" - output = /obj/item/reagent_containers/glass/bowl/turq - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/turq/cup - name = "ceruleabaster cup" - output = /obj/item/reagent_containers/glass/cup/turq - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/turq/figurine - name = "ceruleabaster figurine" - output = /obj/item/carvedgem/turq/figurine - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/turq/fish - name = "ceruleabaster fish figurine" - output = /obj/item/carvedgem/turq/fish - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/turq/vase - name = "ceruleabaster vase" - output = /obj/item/carvedgem/turq/vase - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/turq/amulet - name = "ceruleabaster amulet" - output = /obj/item/clothing/neck/turqamulet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/turq/tablet - name = "ceruleabaster tablet" - output = /obj/item/carvedgem/turq/tablet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/turq/ring - name = "ceruleabaster ring" - output = /obj/item/clothing/ring/turq - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/turq/platter - name = "ceruleabaster platter" - output = /obj/item/plate/turq - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/turq/bracelet - name = "ceruleabaster bracelets" - output = /obj/item/clothing/wrists/gem/turqbracelet - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/turq/circlet - name = "ceruleabaster circlet" - output = /obj/item/clothing/head/crown/circlet/turq - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/turq/fancycup - name = "fancy ceruleabaster cup" - output = /obj/item/reagent_containers/glass/cup/turqfancy - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/turq/fancyvase - name = "fancy ceruleabaster vase" - output = /obj/item/carvedgem/turq/fancyvase - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/turq/bust - name = "ceruleabaster bust" - output = /obj/item/carvedgem/turq/bust - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/turq/comb - name = "ceruleabaster comb" - output = /obj/item/carvedgem/turq/comb - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/turq/duck - name = "ceruleabaster duck" - output = /obj/item/carvedgem/turq/duck - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/turq/urn - name = "ceruleabaster urn" - output = /obj/item/carvedgem/turq/urn - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/turq/statue - name = "ceruleabaster statue" - output = /obj/item/carvedgem/turq/statue - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/turq/obelisk - name = "ceruleabaster obelisk" - output = /obj/item/carvedgem/turq/obelisk - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/turq/mask - name = "ceruleabaster mask" - output = /obj/item/clothing/face/turqmask - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/turq/ka - name = "ceruleabaster ka statue" - output = /obj/item/carvedgem/turq/ka - craftdiff = 5 - -/datum/repeatable_crafting_recipe/crafting/turq/scarab - name = "ceruleabaster scarab" - output = /obj/item/carvedgem/turq/scarab - craftdiff = 5 - -// aoetal // - -/datum/repeatable_crafting_recipe/crafting/coral - abstract_type = /datum/repeatable_crafting_recipe/crafting/coral - requirements = list( - /obj/item/gem/coral = 1, - ) - tool_usage = list( - /obj/item/weapon/knife = list("carves out the raw aoetal", "carve out the raw aoetal") - ) - attacked_atom = /obj/item/gem/coral - starting_atom = /obj/item/weapon/knife - output_amount = 1 - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/coral/cutgem - name = "cut aoetal gem" - output = /obj/item/carvedgem/coral/cutgem - craftdiff = 0 - -/datum/repeatable_crafting_recipe/crafting/coral/fork - name = "aoetal fork" - output = /obj/item/carvedgem/coral/fork - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/coral/spoon - name = "aoetal spoon" - output = /obj/item/carvedgem/coral/spoon - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/coral/cameo - name = "aoetal cameo" - output = /obj/item/carvedgem/coral/cameo - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/coral/cup - name = "aoetal cup" - output = /obj/item/reagent_containers/glass/cup/coral - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/coral/bowl - name = "aoetal bowl" - output = /obj/item/reagent_containers/glass/bowl/coral - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/coral/figurine - name = "aoetal figurine" - output = /obj/item/carvedgem/coral/figurine - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/coral/fish - name = "aoetal fish figurine" - output = /obj/item/carvedgem/coral/fish - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/coral/vase - name = "aoetal vase" - output = /obj/item/carvedgem/coral/vase - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/coral/tablet - name = "aoetal tablet" - output = /obj/item/carvedgem/coral/tablet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/coral/teapot - name = "aoetal teapot" - output = /obj/item/reagent_containers/glass/carafe/teapot/coral - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/coral/platter - name = "aoetal platter" - output = /obj/item/plate/coral - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/coral/amulet - name = "aoetal amulet" - output = /obj/item/clothing/neck/coralamulet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/coral/ring - name = "aoetal ring" - output = /obj/item/clothing/ring/coral - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/coral/bust - name = "aoetal bust" - output = /obj/item/carvedgem/coral/bust - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/coral/fancyvase - name = "fancy aoetal vase" - output = /obj/item/carvedgem/coral/fancyvase - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/coral/comb - name = "aoetal comb" - output = /obj/item/carvedgem/coral/comb - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/coral/duck - name = "aoetal duck" - output = /obj/item/carvedgem/coral/duck - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/coral/fancycup - name = "fancy aoetal cup" - output = /obj/item/reagent_containers/glass/cup/coralfancy - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/coral/circlet - name = "aoetal circlet" - output = /obj/item/clothing/head/crown/circlet/coral - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/coral/bracelet - name = "aoetal bracelets" - output = /obj/item/clothing/wrists/gem/coralbracelet - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/coral/mask - name = "aoetal mask" - output = /obj/item/clothing/face/coralmask - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/coral/statue - name = "aoetal statue" - output = /obj/item/carvedgem/coral/statue - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/coral/urn - name = "aoetal urn" - output = /obj/item/carvedgem/coral/urn - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/coral/obelisk - name = "aoetal obelisk" - output = /obj/item/carvedgem/coral/obelisk - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/coral/jaw - name = "shark jaw statue" - output = /obj/item/carvedgem/coral/jaw - craftdiff = 5 - -/datum/repeatable_crafting_recipe/crafting/coral/shark - name = "aoetal shark statue" - output = /obj/item/carvedgem/coral/shark - craftdiff = 5 - -// petriamber // - -/datum/repeatable_crafting_recipe/crafting/amber - abstract_type = /datum/repeatable_crafting_recipe/crafting/amber - requirements = list( - /obj/item/gem/amber = 1, - ) - tool_usage = list( - /obj/item/weapon/knife = list("carves out the raw petriamber", "carve out the raw petriamber") - ) - attacked_atom = /obj/item/gem/amber - starting_atom = /obj/item/weapon/knife - output_amount = 1 - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/amber/cutgem - name = "cut petriamber gem" - output = /obj/item/carvedgem/amber/cutgem - craftdiff = 0 - -/datum/repeatable_crafting_recipe/crafting/amber/spoon - name = "petriamber spoon" - output = /obj/item/carvedgem/amber/spoon - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/amber/fork - name = "petriamber fork" - output = /obj/item/carvedgem/amber/fork - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/amber/cameo - name = "petriamber cameo" - output = /obj/item/carvedgem/amber/cameo - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/amber/bowl - name = "petriamber bowl" - output = /obj/item/reagent_containers/glass/bowl/amber - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/amber/cup - name = "petriamber cup" - output = /obj/item/reagent_containers/glass/cup/amber - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/amber/figurine - name = "petriamber figurine" - output = /obj/item/carvedgem/amber/figurine - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/amber/fish - name = "petriamber fish figurine" - output = /obj/item/carvedgem/amber/fish - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/amber/tablet - name = "petriamber tablet" - output = /obj/item/carvedgem/amber/tablet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/amber/vase - name = "petriamber vase" - output = /obj/item/carvedgem/amber/vase - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/amber/teapot - name = "petriamber teapot" - output = /obj/item/reagent_containers/glass/carafe/teapot/amber - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/amber/platter - name = "petriamber platter" - output = /obj/item/plate/amber - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/amber/ring - name = "petriamber ring" - output = /obj/item/clothing/ring/amber - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/amber/amulet - name = "petriamber amulet" - output = /obj/item/clothing/neck/amberamulet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/amber/bracelet - name = "petriamber bracelets" - output = /obj/item/clothing/wrists/gem/amberbracelet - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/amber/circlet - name = "petriamber circlet" - output = /obj/item/clothing/head/crown/circlet/amber - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/amber/fancycup - name = "fancy petriamber cup" - output = /obj/item/reagent_containers/glass/cup/amberfancy - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/amber/fancyvase - name = "fancy petriamber vase" - output = /obj/item/carvedgem/amber/fancyvase - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/amber/bust - name = "petriamber bust" - output = /obj/item/carvedgem/amber/bust - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/amber/comb - name = "petriamber comb" - output = /obj/item/carvedgem/amber/comb - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/amber/duck - name = "petriamber duck" - output = /obj/item/carvedgem/amber/duck - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/amber/mask - name = "petriamber mask" - output = /obj/item/clothing/face/ambermask - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/amber/obelisk - name = "petriamber obelisk" - output = /obj/item/carvedgem/amber/obelisk - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/amber/urn - name = "petriamber urn" - output = /obj/item/carvedgem/amber/urn - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/amber/statue - name = "petriamber statue" - output = /obj/item/carvedgem/amber/statue - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/amber/beaver - name = "petriamber beaver statue" - output = /obj/item/carvedgem/amber/beaver - craftdiff = 5 - -/datum/repeatable_crafting_recipe/crafting/amber/sun - name = "petriamber sun carving" - output = /obj/item/carvedgem/amber/sun - craftdiff = 5 - -// opaloise // - -/datum/repeatable_crafting_recipe/crafting/opal - abstract_type = /datum/repeatable_crafting_recipe/crafting/opal - requirements = list( - /obj/item/gem/opal = 1, - ) - tool_usage = list( - /obj/item/weapon/knife = list("carves out the raw opaloise", "carve out the raw opaloise") - ) - attacked_atom = /obj/item/gem/opal - starting_atom = /obj/item/weapon/knife - output_amount = 1 - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/opal/cutgem - name = "cut opaloise gem" - output = /obj/item/carvedgem/opal/cutgem - craftdiff = 0 - -/datum/repeatable_crafting_recipe/crafting/opal/spoon - name = "opaloise spoon" - output = /obj/item/carvedgem/opal/spoon - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/opal/fork - name = "opaloise fork" - output = /obj/item/carvedgem/opal/fork - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/opal/cameo - name = "opaloise cameo" - output = /obj/item/carvedgem/opal/cameo - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/opal/bowl - name = "opaloise bowl" - output = /obj/item/reagent_containers/glass/bowl/opal - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/opal/cup - name = "opaloise cup" - output = /obj/item/reagent_containers/glass/cup/opal - craftdiff = 1 - -/datum/repeatable_crafting_recipe/crafting/opal/teapot - name = "opaloise teapot" - output = /obj/item/reagent_containers/glass/carafe/teapot/opal - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/opal/platter - name = "opaloise platter" - output = /obj/item/plate/opal - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/opal/ring - name = "opaloise ring" - output = /obj/item/clothing/ring/opal - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/opal/amulet - name = "opaloise amulet" - output = /obj/item/clothing/neck/opalamulet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/opal/figurine - name = "opaloise figurine" - output = /obj/item/carvedgem/opal/figurine - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/opal/fish - name = "opaloise fish figurine" - output = /obj/item/carvedgem/opal/fish - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/opal/vase - name = "opaloise vase" - output = /obj/item/carvedgem/opal/vase - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/opal/tablet - name = "opaloise tablet" - output = /obj/item/carvedgem/opal/tablet - craftdiff = 2 - -/datum/repeatable_crafting_recipe/crafting/opal/bracelet - name = "opaloise bracelets" - output = /obj/item/clothing/wrists/gem/opalbracelet - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/opal/circlet - name = "opaloise circlet" - output = /obj/item/clothing/head/crown/circlet/opal - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/opal/fancycup - name = "fancy opaloise cup" - output = /obj/item/reagent_containers/glass/cup/opalfancy - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/opal/bust - name = "opaloise bust" - output = /obj/item/carvedgem/opal/bust - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/opal/fancyvase - name = "fancy opaloise vase" - output = /obj/item/carvedgem/opal/fancyvase - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/opal/comb - name = "opaloise comb" - output = /obj/item/carvedgem/opal/comb - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/opal/duck - name = "opaloise duck" - output = /obj/item/carvedgem/opal/duck - craftdiff = 3 - -/datum/repeatable_crafting_recipe/crafting/opal/mask - name = "opaloise mask" - output = /obj/item/clothing/face/opalmask - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/opal/obelisk - name = "opaloise obelisk" - output = /obj/item/carvedgem/opal/obelisk - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/opal/urn - name = "opaloise urn" - output = /obj/item/carvedgem/opal/urn - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/opal/statue - name = "opaloise statue" - output = /obj/item/carvedgem/opal/statue - craftdiff = 4 - -/datum/repeatable_crafting_recipe/crafting/opal/crab - name = "opaloise crab sculpture" - output = /obj/item/carvedgem/opal/crab - craftdiff = 5 - -/datum/repeatable_crafting_recipe/crafting/opal/knife - name = "opaloise knife" - output = /obj/item/weapon/knife/stone/opal - craftdiff = 5 diff --git a/code/modules/crafting/quality_of_crafting/how_do_i_craft_this.dm b/code/modules/crafting/quality_of_crafting/how_do_i_craft_this.dm index 9daac38e271..054aad0da94 100644 --- a/code/modules/crafting/quality_of_crafting/how_do_i_craft_this.dm +++ b/code/modules/crafting/quality_of_crafting/how_do_i_craft_this.dm @@ -401,8 +401,8 @@ var/list/ingredients = list() - if(recipe.req_bar) - ingredients += recipe.req_bar + if(recipe.required_material) + ingredients += recipe.required_material if(recipe.additional_items) for(var/item in recipe.additional_items) @@ -412,7 +412,7 @@ recipe.created_item, recipe_path, "anvil", - recipe.recipe_name || recipe.name, + recipe.name, ingredients, list( "category" = recipe.category, @@ -420,7 +420,7 @@ "skill_required" = recipe.appro_skill, "materials_needed" = recipe.num_of_materials, "rotations_required" = recipe.rotations_required, - "created_count" = recipe.createditem_extra + 1 + "created_count" = recipe.output_amount ) ) diff --git a/code/modules/crafting/slapcrafting/orderless/orderless_food.dm b/code/modules/crafting/slapcrafting/orderless/orderless_food.dm index e4435202581..20d390b9af6 100644 --- a/code/modules/crafting/slapcrafting/orderless/orderless_food.dm +++ b/code/modules/crafting/slapcrafting/orderless/orderless_food.dm @@ -29,11 +29,8 @@ new_item.warming = min(5 MINUTES, average_freshness) var/datum/quality_calculator/cooking/cook_calc = new( - base_qual = 0, mat_qual = highest_quality, skill_qual = cooking_skill, - perf_qual = 0, - diff_mod = 0, components = 1, fresh = average_freshness, recipe_mod = 1.0 diff --git a/code/modules/crafting/slapcrafting/steps/use_items.dm b/code/modules/crafting/slapcrafting/steps/use_items.dm index 65114f0de3e..5a097a0aeb2 100644 --- a/code/modules/crafting/slapcrafting/steps/use_items.dm +++ b/code/modules/crafting/slapcrafting/steps/use_items.dm @@ -11,7 +11,7 @@ /datum/slapcraft_step/use_item/carpentry/hammer/get_speed_multiplier(mob/living/user, obj/item/item, obj/item/slapcraft_assembly/assembly) . = ..() var/obj/item/weapon/hammer/hammer = item - . *= hammer.time_multiplier + . *= hammer.toolspeed /datum/slapcraft_step/use_item/masonry/hammer desc = "Hammer the stones" @@ -24,7 +24,7 @@ /datum/slapcraft_step/use_item/masonry/hammer/get_speed_multiplier(mob/living/user, obj/item/item, obj/item/slapcraft_assembly/assembly) . = ..() var/obj/item/weapon/hammer/hammer = item - . *= hammer.time_multiplier + . *= hammer.toolspeed /datum/slapcraft_step/use_item/engineering/hammer desc = "Hammer the mechanical parts" @@ -35,7 +35,7 @@ /datum/slapcraft_step/use_item/engineering/hammer/get_speed_multiplier(mob/living/user, obj/item/item, obj/item/slapcraft_assembly/assembly) . = ..() var/obj/item/weapon/hammer/hammer = item - . *= hammer.time_multiplier + . *= hammer.toolspeed /datum/slapcraft_step/use_item/masonry/chisel desc = "Chisel the rock" @@ -48,4 +48,4 @@ /datum/slapcraft_step/use_item/masonry/chisel/get_speed_multiplier(mob/living/user, obj/item/item, obj/item/slapcraft_assembly/assembly) . = ..() var/obj/item/weapon/chisel/chisel = item - . *= chisel.time_multiplier + . *= chisel.toolspeed diff --git a/code/modules/farming/items/chaff.dm b/code/modules/farming/items/chaff.dm index 1a32c0742e3..043511cc2f3 100644 --- a/code/modules/farming/items/chaff.dm +++ b/code/modules/farming/items/chaff.dm @@ -17,6 +17,7 @@ span_notice("I shuck [src].")) var/obj/item/G = new foodextracted(get_turf(src)) G.set_quality(recipe_quality) + G.AddElement(/datum/element/visual_quality, recipe_quality) user.put_in_active_hand(G) new /obj/item/natural/fibers(get_turf(src)) qdel(src) @@ -26,6 +27,7 @@ if(foodextracted && canthresh) var/obj/item/extracted = new foodextracted(loc) extracted.set_quality(recipe_quality) + extracted.AddElement(/datum/element/visual_quality, recipe_quality) new /obj/item/natural/fibers(loc) qdel(src) diff --git a/code/modules/farming/items/tools.dm b/code/modules/farming/items/tools.dm index 6ca3dba9dd8..85abf1d82c6 100644 --- a/code/modules/farming/items/tools.dm +++ b/code/modules/farming/items/tools.dm @@ -201,7 +201,6 @@ associated_skill = /datum/skill/combat/polearms wlength = 66 - var/time_multiplier = 1 max_integrity = INTEGRITY_POOR /obj/item/weapon/hoe/Initialize() @@ -273,14 +272,14 @@ user.changeNext_move(CLICK_CD_MELEE) if(istype(T, /turf/open/floor/grass)) playsound(T,'sound/items/dig_shovel.ogg', 100, TRUE) - if(do_after(user, 3 SECONDS * time_multiplier, src)) + if(do_after(user, 3 SECONDS * toolspeed, src)) apply_farming_fatigue(user, 10) T.ChangeTurf(/turf/open/floor/dirt, flags = CHANGETURF_INHERIT_AIR) playsound(T,'sound/items/dig_shovel.ogg', 100, TRUE) return if(istype(T, /turf/open/floor/dirt)) playsound(T,'sound/items/dig_shovel.ogg', 100, TRUE) - if(do_after(user, 2 SECONDS * time_multiplier, src)) + if(do_after(user, 2 SECONDS * toolspeed, src)) playsound(T,'sound/items/dig_shovel.ogg', 100, TRUE) var/obj/structure/soil/soil = get_soil_on_turf(T) if(soil) @@ -308,7 +307,7 @@ smeltresult = null anvilrepair = null max_integrity = INTEGRITY_WORST - time_multiplier = 2 + toolspeed = 2 /*------------\ | Pitchfork | diff --git a/code/modules/farming/soil.dm b/code/modules/farming/soil.dm index 6640a82364a..d8f4a334be9 100644 --- a/code/modules/farming/soil.dm +++ b/code/modules/farming/soil.dm @@ -2,12 +2,6 @@ #define MAX_PLANT_NUTRITION 300 #define SOIL_DECAY_TIME 20 MINUTES -#define QUALITY_REGULAR 1 -// #define QUALITY_BRONZE 2 -#define QUALITY_SILVER 2 -#define QUALITY_GOLD 3 -#define QUALITY_DIAMOND 4 - #define BLESSING_WEED_DECAY_RATE 10 / (1 MINUTES) #define WEED_GROWTH_RATE 3 / (1 MINUTES) #define WEED_DECAY_RATE 5 / (1 MINUTES) @@ -65,8 +59,8 @@ var/pollination_time = 0 /// Time remaining for the soil to decay and destroy itself, only applicable when its out of water and nutriments and has no plant var/soil_decay_time = SOIL_DECAY_TIME - /// Current quality tier of the crop (1-5, regular to diamond) - var/crop_quality = QUALITY_REGULAR + /// Current quality tier of the crop (CROP_QUALITY defines) + var/crop_quality = CROP_QUALITY_REGULAR /// Tracks quality points that accumulate toward quality tier increases var/quality_points = 0 ///accellerated_growth @@ -159,7 +153,7 @@ var/obj/item/weapon/shovel/shovel = attacking_item to_chat(user, span_notice("I begin to uproot the crop...")) playsound(src,'sound/items/dig_shovel.ogg', 100, TRUE) - if(do_after(user, get_farming_do_time(user, 4 SECONDS * shovel.time_multiplier), src)) + if(do_after(user, get_farming_do_time(user, 4 SECONDS * shovel.toolspeed), src)) to_chat(user, span_notice("I uproot the crop.")) playsound(src,'sound/items/dig_shovel.ogg', 100, TRUE) uproot() @@ -171,7 +165,7 @@ var/obj/item/weapon/hoe/hoe = attacking_item to_chat(user, span_notice("I begin to till the soil...")) playsound(src,'sound/items/dig_shovel.ogg', 100, TRUE) - if(do_after(user, get_farming_do_time(user, 3 SECONDS * hoe.time_multiplier), src)) + if(do_after(user, get_farming_do_time(user, 3 SECONDS * hoe.toolspeed), src)) to_chat(user, span_notice("I till the soil.")) playsound(src,'sound/items/dig_shovel.ogg', 100, TRUE) user_till_soil(user) @@ -265,7 +259,7 @@ to_chat(user, span_notice("I begin flattening the soil with \the [attacking_item]...")) var/obj/item/weapon/shovel/shovel = attacking_item playsound(src,'sound/items/dig_shovel.ogg', 100, TRUE) - if(do_after(user, get_farming_do_time(user, 3 SECONDS * shovel.time_multiplier), src)) + if(do_after(user, get_farming_do_time(user, 3 SECONDS * shovel.toolspeed), src)) if(plant) return FALSE apply_farming_fatigue(user, 10) @@ -667,13 +661,13 @@ // Quality tier thresholds if(quality_points >= max_quality_points * 0.9) - crop_quality = QUALITY_DIAMOND + crop_quality = CROP_QUALITY_DIAMOND else if(quality_points >= max_quality_points * 0.7) - crop_quality = QUALITY_GOLD + crop_quality = CROP_QUALITY_GOLD else if(quality_points >= max_quality_points * 0.5) - crop_quality = QUALITY_SILVER + crop_quality = CROP_QUALITY_SILVER else - crop_quality = QUALITY_REGULAR + crop_quality = CROP_QUALITY_REGULAR // Optional: Add a proc to show current quality progress to players /obj/structure/soil/proc/get_quality_info() @@ -686,11 +680,11 @@ var/quality_name = "Regular" switch(crop_quality) - if(QUALITY_SILVER) + if(CROP_QUALITY_SILVER) quality_name = "Silver" - if(QUALITY_GOLD) + if(CROP_QUALITY_GOLD) quality_name = "Gold" - if(QUALITY_DIAMOND) + if(CROP_QUALITY_DIAMOND) quality_name = "Diamond" return "Current Quality: [quality_name] ([progress_percent]% of maximum potential)" @@ -835,7 +829,7 @@ improvement_chance += 10 if(pollination_time > 0) improvement_chance += 10 - if(crop_quality >= QUALITY_SILVER) // the rich get richer + if(crop_quality >= CROP_QUALITY_SILVER) // the rich get richer improvement_chance += 20 // Improve two random traits @@ -1095,7 +1089,6 @@ update_appearance(UPDATE_OVERLAYS) /// Yields produce on its tile if it's ready for harvest - /obj/structure/soil/proc/yield_produce(modifier = 0) if(!produce_ready || !plant_genetics) return @@ -1114,6 +1107,7 @@ for(var/i in 1 to spawn_amount) var/obj/item/produce = new plant.produce_type(loc) produce.set_quality(crop_quality) + produce.AddElement(/datum/element/visual_quality, crop_quality) if(produce && istype(produce, /obj/item/reagent_containers/food/snacks/produce)) var/obj/item/reagent_containers/food/snacks/produce/P = produce // Pass genetics to the produce for seed extraction @@ -1126,12 +1120,11 @@ // Reset quality for next growth cycle if plant is perennial if(plant?.perennial) - crop_quality = QUALITY_REGULAR + crop_quality = CROP_QUALITY_REGULAR quality_points = 0 update_appearance(UPDATE_OVERLAYS) - /obj/structure/soil/proc/insert_plant(datum/plant_def/new_plant, datum/plant_genetics/new_genetics) if(plant) return @@ -1146,7 +1139,7 @@ plant_dead = FALSE plant_genetics = new_genetics // Reset quality values - crop_quality = QUALITY_REGULAR + crop_quality = CROP_QUALITY_REGULAR quality_points = 0 update_appearance(UPDATE_OVERLAYS) @@ -1278,11 +1271,11 @@ #undef MAX_PLANT_WEEDS #undef SOIL_DECAY_TIME -#undef QUALITY_REGULAR +#undef CROP_QUALITY_REGULAR // #undef QUALITY_BRONZE -#undef QUALITY_SILVER -#undef QUALITY_GOLD -#undef QUALITY_DIAMOND +#undef CROP_QUALITY_SILVER +#undef CROP_QUALITY_GOLD +#undef CROP_QUALITY_DIAMOND #undef BLESSING_WEED_DECAY_RATE #undef WEED_GROWTH_RATE diff --git a/code/modules/farming/structures/bin.dm b/code/modules/farming/structures/bin.dm index 469284fed86..1d8a0816b15 100644 --- a/code/modules/farming/structures/bin.dm +++ b/code/modules/farming/structures/bin.dm @@ -168,6 +168,7 @@ if(!reagents || !reagents.maximum_volume) //trash return ..() + // TODO: REWRITE TONGS INTERACTIONS USING interact_with_atom() if(istype(I, /obj/item/weapon/tongs)) var/obj/item/weapon/tongs/T = I if(T.held_item && HAS_TRAIT(T.held_item, TRAIT_NEEDS_QUENCH)) @@ -199,12 +200,16 @@ return . = ..() -/obj/item/proc/remove_quench() - if(!HAS_TRAIT(src, TRAIT_NEEDS_QUENCH)) - return - REMOVE_TRAIT(src, TRAIT_NEEDS_QUENCH, "quench") - remove_filter("heated") +/obj/item/proc/remove_quench(source) + // Source is null when removing all TRAIT_NEEDS_QUENCH + // If this is the only trait source we have, remove the filter. + if(isnull(source) || !HAS_TRAIT_NOT_FROM(src, TRAIT_NEEDS_QUENCH, source)) + remove_filter("heated") + REMOVE_TRAIT(src, TRAIT_NEEDS_QUENCH, source) -/obj/item/proc/add_quench_requirement() - ADD_TRAIT(src, TRAIT_NEEDS_QUENCH, "quench") - add_filter("heated", 1, list(type="color", color = list(3,0,0,1, 0,2.7,0,0.4, 0,0,1,0, 0,0,0,1))) +/obj/item/proc/add_quench_requirement(source, duration) + if(!HAS_TRAIT(src, TRAIT_NEEDS_QUENCH)) + add_filter("heated", 1, list(type="color", color = list(3,0,0,1, 0,2.7,0,0.4, 0,0,1,0, 0,0,0,1))) + ADD_TRAIT(src, TRAIT_NEEDS_QUENCH, source) + if(duration) + addtimer(CALLBACK(src, PROC_REF(remove_quench), source), duration, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_DELETE_ME) diff --git a/code/modules/farming/structures/fermentation_keg.dm b/code/modules/farming/structures/fermentation_keg.dm index cfe3f258c66..2ec118a05ce 100644 --- a/code/modules/farming/structures/fermentation_keg.dm +++ b/code/modules/farming/structures/fermentation_keg.dm @@ -342,7 +342,6 @@ GLOBAL_LIST_EMPTY(custom_fermentation_recipes) if(selecting_recipe) return selecting_recipe = TRUE - addtimer(VARSET_CALLBACK(src, selecting_recipe, FALSE), 5 SECONDS) var/list/options = list() for(var/datum/brewing_recipe/path as anything in subtypesof(/datum/brewing_recipe)) @@ -362,10 +361,12 @@ GLOBAL_LIST_EMPTY(custom_fermentation_recipes) options[initial(recipe.name)] = recipe if(options.len == 0) + selecting_recipe = FALSE return var/choice = input(user,"What brew do you want to make?", name) as null|anything in options + selecting_recipe = FALSE if(!choice) return if(!Adjacent(user)) @@ -382,7 +383,6 @@ GLOBAL_LIST_EMPTY(custom_fermentation_recipes) selected_recipe = new choice_to_spawn to_chat(user, span_notice("You set the recipe to [selected_recipe.name].")) recipe_completions = 0 - selecting_recipe = FALSE //Second stage brewing gives no refunds! - This is intented design to help make it so folks dont quit halfway through and still get a rebate ready_to_bottle = FALSE @@ -417,6 +417,7 @@ GLOBAL_LIST_EMPTY(custom_fermentation_recipes) brewing = FALSE tapped = FALSE ready_to_bottle = FALSE + reagents.flags |= REFILLABLE | DRAINABLE icon_state = initial(icon_state) update_appearance(UPDATE_OVERLAYS) @@ -432,6 +433,7 @@ GLOBAL_LIST_EMPTY(custom_fermentation_recipes) brewing = TRUE ready_to_bottle = FALSE tapped = FALSE + reagents.flags &= ~(REFILLABLE | DRAINABLE) // Store the user who started brewing for quality calculation if(user) diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index e9aa605489e..3d23016f61e 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -385,9 +385,7 @@ All foods are distributed among various categories. Use common sense. plate_check.fork_usages +=1 if(plate_check.fork_usages >= plate_check.max_fork_usages && !plate_check.dirty) plate_check.dirty = TRUE - var/datum/component/particle_spewer = plate_check.GetComponent(/datum/component/particle_spewer/sparkle) - if(particle_spewer) - qdel(particle_spewer) + qdel(plate_check.GetComponent(/datum/component/particle_spewer/sparkle/turf_only)) plate_check.update_appearance(UPDATE_OVERLAYS) if(M == user) //If you're eating it myself. diff --git a/code/modules/jobs/job_types/adventurer/types/combat/dbomb.dm b/code/modules/jobs/job_types/adventurer/types/combat/dbomb.dm index 065b7079f90..b38df190910 100644 --- a/code/modules/jobs/job_types/adventurer/types/combat/dbomb.dm +++ b/code/modules/jobs/job_types/adventurer/types/combat/dbomb.dm @@ -15,7 +15,7 @@ /datum/skill/labor/mining = 1, /datum/skill/craft/engineering = 5, /datum/skill/craft/bombs = 4, - /datum/skill/craft/smelting = 1, + /datum/skill/craft/blacksmithing = 1, /datum/skill/combat/unarmed = 2, /datum/skill/combat/wrestling = 2, /datum/skill/craft/crafting = 3, @@ -47,4 +47,4 @@ if(1) shoes = /obj/item/clothing/shoes/boots/leather if(2) - shoes = /obj/item/clothing/shoes/simpleshoes \ No newline at end of file + shoes = /obj/item/clothing/shoes/simpleshoes diff --git a/code/modules/jobs/job_types/adventurer/types/combat/dredge.dm b/code/modules/jobs/job_types/adventurer/types/combat/dredge.dm index 843f0c6d2bc..d5d1ac1091a 100644 --- a/code/modules/jobs/job_types/adventurer/types/combat/dredge.dm +++ b/code/modules/jobs/job_types/adventurer/types/combat/dredge.dm @@ -435,7 +435,6 @@ ) if("Smith") spawned.adjust_skillrank(/datum/skill/labor/mining, 2, TRUE) - spawned.adjust_skillrank(/datum/skill/craft/smelting, 1, TRUE) spawned.adjust_skillrank(/datum/skill/craft/blacksmithing, 2, TRUE) spawned.change_stat(STATKEY_INT, -1) spawned.change_stat(STATKEY_CON, 1) diff --git a/code/modules/jobs/job_types/adventurer/types/pilgrim/blacksmith.dm b/code/modules/jobs/job_types/adventurer/types/pilgrim/blacksmith.dm index b0dbd7c0dcd..ee091e642d7 100644 --- a/code/modules/jobs/job_types/adventurer/types/pilgrim/blacksmith.dm +++ b/code/modules/jobs/job_types/adventurer/types/pilgrim/blacksmith.dm @@ -29,7 +29,6 @@ /datum/skill/craft/blacksmithing = 3, /datum/skill/craft/armorsmithing = 3, /datum/skill/craft/weaponsmithing = 3, - /datum/skill/craft/smelting = 3 ) traits = list( diff --git a/code/modules/jobs/job_types/adventurer/types/pilgrim/miner.dm b/code/modules/jobs/job_types/adventurer/types/pilgrim/miner.dm index e9722393e2c..9db90180fd7 100644 --- a/code/modules/jobs/job_types/adventurer/types/pilgrim/miner.dm +++ b/code/modules/jobs/job_types/adventurer/types/pilgrim/miner.dm @@ -27,7 +27,6 @@ /datum/skill/misc/athletics = 3, /datum/skill/craft/traps = 1, /datum/skill/craft/engineering = 2, - /datum/skill/craft/smelting = 4, /datum/skill/misc/reading = 1 ) diff --git a/code/modules/jobs/job_types/adventurer/types/pilgrim/rare/Lmason.dm b/code/modules/jobs/job_types/adventurer/types/pilgrim/rare/Lmason.dm index 81d9c66e994..1da0502c70a 100644 --- a/code/modules/jobs/job_types/adventurer/types/pilgrim/rare/Lmason.dm +++ b/code/modules/jobs/job_types/adventurer/types/pilgrim/rare/Lmason.dm @@ -28,7 +28,6 @@ /datum/skill/craft/masonry = 6, /datum/skill/craft/engineering = 5, /datum/skill/misc/lockpicking = 3, - /datum/skill/craft/smelting = 6, /datum/skill/misc/swimming = 3, /datum/skill/misc/climbing = 4, /datum/skill/misc/athletics = 4, diff --git a/code/modules/jobs/job_types/adventurer/types/pilgrim/rare/Lminer.dm b/code/modules/jobs/job_types/adventurer/types/pilgrim/rare/Lminer.dm index eed87e637a1..d35b3ff5266 100644 --- a/code/modules/jobs/job_types/adventurer/types/pilgrim/rare/Lminer.dm +++ b/code/modules/jobs/job_types/adventurer/types/pilgrim/rare/Lminer.dm @@ -30,7 +30,6 @@ /datum/skill/craft/masonry = 4, /datum/skill/craft/traps = 1, /datum/skill/craft/engineering = 4, - /datum/skill/craft/smelting = 6, /datum/skill/misc/reading = 1 ) diff --git a/code/modules/jobs/job_types/adventurer/types/pilgrim/rare/Lsmith.dm b/code/modules/jobs/job_types/adventurer/types/pilgrim/rare/Lsmith.dm index 2f7c27aa4eb..c400c0d0373 100644 --- a/code/modules/jobs/job_types/adventurer/types/pilgrim/rare/Lsmith.dm +++ b/code/modules/jobs/job_types/adventurer/types/pilgrim/rare/Lsmith.dm @@ -34,7 +34,6 @@ /datum/skill/craft/blacksmithing = 6, /datum/skill/craft/armorsmithing = 6, /datum/skill/craft/weaponsmithing = 6, - /datum/skill/craft/smelting = 6, /datum/skill/labor/mathematics = 2 ) diff --git a/code/modules/jobs/job_types/apprentices/bapprentice.dm b/code/modules/jobs/job_types/apprentices/bapprentice.dm index 9f7f1aa792e..75fea549dee 100644 --- a/code/modules/jobs/job_types/apprentices/bapprentice.dm +++ b/code/modules/jobs/job_types/apprentices/bapprentice.dm @@ -30,10 +30,9 @@ /datum/skill/misc/athletics = 2, /datum/skill/combat/wrestling = 1, /datum/skill/combat/unarmed = 1, - /datum/skill/craft/blacksmithing = 2, + /datum/skill/craft/blacksmithing = 3, /datum/skill/craft/armorsmithing = 2, /datum/skill/craft/weaponsmithing = 2, - /datum/skill/craft/smelting = 2, /datum/skill/craft/crafting = 2, /datum/skill/misc/reading = 2 ) @@ -48,6 +47,7 @@ name = "Smithy Apprentice" belt = /obj/item/storage/belt/leather/rope beltr = /obj/item/key/blacksmith + beltl = /obj/item/weapon/hammer/iron backr = /obj/item/storage/backpack/satchel /datum/outfit/bapprentice/pre_equip(mob/living/carbon/human/equipped_human, visuals_only) diff --git a/code/modules/jobs/job_types/church/monk.dm b/code/modules/jobs/job_types/church/monk.dm index 0c933e197ce..ab30cfba13f 100644 --- a/code/modules/jobs/job_types/church/monk.dm +++ b/code/modules/jobs/job_types/church/monk.dm @@ -119,7 +119,6 @@ spawned.cmode_music = 'sound/music/cmode/church/CombatXylix.ogg' if(/datum/patron/divine/malum) spawned.adjust_skillrank(/datum/skill/craft/blacksmithing, 2, TRUE) - spawned.adjust_skillrank(/datum/skill/craft/smelting, 2, TRUE) spawned.adjust_skillrank(/datum/skill/craft/armorsmithing, 1, TRUE) spawned.adjust_skillrank(/datum/skill/craft/weaponsmithing, 1, TRUE) spawned.adjust_skillrank(/datum/skill/craft/engineering, 1, TRUE) diff --git a/code/modules/jobs/job_types/garrison/town_elder.dm b/code/modules/jobs/job_types/garrison/town_elder.dm index f6a9a31428b..c2d1f8bdd07 100644 --- a/code/modules/jobs/job_types/garrison/town_elder.dm +++ b/code/modules/jobs/job_types/garrison/town_elder.dm @@ -187,7 +187,6 @@ /datum/skill/craft/crafting, /datum/skill/craft/carpentry, /datum/skill/craft/engineering, - /datum/skill/craft/smelting, /datum/skill/craft/sewing, /datum/skill/labor/farming, /datum/skill/misc/medicine, @@ -333,7 +332,6 @@ spawned.cmode_music = 'sound/music/cmode/church/CombatXylix.ogg' if(/datum/patron/divine/malum) spawned.adjust_skillrank(/datum/skill/craft/blacksmithing, 2, TRUE) - spawned.adjust_skillrank(/datum/skill/craft/smelting, 2, TRUE) spawned.adjust_skillrank(/datum/skill/craft/armorsmithing, 1, TRUE) spawned.adjust_skillrank(/datum/skill/craft/weaponsmithing, 1, TRUE) spawned.adjust_skillrank(/datum/skill/craft/engineering, 1, TRUE) diff --git a/code/modules/jobs/job_types/peasants/miner.dm b/code/modules/jobs/job_types/peasants/miner.dm index 69b7f556f14..ecdcc98fa00 100644 --- a/code/modules/jobs/job_types/peasants/miner.dm +++ b/code/modules/jobs/job_types/peasants/miner.dm @@ -39,14 +39,9 @@ /datum/skill/craft/traps = 1, /datum/skill/craft/engineering = 2, /datum/skill/craft/blacksmithing = 1, - /datum/skill/craft/smelting = 2, /datum/skill/misc/reading = 1 ) -/datum/job/miner/after_spawn(mob/living/carbon/human/spawned, client/player_client) - . = ..() - spawned.adjust_skillrank(/datum/skill/craft/smelting, pick(0,1,1,2), TRUE) - /datum/outfit/miner name = "Miner" head = /obj/item/clothing/head/armingcap diff --git a/code/modules/jobs/job_types/serfs/artificer.dm b/code/modules/jobs/job_types/serfs/artificer.dm index 5b919e10c67..aa70cf50ed2 100644 --- a/code/modules/jobs/job_types/serfs/artificer.dm +++ b/code/modules/jobs/job_types/serfs/artificer.dm @@ -40,7 +40,7 @@ /datum/skill/misc/climbing = 2, /datum/skill/misc/athletics = 2, /datum/skill/labor/mining = 2, - /datum/skill/craft/smelting = 4, + /datum/skill/craft/blacksmithing = 1, /datum/skill/misc/reading = 2, /datum/skill/labor/mathematics = 2, /datum/skill/craft/bombs = 3, diff --git a/code/modules/jobs/job_types/serfs/blacksmith.dm b/code/modules/jobs/job_types/serfs/blacksmith.dm index 5fab0f3c73b..62a70913d36 100644 --- a/code/modules/jobs/job_types/serfs/blacksmith.dm +++ b/code/modules/jobs/job_types/serfs/blacksmith.dm @@ -34,7 +34,6 @@ /datum/skill/craft/blacksmithing = 4, /datum/skill/craft/armorsmithing = 3, /datum/skill/craft/weaponsmithing = 3, - /datum/skill/craft/smelting = 3, /datum/skill/craft/engineering = 3, /datum/skill/craft/traps = 2, /datum/skill/misc/reading = 2, @@ -53,14 +52,14 @@ /datum/job/blacksmith/after_spawn(mob/living/carbon/human/spawned, client/player_client) . = ..() if(spawned.age == AGE_OLD) - spawned.adjust_skillrank(/datum/skill/craft/blacksmithing, pick(1,2), TRUE) - spawned.adjust_skillrank(/datum/skill/craft/armorsmithing, pick(1,2), TRUE) - spawned.adjust_skillrank(/datum/skill/craft/weaponsmithing, pick(1,2), TRUE) + spawned.adjust_skillrank(/datum/skill/craft/blacksmithing, 1, TRUE) + spawned.adjust_skillrank(/datum/skill/craft/armorsmithing, 1, TRUE) + spawned.adjust_skillrank(/datum/skill/craft/weaponsmithing, 1, TRUE) if(prob(5)) spawned.adjust_skillrank(/datum/skill/craft/blacksmithing, 1, TRUE) spawned.adjust_skillrank(/datum/skill/craft/armorsmithing, 1, TRUE) - spawned.adjust_skillrank(/datum/skill/craft/smelting, 1, TRUE) + spawned.adjust_skillrank(/datum/skill/craft/weaponsmithing, 1, TRUE) /datum/outfit/blacksmith name = "Blacksmith" diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index b121c80a8cb..6edc52ab688 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -333,65 +333,29 @@ if(IS_WEAKREF_OF(I, offered_item_ref)) stop_offering_item() -//Outdated but still in use apparently. This should at least be a human proc. -//Daily reminder to murder this - Remie. -/mob/living/proc/get_equipped_items(include_pockets = FALSE) - return +/** + * Used to return a list of equipped items on a mob; does not include held items (use get_all_gear) + * + * Argument(s): + * * Optional - include_flags, (see obj.flags.dm) describes which optional things to include or not (pockets, accessories, held items) + */ -/mob/living/carbon/get_equipped_items(include_pockets = FALSE) +/mob/living/proc/get_equipped_items(include_flags = NONE) var/list/items = list() - if(backr) - items += backr - if(backl) - items += backl - if(head) - items += head - if(wear_mask) - items += wear_mask - if(wear_neck) - items += wear_neck - return items - -/mob/living/carbon/human/get_equipped_items(include_pockets = FALSE) - var/list/items = ..() - if(belt) - items += belt - if(beltr) - items += beltr - if(beltl) - items += beltl - if(backr) - items += backr - if(backl) - items += backl - if(gloves) - items += gloves - if(shoes) - items += shoes - if(wear_ring) - items += wear_ring - if(wear_wrists) - items += wear_wrists - if(wear_armor) - items += wear_armor - if(wear_pants) - items += wear_pants - if(cloak) - items += cloak - if(mouth) - items += mouth - if(wear_shirt) - items += wear_shirt + for(var/obj/item/item_contents in contents) + if(item_contents.item_flags & IN_INVENTORY) + items += item_contents + if (!(include_flags & INCLUDE_HELD)) + items -= held_items return items /mob/living/proc/unequip_everything() var/list/items = list() - items |= get_equipped_items(TRUE) + items |= get_equipped_items(INCLUDE_POCKETS) for(var/I in items) dropItemToGround(I) drop_all_held_items() - /mob/living/carbon/proc/check_obscured_slots(transparent_protection) var/obscured = NONE var/hidden_slots = NONE diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 7db171c9d55..9e753d4c4bc 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1298,7 +1298,7 @@ /mob/living/carbon/get_total_weight() var/held_weight = 0 - for(var/obj/item/worn_item as anything in (get_equipped_items(TRUE) + held_items)) + for(var/obj/item/worn_item as anything in get_equipped_items(INCLUDE_POCKETS|INCLUDE_HELD)) if(isnull(worn_item)) continue var/modifier = 1 diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 9ccad4279f2..68141b44ecc 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -96,9 +96,6 @@ shoes_check.polished = 2 if(HAS_TRAIT(user, TRAIT_NOBLE_BLOOD)) user.add_stress(/datum/stress_event/noble_polishing_shoe) - var/datum/component/particle_spewer = shoes_check.GetComponent(/datum/component/particle_spewer/sparkle) - if(particle_spewer) - qdel(particle_spewer) shoes_check.AddComponent(/datum/component/particle_spewer/sparkle, shine_more = TRUE) addtimer(CALLBACK(shoes_check, TYPE_PROC_REF(/obj/item/clothing/shoes, lose_shine)), 15 MINUTES) target.add_stress(/datum/stress_event/extra_shiny_shoes) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 84186abd7a5..444309db8aa 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -207,7 +207,7 @@ if(istype(AM, /obj/item)) I = AM throwpower = I.throwforce - if(I.thrownby == src) //No throwing stuff at myself to trigger hit reactions + if(I.thrownby?.resolve() == src) //No throwing stuff at myself to trigger hit reactions return ..() if(check_shields(AM, throwpower, "\the [AM.name]", THROWN_PROJECTILE_ATTACK)) hitpush = FALSE diff --git a/code/modules/mob/living/carbon/human/species_types/kobold/_kobold.dm b/code/modules/mob/living/carbon/human/species_types/kobold/_kobold.dm index a350b117658..5a626fb926e 100644 --- a/code/modules/mob/living/carbon/human/species_types/kobold/_kobold.dm +++ b/code/modules/mob/living/carbon/human/species_types/kobold/_kobold.dm @@ -128,9 +128,7 @@ /datum/species/kobold/on_species_loss(mob/living/carbon/C) . = ..() if(hungry_hungry_kobold) - var/datum/component/abberant_eater = C.GetComponent(/datum/component/abberant_eater) - if(abberant_eater) - abberant_eater.RemoveComponent() + qdel(GetComponent(/datum/component/abberant_eater)) UnregisterSignal(C, COMSIG_MOB_SAY) C.remove_language(/datum/language/common) diff --git a/code/modules/mob/living/carbon/human/species_types/other/tiefling.dm b/code/modules/mob/living/carbon/human/species_types/other/tiefling.dm index 5391ce2a1a5..0ba8930ecf8 100644 --- a/code/modules/mob/living/carbon/human/species_types/other/tiefling.dm +++ b/code/modules/mob/living/carbon/human/species_types/other/tiefling.dm @@ -144,9 +144,7 @@ . = ..() UnregisterSignal(C, COMSIG_MOB_SAY) C.remove_language(/datum/language/hellspeak) - var/datum/component/bad_luck = C.GetComponent(/datum/component/malaguero) - if(bad_luck) - bad_luck.RemoveComponent() + qdel(C.GetComponent(/datum/component/malaguero)) /datum/species/tieberian/qualifies_for_rank(rank, list/features) return TRUE diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index 8d7cd476ada..c6a862e133b 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -181,8 +181,8 @@ return index && hand_bodyparts[index] //GetAllContents that is reasonable for carbons -/mob/living/carbon/proc/get_all_gear() - var/list/processing_list = get_equipped_items(include_pockets = TRUE) + held_items +/mob/living/proc/get_all_gear() + var/list/processing_list = get_equipped_items(INCLUDE_POCKETS|INCLUDE_HELD) listclearnulls(processing_list) // handles empty hands var/i = 0 while(i < length(processing_list)) diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index 3dc6848837d..3e43e434aa9 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -375,8 +375,9 @@ /mob/living/carbon/monkey/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum, damage_type = "blunt") if(istype(AM, /obj/item)) var/obj/item/I = AM - if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby)) - var/mob/living/carbon/human/H = I.thrownby + var/mob/thrown_by = I.thrownby?.resolve() + if(I.throwforce < src.health && thrown_by && ishuman(thrown_by)) + var/mob/living/carbon/human/H = thrown_by retaliate(H) ..() diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 1e71e4ab005..54a5273629b 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -57,13 +57,6 @@ internal_organs += new /obj/item/organ/stomach ..() -/mob/living/carbon/monkey/on_reagent_change() - . = ..() - remove_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE) - var/amount - if(amount) - add_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount) - /mob/living/carbon/monkey/updatehealth(amount) . = ..() var/slow = 0 diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm index f39966b71d7..b191d69878b 100644 --- a/code/modules/mob/living/init_signals.dm +++ b/code/modules/mob/living/init_signals.dm @@ -169,9 +169,7 @@ ///Called when TRAIT_CRATEMOVER is removed from the mob. /mob/living/proc/on_cratemover_trait_loss(datum/source) SIGNAL_HANDLER - var/datum/component/strongpull = GetComponent(/datum/component/strong_pull) - if(strongpull) - strongpull.RemoveComponent() + qdel(GetComponent(/datum/component/strong_pull)) ///From [element/movetype_handler/on_movement_type_trait_gain()] /mob/living/proc/on_movement_type_flag_enabled(datum/source, trait) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index a8e983b4d6d..c650422da27 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -130,6 +130,7 @@ if(!apply_damage(I.throwforce, damagetype, zone, armor)) nodmg = TRUE next_attack_msg += span_warning(" Armor stops the damage.") + var/mob/thrown_by = I.thrownby?.resolve() if(!nodmg) if(iscarbon(src)) var/obj/item/bodypart/affecting = get_bodypart(zone) @@ -138,18 +139,18 @@ if(throwingdatum) throwee = isliving(throwingdatum.thrower) ? throwingdatum.thrower : null affecting.bodypart_attacked_by(I.thrown_bclass, I.throwforce, throwee, affecting.body_zone, crit_message = TRUE) - I.do_special_attack_effect(I.thrownby, affecting, null, src, zone, thrown = TRUE) + I.do_special_attack_effect(thrown_by, affecting, null, src, zone, thrown = TRUE) else simple_woundcritroll(I.thrown_bclass, I.throwforce, null, zone, crit_message = TRUE) if(((throwingdatum ? throwingdatum.speed : I.throw_speed) >= EMBED_THROWSPEED_THRESHOLD) || I.embedding.embedded_ignore_throwspeed_threshold) if(I.can_embed() && prob(I.embedding.embed_chance) && HAS_TRAIT(src, TRAIT_SIMPLE_WOUNDS) && !HAS_TRAIT(src, TRAIT_PIERCEIMMUNE)) simple_add_embedded_object(I, silent = FALSE, crit_message = TRUE) - I.do_special_attack_effect(I.thrownby, null, null, src, null, thrown = TRUE) + I.do_special_attack_effect(thrown_by, null, null, src, null, thrown = TRUE) visible_message("[src] is hit by [I]![next_attack_msg.Join()]", \ "I'm hit by [I]![next_attack_msg.Join()]") next_attack_msg.Cut() - if(I.thrownby) - log_combat(I.thrownby, src, "threw and hit", I) + if(thrown_by) + log_combat(thrown_by, src, "threw and hit", I) else return 1 else diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 6e7303efb25..941825936c7 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -130,10 +130,10 @@ GLOBAL_VAR_INIT(mobids, 1) if(!client) return - msg = copytext(msg, 1, MAX_MESSAGE_LEN) + msg = copytext_char(msg, 1, MAX_MESSAGE_LEN) if(type) - if(type & MSG_VISUAL && is_blind() )//Vision related + if(type & MSG_VISUAL && is_blind())//Vision related if(!alt_msg) return else @@ -148,6 +148,11 @@ GLOBAL_VAR_INIT(mobids, 1) type = alt_type if(type & MSG_VISUAL && is_blind()) return + // voice muffling + if(stat == UNCONSCIOUS) + if(type & MSG_AUDIBLE) //audio + to_chat(src, "... You can almost hear something ...") + return to_chat(src, msg) /** @@ -418,7 +423,7 @@ GLOBAL_VAR_INIT(mobids, 1) if(isturf(examinify.loc) && isliving(src) && stat == CONSCIOUS) face_atom(examinify) if(m_intent != MOVE_INTENT_SNEAK) - visible_message(span_emote("[src] looks at [examinify]."), span_emote("I look at [examinify]")) + visible_message(span_emote("[src] looks at [examinify]."), span_emote("I look at [examinify].")) else if(isliving(examinify)) var/mob/living/examaniee = examinify if(examaniee.peek_examine_check(src)) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 632a8b3a171..7931b9a332c 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -21,7 +21,7 @@ CH.cavity_item = null if(tr_flags & TR_KEEPITEMS) - var/Itemlist = get_equipped_items(TRUE) + var/Itemlist = get_equipped_items(INCLUDE_POCKETS) Itemlist += held_items for(var/obj/item/W in Itemlist) dropItemToGround(W) @@ -144,7 +144,7 @@ //now the rest if (tr_flags & TR_KEEPITEMS) - var/Itemlist = get_equipped_items(TRUE) + var/Itemlist = get_equipped_items(INCLUDE_POCKETS) Itemlist += held_items for(var/obj/item/W in Itemlist) dropItemToGround(W, TRUE) diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index f464f71d227..b45cf4e28cf 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -432,10 +432,11 @@ var/list/cached_reactions = GLOB.chemical_reactions_list var/datum/cached_my_atom = my_atom - var/reaction_occurred = 0 + . = 0 + var/reaction_occurred = FALSE do var/list/possible_reactions = list() - reaction_occurred = 0 + reaction_occurred = FALSE for(var/datum/reagent/R as anything in cached_reagents) for(var/reaction in cached_reactions[R.type]) // Was a big list but now it should be smaller since we filtered it with our reagent id if(!reaction) @@ -521,13 +522,14 @@ for(var/mob/M in seen) to_chat(M, "[iconhtml] [selected_reaction.mix_message]") - my_atom?.on_reagent_change(REACT_REAGENTS) selected_reaction.on_reaction(src, multiplier) - reaction_occurred = 1 + reaction_occurred = TRUE + .++ while(reaction_occurred) update_total() - return 0 + if(.) + SEND_SIGNAL(src, COMSIG_REAGENTS_REACTED, .) /datum/reagents/proc/isolate_reagent(reagent) var/list/cached_reagents = reagent_list @@ -549,29 +551,28 @@ qdel(R) reagent_list -= R update_total() - if(my_atom) - my_atom.on_reagent_change(DEL_REAGENT) SEND_SIGNAL(src, COMSIG_REAGENTS_DEL_REAGENT, reagent) - return 1 + return TRUE /datum/reagents/proc/update_total() var/list/cached_reagents = reagent_list - total_volume = 0 - for(var/datum/reagent/R as anything in cached_reagents) - if(R.volume < 0.05) - del_reagent(R.type) + . = 0 // This is a relatively hot proc. + for(var/datum/reagent/reagent as anything in cached_reagents) + if(reagent.volume < 0.05) + del_reagent(reagent.type) + else if(reagent.volume <= CHEMICAL_VOLUME_MINIMUM) //For clarity + del_reagent(reagent.type) else - total_volume += R.volume - - return 0 + . += reagent.volume + total_volume = . + //inform hooks about reagent changes + SEND_SIGNAL(src, COMSIG_REAGENTS_HOLDER_UPDATED, .) /datum/reagents/proc/clear_reagents() var/list/cached_reagents = reagent_list for(var/datum/reagent/R as anything in cached_reagents) del_reagent(R.type) - if(my_atom) - my_atom.on_reagent_change(CLEAR_REAGENTS) - return 0 + SEND_SIGNAL(src, COMSIG_REAGENTS_CLEAR_REAGENTS) /datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1) var/react_type @@ -594,7 +595,7 @@ if(method & VAPOR) var/mob/living/L = A touch_protection = L.get_permeability_protection() - R.reaction_mob(A, method, R.volume * volume_modifier, show_message, touch_protection) + R.expose_mob(A, method, R.volume * volume_modifier, show_message, touch_protection) if("TURF") R.reaction_turf(A, R.volume * volume_modifier, show_message) if("OBJ") @@ -619,7 +620,7 @@ if(method & VAPOR) var/mob/living/L = A touch_protection = L.get_permeability_protection() - R.reaction_mob(A, method, R.volume * volume_modifier, show_message, touch_protection) + R.expose_mob(A, method, R.volume * volume_modifier, show_message, touch_protection) if("TURF") R.reaction_turf(A, R.volume * volume_modifier, show_message) if("OBJ") @@ -630,17 +631,25 @@ return TRUE return FALSE -//Returns the average specific heat for all reagents currently in this holder. -/datum/reagents/proc/specific_heat() +/// Returns the total heat capacity for all of the reagents currently in this holder. +/datum/reagents/proc/heat_capacity() . = 0 - var/cached_amount = total_volume //cache amount - var/list/cached_reagents = reagent_list //cache reagents - for(var/datum/reagent/R as anything in cached_reagents) - . += R.specific_heat * (R.volume / cached_amount) + var/list/cached_reagents = reagent_list //cache reagents + for(var/datum/reagent/reagent in cached_reagents) + . += reagent.specific_heat * reagent.volume -/datum/reagents/proc/adjust_thermal_energy(J, min_temp = 2.7, max_temp = 1000) - var/S = specific_heat() - chem_temp = CLAMP(chem_temp + (J / (S * total_volume)), 2.7, 1000) +/** Adjusts the thermal energy of the reagents in this holder by an amount. + * + * Arguments: + * - delta_energy: The amount to change the thermal energy by. + * - min_temp: The minimum temperature that can be reached. + * - max_temp: The maximum temperature that can be reached. + */ +/datum/reagents/proc/adjust_thermal_energy(delta_energy, min_temp = 2.7, max_temp = 1000) + var/heat_capacity = heat_capacity() + if(!heat_capacity) + return // no div/0 please + set_temperature(clamp(chem_temp + (delta_energy / heat_capacity), min_temp, max_temp)) /datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300, no_react = 0) if(!isnum(amount) || !amount) @@ -649,9 +658,9 @@ if(amount <= 0) return FALSE - var/datum/reagent/D = GLOB.chemical_reagents_list[reagent] - if(!D) - WARNING("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])") + var/datum/reagent/glob_reagent = GLOB.chemical_reagents_list[reagent] + if(!glob_reagent) + stack_trace("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])") return FALSE update_total() @@ -660,52 +669,57 @@ amount = (maximum_volume - cached_total) //Doesnt fit in. Make it disappear. Shouldnt happen. Will happen. if(amount <= 0) return FALSE - var/new_total = cached_total + amount + var/cached_temp = chem_temp var/list/cached_reagents = reagent_list //Equalize temperature - Not using specific_heat() because the new chemical isn't in yet. - var/specific_heat = 0 - var/thermal_energy = 0 - for(var/datum/reagent/R as anything in cached_reagents) - specific_heat += R.specific_heat * (R.volume / new_total) - thermal_energy += R.specific_heat * R.volume * cached_temp - specific_heat += D.specific_heat * (amount / new_total) - thermal_energy += D.specific_heat * amount * reagtemp - chem_temp = thermal_energy / (specific_heat * new_total) - //// + var/old_heat_capacity = 0 + if(reagtemp != cached_temp) + for(var/datum/reagent/iter_reagent as anything in cached_reagents) + old_heat_capacity += iter_reagent.specific_heat * iter_reagent.volume //add the reagent to the existing if it exists - for(var/datum/reagent/R as anything in cached_reagents) - if (R.type == reagent) - R.volume += amount + for(var/datum/reagent/iter_reagent as anything in cached_reagents) + if(iter_reagent.type == reagent) + iter_reagent.volume += amount update_total() - if(my_atom) - my_atom.on_reagent_change(ADD_REAGENT) - R.on_merge(data, amount) + iter_reagent.on_merge(data, amount) + + if(reagtemp != cached_temp) + var/new_heat_capacity = heat_capacity() + if(new_heat_capacity) + set_temperature(((old_heat_capacity * cached_temp) + (iter_reagent.specific_heat * amount * reagtemp)) / new_heat_capacity) + else + set_temperature(reagtemp) + + SEND_SIGNAL(src, COMSIG_REAGENTS_ADD_REAGENT, iter_reagent, amount, reagtemp, data, no_react) if(!no_react) handle_reactions() return TRUE //otherwise make a new one - var/datum/reagent/R = new D.type(data) - cached_reagents += R - R.holder = src - R.volume = amount - + var/datum/reagent/new_reagent = new reagent(data) + cached_reagents += new_reagent + new_reagent.holder = src + new_reagent.volume = amount // New reagent color check - if (R.random_reagent_color == TRUE) - R.color = GLOB.chemical_reagents_color_list[R.name] - - if(data) - R.data = data - R.on_new(data) + if (new_reagent.random_reagent_color == TRUE) + new_reagent.color = GLOB.chemical_reagents_color_list[new_reagent.name] + new_reagent.on_new(data) if(isliving(my_atom)) - R.on_mob_add(my_atom) //Must occur befor it could posibly run on_mob_delete + new_reagent.on_mob_add(my_atom) //Must occur befor it could posibly run on_mob_delete + update_total() - if(my_atom) - my_atom.on_reagent_change(ADD_REAGENT) + if(reagtemp != cached_temp) + var/new_heat_capacity = heat_capacity() + if(new_heat_capacity) + set_temperature(((old_heat_capacity * cached_temp) + (new_reagent.specific_heat * amount * reagtemp)) / new_heat_capacity) + else + set_temperature(reagtemp) + + SEND_SIGNAL(src, COMSIG_REAGENTS_NEW_REAGENT, new_reagent, amount, reagtemp, data, no_react) if(!no_react) handle_reactions() return TRUE @@ -728,18 +742,16 @@ return FALSE var/list/cached_reagents = reagent_list - - for(var/datum/reagent/R as anything in cached_reagents) - if (R.type == reagent) + for(var/datum/reagent/cached_reagent as anything in cached_reagents) + if(cached_reagent.type == reagent) //clamp the removal amount to be between current reagent amount //and zero, to prevent removing more than the holder has stored - amount = CLAMP(amount, 0, R.volume) - R.volume -= amount + amount = clamp(amount, 0, cached_reagent.volume) + cached_reagent.volume -= amount update_total() if(!safety)//So it does not handle reactions when it need not to handle_reactions() - if(my_atom) - my_atom.on_reagent_change(REM_REAGENT) + SEND_SIGNAL(src, COMSIG_REAGENTS_REM_REAGENT, QDELING(cached_reagent) ? reagent : cached_reagent, amount) return TRUE return FALSE @@ -883,31 +895,21 @@ out += "[scent_desc]" return english_list(out, "something") -/datum/reagents/proc/generate_taste_message(minimum_percent=15) +/datum/reagents/proc/generate_taste_message(mob/living/taster, minimum_percent=15) // the lower the minimum percent, the more sensitive the message is. var/list/out = list() var/list/tastes = list() //descriptor = strength if(minimum_percent <= 100) - for(var/datum/reagent/R in reagent_list) - if(!R.taste_mult) + for(var/datum/reagent/reagent as anything in reagent_list) + if(!reagent.taste_mult) continue - if(istype(R, /datum/reagent/consumable/nutriment)) - var/list/taste_data = LAZYACCESS(R.data, "tastes") - for(var/taste in taste_data) - var/ratio = taste_data[taste] - var/amount = ratio * R.taste_mult * R.volume - if(taste in tastes) - tastes[taste] += amount - else - tastes[taste] = amount - else - var/taste_desc = R.taste_description - var/taste_amount = R.volume * R.taste_mult - if(taste_desc in tastes) - tastes[taste_desc] += taste_amount + var/list/taste_data = reagent.get_taste_description(taster) + for(var/taste in taste_data) + if(taste in tastes) + tastes[taste] += taste_data[taste] * reagent.volume * reagent.taste_mult else - tastes[taste_desc] = taste_amount + tastes[taste] = taste_data[taste] * reagent.volume * reagent.taste_mult //deal with percentages // TODO it would be great if we could sort these from strong to weak var/total_taste = counterlist_sum(tastes) @@ -916,17 +918,17 @@ var/percent = tastes[taste_desc]/total_taste * 100 if(percent < minimum_percent) continue - var/intensity_desc = "" + var/intensity_desc = "a hint of" if(percent > minimum_percent * 2 || percent == 100) intensity_desc = "" else if(percent > minimum_percent * 3) - intensity_desc = "" + intensity_desc = "the strong flavor of" if(intensity_desc != "") out += "[intensity_desc] [taste_desc]" else out += "[taste_desc]" - return english_list(out, "something") + return english_list(out, "something indescribable") /datum/reagents/proc/expose_temperature(temperature, coeff=0.02) if(istype(my_atom,/obj/item/reagent_containers)) @@ -934,20 +936,27 @@ if(RCs.reagent_flags & NO_REACT) //stasis holders IE cryobeaker return var/temp_delta = (temperature - chem_temp) * coeff - var/old_temp = chem_temp if(temp_delta > 0) chem_temp = min(chem_temp + max(temp_delta, 1), temperature) else chem_temp = max(chem_temp + min(temp_delta, -1), temperature) - chem_temp = round(chem_temp) - - var/increased = FALSE - if(old_temp < chem_temp) - increased = TRUE - for(var/datum/reagent/R as anything in reagent_list) - R.on_temp_change(increased) + set_temperature(round(chem_temp)) handle_reactions() - SEND_SIGNAL(my_atom, COMSIG_REAGENTS_EXPOSE_TEMPERATURE, null, chem_temp) + +/** Sets the temperature of this reagent container to a new value. + * + * Handles setter signals. + * + * Arguments: + * - _temperature: The new temperature value. + */ +/datum/reagents/proc/set_temperature(_temperature) + if(_temperature == chem_temp) + return + + . = chem_temp + chem_temp = clamp(_temperature, 0, CHEMICAL_MAXIMUM_TEMPERATURE) + SEND_SIGNAL(src, COMSIG_REAGENTS_TEMP_CHANGE, _temperature, .) /** * Multiplies reagents inside this holder by a specific amount diff --git a/code/modules/reagents/chemistry/readme.md b/code/modules/reagents/chemistry/readme.md index e72fe3b83cc..7b452576679 100644 --- a/code/modules/reagents/chemistry/readme.md +++ b/code/modules/reagents/chemistry/readme.md @@ -116,7 +116,7 @@ The holder (reagents datum) is the datum that holds a list of all reagents curre # About Reagents: Reagents are all the things you can mix and fille in bottles etc. This can be anything from rejuvs over water to ... iron. Each reagent also has a few procs - i'll explain those below. ``` - reaction_mob(var/mob/living/L, var/method=TOUCH) + expose_mob(var/mob/living/L, var/method=TOUCH) This is called by the holder's reation proc. This version is only called when the reagent reacts with a mob. The method var can be either diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 11ba9dd9512..abb23e7b590 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -24,6 +24,7 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) var/shot_glass_icon_state = null var/datum/reagents/holder = null var/reagent_state = LIQUID + /// Special data associated with the reagent that will be passed on upon transfer to a new holder. KEEP UNINITIALIZED IF POSSIBLE. var/list/data var/current_cycle = 0 var/volume = 0 //pretend this is moles @@ -41,6 +42,8 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) var/reagent_weight = 1 //affects how far it travels when sprayed var/metabolizing = FALSE var/harmful = FALSE //is it bad for you? Currently only used for borghypo. C2s and Toxins have it TRUE by default. + ///The set of exposure methods this penetrates skin with. + var/penetrates_skin = VAPOR var/evaporates = TRUE ///How much fire power does the liquid have, for burning on simulated liquids. Not enough fire power/unit of entire mixture may result in no fire var/liquid_fire_power = 0 @@ -58,36 +61,22 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) var/slippery = TRUE ///do we glow? var/glows = FALSE - /// Quality of the reagent (1-4, where 4 is highest quality) - var/recipe_quality = 1 /// Base quality for newly created reagents of this type - var/base_quality = 1 + var/base_recipe_quality = COOK_QUALITY_NORMAL /datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references . = ..() holder = null -/datum/reagent/proc/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0) - if(!istype(M)) - return 0 - if(method & VAPOR) //smoke, foam, spray - if(M.reagents) - var/modifier = CLAMP((1 - touch_protection), 0, 1) - var/amount = round(reac_volume*modifier, 0.1) - - var/quality_modifier = get_quality_metabolization_modifier() - amount = amount * quality_modifier - - if(amount >= 0.5) - // Create new reagent with same quality - var/datum/reagent/new_reagent = new type() - new_reagent.recipe_quality = recipe_quality - new_reagent.data = list("quality" = recipe_quality, "volume" = amount) - M.reagents.add_reagent(type, amount, new_reagent.data) - return 1 +/// Applies this reagent to a [/mob/living] +/datum/reagent/proc/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume, show_message = TRUE, touch_protection = 0) + SHOULD_CALL_PARENT(TRUE) -/datum/reagent/proc/add_data(data_name, data_value) - LAZYADDASSOC(data, data_name, data_value) + . = SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_MOB, exposed_mob, methods, reac_volume, show_message, touch_protection) + if((methods & penetrates_skin) && exposed_mob.reagents) //smoke, foam, spray + var/amount = round(reac_volume*clamp((1 - touch_protection), 0, 1), 0.1) + if(amount >= 0.5) + exposed_mob.reagents.add_reagent(type, amount) /datum/reagent/proc/reaction_obj(obj/O, volume) return @@ -109,10 +98,6 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) if(istype(src, /datum/reagent/consumable/ethanol) && has_world_trait(/datum/world_trait/baotha_revelry)) adjusted_metabolization_rate = adjusted_metabolization_rate * (is_ascendant(BAOTHA) ? 0.33 : 0.5) - // Apply quality modifier to metabolization - var/quality_modifier = get_quality_metabolization_modifier() - adjusted_metabolization_rate = adjusted_metabolization_rate / quality_modifier // Higher quality lasts longer - holder.remove_reagent(type, adjusted_metabolization_rate) //By default it slowly disappears. if(M.client) if(!istype(src, /datum/reagent/drug) && reagent_state == LIQUID) @@ -130,24 +115,12 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) return /datum/reagent/proc/set_quality(new_quality) - recipe_quality = CLAMP(new_quality, 1, 4) - if(!data) - data = list() - data["quality"] = recipe_quality - return recipe_quality - -/datum/reagent/proc/get_recipe_quality_desc() - switch(recipe_quality) - if(1) - return "poor quality" - if(2) - return "standard quality" - if(3) - return "high quality" - if(4) - return "premium quality" - else - return "unknown quality" + LAZYSET(data, "quality", new_quality) + +/// Use this proc to lazyaccess quality data and keep data uninitialized. +/datum/reagent/proc/get_recipe_quality() + var/recipe_quality = LAZYACCESS(data, "quality") + return recipe_quality ? recipe_quality : base_recipe_quality // Called when this reagent is first added to a mob /datum/reagent/proc/on_mob_add(mob/living/L) @@ -174,75 +147,32 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) // Called after add_reagents creates a new reagent. /datum/reagent/proc/on_new(list/incoming_data) - if(incoming_data && incoming_data["quality"]) - recipe_quality = incoming_data["quality"] - else - recipe_quality = base_quality - recipe_quality = CLAMP(recipe_quality, 1, 4) - - if(!data) - data = list() - data["quality"] = recipe_quality - for(var/data_item in incoming_data) - if(data_item == "quality") //special handling for this - continue - data[data_item] = incoming_data[data_item] - if("custom_name" in data) - name = data["custom_name"] - if("custom_scent" in data) - scent_description = data["custom_scent"] - if("custom_tastes" in data) - taste_description = data["custom_tastes"] - return - -// Called when two reagents of the same are mixing. + if(incoming_data) + data = incoming_data + + if(!("quality" in data)) + data["quality"] = base_recipe_quality + if("custom_name" in data) + name = data["custom_name"] + if("custom_scent" in data) + scent_description = data["custom_scent"] + if("custom_tastes" in data) + taste_description = data["custom_tastes"] + +/// Called when two reagents of the same are mixing. Reminder that incoming_data is not automatically assigned to data here. /datum/reagent/proc/on_merge(list/incoming_data, other_volume) SHOULD_CALL_PARENT(TRUE) - if(!length(incoming_data)) - return - if("quality" in incoming_data) + if(incoming_data && incoming_data["quality"]) //special handling for this + LAZYINITLIST(data) + var/current_quality = get_recipe_quality() var/other_quality = incoming_data["quality"] - var/total_volume = volume + other_volume - var/weighted_average = ((recipe_quality * volume) + (other_quality * other_volume)) / total_volume - recipe_quality = floor(weighted_average) - - recipe_quality = CLAMP(recipe_quality, 1, 4) - - if(!data) - data = list() - data["quality"] = recipe_quality - for(var/data_item in incoming_data) - if(data_item == "quality") //special handling for this - continue - data[data_item] = incoming_data[data_item] - if("custom_name" in data) - name = data["custom_name"] - if("custom_scent" in data) - scent_description = data["custom_scent"] - if("custom_tastes" in data) - taste_description = data["custom_tastes"] - return - -/datum/reagent/proc/get_quality_metabolization_modifier() - switch(recipe_quality) - if(1) - return 0.8 // Poor quality metabolizes 20% slower (less effective) - if(2) - return 1.0 // Standard quality - no modifier - if(3) - return 1.15 // High quality - 15% more effective - if(4) - return 1.3 // Premium quality - 30% more effective - else - return 1.0 + var/weighted_average = LERP(current_quality, other_quality, other_volume / volume) + data["quality"] = weighted_average /datum/reagent/proc/on_update(atom/A) return -//called on expose_temperature -/datum/reagent/proc/on_temp_change(chem_temp) - return // Called when the reagent container is hit by an explosion /datum/reagent/proc/on_ex_act(severity) return @@ -275,6 +205,10 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) if(prob(30)) to_chat(M, "You're not feeling good at all! You really need some [name].") +/// Should return a associative list where keys are taste descriptions and values are strength ratios +/datum/reagent/proc/get_taste_description(mob/living/taster) + return list("[taste_description]" = 1) + /datum/reagent/proc/add_to_member(obj/effect/abstract/liquid_turf/adder) return diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 32ab1617763..34244cde73f 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -79,12 +79,12 @@ All effects don't start immediately, but rather get worse over time; the rate is O.visible_message("[O]'s ink is smeared by [name], but doesn't wash away!") return -/datum/reagent/consumable/ethanol/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with ethanol isn't quite as good as fuel. - if(!isliving(M)) +/datum/reagent/consumable/ethanol/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume)//Splashing people with ethanol isn't quite as good as fuel. + if(!isliving(exposed_mob)) return - if(method in list(TOUCH, VAPOR, PATCH)) - M.adjust_fire_stacks(reac_volume / 15) + if(methods in list(TOUCH, VAPOR, PATCH)) + exposed_mob.adjust_fire_stacks(reac_volume / 15) return ..() diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index f07825376ea..2ba737e0d8d 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -25,9 +25,9 @@ H.adjust_hydration(hydration_factor * actual_metabolized) return ..() -/datum/reagent/consumable/reaction_mob(mob/living/M, method=TOUCH, reac_volume) - if ((method & INGEST) && ishuman(M)) - var/mob/living/carbon/human/HM = M +/datum/reagent/consumable/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume) + if ((methods & INGEST) && ishuman(exposed_mob)) + var/mob/living/carbon/human/HM = exposed_mob if(HM.culinary_preferences) var/favorite_drink_type = HM.culinary_preferences[CULINARY_FAVOURITE_DRINK] @@ -55,27 +55,27 @@ if (quality) switch (quality) if (DRINK_NICE) - M.add_stress(/datum/stress_event/wine_okay) + exposed_mob.add_stress(/datum/stress_event/wine_okay) if (prob(25)) - to_chat(M, span_green("Not bad.")) + to_chat(exposed_mob, span_green("Not bad.")) if (HM.is_noble() || HM.is_courtier() || HM.is_yeoman()) - M.remove_stress(/datum/stress_event/noble_bland_food) + exposed_mob.remove_stress(/datum/stress_event/noble_bland_food) if (DRINK_GOOD) - M.add_stress(/datum/stress_event/wine_good) + exposed_mob.add_stress(/datum/stress_event/wine_good) if (prob(25)) - to_chat(M, span_green("A fine beverage.")) + to_chat(exposed_mob, span_green("A fine beverage.")) if (HM.is_noble() || HM.is_courtier() || HM.is_yeoman()) - M.remove_stress(list(/datum/stress_event/noble_impoverished_food, /datum/stress_event/noble_bland_food)) + exposed_mob.remove_stress(list(/datum/stress_event/noble_impoverished_food, /datum/stress_event/noble_bland_food)) if (DRINK_VERYGOOD to DRINK_FANTASTIC) if (HM.is_noble() || HM.is_courtier() || HM.is_yeoman()) - M.add_stress(/datum/stress_event/wine_great) - M.remove_stress(list(/datum/stress_event/noble_desperate, /datum/stress_event/noble_impoverished_food, /datum/stress_event/noble_bland_food, /datum/stress_event/noble_bad_manners, /datum/stress_event/noble_ate_without_table)) + exposed_mob.add_stress(/datum/stress_event/wine_great) + exposed_mob.remove_stress(list(/datum/stress_event/noble_desperate, /datum/stress_event/noble_impoverished_food, /datum/stress_event/noble_bland_food, /datum/stress_event/noble_bad_manners, /datum/stress_event/noble_ate_without_table)) if (prob(25)) - to_chat(M, span_blue("Absolutely exquisite!")) + to_chat(exposed_mob, span_blue("Absolutely exquisite!")) else - M.add_stress(/datum/stress_event/wine_good) + exposed_mob.add_stress(/datum/stress_event/wine_good) if (prob(25)) - to_chat(M, span_green("Complex, but good.")) + to_chat(exposed_mob, span_green("Complex, but good.")) return ..() /datum/reagent/consumable/nutriment @@ -134,6 +134,9 @@ counterlist_normalise(taste_amounts) LAZYSET(data, "tastes", taste_amounts) +/datum/reagent/consumable/nutriment/get_taste_description(mob/living/taster) + return data["tastes"] + /datum/reagent/consumable/nutriment/vitamin name = "Vitamin" description = "All the best vitamins, minerals, and carbohydrates the body needs in pure form." diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 86aaf9bc26f..74e3139c5ec 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -10,6 +10,7 @@ glass_name = "glass of tomato juice" glass_desc = "" shot_glass_icon_state = "shotglassred" + penetrates_skin = NONE var/toxicity = 0.7 // how toxic will this be to digest to people who cannot drink it /datum/reagent/blood/tiefling @@ -29,46 +30,47 @@ data["preferences"] &= ~(BLOOD_PREFERENCE_LIVING|BLOOD_PREFERENCE_SLEEPING) . = ..() -/datum/reagent/blood/reaction_mob(mob/living/L, method=TOUCH, reac_volume) +/datum/reagent/blood/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume) . = ..() - if(!(. && method & (INJECT|INGEST))) + if(!(. && methods & (INJECT|INGEST))) return - SEND_SIGNAL(L, COMSIG_HANDLE_INFUSION, data["blood_type"], reac_volume) - var/datum/dna/L_dna = L.has_dna() - var/drinking_self = L_dna?.unique_enzymes && L_dna.unique_enzymes == data["blood_DNA"] + SEND_SIGNAL(exposed_mob, COMSIG_HANDLE_INFUSION, data["blood_type"], reac_volume) + var/datum/dna/exposed_mob_dna = exposed_mob.has_dna() + var/drinking_self = exposed_mob_dna?.unique_enzymes && exposed_mob_dna.unique_enzymes == data["blood_DNA"] //if the dna matches, you're drinking your own blood freak. - if(!drinking_self && L.clan && data["vitae"] > 0) - var/vitae = L.clan.handle_bloodsuck(L, data["preferences"], reac_volume * data["vitae"]) - L.adjust_bloodpool(vitae) - L.adjust_hydration(vitae * 0.1) + if(!drinking_self && exposed_mob.clan && data["vitae"] > 0) + var/vitae = exposed_mob.clan.handle_bloodsuck(exposed_mob, data["preferences"], reac_volume * data["vitae"]) + exposed_mob.adjust_bloodpool(vitae) + exposed_mob.adjust_hydration(vitae * 0.1) - var/mob/living/carbon/C = L - if(istype(C) && (NOBLOOD in C.dna?.species?.species_traits)) + var/mob/living/carbon/exposed_carbon = exposed_mob + if(istype(exposed_carbon) && (NOBLOOD in exposed_carbon.dna?.species?.species_traits)) return //if it's non-toxic, drink up, otherwise, you need the blooddrinker trait and it has to be a blood you're compatible with or you need to be a nasty eater - if(method & INJECT) - L.blood_volume = min(L.blood_volume + round(reac_volume, 0.1), BLOOD_VOLUME_MAXIMUM) + if(methods & INJECT) + exposed_mob.blood_volume = min(exposed_mob.blood_volume + round(reac_volume, 0.1), BLOOD_VOLUME_MAXIMUM) return - if(method & INGEST) - if(!drinking_self && (toxicity <= 0 || (HAS_TRAIT(L, TRAIT_BLOODDRINKER) || HAS_TRAIT(L, TRAIT_NASTY_EATER)))) - if(!HAS_TRAIT(L, TRAIT_NOHUNGER)) - L.adjust_hydration(reac_volume * 0.2) - if(L.blood_volume < BLOOD_VOLUME_NORMAL) - L.blood_volume = min(L.blood_volume + reac_volume * 0.2 , BLOOD_VOLUME_NORMAL) + if(methods & INGEST) + if(!drinking_self && (toxicity <= 0 || (HAS_TRAIT(exposed_mob, TRAIT_BLOODDRINKER) || HAS_TRAIT(exposed_mob, TRAIT_NASTY_EATER)))) + if(!HAS_TRAIT(exposed_mob, TRAIT_NOHUNGER)) + exposed_mob.adjust_hydration(reac_volume * 0.2) + if(exposed_mob.blood_volume < BLOOD_VOLUME_NORMAL) + exposed_mob.blood_volume = min(exposed_mob.blood_volume + reac_volume * 0.2 , BLOOD_VOLUME_NORMAL) return var/tox = toxicity * reac_volume - if(HAS_TRAIT(L, TRAIT_POISON_RESILIENCE)) + if(HAS_TRAIT(exposed_carbon, TRAIT_POISON_RESILIENCE)) tox *= 0.5 - L.adjustToxLoss(tox) - C.add_nausea(tox * 2) + exposed_mob.adjustToxLoss(tox) + exposed_carbon.add_nausea(tox * 2) /datum/reagent/blood/on_merge(list/mix_data, other_volume) . = ..() - data["vitae"] = (data["vitae"] * volume + (mix_data?["vitae"] || 0) * other_volume) / (volume + other_volume) // weighted average of both vitae - data["preferences"] |= mix_data?["preferences"] // i have no idea how to effectively deal with this issue, this is gonna get weird sometimes. - if(mix_data && data["blood_DNA"] != mix_data["blood_DNA"]) - data["cloneable"] = 0 //On mix, consider the genetic sampling unviable for pod cloning if the DNA sample doesn't match. - return 1 + if(mix_data) + data["vitae"] = (data["vitae"] * volume + (mix_data?["vitae"] || 0) * other_volume) / (volume + other_volume) // weighted average of both vitae + data["preferences"] |= mix_data?["preferences"] // i have no idea how to effectively deal with this issue, this is gonna get weird sometimes. + if(mix_data && data["blood_DNA"] != mix_data["blood_DNA"]) + data["cloneable"] = 0 //On mix, consider the genetic sampling unviable for pod cloning if the DNA sample doesn't match. + return TRUE /datum/reagent/blood/reaction_turf(turf/T, reac_volume)//splash the blood all over the place if(!istype(T)) @@ -172,7 +174,7 @@ for(var/atom/movable/thing as anything in T.contents) if(ismob(thing)) var/mob/M = thing - reaction_mob(M, reac_volume) + expose_mob(M, reac_volume) else if(isobj(thing)) var/obj/O = thing reaction_obj(O, reac_volume) @@ -206,14 +208,14 @@ * Water reaction to a mob */ -/datum/reagent/water/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with water can help put them out! - if(!istype(M)) +/datum/reagent/water/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume)//Splashing people with water can help put them out! + if(!istype(exposed_mob)) return - if(method & TOUCH) - var/turf/turf_check = get_turf(M) + if(methods & TOUCH) + var/turf/turf_check = get_turf(exposed_mob) if(!istype(turf_check, /turf/open/water)) - M.adjust_fire_stacks(-(reac_volume / 10)) - M.SoakMob(FULL_BODY) + exposed_mob.adjust_fire_stacks(-(reac_volume / 10)) + exposed_mob.SoakMob(FULL_BODY) return ..() @@ -257,9 +259,9 @@ glass_name = "glass of lighter fuel" glass_desc = "" -/datum/reagent/fuel/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with welding fuel to make them easy to ignite! - if((method & TOUCH) || (method & VAPOR)) - M.adjust_fire_stacks(reac_volume / 10) +/datum/reagent/fuel/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume)//Splashing people with welding fuel to make them easy to ignite! + if((methods & TOUCH) || (methods& VAPOR)) + exposed_mob.adjust_fire_stacks(reac_volume / 10) return ..() diff --git a/code/modules/reagents/chemistry/reagents/roguetown.dm b/code/modules/reagents/chemistry/reagents/roguetown.dm index be8c3eff672..3abfc7eeda3 100644 --- a/code/modules/reagents/chemistry/reagents/roguetown.dm +++ b/code/modules/reagents/chemistry/reagents/roguetown.dm @@ -23,8 +23,8 @@ taste_description = "burning" self_consuming = TRUE -/datum/reagent/rogueacid/reaction_mob(mob/living/M, method=TOUCH, reac_volume) - M.adjustFireLoss(35, 0) +/datum/reagent/rogueacid/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume) + exposed_mob.adjustFireLoss(35, 0) ..() /datum/reagent/blastpowder diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index da84fb22c1b..f0f64f14a07 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -32,9 +32,9 @@ color = "#8228A0" toxpwr = 3 -/datum/reagent/toxin/plasma/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with plasma is stronger than fuel! - if((method & TOUCH) || (method & VAPOR)) - M.adjust_fire_stacks(reac_volume / 5) +/datum/reagent/toxin/plasma/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume)//Splashing people with plasma is stronger than fuel! + if((methods & TOUCH) || (methods & VAPOR)) + exposed_mob.adjust_fire_stacks(reac_volume / 5) return ..() @@ -159,20 +159,21 @@ taste_description = "acid" self_consuming = TRUE -/datum/reagent/toxin/acid/reaction_mob(mob/living/carbon/C, method=TOUCH, reac_volume) - if(!istype(C)) +/datum/reagent/toxin/acid/expose_mob(mob/living/carbon/exposed_mob, methods = TOUCH, reac_volume) + . = ..() + if(!istype(exposed_mob)) return reac_volume = round(reac_volume,0.1) - if(method & INGEST) - C.adjustBruteLoss(min(6*toxpwr, reac_volume * toxpwr)) + if(methods & INGEST) + exposed_mob.adjustBruteLoss(min(6*toxpwr, reac_volume * toxpwr)) return - if(method & INJECT) - C.adjustBruteLoss(1.5 * min(6*toxpwr, reac_volume * toxpwr)) + if(methods & INJECT) + exposed_mob.adjustBruteLoss(1.5 * min(6*toxpwr, reac_volume * toxpwr)) return - C.acid_act(acidpwr, reac_volume) + exposed_mob.acid_act(acidpwr, reac_volume) - if(method & TOUCH) - C.try_skin_burn(reac_volume) + if(methods & TOUCH) + exposed_mob.try_skin_burn(reac_volume) /datum/reagent/toxin/acid/reaction_obj(obj/O, reac_volume) if(ismob(O.loc)) //handled in human acid_act() diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index b0e1d0da2e9..b08f512f855 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -62,6 +62,10 @@ if(is_open_container()) GLOB.weather_act_upon_list |= src +/obj/item/reagent_containers/create_reagents(max_vol, flags) + . = ..() + RegisterSignal(reagents, COMSIG_REAGENTS_HOLDER_UPDATED, PROC_REF(on_reagent_change)) + /obj/item/reagent_containers/examine(mob/user) . = ..() if(has_variable_transfer_amount && length(possible_transfer_amounts) > 1) @@ -91,9 +95,10 @@ reagents.expose_temperature(added) ..() -/obj/item/reagent_containers/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) +/obj/item/reagent_containers/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum, do_splash = TRUE) . = ..() - SplashReagents(hit_atom, TRUE) + if(do_splash) + SplashReagents(hit_atom, TRUE) /obj/item/reagent_containers/heating_act() reagents.expose_temperature(1000) @@ -102,7 +107,8 @@ /obj/item/reagent_containers/temperature_expose(exposed_temperature, exposed_volume) reagents.expose_temperature(exposed_temperature) -/obj/item/reagent_containers/on_reagent_change(changetype) +/obj/item/reagent_containers/proc/on_reagent_change(datum/reagents/holder, ...) + SIGNAL_HANDLER update_appearance(UPDATE_OVERLAYS) /obj/item/reagent_containers/update_overlays() @@ -242,6 +248,60 @@ balloon_alert(user, "transferring [UNIT_FORM_STRING(amount_per_transfer_from_this)].") mode_change_message(user) +/obj/item/reagent_containers/pre_attack(atom/target, mob/living/user, list/modifiers) + if(HAS_TRAIT(target, TRAIT_DO_NOT_SPLASH)) + return ..() + if(try_splash(user, target)) + return TRUE + + return ..() + +/// Tries to splash the target. +/obj/item/reagent_containers/proc/try_splash(mob/user, atom/target) + if (!spillable) + return FALSE + if (!reagents?.total_volume) + return FALSE + if(user.used_intent.type != INTENT_SPLASH) + return FALSE + + var/punctuation = ismob(target) ? "!" : "." + var/reagent_text + + user.visible_message( + span_danger("[user] splashes the contents of [src] onto [target][punctuation]"), + span_danger("You splash the contents of [src] onto [target][punctuation]"), + ignored_mobs = target) + if(ismob(target) && user != target) + var/mob/target_mob = target + target_mob.show_message( + span_userdanger("[user] splash the contents of [src] onto you!"), + MSG_VISUAL, + span_userdanger("You feel drenched!")) + + var/mutable_appearance/splash_animation = mutable_appearance('icons/effects/effects.dmi', "splash") + if(isturf(target)) + splash_animation.icon_state = "splash_floor" + splash_animation.color = mix_color_from_reagents(reagents.reagent_list) + target.flick_overlay_view(splash_animation, 1 SECONDS) + + playsound(target, pick('sound/foley/water_land1.ogg','sound/foley/water_land2.ogg', 'sound/foley/water_land3.ogg'), 25, FALSE) + + for(var/datum/reagent/reagent as anything in reagents.reagent_list) + reagent_text += "[reagent] ([num2text(reagent.volume)])," + + var/mob/thrown_by = thrownby?.resolve() + if(isturf(target) && reagents.reagent_list.len && thrown_by) + log_combat(thrown_by, target, "splashed (thrown) [english_list(reagents.reagent_list)]") + message_admins("[ADMIN_LOOKUPFLW(thrown_by)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] at [ADMIN_VERBOSEJMP(target)].") + + SEND_SIGNAL(user, COMSIG_SPLASHED_MOB, target, reagents.reagent_list) + reagents.reaction(target, TOUCH) + chem_splash(target.loc, 2, list(reagents)) + log_combat(user, target, "splashed", reagent_text) + + return TRUE + /obj/item/reagent_containers/proc/canconsume(mob/eater, mob/user, silent = FALSE) if(!iscarbon(eater)) return FALSE @@ -266,13 +326,15 @@ /obj/item/reagent_containers/proc/bartender_check(atom/target) . = FALSE - if(target.CanPass(src, get_turf(src)) && thrownby && HAS_TRAIT(thrownby, TRAIT_BOOZE_SLIDER)) + var/mob/thrown_by = thrownby?.resolve() + if(target.CanPass(src, get_dir(target, src)) && thrown_by && HAS_TRAIT(thrown_by, TRAIT_BOOZE_SLIDER)) . = TRUE /obj/item/reagent_containers/proc/SplashReagents(atom/target, thrown = FALSE) if(!reagents || !reagents.total_volume || !spillable) return + var/mob/thrown_by = thrownby?.resolve() if(ismob(target) && target.reagents) if(thrown) reagents.total_volume *= rand(5,10) * 0.1 //Not all of it makes contact with the target @@ -283,8 +345,8 @@ for(var/datum/reagent/A in reagents.reagent_list) R += "[A.type] ([num2text(A.volume)])," - if(thrownby) - log_combat(thrownby, M, "splashed", R) + if(thrown_by) + log_combat(thrown_by, M, "splashed", R) reagents.reaction(target, TOUCH) else if(bartender_check(target) && thrown) @@ -296,10 +358,10 @@ var/turf/target_turf = target if(istype(target_turf, /turf/open)) target_turf.add_liquid_from_reagents(reagents, FALSE, reagents.chem_temp) - if(reagents.reagent_list.len && thrownby) - log_combat(thrownby, target, "splashed (thrown) [english_list(reagents.reagent_list)]", "in [AREACOORD(target)]") - log_game("[key_name(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] in [AREACOORD(target)].") - message_admins("[ADMIN_LOOKUPFLW(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] in [ADMIN_VERBOSEJMP(target)].") + if(reagents.reagent_list.len && thrown_by) + log_combat(thrown_by, target, "splashed (thrown) [english_list(reagents.reagent_list)]", "in [AREACOORD(target)]") + log_game("[key_name(thrown_by)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] in [AREACOORD(target)].") + message_admins("[ADMIN_LOOKUPFLW(thrown_by)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] in [ADMIN_VERBOSEJMP(target)].") visible_message("[src] spills its contents all over [target].") reagents.reaction(target, TOUCH) if(QDELETED(src)) diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 9717fa43ff8..9f2918f0f0d 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -95,24 +95,6 @@ if(!reagents?.total_volume) to_chat(user, span_danger("[src] is empty!")) return - if(user.used_intent.type == INTENT_SPLASH) - var/R - M.visible_message(span_danger("[user] splashes the contents of [src] onto [M]!"), \ - span_danger("[user] splashes the contents of [src] onto you!")) - if(reagents) - for(var/datum/reagent/A as anything in reagents.reagent_list) - R += "[A] ([num2text(A.volume)])," - - if(reagents?.reagent_list && user) - log_combat(user, M, "splashed (thrown) [english_list(reagents.reagent_list)]") - message_admins("[ADMIN_LOOKUPFLW(user)] splashed (thrown) [english_list(reagents.reagent_list)] on [M] at [ADMIN_VERBOSEJMP(M)].") - - SEND_SIGNAL(user, COMSIG_SPLASHED_MOB, M, reagents.reagent_list) - reagents.reaction(M, TOUCH) - chem_splash(M.loc, 2, list(reagents)) - playsound(M, pick('sound/foley/water_land1.ogg','sound/foley/water_land2.ogg', 'sound/foley/water_land3.ogg'), 100, FALSE) - log_combat(user, M, "splashed", R) - return if(user.used_intent.type == INTENT_POUR) if(!canconsume(M, user)) return @@ -140,9 +122,7 @@ bowl_check.usages += 1 if(bowl_check.usages >= bowl_check.max_usages && !bowl_check.dirty) bowl_check.dirty = TRUE - var/datum/component/particle_spewer = bowl_check.GetComponent(/datum/component/particle_spewer/sparkle) - if(particle_spewer) - qdel(particle_spewer) + qdel(bowl_check.GetComponent(/datum/component/particle_spewer/sparkle/turf_only)) bowl_check.update_appearance(UPDATE_OVERLAYS) if(human_user.is_noble()) // egads we're an unmannered SLOB human_user.add_stress(/datum/stress_event/noble_bad_manners) diff --git a/code/modules/spells/spell_types/pointed/endure.dm b/code/modules/spells/spell_types/pointed/endure.dm index bee596f3f41..c07450bcff2 100644 --- a/code/modules/spells/spell_types/pointed/endure.dm +++ b/code/modules/spells/spell_types/pointed/endure.dm @@ -44,7 +44,7 @@ var/zcross_trigger = FALSE // Bonuses! Flavour! SOVL! - for(var/obj/item/clothing/neck/current_item in target.get_equipped_items(TRUE)) + for(var/obj/item/clothing/neck/current_item in target.get_equipped_items(INCLUDE_POCKETS)) if(istype(current_item, /obj/item/clothing/neck/psycross)) pp += 1 if(pp >= 12 & target == user) // A harmless easter-egg. Only applies on self-cast. You'd have to be pretty deliberate to wear 12 of them. diff --git a/code/modules/spells/spell_types/pointed/heat_metal.dm b/code/modules/spells/spell_types/pointed/heat_metal.dm index 0cc48294fce..2305d570766 100644 --- a/code/modules/spells/spell_types/pointed/heat_metal.dm +++ b/code/modules/spells/spell_types/pointed/heat_metal.dm @@ -59,20 +59,20 @@ /datum/action/cooldown/spell/heat_metal/proc/handle_tongs(obj/item/weapon/tongs/T) //Stole the code from smithing. if(!T.held_item) return - var/tyme = world.time + 20 SECONDS - T.hott = tyme - addtimer(CALLBACK(T, TYPE_PROC_REF(/obj/item/weapon/tongs, make_unhot), tyme), 30 SECONDS) - T.proxy_heat(150) - T.update_appearance(UPDATE_ICON_STATE) + // var/tyme = world.time + 20 SECONDS + // T.hott = tyme + // addtimer(CALLBACK(T, TYPE_PROC_REF(/obj/item/weapon/tongs, make_unhot), tyme), 30 SECONDS) + // T.proxy_heat(150) + // T.update_appearance(UPDATE_ICON_STATE) T.visible_message("After [owner]'s incantation, [T.held_item] inside [T] starts glowing from divine heat.") /datum/action/cooldown/spell/heat_metal/proc/handle_anvil(obj/machinery/anvil/A) //Stole the code from smithing. - if(A.hingot) - A.hott = world.time - START_PROCESSING(SSmachines, A) - A.cool_time = 30 SECONDS - addtimer(VARSET_CALLBACK(A, cool_time, 10 SECONDS), 30 SECONDS) - A.update_appearance(UPDATE_ICON_STATE) + // if(A.hingot) + // A.hott = world.time + // START_PROCESSING(SSmachines, A) + // A.cool_time = 30 SECONDS + // addtimer(VARSET_CALLBACK(A, cool_time, 10 SECONDS), 30 SECONDS) + // A.update_appearance(UPDATE_ICON_STATE) A.visible_message("After [owner]'s incantation, [A] begins to glow from divine heat.") /datum/action/cooldown/spell/heat_metal/proc/handle_living_entity(mob/target) @@ -92,7 +92,9 @@ return if(iscarbon(target)) - if(target.is_holding(targeteditem)) + if(target == owner) + handle_item_smelting(targeteditem) + else if(target.is_holding(targeteditem)) handle_heating_in_hand(target, targeteditem) else handle_heating_equipped(target, targeteditem) @@ -156,6 +158,9 @@ /datum/action/cooldown/spell/heat_metal/proc/get_targeted_item(mob/target) var/target_item + if(target == owner) + target_item = owner.get_active_held_item() + return target_item switch(owner.zone_selected) if(BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_PRECISE_R_INHAND) target_item = target.held_items[2] diff --git a/code/modules/spells/spell_types/pointed/respite.dm b/code/modules/spells/spell_types/pointed/respite.dm index e8dddc9aacc..8323103f62f 100644 --- a/code/modules/spells/spell_types/pointed/respite.dm +++ b/code/modules/spells/spell_types/pointed/respite.dm @@ -25,7 +25,7 @@ var/sit_bonus2 = 0 var/psicross_bonus = 0 - for(var/obj/item/clothing/neck/current_item in H.get_equipped_items(TRUE)) + for(var/obj/item/clothing/neck/current_item in H.get_equipped_items(INCLUDE_POCKETS)) if(istype(current_item, /obj/item/clothing/neck/psycross)) switch(current_item.type) // Worn Psicross Piety bonus. For fun. if(/obj/item/clothing/neck/psycross) diff --git a/code/modules/spells/spell_types/undirected/touch/orison.dm b/code/modules/spells/spell_types/undirected/touch/orison.dm index 51701a61328..ee760c05aa4 100644 --- a/code/modules/spells/spell_types/undirected/touch/orison.dm +++ b/code/modules/spells/spell_types/undirected/touch/orison.dm @@ -216,15 +216,15 @@ if (upd) M.update_damage_overlays() -/datum/reagent/water/blessed/reaction_mob(mob/living/M, method=TOUCH, reac_volume) - if (!istype(M)) +/datum/reagent/water/blessed/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume) + if (!istype(exposed_mob)) return ..() - if (method & TOUCH) - if (M.mob_biotypes & MOB_UNDEAD) - M.adjustFireLoss(2*reac_volume, 0) - M.visible_message(span_warning("[M] erupts into angry fizzling and hissing!"), span_warning("BLESSED WATER!!! IT BURNS!!!")) - M.emote("scream") + if (methods & TOUCH) + if (exposed_mob.mob_biotypes & MOB_UNDEAD) + exposed_mob.adjustFireLoss(2*reac_volume, 0) + exposed_mob.visible_message(span_warning("[exposed_mob] erupts into angry fizzling and hissing!"), span_warning("BLESSED WATER!!! IT BURNS!!!")) + exposed_mob.emote("scream") return ..() diff --git a/code/modules/surgery/surgery_helpers.dm b/code/modules/surgery/surgery_helpers.dm index 59a48d52760..5bd4437a568 100644 --- a/code/modules/surgery/surgery_helpers.dm +++ b/code/modules/surgery/surgery_helpers.dm @@ -2,7 +2,7 @@ var/covered_locations = NONE //based on body_parts_covered if(iscarbon(victim)) var/mob/living/carbon/carbon_victim = victim - for(var/obj/item/equipped_item in carbon_victim.get_equipped_items(include_pockets = FALSE)) + for(var/obj/item/equipped_item in carbon_victim.get_equipped_items()) if(zone2covered(location, equipped_item.body_parts_covered) && equipped_item.surgery_cover) return FALSE if(ishuman(carbon_victim)) diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index c9f499653ec..70c8bd06c33 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/hud/anvil_hud.dmi b/icons/hud/anvil_hud.dmi index 1d5e7fa0b09..62d05219e7e 100644 Binary files a/icons/hud/anvil_hud.dmi and b/icons/hud/anvil_hud.dmi differ diff --git a/sound/foley/footsteps/armor/coatplates (1).ogg b/sound/foley/footsteps/armor/coatplates (1).ogg index a06d0f4e511..f6d3521e7f8 100644 Binary files a/sound/foley/footsteps/armor/coatplates (1).ogg and b/sound/foley/footsteps/armor/coatplates (1).ogg differ diff --git a/sound/foley/footsteps/armor/coatplates (2).ogg b/sound/foley/footsteps/armor/coatplates (2).ogg index ecef00c5de6..02019cfba37 100644 Binary files a/sound/foley/footsteps/armor/coatplates (2).ogg and b/sound/foley/footsteps/armor/coatplates (2).ogg differ diff --git a/sound/foley/footsteps/armor/coatplates (3).ogg b/sound/foley/footsteps/armor/coatplates (3).ogg index c392f0b0006..89947ebd0d5 100644 Binary files a/sound/foley/footsteps/armor/coatplates (3).ogg and b/sound/foley/footsteps/armor/coatplates (3).ogg differ diff --git a/sound/foley/footsteps/armor/plate (1).ogg b/sound/foley/footsteps/armor/plate (1).ogg index 7080892593b..1cf25fb600d 100644 Binary files a/sound/foley/footsteps/armor/plate (1).ogg and b/sound/foley/footsteps/armor/plate (1).ogg differ diff --git a/sound/foley/footsteps/armor/plate (2).ogg b/sound/foley/footsteps/armor/plate (2).ogg index 4e626ebfa99..46e0b60d6ff 100644 Binary files a/sound/foley/footsteps/armor/plate (2).ogg and b/sound/foley/footsteps/armor/plate (2).ogg differ diff --git a/sound/foley/footsteps/armor/plate (3).ogg b/sound/foley/footsteps/armor/plate (3).ogg index 5af889f4d6e..b735d0e2b0d 100644 Binary files a/sound/foley/footsteps/armor/plate (3).ogg and b/sound/foley/footsteps/armor/plate (3).ogg differ diff --git a/sound/items/bsmith1.ogg b/sound/items/bsmith1.ogg index bece24d511b..5848180212f 100644 Binary files a/sound/items/bsmith1.ogg and b/sound/items/bsmith1.ogg differ diff --git a/sound/items/bsmith2.ogg b/sound/items/bsmith2.ogg index 2435fba36a1..38522711cd5 100644 Binary files a/sound/items/bsmith2.ogg and b/sound/items/bsmith2.ogg differ diff --git a/sound/items/bsmith3.ogg b/sound/items/bsmith3.ogg index 9266396542a..499726d093c 100644 Binary files a/sound/items/bsmith3.ogg and b/sound/items/bsmith3.ogg differ diff --git a/sound/items/bsmith4.ogg b/sound/items/bsmith4.ogg index 0e149dcc79e..c0832ecf0f9 100644 Binary files a/sound/items/bsmith4.ogg and b/sound/items/bsmith4.ogg differ diff --git a/sound/items/bsmithfail.ogg b/sound/items/bsmithfail.ogg index 477d2b5ea6e..11096035c58 100644 Binary files a/sound/items/bsmithfail.ogg and b/sound/items/bsmithfail.ogg differ diff --git a/sound/items/empty_shovel.ogg b/sound/items/empty_shovel.ogg index f1d1e1219fb..5f8cfa0096b 100644 Binary files a/sound/items/empty_shovel.ogg and b/sound/items/empty_shovel.ogg differ diff --git a/sound/items/fillbottle.ogg b/sound/items/fillbottle.ogg index 4a356acd602..eadaa563380 100644 Binary files a/sound/items/fillbottle.ogg and b/sound/items/fillbottle.ogg differ diff --git a/sound/items/fillcup.ogg b/sound/items/fillcup.ogg index b127307f3d0..dbf7b0dc3ec 100644 Binary files a/sound/items/fillcup.ogg and b/sound/items/fillcup.ogg differ diff --git a/sound/items/firelight.ogg b/sound/items/firelight.ogg index 18034eda2c8..7190dca77f1 100644 Binary files a/sound/items/firelight.ogg and b/sound/items/firelight.ogg differ diff --git a/sound/items/firesnuff.ogg b/sound/items/firesnuff.ogg index 90fd1b9fba7..d93e67e115c 100644 Binary files a/sound/items/firesnuff.ogg and b/sound/items/firesnuff.ogg differ diff --git a/sound/items/visor.ogg b/sound/items/visor.ogg index 69b71b49b7d..627cf3c9d44 100644 Binary files a/sound/items/visor.ogg and b/sound/items/visor.ogg differ diff --git a/sound/misc/beep.ogg b/sound/misc/beep.ogg index 83f05ddf48d..5ca1515ebb7 100644 Binary files a/sound/misc/beep.ogg and b/sound/misc/beep.ogg differ diff --git a/sound/vo/male/gen/laugh (1).ogg b/sound/vo/male/gen/laugh (1).ogg index 86f1a16ce3f..c8b6bcd8d71 100644 Binary files a/sound/vo/male/gen/laugh (1).ogg and b/sound/vo/male/gen/laugh (1).ogg differ diff --git a/sound/vo/male/gen/laugh (2).ogg b/sound/vo/male/gen/laugh (2).ogg index 3b2eb467871..e9b4a636e7e 100644 Binary files a/sound/vo/male/gen/laugh (2).ogg and b/sound/vo/male/gen/laugh (2).ogg differ diff --git a/sound/vo/male/gen/laugh (3).ogg b/sound/vo/male/gen/laugh (3).ogg index bf6acaff9e3..302d3f44222 100644 Binary files a/sound/vo/male/gen/laugh (3).ogg and b/sound/vo/male/gen/laugh (3).ogg differ diff --git a/sound/vo/male/gen/laugh (4).ogg b/sound/vo/male/gen/laugh (4).ogg index e9986214421..b1075587797 100644 Binary files a/sound/vo/male/gen/laugh (4).ogg and b/sound/vo/male/gen/laugh (4).ogg differ diff --git a/sound/vo/male/gen/laugh (5).ogg b/sound/vo/male/gen/laugh (5).ogg index e238c056dfc..8ff86317cf0 100644 Binary files a/sound/vo/male/gen/laugh (5).ogg and b/sound/vo/male/gen/laugh (5).ogg differ diff --git a/sound/vo/male/gen/laugh (6).ogg b/sound/vo/male/gen/laugh (6).ogg index 5d9c48a8612..05e0c255c10 100644 Binary files a/sound/vo/male/gen/laugh (6).ogg and b/sound/vo/male/gen/laugh (6).ogg differ diff --git a/sound/vo/male/gen/pain (1).ogg b/sound/vo/male/gen/pain (1).ogg index 36e4d0c3e55..d7707009f35 100644 Binary files a/sound/vo/male/gen/pain (1).ogg and b/sound/vo/male/gen/pain (1).ogg differ diff --git a/sound/vo/male/gen/pain (2).ogg b/sound/vo/male/gen/pain (2).ogg index d0e74532469..3c900e38bfd 100644 Binary files a/sound/vo/male/gen/pain (2).ogg and b/sound/vo/male/gen/pain (2).ogg differ diff --git a/sound/vo/male/gen/pain (3).ogg b/sound/vo/male/gen/pain (3).ogg index 9cc72c0c771..12314b6b6c8 100644 Binary files a/sound/vo/male/gen/pain (3).ogg and b/sound/vo/male/gen/pain (3).ogg differ diff --git a/sound/vo/male/gen/paincrit (1).ogg b/sound/vo/male/gen/paincrit (1).ogg index 391973515e6..4b04e68db2a 100644 Binary files a/sound/vo/male/gen/paincrit (1).ogg and b/sound/vo/male/gen/paincrit (1).ogg differ diff --git a/sound/vo/male/gen/paincrit (2).ogg b/sound/vo/male/gen/paincrit (2).ogg index fe641e6979b..e92c6b01464 100644 Binary files a/sound/vo/male/gen/paincrit (2).ogg and b/sound/vo/male/gen/paincrit (2).ogg differ diff --git a/sound/vo/male/gen/painmoan (1).ogg b/sound/vo/male/gen/painmoan (1).ogg index 514c304b820..6b2dcc6f557 100644 Binary files a/sound/vo/male/gen/painmoan (1).ogg and b/sound/vo/male/gen/painmoan (1).ogg differ diff --git a/sound/vo/male/gen/painmoan (2).ogg b/sound/vo/male/gen/painmoan (2).ogg index dd2ce419af3..bddbb7d8436 100644 Binary files a/sound/vo/male/gen/painmoan (2).ogg and b/sound/vo/male/gen/painmoan (2).ogg differ diff --git a/sound/vo/male/gen/painmoan (3).ogg b/sound/vo/male/gen/painmoan (3).ogg index 296c6fa0d50..d1d991aa690 100644 Binary files a/sound/vo/male/gen/painmoan (3).ogg and b/sound/vo/male/gen/painmoan (3).ogg differ diff --git a/sound/vo/male/gen/painmoan (4).ogg b/sound/vo/male/gen/painmoan (4).ogg index 4b28d34d1f6..fda0fb01234 100644 Binary files a/sound/vo/male/gen/painmoan (4).ogg and b/sound/vo/male/gen/painmoan (4).ogg differ diff --git a/sound/vo/male/gen/painmoan (5).ogg b/sound/vo/male/gen/painmoan (5).ogg index e3538e5e667..4a5663685a3 100644 Binary files a/sound/vo/male/gen/painmoan (5).ogg and b/sound/vo/male/gen/painmoan (5).ogg differ diff --git a/sound/vo/male/gen/painscream (1).ogg b/sound/vo/male/gen/painscream (1).ogg index d1a190632f8..f7b746cba21 100644 Binary files a/sound/vo/male/gen/painscream (1).ogg and b/sound/vo/male/gen/painscream (1).ogg differ diff --git a/sound/vo/male/gen/painscream (2).ogg b/sound/vo/male/gen/painscream (2).ogg index 8ce7afaecd5..290232d7b51 100644 Binary files a/sound/vo/male/gen/painscream (2).ogg and b/sound/vo/male/gen/painscream (2).ogg differ diff --git a/sound/vo/male/gen/painscream (3).ogg b/sound/vo/male/gen/painscream (3).ogg index 33c0d0fc867..761ff37861b 100644 Binary files a/sound/vo/male/gen/painscream (3).ogg and b/sound/vo/male/gen/painscream (3).ogg differ diff --git a/sound/vo/male/gen/rage (1).ogg b/sound/vo/male/gen/rage (1).ogg index a7b81fd6530..8b61dabfccb 100644 Binary files a/sound/vo/male/gen/rage (1).ogg and b/sound/vo/male/gen/rage (1).ogg differ diff --git a/sound/vo/male/gen/rage (2).ogg b/sound/vo/male/gen/rage (2).ogg index d7797ef5389..1c528b04389 100644 Binary files a/sound/vo/male/gen/rage (2).ogg and b/sound/vo/male/gen/rage (2).ogg differ diff --git a/sound/vo/male/gen/scream (1).ogg b/sound/vo/male/gen/scream (1).ogg index 75a56d47f64..3e0be777513 100644 Binary files a/sound/vo/male/gen/scream (1).ogg and b/sound/vo/male/gen/scream (1).ogg differ diff --git a/sound/vo/male/gen/scream (2).ogg b/sound/vo/male/gen/scream (2).ogg index 979bf7e496f..32c1e5b4aac 100644 Binary files a/sound/vo/male/gen/scream (2).ogg and b/sound/vo/male/gen/scream (2).ogg differ diff --git a/sound/vo/male/gen/scream (3).ogg b/sound/vo/male/gen/scream (3).ogg index 8983b7f3a37..02e30cecb75 100644 Binary files a/sound/vo/male/gen/scream (3).ogg and b/sound/vo/male/gen/scream (3).ogg differ diff --git a/vanderlin.dme b/vanderlin.dme index 4d85238d1a5..460e8e0ac0d 100644 --- a/vanderlin.dme +++ b/vanderlin.dme @@ -139,6 +139,7 @@ #include "code\__DEFINES\pronouns.dm" #include "code\__DEFINES\putrid.dm" #include "code\__DEFINES\qdel.dm" +#include "code\__DEFINES\qualities.dm" #include "code\__DEFINES\quirks.dm" #include "code\__DEFINES\radial_defines.dm" #include "code\__DEFINES\radio.dm" @@ -225,6 +226,7 @@ #include "code\__DEFINES\dcs\signals\signals_objectives.dm" #include "code\__DEFINES\dcs\signals\signals_organ.dm" #include "code\__DEFINES\dcs\signals\signals_rage.dm" +#include "code\__DEFINES\dcs\signals\signals_reagents.dm" #include "code\__DEFINES\dcs\signals\signals_spatial_grid.dm" #include "code\__DEFINES\dcs\signals\signals_spell.dm" #include "code\__DEFINES\dcs\signals\signals_subsystems.dm" @@ -516,6 +518,7 @@ #include "code\controllers\subsystem\processing\magic.dm" #include "code\controllers\subsystem\processing\mousecharge.dm" #include "code\controllers\subsystem\processing\obj.dm" +#include "code\controllers\subsystem\processing\particle_spewers.dm" #include "code\controllers\subsystem\processing\pollutants.dm" #include "code\controllers\subsystem\processing\projectiles.dm" #include "code\controllers\subsystem\processing\slow_objects.dm" @@ -1102,6 +1105,7 @@ #include "code\datums\elements\snail_crawl.dm" #include "code\datums\elements\tipped_item.dm" #include "code\datums\elements\turf_transparency.dm" +#include "code\datums\elements\visual_quality.dm" #include "code\datums\elements\walking_stick.dm" #include "code\datums\elements\appearance\update_icon_blocker.dm" #include "code\datums\elements\appearance\update_icon_updates_onmob.dm" @@ -2538,6 +2542,7 @@ #include "code\modules\crafting\quality_of_crafting\arcyne.dm" #include "code\modules\crafting\quality_of_crafting\bombs.dm" #include "code\modules\crafting\quality_of_crafting\books.dm" +#include "code\modules\crafting\quality_of_crafting\carving.dm" #include "code\modules\crafting\quality_of_crafting\crafted_items.dm" #include "code\modules\crafting\quality_of_crafting\crafting.dm" #include "code\modules\crafting\quality_of_crafting\dendor.dm"