Pixel adjustments to mobs are now sourced / Refactors riding (#89320)

Fixes #85980

- Pixel adjustments are now sourced

When tweaking a mob's pixel w, x, y, z, is is now done via `add_offsets`
and must have a source string associated

- Refactors riding

Refactors how riding component selects the offsets to use. It's now all
done via the getter rather than a weird mix of a var, a cache, and a
getter.

- Moves a bunch of animations to use `pixel_w` / `pixel_z`

Largely to prevent conflicts with adjustments to a mob's pixel position,
but also as many animations are not actual movements, but visual
movements. Floating is one such example.

It just works

🆑 Melbert
fix: Fixed grab offsets not showing for anything but passive grab
fix: Fix jank with mob offsets when riding things
refactor: Refactored riding component, particularly how it selects layer
and offsets. Report any oddities
refactor: Refactored pixel offsets of mobs. Report any oddities
/🆑
This commit is contained in:
MrMelbert
2025-03-12 16:00:01 -04:00
committed by Roxy
parent 483888e64d
commit 5a16f74fb3
50 changed files with 997 additions and 727 deletions
+6
View File
@@ -13,3 +13,9 @@
/// Getter for a mob/living's lying angle, otherwise protected
#define GET_LYING_ANGLE(mob) (UNLINT(mob.lying_angle))
// Used in living mob offset list for determining pixel offsets
#define PIXEL_W_OFFSET "w"
#define PIXEL_X_OFFSET "x"
#define PIXEL_Y_OFFSET "y"
#define PIXEL_Z_OFFSET "z"
+3
View File
@@ -381,3 +381,6 @@ DEFINE_BITFIELD(janitor_mode_flags, list(
#define REPAIRBOT_VOICED_STRINGS "I had strings. But now I'm free..."
#define REPAIRBOT_VOICED_ENTROPY "Witness! The pure beauty of entropy!"
#define REPAIRBOT_VOICED_PASSION "BE DAMNED YOUR PASSION PROJECTS!"
/// Default offsets for riding a cyborg
#define DEFAULT_ROBOT_RIDING_OFFSETS list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(-6, 3), TEXT_WEST = list(6, 3))
+5 -2
View File
@@ -582,8 +582,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Whether or not the user is in a MODlink call, prevents making more calls
#define TRAIT_IN_CALL "in_call"
/// Is the mob standing on an elevated surface? This prevents them from dropping down if not elevated first.
#define TRAIT_ON_ELEVATED_SURFACE "on_elevated_surface"
/// Does the mob ignore elevation? (e.g. xeno larvas on hiding)
#define TRAIT_IGNORE_ELEVATION "ignore_elevation"
@@ -1431,6 +1429,11 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Trait applied when the wire bundle component is added to an [/obj/item/integrated_circuit]
#define TRAIT_COMPONENT_WIRE_BUNDLE "component_wire_bundle"
/// Apply this trait to mobs which can "buckle" to humans
#define TRAIT_CAN_MOUNT_HUMANS "can_mount_humans"
/// Apply this trait to mobs which can "buckle" to cyborgs
#define TRAIT_CAN_MOUNT_CYBORGS "can_mount_cyborgs"
/// Trait that is added to fishes that someone already caught, be it in-game or just theoretically, such as when they're bought
/// Prevents fishing achievement from being granted by catching one of these
#define TRAIT_NO_FISHING_ACHIEVEMENT "no_fishing_achievement"
+4
View File
@@ -149,6 +149,8 @@
/// A trait gained from a mob's leap action, like the leaper
#define LEAPING_TRAIT "leaping"
/// From grabbing someone
#define GRABBING_TRAIT "grabbing"
/// A trait gained from a mob's vanish action, like the herophant
#define VANISHING_TRAIT "vanishing"
/// A trait gained from a mob's swoop action, like the ash drake
@@ -195,6 +197,8 @@
/// Trait from mob/living/update_transform()
#define UPDATE_TRANSFORM_TRAIT "update_transform"
/// Trait from mob/living/update_offsets()
#define UPDATE_OFFSET_TRAIT "update_offset"
/// Trait granted by the berserker hood.
#define BERSERK_TRAIT "berserk_trait"
-3
View File
@@ -42,6 +42,3 @@
#define VIM_SOUND_COOLDOWN (1 SECONDS)
///how much vim heals per weld
#define VIM_HEAL_AMOUNT 20
/// The vehicle being ridden requires pixel offsets for all directions
#define RIDING_OFFSET_ALL "ALL"
+6 -10
View File
@@ -6,8 +6,8 @@
* This is just so you can apply the animation to things which can be animated but are not movables (like images)
*/
#define DO_FLOATING_ANIM(target) \
animate(target, pixel_y = 2, time = 1 SECONDS, loop = -1, flags = ANIMATION_RELATIVE); \
animate(pixel_y = -2, time = 1 SECONDS, flags = ANIMATION_RELATIVE)
animate(target, pixel_z = 2, time = 1 SECONDS, loop = -1, flags = ANIMATION_RELATIVE); \
animate(pixel_z = -2, time = 1 SECONDS, flags = ANIMATION_RELATIVE)
/**
* Stops the passed atom / image from appearing floating
@@ -17,16 +17,12 @@
* This is just so you can apply the animation to things which can be animated but are not movables (like images)
*/
#define STOP_FLOATING_ANIM(target) \
var/final_pixel_y = 0; \
var/__final_pixel_z = 0; \
if(ismovable(target)) { \
var/atom/movable/movable_target = target; \
final_pixel_y = movable_target.base_pixel_y; \
var/atom/movable/__movable_target = target; \
__final_pixel_z = __movable_target.base_pixel_z; \
}; \
if(isliving(target)) { \
var/mob/living/living_target = target; \
final_pixel_y += living_target.body_position_pixel_y_offset; \
}; \
animate(target, pixel_y = final_pixel_y, time = 1 SECONDS)
animate(target, pixel_z = __final_pixel_z, time = 1 SECONDS)
/// The duration of the animate call in mob/living/update_transform
#define UPDATE_TRANSFORM_ANIMATION_TIME (0.2 SECONDS)
+7 -6
View File
@@ -143,7 +143,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_WALLMOUNTED" = TRAIT_WALLMOUNTED,
),
/mob = list(
"TRAIT_AI_ACCESS" = TRAIT_AI_ACCESS,
"TRAIT_ABDUCTOR_SCIENTIST_TRAINING" = TRAIT_ABDUCTOR_SCIENTIST_TRAINING,
"TRAIT_ABDUCTOR_TRAINING" = TRAIT_ABDUCTOR_TRAINING,
"TRAIT_ACT_AS_CULTIST" = TRAIT_ACT_AS_CULTIST,
@@ -153,6 +152,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_AGENDER" = TRAIT_AGENDER,
"TRAIT_AGEUSIA" = TRAIT_AGEUSIA,
"TRAIT_AIRLOCK_SHOCKIMMUNE" = TRAIT_AIRLOCK_SHOCKIMMUNE,
"TRAIT_AI_ACCESS" = TRAIT_AI_ACCESS,
"TRAIT_AI_BAGATTACK" = TRAIT_AI_BAGATTACK,
"TRAIT_ALCOHOL_TOLERANCE" = TRAIT_ALCOHOL_TOLERANCE,
"TRAIT_ALLOW_HERETIC_CASTING" = TRAIT_ALLOW_HERETIC_CASTING,
@@ -174,15 +174,16 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_BEING_BLADE_SHIELDED" = TRAIT_BEING_BLADE_SHIELDED,
"TRAIT_BIRTHDAY_BOY" = TRAIT_BIRTHDAY_BOY,
"TRAIT_BLOB_ALLY" = TRAIT_BLOB_ALLY,
"TRAIT_BLOCK_SHUTTLE_MOVEMENT" = TRAIT_BLOCK_SHUTTLE_MOVEMENT,
"TRAIT_BLOCKING_PROJECTILES" = TRAIT_BLOCKING_PROJECTILES,
"TRAIT_BLOOD_CLANS" = TRAIT_BLOOD_CLANS,
"TRAIT_BLOCK_SHUTTLE_MOVEMENT" = TRAIT_BLOCK_SHUTTLE_MOVEMENT,
"TRAIT_BLOODSHOT_EYES" = TRAIT_BLOODSHOT_EYES,
"TRAIT_BLOODY_MESS" = TRAIT_BLOODY_MESS,
"TRAIT_BLOOD_CLANS" = TRAIT_BLOOD_CLANS,
"TRAIT_BOMBIMMUNE" = TRAIT_BOMBIMMUNE,
"TRAIT_BONSAI" = TRAIT_BONSAI,
"TRAIT_BOOZE_SLIDER" = TRAIT_BOOZE_SLIDER,
"TRAIT_BORN_MONKEY" = TRAIT_BORN_MONKEY,
"TRAIT_BOT_PATH_HUD" = TRAIT_BOT_PATH_HUD,
"TRAIT_BOXING_READY" = TRAIT_BOXING_READY,
"TRAIT_BRAINWASHING" = TRAIT_BRAINWASHING,
"TRAIT_BRAWLING_KNOCKDOWN_BLOCKED" = TRAIT_BRAWLING_KNOCKDOWN_BLOCKED,
@@ -193,6 +194,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_CANNOT_OPEN_PRESENTS" = TRAIT_CANNOT_OPEN_PRESENTS,
"TRAIT_CANT_RIDE" = TRAIT_CANT_RIDE,
"TRAIT_CAN_HOLD_ITEMS" = TRAIT_CAN_HOLD_ITEMS,
"TRAIT_CAN_MOUNT_CYBORGS" = TRAIT_CAN_MOUNT_CYBORGS,
"TRAIT_CAN_MOUNT_HUMANS" = TRAIT_CAN_MOUNT_HUMANS,
"TRAIT_CAN_SIGN_ON_COMMS" = TRAIT_CAN_SIGN_ON_COMMS,
"TRAIT_CAN_STRIP" = TRAIT_CAN_STRIP,
"TRAIT_CAN_USE_NUKE" = TRAIT_CAN_USE_NUKE,
@@ -208,8 +211,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_CLOWN_ENJOYER" = TRAIT_CLOWN_ENJOYER,
"TRAIT_CLUMSY" = TRAIT_CLUMSY,
"TRAIT_COAGULATING" = TRAIT_COAGULATING,
"TRAIT_CORPSELOCKED" = TRAIT_CORPSELOCKED,
"TRAIT_COMBAT_MODE_LOCK" = TRAIT_COMBAT_MODE_LOCK,
"TRAIT_CORPSELOCKED" = TRAIT_CORPSELOCKED,
"TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION,
"TRAIT_CULT_HALO" = TRAIT_CULT_HALO,
"TRAIT_CURSED" = TRAIT_CURSED,
@@ -221,7 +224,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_DETECTIVES_TASTE" = TRAIT_DETECTIVES_TASTE,
"TRAIT_DETECT_STORM" = TRAIT_DETECT_STORM,
"TRAIT_DIAGNOSTIC_HUD" = TRAIT_DIAGNOSTIC_HUD,
"TRAIT_BOT_PATH_HUD" = TRAIT_BOT_PATH_HUD,
"TRAIT_DISCOORDINATED_TOOL_USER" = TRAIT_DISCOORDINATED_TOOL_USER,
"TRAIT_DISEASELIKE_SEVERITY_MEDIUM" = TRAIT_DISEASELIKE_SEVERITY_MEDIUM,
"TRAIT_DISFIGURED" = TRAIT_DISFIGURED,
@@ -424,7 +426,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_NUKEIMMUNE" = TRAIT_NUKEIMMUNE,
"TRAIT_OFF_BALANCE_TACKLER" = TRAIT_OFF_BALANCE_TACKLER,
"TRAIT_OIL_FRIED" = TRAIT_OIL_FRIED,
"TRAIT_ON_ELEVATED_SURFACE" = TRAIT_ON_ELEVATED_SURFACE,
"TRAIT_ORBITING_FORBIDDEN" = TRAIT_ORBITING_FORBIDDEN,
"TRAIT_OVERDOSEIMMUNE" = TRAIT_OVERDOSEIMMUNE,
"TRAIT_OVERWATCHED" = TRAIT_OVERWATCHED,
+4 -4
View File
@@ -81,8 +81,8 @@
* * leaning_offset - pixel offset to apply on the mob when leaning
*/
/mob/living/proc/start_leaning(atom/lean_target, leaning_offset)
var/new_x = lean_target.pixel_x + base_pixel_x + body_position_pixel_x_offset
var/new_y = lean_target.pixel_y + base_pixel_y + body_position_pixel_y_offset
var/new_x = 0
var/new_y = 0
switch(dir)
if(SOUTH)
new_y += leaning_offset
@@ -93,7 +93,7 @@
if(EAST)
new_x -= leaning_offset
animate(src, 0.2 SECONDS, pixel_x = new_x, pixel_y = new_y)
add_offsets(LEANING_TRAIT, x_add = new_x, y_add = new_y)
add_traits(list(TRAIT_UNDENSE, TRAIT_EXPANDED_FOV), LEANING_TRAIT)
visible_message(
span_notice("[src] leans against [lean_target]."),
@@ -129,7 +129,7 @@
COMSIG_ATOM_POST_DIR_CHANGE,
COMSIG_MOVABLE_TELEPORTED,
))
animate(src, 0.2 SECONDS, pixel_x = base_pixel_x + body_position_pixel_x_offset, pixel_y = base_pixel_y + body_position_pixel_y_offset)
remove_offsets(LEANING_TRAIT)
remove_traits(list(TRAIT_UNDENSE, TRAIT_EXPANDED_FOV), LEANING_TRAIT)
SEND_SIGNAL(src, COMSIG_LIVING_STOPPED_LEANING)
update_fov()
+104 -104
View File
@@ -1,3 +1,8 @@
/// Offsets applied for people riding something
#define RIDING_SOURCE "riding"
/// Offsets applied for something being ridden
#define BEING_RIDDEN_SOURCE "being_ridden"
/**
* This is the riding component, which is applied to a movable atom by the [ridable element][/datum/element/ridable] when a mob is successfully buckled to said movable.
*
@@ -9,22 +14,14 @@
/datum/component/riding
dupe_mode = COMPONENT_DUPE_UNIQUE
///tick delay between movements, lower = faster, higher = slower
/// Tick delay between movements, lower = faster, higher = slower
var/vehicle_move_delay = 2
/**
* If the driver needs a certain item in hand (or inserted, for vehicles) to drive this. For vehicles, this must be duplicated on the actual vehicle object in their
* [/obj/vehicle/var/key_type] variable because the vehicle objects still have a few special checks/functions of their own I'm not porting over to the riding component
* quite yet. Make sure if you define it on the vehicle, you define it here too.
*/
var/keytype
/// position_of_user = list(dir = list(px, py)), or RIDING_OFFSET_ALL for a generic one.
var/list/riding_offsets = list()
/// ["[DIRECTION]"] = layer. Don't set it for a direction for default, set a direction to null for no change.
var/list/directional_vehicle_layers = list()
/// same as above but instead of layer you have a list(px, py)
var/list/directional_vehicle_offsets = list()
/// allow typecache for only certain turfs, forbid to allow all but those. allow only certain turfs will take precedence.
var/list/allowed_turf_typecache
/// allow typecache for only certain turfs, forbid to allow all but those. allow only certain turfs will take precedence.
@@ -47,11 +44,10 @@
COOLDOWN_DECLARE(vehicle_move_cooldown)
/datum/component/riding/Initialize(mob/living/riding_mob, force = FALSE, buckle_mob_flags= NONE)
/datum/component/riding/Initialize(mob/living/riding_mob, force = FALSE, buckle_mob_flags = NONE)
if(!ismovable(parent))
return COMPONENT_INCOMPATIBLE
handle_specials(riding_mob)
riding_mob.updating_glide_size = FALSE
ride_check_flags |= buckle_mob_flags
@@ -72,25 +68,21 @@
if(!can_force_unbuckle)
RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(force_unbuckle))
/**
* This proc handles all of the proc calls to things like set_vehicle_dir_layer() that a type of riding datum needs to call on creation
*
* The original riding component had these procs all called from the ridden object itself through the use of GetComponent() and LoadComponent()
* This was obviously problematic for componentization, but while lots of the variables being set were able to be moved to component variables,
* the proc calls couldn't be. Thus, anything that has to do an initial proc call should be handled here.
*/
/datum/component/riding/proc/handle_specials()
return
/// This proc is called when a rider unbuckles, whether they chose to or not. If there's no more riders, this will be the riding component's death knell.
/datum/component/riding/proc/vehicle_mob_unbuckle(datum/source, mob/living/rider, force = FALSE)
SIGNAL_HANDLER
restore_rider_layer_and_offsets(rider)
handle_unbuckle(rider)
/datum/component/riding/proc/handle_unbuckle(mob/living/rider)
var/atom/movable/movable_parent = parent
restore_position(rider)
if(movable_parent.has_buckled_mobs())
update_parent_layer_and_offsets(movable_parent.dir, animate = TRUE)
else
restore_parent_layer_and_offsets()
qdel(src)
/datum/component/riding/proc/handle_unbuckle(mob/living/rider)
unequip_buckle_inhands(rider)
rider.updating_glide_size = TRUE
UnregisterSignal(rider, COMSIG_LIVING_TRY_PULL)
@@ -98,18 +90,17 @@
if (HAS_TRAIT(parent, trait))
REMOVE_TRAIT(rider, trait, REF(src))
rider.remove_traits(rider_traits, REF(src))
if(!movable_parent.has_buckled_mobs())
qdel(src)
/// This proc is called when a rider buckles, allowing for offsets to be set properly
/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)
update_parent_layer_and_offsets(movable_parent.dir, animate = TRUE)
handle_buckle(rider)
if(rider.pulling == source)
/datum/component/riding/proc/handle_buckle(mob/living/rider)
if(rider.pulling == parent)
rider.stop_pulling()
RegisterSignal(rider, COMSIG_LIVING_TRY_PULL, PROC_REF(on_rider_try_pull))
@@ -117,7 +108,6 @@
if (HAS_TRAIT(parent, trait))
ADD_TRAIT(rider, trait, REF(src))
rider.add_traits(rider_traits, REF(src))
post_vehicle_mob_buckle(movable_parent, rider)
/// 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)
@@ -127,24 +117,6 @@
ridden.balloon_alert(rider_pulling, "not while riding it!")
return COMSIG_LIVING_CANCEL_PULL
///any behavior we want to happen after buckling the mob
/datum/component/riding/proc/post_vehicle_mob_buckle(atom/movable/ridden, atom/movable/rider)
return TRUE
/// 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 = .
/datum/component/riding/proc/set_vehicle_dir_layer(dir, layer)
directional_vehicle_layers["[dir]"] = layer
/// This is called after the ridden atom is successfully moved and is used to handle icon stuff
/datum/component/riding/proc/vehicle_moved(datum/source, oldloc, dir, forced)
SIGNAL_HANDLER
@@ -157,8 +129,7 @@
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)
update_parent_layer_and_offsets(dir)
/// Turning is like moving
/datum/component/riding/proc/vehicle_turned(datum/source, _old_dir, new_dir)
@@ -173,61 +144,80 @@
/datum/component/riding/proc/ride_check(mob/living/rider, consequences = TRUE)
return TRUE
/datum/component/riding/proc/handle_vehicle_offsets(dir)
var/atom/movable/AM = parent
var/AM_dir = "[dir]"
var/passindex = 0
if(!AM.has_buckled_mobs())
#define GET_X_OFFSET(offsets) (length(offsets) >= 1 ? offsets[1] : 0)
#define GET_Y_OFFSET(offsets) (length(offsets) >= 2 ? offsets[2] : 0)
#define GET_LAYER(offsets, default) (length(offsets) >= 3 ? offsets[3] : default)
/datum/component/riding/proc/update_parent_layer_and_offsets(dir, animate = FALSE)
var/atom/movable/seat = parent
if(!seat.has_buckled_mobs())
return
for(var/m in AM.buckled_mobs)
var/passindex = 0
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/static/list/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
update_rider_layer_and_offsets(dir, passindex, buckled_mob)
/datum/component/riding/proc/set_vehicle_dir_offsets(dir, x, y)
directional_vehicle_offsets["[dir]"] = list(x, y)
var/list/offsets = get_parent_offsets_and_layers()?["[dir]"]
var/px = GET_X_OFFSET(offsets)
var/py = GET_Y_OFFSET(offsets)
var/layer = GET_LAYER(offsets, seat.layer)
//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))
if(riding_offsets["[pass_index]"])
. = riding_offsets["[pass_index]"]
else if(riding_offsets["[RIDING_OFFSET_ALL]"])
. = riding_offsets["[RIDING_OFFSET_ALL]"]
if(isliving(seat))
var/mob/living/living_seat = seat
living_seat.add_offsets(BEING_RIDDEN_SOURCE, x_add = px, y_add = py, animate = animate)
else
seat.pixel_x = px + seat.base_pixel_x
seat.pixel_y = py + seat.base_pixel_y
seat.layer = layer
/datum/component/riding/proc/set_riding_offsets(index, list/offsets)
if(!islist(offsets))
return FALSE
riding_offsets["[index]"] = offsets
/datum/component/riding/proc/update_rider_layer_and_offsets(dir, passindex, mob/living/rider, animate = FALSE)
if(rider.dir != dir)
rider.setDir(dir)
/datum/component/riding/proc/set_vehicle_offsets(list/offsets)
if(!islist(offsets))
return FALSE
directional_vehicle_offsets = offsets
var/list/diroffsets = get_rider_offsets_and_layers(passindex, rider)?["[dir]"]
var/x_offset = GET_X_OFFSET(diroffsets)
var/y_offset = GET_Y_OFFSET(diroffsets)
var/layer = GET_LAYER(diroffsets, rider.layer)
// if they are intended to be buckled, offset their existing offset
var/atom/movable/seat = parent
if(seat.buckle_lying && rider.body_position == LYING_DOWN)
y_offset += (-1 * PIXEL_Y_OFFSET_LYING)
rider.add_offsets(RIDING_SOURCE, x_add = x_offset, y_add = y_offset, animate = animate)
rider.layer = layer
#undef GET_X_OFFSET
#undef GET_Y_OFFSET
#undef GET_LAYER
/**
* Determines where riders get offset while riding
*
* * pass_index: The index of the rider in the list of buckled mobs
* * mob/offsetter: The mob that is being offset
*/
/datum/component/riding/proc/get_rider_offsets_and_layers(pass_index, mob/offsetter) as /list // list(dir = x, y, layer)
RETURN_TYPE(/list)
return list(
TEXT_NORTH = list(0, 0),
TEXT_SOUTH = list(0, 0),
TEXT_EAST = list(0, 0),
TEXT_WEST = list(0, 0),
)
/**
* Determines where the parent gets offset while riders are riding
*/
/datum/component/riding/proc/get_parent_offsets_and_layers() as /list // list(dir = x, y, layer)
RETURN_TYPE(/list)
return list(
TEXT_NORTH = list(0, 0, OBJ_LAYER),
TEXT_SOUTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_EAST = list(0, 0, ABOVE_MOB_LAYER),
TEXT_WEST = list(0, 0, ABOVE_MOB_LAYER),
)
/**
* This proc is used to see if we have the appropriate key to drive this atom, if such a key is needed. Returns FALSE if we don't have what we need to drive.
@@ -245,15 +235,22 @@
return user.is_holding_item_of_type(keytype)
//BUCKLE HOOKS
/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
/datum/component/riding/proc/restore_rider_layer_and_offsets(mob/living/buckled_mob)
buckled_mob.remove_offsets(RIDING_SOURCE)
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)
buckled_mob.client.view_size.resetToDefault()
buckled_mob.client?.view_size.resetToDefault()
/datum/component/riding/proc/restore_parent_layer_and_offsets()
var/atom/movable/seat = parent
if(isliving(seat))
var/mob/living/living_seat = seat
living_seat.remove_offsets(BEING_RIDDEN_SOURCE)
else
seat.pixel_x = seat.base_pixel_x
seat.pixel_y = seat.base_pixel_y
seat.layer = initial(seat.layer)
//MOVEMENT
/datum/component/riding/proc/turf_check(turf/next, turf/current)
@@ -327,3 +324,6 @@
SIGNAL_HANDLER
for (var/mob/passenger as anything in ridden.buckled_mobs)
passenger.Bump(supermatter)
#undef RIDING_SOURCE
#undef BEING_RIDDEN_SOURCE
+268 -204
View File
@@ -21,7 +21,7 @@
living_parent.stop_pulling() // was only used on humans previously, may change some other behavior
log_riding(living_parent, riding_mob)
riding_mob.set_glide_size(living_parent.glide_size)
handle_vehicle_offsets(living_parent.dir)
update_parent_layer_and_offsets(living_parent.dir)
if(can_use_abilities)
setup_abilities(riding_mob)
@@ -109,14 +109,8 @@
var/mob/living/living_parent = parent
step(living_parent, direction)
var/modified_move_delay = vehicle_move_delay
if(ishuman(user) && HAS_TRAIT(user, TRAIT_ROUGHRIDER)) // YEEHAW!
var/mob/living/carbon/human/rough_rider = user
var/ride_benefit = null
if(HAS_TRAIT(rough_rider, TRAIT_PRIMITIVE)) // closer to a beast than a man; you don't need to think to ride!
ride_benefit = SANITY_LEVEL_GREAT
else
ride_benefit = rough_rider.mob_mood.sanity_level
switch(ride_benefit)
if(HAS_TRAIT(user, TRAIT_ROUGHRIDER)) // YEEHAW!
switch(HAS_TRAIT(user, TRAIT_PRIMITIVE) ? SANITY_LEVEL_GREAT : user.mob_mood?.sanity_level)
if(SANITY_LEVEL_GREAT)
modified_move_delay *= 0.8
if(SANITY_LEVEL_NEUTRAL)
@@ -216,7 +210,8 @@
else if(ride_check_flags & CARRIER_NEEDS_ARM) // fireman
human_parent.buckle_lying = 90
/datum/component/riding/creature/post_vehicle_mob_buckle(mob/living/ridden, mob/living/rider)
/datum/component/riding/creature/handle_buckle(mob/living/rider)
var/mob/living/ridden = parent
if(!require_minigame || ridden.faction.Find(REF(rider)))
return
ridden.Shake(duration = 2 SECONDS)
@@ -260,81 +255,55 @@
/datum/component/riding/creature/human/proc/check_carrier_fall_over(mob/living/carbon/human/human_parent)
SIGNAL_HANDLER
for(var/i in human_parent.buckled_mobs)
var/mob/living/rider = i
for(var/mob/living/rider as anything in human_parent.buckled_mobs)
human_parent.unbuckle_mob(rider)
rider.Paralyze(1 SECONDS)
rider.Knockdown(4 SECONDS)
human_parent.visible_message(span_danger("[rider] topples off of [human_parent] as they both fall to the ground!"), \
span_warning("You fall to the ground, bringing [rider] with you!"), span_hear("You hear two consecutive thuds."), COMBAT_MESSAGE_RANGE, ignored_mobs=rider)
human_parent.visible_message(
span_danger("[rider] topples off of [human_parent] as they both fall to the ground!"),
span_warning("You fall to the ground, bringing [rider] with you!"),
span_hear("You hear two consecutive thuds."),
COMBAT_MESSAGE_RANGE,
ignored_mobs = rider,
visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE,
)
to_chat(rider, span_danger("[human_parent] falls to the ground, bringing you with [human_parent.p_them()]!"))
/datum/component/riding/creature/human/handle_vehicle_layer(dir)
var/atom/movable/AM = parent
if(!AM.buckled_mobs || !AM.buckled_mobs.len)
AM.layer = MOB_LAYER
return
/datum/component/riding/creature/human/get_rider_offsets_and_layers(pass_index, mob/offsetter)
var/mob/living/carbon/human/seat = parent
// fireman carry
if(seat.buckle_lying)
return list(
TEXT_NORTH = list(0, 6, MOB_ABOVE_PIGGYBACK_LAYER),
TEXT_SOUTH = list(0, 6, MOB_BELOW_PIGGYBACK_LAYER),
TEXT_EAST = list(0, 6, MOB_BELOW_PIGGYBACK_LAYER),
TEXT_WEST = list(0, 6, MOB_BELOW_PIGGYBACK_LAYER),
)
// piggyback
return list(
TEXT_NORTH = list( 0, 8, MOB_ABOVE_PIGGYBACK_LAYER),
TEXT_SOUTH = list( 0, 8, MOB_BELOW_PIGGYBACK_LAYER),
TEXT_EAST = list(-6, 8, MOB_BELOW_PIGGYBACK_LAYER),
TEXT_WEST = list( 6, 8, MOB_BELOW_PIGGYBACK_LAYER),
)
for(var/mob/M in AM.buckled_mobs) //ensure proper layering of piggyback and carry, sometimes weird offsets get applied
M.layer = MOB_LAYER
/datum/component/riding/creature/human/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0),
TEXT_SOUTH = list(0, 0),
TEXT_EAST = list(0, 0),
TEXT_WEST = list(0, 0),
)
if(!AM.buckle_lying) // rider is vertical, must be piggybacking
if(dir == SOUTH)
AM.layer = MOB_ABOVE_PIGGYBACK_LAYER
else
AM.layer = MOB_BELOW_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
/* BUBBER EDIT REMOVAL START
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))
*/ // BUBBER EDIT REMOVAL END
// BUBBER EDIT ADDITION BEGIN - Oversized Overhaul, Taur riding
if(H.buckle_lying)
return HAS_TRAIT(H, TRAIT_OVERSIZED) ? list(
TEXT_NORTH = list(0, OVERSIZED_OFFSET),
TEXT_SOUTH = list(0, OVERSIZED_OFFSET),
TEXT_EAST = list(0, OVERSIZED_OFFSET),
TEXT_WEST = list(0, OVERSIZED_OFFSET),
) : list(
TEXT_NORTH = list(0, REGULAR_OFFSET),
TEXT_SOUTH = list(0, REGULAR_OFFSET),
TEXT_EAST = list(0, REGULAR_OFFSET),
TEXT_WEST = list(0, REGULAR_OFFSET),
)
else if (!(ride_check_flags & RIDING_TAUR)) // BUBBER EDIT CHANGE - ORIGINAL: else
return HAS_TRAIT(H, TRAIT_OVERSIZED) ? list(
TEXT_NORTH = list(0, OVERSIZED_OFFSET),
TEXT_SOUTH = list(0, OVERSIZED_OFFSET),
TEXT_EAST = list(-OVERSIZED_SIDE_OFFSET, OVERSIZED_OFFSET),
TEXT_WEST = list(OVERSIZED_SIDE_OFFSET, OVERSIZED_OFFSET),
) : list(
TEXT_NORTH = list(0, REGULAR_OFFSET),
TEXT_SOUTH = list(0, REGULAR_OFFSET),
TEXT_EAST = list(-REGULAR_OFFSET, REGULAR_SIDE_OFFSET),
TEXT_WEST = list(REGULAR_OFFSET, REGULAR_SIDE_OFFSET)
)
if (ride_check_flags & RIDING_TAUR)
var/obj/item/organ/taur_body/taur_body = H.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAUR)
return taur_body.get_riding_offset(oversized = HAS_TRAIT(H, TRAIT_OVERSIZED))
//BUBBER EDIT END
/datum/component/riding/creature/human/force_dismount(mob/living/dismounted_rider, throw_range = 8, throw_speed = 3, gentle = FALSE)
var/atom/movable/AM = parent
AM.unbuckle_mob(dismounted_rider)
dismounted_rider.Paralyze(1 SECONDS)
dismounted_rider.Knockdown(4 SECONDS)
dismounted_rider.visible_message(span_warning("[AM] pushes [dismounted_rider] off of [AM.p_them()]!"), \
span_warning("[AM] pushes you off of [AM.p_them()]!"))
/datum/component/riding/creature/human/force_dismount(mob/living/rider, throw_range = 8, throw_speed = 3, gentle = FALSE)
var/atom/movable/seat = parent
seat.unbuckle_mob(rider)
rider.Paralyze(1 SECONDS)
rider.Knockdown(4 SECONDS)
rider.visible_message(
span_warning("[seat] pushes [rider] off of [seat.p_them()]!"),
span_warning("[seat] pushes you off of [seat.p_them()]!"),
)
//Now onto cyborg riding//
@@ -350,65 +319,88 @@
Unbuckle(user)
to_chat(user, span_warning("You can't grab onto [robot_parent] with no hands!"))
/datum/component/riding/creature/cyborg/handle_vehicle_layer(dir)
var/atom/movable/robot_parent = parent
if(dir == SOUTH)
robot_parent.layer = MOB_ABOVE_PIGGYBACK_LAYER
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/handle_vehicle_offsets(dir)
/datum/component/riding/creature/cyborg/get_rider_offsets_and_layers(pass_index, mob/offsetter)
var/mob/living/silicon/robot/robot_parent = parent
return robot_parent.model?.ride_offsets || DEFAULT_ROBOT_RIDING_OFFSETS
for(var/mob/living/rider in robot_parent.buckled_mobs)
rider.setDir(dir)
if(istype(robot_parent.model))
rider.pixel_x = robot_parent.model.ride_offset_x[dir2text(dir)]
rider.pixel_y = robot_parent.model.ride_offset_y[dir2text(dir)]
/datum/component/riding/creature/cyborg/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, MOB_BELOW_PIGGYBACK_LAYER),
TEXT_SOUTH = list(0, 0, MOB_ABOVE_PIGGYBACK_LAYER),
TEXT_EAST = list(0, 0, MOB_ABOVE_PIGGYBACK_LAYER),
TEXT_WEST = list(0, 0, MOB_ABOVE_PIGGYBACK_LAYER),
)
//now onto every other ridable mob//
/datum/component/riding/creature/mulebot
/datum/component/riding/creature/mulebot/handle_specials()
. = ..()
var/atom/movable/movable_parent = parent
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 12), TEXT_SOUTH = list(0, 12), TEXT_EAST = list(0, 12), TEXT_WEST = list(0, 12)))
set_vehicle_dir_layer(SOUTH, movable_parent.layer) //vehicles default to ABOVE_MOB_LAYER while moving, let's make sure that doesn't happen while a mob is riding us.
set_vehicle_dir_layer(NORTH, movable_parent.layer)
set_vehicle_dir_layer(EAST, movable_parent.layer)
set_vehicle_dir_layer(WEST, movable_parent.layer)
/datum/component/riding/creature/mulebot/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list(0, 12),
TEXT_SOUTH = list(0, 12),
TEXT_EAST = list(0, 12),
TEXT_WEST = list(0, 12),
)
/datum/component/riding/creature/mulebot/get_parent_offsets_and_layers()
return null
/datum/component/riding/creature/cow/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 8), TEXT_SOUTH = list(0, 8), TEXT_EAST = list(-2, 8), TEXT_WEST = list(2, 8)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
/datum/component/riding/creature/cow
/datum/component/riding/creature/pig/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 8), TEXT_SOUTH = list(0, 8), TEXT_EAST = list(-2, 8), TEXT_WEST = list(2, 8)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
/datum/component/riding/creature/cow/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list( 0, 8),
TEXT_SOUTH = list( 0, 8),
TEXT_EAST = list(-2, 8),
TEXT_WEST = list( 2, 8),
)
/datum/component/riding/creature/pony/handle_specials()
. = ..()
vehicle_move_delay = 1.5
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 9), TEXT_SOUTH = list(0, 9), TEXT_EAST = list(-2, 9), TEXT_WEST = list(2, 9)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
/datum/component/riding/creature/cow/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_SOUTH = list(0, 0, OBJ_LAYER),
TEXT_EAST = list(0, 0, OBJ_LAYER),
TEXT_WEST = list(0, 0, OBJ_LAYER),
)
/datum/component/riding/creature/pig
/datum/component/riding/creature/pig/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list( 0, 8),
TEXT_SOUTH = list( 0, 8),
TEXT_EAST = list(-2, 8),
TEXT_WEST = list( 2, 8),
)
/datum/component/riding/creature/pig/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_SOUTH = list(0, 0, OBJ_LAYER),
TEXT_EAST = list(0, 0, OBJ_LAYER),
TEXT_WEST = list(0, 0, OBJ_LAYER),
)
/datum/component/riding/creature/pony
vehicle_move_delay = 1.5
COOLDOWN_DECLARE(pony_trot_cooldown)
/datum/component/riding/creature/pony/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list( 0, 9),
TEXT_SOUTH = list( 0, 9),
TEXT_EAST = list(-2, 9),
TEXT_WEST = list( 2, 9),
)
/datum/component/riding/creature/pony/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_SOUTH = list(0, 0, OBJ_LAYER),
TEXT_EAST = list(0, 0, OBJ_LAYER),
TEXT_WEST = list(0, 0, OBJ_LAYER),
)
/datum/component/riding/creature/pony/driver_move(atom/movable/movable_parent, mob/living/user, direction)
. = ..()
@@ -422,51 +414,80 @@
playsound(movable_parent, 'sound/mobs/non-humanoids/pony/clown_gallup.ogg', 50)
COOLDOWN_START(src, pony_trot_cooldown, 500 MILLISECONDS)
/datum/component/riding/creature/bear/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(1, 8), TEXT_SOUTH = list(1, 8), TEXT_EAST = list(-3, 6), TEXT_WEST = list(3, 6)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(WEST, ABOVE_MOB_LAYER)
/datum/component/riding/creature/bear
/datum/component/riding/creature/bear/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list( 1, 8),
TEXT_SOUTH = list( 1, 8),
TEXT_EAST = list(-3, 6),
TEXT_WEST = list( 3, 6),
)
/datum/component/riding/creature/bear/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_SOUTH = list(0, 0, OBJ_LAYER),
TEXT_EAST = list(0, 0, ABOVE_MOB_LAYER),
TEXT_WEST = list(0, 0, ABOVE_MOB_LAYER),
)
/datum/component/riding/creature/carp
override_allow_spacemove = TRUE
/datum/component/riding/creature/carp/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 13), TEXT_SOUTH = list(0, 15), TEXT_EAST = list(-2, 12), TEXT_WEST = list(2, 12)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
/datum/component/riding/creature/carp/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list(0, 13),
TEXT_SOUTH = list(0, 15),
TEXT_EAST = list(-2, 12),
TEXT_WEST = list( 2, 12),
)
/datum/component/riding/creature/carp/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_SOUTH = list(0, 0, OBJ_LAYER),
TEXT_EAST = list(0, 0, OBJ_LAYER),
TEXT_WEST = list(0, 0, OBJ_LAYER),
)
/datum/component/riding/creature/megacarp/handle_specials()
. = ..()
var/atom/movable/movable_parent = parent
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(1, 8), TEXT_SOUTH = list(1, 8), TEXT_EAST = list(-3, 6), TEXT_WEST = list(3, 6)))
set_vehicle_dir_offsets(SOUTH, movable_parent.pixel_x, 0)
set_vehicle_dir_offsets(NORTH, movable_parent.pixel_x, 0)
set_vehicle_dir_offsets(EAST, movable_parent.pixel_x, 0)
set_vehicle_dir_offsets(WEST, movable_parent.pixel_x, 0)
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
/datum/component/riding/creature/megacarp
/datum/component/riding/creature/megacarp/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list(1, 8),
TEXT_SOUTH = list(1, 8),
TEXT_EAST = list(-3, 6),
TEXT_WEST = list(3, 6),
)
/datum/component/riding/creature/megacarp/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_SOUTH = list(0, 0, OBJ_LAYER),
TEXT_EAST = list(0, 0, OBJ_LAYER),
TEXT_WEST = list(0, 0, OBJ_LAYER),
)
/datum/component/riding/creature/vatbeast
override_allow_spacemove = TRUE
can_use_abilities = TRUE
/datum/component/riding/creature/vatbeast/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 15), TEXT_SOUTH = list(0, 15), TEXT_EAST = list(-10, 15), TEXT_WEST = list(10, 15)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
/datum/component/riding/creature/vatbeast/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list(0, 15),
TEXT_SOUTH = list(0, 15),
TEXT_EAST = list(-10, 15),
TEXT_WEST = list(10, 15),
)
/datum/component/riding/creature/vatbeast/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_SOUTH = list(0, 0, OBJ_LAYER),
TEXT_EAST = list(0, 0, OBJ_LAYER),
TEXT_WEST = list(0, 0, OBJ_LAYER),
)
/datum/component/riding/creature/goliath
keytype = /obj/item/key/lasso
@@ -486,38 +507,58 @@
goliath.remove_movespeed_modifier(/datum/movespeed_modifier/goliath_mount)
return ..()
/datum/component/riding/creature/goliath/handle_specials()
. = ..()
set_vehicle_offsets(list(TEXT_NORTH = list(-12, 0), TEXT_SOUTH = list(-12, 0), TEXT_EAST = list(-12, 0), TEXT_WEST = list(-12, 0)))
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 12), TEXT_SOUTH = list(0, 12), TEXT_EAST = list(-4, 12), TEXT_WEST = list(3, 12)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
/datum/component/riding/creature/goliath/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list( 0, 12),
TEXT_SOUTH = list( 0, 12),
TEXT_EAST = list(-4, 12),
TEXT_WEST = list( 3, 12),
)
/datum/component/riding/creature/glutton/handle_specials()
. = ..()
var/atom/movable/movable_parent = parent
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 24), TEXT_SOUTH = list(0, 24), TEXT_EAST = list(-16, 24), TEXT_WEST = list(16, 24)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(WEST, ABOVE_MOB_LAYER)
set_vehicle_dir_offsets(SOUTH, movable_parent.pixel_x, 0)
set_vehicle_dir_offsets(NORTH, movable_parent.pixel_x, 0)
set_vehicle_dir_offsets(EAST, movable_parent.pixel_x, 0)
set_vehicle_dir_offsets(WEST, movable_parent.pixel_x, 0)
/datum/component/riding/creature/goliath/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(-12, 0, ABOVE_MOB_LAYER),
TEXT_SOUTH = list(-12, 0, ABOVE_MOB_LAYER),
TEXT_EAST = list(-12, 0, OBJ_LAYER),
TEXT_WEST = list(-12, 0, OBJ_LAYER),
)
/datum/component/riding/creature/glutton
/datum/component/riding/creature/glutton/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list( 0, 24),
TEXT_SOUTH = list( 0, 24),
TEXT_EAST = list(-16, 24),
TEXT_WEST = list( 16, 24),
)
/datum/component/riding/creature/glutton/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_SOUTH = list(0, 0, OBJ_LAYER),
TEXT_EAST = list(0, 0, ABOVE_MOB_LAYER),
TEXT_WEST = list(0, 0, ABOVE_MOB_LAYER),
)
/datum/component/riding/creature/guardian
can_be_driven = FALSE
/datum/component/riding/creature/guardian/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(-6, 3), TEXT_WEST = list(6, 3)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(WEST, ABOVE_MOB_LAYER)
/datum/component/riding/creature/guardian/get_rider_offsets_and_layers(pass_index, mob/offsetter)
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/guardian/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_SOUTH = list(0, 0, OBJ_LAYER),
TEXT_EAST = list(0, 0, ABOVE_MOB_LAYER),
TEXT_WEST = list(0, 0, ABOVE_MOB_LAYER),
)
/datum/component/riding/creature/guardian/ride_check(mob/living/user, consequences = TRUE)
var/mob/living/basic/guardian/charger = parent
@@ -527,22 +568,34 @@
/datum/component/riding/creature/goldgrub
/datum/component/riding/creature/goldgrub/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(11, 3), TEXT_SOUTH = list(11, 3), TEXT_EAST = list(9, 3), TEXT_WEST = list(14, 3)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
/datum/component/riding/creature/goldgrub/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list(11, 3),
TEXT_SOUTH = list(11, 3),
TEXT_EAST = list( 9, 3),
TEXT_WEST = list(14, 3),
)
/datum/component/riding/creature/goldgrub/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_SOUTH = list(0, 0, OBJ_LAYER),
TEXT_EAST = list(0, 0, OBJ_LAYER),
TEXT_WEST = list(0, 0, OBJ_LAYER),
)
/datum/component/riding/creature/leaper
can_force_unbuckle = FALSE
can_use_abilities = TRUE
ride_check_flags = JUST_FRIEND_RIDERS
/datum/component/riding/creature/leaper/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(17, 46), TEXT_SOUTH = list(17,51), TEXT_EAST = list(27, 46), TEXT_WEST = list(6, 46)))
/datum/component/riding/creature/leaper/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list(17, 46),
TEXT_SOUTH = list(17, 51),
TEXT_EAST = list(27, 46),
TEXT_WEST = list( 6, 46),
)
/datum/component/riding/creature/leaper/Initialize(mob/living/riding_mob, force = FALSE, ride_check_flags = NONE)
. = ..()
@@ -557,7 +610,6 @@
return
basic_parent.melee_attack(pointed)
/datum/component/riding/leaper/handle_unbuckle(mob/living/rider)
. = ..()
UnregisterSignal(rider, COMSIG_MOVABLE_POINTED)
@@ -592,16 +644,28 @@
for(var/mob/living/buckled_mob in living_parent.buckled_mobs)
force_dismount(buckled_mob, throw_range = 2, gentle = TRUE)
/datum/component/riding/creature/raptor/handle_specials()
. = ..()
/datum/component/riding/creature/raptor/get_rider_offsets_and_layers(pass_index, mob/offsetter)
if(!SSmapping.is_planetary())
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(7, 7), TEXT_SOUTH = list(2, 10), TEXT_EAST = list(12, 7), TEXT_WEST = list(10, 7)))
else
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 7), TEXT_SOUTH = list(0, 10), TEXT_EAST = list(-3, 9), TEXT_WEST = list(3, 9)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
return list(
TEXT_NORTH = list( 7, 7),
TEXT_SOUTH = list( 2, 10),
TEXT_EAST = list(12, 7),
TEXT_WEST = list(10, 7),
)
return list(
TEXT_NORTH = list( 0, 7),
TEXT_SOUTH = list( 0, 10),
TEXT_EAST = list(-3, 9),
TEXT_WEST = list( 3, 9),
)
/datum/component/riding/creature/raptor/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, OBJ_LAYER),
TEXT_SOUTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_EAST = list(0, 0, OBJ_LAYER),
TEXT_WEST = list(0, 0, OBJ_LAYER),
)
/datum/component/riding/creature/raptor/fast
vehicle_move_delay = 1.5
+142 -68
View File
@@ -101,8 +101,7 @@
if(QDELETED(src))
return
handle_vehicle_layer(movable_parent.dir)
handle_vehicle_offsets(movable_parent.dir)
update_parent_layer_and_offsets(movable_parent.dir)
return TRUE
/datum/component/riding/vehicle/atv
@@ -110,38 +109,54 @@
ride_check_flags = RIDER_NEEDS_LEGS | RIDER_NEEDS_ARMS | UNBUCKLE_DISABLED_RIDER
vehicle_move_delay = 1.5
/datum/component/riding/vehicle/atv/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(0, 4), TEXT_WEST = list( 0, 4)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
/datum/component/riding/vehicle/atv/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list(0, 4),
TEXT_SOUTH = list(0, 4),
TEXT_EAST = list(0, 4),
TEXT_WEST = list(0, 4),
)
/datum/component/riding/vehicle/atv/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, OBJ_LAYER),
TEXT_SOUTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_EAST = list(0, 0, OBJ_LAYER),
TEXT_WEST = list(0, 0, OBJ_LAYER),
)
/datum/component/riding/vehicle/bicycle
ride_check_flags = RIDER_NEEDS_LEGS | RIDER_NEEDS_ARMS | UNBUCKLE_DISABLED_RIDER
vehicle_move_delay = 0
/datum/component/riding/vehicle/bicycle/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(0, 4), TEXT_WEST = list( 0, 4)))
/datum/component/riding/vehicle/bicycle/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list(0, 4),
TEXT_SOUTH = list(0, 4),
TEXT_EAST = list(0, 4),
TEXT_WEST = list(0, 4),
)
/datum/component/riding/vehicle/lavaboat
ride_check_flags = NONE // not sure
keytype = /obj/item/oar
/// The one turf we can move on.
var/allowed_turf = /turf/open/lava
/datum/component/riding/vehicle/lavaboat/handle_specials()
/datum/component/riding/vehicle/lavaboat/Initialize(mob/living/riding_mob, force, ride_check_flags, potion_boost)
. = ..()
allowed_turf_typecache = typecacheof(allowed_turf)
/datum/component/riding/vehicle/lavaboat/dragonboat
vehicle_move_delay = 1
/datum/component/riding/vehicle/lavaboat/dragonboat/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(1, 2), TEXT_SOUTH = list(1, 2), TEXT_EAST = list(1, 2), TEXT_WEST = list( 1, 2)))
/datum/component/riding/vehicle/lavaboat/dragonboat/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list(1, 2),
TEXT_SOUTH = list(1, 2),
TEXT_EAST = list(1, 2),
TEXT_WEST = list(1, 2),
)
/datum/component/riding/vehicle/lavaboat/dragonboat
vehicle_move_delay = 1
@@ -151,19 +166,31 @@
/datum/component/riding/vehicle/janicart
keytype = /obj/item/key/janitor
/datum/component/riding/vehicle/janicart/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 7), TEXT_EAST = list(-12, 7), TEXT_WEST = list( 12, 7)))
/datum/component/riding/vehicle/janicart/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list( 0, 4),
TEXT_SOUTH = list( 0, 7),
TEXT_EAST = list(-12, 7),
TEXT_WEST = list( 12, 7),
)
/datum/component/riding/vehicle/scooter
ride_check_flags = RIDER_NEEDS_LEGS | RIDER_NEEDS_ARMS | UNBUCKLE_DISABLED_RIDER
/datum/component/riding/vehicle/scooter/handle_specials(mob/living/riding_mob)
. = ..()
if(iscyborg(riding_mob))
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0), TEXT_SOUTH = list(0), TEXT_EAST = list(0), TEXT_WEST = list(2)))
else
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(2), TEXT_SOUTH = list(-2), TEXT_EAST = list(0), TEXT_WEST = list(2)))
/datum/component/riding/vehicle/scooter/get_rider_offsets_and_layers(pass_index, mob/offsetter)
if(iscyborg(offsetter))
return list(
TEXT_NORTH = list(0, 2),
TEXT_SOUTH = list(0, 2),
TEXT_EAST = list(0, 2),
TEXT_WEST = list(2, 2),
)
return list(
TEXT_NORTH = list( 2, 2),
TEXT_SOUTH = list(-2, 2),
TEXT_EAST = list( 0, 2),
TEXT_WEST = list( 2, 2),
)
/datum/component/riding/vehicle/scooter/skateboard
vehicle_move_delay = 1.5
@@ -171,12 +198,21 @@
///If TRUE, the vehicle will be slower (but safer) to ride on walk intent.
var/can_slow_down = TRUE
/datum/component/riding/vehicle/scooter/skateboard/handle_specials()
. = ..()
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
/datum/component/riding/vehicle/scooter/skateboard/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list(0, 5),
TEXT_SOUTH = list(0, 5),
TEXT_EAST = list(0, 5),
TEXT_WEST = list(2, 5),
)
/datum/component/riding/vehicle/scooter/skateboard/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_SOUTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_EAST = list(0, 0, OBJ_LAYER),
TEXT_WEST = list(0, 0, OBJ_LAYER),
)
/datum/component/riding/vehicle/scooter/skateboard/RegisterWithParent()
. = ..()
@@ -294,17 +330,13 @@
vehicle_move_delay = 1.75 // SKYRAT EDIT - ORIGINAL: 0
can_slow_down = FALSE
/datum/component/riding/vehicle/scooter/skateboard/wheelys/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0), TEXT_SOUTH = list(0), TEXT_EAST = list(0), TEXT_WEST = list(0)))
/datum/component/riding/vehicle/scooter/skateboard/wheelys/rollerskates
vehicle_move_delay = 1.5
/datum/component/riding/vehicle/scooter/skateboard/wheelys/skishoes
vehicle_move_delay = 1
/datum/component/riding/vehicle/scooter/skateboard/wheelys/skishoes/handle_specials()
/datum/component/riding/vehicle/scooter/skateboard/wheelys/skishoes/Initialize(mob/living/riding_mob, force, ride_check_flags, potion_boost)
. = ..()
allowed_turf_typecache = typecacheof(list(/turf/open/misc/asteroid/snow, /turf/open/misc/snow, /turf/open/floor/holofloor/snow, /turf/open/misc/ice, /turf/open/floor/fake_snow))
@@ -313,10 +345,13 @@
vehicle_move_delay = 1.75
ride_check_flags = RIDER_NEEDS_LEGS | RIDER_NEEDS_ARMS | UNBUCKLE_DISABLED_RIDER
/datum/component/riding/vehicle/secway/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(0, 4), TEXT_WEST = list( 0, 4)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
/datum/component/riding/vehicle/secway/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list(0, 4),
TEXT_SOUTH = list(0, 4),
TEXT_EAST = list(0, 4),
TEXT_WEST = list(0, 4),
)
/datum/component/riding/vehicle/secway/driver_move(mob/living/user, direction)
var/obj/vehicle/ridden/secway/the_secway = parent
@@ -334,48 +369,87 @@
override_allow_spacemove = TRUE
ride_check_flags = RIDER_NEEDS_LEGS | RIDER_NEEDS_ARMS | UNBUCKLE_DISABLED_RIDER
/datum/component/riding/vehicle/speedbike/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, -8), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(-10, 5), TEXT_WEST = list( 10, 5)))
set_vehicle_dir_offsets(NORTH, -16, -16)
set_vehicle_dir_offsets(SOUTH, -16, -16)
set_vehicle_dir_offsets(EAST, -18, 0)
set_vehicle_dir_offsets(WEST, -18, 0)
/datum/component/riding/vehicle/speedbike/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list( 0, -8),
TEXT_SOUTH = list( 0, 4),
TEXT_EAST = list(-10, 5),
TEXT_WEST = list( 10, 5),
)
/datum/component/riding/vehicle/speedbike/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(-16, -16, OBJ_LAYER),
TEXT_SOUTH = list(-16, -16, ABOVE_MOB_LAYER),
TEXT_EAST = list(-18, 0, ABOVE_MOB_LAYER),
TEXT_WEST = list(-18, 0, ABOVE_MOB_LAYER),
)
/datum/component/riding/vehicle/speedwagon
vehicle_move_delay = 0
/datum/component/riding/vehicle/speedwagon/handle_specials()
. = ..()
set_riding_offsets(1, list(TEXT_NORTH = list(-10, -4), TEXT_SOUTH = list(16, 3), TEXT_EAST = list(-4, 30), TEXT_WEST = list(4, -3)))
set_riding_offsets(2, list(TEXT_NORTH = list(19, -5, 4), TEXT_SOUTH = list(-13, 3, 4), TEXT_EAST = list(-4, -3, 4.1), TEXT_WEST = list(4, 28, 3.9)))
set_riding_offsets(3, list(TEXT_NORTH = list(-10, -18, 4.2), TEXT_SOUTH = list(16, 25, 3.9), TEXT_EAST = list(-22, 30), TEXT_WEST = list(22, -3, 4.1)))
set_riding_offsets(4, list(TEXT_NORTH = list(19, -18, 4.2), TEXT_SOUTH = list(-13, 25, 3.9), TEXT_EAST = list(-22, 3, 3.9), TEXT_WEST = list(22, 28)))
set_vehicle_dir_offsets(NORTH, -48, -48)
set_vehicle_dir_offsets(SOUTH, -48, -48)
set_vehicle_dir_offsets(EAST, -48, -48)
set_vehicle_dir_offsets(WEST, -48, -48)
for(var/i in GLOB.cardinals)
set_vehicle_dir_layer(i, BELOW_MOB_LAYER)
/datum/component/riding/vehicle/speedwagon/get_rider_offsets_and_layers(pass_index, mob/offsetter)
switch(pass_index)
if(1)
return list(
TEXT_NORTH = list(-10, -4, LYING_MOB_LAYER),
TEXT_SOUTH = list( 16, -4, LYING_MOB_LAYER),
TEXT_EAST = list( -4, 30, LYING_MOB_LAYER),
TEXT_WEST = list( 4, -3, LYING_MOB_LAYER),
)
if(2)
return list(
TEXT_NORTH = list( 19, -5, MOB_LAYER),
TEXT_SOUTH = list(-13, 3, MOB_LAYER),
TEXT_EAST = list( -4, -3, ABOVE_MOB_LAYER),
TEXT_WEST = list( 4, 28, VEHICLE_LAYER),
)
if(3)
return list(
TEXT_NORTH = list(-10, -18, ABOVE_MOB_LAYER + 0.1),
TEXT_SOUTH = list( 16, 25, VEHICLE_LAYER),
TEXT_EAST = list(-22, 30, LYING_MOB_LAYER),
TEXT_WEST = list( 22, -3, ABOVE_MOB_LAYER),
)
if(4)
return list(
TEXT_NORTH = list( 19, -18, ABOVE_MOB_LAYER + 0.1),
TEXT_SOUTH = list(-13, 25, VEHICLE_LAYER),
TEXT_EAST = list(-22, 3, VEHICLE_LAYER),
TEXT_WEST = list( 22, 28, LYING_MOB_LAYER),
)
/datum/component/riding/vehicle/speedwagon/get_parent_offsets_and_layers()
. = ..()
return list(
TEXT_NORTH = list(-48, -48, BELOW_MOB_LAYER),
TEXT_SOUTH = list(-48, -48, BELOW_MOB_LAYER),
TEXT_EAST = list(-48, -48, BELOW_MOB_LAYER),
TEXT_WEST = list(-48, -48, BELOW_MOB_LAYER),
)
/datum/component/riding/vehicle/wheelchair
vehicle_move_delay = 0
ride_check_flags = RIDER_NEEDS_ARMS
/datum/component/riding/vehicle/wheelchair/handle_specials()
. = ..()
set_vehicle_dir_layer(SOUTH, OBJ_LAYER)
set_vehicle_dir_layer(NORTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
/datum/component/riding/vehicle/wheelchair/get_parent_offsets_and_layers()
return list(
TEXT_NORTH = list(0, 0, OBJ_LAYER),
TEXT_SOUTH = list(0, 0, ABOVE_MOB_LAYER),
TEXT_EAST = list(0, 0, OBJ_LAYER),
TEXT_WEST = list(0, 0, OBJ_LAYER),
)
/datum/component/riding/vehicle/wheelchair/hand
/// Magic number used in calculating the speed of the wheelchair
var/delay_multiplier = 6.7
// special messaging for those without arms
/datum/component/riding/vehicle/wheelchair/hand/driver_move(obj/vehicle/vehicle_parent, mob/living/user, direction)
var/delay_multiplier = 6.7 // magic number from wheelchair code
vehicle_move_delay = round(CONFIG_GET(number/movedelay/run_delay) * delay_multiplier) / clamp(user.usable_hands, 1, 2)
return ..()
/datum/component/riding/vehicle/wheelchair/motorized
/datum/component/riding/vehicle/wheelchair/motorized/driver_move(obj/vehicle/vehicle_parent, mob/living/user, direction)
var/obj/vehicle/ridden/wheelchair/motorized/our_chair = parent
var/speed = our_chair.speed
+69 -43
View File
@@ -78,6 +78,7 @@
reset_elevation(changed)
#define ELEVATE_TIME 0.2 SECONDS
#define ELEVATION_SOURCE(datum) "elevation_[REF(datum)]"
/**
* The core element attached to the turf itself. Do not use this directly!
@@ -109,14 +110,10 @@
src.pixel_shift = pixel_shift
ADD_TRAIT(target, TRAIT_ELEVATED_TURF, REF(src))
ADD_TRAIT(target, TRAIT_ELEVATED_TURF, ELEVATION_SOURCE(src))
for(var/mob/living/living in target)
ADD_TRAIT(living, TRAIT_ON_ELEVATED_SURFACE, REF(src))
RegisterSignal(living, COMSIG_LIVING_SET_BUCKLED, PROC_REF(on_set_buckled))
RegisterSignal(living, SIGNAL_ADDTRAIT(TRAIT_IGNORE_ELEVATION), PROC_REF(on_ignore_elevation_add))
RegisterSignal(living, SIGNAL_REMOVETRAIT(TRAIT_IGNORE_ELEVATION), PROC_REF(on_ignore_elevation_remove))
elevate_mob(living)
register_new_mob(living)
/datum/element/elevation_core/Detach(datum/source)
/**
@@ -130,53 +127,70 @@
COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON,
COMSIG_TURF_RESET_ELEVATION,
))
REMOVE_TRAIT(source, TRAIT_ELEVATED_TURF, REF(src))
REMOVE_TRAIT(source, TRAIT_ELEVATED_TURF, ELEVATION_SOURCE(src))
for(var/mob/living/living in source)
if(!HAS_TRAIT_FROM(living, TRAIT_ON_ELEVATED_SURFACE, REF(src)))
continue
REMOVE_TRAIT(living, TRAIT_ON_ELEVATED_SURFACE, REF(src))
elevate_mob(living, -pixel_shift)
deelevate_mob(living)
UnregisterSignal(living, list(COMSIG_LIVING_SET_BUCKLED, SIGNAL_ADDTRAIT(TRAIT_IGNORE_ELEVATION), SIGNAL_REMOVETRAIT(TRAIT_IGNORE_ELEVATION)))
return ..()
/datum/element/elevation_core/proc/on_entered(turf/source, atom/movable/entered, atom/old_loc)
SIGNAL_HANDLER
if((isnull(old_loc) || !HAS_TRAIT_FROM(old_loc, TRAIT_ELEVATED_TURF, REF(src))) && isliving(entered))
ADD_TRAIT(entered, TRAIT_ON_ELEVATED_SURFACE, REF(src))
var/elevate_time = isturf(old_loc) && source.Adjacent(old_loc) ? ELEVATE_TIME : 0
elevate_mob(entered, elevate_time = elevate_time)
RegisterSignal(entered, COMSIG_LIVING_SET_BUCKLED, PROC_REF(on_set_buckled))
RegisterSignal(entered, SIGNAL_ADDTRAIT(TRAIT_IGNORE_ELEVATION), PROC_REF(on_ignore_elevation_add))
RegisterSignal(entered, SIGNAL_REMOVETRAIT(TRAIT_IGNORE_ELEVATION), PROC_REF(on_ignore_elevation_remove))
if((isnull(old_loc) || !HAS_TRAIT_FROM(old_loc, TRAIT_ELEVATED_TURF, ELEVATION_SOURCE(src))) && isliving(entered))
register_new_mob(entered, elevate_time = isturf(old_loc) && source.Adjacent(old_loc) ? ELEVATE_TIME : 0)
/datum/element/elevation_core/proc/on_initialized_on(turf/source, atom/movable/spawned)
SIGNAL_HANDLER
if(isliving(spawned) && !HAS_TRAIT(spawned, TRAIT_ON_ELEVATED_SURFACE))
on_entered(entered = spawned)
if(isliving(spawned))
register_new_mob(spawned, elevate_time = 0)
/datum/element/elevation_core/proc/on_exited(turf/source, atom/movable/gone)
SIGNAL_HANDLER
if((isnull(gone.loc) || !HAS_TRAIT_FROM(gone.loc, TRAIT_ELEVATED_TURF, REF(src))) && isliving(gone))
if((isnull(gone.loc) || !HAS_TRAIT_FROM(gone.loc, TRAIT_ELEVATED_TURF, ELEVATION_SOURCE(src))) && isliving(gone))
// Always unregister the signals, we're still leaving even if not affected by elevation.
UnregisterSignal(gone, list(COMSIG_LIVING_SET_BUCKLED, SIGNAL_ADDTRAIT(TRAIT_IGNORE_ELEVATION), SIGNAL_REMOVETRAIT(TRAIT_IGNORE_ELEVATION)))
if(!HAS_TRAIT_FROM(gone, TRAIT_ON_ELEVATED_SURFACE, REF(src)))
return
REMOVE_TRAIT(gone, TRAIT_ON_ELEVATED_SURFACE, REF(src))
var/elevate_time = isturf(gone.loc) && source.Adjacent(gone.loc) ? ELEVATE_TIME : 0
elevate_mob(gone, -pixel_shift, elevate_time)
deelevate_mob(gone, isturf(gone.loc) && source.Adjacent(gone.loc) ? ELEVATE_TIME : 0)
/datum/element/elevation_core/proc/elevate_mob(mob/living/target, z_shift = pixel_shift, elevate_time = ELEVATE_TIME, force = FALSE)
/// Registers a new mob to be elevated, and elevates it.
/datum/element/elevation_core/proc/register_new_mob(mob/living/new_mob, elevate_time = ELEVATE_TIME)
elevate_mob(new_mob, elevate_time = elevate_time)
// mobs can reasonably be reigstered twice if the element is attached and then their init finishes
RegisterSignal(new_mob, COMSIG_LIVING_SET_BUCKLED, PROC_REF(on_set_buckled), override = TRUE)
RegisterSignal(new_mob, SIGNAL_ADDTRAIT(TRAIT_IGNORE_ELEVATION), PROC_REF(on_ignore_elevation_add), override = TRUE)
RegisterSignal(new_mob, SIGNAL_REMOVETRAIT(TRAIT_IGNORE_ELEVATION), PROC_REF(on_ignore_elevation_remove), override = TRUE)
/**
* Elevates the mob by pixel_shift amount.
*
* If the mob has the TRAIT_IGNORE_ELEVATION trait, it will not be elevated.
*
* If the mob is buckled to something...
* ...And that something is a vehicle, it will also be elevated.
* ...And that something is an object, neither the mob nor the object will be elevated.
* ...And that something is a mob, we will be elevated (but not the other mob).
*/
/datum/element/elevation_core/proc/elevate_mob(mob/living/target, elevate_time = ELEVATE_TIME, force = FALSE)
if(HAS_TRAIT(target, TRAIT_IGNORE_ELEVATION) && !force)
return
var/buckled_to_vehicle = FALSE
// while the offset system can natively handle this,
// we want to avoid accidentally double-elevating anything they're buckled to (namely vehicles)
if(target.has_offset(ELEVATION_SOURCE(src)))
return
// We are buckled to something
if(target.buckled)
// We are buckled to a vehicle, so it also must be elevated
if(isvehicle(target.buckled))
buckled_to_vehicle = TRUE
else if(!isliving(target.buckled))
animate(target.buckled, pixel_z = pixel_shift, time = elevate_time, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
// We are buckled to a mob - they're elevated so we're elevated
else if(isliving(target.buckled))
pass()
// We are buckled to some other object - perhaps the object itself - so skip
else
return
animate(target, pixel_z = z_shift, time = elevate_time, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
if(buckled_to_vehicle)
animate(target.buckled, pixel_z = z_shift, time = elevate_time, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
target.add_offsets(ELEVATION_SOURCE(src), z_add = pixel_shift, animate = elevate_time > 0)
/// Reverts elevation of the mob.
/datum/element/elevation_core/proc/deelevate_mob(mob/living/target, elevate_time = ELEVATE_TIME)
target.remove_offsets(ELEVATION_SOURCE(src), animate = elevate_time > 0)
/**
* If the mob is buckled or unbuckled to/from a vehicle, shift it up/down
@@ -190,28 +204,40 @@
SIGNAL_HANDLER
if(HAS_TRAIT(source, TRAIT_IGNORE_ELEVATION))
return
// We were buckled to something
if(source.buckled)
// It was a vehicle, so reset its pixel_z
if(isvehicle(source.buckled))
animate(source.buckled, pixel_z = -pixel_shift, time = ELEVATE_TIME, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
else if(!isliving(source.buckled))
animate(source, pixel_z = pixel_shift, time = ELEVATE_TIME, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
if(!new_buckled)
return
if(isvehicle(new_buckled))
animate(new_buckled, pixel_z = pixel_shift, time = ELEVATE_TIME, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
else if(!isliving(new_buckled))
animate(source, pixel_z = -pixel_shift, time = ELEVATE_TIME, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
// It was a mob, so revert our pixel_z
else if(isliving(source.buckled))
deelevate_mob(source)
// It was some object, maybe the object itself, elevate us
else
source.add_offsets(ELEVATION_SOURCE(src), z_add = pixel_shift)
// We are now buckled to something
if(new_buckled)
// It's a vehicle, so elevate it
if(isvehicle(new_buckled))
animate(new_buckled, pixel_z = pixel_shift, time = ELEVATE_TIME, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
// It's a mob, so elevate us
else if(isliving(new_buckled))
elevate_mob(source)
// It's some object, maybe the object itself, so clear elevation
else
source.remove_offsets(ELEVATION_SOURCE(src))
/datum/element/elevation_core/proc/on_ignore_elevation_add(mob/living/source, trait)
SIGNAL_HANDLER
elevate_mob(source, -pixel_shift, force = TRUE)
deelevate_mob(source)
/datum/element/elevation_core/proc/on_ignore_elevation_remove(mob/living/source, trait)
SIGNAL_HANDLER
elevate_mob(source, pixel_shift)
elevate_mob(source)
/datum/element/elevation_core/proc/on_reset_elevation(turf/source, list/current_values)
SIGNAL_HANDLER
current_values[ELEVATION_CURRENT_PIXEL_SHIFT] = pixel_shift
#undef ELEVATE_TIME
#undef ELEVATION_SOURCE
+6 -8
View File
@@ -335,23 +335,23 @@ GLOBAL_LIST_INIT(immerse_ignored_movable, typecacheof(list(
/// Oh, yeah, didn't I mention turning a visual overlay affects its pixel x/y/w/z too? Yeah, it sucks.
var/new_x = vis_overlay.extra_width
var/new_y = vis_overlay.extra_height
var/old_div = source.current_size/resize
var/offset_lying = source.rotate_on_lying ? PIXEL_Y_OFFSET_LYING : source.get_pixel_y_offset_standing(source.current_size/resize)
var/old_div = source.current_size / resize
var/offset_lying = source.rotate_on_lying ? PIXEL_Y_OFFSET_LYING : source.get_transform_translation_size(old_div)
switch(source.lying_prev)
if(270)
vis_overlay.pixel_x += -offset_lying / old_div
if(90)
vis_overlay.pixel_x += offset_lying / old_div
if(0)
vis_overlay.pixel_y += -source.get_pixel_y_offset_standing(source.current_size/resize) / old_div
vis_overlay.pixel_y += -source.get_transform_translation_size(old_div) / old_div
switch(new_lying_angle)
if(270)
new_x += -source.body_position_pixel_y_offset / source.current_size
new_x += -offset_lying / source.current_size
if(90)
new_x += source.body_position_pixel_y_offset / source.current_size
new_x += offset_lying / source.current_size
if(0)
new_y += -source.body_position_pixel_y_offset / source.current_size
new_y += -source.get_transform_translation_size(old_div) / old_div
animate(vis_overlay, transform = new_transform, pixel_x = new_x, pixel_y = new_y, time = UPDATE_TRANSFORM_ANIMATION_TIME, easing = (EASE_IN|EASE_OUT))
addtimer(CALLBACK(vis_overlay, TYPE_PROC_REF(/atom/movable/immerse_overlay, adjust_living_overlay_offset), source), UPDATE_TRANSFORM_ANIMATION_TIME)
@@ -406,6 +406,4 @@ GLOBAL_LIST_INIT(immerse_ignored_movable, typecacheof(list(
/atom/movable/immerse_overlay/proc/adjust_living_overlay_offset(mob/living/source)
pixel_x = extra_width
pixel_y = extra_height
overlay_appearance.pixel_y = -source.body_position_pixel_y_offset
overlays = list(overlay_appearance)
overlay_appearance.pixel_y = 0
+4 -6
View File
@@ -249,12 +249,10 @@
owner.emote("twitch")
if(2 to 3)
owner.say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]", forced=name)
var/x_offset_old = owner.pixel_x
var/y_offset_old = owner.pixel_y
var/x_offset = owner.pixel_x + rand(-2,2)
var/y_offset = owner.pixel_y + rand(-1,1)
animate(owner, pixel_x = x_offset, pixel_y = y_offset, time = 1)
animate(owner, pixel_x = x_offset_old, pixel_y = y_offset_old, time = 1)
var/w_offset = rand(-2, 2)
var/z_offset = rand(-1, 1)
animate(owner, pixel_w = w_offset, pixel_z = z_offset, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(owner, pixel_w = -w_offset, pixel_z = -z_offset, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
//Deafness makes you deaf.
@@ -56,7 +56,7 @@
/// jitter_amount will only apply up to 300 (maximum jitter effect).
/mob/living/proc/do_jitter_animation(jitter_amount = 100)
var/amplitude = min(4, (jitter_amount / 100) + 1)
var/pixel_x_diff = rand(-amplitude, amplitude)
var/pixel_y_diff = rand(-amplitude / 3, amplitude / 3)
animate(src, pixel_x = pixel_x_diff, pixel_y = pixel_y_diff , time = 0.2 SECONDS, loop = 6, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(pixel_x = -pixel_x_diff , pixel_y = -pixel_y_diff , time = 0.2 SECONDS, flags = ANIMATION_RELATIVE)
var/pixel_w_diff = rand(-amplitude, amplitude)
var/pixel_z_diff = rand(-amplitude / 3, amplitude / 3)
animate(src, pixel_w = pixel_w_diff, pixel_z = pixel_z_diff , time = 0.2 SECONDS, loop = 6, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(pixel_w = -pixel_w_diff , pixel_z = -pixel_z_diff , time = 0.2 SECONDS, flags = ANIMATION_RELATIVE)
@@ -30,13 +30,17 @@
if(prob(bio_protection))
owner.apply_status_effect(/datum/status_effect/slimed, our_slime.slime_type.rgb_code, our_slime.slime_type.colour == SLIME_TYPE_RAINBOW)
UnregisterSignal(our_slime, list(COMSIG_LIVING_DEATH, COMSIG_MOB_UNBUCKLED, COMSIG_QDELETING,))
if(!QDELETED(our_slime))
our_slime.stop_feeding()
qdel(src)
/datum/status_effect/slime_leech/on_remove()
our_slime = null
/datum/status_effect/slime_leech/tick(seconds_between_ticks)
if(our_slime.stat)
if(our_slime.stat != CONSCIOUS)
our_slime.stop_feeding(silent = TRUE)
return
@@ -43,12 +43,9 @@
/// Helper proc that causes the mob to do a stagger animation.
/// Doesn't change significantly, just meant to represent swaying back and forth
/mob/living/proc/do_stagger_animation()
var/normal_pos = base_pixel_x + body_position_pixel_x_offset
var/jitter_right = normal_pos + 4
var/jitter_left = normal_pos - 4
animate(src, pixel_x = jitter_left, 0.2 SECONDS, flags = ANIMATION_PARALLEL)
animate(pixel_x = jitter_right, time = 0.4 SECONDS)
animate(pixel_x = normal_pos, time = 0.2 SECONDS)
animate(src, pixel_w = 3, time = 0.2 SECONDS, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(pixel_w = -6, time = 0.4 SECONDS, flags = ANIMATION_RELATIVE)
animate(pixel_w = 3, time = 0.2 SECONDS, flags = ANIMATION_RELATIVE)
/// Status effect specifically for instances where someone is vulnerable to being stunned when shoved.
/datum/status_effect/dazed
-1
View File
@@ -735,7 +735,6 @@
pixel_x = pixel_x + base_pixel_x - .
///Setter for the `base_pixel_y` variable to append behavior related to its changing.
/atom/proc/set_base_pixel_y(new_value)
if(base_pixel_y == new_value)
+1 -1
View File
@@ -598,7 +598,7 @@
if(!. || !isliving(moving_atom))
return
var/mob/living/pulled_mob = moving_atom
set_pull_offsets(pulled_mob, grab_state)
set_pull_offsets(pulled_mob, grab_state, animate = FALSE)
/**
* Checks if the pulling and pulledby should be stopped because they're out of reach.
+10 -10
View File
@@ -46,17 +46,17 @@
user.manual_emote("waves around a blank sign.")
var/direction = prob(50) ? -1 : 1
if(NSCOMPONENT(user.dir)) //So signs are waved horizontally relative to what way the player waving it is facing.
animate(user, pixel_x = user.pixel_x + (1 * direction), time = 1, easing = SINE_EASING)
animate(pixel_x = user.pixel_x - (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_x = user.pixel_x + (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_x = user.pixel_x - (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_x = user.pixel_x + (1 * direction), time = 1, easing = SINE_EASING)
animate(user, pixel_w = (1 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(pixel_w = (-2 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
animate(pixel_w = (2 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
animate(pixel_w = (-2 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
animate(pixel_w = (1 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
else
animate(user, pixel_y = user.pixel_y + (1 * direction), time = 1, easing = SINE_EASING)
animate(pixel_y = user.pixel_y - (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_y = user.pixel_y + (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_y = user.pixel_y - (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_y = user.pixel_y + (1 * direction), time = 1, easing = SINE_EASING)
animate(user, pixel_z = (1 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(pixel_z = (-2 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
animate(pixel_z = (2 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
animate(pixel_z = (-2 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
animate(pixel_z = (1 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
user.changeNext_move(CLICK_CD_MELEE)
/datum/action/item_action/nano_picket_sign
+11 -11
View File
@@ -1558,18 +1558,18 @@
COOLDOWN_START(src, foamfinger_cooldown, 5 SECONDS)
user.manual_emote("waves around the foam finger.")
var/direction = prob(50) ? -1 : 1
if(NSCOMPONENT(user.dir)) //So signs are waved horizontally relative to what way the player waving it is facing.
animate(user, pixel_x = user.pixel_x + (1 * direction), time = 1, easing = SINE_EASING)
animate(pixel_x = user.pixel_x - (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_x = user.pixel_x + (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_x = user.pixel_x - (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_x = user.pixel_x + (1 * direction), time = 1, easing = SINE_EASING)
if(NSCOMPONENT(user.dir))
animate(user, pixel_w = (1 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(pixel_w = (-2 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
animate(pixel_w = (2 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
animate(pixel_w = (-2 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
animate(pixel_w = (1 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
else
animate(user, pixel_y = user.pixel_y + (1 * direction), time = 1, easing = SINE_EASING)
animate(pixel_y = user.pixel_y - (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_y = user.pixel_y + (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_y = user.pixel_y - (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_y = user.pixel_y + (1 * direction), time = 1, easing = SINE_EASING)
animate(user, pixel_z = (1 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(pixel_z = (-2 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
animate(pixel_z = (2 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
animate(pixel_z = (-2 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
animate(pixel_z = (1 * direction), time = 0.1 SECONDS, easing = SINE_EASING, flags = ANIMATION_RELATIVE)
user.changeNext_move(CLICK_CD_MELEE)
///All people who have used an Intento this round along with their high scores.
@@ -74,8 +74,7 @@
/obj/structure/bed/nest/post_buckle_mob(mob/living/M)
ADD_TRAIT(M, TRAIT_HANDS_BLOCKED, type)
M.pixel_y = M.base_pixel_y
M.pixel_x = M.base_pixel_x + 2
M.add_offsets(type, x_add = 2)
M.layer = BELOW_MOB_LAYER
add_overlay(nest_overlay)
@@ -86,8 +85,7 @@
/obj/structure/bed/nest/post_unbuckle_mob(mob/living/M)
REMOVE_TRAIT(M, TRAIT_HANDS_BLOCKED, type)
M.pixel_x = M.base_pixel_x + M.body_position_pixel_x_offset
M.pixel_y = M.base_pixel_y + M.body_position_pixel_y_offset
M.remove_offsets(type)
M.layer = initial(M.layer)
cut_overlay(nest_overlay)
M.remove_status_effect(/datum/status_effect/nest_sustenance)
@@ -563,11 +563,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
return NONE
/obj/structure/chair/mime/post_buckle_mob(mob/living/M)
M.pixel_y += 5
M.add_offsets(type, z_add = 5)
/obj/structure/chair/mime/post_unbuckle_mob(mob/living/M)
M.pixel_y -= 5
M.remove_offsets(type)
/obj/structure/chair/plastic
icon_state = "plastic_chair"
@@ -582,13 +581,13 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
fishing_modifier = -10
/obj/structure/chair/plastic/post_buckle_mob(mob/living/Mob)
Mob.pixel_y += 2
.=..()
Mob.add_offsets(type, z_add = 2)
. = ..()
if(iscarbon(Mob))
INVOKE_ASYNC(src, PROC_REF(snap_check), Mob)
/obj/structure/chair/plastic/post_unbuckle_mob(mob/living/Mob)
Mob.pixel_y -= 2
Mob.remove_offsets(type)
/obj/structure/chair/plastic/proc/snap_check(mob/living/carbon/Mob)
if (Mob.nutrition >= NUTRITION_LEVEL_FAT)
@@ -14,7 +14,7 @@
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
///How much we shift the user's pixel y when using the weight machine.
var/pixel_shift_y = -3
var/pixel_shift_z = -3
///The weight action we give to people that buckle themselves to us.
var/datum/action/push_weights/weight_action
@@ -157,9 +157,9 @@
flick_overlay_view(workout, 0.8 SECONDS)
flick("[base_icon_state]-u", src)
var/mob/living/user = buckled_mobs[1]
animate(user, pixel_y = pixel_shift_y, time = WORKOUT_LENGTH * 0.5)
animate(user, pixel_z = pixel_shift_z, time = WORKOUT_LENGTH * 0.5, flags = ANIMATION_PARALLEL|ANIMATION_RELATIVE)
animate(pixel_z = -pixel_shift_z, time = WORKOUT_LENGTH * 0.5, flags = ANIMATION_PARALLEL)
playsound(user, 'sound/machines/creak.ogg', 60, TRUE)
animate(pixel_y = user.base_pixel_y, time = WORKOUT_LENGTH * 0.5)
if(!iscarbon(user) || isnull(user.mind))
return TRUE
@@ -194,7 +194,7 @@
icon_state = "benchpress"
base_icon_state = "benchpress"
pixel_shift_y = 5
pixel_shift_z = 5
drunk_message = "You raise the bar over you trying to balance it with one hand, keyword tried."
@@ -175,7 +175,7 @@
var/matrix/m180 = matrix(target.transform)
m180.Turn(180)
animate(target, transform = m180, time = 3)
target.pixel_y = target.base_pixel_y + PIXEL_Y_OFFSET_LYING
target.add_offsets(type, y_add = -6, animate = FALSE)
ADD_TRAIT(target, TRAIT_MOVE_UPSIDE_DOWN, REF(src))
/obj/structure/kitchenspike/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
@@ -207,7 +207,7 @@
var/matrix/m180 = matrix(buckled_mob.transform)
m180.Turn(180)
animate(buckled_mob, transform = m180, time = 3)
buckled_mob.pixel_y = buckled_mob.base_pixel_y + PIXEL_Y_OFFSET_LYING
buckled_mob.remove_offsets(type, animate = FALSE)
REMOVE_TRAIT(buckled_mob, TRAIT_MOVE_UPSIDE_DOWN, REF(src))
/obj/structure/kitchenspike/atom_deconstruct(disassembled = TRUE)
+2 -4
View File
@@ -837,13 +837,11 @@
///Align the mob with the table when buckled.
/obj/structure/table/optable/post_buckle_mob(mob/living/buckled)
. = ..()
buckled.pixel_y += 6
buckled.add_offsets(type, z_add = 6)
///Disalign the mob with the table when unbuckled.
/obj/structure/table/optable/post_unbuckle_mob(mob/living/buckled)
. = ..()
buckled.pixel_y -= 6
buckled.remove_offsets(type)
/// Any mob that enters our tile will be marked as a potential patient. They will be turned into a patient if they lie down.
/obj/structure/table/optable/proc/mark_patient(datum/source, mob/living/carbon/potential_patient)
+5 -9
View File
@@ -98,10 +98,12 @@
var/dunk_dir = get_dir(baller, src)
var/dunk_pixel_y = dunk_dir & SOUTH ? -16 : 16
var/dunk_pixel_x = dunk_dir & EAST && 16 || dunk_dir & WEST && -16 || 0
var/dunk_pixel_z = (dunk_dir & SOUTH) ? -16 : 16
var/dunk_pixel_w = ((dunk_dir & EAST) && 16) || ((dunk_dir & WEST) && -16) || 0
animate(baller, pixel_w = dunk_pixel_w, pixel_z = dunk_pixel_z, time = 0.5 SECONDS, easing = BOUNCE_EASING|EASE_IN|EASE_OUT, flags = ANIMATION_PARALLEL|ANIMATION_RELATIVE)
animate(pixel_w = -dunk_pixel_w, pixel_z = -dunk_pixel_z, time = 0.5 SECONDS, flags = ANIMATION_PARALLEL)
INVOKE_ASYNC(src, PROC_REF(dunk_animation), baller, dunk_pixel_y, dunk_pixel_x)
visible_message(span_warning("[baller] dunks [ball] into \the [src]!"))
baller.add_mood_event("basketball", /datum/mood_event/basketball_dunk)
score(ball, baller, 2)
@@ -109,12 +111,6 @@
if(istype(ball, /obj/item/toy/basketball))
baller.adjustStaminaLoss(STAMINA_COST_DUNKING)
/// This bobs the mob in the hoop direction for the dunk animation
/obj/structure/hoop/proc/dunk_animation(mob/living/baller, dunk_pixel_y, dunk_pixel_x)
animate(baller, pixel_x = dunk_pixel_x, pixel_y = dunk_pixel_y, time = 5, easing = BOUNCE_EASING|EASE_IN|EASE_OUT)
sleep(0.5 SECONDS)
animate(baller, pixel_x = 0, pixel_y = 0, time = 3)
/obj/structure/hoop/attack_hand(mob/living/baller, list/modifiers)
. = ..()
if(.)
+3 -3
View File
@@ -588,9 +588,9 @@
for(var/i in 1 to peels_to_spawn)
new banana_type(pick_n_take(reachable_turfs))
playsound(owner, 'sound/mobs/non-humanoids/clown/clownana_rustle.ogg', 60)
animate(owner, time = 1, pixel_x = 6, easing = CUBIC_EASING | EASE_OUT)
animate(time = 2, pixel_x = -8, easing = CUBIC_EASING)
animate(time = 1, pixel_x = 0, easing = CUBIC_EASING | EASE_IN)
animate(owner, time = 0.1 SECONDS, pixel_w = 6, easing = CUBIC_EASING | EASE_OUT, flags = ANIMATION_PARALLEL|ANIMATION_RELATIVE)
animate(time = 0.2 SECONDS, pixel_w = -8, easing = CUBIC_EASING, flags = ANIMATION_RELATIVE)
animate(time = 0.1 SECONDS, pixel_w = 2, easing = CUBIC_EASING | EASE_IN, flags = ANIMATION_RELATIVE)
StartCooldown()
///spawns a plumb bunch of bananas imbued with mystical power.
@@ -9,10 +9,10 @@
// Contains pixel offset data for sprites riding wolves
/datum/component/riding/creature/wolf
/datum/component/riding/creature/wolf/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(1, 9), TEXT_SOUTH = list(1, 9), TEXT_EAST = list(0, 9), TEXT_WEST = list(2, 9)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
/datum/component/riding/creature/wolf/get_rider_offsets_and_layers(pass_index, mob/offsetter)
return list(
TEXT_NORTH = list(1, 9, OBJ_LAYER),
TEXT_SOUTH = list(1, 9, ABOVE_MOB_LAYER),
TEXT_EAST = list(0, 9, OBJ_LAYER),
TEXT_WEST = list(2, 9, OBJ_LAYER),
)
@@ -115,13 +115,13 @@
var/mob/living/basic/mining/mook/mook_owner = owner
mook_owner.change_combatant_state(state = MOOK_ATTACK_ACTIVE)
new /obj/effect/temp_visual/mook_dust(get_turf(owner))
playsound(get_turf(owner), 'sound/items/weapons/thudswoosh.ogg', 50, TRUE)
animate(owner, pixel_y = owner.base_pixel_y + 146, time = 0.5 SECONDS)
playsound(owner, 'sound/items/weapons/thudswoosh.ogg', 50, TRUE)
animate(owner, pixel_z = 146, time = 0.5 SECONDS, flags = ANIMATION_RELATIVE)
addtimer(CALLBACK(src, PROC_REF(land_on_turf), target), 0.5 SECONDS)
/datum/action/cooldown/mob_cooldown/mook_ability/mook_jump/proc/land_on_turf(turf/target)
do_teleport(owner, target, precision = 3, no_effects = TRUE)
animate(owner, pixel_y = owner.base_pixel_y, time = 0.5 SECONDS)
animate(owner, pixel_z = -146, time = 0.5 SECONDS, flags = ANIMATION_RELATIVE)
new /obj/effect/temp_visual/mook_dust(get_turf(owner))
if(is_mook)
addtimer(CALLBACK(owner, TYPE_PROC_REF(/mob/living/basic/mining/mook, change_combatant_state), MOOK_ATTACK_NEUTRAL), 0.5 SECONDS)
@@ -104,6 +104,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
RegisterSignal(src, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_injured)) // this means we got hurt and it's go time
RegisterSignal(src, COMSIG_ANIMAL_PET, PROC_REF(on_pet))
RegisterSignal(src, COMSIG_KB_MOB_DROPITEM_DOWN, PROC_REF(drop_item_on_signal))
ADD_TRAIT(src, TRAIT_CAN_MOUNT_HUMANS, INNATE_TRAIT)
/mob/living/basic/parrot/Destroy()
// should have cleaned these up on death, but let's be super safe in case that didn't happen
@@ -264,13 +265,19 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
UnregisterSignal(src, COMSIG_LIVING_SET_BUCKLED)
toggle_perched(perched = FALSE)
#define PERCH_SOURCE "perched"
/mob/living/basic/parrot/proc/toggle_perched(perched)
if(!perched)
REMOVE_TRAIT(src, TRAIT_PARROT_PERCHED, TRAIT_GENERIC)
REMOVE_TRAIT(src, TRAIT_PARROT_PERCHED, PERCH_SOURCE)
remove_offsets(PERCH_SOURCE)
else
ADD_TRAIT(src, TRAIT_PARROT_PERCHED, TRAIT_GENERIC)
ADD_TRAIT(src, TRAIT_PARROT_PERCHED, PERCH_SOURCE)
add_offsets(PERCH_SOURCE, y_add = 9)
update_appearance(UPDATE_ICON_STATE)
#undef PERCH_SOURCE
/// Master proc which will determine the intent of OUR attacks on an object and summon the relevant procs accordingly.
/// This is pretty much meant for players, AI will use the task-specific procs instead.
/mob/living/basic/parrot/early_melee_attack(atom/target, list/modifiers, ignore_cooldown)
+17 -5
View File
@@ -62,14 +62,22 @@
return TRUE
#define FEEDING_OFFSET "feeding"
///The slime will start feeding on the target
/mob/living/basic/slime/proc/start_feeding(mob/living/target_mob)
target_mob.unbuckle_all_mobs(force=TRUE) //Slimes rip other mobs (eg: shoulder parrots) off (Slimes Vs Slimes is already handled in can_feed_on())
if(target_mob.buckle_mob(src, force=TRUE))
layer = MOB_ABOVE_PIGGYBACK_LAYER //always appear above the target mob, no matter the direction
target_mob.visible_message(span_danger("[name] latches onto [target_mob]!"), \
span_userdanger("[name] latches onto [target_mob]!"))
target_mob.unbuckle_all_mobs(force = TRUE) //Slimes rip other mobs (eg: shoulder parrots) off (Slimes Vs Slimes is already handled in can_feed_on())
if(target_mob.buckle_mob(src, force = TRUE))
add_offsets(FEEDING_OFFSET, y_add = target_mob.mob_size <= MOB_SIZE_SMALL ? 0 : 3)
layer = MOB_ABOVE_PIGGYBACK_LAYER //appear above the target mob
target_mob.apply_status_effect(/datum/status_effect/slime_leech, src)
target_mob.visible_message(
span_danger("[name] latches onto [target_mob]!"),
span_userdanger("[name] latches onto [target_mob]!"),
visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE,
)
to_chat(src, span_notice("<i>I start feeding on [target_mob]...</i>"))
balloon_alert(src, "feeding started")
else
balloon_alert(src, "latch failed!")
@@ -80,5 +88,9 @@
if(!silent)
visible_message(span_warning("[src] lets go of [buckled]!"), span_notice("You let go of [buckled]"))
balloon_alert(src, "feeding stopped")
remove_offsets(FEEDING_OFFSET)
layer = initial(layer)
buckled.unbuckle_mob(src,force=TRUE)
#undef FEEDING_OFFSET
+1 -5
View File
@@ -134,7 +134,7 @@
AddElement(/datum/element/soft_landing)
AddElement(/datum/element/swabable, CELL_LINE_TABLE_SLIME, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
add_traits(list(TRAIT_CANT_RIDE, TRAIT_VENTCRAWLER_ALWAYS), INNATE_TRAIT)
add_traits(list(TRAIT_CANT_RIDE, TRAIT_CAN_MOUNT_HUMANS, TRAIT_VENTCRAWLER_ALWAYS), INNATE_TRAIT)
RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(on_slime_pre_attack))
RegisterSignal(src, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_attack_hand) )
@@ -226,10 +226,6 @@
/mob/living/basic/slime/start_pulling(atom/movable/moveable_atom, state, force = move_force, supress_message = FALSE)
return
/mob/living/basic/slime/get_mob_buckling_height(mob/seat)
if(..() != 0)
return 3
/mob/living/basic/slime/examine(mob/user)
. = ..()
@@ -35,15 +35,11 @@
icon = alt_icon
alt_icon = old_icon
icon_state = "alien[caste]_leap"
pixel_x = base_pixel_x - 32
pixel_y = base_pixel_y - 32
else
if(alt_icon != initial(alt_icon))
var/old_icon = icon
icon = alt_icon
alt_icon = old_icon
pixel_x = base_pixel_x + body_position_pixel_x_offset
pixel_y = base_pixel_y + body_position_pixel_y_offset
update_held_items()
update_worn_handcuffs()
@@ -57,14 +57,14 @@
else //Maybe uses plasma in the future, although that wouldn't make any sense...
leaping = TRUE
//Because the leaping sprite is bigger than the normal one
body_position_pixel_x_offset = -8
add_offsets(LEAPING_TRAIT, x_add = -8, animate = FALSE)
update_icons()
ADD_TRAIT(src, TRAIT_MOVE_FLOATING, LEAPING_TRAIT) //Throwing itself doesn't protect mobs against lava (because gulag).
throw_at(A, MAX_ALIEN_LEAP_DIST, pounce_speed, src, FALSE, TRUE, callback = CALLBACK(src, PROC_REF(leap_end)))
/mob/living/carbon/alien/adult/hunter/proc/leap_end()
leaping = FALSE
body_position_pixel_x_offset = 0
remove_offsets(LEAPING_TRAIT, animate = FALSE)
REMOVE_TRAIT(src, TRAIT_MOVE_FLOATING, LEAPING_TRAIT)
update_icons()
@@ -441,9 +441,9 @@
/mob/proc/shake_up_animation()
var/direction = prob(50) ? -1 : 1
animate(src, pixel_x = pixel_x + SHAKE_ANIMATION_OFFSET * direction, time = 1, easing = QUAD_EASING | EASE_OUT, flags = ANIMATION_PARALLEL)
animate(pixel_x = pixel_x - (SHAKE_ANIMATION_OFFSET * 2 * direction), time = 1)
animate(pixel_x = pixel_x + SHAKE_ANIMATION_OFFSET * direction, time = 1, easing = QUAD_EASING | EASE_IN)
animate(src, pixel_w = SHAKE_ANIMATION_OFFSET * direction, time = 0.1 SECONDS, easing = QUAD_EASING | EASE_OUT, flags = ANIMATION_PARALLEL|ANIMATION_RELATIVE)
animate(pixel_w = SHAKE_ANIMATION_OFFSET * -2 * direction, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
animate(pixel_w = SHAKE_ANIMATION_OFFSET * direction, time = 0.1 SECONDS, easing = QUAD_EASING | EASE_IN, flags = ANIMATION_RELATIVE)
/// Check ourselves to see if we've got any shrapnel, return true if we do. This is a much simpler version of what humans do, we only indicate we're checking ourselves if there's actually shrapnel
/mob/living/carbon/proc/check_self_for_injuries()
@@ -36,6 +36,8 @@
)
AddElement(/datum/element/connect_loc, loc_connections)
GLOB.human_list += src
ADD_TRAIT(src, TRAIT_CAN_MOUNT_HUMANS, INNATE_TRAIT)
ADD_TRAIT(src, TRAIT_CAN_MOUNT_CYBORGS, INNATE_TRAIT)
/mob/living/carbon/human/proc/setup_physiology()
physiology = new()
@@ -1049,14 +1051,13 @@
return buckle_mob(target, TRUE, TRUE, RIDER_NEEDS_ARMS)
/mob/living/carbon/human/buckle_mob(mob/living/target, force = FALSE, check_loc = TRUE, buckle_mob_flags= NONE)
if(!is_type_in_typecache(target, can_ride_typecache))
/mob/living/carbon/human/is_buckle_possible(mob/living/target, force, check_loc)
if(!HAS_TRAIT(target, TRAIT_CAN_MOUNT_HUMANS))
target.visible_message(span_warning("[target] really can't seem to mount [src]..."))
return
if(!force)//humans are only meant to be ridden through piggybacking and special cases
return
return FALSE
// if you don't invoke it with forced, IE via piggyback / fireman, always fail
if(!force)
return FALSE
return ..()
/mob/living/carbon/human/reagent_check(datum/reagent/chem, seconds_per_tick, times_fired)
@@ -8,7 +8,6 @@
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPSEC_FIRST_HUD,IMPSEC_SECOND_HUD,ANTAG_HUD,GLAND_HUD,FAN_HUD,PERMIT_HUD, DNR_HUD) //SKYRAT EDIT ADDITION - PERMIT_HUD, DNR_HUD
hud_type = /datum/hud/human
pressure_resistance = 25
can_buckle = TRUE
buckle_lying = 0
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
can_be_shoved_into = TRUE
@@ -82,13 +81,6 @@
var/datum/physiology/physiology
/// What types of mobs are allowed to ride/buckle to this mob
var/static/list/can_ride_typecache = typecacheof(list(
/mob/living/basic/parrot,
/mob/living/carbon/human,
/mob/living/basic/slime,
))
var/account_id
var/hardcore_survival_score = 0
+23 -18
View File
@@ -423,11 +423,12 @@
#define SHIVER_LOOP_DURATION (1 SECONDS)
/datum/emote/living/shiver/run_emote(mob/living/user, params, type_override, intentional)
. = ..()
animate(user, pixel_x = user.pixel_x + 1, time = 0.1 SECONDS)
animate(user, pixel_w = 1, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
for(var/i in 1 to SHIVER_LOOP_DURATION / (0.2 SECONDS)) //desired total duration divided by the iteration duration to give the necessary iteration count
animate(pixel_x = user.pixel_x - 1, time = 0.1 SECONDS)
animate(pixel_x = user.pixel_x + 1, time = 0.1 SECONDS)
animate(pixel_x = user.pixel_x - 1, time = 0.1 SECONDS)
animate(pixel_w = -2, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE|ANIMATION_CONTINUE)
animate(pixel_w = 2, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE|ANIMATION_CONTINUE)
animate(pixel_w = -1, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
#undef SHIVER_LOOP_DURATION
/datum/emote/living/sigh
@@ -528,11 +529,12 @@
/datum/emote/living/sway/run_emote(mob/living/user, params, type_override, intentional)
. = ..()
animate(user, pixel_x = user.pixel_x + 2, time = 0.5 SECONDS)
animate(user, pixel_w = 2, time = 0.5 SECONDS, flags = ANIMATION_RELATIVE)
for(var/i in 1 to 2)
animate(pixel_x = user.pixel_x - 4, time = 1.0 SECONDS)
animate(pixel_x = user.pixel_x + 4, time = 1.0 SECONDS)
animate(pixel_x = user.pixel_x - 2, time = 0.5 SECONDS)
animate(pixel_w = -6, time = 1.0 SECONDS, flags = ANIMATION_RELATIVE|ANIMATION_CONTINUE)
animate(pixel_w = 6, time = 1.0 SECONDS, flags = ANIMATION_RELATIVE|ANIMATION_CONTINUE)
animate(pixel_w = -2, time = 0.5 SECONDS, flags = ANIMATION_RELATIVE)
/datum/emote/living/tilt
key = "tilt"
@@ -547,11 +549,12 @@
#define TREMBLE_LOOP_DURATION (4.4 SECONDS)
/datum/emote/living/tremble/run_emote(mob/living/user, params, type_override, intentional)
. = ..()
animate(user, pixel_x = user.pixel_x + 2, time = 0.2 SECONDS)
animate(user, pixel_w = 2, time = 0.2 SECONDS, flags = ANIMATION_RELATIVE)
for(var/i in 1 to TREMBLE_LOOP_DURATION / (0.4 SECONDS)) //desired total duration divided by the iteration duration to give the necessary iteration count
animate(pixel_x = user.pixel_x - 2, time = 0.2 SECONDS)
animate(pixel_x = user.pixel_x + 2, time = 0.2 SECONDS)
animate(pixel_x = user.pixel_x - 2, time = 0.2 SECONDS)
animate(pixel_w = -4, time = 0.2 SECONDS, flags = ANIMATION_RELATIVE|ANIMATION_CONTINUE)
animate(pixel_w = 4, time = 0.2 SECONDS, flags = ANIMATION_RELATIVE|ANIMATION_CONTINUE)
animate(pixel_w = -2, time = 0.2 SECONDS, flags = ANIMATION_RELATIVE)
#undef TREMBLE_LOOP_DURATION
/datum/emote/living/twitch
@@ -561,11 +564,12 @@
/datum/emote/living/twitch/run_emote(mob/living/user, params, type_override, intentional)
. = ..()
animate(user, pixel_x = user.pixel_x - 1, time = 0.1 SECONDS)
animate(pixel_x = user.pixel_x + 1, time = 0.1 SECONDS)
animate(user, pixel_w = 1, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
animate(pixel_w = -2, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
animate(time = 0.1 SECONDS)
animate(pixel_x = user.pixel_x - 1, time = 0.1 SECONDS)
animate(pixel_x = user.pixel_x + 1, time = 0.1 SECONDS)
animate(pixel_w = 2, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
animate(pixel_w = -1, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
/datum/emote/living/twitch_s
key = "twitch_s"
@@ -574,8 +578,9 @@
/datum/emote/living/twitch_s/run_emote(mob/living/user, params, type_override, intentional)
. = ..()
animate(user, pixel_x = user.pixel_x - 1, time = 0.1 SECONDS)
animate(pixel_x = user.pixel_x + 1, time = 0.1 SECONDS)
animate(user, pixel_w = -1, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
animate(pixel_w = 1, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
/datum/emote/living/wave
key = "wave"
+36 -26
View File
@@ -485,8 +485,15 @@
set_pull_offsets(M, state)
return TRUE
/mob/living/proc/set_pull_offsets(mob/living/M, grab_state = GRAB_PASSIVE)
if(M.buckled)
/**
* Updates the offsets of the passed mob according to the passed grab state and the direction between them and us
*
* * M - the mob to update the offsets of
* * grab_state - the state of the grab
* * animate - whether or not to animate the offsets
*/
/mob/living/proc/set_pull_offsets(mob/living/mob_to_set, grab_state = GRAB_PASSIVE, animate = TRUE)
if(mob_to_set.buckled)
return //don't make them change direction or offset them if they're buckled into something.
var/offset = 0
switch(grab_state)
@@ -498,27 +505,35 @@
offset = GRAB_PIXEL_SHIFT_NECK
if(GRAB_KILL)
offset = GRAB_PIXEL_SHIFT_NECK
M.setDir(get_dir(M, src))
var/target_pixel_x = M.base_pixel_x + M.body_position_pixel_x_offset
var/target_pixel_y = M.base_pixel_y + M.body_position_pixel_y_offset
switch(M.dir)
mob_to_set.setDir(get_dir(mob_to_set, src))
var/dir_filter = mob_to_set.dir
if(ISDIAGONALDIR(dir_filter))
dir_filter = EWCOMPONENT(dir_filter)
switch(dir_filter)
if(NORTH)
animate(M, pixel_x = target_pixel_x, pixel_y = target_pixel_y + offset, 3)
mob_to_set.add_offsets(GRABBING_TRAIT, x_add = 0, y_add = offset, animate = animate)
if(SOUTH)
animate(M, pixel_x = target_pixel_x, pixel_y = target_pixel_y - offset, 3)
mob_to_set.add_offsets(GRABBING_TRAIT, x_add = 0, y_add = -offset, animate = animate)
if(EAST)
if(M.lying_angle == LYING_ANGLE_WEST) //update the dragged dude's direction if we've turned
M.set_lying_angle(LYING_ANGLE_EAST)
animate(M, pixel_x = target_pixel_x + offset, pixel_y = target_pixel_y, 3)
if(mob_to_set.lying_angle == LYING_ANGLE_WEST) //update the dragged dude's direction if we've turned
mob_to_set.set_lying_angle(LYING_ANGLE_EAST)
mob_to_set.add_offsets(GRABBING_TRAIT, x_add = offset, y_add = 0, animate = animate)
if(WEST)
if(M.lying_angle == LYING_ANGLE_EAST)
M.set_lying_angle(LYING_ANGLE_WEST)
animate(M, pixel_x = target_pixel_x - offset, pixel_y = target_pixel_y, 3)
if(mob_to_set.lying_angle == LYING_ANGLE_EAST)
mob_to_set.set_lying_angle(LYING_ANGLE_WEST)
mob_to_set.add_offsets(GRABBING_TRAIT, x_add = -offset, y_add = 0, animate = animate)
/**
* Removes any offsets from the passed mob that are related to being grabbed
*
* * M - the mob to remove the offsets from
* * override - if TRUE, the offsets will be removed regardless of the mob's buckled state
* otherwise we won't remove the offsets if the mob is buckled
*/
/mob/living/proc/reset_pull_offsets(mob/living/M, override)
if(!override && M.buckled)
return
animate(M, pixel_x = M.base_pixel_x + M.body_position_pixel_x_offset , pixel_y = M.base_pixel_y + M.body_position_pixel_y_offset, 1)
M.remove_offsets(GRABBING_TRAIT)
//mob verbs are a lot faster than object verbs
//for more info on why this is not atom/pull, see examinate() in mob.dm
@@ -779,19 +794,14 @@
if(HAS_TRAIT(src, TRAIT_FLOORED) && !(dir & (NORTH|SOUTH)))
setDir(pick(NORTH, SOUTH)) // We are and look helpless.
if(rotate_on_lying)
body_position_pixel_y_offset = PIXEL_Y_OFFSET_LYING
add_offsets(LYING_DOWN_TRAIT, y_add = PIXEL_Y_OFFSET_LYING)
/// Proc to append behavior related to lying down.
/mob/living/proc/on_standing_up()
if(layer == LYING_MOB_LAYER)
layer = initial(layer)
remove_traits(list(TRAIT_UI_BLOCKED, TRAIT_PULL_BLOCKED, TRAIT_UNDENSE), LYING_DOWN_TRAIT)
// Make sure it doesn't go out of the southern bounds of the tile when standing.
body_position_pixel_y_offset = get_pixel_y_offset_standing(current_size)
/// Returns what the body_position_pixel_y_offset should be if the current size were `value`
/mob/living/proc/get_pixel_y_offset_standing(value)
return (value-1) * get_cached_height() * 0.5
remove_offsets(LYING_DOWN_TRAIT)
/mob/living/proc/update_density()
if(HAS_TRAIT(src, TRAIT_UNDENSE))
@@ -1373,8 +1383,8 @@
var/matrix/flipped_matrix = transform
flipped_matrix.b = -flipped_matrix.b
flipped_matrix.e = -flipped_matrix.e
animate(src, transform = flipped_matrix, pixel_y = pixel_y+4, time = 0.5 SECONDS, easing = EASE_OUT)
base_pixel_y += 4
animate(src, transform = flipped_matrix, time = 0.5 SECONDS, easing = EASE_OUT, flags = ANIMATION_PARALLEL)
add_offsets(NEGATIVE_GRAVITY_TRAIT, y_add = 4)
if(NEGATIVE_GRAVITY + 0.01 to 0)
if(!istype(gravity_alert, /atom/movable/screen/alert/weightless))
throw_alert(ALERT_GRAVITY, /atom/movable/screen/alert/weightless)
@@ -1398,8 +1408,8 @@
var/matrix/flipped_matrix = transform
flipped_matrix.b = -flipped_matrix.b
flipped_matrix.e = -flipped_matrix.e
animate(src, transform = flipped_matrix, pixel_y = pixel_y-4, time = 0.5 SECONDS, easing = EASE_OUT)
base_pixel_y -= 4
animate(src, transform = flipped_matrix, time = 0.5 SECONDS, easing = EASE_OUT, flags = ANIMATION_PARALLEL)
remove_offsets(NEGATIVE_GRAVITY_TRAIT)
/mob/living/singularity_pull(atom/singularity, current_size)
..()
+1 -1
View File
@@ -381,7 +381,7 @@
to_chat(user, span_danger("You're strangling [src]!"))
if(!buckled && !density)
Move(user.loc)
user.set_pull_offsets(src, grab_state)
user.set_pull_offsets(src, user.grab_state)
return TRUE
/mob/living/attack_animal(mob/living/simple_animal/user, list/modifiers)
+5 -4
View File
@@ -204,10 +204,6 @@
/// Is this mob allowed to be buckled/unbuckled to/from things?
var/can_buckle_to = TRUE
///The x amount a mob's sprite should be offset due to the current position they're in
var/body_position_pixel_x_offset = 0
///The y amount a mob's sprite should be offset due to the current position they're in or size (e.g. lying down moves your sprite down)
var/body_position_pixel_y_offset = 0
///The height offset of a mob's maptext due to their current size.
var/body_maptext_height_offset = 0
@@ -233,3 +229,8 @@
/// How long it takes to return to 0 stam
var/stamina_regen_time = 10 SECONDS
/// Lazylists of pixel offsets this mob is currently using
/// Modify this via add_offsets and remove_offsets,
/// NOT directly (and definitely avoid modifying offsets directly)
VAR_PRIVATE/list/offsets
+145 -39
View File
@@ -3,70 +3,176 @@
* IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can.
*/
/mob/living/proc/update_transform(resize = RESIZE_DEFAULT_SIZE)
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
var/final_pixel_y = base_pixel_y + body_position_pixel_y_offset
/**
* pixel x/y/w/z all discard values after the decimal separator.
* That, coupled with the rendered interpolation, may make the
* icons look awfuller than they already are, or not, whatever.
* The solution to this nit is translating the missing decimals.
* also flooring increases the distance from 0 for negative numbers.
*/
var/abs_pixel_y_offset = 0
var/translate = 0
if(current_size != RESIZE_DEFAULT_SIZE)
var/standing_offset = get_pixel_y_offset_standing(current_size)
abs_pixel_y_offset = abs(standing_offset)
translate = (abs_pixel_y_offset - round(abs_pixel_y_offset)) * SIGN(standing_offset)
var/matrix/ntransform = matrix(transform)
var/current_translate = get_transform_translation_size(current_size)
var/final_dir = dir
var/changed = FALSE
if(lying_angle != lying_prev && rotate_on_lying)
changed = TRUE
if(lying_angle && lying_prev == 0)
if(translate)
ntransform.Translate(0, -translate)
if(dir & (EAST|WEST)) //Standing to lying and facing east or west
final_dir = pick(NORTH, SOUTH) //So you fall on your side rather than your face or ass
else if(translate && !lying_angle && lying_prev != 0)
ntransform.Translate(translate * (lying_prev == 270 ? -1 : 1), 0)
///Done last, as it can mess with the translation.
if(current_translate)
ntransform.Translate(0, -current_translate)
// Standing to lying and facing east or west
if(dir & (EAST|WEST))
// ...So you fall on your side, rather than your face or ass
final_dir = pick(NORTH, SOUTH)
else
if(current_translate && !lying_angle && lying_prev != 0)
ntransform.Translate(current_translate * (lying_prev == 270 ? -1 : 1), 0)
// Done last, as it can mess with the translation.
ntransform.TurnTo(lying_prev, lying_angle)
if(resize != RESIZE_DEFAULT_SIZE)
changed = TRUE
var/is_vertical = !lying_angle || !rotate_on_lying
///scaling also affects translation, so we've to undo the old translate beforehand.
if(translate && is_vertical)
ntransform.Translate(0, -translate)
var/new_translation = get_transform_translation_size(resize * current_size)
// scaling also affects translation, so we've to undo the old translate beforehand.
if(is_vertical && current_translate)
ntransform.Translate(0, -current_translate)
ntransform.Scale(resize)
current_size *= resize
//Update the height of the maptext according to the size of the mob so they don't overlap.
// Update the height of the maptext according to the size of the mob so they don't overlap.
var/old_maptext_offset = body_maptext_height_offset
body_maptext_height_offset = initial(maptext_height) * (current_size - 1) * 0.5
maptext_height += body_maptext_height_offset - old_maptext_offset
//Update final_pixel_y so our mob doesn't go out of the southern bounds of the tile when standing
if(is_vertical) //But not if the mob has been rotated.
//Make sure the body position y offset is also updated
body_position_pixel_y_offset = get_pixel_y_offset_standing(current_size)
abs_pixel_y_offset = abs(body_position_pixel_y_offset)
var/new_translate = (abs_pixel_y_offset - round(abs_pixel_y_offset)) * SIGN(body_position_pixel_y_offset)
if(new_translate)
ntransform.Translate(0, new_translate)
final_pixel_y = base_pixel_y + body_position_pixel_y_offset
// and update the new translation
if(is_vertical && new_translation)
ntransform.Translate(0, new_translation)
if(!changed) //Nothing has been changed, nothing has to be done.
return
return FALSE
ADD_TRAIT(src, TRAIT_NO_FLOATING_ANIM, UPDATE_TRANSFORM_TRAIT)
addtimer(TRAIT_CALLBACK_REMOVE(src, TRAIT_NO_FLOATING_ANIM, UPDATE_TRANSFORM_TRAIT), 0.3 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE)
// ensures the floating animation doesn't mess with our animation
if(HAS_TRAIT(src, TRAIT_MOVE_FLOATING))
ADD_TRAIT(src, TRAIT_NO_FLOATING_ANIM, UPDATE_TRANSFORM_TRAIT)
addtimer(TRAIT_CALLBACK_REMOVE(src, TRAIT_NO_FLOATING_ANIM, UPDATE_TRANSFORM_TRAIT), 0.3 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE)
//if true, we want to avoid any animation time, it'll tween and not rotate at all otherwise.
var/is_opposite_angle = REVERSE_ANGLE(lying_angle) == lying_prev
var/animate_time = is_opposite_angle ? 0 : UPDATE_TRANSFORM_ANIMATION_TIME
animate(src, transform = ntransform, time = animate_time, pixel_y = final_pixel_y, dir = final_dir, easing = (EASE_IN|EASE_OUT))
animate(src, transform = ntransform, time = animate_time, dir = final_dir, easing = (EASE_IN|EASE_OUT))
for (var/hud_key in hud_list)
var/image/hud_image = hud_list[hud_key]
if (istype(hud_image))
adjust_hud_position(hud_image, animate_time = animate_time)
SEND_SIGNAL(src, COMSIG_LIVING_POST_UPDATE_TRANSFORM, resize, lying_angle, is_opposite_angle)
return TRUE
/// Calculates how far vertically the mob's transform should translate according to its size (1 being "default")
/mob/living/proc/get_transform_translation_size(value)
return (value - 1) * 16
/**
* Adds an offset to the mob's pixel position.
*
* * source: The source of the offset, a string
* * w_add: pixel_w offset
* * x_add: pixel_x offset
* * y_add: pixel_y offset
* * z_add: pixel_z offset
* * animate: If TRUE, the mob will animate to the new position. If FALSE, it will instantly move.
*/
/mob/living/proc/add_offsets(source, w_add, x_add, y_add, z_add, animate = TRUE)
LAZYINITLIST(offsets)
if(isnum(w_add))
LAZYSET(offsets[PIXEL_W_OFFSET], source, w_add)
if(isnum(x_add))
LAZYSET(offsets[PIXEL_X_OFFSET], source, x_add)
if(isnum(y_add))
LAZYSET(offsets[PIXEL_Y_OFFSET], source, y_add)
if(isnum(z_add))
LAZYSET(offsets[PIXEL_Z_OFFSET], source, z_add)
update_offsets(animate)
/**
* Goes through all pixel adjustments and removes any tied to the passed source.
*
* * source: The source of the offset to remove
* * animate: If TRUE, the mob will animate to the position with any offsets removed. If FALSE, it will instantly move.
*/
/mob/living/proc/remove_offsets(source, animate = TRUE)
for(var/offset in offsets)
LAZYREMOVE(offsets[offset], source)
ASSOC_UNSETEMPTY(offsets, offset)
UNSETEMPTY(offsets)
update_offsets(animate)
/**
* Updates the mob's pixel position according to the offsets.
*
* * animate: If TRUE, the mob will animate to the new position. If FALSE, it will instantly move.
*
* Returns TRUE if the mob's position has changed, FALSE otherwise.
*/
/mob/living/proc/update_offsets(animate = FALSE)
var/new_w = base_pixel_w
var/new_x = base_pixel_x
var/new_y = base_pixel_y
var/new_z = base_pixel_z
for(var/offset_key in LAZYACCESS(offsets, PIXEL_W_OFFSET))
new_w += offsets[PIXEL_W_OFFSET][offset_key]
for(var/offset_key in LAZYACCESS(offsets, PIXEL_X_OFFSET))
new_x += offsets[PIXEL_X_OFFSET][offset_key]
for(var/offset_key in LAZYACCESS(offsets, PIXEL_Y_OFFSET))
new_y += offsets[PIXEL_Y_OFFSET][offset_key]
for(var/offset_key in LAZYACCESS(offsets, PIXEL_Z_OFFSET))
new_z += offsets[PIXEL_Z_OFFSET][offset_key]
if(new_w == pixel_w && new_x == pixel_x && new_y == pixel_y && new_z == pixel_z)
return FALSE
if(!animate)
pixel_w = new_w
pixel_x = new_x
pixel_y = new_y
pixel_z = new_z
return TRUE
// ensures the floating animation doesn't mess with our animation
if(HAS_TRAIT(src, TRAIT_MOVE_FLOATING))
ADD_TRAIT(src, TRAIT_NO_FLOATING_ANIM, UPDATE_OFFSET_TRAIT)
addtimer(TRAIT_CALLBACK_REMOVE(src, TRAIT_NO_FLOATING_ANIM, UPDATE_OFFSET_TRAIT), 0.3 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE)
animate(src,
pixel_w = new_w,
pixel_x = new_x,
pixel_y = new_y,
pixel_z = new_z,
easing = (EASE_IN|EASE_OUT),
flags = ANIMATION_PARALLEL,
time = UPDATE_TRANSFORM_ANIMATION_TIME,
)
return TRUE
/**
* Checks if we are offset by the passed source for the passed pixel.
*
* * source: The source of the offset
* * pixel: Optional, The pixel to check.
* If not supplied, just reports if it's offset by the source at all (returning the first offset found).
*
* Returns the offset if we are, 0 otherwise.
*/
/mob/living/proc/has_offset(source, pixel)
if(isnull(pixel))
for(var/found_pixel in offsets)
var/pixel_source = has_offset(source, found_pixel)
if(pixel_source)
return pixel_source
return 0
return offsets?[pixel]?[source] || 0
// Updates offsets if base pixel changes
// Future TODO: move base pixel onto /obj and make mobs just set a base pixel using a source
/mob/living/set_base_pixel_x(new_value)
. = ..()
update_offsets()
/mob/living/set_base_pixel_y(new_value)
. = ..()
update_offsets()
+12 -10
View File
@@ -970,18 +970,20 @@
if(can_buckle && isliving(user) && isliving(M) && !(M in buckled_mobs) && ((user != src) || (!combat_mode)))
return user_buckle_mob(M, user, check_loc = FALSE)
/mob/living/silicon/robot/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE, buckle_mob_flags= RIDER_NEEDS_ARM)
if(!is_type_in_typecache(M, can_ride_typecache))
M.visible_message(span_warning("[M] really can't seem to mount [src]..."))
return
if(stat || incapacitated)
return
/mob/living/silicon/robot/is_buckle_possible(mob/living/target, force, check_loc)
if(incapacitated)
return FALSE
if(!HAS_TRAIT(target, TRAIT_CAN_MOUNT_CYBORGS))
target.visible_message(span_warning("[target] really can't seem to mount [src]..."))
return FALSE
if(model && !model.allow_riding)
M.visible_message(span_boldwarning("Unfortunately, [M] just can't seem to hold onto [src]!"))
return
target.visible_message(span_boldwarning("Unfortunately, [target] just can't seem to hold onto [src]!"))
return FALSE
buckle_mob_flags= RIDER_NEEDS_ARM // just in case
return ..()
/mob/living/silicon/robot/buckle_mob(mob/living/M, force, check_loc, buckle_mob_flags)
buckle_mob_flags = RIDER_NEEDS_ARM // just in case
return ..()
/mob/living/silicon/robot/post_buckle_mob(mob/living/victim_to_boot)
@@ -142,8 +142,6 @@
var/obj/item/hat
var/hat_offset = list("north" = list(0, -3), "south" = list(0, -3), "east" = list(4, -3), "west" = list(-4, -3))
///What types of mobs are allowed to ride/buckle to this mob
var/static/list/can_ride_typecache = typecacheof(/mob/living/carbon/human)
can_buckle = TRUE
buckle_lying = FALSE
@@ -46,11 +46,11 @@
///Whether the borg can stuff itself into disposals
var/canDispose = FALSE
///The pixel offset of the hat. List of "north" "south" "east" "west" x, y offsets
var/hat_offset = list("north" = list(0, -3), "south" = list(0, -3), "east" = list(4, -3), "west" = list(-4, -3))
///The x offsets of a person riding the borg
var/list/ride_offset_x = list("north" = 0, "south" = 0, "east" = -6, "west" = 6)
///The y offsets of a person riding the borg
var/list/ride_offset_y = list("north" = 4, "south" = 4, "east" = 3, "west" = 3)
var/list/hat_offset = list("north" = list(0, -3), "south" = list(0, -3), "east" = list(4, -3), "west" = list(-4, -3))
///The offsets of a person riding the borg of this model.
/// Format like list("north" = list(x, y, layer), ...)
/// Leave null to use defaults
var/list/ride_offsets
///List of skins the borg can be reskinned to, optional
var/list/borg_skins
@@ -548,17 +548,17 @@
// Start the sound. it'll just last the 4 seconds it takes for us to rev up
wash_audio.start()
// We're just gonna shake the borg a bit. Not a ton, but just enough that it feels like the audio makes sense
var/base_x = robot_owner.base_pixel_x
var/base_y = robot_owner.base_pixel_y
animate(robot_owner, pixel_x = base_x, pixel_y = base_y, time = 1, loop = -1)
var/base_w = robot_owner.base_pixel_w
var/base_z = robot_owner.base_pixel_z
animate(robot_owner, pixel_w = base_w, pixel_z = base_z, time = 0.1 SECONDS, loop = -1)
for(var/i in 1 to 17) //Startup rumble
var/x_offset = base_x + rand(-1, 1)
var/y_offset = base_y + rand(-1, 1)
animate(pixel_x = x_offset, pixel_y = y_offset, time = 1)
var/w_offset = base_w + rand(-1, 1)
var/z_offset = base_z + rand(-1, 1)
animate(pixel_w = w_offset, pixel_z = z_offset, time = 0.1 SECONDS)
if(!do_after(robot_owner, 4 SECONDS, interaction_key = "auto_wash_toggle", extra_checks = allow_buffer_activate))
wash_audio.stop() // Coward
animate(robot_owner, pixel_x = base_x, pixel_y = base_y, time = 1)
animate(robot_owner, pixel_w = base_w, pixel_z = base_z, time = 0.1 SECONDS)
return FALSE
else
if(!COOLDOWN_FINISHED(src, toggle_cooldown))
@@ -583,16 +583,16 @@
robot_owner.add_movespeed_modifier(/datum/movespeed_modifier/auto_wash)
RegisterSignal(robot_owner, COMSIG_MOVABLE_MOVED, PROC_REF(clean))
//This is basically just about adding a shake to the borg, effect should look ilke an engine's running
var/base_x = robot_owner.base_pixel_x
var/base_y = robot_owner.base_pixel_y
robot_owner.pixel_x = base_x + rand(-7, 7)
robot_owner.pixel_y = base_y + rand(-7, 7)
var/base_w = robot_owner.base_pixel_w
var/base_z = robot_owner.base_pixel_z
robot_owner.pixel_w = base_w + rand(-7, 7)
robot_owner.pixel_z = base_z + rand(-7, 7)
//Larger shake with more changes to start out, feels like "Revving"
animate(robot_owner, pixel_x = base_x, pixel_y = base_y, time = 1, loop = -1)
animate(robot_owner, pixel_w = base_w, pixel_z = base_z, time = 0.1 SECONDS, loop = -1)
for(var/i in 1 to 100)
var/x_offset = base_x + rand(-2, 2)
var/y_offset = base_y + rand(-2, 2)
animate(pixel_x = x_offset, pixel_y = y_offset, time = 1)
var/w_offset = base_w + rand(-2, 2)
var/z_offset = base_z + rand(-2, 2)
animate(pixel_w = w_offset, pixel_z = z_offset, time = 0.1 SECONDS)
if(!wash_audio.is_active())
wash_audio.start()
clean()
@@ -608,15 +608,15 @@
// Diable the cleaning, we're revving down
UnregisterSignal(robot_owner, COMSIG_MOVABLE_MOVED)
// Do the rumble animation till we're all finished
var/base_x = robot_owner.base_pixel_x
var/base_y = robot_owner.base_pixel_y
animate(robot_owner, pixel_x = base_x, pixel_y = base_y, time = 1)
var/base_w = robot_owner.base_pixel_w
var/base_z = robot_owner.base_pixel_z
animate(robot_owner, pixel_w = base_w, pixel_z = base_z, time = 0.1 SECONDS)
for(var/i in 1 to finished_by - 0.1 SECONDS) //We rumble until we're finished making noise
var/x_offset = base_x + rand(-1, 1)
var/y_offset = base_y + rand(-1, 1)
animate(pixel_x = x_offset, pixel_y = y_offset, time = 1)
var/w_offset = base_w + rand(-1, 1)
var/z_offset = base_z + rand(-1, 1)
animate(pixel_w = w_offset, pixel_z = z_offset, time = 0.1 SECONDS)
// Reset our animations
animate(pixel_x = base_x, pixel_y = base_y, time = 2)
animate(pixel_w = base_w, pixel_z = base_z, time = 0.2 SECONDS)
addtimer(CALLBACK(wash_audio, TYPE_PROC_REF(/datum/looping_sound, stop)), time_left)
addtimer(CALLBACK(src, PROC_REF(turn_off_wash)), finished_by)
@@ -140,12 +140,12 @@ Difficulty: Extremely Hard
adjustHealth(-maxHealth)
enraged = TRUE
enraging = TRUE
animate(src, pixel_y = pixel_y + 96, time = 100, easing = ELASTIC_EASING)
animate(src, pixel_z = 96, time = 100, easing = ELASTIC_EASING, flags = ANIMATION_RELATIVE)
spin(100, 10)
SLEEP_CHECK_DEATH(60, src)
playsound(src, 'sound/effects/explosion/explosion3.ogg', 100, TRUE)
icon_state = "demonic_miner_phase2"
animate(src, pixel_y = pixel_y - 96, time = 8, flags = ANIMATION_END_NOW)
animate(src, pixel_z = -96, time = 8, flags = ANIMATION_END_NOW, flags = ANIMATION_RELATIVE)
spin(8, 2)
for(var/obj/structure/frost_miner_prism/prism_to_set in GLOB.frost_miner_prisms)
prism_to_set.set_prism_light(LIGHT_COLOR_PURPLE, 5)
-19
View File
@@ -1071,25 +1071,6 @@
return FALSE
return ..(M, force, check_loc, buckle_mob_flags)
///Call back post buckle to a mob to offset your visual height
/mob/post_buckle_mob(mob/living/M)
var/height = M.get_mob_buckling_height(src)
M.pixel_y = initial(M.pixel_y) + height
if(M.layer <= layer) //make sure they stay above our current layer
M.layer = layer + 0.1
///Call back post unbuckle from a mob, (reset your visual height here)
/mob/post_unbuckle_mob(mob/living/M)
M.layer = initial(M.layer)
M.pixel_y = initial(M.pixel_y)
///returns the height in pixel the mob should have when buckled to another mob.
/mob/proc/get_mob_buckling_height(mob/seat)
if(isliving(seat))
var/mob/living/L = seat
if(L.mob_size <= MOB_SIZE_SMALL) //being on top of a small mob doesn't put you very high.
return 0
return 9
///Can the mob interact() with an atom?
/mob/proc/can_interact_with(atom/A, treat_mob_as_adjacent)
if(isAdminGhostAI(src))
+2 -4
View File
@@ -493,8 +493,7 @@
mod.wearer.add_filter("mod_ball", 1, alpha_mask_filter(icon = icon('icons/mob/clothing/modsuit/mod_modules.dmi', "ball_mask"), flags = MASK_INVERSE))
mod.wearer.add_filter("mod_blur", 2, angular_blur_filter(size = 15))
mod.wearer.add_filter("mod_outline", 3, outline_filter(color = "#000000AA"))
mod.wearer.base_pixel_y -= 4
animate(mod.wearer, animate_time, pixel_y = mod.wearer.base_pixel_y, flags = ANIMATION_PARALLEL)
mod.wearer.add_offsets(REF(src), y_add = -4)
mod.wearer.SpinAnimation(1.5)
mod.wearer.add_traits(user_traits, REF(src))
mod.wearer.RemoveElement(/datum/element/footstep, FOOTSTEP_MOB_HUMAN, 1, -6)
@@ -506,8 +505,7 @@
/obj/item/mod/module/sphere_transform/on_deactivation(display_message = TRUE, deleting = FALSE)
if(!deleting)
playsound(src, 'sound/items/modsuit/ballin.ogg', 100, TRUE, frequency = -1)
mod.wearer.base_pixel_y += 4
animate(mod.wearer, animate_time, pixel_y = mod.wearer.base_pixel_y)
mod.wearer.remove_offsets(REF(src))
addtimer(CALLBACK(mod.wearer, TYPE_PROC_REF(/datum, remove_filter), list("mod_ball", "mod_blur", "mod_outline")), animate_time)
mod.wearer.remove_traits(user_traits, REF(src))
mod.wearer.remove_movespeed_mod_immunities(REF(src), /datum/movespeed_modifier/damage_slowdown)
+9 -5
View File
@@ -357,8 +357,10 @@
else
vehicle.obj_flags &= ~BLOCK_Z_OUT_DOWN
rider.spin(spintime = 4, speed = 1)
animate(rider, pixel_y = -6, time = 4)
animate(vehicle, pixel_y = -6, time = 3)
animate(rider, pixel_z = 6, time = 0.4 SECONDS, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(pixel_z = -6, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
animate(vehicle, pixel_z = 6, time = 0.3 SECONDS, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(pixel_z = -6, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
playsound(vehicle, 'sound/vehicles/skateboard_ollie.ogg', 50, TRUE)
passtable_on(rider, VEHICLE_TRAIT)
passtable_on(vehicle, VEHICLE_TRAIT)
@@ -401,10 +403,12 @@
)
playsound(board, 'sound/vehicles/skateboard_ollie.ogg', 50, vary = TRUE)
rider.spin(spintime = 4, speed = 1)
animate(rider, pixel_y = -6, time = 0.4 SECONDS)
animate(board, pixel_y = -6, time = 0.3 SECONDS)
animate(rider, pixel_z = 6, time = 0.4 SECONDS, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(pixel_z = -6, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
animate(board, pixel_z = 6, time = 0.3 SECONDS, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(pixel_z = -6, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
board.unbuckle_mob(rider)
addtimer(CALLBACK(board, TYPE_PROC_REF(/obj/vehicle/ridden/scooter/skateboard, pick_up_board), rider), 1 SECONDS) // so the board can still handle "picking it up"
addtimer(CALLBACK(board, TYPE_PROC_REF(/obj/vehicle/ridden/scooter/skateboard, pick_up_board), rider), 0.5 SECONDS) // so the board can still handle "picking it up"