mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-29 16:18:01 +01:00
## 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.

## 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:
co-authored by
IndieanaJones
IndieanaJones
parent
f125f4592c
commit
e563148710
@@ -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."
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Proximity monitor applies forced gravity to all turfs in range.
|
||||
/datum/proximity_monitor/advanced/gravity
|
||||
edge_is_a_field = TRUE
|
||||
var/gravity_value = 0
|
||||
@@ -10,9 +11,10 @@
|
||||
|
||||
/datum/proximity_monitor/advanced/gravity/setup_field_turf(turf/target)
|
||||
. = ..()
|
||||
if (isnull(modified_turfs[target]))
|
||||
if(!isnull(modified_turfs[target]))
|
||||
return
|
||||
if(HAS_TRAIT(target, TRAIT_FORCED_GRAVITY))
|
||||
return
|
||||
|
||||
target.AddElement(/datum/element/forced_gravity, gravity_value)
|
||||
modified_turfs[target] = gravity_value
|
||||
|
||||
@@ -20,5 +22,44 @@
|
||||
. = ..()
|
||||
if(isnull(modified_turfs[target]))
|
||||
return
|
||||
target.RemoveElement(/datum/element/forced_gravity, modified_turfs[target])
|
||||
var/grav_value = modified_turfs[target] || 0
|
||||
target.RemoveElement(/datum/element/forced_gravity, grav_value)
|
||||
modified_turfs -= target
|
||||
|
||||
// Subtype which pops up a balloon alert when a mob enters the field
|
||||
/datum/proximity_monitor/advanced/gravity/warns_on_entrance
|
||||
/// This is a list of mob refs that have recently entered the field.
|
||||
/// We track it so that we don't spam a player who is stutter stepping in and out with balloon alerts.
|
||||
var/list/recently_warned
|
||||
|
||||
/datum/proximity_monitor/advanced/gravity/warns_on_entrance/setup_field_turf(turf/target)
|
||||
. = ..()
|
||||
for(var/mob/living/guy in target)
|
||||
warn_mob(guy, target)
|
||||
|
||||
/datum/proximity_monitor/advanced/gravity/warns_on_entrance/cleanup_field_turf(turf/target)
|
||||
. = ..()
|
||||
for(var/mob/living/guy in target)
|
||||
warn_mob(guy, target)
|
||||
|
||||
/datum/proximity_monitor/advanced/gravity/warns_on_entrance/field_edge_crossed(atom/movable/movable, turf/location)
|
||||
. = ..()
|
||||
if(isliving(movable))
|
||||
warn_mob(movable, location)
|
||||
|
||||
/datum/proximity_monitor/advanced/gravity/warns_on_entrance/field_edge_uncrossed(atom/movable/movable, turf/location)
|
||||
. = ..()
|
||||
if(isliving(movable))
|
||||
warn_mob(movable, location)
|
||||
|
||||
/datum/proximity_monitor/advanced/gravity/warns_on_entrance/proc/warn_mob(mob/living/to_warn, turf/location)
|
||||
var/mob_ref_key = REF(to_warn)
|
||||
if(mob_ref_key in recently_warned)
|
||||
return
|
||||
|
||||
location.balloon_alert(to_warn, "gravity [(location in modified_turfs) ? "shifts!" : "reverts..."]")
|
||||
LAZYADD(recently_warned, mob_ref_key)
|
||||
addtimer(CALLBACK(src, PROC_REF(clear_recent_warning), mob_ref_key), 3 SECONDS)
|
||||
|
||||
/datum/proximity_monitor/advanced/gravity/warns_on_entrance/proc/clear_recent_warning(mob_ref_key)
|
||||
LAZYREMOVE(recently_warned, mob_ref_key)
|
||||
|
||||
Reference in New Issue
Block a user