mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 13:10:02 +01:00
Light dreaming refactor + new dream (#78996)
## About The Pull Request Makes it so new dream types can be more easily added to the game with effects within them beyond just some text being displayed if you want. I added a dream that plays a random sound file available in the game files to demonstrate how it's used. Mainly I wanted this out of the way for another thing I'm working on. I also made it so if the sound subsystem fails to reserve a channel it throws a runtime since this happening is likely always going to result in a bug, like it did while I was testing this. ## Changelog 🆑 add: New dream that plays sound at you /🆑
This commit is contained in:
@@ -19,14 +19,94 @@
|
||||
|
||||
/mob/living/carbon/proc/dream()
|
||||
set waitfor = FALSE
|
||||
var/list/dream_fragments = list()
|
||||
|
||||
var/datum/dream/chosen_dream = pick_weight(GLOB.dreams)
|
||||
|
||||
dreaming = TRUE
|
||||
dream_sequence(chosen_dream.GenerateDream(src), chosen_dream)
|
||||
|
||||
/**
|
||||
* Displays the passed list of dream fragments to a sleeping carbon.
|
||||
*
|
||||
* Displays the first string of the passed dream fragments, then either ends the dream sequence
|
||||
* or performs a callback on itself depending on if there are any remaining dream fragments to display.
|
||||
*
|
||||
* Arguments:
|
||||
* * dream_fragments - A list of strings, in the order they will be displayed.
|
||||
* * current_dream - The dream datum used for the current dream
|
||||
*/
|
||||
|
||||
/mob/living/carbon/proc/dream_sequence(list/dream_fragments, datum/dream/current_dream)
|
||||
if(stat != UNCONSCIOUS || HAS_TRAIT(src, TRAIT_CRITICAL_CONDITION))
|
||||
dreaming = FALSE
|
||||
current_dream.OnDreamEnd(src)
|
||||
return
|
||||
var/next_message = dream_fragments[1]
|
||||
dream_fragments.Cut(1,2)
|
||||
|
||||
if(istype(next_message, /datum/callback))
|
||||
var/datum/callback/something_happens = next_message
|
||||
next_message = something_happens.InvokeAsync(src)
|
||||
|
||||
to_chat(src, span_notice("<i>... [next_message] ...</i>"))
|
||||
|
||||
if(LAZYLEN(dream_fragments))
|
||||
var/next_wait = rand(10, 30)
|
||||
if(current_dream.sleep_until_finished)
|
||||
AdjustSleeping(next_wait)
|
||||
addtimer(CALLBACK(src, PROC_REF(dream_sequence), dream_fragments, current_dream), next_wait)
|
||||
else
|
||||
dreaming = FALSE
|
||||
current_dream.OnDreamEnd(src)
|
||||
|
||||
//-------------------------
|
||||
// DREAM DATUMS
|
||||
|
||||
GLOBAL_LIST_INIT(dreams, populate_dream_list())
|
||||
|
||||
/proc/populate_dream_list()
|
||||
var/list/output = list()
|
||||
for(var/datum/dream/dream_type as anything in subtypesof(/datum/dream))
|
||||
output[new dream_type] = initial(dream_type.weight)
|
||||
return output
|
||||
|
||||
/**
|
||||
* Contains all the behavior needed to play a kind of dream.
|
||||
* All dream types get randomly selected from based on weight when an appropriate mobs dreams.
|
||||
*/
|
||||
/datum/dream
|
||||
/// The relative chance this dream will be randomly selected
|
||||
var/weight = 0
|
||||
|
||||
/// Causes the mob to sleep long enough for the dream to finish if begun
|
||||
var/sleep_until_finished = FALSE
|
||||
|
||||
/**
|
||||
* Called when beginning a new dream for the dreamer.
|
||||
* Gives back a list of dream events. Events can be text or callbacks that return text.
|
||||
*/
|
||||
/datum/dream/proc/GenerateDream(mob/living/carbon/dreamer)
|
||||
return list()
|
||||
|
||||
/**
|
||||
* Called when the dream ends or is interrupted.
|
||||
*/
|
||||
/datum/dream/proc/OnDreamEnd(mob/living/carbon/dreamer)
|
||||
return
|
||||
|
||||
/// The classic random dream of various words that might form a cohesive narrative, but usually wont
|
||||
/datum/dream/random
|
||||
weight = 1000
|
||||
|
||||
/datum/dream/random/GenerateDream(mob/living/carbon/dreamer)
|
||||
var/list/custom_dream_nouns = list()
|
||||
var/fragment = ""
|
||||
|
||||
for(var/obj/item/bedsheet/sheet in loc)
|
||||
for(var/obj/item/bedsheet/sheet in dreamer.loc)
|
||||
custom_dream_nouns += sheet.dream_messages
|
||||
|
||||
dream_fragments += "you see"
|
||||
. = list()
|
||||
. += "you see"
|
||||
|
||||
//Subject
|
||||
if(custom_dream_nouns.len && prob(90))
|
||||
@@ -40,7 +120,7 @@
|
||||
fragment = replacetext(fragment, "%ADJECTIVE% ", "")
|
||||
if(findtext(fragment, "%A% "))
|
||||
fragment = "\a [replacetext(fragment, "%A% ", "")]"
|
||||
dream_fragments += fragment
|
||||
. += fragment
|
||||
|
||||
//Verb
|
||||
fragment = ""
|
||||
@@ -51,10 +131,9 @@
|
||||
else
|
||||
fragment += "will "
|
||||
fragment += pick(GLOB.verbs)
|
||||
dream_fragments += fragment
|
||||
. += fragment
|
||||
|
||||
if(prob(25))
|
||||
dream_sequence(dream_fragments)
|
||||
return
|
||||
|
||||
//Object
|
||||
@@ -66,29 +145,38 @@
|
||||
fragment = replacetext(fragment, "%ADJECTIVE% ", "")
|
||||
if(findtext(fragment, "%A% "))
|
||||
fragment = "\a [replacetext(fragment, "%A% ", "")]"
|
||||
dream_fragments += fragment
|
||||
. += fragment
|
||||
|
||||
dreaming = TRUE
|
||||
dream_sequence(dream_fragments)
|
||||
/// Dream plays a random sound at you, chosen from all sounds in the folder
|
||||
/datum/dream/hear_something
|
||||
weight = 500
|
||||
|
||||
/**
|
||||
* Displays the passed list of dream fragments to a sleeping carbon.
|
||||
*
|
||||
* Displays the first string of the passed dream fragments, then either ends the dream sequence
|
||||
* or performs a callback on itself depending on if there are any remaining dream fragments to display.
|
||||
*
|
||||
* Arguments:
|
||||
* * dream_fragments - A list of strings, in the order they will be displayed.
|
||||
*/
|
||||
var/reserved_sound_channel
|
||||
|
||||
/mob/living/carbon/proc/dream_sequence(list/dream_fragments)
|
||||
if(stat != UNCONSCIOUS || HAS_TRAIT(src, TRAIT_CRITICAL_CONDITION))
|
||||
dreaming = FALSE
|
||||
return
|
||||
var/next_message = dream_fragments[1]
|
||||
dream_fragments.Cut(1,2)
|
||||
to_chat(src, span_notice("<i>... [next_message] ...</i>"))
|
||||
if(LAZYLEN(dream_fragments))
|
||||
addtimer(CALLBACK(src, PROC_REF(dream_sequence), dream_fragments), rand(10,30))
|
||||
else
|
||||
dreaming = FALSE
|
||||
/datum/dream/hear_something/New()
|
||||
. = ..()
|
||||
RegisterSignal(SSsounds, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(ReserveSoundChannel))
|
||||
|
||||
/datum/dream/hear_something/GenerateDream(mob/living/carbon/dreamer)
|
||||
. = ..()
|
||||
. += pick("you wind up a toy", "you hear something strange", "you pick out a record to play", "you hit shuffle on your music player")
|
||||
. += CALLBACK(src, PROC_REF(PlayRandomSound))
|
||||
. += "it reminds you of something"
|
||||
|
||||
/datum/dream/hear_something/OnDreamEnd(mob/living/carbon/dreamer)
|
||||
. = ..()
|
||||
// In case we play some long ass music track
|
||||
addtimer(CALLBACK(src, PROC_REF(StopSound), dreamer), 5 SECONDS)
|
||||
|
||||
/datum/dream/hear_something/proc/ReserveSoundChannel()
|
||||
reserved_sound_channel = SSsounds.reserve_sound_channel(src)
|
||||
UnregisterSignal(SSsounds, COMSIG_SUBSYSTEM_POST_INITIALIZE)
|
||||
|
||||
/datum/dream/hear_something/proc/PlayRandomSound(mob/living/carbon/dreamer)
|
||||
var/sound/random_sound = sound(pick(SSsounds.all_sounds), channel=reserved_sound_channel)
|
||||
random_sound.status = SOUND_STREAM
|
||||
SEND_SOUND(dreamer, random_sound)
|
||||
return "you hear something you weren't expecting!"
|
||||
|
||||
/datum/dream/hear_something/proc/StopSound(mob/living/carbon/dreamer)
|
||||
SEND_SOUND(dreamer, sound(channel=reserved_sound_channel))
|
||||
|
||||
Reference in New Issue
Block a user