diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 98cf20d05b6..fa10020d4d1 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -50,6 +50,8 @@ #define STATUS_EFFECT_CRUSHERMARK /datum/status_effect/crusher_mark //if struck with a proto-kinetic crusher, takes a ton of damage +#define STATUS_EFFECT_SAWBLEED /datum/status_effect/saw_bleed //if the bleed builds up enough, takes a ton of damage + ///////////// // NEUTRAL // ///////////// diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 139417ffa0d..5966f263bac 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -271,3 +271,75 @@ /datum/status_effect/crusher_mark/be_replaced() owner.underlays -= marked_underlay //if this is being called, we should have an owner at this point. ..() + +/datum/status_effect/saw_bleed + id = "saw_bleed" + duration = -1 //removed under specific conditions + tick_interval = 6 + alert_type = null + var/mutable_appearance/bleed_overlay + var/mutable_appearance/bleed_underlay + var/bleed_amount = 3 + var/bleed_buildup = 3 + var/delay_before_decay = 5 + var/bleed_damage = 200 + var/needs_to_bleed = FALSE + +/datum/status_effect/saw_bleed/Destroy() + if(owner) + owner.cut_overlay(bleed_overlay) + owner.underlays -= bleed_underlay + QDEL_NULL(bleed_overlay) + return ..() + +/datum/status_effect/saw_bleed/on_apply() + if(owner.stat == DEAD) + return FALSE + bleed_overlay = mutable_appearance('icons/effects/bleed.dmi', "bleed[bleed_amount]") + bleed_underlay = mutable_appearance('icons/effects/bleed.dmi', "bleed[bleed_amount]") + var/icon/I = icon(owner.icon, owner.icon_state, owner.dir) + var/icon_height = I.Height() + bleed_overlay.pixel_x = -owner.pixel_x + bleed_overlay.pixel_y = Floor(icon_height * 0.25) + bleed_overlay.transform = matrix() * (icon_height/world.icon_size) //scale the bleed overlay's size based on the target's icon size + bleed_underlay.pixel_x = -owner.pixel_x + bleed_underlay.transform = matrix() * (icon_height/world.icon_size) * 4 + bleed_underlay.alpha = 40 + owner.add_overlay(bleed_overlay) + owner.underlays += bleed_underlay + return ..() + +/datum/status_effect/saw_bleed/tick() + if(owner.stat == DEAD) + qdel(src) + else + add_bleed(-1) + +/datum/status_effect/saw_bleed/proc/add_bleed(amount) + owner.cut_overlay(bleed_overlay) + owner.underlays -= bleed_underlay + bleed_amount += amount + if(bleed_amount) + if(bleed_amount >= 10) + needs_to_bleed = TRUE + qdel(src) + else + if(amount > 0) + tick_interval += delay_before_decay + bleed_overlay.icon_state = "bleed[bleed_amount]" + bleed_underlay.icon_state = "bleed[bleed_amount]" + owner.add_overlay(bleed_overlay) + owner.underlays += bleed_underlay + else + qdel(src) + +/datum/status_effect/saw_bleed/on_remove() + if(needs_to_bleed) + var/turf/T = get_turf(owner) + new /obj/effect/temp_visual/bleed/explode(T) + for(var/d in GLOB.alldirs) + new /obj/effect/temp_visual/dir_setting/bloodsplatter(T, d) + playsound(T, "desceration", 200, 1, -1) + owner.adjustBruteLoss(bleed_damage) + else + new /obj/effect/temp_visual/bleed(get_turf(owner)) diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 6fd05309359..7ace17b82f6 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -312,3 +312,30 @@ pixel_x = rand(-4,4) pixel_y = rand(-4,4) animate(src, pixel_y = pixel_y + 32, alpha = 0, time = 25) + +/obj/effect/temp_visual/bleed + name = "bleed" + icon = 'icons/effects/bleed.dmi' + icon_state = "bleed0" + duration = 10 + var/shrink = TRUE + +/obj/effect/temp_visual/bleed/Initialize(mapload, atom/size_calc_target) + . = ..() + var/size_matrix = matrix() + if(size_calc_target) + layer = size_calc_target.layer + 0.01 + var/icon/I = icon(size_calc_target.icon, size_calc_target.icon_state, size_calc_target.dir) + size_matrix = matrix() * (I.Height()/world.icon_size) + transform = size_matrix //scale the bleed overlay's size based on the target's icon size + var/matrix/M = transform + if(shrink) + M = size_matrix*0.1 + else + M = size_matrix*2 + animate(src, alpha = 20, transform = M, time = duration, flags = ANIMATION_PARALLEL) + +/obj/effect/temp_visual/bleed/explode + icon_state = "bleed10" + duration = 12 + shrink = FALSE diff --git a/code/game/objects/items/weapons/melee/transforming.dm b/code/game/objects/items/weapons/melee/transforming.dm new file mode 100644 index 00000000000..9b31e0eb51d --- /dev/null +++ b/code/game/objects/items/weapons/melee/transforming.dm @@ -0,0 +1,58 @@ +/obj/item/weapon/melee/transforming //TODO: make transforming energy weapons a subtype of this + var/active = FALSE + var/force_on = 30 //force when active + var/throwforce_on = 20 + var/icon_state_on = "axe1" + var/hitsound_on = 'sound/weapons/blade1.ogg' + var/list/attack_verb_on = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + var/list/attack_verb_off = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + w_class = WEIGHT_CLASS_SMALL + sharpness = IS_SHARP + var/w_class_on = WEIGHT_CLASS_BULKY + +/obj/item/weapon/melee/transforming/Initialize() + . = ..() + if(active) + if(attack_verb_on.len) + attack_verb = attack_verb_on + else + if(attack_verb_off.len) + attack_verb = attack_verb_off + +/obj/item/weapon/melee/transforming/attack_self(mob/living/carbon/user) + if(transform_weapon(user)) + clumsy_transform_effect(user) + +/obj/item/weapon/melee/transforming/proc/transform_weapon(mob/living/user, supress_message_text) + active = !active + if(active) + force = force_on + throwforce = throwforce_on + hitsound = hitsound_on + throw_speed = 4 + if(attack_verb_on.len) + attack_verb = attack_verb_on + icon_state = icon_state_on + w_class = w_class_on + else + force = initial(force) + throwforce = initial(throwforce) + hitsound = initial(hitsound) + throw_speed = initial(throw_speed) + if(attack_verb_off.len) + attack_verb = attack_verb_off + icon_state = initial(icon_state) + w_class = initial(w_class) + transform_messages(user, supress_message_text) + add_fingerprint(user) + return TRUE + +/obj/item/weapon/melee/transforming/proc/transform_messages(mob/living/user, supress_message_text) + playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1) //changed it from 50% volume to 35% because deafness + if(!supress_message_text) + to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") + +/obj/item/weapon/melee/transforming/proc/clumsy_transform_effect(mob/living/user) + if(user.disabilities & CLUMSY && prob(50)) + to_chat(user, "You accidentally cut yourself with [src], like a doofus!") + user.take_bodypart_damage(5,5) \ No newline at end of file diff --git a/code/game/sound.dm b/code/game/sound.dm index fb6955ae624..fa311c5ece5 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -131,6 +131,8 @@ soundin = pick('sound/machines/terminal_button01.ogg', 'sound/machines/terminal_button02.ogg', 'sound/machines/terminal_button03.ogg', \ 'sound/machines/terminal_button04.ogg', 'sound/machines/terminal_button05.ogg', 'sound/machines/terminal_button06.ogg', \ 'sound/machines/terminal_button07.ogg', 'sound/machines/terminal_button08.ogg') + if ("desceration") + soundin = pick('sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg') return soundin /proc/playsound_global(file, repeat=0, wait, channel, volume) diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 77a914cbb58..156fd1a5d53 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -528,8 +528,99 @@ ///Bosses +//Miniboss Miner +/obj/item/weapon/melee/transforming/cleaving_saw + name = "cleaving saw" + desc = "This saw, effective at drawing the blood of beasts, transforms into a long cleaver that makes use of centrifugal force." + force = 12 + force_on = 20 //force when active + throwforce = 20 + throwforce_on = 20 + icon = 'icons/obj/lavaland/artefacts.dmi' + lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi' + righthand_file = 'icons/mob/inhands/64x64_righthand.dmi' + inhand_x_dimension = 64 + inhand_y_dimension = 64 + icon_state = "cleaving_saw" + icon_state_on = "cleaving_saw_open" + slot_flags = SLOT_BELT + attack_verb_off = list("attacked", "sawed", "sliced", "torn", "ripped", "diced", "cut") + attack_verb_on = list("cleaved", "swiped", "slashed", "chopped") + hitsound = 'sound/weapons/bladeslice.ogg' + hitsound_on = 'sound/weapons/bladeslice.ogg' + w_class = WEIGHT_CLASS_BULKY + sharpness = IS_SHARP + var/transform_cooldown + var/swiping = FALSE + var/beast_force_bonus = 30 +/obj/item/weapon/melee/transforming/cleaving_saw/examine(mob/user) + ..() + to_chat(user, "It is [active ? "open, and will cleave enemies in a wide arc":"closed, and can be used for rapid consecutive attacks that cause beastly enemies to bleed"].
\ + Both modes will build up existing bleed effects, doing a burst of high damage if the bleed is built up high enough.
\ + Transforming it immediately after an attack causes the next attack to come out faster.
") + +/obj/item/weapon/melee/transforming/cleaving_saw/suicide_act(mob/user) + user.visible_message("[user] is [active ? "closing [src] on [user.p_their()] neck" : "opening [src] into [user.p_their()] chest"]! It looks like [user.p_theyre()] trying to commit suicide!") + transform_cooldown = 0 + transform_weapon(user, TRUE) + return BRUTELOSS + +/obj/item/weapon/melee/transforming/cleaving_saw/transform_weapon(mob/living/user, supress_message_text) + if(transform_cooldown > world.time) + return FALSE + . = ..() + if(.) + transform_cooldown = world.time + (CLICK_CD_MELEE * 0.5) + user.changeNext_move(CLICK_CD_MELEE * 0.25) + +/obj/item/weapon/melee/transforming/cleaving_saw/transform_messages(mob/living/user, supress_message_text) + if(!supress_message_text) + if(active) + to_chat(user, "You open [src]. It will now cleave enemies in a wide arc.") + else + to_chat(user, "You close [src]. It will now attack rapidly and cause beastly enemies to bleed.") + playsound(user, 'sound/magic/clockwork/fellowship_armory.ogg', 35, TRUE, frequency = 90000 - (active * 30000)) + +/obj/item/weapon/melee/transforming/cleaving_saw/clumsy_transform_effect(mob/living/user) + if(user.disabilities & CLUMSY && prob(50)) + to_chat(user, "You accidentally cut yourself with [src], like a doofus!") + user.take_bodypart_damage(10) + +/obj/item/weapon/melee/transforming/cleaving_saw/melee_attack_chain(mob/user, atom/target, params) + ..() + if(!active) + user.changeNext_move(CLICK_CD_MELEE * 0.5) //when closed, it attacks very rapidly + +/obj/item/weapon/melee/transforming/cleaving_saw/attack(mob/living/target, mob/living/carbon/human/user) + if(!active || swiping || !target.density || get_turf(target) == get_turf(user)) + var/beast_bonus_active = FALSE + var/datum/status_effect/saw_bleed/B = target.has_status_effect(STATUS_EFFECT_SAWBLEED) + if(istype(target, /mob/living/simple_animal/hostile/asteroid) || ismegafauna(target)) + if(!active) + if(!B) + target.apply_status_effect(STATUS_EFFECT_SAWBLEED) + else + B.add_bleed(B.bleed_buildup) + else + force += beast_force_bonus //we do bonus damage against beastly creatures + beast_bonus_active = TRUE + ..() + if(beast_bonus_active) + if(B) + B.add_bleed(B.bleed_buildup) + force -= beast_force_bonus + return + var/turf/user_turf = get_turf(user) + var/dir_to_target = get_dir(user_turf, get_turf(target)) + swiping = TRUE + for(var/i in 1 to 3) + var/turf/T = get_step(user_turf, turn(dir_to_target, 90 - (45 * i))) + for(var/mob/living/L in T) + if(user.Adjacent(L) && L.density) + melee_attack_chain(user, L) + swiping = FALSE //Dragon diff --git a/icons/effects/bleed.dmi b/icons/effects/bleed.dmi new file mode 100644 index 00000000000..c41787de32a Binary files /dev/null and b/icons/effects/bleed.dmi differ diff --git a/icons/mob/inhands/64x64_lefthand.dmi b/icons/mob/inhands/64x64_lefthand.dmi index 434756a784a..ba2f54dac33 100644 Binary files a/icons/mob/inhands/64x64_lefthand.dmi and b/icons/mob/inhands/64x64_lefthand.dmi differ diff --git a/icons/mob/inhands/64x64_righthand.dmi b/icons/mob/inhands/64x64_righthand.dmi index d148fbdec2d..05023605fad 100644 Binary files a/icons/mob/inhands/64x64_righthand.dmi and b/icons/mob/inhands/64x64_righthand.dmi differ diff --git a/icons/obj/lavaland/artefacts.dmi b/icons/obj/lavaland/artefacts.dmi index ca254e47e75..e5d3af3dd9b 100644 Binary files a/icons/obj/lavaland/artefacts.dmi and b/icons/obj/lavaland/artefacts.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 4fe60be07d5..fbfa4b80019 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -858,6 +858,7 @@ #include "code\game\objects\items\weapons\implants\implantuplink.dm" #include "code\game\objects\items\weapons\melee\energy.dm" #include "code\game\objects\items\weapons\melee\misc.dm" +#include "code\game\objects\items\weapons\melee\transforming.dm" #include "code\game\objects\items\weapons\storage\backpack.dm" #include "code\game\objects\items\weapons\storage\bags.dm" #include "code\game\objects\items\weapons\storage\belt.dm"