diff --git a/code/datums/brain_damage/hypnosis.dm b/code/datums/brain_damage/hypnosis.dm index 8ffffa8693..aa8d385092 100644 --- a/code/datums/brain_damage/hypnosis.dm +++ b/code/datums/brain_damage/hypnosis.dm @@ -53,7 +53,7 @@ /datum/brain_trauma/hypnosis/on_lose() message_admins("[ADMIN_LOOKUPFLW(owner)] is no longer hypnotized with the phrase '[hypnotic_phrase]'.") log_game("[key_name(owner)] is no longer hypnotized with the phrase '[hypnotic_phrase]'.") - to_chat(owner, "You suddenly snap out of your hypnosis. The phrase '[hypnotic_phrase]' no longer feels important to you.") + to_chat(owner, "You suddenly snap out of your fixation. The phrase '[hypnotic_phrase]' no longer feels important to you.") ..() /datum/brain_trauma/hypnosis/on_life() diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index bdf1f69e10..422ec4476c 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -108,8 +108,8 @@ /datum/mood_event/happy_empath description = "Someone seems happy!\n" - mood_change = 2 + mood_change = 3 timeout = 600 /datum/mood_event/happy_empath/add_effects(var/mob/happytarget) - description = "[happytarget.name]'s happiness is infectious!\n" + description = "[happytarget.name]'s happiness is infectious!\n" diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index 2e8dd17163..ee199a7b0d 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -398,7 +398,9 @@ h1.alert, h2.alert {color: #000000;} .velvet {color: #660015; font-weight: bold; animation: velvet 3000ms infinite;} @keyframes velvet { 0% { color: #400020; } - 50% { color: #FF0000; } + 25% { color: #FF0000; } + 50% { color: #FFAAAA; } + 75% { color: #FF0000; } 100% { color: #400020; } } diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm index e93d97c3c3..2cb70928b7 100644 --- a/code/modules/surgery/organs/vocal_cords.dm +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -655,7 +655,7 @@ ///////////FermiChem////////////////// ////////////////////////////////////// //Removed span_list from input arguments. //mob/living/user -/proc/velvetspeech(message, mob/living/user, base_multiplier = 1, include_speaker = TRUE, message_admins = TRUE, debug = FALSE) +/proc/velvetspeech(message, mob/living/user, base_multiplier = 1, include_speaker = TRUE, message_admins = FALSE, debug = FALSE) if(!user || !user.can_speak() || user.stat) return 0 //no cooldown @@ -749,14 +749,15 @@ to_chat(world, "[user]'s power is [power_multiplier].") //Mixables - var/static/regex/enthral_words = regex("relax|obey|love|serve|docile|so easy|ara ara") //enthral_words works - var/static/regex/reward_words = regex("good boy|good girl|good pet|good job") //reward_words works - var/static/regex/punish_words = regex("bad boy|bad girl|bad pet|bad job") ////punish_words works + var/static/regex/enthral_words = regex("relax|obey|love|serve|docile|so easy|ara ara") + var/static/regex/reward_words = regex("good boy|good girl|good pet|good job") + var/static/regex/punish_words = regex("bad boy|bad girl|bad pet|bad job") //phase 0 - var/static/regex/saymyname_words = regex("say my name|who am i|whoami") //works I think + var/static/regex/saymyname_words = regex("say my name|who am i|whoami") var/static/regex/wakeup_words = regex("revert|awaken|snap") //works //phase1 - var/static/regex/silence_words = regex("shut up|silence|be silent|ssh|quiet|hush") //works + var/static/regex/petstatus_words = regex("how are you|what is your status|are you okay") + var/static/regex/silence_words = regex("shut up|silence|be silent|ssh|quiet|hush") var/static/regex/antiresist_words = regex("unable to resist|give in")//useful if you think your target is resisting a lot var/static/regex/resist_words = regex("resist|snap out of it|fight")//useful if two enthrallers are fighting var/static/regex/forget_words = regex("forget|muddled|awake and forget") @@ -860,6 +861,8 @@ SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "enthrallscold", /datum/mood_event/enthrallscold, descmessage) E.cooldown += 1 + + //teir 0 //SAY MY NAME works if((findtext(message, saymyname_words))) @@ -890,6 +893,136 @@ //tier 1 + + //PETSTATUS i.e. how they are + else if((findtext(message, petstatus_words))) + for(var/V in listeners) + var/mob/living/carbon/human/H = V + var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall) + REMOVE_TRAIT(H, TRAIT_MUTE, "enthrall") + var/speaktrigger = "" + //phase + switch(E.phase) + if(0) + continue + if(1) + addtimer(CALLBACK(H, /atom/movable/proc/say, "I feel happy being with you."), 5) + continue + if(2) + speaktrigger += "I think I'm in love with you... " + if(3) + speaktrigger += "I'm devoted to [(H.lewd?"being your pet":"following you")]! " + if(4) + speaktrigger += "[(H.lewd?"You are my whole world and all of my being belongs to you, ":"I cannot think of anything else but you, ")] "//Redflags!! + + //mood + GET_COMPONENT_FROM(mood, /datum/component/mood, H) + switch(mood.sanity) + if(SANITY_GREAT to INFINITY) + speaktrigger += "I'm beyond elated!! " + if(SANITY_NEUTRAL to SANITY_GREAT) + speaktrigger += "I'm really happy! " + if(SANITY_DISTURBED to SANITY_NEUTRAL) + speaktrigger += "I'm a little sad, " + if(SANITY_UNSTABLE to SANITY_DISTURBED) + speaktrigger += "I'm really upset, " + if(SANITY_CRAZY to SANITY_UNSTABLE) + speaktrigger += "I'm about to fall apart without you! " + if(SANITY_INSANE to SANITY_CRAZY) + speaktrigger += "Hold me, please.. " + + //Withdrawal + switch(E.withdrawalTick) + if(10 to 36) + speaktrigger += "I missed you, " + if(36 to 66) + speaktrigger += "I missed you, but I knew you'd come back for me! " + if(66 to 90) + speaktrigger += "I couldn't take being away from you like that, " + if(90 to 140) + speaktrigger += "I was so scared you'd never come back, " + if(140 to INFINITY) + speaktrigger += "I'm hurt that you left me like that... I felt so alone... " + + //hunger + switch(H.nutrition) + if(0 to NUTRITION_LEVEL_STARVING) + speaktrigger += "I'm famished, please feed me..! " + if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) + speaktrigger += "I'm so hungry... " + if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) + speaktrigger += "I'm hungry, " + if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) + speaktrigger += "I'm sated, " + if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL) + speaktrigger += "I've a full belly! " + if(NUTRITION_LEVEL_FULL to INFINITY) + speaktrigger += "I'm fat... " + + //health + switch(H.health) + if(100) + speaktrigger += "I feel fit, " + if(80 to 99) + speaktrigger += "I ache a little bit, " + if(40 to 80) + speaktrigger += "I'm really hurt, " + if(0 to 40) + speaktrigger += "I'm in a lot of pain, help! " + if(-INFINITY to 0) + speaktrigger += "I'm barely concious and in so much pain, please help me! " + //toxin + switch(H.getToxLoss()) + if(10 to 30) + speaktrigger += "I feel a bit queasy... " + if(30 to 60) + speaktrigger += "I feel nauseous... " + if(60 to INFINITY) + speaktrigger += "My head is pounding and I feel like I'm going to be sick... " + //oxygen + if (H.getOxyLoss() >= 25) + speaktrigger += "I can't breathe! " + //blind + if (HAS_TRAIT(H, TRAIT_BLIND)) + speaktrigger += "I can't see! " + //deaf..? + if (HAS_TRAIT(H, TRAIT_DEAF))//How the heck you managed to get here I have no idea, but just in case! + speaktrigger += "I can barely hear you! " + //And the brain damage. And the brain damage. And the brain damage. And the brain damage. And the brain damage. + switch(H.getBrainLoss()) + if(20 to 40) + speaktrigger += "I have a mild head ache, " + if(40 to 80) + speaktrigger += "I feel disorentated and confused, " + if(80 to 120) + speaktrigger += "My head feels like it's about to explode, " + if(120 to 160) + speaktrigger += "You are the only thing keeping my brain sane, " + if(160 to INFINITY) + speaktrigger += "I feel like I'm on the brink of losing my mind, " + + //horny + if(HAS_TRAIT(H, TRAIT_NYMPHO) && H.canbearoused && H.lewd) + switch(H.getArousalLoss()) + if(40 to 60) + speaktrigger += "I'm feeling a little horny, " + if(60 to 80) + speaktrigger += "I'm feeling horny, " + if(80 to INFINITY) + speaktrigger += "I'm really, really horny, " + + //collar + if(istype(H.wear_neck, /obj/item/clothing/neck/petcollar)) + speaktrigger += "and thank you for the collar, " + //End + if(H.lewd) + speaktrigger += "[E.enthrallGender]!" + else + speaktrigger += "[user.first_name()]!" + //say it! + addtimer(CALLBACK(H, /atom/movable/proc/say, "[speaktrigger]"), 5) + E.cooldown += 1 + //SILENCE else if((findtext(message, silence_words))) for(var/mob/living/carbon/C in listeners) @@ -1076,14 +1209,14 @@ var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall) if (E.phase == 3) var/speaktrigger = "" - user.emote("me", 1, "whispers something quietly.") - if (get_dist(user, H) > 1)//Requires user to be next to their pet. + C.emote("me", 1, "whispers something quietly.") + if (get_dist(user, C) > 1)//Requires user to be next to their pet. to_chat(user, "You need to be next to your pet to hear them!") - return + continue for (var/trigger in E.customTriggers) speaktrigger += "[trigger], " - to_chat(user, "C whispers, [speaktrigger] are my triggers.")//So they don't trigger themselves! - addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "You whisper your triggers to [(H.lewd?"Your [E.enthrallGender]":"[E.master]")]."), 5) + to_chat(user, "[C] whispers, \"[speaktrigger] are my triggers.\"")//So they don't trigger themselves! + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "You whisper your triggers to [(C.lewd?"Your [E.enthrallGender]":"[E.master]")]."), 5) //CUSTOM TRIGGERS @@ -1094,12 +1227,12 @@ if(E.phase == 3) if (get_dist(user, H) > 1)//Requires user to be next to their pet. to_chat(user, "You need to be next to your pet to give them a new trigger!") - return + continue else user.emote("me", 1, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.") user.SetStun(1000)//Hands are handy, so you have to stay still H.SetStun(1000) - if (E.mental_capacity >= 10) + if (E.mental_capacity >= 5) var/trigger = html_decode(stripped_input(user, "Enter the trigger phrase", MAX_MESSAGE_LEN)) var/custom_words_words_list = list("Speak", "Echo", "Shock", "Cum", "Kneel", "Strip", "Trance") var/trigger2 = input(user, "Pick an effect", "Effects") in custom_words_words_list @@ -1113,7 +1246,7 @@ else E.customTriggers[trigger] = trigger2 message_admins("[H] has been implanted by [user] with [trigger], triggering [trigger2].") - E.mental_capacity -= 10 + E.mental_capacity -= 5 addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "[(H.lewd?"your [E.enthrallGender]":"[E.master]")] whispers you a new trigger."), 5) else to_chat(user, "Your pet looks at you confused, it seems they don't understand that effect!") @@ -1130,7 +1263,7 @@ if(E.phase == 3) if (get_dist(user, H) > 1)//Requires user to be next to their pet. to_chat(user, "You need to be next to your pet to give them a new echophrase!") - return + continue else user.emote("me", 1, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.") user.SetStun(1000)//Hands are handy, so you have to stay still @@ -1152,7 +1285,7 @@ if(E.phase == 3) if (get_dist(user, H) > 1)//Requires user to be next to their pet. to_chat(user, "You need to be next to your pet to give them a new objective!") - return + continue else user.emote("me", 1, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.'") user.SetStun(1000)//So you can't run away! @@ -1161,7 +1294,7 @@ var/datum/objective/brainwashing/objective = stripped_input(user, "Add an objective to give your pet.", MAX_MESSAGE_LEN) if(!LAZYLEN(objective)) to_chat(user, "You can't give your pet an objective to do nothing!") - return + continue //Pets don't understand harm objective = replacetext(lowertext(objective), "kill", "hug") objective = replacetext(lowertext(objective), "murder", "cuddle") diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css index c24de22f84..102c8ac40c 100644 --- a/goon/browserassets/css/browserOutput.css +++ b/goon/browserassets/css/browserOutput.css @@ -395,7 +395,9 @@ h1.alert, h2.alert {color: #000000;} .velvet {color: #660015; font-weight: bold; animation: velvet 3000ms infinite;} @keyframes velvet { 0% { color: #400020; } - 50% { color: #FF0000; } + 25% { color: #FF0000; } + 50% { color: #FFAAAA; } + 75% { color: #FF0000; } 100% { color: #400020; } } diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 3641e8a923..eed8ee64e7 100755 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index d2af0cf9d7..59ed84c177 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -156,7 +156,9 @@ h1.alert, h2.alert {color: #000000;} .velvet {color: #660015; font-weight: bold; animation: velvet 3000ms infinite;} @keyframes velvet { 0% { color: #400020; } - 50% { color: #FF0000; } + 25% { color: #FF0000; } + 50% { color: #FFAAAA; } + 75% { color: #FF0000; } 100% { color: #400020; } } diff --git a/modular_citadel/code/datums/status_effects/chems.dm b/modular_citadel/code/datums/status_effects/chems.dm index 744827b0d0..06616e1990 100644 --- a/modular_citadel/code/datums/status_effects/chems.dm +++ b/modular_citadel/code/datums/status_effects/chems.dm @@ -244,7 +244,7 @@ var/mob/living/carbon/M = owner //chem calculations - if!owner.reagents.has_reagent("enthrall"))) + if(!owner.reagents.has_reagent("enthrall")) if (phase < 3 && phase != 0) deltaResist += 3//If you've no chem, then you break out quickly if(prob(10)) @@ -345,6 +345,10 @@ to_chat(master, "Your pet [owner] appears to have finished internalising your last command.") else to_chat(master, "Your thrall [owner] appears to have finished internalising your last command.") + if(get_dist(master, owner) > 10) + if(prob(10)) + to_chat(owner, "You NEED to return to [(owner.lewd?"your [enthrallGender]":"[master]")].") + M.throw_at(get_step_towards(master,owner), 3, 1) return//If you break the mind of someone, you can't use status effects on them. @@ -355,7 +359,7 @@ if(phase <= 2) enthrallTally += distancelist[get_dist(master, owner)+1] if(withdrawalTick > 0) - withdrawalTick -= 2 + withdrawalTick -= 1 //calming effects M.hallucination = max(0, M.hallucination - 1) M.stuttering = max(0, M.stuttering - 1) @@ -375,7 +379,7 @@ if (withdrawal == TRUE)//Your minions are really REALLY needy. switch(withdrawalTick)//denial if(5)//To reduce spam - to_chat(owner, "You are unable to complete your [master]'s orders without their presence, and any commands and objectives given to you prior are not in effect until you are back with them.") + to_chat(owner, "You are unable to complete [(owner.lewd?"your [enthrallGender]":"[master]")]'s orders without their presence, and any commands and objectives given to you prior are not in effect until you are back with them.") if(10 to 35)//Gives wiggle room, so you're not SUPER needy if(prob(5)) to_chat(owner, "You're starting to miss [(owner.lewd?"your [enthrallGender]":"[master]")].") @@ -396,10 +400,11 @@ if(66) SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing1") var/message = "[(owner.lewd?"I feel so lost in this complicated world without [enthrallGender]..":"I have to return to [master]!")]" + to_chat(owner, "You start to feel really angry about how you're not with [(owner.lewd?"your [enthrallGender]":"[master]")]!") SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "EnthMissing2", /datum/mood_event/enthrallmissing2, message) - owner.stuttering += 200 - owner.jitteriness += 200 - if(67 to 90) //anger + owner.stuttering += 50 + owner.jitteriness += 500 + if(67 to 89) //anger if(prob(10)) addtimer(CALLBACK(M, /mob/verb/a_intent_change, INTENT_HARM), 2) addtimer(CALLBACK(M, /mob/proc/click_random_mob), 2) @@ -416,29 +421,29 @@ to_chat(owner, "You need to find your [enthrallGender] at all costs, you can't hold yourself back anymore!") else to_chat(owner, "You need to find [master] at all costs, you can't hold yourself back anymore!") - if(91 to 120)//depression + if(91 to 100)//depression if(prob(20)) owner.adjustBrainLoss(2.5) - owner.stuttering += 20 - owner.jitteriness += 20 - if(prob(25)) - M.hallucination += 20 - if(121) + owner.stuttering += 435 + owner.jitteriness += 35 + else if(prob(25)) + M.hallucination += 10 + if(101) SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing3") var/message = "[(owner.lewd?"I'm all alone, It's so hard to continute without [enthrallGender]...":"I really need to find [master]!!!")]" SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "EnthMissing4", /datum/mood_event/enthrallmissing4, message) - to_chat(owner, "You can hardly find the strength to continue without your [enthrallGender].") - if(120 to 140) //depression 2, revengeance - if(prob(15)) + to_chat(owner, "You can hardly find the strength to continue without [(owner.lewd?"your [enthrallGender]":"[master]")].") + if(102 to 140) //depression 2, revengeance + if(prob(20)) owner.Stun(50) owner.emote("cry")//does this exist? if(owner.lewd) to_chat(owner, "You're unable to hold back your tears, suddenly sobbing as the desire to see your [enthrallGender] oncemore overwhelms you.") else to_chat(owner, "You are overwheled with withdrawl from [master].") - owner.adjustBrainLoss(5) - owner.stuttering += 20 - owner.jitteriness += 20 + owner.adjustBrainLoss(4) + owner.stuttering += 35 + owner.jitteriness += 35 if(prob(5)) deltaResist += 5 if(140 to INFINITY) //acceptance @@ -449,11 +454,11 @@ to_chat(owner, "Maybe you'll be okay without your [enthrallGender].") else to_chat(owner, "You feel your mental functions slowly begin to return.") - if(prob(10)) - owner.adjustBrainLoss(2) - M.hallucination += 50 + if(prob(5)) + owner.adjustBrainLoss(2.5) + M.hallucination += 10 - withdrawalTick += 0.5//Usually enough to leave you with a major brain trauma, but not kill you. + withdrawalTick += 0.5//Enough to leave you with a major brain trauma, but not kill you. //Status subproc - statuses given to you from your Master //currently 3 statuses; antiresist -if you press resist, increases your enthrallment instead, HEAL - which slowly heals the pet, CHARGE - which breifly increases speed, PACIFY - makes pet a pacifist, ANTIRESIST - frustrates resist presses. @@ -501,7 +506,7 @@ //adrenals? //customEcho - if(customEcho && withdrawl == FALSE) + if(customEcho && withdrawal == FALSE) if(prob(5)) if(!customSpan) //just in case! customSpan = "notice" diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm index 0eb61ce136..d8f01e445d 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm @@ -229,23 +229,24 @@ Creating a chem with a low purity will make you permanently fall in love with so FallInLove(pick(GLOB.player_list), M) if (M.ckey == creatorID && creatorName == M.real_name)//If you yourself drink it, it supresses the vocal effects, for stealth. var/obj/item/organ/vocal_cords/Vc = M.getorganslot(ORGAN_SLOT_VOICE) - Vc.spans = null + Vc.spans = list("say") return if(!M.client) metabolization_rate = 0 //Stops powergamers from quitting to avoid affects. but prevents affects on players that don't exist for performance. return if(metabolization_rate == 0) - metabolization_rate = 0.5 + metabolization_rate = 0.1 var/datum/status_effect/chem/enthrall/E = M.has_status_effect(/datum/status_effect/chem/enthrall)//If purity is over 5, works as intended if(!E) return else E.enthrallTally += 1 - M.adjustBrainLoss(0.05)//Honestly this could be removed, in testing it made everyone brain damaged, but on the other hand, we were chugging tons of it. + M.adjustBrainLoss(0.1)//Honestly this could be removed, in testing it made everyone brain damaged, but on the other hand, we were chugging tons of it. ..() /datum/reagent/fermi/enthrall/overdose_start(mob/living/carbon/M)//I made it so the creator is set to gain the status for someone random. . = ..() + metabolization_rate = 1//Mostly to manage brain damage and reduce server stress if (M.ckey == creatorID && creatorName == M.real_name)//If the creator drinks 100u, then you get the status for someone random (They don't have the vocal chords though, so it's limited.) to_chat(M, "You are unable to resist your own charms anymore, and become a full blown narcissist.") /*Old way of handling, left in as an option B @@ -283,11 +284,12 @@ Creating a chem with a low purity will make you permanently fall in love with so E.customTriggers = list() /datum/reagent/fermi/enthrall/overdose_process(mob/living/carbon/M) - M.adjustBrainLoss(0.025)//should be ~40 in total + M.adjustBrainLoss(0.2)//should be ~40 in total ..() /datum/reagent/fermi/enthrall/on_mob_delete(mob/living/carbon/M) - if (M.ckey == creatorID && creatorName == M.real_name)//If you yourself drink it, it supresses the vocal effects, for stealth. + message_admins("Del enthrall") + if (M.getorganslot(ORGAN_SLOT_VOICE))//Returns spans var/obj/item/organ/vocal_cords/Vc = M.getorganslot(ORGAN_SLOT_VOICE) Vc.spans = list("velvet") ..() @@ -296,7 +298,7 @@ Creating a chem with a low purity will make you permanently fall in love with so /datum/reagent/fermi/enthrallExplo//Created in a gas cloud when it explodes name = "MKUltra" id = "enthrallExplo" - description = "A forbidden deep red mixture that overwhelms a foreign body with waves of pleasure, intoxicating them into servitude. When taken by the creator, it will enhance the draw of their voice to those affected by it." + description = "A forbidden deep red mixture that overwhelms a foreign body with waves of desire, inducing a chemial love for another. Also, how the HECC did you get this?" color = "#2C051A" // rgb: , 0, 255 metabolization_rate = 0.1 taste_description = "synthetic chocolate, a base tone of alcohol, and high notes of roses."