Shield Fix (#12074)

This commit is contained in:
Geeves
2021-06-20 17:32:48 -03:00
committed by GitHub
parent c6444fa548
commit e5a34c4f08
18 changed files with 73 additions and 62 deletions
+1
View File
@@ -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
+1 -1
View File
@@ -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
@@ -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
@@ -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("<span class='danger'>\The [user]'s [src.name] blocks [attack_text]!</span>")
update_icon()
return 1
return 0
return PROJECTILE_STOPPED
return FALSE
/obj/item/clothing/suit/armor/tesla/proc/recharge(var/mob/user)
ready = TRUE
@@ -26,16 +26,16 @@
to_chat(owner, "<span class='danger'>Your shield expires!</span>")
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, "<span class='danger'>Your shield fades due to lack of energy!</span>")
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, "<span class='danger'>Your shield fades due being used up!</span>")
qdel(src)
return 1
return 0
return PROJECTILE_STOPPED
return FALSE
@@ -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, "<span class='danger'>Your shield fades due to lack of energy!</span>")
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
+3 -4
View File
@@ -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
@@ -32,8 +32,8 @@
if(default_parry_check(user, attacker, damage_source) && prob(parry_chance * parry_bonus))
user.visible_message("<span class='danger'>\The [user] parries [attack_text] with \the [src]!</span>")
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
@@ -89,8 +89,8 @@
if(wielded && default_parry_check(user, attacker, damage_source) && prob(parry_chance))
user.visible_message("<span class='danger'>\The [user] parries [attack_text] with \the [src]!</span>")
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]"
@@ -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("<span class='danger'>\The [user] parries [attack_text] with \the [src]!</span>")
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("<span class='danger'>\The [user]'s [src.name] overloads!</span>")
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("<span class='danger'>\The [user] blocks [attack_text] with \the [src]!</span>")
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("<span class='danger'>\The [user] blocks [attack_text] with \the [src]!</span>")
return 1
return PROJECTILE_STOPPED
/obj/item/melee/energy/get_print_info()
. = ..()
+10 -10
View File
@@ -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("<span class='danger'>\The [user] blocks [attack_text] with \the [src]!</span>")
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("<span class='danger'>\The [user] blocks [attack_text] with \the [src]!</span>")
return 1
return PROJECTILE_STOPPED
else
user.visible_message("<span class='danger'>\The [user] blocks [attack_text] with \the [src]!</span>")
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)
+1 -1
View File
@@ -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 )
+2 -2
View File
@@ -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)
@@ -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))
+1 -2
View File
@@ -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
@@ -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
+17 -10
View File
@@ -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("<span class='notice'>\The [src] misses [target_mob] narrowly!</span>")
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("<span class='notice'>\The [src] misses [target_mob] narrowly!</span>")
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, "<span class='danger'>You've been hit in the [impacted_organ] by \a [src]!</span>")
+7
View File
@@ -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."