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