diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 08dfdaf94b0..0ef9284f986 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -716,6 +716,12 @@
/atom/proc/handle_middle_mouse_click(var/mob/user)
return FALSE
+/atom/proc/get_standard_pixel_x()
+ return initial(pixel_x)
+
+/atom/proc/get_standard_pixel_y()
+ return initial(pixel_y)
+
/atom/proc/handle_pointed_at(var/mob/pointer)
return
diff --git a/code/game/sound.dm b/code/game/sound.dm
index 85903acd29c..f4b0c57cdb1 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -815,6 +815,12 @@
'sound/items/shaker_lid_off2.ogg'
)
+/singleton/sound_category/boops
+ sounds = list(
+ 'sound/machines/boop1.ogg',
+ 'sound/machines/boop2.ogg'
+ )
+
/singleton/sound_category/quick_arcade // quick punchy arcade sounds
sounds = list(
'sound/arcade/get_fuel.ogg',
diff --git a/code/modules/games/gamehelm.dm b/code/modules/games/gamehelm.dm
index 0ca60a2b95a..f6a4f3ab491 100644
--- a/code/modules/games/gamehelm.dm
+++ b/code/modules/games/gamehelm.dm
@@ -8,103 +8,153 @@
desc_info = "You can ALT-click the game-helm to open it up and turn it on. Click on the open device to play."
icon = 'icons/obj/gamehelm.dmi'
w_class = ITEMSIZE_SMALL
- var/open = "open_white"
- var/closed = "closed_white"
+ update_icon_on_init = TRUE
-/obj/item/gamehelm/Initialize()
- . = ..()
- icon_state = closed
- add_overlay("buttons_closed")
+ var/case_color = "white"
+ var/open = FALSE
-/obj/item/gamehelm/AltClick()
- if(use_check(usr))
- return
- if(icon_state == open) //Toggle the lid, turn it off.
- icon_state = closed
- cut_overlays()
- add_overlay("buttons_closed")
- else if(icon_state == closed) //Otherwise open it up
- icon_state = open
- cut_overlays()
+ var/playing_game = FALSE
+ var/current_screen_state = null
+ var/static/list/game_type_to_state = list(
+ "anime game" = "screen_anime",
+ "shooter game" = "screen_shooter",
+ "strategy game" = "screen_strategy",
+ "piloting game" = "screen_pilot",
+ "horror game" = "screen_dread",
+ "simulation game" = "screen_emotive",
+ "exploration game" = "screen_exploration",
+ "music service" = "screen_music",
+ "video service" = "screen_video",
+ "toggle device mute" = null,
+ "turn off the system" = null
+ )
+
+ var/static/list/non_game_states = list(
+ "screen_music",
+ "screen_video"
+ )
+
+ var/static/list/game_actions = list(
+ "hits all the buttons at the same time" = "hit all the buttons at the same time",
+ "rapidly hits a bunch of buttons" = "rapidly hit a bunch of buttons",
+ "tilts the %NAME% to the right" = "tilt the %NAME% to the right",
+ "tilts the %NAME% to the left" = "tilt the %NAME% to the left",
+ "swipes across the %NAME%'s screen" = "swipe across the %NAME%'s screen"
+ )
+
+ var/next_action_time = 0
+ var/action_time_cooldown = 10 SECONDS
+
+ var/muted = FALSE
+
+/obj/item/gamehelm/update_icon()
+ cut_overlays()
+ if(open)
+ icon_state = "open_[case_color]"
add_overlay("buttons_open")
+ else
+ icon_state = "closed_[case_color]"
+ add_overlay("buttons_closed")
+ if(current_screen_state)
+ add_overlay(current_screen_state)
+
+/obj/item/gamehelm/process()
+ if(world.time < next_action_time)
+ return
+ next_action_time = world.time + action_time_cooldown
+
+ if(playing_game)
+ if(!muted)
+ playsound(loc, /singleton/sound_category/quick_arcade, 20)
+ if(ismob(loc))
+ var/picked_action = pick(game_actions)
+ var/self_action = game_actions[picked_action]
+ picked_action = replacetext(picked_action, "%NAME%", name)
+ self_action = replacetext(self_action, "%NAME%", name)
+ loc.visible_message("[loc] [picked_action]!", SPAN_NOTICE("You [self_action]!"), range = 3)
+ else
+ if(!muted)
+ playsound(loc, /singleton/sound_category/computerbeep_sound, 20)
+
+/obj/item/gamehelm/AltClick(mob/user)
+ if(use_check(user))
+ return
+ toggle_state(user)
+
+/obj/item/gamehelm/proc/toggle_state(mob/user)
+ open = !open
+ update_icon()
+ if(open)
+ user.visible_message("[user] flips open \the [src] with a satisfying snap!", SPAN_NOTICE("You flip open \the [src] with a satisfying snap!"), range = 3)
+ else
+ user.visible_message("[user] flips \the [src] shut with a satisfying snap!", SPAN_NOTICE("You flip \the [src] shut with a satisfying snap!"), range = 3)
+ set_game(null)
+ playsound(user, 'sound/weapons/blade_open.ogg', 30)
+
+/obj/item/gamehelm/proc/set_game(var/screen_type)
+ current_screen_state = screen_type
+ playing_game = !(current_screen_state in non_game_states)
+ update_icon()
+ if(current_screen_state)
+ START_PROCESSING(SSprocessing, src)
+ else
+ STOP_PROCESSING(SSprocessing, src)
/obj/item/gamehelm/attack_self(mob/user)
- if(icon_state == open)
- var/choice = input("What do you want to play?") as null|anything in list("anime game", "shooter game", "simulation game", "strategy game", "piloting game", "horror game", "exploration game", "video service", "music service", "turn off the system")
- cut_overlays()
- add_overlay("buttons_open")
- if(choice != "turn off the system")
- to_chat(user, "You start the application on your Game-Helm and begin playing.")
+ if(open)
+ var/choice = input("What do you want to play?") as null|anything in game_type_to_state
+ if(choice == "turn off the system")
+ user.visible_message("[user] hits the power button on \the [src] and it quickly shuts down.", SPAN_NOTICE("You hit the power button on \the [src] and it quickly shuts down."), range = 3)
+ if(!muted)
+ playsound(loc, 'sound/machines/softbeep.ogg', 20)
+ set_game(null)
+ return
+ if(choice == "toggle device mute")
+ muted = !muted
+ to_chat(user, SPAN_NOTICE("You hit the mute button, [muted ? "disabling" : "enabling"] the device audio."))
+ if(!muted)
+ playsound(loc, 'sound/machines/softbeep.ogg', 20)
+ return
+ if(current_screen_state)
+ user.visible_message("[user] taps on a few buttons and \the [src] swaps to a different application!", SPAN_NOTICE("You tap on a few buttons and \the [src] swaps to a different application!"), range = 3)
else
- to_chat(user, "You turn the Game-Helm off.")
- if(choice == "anime game")
- add_overlay("screen_anime")
- if(choice == "shooter game")
- add_overlay("screen_shooter")
- if(choice == "strategy game")
- add_overlay("screen_strategy")
- if(choice == "piloting game")
- add_overlay("screen_pilot")
- if(choice == "horror game")
- add_overlay("screen_dread")
- if(choice == "simulation game")
- add_overlay("screen_emotive")
- if(choice == "exploration game")
- add_overlay("screen_exploration")
- if(choice == "music service")
- add_overlay("screen_music")
- if(choice == "video service")
- add_overlay("screen_video")
- else
- ..()
+ user.visible_message("[user] taps on a few buttons and \the [src] springs to life!", SPAN_NOTICE("You tap on a few buttons and \the [src] springs to life!"), range = 3)
+ if(!muted)
+ playsound(loc, /singleton/sound_category/boops, 25)
+ set_game(game_type_to_state[choice])
+ return ..()
+
+/obj/item/gamehelm/Destroy()
+ STOP_PROCESSING(SSprocessing, src)
+ return ..()
//The colours!
/obj/item/gamehelm/blue
- open = "open_blue"
- closed = "closed_blue"
- icon_state = "closed_blue"
+ case_color = "blue"
/obj/item/gamehelm/red
- open = "open_red"
- closed = "closed_red"
- icon_state = "closed_red"
+ case_color = "red"
/obj/item/gamehelm/black
- open = "open_black"
- closed = "closed_black"
- icon_state = "closed_black"
+ case_color = "black"
/obj/item/gamehelm/pink
- open = "open_pink"
- closed = "closed_pink"
- icon_state = "closed_pink"
+ case_color = "pink"
/obj/item/gamehelm/purple
- open = "open_purple"
- closed = "closed_purple"
- icon_state = "closed_purple"
+ case_color = "purple"
/obj/item/gamehelm/brown
- open = "open_brown"
- closed = "closed_brown"
- icon_state = "closed_brown"
+ case_color = "brown"
/obj/item/gamehelm/green
- open = "open_green"
- closed = "closed_green"
- icon_state = "closed_green"
+ case_color = "green"
/obj/item/gamehelm/yellow
- open = "open_yellow"
- closed = "closed_yellow"
- icon_state = "closed_yellow"
+ case_color = "yellow"
/obj/item/gamehelm/turquoise
- open = "open_turquoise"
- closed = "closed_turquoise"
- icon_state = "closed_turquoise"
+ case_color = "turqoise"
/obj/item/gamehelm/weathered
- open = "open_weathered"
- closed = "closed_weathered"
- icon_state = "closed_weathered"
+ case_color = "weathered"
diff --git a/code/modules/mob/animations.dm b/code/modules/mob/animations.dm
index 23e97c98d9d..e8d36f330ce 100644
--- a/code/modules/mob/animations.dm
+++ b/code/modules/mob/animations.dm
@@ -288,3 +288,14 @@ note dizziness decrements automatically in the mob's Life() proc.
if(is_floating)
addtimer(CALLBACK(src, PROC_REF(start_floating)), 2.4)
+
+/atom/proc/quick_jitter(var/jitter_time = 5)
+ set waitfor = 0
+
+ jitter_time--
+
+ pixel_x = jitter_time ? get_standard_pixel_x() + rand(-3, 3) : get_standard_pixel_x()
+ pixel_y = jitter_time ? get_standard_pixel_y() + rand(-1, 1) : get_standard_pixel_y()
+
+ if(jitter_time)
+ addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, quick_jitter), jitter_time), 1)
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 8d75edb5a71..d7825e1efc1 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -1223,12 +1223,6 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT)
client.init_verbs()
return src
-/mob/proc/get_standard_pixel_x()
- return initial(pixel_x)
-
-/mob/proc/get_standard_pixel_y()
- return initial(pixel_y)
-
/mob/proc/remove_nearsighted()
disabilities &= ~NEARSIGHTED
diff --git a/html/changelogs/geeves-gamehelm_upgrade.yml b/html/changelogs/geeves-gamehelm_upgrade.yml
new file mode 100644
index 00000000000..9b63695f733
--- /dev/null
+++ b/html/changelogs/geeves-gamehelm_upgrade.yml
@@ -0,0 +1,6 @@
+author: Geeves
+
+delete-after: True
+
+changes:
+ - tweak: "It should now be a bit more obvious when people are playing with their InUs Game-Helm."
\ No newline at end of file