From b3d0512b470e574f9ebef57f7534a60e86a6465e Mon Sep 17 00:00:00 2001
From: SkyratBot <59378654+SkyratBot@users.noreply.github.com>
Date: Sat, 24 Oct 2020 02:05:55 +0200
Subject: [PATCH] =?UTF-8?q?[MIRROR]=20Adds=20=F0=9F=91=8F=20High=20?=
=?UTF-8?q?=F0=9F=91=8F=20Fives=20=F0=9F=91=8F=20(#1445)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Adds 👏 High 👏 Fives 👏 (#54516)
This PR lets you post up for high-fives with your buds so you can slap some skin and show off how well you vibe together. To initiate a high-five, simply stand next to another person with a slapper (the *slap emote one) in hand, and hit the offer item button (default G) to let the people adjacent to you know you're available. They'll get an alert that you're offering a high-five, and clicking it will follow through and award you both a small positive moodlet, or they can just walk away and leave you hanging, earning you a negative moodlet.
Is a high-five not enough to show the world how tight your crew is? Double the fun! If whoever initiates the high-five has a slapper in both hands, and the taker has two hands free, you'll go for the mythical high-ten for a louder slap and extra emphasis! Woo!
* Adds 👏 High 👏 Fives 👏
Co-authored-by: Ryll Ryll <3589655+Ryll-Ryll@users.noreply.github.com>
---
code/__DEFINES/status_effects.dm | 2 +
code/_onclick/hud/alert.dm | 20 +++
.../mood_events/generic_negative_events.dm | 35 +++-
.../mood_events/generic_positive_events.dm | 15 ++
code/datums/status_effects/neutral.dm | 157 ++++++++++++++++++
code/modules/mob/living/carbon/inventory.dm | 16 ++
6 files changed, 243 insertions(+), 2 deletions(-)
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index b81f97c635d..05c11e969c1 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -108,6 +108,8 @@
#define STATUS_EFFECT_HELDUP /datum/status_effect/heldup // someone is currently pointing a gun at you
#define STATUS_EFFECT_HOLDUP /datum/status_effect/holdup // you are currently pointing a gun at someone
+
+#define STATUS_EFFECT_HIGHFIVE /datum/status_effect/high_fiving // you are angling for a high five
/////////////
// SLIME //
/////////////
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index 3d5f0d58d48..74b15baa276 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -315,6 +315,26 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
var/mob/living/carbon/C = owner
C.take(giver, receiving)
+/obj/screen/alert/highfive
+ icon_state = "default"
+ var/mob/living/carbon/giver
+ var/obj/item/slapper/slapper_item
+
+/obj/screen/alert/highfive/proc/setup(mob/living/carbon/taker, mob/living/carbon/giver, obj/item/slapper/slap)
+ name = "[giver] is offering a high-five"
+ desc = "[giver] wants a high-five! Click this alert to take it."
+ icon_state = "template"
+ cut_overlays()
+ add_overlay(slap)
+ src.slapper_item = slap
+ src.giver = giver
+
+/obj/screen/alert/highfive/Click(location, control, params)
+ . = ..()
+ var/datum/status_effect/high_fiving/high_five_effect = giver.has_status_effect(STATUS_EFFECT_HIGHFIVE)
+ if(high_five_effect)
+ high_five_effect.we_did_it(owner)
+
/// Gives the player the option to succumb while in critical condition
/obj/screen/alert/succumb
name = "Succumb"
diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm
index 4c7e5edf86c..5cea54c7e25 100644
--- a/code/datums/mood_events/generic_negative_events.dm
+++ b/code/datums/mood_events/generic_negative_events.dm
@@ -226,12 +226,12 @@
/datum/mood_event/tripped
description = "I can't believe I fell for the oldest trick in the book!\n"
- mood_change = -10
+ mood_change = -5
timeout = 2 MINUTES
/datum/mood_event/untied
description = "I hate when my shoes come untied!\n"
- mood_change = -5
+ mood_change = -3
timeout = 1 MINUTES
/datum/mood_event/gates_of_mansus
@@ -239,6 +239,37 @@
mood_change = -25
timeout = 4 MINUTES
+/datum/mood_event/high_five_alone
+ description = "I tried getting a high-five with no one around, how embarassing!\n"
+ mood_change = -2
+ timeout = 1 MINUTES
+
+/datum/mood_event/high_five_full_hand
+ description = "Oh God, I don't even know how to high-five correctly...\n"
+ mood_change = -1
+ timeout = 45 SECONDS
+
+/datum/mood_event/left_hanging
+ description = "But everyone loves high fives! Maybe people just... hate me?\n"
+ mood_change = -2
+ timeout = 1.5 MINUTES
+
+/datum/mood_event/too_slow
+ description = "NO! HOW COULD I BE.... TOO SLOW???\n"
+ mood_change = -2 // multiplied by how many people saw it happen, up to 8, so potentially massive. the ULTIMATE prank carries a lot of weight
+ timeout = 2 MINUTES
+
+/datum/mood_event/too_slow/add_effects(param)
+ var/people_laughing_at_you = 1 // start with 1 in case they're on the same tile or something
+ for(var/mob/living/carbon/iter_carbon in oview(owner, 7))
+ if(iter_carbon.stat == CONSCIOUS)
+ people_laughing_at_you++
+ if(people_laughing_at_you > 7)
+ break
+
+ mood_change *= people_laughing_at_you
+ return ..()
+
//These are unused so far but I want to remember them to use them later
/datum/mood_event/surgery
description = "HE'S CUTTING ME OPEN!!\n"
diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm
index 00f4e4a064b..390c404286c 100644
--- a/code/datums/mood_events/generic_positive_events.dm
+++ b/code/datums/mood_events/generic_positive_events.dm
@@ -203,3 +203,18 @@
description = "Truly, that was the food of the Divine!\n"
mood_change = 5
timeout = 3 MINUTES
+
+/datum/mood_event/high_five
+ description = "I love getting high fives!\n"
+ mood_change = 2
+ timeout = 45 SECONDS
+
+/datum/mood_event/high_ten
+ description = "AMAZING! A HIGH-TEN!\n"
+ mood_change = 3
+ timeout = 45 SECONDS
+
+/datum/mood_event/down_low
+ description = "HA! What a rube, they never stood a chance...\n"
+ mood_change = 4
+ timeout = 1.5 MINUTES
diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm
index 801f8cbbbd1..0115416b209 100644
--- a/code/datums/status_effects/neutral.dm
+++ b/code/datums/status_effects/neutral.dm
@@ -135,3 +135,160 @@
name = "Holding Up"
desc = "You're currently pointing a gun at someone."
icon_state = "aimed"
+
+// this status effect is used to negotiate the high-fiving capabilities of all concerned parties
+/datum/status_effect/high_fiving
+ id = "high_fiving"
+ duration = -1
+ tick_interval = -1
+ status_type = STATUS_EFFECT_UNIQUE
+ alert_type = null
+ /// The carbons who were offered the ability to partake in the high-five
+ var/list/possible_takers
+ /// The actual slapper item
+ var/obj/item/slapper/slap_item
+
+/datum/status_effect/high_fiving/on_creation(mob/living/new_owner, obj/item/slap)
+ . = ..()
+ if(!.)
+ return
+
+ slap_item = slap
+ owner.visible_message("[owner] raises [owner.p_their()] arm, looking for a high-five!", \
+ "You post up, looking for a high-five!", null, 2)
+
+ for(var/mob/living/carbon/possible_taker in orange(1, owner))
+ if(!owner.CanReach(possible_taker) || possible_taker.incapacitated())
+ continue
+ register_candidate(possible_taker)
+
+ if(!possible_takers) // in case we tried high-fiving with only a dead body around or something
+ owner.visible_message("[owner] realizes no one within range is actually capable of high-fiving, lowering [owner.p_their()] arm in shame...", \
+ "You realize a moment too late that no one within range is actually capable of high-fiving you, oof...", null, 2)
+ SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/high_five_alone)
+ qdel(src)
+ return
+
+ RegisterSignal(owner, COMSIG_MOVABLE_MOVED, .proc/check_owner_in_range)
+ RegisterSignal(slap_item, list(COMSIG_PARENT_QDELETING, COMSIG_ITEM_DROPPED), .proc/dropped_slap)
+ RegisterSignal(owner, COMSIG_PARENT_EXAMINE_MORE, .proc/check_fake_out)
+
+/datum/status_effect/high_fiving/Destroy()
+ QDEL_NULL(slap_item)
+ for(var/i in possible_takers)
+ var/mob/living/carbon/lost_hope = i
+ remove_candidate(lost_hope)
+ LAZYCLEARLIST(possible_takers)
+ return ..()
+
+/// Hook up the specified carbon mob for possible high-fiving, give them the alert and signals and all
+/datum/status_effect/high_fiving/proc/register_candidate(mob/living/carbon/possible_candidate)
+ var/obj/screen/alert/highfive/G = possible_candidate.throw_alert("[owner]", /obj/screen/alert/highfive)
+ if(!G)
+ return
+ LAZYADD(possible_takers, possible_candidate)
+ RegisterSignal(possible_candidate, COMSIG_MOVABLE_MOVED, .proc/check_taker_in_range)
+ G.setup(possible_candidate, owner, slap_item)
+
+/// Remove the alert and signals for the specified carbon mob
+/datum/status_effect/high_fiving/proc/remove_candidate(mob/living/carbon/removed_candidate)
+ removed_candidate.clear_alert("[owner]")
+ LAZYREMOVE(possible_takers, removed_candidate)
+ UnregisterSignal(removed_candidate, COMSIG_MOVABLE_MOVED)
+
+/// We failed to high-five broh, either because there's no one viable next to us anymore, or we lost the slapper, or what
+/datum/status_effect/high_fiving/proc/fail()
+ owner.visible_message("[owner] slowly lowers [owner.p_their()] arm, realizing no one will high-five [owner.p_them()]! How embarassing...", \
+ "You realize the futility of continuing to wait for a high-five, and lower your arm...", null, 2)
+ SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/left_hanging)
+ qdel(src)
+
+/// Yeah broh! This is where we do the high-fiving (or high-tenning :o)
+/datum/status_effect/high_fiving/proc/we_did_it(mob/living/carbon/successful_taker)
+ var/open_hands_taker
+ var/slappers_owner
+ for(var/i in successful_taker.held_items) // see how many hands the taker has open for high'ing
+ if(isnull(i))
+ open_hands_taker++
+
+ if(!open_hands_taker)
+ to_chat(successful_taker, "You can't high-five [owner] with no open hands!")
+ SEND_SIGNAL(successful_taker, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/high_five_full_hand) // not so successful now!
+ return
+
+ for(var/i in owner.held_items)
+ var/obj/item/slapper/slap_check = i
+ if(istype(slap_check))
+ slappers_owner++
+
+ if(!slappers_owner) // THE PRANKAGE
+ too_slow_p1(successful_taker)
+ return
+
+ if(slappers_owner >= 2) // we only check this if it's already established the taker has 2+ hands free
+ owner.visible_message("[successful_taker] enthusiastically high-tens [owner]!", "Wow! You're high-tenned [successful_taker]!", "You hear a sickening sound of flesh hitting flesh!", ignored_mobs=successful_taker)
+ to_chat(successful_taker, "You give high-tenning [owner] your all!")
+ playsound(owner, 'sound/weapons/slap.ogg', 100, TRUE, 1)
+ SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/high_ten)
+ SEND_SIGNAL(successful_taker, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/high_ten)
+ else
+ owner.visible_message("[successful_taker] high-fives [owner]!", "All right! You're high-fived by [successful_taker]!", "You hear a sickening sound of flesh hitting flesh!", ignored_mobs=successful_taker)
+ to_chat(successful_taker, "You high-five [owner]!")
+ playsound(owner, 'sound/weapons/slap.ogg', 50, TRUE, -1)
+ SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/high_five)
+ SEND_SIGNAL(successful_taker, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/high_five)
+ qdel(src)
+
+/// If we don't have any slappers in hand when someone goes to high-five us, we prank the hell out of them
+/datum/status_effect/high_fiving/proc/too_slow_p1(mob/living/carbon/rube)
+ owner.visible_message("[rube] rushes in to high-five [owner], but-", "[rube] falls for your trick just as planned, lunging for a high-five that no longer exists! Classic!", ignored_mobs=rube)
+ to_chat(rube, "You go in for [owner]'s high-five, but-")
+ addtimer(CALLBACK(src, .proc/too_slow_p2, rube), 0.5 SECONDS)
+
+/// Part two of the ultimate prank
+/datum/status_effect/high_fiving/proc/too_slow_p2(mob/living/carbon/rube)
+ if(!owner || !rube)
+ qdel(src)
+ return
+ owner.visible_message("[owner] pulls away from [rube]'s slap at the last second, dodging the high-five entirely!", "[rube] fails to make contact with your hand, making an utter fool of [rube.p_them()]self!", "You hear a disappointing sound of flesh not hitting flesh!", ignored_mobs=rube)
+ var/all_caps_for_emphasis = uppertext("NO! [owner] PULLS [owner.p_their()] HAND AWAY FROM YOURS! YOU'RE TOO SLOW!")
+ to_chat(rube, "[all_caps_for_emphasis]")
+ playsound(owner, 'sound/weapons/thudswoosh.ogg', 100, TRUE, 1)
+ rube.Knockdown(1 SECONDS)
+ SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/down_low)
+ SEND_SIGNAL(rube, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/too_slow)
+ qdel(src)
+
+/// If someone examine_more's us while we don't have a slapper in hand, it'll tip them off to our trickster ways
+/datum/status_effect/high_fiving/proc/check_fake_out(datum/source, mob/user, list/examine_list)
+ SIGNAL_HANDLER
+
+ if(!slap_item)
+ examine_list += "[owner]'s arm appears tensed up, as if [owner.p_they()] plan on pulling it back suddenly...\n"
+
+/// One of our possible takers moved, see if they left us hanging
+/datum/status_effect/high_fiving/proc/check_taker_in_range(mob/living/carbon/taker)
+ SIGNAL_HANDLER
+ if(owner.CanReach(taker) && !taker.incapacitated())
+ return
+
+ to_chat(taker, "You left [owner] hanging!")
+ remove_candidate(taker)
+ if(!possible_takers)
+ fail()
+
+/// The propositioner moved, see if anyone is out of range now
+/datum/status_effect/high_fiving/proc/check_owner_in_range(mob/living/carbon/source)
+ SIGNAL_HANDLER
+
+ for(var/i in possible_takers)
+ var/mob/living/carbon/checking_taker = i
+ if(!istype(checking_taker) || !owner.CanReach(checking_taker) || checking_taker.incapacitated())
+ remove_candidate(checking_taker)
+
+ if(!possible_takers)
+ fail()
+
+/// Something fishy is going on here...
+/datum/status_effect/high_fiving/proc/dropped_slap(obj/item/source)
+ slap_item = null
diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm
index 752b1fa94ce..a1015884be9 100644
--- a/code/modules/mob/living/carbon/inventory.dm
+++ b/code/modules/mob/living/carbon/inventory.dm
@@ -170,6 +170,10 @@
if(!receiving)
to_chat(src, "You're not holding anything to give!")
return
+
+ if(istype(receiving, /obj/item/slapper))
+ offer_high_five(receiving)
+ return
visible_message("[src] is offering [receiving]", \
"You offer [receiving]", null, 2)
for(var/mob/living/carbon/C in orange(1, src)) //Fixed that, now it shouldn't be able to give benos stunbatons and IDs
@@ -210,3 +214,15 @@
visible_message("[src] takes [I] from [giver]", \
"You take [I] from [giver]")
put_in_hands(I)
+
+/// Spin-off of [/mob/living/carbon/proc/give] exclusively for high-fiving
+/mob/living/carbon/proc/offer_high_five(obj/item/slap)
+ if(has_status_effect(STATUS_EFFECT_HIGHFIVE))
+ return
+ if(!(locate(/mob/living/carbon) in orange(1, src)))
+ visible_message("[src] raises [p_their()] arm, looking around for a high-five, but there's no one around! How embarassing...", \
+ "You post up, looking for a high-five, but finding no one within range! How embarassing...", null, 2)
+ SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/high_five_alone)
+ return
+
+ apply_status_effect(STATUS_EFFECT_HIGHFIVE, slap)