Custom statues and sculpting changes. (#53154)

### Gameplay changes:
- Spacemen lose their ability to sculpt all minerals into statues barehanded, you need a chisel now.
- You can now create carving blocks out of 5 sheets of most materials.
- Using a chisel on the blocks you can designate what to carve in it (including the preset statues from before).
- Chisels can be printed at autolathe, there's also one in art storage.
### Code changes:
- Squeak component now squeaks on attack_hand for structures.
- Radials now accept atom paths automatically extracting the name with initial.
- Base and rigid stack recipes renamed appropriately.
- Statues now use custom materials.
This commit is contained in:
AnturK
2020-09-23 07:46:01 +02:00
committed by GitHub
parent dba40e4b9d
commit 61e5c556df
15 changed files with 345 additions and 98 deletions

View File

@@ -546,6 +546,9 @@
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/obj/item/chisel{
pixel_y = 7
},
/turf/open/floor/plasteel/dark,
/area/library)
"abp" = (

View File

@@ -19826,6 +19826,9 @@
/obj/structure/table,
/obj/item/storage/crayons,
/obj/item/storage/crayons,
/obj/item/chisel{
pixel_y = 7
},
/turf/open/floor/plasteel,
/area/storage/art)
"aTH" = (

View File

@@ -29460,6 +29460,9 @@
/obj/item/canvas,
/obj/item/canvas,
/obj/item/canvas,
/obj/item/chisel{
pixel_y = 7
},
/turf/open/floor/plasteel,
/area/storage/art)
"bro" = (

View File

@@ -14948,6 +14948,9 @@
dir = 8
},
/obj/structure/cable,
/obj/item/chisel{
pixel_y = 7
},
/turf/open/floor/plasteel,
/area/storage/art)
"aMY" = (

View File

@@ -88,7 +88,7 @@
"q" = (
/obj/structure/statue/plasma/scientist{
anchored = 1;
oreAmount = 50
custom_materials = list(/datum/material/plasma = 100000)
},
/turf/open/floor/light/colour_cycle,
/area/shuttle/escape)

View File

@@ -195,6 +195,9 @@ GLOBAL_LIST_EMPTY(radial_menus)
else
if(istext(choices_values[choice_id]))
E.name = choices_values[choice_id]
else if(ispath(choices_values[choice_id],/atom))
var/atom/A = choices_values[choice_id]
E.name = initial(A.name)
else
var/atom/movable/AM = choices_values[choice_id] //Movables only
E.name = AM.name

View File

@@ -16,13 +16,17 @@ SUBSYSTEM_DEF(materials)
var/list/materialtypes_by_category
///A cache of all material combinations that have been used
var/list/list/material_combos
///List of stackcrafting recipes for materials using rigid materials
var/list/rigid_stack_recipes = list(
///List of stackcrafting recipes for materials using base recipes
var/list/base_stack_recipes = list(
new /datum/stack_recipe("Chair", /obj/structure/chair/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
new /datum/stack_recipe("Toilet", /obj/structure/toilet/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
new /datum/stack_recipe("Sink Frame", /obj/structure/sinkframe, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
new /datum/stack_recipe("Floor tile", /obj/item/stack/tile/material, 1, 4, 20, applies_mats = TRUE),
)
///List of stackcrafting recipes for materials using rigid recipes
var/list/rigid_stack_recipes = list(
new /datum/stack_recipe("Carving block", /obj/structure/carving_block, 5, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
)
///Ran on initialize, populated the materials and materials_by_category dictionaries with their appropiate vars (See these variables for more info)
/datum/controller/subsystem/materials/proc/InitializeMaterials()

View File

@@ -29,6 +29,8 @@
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
if(istype(parent, /obj/item/clothing/shoes))
RegisterSignal(parent, COMSIG_SHOES_STEP_ACTION, .proc/step_squeak)
else if(isstructure(parent))
RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/use_squeak)
override_squeak_sounds = custom_sounds
if(chance_override)

View File

@@ -26,7 +26,6 @@ Mineral Sheets
GLOBAL_LIST_INIT(sandstone_recipes, list ( \
new/datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("Breakdown into sand", /obj/item/stack/ore/glass, 1, one_per_turf = FALSE, on_floor = TRUE) \
))
@@ -110,9 +109,6 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \
GLOBAL_LIST_INIT(diamond_recipes, list ( \
new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("diamond tile", /obj/item/stack/tile/mineral/diamond, 1, 4, 20), \
new/datum/stack_recipe("Captain Statue", /obj/structure/statue/diamond/captain, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("AI Hologram Statue", /obj/structure/statue/diamond/ai1, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("AI Core Statue", /obj/structure/statue/diamond/ai2, 5, one_per_turf = 1, on_floor = 1), \
))
/obj/item/stack/sheet/mineral/diamond/get_main_recipes()
@@ -139,8 +135,6 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \
GLOBAL_LIST_INIT(uranium_recipes, list ( \
new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("uranium tile", /obj/item/stack/tile/mineral/uranium, 1, 4, 20), \
new/datum/stack_recipe("Nuke Statue", /obj/structure/statue/uranium/nuke, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("Engineer Statue", /obj/structure/statue/uranium/eng, 5, one_per_turf = 1, on_floor = 1), \
))
/obj/item/stack/sheet/mineral/uranium/get_main_recipes()
@@ -172,7 +166,6 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \
GLOBAL_LIST_INIT(plasma_recipes, list ( \
new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("plasma tile", /obj/item/stack/tile/mineral/plasma, 1, 4, 20), \
new/datum/stack_recipe("Scientist Statue", /obj/structure/statue/plasma/scientist, 5, one_per_turf = 1, on_floor = 1), \
))
/obj/item/stack/sheet/mineral/plasma/get_main_recipes()
@@ -212,12 +205,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \
new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("gold tile", /obj/item/stack/tile/mineral/gold, 1, 4, 20), \
new/datum/stack_recipe("blank plaque", /obj/item/plaque, 1), \
new/datum/stack_recipe("HoS Statue", /obj/structure/statue/gold/hos, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("HoP Statue", /obj/structure/statue/gold/hop, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("CE Statue", /obj/structure/statue/gold/ce, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("RD Statue", /obj/structure/statue/gold/rd, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("Simple Crown", /obj/item/clothing/head/crown, 5), \
new/datum/stack_recipe("CMO Statue", /obj/structure/statue/gold/cmo, 5, one_per_turf = 1, on_floor = 1), \
))
/obj/item/stack/sheet/mineral/gold/get_main_recipes()
@@ -244,11 +232,6 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \
GLOBAL_LIST_INIT(silver_recipes, list ( \
new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("silver tile", /obj/item/stack/tile/mineral/silver, 1, 4, 20), \
new/datum/stack_recipe("Med Officer Statue", /obj/structure/statue/silver/md, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("Janitor Statue", /obj/structure/statue/silver/janitor, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("Sec Officer Statue", /obj/structure/statue/silver/sec, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("Sec Borg Statue", /obj/structure/statue/silver/secborg, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("Med Borg Statue", /obj/structure/statue/silver/medborg, 5, one_per_turf = 1, on_floor = 1), \
))
/obj/item/stack/sheet/mineral/silver/get_main_recipes()
@@ -274,7 +257,6 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
GLOBAL_LIST_INIT(bananium_recipes, list ( \
new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \
new/datum/stack_recipe("Clown Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1), \
))
/obj/item/stack/sheet/mineral/bananium/get_main_recipes()

View File

@@ -548,7 +548,6 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
new/datum/stack_recipe("bronze boots", /obj/item/clothing/shoes/bronze), \
null,
new/datum/stack_recipe("bronze chair", /obj/structure/chair/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("Marx Bust", /obj/structure/statue/bronze/marx, 15, one_per_turf = 1, on_floor = 1), \
))
/obj/item/stack/tile/bronze

View File

@@ -76,6 +76,9 @@
for(var/i in M.categories)
switch(i)
if(MAT_CATEGORY_BASE_RECIPES)
var/list/temp = SSmaterials.base_stack_recipes.Copy()
recipes += temp
if(MAT_CATEGORY_RIGID)
var/list/temp = SSmaterials.rigid_stack_recipes.Copy()
recipes += temp
update_weight()

View File

@@ -6,11 +6,13 @@
density = TRUE
anchored = FALSE
max_integrity = 100
var/oreAmount = 5
var/material_drop_type = /obj/item/stack/sheet/metal
var/impressiveness = 15
CanAtmosPass = ATMOS_PASS_DENSITY
/// Beauty component mood modifier
var/impressiveness = 15
/// Art component subtype added to this statue
var/art_type = /datum/component/art
/// Abstract root type
var/abstract_type = /obj/structure/statue
/obj/structure/statue/Initialize()
. = ..()
@@ -37,12 +39,12 @@
/obj/structure/statue/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(material_drop_type)
var/drop_amt = oreAmount
if(!disassembled)
drop_amt -= 2
if(drop_amt > 0)
new material_drop_type(get_turf(src), drop_amt)
var/amount_mod = disassembled ? 0 : -2
for(var/mat in custom_materials)
var/datum/material/custom_material = SSmaterials.GetMaterialRef(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)
qdel(src)
//////////////////////////////////////STATUES/////////////////////////////////////////////////////////////
@@ -51,11 +53,9 @@
/obj/structure/statue/uranium
max_integrity = 300
light_range = 2
material_drop_type = /obj/item/stack/sheet/mineral/uranium
var/last_event = 0
var/active = null
custom_materials = list(/datum/material/uranium=MINERAL_MATERIAL_AMOUNT*5)
impressiveness = 25 // radiation makes an impression
abstract_type = /obj/structure/statue/uranium
/obj/structure/statue/uranium/nuke
name = "statue of a nuclear fission explosive"
@@ -67,39 +67,14 @@
desc = "This statue has a sickening green colour."
icon_state = "eng"
/obj/structure/statue/uranium/attackby(obj/item/W, mob/user, params)
radiate()
return ..()
/obj/structure/statue/uranium/Bumped(atom/movable/AM)
radiate()
..()
/obj/structure/statue/uranium/attack_hand(mob/user)
radiate()
. = ..()
/obj/structure/statue/uranium/attack_paw(mob/user)
radiate()
. = ..()
/obj/structure/statue/uranium/proc/radiate()
if(!active)
if(world.time > last_event+15)
active = 1
radiation_pulse(src, 30)
last_event = world.time
active = null
return
return
////////////////////////////plasma///////////////////////////////////////////////////////////////////////
/obj/structure/statue/plasma
max_integrity = 200
material_drop_type = /obj/item/stack/sheet/mineral/plasma
impressiveness = 20
desc = "This statue is suitably made from plasma."
custom_materials = list(/datum/material/plasma=MINERAL_MATERIAL_AMOUNT*5)
abstract_type = /obj/structure/statue/plasma
/obj/structure/statue/plasma/scientist
name = "statue of a scientist"
@@ -137,7 +112,9 @@
/obj/structure/statue/plasma/proc/PlasmaBurn(exposed_temperature)
if(QDELETED(src))
return
atmos_spawn_air("plasma=[oreAmount*10];TEMP=[exposed_temperature]")
if(custom_materials[/datum/material/plasma])
var/plasma_amount = round(custom_materials[/datum/material/plasma]/MINERAL_MATERIAL_AMOUNT)
atmos_spawn_air("plasma=[plasma_amount*10];TEMP=[exposed_temperature]")
deconstruct(FALSE)
/obj/structure/statue/plasma/proc/ignite(exposed_temperature)
@@ -148,9 +125,10 @@
/obj/structure/statue/gold
max_integrity = 300
material_drop_type = /obj/item/stack/sheet/mineral/gold
impressiveness = 25
desc = "This is a highly valuable statue made from gold."
custom_materials = list(/datum/material/gold=MINERAL_MATERIAL_AMOUNT*5)
abstract_type = /obj/structure/statue/gold
/obj/structure/statue/gold/hos
name = "statue of the head of security"
@@ -176,9 +154,10 @@
/obj/structure/statue/silver
max_integrity = 300
material_drop_type = /obj/item/stack/sheet/mineral/silver
impressiveness = 25
desc = "This is a valuable statue made from silver."
custom_materials = list(/datum/material/silver=MINERAL_MATERIAL_AMOUNT*5)
abstract_type = /obj/structure/statue/silver
/obj/structure/statue/silver/md
name = "statue of a medical officer"
@@ -204,9 +183,10 @@
/obj/structure/statue/diamond
max_integrity = 1000
material_drop_type = /obj/item/stack/sheet/mineral/diamond
impressiveness = 50
desc = "This is a very expensive diamond statue."
custom_materials = list(/datum/material/diamond=MINERAL_MATERIAL_AMOUNT*5)
abstract_type = /obj/structure/statue/diamond
/obj/structure/statue/diamond/captain
name = "statue of THE captain."
@@ -224,43 +204,22 @@
/obj/structure/statue/bananium
max_integrity = 300
material_drop_type = /obj/item/stack/sheet/mineral/bananium
impressiveness = 50
desc = "A bananium statue with a small engraving:'HOOOOOOONK'."
var/limiting_spam = FALSE
custom_materials = list(/datum/material/bananium=MINERAL_MATERIAL_AMOUNT*5)
abstract_type = /obj/structure/statue/bananium
/obj/structure/statue/bananium/clown
name = "statue of a clown"
icon_state = "clown"
/obj/structure/statue/bananium/Bumped(atom/movable/AM)
honk()
..()
/obj/structure/statue/bananium/attackby(obj/item/W, mob/user, params)
honk()
return ..()
/obj/structure/statue/bananium/attack_hand(mob/user)
honk()
. = ..()
/obj/structure/statue/bananium/attack_paw(mob/user)
honk()
..()
/obj/structure/statue/bananium/proc/honk()
if(!limiting_spam)
limiting_spam = TRUE
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, TRUE)
addtimer(VARSET_CALLBACK(src, limiting_spam, FALSE), 2 SECONDS)
/////////////////////sandstone/////////////////////////////////////////
/obj/structure/statue/sandstone
max_integrity = 50
material_drop_type = /obj/item/stack/sheet/mineral/sandstone
impressiveness = 15
custom_materials = list(/datum/material/sandstone=MINERAL_MATERIAL_AMOUNT*5)
abstract_type = /obj/structure/statue/sandstone
/obj/structure/statue/sandstone/assistant
name = "statue of an assistant"
@@ -278,7 +237,8 @@
/obj/structure/statue/snow
max_integrity = 50
material_drop_type = /obj/item/stack/sheet/mineral/snow
custom_materials = list(/datum/material/snow=MINERAL_MATERIAL_AMOUNT*5)
abstract_type = /obj/structure/statue/snow
/obj/structure/statue/snow/snowman
name = "snowman"
@@ -293,7 +253,8 @@
///////////////////////////////bronze///////////////////////////////////
/obj/structure/statue/bronze
material_drop_type = /obj/item/stack/tile/bronze
custom_materials = list(/datum/material/bronze=MINERAL_MATERIAL_AMOUNT*5)
abstract_type = /obj/structure/statue/bronze
/obj/structure/statue/bronze/marx
name = "\improper Karl Marx bust"
@@ -307,6 +268,278 @@
name = "Elder Atmosian"
desc = "A statue of an Elder Atmosian, capable of bending the laws of thermodynamics to their will"
icon_state = "eng"
material_drop_type = /obj/item/stack/sheet/mineral/metal_hydrogen
custom_materials = list(/datum/material/metalhydrogen = MINERAL_MATERIAL_AMOUNT*10)
max_integrity = 1000
impressiveness = 100
abstract_type = /obj/structure/statue/elder_atmosian //This one is uncarvable
/obj/item/chisel
name = "chisel"
desc = "breaking and making art since 4000 BC. This one uses advanced technology to allow creation of lifelike moving statues."
icon = 'icons/obj/statue.dmi'
icon_state = "chisel"
inhand_icon_state = "screwdriver_nuke"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BELT
force = 5
w_class = WEIGHT_CLASS_TINY
throwforce = 5
throw_speed = 3
throw_range = 5
custom_materials = list(/datum/material/iron=75)
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')
drop_sound = 'sound/items/handling/screwdriver_drop.ogg'
pickup_sound = 'sound/items/handling/screwdriver_pickup.ogg'
item_flags = EYE_STAB
sharpness = SHARP_POINTY
/// Block we're currently carving in
var/obj/structure/carving_block/prepared_block
/// If tracked user moves we stop sculpting
var/mob/living/tracked_user
/// Currently sculpting
var/sculpting = FALSE
/obj/item/chisel/Destroy()
prepared_block = null
tracked_user = null
return ..()
/*
Hit the block to start
Point with the chisel at the target to choose what to sculpt or hit block to choose from preset statue types.
Hit block again to start sculpting.
Moving interrupts
*/
/obj/item/chisel/pre_attack(atom/A, 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))
start_sculpting(user)
else if(!prepared_block)
set_block(A,user)
else if(A == 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)
return TRUE
// We aim at something distant.
/obj/item/chisel/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(!proximity_flag && !sculpting && prepared_block && ismovable(target) && prepared_block.completion == 0)
prepared_block.set_target(target,user)
/obj/item/chisel/proc/start_sculpting(mob/living/user)
to_chat(user,"<span class='notice'>You start sculpting [prepared_block].</span>",type=MESSAGE_TYPE_INFO)
sculpting = TRUE
//How long whole process takes
var/sculpting_time = 30 SECONDS
//Single interruptible progress period
var/sculpting_period = round(sculpting_time / world.icon_size) //this is just so it reveals pixels line by line for each.
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 )
while(remaining_time > 0 && !interrupted)
if(do_after(user,sculpting_period, target = prepared_block, progress = FALSE))
remaining_time -= sculpting_period
prepared_block.set_completion((sculpting_time - remaining_time)/sculpting_time)
total_progress_bar.update(sculpting_time - remaining_time)
else
interrupted = TRUE
total_progress_bar.end_progress()
if(!interrupted && !QDELETED(prepared_block))
prepared_block.create_statue()
to_chat(user,"<span class='notice'>The statue is finished!</span>",type=MESSAGE_TYPE_INFO)
break_sculpting()
/obj/item/chisel/proc/set_block(obj/structure/carving_block/B,mob/living/user)
prepared_block = B
tracked_user = user
RegisterSignal(tracked_user,COMSIG_MOVABLE_MOVED,.proc/break_sculpting)
to_chat(user,"<span class='notice'>You prepare to work on [B].</span>",type=MESSAGE_TYPE_INFO)
/obj/item/chisel/dropped(mob/user, silent)
. = ..()
break_sculpting()
/obj/item/chisel/proc/break_sculpting()
SIGNAL_HANDLER
sculpting = FALSE
if(prepared_block && prepared_block.completion == 0)
prepared_block.reset_target()
prepared_block = null
if(tracked_user)
UnregisterSignal(tracked_user,COMSIG_MOVABLE_MOVED)
tracked_user = null
/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)
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 class='notice'>You decide to sculpt [prepared_block] into [initial(S.name)].</span>",type=MESSAGE_TYPE_INFO)
/obj/structure/carving_block
name = "block"
desc = "ready for sculpting."
icon = 'icons/obj/statue.dmi'
icon_state = "block"
material_flags = MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_ADD_PREFIX
density = TRUE
/// The thing it will look like - Unmodified resulting statue appearance
var/current_target
/// Currently chosen preset statue type
var/current_preset_type
//Table of required materials for each non-abstract statue type
var/static/list/statue_costs
/// statue completion from 0 to 1.0
var/completion = 0
/// Greyscaled target with cutout filter
var/mutable_appearance/target_appearance_with_filters
/// Cutout filter for main block sprite
var/partial_uncover_filter
/// HSV color filters parameters
var/static/list/greyscale_with_value_bump = list(0,0,0, 0,0,0, 0,0,1, 0,0,-0.05)
/obj/structure/carving_block/Destroy()
current_target = null
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.")
return
current_target = target.appearance
var/mutable_appearance/ma = current_target
to_chat(user,"<span class='notice'>You decide to sculpt [src] into [ma.name].</span>",type=MESSAGE_TYPE_INFO)
/obj/structure/carving_block/proc/reset_target()
current_target = null
current_preset_type = null
target_appearance_with_filters = null
/obj/structure/carving_block/update_overlays()
. = ..()
if(target_appearance_with_filters)
//We're only keeping one instance here that changes in the middle so we have to clone it to avoid managed overlay issues
var/mutable_appearance/clone = new(target_appearance_with_filters)
. += clone
/obj/structure/carving_block/proc/is_viable_target(atom/movable/target)
//Only things on turfs
if(!isturf(target.loc))
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)
return FALSE
return TRUE
/obj/structure/carving_block/proc/create_statue()
if(current_preset_type)
var/obj/structure/statue/preset_statue = new current_preset_type(get_turf(src))
preset_statue.set_custom_materials(custom_materials)
qdel(src)
else if(current_target)
var/obj/structure/statue/custom/new_statue = new(get_turf(src))
new_statue.set_visuals(current_target)
new_statue.set_custom_materials(custom_materials)
var/mutable_appearance/ma = current_target
new_statue.name = "statue of [ma.name]"
new_statue.desc = "statue depicting [ma.name]"
qdel(src)
/obj/structure/carving_block/proc/set_completion(value)
if(!current_target)
return
if(!target_appearance_with_filters)
target_appearance_with_filters = new(current_target)
target_appearance_with_filters.appearance_flags |= KEEP_TOGETHER
target_appearance_with_filters.filters = filter(type="color",color=greyscale_with_value_bump,space=FILTER_COLOR_HSV)
completion = value
var/static/icon/white = icon('icons/effects/alphacolors.dmi', "white")
switch(value)
if(0)
//delete uncovered and reset filters
filters -= partial_uncover_filter
target_appearance_with_filters = null
else
var/mask_offset = min(world.icon_size,round(completion * world.icon_size))
if(partial_uncover_filter)
filters -= partial_uncover_filter
partial_uncover_filter = filter(type="alpha",icon=white,y=-mask_offset)
filters += partial_uncover_filter
target_appearance_with_filters.filters = filter(type="alpha",icon=white,y=-mask_offset,flags=MASK_INVERSE)
update_icon()
/// Returns a list of preset statues carvable from this block depending on the custom materials
/obj/structure/carving_block/proc/get_possible_statues()
. = list()
if(!statue_costs)
statue_costs = build_statue_cost_table()
for(var/statue_path in statue_costs)
var/list/carving_cost = statue_costs[statue_path]
var/enough_materials = TRUE
for(var/required_material in carving_cost)
if(!custom_materials[required_material] || custom_materials[required_material] < carving_cost[required_material])
enough_materials = FALSE
break
if(enough_materials)
. += statue_path
/obj/structure/carving_block/proc/build_statue_cost_table()
. = list()
for(var/statue_type in subtypesof(/obj/structure/statue) - /obj/structure/statue/custom)
var/obj/structure/statue/S = new statue_type()
if(!S.icon_state || S.abstract_type == S.type || !S.custom_materials)
continue
.[S.type] = S.custom_materials
qdel(S)
/obj/structure/statue/custom
name = "custom statue"
icon_state = "base"
obj_flags = CAN_BE_HIT | UNIQUE_RENAME
appearance_flags = TILE_BOUND | PIXEL_SCALE | KEEP_TOGETHER //Added keep together in case targets has weird layering
material_flags = MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
/// primary statue overlay
var/mutable_appearance/content_ma
var/static/list/greyscale_with_value_bump = list(0,0,0, 0,0,0, 0,0,1, 0,0,-0.05)
/obj/structure/statue/custom/Destroy()
content_ma = null
return ..()
/obj/structure/statue/custom/proc/set_visuals(model_appearance)
content_ma = new
content_ma.appearance = model_appearance
content_ma.pixel_x = 0
content_ma.pixel_y = 0
content_ma.alpha = 255
content_ma.filters = filter(type="color",color=greyscale_with_value_bump,space=FILTER_COLOR_HSV)
update_icon()
/obj/structure/statue/custom/update_overlays()
. = ..()
if(content_ma)
. += content_ma

View File

@@ -1202,3 +1202,11 @@
build_path = /obj/item/swab
category = list("initial","Misc","Equipment")
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
/datum/design/chisel
name = "Chisel"
id = "chisel"
build_type = AUTOLATHE
materials = list(/datum/material/iron = 75)
build_path = /obj/item/chisel
category = list("initial","Tools")

View File

@@ -3,27 +3,28 @@
/obj/structure/statue/bone
anchored = TRUE
max_integrity = 120
material_drop_type = /obj/item/stack/sheet/bone
impressiveness = 18 // Carved from the bones of a massive creature, it's going to be a specticle to say the least
layer = ABOVE_ALL_MOB_LAYER
custom_materials = list(/datum/material/bone=MINERAL_MATERIAL_AMOUNT*5)
abstract_type = /obj/structure/statue/bone
/obj/structure/statue/bone/rib
name = "collosal rib"
desc = "It's staggering to think that something this big could have lived, let alone died."
oreAmount = 4
custom_materials = list(/datum/material/bone=MINERAL_MATERIAL_AMOUNT*4)
icon = 'icons/obj/statuelarge.dmi'
icon_state = "rib"
/obj/structure/statue/bone/skull
name = "collosal skull"
desc = "The gaping maw of a dead, titanic monster."
oreAmount = 12
custom_materials = list(/datum/material/bone=MINERAL_MATERIAL_AMOUNT*12)
icon = 'icons/obj/statuelarge.dmi'
icon_state = "skull"
/obj/structure/statue/bone/skull/half
desc = "The gaping maw of a dead, titanic monster. This one is cracked in half."
oreAmount = 6
custom_materials = list(/datum/material/bone=MINERAL_MATERIAL_AMOUNT*6)
icon = 'icons/obj/statuelarge.dmi'
icon_state = "skull-half"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB