diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 584e24b23ba..9ac44b4460d 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1648,11 +1648,10 @@ * Fetches a list of all of the materials this object has of the desired type. Returns null if there is no valid materials of the type * * Arguments: - * - [mat_type][/datum/material]: The type of material we are checking for - * - exact: Whether to search for the _exact_ material type + * - [required_material][/datum/material]: The type of material we are checking for * - mat_amount: The minimum required amount of material */ -/atom/proc/has_material_type(datum/material/mat_type, exact=FALSE, mat_amount=0) +/atom/proc/has_material_type(datum/material/required_material, mat_amount = 0) var/list/cached_materials = custom_materials if(!length(cached_materials)) return null @@ -1662,7 +1661,7 @@ if(cached_materials[current_material] < mat_amount) continue var/datum/material/material = GET_MATERIAL_REF(current_material) - if(exact ? material.type != current_material : !istype(material, mat_type)) + if(!istype(material, required_material)) continue LAZYSET(materials_of_type, material, cached_materials[current_material]) diff --git a/code/modules/art/statues.dm b/code/modules/art/statues.dm index ad4f3ccc933..c29c9957774 100644 --- a/code/modules/art/statues.dm +++ b/code/modules/art/statues.dm @@ -1,3 +1,7 @@ +/// This controls the delay for the sculpt rock breaking sound +/// Every 4th iterator while sculpting will emit a sound (rougly every couple of seconds) +#define SCULPT_SOUND_INCREMENT 4 + /obj/structure/statue name = "statue" desc = "Placeholder. Yell at Firecage if you SOMEHOW see this." @@ -36,12 +40,8 @@ if(W.tool_behaviour == TOOL_WELDER) if(!W.tool_start_check(user, amount=0)) return FALSE - - user.visible_message(span_notice("[user] is slicing apart the [name]."), \ - span_notice("You are slicing apart the [name]...")) + user.balloon_alert(user, "slicing apart...") if(W.use_tool(src, user, 40, volume=50)) - user.visible_message(span_notice("[user] slices apart the [name]."), \ - span_notice("You slice apart the [name]!")) deconstruct(TRUE) return return ..() @@ -56,7 +56,7 @@ var/datum/material/custom_material = GET_MATERIAL_REF(mat) var/amount = max(0,round(custom_materials[mat]/MINERAL_MATERIAL_AMOUNT) + amount_mod) if(amount > 0) - new custom_material.sheet_type(drop_location(),amount) + new custom_material.sheet_type(drop_location(), amount) qdel(src) //////////////////////////////////////STATUES///////////////////////////////////////////////////////////// @@ -279,7 +279,7 @@ attack_verb_continuous = list("stabs") attack_verb_simple = list("stab") hitsound = 'sound/weapons/bladeslice.ogg' - usesound = list('sound/items/screwdriver.ogg', 'sound/items/screwdriver2.ogg') + usesound = list('sound/effects/picaxe1.ogg', 'sound/effects/picaxe2.ogg', 'sound/effects/picaxe3.ogg') drop_sound = 'sound/items/handling/screwdriver_drop.ogg' pickup_sound = 'sound/items/handling/screwdriver_pickup.ogg' sharpness = SHARP_POINTY @@ -311,35 +311,40 @@ Point with the chisel at the target to choose what to sculpt or hit block to cho Hit block again to start sculpting. Moving interrupts */ -/obj/item/chisel/pre_attack(atom/A, mob/living/user, params) +/obj/item/chisel/pre_attack(atom/target, mob/living/user, params) . = ..() if(sculpting) - return - if(istype(A,/obj/structure/carving_block)) - if(A == prepared_block && (prepared_block.current_target || prepared_block.current_preset_type)) + return TRUE + if(istype(target, /obj/structure/carving_block)) + var/obj/structure/carving_block/sculpt_block = target + + if(sculpt_block.completion) // someone already started sculpting this so just finish + set_block(sculpt_block, user, silent = TRUE) + start_sculpting(user) + else if(sculpt_block == prepared_block && (prepared_block.current_target || prepared_block.current_preset_type)) start_sculpting(user) else if(!prepared_block) - set_block(A,user) - else if(A == prepared_block) + set_block(sculpt_block, user) + else if(sculpt_block == prepared_block) show_generic_statues_prompt(user) return TRUE else if(prepared_block) //We're aiming at something next to us with block prepared - prepared_block.set_target(A,user) + prepared_block.set_target(target, user) return TRUE // We aim at something distant. /obj/item/chisel/afterattack(atom/target, mob/user, proximity_flag, click_parameters) . = ..() - if(proximity_flag) - return . if (!sculpting && prepared_block && ismovable(target) && prepared_block.completion == 0) prepared_block.set_target(target,user) return . | AFTERATTACK_PROCESSED_ITEM +/// Starts or continues the sculpting action on the carving block material /obj/item/chisel/proc/start_sculpting(mob/living/user) - to_chat(user,span_notice("You start sculpting [prepared_block]."),type=MESSAGE_TYPE_INFO) + user.balloon_alert(user, "sculpting block...") + playsound(src, pick(usesound), 75, TRUE) sculpting = TRUE //How long whole process takes var/sculpting_time = 30 SECONDS @@ -348,9 +353,12 @@ Moving interrupts var/interrupted = FALSE var/remaining_time = sculpting_time - (prepared_block.completion * sculpting_time) - var/datum/progressbar/total_progress_bar = new(user, sculpting_time, prepared_block ) + var/datum/progressbar/total_progress_bar = new(user, sculpting_time, prepared_block) while(remaining_time > 0 && !interrupted) - if(do_after(user,sculpting_period, target = prepared_block, progress = FALSE)) + if(do_after(user, sculpting_period, target = prepared_block, progress = FALSE)) + var/time_delay = !(remaining_time % SCULPT_SOUND_INCREMENT) + if(time_delay) + playsound(src, 'sound/effects/break_stone.ogg', 50, TRUE) remaining_time -= sculpting_period prepared_block.set_completion((sculpting_time - remaining_time)/sculpting_time) total_progress_bar.update(sculpting_time - remaining_time) @@ -359,42 +367,54 @@ Moving interrupts total_progress_bar.end_progress() if(!interrupted && !QDELETED(prepared_block)) prepared_block.create_statue() - to_chat(user,span_notice("The statue is finished!"),type=MESSAGE_TYPE_INFO) - break_sculpting() + user.balloon_alert(user, "statue finished") + stop_sculpting(silent = !interrupted) -/obj/item/chisel/proc/set_block(obj/structure/carving_block/B,mob/living/user) +/// To setup the sculpting target for the carving block +/obj/item/chisel/proc/set_block(obj/structure/carving_block/B, mob/living/user, silent = FALSE) prepared_block = B tracked_user = user - RegisterSignal(tracked_user,COMSIG_MOVABLE_MOVED, PROC_REF(break_sculpting)) - to_chat(user,span_notice("You prepare to work on [B]."),type=MESSAGE_TYPE_INFO) + RegisterSignal(tracked_user, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) + if(!silent) + user.balloon_alert(user, "select sculpt target") /obj/item/chisel/dropped(mob/user, silent) . = ..() - break_sculpting() + stop_sculpting() -/obj/item/chisel/proc/break_sculpting() - SIGNAL_HANDLER +/// Cancel the sculpting action +/obj/item/chisel/proc/stop_sculpting(silent = FALSE) sculpting = FALSE if(prepared_block && prepared_block.completion == 0) prepared_block.reset_target() prepared_block = null + + if(!silent && tracked_user) + tracked_user.balloon_alert(tracked_user, "sculpting cancelled!") + if(tracked_user) - UnregisterSignal(tracked_user,COMSIG_MOVABLE_MOVED) + UnregisterSignal(tracked_user, COMSIG_MOVABLE_MOVED) tracked_user = null +/obj/item/chisel/proc/on_moved() + SIGNAL_HANDLER + + stop_sculpting() + /obj/item/chisel/proc/show_generic_statues_prompt(mob/living/user) var/list/choices = list() for(var/statue_path in prepared_block.get_possible_statues()) - var/obj/structure/statue/S = statue_path - choices[statue_path] = image(icon=initial(S.icon),icon_state=initial(S.icon_state)) - var/choice = show_radial_menu(user, prepared_block , choices, require_near = TRUE) + var/obj/structure/statue/abstract_statue = statue_path + choices[statue_path] = image(icon = initial(abstract_statue.icon), icon_state = initial(abstract_statue.icon_state)) + if(!choices.len) + user.balloon_alert(user, "no abstract statues for material!") + + var/choice = show_radial_menu(user, prepared_block, choices, require_near = TRUE) if(choice) prepared_block.current_preset_type = choice var/image/chosen_looks = choices[choice] prepared_block.current_target = chosen_looks.appearance - var/obj/structure/statue/S = choice - to_chat(user,span_notice("You decide to sculpt [prepared_block] into [initial(S.name)]."),type=MESSAGE_TYPE_INFO) - + user.balloon_alert(user, "abstract statue selected") /obj/structure/carving_block name = "block" @@ -423,9 +443,8 @@ Moving interrupts target_appearance_with_filters = null return ..() -/obj/structure/carving_block/proc/set_target(atom/movable/target,mob/living/user) - if(!is_viable_target(target)) - to_chat(user,"You won't be able to carve that.") +/obj/structure/carving_block/proc/set_target(atom/movable/target, mob/living/user) + if(!is_viable_target(user, target)) return if(istype(target,/obj/structure/statue/custom)) var/obj/structure/statue/custom/original = target @@ -433,7 +452,7 @@ Moving interrupts else current_target = target.appearance var/mutable_appearance/ma = current_target - to_chat(user,span_notice("You decide to sculpt [src] into [ma.name]."),type=MESSAGE_TYPE_INFO) + user.balloon_alert(user, "sculpt target is [ma.name]") /obj/structure/carving_block/proc/reset_target() current_target = null @@ -448,13 +467,15 @@ Moving interrupts var/mutable_appearance/clone = new(target_appearance_with_filters) . += clone -/obj/structure/carving_block/proc/is_viable_target(atom/movable/target) +/obj/structure/carving_block/proc/is_viable_target(mob/living/user, atom/movable/target) //Only things on turfs if(!isturf(target.loc)) + user.balloon_alert(user, "no sculpt target!") return FALSE //No big icon things var/icon/thing_icon = icon(target.icon, target.icon_state) if(thing_icon.Height() != world.icon_size || thing_icon.Width() != world.icon_size) + user.balloon_alert(user, "sculpt target is too big!") return FALSE return TRUE @@ -505,7 +526,7 @@ Moving interrupts var/list/carving_cost = statue_costs[statue_path] var/enough_materials = TRUE for(var/required_material in carving_cost) - if(!has_material_type(required_material, TRUE, carving_cost[required_material])) + if(!has_material_type(required_material, carving_cost[required_material])) enough_materials = FALSE break if(enough_materials) @@ -588,3 +609,5 @@ Moving interrupts . = ..() if(content_ma) . += content_ma + +#undef SCULPT_SOUND_INCREMENT