From dad2d44ea2c980135d89596589850e5896f88b31 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 19 Mar 2018 21:33:18 -0500 Subject: [PATCH] [MIRROR] [READY] Several fixes/changes to mood, longterm mood effects, beauty component (#5992) * [READY] Several fixes/changes to mood, longterm mood effects, beauty component (#36344) cl Floyd / Qustinnus del: Removes short-term effects of mood add; Adds long-term effects of mood by implementing sanity which goes up with good mood, down with bad mood, but takes time to change. Your sanity can be seen as your average mood in the recent past. All effects of moods are now covered by this system add: Beauty component, currently only attached to cleanables, but you could attach it to any atom/movable and make them pretty/ugly, affecting mood of anyone in the room. refactor: Removes the original way of adding mood events, uses signals properly instead. fix: Cleanables "giving" area's free beauty during initialization fix: Fixes some events not clearing properly /cl Fixes #36444 From now on mood no longer affects you directly, instead it decides whether your sanity goes up or down, when your sanity gets too low you will get the effects of what mood did before. This means getting hit with bad moods due to being attacked while not mean you are doomed anymore, and you get a large timeframe to get away and just fix your mood later. I also added the beauty component, you could add this to any object and it would either make a room prettier or uglier, comparable to DF or Rimworld. You could add traits to make certain people ugly, for example. * [READY] Several fixes/changes to mood, longterm mood effects, beauty component --- code/__DEFINES/components.dm | 10 ++ code/__DEFINES/mobs.dm | 22 ++- code/__DEFINES/sound.dm | 8 + code/__HELPERS/mobs.dm | 10 +- code/datums/brain_damage/mild.dm | 8 +- code/datums/components/beauty.dm | 35 +++++ code/datums/components/mood.dm | 137 +++++++++++++++--- code/datums/looping_sounds/item_sounds.dm | 6 + code/datums/mood_events/beauty_events.dm | 23 +++ .../mood_events/generic_negative_events.dm | 24 +-- .../mood_events/generic_positive_events.dm | 13 -- code/datums/mutations/body.dm | 4 +- code/datums/mutations/hulk.dm | 10 +- code/game/area/areas.dm | 31 ++-- code/game/machinery/computer/arcade.dm | 20 ++- code/game/objects/effects/contraband.dm | 1 + code/game/objects/effects/decals/cleanable.dm | 25 ++-- .../effects/decals/cleanable/aliens.dm | 2 +- .../effects/decals/cleanable/humans.dm | 2 +- .../objects/effects/decals/cleanable/misc.dm | 26 ++-- .../effects/decals/cleanable/robots.dm | 2 +- code/game/objects/items.dm | 4 +- code/game/objects/items/blueprints.dm | 2 +- code/game/objects/items/cigs_lighters.dm | 4 +- code/game/objects/items/clown_items.dm | 4 +- code/game/objects/items/storage/book.dm | 4 +- code/game/objects/items/weaponry.dm | 4 + code/game/objects/structures/flora.dm | 4 + code/game/objects/structures/showcase.dm | 8 +- code/game/objects/structures/statues.dm | 5 + code/game/objects/structures/tables_racks.dm | 9 +- code/game/objects/structures/watercloset.dm | 4 +- code/game/turfs/open.dm | 4 +- .../antagonists/_common/antag_datum.dm | 8 +- code/modules/client/verbs/suicide.dm | 4 +- code/modules/clothing/shoes/miscellaneous.dm | 8 +- code/modules/flufftext/Hallucination.dm | 7 +- code/modules/food_and_drinks/food.dm | 12 +- .../food_and_drinks/food/snacks_pie.dm | 4 +- code/modules/library/lib_items.dm | 4 +- code/modules/mob/living/carbon/carbon.dm | 7 +- .../mob/living/carbon/carbon_defense.dm | 4 +- code/modules/mob/living/carbon/human/human.dm | 9 +- .../mob/living/carbon/human/human_defense.dm | 4 +- code/modules/mob/living/carbon/human/life.dm | 15 +- .../mob/living/carbon/human/species.dm | 55 +++---- code/modules/mob/living/carbon/life.dm | 7 +- code/modules/mob/living/carbon/monkey/life.dm | 2 +- .../modules/mob/living/carbon/status_procs.dm | 7 +- code/modules/mob/living/living.dm | 7 +- .../mob/living/simple_animal/friendly/dog.dm | 8 +- code/modules/power/supermatter/supermatter.dm | 4 +- .../projectiles/projectile/energy/stun.dm | 4 +- code/modules/reagents/chemistry/holder.dm | 4 +- code/modules/reagents/chemistry/reagents.dm | 20 +-- .../chemistry/reagents/drug_reagents.dm | 13 +- code/modules/spells/spell_types/mime.dm | 7 +- code/modules/spells/spell_types/summonitem.dm | 4 +- .../surgery/bodyparts/dismemberment.dm | 8 +- code/modules/surgery/bodyparts/helpers.dm | 4 +- code/modules/surgery/organs/stomach.dm | 18 +-- .../modules/surgery/remove_embedded_object.dm | 4 +- icons/mob/screen_gen.dmi | Bin 122733 -> 124912 bytes tgstation.dme | 2 + 64 files changed, 394 insertions(+), 345 deletions(-) create mode 100644 code/datums/components/beauty.dm create mode 100644 code/datums/mood_events/beauty_events.dm diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index bbe29f3e85..51579b4d88 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -19,6 +19,10 @@ #define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (/datum/component) #define COMSIG_PARENT_QDELETED "parent_qdeleted" //before a datum's Destroy() is called: () +// /Component signals +#define COMSIG_ADD_MOOD_EVENT "add_mood" //Called when you send a mood event from anywhere in the code. +#define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code. + #define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength) #define COMSIG_COMPONENT_NTNET_RECIEVE "ntnet_recieve" //called on an object by its NTNET connection component on recieve. (sending_id(number), sending_netname(text), data(datum/netdata)) @@ -50,6 +54,8 @@ #define COMSIG_ATOM_SET_LIGHT "atom_set_light" //from base of atom/set_light(): (l_range, l_power, l_color) #define COMSIG_ATOM_ROTATE "atom_rotate" //from base of atom/shuttleRotate(): (rotation, params) #define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" //from base of atom/setDir(): (old_dir, new_dir) +#define COMSIG_ENTER_AREA "enter_area" //from base of area/Entered(): (/area) +#define COMSIG_EXIT_AREA "exit_area" //from base of area/Exited(): (/area) #define COMSIG_CLICK "atom_click" //from base of atom/Click(): (location, control, params) #define COMSIG_CLICK_SHIFT "shift_click" //from base of atom/ShiftClick(): (/mob) @@ -57,6 +63,10 @@ #define COMSIG_CLICK_ALT "alt_click" //from base of atom/AltClick(): (/mob) #define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click" //from base of atom/CtrlShiftClick(/mob) +// /area signals +#define COMSIG_AREA_ENTERED "area_entered" //from base of area/Entered(): (atom/movable/M) +#define COMSIG_AREA_EXITED "area_exited" //from base of area/Exited(): (atom/movable/M) + // /atom/movable signals #define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir) #define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 71267e272f..8be6ac7782 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -95,15 +95,23 @@ #define MOOD_LEVEL_SAD1 -3 #define MOOD_LEVEL_SAD2 -12 #define MOOD_LEVEL_SAD3 -18 -#define MOOD_LEVEL_SAD4 -26 +#define MOOD_LEVEL_SAD4 -25 + +//Sanity levels for humans +#define SANITY_GREAT 125 +#define SANITY_NEUTRAL 100 +#define SANITY_DISTURBED 75 +#define SANITY_UNSTABLE 50 +#define SANITY_CRAZY 25 +#define SANITY_INSANE 0 //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 - - +#define BEAUTY_LEVEL_HORRID -100 +#define BEAUTY_LEVEL_BAD -66 +#define BEAUTY_LEVEL_MEH -33 +#define BEAUTY_LEVEL_DECENT 33 +#define BEAUTY_LEVEL_GOOD 66 +#define BEAUTY_LEVEL_GREAT 100 //Nutrition levels for humans #define NUTRITION_LEVEL_FAT 600 diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm index 453a02db01..f2d78f3438 100644 --- a/code/__DEFINES/sound.dm +++ b/code/__DEFINES/sound.dm @@ -70,3 +70,11 @@ 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambiodd.ogg') #define REEBE list('sound/ambience/ambireebe1.ogg', 'sound/ambience/ambireebe2.ogg', 'sound/ambience/ambireebe3.ogg') + + + +#define CREEPY_SOUNDS list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/screech.ogg',\ + 'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\ + 'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\ + 'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\ + 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg') diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index d2b8ad7d9f..709625ca3f 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -396,13 +396,11 @@ Proc for attack log creation, because really why not 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) + switch(mood.sanity) //Alters do_after delay based on how sane you are + if(SANITY_INSANE to SANITY_DISTURBED) delay *= 1.25 - if(MOOD_LEVEL_HAPPY3 to MOOD_LEVEL_HAPPY4) - delay *= 0.95 - if(MOOD_LEVEL_HAPPY4 to INFINITY) - delay *= 0.9 + if(SANITY_NEUTRAL to SANITY_GREAT) + delay *= 0.90 var/endtime = world.time + delay var/starttime = world.time diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm index 9a523cb39f..5c23fb4c8b 100644 --- a/code/datums/brain_damage/mild.dm +++ b/code/datums/brain_damage/mild.dm @@ -43,9 +43,7 @@ /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) + owner.SendSignal(COMSIG_ADD_MOOD_EVENT, "dumb", /datum/mood_event/oblivious) ..() /datum/brain_trauma/mild/dumbness/on_life() @@ -59,9 +57,7 @@ /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") + owner.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "dumb") ..() /datum/brain_trauma/mild/speech_impediment diff --git a/code/datums/components/beauty.dm b/code/datums/components/beauty.dm new file mode 100644 index 0000000000..4dbfca4014 --- /dev/null +++ b/code/datums/components/beauty.dm @@ -0,0 +1,35 @@ +/datum/component/beauty + var/beauty = 0 + +/datum/component/beauty/Initialize(beautyamount) + if(!ismovableatom(parent)) + . = COMPONENT_INCOMPATIBLE + CRASH("Someone put a beauty component on a non-atom/movable, not everything can be pretty.") + beauty = beautyamount + RegisterSignal(COMSIG_ENTER_AREA, .proc/enter_area) + RegisterSignal(COMSIG_EXIT_AREA, .proc/exit_area) + var/area/A = get_area(parent) + if(!A || A.outdoors) + return + A.totalbeauty += beauty + A.update_beauty() + +/datum/component/beauty/proc/enter_area(area/A) + if(A.outdoors) //Fuck the outside. + return FALSE + A.totalbeauty += beauty + A.update_beauty() + +/datum/component/beauty/proc/exit_area(area/A) + if(A.outdoors) //Fuck the outside. + return FALSE + A.totalbeauty -= beauty + A.update_beauty() + +/datum/component/beauty/Destroy() + . = ..() + var/area/A = get_area(parent) + if(!A || A.outdoors) + return + A.totalbeauty -= beauty + A.update_beauty() diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index 2f0401302f..f522445ee0 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -1,10 +1,12 @@ /datum/component/mood var/mood //Real happiness + var/sanity = 100 //Current sanity 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_level = 5 //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 + var/datum/looping_sound/reverse_bear_trap/slow/soundloop //Insanity ticking /datum/component/mood/Initialize() if(!isliving(parent)) @@ -12,16 +14,61 @@ 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 + soundloop = new(list(owner), FALSE, TRUE) + RegisterSignal(COMSIG_ADD_MOOD_EVENT, .proc/add_event) + RegisterSignal(COMSIG_CLEAR_MOOD_EVENT, .proc/clear_event) + RegisterSignal(COMSIG_ENTER_AREA, .proc/update_beauty) /datum/component/mood/Destroy() STOP_PROCESSING(SSmood, src) + QDEL_NULL(soundloop) 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 + msg += "My mental status: " //Long term + switch(sanity) + if(SANITY_GREAT to INFINITY) + msg += "My mind feels like a temple!\n" + if(SANITY_NEUTRAL to SANITY_GREAT) + msg += "I have been feeling great lately!\n" + if(SANITY_DISTURBED to SANITY_NEUTRAL) + msg += "I have felt quite decent lately.\n" + if(SANITY_UNSTABLE to SANITY_DISTURBED) + msg += "I'm feeling a little bit unhinged...\n" + if(SANITY_CRAZY to SANITY_UNSTABLE) + msg += "I'm freaking out!!\n" + if(SANITY_INSANE to SANITY_CRAZY) + msg += "AHAHAHAHAHAHAHAHAHAH!!\n" + + msg += "My current mood: " //Short term + switch(mood_level) + if(1) + msg += "I wish I was dead!\n" + if(2) + msg += "I feel terrible...\n" + if(3) + msg += "I feel very upset.\n" + if(4) + msg += "I'm a bit sad.\n" + if(5) + msg += "I'm alright.\n" + if(6) + msg += "I feel pretty okay.\n" + if(7) + msg += "I feel pretty good.\n" + if(8) + msg += "I feel amazing!\n" + if(9) + msg += "I love life!\n" + + msg += "Moodlets:\n"//All moodlets + if(mood_events.len) + for(var/i in mood_events) + var/datum/mood_event/event = mood_events[i] + msg += event.description + else + msg += "Nothing special has happend to me lately!\n" to_chat(owner, msg) /datum/component/mood/proc/update_mood() //Called whenever a mood event is added or removed @@ -54,41 +101,87 @@ mood_level = 8 if(MOOD_LEVEL_HAPPY4 to INFINITY) mood_level = 9 + update_mood_icon() + +/datum/component/mood/proc/update_mood_icon() if(owner.client && owner.hud_used) - owner.hud_used.mood.icon_state = "mood[mood_level]" + if(sanity < 25) + owner.hud_used.mood.icon_state = "mood_insane" + else + 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) + switch(sanity) + if(SANITY_INSANE to SANITY_CRAZY) owner.overlay_fullscreen("depression", /obj/screen/fullscreen/depression, 3) - if(MOOD_LEVEL_SAD4 to MOOD_LEVEL_SAD3) + update_mood_icon() + if(prob(7)) + owner.playsound_local(null, pick(CREEPY_SOUNDS), 100, 1) + soundloop.start() + if(SANITY_INSANE to SANITY_UNSTABLE) owner.overlay_fullscreen("depression", /obj/screen/fullscreen/depression, 2) - if(MOOD_LEVEL_SAD3 to MOOD_LEVEL_SAD2) + if(prob(3)) + owner.playsound_local(null, pick(CREEPY_SOUNDS), 60, 1) + soundloop.stop() + if(SANITY_UNSTABLE to SANITY_DISTURBED) owner.overlay_fullscreen("depression", /obj/screen/fullscreen/depression, 1) - if(MOOD_LEVEL_SAD2 to INFINITY) + soundloop.stop() + if(SANITY_DISTURBED to SANITY_GREAT) owner.clear_fullscreen("depression") + soundloop.stop() + + switch(mood_level) + if(1) + DecreaseSanity(0.4) + if(2) + DecreaseSanity(0.25) + if(3) + DecreaseSanity(0.15) + if(4) + DecreaseSanity(0.05) + if(5) + IncreaseSanity(0.1) + if(6) + IncreaseSanity(0.15) + if(7) + IncreaseSanity(0.20) + if(8) + IncreaseSanity(0.25, 125) + if(9) + IncreaseSanity(0.4, 125) if(owner.has_trait(TRAIT_DEPRESSION)) - if(prob(0.1)) + if(prob(0.05)) add_event("depression", /datum/mood_event/depression) clear_event("jolly") if(owner.has_trait(TRAIT_JOLLY)) - if(prob(0.1)) + if(prob(0.05)) add_event("jolly", /datum/mood_event/jolly) clear_event("depression") + var/area/A = get_area(owner) + if(A) + update_beauty(A) + +/datum/component/mood/proc/DecreaseSanity(amount) + sanity = max(0, sanity - amount) + +/datum/component/mood/proc/IncreaseSanity(amount, limit = 99) + if(sanity > limit) + DecreaseSanity(-0.5) //Removes some sanity to go back to our current limit. + else + sanity = min(limit, sanity + amount) + /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) + the_event = new type(src, param) mood_events[category] = the_event update_mood() @@ -105,18 +198,22 @@ qdel(event) update_mood() -/datum/component/mood/proc/update_beauty(var/area/A) +/datum/component/mood/proc/update_beauty(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) + add_event("area_beauty", /datum/mood_event/horridroom) if(BEAUTY_LEVEL_HORRID to BEAUTY_LEVEL_BAD) - add_event("area_beauty", /datum/mood_event/grossroom) - if(BEAUTY_LEVEL_BAD to BEAUTY_LEVEL_GOOD) + add_event("area_beauty", /datum/mood_event/badroom) + if(BEAUTY_LEVEL_BAD to BEAUTY_LEVEL_MEH) + add_event("area_beauty", /datum/mood_event/mehroom) + if(BEAUTY_LEVEL_MEH to BEAUTY_LEVEL_DECENT) clear_event("area_beauty") + if(BEAUTY_LEVEL_DECENT to BEAUTY_LEVEL_GOOD) + add_event("area_beauty", /datum/mood_event/decentroom) if(BEAUTY_LEVEL_GOOD to BEAUTY_LEVEL_GREAT) - add_event("area_beauty", /datum/mood_event/niceroom) + add_event("area_beauty", /datum/mood_event/goodroom) if(BEAUTY_LEVEL_GREAT to INFINITY) add_event("area_beauty", /datum/mood_event/greatroom) diff --git a/code/datums/looping_sounds/item_sounds.dm b/code/datums/looping_sounds/item_sounds.dm index b418d20985..d0ec277b36 100644 --- a/code/datums/looping_sounds/item_sounds.dm +++ b/code/datums/looping_sounds/item_sounds.dm @@ -41,6 +41,12 @@ mid_length = 3.5 volume = 25 +/datum/looping_sound/reverse_bear_trap/slow + mid_sounds = list('sound/effects/clock_tick.ogg') + mid_length = 10 + volume = 40 + + /datum/looping_sound/reverse_bear_trap_beep mid_sounds = list('sound/machines/beep.ogg') mid_length = 60 diff --git a/code/datums/mood_events/beauty_events.dm b/code/datums/mood_events/beauty_events.dm new file mode 100644 index 0000000000..534facdb21 --- /dev/null +++ b/code/datums/mood_events/beauty_events.dm @@ -0,0 +1,23 @@ +/datum/mood_event/horridroom + description = "This room looks terrible!\n" + mood_change = -5 + +/datum/mood_event/badroom + description = "This room looks really bad.\n" + mood_change = -3 + +/datum/mood_event/mehroom + description = "This room doesn't look great.\n" + mood_change = -1 + +/datum/mood_event/decentroom + description = "This room looks alright.\n" + mood_change = 2 + +/datum/mood_event/goodroom + 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/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index c2db1e8a37..95161f4f39 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -49,7 +49,7 @@ /datum/mood_event/depression description = "I feel sad for no particular reason.\n" - mood_change = -6 + mood_change = -9 timeout = 1200 /datum/mood_event/shameful_suicide //suicide_acts that return SHAME, like sord @@ -64,7 +64,7 @@ /datum/mood_event/noshoes description = "I am a disgrace to comedy everywhere!\n" - mood_change = -3 + mood_change = -5 /datum/mood_event/tased description = "There's no \"z\" in \"taser\". It's in the zap.\n" @@ -73,13 +73,22 @@ /datum/mood_event/embedded description = "Pull it out!\n" - mood_change = -6 + mood_change = -7 /datum/mood_event/table description = "Someone threw me on a table!\n" mood_change = -2 timeout = 1200 +/datum/mood_event/table/add_effects() + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + if(iscatperson(H)) + H.startTailWag() + addtimer(CALLBACK(H, /mob/living/carbon/human.proc/endTailWag), 30) + description = "They want to play on the table!\n" + mood_change = 2 + /datum/mood_event/brain_damage mood_change = -3 @@ -96,15 +105,6 @@ 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" diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index f5c5bb9807..e96567cf9d 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -37,11 +37,6 @@ 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 @@ -61,11 +56,3 @@ 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/mutations/body.dm b/code/datums/mutations/body.dm index fd0dd077b7..f0da9b125f 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -11,9 +11,7 @@ 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) + owner.SendSignal(COMSIG_ADD_MOOD_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 b12efbc452..d51b7dd891 100644 --- a/code/datums/mutations/hulk.dm +++ b/code/datums/mutations/hulk.dm @@ -14,9 +14,7 @@ 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) + owner.SendSignal(COMSIG_ADD_MOOD_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 @@ -33,10 +31,8 @@ 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") - + owner.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "hulk") + /datum/mutation/human/hulk/say_mod(message) if(message) message = "[uppertext(replacetext(message, ".", "!"))]!!" diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 0f3bfb12b1..f5d0ec3bd7 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -31,8 +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/totalbeauty = 0 //All beauty in this area combined, only includes indoor area. + var/beauty = 0 // Beauty average per open turf in the area + var/areasize = 0 //Size of the area in open turfs, only calculated for indoors areas. var/power_equip = TRUE var/power_light = TRUE @@ -136,6 +137,7 @@ GLOBAL_LIST_EMPTY(teleportlocs) if(contents.len) var/list/areas_in_z = SSmapping.areas_in_z var/z + update_areasize() for(var/i in 1 to contents.len) var/atom/thing = contents[i] if(!thing) @@ -148,12 +150,12 @@ 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 /area/LateInitialize() power_change() // all machines set to current power level, also updates icon + update_beauty() /area/Destroy() STOP_PROCESSING(SSobj, src) @@ -476,12 +478,14 @@ GLOBAL_LIST_EMPTY(teleportlocs) used_environ += amount -/area/Entered(A) +/area/Entered(atom/movable/M) set waitfor = FALSE - if(!isliving(A)) + SendSignal(COMSIG_AREA_ENTERED, M) + M.SendSignal(COMSIG_ENTER_AREA, src) //The atom that enters the area + if(!isliving(M)) return - var/mob/living/L = A + var/mob/living/L = M if(!L.ckey) return @@ -501,9 +505,9 @@ 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) +/area/Exited(atom/movable/M) + SendSignal(COMSIG_AREA_EXITED, M) + M.SendSignal(COMSIG_EXIT_AREA, src) //The atom that exits the area /client/proc/ResetAmbiencePlayed() played = FALSE @@ -532,11 +536,16 @@ GLOBAL_LIST_EMPTY(teleportlocs) blob_allowed = FALSE addSorted() -/area/proc/update_area_size() +/area/proc/update_beauty() + if(!areasize) + return FALSE + beauty = totalbeauty / areasize + +/area/proc/update_areasize() if(outdoors) return FALSE areasize = 0 - for(var/turf/T in src.contents) + for(var/turf/open/T in contents) areasize++ /area/AllowDrop() diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 07f5c0f923..566df0b6c2 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -70,9 +70,7 @@ Reset() /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) + user.SendSignal(COMSIG_ADD_MOOD_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) @@ -175,7 +173,7 @@ sleep(10) enemy_hp -= attackamt - arcade_action() + arcade_action(usr) else if (href_list["heal"]) blocked = TRUE @@ -191,7 +189,7 @@ player_hp += healamt blocked = TRUE updateUsrDialog() - arcade_action() + arcade_action(usr) else if (href_list["charge"]) blocked = TRUE @@ -204,7 +202,7 @@ updateUsrDialog() sleep(10) - arcade_action() + arcade_action(usr) if (href_list["close"]) usr.unset_machine() @@ -227,7 +225,7 @@ updateUsrDialog() return -/obj/machinery/computer/arcade/battle/proc/arcade_action() +/obj/machinery/computer/arcade/battle/proc/arcade_action(mob/user) if ((enemy_mp <= 0) || (enemy_hp <= 0)) if(!gameover) gameover = TRUE @@ -242,7 +240,7 @@ Reset() obj_flags &= ~EMAGGED else - prizevend(usr) + prizevend(user) SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("win", (obj_flags & EMAGGED ? "emagged":"normal"))) @@ -484,7 +482,7 @@ if (href_list["continue"]) //Continue your travels if(gameStatus == ORION_STATUS_NORMAL && !event && turns != 7) if(turns >= ORION_TRAIL_WINTURN) - win() + win(usr) else food -= (alive+lings_aboard)*2 fuel -= 5 @@ -1028,7 +1026,7 @@ return removed -/obj/machinery/computer/arcade/orion_trail/proc/win() +/obj/machinery/computer/arcade/orion_trail/proc/win(mob/user) gameStatus = ORION_STATUS_START say("Congratulations, you made it to Orion!") if(obj_flags & EMAGGED) @@ -1036,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(usr) + prizevend(user) 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/contraband.dm b/code/game/objects/effects/contraband.dm index 4499b9b62e..4c4427e77f 100644 --- a/code/game/objects/effects/contraband.dm +++ b/code/game/objects/effects/contraband.dm @@ -60,6 +60,7 @@ /obj/structure/sign/poster/Initialize() . = ..() + addtimer(CALLBACK(src, /datum.proc/AddComponent, /datum/component/beauty, 75), 0) if(random_basetype) randomise(random_basetype) if(!ruined) diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index c070c1a6ea..0794b818da 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -4,17 +4,17 @@ 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? + var/beauty /obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases) . = ..() - if (random_icon_states && length(src.random_icon_states) > 0) - src.icon_state = pick(src.random_icon_states) + if (random_icon_states && length(random_icon_states) > 0) + icon_state = pick(random_icon_states) create_reagents(300) - if(src.loc && isturf(src.loc)) - for(var/obj/effect/decal/cleanable/C in src.loc) - if(C != src && C.type == src.type && !QDELETED(C)) + if(loc && isturf(loc)) + for(var/obj/effect/decal/cleanable/C in loc) + if(C != src && C.type == type && !QDELETED(C)) if (replace_decal(C)) return INITIALIZE_HINT_QDEL @@ -26,10 +26,9 @@ 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/ComponentInitialize() + . = ..() + addtimer(CALLBACK(src, /datum.proc/AddComponent, /datum/component/beauty, beauty), 0) //inb4 i get yelled at for using the beauty var on cleanable instead of calling this proc on every subtype which would be pedantic and actually run worse. /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) @@ -97,9 +96,3 @@ 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 79103c28aa..f93d5b5f44 100644 --- a/code/game/objects/effects/decals/cleanable/aliens.dm +++ b/code/game/objects/effects/decals/cleanable/aliens.dm @@ -8,7 +8,7 @@ random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7") bloodiness = MAX_SHOE_BLOODINESS blood_state = BLOOD_STATE_XENO - beauty = -200 + beauty = -250 /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 7b2c00a0b6..215a012b64 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -6,7 +6,7 @@ random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7") blood_state = BLOOD_STATE_HUMAN bloodiness = MAX_SHOE_BLOODINESS - beauty = -200 + beauty = -250 /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 e5253d4b85..53e368ea64 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -3,7 +3,7 @@ desc = "Someone should clean that up." icon = 'icons/obj/objects.dmi' icon_state = "shards" - beauty = -150 + beauty = -300 /obj/effect/decal/cleanable/ash name = "ashes" @@ -11,7 +11,7 @@ icon = 'icons/obj/objects.dmi' icon_state = "ash" mergeable_decal = FALSE - beauty = -150 + beauty = -300 /obj/effect/decal/cleanable/ash/Initialize() . = ..() @@ -26,7 +26,7 @@ /obj/effect/decal/cleanable/ash/large name = "large pile of ashes" icon_state = "big_ash" - beauty = -150 + beauty = -300 /obj/effect/decal/cleanable/ash/large/Initialize() . = ..() @@ -37,7 +37,7 @@ desc = "Back to sand." icon = 'icons/obj/shards.dmi' icon_state = "tiny" - beauty = -20 + beauty = -125 /obj/effect/decal/cleanable/glass/Initialize() . = ..() @@ -51,7 +51,7 @@ desc = "Someone should clean that up." icon_state = "dirt" mouse_opacity = MOUSE_OPACITY_TRANSPARENT - beauty = -150 + beauty = -300 /obj/effect/decal/cleanable/flour name = "flour" @@ -64,7 +64,7 @@ desc = "Jeez. I hope that's not for lunch." light_color = LIGHT_COLOR_GREEN icon_state = "greenglow" - beauty = -100 + beauty = -200 /obj/effect/decal/cleanable/greenglow/Initialize(mapload) . = ..() @@ -80,7 +80,7 @@ layer = WALL_OBJ_LAYER icon_state = "cobweb1" resistance_flags = FLAMMABLE - beauty = -150 + beauty = -300 /obj/effect/decal/cleanable/cobweb/cobweb2 icon_state = "cobweb2" @@ -92,12 +92,12 @@ icon = 'icons/effects/effects.dmi' icon_state = "molten" mergeable_decal = FALSE - beauty = -250 + beauty = -300 /obj/effect/decal/cleanable/molten_object/large name = "big gooey grey mass" icon_state = "big_molten" - beauty = -200 + beauty = -450 //Vomit (sorry) /obj/effect/decal/cleanable/vomit @@ -106,7 +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 + beauty = -600 /obj/effect/decal/cleanable/vomit/attack_hand(mob/user) if(ishuman(user)) @@ -161,7 +161,7 @@ gender = NEUTER icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("smashed_pie") - beauty = -125 + beauty = -200 /obj/effect/decal/cleanable/chem_pile name = "chemical pile" @@ -169,7 +169,7 @@ gender = NEUTER icon = 'icons/obj/objects.dmi' icon_state = "ash" - beauty = -125 + beauty = -200 /obj/effect/decal/cleanable/shreds name = "shreds" @@ -177,7 +177,7 @@ icon_state = "shreds" gender = PLURAL mergeable_decal = FALSE - beauty = -125 + beauty = -200 /obj/effect/decal/cleanable/shreds/ex_act(severity, target) if(severity == 1) //so shreds created during an explosion aren't deleted by the explosion. diff --git a/code/game/objects/effects/decals/cleanable/robots.dm b/code/game/objects/effects/decals/cleanable/robots.dm index b70b500bba..91956fdb65 100644 --- a/code/game/objects/effects/decals/cleanable/robots.dm +++ b/code/game/objects/effects/decals/cleanable/robots.dm @@ -47,7 +47,7 @@ random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7") blood_state = BLOOD_STATE_OIL bloodiness = MAX_SHOE_BLOODINESS - beauty = -125 + beauty = -150 /obj/effect/decal/cleanable/oil/Initialize() . = ..() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index d19f9d1ab6..92a4a93243 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -537,9 +537,7 @@ 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) + M.SendSignal(COMSIG_ADD_MOOD_EVENT, "eye_stab", /datum/mood_event/eye_stab) add_logs(user, M, "attacked", "[src.name]", "(INTENT: [uppertext(user.a_intent)])") diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index 0383121308..ad616e8ad3 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -191,7 +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() + A.update_areasize() interact() return 1 diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index b9f2276e23..cb934ce194 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -549,9 +549,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/hitzone = user.held_index_to_dir(user.active_hand_index) == "r" ? BODY_ZONE_PRECISE_R_HAND : BODY_ZONE_PRECISE_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) + user.SendSignal(COMSIG_ADD_MOOD_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 ab30e7ea18..515dab5e27 100644 --- a/code/game/objects/items/clown_items.dm +++ b/code/game/objects/items/clown_items.dm @@ -117,9 +117,7 @@ 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) + M.SendSignal(COMSIG_ADD_MOOD_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!") diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index 5e8b78769e..10b28e12f6 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -96,9 +96,7 @@ 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) + H.SendSignal(COMSIG_ADD_MOOD_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/items/weaponry.dm b/code/game/objects/items/weaponry.dm index c0802dfb55..bf67efa6c7 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -444,6 +444,10 @@ throw_range = 2 attack_verb = list("busted") +/obj/item/statuebust/Initialize() + . = ..() + addtimer(CALLBACK(src, /datum.proc/AddComponent, /datum/component/beauty, 1000), 0) + /obj/item/tailclub name = "tail club" desc = "For the beating to death of lizards with their own tails." diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 7c99a715cd..7d827abbb1 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -291,6 +291,10 @@ throw_speed = 2 throw_range = 4 +/obj/item/twohanded/required/kirbyplants/Initialize() + . = ..() + addtimer(CALLBACK(src, /datum.proc/AddComponent, /datum/component/beauty, 750), 0) + /obj/item/twohanded/required/kirbyplants/equipped(mob/living/user) var/image/I = image(icon = 'icons/obj/flora/plants.dmi' , icon_state = src.icon_state, loc = user) I.copy_overlays(src) diff --git a/code/game/objects/structures/showcase.dm b/code/game/objects/structures/showcase.dm index a976c2e3fe..fe6785db2d 100644 --- a/code/game/objects/structures/showcase.dm +++ b/code/game/objects/structures/showcase.dm @@ -11,6 +11,10 @@ anchored = TRUE var/deconstruction_state = SHOWCASE_CONSTRUCTED +/obj/structure/showcase/Initialize() + . = ..() + addtimer(CALLBACK(src, /datum.proc/AddComponent, /datum/component/beauty, 750), 0) + /obj/structure/showcase/fakeid name = "\improper CentCom identification console" desc = "You can use this to change ID's." @@ -18,7 +22,7 @@ icon_state = "computer" /obj/structure/showcase/fakeid/Initialize() - ..() + . = ..() add_overlay("id") add_overlay("id_key") @@ -29,7 +33,7 @@ icon_state = "computer" /obj/structure/showcase/fakesec/Initialize() - ..() + . = ..() add_overlay("security") add_overlay("security_key") diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index e5ab4e5776..8a58cce1b0 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -10,6 +10,11 @@ var/material_drop_type = /obj/item/stack/sheet/metal CanAtmosPass = ATMOS_PASS_DENSITY + +/obj/structure/statue/Initialize() + . = ..() + addtimer(CALLBACK(src, /datum.proc/AddComponent, /datum/component/beauty, 1250), 0) + /obj/structure/statue/attackby(obj/item/W, mob/living/user, params) add_fingerprint(user) user.changeNext_move(CLICK_CD_MELEE) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 3f47c7d7df..c83aa0efc7 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -116,14 +116,7 @@ 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) + H.SendSignal(COMSIG_ADD_MOOD_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 81a08c77a1..ec07a51380 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -335,9 +335,7 @@ 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) + L.SendSignal(COMSIG_ADD_MOOD_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 fc0681148a..b8a05de431 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -203,9 +203,7 @@ 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) + C.SendSignal(COMSIG_ADD_MOOD_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 8b603d109a..1ea471a346 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -109,16 +109,12 @@ GLOBAL_LIST_EMPTY(antagonists) /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) + owner.current.SendSignal(COMSIG_ADD_MOOD_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") + owner.current.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "antag_moodlet") //Returns the team antagonist belongs to if any. /datum/antagonist/proc/get_team() diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm index 9471f0ab9e..2b5602833a 100644 --- a/code/modules/client/verbs/suicide.dm +++ b/code/modules/client/verbs/suicide.dm @@ -21,9 +21,7 @@ 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) + SendSignal(COMSIG_ADD_MOOD_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 7ae401f564..d5e75d4bad 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -82,16 +82,12 @@ /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") + user.SendSignal(COMSIG_CLEAR_MOOD_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) + user.SendSignal(COMSIG_ADD_MOOD_EVENT, "noshoes", /datum/mood_event/noshoes) /obj/item/clothing/shoes/clown_shoes/jester name = "jester shoes" diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index c912a9b4e8..26391c0957 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -870,12 +870,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list( //Rare audio if("creepy") //These sounds are (mostly) taken from Hidden: Source - var/static/list/hallucinations_creepyasssounds = list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/screech.ogg',\ - 'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\ - 'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\ - 'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\ - 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg') - target.playsound_local(null, pick(hallucinations_creepyasssounds), 50, 1) + target.playsound_local(null, pick(CREEPY_SOUNDS), 50, 1) if("ratvar") target.playsound_local(null, 'sound/effects/ratvar_rises.ogg', 100) sleep(150) diff --git a/code/modules/food_and_drinks/food.dm b/code/modules/food_and_drinks/food.dm index 4e38cb81d9..375ce80f96 100644 --- a/code/modules/food_and_drinks/food.dm +++ b/code/modules/food_and_drinks/food.dm @@ -23,21 +23,15 @@ 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) + H.SendSignal(COMSIG_ADD_MOOD_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) + H.SendSignal(COMSIG_ADD_MOOD_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) + H.SendSignal(COMSIG_ADD_MOOD_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_pie.dm b/code/modules/food_and_drinks/food/snacks_pie.dm index 1f755e24b2..5efcb98faf 100644 --- a/code/modules/food_and_drinks/food/snacks_pie.dm +++ b/code/modules/food_and_drinks/food/snacks_pie.dm @@ -56,9 +56,7 @@ 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) + H.SendSignal(COMSIG_ADD_MOOD_EVENT, "creampie", /datum/mood_event/creampie) qdel(src) /obj/item/reagent_containers/food/snacks/pie/cream/nostun diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index b302701b24..25b091d2c7 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -206,9 +206,7 @@ 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) + user.SendSignal(COMSIG_ADD_MOOD_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 3b7e60213c..dc0b094128 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -755,17 +755,14 @@ //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) + SendSignal(COMSIG_ADD_MOOD_EVENT, "handcuffed", /datum/mood_event/handcuffed) else clear_alert("handcuffed") - if(mood) - mood.clear_event("handcuffed") + SendSignal(COMSIG_CLEAR_MOOD_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 0444398fba..75233a70c1 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -277,9 +277,7 @@ 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) + SendSignal(COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug) AdjustStun(-60) AdjustKnockdown(-60) AdjustUnconscious(-60) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 2bcb1d5189..22587d97d3 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -32,6 +32,7 @@ /mob/living/carbon/human/ComponentInitialize() + . = ..() if(!CONFIG_GET(flag/disable_human_mood)) AddComponent(/datum/component/mood) @@ -229,9 +230,7 @@ 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") + usr.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "embedded") return if(href_list["item"]) @@ -660,9 +659,7 @@ 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) + SendSignal(COMSIG_ADD_MOOD_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 fd60a60296..b744630a56 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -144,9 +144,7 @@ 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) + SendSignal(COMSIG_ADD_MOOD_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 246e615199..55f66c975e 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -85,18 +85,15 @@ 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 (getBrainLoss() >= 60 && !incapacitated(TRUE)) + SendSignal(COMSIG_ADD_MOOD_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") + SendSignal(COMSIG_CLEAR_MOOD_EVENT, "brain_damage") /mob/living/carbon/human/handle_mutations_and_radiation() if(!dna || !dna.species.handle_mutations_and_radiation(src)) @@ -343,9 +340,7 @@ 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") + SendSignal(COMSIG_CLEAR_MOOD_EVENT, "embedded") /mob/living/carbon/human/proc/handle_active_genes() for(var/datum/mutation/human/HM in dna.mutations) @@ -474,4 +469,4 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put #undef THERMAL_PROTECTION_ARM_LEFT #undef THERMAL_PROTECTION_ARM_RIGHT #undef THERMAL_PROTECTION_HAND_LEFT -#undef THERMAL_PROTECTION_HAND_RIGHT \ No newline at end of file +#undef THERMAL_PROTECTION_HAND_RIGHT diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 8b132f3b38..9e7a508579 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1124,14 +1124,8 @@ GLOBAL_LIST_EMPTY(roundstart_races) // 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(mood && mood.sanity > SANITY_DISTURBED) + hunger_rate *= min(0.5, 1 - 0.002 * mood.sanity) //0.85 to 0.75 if(H.satiety > 0) H.satiety-- @@ -1166,31 +1160,24 @@ 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.SendSignal(COMSIG_ADD_MOOD_EVENT, "nutrition", /datum/mood_event/nutrition/fat) H.throw_alert("nutrition", /obj/screen/alert/fat) if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL) - if(mood) - mood.add_event("nutrition", /datum/mood_event/nutrition/wellfed) + H.SendSignal(COMSIG_ADD_MOOD_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.SendSignal(COMSIG_ADD_MOOD_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.SendSignal(COMSIG_CLEAR_MOOD_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.SendSignal(COMSIG_ADD_MOOD_EVENT, "nutrition", /datum/mood_event/nutrition/hungry) H.throw_alert("nutrition", /obj/screen/alert/hungry) if(0 to NUTRITION_LEVEL_STARVING) - if(mood) - mood.add_event("nutrition", /datum/mood_event/nutrition/starving) + H.SendSignal(COMSIG_ADD_MOOD_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) @@ -1300,12 +1287,12 @@ GLOBAL_LIST_EMPTY(roundstart_races) 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) + switch(mood.sanity) + if(SANITY_INSANE to SANITY_CRAZY) . += 1.5 - if(MOOD_LEVEL_SAD4 to MOOD_LEVEL_SAD3) + if(SANITY_CRAZY to SANITY_UNSTABLE) . += 1 - if(MOOD_LEVEL_SAD3 to MOOD_LEVEL_SAD2) + if(SANITY_UNSTABLE to SANITY_DISTURBED) . += 0.5 if(H.has_trait(TRAIT_FAT)) @@ -1728,13 +1715,11 @@ 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) + H.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "cold") + H.SendSignal(COMSIG_ADD_MOOD_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) @@ -1754,9 +1739,8 @@ GLOBAL_LIST_EMPTY(roundstart_races) 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) + H.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "hot") + H.SendSignal(COMSIG_ADD_MOOD_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) @@ -1770,9 +1754,8 @@ GLOBAL_LIST_EMPTY(roundstart_races) else H.clear_alert("temp") - if(mood) - mood.clear_event("cold") - mood.clear_event("hot") + H.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "cold") + H.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "hot") var/pressure = environment.return_pressure() var/adjusted_pressure = H.calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob. @@ -1866,7 +1849,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) H.adjust_bodytemperature(11) else H.adjust_bodytemperature(BODYTEMP_HEATING_MAX + (H.fire_stacks * 12)) - + H.SendSignal(COMSIG_ADD_MOOD_EVENT, "on_fire", /datum/mood_event/on_fire) /datum/species/proc/CanIgniteMob(mob/living/carbon/human/H) if(H.has_trait(TRAIT_NOFIRE)) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index dc939f8fc1..42547e3544 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -144,7 +144,6 @@ //OXYGEN - GET_COMPONENT_FROM(mood, /datum/component/mood, src) if(O2_partialpressure < safe_oxy_min) //Not enough oxygen if(prob(20)) emote("gasp") @@ -157,8 +156,7 @@ 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) + SendSignal(COMSIG_ADD_MOOD_EVENT, "suffocation", /datum/mood_event/suffocation) else //Enough oxygen failed_last_breath = 0 @@ -166,8 +164,7 @@ adjustOxyLoss(-5) oxygen_used = breath_gases[/datum/gas/oxygen][MOLES] clear_alert("not_enough_oxy") - if(mood) - mood.clear_event("suffocation") + SendSignal(COMSIG_CLEAR_MOOD_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/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index a8f2e282ed..3baf5087d6 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -162,4 +162,4 @@ I.take_damage(fire_stacks, BURN, "fire", 0) adjust_bodytemperature(BODYTEMP_HEATING_MAX) - + SendSignal(COMSIG_ADD_MOOD_EVENT, "on_fire", /datum/mood_event/on_fire) diff --git a/code/modules/mob/living/carbon/status_procs.dm b/code/modules/mob/living/carbon/status_procs.dm index 1db31d5a2d..7a7a4681c5 100644 --- a/code/modules/mob/living/carbon/status_procs.dm +++ b/code/modules/mob/living/carbon/status_procs.dm @@ -42,17 +42,14 @@ /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) + SendSignal(COMSIG_ADD_MOOD_EVENT, "high", /datum/mood_event/drugs/high) else clear_fullscreen("high") clear_alert("high") - if(mood) - mood.clear_event("high") + SendSignal(COMSIG_CLEAR_MOOD_EVENT, "high") /mob/living/carbon/set_drugginess(amount) druggy = max(amount, 0) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 2ddd4281ae..933c25c992 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -984,9 +984,6 @@ "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 @@ -998,9 +995,7 @@ 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") + SendSignal(COMSIG_CLEAR_MOOD_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/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 4dab39e397..5c68ca8117 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -231,9 +231,7 @@ 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) + user.SendSignal(COMSIG_ADD_MOOD_EVENT, "pet_corgi", /datum/mood_event/pet_corgi) return if(user && !user.temporarilyRemoveItemFromInventory(item_to_add)) @@ -616,9 +614,7 @@ 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) + M.SendSignal(COMSIG_ADD_MOOD_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/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index d060286efb..5ed6b84a18 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -233,9 +233,7 @@ 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) + M.SendSignal(COMSIG_ADD_MOOD_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/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm index 3b04febae3..1c24d47a9d 100644 --- a/code/modules/projectiles/projectile/energy/stun.dm +++ b/code/modules/projectiles/projectile/energy/stun.dm @@ -18,9 +18,7 @@ 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) + C.SendSignal(COMSIG_ADD_MOOD_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 2a650f3381..d49c4a6fa0 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -303,9 +303,7 @@ 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") + C.SendSignal(COMSIG_CLEAR_MOOD_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 a1a65409a1..3fe5d47479 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -91,39 +91,29 @@ /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) + M.SendSignal(COMSIG_ADD_MOOD_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) + M.SendSignal(COMSIG_ADD_MOOD_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) + M.SendSignal(COMSIG_ADD_MOOD_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) + M.SendSignal(COMSIG_ADD_MOOD_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) + M.SendSignal(COMSIG_ADD_MOOD_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 22d638ea20..32b96d2780 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -6,9 +6,8 @@ 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") + if(trippy) + M.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "[id]_high") /datum/reagent/drug/space_drugs name = "Space drugs" @@ -29,9 +28,7 @@ /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) + M.SendSignal(COMSIG_ADD_MOOD_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)) @@ -52,9 +49,7 @@ 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.SendSignal(COMSIG_ADD_MOOD_EVENT, "smoked", /datum/mood_event/drugs/smoked, name) M.AdjustStun(-20, 0) M.AdjustKnockdown(-20, 0) M.AdjustUnconscious(-20, 0) diff --git a/code/modules/spells/spell_types/mime.dm b/code/modules/spells/spell_types/mime.dm index d51f89be18..f6b1921e6c 100644 --- a/code/modules/spells/spell_types/mime.dm +++ b/code/modules/spells/spell_types/mime.dm @@ -56,15 +56,12 @@ /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") + H.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "vow") else + H.SendSignal(COMSIG_ADD_MOOD_EVENT, "vow", /datum/mood_event/broken_vow) 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 d568aa67f4..bd5099da68 100644 --- a/code/modules/spells/spell_types/summonitem.dm +++ b/code/modules/spells/spell_types/summonitem.dm @@ -83,9 +83,7 @@ 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") + C.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "embedded") break else diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 5b128de600..aa0b714cc8 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -19,9 +19,7 @@ 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) + C.SendSignal(COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered) drop_limb() if(dam_type == BURN) @@ -104,9 +102,7 @@ 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") + C.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "embedded") if(!special) if(C.dna) diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index 36081ad677..12531a9ee5 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -121,9 +121,7 @@ I.forceMove(T) clear_alert("embeddedobject") - GET_COMPONENT_FROM(mood, /datum/component/mood, src) - if(mood) - mood.clear_event("embedded") + SendSignal(COMSIG_CLEAR_MOOD_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 e0d3dbb384..21b6f6abb3 100755 --- a/code/modules/surgery/organs/stomach.dm +++ b/code/modules/surgery/organs/stomach.dm @@ -36,33 +36,25 @@ 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") + H.SendSignal(COMSIG_CLEAR_MOOD_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) + H.SendSignal(COMSIG_ADD_MOOD_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) + H.SendSignal(COMSIG_ADD_MOOD_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) + H.SendSignal(COMSIG_ADD_MOOD_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") - + H.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "disgust") ..() /obj/item/organ/stomach/fly diff --git a/code/modules/surgery/remove_embedded_object.dm b/code/modules/surgery/remove_embedded_object.dm index 2818ea2ab5..548a73627d 100644 --- a/code/modules/surgery/remove_embedded_object.dm +++ b/code/modules/surgery/remove_embedded_object.dm @@ -30,9 +30,7 @@ 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") + H.SendSignal(COMSIG_CLEAR_MOOD_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 2c234e98941b8efe8166297d01b154b9ae7b7f92..28e37d526ccfa701fbd7ddbc3ca82bd0405cd660 100644 GIT binary patch delta 21761 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 HuEhQaI!FJo delta 19565 zcmbq)by!qk+vm_B2#QDw(jX#TqI8!c4N}rMAcEA)p+Q0jy$KZ{;wY%kOd)GJiP!|Zq zD{U}IEp}dv#DDm({CDkiwZx%1O6=E&0)8Y`tw}~0_EVy$0fRuU9~lWYM+c|oZ#Hy4 z9^c`_W|1cG^9#@8jNsjAE5o#&>p-QJbP#dzv2rbi<)&sjk=f9yVo{{EHV-{&Xl;wl zy4L`@4N$>*dvQj-M>>r9Xd?4Wbt9k3wQpf4Ugxr>GRAAv*u7uYfo>yT!#HYLDq0FI z_1K9$4_FeJu?G&%EFEBV{*$kLQXD$Gj^!?%_r;jUC0a2Vhdq4l8~9890aNCnmR?;p z&L5R;)aZ&>CoNXvbpNjO7LJszySKNG9`z4aasdkUc>DT;60;1hn03_m{Odm2Nm=hdVK>3ybu22BcMZ-Z8+>ltU3uG3roC)t z1UrM+E}>DWpu|y-2)*SoSHEw8Li#hCD5dZG;$JV6@5J`Lj(B$IUl-9R!cd?CPksA# z?Q{j{b4~}4i7;F1+pQ1vc6BBLiVUAprvCtk6(e0=-iL+2ccPxWOm7K;4lQ-nRfe@K zcxrx{Q?{y|W~@yK{Uw1pNZc95_?;DPTl{J&^+>9WdXIHep!;zYiADZsUMIaQ_o?ud zMZbU|zF05y4xd2qXT?-vcfwM?(Yl-3pZEpZWx5T*-ZSkA&FLh`*{%J12;e`*Fn%x_ zQux6m=}4VMpxq*mL`p7{#6om_$d4v$Ry>Z;i4V{odTt(U{QTtR5cG32(Cz z4`Dtd;UM<41wQ4GOwdjK+Lll`%9X-Fvac2BG)nXtCIt9cT0Z|U+cEMZahYTy)hjNa zl%_y5g-aWMdoY7!bd;$dXC1P-guq`mSS zRTnqvdb!HqE-_?a-@?{+9k1|L3l5ebO6Y)Wc#ixfO}-@3vXl{tkOH4O0x*ifex8i= z5h#Hcf)_o2ZvdY^^1=GOBb*7(K?%&QAqCeHEx`A#mi+50Xk3A59oYVf!S+UZ>-up= zL?a0iGJ7(%k>n0IqAmJgyMyD#iE|eUQ^HZdK0Dc7b2$mjbalI1UMpZaVRE0f)`_O} zDX{&B{I>Dc{@8r>KK48EQuwhQ|7t4q;ag2DIB%W(a+v5+0jAQECr?PoYrj28(Dp-H z(`J|nP`MXYbTC0yEO|Cc#tqAd&mh_6;bL21qhz8eO;~RYqYHBJm@O4~?B#6u#H@3+cLn(jiLo0&1HNKs?Oh(|#vZr}UoM-SaPgyI^XaR%=fWvTySH<;x4 z{~exz|4-EaUx~*5p%d`+m2w^qC=y}43d=S6n2fd8AjUvR(FQRJBBk)4ytM*&XyOxQ zhaH^rZi=p)O)y@f4C%~i0!1(kcmK0JA1+ca(k?J9dyT*UHvV)Rlh2d0 zALh^h;|)@pC>m0}YXA~51rhC?%tQ0>{;6Lq!j*pkFZ?hU2m;8&^mKM>t7P@f1+Ud; zuHmlzo+uhY2qar6HYSJhh1qRSss0~7#)Z0emAt(hN^Pjo&ym@iJ)5K1{C;Py^DvoH zIcMGoxIxW58>x~xk}5_`l*MsZG&~OdJBv|Xs&e$Sit*W#L;1fbJXmV^HwpnITig5t zlqu>~PHQSWIP+j4R?v1RI1f5WruZ*tnBV-z{NGWwJ`9%mhcHP8{68tj|1AQ5|7Sh> zzZi=8wg&8FsnBPxir#VU8>EVb6^IR+WZILnX71)iPZI|RLH)8O;wm!cN4=G1u zMa!OM3<4?pY^7i3_qxDFCk?v^)L)=l{r>qFFUxS8#GNZ0N9B+GQoiJAPyuo~ypqtmNZ>ZF*7l@jUZhv4HhMr=U1)Dtq&A58t-9CaS|EZGQelfnPc3Ox*= zmSS(%Ga%!ZiSzoMDka-BNWRLe;UaNDr5AV~hr+B#8uy;_AQen}lqVNE*s4~N=)N+` zLypEm%KH#=<kR=z0L1RK#(Y=uB6mx!fc#4T6hsEm1z{qV8fJlzcCimlku)Zf+s zmVOsuBWxvxbI`>IF9J7JGG-~5_eMRf;>cdl`;ubmg3)PC=C2kzKeovxCnq@{J<{~; zg~{j!#Z59sJb2W@)}@sD^jB*|k&OKJ!ARu0x9edaxni=QGP+$Af>$8OS`E{^Y~cpU zE1amiI>ICptIt-xuQ(q6t0VBQo}w@5%-#C~v?qkakApdprK;)4M3t;5x?6&RS_$%z z*oLsqy^{)}PTcX!+wV#we|q}P;93OQ!{6l$ppI;to;n5cbqKX}WLo2Rr~l-5d}TUS!=oJ(gw+kW%2D~ z0OjEZhNFK2k^j%{21Q4Sw`(PmN4_u=W2m42EBO4kPEiq4<;=_@w><4ZG2 zBsD-o#1O?UW_G^Hj@}rIq~M|vU*9cS*RPFka^GQLlKHw7iyHne%JD+r^}wv|V7U_= z+4_`{Y~ZW$9-mtmBl3pjjh-3Rp)w}z^d+aU^eYGF02U*&C?lqdW4HaW6*O9URy#JOGWj&(& zL4Au94t$iXV$t^LGUtKW^l0iyI0^!94z*+P#nh~TYWU z|KM9=|8jC<{^`)Y!uzLPeMc$O{>ZJ0q%v`}dBvJ3>i#j2Ti3lGL518DI!(c6eU-T# zewslJiR4m-p6=4=82>rzd*)R2CX0h&Hh@TQ`r61s**<%0@|z15X3ez`Ww?0)=O6FM z#`}8HEZ?9}x2+}1ji|nD`vjjwYh?{==m^_ok*}a|bK$h-zq_T|CoMg~s=>0Rv z)SIzBxe+vNK1uMQ{0YY4H*E<@`sm{ZM$judqe#P*iR7PgMAE<30Q~17{z8dWZ{)wN zRAI_`Z_6O@_yqlXdTJ=_wiOe7xx;e~6UUbgGJpnu_Q@*xP23mtq z!xf6Qvkw#Du5ktH`d2qvsS0mdfXlqfPC=}!yn>*JD;)mXJ>wTIuptGdr5f)DDNe0E z<2)QJzf=K~)8f|a9%ca&lX>aj`a5M(%+3X!a?U?Wsd&2HrvK|Wy`waI7P#|x$5xb( z#^8-Ynp=&Ok+&@2JD&V!=`lKOb#gaR$w5EzWTF^9`N2!lKi*gNyIx=O(Is_f zDehOjpaT6bP%Lg4Fv6pr7%02Nq7)^nih&4b6ff2f*)sfBHqPyn()br= zgiJ#@y6wsp0Osm>D{d0Exw4UwQ6=g&-|}mJD*a80g8?#bZF&VnU{R=r?IjUW{P#p) zlLGU%757v&{p_!ys35AM4X2dR!})r#LUGsA%#V=ireRo$g3*%idVI1TsDgy_IiX!PhR$a z4FP>0V8@G4XR)``N8ZCx8=|J}W@x*@yl+lTkh&68KNT zv+}xUU@zm~QbzGebQ~{n-;m`-P#Ne99)3h|=h*70yAKiK!p_@X>>Jsz{3(N9 zq0CE7OL^vBxj*|cZG`MM;Ds+cg1$Vo(>x#oE})3CrLH!#ouSXhi^I9%a)lFyfd-eD zne(4RX~zU_Zt|%Gtr1x8%6{OD{POKHr>bRPh0xtTf=(mc?wAUyfOqp=?}RT-l~SXo z#>PIl)8WiP1bOcJWT9?%@=A?TSld7JulufY{0*sQ{<25o1FqrG0I8|k7eoGxzuFT3 zCDkUL-_M5z56!567J&G^NV%`2o?)wuc&ZN+k`-HavZh9sGj23GclAL+GZ`luEH<0?p)SXJbA6|W7o(w5b{Mt+ zGIYk@Azo2W9=sI8Yg2a>aUM$IU#+4Mw2@~(Iva@dZX9lmDdvGrhcs>>;~P30>q|{` zzLCQwzTY_KXo5=7QHAWGhR2E5k<+Uf2c0kzfiZxJVmDWV=1@2K01Wsf1(gE3vMkn~ zXc@f>+#hc-tQ&&1%(>4_y1s2oWhkeDU~F`eeG8s5b|il+JF; z0^CVxotGr>M5~W(+(%+TxYOo|p{7~G@g)_A$-y=`h81A=Sr5Ztg*t$8lV@=2C9p0Rdz=8p8~ z82Rj4?U`hADUvsm=BwqHR~&V5i?D(4mk)>&sL#3>U4Q3#IAtAc+zTxPSWl#y=gY_$w3%EUKtn99;EfV#2SJr&s+ zF&EPy5L}L5Z{w+vLqus5aJS&foRN{K;f1~#Rj;j3fhPeSyjjy! z)a-`9Q4Szb=_jV?@x{%_7MvR?#r1Vx=%&Hj8i|-~eO@x=*PiOo2LfFTP|m%4B!D)-xQR zI}TRouDenr`!k_JSfJ#kkQ&CJ#+)Q>9iNpx;4CPYSw`Jt8|fSwmQO=YhL_Iv`iv%S z)Ows`mR6B1=KGRr^Bz9Md-V_dn`U?frK@4X)N0}Q=SL_KwlUXMe&#W*TlqZ?K;<0B z?;+JX_MiItInPHE-R!(P`7AEsb{QNI2Ce^z3WME?Q?ttH-(KNOelCPRsY^*S|H0WR zqO~w|cY4_QnYbtk>?3D4S&m{RC`R!GDx>?4n0x!lUr-Qo z5`YW5_6G#AX}=P*q3^!kp8pUfqcgdNSL#0s*o? z;jb<&Hfs|Ch^QTs zbecU$-ctbTv&#txPU=?Luk_NkpR9V_@{~rqdWs9CfEFg+nXd8bN5hh z67SY(C4@)HQc#7g*J&-Z0d4#uW^|q^YHE@EwE*Wa(P3vBuOT+Xz~n`sllzN0m)WAy zM_e){u+KAy&hp;diH!=n>tU*+N91H4uXz+07};km`AVmD#j4>QIlC4->!g8`UTJg?vjBa#IyR z+_2dEaZFH{ou_tvlwNQ4Z1hn_^}5A?b8$JXg}?O(A(JFCOZBzXJXxAg_0SD$L_I$A zg7VfnEfQ-;r#71hAWZHFDUV-(lTyU}aweyXtWHo7f8a@VRy)+1Ad3dKx7$=|Ji=OL z$2P);pe&uuZM4q#YiW@WEgWd|%;bPUW@=E=T&Qc!@T=d|;Zel_z8By6z|Fig8`(g4 zMLV)Kw8;L#SC)LjiUF3Tvmmy>_h!Bz6oT0^tQ`dw%=Pz}rmf?3Z!$bN-d^JMT>YK7 z%R2)X$ZBS!i0C#*@dt4#w9vFvuUpPwX-oZ5n=Yz#dRQrGwN4edK`1L_c~w;@Re37) z3U)3|q-ORg0V_ul&_yFGmHXdPbHf?{Jb&YdQ(ne(`x=8UQ?YtSZIj z_x<5ZdRaYsF~Ifl8uLpj%mbF9YU|V`DVoI(Jp+Yhin>Ul`Hw|eV^p;Ac@qQ>a`*c= zSY+;(0zCKm(0Mwa)zQC=5o$LppNLcro2}FwUHsW#Ei8M&@g4;+m2*D+aJWc~`;f(utCB9{#a$w+9?SpEjK^cxGU~*4;F=hp z`ql46x0vmoI1(C;x*nhsrd?%6snt1YgTT$d+%GLv%qc3Z8m_10-ic4qFZS8pNHu9; z3Gxo#a0Xjul{jn;-_yQkkkhH)0`8+Gf|zZjGEh%`=xjMA4NH z>LVTq6knki1DVQ@YhR06QKuYK8*ysP1h=tbUUyPM%s8S*^S3&Vg2(eIRjHnZ=uH+FH|07`C#Khza>FyMdaZOp-qbHznc{SIG9v5s& z%jxxOZf_HVkqkXyo5t_oolK=+WOXfWAm2_0kN(bEazq0v0F4GhwW6Yk!*eC)C0tKg zz$AMN8fp;;n}i;X5D-*-`EjVws0D_rf zNl3Hj1@H4C6w9YoURsYwGa-D+mmt#!hPFB178zsBzBxCW&Q$rvo`6!fy|c~d-4U3^ z-0ts^Vb*fxgHZFulhIK`7iQgBIW&D5xH65+>Z0%Ur_rg>IF#z9{od~GK%|wqw;NIb z%r1FLv42z_)O`MF`nNWsVf7BbW*(04Ulzxj3uh7IGr3UWk$m}Ue+f>#$;soX{*kodIlqF}-##tv;Wd)Gc)ep&PtqCwx|eB-l``0v{#<~cyfAzpnP3lz(C{o1h>Au$Fv`ZwMg@%g8mZfp4L)qQPC^X&$>;Lg5125a^Ag1+U&9e5U_S)Cv{k5Md9-POXA*QN?Dv zvn@*TS~D3O`zoY`TS}?3DQ112Wr0-abN6Xr z>%D|M#3V(^{<$#LV1XOKBCc(&*^Na%pAyv~BD+wxvO$YW_vP8Ml#5IvyV+LEEcLT0 zPaTv4V{_{j;IaDH`D($#aLZUXs9r5?`q!^ob<}6~^mdb#<~4*FqA#=KQ3#lRm3A35 zdl!WrzuY%@sfu4rbX80@O~Z~W-CqhA8GcZ)-u_tZ$In=RH-bBm-gMLSIRDa1_eiBv z-G>W{-D8c#5q2(f6waPuuR+AJL^!~>Ez`!8iO5M$b!OFL+dY*^KL+Ps46iMJd%9(M zxjPzSk73-uy$%Uq(*I7AACIzMs0>txUT>3JLT&G!p+w8#~!ZRMbBv-dY8KR7+a+hQCxcODGNDB zgqWm;&9$D`TU`l&;B4J>>Ip@Z-AN)d&t>2*O$R>m%h<|8fuYA)c-Y(!XWLGQ2+j-N z7$@}7cM&OAUPmMgRRu#c`fmr{`i+h_WcK;gD?aX|CqoIWq~x9pqehc@2|lrlsKHiG zowS&H%gg|p^Tn;$b7To4d5{UP*eF^9hC05>xI!o9!26Gh6sLB##% z1_bNT7nK!%;PWggH?fngCprqd$091Y;QjK;f$~I=8)1~K5}v!%s|@ScVfr8#XbVb< zwync#FNUu?9-;d_2AMr!i8*HY7J!o(*<#4!R9Zt(vGw|MDUb zm9FiubC2=7k63!A8>v|M$C1CMVx^RHKbn%g{PeP)09L2QK#>{iQl?6NPjUBapBCB;`SQ55l1} zzfD%nj`fv!PcMA>2AH2cQb-{`!FYwMQmh<0E!YMY~ywpD)VCe(h7pF8shZz;TMQv32> z*}?_4nmVFe#~YH51zYevQCWDh#loMb$DAZdd@Ss4ROe0XvEvwl{754fqR{@6mbpi2 z-{su4F|tDiQMv^;H?Ii6IrEX$L79PM$}7{lSf+!&Z`ABX1p8s9^Tkk&2(yj9YoXd(GttSA!v8 zb^W)iCzRZBX*2sJ2*QlnO0rKV8kCbqR0|xiTzTt72RLWvVtpD-%6J5?boRa_gm|3` z7AP>9q5V3Yo(tQhe6;^KzZX?C-s<$6rCos0;I^mfZ<8BkDx<*KUaZ_?oA1vWE)*~H zic<&8_^3!@6xb^LgjEQ&_s>1YF>mm}kK+S0AbK-&qog}^j*e3c51Lb?c~P3|Vk7`8 zKMGq3EiN4a)6=l%G%quBFSgSr^@<44pq93m)_$B{Hx6smpN8%CXm)9Q=Sv(cMA@%5 zjQ(!3zt}tePCPgkEGlPKw-_&Zocm~$&@Q@jGyGMk_OT-!#m?BgQp{u|BBB3>Q|u4? zhGvkN&bh9;K>K}jdb#FaRj51o74V7DrE6ejX-~Sz4?{&wd>+5mk1KBP2Ni$I@1gX{ zcSO;E7O`d-mbb6$L^emLw(329tW_v+dp<~{^9As;=4w+SPkKf{D!SK}C$0~-pVLl6 zY#Y?0i}IO&G^F;tCNHN%uz93Ux2T@~gGo6K9O~{UI@d8N7)lYYivY5Y+&3lcQ7nbd zZ-o5&Rw30wdE4bM(%4cH;w~>WOerl`2|BhQg3ZN9`yl1FC#FStOrN4NG7scDAT*%dYr?UBUf0UW zxXOoR>gko@iea|%oWI5Mdte1poznF?viRE(^^<0SIp;Mp(N|?ln^o}8uVC#F7I||r zvVU#7{I+Jdz6+J~efF~hmj+gY5tTtui733}n{n?)eD6+T`CB{zonNQn23xIr3+fr}a%smN@t>lo^*?cBC*4># z*;6r7a8{zVC{CMueyp^J@7}LifCAOL4LT-fC@h40rp9r)>-BuMsL0cY!R^-FA5?ajnWcPI9Ff5bHBZR#7I1WaP63lDGShNxxc|6D9 z2iRfq(y9qih(`Ti9HZNBNmFcwZq%lVCGuEX?~lJ|rr-G_uCQ*9*;1z}CGyrLTF_9q zA+3DyYszrI#g=X&{_7IsJQFvS`#pIy%h#&N`7;3Hr1co$1IGN6uTfk$Bp5@=oAkEE z0^9m{d~grLcdQTzLxvV~^ZtPKZQ6qV9ZQ70$QzgA!Hr%WY=~VwCS((-f&at-U7#YL zLE21v;54j@+*8+2+MTP}`B`zn)CN)DKLL#{W@JzH2n(|AY#~ouYU(RxMpo5uj}!RT zw~0OV-k4{PqL6X*&Ki;h`(bvQHD$a>y0#ua&3N9ha`Bz_qyi|3(g~-c-PA97K142{ zZYq5tFVeetkn~PrOTyW7k)I;6!fAJ;T9s(_esFjWRS%({<&=XpF0}VEB_)N!`i;tXbyS_fV2_XZ zw5*i1Z$jPTWUJS`SgM@Ex3s<^>PgS9e*N2%nq&=~C1{$K`LF}{X22iaxN!s1)huj#tH+9fMyQZ0n$k5bit^-ax}-t3cm8TDZ8jNNjvB-57lI_u zH`^c;OVkofBZ1N@dM1Ahdn!wgX4B;yH=W@s0m!+mhQ?t0y5aBHBnK(JHkWltYk|#m zcfn-F286?dz!`x%=Z})m&hEo|q`B0q!%iZyDSpLJj02(AM)k`4G(z)r$Spi%%cW zIlD_}(wfG6q(I;cBuidwAB<5yj&94#TUViRu8FuRnx6<;bo>k-H~sMdo230k&l6Ko z7|Rk(V(-=>ddrtu-_tPV{A17CX|5s&gpL%rE+&ZLZX)rOgz>J?OU2oouGL-zk7|fE zfSY1&i|}qv;|yE3WvCdyES?;44bbXmNQtgNe(a4A4%6lXCzsOe$E|f}&OCh+hvZf6 zIyIKv>&{!H^|I-Nw!$=;E{W^Y&J3;s1Y%lBx>IMm(Om)PQZP#C`sAEGn*zjv^bkGB z$l_cWyA}P3DkU0CS%3)>sUnDyLz#raIghcPBC|kF9r-7|X6%}9wR9BC{@IG8LDKCT zr{|f0)LFI(L=j#ECUYN;W;hCkIYVFs$i8s>Do1IAF;v0^9%Hpv^ zV-ZfK0?F#d=vg=x&^sk2)}n8!UZE@T`ibX7GkxkF6;lmh@$9Zn&7vl`@$2~&j=_dO z3igDJJCr8ZcZ>3RYi?>T#+O#L>!Jm%w`?D!!#^g8!0=VM*;ftbu@YjE{Z~!QR=uWg ztx_k`J*RA7dsQ=z=u6N>?)3`my@O=T(?5tW+gu zheN;Y#+%DL1(^Yxp_}DYVl>}hyJOV~*l8+0)b{n1!SIQw`;~@7E<7Ct@nG|a1`HkDdF(7 zRuV5h-HWprj@&>R|Li}?hP+|fweCza&iiQkfv>@6#apIdvTvyMPe87W@~Wc>GjsDr zQWw8Cb2PN9$12jn)m>ciyBF1DHN-Mk6rwvh{-R&GaE4|8B&2`I;*AWd)CQOG3K8y- z0LqBG6CQIZ{^Dyky7oWG=r0%ipu9%u;8cByzgonEd6>qEqMfHu?-aPQ7^LDP|18C1 zFuS-6zOCJpNal4H#^$9$sk4v&pn@Rj^RL7fALzehe!LxQ#>Hv+0&8G3kz(m}w6u~! z9&b^R;h->{&3!%>zYyT}Rg##wjS3M2L~#?O7w9b7s0R=V5E$f%i{(n! z7gCn27!Y_}Q+{`%zX}E1gFUsYf7`;Y5$+T9+2T#4(6ZLn4?x!kq$*YO43gg8u!gjU zM)qwM7h#A)a|Y&jHg{yY%D;pZ@t%re*RwgpEkUoa_1n=D5OL)`g~FV^hZRUv&TEY< zI_^MMp!(Z+*Y}dZ12|+zNupr`SOuHt7$zZQCD5$1gp{FBywv1M)!f{sEJ3qk7n61 zy~Yy%J;AS>hPO2u)N`ElhYnY(it-*ul~+7^XR}lWe2M3FC<;Psh}k$Win-G2>b3_D z@kl?^G|sTZGcHAkT&%577!Qd+U13XE7= zq9WLU7n3dk);QGiCgACQAXwe7v@Y()i)9HiAE}Wi)bUqTh z&T1M;dayt$cRFy2jJWQ+?da66@y0SQc1ueOxvY6_TxWsADmNJWCx>p4zaC2!s_$z? zuyD-}0(+%qdvcG8JJ463p9w9zu1T_-1HODXoiCND6X-r5;gJTPwKSizklrY##2kq2 z6ddhaQt{t_O$i5LJwd>3Hk9C>jv4dN-kprVI0$BHI7wdt<%K-=g#ERY*^7Y1DG1HoUjFi%csB% z9`t%s+H`SC0M&G~b8~-AJwx#^T|GTLVpQ@p#X{#{%|xgUKS~PUjZ` zBA%V?JDL}{=lx~24VkU_Amta6b%RS8N78dQX}D7$gPr1uIZNAvvDuQ|XS7amjeei$U5o&1nDRvU^pq0TF#uUaIiVADeE4Dc8P6Nbtt zp3|g--`jV|MmCEMfI+-Zfk^{so}#+k%{oZ^5CM!e zTHGilz~~(R3Hi|3)0LXL73uhVgnxK;+KUVp^**gWcWG#PJnT0=@3Q{;epCxn~_bWmIp7$Ie7q1E0x2q1;4mzF* zX~;p#uK?fPI9YnBrI^*8dFNP0(K2ky?gSer{YP$T_D$ojd*CIw`HBI9>(fQ_Muy+5 z-qbKE?&$lvM_j2!ak^$z2IbUTWWB$!kWzafJM@=%9)6s{u=QEEti5spIy~B%mfd!n zCgiiJhX63RIrs6g#1vd$W3${4QPf&)Qdo5Y<1kSGu)+u{RF%>hEdIREwfINk1TTY* ze7cZK;6>4K2N~=cE+2d#z)}-FTHszl|MATK2QL=n@rGnTD-{NdjZXtrc^-J3)u~@Q z0aPdTV?J^(h;MUbjl`ftZaJ%=ji~dMUI1;mGzviRCiji(Gl8q_U*evt!@=6WIJCcB zIFV*hYTn?n>U>ngtcBM(HSy!Cg!AwOhp^9H_u07x>+TY_u9-=|fM43A@1u*K-^nGC zvfDK(9N-j`cgOUs;t$#uTEQT%+H=56XrPdC-STs9HF>DhJbU@{k;m|H18%eaas{vx zwkXL9kinUP+reLxfS(;fr7`PNkQhd2PrVyuK~YK!2Ho~dtZr{?7iICLrQ%|Ik6K@Z zE0=x_1aXqMuPNtFdX1-gNj{$HZvh0qcNypma&g}EtoqH>RpB%V+Cm^1k$M~Li$)ckr zCDt1hwzLY_+|ez!YYsy$K_N(dWCOvKw#T`I%dJ;iuqM{>~N~Lu?QER zX+OgHu_U1t?##}mKeY8w@6iKQt2Wl_0yi=@Y?%p71i0)83rmEm;S7dPN4AwOKN<8z2q;+BXrVfrYH^asGdUf~O z-o~vpbb&1YH6fqyd4$D-W*|Km&P*(p3#D|`_=LJyc!vi0egr(er1b2oh=E(bJz{w~ zKo$x>IuJTq$nzXHNQUX}(?z^>HBDa#(R*@o0L{&fC_uG9z#%8zvc84}{My5S2@v%i zwFpUbd5Z&wucKjVFxJ?wlh+CzbUU_1IgaV}kQ!zs50Q>Q@=S4^{&5`1wUT1f}pd~RlTJT8D|QNz($x9>d$*M>^+3ENV-1%tJ8UVoYZeEUvBH|=v~Rh$n;WO zmo1K{-zHx8TqwMEMMOM>sOi1YatUqVQaa+?sUCwTw1AQA*4=x9p8kMe_g%IP@7l-s zI{X4y$MHc>;5YxgI^Rcf-(G#Ddd-#AA*aW0 zYzHuS=D#p840|pe5MflRqnW!5?fg{v$xrktqT|c6y6h%2U*kNP<#7J|;nl@K4!xjr zqsFX1{TW&!-45e*!fe!pz<+mlFj?jHCmXMW|G%$M2AB z%Rkos0P>4kaJh}D^Xo1>|6ZiiJ3+cuE?CP6OGqdtwuOADU;UiRZ0?M9@IRO z3}O_|7iE_v#f2JFC8YmdU{;!*FJH+0BQh@Qpgps;oac{uOV$$c3Ge~fOl)l!XhXJ0!?pd^;CWbp z3i$Ws4Gar83p-24jkzH@-TR&=pHEA-<=9DrntmGvP~4rz>E=s{biiwUoZR|U9Uc3y z*7w^e#F!tfP7=!iHeN1ODVN8y4Js`PBRbwM1+^w2X0|v6G6q6~r)8VKr20)b7Slg6 zs89??b2dE-GJew;ELq@~%Se*C@h4JT);vFtO~cE9Zs}P2;!9q6)O3^-D(?`1!Jd2k zzNnlC>pkl6?sW)}Ot3wTSDcr}{{8at;uW}DRZD{Oi)m+bUsnBaqQ2^19IcfsQ1))mCRB8 zE^vzXTmLNk?e5JKbIa48pcBwT@=mHsJc}D;2b6s^Wa};FYy_ulav$4$U6dzy)ri zxSV#krdKI2=J-QL>;_@QuVt!XLVMH%qU+W3?bNIaNCj8|-C5+6JmIH6$6Pl5Cr5JY z#~YXH{IkYTv9=WUXdQL_J((S%F);%0p9q3Gj3;F8?;yqqVOzEZtmgjg#<#^ zJHgZ*?B61Q5-{Bzgmqm+!s_%|xE%tL5(;|yV42z+&kib-h?MW$ZQAAfEc9U?DP%*y?gQgf*X;LC{Ycv9hp)sZoW}4XB$-FbUkZyVwCyFI%1x$U zF8_}*t~{!#bBVLaj)o$LEFtZoEI#!?2pXXTD4RSXqLrBFOB%v!AQ767K!LJd1ga>c z91g32;sPY4Xh7D`7#0I^M1oNSMA^XrDr>_U0`CU;{(ASXd%iR0J9B4#cfPqZ_cv%Y z30BR}b9|`}076dNEBDLLa}7+*eb)4F?RDNf;Uu7{vhCmI8)PCZs=t(N$-f9T z-bAaFnzA(LpQ`iMHvNNb;@Z`by41uO0zfROrOOW`k!zx0CE7g)usrth^5v6vn(WEM z#h9d%D|)bKts@6ZL8U#-#x7>k{f1(heOf9i%M;(zZHo3u&~QYoNc@wyFGR-$1ep7iT5}Wo?`3GB_H|M&m+v?nXyOL9*tIogFJ@XRKG&!y^0`D)7dRK(4jg7o9)o9cvqiHp=9jzz-b7Mwn#TG&N?Eu0OrS%dXx+90(lXa0#~BRZ#a^i zLO#FPaZ3~-el%o2Jk9vpE%1$IuQ7_-^fv!-epf*8aJJCxfH$D0tDCh=L{be_iYD?$ zHr7PL>Yv#hQ)i(FfArtfFaY zmf54;*u9In1aFLVI9FhlubzRVXXDIObIb!03D$H$~ z5{)`}Yj5y|;bFW_3V9A;FE8m`KKF?vue}zdynWi4X~N(DkKV+zjwS%}e$6!mzrhD_cohOc*gTzkMcm!G zaN$A<;>YJqN=*Nk)82egdx-~xQu%14 z0%rk2=FJW&zJAQ1^=$UqObH+l_m!%>NF-9D``@*GJQvw4-C;Y+-Xy&H1@b2=kyv#b z0xp`k&90%=FLRvE#3GqKytAj~!p4*UaEgkGrWXsHuqGgi!%0LW11 z9b9U4m4~4T{o>xe%=(Ga_ZpC4yQ}acuMbp#DRrz2%bcxTukXf0b(+rRj^4nO`aRbv zkgkJ~nUWw?c=T|cgqItVD>lipeLI+9bH{_qb^ci;G%7?}=&0OS)-cG}1TZ=N<`5z2 z1P48E$+3KI4O59fg*7rV@(|GUZ(w88B~i(pH&Oh!<&a>hiNsc9j0Y;fPp%y4V3e$o z5ds=Hy+i+{Chmc6+VycTwrbcY?y;&(sp;g(x-VJP-P2lhLpJAI0nPVZZ}mfy&(5oV z53hh*g=5tN9{8A%JgSWoH|9?G^IrWOS|uu7(EX`D9r{@1Kk!Ppn4b9mGp}