diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index bbb8e32736..cac3fffad7 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -175,6 +175,7 @@ matter = list("glass" = 7500) origin_tech = "materials=3;phorontech=2" created_window = /obj/structure/window/phoronbasic + sheettype = "phoronglass" /obj/item/stack/sheet/glass/phoronglass/attackby(obj/item/W, mob/user) ..() diff --git a/code/game/objects/items/weapons/shards.dm b/code/game/objects/items/weapons/shards.dm index a383d8fb0c..593b3d019d 100644 --- a/code/game/objects/items/weapons/shards.dm +++ b/code/game/objects/items/weapons/shards.dm @@ -1,19 +1,22 @@ // Glass shards /obj/item/weapon/shard - name = "glass shard" + name = "shard" icon = 'icons/obj/shards.dmi' icon_state = "large" sharp = 1 edge = 1 - desc = "Could probably be used as ... a throwing weapon?" + desc = "Made of nothing. How does this even exist?" // set based on material, if this desc is visible it's a bug (shards default to being made of glass) w_class = 2.0 force = 5.0 throwforce = 8.0 item_state = "shard-glass" - matter = list("glass" = 3750) + //matter = list("glass" = 3750) // Weld it into sheets before you use it! attack_verb = list("stabbed", "slashed", "sliced", "cut") + gender = "neuter" + var/material/material = null + /obj/item/weapon/shard/suicide_act(mob/user) viewers(user) << pick("\red [user] is slitting \his wrists with \the [src]! It looks like \he's trying to commit suicide.", \ "\red [user] is slitting \his throat with \the [src]! It looks like \he's trying to commit suicide.") @@ -34,36 +37,54 @@ return return -/obj/item/weapon/shard/New() +/obj/item/weapon/shard/New(loc, material/material) + ..(loc) - src.icon_state = pick("large", "medium", "small") - switch(src.icon_state) - if("small") - src.pixel_x = rand(-12, 12) - src.pixel_y = rand(-12, 12) - if("medium") - src.pixel_x = rand(-8, 8) - src.pixel_y = rand(-8, 8) - if("large") - src.pixel_x = rand(-5, 5) - src.pixel_y = rand(-5, 5) + if(!material || !istype(material)) // We either don't have a material or we've been passed an invalid material. Use glass instead. + material = get_material_by_name("glass") + + set_material(material) + +/obj/item/weapon/shard/proc/set_material(material/material) + if(istype(material)) + src.material = material + icon_state = "[material.shard_icon][pick("large", "medium", "small")]" + pixel_x = rand(-8, 8) + pixel_y = rand(-8, 8) + update_material() + update_icon() + +/obj/item/weapon/shard/proc/update_material() + if(material) + if(material.shard_type) + name = "[material.display_name] [material.shard_type]" + desc = "A small piece of [material.display_name]. It looks sharp, you wouldn't want to step on it barefoot. Could probably be used as ... a throwing weapon?" + switch(material.shard_type) + if(SHARD_SPLINTER, SHARD_SHRAPNEL) + gender = "plural" + else + gender = "neuter" else - return + qdel(src) + return + else + name = initial(name) + desc = initial(desc) + +/obj/item/weapon/shard/update_icon() + if(material) + color = material.icon_colour + // 1-(1-x)^2, so that glass shards with 0.3 opacity end up somewhat visible at 0.51 opacity + alpha = 255 * (1 - (1 - material.opacity)*(1 - material.opacity)) + else + color = "#ffffff" + alpha = 255 /obj/item/weapon/shard/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - if ( istype(W, /obj/item/weapon/weldingtool)) + if(istype(W, /obj/item/weapon/weldingtool) && material.shard_can_repair) var/obj/item/weapon/weldingtool/WT = W if(WT.remove_fuel(0, user)) - 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) - usr << "You add the newly-formed glass to the stack. It now contains [NG.amount] sheets." - //SN src = null + material.place_sheet(loc) qdel(src) return return ..() @@ -90,26 +111,10 @@ H.Weaken(3) ..() -// Shrapnel +// Preset types - left here for the code that uses them -/obj/item/weapon/shard/shrapnel - name = "shrapnel" - icon = 'icons/obj/shards.dmi' - icon_state = "shrapnellarge" - desc = "A bunch of tiny bits of shattered metal." +/obj/item/weapon/shard/shrapnel/New(loc) + ..(loc, get_material_by_name("steel")) -/obj/item/weapon/shard/shrapnel/New() - - src.icon_state = pick("shrapnellarge", "shrapnelmedium", "shrapnelsmall") - switch(src.icon_state) - if("shrapnelsmall") - src.pixel_x = rand(-12, 12) - src.pixel_y = rand(-12, 12) - if("shrapnelmedium") - src.pixel_x = rand(-8, 8) - src.pixel_y = rand(-8, 8) - if("shrapnellarge") - src.pixel_x = rand(-5, 5) - src.pixel_y = rand(-5, 5) - else - return +/obj/item/weapon/shard/phoron/New(loc) + ..(loc, get_material_by_name("phoron glass")) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 52086c6228..928dbaf36a 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -189,7 +189,7 @@ var/list/global/wall_cache = list() new/obj/effect/overlay/wallrot(src) /turf/simulated/wall/proc/can_melt() - if(material.unmeltable) + if(material.flags & MATERIAL_UNMELTABLE) return 0 return 1 diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm index c791a8b560..d8309e5d6f 100644 --- a/code/modules/materials/materials.dm +++ b/code/modules/materials/materials.dm @@ -27,11 +27,11 @@ var/list/name_to_material /material var/name // Tag for use in overlay generation/list population . var/display_name + var/flags = 0 var/icon_base = "metal" var/icon_colour var/icon_reinf = "reinf_metal" var/stack_type - var/unmeltable var/cut_delay = 0 var/radioactivity var/ignition_point @@ -41,11 +41,17 @@ var/list/name_to_material var/rotting_touch_message = "crumbles under your touch" var/opacity = 1 var/explosion_resistance = 5 + var/shard_type = SHARD_SHRAPNEL + var/shard_icon + var/shard_can_repair = 1 + var/tableslam_noise = 'sound/weapons/tablehit1.ogg' /material/New() ..() if(!display_name) display_name = name + if(!shard_icon) + shard_icon = shard_type /material/proc/place_dismantled_girder(var/turf/target, var/material/reinf_material) var/obj/structure/girder/G = new(target) @@ -59,7 +65,14 @@ var/list/name_to_material /material/proc/place_sheet(var/turf/target) if(stack_type) - new stack_type(target) + return new stack_type(target) + +/material/proc/place_shard(var/turf/target) + if(shard_type) + return new /obj/item/weapon/shard(target, src) + +/material/proc/is_brittle() + return !!(flags & MATERIAL_BRITTLE) /material/uranium name = "uranium" @@ -72,10 +85,12 @@ var/list/name_to_material /material/diamond name = "diamond" stack_type = /obj/item/stack/sheet/mineral/diamond - unmeltable = 1 + flags = MATERIAL_UNMELTABLE cut_delay = 60 icon_colour = "#00FFE1" opacity = 0.4 + shard_type = SHARD_SHARD + tableslam_noise = 'sound/effects/Glasshit.ogg' /material/gold name = "gold" @@ -93,6 +108,7 @@ var/list/name_to_material ignition_point = 300 icon_base = "stone" icon_colour = "#FC2BC5" + shard_type = SHARD_SHARD /material/sandstone name = "sandstone" @@ -100,6 +116,7 @@ var/list/name_to_material icon_base = "stone" icon_reinf = "reinf_stone" icon_colour = "#D9C179" + shard_type = SHARD_STONE_PIECE /material/steel name = DEFAULT_WALL_MATERIAL @@ -112,6 +129,7 @@ var/list/name_to_material name = "holographic " + DEFAULT_WALL_MATERIAL display_name = DEFAULT_WALL_MATERIAL stack_type = null + shard_type = SHARD_NONE /material/plasteel name = "plasteel" @@ -126,13 +144,25 @@ var/list/name_to_material /material/glass name = "glass" stack_type = /obj/item/stack/sheet/glass + flags = MATERIAL_BRITTLE icon_colour = "#00E1FF" opacity = 0.3 integrity = 100 + shard_type = SHARD_SHARD + tableslam_noise = 'sound/effects/Glasshit.ogg' + +/material/glass/phoron + name = "phoron glass" + stack_type = /obj/item/stack/sheet/glass/phoronglass + flags = MATERIAL_BRITTLE + ignition_point = 300 + integrity = 200 // idk why but phoron windows are strong, so. + icon_colour = "#FC2BC5" /material/plastic name = "plastic" stack_type = /obj/item/stack/sheet/mineral/plastic + flags = MATERIAL_BRITTLE icon_base = "solid" icon_reinf = "reinf_over" icon_colour = "#CCCCCC" @@ -169,11 +199,14 @@ var/list/name_to_material integrity = 25 icon_base = "solid" explosion_resistance = 2 + shard_type = SHARD_SPLINTER + shard_can_repair = 0 // you can't weld splinters back into planks /material/wood/holographic name = "holographic wood" display_name = "wood" stack_type = null + shard_type = SHARD_NONE /material/cult name = "cult" @@ -181,6 +214,7 @@ var/list/name_to_material icon_base = "cult" icon_colour = "#402821" icon_reinf = "reinf_cult" + shard_type = SHARD_STONE_PIECE /material/cult/place_dismantled_girder(var/turf/target) new /obj/structure/girder/cult(target) @@ -193,4 +227,4 @@ var/list/name_to_material display_name = "human remains" /material/cult/reinf/place_dismantled_product(var/turf/target) - new /obj/effect/decal/remains/human(target) \ No newline at end of file + new /obj/effect/decal/remains/human(target) diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm index 7bab6d074c..bee6928a23 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm @@ -142,7 +142,7 @@ else if(istype(O, /turf/simulated/wall)) var/turf/simulated/wall/W = O - if(W.material.unmeltable) + if(W.material.flags & MATERIAL_UNMELTABLE) cannot_melt = 1 else if(istype(O, /turf/simulated/floor/engine)) cannot_melt = 1 diff --git a/code/modules/research/xenoarchaeology/finds/finds_misc.dm b/code/modules/research/xenoarchaeology/finds/finds_misc.dm index 8b7dd3fdfa..f494505b63 100644 --- a/code/modules/research/xenoarchaeology/finds/finds_misc.dm +++ b/code/modules/research/xenoarchaeology/finds/finds_misc.dm @@ -1,46 +1,5 @@ -/obj/item/weapon/shard/phoron - name = "phoron shard" - desc = "A shard of phoron glass. Considerably tougher then normal glass shards. Apparently not tough enough to be a window." - force = 8.0 - throwforce = 15.0 - icon_state = "phoronlarge" - sharp = 1 - edge = 1 - -/obj/item/weapon/shard/phoron/New() - - src.icon_state = pick("phoronlarge", "phoronmedium", "phoronsmall") - switch(src.icon_state) - if("phoronsmall") - src.pixel_x = rand(-12, 12) - src.pixel_y = rand(-12, 12) - if("phoronmedium") - src.pixel_x = rand(-8, 8) - src.pixel_y = rand(-8, 8) - if("phoronlarge") - src.pixel_x = rand(-5, 5) - src.pixel_y = rand(-5, 5) - else - return - -/obj/item/weapon/shard/phoron/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - if ( istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(WT.remove_fuel(0, user)) - var/obj/item/stack/sheet/glass/phoronglass/NG = new (user.loc) - for (var/obj/item/stack/sheet/glass/phoronglass/G in user.loc) - if(G==NG) - continue - if(G.amount>=G.max_amount) - continue - G.attackby(NG, user) - usr << "You add the newly-formed phoron glass to the stack. It now contains [NG.amount] sheets." - //SN src = null - qdel(src) - return - return ..() +// Phoron shards have been moved to code/game/objects/items/weapons/shards.dm //legacy crystal /obj/machinery/crystal diff --git a/code/modules/tables/interactions.dm b/code/modules/tables/interactions.dm index 7eed01c237..09e32deebe 100644 --- a/code/modules/tables/interactions.dm +++ b/code/modules/tables/interactions.dm @@ -83,8 +83,19 @@ if (prob(15)) M.Weaken(5) M.apply_damage(8,def_zone = "head") visible_message("[G.assailant] slams [G.affecting]'s face against \the [src]!") - playsound(src.loc, 'sound/weapons/tablehit1.ogg', 50, 1) - take_damage(rand(1,5)) + if(material) + playsound(loc, material.tableslam_noise, 50, 1) + else + playsound(loc, 'sound/weapons/tablehit1.ogg', 50, 1) + var/list/L = take_damage(rand(1,5)) + // Shards. Extra damage, plus potentially the fact YOU LITERALLY HAVE A PIECE OF GLASS/METAL/WHATEVER IN YOUR FACE + for(var/obj/item/weapon/shard/S in L) + if(prob(50)) + M.visible_message("\The [S] slices [M]'s face messily!", + "\The [S] slices your face messily!") + M.apply_damage(10, def_zone = "head") + if(prob(2)) + M.embed(S, def_zone = "head") else user << "You need a better grip to do that!" return diff --git a/code/modules/tables/tables.dm b/code/modules/tables/tables.dm index c5a1abc9c9..88042181a1 100644 --- a/code/modules/tables/tables.dm +++ b/code/modules/tables/tables.dm @@ -41,10 +41,17 @@ health += maxhealth - old_maxhealth /obj/structure/table/proc/take_damage(amount) + // If the table is made of a brittle material, and is *not* reinforced with a non-brittle material, damage is multiplied by TABLE_BRITTLE_MATERIAL_MULTIPLIER + if(material && material.is_brittle()) + if(reinforced) + if(reinforced.is_brittle()) + amount *= TABLE_BRITTLE_MATERIAL_MULTIPLIER + else + amount *= TABLE_BRITTLE_MATERIAL_MULTIPLIER health -= amount if(health <= 0) visible_message("\The [src] breaks down!") - break_to_parts() + return break_to_parts() // if we break and form shards, return them to the caller to do !FUN! things with /obj/structure/table/New() ..() @@ -68,6 +75,7 @@ /obj/structure/table/Destroy() material = null + reinforced = null update_connections(1) // Update tables around us to ignore us (material=null forces no connections) for(var/obj/structure/table/T in oview(src, 1)) T.update_icon() @@ -247,17 +255,39 @@ qdel(src) return +// Returns a list of /obj/item/weapon/shard objects that were created as a result of this table's breakage. +// Used for !fun! things such as embedding shards in the faces of tableslammed people. + +// The repeated +// S = [x].place_shard(loc) +// if(S) shards += S +// is to avoid filling the list with nulls, as place_shard won't place shards of certain materials (holo-wood, holo-steel) + /obj/structure/table/proc/break_to_parts(full_return = 0) - if(reinforced && reinforced.stack_type && (full_return || prob(25))) - new reinforced.stack_type(src.loc) - if(material && material.stack_type && (full_return || prob(50))) - new material.stack_type(src.loc) - if(carpeted && (full_return || prob(50))) + var/list/shards = list() + var/obj/item/weapon/shard/S = null + if(reinforced) + if(reinforced.stack_type && (full_return || prob(20))) + reinforced.place_sheet(loc) + else + S = reinforced.place_shard(loc) + if(S) shards += S + if(material) + if(material.stack_type && (full_return || prob(20))) + material.place_sheet(loc) + else + S = material.place_shard(loc) + if(S) shards += S + if(carpeted && (full_return || prob(50))) // Higher chance to get the carpet back intact, since there's no non-intact option new /obj/item/stack/tile/carpet(src.loc) - if(full_return || prob(50)) + if(full_return || prob(20)) new /obj/item/stack/sheet/metal(src.loc) + else + var/material/M = get_material_by_name(DEFAULT_WALL_MATERIAL) + S = M.place_shard(loc) + if(S) shards += S qdel(src) - return + return shards /obj/structure/table/update_icon() if(flipped != 1) diff --git a/code/setup.dm b/code/setup.dm index 7cbcf93bdd..2942d7447d 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -969,4 +969,15 @@ var/list/be_special_flags = list( #endif #ifndef CUSTOM_ITEM_MOB #define CUSTOM_ITEM_MOB 'icons/mob/custom_items_mob.dmi' -#endif \ No newline at end of file +#endif + +#define SHARD_SHARD "shard" +#define SHARD_SHRAPNEL "shrapnel" +#define SHARD_STONE_PIECE "piece" +#define SHARD_SPLINTER "splinters" +#define SHARD_NONE "" + +#define MATERIAL_UNMELTABLE 1 +#define MATERIAL_BRITTLE 2 + +#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass) \ No newline at end of file diff --git a/icons/obj/shards.dmi b/icons/obj/shards.dmi index 22f5e98314..e8bee2d57f 100644 Binary files a/icons/obj/shards.dmi and b/icons/obj/shards.dmi differ