Upload files

This commit is contained in:
SandPoot
2022-03-18 18:35:29 -03:00
parent a9bd8c3e94
commit 16fddbb140
12 changed files with 516 additions and 155 deletions

View File

@@ -194,6 +194,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

@@ -25,7 +25,7 @@ SUBSYSTEM_DEF(materials)
)
///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),
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)

View File

@@ -42,6 +42,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

@@ -54,11 +54,14 @@
/datum/element/art/rev
/datum/element/art/rev/apply_moodlet(atom/source, mob/M, impress)
M.visible_message("<span class='notice'>[M] stops to inspect [source].</span>", \
"<span class='notice'>You take in [source], inspecting the fine craftsmanship of the proletariat.</span>")
if(M.mind && M.mind.has_antag_datum(/datum/antagonist/rev))
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat)
/datum/element/art/rev/apply_moodlet(atom/source, mob/user, impress)
var/msg
if(user.mind?.has_antag_datum(/datum/antagonist/rev))
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat)
msg = "What \a [pick("masterpiece", "chef-d'oeuvre")] [source.p_theyre()]. So [pick("subversive", "revolutionary", "unitizing", "egalitarian")]!"
else
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad)
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad)
msg = "Wow, [source.p_they()] sucks."
user.visible_message(span_notice("[user] stops to inspect [source]."), \
span_notice("You appraise [source], inspecting the fine craftsmanship of the proletariat... [msg]"))

View File

@@ -1,67 +1,139 @@
#define PROGRESSBAR_HEIGHT 6
#define PROGRESSBAR_ANIMATION_TIME 5
/datum/progressbar
var/goal = 1
///The progress bar visual element.
var/image/bar
var/shown = 0
///The target where this progress bar is applied and where it is shown.
var/atom/bar_loc
///The mob whose client sees the progress bar.
var/mob/user
var/client/client
var/listindex
///The client seeing the progress bar.
var/client/user_client
///Effectively the number of steps the progress bar will need to do before reaching completion.
var/goal = 1
///Control check to see if the progress was interrupted before reaching its goal.
var/last_progress = 0
///Variable to ensure smooth visual stacking on multiple progress bars.
var/listindex = 0
/datum/progressbar/New(mob/User, goal_number, atom/target)
. = ..()
if (!istype(target))
CRASH("Invalid target given")
if (goal_number)
goal = goal_number
bar = image('icons/effects/progessbar.dmi', target, "prog_bar_0", HUD_LAYER)
bar.plane = HUD_PLANE
EXCEPTION("Invalid target given")
if(QDELETED(User) || !istype(User))
stack_trace("/datum/progressbar created with [isnull(User) ? "null" : "invalid"] user")
qdel(src)
return
if(!isnum(goal_number))
stack_trace("/datum/progressbar created with [isnull(User) ? "null" : "invalid"] goal_number")
qdel(src)
return
goal = goal_number
bar_loc = target
bar = image('icons/effects/progessbar.dmi', bar_loc, "prog_bar_0")
bar.plane = ABOVE_HUD_PLANE
bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
user = User
if(user)
client = user.client
LAZYINITLIST(user.progressbars)
LAZYINITLIST(user.progressbars[bar.loc])
var/list/bars = user.progressbars[bar.loc]
bars.Add(src)
LAZYADDASSOCLIST(user.progressbars, bar_loc, src)
var/list/bars = user.progressbars[bar_loc]
listindex = bars.len
bar.pixel_y = 32 + (PROGRESSBAR_HEIGHT * (listindex - 1))
/datum/progressbar/proc/update(progress)
if (!user || !user.client)
shown = 0
return
if (user.client != client)
if (client)
client.images -= bar
if (user.client)
user.client.images += bar
if(user.client)
user_client = user.client
add_prog_bar_image_to_client()
progress = clamp(progress, 0, goal)
bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]"
if (!shown)
user.client.images += bar
shown = 1
/datum/progressbar/proc/shiftDown()
--listindex
bar.pixel_y -= PROGRESSBAR_HEIGHT
RegisterSignal(user, COMSIG_PARENT_QDELETING, .proc/on_user_delete)
RegisterSignal(user, COMSIG_MOB_CLIENT_LOGOUT, .proc/clean_user_client)
RegisterSignal(user, COMSIG_MOB_CLIENT_LOGIN, .proc/on_user_login)
/datum/progressbar/Destroy()
for(var/I in user.progressbars[bar.loc])
var/datum/progressbar/P = I
if(P != src && P.listindex > listindex)
P.shiftDown()
if(user)
for(var/pb in user.progressbars[bar_loc])
var/datum/progressbar/progress_bar = pb
if(progress_bar == src || progress_bar.listindex <= listindex)
continue
progress_bar.listindex--
var/list/bars = user.progressbars[bar.loc]
bars.Remove(src)
if(!bars.len)
LAZYREMOVE(user.progressbars, bar.loc)
progress_bar.bar.pixel_y = 32 + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1))
var/dist_to_travel = 32 + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1)) - PROGRESSBAR_HEIGHT
animate(progress_bar.bar, pixel_y = dist_to_travel, time = PROGRESSBAR_ANIMATION_TIME, easing = SINE_EASING)
if (client)
client.images -= bar
qdel(bar)
. = ..()
LAZYREMOVEASSOC(user.progressbars, bar_loc, src)
user = null
if(user_client)
clean_user_client()
bar_loc = null
if(bar)
QDEL_NULL(bar)
return ..()
///Called right before the user's Destroy()
/datum/progressbar/proc/on_user_delete(datum/source)
SIGNAL_HANDLER
user.progressbars = null //We can simply nuke the list and stop worrying about updating other prog bars if the user itself is gone.
user = null
qdel(src)
///Removes the progress bar image from the user_client and nulls the variable, if it exists.
/datum/progressbar/proc/clean_user_client(datum/source)
SIGNAL_HANDLER
if(!user_client) //Disconnected, already gone.
return
user_client.images -= bar
user_client = null
///Called by user's Login(), it transfers the progress bar image to the new client.
/datum/progressbar/proc/on_user_login(datum/source)
SIGNAL_HANDLER
if(user_client)
if(user_client == user.client) //If this was not client handling I'd condemn this sanity check. But clients are fickle things.
return
clean_user_client()
if(!user.client) //Clients can vanish at any time, the bastards.
return
user_client = user.client
add_prog_bar_image_to_client()
///Adds a smoothly-appearing progress bar image to the player's screen.
/datum/progressbar/proc/add_prog_bar_image_to_client()
bar.pixel_y = 0
bar.alpha = 0
user_client.images += bar
animate(bar, pixel_y = 32 + (PROGRESSBAR_HEIGHT * (listindex - 1)), alpha = 255, time = PROGRESSBAR_ANIMATION_TIME, easing = SINE_EASING)
///Updates the progress bar image visually.
/datum/progressbar/proc/update(progress)
progress = clamp(progress, 0, goal)
if(progress == last_progress)
return
last_progress = progress
bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]"
///Called on progress end, be it successful or a failure. Wraps up things to delete the datum and bar.
/datum/progressbar/proc/end_progress()
if(last_progress != goal)
bar.icon_state = "[bar.icon_state]_fail"
animate(bar, alpha = 0, time = PROGRESSBAR_ANIMATION_TIME)
QDEL_IN(src, PROGRESSBAR_ANIMATION_TIME)
#undef PROGRESSBAR_ANIMATION_TIME
#undef PROGRESSBAR_HEIGHT

View File

@@ -27,7 +27,6 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \
new/datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("aesthetic volcanic floor tile", /obj/item/stack/tile/basalt, 2, 2, 4, 20), \
new/datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("Breakdown into sand", /obj/item/stack/ore/glass, 1, one_per_turf = 0, on_floor = 1) \
))
@@ -114,9 +113,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), \
new/datum/stack_recipe("diamond ingot", /obj/item/ingot/diamond, 6, time = 100), \
))
@@ -144,8 +140,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), \
new/datum/stack_recipe("uranium ingot", /obj/item/ingot/uranium, 6, time = 100), \
))
@@ -178,7 +172,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), \
// new/datum/stack_recipe("plasma ingot", /obj/item/ingot/plasma, 6, time = 100), \ no
))
@@ -218,12 +211,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \
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("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), \
new/datum/stack_recipe("gold ingot", /obj/item/ingot/gold, 6, time = 100), \
))
@@ -251,11 +239,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), \
new/datum/stack_recipe("silver ingot", /obj/item/ingot/silver, 6, time = 100), \
))
@@ -282,7 +265,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), \
new/datum/stack_recipe("hilarious ingot", /obj/item/ingot/bananium, 6, time = 100), \
))

View File

@@ -6,43 +6,59 @@
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/element/art
/// Abstract root type
var/abstract_type = /obj/structure/statue
/obj/structure/statue/Initialize()
. = ..()
AddElement(/datum/element/art, impressiveness)
addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, impressiveness * 75)), 0)
AddElement(art_type, impressiveness)
AddElement(/datum/element/beauty, impressiveness * 75)
/obj/structure/statue/ComponentInitialize()
. = ..()
var/rotation_flags = ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS
AddComponent(/datum/component/simple_rotation, rotation_flags, null, CALLBACK(src, .proc/can_be_rotated))
/obj/structure/statue/proc/can_be_rotated()
if(anchored)
to_chat(user, "<span class='warning'>[src] cannot be rotated while it is fastened to the floor!</span>")
return FALSE
return TRUE
/obj/structure/statue/attackby(obj/item/W, mob/living/user, params)
add_fingerprint(user)
if(!(flags_1 & NODECONSTRUCT_1))
if(default_unfasten_wrench(user, W))
return
if(W.tool_behaviour == TOOL_WELDER || istype(W, /obj/item/gun/energy/plasmacutter))
if(W.tool_behaviour == TOOL_WELDER)
if(!W.tool_start_check(user, amount=0))
return FALSE
user.visible_message("[user] is slicing apart the [name].", \
"<span class='notice'>You are slicing apart the [name]...</span>")
user.visible_message(span_notice("[user] is slicing apart the [name]."), \
span_notice("You are slicing apart the [name]..."))
if(W.use_tool(src, user, 40, volume=50))
user.visible_message("[user] slices apart the [name].", \
"<span class='notice'>You slice apart the [name]!</span>")
user.visible_message(span_notice("[user] slices apart the [name]."), \
span_notice("You slice apart the [name]!"))
deconstruct(TRUE)
return
return ..()
/obj/structure/statue/AltClick(mob/user)
return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation
/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,10 +67,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"
@@ -66,39 +81,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/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
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
desc = "This statue is suitably made from plasma."
impressiveness = 20
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"
@@ -108,7 +98,6 @@
if(exposed_temperature > 300)
PlasmaBurn(exposed_temperature)
/obj/structure/statue/plasma/bullet_act(obj/item/projectile/Proj)
var/burn = FALSE
if(!(Proj.nodamage) && Proj.damage_type == BURN && !QDELETED(src))
@@ -136,7 +125,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)
@@ -147,9 +138,10 @@
/obj/structure/statue/gold
max_integrity = 300
material_drop_type = /obj/item/stack/sheet/mineral/gold
desc = "This is a highly valuable statue made from gold."
impressiveness = 30
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"
@@ -175,9 +167,10 @@
/obj/structure/statue/silver
max_integrity = 300
material_drop_type = /obj/item/stack/sheet/mineral/silver
desc = "This is a valuable statue made from silver."
impressiveness = 25
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"
@@ -203,9 +196,10 @@
/obj/structure/statue/diamond
max_integrity = 1000
material_drop_type = /obj/item/stack/sheet/mineral/diamond
desc = "This is a very expensive diamond statue."
impressiveness = 60
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."
@@ -223,43 +217,22 @@
/obj/structure/statue/bananium
max_integrity = 300
material_drop_type = /obj/item/stack/sheet/mineral/bananium
desc = "A bananium statue with a small engraving:'HOOOOOOONK'."
var/spam_flag = 0
impressiveness = 65
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/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
honk()
. = ..()
/obj/structure/statue/bananium/attack_paw(mob/user)
honk()
..()
/obj/structure/statue/bananium/proc/honk()
if(!spam_flag)
spam_flag = 1
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1)
spawn(20)
spam_flag = 0
/////////////////////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"
@@ -277,9 +250,326 @@
/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"
desc = "Several lumps of snow put together to form a snowman."
icon_state = "snowman"
/obj/structure/statue/snow/snowlegion
name = "snowlegion"
desc = "Looks like that weird kid with the tiger plushie has been round here again."
icon_state = "snowlegion"
///////////////////////////////bronze///////////////////////////////////
/obj/structure/statue/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"
desc = "A bust depicting a certain 19th century economist. You get the feeling a specter is haunting the station."
icon_state = "marx"
art_type = /datum/element/art/rev
///////////Elder Atmosian///////////////////////////////////////////
/* Yeah no.
/obj/structure/statue/elder_atmosian
name = "Elder Atmosian"
desc = "A statue of an Elder Atmosian, capable of bending the laws of thermodynamics to their will"
icon_state = "eng"
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"
item_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 = list("stabs")
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 // don't have it
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/Initialize(mapload)
. = ..()
//AddElement(/datum/element/eyestab)
//AddElement(/datum/element/wall_engraver)
//deals 200 damage to statues, meaning you can actually kill one in ~250 hits
/obj/item/chisel/ComponentInitialize()
. = ..()
AddComponent(/datum/component/bane, /mob/living/simple_animal/hostile/statue, damage_multiplier = 40)
/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_notice("You start sculpting [prepared_block]."),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_notice("The statue is finished!"),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_notice("You prepare to work on [B]."),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_notice("You decide to sculpt [prepared_block] into [initial(S.name)]."),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 // MATERIAL_EFFECTS
density = TRUE
material_modifier = 0.5 //50% effectiveness of materials
/// 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
/// 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
if(istype(target,/obj/structure/statue/custom))
var/obj/structure/statue/custom/original = target
current_target = original.content_ma
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="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)
return
//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 = "A 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)
// KEEP_APART in case carving block gets KEEP_TOGETHER from somewhere like material texture filters.
target_appearance_with_filters.appearance_flags |= KEEP_TOGETHER | KEEP_APART
//Doesn't use filter helpers because MAs aren't atoms
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
remove_filter("partial_uncover")
target_appearance_with_filters = null
else
var/mask_offset = min(world.icon_size,round(completion * world.icon_size))
remove_filter("partial_uncover")
add_filter("partial_uncover", 1, alpha_mask_filter(icon = white, y = -mask_offset))
target_appearance_with_filters.filters = filter(type="alpha",icon=white,y=-mask_offset,flags=MASK_INVERSE)
update_appearance()
/// 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 // MATERIAL_EFFECTS
/// 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)
if(content_ma)
QDEL_NULL(content_ma)
content_ma = new
content_ma.appearance = model_appearance
content_ma.pixel_x = 0
content_ma.pixel_y = 0
content_ma.alpha = 255
content_ma.appearance_flags &= ~KEEP_APART //Don't want this
content_ma.filters = filter(type="color",color=greyscale_with_value_bump,space=FILTER_COLOR_HSV)
update_appearance()
/obj/structure/statue/custom/update_overlays()
. = ..()
if(content_ma)
. += content_ma

View File

@@ -158,3 +158,11 @@
materials = list(/datum/material/iron = 150, /datum/material/glass = 150)
build_path = /obj/item/geiger_counter
category = list("initial", "Tools")
/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: 21 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Binary file not shown.