diff --git a/code/datums/components/crafting/recipes.dm b/code/datums/components/crafting/recipes.dm index 110a19b2ed..98035259a2 100644 --- a/code/datums/components/crafting/recipes.dm +++ b/code/datums/components/crafting/recipes.dm @@ -71,6 +71,8 @@ var/obj/item/material/twohanded/spear/S = result S.set_material(M.material.name) + if(!(S.material.flags & MATERIAL_BRITTLE)) + S.fragile = FALSE qdel(M) /datum/crafting_recipe/surgerytable diff --git a/code/game/objects/items/weapons/material/material_weapons.dm b/code/game/objects/items/weapons/material/material_weapons.dm index cf000db8d7..9e6603be37 100644 --- a/code/game/objects/items/weapons/material/material_weapons.dm +++ b/code/game/objects/items/weapons/material/material_weapons.dm @@ -26,7 +26,7 @@ var/default_material = MAT_STEEL var/datum/material/material var/drops_debris = 1 - var/named_from_material = 1 //YW EDIT, Does it prepend the material's name to it's name? + var/named_from_material = TRUE /obj/item/material/Initialize(mapload, material_key) . = ..() @@ -65,7 +65,7 @@ if(!material) qdel(src) else - if(named_from_material) //YW EDIT + if(named_from_material) name = "[material.display_name] [initial(name)]" health = round(material.integrity/10) if(applies_material_colour) diff --git a/code/game/objects/items/weapons/traps.dm b/code/game/objects/items/weapons/traps.dm index 74b21ec156..438012bca5 100644 --- a/code/game/objects/items/weapons/traps.dm +++ b/code/game/objects/items/weapons/traps.dm @@ -21,6 +21,24 @@ var/deployed = 0 var/camo_net = FALSE var/stun_length = 0.25 SECONDS + slot_flags = SLOT_MASK + item_icons = list( + slot_wear_mask_str = 'icons/inventory/face/mob.dmi' + ) + +/obj/item/beartrap/equipped() + if(ishuman(src.loc)) + var/mob/living/carbon/human/H = src.loc + if(H.wear_mask == src) + add_verb(H, /mob/living/proc/shred_limb_temp) + else + remove_verb(H, /mob/living/proc/shred_limb_temp) + ..() + +/obj/item/beartrap/dropped(mob/user, equipping, slot) + remove_verb(user, /mob/living/proc/shred_limb_temp) + ..() + /obj/item/beartrap/start_active deployed = TRUE @@ -193,12 +211,13 @@ if(!QDELETED(src)) health = round(material.integrity / 3) - name = (material.get_edge_damage() * force_divisor > 15) ? "[material.display_name] razor wire" : "[material.display_name] [initial(name)]" + if(named_from_material) + name = (material.get_edge_damage() * force_divisor > 15) ? "[material.display_name] razor wire" : "[material.display_name] [initial(name)]" /obj/item/material/barbedwire/proc/can_use(mob/user) return (user.IsAdvancedToolUser() && !issilicon(user) && !user.stat && !user.restrained()) -/obj/item/material/barbedwire/attack_hand(mob/user as mob) +/obj/item/material/barbedwire/attack_hand(mob/user) if(anchored && can_use(user)) user.visible_message( span_danger("[user] starts to collect \the [src]."), @@ -242,7 +261,7 @@ anchored = TRUE update_icon() -/obj/item/material/barbedwire/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/material/barbedwire/attackby(obj/item/W, mob/user) if(!istype(W)) return @@ -275,7 +294,7 @@ else icon_state = "[initial(icon_state)]" -/obj/item/material/barbedwire/Crossed(atom/movable/AM as mob|obj) +/obj/item/material/barbedwire/Crossed(atom/movable/AM) if(AM.is_incorporeal()) return if(anchored && isliving(AM)) @@ -290,7 +309,7 @@ update_icon() ..() -/obj/item/material/barbedwire/proc/shock(mob/user as mob, prb, target_zone = BP_TORSO) +/obj/item/material/barbedwire/proc/shock(mob/user, prb, target_zone = BP_TORSO) if(!anchored || health == 0) // anchored/destroyed grilles are never connected return 0 if(material.conductivity <= 0) @@ -399,3 +418,21 @@ /obj/item/material/barbedwire/plastic name = "snare wire" default_material = MAT_PLASTIC + +/obj/item/material/barbedwire/plastic/starts_active + anchored = TRUE + +/obj/item/material/barbedwire/plastic/starts_active/Initialize(mapload, material_key) + . = ..() + update_icon() + +/obj/item/material/barbedwire/durasteel + name = "durasteel razor wire" + default_material = MAT_DURASTEEL + +/obj/item/material/barbedwire/durasteel/starts_active + anchored = TRUE + +/obj/item/material/barbedwire/durasteel/starts_active/Initialize(mapload, material_key) + . = ..() + update_icon() diff --git a/code/game/objects/items/weapons/traps_vr.dm b/code/game/objects/items/weapons/traps_vr.dm deleted file mode 100644 index 96a0f31968..0000000000 --- a/code/game/objects/items/weapons/traps_vr.dm +++ /dev/null @@ -1,18 +0,0 @@ -/obj/item/beartrap - slot_flags = SLOT_MASK - item_icons = list( - slot_wear_mask_str = 'icons/inventory/face/mob.dmi' - ) - -/obj/item/beartrap/equipped() - if(ishuman(src.loc)) - var/mob/living/carbon/human/H = src.loc - if(H.wear_mask == src) - add_verb(H, /mob/living/proc/shred_limb_temp) - else - remove_verb(H, /mob/living/proc/shred_limb_temp) - ..() - -/obj/item/beartrap/dropped(mob/user, equipping, slot) - remove_verb(user, /mob/living/proc/shred_limb_temp) - ..() diff --git a/code/game/objects/traps/aberrations/aberration.dm b/code/game/objects/traps/aberrations/aberration.dm new file mode 100644 index 0000000000..fe9239c453 --- /dev/null +++ b/code/game/objects/traps/aberrations/aberration.dm @@ -0,0 +1,55 @@ + +/obj/effect/abstract/abberation + name = "Abberation" + desc = "Some sort of weird, pulsating entity." + icon = 'icons/effects/effects.dmi' + icon_state = "pre_confuse" + alpha = 0 + + ///If the abberation starts active or not. + var/start_active = TRUE + + ///If the abberation has a toggling effect (Turns on-off) + var/enabled = FALSE + + ///If it pulses or not. i.e. has a non-continuous effect + var/pulses = FALSE + + ///Min time for pulses to occur + var/pulse_time_min = 15 + + ///Max time for pulses to occur + var/pulse_time_max = 30 + + ///The cooldown for our pulse + COOLDOWN_DECLARE(pulse) + +/obj/effect/abstract/abberation/Initialize(mapload) + . = ..() + if(start_active) + START_PROCESSING(SSobj, src) + +/obj/effect/abstract/abberation/Destroy() + . = ..() + STOP_PROCESSING(SSobj, src) + +/obj/effect/abstract/abberation/process() + if(COOLDOWN_FINISHED(src, pulse)) + perform_pulse() + COOLDOWN_START(src, pulse, rand(pulse_time_min, pulse_time_max)) + perform_ambient_effects() + +/obj/effect/abstract/abberation/proc/perform_pulse() + return + +/obj/effect/abstract/abberation/proc/perform_ambient_effects() + return + + +/* +//Useful for later + var/static/list/connections = list( + COMSIG_ATOM_ENTERED = PROC_REF(ignite_the_unworthy), + ) + AddComponent(/datum/component/connect_range, src, connections, range) +*/ diff --git a/code/game/objects/traps/aberrations/mapped.dm b/code/game/objects/traps/aberrations/mapped.dm new file mode 100644 index 0000000000..1cc03ecae7 --- /dev/null +++ b/code/game/objects/traps/aberrations/mapped.dm @@ -0,0 +1,10 @@ +/obj/random/aberration + name = "Random Abberation" + desc = "This is a random abberation." + icon = 'icons/obj/toy.dmi' + icon_state = "generic" + spawn_nothing_percentage = 25 + +/obj/random/aberration/item_to_spawn() + return pick(prob(15);/obj/effect/abstract/abberation/spawner/fire, + prob(15);/obj/effect/abstract/abberation/spawner/glass) diff --git a/code/game/objects/traps/aberrations/spawners/_spawner.dm b/code/game/objects/traps/aberrations/spawners/_spawner.dm new file mode 100644 index 0000000000..e5bb7f4bb7 --- /dev/null +++ b/code/game/objects/traps/aberrations/spawners/_spawner.dm @@ -0,0 +1,46 @@ +//Fire abberation +/obj/effect/abstract/abberation/spawner + name = "Spawner Abberation" + + ///What range we spawn our effects. + var/range = 4 + + ///If we use random range or not + var/random_range = TRUE + + ///Minimum range of effects + var/random_min = 3 + + ///Maximum range of effects + var/random_max = 5 + + ///How much the % chance drops the further it goes outwards. Avoids having a giant square. + var/percent_drop = 15 + + ///What effect we spawn + var/effect_to_spawn + + ///If we qdel after we place our stuff or not. + var/delete_after_placement = TRUE + + start_active = FALSE + + +/obj/effect/abstract/abberation/spawner/Initialize(mapload) + if(!effect_to_spawn) + return INITIALIZE_HINT_QDEL + . = ..() + if(random_range) + range = rand(random_min, random_max) + place_effects() + if(delete_after_placement) + return INITIALIZE_HINT_QDEL + +/obj/effect/abstract/abberation/spawner/proc/place_effects() + for(var/turf/simulated/turf in range(src, range)) + var/how_far = get_dist(src, turf) + if(prob(100 - ((how_far - 1) * percent_drop))) //100% at 1 range, 85 at 2 range, 70 at 3, 55 at 4, 40 at 5 + var/obj/thing_to_find = locate(effect_to_spawn) in turf + if(thing_to_find) + continue + new effect_to_spawn(turf) diff --git a/code/game/objects/traps/aberrations/spawners/fire.dm b/code/game/objects/traps/aberrations/spawners/fire.dm new file mode 100644 index 0000000000..6b238c0a7e --- /dev/null +++ b/code/game/objects/traps/aberrations/spawners/fire.dm @@ -0,0 +1,34 @@ +//Fire abberation +/obj/effect/abstract/abberation/spawner/fire + name = "Fire Abberation" + effect_to_spawn = /obj/effect/abberation_fire + +//The things that actually light you on fire. +/obj/effect/abberation_fire + icon = 'icons/obj/traps/abberations.dmi' + icon_state = "abb_fire" + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + COOLDOWN_DECLARE(fire_timer) + +/obj/effect/abberation_fire/Crossed(atom/movable/AM) + if(AM.is_incorporeal() || isobserver(AM) || istype(AM, /obj/effect/abstract)) + return + if(isobj(AM)) + var/obj/item/item_check = AM + if(item_check.item_flags & ABSTRACT) + return + if(COOLDOWN_FINISHED(src, fire_timer)) + ignite_entity(AM) + +/obj/effect/abberation_fire/proc/reset_trap() + for(var/mob/living/living_being in get_turf(src)) + if(living_being.is_incorporeal()) + continue + ignite_entity(living_being) //Begin anew + +/obj/effect/abberation_fire/proc/ignite_entity(atom/movable/AM) + AM.fire_act(null, 10000, 1000) + alpha = 125 + animate(src, alpha = 255, time = 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(reset_trap)), 2 SECONDS, TIMER_DELETE_ME|TIMER_UNIQUE) //Calling a proc with no arguments + COOLDOWN_START(src, fire_timer, 2 SECONDS) diff --git a/code/game/objects/traps/aberrations/spawners/glass.dm b/code/game/objects/traps/aberrations/spawners/glass.dm new file mode 100644 index 0000000000..1cfc688c4e --- /dev/null +++ b/code/game/objects/traps/aberrations/spawners/glass.dm @@ -0,0 +1,10 @@ +//Fire abberation +/obj/effect/abstract/abberation/spawner/glass + name = "Glass Abberation" + effect_to_spawn = /obj/item/material/barbedwire/glass/start_active + start_active = TRUE + delete_after_placement = FALSE + +/obj/effect/abstract/abberation/spawner/glass/perform_pulse() + place_effects() + return diff --git a/code/game/objects/traps/glass_wire.dm b/code/game/objects/traps/glass_wire.dm new file mode 100644 index 0000000000..2a9a786e32 --- /dev/null +++ b/code/game/objects/traps/glass_wire.dm @@ -0,0 +1,106 @@ +/obj/item/material/barbedwire/glass + name = "glass wire" + desc = "Thin webs of strewn glass, very easy to break." + icon = 'icons/obj/traps/abberations.dmi' + icon_state = "abb_glass" + default_material = MAT_GLASS + applies_material_colour = FALSE + named_from_material = FALSE + drops_debris = FALSE + +/obj/item/material/barbedwire/glass/start_active + anchored = TRUE + +/obj/item/material/barbedwire/glass/start_active/Initialize(mapload, material_key) + . = ..() + update_icon() + +/obj/item/material/barbedwire/glass/attack_hand(mob/user) + playsound(src, 'sound/effects/glass_step.ogg', 50, 1) + user.visible_message( + span_danger("[user] touches \the [src] and it shatters."), + span_notice("You touch \the [src] and it shatters!") + ) + //also cut hands if gloves are not thick, TODO. + health = 0 //Instantly shatters. + check_health() + return + +/obj/item/material/barbedwire/glass/attackby(obj/item/W, mob/user) + if(!istype(W)) + return + + user.setClickCooldown(user.get_attack_speed(W)) + user.do_attack_animation(src) + playsound(src, 'sound/effects/grillehit.ogg', 40, 1) + health = 0 //Instantly shatters. + check_health() + +/obj/item/material/barbedwire/glass/update_icon() + ..() + icon_state = "abb_glass" + +/obj/item/material/barbedwire/glass/Crossed(atom/movable/AM) + if(AM.is_incorporeal()) + return + if(anchored) + if(isliving(AM)) + var/mob/living/L = AM + L.visible_message( + span_danger("[L] steps in \the [src]."), + span_danger("You step in \the [src]!"), + span_infoplain(span_bold("You hear a sharp rustling!")) + ) + attack_mob(L) + update_icon() + else + health = 0 + check_health() + +/obj/item/material/barbedwire/glass/attack_mob(mob/living/L) + L.add_modifier(/datum/modifier/entangled, 3 SECONDS) + + var/target_zone = ran_zone() + var/obj/item/organ/external/affecting = L.get_organ(target_zone) + + //armour + var/blocked = L.run_armor_check(target_zone, "melee") + if(!affecting) //touched a limb that doesn't exist + break_wire() + to_chat(L, span_danger("You narrowly avoid being cut by \the [src]!")) + return + + //Check the list of clothing for thick materials. + var/list/our_clothing = affecting.get_covering_clothing() + for(var/obj/item/clothing/gear in our_clothing) + if(gear.item_flags & THICKMATERIAL) + break_wire() + to_chat(L, span_danger("Your [gear] snags on \the [src], shattering it and protecting you!")) + return + + if(blocked >= 100) + break_wire() + to_chat(L, span_danger("Your equipment protects you from \the [src]!")) + return + + if(!L.apply_damage(force * (issilicon(L) ? 0.25 : 1), BRUTE, target_zone, blocked, sharp, edge, src)) + break_wire() + to_chat(L, span_danger("You narrowly avoid being cut by \the [src]!")) + return + + to_chat(L, span_danger("You're cut by \the [src]!")) + + if(ishuman(L)) + var/mob/living/carbon/human/human_target = L + if(affecting && (affecting.robotic < ORGAN_ROBOT) && (affecting.take_damage(brute = force, sharp = TRUE, edge = TRUE, used_weapon = "Glass strands"))) + affecting.open = TRUE + human_target.UpdateDamageIcon() + human_target.updatehealth() + + break_wire() + return + +/obj/item/material/barbedwire/glass/proc/break_wire() + playsound(src, 'sound/effects/glass_step.ogg', 50, 1) + health = 0 + check_health() diff --git a/code/modules/materials/materials/alien_alloy.dm b/code/modules/materials/materials/alien_alloy.dm index f56ee5841c..77e04d444b 100644 --- a/code/modules/materials/materials/alien_alloy.dm +++ b/code/modules/materials/materials/alien_alloy.dm @@ -13,6 +13,7 @@ protectiveness = 80 // 80% wiki_flag = WIKI_SPOILER supply_conversion_value = 5 // Neat if you somehow manage to sell this + shard_type = null /datum/material/alienalloy/elevatorium name = MAT_ALIEN_ELEVAT diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index 8bb396b61d..abb4c28963 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -349,6 +349,7 @@ span_notice("You cauterize the incision on [target]'s [affected.name] with \the [tool].")) user.balloon_alert_visible("cauterizes the incision on [target]'s [affected.name]", "incison cauterized on \the [affected.name]") affected.open = 0 + affected.organ_clamp() //Technically cauterizing them, but this does the same on the backend. affected.germ_level = 0 affected.status &= ~ORGAN_BLEEDING diff --git a/icons/obj/traps/abberations.dmi b/icons/obj/traps/abberations.dmi new file mode 100644 index 0000000000..6316b9f597 Binary files /dev/null and b/icons/obj/traps/abberations.dmi differ diff --git a/vorestation.dme b/vorestation.dme index 194c8d6232..4958862a94 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -1908,7 +1908,6 @@ #include "code\game\objects\items\weapons\teleportation.dm" #include "code\game\objects\items\weapons\towels.dm" #include "code\game\objects\items\weapons\traps.dm" -#include "code\game\objects\items\weapons\traps_vr.dm" #include "code\game\objects\items\weapons\trays.dm" #include "code\game\objects\items\weapons\weaponry.dm" #include "code\game\objects\items\weapons\weldbackpack.dm" @@ -2227,6 +2226,12 @@ #include "code\game\objects\structures\stool_bed_chair_nest\stools_vr.dm" #include "code\game\objects\structures\stool_bed_chair_nest\wheelchair.dm" #include "code\game\objects\structures\stool_bed_chair_nest\wheelchair_item.dm" +#include "code\game\objects\traps\glass_wire.dm" +#include "code\game\objects\traps\aberrations\aberration.dm" +#include "code\game\objects\traps\aberrations\mapped.dm" +#include "code\game\objects\traps\aberrations\spawners\_spawner.dm" +#include "code\game\objects\traps\aberrations\spawners\fire.dm" +#include "code\game\objects\traps\aberrations\spawners\glass.dm" #include "code\game\turfs\glamour_turfs.dm" #include "code\game\turfs\simulated.dm" #include "code\game\turfs\simulated_vr.dm"