Skip to content

Commit

Permalink
Rat RP expansion (#76455)
Browse files Browse the repository at this point in the history
This fixes a vile and long-standing bug where putting a mouse inside
your hat would not allow the mouse to control your movements, as it
would pop out of the hat whenever it tried to move.
Additionally as a feature this allows a mouse sitting on your head to
convey complicated instructions such as "scream" or "do a flip", via
emoting. Through drift compatibility, the rat's living mech will also
perform this action.

I could have made this into a component but there's no fucking way any
other item is going to have this behaviour, so I didn't.

This feature was already in the game but broken and I want it not to be
broken.
The mouse should be able to control your entire life.

:cl:
fix: Placing a mouse inside your chef hat will once more allow it to
pilot you around.
add: A player-controlled mouse inside your chef hat can compel you to
perform complex actions, such as flipping and spinning. You will obey
because the mouse knows better than you do.
/:cl:
  • Loading branch information
Jacquerel authored and AlbertNanotracen committed Mar 25, 2024
1 parent 1962ad7 commit 40b3b4c
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 16 deletions.
5 changes: 4 additions & 1 deletion code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
/// Should we stop the current living movement attempt
#define COMSIG_MOB_CLIENT_BLOCK_PRE_LIVING_MOVE COMPONENT_MOVABLE_BLOCK_PRE_MOVE

/// From base of /client/Move(): (list/move_args)
/// From base of /client/Move(): (new_loc, direction)
#define COMSIG_MOB_CLIENT_PRE_MOVE "mob_client_pre_move"
/// Should always match COMPONENT_MOVABLE_BLOCK_PRE_MOVE as these are interchangeable and used to block movement.
#define COMSIG_MOB_CLIENT_BLOCK_PRE_MOVE COMPONENT_MOVABLE_BLOCK_PRE_MOVE
Expand Down Expand Up @@ -140,6 +140,9 @@
///Mob is trying to open the wires of a target [/atom], from /datum/wires/interactable(): (atom/target)
#define COMSIG_TRY_WIRES_INTERACT "try_wires_interact"
#define COMPONENT_CANT_INTERACT_WIRES (1<<0)
///Mob is trying to emote, from /datum/emote/proc/run_emote(): (key, params, type_override, intentional)
#define COMSIG_MOB_PRE_EMOTED "mob_pre_emoted"
#define COMPONENT_CANT_EMOTE (1<<0)
#define COMSIG_MOB_EMOTED(emote_key) "mob_emoted_[emote_key]"
///sent when a mob/login() finishes: (client)
#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login"
Expand Down
2 changes: 2 additions & 0 deletions code/datums/emotes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@
. = TRUE
if(!can_run_emote(user, TRUE, intentional))
return FALSE
if(SEND_SIGNAL(user, COMSIG_MOB_PRE_EMOTED, key, params, type_override, intentional) & COMPONENT_CANT_EMOTE)
return // We don't return FALSE because the error output would be incorrect, provide your own if necessary.
var/msg = select_message_type(user, message, intentional)
if(params && message_param)
msg = select_param(user, params)
Expand Down
78 changes: 64 additions & 14 deletions code/modules/clothing/head/jobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,77 @@
desc = "The commander in chef's head wear."
strip_delay = 10
equip_delay_other = 10

dog_fashion = /datum/dog_fashion/head/chef
///the chance that the movements of a mouse inside of this hat get relayed to the human wearing the hat
/// The chance that the movements of a mouse inside of this hat get relayed to the human wearing the hat
var/mouse_control_probability = 20
/// Allowed time between movements
COOLDOWN_DECLARE(move_cooldown)

/// Admin variant of the chef hat where every mouse pilot input will always be transferred to the wearer
/obj/item/clothing/head/utility/chefhat/i_am_assuming_direct_control
desc = "The commander in chef's head wear. Upon closer inspection, there seem to be dozens of tiny levers, buttons, dials, and screens inside of this hat. What the hell...?"
mouse_control_probability = 100

/obj/item/clothing/head/utility/chefhat/Initialize(mapload)
. = ..()

create_storage(storage_type = /datum/storage/pockets/chefhat)

/obj/item/clothing/head/utility/chefhat/i_am_assuming_direct_control
desc = "The commander in chef's head wear. Upon closer inspection, there seem to be dozens of tiny levers, buttons, dials, and screens inside of this hat. What the hell...?"
mouse_control_probability = 100
/obj/item/clothing/head/utility/chefhat/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs)
. = ..()
var/mob/living/basic/new_boss = get_mouse(arrived)
if(!new_boss)
return
RegisterSignal(new_boss, COMSIG_MOB_PRE_EMOTED, PROC_REF(on_mouse_emote))
RegisterSignal(new_boss, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_mouse_moving))
RegisterSignal(new_boss, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, PROC_REF(on_mouse_moving))

/obj/item/clothing/head/utility/chefhat/Exited(atom/movable/gone, direction)
. = ..()
var/mob/living/basic/old_boss = get_mouse(gone)
if(!old_boss)
return
UnregisterSignal(old_boss, list(COMSIG_MOB_PRE_EMOTED, COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE))

/// Returns a mob stored inside a mob container, if there is one
/obj/item/clothing/head/utility/chefhat/proc/get_mouse(atom/possible_mouse)
if (!ispickedupmob(possible_mouse))
return
var/obj/item/clothing/head/mob_holder/mousey_holder = possible_mouse
return locate(/mob/living/basic) in mousey_holder.contents

/// Relays emotes emoted by your boss to the hat wearer for full immersion
/obj/item/clothing/head/utility/chefhat/proc/on_mouse_emote(mob/living/source, key, emote_message, type_override)
SIGNAL_HANDLER
var/mob/living/carbon/wearer = loc
if(!wearer || wearer.incapacitated(IGNORE_RESTRAINTS))
return
if (!prob(mouse_control_probability))
return COMPONENT_CANT_EMOTE
INVOKE_ASYNC(wearer, TYPE_PROC_REF(/mob, emote), key, type_override, emote_message, FALSE)
return COMPONENT_CANT_EMOTE

/// Relays movement made by the mouse in your hat to the wearer of the hat
/obj/item/clothing/head/utility/chefhat/proc/on_mouse_moving(mob/living/source, atom/moved_to)
SIGNAL_HANDLER
if (!prob(mouse_control_probability) || !COOLDOWN_FINISHED(src, move_cooldown))
return COMPONENT_MOVABLE_BLOCK_PRE_MOVE // Didn't roll well enough or on cooldown

var/mob/living/carbon/wearer = loc
if(!wearer || wearer.incapacitated(IGNORE_RESTRAINTS))
return COMPONENT_MOVABLE_BLOCK_PRE_MOVE // Not worn or can't move

var/move_direction = get_dir(wearer, moved_to)
if(!wearer.Process_Spacemove(move_direction))
return COMPONENT_MOVABLE_BLOCK_PRE_MOVE // Currently drifting in space
if(!has_gravity() || !isturf(wearer.loc))
return COMPONENT_MOVABLE_BLOCK_PRE_MOVE // Not in a location where we can move

step_towards(wearer, moved_to)
var/move_delay = wearer.cached_multiplicative_slowdown
if (ISDIAGONALDIR(move_direction))
move_delay *= sqrt(2)
COOLDOWN_START(src, move_cooldown, move_delay)
return COMPONENT_MOVABLE_BLOCK_PRE_MOVE

/obj/item/clothing/head/utility/chefhat/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] is donning [src]! It looks like [user.p_theyre()] trying to become a chef."))
Expand All @@ -35,14 +93,6 @@
playsound(user, 'sound/machines/ding.ogg', 50, TRUE)
return FIRELOSS

/obj/item/clothing/head/utility/chefhat/relaymove(mob/living/user, direction)
if(!ismouse(user) || !isliving(loc) || !prob(mouse_control_probability))
return
var/mob/living/L = loc
if(L.incapacitated(IGNORE_RESTRAINTS)) //just in case
return
step_towards(L, get_step(L, direction))

//Captain
/obj/item/clothing/head/hats/caphat
name = "captain's hat"
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/mob_movement.dm
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
if(mob.stat == DEAD)
mob.ghostize()
return FALSE
if(SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE) & COMSIG_MOB_CLIENT_BLOCK_PRE_LIVING_MOVE)
if(SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, new_loc, direct) & COMSIG_MOB_CLIENT_BLOCK_PRE_LIVING_MOVE)
return FALSE

var/mob/living/L = mob //Already checked for isliving earlier
Expand Down

0 comments on commit 40b3b4c

Please sign in to comment.