Skip to content

Commit

Permalink
improvments to thrown so you can target items and stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
FalloutFalcon committed May 2, 2024
1 parent e74fe9a commit 342eae8
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 51 deletions.
1 change: 1 addition & 0 deletions code/__DEFINES/flags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions code/_globalvars/bitfields.dm
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ DEFINE_BITFIELD(movement_type, list(
"GROUND" = GROUND,
"PHASING" = PHASING,
"VENTCRAWLING" = VENTCRAWLING,
"THROWN" = THROWN,
))

DEFINE_BITFIELD(obj_flags, list(
Expand Down
61 changes: 32 additions & 29 deletions code/controllers/subsystem/throwing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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 ..()
Expand All @@ -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
Expand All @@ -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

Expand All @@ -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++
Expand All @@ -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
Expand All @@ -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
4 changes: 2 additions & 2 deletions code/game/atoms_movable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
11 changes: 6 additions & 5 deletions code/game/objects/items/devices/mines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -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)
Expand Down
37 changes: 22 additions & 15 deletions code/modules/food_and_drinks/drinks/drinks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
. = ..()
Expand Down

0 comments on commit 342eae8

Please sign in to comment.