From 5aab6c61e361ad2d72d21f64a789920a8d3aa867 Mon Sep 17 00:00:00 2001 From: silicons Date: Sun, 10 Sep 2023 12:43:57 -0700 Subject: [PATCH] more --- code/controllers/subsystem/materials.dm | 2 + .../recipe/material_recipes/furniture.dm | 2 - .../recipe/material_recipes/structures.dm | 9 + code/modules/sculpting/sculpting_block.dm | 175 +++++++++++++++++- code/modules/sculpting/sculpting_helpers.dm | 43 ----- icons/modules/sculpting/sculpting.dmi | Bin 0 -> 302 bytes 6 files changed, 184 insertions(+), 47 deletions(-) delete mode 100644 code/modules/sculpting/sculpting_helpers.dm create mode 100644 icons/modules/sculpting/sculpting.dmi diff --git a/code/controllers/subsystem/materials.dm b/code/controllers/subsystem/materials.dm index ce0622ac76c..6d7bba8dae9 100644 --- a/code/controllers/subsystem/materials.dm +++ b/code/controllers/subsystem/materials.dm @@ -66,6 +66,8 @@ SUBSYSTEM_DEF(materials) else if(ispath(id_or_path)) // yay it's a path return material_lookup[initial(id_or_path.id)] + else if(istype(id_or_path)) + return id_or_path else // what // yes you get a runtime if you pass null in, the subsystem shouldn't have to sanitycheck for you. diff --git a/code/datums/recipe/material_recipes/furniture.dm b/code/datums/recipe/material_recipes/furniture.dm index 56cbc01b1b2..5440955981c 100644 --- a/code/datums/recipe/material_recipes/furniture.dm +++ b/code/datums/recipe/material_recipes/furniture.dm @@ -5,8 +5,6 @@ abstract_type = /datum/stack_recipe/material/furniture category = "Material - Furniture" -#warn sculpting block - /datum/stack_recipe/material/furniture/bed name = "bed" result_type = /obj/structure/bed diff --git a/code/datums/recipe/material_recipes/structures.dm b/code/datums/recipe/material_recipes/structures.dm index 6b200204f94..4dfda97ac7d 100644 --- a/code/datums/recipe/material_recipes/structures.dm +++ b/code/datums/recipe/material_recipes/structures.dm @@ -40,3 +40,12 @@ /datum/stack_recipe/material/structure/low_wall/make(atom/where, amount, obj/item/stack/material/stack, mob/user, silent, use_dir) for(var/i in 1 to amount) new /obj/structure/wall_frame(where, stack.material) + +/datum/stack_recipe/material/structure/sculpting_block + name = "sculpting block" + result_type = /obj/structure/sculpting_block + cost = 15 + +/datum/stack_recipe/material/structure/low_wall/make(atom/where, amount, obj/item/stack/material/stack, mob/user, silent, use_dir) + for(var/i in 1 to amount) + new /obj/structure/sculpting_block(where, stack.material) diff --git a/code/modules/sculpting/sculpting_block.dm b/code/modules/sculpting/sculpting_block.dm index 25ea6dc5d64..8cc7654d2bf 100644 --- a/code/modules/sculpting/sculpting_block.dm +++ b/code/modules/sculpting/sculpting_block.dm @@ -1,11 +1,182 @@ //* This file is explicitly licensed under the MIT license. *// //* Copyright (c) 2023 Citadel Station developers. *// +/** + * Dynamic sculpting! + * + * Later to replace statues entirely. + * + * Sprites generously 'borrowed' from /tg/station. + * Idea is from /tg/station, but entirely reimplemented here. + * + * stay awesome tg (: + * + * todo: add in a way to preload a template so it starts out sculpted, and an initialize() override for such + * todo: de/serialization + * todo: sculpting with shit tools should result in a bad image + */ /obj/structure/sculpting_block + name = "material block" + desc = "A block of material. You can sculpt this with appropriate tools, like a screwdriver." + icon = 'icons/modules/sculpting/sculpting.dmi' + icon_state = "block" -#warn impl + /// finished base state + var/sculpture_base_state = "base" + /// material ref + var/datum/material/material + icon_x_dimension = 32 + icon_y_dimension = 32 + bound_width = 32 + bound_height = 32 + /// is this sculpture finished? + var/finished = FALSE -/obj/structure/sculpting_block/proc/initiate_sculpting(mob/user, atom/movable/forced_target) + /// currently being sculpted + var/sculpting = FALSE + /// current icon being sculpted + var/icon/sculpting_buffer + /// y start; this is set to sculpting_line at the start of an operation + var/sculpting_line_start + /// y end; this is set after end of sculpting right before we blend it into our icon + var/sculpting_line_end + + /// current icon for sculpting; every operation flushes to this, this begins at a x by y blank. + /// we don't flush directly to our icon only because icon might get fucked with + var/icon/sculpting_slate + /// sculpting block is assumed to be a certain size + /// store the current line being sculpted + /// this starts at the topmost y + /// if we're done sculpting, this should be nulled for consistency + var/sculpting_line + +/obj/structure/sculpting_block/Initialize(mapload, material) + material = SSmaterials.get_material(material) + // todo: if it autoinit'd, don't do this + reset_sculpting() + return ..() + +/obj/structure/sculpting_block/proc/reset_sculpting() + sculpting_line = icon_y_dimension + finished = FALSE + +/obj/structure/sculpting_block/update_icon(updates) + cut_overlays() + if(length(underlays)) + underlays.len = 0 + . = ..() + if(!finished) + underlays += sculpture_base_state + else + add_overlay(sculpture_base_state) + + #warn impl above + +/** + * returns speed multiplier, or null if not tool + */ +/obj/structure/sculpting_block/proc/is_sculpting_tool(obj/item/tool, mob/user) + #warn impl + +/obj/structure/sculpting_block/proc/initiate_sculpting(mob/user, silent, atom/movable/forced_target, obj/item/tool) + if(sculpting) + if(!silent) + user.action_feedback(SPAN_WARNING("Someone's already working on [src].")) + return FALSE + var/atom/movable/target = isnull(forced_target)? ask_for_target(user) : forced_target + if(isnull(tool)) + tool = user.get_active_held_item() + var/tool_multiplier = is_sculpting_tool(tool) + if(isnull(tool_multiplier)) + if(!silent) + user.action_feedback(SPAN_WARNING("You must be holding a valid sculpting tool.")) + return FALSE + + setup_op(target) + + var/lines = 0 + + #warn impl + + finish_op(lines) + + check_completion() + +/obj/structure/sculpting_block/proc/check_completion() + if(sculpting_line > icon_y_dimension) + finished = TRUE + flush_finished() + +/obj/structure/sculpting_block/proc/flush_finished() + #warn impl + update_appearance() + +/** + * grabs an icon from something for sculpting, processing it into a greyscale toned to the material's color + * + * @params + * * to_clone - the atom the person is trying to replicate with the sculpt. no turfs. + * * material_color - the color to tone to as rgb color string + * + * @return list(icon, x, y) where x/y are centering offsets + */ +/obj/structure/sculpting_block/proc/get_model_tuple(atom/movable/to_clone, material_color) + . = get_flat_icon(to_clone) + if(isnull(.)) + return + var/icon/flattened = .[1] + flattened.ColorTone(material_color) + +/** + * get things in range of user that can be sculpted + */ +/obj/structure/sculpting_block/proc/get_possible_targets(mob/user, range_to_scan = 7) + . = list() + var/list/atom/potential = view(range_to_scan, user) + for(var/atom/movable/AM in potential) + if(AM.atom_flags & ATOM_ABSTRACT) + continue + if(AM.invisibility > user.see_invisible) + continue + if(!user.can_see_plane(AM.plane)) + continue + if(isobj(AM)) + var/obj/O = AM + if(!(O.obj_flags & OBJ_NO_SCULPTING)) + continue + else + var/mob/M = AM + //! legacy code + if(M.is_incorporeal()) + continue + //! end + . += AM + +/** + * ask someone for target + */ +/obj/structure/sculpting_block/proc/ask_for_target(mob/user) + #warn impl + +/obj/structure/sculpting_block/proc/setup_op(atom/movable/target) + sculpting_line_start = sculpting_line + #warn buffer + +/obj/structure/sculpting_block/proc/finish_op(lines) + sculpting_line_end = sculpting_line_start + lines + + sculpting_line += lines + + if(lines) + if(isnull(sculpting_slate)) + create_slate() + #warn crop out irrelevant parts and blend in + + sculpting_line_start = null + scultping_buffer = null + sculpting_line_end = null + +/obj/structure/sculpting_block/proc/create_slate() #warn impl diff --git a/code/modules/sculpting/sculpting_helpers.dm b/code/modules/sculpting/sculpting_helpers.dm deleted file mode 100644 index dfdab1652f6..00000000000 --- a/code/modules/sculpting/sculpting_helpers.dm +++ /dev/null @@ -1,43 +0,0 @@ -//* This file is explicitly licensed under the MIT license. *// -//* Copyright (c) 2023 Citadel Station developers. *// - -/** - * grabs an icon from something for sculpting, processing it into a greyscale toned to the material's color - * - * @params - * * to_clone - the atom the person is trying to replicate with the sculpt. no turfs. - * * material_color - the color to tone to as rgb color string - * - * @return list(icon, x, y) where x/y are centering offsets - */ -/obj/structure/sculpting_block/proc/get_model_tuple(atom/movable/to_clone, material_color) - . = get_flat_icon(to_clone) - if(isnull(.)) - return - var/icon/flattened = .[1] - flattened.ColorTone(material_color) - -/** - * get things in range of user that can be sculpted - */ -/obj/structure/sculpting_block/proc/get_possible_targets(mob/user, range_to_scan = 7) - . = list() - var/list/atom/potential = view(range_to_scan, user) - for(var/atom/movable/AM in potential) - if(AM.atom_flags & ATOM_ABSTRACT) - continue - if(AM.invisibility > user.see_invisible) - continue - if(!user.can_see_plane(AM.plane)) - continue - if(isobj(AM)) - var/obj/O = AM - if(!(O.obj_flags & OBJ_NO_SCULPTING)) - continue - else - var/mob/M = AM - //! legacy code - if(M.is_incorporeal()) - continue - //! end - . += AM diff --git a/icons/modules/sculpting/sculpting.dmi b/icons/modules/sculpting/sculpting.dmi new file mode 100644 index 0000000000000000000000000000000000000000..08515e903993a86c78f345e3b03978be1f91cf48 GIT binary patch literal 302 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH!VDw>HYaZfQlbGqA+84w9N2kq$Ma`*f4_Uy zT@o|BrEpShy4BTRFMtXdOM?7@862M7NCR>TszM@4TvCgZi!uvJGV}8o7%JujhZPi+ ze*Y3&@bT*tEpJ_|b7#&6ZwNKGX#C)j&UqirlMF>Yy*n(7gN!d5dnwF$H0j8s5QSh( z&5ahJo!!Q&n^#DjFn#jKN89U+Z|erZuA)zqHy5r93M=?p%y^rZ;ob=q|K?3hn}K$F zd%8G=So9_*C@^yzYGB}Fb@B>m@Md%rZs}c^5OQ!uli->Itb7F;1-`6J1_~Sp7dEJ> wnjSrRRQJqT#_6If_13LSRMblh&<^;d#_&YUj_=uS50J48p00i_>zopr0AD$E0ssI2 literal 0 HcmV?d00001