Files
Waterpig bb70889f6e TG Upstream Part 1
3591 individual conflicts

Update build.js

Update install_node.sh

Update byond.js

oh my fucking god

hat

slow

huh

holy shit

we all fall down

2 more I missed

2900 individual conflicts

2700 Individual conflicts

replaces yarn file with tg version, bumping us down to 2200-ish

Down to 2000 individual conflicts

140 down

mmm

aaaaaaaaaaaaaaaaaaa

not yt

575

soon

900 individual conflicts

600 individual conflicts, 121 file conflicts

im not okay

160 across 19 files

29 in 4 files

0 conflicts, compiletime fix time

some minor incap stuff

missed ticks

weird dupe definition stuff

missed ticks 2

incap fixes

undefs and pie fix

Radio update and some extra minor stuff

returns a single override

no more dupe definitions, 175 compiletime errors

Unticked file fix

sound and emote stuff

honk and more radio stuff
2024-10-19 08:04:33 -07:00

271 lines
9.7 KiB
Plaintext

/**
* # Mind Linker
*
* A component that handles linking multiple player's minds
* into one network which allows them to talk directly to one another.
* Like telepathy but for multiple people at once!
*/
/datum/component/mind_linker
/// The name of our network, displayed to all users.
var/network_name = "Mind Link"
/// The color of the network when talking in chat
var/chat_color
/// A list of all signals that will call qdel() on our component if triggered. Optional.
var/list/signals_which_destroy_us
/// A callback invoked after an unlink is done. Optional.
var/datum/callback/post_unlink_callback
/// The icon file given to the speech action handed out.
var/speech_action_icon = 'icons/mob/actions/actions_slime.dmi'
/// The icon state applied to the speech action handed out.
var/speech_action_icon_state = "link_speech"
/// The icon background for the speech action handed out.
var/speech_action_background_icon_state = "bg_alien"
/// The border icon state for the speech action handed out.
var/speech_action_overlay_state = "bg_alien_border"
/// The master's speech action. The owner of the link shouldn't lose this as long as the link remains.
VAR_FINAL/datum/action/innate/linked_speech/master_speech
/// An assoc list of [mob/living]s to [datum/action/innate/linked_speech]s. All the mobs that are linked to our network.
VAR_FINAL/list/mob/living/linked_mobs = list()
/datum/component/mind_linker/Initialize(
// Customization related settings
network_name = "Mind Link",
chat_color = "#008CA2",
speech_action_icon = 'icons/mob/actions/actions_slime.dmi',
speech_action_icon_state = "link_speech",
speech_action_background_icon_state = "bg_alien",
speech_action_overlay_state = "bg_alien_border",
// Optional
signals_which_destroy_us,
datum/callback/post_unlink_callback,
)
if(!isliving(parent))
return COMPONENT_INCOMPATIBLE
var/mob/living/owner = parent
src.network_name = network_name
src.chat_color = chat_color
src.speech_action_icon = speech_action_icon
src.speech_action_icon_state = speech_action_icon_state
src.speech_action_background_icon_state = speech_action_background_icon_state
if(islist(signals_which_destroy_us))
src.signals_which_destroy_us = signals_which_destroy_us
if(post_unlink_callback)
src.post_unlink_callback = post_unlink_callback
src.speech_action_icon = speech_action_icon
src.speech_action_icon_state = speech_action_icon_state
src.speech_action_background_icon_state = speech_action_background_icon_state
//SKYRAT EDIT - NIFs
if(speech_action)
master_speech = new(src)
master_speech.Grant(owner)
//SKYRAT EDIT END
/datum/component/mind_linker/Destroy(force)
for(var/mob/living/remaining_mob as anything in linked_mobs)
unlink_mob(remaining_mob)
linked_mobs.Cut()
QDEL_NULL(master_speech)
post_unlink_callback = null
return ..()
/datum/component/mind_linker/RegisterWithParent()
if(signals_which_destroy_us)
RegisterSignals(parent, signals_which_destroy_us, PROC_REF(destroy_link))
/datum/component/mind_linker/UnregisterFromParent()
if(signals_which_destroy_us)
UnregisterSignal(parent, signals_which_destroy_us)
/**
* Attempts to link [to_link] to our network, giving them a speech action.
*
* Returns TRUE if successful, FALSE otherwise
*/
/datum/component/mind_linker/proc/link_mob(mob/living/to_link)
if(QDELETED(to_link) || to_link.stat == DEAD)
return FALSE
if(linked_mobs[to_link])
return FALSE
var/mob/living/owner = parent
if(to_link == owner)
return FALSE
var/datum/action/innate/linked_speech/new_link = new(src)
new_link.Grant(to_link)
linked_mobs[to_link] = new_link
RegisterSignals(to_link, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING), PROC_REF(sig_unlink_mob))
return TRUE
/datum/component/mind_linker/proc/sig_unlink_mob(mob/living/to_unlink)
SIGNAL_HANDLER
unlink_mob(to_unlink)
/**
* Unlinks [to_unlink] from our network, deleting their speech action
* and cleaning up anything involved.
*
* Also invokes post_unlink_callback, if supplied.
*/
/datum/component/mind_linker/proc/unlink_mob(mob/living/to_unlink)
if(!linked_mobs[to_unlink])
return FALSE
post_unlink_callback?.Invoke(to_unlink)
UnregisterSignal(to_unlink, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING))
var/datum/action/innate/linked_speech/old_link = linked_mobs[to_unlink]
linked_mobs -= to_unlink
qdel(old_link)
return TRUE
/**
* Signal proc sent from any signals given to us initialize.
* Destroys our component and unlinks everyone.
*/
/datum/component/mind_linker/proc/destroy_link(datum/source)
SIGNAL_HANDLER
if(isliving(source))
var/mob/living/owner = source
to_chat(owner, span_boldwarning("Your [network_name] breaks!"))
qdel(src)
/// Subtype of mind linker (I know) which is more active rather than passive,
/// which involves the master linking people manually rather than people being added automatically.
/datum/component/mind_linker/active_linking
/// The message sent to someone when linked up.
var/link_message
/// The message sent to someone when unlinked.
var/unlink_message
/// The master's linking action, which allows them to link people to the network.
VAR_FINAL/datum/action/linker_action
/datum/component/mind_linker/active_linking/Initialize(
// Customization related settings
network_name = "Mind Link",
chat_color = "#008CA2",
speech_action_icon = 'icons/mob/actions/actions_slime.dmi',
speech_action_icon_state = "link_speech",
speech_action_background_icon_state = "bg_alien",
speech_action_overlay_state = "bg_alien_border",
// Optional
signals_which_destroy_us,
datum/callback/post_unlink_callback,
// Optional for this subtype
link_message,
unlink_message,
// Required for this subtype
linker_action_path,
)
. = ..()
if(. == COMPONENT_INCOMPATIBLE)
return
var/mob/living/owner = parent
src.link_message = link_message || "You are now connected to [owner.real_name]'s [network_name]."
src.unlink_message = unlink_message || "You are no longer connected to [owner.real_name]'s [network_name]."
if(ispath(linker_action_path))
linker_action = new linker_action_path(src)
linker_action.Grant(owner)
else
stack_trace("[type] was created without a valid linker_action_path. No one will be able to link to it.")
to_chat(owner, span_boldnotice("You establish a [network_name], allowing you to link minds to communicate telepathically."))
/datum/component/mind_linker/active_linking/Destroy()
QDEL_NULL(linker_action)
return ..()
/datum/component/mind_linker/active_linking/link_mob(mob/living/to_link)
if(HAS_MIND_TRAIT(to_link, TRAIT_UNCONVERTABLE)) // Protected mind, so they can't be added to the mindlink
return FALSE
if(to_link.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0))
return FALSE
. = ..()
if(!.)
return
RegisterSignal(to_link, COMSIG_MINDSHIELD_IMPLANTED, PROC_REF(sig_unlink_mob))
var/mob/living/owner = parent
to_chat(to_link, span_notice(link_message))
to_chat(owner, span_notice("You connect [to_link]'s mind to your [network_name]."))
for(var/mob/living/other_link as anything in linked_mobs)
to_chat(other_link, span_notice("You feel a new presence within [owner.real_name]'s [network_name]."))
/datum/component/mind_linker/active_linking/unlink_mob(mob/living/to_unlink)
. = ..()
if(!.)
return
UnregisterSignal(to_unlink, COMSIG_MINDSHIELD_IMPLANTED)
var/mob/living/owner = parent
to_chat(to_unlink, span_warning(unlink_message))
to_chat(owner, span_warning("You feel someone disconnect from your [network_name]."))
for(var/mob/living/other_link as anything in linked_mobs)
to_chat(other_link, span_warning("You feel a pressence disappear from [owner.real_name]'s [network_name]."))
// Used in mind linker to talk to everyone in the network.
/datum/action/innate/linked_speech
name = "Mind Link Speech"
desc = "Send a psychic message to everyone connected to your Link."
button_icon_state = "link_speech"
button_icon = 'icons/mob/actions/actions_slime.dmi'
background_icon_state = "bg_alien"
overlay_icon_state = "bg_alien_border"
/datum/action/innate/linked_speech/New(Target)
. = ..()
if(!istype(Target, /datum/component/mind_linker))
stack_trace("[name] ([type]) was instantiated on a non-mind_linker target, this doesn't work.")
qdel(src)
return
var/datum/component/mind_linker/linker = Target
name = "[linker.network_name] Speech"
desc = "Send a psychic message to everyone connected to your [linker.network_name]."
button_icon = linker.speech_action_icon
button_icon_state = linker.speech_action_icon_state
background_icon_state = linker.speech_action_background_icon_state
/datum/action/innate/linked_speech/IsAvailable(feedback = FALSE)
return ..() && (owner.stat != DEAD)
/datum/action/innate/linked_speech/Activate()
var/datum/component/mind_linker/linker = target
var/mob/living/linker_parent = linker.parent
var/message = tgui_input_text(owner, "Enter a message to transmit.", "[linker.network_name] Telepathy")
if(!message || QDELETED(src) || QDELETED(owner) || owner.stat == DEAD)
return
if(QDELETED(linker))
to_chat(owner, span_warning("The link seems to have been severed."))
return
var/formatted_message = "<i><font color=[linker.chat_color]>\[[linker_parent.real_name]'s [linker.network_name]\] <b>[owner]:</b> [message]</font></i>"
log_directed_talk(owner, linker_parent, message, LOG_SAY, "mind link ([linker.network_name])")
var/list/all_who_can_hear = assoc_to_keys(linker.linked_mobs) + linker_parent
for(var/mob/living/recipient as anything in all_who_can_hear)
var/avoid_highlighting = (recipient == owner) || (recipient == linker_parent)
to_chat(recipient, formatted_message, type = MESSAGE_TYPE_RADIO, avoid_highlighting = avoid_highlighting)
for(var/mob/recipient as anything in GLOB.dead_mob_list)
to_chat(recipient, "[FOLLOW_LINK(recipient, owner)] [formatted_message]", type = MESSAGE_TYPE_RADIO)