diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 1bfbf9841f..e3eab3a8d8 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -219,19 +219,19 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( /// Attack was and should be redirected according to list argument REDIRECT_METHOD (NOTE: the SHOULD here is important, as it says "the thing blocking isn't handling the reflecting for you so do it yourself"!) #define BLOCK_SHOULD_REDIRECT (1<<2) -/// Attack was manually redirected (including reflected) by any means by the defender. For when YOU are handling the reflection, rather than the thing hitting you. (see sleeping carp) +/// Attack was redirected (whether by us or by SHOULD_REDIRECT flagging for automatic handling) #define BLOCK_REDIRECTED (1<<3) /// Attack was blocked by something like a shield. #define BLOCK_PHYSICAL_EXTERNAL (1<<4) /// Attack was blocked by something worn on you. #define BLOCK_PHYSICAL_INTERNAL (1<<5) -/// Attack outright missed because the target dodged. Should usually be combined with SHOULD_PASSTHROUGH or something (see martial arts) +/// 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 : Whatever triggered this has completely blocked the attack (or failed so miserably hard it wants us to stop for when that's implemented), do not keep checking. Most methods of block should probably use this. #define BLOCK_INTERRUPT_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_METOHD "REDIRECT_METHOD" +#define BLOCK_RETURN_REDIRECT_METHOD "REDIRECT_METHOD" /// Pass through victim #define REDIRECT_MODE_PASSTHROUGH "passthrough" /// Reflect using normal angular/mirrorlike reflection diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index b5b71f915a..af0147e421 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -27,16 +27,15 @@ max_integrity = 75 /obj/item/shield/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(transparent && (hitby.pass_flags & PASSGLASS)) + if(transparent && (object.pass_flags & PASSGLASS)) return FALSE if(attack_type == ATTACK_TYPE_THROWN) final_block_chance += 30 - if(attack_type == ATTACK_TYPE_LEAP) + if(attack_type == ATTACK_TYPE_TACKLE) final_block_chance = 100 . = ..() if(. & BLOCK_SUCCESS) - on_shield_block - on_shield_block(owner, hitby, attack_text, damage, attack_type) + on_shield_block(owner, real_attack, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return) /obj/item/shield/riot/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/melee/baton)) @@ -70,10 +69,10 @@ playsound(owner, 'sound/effects/glassbr3.ogg', 100) new /obj/item/shard((get_turf(src))) -/obj/item/shield/riot/on_shield_block(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", damage = 0, attack_type = MELEE_ATTACK) +/obj/item/shield/riot/on_shield_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(obj_integrity <= damage) var/turf/T = get_turf(owner) - T.visible_message("[hitby] destroys [src]!") + T.visible_message("[attack_text] destroys [src]!") shatter(owner) qdel(src) return FALSE @@ -140,11 +139,11 @@ . = ..() icon_state = "[base_icon_state]0" -/obj/item/shield/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - return 0 - -/obj/item/shield/energy/IsReflect() - return (active) +/obj/item/shield/energy/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)) + block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_REFLECT + return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT + return ..() /obj/item/shield/energy/attack_self(mob/living/carbon/human/user) if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) @@ -250,7 +249,7 @@ transparent = FALSE item_flags = SLOWS_WHILE_IN_HAND -/obj/item/shield/riot/implant/hit_reaction(mob/living/owner, real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) +/obj/item/shield/riot/implant/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) final_block_chance = 60 //Massive shield return ..() diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index ae25681205..1fa09555a9 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -373,10 +373,13 @@ else user.adjustStaminaLoss(25) -/obj/item/twohanded/dualsaber/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(wielded) - return ..() - return 0 +/obj/item/twohanded/dualsaber/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) + return NONE + if(is_energy_reflectable_projectile(object) && (attack_type == ATTACK_TYPE_PROJECTILE)) + block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_RETURN_TO_SENDER //no you + return BLOCK_SHOULD_REDIRECT | BLOCK_SUCCESS | BLOCK_REDIRECTED + return ..() /obj/item/twohanded/dualsaber/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) //In case thats just so happens that it is still activated on the groud, prevents hulk from picking it up if(wielded) @@ -419,10 +422,6 @@ /obj/item/twohanded/dualsaber/proc/rainbow_process() light_color = pick(rainbow_colors) -/obj/item/twohanded/dualsaber/IsReflect() - if(wielded) - return 1 - /obj/item/twohanded/dualsaber/ignition_effect(atom/A, mob/user) // same as /obj/item/melee/transforming/energy, mostly if(!wielded) @@ -753,7 +752,7 @@ force_on = 30 /obj/item/twohanded/required/chainsaw/doomslayer/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 && (attack_type == PROJECTILE_ATTACK)) + 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 diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index e0c2d6e2c7..aad4c16e83 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -362,18 +362,17 @@ new stack_type(get_turf(loc)) qdel(src) -/obj/item/chair/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(attack_type == UNARMED_ATTACK && prob(hit_reaction_chance)) - owner.visible_message("[owner] fends off [attack_text] with [src]!") - return 1 - return 0 +/obj/item/chair/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_UNARMED) + return NONE + return ..() /obj/item/chair/afterattack(atom/target, mob/living/carbon/user, proximity) . = ..() if(!proximity) return if(prob(break_chance)) - user.visible_message("[user] smashes \the [src] to pieces against \the [target]") + user.visible_message("[user] smashes [src] to pieces against [target]") if(iscarbon(target)) var/mob/living/carbon/C = target if(C.health < C.maxHealth*0.5) diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm index 468c14278b..7bc6a668ce 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm @@ -493,7 +493,7 @@ user.do_attack_animation(L) - if(L.run_block(src, 0, "[user]'s [src]", MELEE_ATTACK, 0, user, check_zone(user.zone_selected)) & BLOCK_SUCCESS) + if(L.run_block(src, 0, "[user]'s [src]", ATTACK_TYPE_MELEE, 0, user, check_zone(user.zone_selected)) & BLOCK_SUCCESS) playsound(L, 'sound/weapons/genhit.ogg', 50, TRUE) return FALSE diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm index 884769ebd4..1b1fb26148 100644 --- a/code/modules/holodeck/items.dm +++ b/code/modules/holodeck/items.dm @@ -34,10 +34,10 @@ . = ..() item_color = "red" -/obj/item/holo/esword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(active) +/obj/item/holo/esword/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(!active) return ..() - return 0 + return ..() /obj/item/holo/esword/attack(target as mob, mob/user as mob) ..() diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm index 0d62eb260d..1cbf13e064 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm @@ -39,27 +39,27 @@ deathsound = 'sound/magic/demon_dies.ogg' deathmessage = "begins to shudder as it becomes transparent..." loot_drop = /obj/item/clothing/neck/cloak/herald_cloak - + can_talk = 1 attack_action_types = list(/datum/action/innate/elite_attack/herald_trishot, /datum/action/innate/elite_attack/herald_directionalshot, /datum/action/innate/elite_attack/herald_teleshot, /datum/action/innate/elite_attack/herald_mirror) - + var/mob/living/simple_animal/hostile/asteroid/elite/herald/mirror/my_mirror = null var/is_mirror = FALSE - + /mob/living/simple_animal/hostile/asteroid/elite/herald/death() . = ..() if(!is_mirror) addtimer(CALLBACK(src, .proc/become_ghost), 8) if(my_mirror != null) qdel(my_mirror) - + /mob/living/simple_animal/hostile/asteroid/elite/herald/proc/become_ghost() icon_state = "herald_ghost" - + /mob/living/simple_animal/hostile/asteroid/elite/herald/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) . = ..() if(.) @@ -70,25 +70,25 @@ button_icon_state = "herald_trishot" chosen_message = "You are now firing three shots in your chosen direction." chosen_attack_num = HERALD_TRISHOT - + /datum/action/innate/elite_attack/herald_directionalshot name = "Circular Shot" button_icon_state = "herald_directionalshot" chosen_message = "You are firing projectiles in all directions." chosen_attack_num = HERALD_DIRECTIONALSHOT - + /datum/action/innate/elite_attack/herald_teleshot name = "Teleport Shot" button_icon_state = "herald_teleshot" chosen_message = "You will now fire a shot which teleports you where it lands." chosen_attack_num = HERALD_TELESHOT - + /datum/action/innate/elite_attack/herald_mirror name = "Summon Mirror" button_icon_state = "herald_mirror" chosen_message = "You will spawn a mirror which duplicates your attacks." chosen_attack_num = HERALD_MIRROR - + /mob/living/simple_animal/hostile/asteroid/elite/herald/OpenFire() if(client) switch(chosen_attack) @@ -123,7 +123,7 @@ my_mirror.herald_teleshot(target) if(HERALD_MIRROR) herald_mirror() - + /mob/living/simple_animal/hostile/asteroid/elite/herald/proc/shoot_projectile(turf/marker, set_angle, var/is_teleshot) var/turf/startloc = get_turf(src) var/obj/item/projectile/herald/H = null @@ -136,7 +136,7 @@ if(target) H.original = target H.fire(set_angle) - + /mob/living/simple_animal/hostile/asteroid/elite/herald/proc/herald_trishot(target) ranged_cooldown = world.time + 30 playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE) @@ -150,17 +150,17 @@ addtimer(CALLBACK(src, .proc/shoot_projectile, target_turf, angle_to_target, FALSE), 10) addtimer(CALLBACK(src, .proc/shoot_projectile, target_turf, angle_to_target, FALSE), 12) addtimer(CALLBACK(src, .proc/shoot_projectile, target_turf, angle_to_target, FALSE), 14) - + /mob/living/simple_animal/hostile/asteroid/elite/herald/proc/herald_circleshot() var/static/list/directional_shot_angles = list(0, 45, 90, 135, 180, 225, 270, 315) for(var/i in directional_shot_angles) shoot_projectile(get_turf(src), i, FALSE) - + /mob/living/simple_animal/hostile/asteroid/elite/herald/proc/unenrage() if(stat == DEAD || is_mirror) return icon_state = "herald" - + /mob/living/simple_animal/hostile/asteroid/elite/herald/proc/herald_directionalshot() ranged_cooldown = world.time + 50 if(!is_mirror) @@ -171,14 +171,14 @@ playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE) addtimer(CALLBACK(src, .proc/herald_circleshot), 15) addtimer(CALLBACK(src, .proc/unenrage), 20) - + /mob/living/simple_animal/hostile/asteroid/elite/herald/proc/herald_teleshot(target) ranged_cooldown = world.time + 30 playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE) var/target_turf = get_turf(target) var/angle_to_target = Get_Angle(src, target_turf) shoot_projectile(target_turf, angle_to_target, TRUE) - + /mob/living/simple_animal/hostile/asteroid/elite/herald/proc/herald_mirror() ranged_cooldown = world.time + 40 playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE) @@ -189,7 +189,7 @@ my_mirror = new_mirror my_mirror.my_master = src my_mirror.faction = faction.Copy() - + /mob/living/simple_animal/hostile/asteroid/elite/herald/mirror name = "herald's mirror" desc = "This fiendish work of magic copies the herald's attacks. Seems logical to smash it." @@ -202,16 +202,16 @@ del_on_death = TRUE is_mirror = TRUE var/mob/living/simple_animal/hostile/asteroid/elite/herald/my_master = null - + /mob/living/simple_animal/hostile/asteroid/elite/herald/mirror/Initialize() ..() toggle_ai(AI_OFF) - + /mob/living/simple_animal/hostile/asteroid/elite/herald/mirror/Destroy() if(my_master != null) my_master.my_mirror = null . = ..() - + /obj/item/projectile/herald name ="death bolt" icon_state= "chronobolt" @@ -221,7 +221,7 @@ eyeblur = 0 damage_type = BRUTE pass_flags = PASSTABLE - + /obj/item/projectile/herald/teleshot name ="golden bolt" damage = 0 @@ -238,11 +238,11 @@ var/mob/living/F = firer if(F != null && istype(F, /mob/living/simple_animal/hostile/asteroid/elite) && F.faction_check_mob(L)) L.heal_overall_damage(damage) - + /obj/item/projectile/herald/teleshot/on_hit(atom/target, blocked = FALSE) . = ..() firer.forceMove(get_turf(src)) - + //Herald's loot: Cloak of the Prophet /obj/item/clothing/neck/cloak/herald_cloak @@ -252,12 +252,12 @@ icon_state = "herald_cloak" body_parts_covered = CHEST|GROIN|ARMS hit_reaction_chance = 10 - + /obj/item/clothing/neck/cloak/herald_cloak/proc/reactionshot(mob/living/carbon/owner) var/static/list/directional_shot_angles = list(0, 45, 90, 135, 180, 225, 270, 315) for(var/i in directional_shot_angles) shoot_projectile(get_turf(owner), i, owner) - + /obj/item/clothing/neck/cloak/herald_cloak/proc/shoot_projectile(turf/marker, set_angle, mob/living/carbon/owner) var/turf/startloc = get_turf(owner) var/obj/item/projectile/herald/H = null @@ -265,12 +265,13 @@ H.preparePixelProjectile(marker, startloc) H.firer = owner H.fire(set_angle) - -/obj/item/clothing/neck/cloak/herald_cloak/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/neck/cloak/herald_cloak/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) + return if(rand(1,100) > hit_reaction_chance) return owner.visible_message("[owner]'s [src] emits a loud noise as [owner] is struck!") - var/static/list/directional_shot_angles = list(0, 45, 90, 135, 180, 225, 270, 315) playsound(get_turf(owner), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE) addtimer(CALLBACK(src, .proc/reactionshot, owner), 10)