diff --git a/code/__DEFINES/keybinding.dm b/code/__DEFINES/keybinding.dm index ed61860b937..c1f6ef14b53 100644 --- a/code/__DEFINES/keybinding.dm +++ b/code/__DEFINES/keybinding.dm @@ -59,6 +59,7 @@ #define COMSIG_KB_LIVING_TOGGLEMOVEINTENT_DOWN "keybinding_mob_togglemoveintent_down" #define COMSIG_KB_LIVING_TOGGLEMOVEINTENTALT_DOWN "keybinding_mob_togglemoveintentalt_down" #define COMSIG_KB_LIVING_VIEW_PET_COMMANDS "keybinding_living_view_pet_commands" +#define COMSIG_KB_LIVING_FACECURSOR_DOWN "keybinding_living_facecursor_down" //Mob #define COMSIG_KB_MOB_FACENORTH_DOWN "keybinding_mob_facenorth_down" diff --git a/code/datums/keybinding/living.dm b/code/datums/keybinding/living.dm index cdc80565f75..f74fbe4f7a7 100644 --- a/code/datums/keybinding/living.dm +++ b/code/datums/keybinding/living.dm @@ -165,3 +165,24 @@ var/mob/living/M = user.mob M.toggle_move_intent() return TRUE + +/datum/keybinding/living/face_cursor + hotkey_keys = list("Unbound") + name = "face_cursor" + full_name = "Face Cursor" + description = "Hold for face to cursor." + keybind_signal = COMSIG_KB_LIVING_FACECURSOR_DOWN + +/datum/keybinding/living/face_cursor/down(client/user) + . = ..() + if(.) + return + var/mob/M = user.mob + M.face_mouse = TRUE + +/datum/keybinding/living/face_cursor/up(client/user) + . = ..() + if(.) + return + var/mob/M = user.mob + M.face_mouse = FALSE diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index a7d057aa9fa..ffea0055b6c 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -866,6 +866,10 @@ SEND_SIGNAL(user, COMSIG_ATOM_MOUSE_ENTERED, src) + // Face directions on combat mode. No procs, no typechecks, just a var for speed + if(user.face_mouse) + user.face_atom(src) + // Screentips var/datum/hud/active_hud = user.hud_used if(!active_hud) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index e6fe68ea4c4..571a23422c5 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -131,6 +131,9 @@ /// Example: If req_one_access = list(ACCESS_ENGINE, ACCESS_CE)- then the user must have either ACCESS_ENGINE or ACCESS_CE in order to use the object. var/list/req_one_access + /// Whether a user will face atoms on entering them with a mouse. Despite being a mob variable, it is here for performance reasons + var/face_mouse = FALSE + /mutable_appearance/emissive_blocker /mutable_appearance/emissive_blocker/New() @@ -644,7 +647,7 @@ if(!direction) direction = get_dir(src, newloc) - if(set_dir_on_move && dir != direction && update_dir) + if(set_dir_on_move && dir != direction && update_dir && !face_mouse) setDir(direction) var/is_multi_tile_object = is_multi_tile_object(src) @@ -771,7 +774,7 @@ moving_diagonally = SECOND_DIAG_STEP . = step(src, SOUTH) if(moving_diagonally == SECOND_DIAG_STEP) - if(!. && set_dir_on_move && update_dir) + if(!. && set_dir_on_move && update_dir && !face_mouse) setDir(first_step_dir) else if(!inertia_moving) newtonian_move(dir2angle(direct)) @@ -818,7 +821,7 @@ last_move = direct - if(set_dir_on_move && dir != direct && update_dir) + if(set_dir_on_move && dir != direct && update_dir && !face_mouse) setDir(direct) if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc, direct, glide_size_override)) //movement failed due to buckled mob(s) . = FALSE diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index dc5d46fe2c9..c303a6c483f 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -195,6 +195,7 @@ return . = combat_mode combat_mode = new_mode + if(hud_used?.action_intent) hud_used.action_intent.update_appearance() if(silent || !(client?.prefs.read_preference(/datum/preference/toggle/sound_combatmode))) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 743bdad8c45..fead171f4e7 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -101,6 +101,11 @@ //We are now going to move var/add_delay = mob.cached_multiplicative_slowdown + if(mob.face_mouse && mob.dir != direct && !(mob.movement_type & FLYING)) + if((NSCOMPONENT(mob.dir) && NSDIRFLIP(mob.dir) == direct) || (EWCOMPONENT(mob.dir) && EWDIRFLIP(mob.dir) == direct)) // If we're waling backwards + add_delay += /datum/movespeed_modifier/backward_walk::multiplicative_slowdown + else //Otherwise + add_delay += /datum/movespeed_modifier/side_walk::multiplicative_slowdown var/new_glide_size = DELAY_TO_GLIDE_SIZE(add_delay * ( (NSCOMPONENT(direct) && EWCOMPONENT(direct)) ? sqrt(2) : 1 ) ) mob.set_glide_size(new_glide_size) // set it now in case of pulled objects //If the move was recent, count using old_move_delay diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm index 55ee105d56c..7740e825383 100644 --- a/code/modules/movespeed/modifiers/mobs.dm +++ b/code/modules/movespeed/modifiers/mobs.dm @@ -180,3 +180,9 @@ /datum/movespeed_modifier/fish_on_water blacklisted_movetypes = MOVETYPES_NOT_TOUCHING_GROUND multiplicative_slowdown = - /turf/open/water::slowdown + +/datum/movespeed_modifier/backward_walk + multiplicative_slowdown = 1.5 + +/datum/movespeed_modifier/side_walk + multiplicative_slowdown = 0.75