Skip to content

Commit

Permalink
Reworks grabs (#540)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrMelbert authored Aug 12, 2024
1 parent 6a1a37c commit 0882b6c
Show file tree
Hide file tree
Showing 39 changed files with 863 additions and 323 deletions.
4 changes: 4 additions & 0 deletions code/__DEFINES/living.dm
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@
#define TRAIT_NO_PAIN_EFFECTS "no_pain_effects"
/// Shock buildup does not increase, only decrease. No effect if already in shock (unlike abates_shock)
#define TRAIT_NO_SHOCK_BUILDUP "no_shock_buildup"
/// Don't get slowed down by aggro grabbing (or above)
#define TRAIT_NO_GRAB_SPEED_PENALTY "no_grab_speed_penalty"
/// Doesn't let a mob shift this atom around with move_pulled
#define TRAIT_NO_MOVE_PULL "no_move_pull"

/// The trait that determines if someone has the robotic limb reattachment quirk.
#define TRAIT_ROBOTIC_LIMBATTACHMENT "trait_robotic_limbattachment"
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@
#define GRAB_PIXEL_SHIFT_PASSIVE 6
#define GRAB_PIXEL_SHIFT_AGGRESSIVE 12
#define GRAB_PIXEL_SHIFT_NECK 16
#define GRAB_PIXEL_SHIFT_STRANGLE 12

#define PULL_PRONE_SLOWDOWN 1.5
#define HUMAN_CARRY_SLOWDOWN 0.35
Expand Down
3 changes: 0 additions & 3 deletions code/__DEFINES/traits/sources.dm
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@
#define TURF_TRAIT "turf"
/// trait associated to being buckled
#define BUCKLED_TRAIT "buckled"
/// trait associated to being held in a chokehold
#define CHOKEHOLD_TRAIT "chokehold"
/// trait associated to resting
#define RESTING_TRAIT "resting"
/// trait associated to a stat value or range of
Expand Down Expand Up @@ -154,7 +152,6 @@
#define SKILLCHIP_TRAIT "skillchip"
#define SKILL_TRAIT "skill"
#define BUSY_FLOORBOT_TRAIT "busy-floorbot"
#define PULLED_WHILE_SOFTCRIT_TRAIT "pulled-while-softcrit"
#define LOCKED_BORG_TRAIT "locked-borg"
/// trait associated to not having locomotion appendages nor the ability to fly or float
#define LACKING_LOCOMOTION_APPENDAGES_TRAIT "lacking-locomotion-appengades"
Expand Down
11 changes: 9 additions & 2 deletions code/datums/components/gunpoint.dm
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@
RegisterSignals(targ, list(
COMSIG_MOB_ATTACK_HAND,
COMSIG_MOB_ITEM_ATTACK,
COMSIG_MOVABLE_MOVED,
COMSIG_MOB_FIRED_GUN,
COMSIG_MOVABLE_SET_GRAB_STATE,
COMSIG_LIVING_START_PULL), PROC_REF(trigger_reaction))
RegisterSignal(targ, COMSIG_MOVABLE_MOVED, PROC_REF(move_trigger_reaction)) // NON-MODULE CHANGE
RegisterSignal(targ, COMSIG_MOVABLE_USING_RADIO, PROC_REF(radio_trigger_reaction)) // NON-MODULE CHANGE
RegisterSignal(targ, COMSIG_ATOM_EXAMINE, PROC_REF(examine_target))
RegisterSignal(targ, COMSIG_LIVING_PRE_MOB_BUMP, PROC_REF(block_bumps_target))
RegisterSignals(targ, list(COMSIG_LIVING_DISARM_HIT, COMSIG_LIVING_GET_PULLED), PROC_REF(cancel))
RegisterSignals(weapon, list(COMSIG_ITEM_DROPPED, COMSIG_ITEM_EQUIPPED), PROC_REF(cancel))

var/distance = min(get_dist(shooter, target), 1) // treat 0 distance as adjacent
var/distance = max(get_dist(shooter, target), 1) // treat 0 distance as adjacent // NON-MODULE CHANGE / melbert todo : min -> max, upstream fix
var/distance_description = (distance <= 1 ? "point blank " : "")

shooter.visible_message(span_danger("[shooter] aims [weapon] [distance_description]at [target]!"),
Expand Down Expand Up @@ -160,6 +160,13 @@
INVOKE_ASYNC(src, PROC_REF(async_trigger_reaction))
to_chat(source, span_warning("You fail to reach [radio]!"))
return COMPONENT_CANNOT_USE_RADIO

/datum/component/gunpoint/proc/move_trigger_reaction(datum/source, atom/new_loc)
SIGNAL_HANDLER
if(target.pulledby == parent)
return
INVOKE_ASYNC(src, PROC_REF(async_trigger_reaction))

// NON-MODULE CHANGE END

/datum/component/gunpoint/proc/async_trigger_reaction()
Expand Down
113 changes: 62 additions & 51 deletions code/datums/components/riding/riding.dm
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,7 @@
/datum/component/riding/proc/vehicle_mob_buckle(datum/source, mob/living/rider, force = FALSE)
SIGNAL_HANDLER

var/atom/movable/movable_parent = parent
handle_vehicle_layer(movable_parent.dir)
handle_vehicle_offsets(movable_parent.dir)

addtimer(CALLBACK(src, PROC_REF(vehicle_mob_buckle_hack)), 1, TIMER_UNIQUE)
if(rider.pulling == source)
rider.stop_pulling()
RegisterSignal(rider, COMSIG_LIVING_TRY_PULL, PROC_REF(on_rider_try_pull))
Expand All @@ -116,6 +113,12 @@
ADD_TRAIT(rider, trait, REF(src))
ADD_TRAIT(rider, TRAIT_NO_FLOATING_ANIM, REF(src))

// melbert todo : fuck you.
/datum/component/riding/proc/vehicle_mob_buckle_hack()
var/atom/movable/movable_parent = parent
handle_vehicle_layer(movable_parent.dir)
handle_vehicle_offsets(movable_parent.dir)

/// This proc is called when the rider attempts to grab the thing they're riding, preventing them from doing so.
/datum/component/riding/proc/on_rider_try_pull(mob/living/rider_pulling, atom/movable/target, force)
SIGNAL_HANDLER
Expand All @@ -127,13 +130,13 @@
/// Some ridable atoms may want to only show on top of the rider in certain directions, like wheelchairs
/datum/component/riding/proc/handle_vehicle_layer(dir)
var/atom/movable/AM = parent
var/static/list/defaults = list(TEXT_NORTH = OBJ_LAYER, TEXT_SOUTH = ABOVE_MOB_LAYER, TEXT_EAST = ABOVE_MOB_LAYER, TEXT_WEST = ABOVE_MOB_LAYER)
. = defaults["[dir]"]
if(directional_vehicle_layers["[dir]"])
. = directional_vehicle_layers["[dir]"]
if(isnull(.)) //you can set it to null to not change it.
. = AM.layer
AM.layer = .
var/static/list/defaults = list(
TEXT_NORTH = OBJ_LAYER,
TEXT_SOUTH = ABOVE_MOB_LAYER,
TEXT_EAST = ABOVE_MOB_LAYER,
TEXT_WEST = ABOVE_MOB_LAYER,
)
AM.layer = directional_vehicle_layers["[dir]"] || defaults["[dir]"] || AM.layer

/datum/component/riding/proc/set_vehicle_dir_layer(dir, layer)
directional_vehicle_layers["[dir]"] = layer
Expand All @@ -145,19 +148,19 @@
var/atom/movable/movable_parent = parent
if (isnull(dir))
dir = movable_parent.dir
for (var/m in movable_parent.buckled_mobs)
var/mob/buckled_mob = m
for (var/mob/buckled_mob as anything in movable_parent.buckled_mobs)
ride_check(buckled_mob)
if(QDELETED(src))
return // runtimed with piggy's without this, look into this more
handle_vehicle_offsets(dir)
handle_vehicle_layer(dir)

/// Turning is like moving
/datum/component/riding/proc/vehicle_turned(datum/source, _old_dir, new_dir)
/datum/component/riding/proc/vehicle_turned(datum/source, old_dir, new_dir)
SIGNAL_HANDLER

vehicle_moved(source, null, new_dir)
if(old_dir != new_dir)
vehicle_moved(source, null, new_dir)

/**
* Check to see if we have all of the necessary bodyparts and not-falling-over statuses we need to stay onboard.
Expand All @@ -166,51 +169,58 @@
/datum/component/riding/proc/ride_check(mob/living/rider, consequences = TRUE)
return TRUE

/datum/component/riding/proc/handle_vehicle_offset_per_mob(dir, passindex, mob/living/rider)
var/list/diroffsets = get_offsets(passindex, rider)["[dir]"]

if(rider.dir != dir)
rider.setDir(dir)

var/x_offset = length(diroffsets) >= 1 ? diroffsets[1] + rider.body_position_pixel_x_offset + rider.base_pixel_x : rider.pixel_x
var/y_offset = length(diroffsets) >= 2 ? diroffsets[2] + rider.body_position_pixel_y_offset + rider.base_pixel_y : rider.pixel_y
var/layer = length(diroffsets) >= 3 ? diroffsets[3] : rider.layer

rider.pixel_x = x_offset
rider.pixel_y = y_offset
rider.layer = layer

/datum/component/riding/proc/handle_vehicle_offsets(dir)
var/atom/movable/AM = parent
var/AM_dir = "[dir]"
var/atom/movable/seat = parent
var/passindex = 0
if(!AM.has_buckled_mobs())
if(!seat.has_buckled_mobs())
return

for(var/m in AM.buckled_mobs)
for(var/mob/living/buckled_mob as anything in seat.buckled_mobs)
passindex++
var/mob/living/buckled_mob = m
var/list/offsets = get_offsets(passindex)
buckled_mob.setDir(dir)
dir_loop:
for(var/offsetdir in offsets)
if(offsetdir == AM_dir)
var/list/diroffsets = offsets[offsetdir]
buckled_mob.pixel_x = diroffsets[1]
if(diroffsets.len >= 2)
buckled_mob.pixel_y = diroffsets[2]
if(diroffsets.len == 3)
buckled_mob.layer = diroffsets[3]
break dir_loop
var/list/static/default_vehicle_pixel_offsets = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0))
var/px = default_vehicle_pixel_offsets[AM_dir]
var/py = default_vehicle_pixel_offsets[AM_dir]
if(directional_vehicle_offsets[AM_dir])
if(isnull(directional_vehicle_offsets[AM_dir]))
px = AM.pixel_x
py = AM.pixel_y
else
px = directional_vehicle_offsets[AM_dir][1]
py = directional_vehicle_offsets[AM_dir][2]
AM.pixel_x = px
AM.pixel_y = py
handle_vehicle_offset_per_mob(dir, passindex, buckled_mob)

var/px = directional_vehicle_offsets["[dir]"]?[1] || 0
var/py = directional_vehicle_offsets["[dir]"]?[2] || 0

seat.pixel_x = px + seat.base_pixel_x
seat.pixel_y = py + seat.base_pixel_y
if(isliving(seat))
var/mob/living/living_seat = seat
seat.pixel_x += living_seat.body_position_pixel_x_offset
seat.pixel_y += living_seat.body_position_pixel_y_offset

/datum/component/riding/proc/set_vehicle_dir_offsets(dir, x, y)
directional_vehicle_offsets["[dir]"] = list(x, y)

//Override this to set your vehicle's various pixel offsets
/datum/component/riding/proc/get_offsets(pass_index) // list(dir = x, y, layer)
. = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0))
/datum/component/riding/proc/get_offsets(pass_index, mob/offsetter) as /list // list(dir = x, y, layer)
RETURN_TYPE(/list)
if(riding_offsets["[pass_index]"])
. = riding_offsets["[pass_index]"]
else if(riding_offsets["[RIDING_OFFSET_ALL]"])
. = riding_offsets["[RIDING_OFFSET_ALL]"]
return riding_offsets["[pass_index]"]

if(riding_offsets["[RIDING_OFFSET_ALL]"])
return riding_offsets["[RIDING_OFFSET_ALL]"]

return list(
TEXT_NORTH = list(0, 0),
TEXT_SOUTH = list(0, 0),
TEXT_EAST = list(0, 0),
TEXT_WEST = list(0, 0),
)

/datum/component/riding/proc/set_riding_offsets(index, list/offsets)
if(!islist(offsets))
Expand Down Expand Up @@ -241,8 +251,9 @@
/datum/component/riding/proc/restore_position(mob/living/buckled_mob)
if(isnull(buckled_mob))
return
buckled_mob.pixel_x = buckled_mob.base_pixel_x
buckled_mob.pixel_y = buckled_mob.base_pixel_y
buckled_mob.pixel_x = buckled_mob.base_pixel_x + buckled_mob.body_position_pixel_x_offset
buckled_mob.pixel_y = buckled_mob.base_pixel_y + buckled_mob.body_position_pixel_y_offset
buckled_mob.layer = initial(buckled_mob.layer)
var/atom/source = parent
SET_PLANE_EXPLICIT(buckled_mob, initial(buckled_mob.plane), source)
if(buckled_mob.client)
Expand Down
36 changes: 23 additions & 13 deletions code/datums/components/riding/riding_mob.dm
Original file line number Diff line number Diff line change
Expand Up @@ -206,15 +206,17 @@
/datum/component/riding/creature/human/Initialize(mob/living/riding_mob, force = FALSE, ride_check_flags = NONE, potion_boost = FALSE)
. = ..()
var/mob/living/carbon/human/human_parent = parent
human_parent.add_movespeed_modifier(/datum/movespeed_modifier/human_carry)

if(ride_check_flags & RIDER_NEEDS_ARMS) // piggyback
human_parent.buckle_lying = 0
// the riding mob is made nondense so they don't bump into any dense atoms the carrier is pulling,
// since pulled movables are moved before buckled movables
ADD_TRAIT(riding_mob, TRAIT_UNDENSE, VEHICLE_TRAIT)
human_parent.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/human_carry, TRUE, HUMAN_CARRY_SLOWDOWN)

else if(ride_check_flags & CARRIER_NEEDS_ARM) // fireman
human_parent.buckle_lying = 90
// melbert todo : tweak this value
human_parent.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/human_carry, TRUE, round(HUMAN_CARRY_SLOWDOWN * 1.33, 0.1))

/datum/component/riding/creature/human/RegisterWithParent()
. = ..()
Expand Down Expand Up @@ -271,22 +273,25 @@
M.layer = MOB_LAYER

if(!AM.buckle_lying) // rider is vertical, must be piggybacking
if(dir == SOUTH)
AM.layer = MOB_ABOVE_PIGGYBACK_LAYER
else
if(dir == NORTH)
AM.layer = MOB_BELOW_PIGGYBACK_LAYER
else
AM.layer = MOB_ABOVE_PIGGYBACK_LAYER
else // laying flat, we must be firemanning the rider
if(dir == NORTH)
AM.layer = MOB_BELOW_PIGGYBACK_LAYER
else
AM.layer = MOB_ABOVE_PIGGYBACK_LAYER

/datum/component/riding/creature/human/get_offsets(pass_index)
var/mob/living/carbon/human/H = parent
if(H.buckle_lying)
return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(0, 6), TEXT_WEST = list(0, 6))
else
return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(-6, 4), TEXT_WEST = list( 6, 4))
/datum/component/riding/creature/human/get_offsets(pass_index, mob/offsetter)
var/mob/living/carbon/human/seat = parent
var/height = offsetter.get_mob_buckling_height(seat) + seat.body_position_pixel_y_offset + seat.base_pixel_y + 6
return list(
TEXT_NORTH = ( seat.buckle_lying ? list(0, height) : list( 0, round(height * 0.33, 1) ) ),
TEXT_SOUTH = ( seat.buckle_lying ? list(0, height) : list( 0, round(height * 0.33, 1) ) ),
TEXT_EAST = ( seat.buckle_lying ? list(0, height) : list(-6, round(height * 0.33, 1) ) ),
TEXT_WEST = ( seat.buckle_lying ? list(0, height) : list( 6, round(height * 0.33, 1) ) ),
)

/datum/component/riding/creature/human/force_dismount(mob/living/dismounted_rider)
var/atom/movable/AM = parent
Expand Down Expand Up @@ -317,8 +322,13 @@
else
robot_parent.layer = MOB_BELOW_PIGGYBACK_LAYER

/datum/component/riding/creature/cyborg/get_offsets(pass_index) // list(dir = x, y, layer)
return list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(-6, 3), TEXT_WEST = list( 6, 3))
/datum/component/riding/creature/cyborg/get_offsets(pass_index, mob/offsetter) // list(dir = x, y, layer)
return list(
TEXT_NORTH = list(0, 4),
TEXT_SOUTH = list(0, 4),
TEXT_EAST = list(-6, 3),
TEXT_WEST = list(6, 3),
)

/datum/component/riding/creature/cyborg/handle_vehicle_offsets(dir)
var/mob/living/silicon/robot/robot_parent = parent
Expand Down
5 changes: 4 additions & 1 deletion code/datums/elements/ridable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,7 @@
if(HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, span_notice("You gently let go of [rider]."))
return
return rider
var/mob/throwing = rider
user.set_pulling(throwing)
user.setGrabState(GRAB_AGGRESSIVE)
return throwing
17 changes: 0 additions & 17 deletions code/datums/skills/fitness.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,3 @@
desc = "Twinkle twinkle little star, hit the gym and lift the bar."
/// The skill value modifier effects the max duration that is possible for /datum/status_effect/exercised
modifiers = list(SKILL_VALUE_MODIFIER = list(1 MINUTES, 1.5 MINUTES, 2 MINUTES, 2.5 MINUTES, 3 MINUTES, 3.5 MINUTES, 5 MINUTES))
/// How much bigger your mob becomes per level (these effects don't stack together)
var/static/size_boost = list(0, 1/16, 1/8, 3/16, 2/8, 3/8, 4/8)
// skill_item_path - your mob sprite gets bigger to showoff so we don't get a special item

/datum/skill/fitness/level_gained(datum/mind/mind, new_level, old_level, silent)
. = ..()
var/old_gym_size = RESIZE_DEFAULT_SIZE + size_boost[old_level]
var/new_gym_size = RESIZE_DEFAULT_SIZE + size_boost[new_level]

mind.current.update_transform(new_gym_size / old_gym_size)

/datum/skill/fitness/level_lost(datum/mind/mind, new_level, old_level, silent)
. = ..()
var/old_gym_size = RESIZE_DEFAULT_SIZE + size_boost[old_level]
var/new_gym_size = RESIZE_DEFAULT_SIZE + size_boost[new_level]

mind.current.update_transform(new_gym_size / old_gym_size)
Loading

0 comments on commit 0882b6c

Please sign in to comment.