From 858f994b5d8c5d196d2821c7b2ece8752f51c679 Mon Sep 17 00:00:00 2001 From: nik707 <38332985+nik707@users.noreply.github.com> Date: Mon, 2 Sep 2019 18:37:22 -0500 Subject: [PATCH 1/2] Adds: The Chad Plasmaglass Table --- .../objects/effects/decals/cleanable/misc.dm | 3 + .../game/objects/items/stacks/sheets/glass.dm | 668 ++++----- code/game/objects/items/twohanded.dm | 10 +- code/game/objects/items/weaponry.dm | 4 +- code/game/objects/structures/tables_racks.dm | 1255 +++++++++-------- code/game/objects/structures/window.dm | 11 + icons/mob/back.dmi | Bin 99219 -> 99521 bytes .../mob/inhands/weapons/polearms_lefthand.dmi | Bin 5905 -> 6634 bytes .../inhands/weapons/polearms_righthand.dmi | Bin 6522 -> 7290 bytes icons/obj/items_and_weapons.dmi | Bin 125067 -> 125250 bytes icons/obj/shards.dmi | Bin 3402 -> 3678 bytes 11 files changed, 1022 insertions(+), 929 deletions(-) diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index 6a257860..e79ffda3 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -42,6 +42,9 @@ /obj/effect/decal/cleanable/glass/ex_act() qdel(src) +/obj/effect/decal/cleanable/glass/plasma + icon_state = "plasmatiny" + /obj/effect/decal/cleanable/dirt name = "dirt" desc = "Someone should clean that up." diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 48dc7fd8..12c37607 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -1,323 +1,345 @@ -/* Glass stack types - * Contains: - * Glass sheets - * Reinforced glass sheets - * Glass shards - TODO: Move this into code/game/object/item/weapons - */ - -/* - * Glass sheets - */ -GLOBAL_LIST_INIT(glass_recipes, list ( \ - new/datum/stack_recipe("directional window", /obj/structure/window/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile window", /obj/structure/window/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ -)) - -/obj/item/stack/sheet/glass - name = "glass" - desc = "HOLY SHEET! That is a lot of glass." - singular_name = "glass sheet" - icon_state = "sheet-glass" - item_state = "sheet-glass" - materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/glass - grind_results = list(/datum/reagent/silicon = 20) - point_value = 1 - tableVariant = /obj/structure/table/glass - -/obj/item/stack/sheet/glass/suicide_act(mob/living/carbon/user) - user.visible_message("[user] begins to slice [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return BRUTELOSS - -/obj/item/stack/sheet/glass/cyborg - materials = list() - is_cyborg = 1 - cost = 500 - -/obj/item/stack/sheet/glass/fifty - amount = 50 - -/obj/item/stack/sheet/glass/five - amount = 5 - -/obj/item/stack/sheet/glass/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.glass_recipes - return ..() - -/obj/item/stack/sheet/glass/attackby(obj/item/W, mob/user, params) - add_fingerprint(user) - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/CC = W - if (get_amount() < 1 || CC.get_amount() < 5) - to_chat(user, "You attach wire to the [name].") - var/obj/item/stack/light_w/new_tile = new(user.loc) - new_tile.add_fingerprint(user) - else if(istype(W, /obj/item/stack/rods)) - var/obj/item/stack/rods/V = W - if (V.get_amount() >= 1 && get_amount() >= 1) - var/obj/item/stack/sheet/rglass/RG = new (get_turf(user)) - RG.add_fingerprint(user) - var/replace = user.get_inactive_held_item()==src - V.use(1) - use(1) - if(QDELETED(src) && replace) - user.put_in_hands(RG) - else - to_chat(user, "You need one rod and one sheet of glass to make reinforced glass!") - return - else - return ..() - - - -GLOBAL_LIST_INIT(pglass_recipes, list ( \ - new/datum/stack_recipe("directional window", /obj/structure/window/plasma/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile window", /obj/structure/window/plasma/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ -)) - -/obj/item/stack/sheet/plasmaglass - name = "plasma glass" - desc = "A glass sheet made out of a plasma-silicate alloy. It looks extremely tough and heavily fire resistant." - singular_name = "plasma glass sheet" - icon_state = "sheet-pglass" - item_state = "sheet-pglass" - materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/plasmaglass - grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10) - -/obj/item/stack/sheet/plasmaglass/fifty - amount = 50 - -/obj/item/stack/sheet/plasmaglass/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.pglass_recipes - return ..() - -/obj/item/stack/sheet/plasmaglass/attackby(obj/item/W, mob/user, params) - add_fingerprint(user) - - if(istype(W, /obj/item/stack/rods)) - var/obj/item/stack/rods/V = W - if (V.get_amount() >= 1 && get_amount() >= 1) - var/obj/item/stack/sheet/plasmarglass/RG = new (get_turf(user)) - RG.add_fingerprint(user) - var/replace = user.get_inactive_held_item()==src - V.use(1) - use(1) - if(QDELETED(src) && replace) - user.put_in_hands(RG) - else - to_chat(user, "You need one rod and one sheet of plasma glass to make reinforced plasma glass!") - return - else - return ..() - - - -/* - * Reinforced glass sheets - */ -GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ - new/datum/stack_recipe("windoor frame", /obj/structure/windoor_assembly, 5, time = 0, on_floor = TRUE, window_checks = TRUE), \ - null, \ - new/datum/stack_recipe("directional reinforced window", /obj/structure/window/reinforced/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile reinforced window", /obj/structure/window/reinforced/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ -)) - - -/obj/item/stack/sheet/rglass - name = "reinforced glass" - desc = "Glass which seems to have rods or something stuck in them." - singular_name = "reinforced glass sheet" - icon_state = "sheet-rglass" - item_state = "sheet-rglass" - materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/rglass - grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/iron = 10) - point_value = 4 - -/obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params) - add_fingerprint(user) - ..() - -/obj/item/stack/sheet/rglass/cyborg - materials = list() - var/datum/robot_energy_storage/glasource - var/metcost = 250 - var/glacost = 500 - -/obj/item/stack/sheet/rglass/cyborg/get_amount() - return min(round(source.energy / metcost), round(glasource.energy / glacost)) - -/obj/item/stack/sheet/rglass/cyborg/use(used, transfer = FALSE) // Requires special checks, because it uses two storages - source.use_charge(used * metcost) - glasource.use_charge(used * glacost) - -/obj/item/stack/sheet/rglass/cyborg/add(amount) - source.add_charge(amount * metcost) - glasource.add_charge(amount * glacost) - -/obj/item/stack/sheet/rglass/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.reinforced_glass_recipes - return ..() - -GLOBAL_LIST_INIT(prglass_recipes, list ( \ - new/datum/stack_recipe("directional reinforced window", /obj/structure/window/plasma/reinforced/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile reinforced window", /obj/structure/window/plasma/reinforced/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ -)) - -/obj/item/stack/sheet/plasmarglass - name = "reinforced plasma glass" - desc = "A glass sheet made out of a plasma-silicate alloy and a rod matrix. It looks hopelessly tough and nearly fire-proof!" - singular_name = "reinforced plasma glass sheet" - icon_state = "sheet-prglass" - item_state = "sheet-prglass" - materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT, MAT_METAL = MINERAL_MATERIAL_AMOUNT * 0.5,) - armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/plasmarglass - grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10, /datum/reagent/iron = 10) - point_value = 23 - -/obj/item/stack/sheet/plasmarglass/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.prglass_recipes - return ..() - -GLOBAL_LIST_INIT(titaniumglass_recipes, list( - new/datum/stack_recipe("shuttle window", /obj/structure/window/shuttle/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) - )) - -/obj/item/stack/sheet/titaniumglass - name = "titanium glass" - desc = "A glass sheet made out of a titanium-silicate alloy." - singular_name = "titanium glass sheet" - icon_state = "sheet-titaniumglass" - item_state = "sheet-titaniumglass" - materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/titaniumglass - -/obj/item/stack/sheet/titaniumglass/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.titaniumglass_recipes - return ..() - -GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( - new/datum/stack_recipe("plastitanium window", /obj/structure/window/plastitanium/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) - )) - -/obj/item/stack/sheet/plastitaniumglass - name = "plastitanium glass" - desc = "A glass sheet made out of a plasma-titanium-silicate alloy." - singular_name = "plastitanium glass sheet" - icon_state = "sheet-plastitaniumglass" - item_state = "sheet-plastitaniumglass" - materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/plastitaniumglass - -/obj/item/stack/sheet/plastitaniumglass/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.plastitaniumglass_recipes - return ..() - -/obj/item/shard - name = "shard" - desc = "A nasty looking shard of glass." - icon = 'icons/obj/shards.dmi' - icon_state = "large" - w_class = WEIGHT_CLASS_TINY - force = 5 - throwforce = 10 - item_state = "shard-glass" - lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' - materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - attack_verb = list("stabbed", "slashed", "sliced", "cut") - hitsound = 'sound/weapons/bladeslice.ogg' - resistance_flags = ACID_PROOF - armor = list("melee" = 100, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) - max_integrity = 40 - var/cooldown = 0 - sharpness = IS_SHARP - -/obj/item/shard/suicide_act(mob/user) - user.visible_message("[user] is slitting [user.p_their()] [pick("wrists", "throat")] with the shard of glass! It looks like [user.p_theyre()] trying to commit suicide.") - return (BRUTELOSS) - - -/obj/item/shard/Initialize() - . = ..() - AddComponent(/datum/component/caltrop, force) - AddComponent(/datum/component/butchering, 150, 65) - icon_state = pick("large", "medium", "small") - switch(icon_state) - if("small") - pixel_x = rand(-12, 12) - pixel_y = rand(-12, 12) - if("medium") - pixel_x = rand(-8, 8) - pixel_y = rand(-8, 8) - if("large") - pixel_x = rand(-5, 5) - pixel_y = rand(-5, 5) - var/matrix/M = matrix(transform) - M.Turn(rand(-170, 170)) - transform = M - -/obj/item/shard/afterattack(atom/A as mob|obj, mob/user, proximity) - . = ..() - if(!proximity || !(src in user)) - return - if(isturf(A)) - return - if(istype(A, /obj/item/storage)) - return - var/hit_hand = ((user.active_hand_index % 2 == 0) ? "r_" : "l_") + "arm" - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(!H.gloves && !HAS_TRAIT(H, TRAIT_PIERCEIMMUNE)) // golems, etc - to_chat(H, "[src] cuts into your hand!") - H.apply_damage(force*0.5, BRUTE, hit_hand) - else if(ismonkey(user)) - var/mob/living/carbon/monkey/M = user - if(!HAS_TRAIT(M, TRAIT_PIERCEIMMUNE)) - to_chat(M, "[src] cuts into your hand!") - M.apply_damage(force*0.5, BRUTE, hit_hand) - - -/obj/item/shard/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/lightreplacer)) - I.attackby(src, user) - else - return ..() - -/obj/item/shard/welder_act(mob/living/user, obj/item/I) - if(I.use_tool(src, user, 0, volume=50)) - var/obj/item/stack/sheet/glass/NG = new (user.loc) - for(var/obj/item/stack/sheet/glass/G in user.loc) - if(G == NG) - continue - if(G.amount >= G.max_amount) - continue - G.attackby(NG, user) - to_chat(user, "You add the newly-formed glass to the stack. It now contains [NG.amount] sheet\s.") - qdel(src) - return TRUE - -/obj/item/shard/Crossed(mob/living/L) - if(istype(L) && has_gravity(loc)) - if(HAS_TRAIT(L, TRAIT_LIGHT_STEP)) - playsound(loc, 'sound/effects/glass_step.ogg', 30, 1) - else - playsound(loc, 'sound/effects/glass_step.ogg', 50, 1) - . = ..() +/* Glass stack types + * Contains: + * Glass sheets + * Reinforced glass sheets + * Glass shards - TODO: Move this into code/game/object/item/weapons + */ + +/* + * Glass sheets + */ +GLOBAL_LIST_INIT(glass_recipes, list ( \ + new/datum/stack_recipe("directional window", /obj/structure/window/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("fulltile window", /obj/structure/window/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ +)) + +/obj/item/stack/sheet/glass + name = "glass" + desc = "HOLY SHEET! That is a lot of glass." + singular_name = "glass sheet" + icon_state = "sheet-glass" + item_state = "sheet-glass" + materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) + resistance_flags = ACID_PROOF + merge_type = /obj/item/stack/sheet/glass + grind_results = list(/datum/reagent/silicon = 20) + point_value = 1 + tableVariant = /obj/structure/table/glass + +/obj/item/stack/sheet/glass/suicide_act(mob/living/carbon/user) + user.visible_message("[user] begins to slice [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return BRUTELOSS + +/obj/item/stack/sheet/glass/cyborg + materials = list() + is_cyborg = 1 + cost = 500 + +/obj/item/stack/sheet/glass/fifty + amount = 50 + +/obj/item/stack/sheet/glass/five + amount = 5 + +/obj/item/stack/sheet/glass/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.glass_recipes + return ..() + +/obj/item/stack/sheet/glass/attackby(obj/item/W, mob/user, params) + add_fingerprint(user) + if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/CC = W + if (get_amount() < 1 || CC.get_amount() < 5) + to_chat(user, "You attach wire to the [name].") + var/obj/item/stack/light_w/new_tile = new(user.loc) + new_tile.add_fingerprint(user) + else if(istype(W, /obj/item/stack/rods)) + var/obj/item/stack/rods/V = W + if (V.get_amount() >= 1 && get_amount() >= 1) + var/obj/item/stack/sheet/rglass/RG = new (get_turf(user)) + RG.add_fingerprint(user) + var/replace = user.get_inactive_held_item()==src + V.use(1) + use(1) + if(QDELETED(src) && replace) + user.put_in_hands(RG) + else + to_chat(user, "You need one rod and one sheet of glass to make reinforced glass!") + return + else + return ..() + + + +GLOBAL_LIST_INIT(pglass_recipes, list ( \ + new/datum/stack_recipe("directional window", /obj/structure/window/plasma/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("fulltile window", /obj/structure/window/plasma/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ +)) + +/obj/item/stack/sheet/plasmaglass + name = "plasma glass" + desc = "A glass sheet made out of a plasma-silicate alloy. It looks extremely tough and heavily fire resistant." + singular_name = "plasma glass sheet" + icon_state = "sheet-pglass" + item_state = "sheet-pglass" + materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100) + resistance_flags = ACID_PROOF + merge_type = /obj/item/stack/sheet/plasmaglass + grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10) + tableVariant = /obj/structure/table/plasmaglass + +/obj/item/stack/sheet/plasmaglass/fifty + amount = 50 + +/obj/item/stack/sheet/plasmaglass/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.pglass_recipes + return ..() + +/obj/item/stack/sheet/plasmaglass/attackby(obj/item/W, mob/user, params) + add_fingerprint(user) + + if(istype(W, /obj/item/stack/rods)) + var/obj/item/stack/rods/V = W + if (V.get_amount() >= 1 && get_amount() >= 1) + var/obj/item/stack/sheet/plasmarglass/RG = new (get_turf(user)) + RG.add_fingerprint(user) + var/replace = user.get_inactive_held_item()==src + V.use(1) + use(1) + if(QDELETED(src) && replace) + user.put_in_hands(RG) + else + to_chat(user, "You need one rod and one sheet of plasma glass to make reinforced plasma glass!") + return + else + return ..() + + + +/* + * Reinforced glass sheets + */ +GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ + new/datum/stack_recipe("windoor frame", /obj/structure/windoor_assembly, 5, time = 0, on_floor = TRUE, window_checks = TRUE), \ + null, \ + new/datum/stack_recipe("directional reinforced window", /obj/structure/window/reinforced/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("fulltile reinforced window", /obj/structure/window/reinforced/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ +)) + + +/obj/item/stack/sheet/rglass + name = "reinforced glass" + desc = "Glass which seems to have rods or something stuck in them." + singular_name = "reinforced glass sheet" + icon_state = "sheet-rglass" + item_state = "sheet-rglass" + materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) + resistance_flags = ACID_PROOF + merge_type = /obj/item/stack/sheet/rglass + grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/iron = 10) + point_value = 4 + +/obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params) + add_fingerprint(user) + ..() + +/obj/item/stack/sheet/rglass/cyborg + materials = list() + var/datum/robot_energy_storage/glasource + var/metcost = 250 + var/glacost = 500 + +/obj/item/stack/sheet/rglass/cyborg/get_amount() + return min(round(source.energy / metcost), round(glasource.energy / glacost)) + +/obj/item/stack/sheet/rglass/cyborg/use(used, transfer = FALSE) // Requires special checks, because it uses two storages + source.use_charge(used * metcost) + glasource.use_charge(used * glacost) + +/obj/item/stack/sheet/rglass/cyborg/add(amount) + source.add_charge(amount * metcost) + glasource.add_charge(amount * glacost) + +/obj/item/stack/sheet/rglass/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.reinforced_glass_recipes + return ..() + +GLOBAL_LIST_INIT(prglass_recipes, list ( \ + new/datum/stack_recipe("directional reinforced window", /obj/structure/window/plasma/reinforced/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("fulltile reinforced window", /obj/structure/window/plasma/reinforced/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ +)) + +/obj/item/stack/sheet/plasmarglass + name = "reinforced plasma glass" + desc = "A glass sheet made out of a plasma-silicate alloy and a rod matrix. It looks hopelessly tough and nearly fire-proof!" + singular_name = "reinforced plasma glass sheet" + icon_state = "sheet-prglass" + item_state = "sheet-prglass" + materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT, MAT_METAL=MINERAL_MATERIAL_AMOUNT * 0.5,) + armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + resistance_flags = ACID_PROOF + merge_type = /obj/item/stack/sheet/plasmarglass + grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10, /datum/reagent/iron = 10) + point_value = 23 + +/obj/item/stack/sheet/plasmarglass/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.prglass_recipes + return ..() + +GLOBAL_LIST_INIT(titaniumglass_recipes, list( + new/datum/stack_recipe("shuttle window", /obj/structure/window/shuttle/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) + )) + +/obj/item/stack/sheet/titaniumglass + name = "titanium glass" + desc = "A glass sheet made out of a titanium-silicate alloy." + singular_name = "titanium glass sheet" + icon_state = "sheet-titaniumglass" + item_state = "sheet-titaniumglass" + materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + resistance_flags = ACID_PROOF + merge_type = /obj/item/stack/sheet/titaniumglass + +/obj/item/stack/sheet/titaniumglass/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.titaniumglass_recipes + return ..() + +GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( + new/datum/stack_recipe("plastitanium window", /obj/structure/window/plastitanium/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) + )) + +/obj/item/stack/sheet/plastitaniumglass + name = "plastitanium glass" + desc = "A glass sheet made out of a plasma-titanium-silicate alloy." + singular_name = "plastitanium glass sheet" + icon_state = "sheet-plastitaniumglass" + item_state = "sheet-plastitaniumglass" + materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + resistance_flags = ACID_PROOF + merge_type = /obj/item/stack/sheet/plastitaniumglass + +/obj/item/stack/sheet/plastitaniumglass/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.plastitaniumglass_recipes + return ..() + +/obj/item/shard + name = "shard" + desc = "A nasty looking shard of glass." + icon = 'icons/obj/shards.dmi' + icon_state = "large" + w_class = WEIGHT_CLASS_TINY + force = 5 + throwforce = 10 + item_state = "shard-glass" + lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' + materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + attack_verb = list("stabbed", "slashed", "sliced", "cut") + hitsound = 'sound/weapons/bladeslice.ogg' + resistance_flags = ACID_PROOF + armor = list("melee" = 100, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) + max_integrity = 40 + sharpness = IS_SHARP + var/icon_prefix + + +/obj/item/shard/suicide_act(mob/user) + user.visible_message("[user] is slitting [user.p_their()] [pick("wrists", "throat")] with the shard of glass! It looks like [user.p_theyre()] trying to commit suicide.") + return (BRUTELOSS) + + +/obj/item/shard/Initialize() + . = ..() + AddComponent(/datum/component/caltrop, force) + AddComponent(/datum/component/butchering, 150, 65) + icon_state = pick("large", "medium", "small") + switch(icon_state) + if("small") + pixel_x = rand(-12, 12) + pixel_y = rand(-12, 12) + if("medium") + pixel_x = rand(-8, 8) + pixel_y = rand(-8, 8) + if("large") + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) + if (icon_prefix) + icon_state = "[icon_prefix][icon_state]" + + var/turf/T = get_turf(src) + if(T && is_station_level(T.z)) + SSblackbox.record_feedback("tally", "station_mess_created", 1, name) + +/obj/item/shard/Destroy() + . = ..() + + var/turf/T = get_turf(src) + if(T && is_station_level(T.z)) + SSblackbox.record_feedback("tally", "station_mess_destroyed", 1, name) + +/obj/item/shard/afterattack(atom/A as mob|obj, mob/user, proximity) + . = ..() + if(!proximity || !(src in user)) + return + if(isturf(A)) + return + if(istype(A, /obj/item/storage)) + return + var/hit_hand = ((user.active_hand_index % 2 == 0) ? "r_" : "l_") + "arm" + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(!H.gloves && !HAS_TRAIT(H, TRAIT_PIERCEIMMUNE)) // golems, etc + to_chat(H, "[src] cuts into your hand!") + H.apply_damage(force*0.5, BRUTE, hit_hand) + else if(ismonkey(user)) + var/mob/living/carbon/monkey/M = user + if(!HAS_TRAIT(M, TRAIT_PIERCEIMMUNE)) + to_chat(M, "[src] cuts into your hand!") + M.apply_damage(force*0.5, BRUTE, hit_hand) + + +/obj/item/shard/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/lightreplacer)) + I.attackby(src, user) + else + return ..() + +/obj/item/shard/welder_act(mob/living/user, obj/item/I) + ..() + if(I.use_tool(src, user, 0, volume=50)) + var/obj/item/stack/sheet/glass/NG = new (user.loc) + for(var/obj/item/stack/sheet/glass/G in user.loc) + if(G == NG) + continue + if(G.amount >= G.max_amount) + continue + G.attackby(NG, user) + to_chat(user, "You add the newly-formed glass to the stack. It now contains [NG.amount] sheet\s.") + qdel(src) + return TRUE + +/obj/item/shard/Crossed(mob/living/L) + if(istype(L) && has_gravity(loc)) + if(HAS_TRAIT(L, TRAIT_LIGHT_STEP)) + playsound(loc, 'sound/effects/glass_step.ogg', 30, 1) + else + playsound(loc, 'sound/effects/glass_step.ogg', 50, 1) + return ..() + +/obj/item/shard/plasma + name = "purple shard" + desc = "A nasty looking shard of plasma glass." + force = 6 + throwforce = 11 + icon_state = "plasmalarge" + materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + icon_prefix = "plasma" diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index 078e9063..0b6bc6af 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -487,6 +487,7 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) var/obj/item/grenade/explosive = null var/war_cry = "AAAAARGH!!!" + var/icon_prefix = "spearglass" /obj/item/twohanded/spear/Initialize() . = ..() @@ -529,7 +530,7 @@ if(explosive) icon_state = "spearbomb[wielded]" else - icon_state = "spearglass[wielded]" + icon_state = "[icon_prefix][wielded]" /obj/item/twohanded/spear/afterattack(atom/movable/AM, mob/user, proximity) . = ..() @@ -558,6 +559,13 @@ return TRUE /obj/item/twohanded/spear/CheckParts(list/parts_list) + var/obj/item/shard/tip = locate() in parts_list + if (istype(tip, /obj/item/shard/plasma)) + force_wielded = 19 + force_unwielded = 11 + throwforce = 21 + icon_prefix = "spearplasma" + qdel(tip) var/obj/item/twohanded/spear/S = locate() in parts_list if(S) if(S.explosive) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 72d328ad..71a1ded2 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -255,7 +255,9 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 var/obj/item/twohanded/spear/S = new /obj/item/twohanded/spear remove_item_from_storage(user) - qdel(I) + if (!user.transferItemToLoc(I, S)) + return + S.CheckParts(list(I)) qdel(src) user.put_in_hands(S) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 9c08d100..59710969 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -1,604 +1,651 @@ -/* Tables and Racks - * Contains: - * Tables - * Glass Tables - * Wooden Tables - * Reinforced Tables - * Racks - * Rack Parts - */ - -/* - * Tables - */ - -/obj/structure/table - name = "table" - desc = "A square piece of metal standing on four metal legs. It can not move." - icon = 'icons/obj/smooth_structures/table.dmi' - icon_state = "table" - density = TRUE - anchored = TRUE - layer = TABLE_LAYER - climbable = TRUE - obj_flags = CAN_BE_HIT|SHOVABLE_ONTO - pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.") - var/frame = /obj/structure/table_frame - var/framestack = /obj/item/stack/rods - var/buildstack = /obj/item/stack/sheet/metal - var/busy = FALSE - var/buildstackamount = 1 - var/framestackamount = 2 - var/deconstruction_ready = 1 - max_integrity = 100 - integrity_failure = 30 - smooth = SMOOTH_TRUE - canSmoothWith = list(/obj/structure/table, /obj/structure/table/reinforced) - -/obj/structure/table/examine(mob/user) - . = ..() - . += deconstruction_hints(user) - -/obj/structure/table/proc/deconstruction_hints(mob/user) - return "The top is screwed on, but the main bolts are also visible." - -/obj/structure/table/update_icon() - if(smooth) - queue_smooth(src) - queue_smooth_neighbors(src) - -/obj/structure/table/narsie_act() - var/atom/A = loc - qdel(src) - new /obj/structure/table/wood(A) - -/obj/structure/table/ratvar_act() - var/atom/A = loc - qdel(src) - new /obj/structure/table/reinforced/brass(A) - -/obj/structure/table/attack_paw(mob/user) - return attack_hand(user) - -/obj/structure/table/attack_hand(mob/living/user) - if(Adjacent(user) && user.pulling) - if(isliving(user.pulling)) - var/mob/living/pushed_mob = user.pulling - if(pushed_mob.buckled) - to_chat(user, "[pushed_mob] is buckled to [pushed_mob.buckled]!") - return - if(user.a_intent == INTENT_GRAB) - if(user.grab_state < GRAB_AGGRESSIVE) - to_chat(user, "You need a better grip to do that!") - return - tablepush(user, pushed_mob) - if(user.a_intent == INTENT_HELP) - pushed_mob.visible_message("[user] begins to place [pushed_mob] onto [src]...", \ - "[user] begins to place [pushed_mob] onto [src]...") - if(do_after(user, 35, target = pushed_mob)) - tableplace(user, pushed_mob) - else - return - user.stop_pulling() - else if(user.pulling.pass_flags & PASSTABLE) - user.Move_Pulled(src) - if (user.pulling.loc == loc) - user.visible_message("[user] places [user.pulling] onto [src].", - "You place [user.pulling] onto [src].") - user.stop_pulling() - return ..() - -/obj/structure/table/attack_tk() - return FALSE - -/obj/structure/table/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSTABLE)) - return 1 - if(mover.throwing) - return 1 - if(locate(/obj/structure/table) in get_turf(mover)) - return 1 - else - return !density - -/obj/structure/table/CanAStarPass(ID, dir, caller) - . = !density - if(ismovableatom(caller)) - var/atom/movable/mover = caller - . = . || (mover.pass_flags & PASSTABLE) - -/obj/structure/table/proc/tableplace(mob/living/user, mob/living/pushed_mob) - pushed_mob.forceMove(src.loc) - pushed_mob.resting = TRUE - pushed_mob.update_canmove() - pushed_mob.visible_message("[user] places [pushed_mob] onto [src].", \ - "[user] places [pushed_mob] onto [src].") - log_combat(user, pushed_mob, "placed") - -/obj/structure/table/proc/tablepush(mob/living/user, mob/living/pushed_mob) - if(HAS_TRAIT(user, TRAIT_PACIFISM)) - to_chat(user, "Throwing [pushed_mob] onto the table might hurt them!") - return - var/added_passtable = FALSE - if(!pushed_mob.pass_flags & PASSTABLE) - added_passtable = TRUE - pushed_mob.pass_flags |= PASSTABLE - pushed_mob.Move(src.loc) - if(added_passtable) - pushed_mob.pass_flags &= ~PASSTABLE - if(pushed_mob.loc != loc) //Something prevented the tabling - return - pushed_mob.Knockdown(40) - pushed_mob.visible_message("[user] slams [pushed_mob] onto [src]!", \ - "[user] slams you onto [src]!") - log_combat(user, pushed_mob, "tabled", null, "onto [src]") - if(!ishuman(pushed_mob)) - return - var/mob/living/carbon/human/H = pushed_mob - SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table) - -/obj/structure/table/shove_act(mob/living/target, mob/living/user) - if(!target.resting) - target.Knockdown(SHOVE_KNOCKDOWN_TABLE) - user.visible_message("[user.name] shoves [target.name] onto \the [src]!", - "You shove [target.name] onto \the [src]!", null, COMBAT_MESSAGE_RANGE) - target.forceMove(src.loc) - log_combat(user, target, "shoved", "onto [src] (table)") - return TRUE - -/obj/structure/table/attackby(obj/item/I, mob/user, params) - if(!(flags_1 & NODECONSTRUCT_1)) - if(istype(I, /obj/item/screwdriver) && deconstruction_ready) - to_chat(user, "You start disassembling [src]...") - if(I.use_tool(src, user, 20, volume=50)) - deconstruct(TRUE) - return - - if(istype(I, /obj/item/wrench) && deconstruction_ready) - to_chat(user, "You start deconstructing [src]...") - if(I.use_tool(src, user, 40, volume=50)) - playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) - deconstruct(TRUE, 1) - return - - if(istype(I, /obj/item/storage/bag/tray)) - var/obj/item/storage/bag/tray/T = I - if(T.contents.len > 0) // If the tray isn't empty - SEND_SIGNAL(I, COMSIG_TRY_STORAGE_QUICK_EMPTY, drop_location()) - user.visible_message("[user] empties [I] on [src].") - return - // If the tray IS empty, continue on (tray will be placed on the table like other items) - - if(user.a_intent != INTENT_HARM && !(I.item_flags & ABSTRACT)) - if(user.transferItemToLoc(I, drop_location())) - var/list/click_params = params2list(params) - //Center the icon where the user clicked. - if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) - return - //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) - I.pixel_x = CLAMP(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) - I.pixel_y = CLAMP(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) - return 1 - else - return ..() - - -/obj/structure/table/deconstruct(disassembled = TRUE, wrench_disassembly = 0) - if(!(flags_1 & NODECONSTRUCT_1)) - var/turf/T = get_turf(src) - new buildstack(T, buildstackamount) - if(!wrench_disassembly) - new frame(T) - else - new framestack(T, framestackamount) - qdel(src) - - -/* - * Glass tables - */ -/obj/structure/table/glass - name = "glass table" - desc = "What did I say about leaning on the glass tables? Now you need surgery." - icon = 'icons/obj/smooth_structures/glass_table.dmi' - icon_state = "glass_table" - buildstack = /obj/item/stack/sheet/glass - canSmoothWith = null - max_integrity = 70 - resistance_flags = ACID_PROOF - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) - var/list/debris = list() - -/obj/structure/table/glass/New() - . = ..() - debris += new frame - debris += new /obj/item/shard - -/obj/structure/table/glass/Destroy() - QDEL_LIST(debris) - . = ..() - -/obj/structure/table/glass/Crossed(atom/movable/AM) - . = ..() - if(flags_1 & NODECONSTRUCT_1) - return - if(!isliving(AM)) - return - // Don't break if they're just flying past - if(AM.throwing) - addtimer(CALLBACK(src, .proc/throw_check, AM), 5) - else - check_break(AM) - -/obj/structure/table/glass/proc/throw_check(mob/living/M) - if(M.loc == get_turf(src)) - check_break(M) - -/obj/structure/table/glass/proc/check_break(mob/living/M) - if(M.has_gravity() && M.mob_size > MOB_SIZE_SMALL && !(M.movement_type & FLYING)) - table_shatter(M) - -/obj/structure/table/glass/proc/table_shatter(mob/living/L) - visible_message("[src] breaks!", - "You hear breaking glass.") - var/turf/T = get_turf(src) - playsound(T, "shatter", 50, 1) - for(var/I in debris) - var/atom/movable/AM = I - AM.forceMove(T) - debris -= AM - if(istype(AM, /obj/item/shard)) - AM.throw_impact(L) - L.Knockdown(100) - qdel(src) - -/obj/structure/table/glass/deconstruct(disassembled = TRUE, wrench_disassembly = 0) - if(!(flags_1 & NODECONSTRUCT_1)) - if(disassembled) - ..() - return - else - var/turf/T = get_turf(src) - playsound(T, "shatter", 50, 1) - for(var/X in debris) - var/atom/movable/AM = X - AM.forceMove(T) - debris -= AM - qdel(src) - -/obj/structure/table/glass/narsie_act() - color = NARSIE_WINDOW_COLOUR - for(var/obj/item/shard/S in debris) - S.color = NARSIE_WINDOW_COLOUR - -/* - * Wooden tables - */ - -/obj/structure/table/wood - name = "wooden table" - desc = "Do not apply fire to this. Rumour says it burns easily." - icon = 'icons/obj/smooth_structures/wood_table.dmi' - icon_state = "wood_table" - frame = /obj/structure/table_frame/wood - framestack = /obj/item/stack/sheet/mineral/wood - buildstack = /obj/item/stack/sheet/mineral/wood - resistance_flags = FLAMMABLE - max_integrity = 70 - canSmoothWith = list(/obj/structure/table/wood, - /obj/structure/table/wood/poker, - /obj/structure/table/wood/bar) - -/obj/structure/table/wood/narsie_act(total_override = TRUE) - if(!total_override) - ..() - -/obj/structure/table/wood/poker //No specialties, Just a mapping object. - name = "gambling table" - desc = "A seedy table for seedy dealings in seedy places." - icon = 'icons/obj/smooth_structures/poker_table.dmi' - icon_state = "poker_table" - buildstack = /obj/item/stack/tile/carpet - -/obj/structure/table/wood/poker/narsie_act() - ..(FALSE) - -/obj/structure/table/wood/fancy - name = "fancy table" - desc = "A standard metal table frame covered with an amazingly fancy, patterned cloth." - icon = 'icons/obj/structures.dmi' - icon_state = "fancy_table" - frame = /obj/structure/table_frame - framestack = /obj/item/stack/rods - buildstack = /obj/item/stack/tile/carpet - canSmoothWith = list(/obj/structure/table/wood/fancy, /obj/structure/table/wood/fancy/black, /obj/structure/table/wood/fancy/blackred, /obj/structure/table/wood/fancy/monochrome) - -/obj/structure/table/wood/fancy/New() - // New() is used so that the /black subtype can override `icon` easily and - // the correct value will be used by the smoothing subsystem. - . = ..() - // Needs to be set dynamically because table smooth sprites are 32x34, - // which the editor treats as a two-tile-tall object. The sprites are that - // size so that the north/south corners look nice - examine the detail on - // the sprites in the editor to see why. - icon = 'icons/obj/smooth_structures/fancy_table.dmi' - -/obj/structure/table/wood/fancy/black - icon_state = "fancy_table_black" - buildstack = /obj/item/stack/tile/carpet/black - -/obj/structure/table/wood/fancy/blackred - icon = 'icons/obj/structures.dmi' - icon_state = "fancy_table_blackred" - buildstack = /obj/item/stack/tile/carpet/blackred - -/obj/structure/table/wood/fancy/blackred/New() - . = ..() - icon = 'icons/obj/smooth_structures/fancy_table_blackred.dmi' - -/obj/structure/table/wood/fancy/monochrome - icon = 'icons/obj/structures.dmi' - icon_state = "fancy_table_monochrome" - buildstack = /obj/item/stack/tile/carpet/monochrome - -/obj/structure/table/wood/fancy/monochrome/New() - . = ..() - icon = 'icons/obj/smooth_structures/fancy_table_monochrome.dmi' - -/obj/structure/table/wood/fancy/black/New() - . = ..() - // Ditto above. - icon = 'icons/obj/smooth_structures/fancy_table_black.dmi' -/* - * Reinforced tables - */ -/obj/structure/table/reinforced - name = "reinforced table" - desc = "A reinforced version of the four legged table." - icon = 'icons/obj/smooth_structures/reinforced_table.dmi' - icon_state = "r_table" - deconstruction_ready = 0 - buildstack = /obj/item/stack/sheet/plasteel - canSmoothWith = list(/obj/structure/table/reinforced, /obj/structure/table) - max_integrity = 200 - integrity_failure = 50 - armor = list("melee" = 10, "bullet" = 30, "laser" = 30, "energy" = 100, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) - -/obj/structure/table/reinforced/deconstruction_hints(mob/user) - if(deconstruction_ready) - to_chat(user, "The top cover has been welded loose and the main frame's bolts are exposed.") - else - to_chat(user, "The top cover is firmly welded on.") - -/obj/structure/table/reinforced/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/weldingtool)) - if(!W.tool_start_check(user, amount=0)) - return - - if(deconstruction_ready) - to_chat(user, "You start strengthening the reinforced table...") - if (W.use_tool(src, user, 50, volume=50)) - to_chat(user, "You strengthen the table.") - deconstruction_ready = 0 - else - to_chat(user, "You start weakening the reinforced table...") - if (W.use_tool(src, user, 50, volume=50)) - to_chat(user, "You weaken the table.") - deconstruction_ready = 1 - else - . = ..() - -/obj/structure/table/reinforced/brass - name = "brass table" - desc = "A solid, slightly beveled brass table." - icon = 'icons/obj/smooth_structures/brass_table.dmi' - icon_state = "brass_table" - resistance_flags = FIRE_PROOF | ACID_PROOF - frame = /obj/structure/table_frame/brass - framestack = /obj/item/stack/tile/brass - buildstack = /obj/item/stack/tile/brass - framestackamount = 1 - buildstackamount = 1 - canSmoothWith = list(/obj/structure/table/reinforced/brass, /obj/structure/table/bronze) - -/obj/structure/table/reinforced/brass/New() - change_construction_value(2) - ..() - -/obj/structure/table/reinforced/brass/Destroy() - change_construction_value(-2) - return ..() - -/obj/structure/table/reinforced/brass/tablepush(mob/living/user, mob/living/pushed_mob) - .= ..() - playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 50, TRUE) - -/obj/structure/table/reinforced/brass/narsie_act() - take_damage(rand(15, 45), BRUTE) - if(src) //do we still exist? - var/previouscolor = color - color = "#960000" - animate(src, color = previouscolor, time = 8) - addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8) - -/obj/structure/table/reinforced/brass/ratvar_act() - obj_integrity = max_integrity - -/obj/structure/table/bronze - name = "bronze table" - desc = "A solid table made out of bronze." - icon = 'icons/obj/smooth_structures/brass_table.dmi' - icon_state = "brass_table" - resistance_flags = FIRE_PROOF | ACID_PROOF - buildstack = /obj/item/stack/tile/bronze - canSmoothWith = list(/obj/structure/table/reinforced/brass, /obj/structure/table/bronze) - -/obj/structure/table/bronze/tablepush(mob/living/user, mob/living/pushed_mob) - ..() - playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 50, TRUE) - -/* - * Surgery Tables - */ - -/obj/structure/table/optable - name = "operating table" - desc = "Used for advanced medical procedures." - icon = 'icons/obj/surgery.dmi' - icon_state = "optable" - buildstack = /obj/item/stack/sheet/mineral/silver - smooth = SMOOTH_FALSE - can_buckle = 1 - buckle_lying = 1 - buckle_requires_restraints = 1 - var/mob/living/carbon/human/patient = null - var/obj/machinery/computer/operating/computer = null - -/obj/structure/table/optable/New() - ..() - for(var/direction in GLOB.cardinals) - computer = locate(/obj/machinery/computer/operating, get_step(src, direction)) - if(computer) - computer.table = src - break - -/obj/structure/table/optable/tablepush(mob/living/user, mob/living/pushed_mob) - pushed_mob.forceMove(src.loc) - pushed_mob.resting = 1 - pushed_mob.update_canmove() - visible_message("[user] has laid [pushed_mob] on [src].") - check_patient() - -/obj/structure/table/optable/proc/check_patient() - var/mob/M = locate(/mob/living/carbon/human, loc) - if(M) - if(M.resting) - patient = M - return 1 - else - patient = null - return 0 - - - -/* - * Racks - */ -/obj/structure/rack - name = "rack" - desc = "Different from the Middle Ages version." - icon = 'icons/obj/objects.dmi' - icon_state = "rack" - layer = TABLE_LAYER - density = TRUE - anchored = TRUE - pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density. - max_integrity = 20 - -/obj/structure/rack/examine(mob/user) - . = ..() - . += "It's held together by a couple of bolts." - -/obj/structure/rack/CanPass(atom/movable/mover, turf/target) - if(src.density == 0) //Because broken racks -Agouri |TODO: SPRITE!| - return 1 - if(istype(mover) && (mover.pass_flags & PASSTABLE)) - return 1 - else - return 0 - -/obj/structure/rack/CanAStarPass(ID, dir, caller) - . = !density - if(ismovableatom(caller)) - var/atom/movable/mover = caller - . = . || (mover.pass_flags & PASSTABLE) - -/obj/structure/rack/MouseDrop_T(obj/O, mob/user) - . = ..() - if ((!( istype(O, /obj/item) ) || user.get_active_held_item() != O)) - return - if(!user.dropItemToGround(O)) - return - if(O.loc != src.loc) - step(O, get_dir(O, src)) - -/obj/structure/rack/attackby(obj/item/W, mob/user, params) - if (istype(W, /obj/item/wrench) && !(flags_1&NODECONSTRUCT_1)) - W.play_tool_sound(src) - deconstruct(TRUE) - return - if(user.a_intent == INTENT_HARM) - return ..() - if(user.transferItemToLoc(W, drop_location())) - return 1 - -/obj/structure/rack/attack_paw(mob/living/user) - attack_hand(user) - -/obj/structure/rack/attack_hand(mob/living/user) - . = ..() - if(.) - return - if(user.IsKnockdown() || user.resting || user.lying || user.get_num_legs() < 2) - return - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src, ATTACK_EFFECT_KICK) - user.visible_message("[user] kicks [src].", null, null, COMBAT_MESSAGE_RANGE) - take_damage(rand(4,8), BRUTE, "melee", 1) - -/obj/structure/rack/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - if(damage_amount) - playsound(loc, 'sound/items/dodgeball.ogg', 80, 1) - else - playsound(loc, 'sound/weapons/tap.ogg', 50, 1) - if(BURN) - playsound(loc, 'sound/items/welder.ogg', 40, 1) - -/* - * Rack destruction - */ - -/obj/structure/rack/deconstruct(disassembled = TRUE) - if(!(flags_1&NODECONSTRUCT_1)) - density = FALSE - var/obj/item/rack_parts/newparts = new(loc) - transfer_fingerprints_to(newparts) - qdel(src) - - -/* - * Rack Parts - */ - -/obj/item/rack_parts - name = "rack parts" - desc = "Parts of a rack." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "rack_parts" - flags_1 = CONDUCT_1 - materials = list(MAT_METAL=2000) - var/building = FALSE - -/obj/item/rack_parts/attackby(obj/item/W, mob/user, params) - if (istype(W, /obj/item/wrench)) - new /obj/item/stack/sheet/metal(user.loc) - qdel(src) - else - . = ..() - -/obj/item/rack_parts/attack_self(mob/user) - if(building) - return - building = TRUE - to_chat(user, "You start constructing a rack...") - if(do_after(user, 50, target = user, progress=TRUE)) - if(!user.temporarilyRemoveItemFromInventory(src)) - return - var/obj/structure/rack/R = new /obj/structure/rack(user.loc) - user.visible_message("[user] assembles \a [R].\ - ", "You assemble \a [R].") - R.add_fingerprint(user) - qdel(src) - building = FALSE +/* Tables and Racks + * Contains: + * Tables + * Glass Tables + * Wooden Tables + * Reinforced Tables + * Racks + * Rack Parts + */ + +/* + * Tables + */ + +/obj/structure/table + name = "table" + desc = "A square piece of metal standing on four metal legs. It can not move." + icon = 'icons/obj/smooth_structures/table.dmi' + icon_state = "table" + density = TRUE + anchored = TRUE + layer = TABLE_LAYER + climbable = TRUE + obj_flags = CAN_BE_HIT|SHOVABLE_ONTO + pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.") + var/frame = /obj/structure/table_frame + var/framestack = /obj/item/stack/rods + var/buildstack = /obj/item/stack/sheet/metal + var/busy = FALSE + var/buildstackamount = 1 + var/framestackamount = 2 + var/deconstruction_ready = 1 + max_integrity = 100 + integrity_failure = 30 + smooth = SMOOTH_TRUE + canSmoothWith = list(/obj/structure/table, /obj/structure/table/reinforced) + +/obj/structure/table/examine(mob/user) + . = ..() + . += deconstruction_hints(user) + +/obj/structure/table/proc/deconstruction_hints(mob/user) + return "The top is screwed on, but the main bolts are also visible." + +/obj/structure/table/update_icon() + if(smooth) + queue_smooth(src) + queue_smooth_neighbors(src) + +/obj/structure/table/narsie_act() + var/atom/A = loc + qdel(src) + new /obj/structure/table/wood(A) + +/obj/structure/table/ratvar_act() + var/atom/A = loc + qdel(src) + new /obj/structure/table/reinforced/brass(A) + +/obj/structure/table/attack_paw(mob/user) + return attack_hand(user) + +/obj/structure/table/attack_hand(mob/living/user) + if(Adjacent(user) && user.pulling) + if(isliving(user.pulling)) + var/mob/living/pushed_mob = user.pulling + if(pushed_mob.buckled) + to_chat(user, "[pushed_mob] is buckled to [pushed_mob.buckled]!") + return + if(user.a_intent == INTENT_GRAB) + if(user.grab_state < GRAB_AGGRESSIVE) + to_chat(user, "You need a better grip to do that!") + return + tablepush(user, pushed_mob) + if(user.a_intent == INTENT_HELP) + pushed_mob.visible_message("[user] begins to place [pushed_mob] onto [src]...", \ + "[user] begins to place [pushed_mob] onto [src]...") + if(do_after(user, 35, target = pushed_mob)) + tableplace(user, pushed_mob) + else + return + user.stop_pulling() + else if(user.pulling.pass_flags & PASSTABLE) + user.Move_Pulled(src) + if (user.pulling.loc == loc) + user.visible_message("[user] places [user.pulling] onto [src].", + "You place [user.pulling] onto [src].") + user.stop_pulling() + return ..() + +/obj/structure/table/attack_tk() + return FALSE + +/obj/structure/table/CanPass(atom/movable/mover, turf/target) + if(istype(mover) && (mover.pass_flags & PASSTABLE)) + return 1 + if(mover.throwing) + return 1 + if(locate(/obj/structure/table) in get_turf(mover)) + return 1 + else + return !density + +/obj/structure/table/CanAStarPass(ID, dir, caller) + . = !density + if(ismovableatom(caller)) + var/atom/movable/mover = caller + . = . || (mover.pass_flags & PASSTABLE) + +/obj/structure/table/proc/tableplace(mob/living/user, mob/living/pushed_mob) + pushed_mob.forceMove(src.loc) + pushed_mob.resting = TRUE + pushed_mob.update_canmove() + pushed_mob.visible_message("[user] places [pushed_mob] onto [src].", \ + "[user] places [pushed_mob] onto [src].") + log_combat(user, pushed_mob, "placed") + +/obj/structure/table/proc/tablepush(mob/living/user, mob/living/pushed_mob) + if(HAS_TRAIT(user, TRAIT_PACIFISM)) + to_chat(user, "Throwing [pushed_mob] onto the table might hurt them!") + return + var/added_passtable = FALSE + if(!pushed_mob.pass_flags & PASSTABLE) + added_passtable = TRUE + pushed_mob.pass_flags |= PASSTABLE + pushed_mob.Move(src.loc) + if(added_passtable) + pushed_mob.pass_flags &= ~PASSTABLE + if(pushed_mob.loc != loc) //Something prevented the tabling + return + pushed_mob.Knockdown(40) + pushed_mob.visible_message("[user] slams [pushed_mob] onto [src]!", \ + "[user] slams you onto [src]!") + log_combat(user, pushed_mob, "tabled", null, "onto [src]") + if(!ishuman(pushed_mob)) + return + var/mob/living/carbon/human/H = pushed_mob + SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table) + +/obj/structure/table/shove_act(mob/living/target, mob/living/user) + if(!target.resting) + target.Knockdown(SHOVE_KNOCKDOWN_TABLE) + user.visible_message("[user.name] shoves [target.name] onto \the [src]!", + "You shove [target.name] onto \the [src]!", null, COMBAT_MESSAGE_RANGE) + target.forceMove(src.loc) + log_combat(user, target, "shoved", "onto [src] (table)") + return TRUE + +/obj/structure/table/attackby(obj/item/I, mob/user, params) + if(!(flags_1 & NODECONSTRUCT_1)) + if(istype(I, /obj/item/screwdriver) && deconstruction_ready) + to_chat(user, "You start disassembling [src]...") + if(I.use_tool(src, user, 20, volume=50)) + deconstruct(TRUE) + return + + if(istype(I, /obj/item/wrench) && deconstruction_ready) + to_chat(user, "You start deconstructing [src]...") + if(I.use_tool(src, user, 40, volume=50)) + playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) + deconstruct(TRUE, 1) + return + + if(istype(I, /obj/item/storage/bag/tray)) + var/obj/item/storage/bag/tray/T = I + if(T.contents.len > 0) // If the tray isn't empty + SEND_SIGNAL(I, COMSIG_TRY_STORAGE_QUICK_EMPTY, drop_location()) + user.visible_message("[user] empties [I] on [src].") + return + // If the tray IS empty, continue on (tray will be placed on the table like other items) + + if(user.a_intent != INTENT_HARM && !(I.item_flags & ABSTRACT)) + if(user.transferItemToLoc(I, drop_location())) + var/list/click_params = params2list(params) + //Center the icon where the user clicked. + if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) + return + //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) + I.pixel_x = CLAMP(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + I.pixel_y = CLAMP(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) + return 1 + else + return ..() + + +/obj/structure/table/deconstruct(disassembled = TRUE, wrench_disassembly = 0) + if(!(flags_1 & NODECONSTRUCT_1)) + var/turf/T = get_turf(src) + new buildstack(T, buildstackamount) + if(!wrench_disassembly) + new frame(T) + else + new framestack(T, framestackamount) + qdel(src) + + +/* + * Glass tables + */ +/obj/structure/table/glass + name = "glass table" + desc = "What did I say about leaning on the glass tables? Now you need surgery." + icon = 'icons/obj/smooth_structures/glass_table.dmi' + icon_state = "glass_table" + buildstack = /obj/item/stack/sheet/glass + canSmoothWith = null + max_integrity = 70 + resistance_flags = ACID_PROOF + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + var/list/debris = list() + +/obj/structure/table/glass/New() + . = ..() + debris += new frame + debris += new /obj/item/shard + +/obj/structure/table/glass/Destroy() + QDEL_LIST(debris) + . = ..() + +/obj/structure/table/glass/Crossed(atom/movable/AM) + . = ..() + if(flags_1 & NODECONSTRUCT_1) + return + if(!isliving(AM)) + return + // Don't break if they're just flying past + if(AM.throwing) + addtimer(CALLBACK(src, .proc/throw_check, AM), 5) + else + check_break(AM) + +/obj/structure/table/glass/proc/throw_check(mob/living/M) + if(M.loc == get_turf(src)) + check_break(M) + +/obj/structure/table/glass/proc/check_break(mob/living/M) + if(M.has_gravity() && M.mob_size > MOB_SIZE_SMALL && !(M.movement_type & FLYING)) + table_shatter(M) + +/obj/structure/table/glass/proc/table_shatter(mob/living/L) + visible_message("[src] breaks!", + "You hear breaking glass.") + var/turf/T = get_turf(src) + playsound(T, "shatter", 50, 1) + for(var/I in debris) + var/atom/movable/AM = I + AM.forceMove(T) + debris -= AM + if(istype(AM, /obj/item/shard)) + AM.throw_impact(L) + L.Knockdown(100) + qdel(src) + +/obj/structure/table/glass/deconstruct(disassembled = TRUE, wrench_disassembly = 0) + if(!(flags_1 & NODECONSTRUCT_1)) + if(disassembled) + ..() + return + else + var/turf/T = get_turf(src) + playsound(T, "shatter", 50, 1) + for(var/X in debris) + var/atom/movable/AM = X + AM.forceMove(T) + debris -= AM + qdel(src) + +/obj/structure/table/glass/narsie_act() + color = NARSIE_WINDOW_COLOUR + for(var/obj/item/shard/S in debris) + S.color = NARSIE_WINDOW_COLOUR + +/* + * Plasmaglass tables + */ +/obj/structure/table/plasmaglass + name = "plasmaglass table" + desc = "A glasstable, but it's pink and more sturdy. What will Nanotrasen design next with plasma?" + icon = 'icons/obj/smooth_structures/plasmaglass_table.dmi' + icon_state = "plasmaglass_table" + climbable = TRUE + buildstack = /obj/item/stack/sheet/plasmaglass + canSmoothWith = null + max_integrity = 270 + resistance_flags = ACID_PROOF + armor = list("melee" = 10, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + var/list/debris = list() + +/obj/structure/table/plasmaglass/New() + . = ..() + debris += new frame + debris += new /obj/item/shard/plasma + +/obj/structure/table/plasmaglass/Destroy() + QDEL_LIST(debris) + . = ..() + +/obj/structure/table/plasmaglass/proc/check_break(mob/living/M) + return + +/obj/structure/table/plasmaglass/deconstruct(disassembled = TRUE, wrench_disassembly = 0) + if(!(flags_1 & NODECONSTRUCT_1)) + if(disassembled) + ..() + return + else + var/turf/T = get_turf(src) + playsound(T, "shatter", 50, 1) + for(var/X in debris) + var/atom/movable/AM = X + AM.forceMove(T) + debris -= AM + qdel(src) + +/obj/structure/table/plasmaglass/narsie_act() + color = NARSIE_WINDOW_COLOUR + for(var/obj/item/shard/S in debris) + S.color = NARSIE_WINDOW_COLOUR + +/* + * Wooden tables + */ + +/obj/structure/table/wood + name = "wooden table" + desc = "Do not apply fire to this. Rumour says it burns easily." + icon = 'icons/obj/smooth_structures/wood_table.dmi' + icon_state = "wood_table" + frame = /obj/structure/table_frame/wood + framestack = /obj/item/stack/sheet/mineral/wood + buildstack = /obj/item/stack/sheet/mineral/wood + resistance_flags = FLAMMABLE + max_integrity = 70 + canSmoothWith = list(/obj/structure/table/wood, + /obj/structure/table/wood/poker, + /obj/structure/table/wood/bar) + +/obj/structure/table/wood/narsie_act(total_override = TRUE) + if(!total_override) + ..() + +/obj/structure/table/wood/poker //No specialties, Just a mapping object. + name = "gambling table" + desc = "A seedy table for seedy dealings in seedy places." + icon = 'icons/obj/smooth_structures/poker_table.dmi' + icon_state = "poker_table" + buildstack = /obj/item/stack/tile/carpet + +/obj/structure/table/wood/poker/narsie_act() + ..(FALSE) + +/obj/structure/table/wood/fancy + name = "fancy table" + desc = "A standard metal table frame covered with an amazingly fancy, patterned cloth." + icon = 'icons/obj/structures.dmi' + icon_state = "fancy_table" + frame = /obj/structure/table_frame + framestack = /obj/item/stack/rods + buildstack = /obj/item/stack/tile/carpet + canSmoothWith = list(/obj/structure/table/wood/fancy, /obj/structure/table/wood/fancy/black, /obj/structure/table/wood/fancy/blackred, /obj/structure/table/wood/fancy/monochrome) + +/obj/structure/table/wood/fancy/New() + // New() is used so that the /black subtype can override `icon` easily and + // the correct value will be used by the smoothing subsystem. + . = ..() + // Needs to be set dynamically because table smooth sprites are 32x34, + // which the editor treats as a two-tile-tall object. The sprites are that + // size so that the north/south corners look nice - examine the detail on + // the sprites in the editor to see why. + icon = 'icons/obj/smooth_structures/fancy_table.dmi' + +/obj/structure/table/wood/fancy/black + icon_state = "fancy_table_black" + buildstack = /obj/item/stack/tile/carpet/black + +/obj/structure/table/wood/fancy/blackred + icon = 'icons/obj/structures.dmi' + icon_state = "fancy_table_blackred" + buildstack = /obj/item/stack/tile/carpet/blackred + +/obj/structure/table/wood/fancy/blackred/New() + . = ..() + icon = 'icons/obj/smooth_structures/fancy_table_blackred.dmi' + +/obj/structure/table/wood/fancy/monochrome + icon = 'icons/obj/structures.dmi' + icon_state = "fancy_table_monochrome" + buildstack = /obj/item/stack/tile/carpet/monochrome + +/obj/structure/table/wood/fancy/monochrome/New() + . = ..() + icon = 'icons/obj/smooth_structures/fancy_table_monochrome.dmi' + +/obj/structure/table/wood/fancy/black/New() + . = ..() + // Ditto above. + icon = 'icons/obj/smooth_structures/fancy_table_black.dmi' +/* + * Reinforced tables + */ +/obj/structure/table/reinforced + name = "reinforced table" + desc = "A reinforced version of the four legged table." + icon = 'icons/obj/smooth_structures/reinforced_table.dmi' + icon_state = "r_table" + deconstruction_ready = 0 + buildstack = /obj/item/stack/sheet/plasteel + canSmoothWith = list(/obj/structure/table/reinforced, /obj/structure/table) + max_integrity = 200 + integrity_failure = 50 + armor = list("melee" = 10, "bullet" = 30, "laser" = 30, "energy" = 100, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) + +/obj/structure/table/reinforced/deconstruction_hints(mob/user) + if(deconstruction_ready) + to_chat(user, "The top cover has been welded loose and the main frame's bolts are exposed.") + else + to_chat(user, "The top cover is firmly welded on.") + +/obj/structure/table/reinforced/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/weldingtool)) + if(!W.tool_start_check(user, amount=0)) + return + + if(deconstruction_ready) + to_chat(user, "You start strengthening the reinforced table...") + if (W.use_tool(src, user, 50, volume=50)) + to_chat(user, "You strengthen the table.") + deconstruction_ready = 0 + else + to_chat(user, "You start weakening the reinforced table...") + if (W.use_tool(src, user, 50, volume=50)) + to_chat(user, "You weaken the table.") + deconstruction_ready = 1 + else + . = ..() + +/obj/structure/table/reinforced/brass + name = "brass table" + desc = "A solid, slightly beveled brass table." + icon = 'icons/obj/smooth_structures/brass_table.dmi' + icon_state = "brass_table" + resistance_flags = FIRE_PROOF | ACID_PROOF + frame = /obj/structure/table_frame/brass + framestack = /obj/item/stack/tile/brass + buildstack = /obj/item/stack/tile/brass + framestackamount = 1 + buildstackamount = 1 + canSmoothWith = list(/obj/structure/table/reinforced/brass, /obj/structure/table/bronze) + +/obj/structure/table/reinforced/brass/New() + change_construction_value(2) + ..() + +/obj/structure/table/reinforced/brass/Destroy() + change_construction_value(-2) + return ..() + +/obj/structure/table/reinforced/brass/tablepush(mob/living/user, mob/living/pushed_mob) + .= ..() + playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 50, TRUE) + +/obj/structure/table/reinforced/brass/narsie_act() + take_damage(rand(15, 45), BRUTE) + if(src) //do we still exist? + var/previouscolor = color + color = "#960000" + animate(src, color = previouscolor, time = 8) + addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8) + +/obj/structure/table/reinforced/brass/ratvar_act() + obj_integrity = max_integrity + +/obj/structure/table/bronze + name = "bronze table" + desc = "A solid table made out of bronze." + icon = 'icons/obj/smooth_structures/brass_table.dmi' + icon_state = "brass_table" + resistance_flags = FIRE_PROOF | ACID_PROOF + buildstack = /obj/item/stack/tile/bronze + canSmoothWith = list(/obj/structure/table/reinforced/brass, /obj/structure/table/bronze) + +/obj/structure/table/bronze/tablepush(mob/living/user, mob/living/pushed_mob) + ..() + playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 50, TRUE) + +/* + * Surgery Tables + */ + +/obj/structure/table/optable + name = "operating table" + desc = "Used for advanced medical procedures." + icon = 'icons/obj/surgery.dmi' + icon_state = "optable" + buildstack = /obj/item/stack/sheet/mineral/silver + smooth = SMOOTH_FALSE + can_buckle = 1 + buckle_lying = 1 + buckle_requires_restraints = 1 + var/mob/living/carbon/human/patient = null + var/obj/machinery/computer/operating/computer = null + +/obj/structure/table/optable/New() + ..() + for(var/direction in GLOB.cardinals) + computer = locate(/obj/machinery/computer/operating, get_step(src, direction)) + if(computer) + computer.table = src + break + +/obj/structure/table/optable/tablepush(mob/living/user, mob/living/pushed_mob) + pushed_mob.forceMove(src.loc) + pushed_mob.resting = 1 + pushed_mob.update_canmove() + visible_message("[user] has laid [pushed_mob] on [src].") + check_patient() + +/obj/structure/table/optable/proc/check_patient() + var/mob/M = locate(/mob/living/carbon/human, loc) + if(M) + if(M.resting) + patient = M + return 1 + else + patient = null + return 0 + + + +/* + * Racks + */ +/obj/structure/rack + name = "rack" + desc = "Different from the Middle Ages version." + icon = 'icons/obj/objects.dmi' + icon_state = "rack" + layer = TABLE_LAYER + density = TRUE + anchored = TRUE + pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density. + max_integrity = 20 + +/obj/structure/rack/examine(mob/user) + . = ..() + . += "It's held together by a couple of bolts." + +/obj/structure/rack/CanPass(atom/movable/mover, turf/target) + if(src.density == 0) //Because broken racks -Agouri |TODO: SPRITE!| + return 1 + if(istype(mover) && (mover.pass_flags & PASSTABLE)) + return 1 + else + return 0 + +/obj/structure/rack/CanAStarPass(ID, dir, caller) + . = !density + if(ismovableatom(caller)) + var/atom/movable/mover = caller + . = . || (mover.pass_flags & PASSTABLE) + +/obj/structure/rack/MouseDrop_T(obj/O, mob/user) + . = ..() + if ((!( istype(O, /obj/item) ) || user.get_active_held_item() != O)) + return + if(!user.dropItemToGround(O)) + return + if(O.loc != src.loc) + step(O, get_dir(O, src)) + +/obj/structure/rack/attackby(obj/item/W, mob/user, params) + if (istype(W, /obj/item/wrench) && !(flags_1&NODECONSTRUCT_1)) + W.play_tool_sound(src) + deconstruct(TRUE) + return + if(user.a_intent == INTENT_HARM) + return ..() + if(user.transferItemToLoc(W, drop_location())) + return 1 + +/obj/structure/rack/attack_paw(mob/living/user) + attack_hand(user) + +/obj/structure/rack/attack_hand(mob/living/user) + . = ..() + if(.) + return + if(user.IsKnockdown() || user.resting || user.lying || user.get_num_legs() < 2) + return + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src, ATTACK_EFFECT_KICK) + user.visible_message("[user] kicks [src].", null, null, COMBAT_MESSAGE_RANGE) + take_damage(rand(4,8), BRUTE, "melee", 1) + +/obj/structure/rack/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + if(damage_amount) + playsound(loc, 'sound/items/dodgeball.ogg', 80, 1) + else + playsound(loc, 'sound/weapons/tap.ogg', 50, 1) + if(BURN) + playsound(loc, 'sound/items/welder.ogg', 40, 1) + +/* + * Rack destruction + */ + +/obj/structure/rack/deconstruct(disassembled = TRUE) + if(!(flags_1&NODECONSTRUCT_1)) + density = FALSE + var/obj/item/rack_parts/newparts = new(loc) + transfer_fingerprints_to(newparts) + qdel(src) + + +/* + * Rack Parts + */ + +/obj/item/rack_parts + name = "rack parts" + desc = "Parts of a rack." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "rack_parts" + flags_1 = CONDUCT_1 + materials = list(MAT_METAL=2000) + var/building = FALSE + +/obj/item/rack_parts/attackby(obj/item/W, mob/user, params) + if (istype(W, /obj/item/wrench)) + new /obj/item/stack/sheet/metal(user.loc) + qdel(src) + else + . = ..() + +/obj/item/rack_parts/attack_self(mob/user) + if(building) + return + building = TRUE + to_chat(user, "You start constructing a rack...") + if(do_after(user, 50, target = user, progress=TRUE)) + if(!user.temporarilyRemoveItemFromInventory(src)) + return + var/obj/structure/rack/R = new /obj/structure/rack(user.loc) + user.visible_message("[user] assembles \a [R].\ + ", "You assemble \a [R].") + R.add_fingerprint(user) + qdel(src) + building = FALSE diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index c5518842..f6588b00 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -283,6 +283,8 @@ . += new /obj/effect/decal/cleanable/glass(location) if (reinf) . += new /obj/item/stack/rods(location, (fulltile ? 2 : 1)) + if (fulltile) + . += new /obj/item/shard(location) /obj/structure/window/proc/can_be_rotated(mob/user,rotation_type) if(anchored) @@ -411,6 +413,15 @@ glass_type = /obj/item/stack/sheet/plasmaglass rad_insulation = RAD_NO_INSULATION +/obj/structure/window/plasma/spawnDebris(location) + . = list() + . += new /obj/item/shard/plasma(location) + . += new /obj/effect/decal/cleanable/glass/plasma(location) + if (reinf) + . += new /obj/item/stack/rods(location, (fulltile ? 2 : 1)) + if (fulltile) + . += new /obj/item/shard/plasma(location) + /obj/structure/window/plasma/spawner/east dir = EAST diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 52822ed5be39f8acffe6ceacf9a850d7f2ffb7f8..b22f50623c1c3464007c1e440c1119c5ee064a58 100644 GIT binary patch delta 14289 zcmZv@1y~f(_cy+XfQW#Kg0zZ&B8{}LN{C8{bc=vUcgLWlgmkA!H%sTz9g<5oi*zit zu+ztuQS}9T_tOwPb$$2 z02G=oUEZfQLAh}F;XaM!e-Ii=Bybnd+SMukJLKf*Mbaf}d_r z*S(djd;5L(2|kZ>Ze%N9Zc8hxsxoimtfwn_y3>?3w?2(jap$Rl-Py&-3H@9=NE4h8j+L5N z;$823rzb7#7l>nbj;bVMu_V!~6yM)s?9m8OgH5z#T0SaJi}FGmE@4XmVG&nbZ5P`V z!-M6j{biA^yowXR#ysfyoxYb4u+ZE0O{IHv?i~V&P~2l^GeN zB|oT-ylU`4so>d`l_9o24b2B2hgP5rxUA0SXxYZ=x{wjBC{rt|s=E669sSl~R`+$3 z$bX24hgb7lv3$N0)5tN3iW9-N!i$~r)xK-JKLO5$Ur?}5E17o|J@)BelTh^kngA~# zjLS4>hUyDp*sBRN1X=6<+*)iOG-*|^ln7MH|HF_zFZ=>P_V_|;J+c9gQ zSr$t-|IckG&okZcOGG6a`KxT1O=Kg z%GBDF$h4Qpw3=vIo9cProi7^7Mw}&ZIAddD9?GfS|2G*>|H0&eX;A?{B3bwS_-(t6%@ zf(vlJ&9 zFEpe6Bu(e7?GyI=OPFOZ&=Ti;+kj}1%rd8x=H41P>DGObDq_A**CeiQIoLpd6t-aD z{TLtC`;c`MQHT&R#q3FJIh?i4>_a7vDYMo_2%tFeTpU^JDk9rsHQ?Xhg9~6T(i%d{ zo4>tc`T!bLqghCLZtl~-izur zu7|$;m^f7q$%M=1MK1lELvk_5ElbYX_CaXH1n>1K zH|FMHd~ZSVY~w)B#1ZCoFX&bM#7H9gLM5uJw{KBi4fe0ERUSYr9`4Z(bxnwdg09IB zaP^Mqj>^x^_r1i)CkZegiPd%Ik7qjm>Ke8=KVY*LZGjZr`^e1`p$*s8cO0q!hq;6%-W>)c8zo zZki2GOt4tGvIsuj04;j|LZPDx)~r8SSb24IwdRZH)fF88^`bio=p~$D2$ruAHTo?# z$@nuQCWV7RlXv=f3JNo-=pGz&GOF(m-@jF(4!Rlbxw*NgPoMtLeJ`<%EU2%i9T*t! zAhk#YZTb|^5^Ar(ep3H$iZ>H{e;aWJjV@IoU5=;t%HF>G7=s$B z-=wmBVbOHu8LL3{Yze|IE&F$-h;QhB7pwr};>b%s)B6s=Q3}JOGtZ9~lj7kB9w5W} z!gBa=G6@tr7^fL7`JX`*!JXW(pSIttaUz<@BKL;S+0Q`%@ zM4BC1Q6*4AS~F$+jZ67Hmd*DsT*l*=6_8wXiRd7~U5x17J-#pfe_|t)`Medv?vta) zK?B@njGgBL1?OOD$V=et*ZExs)jk2~27hHI$;43JCG&d*ampsY<y=>NWPA$TYp zu@JX8`O8qsJ#}zuALKM;^&s#A_Vdn+j2cDpV_?vmwh#m}lZ?seBL>hfKz!H!^s7H1 zDc$z5nd8%MZJ~bkkeej8;DERTgC7q^#lx`}$BRMdCcf=;wywkcdaEDvMtGH zW}djnb-sXHmR{Wn%Vc~{daxij_x9S_8pIom^%Br$Xu}+jxb9nqSu*-k9l(^k{vo2w z8R+FG)Sxexqh%9<9IB3)_Ct3H3a8DD_W( z7rrrRM^MzVYsYxzbQ(A*K-JVQ+7nq%{VeycZmu7Zg8eb@$tudyDobN+X>F9b*61x1 zq*w%)olup|dwL*B{PgM5tBwB+T7XPmAcbh5wpPMp54&gJsh2ugVapWc=DxH5*H`5E zQ_ZoBl5f>T7DTbs7WzLyJrhi%MLPArnUl@gSxx+F<6>jG2HBpgrvi=J zyV(4pPI+29NNsIxi=&O3g(e8y!a=W9wf(0HoWP&a(ci0whRC$@NfQyMyd|h!5aLzb=3D!uz?fKu(qLQaofvP@(NyEZBO96~zUg25@ zs(vY8b!`w*YS=|~bbPG&4Jr4N?`tKD9P_}XjNySrle&gl%H{DIic4l~x>7?Ncer?Z z%j@#CH`V@UF|d`;8nXO#p!-A+cwzBfkur9)QfHxkl$A&_p_^z>MTAZfn^DN1X+ET>Bn3ozz(E|b!h zR*LNJ9paA*DO1%fCC>TgjC$ZV-|TavZqD%kt%%pB-mCeDl|%o>)tBas7RPrU^44-#!&l#{#Qv!U=#) z8t?0Nug`ASSBr}?xKMWB?9}Af*Unq>HqY>|)%!&8wsE2 z#@(&8hP@nZP#VDvSziUFN303`6_2XQXtOlif}7CUCnC?mAiRsM3a5W7#!ZJx6{Utumgn zSoGz`;!%EJX-$$9%*)Te8zz39tD#nT%lO2H5-2S+OIQ(HYF%^!LD*ehaL$lxEypnH z)~t`KlPn+d4(P= zqqv{m1tJ7MXmS$3WN2&>EE5}|CazWoq9-jQ6BALGuES^SFb^PY$OEVw{J*b+BLNWV zSXvhC^WRj`)-G@;wTLFx|9v}*otgtQH&O};KQ%5VEf54{AP#xV$|?hz*&pCIlud6Q zdDgdU1J*fJBq+upbOCKJTAzj~rKGPF6Yv?k+4&h8*ZFpR3$#+d;^B2=@whCW5p*4U zKai_}g0s(4Jf?~a<&Bt`{GOf70(qsZOaX$Y3~{a=$3PJ$D?<{Ig=_QF@d36gody%6 zdn;d^MX#jltT#hx+NX3&XnO9areH&uEwIwLl=98>uLp@zwQRl`R6v_<$BOYp7=%1o zd%pdE%m2hVFbPmp*rjLQ&jAoTKv9SYAX5qzCmd^nsvZ*e<$OYGe9ckfj7EAA9x?Rp z^j3Id$RC~zF~#+%@c$r{{{WQ?UB&_-Q=(0lJbW83~kZ?*<-AZ!7O z)CIQNt}U$n#NGMwKS3QvtXMyk?=b8h8U^uP=W_34-0wVC=w51?M7xNUdNAjkultHM zk-b{SmtAz<I`GAfvkIsn}I*~K_4`?pBGT>ILkTOD$@(ZpKHz~E6`U0t~Qv1oiW zz7B5qe!Syc*W+n&X|{O4;@^r~qW3O_6t+eA$zFj{!yNW67>L zQ5RYNU@Zi*F*MS7J$VQYIyQzXt1s9)4UzCrbO1^MODZvo5Baf+n-PUpC5xY3iyT_e zE4dHE9^2&`^5O#P;-Qc$8Gw&AL<27(&;^TrEASdY1AOnzBJDD@icdvfU0b}icjiqE zaMzl(h7Vh{hQEWiC^WZACxT+74MZD%T>%5FVc6S=!)qojt>a^3f%KwIi}q_dWsRtz z5#XWZA-Omu6Ofq%zYI15JuAzaHBh2n_hNnM68et13I{BBvA@ACm|&N{9cw(`(7(Wb z6*Gd0(4%E2IDmw~^zq(k%+SM=`@}r7`~Sz+&wKqPfCOwS#ty;hV$2br(U?9-_|Bh2 zlsDB@gy&*c8yQ32r*fEO(N{ci3w*u8E?H{@`oovHCeY<^V1Fb@8GmM{O`zU%j^#Jr z75IJ31~M@fi0qo@?I)4bGwlOXr*s;uXcPGPrHRCM{TLvTjZpT}P3NSHA`V>+W?nupTzN>EE@@o(HoEEqqDTk??4~ zN|D2LY+A#uIUFdN9zYF7l1oX>5f>Ky4Bgj^8EC#zL=$X6IPNyr#1&Ef9Un1W!E+Dn z%kFu>p~#rK8#MN1W0ROJ9e`bxues52%g3Y|bnW%kR*kT73Q$#kFZTzT`Itbm`aS&4 zL8HA~to??-Sse7uyLHk#Nh30;Jt1)bn~C`E5Ysebelg%#`GNo_rps7HeU@#Uk2>EN zDfSj(Dxs?vx>|c8qZ_m`A7y$0FHFNHMU(d^8)KD#s$Jv|W zSTq`UDgiK@dtF1bVlW1=hSv3#4;tLM7cntKk}ODQ&76cjUlK8ThO$Q|Os*fW5uU|S zG_OEWJVK8j2eDNUE3STGn_BPEj2)rS$Txm<>F9%#|LYr+Pr*%S4gHOHZHP~%W2VFR z3lIO64*4!_qsQ0rVdY&nTHeQx4;d~XY{U3@MnD>)i6&Q)$6_SjF@h8;_{(R*=<26V ztLnGe#eJW=PPW`u1V($rp`E-TvuZ!ME$3=*eG%`rB<#xYSRZG^M~a0<4tqq2{(XtZ zS3_q=t|wnSM^FLph?eRsCOO58CFqC>`^2SFfH5eg2fAFZdwlzx`3&f<01Fs#dVRNN zen4d085#(q%iDYSOOmA!KkCubXF!CT;zSd>1A?2b8X+SE9@imp8=T(%^BBpbH-(Z! zllEnPfk}cY!laeGo|ykC%;ic=Yx6j0t3N?;F{O=hlaq<%-{VFZ+AOd7lddCDXHx`; zmt%=HHrQ(p)o< zP062cQR-gIrQ7nySx%PwKZkV(Z~rQB{#mGqH2+0)kCTkEZ$KT-cY;!j4`h#s9`t93 zx%b-$RSCe?GxPA$c#`5IqSwyot%=z3;w_;&)J3GC91e5E+i|FaVsgm!;%i^q6c7x) z6$Uweq~8$06#o^QgfTcEzmQ{a2aq{0u(;K{I}y8Q#v);1W9=AocDkZX9`FL!La! zqu$pq^8}~*vohVLY;wMGTy@KO#dzIJ42;#C4acI2`{%z%gk}T0 z1~Z8te&@+eR4N7 ztI8L9*%(^L;(~w`!>@dQ_(d0h_S@tcxsyl^k?I3IV*=dy5I5m}VGDF9w+ziqc*snc zKu>gbM4t6kn~dVT+H@zL#18|DRR%eZ8*JVrBe56bC0?p8QT=>8sIXH<>L&Fl<|Z7b zIh^OS7^iu|g%$fmk2XoNJLhy$}i%r=4!)H8TD=yVvxJs!+dTZh#a5|B^^K2y$qHU9ccjKa>r*$P~FkW(vcRjj^Ba1y+t#Sy?Kx5&H0 zNT%bRKb^q=H|e^Ra2}=Alw+HR;0Y%;(u4O@Q9Wt^;aEij;WB zd&{b6ws~iO>UQq1Rjbiw?0g>%oV$jV7pZOGxe9z-B^8w?80;@12We^PRN2UQcOwuB9Bn zyGfRRkaiDgUC*{f!Ar?BHx6k2-e2-=C}_;!fWqMvMh2Py7yz;hYwt}PZ7MH=9ohX=cTL--H{dMwkM z6ljsr_AWk_3(v+ApD=9Rq)*@C(i1Ujk*W6=i8q$N$CN@JbXT%QuAKr`7_#U&{i+W#ES0t|TZ zFsAVu2lfAI-KKG64r-S%NYh^!_4%#Dpw2U2mYVu#C_&V@IR2$8Ec)OhkL%%TZuzH( z%HC-f2#UM|)5d6m9UO_kO??Z?;t1~E3UQ-_fq7MSJ)q$M8jXIy_vP09bYrvm>F54< zp6;O`FhL(2k+UhcW`3HlS$vaaJn=d*?O~Kz%)^Qv6&}OA2}CowjOqXZ0l_;l&c0ck zaDYkS^Zn*rx|dF>WJv6g@HVC-MTs$PsqOTqFURR>Pn1#`;?JM-9TTRBNmj+wc0={G z#cxW&E@FsYpa>D=5e_C4$0`(i}~?3)z_pM1@5lF?Cd-(+0oIb zp;WO4{APcRxfwn7@lLj)`7wMVU3i~t*t1S4j3Wh zT7`0o(hAuoqGf)u0easRo+!5RE%tt)j0%s73lO$PUjG8c+eTMYm9FObts4&fPxJ*C!TGt^YBQ5ia9JE@L(Bd>jQ^M-kZ*^4+(KP+c%JMCwUAx zS?L|@g!3)Y+-p1)x5Ls2)wmc&`xOrVJ|G;8ICjw29PoBt4U6Od;*h*&69(Rk zK)qf}dBnZUYdYhLPWlF>7{kyqz|8Y%m!pXFgQnJ`{Q|uvcKr(|E%!vfd#78ZEve8Q zrOd7Ro5pm8f4DJT@GC=R3(_E$z)Jucb8;_io}%Z?l7_<|m{0kfygVh_bAowyMx57< z#$rD;pyN8O`alQ}-$yU5)F&loj@=fXk6{`>E4!|#svC^oS6?KFtR_YY;-liA3@Gx3 zu8NSg+e)um;i_K->a`ot=VZIy3>}!BfuEF4cnuhx+MStdZOHdM0y=cru~e132~Po|Er7@G;-s6soZKoPo#T`o*+qg8bWMyM6d2&ccpoVZEI@;)}SuklD)RUtEpT`xVcD zvboCTN5h^EU0BZh^1BSNyUPw(t3&j3+(8;#x1|1--K*7aS)2Is6y!$o{~cc89x808 zJ+a4A!X!$5#Az`cPzABuqSJMUjVLF45>N&?Q`L2t>NAoBM3?OoyjR+00U9bJl~a@B@;y zbG~jZe*u0~n)T`%qqZHe5nG23wNhwAn3raB_1p6ET_>V}eS7>va@!tv0uWnd?^Q~KW8){XZerS3y}V385$$?n`%uOrcIi;qqFejO0+9~51|a2@~X zFXU7lT2H|sFpqKXz2ui(AN$<6bQ(U)ima>k*IP1V%em5b4boF~U9!^U`JmlJ0pM|l z9BU;W*Bt+SOBZK_vvq&B3D{%W-Vt5prN3+IH>^ejhvs@RwN{8<2p1Wkp<-eS2bi?f zRC2nnAlyVhVwHUx|E{ug1%_b~cU~6=o&AzGaW(CO1mWt8+}s;0CG_Nwr)+GkRPdUy zN+MiT5KADJhrvO3;-wc95@-Y@mj3BnUv+22dnJoPCA83ptczDYC2Aha8m+?nphtvq zR>#KJuWLc}6SAsr3WWptLBYY&GBN=p)5#BfKDJ>R2ih@N0*jVJWSUv=Y!cA8T8xp| z4a@6znNE_WCLGU?BGpp1ewX`8)&80Qm%T6tT>d|AZol2}|3H4NxEsKk4)8zeC9U*d zWjt}oUe)JDA+Z8+0*lR`M#Y}S>=+B`JFPfNm^qrsu_Zpt9*p--vn=ZJ)cBD+j%(`1 zPB-W(TG3*xTjeLg#r4?&%m%2cE-lQ(z?OtUlNff8`S5H=g4Nx2&cs`{tda2H|$QI_6+8*KH9L`M{@BEseBPa{{rmUthqAMZjjv?E!NER2l7nD2hz#4>&_pqy$pg(&rQT1SE5pDj zvK4Ni=US$;)q+|3jLjQw#vH%p$N2?Q1@W6>U%vo$rkN*xZ!=s-N{7O(rudJ#wq#Su z2}Cj66v0{cWdQo*$Zh`X3r?gy~!Ulp>)*UOs>P9*d=Nlo`L@yO|f`T2!2RLYcsU zL%CF9$sd-N5rh`w`4_rnq%^dGqIy0laOIV(=Mfmo9wb*z>lnX))r6j8h6CO0`kjZf z8%Wj(7m-A6aIe(J{iRh-MB@e6=UAqeyupY7f1a9he1*Jn%B7R!NZ4;Kv`=huhgcHmtO1OPzLgc!pOMB(7Gy(2#dT!P(rV zNr@^2&*Y}FS;oz7Mpc=zRr(KN@^jy@)T0wsUOZYluAtplE!br|ai4{eCKtDH@WFq) zWdJ(M_MP zp45Tx)Du8kV?#~Yx!4%7?JGC5@Z}@6&O9)ys!FX;yLyoSxCs1jrz{!1aaGEQ6Ov0T z;`zTAEuYV?B-o!2dt~mVY|tA6(OWUXvc*~F2UDQkwyTebh-7Qkt51 z$c%Df0W;lD3e@^7KnQdRw=^k=?=eAn?s|49ERwsEv5BE}kNWvK)*b$JHGKZxl7U)xfDXd(xHuMe<>CuBR$GFOy$r74ADs4>&VO?{ybsHECif1 z93q2f1JGOQIy&q$w6wzrL{5El&H4HHpUKHwBQ?8OpvG2`;rX*?KhCdc0+)UU%_`Ty z9GEqV3Kbqz2305;R4CqRpLcPNykK3Ed%{(doX1o3Dl!*Xm0hPISrI{^s2+})VD#1_ zclRP99nTHZ%;n|JWenk3C7$S=kt|uCzM`U{`?7JI_fN7)c)RSc_V|4Kzy{wU8$cE< zFLFlc4Vor)hzo98IFINzivs=FiG-3LnGIy zK_%BL8dOX{Y2L~@>|F=o!rN+lTz!+1`B^?$Yoq^FW-~_x9HjIo{q}1%`S>{xdeKQk zITRSTpZTeQP^fvck(ykF0`)ku-Ub6F)(1V#1hlix?<8ektMGU$HiBTJkenngUX z(I4+L2OXTb$pl2&`t!{WG^;eci9_oj9{(guUwR_4Ib$%#0mQ>)nYGFbX!rm4>>*C; zPCHJ^_8-0!yYi;ctd&;3Fq`d9NQ2yVnKM;ZjxvN6lqIsO3U+_SE}^xZ zNdoDCI01f?bDETSY*WkooOKdvqW)|~kATQBPSA*UT$l_IkZ;Zfp}`%XvNl;W#!|0O zpVIwgG&4aiG61d2^5aBHpEZeVBp7WH8&O9R$Pz`?^sQM=1H_*P*eUxuS)ObE3g2L* z2Zvz&TY~REELh)66C0AW-`(V6lWjxRNBYyh4Kr?lokzxCenctVeG0tAFVm|zM`l=+ zgk{vrIpbYn81T?*CIn#=cs%_`{ZLEiW#9HIPnLdI(g(w*0*n7?@~GYI(LTGk+FXp( z`pNmf#({x%A8Yx7`TWm2lV!!px{mqc!;gKFO0Ld(!aEUn--U#$_}P<5dY088I99&B!Hb(ohlX74O2oSyZ#>{KG8JUtsL zwB)s%d*z6p$cKabuuQPt>Up9Iwa%4J*to_D?d|xJp|;C9b1=J-5Ot;e@i} zGnjj3ud1$I?{RrW`)$$&{cb}Cl|6;r$Xh~9^`iEu*uzV~FRxW~|#cn`E2HbCa zo^Uiv8frnbkW{CHTvbL?2+SRS{k^i7UQ?qn$*2%Up9dODQ~E0_2VPvbb+&@pxt}}< za8WQZQ(`Dry}EaAF7zuqTaqQGNAhn%kQseQMqsh^!2P_MF1VDvynqYE!$hO9LnK!yp^A=A)?WC3UsY<$~+9k#BN z*g2IpasP^kR}?c~CTQ+VKkTy#ykhTjhV$3^u-&CpCi8wN(l{T_XLTUqZq#+feXWkE z;Wk@6;YJT!sg6LiG(0?Puu+VEgYL$ampRayDAG2m-Fes#Jo^{qLYCB%fhKJ+8{?=| zYnSD?+I^>#_%xOFrd8`yIn#c?ZuNcvDXGxpu>jWNb4kUTdcQuixUS}Ph>N{Gk;0MZ z6U(Xml)o1@tarB{5RW?84c?^vB&)i26B)d%GuH5(o-*Bzp7KE}k+vOw{D=SX%J`^L zCsF{kJ^U{GK=q8FRM>jda5RPD5zC|lxRFOH7DH8ETA|4PzmJp#3KIi~L>^*Z9oe9!D zhxs#hRW@@gmvieP#rtwGBISwsSF-~Or#e2yY4QLuU$Fz_)a7aXIHabmnwnKA9^9s= z?i4S~k8hE4v9f%`>gD3FCIt!+h87LD>iC=oa1OMB**alMW;&5-1ua1x#2B&Gz;74Dc-i3UI<%QocV{ zxsT}I4S2hw$#*(_P!#p{zE{%G*$zqwd%HDJRDK1+jg7Nvglsb+&q1+MFVndy`~?A7 z5|E)*tV3P3V@@f)s6hep4uL=fC;E{uDpG}I@_Vh?$vrZhqqrkNv8%#l1wYXy5^UJf zc$shRuyyN<6>1AKAMglTOr~G%rPG?dm6?u9S65T3^U8@f(0kpY4?2GxPhuT#2cY`# zw1QUMhRn>&N{mBKu53kF*&R<$&pO#31tlfqp`oGgzdQ#S83wdt z=KRooT^Rg^L_j3jq6u8dj$`$bcEAxsgc*p+e39-%v1^_Bq(E-XsK`BoCKapQhqd|K z0MZn%rtzKj=GZ`|04OtCp)61qxrS@yU#M0-sbdf`A_sK`Qk_>S^97uv?+^9GP!@Pa z9T@X@o@DJ^5+I=3O6p<^7-xa6uykGF7GToc++12;pAmdPh3{PM3?V9F(?#$6356Ue zp2M?D611+`tyv-SX#6d?Y4v zRO}8@(F^h_-P$RAGnpErHg%T9C`4s(W-`F}rUCJN>!=+7O(Dqt7PletsLDZJ1DMj&6i!aHwFg3%)bz+G|J?@GeN74_x?*O!*BL4 z-0Ig~=(`RIqv<#TL842Vo`2w2q{!wlk#9!nVpDq!@@3HL`B_ab!iT6+huJ%gh|zq( zSp%4I*)YSbsr4s|5deS5EYeOq1LzZCSl_FTl;GjqWQYn!S^qRO;A`;cohO_~wbwN$ zj598zsjKzsW!mMNkqs==X>$W{U>u4@A;Z(05#`LYi#z1T$!=prH)q760GNYdL0uOs ze|&})GlfU zL5bQURwR=D@xH(Dy?)pKTvt3fl5?KVeV^yK@6SEb5_u{<{M7p!R3&A+A8FZB=38(6(ANB+rJ8&I5dY@q%el;Ac^>f!@Llmt*$G922T>L5`A|j(5O_}K+ zMaDlqZwBxiByCVfaOV{jUD&6Ll^|Uf2J#A>M4#W%%ufWrJH^Wx!{b9*igt?O%W|r1 zu6udj=<(z0)`*^ITce6Q^r1llIU23bbp5~{1EdS+5FlaudcnXDbAop*MVH|S?! z8p9of{n(i>{Vs=2hH{5R@}^TS7L#%!qKm0n!=>PfPGDauTisAj`+Z~Iat68pK3h#9 z1wcgkLf*b*j6WGk6_##=%1U(7aSQ1gw^|6E(`(T@P;E^LWh zc=x^AiE7j{QY!6K#yCN9JWuP}V>;ZXy<)V0D1d-E=)WQmQy+a{?8Od*TrsdD2l4&> zMvXrZ|McL(hdxB!$t~`Yiql=JE(X-7W)XI{{u9-|Q))dRGw3t}W6Xl10*B75-_brQ zDxv%$fCxS0%$YN;OZZFwpKA=sYSSS_hd^Ol4f@#0W+wTOl>e6Z##H31S5#+MSOnHJ zjQ=nuCMRDt^}p4Nkiv2?Cf%@O0qm0Ch`*8|7l||2xtE;O@&d$Pqetz%M)6+HaZhO-hOw`WK zOAzG4O{K(^miyqu+|tt0rJP+)-}B>2V0ax)ybcR~ES8WPLx6`9Ry#?0ouqgh6Y|YQ z=G3e3IjlK)<9+WwBNJ0xd^~i>Ys;ptuI}&py1`3=8enC09b&oEpZVZB{m1nU>@geU zJ@}>ZQ@NtRu?G(Ad@P%{PG|2_(??Q$8VkkiG`a*6;KMbbxNf~j3oHb$^VP*T1(;6( zNFTC-8}|5KjJ2e3S2The+TGimYgirQ^kdZdXWStKyb{;V_flwZfgC=^>?^f9^#Ix0 zw+tre+_q|9F0#ARd#fyadwViLxER7}jvT<0^!wHtX{-oIf0`m#TxyU|?XHpgJ=i(9x8|xlndOLz}?~cEAaa1F(FjujYDm12z35t#eY^ z%Lxd`S{REy~vVOFs(MX=oG3!0HU~0_5XZD1{8ak;72SPOH=OVt+wV z70c)5kfCo)?$QV+y zQ>9qJrw2~mEy=;a+3WPPEYW%oncwb&hpjViU_vg4QeCI^l&wXDj9F5UPsy+18H4cz zngllYwR+D!7t&{!FuM!mmq$mRE{IMAcTN2h)%v?>RXY zy?3JtZf$LSANgKBuM`DxH z6DC;C9PfAvP-bbGXS+hv#|iXfCZ{NOax}Y3QJw|Klk@pqs)X8?wQxFugYA2e~rP07p8#s%Ki@Uyf3PM9e^YiD=)0!b`UCB^s z_K4pHK)GFySsj$+%$aL&I6T|X`0|a{gw?qu(mLXOIlcy9z@P&%dl9uRHA^rvL3}b+ z8Xx~fml1)S@3pe%@W}TlRcO1~{=J~H(xGihee@D}C?+MwY>!0RwnfRYO zYP`{3aH%Qcq0Fwo{4%?plzE>!g$>Qsi&Vg&?%+!3@yW3SxNznUJe~?^1F)9P`|5%^ zETy1>j*n`aRM|n_QrS1?<96%Bae%|W9xCGd(rX`7Ex1t=JsKP$HRRbc%#fZMDhQCV)zG#dK*H@MMPczSw%ZfrC+@#oV~ z)@>mjr=X27{iKl;8TYS0`}@86?(}BJ=yAvcer)^U-3;Z^?C`mb_n~4SiXkJzq+0aT z!qo~i`1fab_e)zd+X#QUse=DResw(4wyZCnnLE8^nyOOVf4jn||*tkQ) zs&Wnp-(zd{Rq6rsFHjj)zS*j)nd0^%9%XX{K=B8%IGu&D!NIvnlu#mE)lfmglw)K0 z(zZ;vzihTn>koL`en@Rq)dk3}$;m5j!>j%|^&(-hH&mw?QWc7>G{g#+9aEFAbC7w ztkNFu-~34_l|qKxHHPP)`W{D}uFH^RvZH2JWUGpJ5Bxwu$$?$_oKvdVOUq`=NW!ld zZa;vG)0j(A3gvur0y|5LwJiby0wKpOi8`BBWIu*`PgsfqLMtFW3a7^!cX&C>sAx$A z!S#F!Eh%Ui-kS?QhC(}IDdYoHl9?US!gF;m4sP5MtD3>a$M3T@LB1QnZCt)RX@#{x zsCF>A?)4me`fCE1s*F7d>R$yod<~u?0=_EjZ<9wiT43I5T>Jj;THH$VX8dHy8cDT> z|82$z3GD9ap*k@s83Dd$@M9WFEj80MfoCm#_GoiXka_CU(9yL3bz*O0NmVKjPZkefGf1rR%T^o zDdg_V>5r=$SJ>o_`RX@{sha9;@3?b0D;hE$qwe~OJ^Im${ryRBZFSo$si->(nwpX+ zADrl^Vm)Hxuh`*_b6NQ%87NfG<=omk6hCyN9|!a@)aE7cuxM#3%WA8yb&d6B%AL?e zkXhse-gGp({x6FG1hd6}OnR)0j3Vi8G0aNKx%dg%nUj%tG>d64(z*Rh`r`hAk}9^B zau>IG3%8jo4%8fy574p1jRuhge0{yFU0|LAhHc*#zeqW1qptrovWWWN)j}z+LAgx4 zo|u5q0OY8tAXeCeReazQ>={J;<^GqQMWU#HJz|Es6sUGno$W~k;%PJ=He$u?`;|$+ z$KouOyTn$w$v&D)4svuyh$@uWjBh_LtdGy(rhJ2LO-`Cn9b!jwzklZdpG)5Fjc@|JQ>hUG7g{$kF{m~x)R^pXZ_$i2u;uLe4!=FBA|-86J(9NaE# zNkXPu?K|=6eA%AqQlD6SE;hd+7On=-LR|K=loo%Xt4FNIcpy8FfMbHH?kb+m%d}`f z$zvDzFpS(@KKo3INg^YkeuVm0nEOUzl@|lo*V=IOy=m zQ(OQCQ$Kj3T=0q@r*tyjU+Vjt;e`!6pi_8QB#5^MxJfVVA)qu&M?|6!WkEAWZ`{dl zop^c63@R!?uy8PD-XBZuZ9JP;U}V!Z#YBS@-`%5uWVO3%{hU0g$cCf(6sMX@)~FR; z&}TWe;$1X3_c_c9uw@QDdQO}Hxg|9nd`s%US!IVznzt^U0TjE6^(X~g8X^XHXb8Q@KJXiBK38!=gTD3r9cE06W{Z+s3kPXZs)gdjGz6w~cc z%c6i{jn+t-jX3+vteh4+F=ig46#4J+UnB=Yg%eweQrAJ!`SLFCt>=GfXByt9rQW`#T|=ia>LkR4 zzf3MJ7Iys85j_Q$SARgh?b4bQ7k4fNa;w<aC$~~@b}k0V+C`8Rt=C^W;UTv6 z_EA$)W^O>=6Yx9Pu^NTzfR}?=3dOY-X^!lr1i(Qpxq-}SzS#HF)=lb8!i`|$Df}HiwIl-dDmEa zGssm=C`(}hwsS6v<%G>_@6p**(p!z4Fr13wAXsWDkm}=Kdd1v@d%pIDBS^>E=dxnX zq1#{AG{XFq>a z2_ao2XXp<=CY)#w&Mo`O4ulm3Jgcs?(hhMta}{Qc$S4b%wWZt>qr`!fcYw6F2mn7a z#ER^H{5uOU&JHG4bl#ADsB|m0dp%ec9Kvf3AXXTCwkGI__^mK?DGRwZ|Fxx`cW53R z?*#JKk75l6tKv}jBbcg!V0QQS&rIzajt8@`a$cr$NT%YtqeWu&zCXxpyvt`hdB~4$ zL=a-%fdb%4q$!Avai>P0(u);$!Tj$b%nAhb4~$RPAEaR(it8ML_1-gbxe{dyV|L%>TnTKK)<5p_oEQ zm-Wy>Miqyrivkt9*_8?dXL^>?hzGj&I$@MnGLL zb3eidj{>j+`YXX7GLF9m5ER~ZPsG+h3Y~zdbB8Y%u?rCBJT~Q7e})WnoARpOPj+jK z3B^yaipoKwv6EA*?*>*cd3C@Ir@P95aSL*Z&aID3=H_HrmoTI!NeGI-meW;KAWo4< z?9T(K`4SX^D1GLrC)%(8s>mf5moeQQ!0+~i zLMrgYycY&JNvUC^DMTDOtC>7`WnroU=E5%RLC8s95C9ybjfRwUB}gUp}; zbd0~9CfRfIOVNu6Qc?WPa0s52?;oG>DeemTYYd@Z(@FYYNB;)B-uw$6yp;C7YSW&_ zi>vRK?PBPNHT#y897qka0GpN4rDa*-xdI?;37fJ4t6{~gtF1DL@mU(-29ysMSs;4cfXLq7omjStn9PU|o)@bK{RuMETi<@DWZ3cYd{w~J?(fgobsW>|z!8B-zrE=@~!28)agzSiAC^L=-dwM-fZLj?hq%AYI zLY`ez@@`Hi1y?sr^S;=jp=KsehATKHyOrkt5spwweS7a~86Nm*d;?Hzo1Gfw2dsR^ zQxs?%9}%5d*U0IHgZVfE6=#{%c76R1H-ja9BD)8I!*_H#v6Pz>W=nFICAk;Dyu-?# zLHYLhiz1mB4Q;yhCuhWn8erd3kJOKrGje!A z{sZ(U<}c62gh{@tFzr*6m>Mj7FfkDcZWbfArz%yS#DjGWn_dTkrrT|G&xTqK`S@{M z?Vewii#jZbPu!5)l|gv-D>snu_bw@?FbLzZ0E;04FP2Lwtmb{cM0drfEbY03C?A(5 zVa#g#{{Hprl=2`Ji3P+hokW6aEj2eMu#@a};T`=B`|}iZWx?#-_uzWszdU_s83N(D zs-}Ej-vdTb@sq267~8d>XMo9XGp*Qn{Cm?^MMdTF$B&S!($4y6HsCW<5=>Xmg5^Xv ziwIsW2$vnle9RBZ-GO`SW&+tX-{SUHKQ2*DD;>OfxPNf(u;uM@G)=}g>?aZcuay77vdhES#AqZl^JbHm=Q?HTY=_~}y#h+6#;Q2Ss4T{_BHi~eGtF zwz~|mOO^tIOP$X&mKko141FYreWG-DDyobyTzbQk3$Ij1Ok z@hq5o4()qVw#v#2^7~Z!-|2OMNCm_LQ<1cQ*$=1oq|Y2n7r$9nM!~)a*>nnJIBP;l_L+AJ#qj*Pe zs&$v!ym4ii)?;$4ls=&)yZ<`_ru4l{|Z# zH#{DOJ6(%+qq_;{Zk8Rfhi+VXFu#8UmRKSpAhXodbZ5al6?phk!Dp4(l3}BbYbyp% zNA^-nyPXxIPo}WwV7POx-DBl!sthPZDY zn2$+rUzd5z4@$u=Oq?XEcr)<4{H!32q?^S}MgS2J`nAszCf0jwb&D*dO}wd;7lP79 zi-*h=^>b>~UYIm6#xr(&YBV)RI3w)<;%s>BspP-HZ$O~@zJkhsU$^Qd<>Z~WtEJXf zJ~vSU7jD|+EvTeHPXVKDn&(yhz@mg*5Y+7VQgzom_V=!?W!Df72 z8ThFxhDC;PUWav6@+b*l&e0e(NB(@aKJM^|$Y+Pni1h*>&A^3wa@Fg?_7`MGw;2S-bB6KC#3q`4&NnKP7b8!gJU%Ynup5ji8XeqV4J#6Bcy(OA zG&^bAcyZD~#ii4*r^tvZBwb&WB?qWg8;3Lc7o2NGRgxFMF5ofu#`1>G_psfqml;cb=oEej9l!D!R4K>3nvYavKZyl6vM7hQ#tbCrIe z)658Dt7KK`ovy(TR`MJQD5{Uur(L3f#EE?vQNSN)ld;DB>>K$$cem;=eAv0YiCB4a zEPqa*zvS`e=!}Eb>&wt7!0Sa-Kay^%tkMg;9qkeUM+JyEkipd6kJu!;2-U319HXk0 zopyWPOOm11z$#?pJD<)P#Y3vv34_Z&{+OSyu1Ul*j7yStoKU>}n*Y?xX8KSiR0pfm zFO%=cA2NI$yZh(u_IQn3YORFLnU^laI>D8=`I|kAK%eJwHIV1JyW`%V^IZ+U;0 zb1B#Gj?IXx&ARl}R#*+(vZT>>HWN`uF@Ez_R+{u_)d*7hx8rk3m$NCKfu|U-xk!0( z95w$tPiGDkX{8&v*0MKIfKG3aHbxZs8{66iz6-zNqLb&`5ZDZaZy#WZyi@f@PU%La zkIcNR9*pD!TFmztV7js_4Nv9Q?hO*W;D$+!7VdMq~9GF0)P1J#FD{ zU`hr~ag&>%3V+EjGnZJ6m8`b$UPcZ1z5M9mm-Vc~PkOiIhEenzk>}oiJL}5KZY9C1 zSpjvgFmPlr`hov>J}^IOL1vYlajqjswhgYtOD=;+!DU1qQ3g^Qw8MPpXr}9y3t6xL z7`7JTbxiQMK4@rYXzS9|pnFD7p75_NsV$54W{$DFZGHS@YhsWrEtB~^^(G6gd{cl~ z5+!nsjqx&l#w#zlHUvUCeb2}!d1Ped!p@1PpH{EkHNi?xd&EBpn#&E2gl-)Hs2`c< zJ3>zQ_~tapDcLqa{ek$9dD`t$Fo31IVNy_+I2S)Tg$Z(AzI(lFbw{68Fy-Hu9LR2mC8r%HhvKgHdHeNdxJ~3OLreVK?Z;KviJ-5ipmK+^(|{ z6mu&w`6JD}pdbY>ozm8cAU~O=dUPY+-ThUQP5+)j0}5} zO3ArwlThg>kO{vr-(hE_4-SL%)Ed-7RmK|OWh&{OR}3-o*~0)c&dQm+Vs(t!?R_t z(Wbc1Q2lA|*sczxWZN$*=mE=Bz&ZM`_6)4an?HN{PiL%ZfQ7qzMKvn=Ss)A%#KCI* zA-bW{_K(^scK~oWbNzXs80Aqfu+V82nScj3PbxqwfQNJY&Rb9o^z~f;i}QXicYa}_ zIOV)7dsF6;TLQLP=*P=!=>2#y^0I&523|INnT9=d8MdI4Uepap&rkC#3Z`n7Zc{y6 zgQFlQh!!NoAdKSKH(?dqBT6Y3e01rzb7Qtw=FWIH0Ea+IqTIL4z374_up&9;IG0l* z3#imYIu5xm63?SVgvfpP2l&PXS3AKd1~4(&o+0B-DnLQJNUIg&Zrc@*V7EUVR$xHY zy;4cM-4X*NA_egWUSx}>lM7cxD{#tz>oLnQdy)l}9^*Fko537KVGpam^58btNq9D$ zL*UJAfU(BqkJu-?^PgeItg?M4Gu&kQg6<1&OQXq0tCPS)fY|=a7n7AYx30{}pfAyp zs38i?^soR3$a@Eq3sQsoQpMHP8U%U?p(K-3bPe9SVc;`II8*)L3@5QJfotZOOQ${O zS`V8`Wep8`HbwoyNyt;M+{0$kg#c1k#=fGsNVemqrFCE2N%k9zRuM=`>d!WTwv%kc^9+qy*ggKdIN+PM%dUDu&&oYy zdX}mbX5=MBUS~-DvekGHcg#*{XwFwQ# zo(rl*z;exbFl}CS5^ik$5g^7-RI7K!!c;-C34FM1Mcx22KfCY>r$l|6&WygSyiUr_ z%nV3sXdz}^%k4f+_PGU)QY%hBJuqA0#mMF2>ldL85{V2pj$lhj#`;W186A^n^8L49 zG12&huNM^byxpx^A!}M%_ibB~%Tk}Xe@_8k@QrG2*y%jevO@9uP#1 zvOUcEhR}if5{RRkn2iO0jKzyfC^^Z6vMi?K5^ou|EuHS8^@$~-0A#9ucc!FiiWDLU zlug&~S`1c*xbhu2<`Zqm8}lAy=bfA*_H7s%`K95^%X^2fa#m=xpsco9g)$akKM2$@ zh8-W<*Ot~5_}VC5Yp7{6*g#eu&>4?+ttk%al&6aIAZ*W!0U|YNcN|hc{oWb$zg8IY zYw6oxqBNQu`u1s#?4bWW<4iDhN=Tn&s+oGz_x;>ekR?AJ(yULAJFmw#r>xxJUr1K@ zBAf`a?$5si+{D`UpueX>k)FhIGX&LqRJ>kE1?WKeGqd2f7Oh25@1&gagheh22;X0F z1lQ6DtGolt6mJMj)h!y?P26;CDPe$fb9dDqX@R6W;k$=1A*ru2eK7tyzY3sYw=CQ| zVtD%84ngl?XOGe-&yQEC~qFUk&GohpU@BzV)d&VK19xvieJ0!S- z^CU;QhOgW!yf+c^OVyi+Grn}z$&Gm9mr#{@H)8EE4i@!qt$O(yKy49*kH44+HB^aT z8d~=K9Ehb_s=hf?T?-hy7NzYN$@qH7QnsAx=o>OuWN&`@Q|!{3@32#NlhV9&Y5}&J znnhB}0$XNo2MzgruUzKE{k`9dig*~!rgK4O>0ZbFjW+~;Ie`1K2d_6BFa;2{V^RjbEG*aOU*nof zK92Wrgp3snu$Tw+9wV>Q>?B)*H<^Eprk0*^rGZ!yV-TOee>Yp3svAzkuv`;WBkUxz zQ$zT)IYh{QR3A*_%}Onsz;aFt$h}-if8B&I^1xhx+mDQ^j{ey4!=f?R_K>x6p!dvD^x?gT2;q9YGI9~ixRo) z8?!`d+r4Xv-H`c&g1MH5)TZh?-V*LXthsx~JU>j~HC+XTZ(qVqft?zP@6gtFAsE09#T%HJ-IA4)OB}^1!xA{a9xFbah$r>T$yRuq$9?FY zx(?S>+EPAy@1-=Ye|Pz7k>?|I^0JN*$yXhmu-?sn)_z&1vrbcYO`l!i0;3`V;!|Ci zPu-`{k0d27on#W;-a`7<#t_3DQHf=)54}DU@gn~7-kJ`c4w@kJul*@uNN0!E%qKBx ziInPQvdLa`r^Tfsm#O&DE>u6m3reH`GH5P2Jx$cJL!!B*YXH=R3RrTh&*w6MKn^Sq zqQ)Vs?orNXRRdRa8TtWi)?uBw4_VNNjJ-EqgsGk&I=2#x3=ND6438Usr2?*}Fw&&Q zzT~`b`T5ikJNmiy_V&;D`HY#FnF47#sWDwvZfAV!~ue zBm)7wm|uRnt=aS%KDVveY*<*^bHV1ZO(%;pxKY!rK{0LeHDGKsg*y%#uuHZR+ZM8eOt?G55o){@Zl9B zsN0?|wpo-p&sl(V9^dfc{eTvVBk7fhN;(7Iu5-z{$-B@U|&u+@d3cd{>aGQ6f z7h$d0Z&dyl@b7FBEvumvK0U{+?vl4@w&ieSJR`iVF>{|bp#5#b0}@xwyH~@WwRVfr zTwM#Shn*5xB)tM{mYUzU&r5Sa8a|z>(QL}Vg_U_LF@x4u@{G+;%jcVb<`uno2gy)1 z8wcH@6A|L`MueaPPrxdA!cf8a$&Oirt+*_ERQRHvz2=X&-u=1LM^8T)ft*`VZ}q?DA2bK2Q# zxszT-#Hn~gM@>)(Y5D~>{}cFjyk1riG|`mTua)u4z|fFUx@7+X zJ9|`jx4N72yt19kn}nZ#mcclN;?au|1ZF{(@Yq(f_Q^Z)?`OL(nJ{m!H6uUV^m3y8 z+rDLzLA6W%3WfS~~|FYmYh0ZM^hprN5*y_X_4^n{BwsEQHX!K{Tc zTMM{~tw*DI@Aw}T?sT!&vEs){YHOcVR#tvQqmkY>Z|@x(e96gC>B_f#3OvP?cB-qZ zb1P(NpLBYFq|;5$jlmi;>NfqmU>*YsZl{o5H__#CZLn})SJOpm%ml>FH)?ohZ|dNj z$Lh0Rx{IbxiCOd_SttHfopRmF$(?%}71e&_oqs6lYBt~i_|rYMm?7&#mM4%c^0K%t>jSMz^x#Zd&-8e4CD;>DR^B~V(>b-a z33zV?aqMx5TQA~&k}cjfdK8Xc`HFpVVw1jBoeCzbeii`Y4GH=qCXXHkZ)`Y6cy~t4 z&s&$t=AN6Lp62K0e>8*?)7MG>^9#}{+*S4D^BzPXc%xiHWYk<;QJ*u!pZTQyR;TOE ziriDq32c-tpVj`tDma%79}?nPdi>tAJ)|dbhT(2fAn><(M$YT}u*QNk} zL_p9^a`BRZBv4QR9qqFD`(g!>6w_HFE0?${{vpo!)Yo~*`d-R+7f&zhzRtmk-&Cto zEda?}U?$C6o{ClBFvuy_9~l5+W^L8`ankLgC!jz+PC;t&!lpq@hdCqh*x6`ihE*47VID+ZUmhnRib$Q|gCD zM-4lJ48LfV>rY>cB81~yrunW_0~s&}+@`|z=&itJba-Pr*u^ZuiMm|0E04?eEoB~PxK zO)HE@7~bnN@@B3+I`Zp0@+vR!0ZXYR4LZ0IR?u126L-6BaLn>f$ezg5DimM;wob6E z18@pgRNx9cqPy;|OZq!3LOaPynH=&5ZZ)Enl~)lycRhZqEZoVZ9ICA9bi%AS>6M-3 zPTP=|u}cqAfTIJM^EebaFs7}Cu-d9ti=Pr@0M)8Eh0ipY&)O_J-vYIrfX<&xbaKm+ zX|^qY{5glILh%#~_(UiCcmpuU(rZ8X+yD024X{z(`)#@fy%A_Xu3Wv!S&{=9<(HWI zDIhyODF7n9IU)G57A?Z+0Dp!x6ChKqXF}XxZK9fu zmd|`O7MMQ!gre$WqXUP`RwRagXUiN)kGId9_6Wl;)8BLc_KE=bH=F_^>nq?2a@=wt zJGUgd+Ao_KGdJx{Suh~|He+ch-D_|kPx(p4+G8`gQHxD972BDEb94lL++ws)_L5XP)W z*R1oL413Li>qE;d^G+pq?dq-za`S%oGMtR2zbor#O+EsDg&_)NIgp@(W|@N`;P8?b z!8t80Ek%y2@jL!6dmK8|v`5x<)qS=c(d%RW^k}l_Q$#aiOt;frNj%rE< zd*fq`4l%Am=|GK5ysJO&_q;r{Tj_u_Ibh?F`f+%T4dZ1DSL|$}Yc8M9z9ZVx^#>-V z-5M-5R40hsFDWeCZDS4a3?d^n)YZ)b8O-eMa}9KLU!V9l*%3J2n-y0AR#E}bm(kXds@6L95b`Ve2}j7LfV#b24V^#3Uy55%1IvMwb>*Mq`yfNz0@Y|BOQ^uc z`kUNmc-kl2Q8>|FyF285c)%VMiY;~uJD!;mqeYe7?11=qpLlzav9%c5pavWKqvSnILR#RcUHC3yXck649R(BQ< zA~%iq!=cAog8VI&ug{xh0!8HtlNP?+evKnQI0ICq6%=3`du(Wi{Zjam_6U4?@kFeU zNcOosLllqaIbNO(1|K`SoJ*H3HGfu#q6WsnA3CUjpiZ4SHFTtT2)Z3Ne4n(Xr7@Js) z{9^$T6)cG2r}DT(qM^(-Le7UzbPgriaH-6Ksd)H{4*D91isiSz*Vem@4-pR}WaHrM zY-}GJ8m`VyZ(HM9BcEgrN2FrjK7RCQHf@B;VDp^Aka3Vfl^7rns;z_?FHM6VI}m%d z*pqB}vW~}S9~l6Y`fB)PSx1AaN!j1Ukl@q`?3ug8JA1Qa1*6lmMz1<$_c`=Ok@+S; z6%69`IxTYY-k}RAf21vkEJHH0uHm#>9i&o^N34*tjC*Z?JQC`j}T-iYVe&)Y;vjB7l zg~Pe3E#yam6aE-M9b-;^mR7PWK4di8B=Wo=xKlEH%_#3qae)0LH?Tq3Xg@}QS%c~G3QBCt vY_U#`j)DUczO?`QV;}^WD-gXDhamy8;%3EbRUN+};Gw3Xtz4{V`TG9>p=^kQWc03cOUReTBn5bzdQ zASMK_8}d!M;7@mefw7mOttZUG!OhFT)dc|ja^8-3v^LT!|vqoZmmcbOW|@VcfH$N1-S z*W(jFC>Q|fmedsG4g7L8XG5K+v6)1Fx6vqqk_wz2W47*hdNYPZ;o*SnX9QKv+F_*b zO$vxdyzHF$tVywz200$r)fs4T3G2|weTG6$jnSM`6fK-s3widko0rX?y>lgt&S}lk z?0XU#tuEvYS)!9Yijp4mlWvi0`H(p~bskbg9O&yacjSK*oO=W}v9k<&`){M1Cg2d{M;e#d)tVf7@C2q=L%tJVabG4VPCFm?Ab1%7*f;HtOr&EK9!d% z=G|@JT-d{1tu04t7?R3U)aH)K*Ypk$EaY{M2JyCgQiSZR(~e9}$FvwB4JXQ!VOBwf-q{jQ_KN7{&962Mj#n6mELh{I zHac1b|FvxY88ztJoGKmo;psj$CMKq!5)bbY#Khl-izRqpuiT`b(9y7>%ab zuS#S-Wz%@x&p69sR%~_WqtQ`*`%V=%tcK5QW28tid>5YroZ|+JjBe;`omsrDd3VCE6cy+%(N+Elh$Y*-bu|K5b1SK%9qA z$bBaa2wr+lAqPI_^x8m+(1oS0Qv9a5XHiWS+0@{v6<4|-nI3!TYQv>?y}bjqh;VO6 zA>iKGKgTx@_SM;@7l@RpJRY5-&|TbXRrB zYFM&$YQt`0KZ=YwwYjJg5Y)N>>D@_4_E)&kIVowb?s3M1R(XA$NYCl4}Ya+V3}%9-c18Q*kG+ zoPX$9dsO9qNY0&U_t`JAmuXaeD^+^kBj@#N3EXBrNlm0&QFhT zhRSW!U>bEOOHdQQjIhK%3Y~FXZJpgVH@I)P_9X_o+;qN|`*oX4lxzDy2hSXgv+@o8 zqS3Wa#l=ditDDQ}tZ}7vTHTk_=#3Y~;_z)R-sr7`z7WBJJ^1})RIZCvFJiX{>Bzs& zxsaLIW%hfOfPN@m@Z6(wlWeP4gS@S>G?f5I48FZpQ}>dwQL>4aD3x|yQ~wL+f|Z2f z>qLMYcUGcQvS4T)LuYENV5)rY-Q6<=nj!l=`BqjX?PEnfEu-j3mt$0RjDE{BW zhH=TI@xwe$RJrdq65Bx@)>_QQ^I*o^=IkgHeKB1yjIL-$<*xx&c&xP2r@!R=v9cjT z|4654~n1iNt@Eb2tiHe{LqO;%P`4R!^~QQFv% z(5=2fEA_q)G6V(;DkZcp##clFrDe z_Yv_|x{AKNc=;P2JzQ%^jWB?H_$Xu&^ZUJ+B$Gqp$&8u*#@aXu)({F!mZmT`Js%yz z#P-J03f|-4@w3c)gwIXR+;-q~8K-Y6_HgpOd7$qtU~u-L9y6%b;k`lRFSccIp1%HY zxu10Z@bLcn#zv5(D-2o9&_bilt$OX)$%hI2NEf)h{2|eN*RVOQ`xKIA#z41XHFf9o!^<~`@XN?D_QvvUioU0_6r60N!CFfEV7OxHWs z*4EUpe2@t~@twQT-cr4olBsZXhC3%=q;9?VY>Sh8L2e_6Jf23n%(de778e&SnPfwP zc=Wt;5ysYus8s@qRe~1}6X@HP*86vr=aIviRSgKmxIXq#O$RBv)~-mh>y30qgwYId zQ8uak(Vb-DAsv1=4=aS3);sMPckq;6mZ@`!I25r%p;Rn(4}NxOBM|C{5Jh{U2GU}w zyRZJDMN@B&zQkhagh_OtSy2)vIxD2EWDxvYwf=7tJQf!7t2`EcbYhK!97ZIpmoB@; z56H+Qdl@Ys*O3;#LRBX)O=lj=bA8_{?W8l6+9`h7qMJp$*@>F}a-O3ex6`}JP%B#7 z66{AJm!N->aabh5+v;5S+>*p!YW%e+?)8#ki;aZ)Q=}tt4AANJl|s{2K@XX>O%1aX zy(qs7Nt`Fo5l=#^KVD$zxPxT;bzSUOfv9EfK5A)Go4^c`fxgPyJjVdG)j$ zUGF&QtRr&}TsriFMr-VMzU!cGy{9OFQrdlUzN`5Wksm3RN97LFubuk|-l2#G77b3G ztq-GN&wZALqZ{ZgAtD4yYmDS2ieIv?YV*nHG-7aYaP68ewe`q7Pj{;wO-+p{tujjvT-q#jFA*+1hBR*>T&SImJrIqqTi-D- zs5EBNNE0~atRss?CrI4}BW{2HFu*0x*Ar47dMz-!Uef`YFDtd z7`3>E6M~^`w>@j~61yfjAe5*}1udw6xnG>~u9PH(opx`mBI@@U9GjD5|Qu#UU-9 zvp$qi25~G??-8dv;6e{-q`&jF2EbIq)13S@LbW9+WY?S+j;-| zuh4b7=PQo1!pG}lf3~+(G&EvI@#LVjU(?v8sGxMR{U#B?VvCxAZ+RKBPTvwN~u7zvm7j7hq zpOehZ%vv`#rfQeI(yd9f^VfQ^DkBu^86Sy>DL|pTf`U57{hfmlusMolu7#V(1IFbGeEyhl8iUz6oxhx`!xMOZ-Ea8^nG&?N znBSEcds53`h)T%Q&XtLmv+|0zeEJj*$dCzs?BU^IEn_rQ?@MH9lossx7iHyRdD?3^ z+v>lE{qp5YsF0)~vIT({ota_sJ>UF<52zK>HZpgF2T-n5~E_tvySj5avI_aP9uNSXRB3%dj`fz0h1qF7=(*AljeIEWPaT%=v&XB7NQ{j`aIPhWp*vTrWV^Fp>H z!X`F7J3`rNW_aXB*C$uX%(pf03E#!MxS#;rv!f&(BoM22BI^dw#y09=!*WQ6YqabAF{+OEUo!}=A zwmN7x#~$cb*G_LnXH)Os` zB6w%eydo0A)i7+655$bM0E`2VDuMl)gEpF!U{kk3Y;K_9pl|$wifoAR$L6iMdgzu} z>MNDYlgOe(;T%6$;)|ooirvmO&+3=wveTXxwYKg}Q_5o^r4@Ycws&jFZfcEbreEw- z`WZlJr0M@)krjN^_0n+%WkWyUUM|6VQ8pG7QkOFv`dQ~2SrSyw5!EWSfs=;*7oSyf zT9`gn@MRA7c?V!8Q^JJV6xA6F2apH^gKUWj&hRyva@(M``P?6@PEXiP=RzBGVhff| z{bl71Fx?#JpL>@wP2>7^-+(AZu8r&&7E$paOjZi(Oa+zvzAU(^Cu`COFKcpU!MT; z<|#{xoSze;`i;_kiu~CO0v-V&lGk4w*wj5W@&50o`JZoCP{?O@)jec#bpTeR5V=Z7 zaLW#z!H*k>2q<HeYr8vh(Y+N2_0@<9uC~Wvd!JZvT4RatpKp-{yZZeJh3`khPjrThklP zK_xyg2B#t|*{RUBSNV!WW=zbE+XBXi^10XTh5y3M>v2>+ezHUI#*YzpC(rzPf&`g$6e#w?j{ z*#@x&$t^mqaGkA-7W)WGI}OTjYb|cN$}(-?AZi>hbmcDi?U*^_roCDoa_K@GT#Dzj zpG+uNTBM4tO0={E?~_y)#$6@rGYj=>lX9*q0>&&zT)L)4Zt6N(vq5Pm?0;22A zJZaxAX>8e=xHKd|Hjle=_>^gpQh{JVcv?At^6h6qn`K(pr=Y)Y=KyZMWv`Tag<7nc;Ld8YKyO6h_U zgi@}R?3an=Z7=D<1hxGtEObf;i>jSq%=?N~K{J&_4*1s!nLYiR@Z<33#80D`UIYb8 zhEZ}}s!Rs#p6;Tz^{Db(K%L0YE|f!>q-XrTN#~z~j~AUsw}(`eN_*LC65o}^DbR92`T8(TcQ&Ln3npv*=sXSWw#O=XR4f;A98PruS=%C88j}n z2SJV`@nM&DRh^Tp*Pq%`VU&&4;>@P%V0J|KNV7?d?3)bO`|?eNeflLp=q~<^WMPsX zk>ghxummN|%`b@%-o^b6ui9@DLtW0d4&T^u3Zs}}Gp3_R!YJ7jvdxwIk_mn>oZVMV zJ7n`PU>78^wm9ULdth;&Vv3IfK64|&lD7J)&9=ZEdWe~%pC<*~pP|wOQu(@lJQC9% zK?flFT+Nh<+JWR-6+mm%KKK7x6+L=7o4p-QFL_mBq~Vyz(W^&xhZCi1Bi6KXAbQze zgHXtYJD^A6t96#?*oV-v6PX905pM?JYqjP@Xbxc(N2w@A?~lKeA1uK-`T*7RsX_ij z`*5aXH8y&}g)oI+)`94hEE2pLy3PT%L?a+Zh9^8Mhw!gAPy*S|oMX1Kro4Y>ubp^) z${L2mf11R;x%lW|BC|drkh%KglrcpMTMYx0zp9puU6bVXT6Gk?@o~+`j_Xhr`A9Nq zEcrRAR-b?8X1OW%N$5_yt3Fpo5Dq&NeWm1m}f)ir@XTAE2n#NwLF_jJH#M zq2HRS0x8`#OkWWJt37`XV&5+vtec-7_i97GU#mv3+&B*yuGG#G^o1;#$F-9$K5oi> zm;?{yD3~`5@ZIo*eNXyxl(&E6&YhQovI~aFHl}P=j|s8x0k$6(&vn*lN@RNAA9R_7g7f%QaaK*em|Okyi-@} zOz3h=Rd-&Zp``wou1Ji8K*<2gEI1#1Gm z9a{u8Hp>6#Yw~%+}@_HBq#{ZU59Rgp7su;<6At<&Ata>HbZ@df|0nbzXAX(E#NB?6$zWXmbtT) zvvapmQA;Xd))b_#euM>ZZ?|8R!ucC!yC2ylF{o(CK~R)%hDH~rEA_GOQ?i+_TS@*i yu#Sa|{WS4XZ)Xs6!!WmsCGJB06`$}f?zC;!7sZwNFMxmE0BTCwij_~S!v6#5Mhuz& literal 5905 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 f_x}uudUXj-hG1bji-NR3jT@w6m z0!yUC`1o7({XP8Q({odcry7oa_P(y(PhGt{0U$6xbE1(v3PKyPEFYApeo|8Bo>js~ z5*qVr(^c(~s`!b~O^W~>p zw02J-KVV1+>9=n;Na)G!B=gbU^S&)7&leei8?F=nC8tvo4&!ppEHHC;F#9m3rUqTW zRT~^#LqcVq`S_2ah%U=$7_6VFTNxkj9&9ors>tc_?vxcE;!Oh86)pQW zV89b$f~*&iUO?^&UZ8ZB`Uidjbw&RY{LnSWwV8H5q3K`diP|2PCRXZaXJ;#m`?H4` z)0Yq8rjenu(hPDzf!u6)U9J1)gHGZFN*|2e;DMBbm@uB}v~(XaCpC!tVQ!X!6%mvYH$Xxk2?5Pbak7l5o<8AzF{Ikc9HV@ zeC>p3yhA+uzUPEmRcO=IK&b}Me)A>_d4gK2e#1lPa+P$q{PD^qOUmT2GBjB}cJ?Bb zm|ylvI_lLcddmQt8xI;jQsl`B`NyPhd@gpZAs5f?%D z3lt$P)Fs>n#_!qGMQZPC?ZynPG#V^YC~?soVU7tkEY(9>n9mp{OtyTDqdJM*_eHg8 zB}Vq*q5_~Gl;jq}dFT%)U@3%Zrir}aiVdmk8AX0_tLA(>*?<>y?aqhFokZL}z* zu)GG)^PO-z76#Hb>9Mh~6n7?`{;S>?Lv<9AVKjt!#Kv~>9m`dv-W(70!2XH5a#vTD zY-HhrbrmYx1JZQPt9<{m9p#lhb$0`+&mM@r-XDZI37-V?={IvGjLprni&wslwr4hZ zQI1g`_na+p6N@X&o6SPwwg!IV$~~73C@T?pLgS=`OYfgJqfn{qjhCA z1)JGxX*r{(n2_m{DrQe6#vK@kXFK%qxe)tolohd4z2%4-_d}ma_$mUpFG)3?P!!jcuG7x*EzUo^Ks3)H&N-&9`W6R%5kGrIV_|sjLCNGAx#ytHOJ13XgfiA| zP!ky{TGXS*58xm7hGU(bN(V`RcQHjHyhaC!tEJjf$23tzI zc4eST&XMZR?=!!NUqNJ%J*n_MJpo#Y!x$p(w~3u-#2RG}r4Myj2ob(pzFKa=J2c% zG6R5tFI5HzebkL*P6N2h0s^jL3$h(N+YdjN2)oSdYn6@s7wj#l)>oH9U0}z#(-d7AgzL7SK$pltyWeADR^`tlLiI! z{_HNE8ZccQC(hqUHHkg47N1-MLpXx*ECn*G^jnQG9{T`azCd10PDs@h6#)hY2CadZ z+@Y1?(NV*Yu%Nx8J6KugTYB!;{{53Nxlk-7UtJzMETlj*~5)hp5Q0TwB^7gB-~pU{CL02Kdca#VLezxh~fyEBBfyu3W}WKTnDT_l|A z%SX%?cQ2c*(3Y+p)EGS-A02TzTt(ZcUlspsl8^IME%&<8f9g_>RIu1+l=elow5U+F zv6x^Jx5;`LeIPTPef-4KmL&coLYxWmss^bq-M?=Beo#>?j zc4SUbV zVRBM=WhKc_3U^8ko%+0EN1}vezc`ksxohRIhn$MC)c3>o&MTkIxqE|atyiI2*rS~* zNhKv*;m91uY5C;5rMkKrzPGpMHL{I38Xs>d?l_CIB7A8y#=kmykRX}kfa#59yhBPv zny6sveZ)@TMXkcAMQrooUGdabnFUGvNAwfrSYaBbF$t6^IORRFVpf$dzf*%Hep<=N zsi}aGT$!EXfYIjZi|urI0;J8N&YABd17*+F(^t(nvnf)IERNgb^vsaI>-Wmm?ZpKEa1TgnbX!3`4IbOKd*Sp8PGI<~H+c_)7}96^ihv#H6Q-;L zC`%!*|2*i^8mwGV7!m33k=zD|fpN+=_Jp}wlMOP3V8LS$ls3Bk%S?|u@jb5zAvvQY zYYUCsW+AgAxd|>s(^EkVJ{PH=oKo1U~af!WqM*#Qu%a+Y`RX$QC6zGQG8ki zm9iAJ2g7v7{#`b8^Ala=!KSR1+r^I*TU` z)!zNEI7Q}-lG4&X$JN6l-goK$&5I$JUmVD!&k3vC4rwd)}BT}ituajD-kHz$zxb@xt0bafT2Cp0kH6t^#TE?Vx z$I~156eHY`^~;#8DGQ%XT0Gn0btntf(GP}~zy8UL;QE{>JTU|MwXs&+jj3vSS?sE& z%7(*TEXvBta$&f@5h~U>!6)8KEG#CjuC7a6ifL(QUlDhk#6u6}=FOkmcL`s|J z;GJF0_Z>r#>ClTCg<)7%2S>+ZJ6oPWI`?WJPAl-IfPmjc%I?VPQc?^lDp=vi9|Gxs zdmk=EBp#RHUsJxJP=a4FQDZ+v01U8bh0Q+BtthzFk&z&)2<>@!IWod+-MyPFK|;yU zT~(z+Arul>>-VT3sC(yS+~0Nrq=X2A{)k!YT-Hlqk_rSw?Y-byweKXWQpL zJJ(cK@BQB1evaM#Q4{yBsmVG=!hUdiOy&G{Os0srC()ABlk4#3ImW$6yt2A~x(|?( zlOO*Ip06~*g?g#PM>scstgWxFcmJXyE+`|Rj`J6#D{La}fmB6v4*cat_~f4}!hcr+ z{a?!IGe1+JN1|WOx)K(uRQuD!?mjv<-Nz6HNRCs8J#=hUAG6Cn1b6ue{4K98X=tW4 zlSL-&HO^l(@Q!*ur(d*coM{#O)5Vmu^}9kS4S&^_JV19VC6E$dx)r@7*z~gl z1^N7JykHe6&C;3&zz3+2Q6}%pYEIuWUZM*tQ8pEEt^El1sZ~Ezimm2s@xa^4W#rmfFUf8>nnL_2*F9JH_H{^9G)6dGVy! z?D^e_2ABoiaX>~4_5Gt{<2+_^iY4{+BN#Z8ifMG+|+E#R0lHXY-3$4t9*9>Wvn|$vb9$f zjR&dVHjWdpcQXk&ZDhSu`l05TdW~x60_nfBWQpH~wz_|Ih&cVaT~- z;6as{k)eTGJjWN()m3%Na}kvGEV{b7F26#{ExNE`umz=-_p<+ET-f!C(yMl`s)Du5 zqzy{Dg2P{wlw8lq&Rn4h$AR!>$L3~QDMO){Dc(ld(bY4ye(>@#<$MUL_e$g$nmod8 zb@FmG9V!=mi3_R~5t;fr{I$`+c%e-8*29drgC^g<*G3W06d?qz_aU&GyV`UB14iVW zHV}#4nelrI?>4H?ua%%sZmfTORb4TjvCuTX@kWJ~MgZtN`4_>S8xb0K(CU}U*7JC* zKLUDQh%4D{s|%DSh#!pMa3L8P8RJzZm9QgV1aG!%?{CHZ-eF^KSEOSi?8!+TdT9Qj zf}jXbIB3L{bNEGY!ltLe)Ix6#*=KE%Kq8(5d!nSxuWKg+0Dk_Qo0s@gZSL@17OwG% zBpdvK@j88`^%;9&V&XmXHln8NLZ>HB8N{rkPwDd8D>b1jJKfZp$GQ=C&*v|yge?6T zfJYb{hpW`abvz5WqM#E^d3ZP%dpNPJi#>7`_HQ~ck{Xvz-rjC4`j_!=!=X(6IXZ3> zTO8j7sJ@@INm;l?|FmNz#|;SeAgQ|Q>od6>b`=*_)v#M6KvF<^nPwmAvh#b$y(Mq_ zw$!)g*EZbUHP|p<@cv7Ob%dau3xgO}30?P{-QJAgjlT@k?^B_u z0>po!+o|!qtVf^8Pxc?;E(=U8-r9ahe#x-|ia?{7wCshXuA~!mN*MFJi`!67c$v|l zo)>2npTd+mCpZ>`P1x?pEywp#18RR_h$zOVXHzH&O6^koRxP*>2=D}_zMO14^7y?Z z%{w&AGHrt1eC*7D%tnFo$7tU%Oz0@IQx>dYOZ+QA5HZn3gNej~( zGiv;3^TVuGv6(x3@MT80Tki48%zo}+!ABn&Y0FPd63B>ooS1lo{~YmpF_$2dF4Q(K z0_lZ8$EmT-k^6NP`YBJ34bN24YE%vuKz8BK%w7!?o*`XRpsi72Pmc#ML6H{Lpd4F$ zr_3b!K?a4Xp`>2i6n%dO8H-n~#hmuy`cz9dOb~qMomA^&?NW4+p!WPrU$WQI(Xi|jJcpIFem$MV4(5fH==*`)HiYT z(s;3TjWME;-`^@x=tbjv>qFoHxXZ6k1Q_&vd)mh^%UO%m@SEOgdi- z-kaKvFp9H>Lih1qPhdpeSVp@A&ef*kbolQ(!Be?g9_`5V)ZME95NQ1@k znfJtawQDo6>T;cq?L^Xsbh0jxPk687ygd#49Gx_VApG+-Ceat-3;x-h;NWV)cir`c zHWP}@NeNw&%&Q*}gRuO}ShVanF8wtNA~=X3Df&doSOY07Hk)#hkEm$eFLmwS7{vB~ zia^KG_BGe_BGOTtljxU?jL)djrmJ1~?UnQcdEyJ4ivpur4JgsiL<4>p_Yejqm12;HF^k1ZDBaN%_M=z2Y8ksTQPaY!tkrEd}+CPSB*fn6qL} z8h9t0hOke@qr?6#v&i*(wUneH#7@+mjkRM%W;&&KW%c`v&&Xs9nC6LoLSyP@G~O2O zCrXMKwi{ha*SQ`ouMa*CCCWnk+)RpDdYj9TZRIkA>FHDF~RgHKeuJ|zctbJldP zZ;>)B_1RYx$r8`*qTd=O6{o9RM`?u!zp+T1vy&GFz4KMC@}XSM#|muu{>*=zy|cie zU|90-#m>IgKnD%eoFO)}4!uJdA)KQ8<5{%Wlp|)sG#FfrWYg=g->m9+AVtu*+Tg@T zeAq{KtV1l5oU0agI}^YJv!*@J9ouqhwlH@sJ{LnNV35qa63MXZY#xfQN#7-D)x>gB z6xJpsGSBMy()H~Tr+;?;e#IF(8<0J+R}%;qG$!SPln_|`Ai`UA{vGP{)R|tO>R1oT zh=DQ4gniN#u>)F4A2#y|u)t9=u(#?EI6TRux)+nHvX_uhZ*;QHf$ zW$}VK0bXL7p!302e3Wmx^h}|^^wA@DMTMZ15*hMeezw1|a?+ibTF&-!ANE z_OXNL?2XP$Z7ZjA+LM@?FJAq}pz7&AC->HM|#*4{SUzqNU$cz4%Z?g?8Q z-43B#fuZEom)h8eyY~LjKqW4617%DweW|i@YF6<6>0f^eNO$JKui%LmY;%uVOt0_T zfqhNXV4}Rsqo!-4Lu8sXe@C!Jhug2Q$uVUt&)zKIJuUhOpGFEe<)=Y;zc=_&bX_Ikt_$9p3`re&PMNko z;0F(+9ptMQFy63L1VQ*V+G=_?op++!5EXQyme#i>O7zP8-ewZy2!zc_fCoikhhuk8 zD$pc^9o(J*1ljr9Y-DfMC2+8d?S<$|;%!}UOrs{=Nz#Y?Z@w`O`WCWj32#^y!2e7H NbTkb$>eXyt{1=bM=w$!^ literal 6522 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 TQO1gXnF3H%(p0RFHx2tQ-Ucx( diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index 8dac840e1d8ee2b8b2177192ec112ad28fab6749..ec5fb22bda819af252f7a54b758897c1b4815798 100644 GIT binary patch delta 20809 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 diff --git a/icons/obj/shards.dmi b/icons/obj/shards.dmi index a575ab292ff35b43c0ba64bd8c1f2262b12272e7..e7875efa2648cbcfb9b299fc4808b887630d0c7a 100644 GIT binary patch delta 3677 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 XcB3diuMgH!KSzLxp@l(%J{ Date: Thu, 21 Jan 2021 02:45:10 -0300 Subject: [PATCH 2/2] Line ending conflict fix --- .../game/objects/items/stacks/sheets/glass.dm | 691 ++++----- code/game/objects/structures/tables_racks.dm | 1303 +++++++++-------- 2 files changed, 998 insertions(+), 996 deletions(-) diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 12c37607..1159bd44 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -1,345 +1,346 @@ -/* Glass stack types - * Contains: - * Glass sheets - * Reinforced glass sheets - * Glass shards - TODO: Move this into code/game/object/item/weapons - */ - -/* - * Glass sheets - */ -GLOBAL_LIST_INIT(glass_recipes, list ( \ - new/datum/stack_recipe("directional window", /obj/structure/window/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile window", /obj/structure/window/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ -)) - -/obj/item/stack/sheet/glass - name = "glass" - desc = "HOLY SHEET! That is a lot of glass." - singular_name = "glass sheet" - icon_state = "sheet-glass" - item_state = "sheet-glass" - materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/glass - grind_results = list(/datum/reagent/silicon = 20) - point_value = 1 - tableVariant = /obj/structure/table/glass - -/obj/item/stack/sheet/glass/suicide_act(mob/living/carbon/user) - user.visible_message("[user] begins to slice [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return BRUTELOSS - -/obj/item/stack/sheet/glass/cyborg - materials = list() - is_cyborg = 1 - cost = 500 - -/obj/item/stack/sheet/glass/fifty - amount = 50 - -/obj/item/stack/sheet/glass/five - amount = 5 - -/obj/item/stack/sheet/glass/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.glass_recipes - return ..() - -/obj/item/stack/sheet/glass/attackby(obj/item/W, mob/user, params) - add_fingerprint(user) - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/CC = W - if (get_amount() < 1 || CC.get_amount() < 5) - to_chat(user, "You attach wire to the [name].") - var/obj/item/stack/light_w/new_tile = new(user.loc) - new_tile.add_fingerprint(user) - else if(istype(W, /obj/item/stack/rods)) - var/obj/item/stack/rods/V = W - if (V.get_amount() >= 1 && get_amount() >= 1) - var/obj/item/stack/sheet/rglass/RG = new (get_turf(user)) - RG.add_fingerprint(user) - var/replace = user.get_inactive_held_item()==src - V.use(1) - use(1) - if(QDELETED(src) && replace) - user.put_in_hands(RG) - else - to_chat(user, "You need one rod and one sheet of glass to make reinforced glass!") - return - else - return ..() - - - -GLOBAL_LIST_INIT(pglass_recipes, list ( \ - new/datum/stack_recipe("directional window", /obj/structure/window/plasma/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile window", /obj/structure/window/plasma/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ -)) - -/obj/item/stack/sheet/plasmaglass - name = "plasma glass" - desc = "A glass sheet made out of a plasma-silicate alloy. It looks extremely tough and heavily fire resistant." - singular_name = "plasma glass sheet" - icon_state = "sheet-pglass" - item_state = "sheet-pglass" - materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/plasmaglass - grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10) - tableVariant = /obj/structure/table/plasmaglass - -/obj/item/stack/sheet/plasmaglass/fifty - amount = 50 - -/obj/item/stack/sheet/plasmaglass/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.pglass_recipes - return ..() - -/obj/item/stack/sheet/plasmaglass/attackby(obj/item/W, mob/user, params) - add_fingerprint(user) - - if(istype(W, /obj/item/stack/rods)) - var/obj/item/stack/rods/V = W - if (V.get_amount() >= 1 && get_amount() >= 1) - var/obj/item/stack/sheet/plasmarglass/RG = new (get_turf(user)) - RG.add_fingerprint(user) - var/replace = user.get_inactive_held_item()==src - V.use(1) - use(1) - if(QDELETED(src) && replace) - user.put_in_hands(RG) - else - to_chat(user, "You need one rod and one sheet of plasma glass to make reinforced plasma glass!") - return - else - return ..() - - - -/* - * Reinforced glass sheets - */ -GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ - new/datum/stack_recipe("windoor frame", /obj/structure/windoor_assembly, 5, time = 0, on_floor = TRUE, window_checks = TRUE), \ - null, \ - new/datum/stack_recipe("directional reinforced window", /obj/structure/window/reinforced/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile reinforced window", /obj/structure/window/reinforced/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ -)) - - -/obj/item/stack/sheet/rglass - name = "reinforced glass" - desc = "Glass which seems to have rods or something stuck in them." - singular_name = "reinforced glass sheet" - icon_state = "sheet-rglass" - item_state = "sheet-rglass" - materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/rglass - grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/iron = 10) - point_value = 4 - -/obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params) - add_fingerprint(user) - ..() - -/obj/item/stack/sheet/rglass/cyborg - materials = list() - var/datum/robot_energy_storage/glasource - var/metcost = 250 - var/glacost = 500 - -/obj/item/stack/sheet/rglass/cyborg/get_amount() - return min(round(source.energy / metcost), round(glasource.energy / glacost)) - -/obj/item/stack/sheet/rglass/cyborg/use(used, transfer = FALSE) // Requires special checks, because it uses two storages - source.use_charge(used * metcost) - glasource.use_charge(used * glacost) - -/obj/item/stack/sheet/rglass/cyborg/add(amount) - source.add_charge(amount * metcost) - glasource.add_charge(amount * glacost) - -/obj/item/stack/sheet/rglass/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.reinforced_glass_recipes - return ..() - -GLOBAL_LIST_INIT(prglass_recipes, list ( \ - new/datum/stack_recipe("directional reinforced window", /obj/structure/window/plasma/reinforced/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile reinforced window", /obj/structure/window/plasma/reinforced/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ -)) - -/obj/item/stack/sheet/plasmarglass - name = "reinforced plasma glass" - desc = "A glass sheet made out of a plasma-silicate alloy and a rod matrix. It looks hopelessly tough and nearly fire-proof!" - singular_name = "reinforced plasma glass sheet" - icon_state = "sheet-prglass" - item_state = "sheet-prglass" - materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT, MAT_METAL=MINERAL_MATERIAL_AMOUNT * 0.5,) - armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/plasmarglass - grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10, /datum/reagent/iron = 10) - point_value = 23 - -/obj/item/stack/sheet/plasmarglass/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.prglass_recipes - return ..() - -GLOBAL_LIST_INIT(titaniumglass_recipes, list( - new/datum/stack_recipe("shuttle window", /obj/structure/window/shuttle/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) - )) - -/obj/item/stack/sheet/titaniumglass - name = "titanium glass" - desc = "A glass sheet made out of a titanium-silicate alloy." - singular_name = "titanium glass sheet" - icon_state = "sheet-titaniumglass" - item_state = "sheet-titaniumglass" - materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/titaniumglass - -/obj/item/stack/sheet/titaniumglass/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.titaniumglass_recipes - return ..() - -GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( - new/datum/stack_recipe("plastitanium window", /obj/structure/window/plastitanium/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) - )) - -/obj/item/stack/sheet/plastitaniumglass - name = "plastitanium glass" - desc = "A glass sheet made out of a plasma-titanium-silicate alloy." - singular_name = "plastitanium glass sheet" - icon_state = "sheet-plastitaniumglass" - item_state = "sheet-plastitaniumglass" - materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/plastitaniumglass - -/obj/item/stack/sheet/plastitaniumglass/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.plastitaniumglass_recipes - return ..() - -/obj/item/shard - name = "shard" - desc = "A nasty looking shard of glass." - icon = 'icons/obj/shards.dmi' - icon_state = "large" - w_class = WEIGHT_CLASS_TINY - force = 5 - throwforce = 10 - item_state = "shard-glass" - lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' - materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - attack_verb = list("stabbed", "slashed", "sliced", "cut") - hitsound = 'sound/weapons/bladeslice.ogg' - resistance_flags = ACID_PROOF - armor = list("melee" = 100, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) - max_integrity = 40 - sharpness = IS_SHARP - var/icon_prefix - - -/obj/item/shard/suicide_act(mob/user) - user.visible_message("[user] is slitting [user.p_their()] [pick("wrists", "throat")] with the shard of glass! It looks like [user.p_theyre()] trying to commit suicide.") - return (BRUTELOSS) - - -/obj/item/shard/Initialize() - . = ..() - AddComponent(/datum/component/caltrop, force) - AddComponent(/datum/component/butchering, 150, 65) - icon_state = pick("large", "medium", "small") - switch(icon_state) - if("small") - pixel_x = rand(-12, 12) - pixel_y = rand(-12, 12) - if("medium") - pixel_x = rand(-8, 8) - pixel_y = rand(-8, 8) - if("large") - pixel_x = rand(-5, 5) - pixel_y = rand(-5, 5) - if (icon_prefix) - icon_state = "[icon_prefix][icon_state]" - - var/turf/T = get_turf(src) - if(T && is_station_level(T.z)) - SSblackbox.record_feedback("tally", "station_mess_created", 1, name) - -/obj/item/shard/Destroy() - . = ..() - - var/turf/T = get_turf(src) - if(T && is_station_level(T.z)) - SSblackbox.record_feedback("tally", "station_mess_destroyed", 1, name) - -/obj/item/shard/afterattack(atom/A as mob|obj, mob/user, proximity) - . = ..() - if(!proximity || !(src in user)) - return - if(isturf(A)) - return - if(istype(A, /obj/item/storage)) - return - var/hit_hand = ((user.active_hand_index % 2 == 0) ? "r_" : "l_") + "arm" - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(!H.gloves && !HAS_TRAIT(H, TRAIT_PIERCEIMMUNE)) // golems, etc - to_chat(H, "[src] cuts into your hand!") - H.apply_damage(force*0.5, BRUTE, hit_hand) - else if(ismonkey(user)) - var/mob/living/carbon/monkey/M = user - if(!HAS_TRAIT(M, TRAIT_PIERCEIMMUNE)) - to_chat(M, "[src] cuts into your hand!") - M.apply_damage(force*0.5, BRUTE, hit_hand) - - -/obj/item/shard/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/lightreplacer)) - I.attackby(src, user) - else - return ..() - -/obj/item/shard/welder_act(mob/living/user, obj/item/I) - ..() - if(I.use_tool(src, user, 0, volume=50)) - var/obj/item/stack/sheet/glass/NG = new (user.loc) - for(var/obj/item/stack/sheet/glass/G in user.loc) - if(G == NG) - continue - if(G.amount >= G.max_amount) - continue - G.attackby(NG, user) - to_chat(user, "You add the newly-formed glass to the stack. It now contains [NG.amount] sheet\s.") - qdel(src) - return TRUE - -/obj/item/shard/Crossed(mob/living/L) - if(istype(L) && has_gravity(loc)) - if(HAS_TRAIT(L, TRAIT_LIGHT_STEP)) - playsound(loc, 'sound/effects/glass_step.ogg', 30, 1) - else - playsound(loc, 'sound/effects/glass_step.ogg', 50, 1) - return ..() - -/obj/item/shard/plasma - name = "purple shard" - desc = "A nasty looking shard of plasma glass." - force = 6 - throwforce = 11 - icon_state = "plasmalarge" - materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - icon_prefix = "plasma" +/* Glass stack types + * Contains: + * Glass sheets + * Reinforced glass sheets + * Glass shards - TODO: Move this into code/game/object/item/weapons + */ + +/* + * Glass sheets + */ +GLOBAL_LIST_INIT(glass_recipes, list ( \ + new/datum/stack_recipe("directional window", /obj/structure/window/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("fulltile window", /obj/structure/window/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ +)) + +/obj/item/stack/sheet/glass + name = "glass" + desc = "HOLY SHEET! That is a lot of glass." + singular_name = "glass sheet" + icon_state = "sheet-glass" + item_state = "sheet-glass" + materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) + resistance_flags = ACID_PROOF + merge_type = /obj/item/stack/sheet/glass + grind_results = list(/datum/reagent/silicon = 20) + point_value = 1 + tableVariant = /obj/structure/table/glass + +/obj/item/stack/sheet/glass/suicide_act(mob/living/carbon/user) + user.visible_message("[user] begins to slice [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return BRUTELOSS + +/obj/item/stack/sheet/glass/cyborg + materials = list() + is_cyborg = 1 + cost = 500 + +/obj/item/stack/sheet/glass/fifty + amount = 50 + +/obj/item/stack/sheet/glass/five + amount = 5 + +/obj/item/stack/sheet/glass/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.glass_recipes + return ..() + +/obj/item/stack/sheet/glass/attackby(obj/item/W, mob/user, params) + add_fingerprint(user) + if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/CC = W + if (get_amount() < 1 || CC.get_amount() < 5) + to_chat(user, "You attach wire to the [name].") + var/obj/item/stack/light_w/new_tile = new(user.loc) + new_tile.add_fingerprint(user) + else if(istype(W, /obj/item/stack/rods)) + var/obj/item/stack/rods/V = W + if (V.get_amount() >= 1 && get_amount() >= 1) + var/obj/item/stack/sheet/rglass/RG = new (get_turf(user)) + RG.add_fingerprint(user) + var/replace = user.get_inactive_held_item()==src + V.use(1) + use(1) + if(QDELETED(src) && replace) + user.put_in_hands(RG) + else + to_chat(user, "You need one rod and one sheet of glass to make reinforced glass!") + return + else + return ..() + + + +GLOBAL_LIST_INIT(pglass_recipes, list ( \ + new/datum/stack_recipe("directional window", /obj/structure/window/plasma/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("fulltile window", /obj/structure/window/plasma/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ +)) + +/obj/item/stack/sheet/plasmaglass + name = "plasma glass" + desc = "A glass sheet made out of a plasma-silicate alloy. It looks extremely tough and heavily fire resistant." + singular_name = "plasma glass sheet" + icon_state = "sheet-pglass" + item_state = "sheet-pglass" + materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100) + resistance_flags = ACID_PROOF + merge_type = /obj/item/stack/sheet/plasmaglass + grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10) + tableVariant = /obj/structure/table/plasmaglass + +/obj/item/stack/sheet/plasmaglass/fifty + amount = 50 + +/obj/item/stack/sheet/plasmaglass/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.pglass_recipes + return ..() + +/obj/item/stack/sheet/plasmaglass/attackby(obj/item/W, mob/user, params) + add_fingerprint(user) + + if(istype(W, /obj/item/stack/rods)) + var/obj/item/stack/rods/V = W + if (V.get_amount() >= 1 && get_amount() >= 1) + var/obj/item/stack/sheet/plasmarglass/RG = new (get_turf(user)) + RG.add_fingerprint(user) + var/replace = user.get_inactive_held_item()==src + V.use(1) + use(1) + if(QDELETED(src) && replace) + user.put_in_hands(RG) + else + to_chat(user, "You need one rod and one sheet of plasma glass to make reinforced plasma glass!") + return + else + return ..() + + + +/* + * Reinforced glass sheets + */ +GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ + new/datum/stack_recipe("windoor frame", /obj/structure/windoor_assembly, 5, time = 0, on_floor = TRUE, window_checks = TRUE), \ + null, \ + new/datum/stack_recipe("directional reinforced window", /obj/structure/window/reinforced/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("fulltile reinforced window", /obj/structure/window/reinforced/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ +)) + + +/obj/item/stack/sheet/rglass + name = "reinforced glass" + desc = "Glass which seems to have rods or something stuck in them." + singular_name = "reinforced glass sheet" + icon_state = "sheet-rglass" + item_state = "sheet-rglass" + materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) + resistance_flags = ACID_PROOF + merge_type = /obj/item/stack/sheet/rglass + grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/iron = 10) + point_value = 4 + +/obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params) + add_fingerprint(user) + ..() + +/obj/item/stack/sheet/rglass/cyborg + materials = list() + var/datum/robot_energy_storage/glasource + var/metcost = 250 + var/glacost = 500 + +/obj/item/stack/sheet/rglass/cyborg/get_amount() + return min(round(source.energy / metcost), round(glasource.energy / glacost)) + +/obj/item/stack/sheet/rglass/cyborg/use(used, transfer = FALSE) // Requires special checks, because it uses two storages + source.use_charge(used * metcost) + glasource.use_charge(used * glacost) + +/obj/item/stack/sheet/rglass/cyborg/add(amount) + source.add_charge(amount * metcost) + glasource.add_charge(amount * glacost) + +/obj/item/stack/sheet/rglass/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.reinforced_glass_recipes + return ..() + +GLOBAL_LIST_INIT(prglass_recipes, list ( \ + new/datum/stack_recipe("directional reinforced window", /obj/structure/window/plasma/reinforced/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("fulltile reinforced window", /obj/structure/window/plasma/reinforced/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ +)) + +/obj/item/stack/sheet/plasmarglass + name = "reinforced plasma glass" + desc = "A glass sheet made out of a plasma-silicate alloy and a rod matrix. It looks hopelessly tough and nearly fire-proof!" + singular_name = "reinforced plasma glass sheet" + icon_state = "sheet-prglass" + item_state = "sheet-prglass" + materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT, MAT_METAL=MINERAL_MATERIAL_AMOUNT * 0.5,) + armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + resistance_flags = ACID_PROOF + merge_type = /obj/item/stack/sheet/plasmarglass + grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10, /datum/reagent/iron = 10) + point_value = 23 + +/obj/item/stack/sheet/plasmarglass/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.prglass_recipes + return ..() + +GLOBAL_LIST_INIT(titaniumglass_recipes, list( + new/datum/stack_recipe("shuttle window", /obj/structure/window/shuttle/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) + )) + +/obj/item/stack/sheet/titaniumglass + name = "titanium glass" + desc = "A glass sheet made out of a titanium-silicate alloy." + singular_name = "titanium glass sheet" + icon_state = "sheet-titaniumglass" + item_state = "sheet-titaniumglass" + materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + resistance_flags = ACID_PROOF + merge_type = /obj/item/stack/sheet/titaniumglass + +/obj/item/stack/sheet/titaniumglass/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.titaniumglass_recipes + return ..() + +GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( + new/datum/stack_recipe("plastitanium window", /obj/structure/window/plastitanium/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) + )) + +/obj/item/stack/sheet/plastitaniumglass + name = "plastitanium glass" + desc = "A glass sheet made out of a plasma-titanium-silicate alloy." + singular_name = "plastitanium glass sheet" + icon_state = "sheet-plastitaniumglass" + item_state = "sheet-plastitaniumglass" + materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + resistance_flags = ACID_PROOF + merge_type = /obj/item/stack/sheet/plastitaniumglass + +/obj/item/stack/sheet/plastitaniumglass/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.plastitaniumglass_recipes + return ..() + +/obj/item/shard + name = "shard" + desc = "A nasty looking shard of glass." + icon = 'icons/obj/shards.dmi' + icon_state = "large" + w_class = WEIGHT_CLASS_TINY + force = 5 + throwforce = 10 + item_state = "shard-glass" + lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' + materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + attack_verb = list("stabbed", "slashed", "sliced", "cut") + hitsound = 'sound/weapons/bladeslice.ogg' + resistance_flags = ACID_PROOF + armor = list("melee" = 100, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) + max_integrity = 40 + sharpness = IS_SHARP + var/icon_prefix + + +/obj/item/shard/suicide_act(mob/user) + user.visible_message("[user] is slitting [user.p_their()] [pick("wrists", "throat")] with the shard of glass! It looks like [user.p_theyre()] trying to commit suicide.") + return (BRUTELOSS) + + +/obj/item/shard/Initialize() + . = ..() + AddComponent(/datum/component/caltrop, force) + AddComponent(/datum/component/butchering, 150, 65) + icon_state = pick("large", "medium", "small") + switch(icon_state) + if("small") + pixel_x = rand(-12, 12) + pixel_y = rand(-12, 12) + if("medium") + pixel_x = rand(-8, 8) + pixel_y = rand(-8, 8) + if("large") + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) + if (icon_prefix) + icon_state = "[icon_prefix][icon_state]" + + var/turf/T = get_turf(src) + if(T && is_station_level(T.z)) + SSblackbox.record_feedback("tally", "station_mess_created", 1, name) + +/obj/item/shard/Destroy() + . = ..() + + var/turf/T = get_turf(src) + if(T && is_station_level(T.z)) + SSblackbox.record_feedback("tally", "station_mess_destroyed", 1, name) + +/obj/item/shard/afterattack(atom/A as mob|obj, mob/user, proximity) + . = ..() + if(!proximity || !(src in user)) + return + if(isturf(A)) + return + if(istype(A, /obj/item/storage)) + return + var/hit_hand = ((user.active_hand_index % 2 == 0) ? "r_" : "l_") + "arm" + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(!H.gloves && !HAS_TRAIT(H, TRAIT_PIERCEIMMUNE)) // golems, etc + to_chat(H, "[src] cuts into your hand!") + H.apply_damage(force*0.5, BRUTE, hit_hand) + else if(ismonkey(user)) + var/mob/living/carbon/monkey/M = user + if(!HAS_TRAIT(M, TRAIT_PIERCEIMMUNE)) + to_chat(M, "[src] cuts into your hand!") + M.apply_damage(force*0.5, BRUTE, hit_hand) + + +/obj/item/shard/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/lightreplacer)) + I.attackby(src, user) + else + return ..() + +/obj/item/shard/welder_act(mob/living/user, obj/item/I) + ..() + if(I.use_tool(src, user, 0, volume=50)) + var/obj/item/stack/sheet/glass/NG = new (user.loc) + for(var/obj/item/stack/sheet/glass/G in user.loc) + if(G == NG) + continue + if(G.amount >= G.max_amount) + continue + G.attackby(NG, user) + to_chat(user, "You add the newly-formed glass to the stack. It now contains [NG.amount] sheet\s.") + qdel(src) + return TRUE + +/obj/item/shard/Crossed(mob/living/L) + if(istype(L) && has_gravity(loc)) + if(HAS_TRAIT(L, TRAIT_LIGHT_STEP)) + playsound(loc, 'sound/effects/glass_step.ogg', 30, 1) + else + playsound(loc, 'sound/effects/glass_step.ogg', 50, 1) + return ..() + +/obj/item/shard/plasma + name = "purple shard" + desc = "A nasty looking shard of plasma glass." + force = 6 + throwforce = 11 + icon_state = "plasmalarge" + materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + icon_prefix = "plasma" + diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 59710969..c2578322 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -1,651 +1,652 @@ -/* Tables and Racks - * Contains: - * Tables - * Glass Tables - * Wooden Tables - * Reinforced Tables - * Racks - * Rack Parts - */ - -/* - * Tables - */ - -/obj/structure/table - name = "table" - desc = "A square piece of metal standing on four metal legs. It can not move." - icon = 'icons/obj/smooth_structures/table.dmi' - icon_state = "table" - density = TRUE - anchored = TRUE - layer = TABLE_LAYER - climbable = TRUE - obj_flags = CAN_BE_HIT|SHOVABLE_ONTO - pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.") - var/frame = /obj/structure/table_frame - var/framestack = /obj/item/stack/rods - var/buildstack = /obj/item/stack/sheet/metal - var/busy = FALSE - var/buildstackamount = 1 - var/framestackamount = 2 - var/deconstruction_ready = 1 - max_integrity = 100 - integrity_failure = 30 - smooth = SMOOTH_TRUE - canSmoothWith = list(/obj/structure/table, /obj/structure/table/reinforced) - -/obj/structure/table/examine(mob/user) - . = ..() - . += deconstruction_hints(user) - -/obj/structure/table/proc/deconstruction_hints(mob/user) - return "The top is screwed on, but the main bolts are also visible." - -/obj/structure/table/update_icon() - if(smooth) - queue_smooth(src) - queue_smooth_neighbors(src) - -/obj/structure/table/narsie_act() - var/atom/A = loc - qdel(src) - new /obj/structure/table/wood(A) - -/obj/structure/table/ratvar_act() - var/atom/A = loc - qdel(src) - new /obj/structure/table/reinforced/brass(A) - -/obj/structure/table/attack_paw(mob/user) - return attack_hand(user) - -/obj/structure/table/attack_hand(mob/living/user) - if(Adjacent(user) && user.pulling) - if(isliving(user.pulling)) - var/mob/living/pushed_mob = user.pulling - if(pushed_mob.buckled) - to_chat(user, "[pushed_mob] is buckled to [pushed_mob.buckled]!") - return - if(user.a_intent == INTENT_GRAB) - if(user.grab_state < GRAB_AGGRESSIVE) - to_chat(user, "You need a better grip to do that!") - return - tablepush(user, pushed_mob) - if(user.a_intent == INTENT_HELP) - pushed_mob.visible_message("[user] begins to place [pushed_mob] onto [src]...", \ - "[user] begins to place [pushed_mob] onto [src]...") - if(do_after(user, 35, target = pushed_mob)) - tableplace(user, pushed_mob) - else - return - user.stop_pulling() - else if(user.pulling.pass_flags & PASSTABLE) - user.Move_Pulled(src) - if (user.pulling.loc == loc) - user.visible_message("[user] places [user.pulling] onto [src].", - "You place [user.pulling] onto [src].") - user.stop_pulling() - return ..() - -/obj/structure/table/attack_tk() - return FALSE - -/obj/structure/table/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSTABLE)) - return 1 - if(mover.throwing) - return 1 - if(locate(/obj/structure/table) in get_turf(mover)) - return 1 - else - return !density - -/obj/structure/table/CanAStarPass(ID, dir, caller) - . = !density - if(ismovableatom(caller)) - var/atom/movable/mover = caller - . = . || (mover.pass_flags & PASSTABLE) - -/obj/structure/table/proc/tableplace(mob/living/user, mob/living/pushed_mob) - pushed_mob.forceMove(src.loc) - pushed_mob.resting = TRUE - pushed_mob.update_canmove() - pushed_mob.visible_message("[user] places [pushed_mob] onto [src].", \ - "[user] places [pushed_mob] onto [src].") - log_combat(user, pushed_mob, "placed") - -/obj/structure/table/proc/tablepush(mob/living/user, mob/living/pushed_mob) - if(HAS_TRAIT(user, TRAIT_PACIFISM)) - to_chat(user, "Throwing [pushed_mob] onto the table might hurt them!") - return - var/added_passtable = FALSE - if(!pushed_mob.pass_flags & PASSTABLE) - added_passtable = TRUE - pushed_mob.pass_flags |= PASSTABLE - pushed_mob.Move(src.loc) - if(added_passtable) - pushed_mob.pass_flags &= ~PASSTABLE - if(pushed_mob.loc != loc) //Something prevented the tabling - return - pushed_mob.Knockdown(40) - pushed_mob.visible_message("[user] slams [pushed_mob] onto [src]!", \ - "[user] slams you onto [src]!") - log_combat(user, pushed_mob, "tabled", null, "onto [src]") - if(!ishuman(pushed_mob)) - return - var/mob/living/carbon/human/H = pushed_mob - SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table) - -/obj/structure/table/shove_act(mob/living/target, mob/living/user) - if(!target.resting) - target.Knockdown(SHOVE_KNOCKDOWN_TABLE) - user.visible_message("[user.name] shoves [target.name] onto \the [src]!", - "You shove [target.name] onto \the [src]!", null, COMBAT_MESSAGE_RANGE) - target.forceMove(src.loc) - log_combat(user, target, "shoved", "onto [src] (table)") - return TRUE - -/obj/structure/table/attackby(obj/item/I, mob/user, params) - if(!(flags_1 & NODECONSTRUCT_1)) - if(istype(I, /obj/item/screwdriver) && deconstruction_ready) - to_chat(user, "You start disassembling [src]...") - if(I.use_tool(src, user, 20, volume=50)) - deconstruct(TRUE) - return - - if(istype(I, /obj/item/wrench) && deconstruction_ready) - to_chat(user, "You start deconstructing [src]...") - if(I.use_tool(src, user, 40, volume=50)) - playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) - deconstruct(TRUE, 1) - return - - if(istype(I, /obj/item/storage/bag/tray)) - var/obj/item/storage/bag/tray/T = I - if(T.contents.len > 0) // If the tray isn't empty - SEND_SIGNAL(I, COMSIG_TRY_STORAGE_QUICK_EMPTY, drop_location()) - user.visible_message("[user] empties [I] on [src].") - return - // If the tray IS empty, continue on (tray will be placed on the table like other items) - - if(user.a_intent != INTENT_HARM && !(I.item_flags & ABSTRACT)) - if(user.transferItemToLoc(I, drop_location())) - var/list/click_params = params2list(params) - //Center the icon where the user clicked. - if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) - return - //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) - I.pixel_x = CLAMP(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) - I.pixel_y = CLAMP(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) - return 1 - else - return ..() - - -/obj/structure/table/deconstruct(disassembled = TRUE, wrench_disassembly = 0) - if(!(flags_1 & NODECONSTRUCT_1)) - var/turf/T = get_turf(src) - new buildstack(T, buildstackamount) - if(!wrench_disassembly) - new frame(T) - else - new framestack(T, framestackamount) - qdel(src) - - -/* - * Glass tables - */ -/obj/structure/table/glass - name = "glass table" - desc = "What did I say about leaning on the glass tables? Now you need surgery." - icon = 'icons/obj/smooth_structures/glass_table.dmi' - icon_state = "glass_table" - buildstack = /obj/item/stack/sheet/glass - canSmoothWith = null - max_integrity = 70 - resistance_flags = ACID_PROOF - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) - var/list/debris = list() - -/obj/structure/table/glass/New() - . = ..() - debris += new frame - debris += new /obj/item/shard - -/obj/structure/table/glass/Destroy() - QDEL_LIST(debris) - . = ..() - -/obj/structure/table/glass/Crossed(atom/movable/AM) - . = ..() - if(flags_1 & NODECONSTRUCT_1) - return - if(!isliving(AM)) - return - // Don't break if they're just flying past - if(AM.throwing) - addtimer(CALLBACK(src, .proc/throw_check, AM), 5) - else - check_break(AM) - -/obj/structure/table/glass/proc/throw_check(mob/living/M) - if(M.loc == get_turf(src)) - check_break(M) - -/obj/structure/table/glass/proc/check_break(mob/living/M) - if(M.has_gravity() && M.mob_size > MOB_SIZE_SMALL && !(M.movement_type & FLYING)) - table_shatter(M) - -/obj/structure/table/glass/proc/table_shatter(mob/living/L) - visible_message("[src] breaks!", - "You hear breaking glass.") - var/turf/T = get_turf(src) - playsound(T, "shatter", 50, 1) - for(var/I in debris) - var/atom/movable/AM = I - AM.forceMove(T) - debris -= AM - if(istype(AM, /obj/item/shard)) - AM.throw_impact(L) - L.Knockdown(100) - qdel(src) - -/obj/structure/table/glass/deconstruct(disassembled = TRUE, wrench_disassembly = 0) - if(!(flags_1 & NODECONSTRUCT_1)) - if(disassembled) - ..() - return - else - var/turf/T = get_turf(src) - playsound(T, "shatter", 50, 1) - for(var/X in debris) - var/atom/movable/AM = X - AM.forceMove(T) - debris -= AM - qdel(src) - -/obj/structure/table/glass/narsie_act() - color = NARSIE_WINDOW_COLOUR - for(var/obj/item/shard/S in debris) - S.color = NARSIE_WINDOW_COLOUR - -/* - * Plasmaglass tables - */ -/obj/structure/table/plasmaglass - name = "plasmaglass table" - desc = "A glasstable, but it's pink and more sturdy. What will Nanotrasen design next with plasma?" - icon = 'icons/obj/smooth_structures/plasmaglass_table.dmi' - icon_state = "plasmaglass_table" - climbable = TRUE - buildstack = /obj/item/stack/sheet/plasmaglass - canSmoothWith = null - max_integrity = 270 - resistance_flags = ACID_PROOF - armor = list("melee" = 10, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) - var/list/debris = list() - -/obj/structure/table/plasmaglass/New() - . = ..() - debris += new frame - debris += new /obj/item/shard/plasma - -/obj/structure/table/plasmaglass/Destroy() - QDEL_LIST(debris) - . = ..() - -/obj/structure/table/plasmaglass/proc/check_break(mob/living/M) - return - -/obj/structure/table/plasmaglass/deconstruct(disassembled = TRUE, wrench_disassembly = 0) - if(!(flags_1 & NODECONSTRUCT_1)) - if(disassembled) - ..() - return - else - var/turf/T = get_turf(src) - playsound(T, "shatter", 50, 1) - for(var/X in debris) - var/atom/movable/AM = X - AM.forceMove(T) - debris -= AM - qdel(src) - -/obj/structure/table/plasmaglass/narsie_act() - color = NARSIE_WINDOW_COLOUR - for(var/obj/item/shard/S in debris) - S.color = NARSIE_WINDOW_COLOUR - -/* - * Wooden tables - */ - -/obj/structure/table/wood - name = "wooden table" - desc = "Do not apply fire to this. Rumour says it burns easily." - icon = 'icons/obj/smooth_structures/wood_table.dmi' - icon_state = "wood_table" - frame = /obj/structure/table_frame/wood - framestack = /obj/item/stack/sheet/mineral/wood - buildstack = /obj/item/stack/sheet/mineral/wood - resistance_flags = FLAMMABLE - max_integrity = 70 - canSmoothWith = list(/obj/structure/table/wood, - /obj/structure/table/wood/poker, - /obj/structure/table/wood/bar) - -/obj/structure/table/wood/narsie_act(total_override = TRUE) - if(!total_override) - ..() - -/obj/structure/table/wood/poker //No specialties, Just a mapping object. - name = "gambling table" - desc = "A seedy table for seedy dealings in seedy places." - icon = 'icons/obj/smooth_structures/poker_table.dmi' - icon_state = "poker_table" - buildstack = /obj/item/stack/tile/carpet - -/obj/structure/table/wood/poker/narsie_act() - ..(FALSE) - -/obj/structure/table/wood/fancy - name = "fancy table" - desc = "A standard metal table frame covered with an amazingly fancy, patterned cloth." - icon = 'icons/obj/structures.dmi' - icon_state = "fancy_table" - frame = /obj/structure/table_frame - framestack = /obj/item/stack/rods - buildstack = /obj/item/stack/tile/carpet - canSmoothWith = list(/obj/structure/table/wood/fancy, /obj/structure/table/wood/fancy/black, /obj/structure/table/wood/fancy/blackred, /obj/structure/table/wood/fancy/monochrome) - -/obj/structure/table/wood/fancy/New() - // New() is used so that the /black subtype can override `icon` easily and - // the correct value will be used by the smoothing subsystem. - . = ..() - // Needs to be set dynamically because table smooth sprites are 32x34, - // which the editor treats as a two-tile-tall object. The sprites are that - // size so that the north/south corners look nice - examine the detail on - // the sprites in the editor to see why. - icon = 'icons/obj/smooth_structures/fancy_table.dmi' - -/obj/structure/table/wood/fancy/black - icon_state = "fancy_table_black" - buildstack = /obj/item/stack/tile/carpet/black - -/obj/structure/table/wood/fancy/blackred - icon = 'icons/obj/structures.dmi' - icon_state = "fancy_table_blackred" - buildstack = /obj/item/stack/tile/carpet/blackred - -/obj/structure/table/wood/fancy/blackred/New() - . = ..() - icon = 'icons/obj/smooth_structures/fancy_table_blackred.dmi' - -/obj/structure/table/wood/fancy/monochrome - icon = 'icons/obj/structures.dmi' - icon_state = "fancy_table_monochrome" - buildstack = /obj/item/stack/tile/carpet/monochrome - -/obj/structure/table/wood/fancy/monochrome/New() - . = ..() - icon = 'icons/obj/smooth_structures/fancy_table_monochrome.dmi' - -/obj/structure/table/wood/fancy/black/New() - . = ..() - // Ditto above. - icon = 'icons/obj/smooth_structures/fancy_table_black.dmi' -/* - * Reinforced tables - */ -/obj/structure/table/reinforced - name = "reinforced table" - desc = "A reinforced version of the four legged table." - icon = 'icons/obj/smooth_structures/reinforced_table.dmi' - icon_state = "r_table" - deconstruction_ready = 0 - buildstack = /obj/item/stack/sheet/plasteel - canSmoothWith = list(/obj/structure/table/reinforced, /obj/structure/table) - max_integrity = 200 - integrity_failure = 50 - armor = list("melee" = 10, "bullet" = 30, "laser" = 30, "energy" = 100, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) - -/obj/structure/table/reinforced/deconstruction_hints(mob/user) - if(deconstruction_ready) - to_chat(user, "The top cover has been welded loose and the main frame's bolts are exposed.") - else - to_chat(user, "The top cover is firmly welded on.") - -/obj/structure/table/reinforced/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/weldingtool)) - if(!W.tool_start_check(user, amount=0)) - return - - if(deconstruction_ready) - to_chat(user, "You start strengthening the reinforced table...") - if (W.use_tool(src, user, 50, volume=50)) - to_chat(user, "You strengthen the table.") - deconstruction_ready = 0 - else - to_chat(user, "You start weakening the reinforced table...") - if (W.use_tool(src, user, 50, volume=50)) - to_chat(user, "You weaken the table.") - deconstruction_ready = 1 - else - . = ..() - -/obj/structure/table/reinforced/brass - name = "brass table" - desc = "A solid, slightly beveled brass table." - icon = 'icons/obj/smooth_structures/brass_table.dmi' - icon_state = "brass_table" - resistance_flags = FIRE_PROOF | ACID_PROOF - frame = /obj/structure/table_frame/brass - framestack = /obj/item/stack/tile/brass - buildstack = /obj/item/stack/tile/brass - framestackamount = 1 - buildstackamount = 1 - canSmoothWith = list(/obj/structure/table/reinforced/brass, /obj/structure/table/bronze) - -/obj/structure/table/reinforced/brass/New() - change_construction_value(2) - ..() - -/obj/structure/table/reinforced/brass/Destroy() - change_construction_value(-2) - return ..() - -/obj/structure/table/reinforced/brass/tablepush(mob/living/user, mob/living/pushed_mob) - .= ..() - playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 50, TRUE) - -/obj/structure/table/reinforced/brass/narsie_act() - take_damage(rand(15, 45), BRUTE) - if(src) //do we still exist? - var/previouscolor = color - color = "#960000" - animate(src, color = previouscolor, time = 8) - addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8) - -/obj/structure/table/reinforced/brass/ratvar_act() - obj_integrity = max_integrity - -/obj/structure/table/bronze - name = "bronze table" - desc = "A solid table made out of bronze." - icon = 'icons/obj/smooth_structures/brass_table.dmi' - icon_state = "brass_table" - resistance_flags = FIRE_PROOF | ACID_PROOF - buildstack = /obj/item/stack/tile/bronze - canSmoothWith = list(/obj/structure/table/reinforced/brass, /obj/structure/table/bronze) - -/obj/structure/table/bronze/tablepush(mob/living/user, mob/living/pushed_mob) - ..() - playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 50, TRUE) - -/* - * Surgery Tables - */ - -/obj/structure/table/optable - name = "operating table" - desc = "Used for advanced medical procedures." - icon = 'icons/obj/surgery.dmi' - icon_state = "optable" - buildstack = /obj/item/stack/sheet/mineral/silver - smooth = SMOOTH_FALSE - can_buckle = 1 - buckle_lying = 1 - buckle_requires_restraints = 1 - var/mob/living/carbon/human/patient = null - var/obj/machinery/computer/operating/computer = null - -/obj/structure/table/optable/New() - ..() - for(var/direction in GLOB.cardinals) - computer = locate(/obj/machinery/computer/operating, get_step(src, direction)) - if(computer) - computer.table = src - break - -/obj/structure/table/optable/tablepush(mob/living/user, mob/living/pushed_mob) - pushed_mob.forceMove(src.loc) - pushed_mob.resting = 1 - pushed_mob.update_canmove() - visible_message("[user] has laid [pushed_mob] on [src].") - check_patient() - -/obj/structure/table/optable/proc/check_patient() - var/mob/M = locate(/mob/living/carbon/human, loc) - if(M) - if(M.resting) - patient = M - return 1 - else - patient = null - return 0 - - - -/* - * Racks - */ -/obj/structure/rack - name = "rack" - desc = "Different from the Middle Ages version." - icon = 'icons/obj/objects.dmi' - icon_state = "rack" - layer = TABLE_LAYER - density = TRUE - anchored = TRUE - pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density. - max_integrity = 20 - -/obj/structure/rack/examine(mob/user) - . = ..() - . += "It's held together by a couple of bolts." - -/obj/structure/rack/CanPass(atom/movable/mover, turf/target) - if(src.density == 0) //Because broken racks -Agouri |TODO: SPRITE!| - return 1 - if(istype(mover) && (mover.pass_flags & PASSTABLE)) - return 1 - else - return 0 - -/obj/structure/rack/CanAStarPass(ID, dir, caller) - . = !density - if(ismovableatom(caller)) - var/atom/movable/mover = caller - . = . || (mover.pass_flags & PASSTABLE) - -/obj/structure/rack/MouseDrop_T(obj/O, mob/user) - . = ..() - if ((!( istype(O, /obj/item) ) || user.get_active_held_item() != O)) - return - if(!user.dropItemToGround(O)) - return - if(O.loc != src.loc) - step(O, get_dir(O, src)) - -/obj/structure/rack/attackby(obj/item/W, mob/user, params) - if (istype(W, /obj/item/wrench) && !(flags_1&NODECONSTRUCT_1)) - W.play_tool_sound(src) - deconstruct(TRUE) - return - if(user.a_intent == INTENT_HARM) - return ..() - if(user.transferItemToLoc(W, drop_location())) - return 1 - -/obj/structure/rack/attack_paw(mob/living/user) - attack_hand(user) - -/obj/structure/rack/attack_hand(mob/living/user) - . = ..() - if(.) - return - if(user.IsKnockdown() || user.resting || user.lying || user.get_num_legs() < 2) - return - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src, ATTACK_EFFECT_KICK) - user.visible_message("[user] kicks [src].", null, null, COMBAT_MESSAGE_RANGE) - take_damage(rand(4,8), BRUTE, "melee", 1) - -/obj/structure/rack/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - if(damage_amount) - playsound(loc, 'sound/items/dodgeball.ogg', 80, 1) - else - playsound(loc, 'sound/weapons/tap.ogg', 50, 1) - if(BURN) - playsound(loc, 'sound/items/welder.ogg', 40, 1) - -/* - * Rack destruction - */ - -/obj/structure/rack/deconstruct(disassembled = TRUE) - if(!(flags_1&NODECONSTRUCT_1)) - density = FALSE - var/obj/item/rack_parts/newparts = new(loc) - transfer_fingerprints_to(newparts) - qdel(src) - - -/* - * Rack Parts - */ - -/obj/item/rack_parts - name = "rack parts" - desc = "Parts of a rack." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "rack_parts" - flags_1 = CONDUCT_1 - materials = list(MAT_METAL=2000) - var/building = FALSE - -/obj/item/rack_parts/attackby(obj/item/W, mob/user, params) - if (istype(W, /obj/item/wrench)) - new /obj/item/stack/sheet/metal(user.loc) - qdel(src) - else - . = ..() - -/obj/item/rack_parts/attack_self(mob/user) - if(building) - return - building = TRUE - to_chat(user, "You start constructing a rack...") - if(do_after(user, 50, target = user, progress=TRUE)) - if(!user.temporarilyRemoveItemFromInventory(src)) - return - var/obj/structure/rack/R = new /obj/structure/rack(user.loc) - user.visible_message("[user] assembles \a [R].\ - ", "You assemble \a [R].") - R.add_fingerprint(user) - qdel(src) - building = FALSE +/* Tables and Racks + * Contains: + * Tables + * Glass Tables + * Wooden Tables + * Reinforced Tables + * Racks + * Rack Parts + */ + +/* + * Tables + */ + +/obj/structure/table + name = "table" + desc = "A square piece of metal standing on four metal legs. It can not move." + icon = 'icons/obj/smooth_structures/table.dmi' + icon_state = "table" + density = TRUE + anchored = TRUE + layer = TABLE_LAYER + climbable = TRUE + obj_flags = CAN_BE_HIT|SHOVABLE_ONTO + pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.") + var/frame = /obj/structure/table_frame + var/framestack = /obj/item/stack/rods + var/buildstack = /obj/item/stack/sheet/metal + var/busy = FALSE + var/buildstackamount = 1 + var/framestackamount = 2 + var/deconstruction_ready = 1 + max_integrity = 100 + integrity_failure = 30 + smooth = SMOOTH_TRUE + canSmoothWith = list(/obj/structure/table, /obj/structure/table/reinforced) + +/obj/structure/table/examine(mob/user) + . = ..() + . += deconstruction_hints(user) + +/obj/structure/table/proc/deconstruction_hints(mob/user) + return "The top is screwed on, but the main bolts are also visible." + +/obj/structure/table/update_icon() + if(smooth) + queue_smooth(src) + queue_smooth_neighbors(src) + +/obj/structure/table/narsie_act() + var/atom/A = loc + qdel(src) + new /obj/structure/table/wood(A) + +/obj/structure/table/ratvar_act() + var/atom/A = loc + qdel(src) + new /obj/structure/table/reinforced/brass(A) + +/obj/structure/table/attack_paw(mob/user) + return attack_hand(user) + +/obj/structure/table/attack_hand(mob/living/user) + if(Adjacent(user) && user.pulling) + if(isliving(user.pulling)) + var/mob/living/pushed_mob = user.pulling + if(pushed_mob.buckled) + to_chat(user, "[pushed_mob] is buckled to [pushed_mob.buckled]!") + return + if(user.a_intent == INTENT_GRAB) + if(user.grab_state < GRAB_AGGRESSIVE) + to_chat(user, "You need a better grip to do that!") + return + tablepush(user, pushed_mob) + if(user.a_intent == INTENT_HELP) + pushed_mob.visible_message("[user] begins to place [pushed_mob] onto [src]...", \ + "[user] begins to place [pushed_mob] onto [src]...") + if(do_after(user, 35, target = pushed_mob)) + tableplace(user, pushed_mob) + else + return + user.stop_pulling() + else if(user.pulling.pass_flags & PASSTABLE) + user.Move_Pulled(src) + if (user.pulling.loc == loc) + user.visible_message("[user] places [user.pulling] onto [src].", + "You place [user.pulling] onto [src].") + user.stop_pulling() + return ..() + +/obj/structure/table/attack_tk() + return FALSE + +/obj/structure/table/CanPass(atom/movable/mover, turf/target) + if(istype(mover) && (mover.pass_flags & PASSTABLE)) + return 1 + if(mover.throwing) + return 1 + if(locate(/obj/structure/table) in get_turf(mover)) + return 1 + else + return !density + +/obj/structure/table/CanAStarPass(ID, dir, caller) + . = !density + if(ismovableatom(caller)) + var/atom/movable/mover = caller + . = . || (mover.pass_flags & PASSTABLE) + +/obj/structure/table/proc/tableplace(mob/living/user, mob/living/pushed_mob) + pushed_mob.forceMove(src.loc) + pushed_mob.resting = TRUE + pushed_mob.update_canmove() + pushed_mob.visible_message("[user] places [pushed_mob] onto [src].", \ + "[user] places [pushed_mob] onto [src].") + log_combat(user, pushed_mob, "placed") + +/obj/structure/table/proc/tablepush(mob/living/user, mob/living/pushed_mob) + if(HAS_TRAIT(user, TRAIT_PACIFISM)) + to_chat(user, "Throwing [pushed_mob] onto the table might hurt them!") + return + var/added_passtable = FALSE + if(!pushed_mob.pass_flags & PASSTABLE) + added_passtable = TRUE + pushed_mob.pass_flags |= PASSTABLE + pushed_mob.Move(src.loc) + if(added_passtable) + pushed_mob.pass_flags &= ~PASSTABLE + if(pushed_mob.loc != loc) //Something prevented the tabling + return + pushed_mob.Knockdown(40) + pushed_mob.visible_message("[user] slams [pushed_mob] onto [src]!", \ + "[user] slams you onto [src]!") + log_combat(user, pushed_mob, "tabled", null, "onto [src]") + if(!ishuman(pushed_mob)) + return + var/mob/living/carbon/human/H = pushed_mob + SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table) + +/obj/structure/table/shove_act(mob/living/target, mob/living/user) + if(!target.resting) + target.Knockdown(SHOVE_KNOCKDOWN_TABLE) + user.visible_message("[user.name] shoves [target.name] onto \the [src]!", + "You shove [target.name] onto \the [src]!", null, COMBAT_MESSAGE_RANGE) + target.forceMove(src.loc) + log_combat(user, target, "shoved", "onto [src] (table)") + return TRUE + +/obj/structure/table/attackby(obj/item/I, mob/user, params) + if(!(flags_1 & NODECONSTRUCT_1)) + if(istype(I, /obj/item/screwdriver) && deconstruction_ready) + to_chat(user, "You start disassembling [src]...") + if(I.use_tool(src, user, 20, volume=50)) + deconstruct(TRUE) + return + + if(istype(I, /obj/item/wrench) && deconstruction_ready) + to_chat(user, "You start deconstructing [src]...") + if(I.use_tool(src, user, 40, volume=50)) + playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) + deconstruct(TRUE, 1) + return + + if(istype(I, /obj/item/storage/bag/tray)) + var/obj/item/storage/bag/tray/T = I + if(T.contents.len > 0) // If the tray isn't empty + SEND_SIGNAL(I, COMSIG_TRY_STORAGE_QUICK_EMPTY, drop_location()) + user.visible_message("[user] empties [I] on [src].") + return + // If the tray IS empty, continue on (tray will be placed on the table like other items) + + if(user.a_intent != INTENT_HARM && !(I.item_flags & ABSTRACT)) + if(user.transferItemToLoc(I, drop_location())) + var/list/click_params = params2list(params) + //Center the icon where the user clicked. + if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) + return + //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) + I.pixel_x = CLAMP(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + I.pixel_y = CLAMP(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) + return 1 + else + return ..() + + +/obj/structure/table/deconstruct(disassembled = TRUE, wrench_disassembly = 0) + if(!(flags_1 & NODECONSTRUCT_1)) + var/turf/T = get_turf(src) + new buildstack(T, buildstackamount) + if(!wrench_disassembly) + new frame(T) + else + new framestack(T, framestackamount) + qdel(src) + + +/* + * Glass tables + */ +/obj/structure/table/glass + name = "glass table" + desc = "What did I say about leaning on the glass tables? Now you need surgery." + icon = 'icons/obj/smooth_structures/glass_table.dmi' + icon_state = "glass_table" + buildstack = /obj/item/stack/sheet/glass + canSmoothWith = null + max_integrity = 70 + resistance_flags = ACID_PROOF + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + var/list/debris = list() + +/obj/structure/table/glass/New() + . = ..() + debris += new frame + debris += new /obj/item/shard + +/obj/structure/table/glass/Destroy() + QDEL_LIST(debris) + . = ..() + +/obj/structure/table/glass/Crossed(atom/movable/AM) + . = ..() + if(flags_1 & NODECONSTRUCT_1) + return + if(!isliving(AM)) + return + // Don't break if they're just flying past + if(AM.throwing) + addtimer(CALLBACK(src, .proc/throw_check, AM), 5) + else + check_break(AM) + +/obj/structure/table/glass/proc/throw_check(mob/living/M) + if(M.loc == get_turf(src)) + check_break(M) + +/obj/structure/table/glass/proc/check_break(mob/living/M) + if(M.has_gravity() && M.mob_size > MOB_SIZE_SMALL && !(M.movement_type & FLYING)) + table_shatter(M) + +/obj/structure/table/glass/proc/table_shatter(mob/living/L) + visible_message("[src] breaks!", + "You hear breaking glass.") + var/turf/T = get_turf(src) + playsound(T, "shatter", 50, 1) + for(var/I in debris) + var/atom/movable/AM = I + AM.forceMove(T) + debris -= AM + if(istype(AM, /obj/item/shard)) + AM.throw_impact(L) + L.Knockdown(100) + qdel(src) + +/obj/structure/table/glass/deconstruct(disassembled = TRUE, wrench_disassembly = 0) + if(!(flags_1 & NODECONSTRUCT_1)) + if(disassembled) + ..() + return + else + var/turf/T = get_turf(src) + playsound(T, "shatter", 50, 1) + for(var/X in debris) + var/atom/movable/AM = X + AM.forceMove(T) + debris -= AM + qdel(src) + +/obj/structure/table/glass/narsie_act() + color = NARSIE_WINDOW_COLOUR + for(var/obj/item/shard/S in debris) + S.color = NARSIE_WINDOW_COLOUR + +/* + * Plasmaglass tables + */ +/obj/structure/table/plasmaglass + name = "plasmaglass table" + desc = "A glasstable, but it's pink and more sturdy. What will Nanotrasen design next with plasma?" + icon = 'icons/obj/smooth_structures/plasmaglass_table.dmi' + icon_state = "plasmaglass_table" + climbable = TRUE + buildstack = /obj/item/stack/sheet/plasmaglass + canSmoothWith = null + max_integrity = 270 + resistance_flags = ACID_PROOF + armor = list("melee" = 10, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + var/list/debris = list() + +/obj/structure/table/plasmaglass/New() + . = ..() + debris += new frame + debris += new /obj/item/shard/plasma + +/obj/structure/table/plasmaglass/Destroy() + QDEL_LIST(debris) + . = ..() + +/obj/structure/table/plasmaglass/proc/check_break(mob/living/M) + return + +/obj/structure/table/plasmaglass/deconstruct(disassembled = TRUE, wrench_disassembly = 0) + if(!(flags_1 & NODECONSTRUCT_1)) + if(disassembled) + ..() + return + else + var/turf/T = get_turf(src) + playsound(T, "shatter", 50, 1) + for(var/X in debris) + var/atom/movable/AM = X + AM.forceMove(T) + debris -= AM + qdel(src) + +/obj/structure/table/plasmaglass/narsie_act() + color = NARSIE_WINDOW_COLOUR + for(var/obj/item/shard/S in debris) + S.color = NARSIE_WINDOW_COLOUR + +/* + * Wooden tables + */ + +/obj/structure/table/wood + name = "wooden table" + desc = "Do not apply fire to this. Rumour says it burns easily." + icon = 'icons/obj/smooth_structures/wood_table.dmi' + icon_state = "wood_table" + frame = /obj/structure/table_frame/wood + framestack = /obj/item/stack/sheet/mineral/wood + buildstack = /obj/item/stack/sheet/mineral/wood + resistance_flags = FLAMMABLE + max_integrity = 70 + canSmoothWith = list(/obj/structure/table/wood, + /obj/structure/table/wood/poker, + /obj/structure/table/wood/bar) + +/obj/structure/table/wood/narsie_act(total_override = TRUE) + if(!total_override) + ..() + +/obj/structure/table/wood/poker //No specialties, Just a mapping object. + name = "gambling table" + desc = "A seedy table for seedy dealings in seedy places." + icon = 'icons/obj/smooth_structures/poker_table.dmi' + icon_state = "poker_table" + buildstack = /obj/item/stack/tile/carpet + +/obj/structure/table/wood/poker/narsie_act() + ..(FALSE) + +/obj/structure/table/wood/fancy + name = "fancy table" + desc = "A standard metal table frame covered with an amazingly fancy, patterned cloth." + icon = 'icons/obj/structures.dmi' + icon_state = "fancy_table" + frame = /obj/structure/table_frame + framestack = /obj/item/stack/rods + buildstack = /obj/item/stack/tile/carpet + canSmoothWith = list(/obj/structure/table/wood/fancy, /obj/structure/table/wood/fancy/black, /obj/structure/table/wood/fancy/blackred, /obj/structure/table/wood/fancy/monochrome) + +/obj/structure/table/wood/fancy/New() + // New() is used so that the /black subtype can override `icon` easily and + // the correct value will be used by the smoothing subsystem. + . = ..() + // Needs to be set dynamically because table smooth sprites are 32x34, + // which the editor treats as a two-tile-tall object. The sprites are that + // size so that the north/south corners look nice - examine the detail on + // the sprites in the editor to see why. + icon = 'icons/obj/smooth_structures/fancy_table.dmi' + +/obj/structure/table/wood/fancy/black + icon_state = "fancy_table_black" + buildstack = /obj/item/stack/tile/carpet/black + +/obj/structure/table/wood/fancy/blackred + icon = 'icons/obj/structures.dmi' + icon_state = "fancy_table_blackred" + buildstack = /obj/item/stack/tile/carpet/blackred + +/obj/structure/table/wood/fancy/blackred/New() + . = ..() + icon = 'icons/obj/smooth_structures/fancy_table_blackred.dmi' + +/obj/structure/table/wood/fancy/monochrome + icon = 'icons/obj/structures.dmi' + icon_state = "fancy_table_monochrome" + buildstack = /obj/item/stack/tile/carpet/monochrome + +/obj/structure/table/wood/fancy/monochrome/New() + . = ..() + icon = 'icons/obj/smooth_structures/fancy_table_monochrome.dmi' + +/obj/structure/table/wood/fancy/black/New() + . = ..() + // Ditto above. + icon = 'icons/obj/smooth_structures/fancy_table_black.dmi' +/* + * Reinforced tables + */ +/obj/structure/table/reinforced + name = "reinforced table" + desc = "A reinforced version of the four legged table." + icon = 'icons/obj/smooth_structures/reinforced_table.dmi' + icon_state = "r_table" + deconstruction_ready = 0 + buildstack = /obj/item/stack/sheet/plasteel + canSmoothWith = list(/obj/structure/table/reinforced, /obj/structure/table) + max_integrity = 200 + integrity_failure = 50 + armor = list("melee" = 10, "bullet" = 30, "laser" = 30, "energy" = 100, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) + +/obj/structure/table/reinforced/deconstruction_hints(mob/user) + if(deconstruction_ready) + to_chat(user, "The top cover has been welded loose and the main frame's bolts are exposed.") + else + to_chat(user, "The top cover is firmly welded on.") + +/obj/structure/table/reinforced/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/weldingtool)) + if(!W.tool_start_check(user, amount=0)) + return + + if(deconstruction_ready) + to_chat(user, "You start strengthening the reinforced table...") + if (W.use_tool(src, user, 50, volume=50)) + to_chat(user, "You strengthen the table.") + deconstruction_ready = 0 + else + to_chat(user, "You start weakening the reinforced table...") + if (W.use_tool(src, user, 50, volume=50)) + to_chat(user, "You weaken the table.") + deconstruction_ready = 1 + else + . = ..() + +/obj/structure/table/reinforced/brass + name = "brass table" + desc = "A solid, slightly beveled brass table." + icon = 'icons/obj/smooth_structures/brass_table.dmi' + icon_state = "brass_table" + resistance_flags = FIRE_PROOF | ACID_PROOF + frame = /obj/structure/table_frame/brass + framestack = /obj/item/stack/tile/brass + buildstack = /obj/item/stack/tile/brass + framestackamount = 1 + buildstackamount = 1 + canSmoothWith = list(/obj/structure/table/reinforced/brass, /obj/structure/table/bronze) + +/obj/structure/table/reinforced/brass/New() + change_construction_value(2) + ..() + +/obj/structure/table/reinforced/brass/Destroy() + change_construction_value(-2) + return ..() + +/obj/structure/table/reinforced/brass/tablepush(mob/living/user, mob/living/pushed_mob) + .= ..() + playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 50, TRUE) + +/obj/structure/table/reinforced/brass/narsie_act() + take_damage(rand(15, 45), BRUTE) + if(src) //do we still exist? + var/previouscolor = color + color = "#960000" + animate(src, color = previouscolor, time = 8) + addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8) + +/obj/structure/table/reinforced/brass/ratvar_act() + obj_integrity = max_integrity + +/obj/structure/table/bronze + name = "bronze table" + desc = "A solid table made out of bronze." + icon = 'icons/obj/smooth_structures/brass_table.dmi' + icon_state = "brass_table" + resistance_flags = FIRE_PROOF | ACID_PROOF + buildstack = /obj/item/stack/tile/bronze + canSmoothWith = list(/obj/structure/table/reinforced/brass, /obj/structure/table/bronze) + +/obj/structure/table/bronze/tablepush(mob/living/user, mob/living/pushed_mob) + ..() + playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 50, TRUE) + +/* + * Surgery Tables + */ + +/obj/structure/table/optable + name = "operating table" + desc = "Used for advanced medical procedures." + icon = 'icons/obj/surgery.dmi' + icon_state = "optable" + buildstack = /obj/item/stack/sheet/mineral/silver + smooth = SMOOTH_FALSE + can_buckle = 1 + buckle_lying = 1 + buckle_requires_restraints = 1 + var/mob/living/carbon/human/patient = null + var/obj/machinery/computer/operating/computer = null + +/obj/structure/table/optable/New() + ..() + for(var/direction in GLOB.cardinals) + computer = locate(/obj/machinery/computer/operating, get_step(src, direction)) + if(computer) + computer.table = src + break + +/obj/structure/table/optable/tablepush(mob/living/user, mob/living/pushed_mob) + pushed_mob.forceMove(src.loc) + pushed_mob.resting = 1 + pushed_mob.update_canmove() + visible_message("[user] has laid [pushed_mob] on [src].") + check_patient() + +/obj/structure/table/optable/proc/check_patient() + var/mob/M = locate(/mob/living/carbon/human, loc) + if(M) + if(M.resting) + patient = M + return 1 + else + patient = null + return 0 + + + +/* + * Racks + */ +/obj/structure/rack + name = "rack" + desc = "Different from the Middle Ages version." + icon = 'icons/obj/objects.dmi' + icon_state = "rack" + layer = TABLE_LAYER + density = TRUE + anchored = TRUE + pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density. + max_integrity = 20 + +/obj/structure/rack/examine(mob/user) + . = ..() + . += "It's held together by a couple of bolts." + +/obj/structure/rack/CanPass(atom/movable/mover, turf/target) + if(src.density == 0) //Because broken racks -Agouri |TODO: SPRITE!| + return 1 + if(istype(mover) && (mover.pass_flags & PASSTABLE)) + return 1 + else + return 0 + +/obj/structure/rack/CanAStarPass(ID, dir, caller) + . = !density + if(ismovableatom(caller)) + var/atom/movable/mover = caller + . = . || (mover.pass_flags & PASSTABLE) + +/obj/structure/rack/MouseDrop_T(obj/O, mob/user) + . = ..() + if ((!( istype(O, /obj/item) ) || user.get_active_held_item() != O)) + return + if(!user.dropItemToGround(O)) + return + if(O.loc != src.loc) + step(O, get_dir(O, src)) + +/obj/structure/rack/attackby(obj/item/W, mob/user, params) + if (istype(W, /obj/item/wrench) && !(flags_1&NODECONSTRUCT_1)) + W.play_tool_sound(src) + deconstruct(TRUE) + return + if(user.a_intent == INTENT_HARM) + return ..() + if(user.transferItemToLoc(W, drop_location())) + return 1 + +/obj/structure/rack/attack_paw(mob/living/user) + attack_hand(user) + +/obj/structure/rack/attack_hand(mob/living/user) + . = ..() + if(.) + return + if(user.IsKnockdown() || user.resting || user.lying || user.get_num_legs() < 2) + return + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src, ATTACK_EFFECT_KICK) + user.visible_message("[user] kicks [src].", null, null, COMBAT_MESSAGE_RANGE) + take_damage(rand(4,8), BRUTE, "melee", 1) + +/obj/structure/rack/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + if(damage_amount) + playsound(loc, 'sound/items/dodgeball.ogg', 80, 1) + else + playsound(loc, 'sound/weapons/tap.ogg', 50, 1) + if(BURN) + playsound(loc, 'sound/items/welder.ogg', 40, 1) + +/* + * Rack destruction + */ + +/obj/structure/rack/deconstruct(disassembled = TRUE) + if(!(flags_1&NODECONSTRUCT_1)) + density = FALSE + var/obj/item/rack_parts/newparts = new(loc) + transfer_fingerprints_to(newparts) + qdel(src) + + +/* + * Rack Parts + */ + +/obj/item/rack_parts + name = "rack parts" + desc = "Parts of a rack." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "rack_parts" + flags_1 = CONDUCT_1 + materials = list(MAT_METAL=2000) + var/building = FALSE + +/obj/item/rack_parts/attackby(obj/item/W, mob/user, params) + if (istype(W, /obj/item/wrench)) + new /obj/item/stack/sheet/metal(user.loc) + qdel(src) + else + . = ..() + +/obj/item/rack_parts/attack_self(mob/user) + if(building) + return + building = TRUE + to_chat(user, "You start constructing a rack...") + if(do_after(user, 50, target = user, progress=TRUE)) + if(!user.temporarilyRemoveItemFromInventory(src)) + return + var/obj/structure/rack/R = new /obj/structure/rack(user.loc) + user.visible_message("[user] assembles \a [R].\ + ", "You assemble \a [R].") + R.add_fingerprint(user) + qdel(src) + building = FALSE +