Merge pull request #9380 from Ghommie/Ghommie_cit212

refactoring and fixing altdisarm() exploits (ergo pushing people over directional windows etc).
This commit is contained in:
kevinz000
2019-10-01 23:58:27 -07:00
committed by GitHub
6 changed files with 65 additions and 49 deletions
+1
View File
@@ -10,6 +10,7 @@
#define UNIQUE_RENAME (1<<6) // can you customize the description/name of the thing?
#define USES_TGUI (1<<7) //put on things that use tgui on ui_interact instead of custom/old UI.
#define FROZEN (1<<8)
#define SHOVABLE_ONTO (1<<9) //called on turf.shove_act() to consider whether an object should have a niche effect (defined in their own shove_act()) when someone is pushed onto it, or do a sanity CanPass() check.
// If you add new ones, be sure to add them to /obj/Initialize as well for complete mapping support
+5
View File
@@ -235,6 +235,11 @@
SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, P, def_zone)
. = P.on_hit(src, 0, def_zone)
//used on altdisarm() for special interactions between the shoved victim (target) and the src, with user being the one shoving the target on it.
// IMPORTANT: if you wish to add a new own shove_act() to a certain object, remember to add SHOVABLE_ONTO to its obj_flags bitfied var first.
/atom/proc/shove_act(mob/living/target, mob/living/user)
return FALSE
/atom/proc/in_contents_of(container)//can take class or object instance as argument
if(ispath(container))
if(istype(src.loc, container))
@@ -21,6 +21,7 @@
anchored = TRUE
layer = TABLE_LAYER
climbable = TRUE
obj_flags = CAN_BE_HIT|SHOVABLE_ONTO
pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.")
var/frame = /obj/structure/table_frame
var/framestack = /obj/item/stack/rods
@@ -136,6 +137,15 @@
var/mob/living/carbon/human/H = pushed_mob
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table)
/obj/structure/table/shove_act(mob/living/target, mob/living/user)
if(!target.resting)
target.Knockdown(SHOVE_KNOCKDOWN_TABLE)
user.visible_message("<span class='danger'>[user.name] shoves [target.name] onto \the [src]!</span>",
"<span class='danger'>You shove [target.name] onto \the [src]!</span>", null, COMBAT_MESSAGE_RANGE)
target.forceMove(src.loc)
log_combat(user, target, "shoved", "onto [src] (table)")
return TRUE
/obj/structure/table/attackby(obj/item/I, mob/user, params)
if(!(flags_1 & NODECONSTRUCT_1))
if(istype(I, /obj/item/screwdriver) && deconstruction_ready)
+13
View File
@@ -382,6 +382,19 @@
if(ismob(A) || .)
A.ratvar_act()
//called on /datum/species/proc/altdisarm()
/turf/shove_act(mob/living/target, mob/living/user, pre_act = FALSE)
var/list/possibilities
for(var/obj/O in contents)
if(CHECK_BITFIELD(O.obj_flags, SHOVABLE_ONTO))
LAZYADD(possibilities, O)
else if(!O.CanPass(target, src))
return FALSE
if(possibilities)
var/obj/O = pick(possibilities)
return O.shove_act(target, user)
return FALSE
/turf/proc/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
underlay_appearance.icon = icon
underlay_appearance.icon_state = icon_state
@@ -1821,67 +1821,36 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(!target.resting)
target.adjustStaminaLoss(5)
if(target.is_shove_knockdown_blocked())
return
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/target_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
//Thank you based whoneedsspace
target_collateral_human = locate(/mob/living/carbon/human) in target_shove_turf.contents
if(target_collateral_human)
if(target_collateral_human && target_collateral_human.resting)
shove_blocked = TRUE
else
target_collateral_human = null
target.Move(target_shove_turf, shove_dir)
if(get_turf(target) == target_oldturf)
if(target_shove_turf.density)
shove_blocked = TRUE
else
var/thoushallnotpass = FALSE
for(var/obj/O in target_shove_turf)
if(istype(O, /obj/structure/table))
target_table = O
else if(!O.CanPass(src, target_shove_turf))
shove_blocked = TRUE
thoushallnotpass = TRUE
if(thoushallnotpass)
target_table = null
shove_blocked = TRUE
if(target.is_shove_knockdown_blocked())
return
if(shove_blocked || target_table)
var/directional_blocked = FALSE
if(shove_dir in GLOB.cardinals) //Directional checks to make sure that we're not shoving through a windoor or something like that
var/target_turf = get_turf(target)
for(var/obj/O in target_turf)
if(O.flags_1 & ON_BORDER_1 && O.dir == shove_dir && O.density)
directional_blocked = TRUE
break
if(target_turf != target_shove_turf) //Make sure that we don't run the exact same check twice on the same tile
for(var/obj/O in target_shove_turf)
if(O.flags_1 & ON_BORDER_1 && O.dir == turn(shove_dir, 180) && O.density)
directional_blocked = TRUE
break
if(shove_blocked && !target.buckled)
var/directional_blocked = !target.Adjacent(target_shove_turf)
var/targetatrest = target.resting
if(((!target_table && !target_collateral_human) || directional_blocked) && !targetatrest)
if((directional_blocked || (!target_collateral_human && !target_shove_turf.shove_act(target, user))) && !targetatrest)
target.Knockdown(SHOVE_KNOCKDOWN_SOLID)
user.visible_message("<span class='danger'>[user.name] shoves [target.name], knocking them down!</span>",
"<span class='danger'>You shove [target.name], knocking them down!</span>", null, COMBAT_MESSAGE_RANGE)
log_combat(user, target, "shoved", "knocking them down")
else 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(target_collateral_human && !targetatrest)
target.Knockdown(SHOVE_KNOCKDOWN_HUMAN)
if(!target_collateral_human.resting)
target_collateral_human.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
target_collateral_human.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
user.visible_message("<span class='danger'>[user.name] shoves [target.name] into [target_collateral_human.name]!</span>",
"<span class='danger'>You shove [target.name] into [target_collateral_human.name]!</span>", null, COMBAT_MESSAGE_RANGE)
log_combat(user, target, "shoved", "into [target_collateral_human.name]")
+27 -9
View File
@@ -111,14 +111,7 @@
stuff_mob_in(target, user)
/obj/machinery/disposal/proc/stuff_mob_in(mob/living/target, mob/living/user)
if(!iscarbon(user) && !user.ventcrawler) //only carbon and ventcrawlers can climb into disposal by themselves.
return
if(!isturf(user.loc)) //No magically doing it from inside closets
return
if(target.buckled || target.has_buckled_mobs())
return
if(target.mob_size > MOB_SIZE_HUMAN)
to_chat(user, "<span class='warning'>[target] doesn't fit inside [src]!</span>")
if(!can_stuff_mob_in(target, user))
return
add_fingerprint(user)
if(user == target)
@@ -137,6 +130,19 @@
target.LAssailant = user
update_icon()
/obj/machinery/disposal/proc/can_stuff_mob_in(mob/living/target, mob/living/user, pushing = FALSE)
if(!pushing && !iscarbon(user) && !user.ventcrawler) //only carbon and ventcrawlers can climb into disposal by themselves.
return FALSE
if(!isturf(user.loc)) //No magically doing it from inside closets
return FALSE
if(target.buckled || target.has_buckled_mobs())
return FALSE
if(target.mob_size > MOB_SIZE_HUMAN)
if(!pushing)
to_chat(user, "<span class='warning'>[target] doesn't fit inside [src]!</span>")
return FALSE
return TRUE
/obj/machinery/disposal/relaymove(mob/user)
attempt_escape(user)
@@ -265,6 +271,7 @@
desc = "A pneumatic waste disposal unit."
icon_state = "disposal"
var/datum/oracle_ui/themed/nano/ui
obj_flags = CAN_BE_HIT | USES_TGUI | SHOVABLE_ONTO
/obj/machinery/disposal/bin/Initialize(mapload, obj/structure/disposalconstruct/make_from)
. = ..()
@@ -305,7 +312,7 @@
if(Adjacent(user))
return TRUE
return ..()
/obj/machinery/disposal/bin/oui_data(mob/user)
var/list/data = list()
@@ -360,6 +367,17 @@
else
return ..()
/obj/machinery/disposal/bin/shove_act(mob/living/target, mob/living/user)
if(can_stuff_mob_in(target, user, TRUE))
target.Knockdown(SHOVE_KNOCKDOWN_SOLID)
target.forceMove(src)
user.visible_message("<span class='danger'>[user.name] shoves [target.name] into \the [src]!</span>",
"<span class='danger'>You shove [target.name] into \the [src]!</span>", null, COMBAT_MESSAGE_RANGE)
log_combat(user, target, "shoved", "into [src] (disposal bin)")
return TRUE
return FALSE
/obj/machinery/disposal/bin/flush()
..()
full_pressure = FALSE