From 595cdeb7b5915691fc86ae9f6848d87d9179c830 Mon Sep 17 00:00:00 2001 From: Mechoid Date: Tue, 18 Jun 2019 02:50:47 -0700 Subject: [PATCH 1/2] THIS PR IS 7+ DAYS OLD, SEE #6203 . Energy-Swords and Changeling Melee Weapons Can Deflect Projectiles (#6215) * MakeMeleeGreatAgain * Where is melee defined?! --- .../gamemodes/changeling/powers/armblade.dm | 37 +++++++++++- .../objects/items/weapons/material/swords.dm | 3 +- .../objects/items/weapons/melee/deflect.dm | 31 ++++++++++ .../objects/items/weapons/melee/energy.dm | 57 ++++++++++++++++++- code/game/objects/items/weapons/shields.dm | 3 + .../Mechoid - Melee2RevengeoftheDeflect.yml | 36 ++++++++++++ vorestation.dme | 1 + 7 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 code/game/objects/items/weapons/melee/deflect.dm create mode 100644 html/changelogs/Mechoid - Melee2RevengeoftheDeflect.yml diff --git a/code/game/gamemodes/changeling/powers/armblade.dm b/code/game/gamemodes/changeling/powers/armblade.dm index ed27a49ba0..947f06cee4 100644 --- a/code/game/gamemodes/changeling/powers/armblade.dm +++ b/code/game/gamemodes/changeling/powers/armblade.dm @@ -32,7 +32,7 @@ genomecost = 1 verbpath = /mob/proc/changeling_claw -//Grows a scary, and powerful arm blade. +//Grows a scary, and powerful claw. /mob/proc/changeling_claw() set category = "Changeling" set name = "Claw (15)" @@ -62,6 +62,9 @@ var/weapType = "weapon" var/weapLocation = "arm" + defend_chance = 40 // The base chance for the weapon to parry. + projectile_parry_chance = 15 // The base chance for a projectile to be deflected. + /obj/item/weapon/melee/changeling/New(location) ..() START_PROCESSING(SSobj, src) @@ -107,6 +110,28 @@ if(src) qdel(src) +/obj/item/weapon/melee/changeling/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") + if(default_parry_check(user, attacker, damage_source) && prob(defend_chance)) + user.visible_message("\The [user] parries [attack_text] with \the [src]!") + playsound(user.loc, 'sound/weapons/slash.ogg', 50, 1) + return 1 + if(unique_parry_check(user, attacker, damage_source) && prob(projectile_parry_chance)) + user.visible_message("\The [user] deflects [attack_text] with \the [src]!") + playsound(user.loc, 'sound/weapons/slash.ogg', 50, 1) + return 1 + + return 0 + +/obj/item/weapon/melee/changeling/unique_parry_check(mob/user, mob/attacker, atom/damage_source) + if(user.incapacitated() || !istype(damage_source, /obj/item/projectile)) + return 0 + + var/bad_arc = reverse_direction(user.dir) + if(!check_shield_arc(user, bad_arc, damage_source, attacker)) + return 0 + + return 1 + /obj/item/weapon/melee/changeling/arm_blade name = "arm blade" desc = "A grotesque blade made out of bone and flesh that cleaves through people as a hot knife through butter." @@ -117,11 +142,15 @@ edge = 1 pry = 1 attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + defend_chance = 60 + projectile_parry_chance = 25 /obj/item/weapon/melee/changeling/arm_blade/greater name = "arm greatblade" desc = "A grotesque blade made out of bone and flesh that cleaves through people and armor as a hot knife through butter." armor_penetration = 30 + defend_chance = 70 + projectile_parry_chance = 35 /obj/item/weapon/melee/changeling/claw name = "hand claw" @@ -131,9 +160,13 @@ sharp = 1 edge = 1 attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + defend_chance = 50 + projectile_parry_chance = 15 /obj/item/weapon/melee/changeling/claw/greater name = "hand greatclaw" force = 20 armor_penetration = 20 - pry = 1 \ No newline at end of file + pry = 1 + defend_chance = 60 + projectile_parry_chance = 25 diff --git a/code/game/objects/items/weapons/material/swords.dm b/code/game/objects/items/weapons/material/swords.dm index 9efe911360..46551e588a 100644 --- a/code/game/objects/items/weapons/material/swords.dm +++ b/code/game/objects/items/weapons/material/swords.dm @@ -11,8 +11,7 @@ hitsound = 'sound/weapons/bladeslice.ogg' /obj/item/weapon/material/sword/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") - - if(default_parry_check(user, attacker, damage_source) && prob(50)) + if(unique_parry_check(user, attacker, damage_source) && prob(50)) user.visible_message("\The [user] parries [attack_text] with \the [src]!") playsound(user.loc, 'sound/weapons/punchmiss.ogg', 50, 1) return 1 diff --git a/code/game/objects/items/weapons/melee/deflect.dm b/code/game/objects/items/weapons/melee/deflect.dm new file mode 100644 index 0000000000..293d2b9e29 --- /dev/null +++ b/code/game/objects/items/weapons/melee/deflect.dm @@ -0,0 +1,31 @@ +/* + * The home of basic deflect / defense code. + */ + +/obj/item/weapon/melee + var/defend_chance = 5 // The base chance for the weapon to parry. + var/projectile_parry_chance = 0 // The base chance for a projectile to be deflected. + +/obj/item/weapon/melee/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") + if(.) + return . + if(default_parry_check(user, attacker, damage_source) && prob(defend_chance)) + user.visible_message("\The [user] parries [attack_text] with \the [src]!") + return 1 + if(unique_parry_check(user, attacker, damage_source) && prob(projectile_parry_chance)) + user.visible_message("\The [user] deflects [attack_text] with \the [src]!") + return 1 + + return 0 + +/obj/item/weapon/melee/unique_parry_check(mob/user, mob/attacker, atom/damage_source) + if(.) + return . + if(user.incapacitated() || !istype(damage_source, /obj/item/projectile)) + return 0 + + var/bad_arc = reverse_direction(user.dir) + if(!check_shield_arc(user, bad_arc, damage_source, attacker)) + return 0 + + return 1 diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 72fe26da36..f825577d6f 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -127,6 +127,8 @@ var/random_color = TRUE var/active_state = "sword" + projectile_parry_chance = 65 + /obj/item/weapon/melee/energy/sword/dropped(var/mob/user) ..() if(!istype(loc,/mob)) @@ -173,7 +175,7 @@ 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)) + if(active && default_parry_check(user, attacker, damage_source) && prob(60)) user.visible_message("\The [user] parries [attack_text] with \the [src]!") var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() @@ -181,8 +183,27 @@ spark_system.start() playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) return 1 + if(active && unique_parry_check(user, attacker, damage_source) && prob(projectile_parry_chance)) + user.visible_message("\The [user] deflects [attack_text] with \the [src]!") + + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, user.loc) + spark_system.start() + playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) + return 1 + return 0 +/obj/item/weapon/melee/energy/sword/unique_parry_check(mob/user, mob/attacker, atom/damage_source) + if(user.incapacitated() || !istype(damage_source, /obj/item/projectile/)) + return 0 + + var/bad_arc = reverse_direction(user.dir) + if(!check_shield_arc(user, bad_arc, damage_source, attacker)) + return 0 + + return 1 + /obj/item/weapon/melee/energy/sword/pirate name = "energy cutlass" desc = "Arrrr matey." @@ -215,6 +236,7 @@ lpower = 2 lcolor = "#0000FF" active_state = "ionic_rapier" + projectile_parry_chance = 30 // It's not specifically designed for cutting and slashing, but it can still, maybe, save your life. /obj/item/weapon/melee/energy/sword/ionic_rapier/afterattack(var/atom/movable/AM, var/mob/living/user, var/proximity) if(istype(AM, /obj) && proximity && active) @@ -250,6 +272,7 @@ origin_tech = list(TECH_COMBAT = 5, TECH_MAGNET = 3, TECH_ILLEGAL = 4) active_force = 25 armor_penetration = 25 + projectile_parry_chance = 40 var/hitcost = 75 var/obj/item/weapon/cell/bcell = null @@ -336,6 +359,7 @@ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") var/mob/living/creator var/datum/effect/effect/system/spark_spread/spark_system + projectile_parry_chance = 60 lcolor = "#00FF00" /obj/item/weapon/melee/energy/blade/New() @@ -373,6 +397,37 @@ host.drop_from_inventory(src) spawn(1) if(src) qdel(src) +/obj/item/weapon/melee/energy/blade/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") + if(default_parry_check(user, attacker, damage_source) && prob(60)) + user.visible_message("\The [user] parries [attack_text] with \the [src]!") + + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, user.loc) + spark_system.start() + playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) + return 1 + if(unique_parry_check(user, attacker, damage_source) && prob(projectile_parry_chance)) + user.visible_message("\The [user] deflects [attack_text] with \the [src]!") + + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, user.loc) + spark_system.start() + playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) + return 1 + + return 0 + +/obj/item/weapon/melee/energy/blade/unique_parry_check(mob/user, mob/attacker, atom/damage_source) + + if(user.incapacitated() || !istype(damage_source, /obj/item/projectile/)) + return 0 + + var/bad_arc = reverse_direction(user.dir) + if(!check_shield_arc(user, bad_arc, damage_source, attacker)) + return 0 + + return 1 + /* *Energy Spear */ diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm index a1a2756eca..5ea586f43d 100644 --- a/code/game/objects/items/weapons/shields.dm +++ b/code/game/objects/items/weapons/shields.dm @@ -29,6 +29,9 @@ return 1 +/obj/item/proc/unique_parry_check(mob/user, mob/attacker, atom/damage_source) // An overrideable version of the above proc. + return default_parry_check(user, attacker, damage_source) + /obj/item/weapon/shield name = "shield" var/base_block_chance = 50 diff --git a/html/changelogs/Mechoid - Melee2RevengeoftheDeflect.yml b/html/changelogs/Mechoid - Melee2RevengeoftheDeflect.yml new file mode 100644 index 0000000000..6841c34912 --- /dev/null +++ b/html/changelogs/Mechoid - Melee2RevengeoftheDeflect.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: Mechoid + +# 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: + - tweak: "Changeling arm-weapons and E-swords can now block projectiles (again)." diff --git a/vorestation.dme b/vorestation.dme index d68700dd85..6ad16ba61d 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -1141,6 +1141,7 @@ #include "code\game\objects\items\weapons\material\thrown.dm" #include "code\game\objects\items\weapons\material\twohanded.dm" #include "code\game\objects\items\weapons\material\whetstone.dm" +#include "code\game\objects\items\weapons\melee\deflect.dm" #include "code\game\objects\items\weapons\melee\energy.dm" #include "code\game\objects\items\weapons\melee\energy_vr.dm" #include "code\game\objects\items\weapons\melee\misc.dm"