Makes MOD hypnovisor module toggleable, editable in-suit (#5110)

## About The Pull Request

Changes the hypnovisor significantly:
- Renames it (hypnosis module --> MOD hypnotic visor module) to be
similar to normal modules
- Changing the directive now fills the text box with the previously
selected directive.
- Use a screwdriver on the module to toggle its visor effects, so nobody
will suspect you're doing something lewd while you walk around in your
fully-deployed Lustwish modsuit.
- Use wirecutters on the module to cut its control wire, switching
between toggleable mode and passive mode.
-- Passive mode retains current hypnovisor functionality, which means it
is always-on, and cannot be configured while installed.
-- Toggleable mode can be switched on/off and configured via the MOD UI
(including via remote control), with changes to the directive and
display taking effect upon restart.
- Tutorial text added for the module's examine text, explaining the
interactions, what they do, and also what the module is currently
configured to.

No other changes to functionality are intended for this module.

If someone is willing to sprite them, I'd be happy to add support for
additional spiral visor overlays for other MOD platings (Standard,
Engineering, Loader, Medical, Corpsman, etc.?) that have big enough
visors for it...

## Why It's Good For The Game

Adding additional functionalities to the lewder modules makes them more
attractive to use and ultimately will lead to me seeing more of the
content I like in the game. Being able to edit directives on-the-fly
also makes use of this module much less clunky.

## Proof Of Testing
<details>
<summary>
<img width="967" height="351" alt="image"
src="https://github.com/user-attachments/assets/124b807d-49f3-470c-83bf-2e5c18dc3b24"
/>
</summary>

</details>

## Changelog

🆑
add: MOD hypnosis module is now configurable via the MOD UI... including
remote control.
/🆑
This commit is contained in:
Minty
2026-01-29 17:24:34 -05:00
committed by GitHub
parent 18234dd866
commit 79f3e7954b
@@ -4,49 +4,123 @@
theme = /datum/mod_theme/lustwish
/obj/item/mod/module/hypno_visor
name = "hypnosis module"
desc = "A module inserted into the visor of a suit in which commands can be processed. Use on self to set directives."
name = "\improper MOD hypnotic visor module"
desc = "A module inserted into the visor of a suit in which commands can be processed."
icon = 'modular_zubbers/icons/mob/clothing/modsuit/mod_modules.dmi'
icon_state = "module_hypno"
module_type = MODULE_PASSIVE
complexity = 0
idle_power_cost = DEFAULT_CHARGE_DRAIN * 0
idle_power_cost = 0
incompatible_modules = list(/obj/item/mod/module/hypno_visor)
required_slots = list(ITEM_SLOT_HEAD)
overlay_state_inactive = "module_hypno_overlay"
overlay_icon_file = 'modular_zubbers/icons/mob/clothing/modsuit/mod_modules.dmi'
var/hypno_message
/obj/item/mod/module/hypno_visor/Destroy()
if(!mod)
return ..()
if(mod.wearer && part_activated)
mod.wearer.cure_trauma_type(/datum/brain_trauma/very_special/induced_hypnosis, TRAUMA_RESILIENCE_MAGIC)
return ..()
module_type = MODULE_PASSIVE //These three are changed when the control wire is snipped
overlay_state_active = null
overlay_state_inactive = "module_hypno_overlay"
var/hypno_message = "Obey"
///Does the visor overlay show on the character sprite when installed? Only eligible with certain skins.
var/visor_effect = TRUE
/obj/item/mod/module/hypno_visor/examine(mob/user)
. = ..()
. += span_info("It's currently programmed with the following directive: \"[hypno_message]\" Use it in-hand to rewrite it.")
. += span_info("Its visor will [visor_effect ? "" : "<b>not</b>"] display an external hypnotic effect. Use a screwdriver to toggle.")
. += span_info("Its control wire is currently [(module_type == MODULE_TOGGLE) ? \
"<b>intact,</b> allowing for on-the-fly configuration via the MOD UI." \
: \
"<b>snipped,</b> forcing the module to be always-on when the helmet is activated."] \
Use wirecutters to toggle.")
/obj/item/mod/module/hypno_visor/attack_self(mob/user)
. = ..()
hypno_message = tgui_input_text(user, "Change the hypnotic phrase.", max_length = MAX_MESSAGE_LEN)
var/message_input = tgui_input_text(user, "Change the hypnotic phrase.", default = hypno_message, max_length = MAX_MESSAGE_LEN)
if(message_input)
hypno_message = message_input
else
hypno_message = "Obey"
/obj/item/mod/module/hypno_visor/on_part_activation()
/obj/item/mod/module/hypno_visor/screwdriver_act(mob/living/user, obj/item/tool)
visor_effect = !visor_effect
to_chat(user, span_notice("You turn the visor display of [src] [visor_effect ? "on" : "off"]."))
return TRUE
/obj/item/mod/module/hypno_visor/wirecutter_act(mob/living/user, obj/item/tool)
if(module_type == MODULE_TOGGLE) // If it's not toggle, make it so. If it is, make it passive.
module_type = MODULE_PASSIVE
overlay_state_active = null
overlay_state_inactive = "module_hypno_overlay"
else
module_type = MODULE_TOGGLE
overlay_state_active = "module_hypno_overlay"
overlay_state_inactive = null
to_chat(user, span_notice("You [(module_type == MODULE_TOGGLE) ? "mend" : "snip"] the control wire on [src]."))
return TRUE
/obj/item/mod/module/hypno_visor/on_install()
. = ..()
if(mod.skin != "lustwish" && visor_effect == TRUE)
overlay_state_inactive = null // Visual thing. Removes the overlay if it's not a part of the lustwish suit.
overlay_state_active = null
visor_effect = FALSE
balloon_alert(usr, "visor effect unavailable for this plating!")
/obj/item/mod/module/hypno_visor/on_uninstall(deleting = FALSE)
. = ..()
overlay_state_inactive = initial(overlay_state_inactive) //This part only matters for visor/passive
overlay_state_active = initial(overlay_state_active) //This part only matters for visor/toggleable
/obj/item/mod/module/hypno_visor/proc/apply_hypnosis()
if(!(mod.wearer.client?.prefs?.read_preference(/datum/preference/toggle/erp/hypnosis) && mod.wearer.client.prefs.read_preference(/datum/preference/toggle/erp/sex_toy)))
return to_chat(mod.wearer, span_warning("Mind resilient to hypnotic effects: Shutting down"))
if(hypno_message == "" || isnull(hypno_message))
hypno_message = "Obey"
mod.wearer.gain_trauma(new /datum/brain_trauma/very_special/induced_hypnosis(hypno_message), TRAUMA_RESILIENCE_MAGIC)
/obj/item/mod/module/hypno_visor/Destroy()
if(!mod)
return ..()
if(module_type == ((module_type == MODULE_PASSIVE && part_activated) || (module_type == MODULE_TOGGLE && active)) && mod.wearer)
mod.wearer.cure_trauma_type(/datum/brain_trauma/very_special/induced_hypnosis, TRAUMA_RESILIENCE_MAGIC)
return ..()
/obj/item/mod/module/hypno_visor/on_part_activation()
if(module_type == MODULE_PASSIVE)
apply_hypnosis()
/obj/item/mod/module/hypno_visor/on_part_deactivation(deleting = FALSE)
mod.wearer.cure_trauma_type(/datum/brain_trauma/very_special/induced_hypnosis, TRAUMA_RESILIENCE_MAGIC)
if(module_type == MODULE_PASSIVE)
mod.wearer.cure_trauma_type(/datum/brain_trauma/very_special/induced_hypnosis, TRAUMA_RESILIENCE_MAGIC)
/obj/item/mod/module/hypno_visor/on_install()
. = ..()
if(mod.skin != "lustwish")
overlay_state_inactive = null // Visual thing. Removes the overlay if it's not a part of the lustwish suit.
/obj/item/mod/module/hypno_visor/on_activation(mob/activator)
if(module_type == MODULE_TOGGLE)
apply_hypnosis()
/obj/item/mod/module/hypno_visor/on_uninstall(deleting = FALSE)
/obj/item/mod/module/hypno_visor/on_deactivation(mob/activator, display_message = TRUE, deleting = FALSE)
if(module_type == MODULE_TOGGLE)
mod.wearer.cure_trauma_type(/datum/brain_trauma/very_special/induced_hypnosis, TRAUMA_RESILIENCE_MAGIC)
/obj/item/mod/module/hypno_visor/get_configuration()
. = ..()
if(isnull(overlay_state_inactive))
overlay_state_inactive = initial(overlay_state_inactive)
if(module_type == MODULE_TOGGLE)
.["hypno_message"] = add_ui_configuration("Hypnotic Message", "button", "list")
.["visor_effect"] = add_ui_configuration("Visor Effect", "bool", visor_effect)
/obj/item/mod/module/hypno_visor/configure_edit(key, value)
switch(key)
if("hypno_message")
hypno_message = tgui_input_text(usr, "Change the hypnotic phrase.", default = hypno_message, max_length = MAX_MESSAGE_LEN)
if(active)
balloon_alert(usr, "restart to finalize changes")
if("visor_effect")
if(mod.skin != "lustwish")
return balloon_alert(usr, "visor effect unavailable for this plating!")
visor_effect = text2num(value)
overlay_state_active = visor_effect ? "module_hypno_overlay" : null
if(active)
balloon_alert(usr, "restart to finalize changes")
/datum/storage/pockets/small/remote_module
max_slots = 1