From 342eae84cd1039ce4ee88a7d223c281ecb57948d Mon Sep 17 00:00:00 2001 From: FalloutFalcon Date: Wed, 1 May 2024 22:49:30 -0500 Subject: [PATCH 1/6] improvments to thrown so you can target items and stuff --- code/__DEFINES/flags.dm | 1 + code/_globalvars/bitfields.dm | 1 + code/controllers/subsystem/throwing.dm | 61 ++++++++++--------- code/game/atoms_movable.dm | 4 +- code/game/objects/items/devices/mines.dm | 11 ++-- code/modules/food_and_drinks/drinks/drinks.dm | 37 ++++++----- 6 files changed, 64 insertions(+), 51 deletions(-) diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index e0ac4b177001..c27a78ffd2de 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -123,6 +123,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define FLOATING (1<<3) /// When moving, will Cross()/Uncross() everything, but won't stop or Bump() anything. #define PHASING (1<<4) +#define THROWN (1<<5) //Fire and Acid stuff, for resistance_flags #define LAVA_PROOF (1<<0) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 406f0bb0b101..52ffff0401ac 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -190,6 +190,7 @@ DEFINE_BITFIELD(movement_type, list( "GROUND" = GROUND, "PHASING" = PHASING, "VENTCRAWLING" = VENTCRAWLING, + "THROWN" = THROWN, )) DEFINE_BITFIELD(obj_flags, list( diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm index 0260e952d10d..e8cd514eb48b 100644 --- a/code/controllers/subsystem/throwing.dm +++ b/code/controllers/subsystem/throwing.dm @@ -47,7 +47,7 @@ SUBSYSTEM_DEF(throwing) /datum/thrownthing var/atom/movable/thrownthing - var/atom/target + var/datum/weakref/initial_target var/turf/target_turf var/target_zone var/init_dir @@ -71,12 +71,13 @@ SUBSYSTEM_DEF(throwing) var/last_move = 0 -/datum/thrownthing/New(thrownthing, target, target_turf, init_dir, maxrange, speed, thrower, diagonals_first, force, gentle, callback, target_zone) +/datum/thrownthing/New(thrownthing, target, init_dir, maxrange, speed, thrower, diagonals_first, force, gentle, callback, target_zone) . = ..() src.thrownthing = thrownthing RegisterSignal(thrownthing, COMSIG_PARENT_QDELETING, PROC_REF(on_thrownthing_qdel)) - src.target = target - src.target_turf = target_turf + src.target_turf = get_turf(target) + if(target_turf != target) + src.initial_target = WEAKREF(target) src.init_dir = init_dir src.maxrange = maxrange src.speed = speed @@ -87,14 +88,13 @@ SUBSYSTEM_DEF(throwing) src.callback = callback src.target_zone = target_zone - /datum/thrownthing/Destroy() SSthrowing.processing -= thrownthing SSthrowing.currentrun -= thrownthing thrownthing.throwing = null thrownthing = null - target = null thrower = null + initial_target = null if(callback) QDEL_NULL(callback) //It stores a reference to the thrownthing, its source. Let's clean that. return ..() @@ -109,6 +109,7 @@ SUBSYSTEM_DEF(throwing) /datum/thrownthing/proc/tick() var/atom/movable/AM = thrownthing + AM.setMovetype(AM.movement_type | THROWN) if (!isturf(AM.loc) || !AM.throwing) finalize() return @@ -117,9 +118,17 @@ SUBSYSTEM_DEF(throwing) delayed_time += world.time - last_move return - if (dist_travelled && hitcheck()) //to catch sneaky things moving on our tile while we slept - finalize() - return + var/atom/movable/actual_target = initial_target?.resolve() + + if(dist_travelled) //to catch sneaky things moving on our tile while we slept + for(var/atom/movable/obstacle as anything in get_turf(thrownthing)) + if (obstacle == thrownthing || (obstacle == thrower && !ismob(thrownthing))) + continue + if(obstacle.pass_flags_self & LETPASSTHROW) + continue + if (obstacle == actual_target || (obstacle.density && !(obstacle.flags_1 & ON_BORDER_1))) + finalize(TRUE, obstacle) + return var/atom/step @@ -146,10 +155,15 @@ SUBSYSTEM_DEF(throwing) finalize() return - AM.Move(step, get_dir(AM, step), DELAY_TO_GLIDE_SIZE(1 / speed)) + if(!AM.Move(step, get_dir(AM, step), DELAY_TO_GLIDE_SIZE(1 / speed))) // we hit something during our move... + if(AM.throwing) // ...but finalize() wasn't called on Bump() because of a higher level definition that doesn't always call parent. + finalize() + return - if (!AM.throwing) // we hit something during our move - finalize(hit = TRUE) + dist_travelled++ + + if(actual_target && !(actual_target.pass_flags_self & LETPASSTHROW) && actual_target.loc == AM.loc) // we crossed a movable with no density (e.g. a mouse or APC) we intend to hit anyway. + finalize(TRUE, actual_target) return dist_travelled++ @@ -158,18 +172,19 @@ SUBSYSTEM_DEF(throwing) finalize() return -/datum/thrownthing/proc/finalize(hit = FALSE, target=null) +//If the target hasent been hit search for it in the turf we landed on. +/datum/thrownthing/proc/finalize(hit = FALSE, target = null) set waitfor = FALSE //done throwing, either because it hit something or it finished moving if(!thrownthing) return thrownthing.throwing = null + thrownthing.setMovetype(thrownthing.movement_type & ~THROWN) if (!hit) - for (var/thing in get_turf(thrownthing)) //looking for our target on the turf we land on. - var/atom/A = thing - if (A == target) + for (var/atom/movable/obstacle as anything in get_turf(thrownthing)) //looking for our target on the turf we land on. + if (obstacle == target) hit = TRUE - thrownthing.throw_impact(A, src) + thrownthing.throw_impact(obstacle, src) if(QDELETED(thrownthing)) //throw_impact can delete things, such as glasses smashing return //deletion should already be handled by on_thrownthing_qdel() break @@ -195,15 +210,3 @@ SUBSYSTEM_DEF(throwing) T.zFall(thrownthing) qdel(src) - -/datum/thrownthing/proc/hit_atom(atom/A) - finalize(hit=TRUE, target=A) - -/datum/thrownthing/proc/hitcheck() - for (var/thing in get_turf(thrownthing)) - var/atom/movable/AM = thing - if (AM == thrownthing || (AM == thrower && !ismob(thrownthing))) - continue - if (AM.density && !(AM.pass_flags_self & LETPASSTHROW) && !(AM.flags_1 & ON_BORDER_1)) - finalize(hit=TRUE, target=AM) - return TRUE diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 989db20efd1f..7702d75b98f4 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -624,7 +624,7 @@ SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A) . = ..() if(!QDELETED(throwing)) - throwing.hit_atom(A) + throwing.finalize(hit = TRUE, target = A) . = TRUE if(QDELETED(A)) return @@ -883,7 +883,7 @@ else target_zone = thrower.zone_selected - var/datum/thrownthing/TT = new(src, target, get_turf(target), get_dir(src, target), range, speed, thrower, diagonals_first, force, gentle, callback, target_zone) + var/datum/thrownthing/TT = new(src, target, get_dir(src, target), range, speed, thrower, diagonals_first, force, gentle, callback, target_zone) var/dist_x = abs(target.x - src.x) var/dist_y = abs(target.y - src.y) diff --git a/code/game/objects/items/devices/mines.dm b/code/game/objects/items/devices/mines.dm index 112e26e1303b..1772cbf497c3 100644 --- a/code/game/objects/items/devices/mines.dm +++ b/code/game/objects/items/devices/mines.dm @@ -212,11 +212,8 @@ SIGNAL_HANDLER if(!can_trigger(arrived)) return - // Flying = can't step on a mine - if(arrived.movement_type & FLYING) - return - //no cheap disarming - if(arrived.throwing && isitem(arrived)) + // All other movment types rn can easily avoid it + if(!(arrived.movement_type == GROUND)) return // Someone already on it if(foot_on_mine?.resolve()) @@ -257,6 +254,10 @@ clicked = FALSE . = ..() +/obj/item/mine/pressure/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) + trigger_mine(AM) + ..() + //handles disarming(and failing to disarm) /obj/item/mine/pressure/attackby(obj/item/I, mob/user) if(I.tool_behaviour == TOOL_SCREWDRIVER) diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 8f88924930f4..51d17efbd04d 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -120,27 +120,34 @@ if(!.) //if the bottle wasn't caught smash(hit_atom, throwingdatum?.thrower, TRUE) -/obj/item/reagent_containers/food/drinks/proc/smash(atom/target, mob/thrower, ranged = FALSE) +/obj/item/reagent_containers/food/drinks/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) + smash() + ..() + +/obj/item/reagent_containers/food/drinks/proc/smash(atom/target = FALSE, mob/thrower = FALSE, ranged = FALSE) if(!isGlass) return - if(QDELING(src) || !target || !(flags_1 & INITIALIZED_1)) //Invalid loc - return - if(bartender_check(target) && ranged) + if(QDELING(src) || !(flags_1 & INITIALIZED_1)) //Invalid loc return - var/obj/item/broken_bottle/B = new (loc) - B.icon_state = icon_state - var/icon/I = new(icon, icon_state) - I.Blend(B.broken_outline, ICON_OVERLAY, rand(5), 1) - I.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0)) - B.icon = I - B.name = "broken [name]" + if(target) + if(bartender_check(target) && ranged) + return + var/obj/item/broken_bottle/smashed_bottle = new (loc) + smashed_bottle.icon_state = icon_state + var/icon/new_icon = new(icon, icon_state) + new_icon.Blend(smashed_bottle.broken_outline, ICON_OVERLAY, rand(5), 1) + new_icon.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0)) + smashed_bottle.icon = new_icon + smashed_bottle.name = "broken [name]" if(prob(33)) - var/obj/item/shard/S = new(drop_location()) - target.Bumped(S) + var/obj/item/shard/new_shard = new(drop_location()) + if(target) + target.Bumped(new_shard) playsound(src, "shatter", 70, TRUE) - transfer_fingerprints_to(B) + transfer_fingerprints_to(smashed_bottle) qdel(src) - target.Bumped(B) + if(target) + target.Bumped(smashed_bottle) /obj/item/reagent_containers/food/drinks/bullet_act(obj/projectile/P) . = ..() From 7edac5c9841c1f3dd997da2c5ac35ae8a4aef7ed Mon Sep 17 00:00:00 2001 From: fallcon Date: Thu, 2 May 2024 08:10:59 -0500 Subject: [PATCH 2/6] dont push resting and make bottles break --- .../food_and_drinks/drinks/drinks/bottle.dm | 44 +++++++++---------- code/modules/mob/living/living_defense.dm | 3 ++ 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 4da78a5989a1..b3d461fa8889 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -34,36 +34,36 @@ volume = 50 custom_price = 55 -/obj/item/reagent_containers/food/drinks/bottle/smash(mob/living/target, mob/thrower, ranged = FALSE) - if(QDELING(src) || !target || !(flags_1 & INITIALIZED_1)) //Invalid loc +//Creates a shattering noise and replaces the bottle with a broken_bottle +/obj/item/reagent_containers/food/drinks/bottle/smash(mob/living/target = FALSE, mob/thrower = FALSE, ranged = FALSE) + if(QDELING(src) || !(flags_1 & INITIALIZED_1)) //Invalid loc return - //Creates a shattering noise and replaces the bottle with a broken_bottle - if(bartender_check(target) && ranged) - return - var/obj/item/broken_bottle/B = new (loc) + if(target) + if(bartender_check(target) && ranged) + return + var/obj/item/broken_bottle/smashed_bottle = new (loc) if(!ranged && thrower) thrower.put_in_hands(B) - B.icon_state = icon_state - - var/icon/I = new('icons/obj/drinks/drinks.dmi', src.icon_state) - I.Blend(B.broken_outline, ICON_OVERLAY, rand(5), 1) - I.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0)) - B.icon = I - + smashed_bottle.icon_state = icon_state + var/icon/new_icon = new('icons/obj/drinks/drinks.dmi', src.icon_state) + new_icon.Blend(smashed_bottle.broken_outline, ICON_OVERLAY, rand(5), 1) + new_icon.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0)) + smashed_bottle.icon = I if(isGlass) if(prob(33)) - var/obj/item/shard/S = new(drop_location()) - target.Bumped(S) + var/obj/item/shard/new_shard = new(drop_location()) + if(target) + target.Bumped(new_shard) playsound(src, "shatter", 70, TRUE) else - B.force = 0 - B.throwforce = 0 - B.desc = "A carton with the bottom half burst open. Might give you a papercut." - B.name = "broken [name]" - transfer_fingerprints_to(B) - + smashed_bottle.force = 0 + smashed_bottle.throwforce = 0 + smashed_bottle.desc = "A carton with the bottom half burst open. Might give you a papercut." + smashed_bottle.name = "broken [name]" + transfer_fingerprints_to(smashed_bottle) qdel(src) - target.Bumped(B) + if(target) + target.Bumped(smashed_bottle) /obj/item/reagent_containers/food/drinks/bottle/attack(mob/living/target, mob/living/user) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 86c85d27360a..977cb220568e 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -101,6 +101,9 @@ return 1 else playsound(loc, 'sound/weapons/genhit.ogg', 50, TRUE, -1) //Item sounds are handled in the item itself + + if(body_position == LYING_DOWN) // physics says it's significantly harder to push someone by constantly chucking random furniture at them if they are down on the floor. + hitpush = FALSE ..() From 125de5ae0687e1ba265c76eb4a7b45ae1624be91 Mon Sep 17 00:00:00 2001 From: fallcon Date: Thu, 2 May 2024 08:24:16 -0500 Subject: [PATCH 3/6] only glass things shatter like that? we dont need a snowflake proc just to let you break cartons --- code/modules/food_and_drinks/drinks/drinks.dm | 2 ++ .../food_and_drinks/drinks/drinks/bottle.dm | 31 ------------------- 2 files changed, 2 insertions(+), 31 deletions(-) diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 51d17efbd04d..aa2830daee92 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -133,6 +133,8 @@ if(bartender_check(target) && ranged) return var/obj/item/broken_bottle/smashed_bottle = new (loc) + if(!ranged && thrower) + thrower.put_in_hands(smashed_bottle) smashed_bottle.icon_state = icon_state var/icon/new_icon = new(icon, icon_state) new_icon.Blend(smashed_bottle.broken_outline, ICON_OVERLAY, rand(5), 1) diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index b3d461fa8889..34a475c1dfda 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -34,37 +34,6 @@ volume = 50 custom_price = 55 -//Creates a shattering noise and replaces the bottle with a broken_bottle -/obj/item/reagent_containers/food/drinks/bottle/smash(mob/living/target = FALSE, mob/thrower = FALSE, ranged = FALSE) - if(QDELING(src) || !(flags_1 & INITIALIZED_1)) //Invalid loc - return - if(target) - if(bartender_check(target) && ranged) - return - var/obj/item/broken_bottle/smashed_bottle = new (loc) - if(!ranged && thrower) - thrower.put_in_hands(B) - smashed_bottle.icon_state = icon_state - var/icon/new_icon = new('icons/obj/drinks/drinks.dmi', src.icon_state) - new_icon.Blend(smashed_bottle.broken_outline, ICON_OVERLAY, rand(5), 1) - new_icon.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0)) - smashed_bottle.icon = I - if(isGlass) - if(prob(33)) - var/obj/item/shard/new_shard = new(drop_location()) - if(target) - target.Bumped(new_shard) - playsound(src, "shatter", 70, TRUE) - else - smashed_bottle.force = 0 - smashed_bottle.throwforce = 0 - smashed_bottle.desc = "A carton with the bottom half burst open. Might give you a papercut." - smashed_bottle.name = "broken [name]" - transfer_fingerprints_to(smashed_bottle) - qdel(src) - if(target) - target.Bumped(smashed_bottle) - /obj/item/reagent_containers/food/drinks/bottle/attack(mob/living/target, mob/living/user) if(!target) From 0246c2f46ef64ca01508c12a26b04d8f90efddfd Mon Sep 17 00:00:00 2001 From: fallcon Date: Thu, 2 May 2024 09:33:43 -0500 Subject: [PATCH 4/6] beartrap and lights --- code/game/objects/items/handcuffs.dm | 5 +++++ code/modules/power/lighting.dm | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index 496fc07288ec..f41deb5598a6 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -272,6 +272,11 @@ update_appearance() playsound(src, 'sound/effects/snap.ogg', 50, TRUE) +/obj/item/restraints/legcuffs/beartrap/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) + if(armed) + close_trap() + ..() + /obj/item/restraints/legcuffs/beartrap/proc/on_entered(datum/source, AM as mob|obj) SIGNAL_HANDLER if(armed && isturf(loc)) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 5b0655ddd42d..8125a3827399 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -859,8 +859,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/small/built, 28) if(!..()) //not caught by a mob shatter() -// update the icon state and description of the light +/obj/item/light/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) + shatter() + ..() +// update the icon state and description of the light /obj/item/light/proc/update() switch(status) if(LIGHT_OK) From c5b5d5ce0f88c67050320f779c8cae8b645b9735 Mon Sep 17 00:00:00 2001 From: fallcon Date: Thu, 2 May 2024 12:37:02 -0500 Subject: [PATCH 5/6] random formating --- code/game/objects/items/puzzle_pieces.dm | 4 ++-- code/modules/food_and_drinks/drinks/drinks/bottle.dm | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/code/game/objects/items/puzzle_pieces.dm b/code/game/objects/items/puzzle_pieces.dm index 5d6b409e8d32..473bcd945c58 100644 --- a/code/game/objects/items/puzzle_pieces.dm +++ b/code/game/objects/items/puzzle_pieces.dm @@ -1,6 +1,6 @@ //************** -//*****Keys******************* -//************** ** ** +//*****Keys***** +//************** /obj/item/keycard name = "security keycard" desc = "This feels like it belongs to a door." diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 34a475c1dfda..c19fd9dd3baa 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -35,7 +35,6 @@ custom_price = 55 /obj/item/reagent_containers/food/drinks/bottle/attack(mob/living/target, mob/living/user) - if(!target) return From 816dc9137c1675320838cbc7bcfc04bf7d1dee1a Mon Sep 17 00:00:00 2001 From: FalloutFalcon Date: Sun, 5 May 2024 13:08:10 -0500 Subject: [PATCH 6/6] recalls enter so it triggers for real --- code/game/atoms_movable.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 7702d75b98f4..beb7cef2718f 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -821,7 +821,9 @@ var/impact_signal = SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum) if(impact_signal & COMPONENT_MOVABLE_IMPACT_FLIP_HITPUSH) hitpush = FALSE // hacky, tie this to something else or a proper workaround later - + if(isturf(loc)) + var/turf/T = loc + T.Entered(src) if(impact_signal & ~COMPONENT_MOVABLE_IMPACT_NEVERMIND) // in case a signal interceptor broke or deleted the thing before we could process our hit return hit_atom.hitby(src, throwingdatum=throwingdatum, hitpush=hitpush)