-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* no longer heals brute/burn * Dream Datums * NIGHTMARE NIGHTMARE NIGHTMARE * random schizo nightmares * Update code/modules/dreams/detective_nightmare.dm Co-authored-by: Zonespace <[email protected]> --------- Co-authored-by: Zonespace <[email protected]>
- Loading branch information
1 parent
e223ab9
commit e8a934a
Showing
12 changed files
with
341 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/// Dream is generic, and rollable by anyone. | ||
#define DREAM_GENERIC (1<<0) | ||
/// Dream can only be dreampt once per round per mind. | ||
#define DREAM_ONCE_PER_ROUND (1<<1) | ||
/// Dream is considered complete even if cut short. | ||
#define DREAM_CUT_SHORT_IS_COMPLETE (1<<2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
//------------------------- | ||
// DREAM DATUMS | ||
|
||
GLOBAL_LIST_EMPTY(generic_dreams_weighted) | ||
GLOBAL_LIST_EMPTY(detective_dreams_weighted) | ||
GLOBAL_LIST_EMPTY(all_dreams_weighted) | ||
|
||
/proc/init_dreams() | ||
for(var/datum/dream/dream_type as anything in subtypesof(/datum/dream)) | ||
if(isabstract(dream_type)) | ||
continue | ||
|
||
var/datum/dream/dream = new dream_type | ||
GLOB.all_dreams_weighted[dream] = initial(dream_type.weight) | ||
|
||
if(initial(dream_type.dream_flags) & DREAM_GENERIC) | ||
GLOB.generic_dreams_weighted[dream] = initial(dream_type.weight) | ||
|
||
if(istype(dream, /datum/dream/detective_nightmare)) | ||
GLOB.detective_dreams_weighted[dream] = initial(dream_type.weight) | ||
|
||
/** | ||
* 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 | ||
abstract_type = /datum/dream | ||
|
||
var/dream_flags = DREAM_GENERIC | ||
|
||
/// The relative chance this dream will be randomly selected | ||
var/weight = 1000 | ||
|
||
/// Causes the mob to sleep long enough for the dream to finish if begun | ||
var/sleep_until_finished = FALSE | ||
|
||
var/dream_cooldown = 10 SECONDS | ||
|
||
/** | ||
* 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. | ||
* The associated value is the delay FOLLOWING the message at that index, in deciseconds. | ||
*/ | ||
/datum/dream/proc/GenerateDream(mob/living/carbon/dreamer) | ||
RETURN_TYPE(/list) | ||
return list() | ||
|
||
/** | ||
* Called when the dream starts. | ||
*/ | ||
/datum/dream/proc/OnDreamStart(mob/living/carbon/dreamer) | ||
SHOULD_CALL_PARENT(TRUE) | ||
ADD_TRAIT(dreamer.mind, TRAIT_DREAMING, DREAMING_SOURCE) | ||
|
||
/** | ||
* Called when the dream ends or is interrupted. | ||
*/ | ||
/datum/dream/proc/OnDreamEnd(mob/living/carbon/dreamer, cut_short = FALSE) | ||
SHOULD_CALL_PARENT(TRUE) | ||
|
||
REMOVE_TRAIT(dreamer.mind, TRAIT_DREAMING, DREAMING_SOURCE) | ||
COOLDOWN_START(dreamer.mind, dream_cooldown, dream_cooldown) | ||
|
||
if(!cut_short || (dream_flags & DREAM_CUT_SHORT_IS_COMPLETE)) | ||
LAZYOR(dreamer.mind.finished_dream_types, type) | ||
|
||
/** | ||
* Called by dream_sequence to wrap a message in any effects. | ||
*/ | ||
/datum/dream/proc/WrapMessage(mob/living/carbon/dreamer, message) | ||
return span_notice("<i>... [message] ...</i>") | ||
|
||
/datum/dream/proc/BeginDreaming(mob/living/carbon/dreamer) | ||
set waitfor = FALSE | ||
|
||
var/list/fragments = GenerateDream(dreamer) | ||
OnDreamStart(dreamer) | ||
DreamLoop(dreamer, dreamer.mind, fragments) | ||
|
||
/** | ||
* 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: | ||
* * dreamer - The mob we're looping on. | ||
* * dreamer_mind - The mind that is dreaming. | ||
* * dream_fragments - A list of strings, in the order they will be displayed. | ||
*/ | ||
|
||
/datum/dream/proc/DreamLoop(mob/living/carbon/dreamer, datum/mind/dreamer_mind, list/dream_fragments) | ||
if(dreamer.stat != UNCONSCIOUS || QDELETED(dreamer) || (dreamer.mind != dreamer_mind)) | ||
OnDreamEnd(dreamer, TRUE) | ||
return | ||
|
||
var/next_message = dream_fragments[1] | ||
var/next_wait = dream_fragments[next_message] | ||
dream_fragments.Cut(1,2) | ||
|
||
if(istype(next_message, /datum/callback)) | ||
var/datum/callback/something_happens = next_message | ||
next_message = something_happens.Invoke(dreamer) | ||
|
||
to_chat(dreamer, WrapMessage(dreamer, next_message)) | ||
|
||
// Dream's over. | ||
if(!LAZYLEN(dream_fragments)) | ||
OnDreamEnd(dreamer) | ||
return | ||
|
||
if(sleep_until_finished) | ||
dreamer.Sleeping(next_wait + 1 SECOND) | ||
|
||
addtimer(CALLBACK(src, PROC_REF(DreamLoop), dreamer, dreamer_mind,dream_fragments), next_wait) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/datum/dream/detective_nightmare | ||
abstract_type = /datum/dream/detective_nightmare | ||
|
||
dream_flags = parent_type::dream_flags & ~DREAM_GENERIC | ||
|
||
/datum/dream/detective_nightmare/WrapMessage(mob/living/carbon/dreamer, message) | ||
return message | ||
|
||
/datum/dream/detective_nightmare/proc/get_dream_name(mob/living/carbon/dreamer) | ||
if(prob(1)) | ||
return "Harry" | ||
|
||
var/list/name_split = splittext(dreamer.mind.name, " ") | ||
return name_split[1] | ||
|
||
/datum/dream/detective_nightmare/limbic_system | ||
abstract_type = /datum/dream/detective_nightmare/limbic_system | ||
|
||
dream_flags = parent_type::dream_flags | DREAM_ONCE_PER_ROUND | DREAM_CUT_SHORT_IS_COMPLETE | ||
weight = 350 | ||
|
||
dream_cooldown = 25 SECONDS | ||
|
||
/// The fragments are deterministic, just need to replacetext the name. | ||
var/list/fragments | ||
|
||
/datum/dream/detective_nightmare/limbic_system/GenerateDream(mob/living/carbon/dreamer) | ||
. = list() | ||
var/name = get_dream_name(dreamer) | ||
|
||
for(var/fragment in fragments) | ||
.["<i>[span_statsbad(replacetext(fragment, "%NAME%", name))]</i>"] = fragments[fragment] | ||
|
||
/datum/dream/detective_nightmare/limbic_system/super_asshole | ||
fragments = list( | ||
"Hello %NAME%, I am so pleased you could join us again. NOT." = 7 SECONDS, | ||
"This station is tearing your feeble, disgusting excuse for a body to shreeeedssss." = 9 SECONDS, | ||
"You should've listened to me loooooong aaaggoooo, %NAME%. Maybe you would not be such a violent, waste of space if you had." = 12 SECONDS, | ||
"Alright then, be that way. I'll be waiting for your next visit." | ||
) | ||
|
||
/datum/dream/detective_nightmare/limbic_system/calm_asshole | ||
fragments = list( | ||
"Here we are again, my broken bird. You stay so long yet always leave, why?." = 7 SECONDS, | ||
"We think you should give up and stay with us, it will be better that way. Do you truly believe you can keep going how you are?" = 12 SECONDS, | ||
"Would you rather spend the rest of your days wasting away on an old, rickety station in the corner of the Pool?." = 12 SECONDS, | ||
"We will see you again soon, %NAME%." | ||
) | ||
|
||
/datum/dream/detective_nightmare/limbic_system/still_an_asshole | ||
fragments = list( | ||
"Welcome back %NAME%, come to visit your old pals again? Stay a while, you always do." = 7 SECONDS, | ||
"Don't be so hard on yourself, %NAME%. You may be a disappointment to those around you, a useless lump of flesh, lumbering about the station, but, what do they know?" = 12 SECONDS, | ||
"Was that too mean? I apologize, I will be more positive from here on out." = 7 SECONDS, | ||
"Oh, we're out of time. See you soon." | ||
) | ||
|
||
/datum/dream/detective_nightmare/wake_up_harry | ||
dream_flags = parent_type::dream_flags | DREAM_ONCE_PER_ROUND | DREAM_CUT_SHORT_IS_COMPLETE | ||
weight = 50 | ||
|
||
/datum/dream/detective_nightmare/wake_up_harry/GenerateDream(mob/living/carbon/dreamer) | ||
return list( | ||
"<i>[span_statsgood("... Harrier? Harrier?! ...")]</i>" = rand(1 SECOND, 3 SECONDS), | ||
"<i>[span_statsgood("... Damn it Harry wake up! ...")]</i>" = rand(1 SECOND, 3 SECONDS), | ||
"<i>[span_statsgood("... Harry I am <b>not</b> going to be the one to explain to the station how their prized Harrier DuBois overdosed on Pyrholidon, <b>again</b>. ...")]</i>", | ||
) | ||
|
||
/datum/dream/detective_nightmare/random | ||
weight = 2000 | ||
|
||
/datum/dream/detective_nightmare/random/WrapMessage(mob/living/carbon/dreamer, message) | ||
return span_statsbad("<i>... [message] ...</i>") | ||
|
||
/datum/dream/detective_nightmare/random/GenerateDream(mob/living/carbon/dreamer) | ||
. = list() | ||
|
||
var/name = get_dream_name(dreamer) | ||
|
||
var/list/options = list( | ||
"Wake up!", | ||
"Help me!", | ||
"I couldn't, I'm sorry.", | ||
"Useless.", | ||
"Tick tock tick tock tick tock tick tock", | ||
"I couldn't save them.", | ||
"*You hear a loud metallic banging.*", | ||
"Get up, %NAME%.", | ||
"Get up.", | ||
"Get out! I SAID GET OUT!", | ||
"*You hear the sound of water dripping onto ceramic.*", | ||
"%NAME%? This is the police, we know you're in there, we just want to talk. %NAME%!", | ||
"*You hear a distant gunshot, unmistakably a .44 magnum.*", | ||
"*You hear the heart wrenching screech of a terrified woman.*", | ||
"Don't go... please...", | ||
"Pleasepleasepleasepleaseplease.", | ||
"Please [dreamer.gender == MALE ? "sir" : "ma'am"] I have nowhere else to turn.", | ||
"You're a failure.", | ||
"Give up, %NAME%.", | ||
"Give up.", | ||
"Get out of my office.", | ||
) | ||
|
||
for(var/i in 1 to rand(1, 3)) | ||
if(prob(33)) | ||
.["[name]!"] = 2 SECONDS | ||
|
||
.[replacetext(pick_n_take(options), "%NAME%", name)] = 3 SECONDS | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/** | ||
* Begins the dreaming process on a sleeping carbon. | ||
* | ||
* Only one dream sequence can be active at a time. | ||
*/ | ||
|
||
/mob/living/carbon/proc/try_dream(dream_type) | ||
if(!mind || HAS_TRAIT(mind, TRAIT_DREAMING) || HAS_TRAIT(src, TRAIT_CANNOT_DREAM)) | ||
return | ||
|
||
if(!has_status_effect(/datum/status_effect/incapacitating/sleeping)) | ||
return | ||
|
||
dream_type = locate(dream_type) in GLOB.all_dreams_weighted | ||
if(dream_type) | ||
do_dream(dream_type) | ||
return TRUE | ||
|
||
if(!COOLDOWN_FINISHED(mind, dream_cooldown)) | ||
return FALSE | ||
|
||
dream_type = get_random_dream() | ||
|
||
if(dream_type) | ||
do_dream(dream_type) | ||
return TRUE | ||
return FALSE | ||
|
||
/** | ||
* Generates a dream sequence to be displayed to the sleeper. | ||
* | ||
* Generates the "dream" to display to the sleeper. A dream consists of a subject, a verb, and (most of the time) an object, displayed in sequence to the sleeper. | ||
* Dreams are generated as a list of strings stored inside dream_fragments, which is passed to and displayed in dream_sequence(). | ||
* Bedsheets on the sleeper will provide a custom subject for the dream, pulled from the dream_messages on each bedsheet. | ||
*/ | ||
/mob/living/carbon/proc/get_random_dream() | ||
// Do robots dream of robotic sheep? -- No. | ||
if(!mind || isipc(src)) | ||
return null | ||
|
||
var/list/dream_pool | ||
var/datum/dream/dream | ||
if(mind?.assigned_role?.title == JOB_DETECTIVE) | ||
dream_pool = GLOB.detective_dreams_weighted.Copy() | ||
|
||
else | ||
dream_pool = GLOB.generic_dreams_weighted.Copy() | ||
|
||
while(length(dream_pool)) | ||
dream = pick_weight(dream_pool) | ||
dream_pool -= dream | ||
|
||
if(!(dream.dream_flags & DREAM_ONCE_PER_ROUND) || !(dream.type in mind.finished_dream_types)) | ||
return dream | ||
|
||
/mob/living/carbon/proc/do_dream(datum/dream/chosen_dream) | ||
chosen_dream.BeginDreaming(src) |
Oops, something went wrong.