Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BOUNTY] [PORT] Nova's pixelshieft #2801

Closed
wants to merge 13 commits into from
4 changes: 3 additions & 1 deletion code/__DEFINES/keybinding.dm
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@
#define COMSIG_KB_MOB_TARGETLEFTLEG_DOWN "keybinding_mob_targetleftleg_down"
#define COMSIG_KB_MOB_BLOCKMOVEMENT_DOWN "keybinding_mob_blockmovement_down"
#define COMSIG_KB_MOB_SHOW_NAMES_DOWN "keybinding_mob_show_names_down"

#define COMSIG_KB_MOB_PIXELSHIFT "keybinding_mob_pixelshift"
#define COMSIG_KB_MOB_PIXEL_SHIFT_DOWN "keybinding_mob_pixelshift_down"
#define COMSIG_KB_MOB_PIXEL_SHIFT_UP "keybinding_mob_pixelshift_up"
//Robot
#define COMSIG_KB_SILICON_TOGGLEMODULEONE_DOWN "keybinding_silicon_togglemoduleone_down"
#define COMSIG_KB_SILICON_TOGGLEMODULETWO_DOWN "keybinding_silicon_togglemoduletwo_down"
Expand Down
9 changes: 9 additions & 0 deletions code/__DEFINES/living.dm
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
// living_flags
/// Simple mob trait, indicating it may follow continuous move actions controlled by code instead of by user input.
#define MOVES_ON_ITS_OWN (1<<0)

///from base of living/set_pull_offset(): (mob/living/pull_target, grab_state)
#define COMSIG_LIVING_SET_PULL_OFFSET "living_set_pull_offset"
///from base of living/reset_pull_offsets(): (mob/living/pull_target, override)
#define COMSIG_LIVING_RESET_PULL_OFFSETS "living_reset_pull_offsets"
///from base of living/CanAllowThrough(): (atom/movable/mover, border_dir)
#define COMSIG_LIVING_CAN_ALLOW_THROUGH "living_can_allow_through"
/// Allow to movable atoms to pass through this living mob
#define COMPONENT_LIVING_PASSABLE (1<<0)
18 changes: 18 additions & 0 deletions code/datums/keybinding/mob.dm
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,21 @@
if(.)
return
user.movement_locked = FALSE

/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)
99 changes: 99 additions & 0 deletions code/modules/pixel_shift/pixel_shift.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/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
6 changes: 6 additions & 0 deletions code/modules/pixel_shift/pixel_shift_mob.dm
Original file line number Diff line number Diff line change
@@ -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)
2 changes: 2 additions & 0 deletions tgstation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -4866,6 +4866,8 @@
#include "code\modules\photography\photos\album.dm"
#include "code\modules\photography\photos\frame.dm"
#include "code\modules\photography\photos\photo.dm"
#include "code\modules\pixel_shift\pixel_shift.dm"
#include "code\modules\pixel_shift\pixel_shift_mob.dm"
#include "code\modules\plumbing\ducts.dm"
#include "code\modules\plumbing\plumbers\_plumb_machinery.dm"
#include "code\modules\plumbing\plumbers\acclimator.dm"
Expand Down
Loading