Re-pr of #70522 "Space Dragon Update: Up Close and Personal" (#75607)

## About The Pull Request

This PR is a re-pr of ##70522 , with some tweaks: 

Notably:

- Wavespeak is not a say override, but instead uses a mindlink. Meaning
carp and space dragons can still talk verbally, but they can also use
telepathy to talk to all carp and the dragon.
- I would refactor Mind Linker a bit further to be a full datum rather
than a component but that's for another time.
- Removed the gravity aura component in favor of using the existing
forced gravity proximity monitor.
    - Also fixed a bug involving that. Lol.  
- Minor refactoring around the place.
- Reduced the volume on a lot of space dragon sounds. 
- Edited the roundend report for Space Dragons to collate all entries
into one per player.


![image](https://github.com/tgstation/tgstation/assets/51863163/5c3222b2-a80c-4df9-a060-4c5733ab712f)


## Why It's Good For The Game

Space dragon still plays pretty "play lame win game" right now, the
optimal strategy for them is to find the cheesiest spot for a portal and
spam their stun / fire breath to make it unreachable.

I was a fan of the original PR so I updated it and brought it back. 

## Changelog

🆑 IndieanaJones, Melbert
balance: Space Dragon can no longer choose its rift locations freely,
and instead is given 5 pre-determined locations to pick from instead
balance: Space Dragon itself has been buffed in order to support a more
confrontational playstyle, however its wing gust now requires a line of
sight to targets in order to affect them.
balance: Player Space Carp from rifts now have buffed health, but
reduced object damage values. They also gain a temporary speed boost
when hit by Space Dragon's fire breath instead of taking damage.
balance: Carp rift spawn times have been reduced, the healing AOE is now
a 3x3 instead of a 1x1, and apply normal gravity in a large radius
around them
balance: Space Dragon and rift carps now communicate on a private mind
link channel via action button similar to Raw Prophets and Slimepeople.
fix: Fixed Gravity Generator forced gravity not applying. 
fix: Intern Announcer will no longer replace Space Dragon announcements.
qol: The roundend report for space dragons now collates all players who
played a carp into one entry, rather than one per carp spawned.
qol: Space Dragon sounds are much less ear piercingly loud. 
/🆑

---------

Co-authored-by: IndieanaJones <mariosuperstar384@gmail.com>
Co-authored-by: IndieanaJones <47086570+IndieanaJones@users.noreply.github.com>
This commit is contained in:
MrMelbert
2023-05-31 10:51:07 -07:00
committed by GitHub
co-authored by IndieanaJones IndieanaJones
parent f125f4592c
commit e563148710
12 changed files with 318 additions and 115 deletions
+100 -51
View File
@@ -10,10 +10,6 @@
var/network_name = "Mind Link"
/// The color of the network when talking in chat
var/chat_color
/// The message sent to someone when linked up.
var/link_message
/// The message sent to someone when unlinked.
var/unlink_message
/// 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.
@@ -24,25 +20,25 @@
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 master's linking action, which allows them to link people to the network.
var/datum/action/linker_action
/// 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/datum/action/innate/linked_speech/master_speech
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/list/mob/living/linked_mobs = list()
VAR_FINAL/list/mob/living/linked_mobs = list()
/datum/component/mind_linker/Initialize(
// Customization related settings
network_name = "Mind Link",
chat_color = "#008CA2",
linker_action_path,
link_message,
unlink_message,
signals_which_destroy_us,
datum/callback/post_unlink_callback,
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
@@ -51,34 +47,22 @@
src.network_name = network_name
src.chat_color = chat_color
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]."
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
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.")
master_speech = new(src)
master_speech.Grant(owner)
to_chat(owner, span_boldnotice("You establish a [network_name], allowing you to link minds to communicate telepathically."))
/datum/component/mind_linker/Destroy(force, silent)
for(var/mob/living/remaining_mob as anything in linked_mobs)
unlink_mob(remaining_mob)
linked_mobs.Cut()
QDEL_NULL(linker_action)
QDEL_NULL(master_speech)
QDEL_NULL(post_unlink_callback)
return ..()
@@ -99,10 +83,6 @@
/datum/component/mind_linker/proc/link_mob(mob/living/to_link)
if(QDELETED(to_link) || to_link.stat == DEAD)
return FALSE
if(HAS_TRAIT(to_link, TRAIT_MINDSHIELD)) // Mindshield implant - no dice
return FALSE
if(to_link.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0))
return FALSE
if(linked_mobs[to_link])
return FALSE
@@ -110,20 +90,19 @@
if(to_link == owner)
return FALSE
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]."))
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_PARENT_QDELETING, COMSIG_MINDSHIELD_IMPLANTED), PROC_REF(unlink_mob))
RegisterSignals(to_link, list(COMSIG_LIVING_DEATH, COMSIG_PARENT_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.
@@ -131,25 +110,17 @@
* Also invokes post_unlink_callback, if supplied.
*/
/datum/component/mind_linker/proc/unlink_mob(mob/living/to_unlink)
SIGNAL_HANDLER
if(!linked_mobs[to_unlink])
return
return FALSE
to_chat(to_unlink, span_warning(unlink_message))
post_unlink_callback?.Invoke(to_unlink)
UnregisterSignal(to_unlink, list(COMSIG_LIVING_DEATH, COMSIG_PARENT_QDELETING, COMSIG_MINDSHIELD_IMPLANTED))
UnregisterSignal(to_unlink, list(COMSIG_LIVING_DEATH, COMSIG_PARENT_QDELETING))
var/datum/action/innate/linked_speech/old_link = linked_mobs[to_unlink]
linked_mobs -= to_unlink
qdel(old_link)
var/mob/living/owner = parent
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]."))
return TRUE
/**
* Signal proc sent from any signals given to us initialize.
@@ -164,6 +135,84 @@
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_TRAIT(to_link, TRAIT_MINDSHIELD)) // Mindshield implant - no dice
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."