mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-09 07:46:20 +00:00
688 lines
25 KiB
Plaintext
688 lines
25 KiB
Plaintext
#define MINOR_INSANITY_PEN 5
|
|
#define MAJOR_INSANITY_PEN 10
|
|
#define MOOD_CATEGORY_NUTRITION "nutrition"
|
|
#define MOOD_CATEGORY_AREA_BEAUTY "area_beauty"
|
|
|
|
/**
|
|
* Mood datum
|
|
*
|
|
* Contains the logic for controlling a living mob's mood and sanity.
|
|
*/
|
|
/datum/mood
|
|
/// The parent (living) mob
|
|
var/mob/living/mob_parent
|
|
|
|
/// The total combined value of all moodlets for the mob
|
|
var/mood
|
|
/// Current sanity of the mob (ranges from 0 - 150)
|
|
var/sanity = SANITY_NEUTRAL
|
|
/// the total combined value of all visible moodlets for the mob
|
|
var/shown_mood
|
|
/// Multiplier to the sum total of mood the mob is experiencing
|
|
var/mood_modifier = 1
|
|
/// Multiplier to positive moodlet values. Stacks with mood_modifier
|
|
var/positive_mood_modifier = 1
|
|
/// Multiplier to negative moodlet values. Stacks with mood_modifier
|
|
var/negative_mood_modifier = 1
|
|
/// Multiplier to the length of positive moodlets.
|
|
/// Please don't set this to 0
|
|
var/positive_moodlet_length_modifier = 1
|
|
/// Multiplier to the length of negative moodlets.
|
|
/// Please don't set this to 0
|
|
var/negative_moodlet_length_modifier = 1
|
|
/// Used to track what stage of moodies they're on (1-9)
|
|
var/mood_level = MOOD_LEVEL_NEUTRAL
|
|
/// To track what stage of sanity they're on (1-6)
|
|
var/sanity_level = SANITY_LEVEL_NEUTRAL
|
|
/// Is the owner being punished for low mood? if so, how much?
|
|
var/insanity_effect = 0
|
|
/// The screen object for the current mood level
|
|
var/atom/movable/screen/mood/mood_screen_object
|
|
|
|
/// List of mood events currently active on this datum
|
|
var/list/mood_events = list()
|
|
|
|
/datum/mood/New(mob/living/mob_to_make_moody)
|
|
if (!istype(mob_to_make_moody))
|
|
stack_trace("Tried to apply mood to a non-living atom!")
|
|
qdel(src)
|
|
return
|
|
|
|
START_PROCESSING(SSmood, src)
|
|
|
|
mob_parent = mob_to_make_moody
|
|
|
|
RegisterSignal(mob_to_make_moody, COMSIG_MOB_HUD_CREATED, PROC_REF(modify_hud))
|
|
RegisterSignal(mob_to_make_moody, COMSIG_ENTER_AREA, PROC_REF(check_area_mood))
|
|
RegisterSignal(mob_to_make_moody, COMSIG_EXIT_AREA, PROC_REF(exit_area))
|
|
RegisterSignal(mob_to_make_moody, COMSIG_LIVING_REVIVE, PROC_REF(on_revive))
|
|
RegisterSignal(mob_to_make_moody, COMSIG_MOB_STATCHANGE, PROC_REF(handle_mob_death))
|
|
RegisterSignal(mob_to_make_moody, COMSIG_QDELETING, PROC_REF(clear_parent_ref))
|
|
|
|
var/area/our_area = get_area(mob_to_make_moody)
|
|
if(our_area)
|
|
check_area_mood(mob_to_make_moody, our_area)
|
|
|
|
mob_to_make_moody.become_area_sensitive(MOOD_DATUM_TRAIT)
|
|
if(mob_to_make_moody.hud_used)
|
|
modify_hud()
|
|
var/datum/hud/hud = mob_to_make_moody.hud_used
|
|
hud.show_hud(hud.hud_version)
|
|
|
|
/datum/mood/proc/clear_parent_ref()
|
|
SIGNAL_HANDLER
|
|
|
|
unmodify_hud()
|
|
mob_parent.lose_area_sensitivity(MOOD_DATUM_TRAIT)
|
|
UnregisterSignal(mob_parent, list(COMSIG_MOB_HUD_CREATED, COMSIG_ENTER_AREA, COMSIG_EXIT_AREA, COMSIG_LIVING_REVIVE, COMSIG_MOB_STATCHANGE, COMSIG_QDELETING))
|
|
var/area/our_area = get_area(mob_parent)
|
|
if(our_area)
|
|
UnregisterSignal(our_area, COMSIG_AREA_BEAUTY_UPDATED)
|
|
|
|
mob_parent = null
|
|
|
|
/datum/mood/Destroy(force)
|
|
STOP_PROCESSING(SSmood, src)
|
|
QDEL_LIST_ASSOC_VAL(mood_events)
|
|
return ..()
|
|
|
|
/datum/mood/process(seconds_per_tick)
|
|
switch(mood_level)
|
|
if(MOOD_LEVEL_SAD4)
|
|
adjust_sanity(-0.3 * seconds_per_tick, SANITY_INSANE)
|
|
if(MOOD_LEVEL_SAD3)
|
|
adjust_sanity(-0.15 * seconds_per_tick, SANITY_CRAZY)
|
|
if(MOOD_LEVEL_SAD2)
|
|
adjust_sanity(-0.1 * seconds_per_tick, SANITY_UNSTABLE)
|
|
if(MOOD_LEVEL_SAD1)
|
|
adjust_sanity(-0.05 * seconds_per_tick, SANITY_UNSTABLE)
|
|
if(MOOD_LEVEL_NEUTRAL)
|
|
adjust_sanity(0, SANITY_UNSTABLE) //This makes sure that mood gets increased should you be below the minimum.
|
|
if(MOOD_LEVEL_HAPPY1)
|
|
adjust_sanity(0.2 * seconds_per_tick, SANITY_UNSTABLE)
|
|
if(MOOD_LEVEL_HAPPY2)
|
|
adjust_sanity(0.3 * seconds_per_tick, SANITY_UNSTABLE)
|
|
if(MOOD_LEVEL_HAPPY3)
|
|
adjust_sanity(0.4 * seconds_per_tick, SANITY_NEUTRAL, SANITY_MAXIMUM)
|
|
if(MOOD_LEVEL_HAPPY4)
|
|
adjust_sanity(0.6 * seconds_per_tick, SANITY_NEUTRAL, SANITY_MAXIMUM)
|
|
|
|
/datum/mood/proc/handle_mob_death(datum/source, new_stat, old_stat)
|
|
SIGNAL_HANDLER
|
|
|
|
if (old_stat == DEAD && new_stat != DEAD)
|
|
START_PROCESSING(SSmood, src)
|
|
else if (old_stat != DEAD && new_stat == DEAD)
|
|
STOP_PROCESSING(SSmood, src)
|
|
|
|
/// Handles mood given by nutrition
|
|
/datum/mood/proc/update_nutrition_moodlets()
|
|
if(HAS_TRAIT(mob_parent, TRAIT_NOHUNGER))
|
|
clear_mood_event(MOOD_CATEGORY_NUTRITION)
|
|
return FALSE
|
|
|
|
if(HAS_TRAIT(mob_parent, TRAIT_GLUTTON))
|
|
add_mood_event(MOOD_CATEGORY_NUTRITION, /datum/mood_event/hungry) //you'll never get enough
|
|
return TRUE
|
|
|
|
if(HAS_TRAIT(mob_parent, TRAIT_FAT) && !HAS_TRAIT(mob_parent, TRAIT_VORACIOUS))
|
|
add_mood_event(MOOD_CATEGORY_NUTRITION, /datum/mood_event/fat)
|
|
return TRUE
|
|
|
|
switch(mob_parent.nutrition)
|
|
if(NUTRITION_LEVEL_FULL to INFINITY)
|
|
add_mood_event(MOOD_CATEGORY_NUTRITION, HAS_TRAIT(mob_parent, TRAIT_VORACIOUS) ? /datum/mood_event/wellfed : /datum/mood_event/too_wellfed)
|
|
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
|
|
add_mood_event(MOOD_CATEGORY_NUTRITION, /datum/mood_event/wellfed)
|
|
if( NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
|
add_mood_event(MOOD_CATEGORY_NUTRITION, /datum/mood_event/fed)
|
|
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
|
clear_mood_event(MOOD_CATEGORY_NUTRITION)
|
|
if(NUTRITION_LEVEL_VERY_HUNGRY to NUTRITION_LEVEL_HUNGRY)
|
|
add_mood_event(MOOD_CATEGORY_NUTRITION, /datum/mood_event/hungry)
|
|
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_VERY_HUNGRY)
|
|
add_mood_event(MOOD_CATEGORY_NUTRITION, /datum/mood_event/hungry_very)
|
|
if(0 to NUTRITION_LEVEL_STARVING)
|
|
add_mood_event(MOOD_CATEGORY_NUTRITION, /datum/mood_event/starving)
|
|
|
|
return TRUE
|
|
|
|
/**
|
|
* Adds a mood event to the mob
|
|
*
|
|
* Arguments:
|
|
* * category - (text) category of the mood event - see /datum/mood_event for category explanation
|
|
* * type - (path) any /datum/mood_event
|
|
*/
|
|
/datum/mood/proc/add_mood_event(category, new_type, ...)
|
|
if (!ispath(new_type, /datum/mood_event))
|
|
CRASH("A non path ([new_type]), was used to add a mood event. This shouldn't be happening.")
|
|
if (!istext(category))
|
|
category = REF(category)
|
|
|
|
var/list/params = args.Copy(3)
|
|
var/datum/mood_event/new_event = new new_type(category)
|
|
if(!new_event.can_effect_mob(arglist(list(src, mob_parent) + params)))
|
|
qdel(new_event)
|
|
return
|
|
|
|
var/datum/mood_event/existing_event = mood_events[category]
|
|
if(existing_event)
|
|
var/continue_adding = FALSE
|
|
if(existing_event.type == new_event.type)
|
|
continue_adding = existing_event.be_refreshed(arglist(list(src) + params))
|
|
else
|
|
continue_adding = existing_event.be_replaced(arglist(list(src, new_event) + params))
|
|
if(!continue_adding)
|
|
update_mood()
|
|
qdel(new_event)
|
|
return
|
|
clear_mood_event(category)
|
|
|
|
new_event.on_add(src, mob_parent, params)
|
|
mood_events[category] = new_event
|
|
update_mood()
|
|
if(new_event.mood_change == 0 || new_event.hidden)
|
|
return
|
|
if(new_event.mood_change > 0)
|
|
add_personality_mood_to_viewers(mob_parent, "other_good_moodlet", list(
|
|
/datum/personality/empathetic = /datum/mood_event/empathetic_happy,
|
|
/datum/personality/misanthropic = /datum/mood_event/misanthropic_sad
|
|
), range = 4)
|
|
else
|
|
add_personality_mood_to_viewers(mob_parent, "other_bad_moodlet", list(
|
|
/datum/personality/empathetic = /datum/mood_event/empathetic_sad,
|
|
/datum/personality/misanthropic = /datum/mood_event/misanthropic_happy
|
|
), range = 4)
|
|
|
|
/**
|
|
* Removes a mood event from the mob
|
|
*
|
|
* Arguments:
|
|
* * category - (Text) Removes the mood event with the given category
|
|
*/
|
|
/datum/mood/proc/clear_mood_event(category)
|
|
if (!istext(category))
|
|
category = REF(category)
|
|
|
|
var/datum/mood_event/event = mood_events[category]
|
|
if (!event)
|
|
return
|
|
|
|
mood_events -= category
|
|
qdel(event)
|
|
update_mood()
|
|
|
|
/datum/mood/proc/get_mood_event(category)
|
|
return mood_events[category]
|
|
|
|
/// Updates the mobs mood.
|
|
/// Called after mood events have been added/removed.
|
|
/datum/mood/proc/update_mood()
|
|
if(QDELETED(mob_parent)) //don't bother updating their mood if they're about to be salty anyway. (in other words, we're about to be destroyed too anyway.)
|
|
return
|
|
mood = 0
|
|
shown_mood = 0
|
|
|
|
for(var/category in mood_events)
|
|
var/datum/mood_event/the_event = mood_events[category]
|
|
var/event_mood = the_event.mood_change
|
|
event_mood *= max((event_mood > 0) ? positive_mood_modifier : negative_mood_modifier, 0)
|
|
mood += event_mood
|
|
if (!the_event.hidden)
|
|
shown_mood += event_mood
|
|
|
|
mood *= max(mood_modifier, 0)
|
|
shown_mood *= max(mood_modifier, 0)
|
|
|
|
switch(mood)
|
|
if (-INFINITY to MOOD_SAD4)
|
|
mood_level = MOOD_LEVEL_SAD4
|
|
if (MOOD_SAD4 to MOOD_SAD3)
|
|
mood_level = MOOD_LEVEL_SAD3
|
|
if (MOOD_SAD3 to MOOD_SAD2)
|
|
mood_level = MOOD_LEVEL_SAD2
|
|
if (MOOD_SAD2 to MOOD_SAD1)
|
|
mood_level = MOOD_LEVEL_SAD1
|
|
if (MOOD_SAD1 to MOOD_HAPPY1)
|
|
mood_level = MOOD_LEVEL_NEUTRAL
|
|
if (MOOD_HAPPY1 to MOOD_HAPPY2)
|
|
mood_level = MOOD_LEVEL_HAPPY1
|
|
if (MOOD_HAPPY2 to MOOD_HAPPY3)
|
|
mood_level = MOOD_LEVEL_HAPPY2
|
|
if (MOOD_HAPPY3 to MOOD_HAPPY4)
|
|
mood_level = MOOD_LEVEL_HAPPY3
|
|
if (MOOD_HAPPY4 to INFINITY)
|
|
mood_level = MOOD_LEVEL_HAPPY4
|
|
|
|
update_mood_icon()
|
|
SEND_SIGNAL(mob_parent, COMSIG_CARBON_MOOD_UPDATE)
|
|
|
|
/// Updates the mob's mood icon
|
|
/datum/mood/proc/update_mood_icon()
|
|
if (!(mob_parent.client || mob_parent.hud_used) || isnull(mood_screen_object))
|
|
return
|
|
|
|
mood_screen_object.cut_overlays()
|
|
mood_screen_object.color = initial(mood_screen_object.color)
|
|
|
|
// lets see if we have an special icons to show instead of the normal mood levels
|
|
var/list/conflicting_moodies = list()
|
|
var/highest_absolute_mood = 0
|
|
for (var/category in mood_events)
|
|
var/datum/mood_event/the_event = mood_events[category]
|
|
if (!the_event.special_screen_obj)
|
|
continue
|
|
if (!the_event.special_screen_replace)
|
|
mood_screen_object.add_overlay(the_event.special_screen_obj)
|
|
else
|
|
conflicting_moodies += the_event
|
|
var/absmood = abs(the_event.mood_change)
|
|
highest_absolute_mood = absmood > highest_absolute_mood ? absmood : highest_absolute_mood
|
|
|
|
switch(sanity_level)
|
|
if (SANITY_LEVEL_GREAT)
|
|
mood_screen_object.color = "#2eeb9a"
|
|
if (SANITY_LEVEL_NEUTRAL)
|
|
mood_screen_object.color = "#86d656"
|
|
if (SANITY_LEVEL_DISTURBED)
|
|
mood_screen_object.color = "#4b96c4"
|
|
if (SANITY_LEVEL_UNSTABLE)
|
|
mood_screen_object.color = "#dfa65b"
|
|
if (SANITY_LEVEL_CRAZY)
|
|
mood_screen_object.color = "#f38943"
|
|
if (SANITY_LEVEL_INSANE)
|
|
mood_screen_object.color = "#f15d36"
|
|
|
|
if (!conflicting_moodies.len) // theres no special icons, use the normal icon states
|
|
//SKYRAT EDIT ADDITION BEGIN - ALEXITHYMIA
|
|
if(HAS_TRAIT(mob_parent, TRAIT_MOOD_NOEXAMINE))
|
|
mood_screen_object.icon_state = "mood5"
|
|
mood_screen_object.color = "#4b96c4"
|
|
return
|
|
//SKYRAT EDIT ADDITION END
|
|
mood_screen_object.icon_state = "mood[mood_level]"
|
|
return
|
|
|
|
for (var/datum/mood_event/conflicting_event as anything in conflicting_moodies)
|
|
if (abs(conflicting_event.mood_change) == highest_absolute_mood)
|
|
mood_screen_object.icon_state = "[conflicting_event.special_screen_obj]"
|
|
break
|
|
|
|
/// Sets up the mood HUD object
|
|
/datum/mood/proc/modify_hud(datum/source)
|
|
SIGNAL_HANDLER
|
|
|
|
var/datum/hud/hud = mob_parent.hud_used
|
|
mood_screen_object = new
|
|
mood_screen_object.color = "#4b96c4"
|
|
hud.infodisplay += mood_screen_object
|
|
RegisterSignal(hud, COMSIG_QDELETING, PROC_REF(unmodify_hud))
|
|
RegisterSignal(mood_screen_object, COMSIG_SCREEN_ELEMENT_CLICK, PROC_REF(hud_click))
|
|
|
|
/// Removes the mood HUD object
|
|
/datum/mood/proc/unmodify_hud(datum/source)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!mood_screen_object)
|
|
return
|
|
var/datum/hud/hud = mob_parent.hud_used
|
|
if(hud?.infodisplay)
|
|
hud.infodisplay -= mood_screen_object
|
|
QDEL_NULL(mood_screen_object)
|
|
UnregisterSignal(hud, COMSIG_QDELETING)
|
|
|
|
/// Handles clicking on the mood HUD object
|
|
/datum/mood/proc/hud_click(datum/source, location, control, params, mob/user)
|
|
SIGNAL_HANDLER
|
|
|
|
if(user != mob_parent)
|
|
return
|
|
if(user.stat >= UNCONSCIOUS)
|
|
return
|
|
print_mood(user)
|
|
|
|
/// Prints the users mood, sanity, and moodies to chat
|
|
/datum/mood/proc/print_mood(mob/user)
|
|
var/msg = "[span_info("<EM>My current mental status:</EM>")]<br>"
|
|
|
|
if(!HAS_TRAIT(src, TRAIT_NOHUNGER))
|
|
msg += span_notice("My hunger: ")
|
|
var/nutrition = mob_parent.nutrition
|
|
switch(nutrition)
|
|
if(NUTRITION_LEVEL_FULL to INFINITY)
|
|
msg += "[span_info("I'm completely stuffed!")]<br>"
|
|
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
|
|
msg += "[span_info("I'm well fed!")]<br>"
|
|
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
|
msg += "[span_info("I'm not hungry.")]<br>"
|
|
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
|
msg += "[span_info("I could use a bite to eat.")]<br>"
|
|
if(NUTRITION_LEVEL_VERY_HUNGRY to NUTRITION_LEVEL_HUNGRY)
|
|
msg += "[span_warning("I'm feeling hungry.")]<br>"
|
|
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_VERY_HUNGRY)
|
|
msg += "[span_warning("I feel quite hungry.")]<br>"
|
|
if(0 to NUTRITION_LEVEL_STARVING)
|
|
msg += "[span_boldwarning("I'm starving!")]<br>"
|
|
|
|
// BUBBER EDIT CHANGE BEGIN - ALCOHOL PROCESSING
|
|
/*
|
|
var/drunkness = mob_parent.get_drunk_amount()
|
|
if(drunkness >= 1)
|
|
msg += span_notice("My current drunkenness: ")
|
|
switch(drunkness)
|
|
if(1 to 10)
|
|
msg += "[span_info("I'm feeling a little tipsy.")]<br>"
|
|
if(11 to 21)
|
|
msg += "[span_info("I'm feeling a bit drunk.")]<br>"
|
|
if(21 to 41)
|
|
msg += "[span_info("I'm feeling quite drunk.")]<br>"
|
|
if(41 to 61)
|
|
msg += "[span_info("I'm feeling very drunk.")]<br>"
|
|
if(61 to 81)
|
|
msg += "[span_warning("I'm feeling like a mess.")]<br>"
|
|
if(81 to INFINITY)
|
|
msg += "[span_boldwarning("I'm completely wasted.")]<br>"
|
|
*/
|
|
|
|
var/drunkness = get_drunk_mood(mob_parent)
|
|
if(drunkness)
|
|
msg += span_notice("My current drunkenness: [drunkness]")
|
|
if(get_alcohol_processing(mob_parent))
|
|
msg += "[span_info(" I'm still processing what I drank...")]<br>"
|
|
else
|
|
msg += "<br>"
|
|
// BUBBER EDIT CHANGE END - ALCOHOL PROCESSING
|
|
|
|
msg += span_notice("My current sanity: ") //Long term
|
|
//ORIGINAL
|
|
/*
|
|
switch(sanity)
|
|
if(SANITY_GREAT to INFINITY)
|
|
msg += "[span_boldnicegreen("My mind feels like a temple!")]<br>"
|
|
if(SANITY_NEUTRAL to SANITY_GREAT)
|
|
msg += "[span_nicegreen("I have been feeling great lately!")]<br>"
|
|
if(SANITY_DISTURBED to SANITY_NEUTRAL)
|
|
msg += "[span_nicegreen("I have felt quite decent lately.")]<br>"
|
|
if(SANITY_UNSTABLE to SANITY_DISTURBED)
|
|
msg += "[span_warning("I'm feeling a little bit unhinged...")]<br>"
|
|
if(SANITY_CRAZY to SANITY_UNSTABLE)
|
|
msg += "[span_warning("I'm freaking out!!")]<br>"
|
|
if(SANITY_INSANE to SANITY_CRAZY)
|
|
msg += "[span_boldwarning("AHAHAHAHAHAHAHAHAHAH!!")]\n"
|
|
*/
|
|
//SKYRAT EDIT CHANGE BEGIN - ALEXITHYMIA
|
|
if(!HAS_TRAIT(user, TRAIT_MOOD_NOEXAMINE))
|
|
switch(sanity)
|
|
if(SANITY_GREAT to INFINITY)
|
|
msg += "[span_nicegreen("My mind feels like a temple!")]\n"
|
|
if(SANITY_NEUTRAL to SANITY_GREAT)
|
|
msg += "[span_nicegreen("I have been feeling great lately!")]\n"
|
|
if(SANITY_DISTURBED to SANITY_NEUTRAL)
|
|
msg += "[span_nicegreen("I have felt quite decent lately.")]\n"
|
|
if(SANITY_UNSTABLE to SANITY_DISTURBED)
|
|
msg += "[span_warning("I'm feeling a little bit unhinged...")]\n"
|
|
if(SANITY_CRAZY to SANITY_UNSTABLE)
|
|
msg += "[span_boldwarning("I'm freaking out!!")]\n"
|
|
if(SANITY_INSANE to SANITY_CRAZY)
|
|
msg += "[span_boldwarning("AHAHAHAHAHAHAHAHAHAH!!")]\n"
|
|
else
|
|
msg += "[span_notice("I don't really know.")]\n"
|
|
//SKYRAT EDIT CHANGE END
|
|
|
|
msg += span_notice("My current mood: ") //Short term
|
|
//ORIGINAL
|
|
/*
|
|
switch(mood_level)
|
|
if(MOOD_LEVEL_SAD4)
|
|
msg += "[span_boldwarning("I wish I was dead!")]<br>"
|
|
if(MOOD_LEVEL_SAD3)
|
|
msg += "[span_boldwarning("I feel terrible...")]<br>"
|
|
if(MOOD_LEVEL_SAD2)
|
|
msg += "[span_boldwarning("I feel very upset.")]<br>"
|
|
if(MOOD_LEVEL_SAD1)
|
|
msg += "[span_warning("I'm a bit sad.")]<br>"
|
|
if(MOOD_LEVEL_NEUTRAL)
|
|
msg += "[span_grey("I'm alright.")]<br>"
|
|
if(MOOD_LEVEL_HAPPY1)
|
|
msg += "[span_nicegreen("I feel pretty okay.")]<br>"
|
|
if(MOOD_LEVEL_HAPPY2)
|
|
msg += "[span_boldnicegreen("I feel pretty good.")]<br>"
|
|
if(MOOD_LEVEL_HAPPY3)
|
|
msg += "[span_boldnicegreen("I feel amazing!")]<br>"
|
|
if(MOOD_LEVEL_HAPPY4)
|
|
msg += "[span_boldnicegreen("I love life!")]\n"
|
|
*/
|
|
//SKYRAT EDIT CHANGE BEGIN - ALEXITHYMIA / ALCOHOL_PROCESSING
|
|
if(!HAS_TRAIT(user, TRAIT_MOOD_NOEXAMINE))
|
|
switch(mood_level)
|
|
if(MOOD_LEVEL_SAD4)
|
|
msg += "[span_boldwarning("I wish I was dead!")]\n"
|
|
if(MOOD_LEVEL_SAD3)
|
|
msg += "[span_boldwarning("I feel terrible...")]\n"
|
|
if(MOOD_LEVEL_SAD2)
|
|
msg += "[span_boldwarning("I feel very upset.")]\n"
|
|
if(MOOD_LEVEL_SAD1)
|
|
msg += "[span_warning("I'm a bit sad.")]\n"
|
|
if(MOOD_LEVEL_NEUTRAL)
|
|
msg += "[span_grey("I'm alright.")]\n"
|
|
if(MOOD_LEVEL_HAPPY1)
|
|
msg += "[span_nicegreen("I feel pretty okay.")]\n"
|
|
if(MOOD_LEVEL_HAPPY2)
|
|
msg += "[span_boldnicegreen("I feel pretty good.")]\n"
|
|
if(MOOD_LEVEL_HAPPY3)
|
|
msg += "[span_boldnicegreen("I feel amazing!")]\n"
|
|
if(MOOD_LEVEL_HAPPY4)
|
|
msg += "[span_boldnicegreen("I love life!")]\n"
|
|
else
|
|
msg += "[span_notice("No clue.")]\n"
|
|
|
|
var/list/additional_lines = list()
|
|
SEND_SIGNAL(user, COMSIG_CARBON_MOOD_CHECK, additional_lines)
|
|
if (length(additional_lines))
|
|
msg += "[additional_lines.Join("<br>")]<br>"
|
|
|
|
msg += "[span_notice("Moodlets:")]<br>"//All moodlets
|
|
if(mood_events.len && !HAS_TRAIT(user, TRAIT_MOOD_NOEXAMINE)) // ORIGINAL - //if(mood_events.len)
|
|
//SKYRAT EDIT CHANGE END
|
|
for(var/category in mood_events)
|
|
var/datum/mood_event/event = mood_events[category]
|
|
msg += "• "
|
|
switch(event.mood_change)
|
|
if(-INFINITY to MOOD_SAD2)
|
|
msg += "[span_boldwarning(event.description)]<br>"
|
|
if(MOOD_SAD2 to MOOD_SAD1)
|
|
msg += "[span_warning(event.description)]<br>"
|
|
if(MOOD_SAD1 to MOOD_NEUTRAL)
|
|
msg += "[span_grey(event.description)]<br>"
|
|
if(MOOD_NEUTRAL to MOOD_HAPPY1)
|
|
msg += "[span_info(event.description)]<br>"
|
|
if(MOOD_HAPPY1 to MOOD_HAPPY2)
|
|
msg += "[span_nicegreen(event.description)]<br>"
|
|
if(MOOD_HAPPY2 to INFINITY)
|
|
msg += "[span_boldnicegreen(event.description)]<br>"
|
|
else
|
|
msg += "• [span_grey("I don't have much of a reaction to anything right now.")]<br>"
|
|
|
|
if(LAZYLEN(mob_parent.quirks))
|
|
msg += span_notice("You have these quirks: [mob_parent.get_quirk_string(FALSE, CAT_QUIRK_ALL)].")
|
|
|
|
to_chat(user, boxed_message(msg))
|
|
|
|
/// Updates the mob's moodies, if the area provides a mood bonus
|
|
/datum/mood/proc/check_area_mood(datum/source, area/new_area)
|
|
SIGNAL_HANDLER
|
|
|
|
RegisterSignal(new_area, COMSIG_AREA_BEAUTY_UPDATED, PROC_REF(update_beauty))
|
|
|
|
update_beauty(new_area)
|
|
if (new_area.mood_bonus && (!new_area.mood_trait || HAS_TRAIT(source, new_area.mood_trait)))
|
|
add_mood_event("area", /datum/mood_event/area, new_area.mood_bonus, new_area.mood_message)
|
|
else
|
|
clear_mood_event("area")
|
|
|
|
/// Updates the mob's given beauty moodie, based on the area
|
|
/datum/mood/proc/update_beauty(area/area_to_beautify)
|
|
SIGNAL_HANDLER
|
|
if (area_to_beautify.outdoors) // if we're outside, we don't care
|
|
clear_mood_event(MOOD_CATEGORY_AREA_BEAUTY)
|
|
return
|
|
|
|
if(HAS_MIND_TRAIT(mob_parent, TRAIT_MORBID))
|
|
if(HAS_TRAIT(mob_parent, TRAIT_SNOB))
|
|
switch(area_to_beautify.beauty)
|
|
if(BEAUTY_LEVEL_DECENT to BEAUTY_LEVEL_GOOD)
|
|
add_mood_event(MOOD_CATEGORY_AREA_BEAUTY, /datum/mood_event/ehroom)
|
|
return
|
|
if(BEAUTY_LEVEL_GOOD to BEAUTY_LEVEL_GREAT)
|
|
add_mood_event(MOOD_CATEGORY_AREA_BEAUTY, /datum/mood_event/badroom)
|
|
return
|
|
if(BEAUTY_LEVEL_GREAT to INFINITY)
|
|
add_mood_event(MOOD_CATEGORY_AREA_BEAUTY, /datum/mood_event/horridroom)
|
|
return
|
|
switch(area_to_beautify.beauty)
|
|
if(-INFINITY to BEAUTY_LEVEL_HORRID)
|
|
add_mood_event(MOOD_CATEGORY_AREA_BEAUTY, /datum/mood_event/greatroom)
|
|
if(BEAUTY_LEVEL_HORRID to BEAUTY_LEVEL_BAD)
|
|
add_mood_event(MOOD_CATEGORY_AREA_BEAUTY, /datum/mood_event/goodroom)
|
|
if(BEAUTY_LEVEL_BAD to BEAUTY_LEVEL_DECENT)
|
|
clear_mood_event(MOOD_CATEGORY_AREA_BEAUTY)
|
|
return
|
|
|
|
if(HAS_TRAIT(mob_parent, TRAIT_SNOB))
|
|
switch(area_to_beautify.beauty)
|
|
if(-INFINITY to BEAUTY_LEVEL_HORRID)
|
|
add_mood_event(MOOD_CATEGORY_AREA_BEAUTY, /datum/mood_event/horridroom)
|
|
return
|
|
if(BEAUTY_LEVEL_HORRID to BEAUTY_LEVEL_BAD)
|
|
add_mood_event(MOOD_CATEGORY_AREA_BEAUTY, /datum/mood_event/badroom)
|
|
return
|
|
switch(area_to_beautify.beauty)
|
|
if(BEAUTY_LEVEL_BAD to BEAUTY_LEVEL_DECENT)
|
|
clear_mood_event(MOOD_CATEGORY_AREA_BEAUTY)
|
|
if(BEAUTY_LEVEL_DECENT to BEAUTY_LEVEL_GOOD)
|
|
add_mood_event(MOOD_CATEGORY_AREA_BEAUTY, /datum/mood_event/decentroom)
|
|
if(BEAUTY_LEVEL_GOOD to BEAUTY_LEVEL_GREAT)
|
|
add_mood_event(MOOD_CATEGORY_AREA_BEAUTY, /datum/mood_event/goodroom)
|
|
if(BEAUTY_LEVEL_GREAT to INFINITY)
|
|
add_mood_event(MOOD_CATEGORY_AREA_BEAUTY, /datum/mood_event/greatroom)
|
|
|
|
/datum/mood/proc/exit_area(datum/source, area/old_area)
|
|
SIGNAL_HANDLER
|
|
UnregisterSignal(old_area, COMSIG_AREA_BEAUTY_UPDATED)
|
|
|
|
/// Called when parent is ahealed.
|
|
/datum/mood/proc/on_revive(datum/source, full_heal)
|
|
SIGNAL_HANDLER
|
|
|
|
if (!full_heal)
|
|
return
|
|
remove_temp_moods()
|
|
set_sanity(initial(sanity), override = TRUE)
|
|
|
|
/// Sets sanity to the specified amount and applies effects.
|
|
/datum/mood/proc/set_sanity(amount, minimum = SANITY_INSANE, maximum = SANITY_GREAT, override = FALSE)
|
|
// If we're out of the acceptable minimum-maximum range move back towards it in steps of 0.7
|
|
// If the new amount would move towards the acceptable range faster then use it instead
|
|
if(amount < minimum && sanity < minimum)
|
|
amount = sanity + 0.7
|
|
|
|
if(!override && HAS_TRAIT(mob_parent, TRAIT_UNSTABLE))
|
|
amount = min(sanity, amount)
|
|
|
|
if (amount > maximum)
|
|
amount = min(amount, maximum)
|
|
|
|
if(amount == sanity) //Prevents stuff from flicking around.
|
|
return
|
|
|
|
sanity = amount
|
|
SEND_SIGNAL(mob_parent, COMSIG_CARBON_SANITY_UPDATE, amount)
|
|
switch(sanity)
|
|
if(SANITY_INSANE to SANITY_CRAZY)
|
|
set_insanity_effect(MAJOR_INSANITY_PEN)
|
|
mob_parent.add_movespeed_modifier(/datum/movespeed_modifier/sanity/insane)
|
|
mob_parent.add_actionspeed_modifier(/datum/actionspeed_modifier/low_sanity)
|
|
sanity_level = SANITY_LEVEL_INSANE
|
|
if(SANITY_CRAZY to SANITY_UNSTABLE)
|
|
set_insanity_effect(MINOR_INSANITY_PEN)
|
|
mob_parent.add_movespeed_modifier(/datum/movespeed_modifier/sanity/crazy)
|
|
mob_parent.add_actionspeed_modifier(/datum/actionspeed_modifier/low_sanity)
|
|
sanity_level = SANITY_LEVEL_CRAZY
|
|
if(SANITY_UNSTABLE to SANITY_DISTURBED)
|
|
set_insanity_effect(0)
|
|
mob_parent.add_movespeed_modifier(/datum/movespeed_modifier/sanity/disturbed)
|
|
mob_parent.add_actionspeed_modifier(/datum/actionspeed_modifier/low_sanity)
|
|
sanity_level = SANITY_LEVEL_UNSTABLE
|
|
if(SANITY_DISTURBED to SANITY_NEUTRAL)
|
|
set_insanity_effect(0)
|
|
mob_parent.remove_movespeed_modifier(MOVESPEED_ID_SANITY)
|
|
mob_parent.remove_actionspeed_modifier(ACTIONSPEED_ID_SANITY)
|
|
sanity_level = SANITY_LEVEL_DISTURBED
|
|
if(SANITY_NEUTRAL+1 to SANITY_GREAT+1) //shitty hack but +1 to prevent it from responding to super small differences
|
|
set_insanity_effect(0)
|
|
mob_parent.remove_movespeed_modifier(MOVESPEED_ID_SANITY)
|
|
mob_parent.add_actionspeed_modifier(/datum/actionspeed_modifier/high_sanity)
|
|
sanity_level = SANITY_LEVEL_NEUTRAL
|
|
if(SANITY_GREAT+1 to INFINITY)
|
|
set_insanity_effect(0)
|
|
mob_parent.remove_movespeed_modifier(MOVESPEED_ID_SANITY)
|
|
mob_parent.add_actionspeed_modifier(/datum/actionspeed_modifier/high_sanity)
|
|
sanity_level = SANITY_LEVEL_GREAT
|
|
|
|
// BUBBER EDIT REMOVAL BEGIN - No hallucination on hunger/sanity
|
|
/*
|
|
// Crazy or insane = add some uncommon hallucinations
|
|
if(sanity_level >= SANITY_LEVEL_CRAZY)
|
|
mob_parent.apply_status_effect(/datum/status_effect/hallucination/sanity)
|
|
else
|
|
mob_parent.remove_status_effect(/datum/status_effect/hallucination/sanity)
|
|
*/
|
|
// BUBBER EDIT REMOVAL END - No hallucination on hunger/sanity
|
|
|
|
update_mood_icon()
|
|
|
|
/// Adjusts sanity by a value
|
|
/datum/mood/proc/adjust_sanity(amount, minimum = SANITY_INSANE, maximum = SANITY_GREAT, override = FALSE)
|
|
set_sanity(sanity + amount, minimum, maximum, override)
|
|
|
|
/// Sets the insanity effect on the mob
|
|
/datum/mood/proc/set_insanity_effect(newval)
|
|
if (newval == insanity_effect)
|
|
return
|
|
mob_parent.crit_threshold = (mob_parent.crit_threshold - insanity_effect) + newval
|
|
insanity_effect = newval
|
|
|
|
/// Removes all temporary moods
|
|
/datum/mood/proc/remove_temp_moods()
|
|
for (var/category in mood_events)
|
|
var/datum/mood_event/moodlet = mood_events[category]
|
|
if (!moodlet || !moodlet.timeout)
|
|
continue
|
|
mood_events -= moodlet.category
|
|
qdel(moodlet)
|
|
update_mood()
|
|
|
|
/// Helper to forcefully drain sanity
|
|
/datum/mood/proc/direct_sanity_drain(amount)
|
|
adjust_sanity(amount, override = TRUE)
|
|
|
|
/**
|
|
* Returns true if you already have a mood from a provided category.
|
|
* You may think to yourself, why am I trying to get a boolean from a component? Well, this system probably should not be a component.
|
|
*
|
|
* Arguments
|
|
* * category - Mood category to validate against.
|
|
*/
|
|
/datum/mood/proc/has_mood_of_category(category)
|
|
for(var/i in mood_events)
|
|
var/datum/mood_event/moodlet = mood_events[i]
|
|
if (moodlet.category == category)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
#undef MINOR_INSANITY_PEN
|
|
#undef MAJOR_INSANITY_PEN
|
|
#undef MOOD_CATEGORY_NUTRITION
|
|
#undef MOOD_CATEGORY_AREA_BEAUTY
|