diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 4b7db053bd8..3c0f7623b63 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -5,9 +5,13 @@ var/active_w_class sharp = 0 edge = 0 - armor_penetration = 50 + armor_penetration = 10 flags = NOBLOODY can_embed = 0//No embedding pls + var/base_reflectchance = 40 + var/base_block_chance = 25 + var/shield_power = 100 + var/can_block_bullets = 0 var/datum/effect_system/sparks/spark_system /obj/item/weapon/melee/energy/New() @@ -56,6 +60,66 @@ add_fingerprint(user) return +/obj/item/weapon/melee/energy/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") + if(active && default_parry_check(user, attacker, damage_source) && prob(50)) + user.visible_message("\The [user] parries [attack_text] with \the [src]!") + + spark_system.queue() + playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) + return 1 + else + + if(!active) + return 0 //turn it on first! + + if(user.incapacitated()) + return 0 + + //block as long as they are not directly behind us + var/bad_arc = reverse_direction(user.dir) //arc of directions from which we cannot block + if(check_shield_arc(user, bad_arc, damage_source, attacker)) + + if(prob(base_block_chance)) + spark_system.queue() + playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) + shield_power -= round(damage/4) + + if(shield_power <= 0) + visible_message("\The [user]'s [src.name] overloads!") + deactivate() + shield_power = initial(shield_power) + return 0 + + if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam)) + var/obj/item/projectile/P = damage_source + + var/reflectchance = base_reflectchance - round(damage/3) + if(!(def_zone in list("chest", "groin","head"))) + reflectchance /= 2 + if(P.starting && prob(reflectchance)) + visible_message("\The [user]'s [src.name] reflects [attack_text]!") + + // Find a turf near or on the original location to bounce to + var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) + var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) + var/turf/curloc = get_turf(user) + + // redirect the projectile + P.redirect(new_x, new_y, curloc, user) + + return PROJECTILE_CONTINUE // complete projectile permutation + else + user.visible_message("\The [user] blocks [attack_text] with \the [src]!") + return 1 + + else if(istype(damage_source, /obj/item/projectile/bullet) && can_block_bullets) + var/reflectchance = (base_reflectchance) - round(damage/3) + if(!(def_zone in list("chest", "groin","head"))) + reflectchance /= 2 + if(prob(reflectchance)) + user.visible_message("\The [user] blocks [attack_text] with \the [src]!") + return 1 + /obj/item/weapon/melee/energy/glaive name = "energy glaive" desc = "An energized glaive." @@ -74,6 +138,11 @@ sharp = 1 edge = 1 slot_flags = SLOT_BACK + base_reflectchance = 0 + base_block_chance = 0 //cannot be used to block guns + shield_power = 0 + can_block_bullets = 0 + armor_penetration = 20 /obj/item/weapon/melee/energy/glaive/activate(mob/living/user) ..() @@ -108,6 +177,11 @@ attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") sharp = 1 edge = 1 + base_reflectchance = 0 + base_block_chance = 0 //cannot be used to block guns + shield_power = 0 + can_block_bullets = 0 + armor_penetration = 35 /obj/item/weapon/melee/energy/axe/activate(mob/living/user) ..() @@ -140,6 +214,7 @@ sharp = 1 edge = 1 var/blade_color + shield_power = 75 /obj/item/weapon/melee/energy/sword/dropped(var/mob/user) ..() @@ -175,19 +250,12 @@ attack_verb = list() icon_state = initial(icon_state) -/obj/item/weapon/melee/energy/sword/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") - if(active && default_parry_check(user, attacker, damage_source) && prob(50)) - user.visible_message("\The [user] parries [attack_text] with \the [src]!") - - spark_system.queue() - playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) - return 1 - return 0 - /obj/item/weapon/melee/energy/sword/pirate name = "energy cutlass" desc = "Arrrr matey." icon_state = "cutlass0" + base_reflectchance = 60 + base_block_chance = 60 /obj/item/weapon/melee/energy/sword/pirate/activate(mob/living/user) ..() @@ -196,13 +264,12 @@ /* *Energy Blade */ - -//Can't be activated or deactivated, so no reason to be a subtype of energy /obj/item/weapon/melee/energy/blade name = "energy blade" desc = "A concentrated beam of energy in the shape of a blade. Very stylish... and lethal." icon_state = "blade" - force = 40 //Normal attacks deal very high damage - about the same as wielded fire axe + force = 40 + active_force = 40 //Normal attacks deal very high damage - about the same as wielded fire axe armor_penetration = 100 sharp = 1 edge = 1 @@ -214,6 +281,12 @@ flags = NOBLOODY attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") var/mob/living/creator + base_reflectchance = 140 + base_block_chance = 75 + shield_power = 150 + can_block_bullets = 1 + active = 1 + armor_penetration = 20 /obj/item/weapon/melee/energy/blade/New() processing_objects |= src @@ -223,10 +296,14 @@ processing_objects -= src ..() -/obj/item/weapon/melee/energy/blade/attack_self(mob/user as mob) +/obj/item/weapon/melee/energy/blade/deactivate(mob/living/user) + if(!active) + return + playsound(user, 'sound/weapons/saberoff.ogg', 50, 1) user.drop_from_inventory(src) spawn(1) if(src) qdel(src) + /obj/item/weapon/melee/energy/blade/dropped() spawn(1) if(src) qdel(src) diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm index d57d312ab15..45483b8c8f0 100644 --- a/code/game/objects/items/weapons/shields.dm +++ b/code/game/objects/items/weapons/shields.dm @@ -103,17 +103,62 @@ w_class = 2 origin_tech = list(TECH_MATERIAL = 4, TECH_MAGNET = 3, TECH_ILLEGAL = 4) attack_verb = list("shoved", "bashed") + var/shield_power = 150 var/active = 0 -/obj/item/weapon/shield/energy/handle_shield(mob/user) +/obj/item/weapon/shield/energy/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") if(!active) return 0 //turn it on first! - . = ..() + if(user.incapacitated()) + return 0 + if(.) spark(user.loc, 5) playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) + //block as long as they are not directly behind us + var/bad_arc = reverse_direction(user.dir) //arc of directions from which we cannot block + if(check_shield_arc(user, bad_arc, damage_source, attacker)) + + if(prob(get_block_chance(user, damage, damage_source, attacker))) + spark(user.loc, 5) + playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) + shield_power -= round(damage/4) + + if(shield_power <= 0) + visible_message("\The [user]'s [src.name] overloads!") + active = 0 + force = 3 + update_icon() + w_class = 1 + playsound(user, 'sound/weapons/saberoff.ogg', 50, 1) + shield_power = initial(shield_power) + return 0 + + if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam)) + var/obj/item/projectile/P = damage_source + + var/reflectchance = 80 - round(damage/3) + if(P.starting && prob(reflectchance)) + visible_message("\The [user]'s [src.name] reflects [attack_text]!") + + // Find a turf near or on the original location to bounce to + var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) + var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) + var/turf/curloc = get_turf(user) + + // redirect the projectile + P.redirect(new_x, new_y, curloc, user) + + return PROJECTILE_CONTINUE // complete projectile permutation + else + user.visible_message("\The [user] blocks [attack_text] with \the [src]!") + return 1 + else + user.visible_message("\The [user] blocks [attack_text] with \the [src]!") + return 1 + /obj/item/weapon/shield/energy/get_block_chance(mob/user, var/damage, atom/damage_source = null, mob/attacker = null) if(istype(damage_source, /obj/item/projectile)) var/obj/item/projectile/P = damage_source diff --git a/html/changelogs/LordFowl - 11081998.yml b/html/changelogs/LordFowl - 11081998.yml new file mode 100644 index 00000000000..03d6d3be098 --- /dev/null +++ b/html/changelogs/LordFowl - 11081998.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: LordFowl + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Energy swords and shields can now reflect energy weapon projectiles. The ninja sword additionally can deflect bullets."