Replaces disarm right click action with tgstation/tgstation#42958 's disarm action, also ports the removal of non-help intent pushing from that same pr

This commit is contained in:
deathride58
2019-03-04 21:05:50 -05:00
parent bf829a2d79
commit d8f738184b
6 changed files with 207 additions and 23 deletions
+14
View File
@@ -97,6 +97,20 @@
//the define for visible message range in combat
#define COMBAT_MESSAGE_RANGE 3
//Shove knockdown lengths (deciseconds)
#define SHOVE_KNOCKDOWN_SOLID 30
#define SHOVE_KNOCKDOWN_HUMAN 30
#define SHOVE_KNOCKDOWN_TABLE 30
#define SHOVE_KNOCKDOWN_COLLATERAL 10
//Shove slowdown
#define SHOVE_SLOWDOWN_ID "shove_slowdown"
#define SHOVE_SLOWDOWN_LENGTH 30
#define SHOVE_SLOWDOWN_STRENGTH 0.85 //multiplier
//Shove disarming item list
GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
/obj/item/gun)))
//Combat object defines
//Embedded objects
+2
View File
@@ -24,6 +24,8 @@
var/can_flashlight = 0
var/scan_reagents = 0 //Can the wearer see reagents while it's equipped?
var/blocks_shove_knockdown = FALSE //Whether wearing the clothing item blocks the ability for shove to knock down.
var/clothing_flags = NONE
//Var modification - PLEASE be careful with this I know who you are and where you live
+2 -1
View File
@@ -110,13 +110,14 @@
/obj/item/clothing/suit/armor/riot
name = "riot suit"
desc = "A suit of semi-flexible polycarbonate body armor with heavy padding to protect against melee attacks."
desc = "A suit of semi-flexible polycarbonate body armor with heavy padding to protect against melee attacks. Helps the wearer resist shoving in close quarters."
icon_state = "riot"
item_state = "swat_suit"
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
blocks_shove_knockdown = TRUE
strip_delay = 80
equip_delay_other = 60
@@ -892,6 +892,21 @@
. = ..(M,force,check_loc)
stop_pulling()
/mob/living/carbon/human/proc/is_shove_knockdown_blocked() //If you want to add more things that block shove knockdown, extend this
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor)
for(var/bp in body_parts)
if(istype(bp, /obj/item/clothing))
var/obj/item/clothing/C = bp
if(C.blocks_shove_knockdown)
return TRUE
return FALSE
/mob/living/carbon/human/proc/clear_shove_slowdown()
remove_movespeed_modifier(SHOVE_SLOWDOWN_ID)
var/active_item = get_active_held_item()
if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
visible_message("<span class='warning'>[src.name] regains their grip on \the [active_item]!</span>", "<span class='warning'>You regain your grip on \the [active_item]</span>", null, COMBAT_MESSAGE_RANGE)
/mob/living/carbon/human/do_after_coefficent()
. = ..()
. *= physiology.do_after_speed
+3
View File
@@ -170,6 +170,9 @@
var/mob/living/L = M
if(L.has_trait(TRAIT_PUSHIMMUNE))
return 1
//If they're a human, and they're not in help intent, block pushing
if(ishuman(M) && (M.a_intent != INTENT_HELP))
return TRUE
//anti-riot equipment is also anti-push
for(var/obj/item/I in M.held_items)
if(!istype(M, /obj/item/clothing))
@@ -44,37 +44,186 @@
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
to_chat(user, "<span class='warning'>You're too exhausted.</span>")
return FALSE
else if(target.check_block())
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</span>")
return 0
if(target.check_block())
target.visible_message("<span class='warning'>[target] blocks [user]'s shoving attempt!</span>")
return FALSE
if(attacker_style && attacker_style.disarm_act(user,target))
return 1
return TRUE
if(user.resting)
return FALSE
else
if(user == target)
return
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
user.adjustStaminaLossBuffered(4) //CITADEL CHANGE - makes disarmspam cause staminaloss
user.adjustStaminaLossBuffered(4)
playsound(target, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
if(target.w_uniform)
target.w_uniform.add_fingerprint(user)
var/randomized_zone = ran_zone(user.zone_selected)
SEND_SIGNAL(target, COMSIG_HUMAN_DISARM_HIT, user, user.zone_selected)
var/obj/item/bodypart/affecting = target.get_bodypart(randomized_zone)
if((!target.combatmode && user.combatmode || prob(target.getStaminaLoss()*(user.resting ? 0.25 : 1)*(user.combatmode ? 1 : 0.05))) && !target.resting) //probability depends on staminaloss. it's plausible, but unlikely that you'll be able to push someone over while resting, and pretty rare to successfully push someone outside of combat mode. The few people that even know how to right-click outside of combat mode are a rarity but let's take that into account regardless.
playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
target.visible_message("<span class='danger'>[user] [user.combatmode ? "has" : "gently"] pushed [target]!</span>",
"<span class='userdanger'>[user] has pushed [target]!</span>", null, COMBAT_MESSAGE_RANGE)
target.apply_effect(40, EFFECT_KNOCKDOWN, target.run_armor_check(affecting, "melee", "Your armor prevents your fall!", "Your armor softens your fall!"))
target.forcesay(GLOB.hit_appends)
log_combat(user, target, "disarmed", " pushing them to the ground")
return
if(!target.resting)
target.adjustStaminaLoss(5)
var/turf/target_oldturf = target.loc
var/shove_dir = get_dir(user.loc, target_oldturf)
var/turf/target_shove_turf = get_step(target.loc, shove_dir)
var/mob/living/carbon/human/collateral_human
var/obj/structure/table/target_table
var/shove_blocked = FALSE //Used to check if a shove is blocked so that if it is knockdown logic can be applied
var/directional_obstruction = FALSE //used for checking if a directional structure on the tile is potentially blocking
//WARNING: INCOMING MEGA HELLCODE
//Blame that directional windows are insane and that diagonal movement is kind of a bitch.
for(var/obj/O in target_oldturf.contents)
if(O.flags_1 & ON_BORDER_1)
directional_obstruction = TRUE
break
if(directional_obstruction)
if(!(shove_dir in GLOB.diagonals)) //the logic is a bit different for diagonal shoves, see later in the code
for(var/obj/A in target_oldturf.contents)
if(A.flags_1 & ON_BORDER_1 && A.dir == shove_dir)
shove_blocked = TRUE
else
var/dir_1 = turn(shove_dir, -45) //No randomization on the assignment here because the situation that requires randomization can't happen
var/dir_1_blocked = FALSE
var/dir_2 = turn(shove_dir, 45)
var/dir_2_blocked = FALSE
for(var/obj/A in target_oldturf.contents)
if(A.flags_1 & ON_BORDER_1)
if(A.dir == dir_1)
dir_1_blocked = TRUE
else if(A.dir == dir_2)
dir_2_blocked = TRUE
if(dir_1_blocked && dir_2_blocked)
break
if(dir_1_blocked && dir_2_blocked)
shove_blocked = TRUE
else if(dir_1_blocked && !dir_2_blocked)
shove_dir = dir_2
else if(dir_2 && !dir_1_blocked)
shove_dir = dir_1
target_shove_turf = get_step(target.loc, shove_dir)
if(!shove_blocked) //Skip this if it's already directionally blocked for speed reasons
if (!(shove_dir in GLOB.diagonals)) //Diagonals have a lot more complicated of logic, so if it's not a diagonal a much faster check can be run
if(is_blocked_turf(target_shove_turf, FALSE))
var/blocking_dir = turn(shove_dir, 180)
var/no_directionals = TRUE
var/blocked_by_directional = FALSE
for(var/obj/O in target_shove_turf.contents)
if(O.anchored)
shove_blocked = TRUE
if(O.flags_1 & ON_BORDER_1)
no_directionals = FALSE
if(O.dir == blocking_dir)
blocked_by_directional = TRUE
if(no_directionals && blocked_by_directional)
shove_blocked = TRUE
else
var/turf/diagonal_turf = target_shove_turf
var/turf/cardinal_turf_1
var/turf/cardinal_turf_2
target_shove_turf = diagonal_turf
if(prob(50)) //Check the two turfs in a random order to make sure if both are free one isn't always favored
cardinal_turf_1 = get_step(target.loc, turn(shove_dir, -45))
cardinal_turf_2 = get_step(target.loc, turn(shove_dir, 45))
else
cardinal_turf_1 = get_step(target.loc, turn(shove_dir, 45))
cardinal_turf_2 = get_step(target.loc, turn(shove_dir, -45))
var/cardinal_1_free = FALSE
var/cardinal_2_free = FALSE
var/diagonal_free = FALSE
if(!is_blocked_turf(cardinal_turf_1, FALSE))
target_shove_turf = cardinal_turf_1
cardinal_1_free = TRUE
if(!is_blocked_turf(cardinal_turf_2, FALSE))
target_shove_turf = cardinal_turf_2
cardinal_2_free = TRUE
if(cardinal_1_free && cardinal_2_free && !is_blocked_turf(diagonal_turf, FALSE)) //Check the diagonal last because the other two need to be clear as well
target_shove_turf = diagonal_turf
diagonal_free = TRUE
if(!cardinal_1_free && !cardinal_2_free && !diagonal_free) //If a free tile wasn't found, we need to do even more expensive of checks
shove_blocked = TRUE
if(!istype(cardinal_turf_1, /turf/closed))
for(var/content in cardinal_turf_1.contents)
if(istype(content, /obj/structure/table))
target_table = content
break
if(ishuman(content))
collateral_human = content
break
if(target_table || collateral_human)
target_shove_turf = cardinal_turf_1
if(!target_table && !collateral_human && !istype(cardinal_turf_2, /turf/closed))
for(var/content in cardinal_turf_2.contents)
if(istype(content, /obj/structure/table))
target_table = content
break
if(ishuman(content))
collateral_human = content
break
if(target_table || collateral_human)
target_shove_turf = cardinal_turf_2
var/targetatrest = target.resting
if(shove_blocked && !target.is_shove_knockdown_blocked())
if((!target_table || !collateral_human) && !directional_obstruction && !(shove_dir in GLOB.diagonals))
for(var/content in target_shove_turf.contents)
if(istype(content, /obj/structure/table))
target_table = content
break
if(ishuman(content))
collateral_human = content
break
if(target_table)
if(!targetatrest)
target.Knockdown(SHOVE_KNOCKDOWN_TABLE)
user.visible_message("<span class='danger'>[user.name] shoves [target.name] onto \the [target_table]!</span>",
"<span class='danger'>You shove [target.name] onto \the [target_table]!</span>", null, COMBAT_MESSAGE_RANGE)
target.forceMove(target_shove_turf)
log_combat(user, target, "shoved", "onto [target_table]")
else if(collateral_human && !targetatrest)
target.Knockdown(SHOVE_KNOCKDOWN_HUMAN)
collateral_human.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
user.visible_message("<span class='danger'>[user.name] shoves [target.name] into [collateral_human.name]!</span>",
"<span class='danger'>You shove [target.name] into [collateral_human.name]!</span>", null, COMBAT_MESSAGE_RANGE)
log_combat(user, target, "shoved", "into [collateral_human.name]")
else
target.Move(target_shove_turf) //This move should be blocked anyways, this fixes some odd behavior with things like doors and grills
if(!targetatrest)
target.Knockdown(SHOVE_KNOCKDOWN_SOLID)
user.visible_message("<span class='danger'>[user.name] shoves [target.name][targetatrest ? ".": ", knocking them down!"]</span>",
"<span class='danger'>You shove [target.name][targetatrest ? ".": ", knocking them down!"]</span>", null, COMBAT_MESSAGE_RANGE)
log_combat(user, target, "shoved", "knocking them down")
else
user.visible_message("<span class='danger'>[user.name] shoves [target.name]!</span>",
"<span class='danger'>You shove [target.name]!</span>", null, COMBAT_MESSAGE_RANGE)
var/target_held_item = target.get_active_held_item()
var/knocked_item = FALSE
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
if(!target.has_movespeed_modifier(SHOVE_SLOWDOWN_ID))
target.add_movespeed_modifier(SHOVE_SLOWDOWN_ID, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
if(target_held_item)
target.visible_message("<span class='danger'>[target.name]'s grip on \the [target_held_item] loosens!</span>",
"<span class='danger'>Your grip on \the [target_held_item] loosens!</span>", null, COMBAT_MESSAGE_RANGE)
addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
else if(target_held_item)
target.dropItemToGround(target_held_item)
knocked_item = TRUE
target.visible_message("<span class='danger'>[target.name] drops \the [target_held_item]!!</span>",
"<span class='danger'>You drop \the [target_held_item]!!</span>", null, COMBAT_MESSAGE_RANGE)
target.Move(target_shove_turf)
var/append_message = ""
if(target_held_item)
if(knocked_item)
append_message = "causing them to drop [target_held_item]"
else
append_message = "loosening their grip on [target_held_item]"
log_combat(user, target, "shoved", append_message)
playsound(target, 'sound/weapons/thudswoosh.ogg', 25, 1, -1)
target.visible_message("<span class='danger'>[user] [user.combatmode ? "attempted to push" : "tries to gently push"] [target] over!</span>", \
"<span class='userdanger'>[user] [user.combatmode ? "attempted to push" : "tries to gently push"] [target] over!</span>", null, COMBAT_MESSAGE_RANGE)
if(!target.resting && !user.resting && user.combatmode)
target.adjustStaminaLoss(rand(1,5)) //This is the absolute most inefficient way to get someone into soft stamcrit, but if you've got a crowd trying to shove you over, you've no option but to get knocked down and accept fate
log_combat(user, target, "attempted to disarm push")
////////////////////
/////BODYPARTS/////