mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-24 05:23:22 +01:00
Shield Fix (#12074)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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()
|
||||
. = ..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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."
|
||||
Reference in New Issue
Block a user