diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index c89c563cf11..5727a024149 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -233,6 +233,7 @@ #define PROJECTILE_CONTINUE -1 //if the projectile should continue flying after calling bullet_act() #define PROJECTILE_FORCE_MISS -2 //if the projectile should treat the attack as a miss (suppresses attack and admin logs) - only applies to mobs. #define PROJECTILE_DODGED -3 //this is similar to the above, but the check and message is run on the mob, instead of on the projectile code. basically just has a unique message +#define PROJECTILE_STOPPED -4 //stops the projectile completely, as if a shield absorbed it //Camera capture modes #define CAPTURE_MODE_REGULAR 0 //Regular polaroid camera mode diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 244799a7098..cc31ada747b 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -86,7 +86,7 @@ if (targetIsHuman) var/mob/living/carbon/human/targethuman = target armorpercent = targethuman.get_blocked_ratio(target_zone, BRUTE, damage = force)*100 - wasblocked = targethuman.check_shields(force, src, user, target_zone, null) //returns 1 if it's a block + wasblocked = targethuman.check_shields(force, src, user, target_zone, null) var/damageamount = force diff --git a/code/game/gamemodes/technomancer/devices/shield_armor.dm b/code/game/gamemodes/technomancer/devices/shield_armor.dm index 40a9bd90f70..6316e6779b4 100644 --- a/code/game/gamemodes/technomancer/devices/shield_armor.dm +++ b/code/game/gamemodes/technomancer/devices/shield_armor.dm @@ -27,10 +27,10 @@ ..() spark(src, 5, cardinal) -/obj/item/clothing/suit/armor/shield/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") +/obj/item/clothing/suit/armor/shield/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") //Since this is a pierce of armor that is passive, we do not need to check if the user is incapacitated. if(!active) - return 0 + return FALSE var/modified_block_percentage = block_percentage @@ -65,7 +65,7 @@ spark(src, 5, cardinal) playsound(src, 'sound/weapons/blade.ogg', 50, 1) - return 0 // This shield does not block all damage, so returning 0 is needed to tell the game to apply the new damage. + return FALSE // This shield does not block all damage, so returning 0 is needed to tell the game to apply the new damage. /obj/item/clothing/suit/armor/shield/attack_self(mob/user) active = !active diff --git a/code/game/gamemodes/technomancer/devices/tesla_armor.dm b/code/game/gamemodes/technomancer/devices/tesla_armor.dm index 8803bc590c3..95fda406d08 100644 --- a/code/game/gamemodes/technomancer/devices/tesla_armor.dm +++ b/code/game/gamemodes/technomancer/devices/tesla_armor.dm @@ -21,7 +21,7 @@ var/normal_icon_state = "tesla_armor_0" var/cooldown_to_charge = 15 SECONDS -/obj/item/clothing/suit/armor/tesla/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") +/obj/item/clothing/suit/armor/tesla/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") //First, some retaliation. if(active) if(istype(damage_source, /obj/item/projectile)) @@ -46,8 +46,8 @@ addtimer(CALLBACK(src, .proc/recharge, user), cooldown_to_charge) visible_message("\The [user]'s [src.name] blocks [attack_text]!") update_icon() - return 1 - return 0 + return PROJECTILE_STOPPED + return FALSE /obj/item/clothing/suit/armor/tesla/proc/recharge(var/mob/user) ready = TRUE diff --git a/code/game/gamemodes/technomancer/spells/reflect.dm b/code/game/gamemodes/technomancer/spells/reflect.dm index 1bb277b37cc..b713c02ca63 100644 --- a/code/game/gamemodes/technomancer/spells/reflect.dm +++ b/code/game/gamemodes/technomancer/spells/reflect.dm @@ -26,16 +26,16 @@ to_chat(owner, "Your shield expires!") return ..() -/obj/item/spell/reflect/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") +/obj/item/spell/reflect/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") if(user.incapacitated()) - return 0 + return FALSE var/damage_to_energy_cost = (damage_to_energy_multiplier * damage) if(!pay_energy(damage_to_energy_cost)) to_chat(owner, "Your shield fades due to lack of energy!") qdel(src) - return 0 + return FALSE //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 @@ -85,5 +85,5 @@ spawn(2 SECONDS) //To ensure that most or all of a burst fire cycle is reflected. to_chat(owner, "Your shield fades due being used up!") qdel(src) - return 1 - return 0 + return PROJECTILE_STOPPED + return FALSE \ No newline at end of file diff --git a/code/game/gamemodes/technomancer/spells/shield.dm b/code/game/gamemodes/technomancer/spells/shield.dm index b403e4e0805..31a253a9e75 100644 --- a/code/game/gamemodes/technomancer/spells/shield.dm +++ b/code/game/gamemodes/technomancer/spells/shield.dm @@ -21,9 +21,9 @@ . = ..() set_light(3, 2, l_color = "#006AFF") -/obj/item/spell/shield/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") +/obj/item/spell/shield/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") if(user.incapacitated()) - return 0 + return FALSE var/damage_to_energy_cost = damage_to_energy_multiplier * damage @@ -41,7 +41,7 @@ if(!pay_energy(damage_to_energy_cost)) to_chat(owner, "Your shield fades due to lack of energy!") qdel(src) - return 0 + return FALSE //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 @@ -50,5 +50,5 @@ spark(src, 3, cardinal) playsound(src, 'sound/weapons/blade.ogg', 50, 1) adjust_instability(2) - return 1 - return 0 + return PROJECTILE_STOPPED + return FALSE \ No newline at end of file diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 32b00537d9e..b86c58ffcfb 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -530,12 +530,11 @@ var/list/global/slot_flags_enumeration = list( attack_self(usr) //RETURN VALUES -//handle_shield should return a positive value to indicate that the attack is blocked and should be prevented. -//If a negative value is returned, it should be treated as a special return value for bullet_act() and handled appropriately. -//For non-projectile attacks this usually means the attack is blocked. +//handle_shield +//Return a negative value corresponding to the degree an attack is blocked. PROJECTILE_STOPPED stops the attack entirely, and is the default for projectile and non-projectile attacks //Otherwise should return 0 to indicate that the attack is not affected in any way. /obj/item/proc/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") - return 0 + return FALSE /obj/item/proc/can_shield_back() return diff --git a/code/game/objects/items/weapons/material/swords.dm b/code/game/objects/items/weapons/material/swords.dm index 16dec2374aa..0f628f72fb3 100644 --- a/code/game/objects/items/weapons/material/swords.dm +++ b/code/game/objects/items/weapons/material/swords.dm @@ -32,8 +32,8 @@ if(default_parry_check(user, attacker, damage_source) && prob(parry_chance * parry_bonus)) user.visible_message("\The [user] parries [attack_text] with \the [src]!") playsound(user.loc, 'sound/weapons/bladeparry.ogg', 50, 1) - return 1 - return 0 + return PROJECTILE_STOPPED + return FALSE /obj/item/material/sword/perform_technique(var/mob/living/carbon/human/target, var/mob/living/carbon/human/user, var/target_zone) var/armor_reduction = target.get_blocked_ratio(target_zone, BRUTE, DAM_EDGE|DAM_SHARP, damage = force)*100 diff --git a/code/game/objects/items/weapons/material/twohanded.dm b/code/game/objects/items/weapons/material/twohanded.dm index c704c2ded0f..f8cfc2d3e08 100644 --- a/code/game/objects/items/weapons/material/twohanded.dm +++ b/code/game/objects/items/weapons/material/twohanded.dm @@ -89,8 +89,8 @@ if(wielded && default_parry_check(user, attacker, damage_source) && prob(parry_chance)) user.visible_message("\The [user] parries [attack_text] with \the [src]!") playsound(user.loc, /decl/sound_category/punchmiss_sound, 50, 1) - return 1 - return 0 + return PROJECTILE_STOPPED + return FALSE /obj/item/material/twohanded/update_icon() icon_state = "[base_icon][wielded]" diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 15c34aae441..a9ccaab6b37 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -65,17 +65,15 @@ /obj/item/melee/energy/handle_shield(mob/user, var/on_back, 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(src, 5) playsound(user.loc, 'sound/weapons/blade.ogg', 50, 1) - return 1 + return PROJECTILE_STOPPED else - if(!active) - return 0 //turn it on first! + return FALSE //turn it on first! if(user.incapacitated()) - return 0 + return FALSE //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 @@ -90,7 +88,7 @@ visible_message("\The [user]'s [src.name] overloads!") deactivate() shield_power = initial(shield_power) - return 0 + return FALSE if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam)) var/obj/item/projectile/P = damage_source @@ -112,7 +110,7 @@ return PROJECTILE_CONTINUE // complete projectile permutation else user.visible_message("\The [user] blocks [attack_text] with \the [src]!") - return 1 + return PROJECTILE_STOPPED else if(istype(damage_source, /obj/item/projectile/bullet) && can_block_bullets) var/reflectchance = (base_reflectchance) - round(damage/3) @@ -120,7 +118,7 @@ reflectchance /= 2 if(prob(reflectchance)) user.visible_message("\The [user] blocks [attack_text] with \the [src]!") - return 1 + return PROJECTILE_STOPPED /obj/item/melee/energy/get_print_info() . = ..() diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm index 0ba75c8ca3c..84649f5c308 100644 --- a/code/game/objects/items/weapons/shields.dm +++ b/code/game/objects/items/weapons/shields.dm @@ -41,7 +41,7 @@ /obj/item/shield/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") if(user.incapacitated()) - return 0 + return FALSE var/shield_dir = reverse_dir[user.dir] if(on_back) @@ -52,8 +52,8 @@ if(check_shield_arc(user, bad_arc, damage_source, attacker)) if(prob(get_block_chance(user, damage, damage_source, attacker))) user.visible_message("\The [user] blocks [attack_text] with \the [src]!") - return 1 - return 0 + return PROJECTILE_STOPPED + return FALSE /obj/item/shield/can_shield_back() return TRUE @@ -148,10 +148,10 @@ /obj/item/shield/energy/handle_shield(mob/user, var/on_back, 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! + return FALSE //turn it on first! if(user.incapacitated()) - return 0 + return FALSE if(.) spark(user.loc, 5) @@ -178,7 +178,7 @@ w_class = ITEMSIZE_TINY playsound(user, 'sound/weapons/saberoff.ogg', 50, 1) shield_power = initial(shield_power) - return 0 + return FALSE if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam)) var/obj/item/projectile/P = damage_source @@ -198,10 +198,10 @@ return PROJECTILE_CONTINUE // complete projectile permutation else user.visible_message("\The [user] blocks [attack_text] with \the [src]!") - return 1 + return PROJECTILE_STOPPED else user.visible_message("\The [user] blocks [attack_text] with \the [src]!") - return 1 + return PROJECTILE_STOPPED /obj/item/shield/energy/get_block_chance(mob/user, var/damage, atom/damage_source = null, mob/attacker = null) if(istype(damage_source, /obj/item/projectile)) @@ -304,9 +304,9 @@ /obj/item/shield/riot/tact/handle_shield(mob/user) if(!active) - return 0 //turn it on first! - . = ..() + return FALSE //turn it on first! + . = ..() if(.) if(.) playsound(user.loc, 'sound/weapons/genhit.ogg', 50, 1) diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 0ebdbbb1f97..6ccbb45912f 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -168,7 +168,7 @@ user.forceMove(picked) return PROJECTILE_FORCE_MISS - return 0 + return FALSE /obj/item/clothing/suit/armor/reactive/attack_self(mob/user as mob) src.active = !( src.active ) diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index 53bcae8cc34..97996674d3f 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -272,8 +272,8 @@ spark(user.loc, 5) playsound(user.loc, 'sound/weapons/blade.ogg', 50, 1) - return 1 - return 0 + return PROJECTILE_STOPPED + return FALSE /obj/item/holo/esword/New() if(!item_color) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index c4c05b35977..1c76a0f5049 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -165,15 +165,15 @@ emp_act for(var/obj/item/shield in list(l_hand, r_hand, wear_suit, back)) if(!shield) continue - if(!shield.can_shield_back()) - continue var/is_on_back = FALSE if(back && back == shield) + if(!shield.can_shield_back()) + continue is_on_back = TRUE . = shield.handle_shield(src, is_on_back, damage, damage_source, attacker, def_zone, attack_text) if(.) return - return 0 + return FALSE /mob/living/carbon/human/emp_act(severity) if(isipc(src)) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 1657ca84e52..8ca0f3e7ca0 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -480,8 +480,7 @@ else if(grabstate >= GRAB_AGGRESSIVE) damage_mult = 1.5 P.damage *= damage_mult - //you can't miss at point blank.. - P.can_miss = 1 + P.point_blank = TRUE /obj/item/gun/proc/process_accuracy(obj/projectile, mob/user, atom/target, acc_mod, dispersion) var/obj/item/projectile/P = projectile diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index e60d6a1caaa..416d67137fc 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -274,5 +274,5 @@ if(default_parry_check(user, attacker, damage_source) && prob(20)) user.visible_message(SPAN_DANGER("\The [user] parries [attack_text] with \the [src]!")) playsound(user.loc, "punchmiss", 50, 1) - return TRUE + return PROJECTILE_STOPPED return FALSE diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 3b9a0090712..74b447bae91 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -23,7 +23,7 @@ var/dispersion = 0.0 //used for shooting at blank range, you shouldn't be able to miss - var/can_miss = 0 + var/point_blank = FALSE //Effects var/damage = 10 @@ -190,19 +190,26 @@ return TRUE result = target_mob.bullet_act(src, def_zone) - if(result == PROJECTILE_FORCE_MISS && (can_miss == 0)) //if you're shooting at point blank you can't miss. - if(!silenced) - target_mob.visible_message("\The [src] misses [target_mob] narrowly!") - playsound(target_mob, /decl/sound_category/bulletflyby_sound, 50, 1) - return FALSE - - if(result == PROJECTILE_DODGED) - return FALSE + switch(result) + if(PROJECTILE_FORCE_MISS) + if(!point_blank) + if(!silenced) + target_mob.visible_message("\The [src] misses [target_mob] narrowly!") + playsound(target_mob, /decl/sound_category/bulletflyby_sound, 50, 1) + return FALSE + if(PROJECTILE_DODGED) + return FALSE + if(PROJECTILE_STOPPED) + return TRUE var/impacted_organ = parse_zone(def_zone) - if(istype(target_mob, /mob/living/simple_animal)) + if(isanimal(target_mob)) var/mob/living/simple_animal/SA = target_mob impacted_organ = pick(SA.organ_names) + else if(ishuman(target_mob)) + var/mob/living/carbon/human/H = target_mob + var/obj/item/organ/external/E = H.organs_by_name[impacted_organ] + impacted_organ = E.name //hit messages if(silenced) to_chat(target_mob, "You've been hit in the [impacted_organ] by \a [src]!") diff --git a/html/changelogs/geeves-shield_fix.yml b/html/changelogs/geeves-shield_fix.yml new file mode 100644 index 00000000000..1004775d248 --- /dev/null +++ b/html/changelogs/geeves-shield_fix.yml @@ -0,0 +1,7 @@ +author: Geeves + +delete-after: True + +changes: + - bugfix: "Fixed a bug that caused technomancer shields to entirely not work." + - tweak: "Getting hit by a projectile will now properly say the limb name instead of the attack zone name." \ No newline at end of file