From a77be038b8614ef296c3e2beafd3d88eef6abc19 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Mon, 16 Mar 2020 04:56:32 -0700 Subject: [PATCH] refactoring this whole thing again --- code/__DEFINES/combat.dm | 16 +++++++--- code/game/objects/items/grenades/grenade.dm | 2 +- code/game/objects/items/twohanded.dm | 4 +-- code/game/objects/items/weaponry.dm | 17 +++++----- code/modules/antagonists/cult/cult_items.dm | 31 +++++++++++-------- code/modules/clothing/spacesuits/hardsuit.dm | 10 ++++-- .../modules/clothing/suits/reactive_armour.dm | 2 +- code/modules/clothing/under/color.dm | 5 +-- .../mining/lavaland/necropolis_chests.dm | 4 +-- .../carbon/alien/humanoid/caste/hunter.dm | 2 +- code/modules/mob/living/living_block.dm | 6 ++++ .../mob/living/silicon/silicon_defense.dm | 2 +- .../simple_animal/guardian/types/charger.dm | 2 +- code/modules/projectiles/guns/magic/staff.dm | 2 +- .../living/silicon/robot/dogborg_equipment.dm | 2 +- 15 files changed, 64 insertions(+), 43 deletions(-) diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 714e011a29..2fdd6a98bc 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -228,21 +228,27 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( /// Attack outright missed because the target dodged. Should usually be combined with redirection passthrough or something (see martial arts) #define BLOCK_TARGET_DODGED (1<<7) /// Meta-flag for run_block/do_run_block : By default, BLOCK_SUCCESS tells do_run_block() to assume the attack is completely blocked and not continue the block chain. If this is present, it will continue to check other items in the chain rather than stopping. -#define BLOCK_cONTINUE_CHAIN (1<<8) +#define BLOCK_CONTINUE_CHAIN (1<<8) /// For keys in associative list/block_return as we don't want to saturate our (somewhat) limited flags. #define BLOCK_RETURN_REDIRECT_METHOD "REDIRECT_METHOD" /// Pass through victim #define REDIRECT_METHOD_PASSTHROUGH "passthrough" - /// Reflect using normal angular/mirrorlike reflection - #define REDIRECT_METHOD_REFLECT "reflect" /// Deflect at randomish angle #define REDIRECT_METHOD_DEFLECT "deflect" - /// do not taser the bad man with the desword + /// reverse 180 angle, basically (as opposed to "realistic" wall reflections) + #define REDIRECT_METHOD_REFLECT "reflect" + /// "do not taser the bad man with the desword" - actually aims at the firer/attacker rather than just reversing #define REDIRECT_METHOD_RETURN_TO_SENDER "no_you" +/// These keys are generally only applied to the list if real_attack is FALSE. Used incase we want to make "smarter" mob AI in the future or something. +/// Tells the caller how likely from 0 (none) to 100 (always) we are to reflect energy projectiles +#define BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE +/// Tells the caller how likely we are to block attacks from 0 to 100 in general +#define BLOCK_RETURN_NORMAL_BLOCK_CHANCE + /// Default if the above isn't set in the list. -#define DEFAULT_REDIRECT_METHOD_PROJECTILE REDIRECT_METHOD_REFLECT +#define DEFAULT_REDIRECT_METHOD_PROJECTILE REDIRECT_METHOD_DEFLECT /// Block priorities #define BLOCK_PRIORITY_HELD_ITEM 100 diff --git a/code/game/objects/items/grenades/grenade.dm b/code/game/objects/items/grenades/grenade.dm index 85ec9ad634..c72813bec3 100644 --- a/code/game/objects/items/grenades/grenade.dm +++ b/code/game/objects/items/grenades/grenade.dm @@ -121,7 +121,7 @@ if(damage && !P.nodamage && (P.damage_type != STAMINA) && prob(15)) owner.visible_message("[attack_text] hits [owner]'s [src], setting it off! What a shot!") prime() - return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL | BLOCK_INTERRUPT_CHAIN + return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL return ..() /obj/item/proc/grenade_prime_react(obj/item/grenade/nade) diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index dafb7430ae..66f85bb459 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -755,7 +755,7 @@ if(real_attack && (attack_type & ATTACK_TYPE_PROJECTILE)) owner.visible_message("Ranged attacks just make [owner] angrier!") playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1) - return BLOCK_SUCCESS | BLOCK_INTERRUPT_CHAIN | BLOCK_PHYSICAL_EXTERNAL + return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL return ..() //GREY TIDE @@ -908,7 +908,7 @@ return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT | BLOCK_PHYSICAL_EXTERNAL else owner.visible_message("[owner] parries [attack_text] with [src]!") - return BLOCK_SUCCESS | BLOCK_PARRY + return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL return NONE /obj/item/twohanded/vibro_weapon/update_icon_state() diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 8746ac49a5..58c8aa2d8e 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -157,7 +157,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/claymore/highlander/run_block(mob/living/owner, real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) if((attack_type & ATTACK_TYPE_PROJECTILE) && is_energy_reflectable_projectile(object)) - return BLOCK_SUCCESS | BLOCK_SHOULD_REDIRECT | BLOCK_PHYSICAL_EXTERNAL | BLOCK_REDIRECT + return BLOCK_SUCCESS | BLOCK_SHOULD_REDIRECT | BLOCK_PHYSICAL_EXTERNAL | BLOCK_REDIRECTED return ..() /obj/item/claymore/highlander/proc/add_notch(mob/living/user) //DYNAMIC CLAYMORE PROGRESSION SYSTEM - THIS IS THE FUTURE @@ -583,14 +583,13 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 force = 12 throwforce = 15 -/obj/item/melee/baseball_bat/ablative/IsReflect()//some day this will reflect thrown items instead of lasers - var/picksound = rand(1,2) - var/turf = get_turf(src) - if(picksound == 1) - playsound(turf, 'sound/weapons/effects/batreflect1.ogg', 50, 1) - if(picksound == 2) - playsound(turf, 'sound/weapons/effects/batreflect2.ogg', 50, 1) - return 1 +/obj/item/melee/baseball_bat/ablative/run_block(mob/living/owner, real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) + //some day this will reflect thrown items instead of lasers + if(is_energy_reflectable_projectile(object) && (attack_type == ATTACK_TYPE_PROJECTILE)) + var/turf = get_turf(src) + playsound(turf, pick('sound/weapons/effects/batreflect1.ogg', 'sound/weapons/effects/batreflect2.ogg'), 50, 1) + return BLOCK_SUCESS | BLOCK_SHOULD_REDIRECT | BLOCK_PHYSICAL_EXTERNAL | BLOCK_REDIRECTED + return ..() /obj/item/melee/baseball_bat/ablative/syndi name = "syndicate major league bat" diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 7d1bbeeddc..cc6ea983e8 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -725,19 +725,19 @@ playsound(T, 'sound/effects/glassbr3.ogg', 100) qdel(src) -/obj/item/twohanded/cult_spear/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) +/obj/item/twohanded/cult_spear/run_block(mob/living/owner, real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) if(wielded) final_block_chance *= 2 if(prob(final_block_chance)) - if(attack_type & PROJECTILE_ATTACK) + if(attack_type & ATTACK_TYPE_PROJECTILE) owner.visible_message("[owner] deflects [attack_text] with [src]!") playsound(src, pick('sound/weapons/effects/ric1.ogg', 'sound/weapons/effects/ric2.ogg', 'sound/weapons/effects/ric3.ogg', 'sound/weapons/effects/ric4.ogg', 'sound/weapons/effects/ric5.ogg'), 100, 1) - return TRUE + return BLOCK_SUCCESS | BLOCK_SHOULD_REDIRECT | BLOCK_REDIRECTED | BLOCK_PHYSICAL_EXTERNAL else playsound(src, 'sound/weapons/parry.ogg', 100, 1) owner.visible_message("[owner] parries [attack_text] with [src]!") - return TRUE - return FALSE + return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL + return BLOCK_NONE /datum/action/innate/cult/spear name = "Bloody Bond" @@ -936,10 +936,13 @@ hitsound = 'sound/weapons/smash.ogg' var/illusions = 2 -/obj/item/shield/mirror/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) +/obj/item/shield/mirror/run_block(mob/living/owner, real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) + if(!real_attack) + block_return[BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE] = final_block_chance + return ..() if(iscultist(owner)) - if(istype(hitby, /obj/item/projectile)) - var/obj/item/projectile/P = hitby + if(istype(object, /obj/item/projectile) && (attack_type == ATTACK_TYPE_PROJECTILE)) + var/obj/item/projectile/P = object if(P.damage >= 30) var/turf/T = get_turf(owner) T.visible_message("The sheer force from [P] shatters the mirror shield!") @@ -947,11 +950,13 @@ playsound(T, 'sound/effects/glassbr3.ogg', 100) owner.DefaultCombatKnockdown(25) qdel(src) - return FALSE + return BLOCK_NONE if(P.is_reflectable) - return FALSE //To avoid reflection chance double-dipping with block chance + if(prob(final_block_chance)) + return BLOCK_SUCCESS | BLOCK_SHOULD_REDIRECT | BLOCK_PHYSICAL_EXTERNAL | BLOCK_REDIRECTED + return BLOCK_NONE //To avoid reflection chance double-dipping with block chance . = ..() - if(.) + if(. & BLOCK_SUCCESS) playsound(src, 'sound/weapons/parry.ogg', 100, 1) if(illusions > 0) illusions-- @@ -966,7 +971,7 @@ E.Copy_Parent(owner, 70, 10) E.GiveTarget(owner) E.Goto(owner, owner.movement_delay(), E.minimum_distance) - return TRUE + return else if(prob(50)) var/mob/living/simple_animal/hostile/illusion/H = new(owner.loc) @@ -975,7 +980,7 @@ H.GiveTarget(owner) H.move_to_delay = owner.movement_delay() to_chat(owner, "[src] betrays you!") - return FALSE + return BLOCK_NONE /obj/item/shield/mirror/proc/readd() illusions++ diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 1bad198c73..a3d4cf367b 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -757,7 +757,11 @@ if(!allowed) allowed = GLOB.advanced_hardsuit_allowed -/obj/item/clothing/suit/space/hardsuit/shielded/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) +/obj/item/clothing/suit/space/hardsuit/shielded/run_block(mob/living/owner, real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) + if(!real_attack) + if(current_charges > 0) + return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL + return BLOCK_NONE recharge_cooldown = world.time + recharge_delay if(current_charges > 0) var/datum/effect_system/spark_spread/s = new @@ -771,8 +775,8 @@ owner.visible_message("[owner]'s shield overloads!") shield_state = "broken" owner.update_inv_wear_suit() - return 1 - return 0 + return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL + return BLOCK_NONE /obj/item/clothing/suit/space/hardsuit/shielded/Destroy() STOP_PROCESSING(SSobj, src) diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm index fb8d62e350..24280f953a 100644 --- a/code/modules/clothing/suits/reactive_armour.dm +++ b/code/modules/clothing/suits/reactive_armour.dm @@ -4,7 +4,6 @@ icon_state = "reactiveoff" icon = 'icons/obj/clothing/suits.dmi' w_class = WEIGHT_CLASS_BULKY - var/hit_reaction_chance = 50 /obj/item/reactive_armour_shell/attackby(obj/item/I, mob/user, params) ..() @@ -39,6 +38,7 @@ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF hit_reaction_chance = 50 // Only on the chest yet blocks all attacks? rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE + var/hit_reaction_chance = 50 /obj/item/clothing/suit/armor/reactive/attack_self(mob/user) active = !(active) diff --git a/code/modules/clothing/under/color.dm b/code/modules/clothing/under/color.dm index c02f78cb8f..cce41b9fc0 100644 --- a/code/modules/clothing/under/color.dm +++ b/code/modules/clothing/under/color.dm @@ -81,8 +81,9 @@ /obj/item/clothing/under/color/grey/glorf/run_block(mob/living/owner, real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) . = ..() - if(real_attack) - owner.forcesay(GLOB.hit_appends) + if(real_attack && ishuman(owner)) + var/mob/living/human/H = owner + H.forcesay(GLOB.hit_appends) /obj/item/clothing/under/color/blue name = "blue jumpsuit" diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index bf25bb9da8..d0b8c113b4 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -835,9 +835,9 @@ force = CLAMP((ghost_counter * 4), 0, 75) user.visible_message("[user] strikes with the force of [ghost_counter] vengeful spirits!") - ..() + return ..() -/obj/item/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) +/obj/item/melee/ghost_sword/run_block(mob/living/owner, real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) var/ghost_counter = ghost_check() final_block_chance += CLAMP((ghost_counter * 5), 0, 75) owner.visible_message("[owner] is protected by a ring of [ghost_counter] ghosts!") diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index 189af32da8..1bb545b8ea 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -63,7 +63,7 @@ if(hit_atom) if(isliving(hit_atom)) var/mob/living/L = hit_atom - if(L.run_block(src, 0, "the [name]", attack_type = LEAP_ATTACK, 0, src) & BLOCK_SUCCESS) + if(L.run_block(src, 0, "the [name]", attack_type = ATTACK_TYPE_TACKLE, 0, src) & BLOCK_SUCCESS) DefaultCombatKnockdown(40, 1, 1) else L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") diff --git a/code/modules/mob/living/living_block.dm b/code/modules/mob/living/living_block.dm index 13e236a931..c3b9fc73f4 100644 --- a/code/modules/mob/living/living_block.dm +++ b/code/modules/mob/living/living_block.dm @@ -76,9 +76,15 @@ /// Block priority, higher means we check this higher in the "chain". var/block_priority = BLOCK_PRIORITY_DEFAULT +/// Runs block and returns flag for do_run_block to process. /obj/item/proc/run_block(mob/living/owner, real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) SEND_SIGNAL(src, COMSIG_ITEM_RUN_BLOCK, args) if(prob(final_block_chance)) owner.visible_message("[owner] blocks [attack_text] with [src]!") return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL return BLOCK_NONE + +/// Returns block information using list/block_return. Used for check_block() on mobs. +/obj/item/proc/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) + SEND_SIGNAL(src, COMSIG_ITEM_CHECK_BLOCK, args) + block_return[BLOCK_RETURN_NORMAL_BLOCK_CHANCE] = final_block_chance diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index 1c6784ab95..98d990e5ea 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -115,7 +115,7 @@ if(reflect_bullet_check(P, def_zone)) return -1 // complete projectile permutation #warn implement blocktypes - if(run_block(P, P.damage, "the [P.name]", PROJECTILE_ATTACK, P.armour_penetration) & BLOCK_SUCCESS) + if(run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration) & BLOCK_SUCCESS) P.on_hit(src, 100, def_zone) return BULLET_ACT_BLOCK if((P.damage_type == BRUTE || P.damage_type == BURN)) diff --git a/code/modules/mob/living/simple_animal/guardian/types/charger.dm b/code/modules/mob/living/simple_animal/guardian/types/charger.dm index 10f7b6893f..9457c8153d 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/charger.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/charger.dm @@ -54,7 +54,7 @@ var/blocked = FALSE if(hasmatchingsummoner(hit_atom)) //if the summoner matches don't hurt them blocked = TRUE - if(L.run_block(src, 90, "[name]", attack_type = ATTACK_TYPE_LEAP, 0, src) & BLOCK_SUCCESS) + if(L.run_block(src, 90, "[name]", attack_type = ATTACK_TYPE_TACKLE, 0, src) & BLOCK_SUCCESS) blocked = TRUE if(!blocked) L.drop_all_held_items() diff --git a/code/modules/projectiles/guns/magic/staff.dm b/code/modules/projectiles/guns/magic/staff.dm index c81880ab55..274a1c96f9 100644 --- a/code/modules/projectiles/guns/magic/staff.dm +++ b/code/modules/projectiles/guns/magic/staff.dm @@ -92,7 +92,7 @@ /obj/item/gun/magic/staff/spellblade/run_block(mob/living/owner, real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) // Do not block projectiles. - if(attack_type & PROJECTILE_ATTACK) + if(attack_type & ATTACK_TYPE_PROJECTILE) return BLOCK_NONE return ..() diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm index 5cf4abb5bf..a38f58b655 100644 --- a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm +++ b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm @@ -424,7 +424,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! if(hit_atom) if(isliving(hit_atom)) var/mob/living/L = hit_atom - if(L.run_block(0, "the [name]", src, attack_type = LEAP_ATTACK, 0, src) & BLOCK_SUCCESS) + if(L.run_block(0, "the [name]", src, attack_type = ATTACK_TYPE_TACKLE, 0, src) & BLOCK_SUCCESS) DefaultCombatKnockdown(15, 1, 1) else L.visible_message("[src] pounces on [L]!", "[src] pounces on you!")