mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 14:39:58 +01:00
Chisel and Statue Improvements (#72638)
## About The Pull Request Resolves #72607 Resolves #65701 Chisels and statues had quite a few bugs and they lacked any kind of feedback system to inform the user on it's proper usage. My improvements do the following: - Chisels now give balloon alerts when selecting a target, cancelling, or sculpting - Chisels used on carving blocks that were interrupted will now continue - Fixed abstract statues not letting people use the radial menu - Fixed chisel targets to have no range requirement (so you can use binoculars, cameras, etc.) - Refactor a lot of the chisel and statue code to be more robust - Add sculpting sounds when chisels are used on carving blocks ## Why It's Good For The Game Less bugs and now people can now sculpt easier. ## Changelog 🆑 soundadd: Chisels now make sculpting sounds when used on carving blocks qol: Chisels now give balloon alerts when selecting a target, cancelling, or sculpting qol: Chisels used on carving blocks that were interrupted will now continue fix: Fix chisel targets to have no range requirement (so you can use binoculars, cameras, etc.) fix: Fix standard mineral blocks (uranium, diamond, plasma, etc.) not letting people use the radial menu to craft abstract statues properly. This does not work with custom mineral blocks. (pizza, glass, etc.) code: Change chisel and statue code to be more readable /🆑 Co-authored-by: Time-Green <timkoster1@hotmail.com>
This commit is contained in:
+3
-4
@@ -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])
|
||||
|
||||
|
||||
+63
-40
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user