diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 7af6fecce2..753ee75af3 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -86,6 +86,25 @@ #define SCREWYHUD_DEAD 2 #define SCREWYHUD_HEALTHY 3 +//Moods levels for humans +#define MOOD_LEVEL_HAPPY4 15 +#define MOOD_LEVEL_HAPPY3 10 +#define MOOD_LEVEL_HAPPY2 6 +#define MOOD_LEVEL_HAPPY1 2 +#define MOOD_LEVEL_NEUTRAL 0 +#define MOOD_LEVEL_SAD1 -3 +#define MOOD_LEVEL_SAD2 -10 +#define MOOD_LEVEL_SAD3 -15 +#define MOOD_LEVEL_SAD4 -20 + +//Beauty levels of areas for carbons +#define BEAUTY_LEVEL_HORRID -50 +#define BEAUTY_LEVEL_BAD -25 +#define BEAUTY_LEVEL_GOOD 25 +#define BEAUTY_LEVEL_GREAT 50 + + + //Nutrition levels for humans #define NUTRITION_LEVEL_FAT 600 #define NUTRITION_LEVEL_FULL 550 diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 854ea01114..57186c26d1 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -39,8 +39,11 @@ #define TRAIT_NOBREATH "no_breath" #define TRAIT_ANTIMAGIC "anti_magic" #define TRAIT_HOLY "holy" +#define TRAIT_DEPRESSION "depression" +#define TRAIT_JOLLY "jolly" #define TRAIT_NOCRITDAMAGE "no_crit" + #define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" #define TRAIT_AGEUSIA "ageusia" #define TRAIT_HEAVY_SLEEPER "heavy_sleeper" diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index b2bb939b11..54fb88ba88 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -369,7 +369,7 @@ Proc for attack log creation, because really why not checked_health["health"] = health return ..() -/proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null) +/proc/do_after(mob/user, var/delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null) if(!user) return 0 var/atom/Tloc = null @@ -392,6 +392,16 @@ Proc for attack log creation, because really why not if (progress) progbar = new(user, delay, target) + GET_COMPONENT_FROM(mood, /datum/component/mood, user) + if(mood) + switch(mood.mood) //Alerts do_after delay based on how happy you are + if(-INFINITY to MOOD_LEVEL_SAD2) + delay *= 1.25 + if(MOOD_LEVEL_HAPPY3 to MOOD_LEVEL_HAPPY4) + delay *= 0.95 + if(MOOD_LEVEL_HAPPY4 to INFINITY) + delay *= 0.9 + var/endtime = world.time + delay var/starttime = world.time . = 1 diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index 4ce615dd01..9a325dfa1a 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -103,6 +103,7 @@ #define ui_healthdoll "EAST-1:28,CENTER-2:13" #define ui_health "EAST-1:28,CENTER-1:15" #define ui_internal "EAST-1:28,CENTER:17" +#define ui_mood "EAST-1:28,CENTER-3:10" //borgs #define ui_borg_health "EAST-1:28,CENTER-1:15" //borgs have the health display where humans have the pressure damage indicator. diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 65c4bd23c2..c579c7adab 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -106,6 +106,11 @@ layer = BLIND_LAYER plane = FULLSCREEN_PLANE +/obj/screen/fullscreen/depression + icon_state = "depression" + layer = FLASH_LAYER + plane = FULLSCREEN_PLANE + /obj/screen/fullscreen/curse icon_state = "curse" layer = CURSE_LAYER diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 5693e9c47e..e5de695789 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -43,6 +43,7 @@ var/obj/screen/healths var/obj/screen/healthdoll var/obj/screen/internals + var/obj/screen/mood var/ui_style_icon = 'icons/mob/screen_midnight.dmi' @@ -103,6 +104,7 @@ healths = null healthdoll = null internals = null + mood = null lingchemdisplay = null devilsouldisplay = null lingstingdisplay = null @@ -268,4 +270,4 @@ show_hud(HUD_STYLE_STANDARD,mymob) /datum/hud/proc/update_locked_slots() - return \ No newline at end of file + return diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index b0468c74cb..455a0f20e1 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -289,6 +289,10 @@ healthdoll = new /obj/screen/healthdoll() infodisplay += healthdoll + if(!CONFIG_GET(flag/disable_human_mood)) + mood = new /obj/screen/mood() + infodisplay += mood + pull_icon = new /obj/screen/pull() pull_icon.icon = ui_style pull_icon.update_icon(mymob) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 1e574cd8aa..e582e3ec0b 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -538,6 +538,16 @@ name = "health doll" screen_loc = ui_healthdoll +/obj/screen/mood + name = "mood" + icon_state = "mood5" + screen_loc = ui_mood + +/obj/screen/mood/Click() + GET_COMPONENT_FROM(mood, /datum/component/mood, usr) + if(mood) + mood.print_mood() + /obj/screen/splash icon = 'icons/blank_title.png' icon_state = "" diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 12a8196dd6..4ac9910336 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -47,8 +47,10 @@ /datum/config_entry/flag/force_random_names /datum/config_entry/flag/humans_need_surnames - + /datum/config_entry/flag/allow_ai // allow ai job + +/datum/config_entry/flag/disable_human_mood /datum/config_entry/flag/disable_secborg // disallow secborg module to be chosen. diff --git a/code/controllers/subsystem/moods.dm b/code/controllers/subsystem/moods.dm new file mode 100644 index 0000000000..d1e58c7452 --- /dev/null +++ b/code/controllers/subsystem/moods.dm @@ -0,0 +1,4 @@ +PROCESSING_SUBSYSTEM_DEF(mood) + name = "Mood" + flags = SS_NO_INIT | SS_BACKGROUND + priority = 20 diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm index 87e0cb3457..9a523cb39f 100644 --- a/code/datums/brain_damage/mild.dm +++ b/code/datums/brain_damage/mild.dm @@ -43,6 +43,9 @@ /datum/brain_trauma/mild/dumbness/on_gain() owner.add_trait(TRAIT_DUMB, TRAUMA_TRAIT) + GET_COMPONENT_FROM(mood, /datum/component/mood, owner) + if(mood) + mood.add_event("dumb", /datum/mood_event/oblivious) ..() /datum/brain_trauma/mild/dumbness/on_life() @@ -56,6 +59,9 @@ /datum/brain_trauma/mild/dumbness/on_lose() owner.remove_trait(TRAIT_DUMB, TRAUMA_TRAIT) owner.derpspeech = 0 + GET_COMPONENT_FROM(mood, /datum/component/mood, owner) + if(mood) + mood.clear_event("dumb") ..() /datum/brain_trauma/mild/speech_impediment @@ -211,4 +217,4 @@ to_chat(owner, "Your arm spasms!") log_attack("[key_name(owner)] threw [I] due to a Muscle Spasm.") owner.throw_item(pick(targets)) - ..() \ No newline at end of file + ..() diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm new file mode 100644 index 0000000000..2f0401302f --- /dev/null +++ b/code/datums/components/mood.dm @@ -0,0 +1,122 @@ +/datum/component/mood + var/mood //Real happiness + var/shown_mood //Shown happiness, this is what others can see when they try to examine you, prevents antag checking by noticing traitors are always very happy. + var/mood_level //To track what stage of moodies they're on + var/mood_modifier = 1 //Modifier to allow certain mobs to be less affected by moodlets + var/datum/mood_event/list/mood_events = list() + var/mob/living/owner + +/datum/component/mood/Initialize() + if(!isliving(parent)) + . = COMPONENT_INCOMPATIBLE + CRASH("Some good for nothing loser put a mood component on something that isn't even a living mob.") + START_PROCESSING(SSmood, src) + owner = parent + +/datum/component/mood/Destroy() + STOP_PROCESSING(SSmood, src) + return ..() + +/datum/component/mood/proc/print_mood() + var/msg = "*---------*\nYour current mood\n" + for(var/i in mood_events) + var/datum/mood_event/event = mood_events[i] + msg += event.description + to_chat(owner, msg) + +/datum/component/mood/proc/update_mood() //Called whenever a mood event is added or removed + mood = 0 + shown_mood = 0 + for(var/i in mood_events) + var/datum/mood_event/event = mood_events[i] + mood += event.mood_change + if(!event.hidden) + shown_mood += event.mood_change + mood *= mood_modifier + shown_mood *= mood_modifier + + switch(mood) + if(-INFINITY to MOOD_LEVEL_SAD4) + mood_level = 1 + if(MOOD_LEVEL_SAD4 to MOOD_LEVEL_SAD3) + mood_level = 2 + if(MOOD_LEVEL_SAD3 to MOOD_LEVEL_SAD2) + mood_level = 3 + if(MOOD_LEVEL_SAD2 to MOOD_LEVEL_SAD1) + mood_level = 4 + if(MOOD_LEVEL_SAD1 to MOOD_LEVEL_HAPPY1) + mood_level = 5 + if(MOOD_LEVEL_HAPPY1 to MOOD_LEVEL_HAPPY2) + mood_level = 6 + if(MOOD_LEVEL_HAPPY2 to MOOD_LEVEL_HAPPY3) + mood_level = 7 + if(MOOD_LEVEL_HAPPY3 to MOOD_LEVEL_HAPPY4) + mood_level = 8 + if(MOOD_LEVEL_HAPPY4 to INFINITY) + mood_level = 9 + + if(owner.client && owner.hud_used) + owner.hud_used.mood.icon_state = "mood[mood_level]" + +/datum/component/mood/process() //Called on SSmood process + switch(mood) + if(-INFINITY to MOOD_LEVEL_SAD4) + owner.overlay_fullscreen("depression", /obj/screen/fullscreen/depression, 3) + if(MOOD_LEVEL_SAD4 to MOOD_LEVEL_SAD3) + owner.overlay_fullscreen("depression", /obj/screen/fullscreen/depression, 2) + if(MOOD_LEVEL_SAD3 to MOOD_LEVEL_SAD2) + owner.overlay_fullscreen("depression", /obj/screen/fullscreen/depression, 1) + if(MOOD_LEVEL_SAD2 to INFINITY) + owner.clear_fullscreen("depression") + + if(owner.has_trait(TRAIT_DEPRESSION)) + if(prob(0.1)) + add_event("depression", /datum/mood_event/depression) + clear_event("jolly") + if(owner.has_trait(TRAIT_JOLLY)) + if(prob(0.1)) + add_event("jolly", /datum/mood_event/jolly) + clear_event("depression") + +/datum/component/mood/proc/add_event(category, type, param) //Category will override any events in the same category, should be unique unless the event is based on the same thing like hunger. + var/datum/mood_event/the_event + if(mood_events[category]) + the_event = mood_events[category] + if(the_event.type != type) + clear_event(category) + return .() + else + return 0 //Don't have to update the event. + else + the_event = new type(src, param) + + mood_events[category] = the_event + update_mood() + + if(the_event.timeout) + addtimer(CALLBACK(src, .proc/clear_event, category), the_event.timeout) + +/datum/component/mood/proc/clear_event(category) + var/datum/mood_event/event = mood_events[category] + if(!event) + return 0 + + mood_events -= category + qdel(event) + update_mood() + +/datum/component/mood/proc/update_beauty(var/area/A) + if(A.outdoors) //if we're outside, we don't care. + clear_event("area_beauty") + return FALSE + switch(A.beauty) + if(-INFINITY to BEAUTY_LEVEL_HORRID) + add_event("area_beauty", /datum/mood_event/disgustingroom) + if(BEAUTY_LEVEL_HORRID to BEAUTY_LEVEL_BAD) + add_event("area_beauty", /datum/mood_event/grossroom) + if(BEAUTY_LEVEL_BAD to BEAUTY_LEVEL_GOOD) + clear_event("area_beauty") + if(BEAUTY_LEVEL_GOOD to BEAUTY_LEVEL_GREAT) + add_event("area_beauty", /datum/mood_event/niceroom) + if(BEAUTY_LEVEL_GREAT to INFINITY) + add_event("area_beauty", /datum/mood_event/greatroom) diff --git a/code/datums/mood_events/drug_events.dm b/code/datums/mood_events/drug_events.dm new file mode 100644 index 0000000000..5d585ab6b2 --- /dev/null +++ b/code/datums/mood_events/drug_events.dm @@ -0,0 +1,39 @@ +/datum/mood_event/drugs/high + mood_change = 6 + description = "Woooow duudeeeeee...I'm tripping baaalls...\n" + +/datum/mood_event/drugs/smoked + description = "I have had a smoke recently.\n" + mood_change = 2 + timeout = 3600 + +/datum/mood_event/drugs/overdose + mood_change = -8 + timeout = 3000 + +/datum/mood_event/drugs/overdose/add_effects(drug_name) + description = "I think I took a bit too much of that [drug_name]\n" + +/datum/mood_event/drugs/withdrawal_light + mood_change = -2 + +/datum/mood_event/drugs/withdrawal_light/add_effects(drug_name) + description = "I could use some [drug_name]\n" + +/datum/mood_event/drugs/withdrawal_medium + mood_change = -5 + +/datum/mood_event/drugs/withdrawal_medium/add_effects(drug_name) + description = "I really need [drug_name]\n" + +/datum/mood_event/drugs/withdrawal_severe + mood_change = -8 + +/datum/mood_event/drugs/withdrawal_severe/add_effects(drug_name) + description = "Oh god I need some [drug_name]\n" + +/datum/mood_event/drugs/withdrawal_critical + mood_change = -10 + +/datum/mood_event/drugs/withdrawal_critical/add_effects(drug_name) + description = "[drug_name]! [drug_name]! [drug_name]!\n" diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm new file mode 100644 index 0000000000..afb58bf379 --- /dev/null +++ b/code/datums/mood_events/generic_negative_events.dm @@ -0,0 +1,115 @@ +/datum/mood_event/handcuffed + description = "I guess my antics have finally caught up with me..\n" + mood_change = -1 + +/datum/mood_event/broken_vow //Used for when mimes break their vow of silence + description = "I have brought shame upon my name, and betrayed my fellow mimes by breaking our sacred vow...\n" + mood_change = -8 + +/datum/mood_event/on_fire + description = "I'M ON FIRE!!!\n" + mood_change = -8 + +/datum/mood_event/suffocation + description = "CAN'T... BREATHE...\n" + mood_change = -6 + +/datum/mood_event/burnt_thumb + description = "I shouldn't play with lighters...\n" + mood_change = -1 + timeout = 1200 + +/datum/mood_event/cold + description = "It's way too cold in here.\n" + mood_change = -2 + +/datum/mood_event/hot + description = "It's getting hot in here.\n" + mood_change = -2 + +/datum/mood_event/creampie + description = "I've been creamed. Tastes like pie flavor.\n" + mood_change = -2 + timeout = 1800 + +/datum/mood_event/slipped + description = "I slipped. I should be more careful next time...\n" + mood_change = -3 + timeout = 1800 + +/datum/mood_event/eye_stab + description = "I used to be an adventurer like you, until I took a screwdriver to the eye.\n" + mood_change = -6 + timeout = 2400 + +/datum/mood_event/delam //SM delamination + description = "Those God damn engineers can't do anything right...\n" + mood_change = -6 + timeout = 3000 + +/datum/mood_event/depression + description = "I feel sad for no particular reason.\n" + mood_change = -6 + timeout = 1200 + +/datum/mood_event/shameful_suicide //suicide_acts that return SHAME, like sord + description = "I can't even end it all!\n" + mood_change = -10 + timeout = 600 + +/datum/mood_event/dismembered + description = "AHH! I WAS USING THAT LIMB!\n" + mood_change = -8 + timeout = 3000 + +/datum/mood_event/noshoes + description = "I am a disgrace to comedy everywhere!\n" + mood_change = -3 + +/datum/mood_event/tased + description = "There's no \"z\" in \"taser\". It's in the zap.\n" + mood_change = -4 + timeout = 1200 + +/datum/mood_event/embedded + description = "Pull it out!\n" + mood_change = -6 + +/datum/mood_event/table + description = "Someone threw me on a table!\n" + mood_change = -2 + timeout = 1200 + +/datum/mood_event/brain_damage + mood_change = -3 + +/datum/mood_event/brain_damage/add_effects() + var/damage_message = pick_list_replacements("brain_damage_lines.json", "brain_damage") + description = "Hurr durr... [damage_message]\n" + +/datum/mood_event/hulk //Entire duration of having the hulk mutation + description = "HULK SMASH!\n" + mood_change = -4 + +/datum/mood_event/epilepsy //Only when the mutation causes a seizure + description = "I should have paid attention to the epilepsy warning.\n" + mood_change = -3 + timeout = 3000 + + +/datum/mood_event/grossroom + description = "This room is kind of dirty...\n" + mood_change = -3 + +/datum/mood_event/disgustingroom + description = "This room is disgusting!\n" + mood_change = -5 + +//These are unused so far but I want to remember them to use them later +/datum/mood_event/cloned_corpse + description = "I recently saw my own corpse...\n" + mood_change = -6 + +/datum/mood_event/surgery + description = "HE'S CUTTING ME OPEN!!\n" + mood_change = -8 diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm new file mode 100644 index 0000000000..f5c5bb9807 --- /dev/null +++ b/code/datums/mood_events/generic_positive_events.dm @@ -0,0 +1,71 @@ +/datum/mood_event/hug + description = "Hugs are nice.\n" + mood_change = 1 + timeout = 1200 + +/datum/mood_event/arcade + description = "I beat the arcade game!\n" + mood_change = 3 + timeout = 3000 + +/datum/mood_event/blessing + description = "I've been blessed.\n" + mood_change = 3 + timeout = 3000 + +/datum/mood_event/book_nerd + description = "I have recently read a book.\n" + mood_change = 3 + timeout = 3000 + +/datum/mood_event/pet_corgi + description = "Corgis are adorable! I can't stop petting them!\n" + mood_change = 3 + timeout = 3000 + +/datum/mood_event/honk + description = "Maybe clowns aren't so bad after all. Honk!\n" + mood_change = 2 + timeout = 2400 + +/datum/mood_event/perform_cpr + description = "It feels good to save a life.\n" + mood_change = 6 + timeout = 3000 + +/datum/mood_event/oblivious + description = "What a lovely day.\n" + mood_change = 3 + +/datum/mood_event/happytable + description = "They want to play on the table!\n" + mood_change = 2 + timeout = 1200 + +/datum/mood_event/jolly + description = "I feel happy for no particular reason.\n" + mood_change = 6 + timeout = 1200 + +/datum/mood_event/focused + description = "I have a goal, and I will reach it, whatever it takes!\n" //Used for syndies, nukeops etc so they can focus on their goals + mood_change = 12 + hidden = TRUE + +/datum/mood_event/revolution + description = "VIVA LA REVOLUTION!\n" + mood_change = 3 + hidden = TRUE + +/datum/mood_event/cult + description = "I have seen the truth, praise the almighty one!\n" + mood_change = 40 //maybe being a cultist isnt that bad after all + hidden = TRUE + +/datum/mood_event/niceroom + description = "This room looks really pretty!\n" + mood_change = 4 + +/datum/mood_event/greatroom + description = "This room is beautiful!\n" + mood_change = 7 diff --git a/code/datums/mood_events/mood_event.dm b/code/datums/mood_events/mood_event.dm new file mode 100644 index 0000000000..6b4301b83a --- /dev/null +++ b/code/datums/mood_events/mood_event.dm @@ -0,0 +1,19 @@ +/datum/mood_event + var/description ///For descriptions, use the span classes bold nicegreen, nicegreen, none, warning and boldwarning in order from great to horrible. + var/mood_change = 0 + var/timeout = 0 + var/hidden = FALSE//Not shown on examine + var/mob/owner + +/datum/mood_event/New(mob/M, param) + owner = M + add_effects(param) + +/datum/mood_event/Destroy() + remove_effects() + +/datum/mood_event/proc/add_effects(param) + return + +/datum/mood_event/proc/remove_effects() + return diff --git a/code/datums/mood_events/needs_events.dm b/code/datums/mood_events/needs_events.dm new file mode 100644 index 0000000000..6059d2e7b6 --- /dev/null +++ b/code/datums/mood_events/needs_events.dm @@ -0,0 +1,54 @@ +//nutrition +/datum/mood_event/nutrition/fat + description = "I'm so fat..\n" //muh fatshaming + mood_change = -4 + +/datum/mood_event/nutrition/wellfed + description = "My belly feels round and full.\n" + mood_change = 6 + +/datum/mood_event/nutrition/fed + description = "I have recently had some food.\n" + mood_change = 3 + +/datum/mood_event/nutrition/hungry + description = "I'm getting a bit hungry.\n" + mood_change = -8 + +/datum/mood_event/nutrition/starving + description = "I'm starving!\n" + mood_change = -15 + +//Disgust +/datum/mood_event/disgust/gross + description = "I saw something gross.\n" + mood_change = -2 + +/datum/mood_event/disgust/verygross + description = "I think I'm going to puke...\n" + mood_change = -5 + +/datum/mood_event/disgust/disgusted + description = "Oh god that's disgusting...\n" + mood_change = -8 + +//Generic needs events +/datum/mood_event/favorite_food + description = "I really enjoyed eating that.\n" + mood_change = 3 + timeout = 2400 + +/datum/mood_event/gross_food + description = "I really didn't like that food.\n" + mood_change = -2 + timeout = 2400 + +/datum/mood_event/disgusting_food + description = "That food was disgusting!\n" + mood_change = -4 + timeout = 2400 + +/datum/mood_event/nice_shower + description = "I have recently had a nice shower.\n" + mood_change = 2 + timeout = 1800 diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm index 418b783b94..fd0dd077b7 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -11,6 +11,9 @@ owner.visible_message("[owner] starts having a seizure!", "You have a seizure!") owner.Unconscious(200) owner.Jitter(1000) + GET_COMPONENT_FROM(mood, /datum/component/mood, owner) + if(mood) + mood.add_event("epilepsy", /datum/mood_event/epilepsy) addtimer(CALLBACK(src, .proc/jitter_less, owner), 90) /datum/mutation/human/epilepsy/proc/jitter_less(mob/living/carbon/human/owner) diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm index 8397c3b064..b12efbc452 100644 --- a/code/datums/mutations/hulk.dm +++ b/code/datums/mutations/hulk.dm @@ -14,6 +14,9 @@ owner.add_trait(TRAIT_STUNIMMUNE, TRAIT_HULK) owner.add_trait(TRAIT_PUSHIMMUNE, TRAIT_HULK) owner.update_body_parts() + GET_COMPONENT_FROM(mood, /datum/component/mood, owner) + if(mood) + mood.add_event("hulk", /datum/mood_event/hulk) /datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity) if(proximity) //no telekinetic hulk attack @@ -30,7 +33,10 @@ owner.remove_trait(TRAIT_STUNIMMUNE, TRAIT_HULK) owner.remove_trait(TRAIT_PUSHIMMUNE, TRAIT_HULK) owner.update_body_parts() - + GET_COMPONENT_FROM(mood, /datum/component/mood, owner) + if(mood) + mood.clear_event("hulk") + /datum/mutation/human/hulk/say_mod(message) if(message) message = "[uppertext(replacetext(message, ".", "!"))]!!" diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm index 538146b873..3ec2a87dc0 100644 --- a/code/datums/traits/good.dm +++ b/code/datums/traits/good.dm @@ -81,3 +81,26 @@ mob_trait = TRAIT_VORACIOUS gain_text = "You feel HONGRY." lose_text = "You no longer feel HONGRY." + + +/datum/trait/jolly + name = "Jolly" + desc = "You sometimes just feel happy, for no reason at all." + value = 1 + mob_trait = TRAIT_JOLLY + + +/datum/trait/apathetic + name = "Apathetic" + desc = "You just don't care as much as other people, that's nice to have in a place like this, I guess." + value = 1 + +/datum/trait/apathetic/add() + GET_COMPONENT_FROM(mood, /datum/component/mood, trait_holder) + if(mood) + mood.mood_modifier = 0.8 + +/datum/trait/apathetic/remove() + GET_COMPONENT_FROM(mood, /datum/component/mood, trait_holder) + if(mood) + mood.mood_modifier = 1 //Change this once/if species get their own mood modifiers. diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm index 9fd966eead..35205421ff 100644 --- a/code/datums/traits/negative.dm +++ b/code/datums/traits/negative.dm @@ -154,3 +154,12 @@ else if(prob(0.5) && dumb_thing) to_chat(H, "You think of a dumb thing you said a long time ago and scream internally.") dumb_thing = FALSE //only once per life + +/datum/trait/depression + name = "Depression" + desc = "You sometimes just hate life." + mob_trait = TRAIT_DEPRESSION + value = -1 + gain_text = "You start feeling depressed." + lose_text = "You no longer feel depressed." //if only it were that easy! + medical_record_text = "Patient has a severe mood disorder causing them to experience sudden moments of sadness." diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 450d70508e..0f3bfb12b1 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -31,6 +31,9 @@ var/outdoors = FALSE //For space, the asteroid, lavaland, etc. Used with blueprints to determine if we are adding a new area (vs editing a station room) + var/beauty = 0 //To see how clean/dirty this area is, only works with indoors areas. + var/areasize = 0 //Size of the area in tiles, only calculated for indoors areas. + var/power_equip = TRUE var/power_light = TRUE var/power_environ = TRUE @@ -145,6 +148,7 @@ GLOBAL_LIST_EMPTY(teleportlocs) if(!areas_in_z["[z]"]) areas_in_z["[z]"] = list() areas_in_z["[z]"] += src + update_area_size() return INITIALIZE_HINT_LATELOAD @@ -497,6 +501,10 @@ GLOBAL_LIST_EMPTY(teleportlocs) L.client.played = TRUE addtimer(CALLBACK(L.client, /client/proc/ResetAmbiencePlayed), 600) + GET_COMPONENT_FROM(mood, /datum/component/mood, L) + if(mood) + mood.update_beauty(src) + /client/proc/ResetAmbiencePlayed() played = FALSE @@ -524,6 +532,13 @@ GLOBAL_LIST_EMPTY(teleportlocs) blob_allowed = FALSE addSorted() +/area/proc/update_area_size() + if(outdoors) + return FALSE + areasize = 0 + for(var/turf/T in src.contents) + areasize++ + /area/AllowDrop() CRASH("Bad op: area/AllowDrop() called") diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 90dc4f4f45..fbb5faedc2 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -67,7 +67,10 @@ return INITIALIZE_HINT_QDEL Reset() -/obj/machinery/computer/arcade/proc/prizevend() +/obj/machinery/computer/arcade/proc/prizevend(mob/user) + GET_COMPONENT_FROM(mood, /datum/component/mood, user) + if(mood) + mood.add_event("arcade", /datum/mood_event/arcade) if(prob(0.0001)) //1 in a million new /obj/item/gun/energy/pulse/prize(src) SSmedals.UnlockMedal(MEDAL_PULSE, usr.client) @@ -237,7 +240,7 @@ Reset() obj_flags &= ~EMAGGED else - prizevend() + prizevend(usr) SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("win", (obj_flags & EMAGGED ? "emagged":"normal"))) @@ -1031,7 +1034,7 @@ message_admins("[key_name_admin(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") log_game("[key_name(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") else - prizevend() + prizevend(usr) obj_flags &= ~EMAGGED name = "The Orion Trail" desc = "Learn how our ancestors got to Orion, and have fun in the process!" diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index f23f13cca4..a3123159f5 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -4,6 +4,7 @@ var/list/random_icon_states = list() var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints + var/beauty = 0 var/mergeable_decal = TRUE //when two of these are on a same tile or do we need to merge them into just one? /obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases) @@ -16,6 +17,7 @@ if(C != src && C.type == src.type && !QDELETED(C)) if (replace_decal(C)) return INITIALIZE_HINT_QDEL + if(LAZYLEN(diseases)) var/list/datum/disease/diseases_to_add = list() for(var/datum/disease/D in diseases) @@ -24,6 +26,11 @@ if(LAZYLEN(diseases_to_add)) AddComponent(/datum/component/infective, diseases_to_add) +/obj/effect/decal/cleanable/LateInitialize() + if(src.loc && isturf(src.loc)) + var/area/A = get_area(src) + A.beauty += beauty / max(1, A.areasize) //Ensures that the effects scale with room size + /obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal if(mergeable_decal) return TRUE @@ -90,3 +97,8 @@ return bloodiness else return 0 + +/obj/effect/decal/cleanable/Destroy() + if(src.loc && isturf(src.loc)) + var/area/A = get_area(src) + A.beauty -= beauty / max(1, A.areasize) diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm index 55d5d32ffc..79103c28aa 100644 --- a/code/game/objects/effects/decals/cleanable/aliens.dm +++ b/code/game/objects/effects/decals/cleanable/aliens.dm @@ -8,6 +8,7 @@ random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7") bloodiness = MAX_SHOE_BLOODINESS blood_state = BLOOD_STATE_XENO + beauty = -200 /obj/effect/decal/cleanable/xenoblood/Initialize() . = ..() diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index 9d9d8d17a4..7b2c00a0b6 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -6,6 +6,7 @@ random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7") blood_state = BLOOD_STATE_HUMAN bloodiness = MAX_SHOE_BLOODINESS + beauty = -200 /obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C) C.add_blood_DNA(return_blood_DNA()) diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index 3ff1bdc19f..e5253d4b85 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -3,6 +3,7 @@ desc = "Someone should clean that up." icon = 'icons/obj/objects.dmi' icon_state = "shards" + beauty = -150 /obj/effect/decal/cleanable/ash name = "ashes" @@ -10,6 +11,7 @@ icon = 'icons/obj/objects.dmi' icon_state = "ash" mergeable_decal = FALSE + beauty = -150 /obj/effect/decal/cleanable/ash/Initialize() . = ..() @@ -24,6 +26,7 @@ /obj/effect/decal/cleanable/ash/large name = "large pile of ashes" icon_state = "big_ash" + beauty = -150 /obj/effect/decal/cleanable/ash/large/Initialize() . = ..() @@ -34,6 +37,7 @@ desc = "Back to sand." icon = 'icons/obj/shards.dmi' icon_state = "tiny" + beauty = -20 /obj/effect/decal/cleanable/glass/Initialize() . = ..() @@ -47,17 +51,20 @@ desc = "Someone should clean that up." icon_state = "dirt" mouse_opacity = MOUSE_OPACITY_TRANSPARENT + beauty = -150 /obj/effect/decal/cleanable/flour name = "flour" desc = "It's still good. Four second rule!" icon_state = "flour" + beauty = -100 /obj/effect/decal/cleanable/greenglow name = "glowing goo" desc = "Jeez. I hope that's not for lunch." light_color = LIGHT_COLOR_GREEN icon_state = "greenglow" + beauty = -100 /obj/effect/decal/cleanable/greenglow/Initialize(mapload) . = ..() @@ -73,6 +80,7 @@ layer = WALL_OBJ_LAYER icon_state = "cobweb1" resistance_flags = FLAMMABLE + beauty = -150 /obj/effect/decal/cleanable/cobweb/cobweb2 icon_state = "cobweb2" @@ -84,10 +92,12 @@ icon = 'icons/effects/effects.dmi' icon_state = "molten" mergeable_decal = FALSE + beauty = -250 /obj/effect/decal/cleanable/molten_object/large name = "big gooey grey mass" icon_state = "big_molten" + beauty = -200 //Vomit (sorry) /obj/effect/decal/cleanable/vomit @@ -96,6 +106,7 @@ icon = 'icons/effects/blood.dmi' icon_state = "vomit_1" random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4") + beauty = -400 /obj/effect/decal/cleanable/vomit/attack_hand(mob/user) if(ishuman(user)) @@ -127,12 +138,14 @@ gender = NEUTER icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3") + beauty = -125 /obj/effect/decal/cleanable/plant_smudge name = "plant smudge" gender = NEUTER icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("smashed_plant") + beauty = -125 /obj/effect/decal/cleanable/egg_smudge name = "smashed egg" @@ -140,6 +153,7 @@ gender = NEUTER icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("smashed_egg1", "smashed_egg2", "smashed_egg3") + beauty = -125 /obj/effect/decal/cleanable/pie_smudge //honk name = "smashed pie" @@ -147,6 +161,7 @@ gender = NEUTER icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("smashed_pie") + beauty = -125 /obj/effect/decal/cleanable/chem_pile name = "chemical pile" @@ -154,6 +169,7 @@ gender = NEUTER icon = 'icons/obj/objects.dmi' icon_state = "ash" + beauty = -125 /obj/effect/decal/cleanable/shreds name = "shreds" @@ -161,6 +177,7 @@ icon_state = "shreds" gender = PLURAL mergeable_decal = FALSE + beauty = -125 /obj/effect/decal/cleanable/shreds/ex_act(severity, target) if(severity == 1) //so shreds created during an explosion aren't deleted by the explosion. @@ -177,12 +194,14 @@ icon = 'icons/effects/tomatodecal.dmi' icon_state = "salt_pile" gender = NEUTER + beauty = -125 /obj/effect/decal/cleanable/glitter name = "generic glitter pile" desc = "The herpes of arts and crafts." icon = 'icons/effects/tile_effects.dmi' gender = NEUTER + beauty = 300 /obj/effect/decal/cleanable/glitter/pink name = "pink glitter" @@ -200,4 +219,5 @@ name = "stabilized plasma" desc = "A puddle of stabilized plasma." icon_state = "flour" - color = "#C8A5DC" \ No newline at end of file + color = "#C8A5DC" + beauty = -200 diff --git a/code/game/objects/effects/decals/cleanable/robots.dm b/code/game/objects/effects/decals/cleanable/robots.dm index b0159818eb..b70b500bba 100644 --- a/code/game/objects/effects/decals/cleanable/robots.dm +++ b/code/game/objects/effects/decals/cleanable/robots.dm @@ -10,6 +10,7 @@ blood_state = BLOOD_STATE_OIL bloodiness = MAX_SHOE_BLOODINESS mergeable_decal = FALSE + beauty = -200 /obj/effect/decal/cleanable/robot_debris/proc/streak(list/directions) set waitfor = 0 @@ -46,6 +47,7 @@ random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7") blood_state = BLOOD_STATE_OIL bloodiness = MAX_SHOE_BLOODINESS + beauty = -125 /obj/effect/decal/cleanable/oil/Initialize() . = ..() @@ -57,4 +59,4 @@ /obj/effect/decal/cleanable/oil/slippery /obj/effect/decal/cleanable/oil/slippery/Initialize() - AddComponent(/datum/component/slippery, 80, (NO_SLIP_WHEN_WALKING | SLIDE)) \ No newline at end of file + AddComponent(/datum/component/slippery, 80, (NO_SLIP_WHEN_WALKING | SLIDE)) diff --git a/code/game/objects/effects/decals/remains.dm b/code/game/objects/effects/decals/remains.dm index 31e0f1c540..75fe78959d 100644 --- a/code/game/objects/effects/decals/remains.dm +++ b/code/game/objects/effects/decals/remains.dm @@ -30,4 +30,4 @@ /obj/effect/decal/cleanable/robot_debris/old name = "dusty robot debris" - desc = "Looks like nobody has touched this in a while." \ No newline at end of file + desc = "Looks like nobody has touched this in a while." diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 0cd102cb5a..aeb7acb651 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -531,6 +531,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) else M.take_bodypart_damage(7) + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if(mood) + mood.add_event("eye_stab", /datum/mood_event/eye_stab) + add_logs(user, M, "attacked", "[src.name]", "(INTENT: [uppertext(user.a_intent)])") M.adjust_blurriness(3) diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index e3c74a4ddf..0383121308 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -191,6 +191,7 @@ FD.CalculateAffectingAreas() to_chat(usr, "You rename the '[prevname]' to '[str]'.") log_game("[key_name(usr)] has renamed [prevname] to [str]") + A.update_area_size() interact() return 1 diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index e622026d21..f2b656a074 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -549,6 +549,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/hitzone = user.held_index_to_dir(user.active_hand_index) == "r" ? "r_hand" : "l_hand" user.apply_damage(5, BURN, hitzone) user.visible_message("After a few attempts, [user] manages to light [src] - however, [user.p_they()] burn their finger in the process.", "You burn yourself while lighting the lighter!") + GET_COMPONENT_FROM(mood, /datum/component/mood, user) + if(mood) + mood.add_event("burnt_thumb", /datum/mood_event/burnt_thumb) else set_lit(FALSE) diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm index 28171186fe..376f003232 100644 --- a/code/game/objects/items/clown_items.dm +++ b/code/game/objects/items/clown_items.dm @@ -116,6 +116,11 @@ . = ..() AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50) +/obj/item/weapon/bikehorn/attack(mob/living/carbon/M, mob/living/carbon/user) + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if(mood) + mood.add_event("honk", /datum/mood_event/honk) + /obj/item/bikehorn/suicide_act(mob/user) user.visible_message("[user] solemnly points the horn at [user.p_their()] temple! It looks like [user.p_theyre()] trying to commit suicide!") playsound(src, 'sound/items/bikehorn.ogg', 50, 1) diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index 875183f9d2..cea183d493 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -96,6 +96,9 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", H.visible_message("[user] heals [H] with the power of [deity_name]!") to_chat(H, "May the power of [deity_name] compel you to be healed!") playsound(src.loc, "punch", 25, 1, -1) + GET_COMPONENT_FROM(mood, /datum/component/mood, H) + if(mood) + mood.add_event("blessing", /datum/mood_event/blessing) return 1 /obj/item/storage/book/bible/attack(mob/living/M, mob/living/carbon/human/user, heal_mode = TRUE) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index ad0b33f966..841312be3a 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -95,7 +95,17 @@ pushed_mob.visible_message("[user] pushes [pushed_mob] onto [src].", \ "[user] pushes [pushed_mob] onto [src].") add_logs(user, pushed_mob, "pushed") - + if(!ishuman(pushed_mob)) + return + var/mob/living/carbon/human/H = pushed_mob + GET_COMPONENT_FROM(mood, /datum/component/mood, H) + if(mood) + if(iscatperson(H)) //Catpeople are a bit dumb and think its fun to be on a table + mood.add_event("table", /datum/mood_event/happytable) + H.startTailWag() + addtimer(CALLBACK(H, /mob/living/carbon/human.proc/endTailWag), 30) + else + mood.add_event("table", /datum/mood_event/table) /obj/structure/table/attackby(obj/item/I, mob/user, params) if(!(flags_1 & NODECONSTRUCT_1)) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index ab9a6334a0..2213e56921 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -335,6 +335,9 @@ L.ExtinguishMob() L.adjust_fire_stacks(-20) //Douse ourselves with water to avoid fire more easily L.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) + GET_COMPONENT_FROM(mood, /datum/component/mood, L) + if(mood) + mood.add_event("shower", /datum/mood_event/nice_shower) if(iscarbon(L)) var/mob/living/carbon/M = L . = TRUE diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index bcd597424d..e9276d777b 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -199,6 +199,9 @@ if(!(lube&SLIDE_ICE)) playsound(C.loc, 'sound/misc/slip.ogg', 50, 1, -3) + GET_COMPONENT_FROM(mood, /datum/component/mood, C) + if(mood) + mood.add_event("slipped", /datum/mood_event/slipped) for(var/obj/item/I in C.held_items) C.accident(I) diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index f9582bdce8..8b603d109a 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -13,7 +13,8 @@ GLOBAL_LIST_EMPTY(antagonists) var/replace_banned = TRUE //Should replace jobbaned player with ghosts if granted. var/list/objectives = list() var/antag_memory = ""//These will be removed with antag datum - + var/antag_moodlet //typepath of moodlet that the mob will gain with their status + //Antag panel properties var/show_in_antagpanel = TRUE //This will hide adding this antag type in antag panel, use only for internal subtypes that shouldn't be added directly but still show if possessed by mind var/antagpanel_category = "Uncategorized" //Antagpanel will display these together, REQUIRED @@ -67,6 +68,7 @@ GLOBAL_LIST_EMPTY(antagonists) if(!silent) greet() apply_innate_effects() + give_antag_moodies() if(is_banned(owner.current) && replace_banned) replace_banned_player() @@ -88,6 +90,7 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/on_removal() remove_innate_effects() + clear_antag_moodies() if(owner) LAZYREMOVE(owner.antag_datums, src) if(!silent && owner.current) @@ -103,6 +106,20 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/farewell() return +/datum/antagonist/proc/give_antag_moodies() + if(!antag_moodlet) + return + GET_COMPONENT_FROM(mood, /datum/component/mood, owner.current) + if(mood) + mood.add_event("antag_moodlet", antag_moodlet) + +/datum/antagonist/proc/clear_antag_moodies() + if(!antag_moodlet) + return + GET_COMPONENT_FROM(mood, /datum/component/mood, owner.current) + if(mood) + mood.add_event("antag_moodlet") + //Returns the team antagonist belongs to if any. /datum/antagonist/proc/get_team() return @@ -183,7 +200,7 @@ GLOBAL_LIST_EMPTY(antagonists) edit_memory(usr) owner.traitor_panel() return - + //Some commands might delete/modify this datum clearing or changing owner var/datum/mind/persistent_owner = owner @@ -231,4 +248,4 @@ GLOBAL_LIST_EMPTY(antagonists) name = custom_name else return - ..() \ No newline at end of file + ..() diff --git a/code/modules/antagonists/brother/brother.dm b/code/modules/antagonists/brother/brother.dm index d8371d3751..9df812822c 100644 --- a/code/modules/antagonists/brother/brother.dm +++ b/code/modules/antagonists/brother/brother.dm @@ -4,6 +4,7 @@ job_rank = ROLE_BROTHER var/special_role = ROLE_BROTHER var/datum/team/brother_team/team + antag_moodlet = /datum/mood_event/focused /datum/antagonist/brother/create_team(datum/team/brother_team/new_team) if(!new_team) @@ -151,4 +152,4 @@ add_objective(new/datum/objective/steal, TRUE) /datum/team/brother_team/antag_listing_name() - return "[name] blood brothers" \ No newline at end of file + return "[name] blood brothers" diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index d6afa339d5..afbe823354 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -7,6 +7,7 @@ roundend_category = "changelings" antagpanel_category = "Changeling" job_rank = ROLE_CHANGELING + antag_moodlet = /datum/mood_event/focused var/you_are_greet = TRUE var/give_objectives = TRUE @@ -542,4 +543,4 @@ return ..() + "([changelingID])" /datum/antagonist/changeling/xenobio/antag_listing_name() - return ..() + "(Xenobio)" \ No newline at end of file + return ..() + "(Xenobio)" diff --git a/code/modules/antagonists/clockcult/clockcult.dm b/code/modules/antagonists/clockcult/clockcult.dm index 067801677b..f921b6b527 100644 --- a/code/modules/antagonists/clockcult/clockcult.dm +++ b/code/modules/antagonists/clockcult/clockcult.dm @@ -4,6 +4,7 @@ roundend_category = "clock cultists" antagpanel_category = "Clockcult" job_rank = ROLE_SERVANT_OF_RATVAR + antag_moodlet = /datum/mood_event/cult var/datum/action/innate/hierophant/hierophant_network = new() var/datum/team/clockcult/clock_team var/make_team = TRUE //This should be only false for tutorial scarabs @@ -216,4 +217,4 @@ parts += "Ratvar's servants were:" parts += printplayerlist(members - eminence) - return "
[parts.Join("
")]
" \ No newline at end of file + return "
[parts.Join("
")]
" diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index 1c90834cbd..a31f29efe0 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -4,6 +4,7 @@ name = "Cultist" roundend_category = "cultists" antagpanel_category = "Cult" + antag_moodlet = /datum/mood_event/cult var/datum/action/innate/cult/comm/communion = new var/datum/action/innate/cult/mastervote/vote = new var/datum/action/innate/cult/blood_magic/magic = new diff --git a/code/modules/antagonists/ert/ert.dm b/code/modules/antagonists/ert/ert.dm index b2fab75eb4..7a573e34d1 100644 --- a/code/modules/antagonists/ert/ert.dm +++ b/code/modules/antagonists/ert/ert.dm @@ -9,6 +9,7 @@ var/role = ERT_SEC var/high_alert = FALSE show_in_antagpanel = FALSE + antag_moodlet = /datum/mood_event/focused /datum/antagonist/ert/on_gain() update_name() @@ -71,11 +72,11 @@ /datum/antagonist/ert/greet() if(!ert_team) return - + var/leader = role == ERT_LEADER || role == DEATHSQUAD_LEADER - + to_chat(owner, "You are the [name].") - + var/missiondesc = "Your squad is being sent on a mission to [station_name()] by Nanotrasen's Security Division." if(leader) //If Squad Leader missiondesc += " Lead your squad to ensure the completion of the mission. Board the shuttle when your team is ready." @@ -83,6 +84,6 @@ missiondesc += " Follow orders given to you by your squad leader." if(role != DEATHSQUAD && role != DEATHSQUAD_LEADER) missiondesc += "Avoid civilian casualites when possible." - + missiondesc += "
Your Mission : [ert_team.mission.explanation_text]" to_chat(owner,missiondesc) diff --git a/code/modules/antagonists/ninja/ninja.dm b/code/modules/antagonists/ninja/ninja.dm index b55165e712..385c9c5f47 100644 --- a/code/modules/antagonists/ninja/ninja.dm +++ b/code/modules/antagonists/ninja/ninja.dm @@ -3,6 +3,7 @@ antagpanel_category = "Ninja" job_rank = ROLE_NINJA show_name_in_check_antagonists = TRUE + antag_moodlet = /datum/mood_event/focused var/helping_station = FALSE var/give_objectives = TRUE var/give_equipment = TRUE @@ -149,4 +150,4 @@ /datum/antagonist/ninja/proc/update_ninja_icons_removed(var/mob/living/carbon/human/ninja) var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA] ninjahud.leave_hud(ninja) - set_antag_hud(ninja, null) \ No newline at end of file + set_antag_hud(ninja, null) diff --git a/code/modules/antagonists/nukeop/nukeop.dm b/code/modules/antagonists/nukeop/nukeop.dm index 7b07b762c0..9b3fa4bed9 100644 --- a/code/modules/antagonists/nukeop/nukeop.dm +++ b/code/modules/antagonists/nukeop/nukeop.dm @@ -3,6 +3,7 @@ roundend_category = "syndicate operatives" //just in case antagpanel_category = "NukeOp" job_rank = ROLE_OPERATIVE + antag_moodlet = /datum/mood_event/focused var/datum/team/nuclear/nuke_team var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team. var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint. @@ -136,7 +137,7 @@ to_chat(owner.current, "The nuclear authorization code is: [code]") else to_chat(admin, "No valid nuke found!") - + /datum/antagonist/nukeop/leader name = "Nuclear Operative Leader" nukeop_outfit = /datum/outfit/syndicate/leader @@ -366,4 +367,4 @@ return common_part + disk_report /datum/team/nuclear/is_gamemode_hero() - return SSticker.mode.name == "nuclear emergency" \ No newline at end of file + return SSticker.mode.name == "nuclear emergency" diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm index e708cb9254..eeeee03663 100644 --- a/code/modules/antagonists/revolution/revolution.dm +++ b/code/modules/antagonists/revolution/revolution.dm @@ -6,6 +6,7 @@ roundend_category = "revolutionaries" // if by some miracle revolutionaries without revolution happen antagpanel_category = "Revolution" job_rank = ROLE_REV + antag_moodlet = /datum/mood_event/revolution var/hud_type = "rev" var/datum/team/revolution/rev_team @@ -365,4 +366,4 @@ return common_part + heads_report /datum/team/revolution/is_gamemode_hero() - return SSticker.mode.name == "revolution" \ No newline at end of file + return SSticker.mode.name == "revolution" diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index e5fdc18f32..c6aaee9c2c 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -3,6 +3,7 @@ roundend_category = "traitors" antagpanel_category = "Traitor" job_rank = ROLE_TRAITOR + antag_moodlet = /datum/mood_event/focused var/should_specialise = TRUE //do we split into AI and human, set to true on inital assignment only var/ai_datum = /datum/antagonist/traitor/AI var/human_datum = /datum/antagonist/traitor/human @@ -11,7 +12,7 @@ var/give_objectives = TRUE var/should_give_codewords = TRUE - + /datum/antagonist/traitor/human show_in_antagpanel = FALSE @@ -343,7 +344,7 @@ var/static/icon/badass = icon('icons/badass.dmi', "badass") uplink_text += "[icon2html(badass, world)]" result += uplink_text - + result += objectives_text var/special_role_text = lowertext(name) @@ -361,4 +362,4 @@ The code responses were: [GLOB.syndicate_code_response]
" /datum/antagonist/traitor/is_gamemode_hero() - return SSticker.mode.name == "traitor" \ No newline at end of file + return SSticker.mode.name == "traitor" diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm index c23d7fe5a5..ba89d2ed9f 100644 --- a/code/modules/antagonists/wizard/wizard.dm +++ b/code/modules/antagonists/wizard/wizard.dm @@ -3,6 +3,7 @@ roundend_category = "wizards/witches" antagpanel_category = "Wizard" job_rank = ROLE_WIZARD + antag_moodlet = /datum/mood_event/focused var/give_objectives = TRUE var/strip = TRUE //strip before equipping var/allow_rename = TRUE @@ -331,4 +332,4 @@ parts += "[master_wizard.owner.name] apprentices were:" parts += printplayerlist(members - master_wizard.owner) - return "
[parts.Join("
")]
" \ No newline at end of file + return "
[parts.Join("
")]
" diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm index a6b7156ea8..9471f0ab9e 100644 --- a/code/modules/client/verbs/suicide.dm +++ b/code/modules/client/verbs/suicide.dm @@ -21,6 +21,9 @@ if(damagetype & SHAME) adjustStaminaLoss(200) suiciding = FALSE + GET_COMPONENT_FROM(mood, /datum/component/mood, src) + if(mood) + mood.add_event("shameful_suicide", /datum/mood_event/shameful_suicide) return var/damage_mod = 0 for(var/T in list(BRUTELOSS, FIRELOSS, TOXLOSS, OXYLOSS)) diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 0d8c00cad7..e5bc99fabf 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -81,6 +81,20 @@ . = ..() AddComponent(/datum/component/squeak, list('sound/effects/clownstep1.ogg'=1,'sound/effects/clownstep2.ogg'=1), 50) +/obj/item/clothing/shoes/clown_shoes/equipped(mob/user, slot) + . = ..() + if(user.mind && user.mind.assigned_role == "Clown") + GET_COMPONENT_FROM(mood, /datum/component/mood, user) + if(mood) + mood.clear_event("noshoes") + +/obj/item/clothing/shoes/clown_shoes/dropped(mob/user) + . = ..() + if(user.mind && user.mind.assigned_role == "Clown") + GET_COMPONENT_FROM(mood, /datum/component/mood, user) + if(mood) + mood.add_event("noshoes", /datum/mood_event/noshoes) + /obj/item/clothing/shoes/clown_shoes/jester name = "jester shoes" desc = "A court jesters shoes, updated with modern squeaking technology." diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index 68ec168a1e..c777fea85b 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -75,4 +75,4 @@ rebel.shoot_inventory = 1 if(ISMULTIPLE(activeFor, 8)) - originMachine.speak(pick(rampant_speeches)) \ No newline at end of file + originMachine.speak(pick(rampant_speeches)) diff --git a/code/modules/food_and_drinks/food.dm b/code/modules/food_and_drinks/food.dm index 67e8a6e913..4e38cb81d9 100644 --- a/code/modules/food_and_drinks/food.dm +++ b/code/modules/food_and_drinks/food.dm @@ -23,12 +23,21 @@ if(foodtype & H.dna.species.toxic_food) to_chat(H,"What the hell was that thing?!") H.adjust_disgust(25 + 30 * fraction) + GET_COMPONENT_FROM(mood, /datum/component/mood, H) + if(mood) + mood.add_event("toxic_food", /datum/mood_event/disgusting_food) else if(foodtype & H.dna.species.disliked_food) to_chat(H,"That didn't taste very good...") H.adjust_disgust(11 + 15 * fraction) + GET_COMPONENT_FROM(mood, /datum/component/mood, H) + if(mood) + mood.add_event("gross_food", /datum/mood_event/gross_food) else if(foodtype & H.dna.species.liked_food) to_chat(H,"I love this taste!") H.adjust_disgust(-5 + -2.5 * fraction) + GET_COMPONENT_FROM(mood, /datum/component/mood, H) + if(mood) + mood.add_event("fav_food", /datum/mood_event/favorite_food) else if(foodtype & H.dna.species.toxic_food) to_chat(H, "You don't feel so good...") diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm index 0139ab116c..6bc5edf096 100644 --- a/code/modules/food_and_drinks/food/snacks_pastry.dm +++ b/code/modules/food_and_drinks/food/snacks_pastry.dm @@ -459,4 +459,4 @@ . = O.attack(M, user, def_zone, FALSE) update_icon() -#undef PANCAKE_MAX_STACK \ No newline at end of file +#undef PANCAKE_MAX_STACK diff --git a/code/modules/food_and_drinks/food/snacks_pie.dm b/code/modules/food_and_drinks/food/snacks_pie.dm index faffdf5383..1f755e24b2 100644 --- a/code/modules/food_and_drinks/food/snacks_pie.dm +++ b/code/modules/food_and_drinks/food/snacks_pie.dm @@ -56,6 +56,9 @@ if(!H.creamed) // one layer at a time H.add_overlay(creamoverlay) H.creamed = TRUE + GET_COMPONENT_FROM(mood, /datum/component/mood, H) + if(mood) + mood.add_event("creampie", /datum/mood_event/creampie) qdel(src) /obj/item/reagent_containers/food/snacks/pie/cream/nostun @@ -244,4 +247,4 @@ icon_state = "frostypie" bonus_reagents = list("nutriment" = 4, "vitamin" = 6) tastes = list("mint" = 1, "pie" = 1) - foodtype = GRAIN | FRUIT | SUGAR \ No newline at end of file + foodtype = GRAIN | FRUIT | SUGAR diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index d2f81e497e..778e16a831 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -316,6 +316,7 @@ h1.alert, h2.alert {color: #000000;} .unconscious {color: #0000ff; font-weight: bold;} .suicide {color: #ff5050; font-style: italic;} .green {color: #03ff39;} +.nicegreen {color: #14a833;} .shadowling {color: #3b2769;} .cult {color: #960000;} diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index 92122411e4..b302701b24 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -206,6 +206,9 @@ if(dat) user << browse("Penned by [author].
" + "[dat]", "window=book[window_size != null ? ";size=[window_size]" : ""]") user.visible_message("[user] opens a book titled \"[title]\" and begins reading intently.") + GET_COMPONENT_FROM(mood, /datum/component/mood, user) + if(mood) + mood.add_event("book_nerd", /datum/mood_event/book_nerd) onclose(user, "book") else to_chat(user, "This book is completely blank!") diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index ddc4e2e9c1..8a73f8812e 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -738,12 +738,17 @@ //called when we get cuffed/uncuffed /mob/living/carbon/proc/update_handcuffed() + GET_COMPONENT_FROM(mood, /datum/component/mood, src) if(handcuffed) drop_all_held_items() stop_pulling() throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = src.handcuffed) + if(mood) + mood.add_event("handcuffed", /datum/mood_event/handcuffed) else clear_alert("handcuffed") + if(mood) + mood.clear_event("handcuffed") update_action_buttons_icon() //some of our action buttons might be unusable when we're handcuffed. update_inv_handcuffed() update_hud_handcuffed() diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 4995caaca0..6192d9ad44 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -266,6 +266,9 @@ else M.visible_message("[M] hugs [src] to make [p_them()] feel better!", \ "You hug [src] to make [p_them()] feel better!") + GET_COMPONENT_FROM(mood, /datum/component/mood, src) + if(mood) + mood.add_event("hug", /datum/mood_event/hug) AdjustStun(-60) AdjustKnockdown(-60) AdjustUnconscious(-60) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 26fc9ce245..48df33345c 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -89,7 +89,21 @@ if(digitalcamo) msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner.\n" - + GET_COMPONENT_FROM(mood, /datum/component/mood, src) + if(mood) + switch(mood.shown_mood) + if(-INFINITY to MOOD_LEVEL_SAD4) + msg += "[t_He] look[p_s()] depressed.\n" + if(MOOD_LEVEL_SAD4 to MOOD_LEVEL_SAD3) + msg += "[t_He] look[p_s()] very sad.\n" + if(MOOD_LEVEL_SAD3 to MOOD_LEVEL_SAD2) + msg += "[t_He] look[p_s()] a bit down.\n" + if(MOOD_LEVEL_HAPPY2 to MOOD_LEVEL_HAPPY3) + msg += "[t_He] look[p_s()] quite happy.\n" + if(MOOD_LEVEL_HAPPY3 to MOOD_LEVEL_HAPPY4) + msg += "[t_He] look[p_s()] very happy.\n" + if(MOOD_LEVEL_HAPPY4 to INFINITY) + msg += "[t_He] look[p_s()] ecstatic.\n" msg += "*---------*
" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 2061924951..8d8eead442 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -30,11 +30,17 @@ AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT), CALLBACK(src, .proc/clean_blood)) + +/mob/living/carbon/human/ComponentInitialize() + if(!CONFIG_GET(flag/disable_human_mood)) + AddComponent(/datum/component/mood) + /mob/living/carbon/human/Destroy() QDEL_NULL(physiology) QDEL_NULL_LIST(vore_organs) // CITADEL EDIT belly stuff return ..() + /mob/living/carbon/human/OpenCraftingMenu() handcrafting.ui_interact(src) @@ -223,6 +229,9 @@ usr.visible_message("[usr] successfully rips [I] out of their [L.name]!","You successfully remove [I] from your [L.name].") if(!has_embedded_objects()) clear_alert("embeddedobject") + GET_COMPONENT_FROM(mood, /datum/component/mood, usr) + if(mood) + mood.clear_event("embeddedobject") return if(href_list["item"]) @@ -651,6 +660,9 @@ return src.visible_message("[src] performs CPR on [C.name]!", "You perform CPR on [C.name].") + GET_COMPONENT_FROM(mood, /datum/component/mood, src) + if(mood) + mood.add_event("perform_cpr", /datum/mood_event/perform_cpr) C.cpr_time = world.time add_logs(src, C, "CPRed") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index c7d2541b08..06cf675427 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -144,6 +144,9 @@ I.forceMove(src) L.receive_damage(I.w_class*I.embedding.embedded_impact_pain_multiplier) visible_message("[I] embeds itself in [src]'s [L.name]!","[I] embeds itself in your [L.name]!") + GET_COMPONENT_FROM(mood, /datum/component/mood, src) + if(mood) + mood.add_event("embedded", /datum/mood_event/embedded) hitpush = FALSE skipcatch = TRUE //can't catch the now embedded item diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index bf9a4492d6..246e615199 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -85,6 +85,19 @@ to_chat(src, "You don't feel like harming anybody.") a_intent_change(INTENT_HELP) + GET_COMPONENT_FROM(mood, /datum/component/mood, src) + if (getBrainLoss() >= 60 && stat == CONSCIOUS) + if(mood) + mood.add_event("brain_damage", /datum/mood_event/brain_damage) + if(prob(3)) + if(prob(25)) + emote("drool") + else + say(pick_list_replacements(BRAIN_DAMAGE_FILE, "brain_damage")) + else + if(mood) + mood.clear_event("brain_damage") + /mob/living/carbon/human/handle_mutations_and_radiation() if(!dna || !dna.species.handle_mutations_and_radiation(src)) ..() @@ -330,6 +343,9 @@ visible_message("[I] falls out of [name]'s [BP.name]!","[I] falls out of your [BP.name]!") if(!has_embedded_objects()) clear_alert("embeddedobject") + GET_COMPONENT_FROM(mood, /datum/component/mood, src) + if(mood) + mood.clear_event("embedded") /mob/living/carbon/human/proc/handle_active_genes() for(var/datum/mutation/human/HM in dna.mutations) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 8a78c1532e..97bb2ffb0a 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1121,6 +1121,16 @@ GLOBAL_LIST_EMPTY(roundstart_races) if (H.nutrition > 0 && H.stat != DEAD && !H.has_trait(TRAIT_NOHUNGER)) // THEY HUNGER var/hunger_rate = HUNGER_FACTOR + GET_COMPONENT_FROM(mood, /datum/component/mood, H) + if(mood) + switch(mood.mood) //Alerts do_after delay based on how happy you are + if(MOOD_LEVEL_HAPPY2 to MOOD_LEVEL_HAPPY3) + hunger_rate *= 0.9 + if(MOOD_LEVEL_HAPPY3 to MOOD_LEVEL_HAPPY4) + hunger_rate *= 0.8 + if(MOOD_LEVEL_HAPPY4 to INFINITY) + hunger_rate *= 0.7 + if(H.satiety > 0) H.satiety-- if(H.satiety < 0) @@ -1154,14 +1164,31 @@ GLOBAL_LIST_EMPTY(roundstart_races) to_chat(H, "You no longer feel vigorous.") H.metabolism_efficiency = 1 + GET_COMPONENT_FROM(mood, /datum/component/mood, H) switch(H.nutrition) if(NUTRITION_LEVEL_FULL to INFINITY) + if(mood) + mood.add_event("nutrition", /datum/mood_event/nutrition/fat) H.throw_alert("nutrition", /obj/screen/alert/fat) - if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FULL) + if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL) + if(mood) + mood.add_event("nutrition", /datum/mood_event/nutrition/wellfed) + H.clear_alert("nutrition") + if( NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) + if(mood) + mood.add_event("nutrition", /datum/mood_event/nutrition/fed) + H.clear_alert("nutrition") + if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) + if(mood) + mood.clear_event("nutrition") H.clear_alert("nutrition") if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) + if(mood) + mood.add_event("nutrition", /datum/mood_event/nutrition/hungry) H.throw_alert("nutrition", /obj/screen/alert/hungry) - else + if(0 to NUTRITION_LEVEL_STARVING) + if(mood) + mood.add_event("nutrition", /datum/mood_event/nutrition/starving) H.throw_alert("nutrition", /obj/screen/alert/starving) /datum/species/proc/update_health_hud(mob/living/carbon/human/H) @@ -1262,14 +1289,22 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(I.flags_2 & SLOWS_WHILE_IN_HAND_2) . += I.slowdown var/health_deficiency = (100 - H.health + H.staminaloss) - var/hungry = (500 - H.nutrition) / 5 // So overeat would be 100 and default level would be 80 if(health_deficiency >= 40) if(flight) . += (health_deficiency / 75) else . += (health_deficiency / 25) - if((hungry >= 70) && !flight) //Being hungry won't stop you from using flightpack controls/flapping your wings although it probably will in the wing case but who cares. - . += hungry / 50 + + GET_COMPONENT_FROM(mood, /datum/component/mood, H) + if(mood && !flight) //How can depression slow you down if you can just fly away from your problems? + switch(mood.mood) + if(-INFINITY to MOOD_LEVEL_SAD4) + . += 1.5 + if(MOOD_LEVEL_SAD4 to MOOD_LEVEL_SAD3) + . += 1 + if(MOOD_LEVEL_SAD3 to MOOD_LEVEL_SAD2) + . += 0.5 + if(H.has_trait(TRAIT_FAT)) . += (1.5 - flight) if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT) @@ -1621,6 +1656,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(H.has_trait(TRAIT_NOBREATH)) return TRUE + /datum/species/proc/handle_environment(datum/gas_mixture/environment, mob/living/carbon/human/H) if(!environment) return @@ -1650,9 +1686,13 @@ GLOBAL_LIST_EMPTY(roundstart_races) H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + min(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_HEAT_DIVISOR, BODYTEMP_HEATING_MAX)) // +/- 50 degrees from 310K is the 'safe' zone, where no damage is dealt. + GET_COMPONENT_FROM(mood, /datum/component/mood, H) if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !H.has_trait(TRAIT_RESISTHEAT)) //Body temperature is too hot. var/burn_damage + if(mood) + mood.clear_event("cold") + mood.add_event("hot", /datum/mood_event/hot) switch(H.bodytemperature) if(BODYTEMP_HEAT_DAMAGE_LIMIT to 400) H.throw_alert("temp", /obj/screen/alert/hot, 1) @@ -1670,7 +1710,11 @@ GLOBAL_LIST_EMPTY(roundstart_races) if (H.stat < UNCONSCIOUS && (prob(burn_damage) * 10) / 4) //40% for level 3 damage on humans H.emote("scream") H.apply_damage(burn_damage, BURN) + else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !(GLOB.mutations_list[COLDRES] in H.dna.mutations)) + if(mood) + mood.clear_event("hot") + mood.add_event("cold", /datum/mood_event/cold) switch(H.bodytemperature) if(200 to BODYTEMP_COLD_DAMAGE_LIMIT) H.throw_alert("temp", /obj/screen/alert/cold, 1) @@ -1684,6 +1728,9 @@ GLOBAL_LIST_EMPTY(roundstart_races) else H.clear_alert("temp") + if(mood) + mood.clear_event("cold") + mood.clear_event("hot") var/pressure = environment.return_pressure() var/adjusted_pressure = H.calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob. @@ -1778,6 +1825,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) else H.adjust_bodytemperature(BODYTEMP_HEATING_MAX + (H.fire_stacks * 12)) + /datum/species/proc/CanIgniteMob(mob/living/carbon/human/H) if(H.has_trait(TRAIT_NOFIRE)) return FALSE diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index e5c82f0ead..fec5ae0e63 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -144,6 +144,7 @@ //OXYGEN + GET_COMPONENT_FROM(mood, /datum/component/mood, src) if(O2_partialpressure < safe_oxy_min) //Not enough oxygen if(prob(20)) emote("gasp") @@ -156,6 +157,8 @@ adjustOxyLoss(3) failed_last_breath = 1 throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy) + if(mood) + mood.add_event("suffocation", /datum/mood_event/suffocation) else //Enough oxygen failed_last_breath = 0 @@ -163,6 +166,8 @@ adjustOxyLoss(-5) oxygen_used = breath_gases[/datum/gas/oxygen][MOLES] clear_alert("not_enough_oxy") + if(mood) + mood.clear_event("suffocation") breath_gases[/datum/gas/oxygen][MOLES] -= oxygen_used breath_gases[/datum/gas/carbon_dioxide][MOLES] += oxygen_used diff --git a/code/modules/mob/living/carbon/status_procs.dm b/code/modules/mob/living/carbon/status_procs.dm index eccdd5d2cf..1db31d5a2d 100644 --- a/code/modules/mob/living/carbon/status_procs.dm +++ b/code/modules/mob/living/carbon/status_procs.dm @@ -42,12 +42,17 @@ /mob/living/carbon/adjust_drugginess(amount) druggy = max(druggy+amount, 0) + GET_COMPONENT_FROM(mood, /datum/component/mood, src) if(druggy) overlay_fullscreen("high", /obj/screen/fullscreen/high) throw_alert("high", /obj/screen/alert/high) + if(mood) + mood.add_event("high", /datum/mood_event/drugs/high) else clear_fullscreen("high") clear_alert("high") + if(mood) + mood.clear_event("high") /mob/living/carbon/set_drugginess(amount) druggy = max(amount, 0) @@ -97,4 +102,3 @@ var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) if(B) . = B.cure_all_traumas(resilience) - diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index dcd3789360..b5a0ff369d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -952,6 +952,9 @@ "You're set on fire!") new/obj/effect/dummy/fire(src) throw_alert("fire", /obj/screen/alert/fire) + GET_COMPONENT_FROM(mood, /datum/component/mood, src) + if(mood) + mood.add_event("on_fire", /datum/mood_event/on_fire) update_fire() return TRUE return FALSE @@ -963,6 +966,9 @@ for(var/obj/effect/dummy/fire/F in src) qdel(F) clear_alert("fire") + GET_COMPONENT_FROM(mood, /datum/component/mood, src) + if(mood) + mood.clear_event("on_fire") update_fire() /mob/living/proc/adjust_fire_stacks(add_fire_stacks) //Adjusting the amount of fire_stacks we have on person diff --git a/code/modules/mob/living/simple_animal/friendly/cockroach.dm b/code/modules/mob/living/simple_animal/friendly/cockroach.dm index a6e24f43dd..5a9ae07374 100644 --- a/code/modules/mob/living/simple_animal/friendly/cockroach.dm +++ b/code/modules/mob/living/simple_animal/friendly/cockroach.dm @@ -58,3 +58,4 @@ icon = 'icons/effects/blood.dmi' icon_state = "xfloor1" random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7") + beauty = -300 diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 282a02494a..ae1681cbef 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -231,6 +231,9 @@ return if(!item_to_add) user.visible_message("[user] pets [src].","You rest your hand on [src]'s head for a moment.") + GET_COMPONENT_FROM(mood, /datum/component/mood, user) + if(mood) + mood.add_event("pet_corgi", /datum/mood_event/pet_corgi) return if(user && !user.temporarilyRemoveItemFromInventory(item_to_add)) @@ -613,6 +616,9 @@ if(M && stat != DEAD) // Added check to see if this mob (the dog) is dead to fix issue 2454 new /obj/effect/temp_visual/heart(loc) emote("me", 1, "yaps happily!") + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if(mood) + mood.add_event("pet_corgi", /datum/mood_event/pet_corgi) else if(M && stat != DEAD) // Same check here, even though emote checks it as well (poor form to check it only in the help case) emote("me", 1, "growls!") diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm index de8545d3f0..eb2b1be1d4 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm @@ -66,6 +66,7 @@ desc = "A small pool of sludge, containing trace amounts of leaper venom." icon = 'icons/effects/tomatodecal.dmi' icon_state = "tomato_floor1" + beauty = -200 /obj/structure/leaper_bubble name = "leaper bubble" diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 017b1e7b2b..7a07ba5a7f 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -233,6 +233,9 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) if(M.z == z) SEND_SOUND(M, 'sound/magic/charge.ogg') to_chat(M, "You feel reality distort for a moment...") + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if(mood) + mood.add_event("delam", /datum/mood_event/delam) if(combined_gas > MOLE_PENALTY_THRESHOLD) investigate_log("has collapsed into a singularity.", INVESTIGATE_SUPERMATTER) if(T) diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm new file mode 100644 index 0000000000..2d7f8f5cce --- /dev/null +++ b/code/modules/projectiles/projectile/energy.dm @@ -0,0 +1,203 @@ +/obj/item/projectile/energy + name = "energy" + icon_state = "spark" + damage = 0 + damage_type = BURN + flag = "energy" + is_reflectable = TRUE + +/obj/item/projectile/energy/chameleon + nodamage = TRUE + +/obj/item/projectile/energy/electrode + name = "electrode" + icon_state = "spark" + color = "#FFFF00" + nodamage = 1 + knockdown = 100 + stutter = 5 + jitter = 20 + hitsound = 'sound/weapons/taserhit.ogg' + range = 7 + tracer_type = /obj/effect/projectile/tracer/stun + muzzle_type = /obj/effect/projectile/muzzle/stun + impact_type = /obj/effect/projectile/impact/stun + +/obj/item/projectile/energy/electrode/on_hit(atom/target, blocked = FALSE) + . = ..() + if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - burst into sparks! + do_sparks(1, TRUE, src) + else if(iscarbon(target)) + var/mob/living/carbon/C = target + if(C.dna && C.dna.check_mutation(HULK)) + C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) + else if((C.status_flags & CANKNOCKDOWN) && !C.has_trait(TRAIT_STUNIMMUNE)) + addtimer(CALLBACK(C, /mob/living/carbon.proc/do_jitter_animation, jitter), 5) + +/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet + do_sparks(1, TRUE, src) + ..() + +/obj/item/projectile/energy/net + name = "energy netting" + icon_state = "e_netting" + damage = 10 + damage_type = STAMINA + hitsound = 'sound/weapons/taserhit.ogg' + range = 10 + +/obj/item/projectile/energy/net/Initialize() + . = ..() + SpinAnimation() + +/obj/item/projectile/energy/net/on_hit(atom/target, blocked = FALSE) + if(isliving(target)) + var/turf/Tloc = get_turf(target) + if(!locate(/obj/effect/nettingportal) in Tloc) + new /obj/effect/nettingportal(Tloc) + ..() + +/obj/item/projectile/energy/net/on_range() + do_sparks(1, TRUE, src) + ..() + +/obj/effect/nettingportal + name = "DRAGnet teleportation field" + desc = "A field of bluespace energy, locking on to teleport a target." + icon = 'icons/effects/effects.dmi' + icon_state = "dragnetfield" + light_range = 3 + anchored = TRUE + +/obj/effect/nettingportal/Initialize() + . = ..() + var/obj/item/device/radio/beacon/teletarget = null + for(var/obj/machinery/computer/teleporter/com in GLOB.machines) + if(com.target) + if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged) + teletarget = com.target + + addtimer(CALLBACK(src, .proc/pop, teletarget), 30) + +/obj/effect/nettingportal/proc/pop(teletarget) + if(teletarget) + for(var/mob/living/L in get_turf(src)) + do_teleport(L, teletarget, 2)//teleport what's in the tile to the beacon + else + for(var/mob/living/L in get_turf(src)) + do_teleport(L, L, 15) //Otherwise it just warps you off somewhere. + + qdel(src) + +/obj/effect/nettingportal/singularity_act() + return + +/obj/effect/nettingportal/singularity_pull() + return + + +/obj/item/projectile/energy/trap + name = "energy snare" + icon_state = "e_snare" + nodamage = 1 + knockdown = 20 + hitsound = 'sound/weapons/taserhit.ogg' + range = 4 + +/obj/item/projectile/energy/trap/on_hit(atom/target, blocked = FALSE) + if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - drop a trap + new/obj/item/restraints/legcuffs/beartrap/energy(get_turf(loc)) + else if(iscarbon(target)) + var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy(get_turf(target)) + B.Crossed(target) + ..() + +/obj/item/projectile/energy/trap/on_range() + new /obj/item/restraints/legcuffs/beartrap/energy(loc) + ..() + +/obj/item/projectile/energy/trap/cyborg + name = "Energy Bola" + icon_state = "e_snare" + nodamage = 1 + knockdown = 0 + hitsound = 'sound/weapons/taserhit.ogg' + range = 10 + +/obj/item/projectile/energy/trap/cyborg/on_hit(atom/target, blocked = FALSE) + if(!ismob(target) || blocked >= 100) + do_sparks(1, TRUE, src) + qdel(src) + if(iscarbon(target)) + var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy/cyborg(get_turf(target)) + B.Crossed(target) + QDEL_IN(src, 10) + ..() + +/obj/item/projectile/energy/trap/cyborg/on_range() + do_sparks(1, TRUE, src) + qdel(src) + +/obj/item/projectile/energy/declone + name = "radiation beam" + icon_state = "declone" + damage = 20 + damage_type = CLONE + irradiate = 10 + impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser + +/obj/item/projectile/energy/dart //ninja throwing dart + name = "dart" + icon_state = "toxin" + damage = 5 + damage_type = TOX + knockdown = 100 + range = 7 + +/obj/item/projectile/energy/bolt //ebow bolts + name = "bolt" + icon_state = "cbbolt" + damage = 8 + damage_type = TOX + nodamage = 0 + knockdown = 100 + stutter = 5 + +/obj/item/projectile/energy/bolt/halloween + name = "candy corn" + icon_state = "candy_corn" + +/obj/item/projectile/energy/bolt/large + damage = 20 + +/obj/item/projectile/energy/tesla + name = "tesla bolt" + icon_state = "tesla_projectile" + impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser + var/chain + +/obj/item/projectile/energy/tesla/fire(setAngle) + if(firer) + chain = firer.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY) + ..() + +/obj/item/projectile/energy/tesla/Destroy() + qdel(chain) + return ..() + +/obj/item/projectile/energy/tesla/revolver + name = "energy orb" + +/obj/item/projectile/energy/tesla/revolver/on_hit(atom/target) + . = ..() + if(isliving(target)) + tesla_zap(target, 3, 10000) + qdel(src) + +/obj/item/projectile/energy/tesla/cannon + name = "tesla orb" + +/obj/item/projectile/energy/tesla/cannon/on_hit(atom/target) + . = ..() + tesla_zap(target, 3, 10000, explosive = FALSE, stun_mobs = FALSE) + qdel(src) diff --git a/code/modules/projectiles/projectile/energy/net_snare.dm b/code/modules/projectiles/projectile/energy/net_snare.dm index 01e87d26cd..8cf4dc6f41 100644 --- a/code/modules/projectiles/projectile/energy/net_snare.dm +++ b/code/modules/projectiles/projectile/energy/net_snare.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/item/projectile/energy/net name = "energy netting" icon_state = "e_netting" @@ -96,3 +97,103 @@ /obj/item/projectile/energy/trap/cyborg/on_range() do_sparks(1, TRUE, src) qdel(src) +======= +/obj/item/projectile/energy/net + name = "energy netting" + icon_state = "e_netting" + damage = 10 + damage_type = STAMINA + hitsound = 'sound/weapons/taserhit.ogg' + range = 10 + +/obj/item/projectile/energy/net/Initialize() + . = ..() + SpinAnimation() + +/obj/item/projectile/energy/net/on_hit(atom/target, blocked = FALSE) + if(isliving(target)) + var/turf/Tloc = get_turf(target) + if(!locate(/obj/effect/nettingportal) in Tloc) + new /obj/effect/nettingportal(Tloc) + ..() + +/obj/item/projectile/energy/net/on_range() + do_sparks(1, TRUE, src) + ..() + +/obj/effect/nettingportal + name = "DRAGnet teleportation field" + desc = "A field of bluespace energy, locking on to teleport a target." + icon = 'icons/effects/effects.dmi' + icon_state = "dragnetfield" + light_range = 3 + anchored = TRUE + +/obj/effect/nettingportal/Initialize() + . = ..() + var/obj/item/device/beacon/teletarget = null + for(var/obj/machinery/computer/teleporter/com in GLOB.machines) + if(com.target) + if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged) + teletarget = com.target + + addtimer(CALLBACK(src, .proc/pop, teletarget), 30) + +/obj/effect/nettingportal/proc/pop(teletarget) + if(teletarget) + for(var/mob/living/L in get_turf(src)) + do_teleport(L, teletarget, 2)//teleport what's in the tile to the beacon + else + for(var/mob/living/L in get_turf(src)) + do_teleport(L, L, 15) //Otherwise it just warps you off somewhere. + + qdel(src) + +/obj/effect/nettingportal/singularity_act() + return + +/obj/effect/nettingportal/singularity_pull() + return + +/obj/item/projectile/energy/trap + name = "energy snare" + icon_state = "e_snare" + nodamage = 1 + knockdown = 20 + hitsound = 'sound/weapons/taserhit.ogg' + range = 4 + +/obj/item/projectile/energy/trap/on_hit(atom/target, blocked = FALSE) + if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - drop a trap + new/obj/item/restraints/legcuffs/beartrap/energy(get_turf(loc)) + else if(iscarbon(target)) + var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy(get_turf(target)) + B.Crossed(target) + ..() + +/obj/item/projectile/energy/trap/on_range() + new /obj/item/restraints/legcuffs/beartrap/energy(loc) + ..() + +/obj/item/projectile/energy/trap/cyborg + name = "Energy Bola" + icon_state = "e_snare" + nodamage = 1 + knockdown = 0 + hitsound = 'sound/weapons/taserhit.ogg' + range = 10 + +/obj/item/projectile/energy/trap/cyborg/on_hit(atom/target, blocked = FALSE) + if(!ismob(target) || blocked >= 100) + do_sparks(1, TRUE, src) + qdel(src) + if(iscarbon(target)) + var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy/cyborg(get_turf(target)) + B.Crossed(target) + QDEL_IN(src, 10) + ..() + +/obj/item/projectile/energy/trap/cyborg/on_range() + do_sparks(1, TRUE, src) + qdel(src) +>>>>>>> 5140cff... [reviewpls] Adds moodlets to the game - [Please give suggestions for trait additions in comments] (#35475) diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm index 598b64d025..3b04febae3 100644 --- a/code/modules/projectiles/projectile/energy/stun.dm +++ b/code/modules/projectiles/projectile/energy/stun.dm @@ -18,6 +18,9 @@ do_sparks(1, TRUE, src) else if(iscarbon(target)) var/mob/living/carbon/C = target + GET_COMPONENT_FROM(mood, /datum/component/mood, C) + if(mood) + mood.add_event("tased", /datum/mood_event/tased) if(C.dna && C.dna.check_mutation(HULK)) C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) else if((C.status_flags & CANKNOCKDOWN) && !C.has_trait(TRAIT_STUNIMMUNE)) diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 5735463af2..2a650f3381 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -303,6 +303,9 @@ need_mob_update += R.addiction_act_stage4(C) if(40 to INFINITY) to_chat(C, "You feel like you've gotten over your need for [R.name].") + GET_COMPONENT_FROM(mood, /datum/component/mood, C) + if(mood) + mood.clear_event("[R.id]_addiction") cached_addictions.Remove(R) addiction_tick++ if(C && need_mob_update) //some of the metabolized reagents had effects on the mob that requires some updates. diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 70bb594c8b..a1a65409a1 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -91,24 +91,39 @@ /datum/reagent/proc/overdose_start(mob/living/M) to_chat(M, "You feel like you took too much of [name]!") + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if(mood) + mood.add_event("[id]_overdose", /datum/mood_event/drugs/overdose, name) return /datum/reagent/proc/addiction_act_stage1(mob/living/M) + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if(mood) + mood.add_event("[id]_overdose", /datum/mood_event/drugs/withdrawal_light, name) if(prob(30)) to_chat(M, "You feel like having some [name] right about now.") return /datum/reagent/proc/addiction_act_stage2(mob/living/M) + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if(mood) + mood.add_event("[id]_overdose", /datum/mood_event/drugs/withdrawal_medium, name) if(prob(30)) to_chat(M, "You feel like you need [name]. You just can't get enough.") return /datum/reagent/proc/addiction_act_stage3(mob/living/M) + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if(mood) + mood.add_event("[id]_overdose", /datum/mood_event/drugs/withdrawal_severe, name) if(prob(30)) to_chat(M, "You have an intense craving for [name].") return /datum/reagent/proc/addiction_act_stage4(mob/living/M) + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if(mood) + mood.add_event("[id]_overdose", /datum/mood_event/drugs/withdrawal_critical, name) if(prob(30)) to_chat(M, "You're not feeling good at all! You really need some [name].") return diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index b07b3ece5c..adcf7996d6 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -3,6 +3,12 @@ id = "drug" metabolization_rate = 0.5 * REAGENTS_METABOLISM taste_description = "bitterness" + var/trippy = TRUE //Does this drug make you trip? + +/datum/reagent/drug/on_mob_delete(mob/living/M) + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if(mood && trippy) + mood.clear_event("[id]_high") /datum/reagent/drug/space_drugs name = "Space drugs" @@ -23,7 +29,9 @@ /datum/reagent/drug/space_drugs/overdose_start(mob/living/M) to_chat(M, "You start tripping hard!") - + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if(mood) + mood.add_event("[id]_overdose", /datum/mood_event/drugs/overdose, name) /datum/reagent/drug/space_drugs/overdose_process(mob/living/M) if(M.hallucination < volume && prob(20)) @@ -38,11 +46,15 @@ color = "#60A584" // rgb: 96, 165, 132 addiction_threshold = 30 taste_description = "smoke" + trippy = FALSE /datum/reagent/drug/nicotine/on_mob_life(mob/living/M) if(prob(1)) var/smoke_message = pick("You feel relaxed.", "You feel calmed.","You feel alert.","You feel rugged.") to_chat(M, "[smoke_message]") + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if(mood) + mood.add_event("smoked", /datum/mood_event/drugs/smoked, name) M.AdjustStun(-20, 0) M.AdjustKnockdown(-20, 0) M.AdjustUnconscious(-20, 0) @@ -57,6 +69,7 @@ taste_description = "mint" reagent_state = LIQUID color = "#80AF9C" + trippy = FALSE /datum/reagent/drug/crank name = "Crank" diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 3dcf29f15e..55d64ea36c 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -378,7 +378,7 @@ M.adjust_bodytemperature(5 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL) ..() -/datum/reagent/mushroomhallucinogen +/datum/reagent/drug/mushroomhallucinogen name = "Mushroom Hallucinogen" id = "mushroomhallucinogen" description = "A strong hallucinogenic drug derived from certain species of mushroom." diff --git a/code/modules/spells/spell_types/mime.dm b/code/modules/spells/spell_types/mime.dm index 28960fce31..d51f89be18 100644 --- a/code/modules/spells/spell_types/mime.dm +++ b/code/modules/spells/spell_types/mime.dm @@ -56,10 +56,15 @@ /obj/effect/proc_holder/spell/targeted/mime/speak/cast(list/targets,mob/user = usr) for(var/mob/living/carbon/human/H in targets) H.mind.miming=!H.mind.miming + GET_COMPONENT_FROM(mood, /datum/component/mood, H) if(H.mind.miming) to_chat(H, "You make a vow of silence.") + if(mood) + mood.clear_event("vow") else to_chat(H, "You break your vow of silence.") + if(mood) + mood.add_event("vow", /datum/mood_event/broken_vow) // These spells can only be gotten from the "Guide for Advanced Mimery series" for Mime Traitors. diff --git a/code/modules/spells/spell_types/summonitem.dm b/code/modules/spells/spell_types/summonitem.dm index ab7702fcce..d568aa67f4 100644 --- a/code/modules/spells/spell_types/summonitem.dm +++ b/code/modules/spells/spell_types/summonitem.dm @@ -83,6 +83,9 @@ to_chat(C, "The [item_to_retrieve] that was embedded in your [L] has mysteriously vanished. How fortunate!") if(!C.has_embedded_objects()) C.clear_alert("embeddedobject") + GET_COMPONENT_FROM(mood, /datum/component/mood, C) + if(mood) + mood.clear_event("embedded") break else diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 7af437ae86..2cf8389a6b 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -19,6 +19,9 @@ affecting.receive_damage(CLAMP(brute_dam/2, 15, 50), CLAMP(burn_dam/2, 0, 50)) //Damage the chest based on limb's existing damage C.visible_message("[C]'s [src.name] has been violently dismembered!") C.emote("scream") + GET_COMPONENT_FROM(mood, /datum/component/mood, C) + if(mood) + mood.add_event("dismembered", /datum/mood_event/dismembered) drop_limb() if(dam_type == BURN) @@ -101,6 +104,9 @@ I.forceMove(src) if(!C.has_embedded_objects()) C.clear_alert("embeddedobject") + GET_COMPONENT_FROM(mood, /datum/component/mood, C) + if(mood) + mood.add_event("embedded") if(!special) if(C.dna) diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index 7ac387b4d8..2c90496eb6 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -121,6 +121,9 @@ I.forceMove(T) clear_alert("embeddedobject") + GET_COMPONENT_FROM(mood, /datum/component/mood, src) + if(mood) + mood.clear_event("embedded") /mob/living/carbon/proc/has_embedded_objects() . = 0 diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm index 1422c20c7b..d54f94b0be 100755 --- a/code/modules/surgery/organs/stomach.dm +++ b/code/modules/surgery/organs/stomach.dm @@ -36,21 +36,32 @@ H.blur_eyes(3) //We need to add more shit down here H.adjust_disgust(-0.5 * disgust_metabolism) - + GET_COMPONENT_FROM(mood, /datum/component/mood, H) switch(H.disgust) if(0 to DISGUST_LEVEL_GROSS) H.clear_alert("disgust") + if(mood) + mood.clear_event("disgust") if(DISGUST_LEVEL_GROSS to DISGUST_LEVEL_VERYGROSS) H.throw_alert("disgust", /obj/screen/alert/gross) + if(mood) + mood.add_event("disgust", /datum/mood_event/disgust/gross) if(DISGUST_LEVEL_VERYGROSS to DISGUST_LEVEL_DISGUSTED) H.throw_alert("disgust", /obj/screen/alert/verygross) + if(mood) + mood.add_event("disgust", /datum/mood_event/disgust/verygross) if(DISGUST_LEVEL_DISGUSTED to INFINITY) H.throw_alert("disgust", /obj/screen/alert/disgusted) + if(mood) + mood.add_event("disgust", /datum/mood_event/disgust/disgusted) /obj/item/organ/stomach/Remove(mob/living/carbon/M, special = 0) var/mob/living/carbon/human/H = owner if(istype(H)) H.clear_alert("disgust") + GET_COMPONENT_FROM(mood, /datum/component/mood, H) + if(mood) + mood.clear_event("disgust") ..() diff --git a/code/modules/surgery/remove_embedded_object.dm b/code/modules/surgery/remove_embedded_object.dm index 577541e6c4..8f3fad38f8 100644 --- a/code/modules/surgery/remove_embedded_object.dm +++ b/code/modules/surgery/remove_embedded_object.dm @@ -30,6 +30,9 @@ L.embedded_objects -= I if(!H.has_embedded_objects()) H.clear_alert("embeddedobject") + GET_COMPONENT_FROM(mood, /datum/component/mood, H) + if(mood) + mood.clear_event("embedded") if(objects > 0) user.visible_message("[user] successfully removes [objects] objects from [H]'s [L]!", "You successfully remove [objects] objects from [H]'s [L.name].") diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi index 5a088e451f..2c234e9894 100644 Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index e22c35a6c4..cdf6df2dab 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -81,6 +81,7 @@ h1.alert, h2.alert {color: #000000;} .unconscious {color: #0000ff; font-weight: bold;} .suicide {color: #ff5050; font-style: italic;} .green {color: #03ff39;} +.nicegreen {color: #14a833;} .shadowling {color: #3b2769;} .cult {color: #960000;} .cultlarge {color: #960000; font-weight: bold; font-size: 3;} diff --git a/tgstation.dme b/tgstation.dme index b1787c6712..f7b36ab728 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -222,6 +222,7 @@ #include "code\controllers\subsystem\medals.dm" #include "code\controllers\subsystem\minimap.dm" #include "code\controllers\subsystem\mobs.dm" +#include "code\controllers\subsystem\moods.dm" #include "code\controllers\subsystem\nightshift.dm" #include "code\controllers\subsystem\npcpool.dm" #include "code\controllers\subsystem\orbit.dm" @@ -321,6 +322,7 @@ #include "code\datums\components\jousting.dm" #include "code\datums\components\knockoff.dm" #include "code\datums\components\material_container.dm" +#include "code\datums\components\mood.dm" #include "code\datums\components\ntnet_interface.dm" #include "code\datums\components\paintable.dm" #include "code\datums\components\rad_insulation.dm" @@ -401,6 +403,11 @@ #include "code\datums\martial\psychotic_brawl.dm" #include "code\datums\martial\sleeping_carp.dm" #include "code\datums\martial\wrestling.dm" +#include "code\datums\mood_events\drug_events.dm" +#include "code\datums\mood_events\generic_negative_events.dm" +#include "code\datums\mood_events\generic_positive_events.dm" +#include "code\datums\mood_events\mood_event.dm" +#include "code\datums\mood_events\needs_events.dm" #include "code\datums\mutations\body.dm" #include "code\datums\mutations\chameleon.dm" #include "code\datums\mutations\cold_resistance.dm"