[REFACTOR] Pixel Shift Component (#22564)

* Pixel Shift - Move to Component

* oops return ais

* more refactor

* update authors

* remove more unused signals!

* one more little refactor

* update override and readme

* update dme

* move addcomponent to login

* review

* more review fixes

* more changes, now qdels on unpixel_shift

* remove unnecessary

* update readme

* return signal

* update documentation?

---------

Co-authored-by: Bloop <vinylspiders@gmail.com>
This commit is contained in:
larentoun
2023-08-05 14:56:24 -04:00
committed by GitHub
co-authored by Bloop
parent 47ee662f91
commit 3eb53be29e
13 changed files with 168 additions and 113 deletions
@@ -1,97 +0,0 @@
#define MAXIMUM_PIXEL_SHIFT 16
#define PASSABLE_SHIFT_THRESHOLD 8
/mob
/// Whether the mob is pixel shifted or not
var/is_shifted = FALSE
/// If we are in the shifting setting.
var/shifting = FALSE
/// Takes the four cardinal direction defines. Any atoms moving into this atom's tile will be allowed to from the added directions.
var/passthroughable = NONE
/datum/keybinding/mob/pixel_shift
hotkey_keys = list("B")
name = "pixel_shift"
full_name = "Pixel Shift"
description = "Shift your characters offset."
category = CATEGORY_MOVEMENT
keybind_signal = COMSIG_KB_MOB_PIXELSHIFT
/datum/keybinding/mob/pixel_shift/down(client/user)
. = ..()
if(.)
return
var/mob/M = user.mob
M.shifting = TRUE
return TRUE
/datum/keybinding/mob/pixel_shift/up(client/user)
. = ..()
if(.)
return
var/mob/M = user.mob
M.shifting = FALSE
return TRUE
/mob/proc/unpixel_shift()
return
/mob/living/unpixel_shift()
. = ..()
passthroughable = NONE
if(is_shifted)
is_shifted = FALSE
pixel_x = body_position_pixel_x_offset + base_pixel_x
pixel_y = body_position_pixel_y_offset + base_pixel_y
/mob/proc/pixel_shift(direction)
return
/mob/living/set_pull_offsets(mob/living/pull_target, grab_state)
pull_target.unpixel_shift()
return ..()
/mob/living/reset_pull_offsets(mob/living/pull_target, override)
pull_target.unpixel_shift()
return ..()
/mob/living/pixel_shift(direction)
passthroughable = NONE
switch(direction)
if(NORTH)
if(pixel_y <= MAXIMUM_PIXEL_SHIFT + base_pixel_y)
pixel_y++
is_shifted = TRUE
if(EAST)
if(pixel_x <= MAXIMUM_PIXEL_SHIFT + base_pixel_x)
pixel_x++
is_shifted = TRUE
if(SOUTH)
if(pixel_y >= -MAXIMUM_PIXEL_SHIFT + base_pixel_y)
pixel_y--
is_shifted = TRUE
if(WEST)
if(pixel_x >= -MAXIMUM_PIXEL_SHIFT + base_pixel_x)
pixel_x--
is_shifted = TRUE
// Yes, I know this sets it to true for everything if more than one is matched.
// Movement doesn't check diagonals, and instead just checks EAST or WEST, depending on where you are for those.
if(pixel_y > PASSABLE_SHIFT_THRESHOLD)
passthroughable |= EAST | SOUTH | WEST
if(pixel_x > PASSABLE_SHIFT_THRESHOLD)
passthroughable |= NORTH | SOUTH | WEST
if(pixel_y < -PASSABLE_SHIFT_THRESHOLD)
passthroughable |= NORTH | EAST | WEST
if(pixel_x < -PASSABLE_SHIFT_THRESHOLD)
passthroughable |= NORTH | EAST | SOUTH
/mob/living/CanAllowThrough(atom/movable/mover, border_dir)
// Make sure to not allow projectiles of any kind past where they normally wouldn't.
if(!istype(mover, /obj/projectile) && !mover.throwing && passthroughable & border_dir)
return TRUE
return ..()
#undef MAXIMUM_PIXEL_SHIFT
#undef PASSABLE_SHIFT_THRESHOLD
@@ -0,0 +1,100 @@
/datum/component/pixel_shift
dupe_mode = COMPONENT_DUPE_UNIQUE
/// Whether the mob is pixel shifted or not
var/is_shifted = FALSE
/// If we are in the shifting setting.
var/shifting = TRUE
/// Takes the four cardinal direction defines. Any atoms moving into this atom's tile will be allowed to from the added directions.
var/passthroughable = NONE
/// The maximum amount of pixels allowed to move in the turf.
var/maximum_pixel_shift = 16
/// The amount of pixel shift required to make the parent passthroughable.
var/passable_shift_threshold = 8
/datum/component/pixel_shift/Initialize(...)
. = ..()
if(!isliving(parent))
return COMPONENT_INCOMPATIBLE
/datum/component/pixel_shift/RegisterWithParent()
RegisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_DOWN, PROC_REF(pixel_shift_down))
RegisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_UP, PROC_REF(pixel_shift_up))
RegisterSignals(parent, list(COMSIG_LIVING_RESET_PULL_OFFSETS, COMSIG_LIVING_SET_PULL_OFFSET, COMSIG_MOVABLE_MOVED), PROC_REF(unpixel_shift))
RegisterSignal(parent, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, PROC_REF(pre_move_check))
RegisterSignal(parent, COMSIG_LIVING_CAN_ALLOW_THROUGH, PROC_REF(check_passable))
/datum/component/pixel_shift/UnregisterFromParent()
UnregisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_DOWN)
UnregisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_UP)
UnregisterSignal(parent, COMSIG_LIVING_RESET_PULL_OFFSETS)
UnregisterSignal(parent, COMSIG_LIVING_SET_PULL_OFFSET)
UnregisterSignal(parent, COMSIG_MOVABLE_MOVED)
UnregisterSignal(parent, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE)
UnregisterSignal(parent, COMSIG_LIVING_CAN_ALLOW_THROUGH)
/// Overrides Move to Pixel Shift.
/datum/component/pixel_shift/proc/pre_move_check(mob/source, new_loc, direct)
SIGNAL_HANDLER
if(shifting)
pixel_shift(source, direct)
return COMSIG_MOB_CLIENT_BLOCK_PRE_LIVING_MOVE
/// Checks if the parent is considered passthroughable from a direction. Projectiles will ignore the check and hit.
/datum/component/pixel_shift/proc/check_passable(mob/source, atom/movable/mover, border_dir)
SIGNAL_HANDLER
if(!isprojectile(mover) && !mover.throwing && passthroughable & border_dir)
return COMPONENT_LIVING_PASSABLE
/// Activates Pixel Shift on Keybind down. Only Pixel Shift movement will be allowed.
/datum/component/pixel_shift/proc/pixel_shift_down()
SIGNAL_HANDLER
shifting = TRUE
return COMSIG_KB_ACTIVATED
/// Disables Pixel Shift on Keybind up. Allows to Move.
/datum/component/pixel_shift/proc/pixel_shift_up()
SIGNAL_HANDLER
shifting = FALSE
/// Sets parent pixel offsets to default and deletes the component.
/datum/component/pixel_shift/proc/unpixel_shift()
SIGNAL_HANDLER
passthroughable = NONE
if(is_shifted)
var/mob/living/owner = parent
owner.pixel_x = owner.body_position_pixel_x_offset + owner.base_pixel_x
owner.pixel_y = owner.body_position_pixel_y_offset + owner.base_pixel_y
qdel(src)
/// In-turf pixel movement which can allow things to pass through if the threshold is met.
/datum/component/pixel_shift/proc/pixel_shift(mob/source, direct)
passthroughable = NONE
var/mob/living/owner = parent
switch(direct)
if(NORTH)
if(owner.pixel_y <= maximum_pixel_shift + owner.base_pixel_y)
owner.pixel_y++
is_shifted = TRUE
if(EAST)
if(owner.pixel_x <= maximum_pixel_shift + owner.base_pixel_x)
owner.pixel_x++
is_shifted = TRUE
if(SOUTH)
if(owner.pixel_y >= -maximum_pixel_shift + owner.base_pixel_y)
owner.pixel_y--
is_shifted = TRUE
if(WEST)
if(owner.pixel_x >= -maximum_pixel_shift + owner.base_pixel_x)
owner.pixel_x--
is_shifted = TRUE
// Yes, I know this sets it to true for everything if more than one is matched.
// Movement doesn't check diagonals, and instead just checks EAST or WEST, depending on where you are for those.
if(owner.pixel_y > passable_shift_threshold)
passthroughable |= EAST | SOUTH | WEST
else if(owner.pixel_y < -passable_shift_threshold)
passthroughable |= NORTH | EAST | WEST
if(owner.pixel_x > passable_shift_threshold)
passthroughable |= NORTH | SOUTH | WEST
else if(owner.pixel_x < -passable_shift_threshold)
passthroughable |= NORTH | EAST | SOUTH
@@ -0,0 +1,17 @@
/datum/keybinding/mob/pixel_shift
hotkey_keys = list("B")
name = "pixel_shift"
full_name = "Pixel Shift"
description = "Shift your characters offset."
category = CATEGORY_MOVEMENT
keybind_signal = COMSIG_KB_MOB_PIXEL_SHIFT_DOWN
/datum/keybinding/mob/pixel_shift/down(client/user)
. = ..()
if(.)
return
user.mob.add_pixel_shift_component()
/datum/keybinding/mob/pixel_shift/up(client/user)
. = ..()
SEND_SIGNAL(user.mob, COMSIG_KB_MOB_PIXEL_SHIFT_UP)
@@ -0,0 +1,6 @@
/// Adds pixel_shift component on call. Default proc does nothing.
/mob/proc/add_pixel_shift_component()
return
/mob/living/add_pixel_shift_component()
AddComponent(/datum/component/pixel_shift)