mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 19:47:22 +01:00
Pops up a little bubble when you're requesting a high-five, along with some other emotes (#20472)
* High five! * Add in-hand use * use in hand too * closing remarks * better looking * Fixes daps * grab my hand fat man * hand shake * Implement missed messages * i can spell * Update code/modules/mob/living/carbon/human/human_emote.dm Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com> * Review concerns * Add some auto-doc, minor changes * more cleverly handles pointing * Update code/modules/point/point.dm Path clarity Co-authored-by: Farie82 <farie82@users.noreply.github.com> --------- Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com> Co-authored-by: Farie82 <farie82@users.noreply.github.com>
This commit is contained in:
@@ -140,6 +140,8 @@
|
||||
/////////////
|
||||
|
||||
#define STATUS_EFFECT_HIGHFIVE /datum/status_effect/high_five
|
||||
#define STATUS_EFFECT_DAP /datum/status_effect/high_five/dap
|
||||
#define STATUS_EFFECT_HANDSHAKE /datum/status_effect/high_five/handshake
|
||||
|
||||
#define STATUS_EFFECT_CHARGING /datum/status_effect/charging
|
||||
|
||||
|
||||
@@ -338,7 +338,7 @@
|
||||
name = "Cry"
|
||||
|
||||
/datum/keybinding/emote/carbon/human/dap
|
||||
linked_emote = /datum/emote/living/carbon/human/dap
|
||||
linked_emote = /datum/emote/living/carbon/human/highfive/dap
|
||||
name = "Dap"
|
||||
|
||||
/datum/keybinding/emote/carbon/human/eyebrow
|
||||
@@ -418,7 +418,7 @@
|
||||
name = "High Five"
|
||||
|
||||
/datum/keybinding/emote/carbon/human/handshake
|
||||
linked_emote = /datum/emote/living/carbon/human/handshake
|
||||
linked_emote = /datum/emote/living/carbon/human/highfive/handshake
|
||||
name = "Handshake"
|
||||
|
||||
/datum/keybinding/emote/carbon/human/snap
|
||||
|
||||
@@ -47,25 +47,98 @@
|
||||
|
||||
/datum/status_effect/high_five
|
||||
id = "high_five"
|
||||
duration = 5 SECONDS
|
||||
duration = 10 SECONDS
|
||||
alert_type = null
|
||||
status_type = STATUS_EFFECT_REFRESH
|
||||
/// Message displayed when wizards perform this together
|
||||
var/critical_success = "high-five EPICALLY!"
|
||||
/// Message displayed when normal people perform this together
|
||||
var/success = "high-five!"
|
||||
/// Message displayed when this status effect is applied.
|
||||
var/request = "requests a high-five."
|
||||
/// Item to be shown in the pop-up balloon.
|
||||
var/obj/item/item_path = /obj/item/latexballon
|
||||
/// Sound effect played when this emote is completed.
|
||||
var/sound_effect = 'sound/weapons/slap.ogg'
|
||||
|
||||
/// So we don't leave folks with god-mode
|
||||
/datum/status_effect/high_five/proc/wiz_cleanup(mob/user, mob/highfived)
|
||||
user.status_flags &= ~GODMODE
|
||||
highfived.status_flags &= ~GODMODE
|
||||
|
||||
/datum/status_effect/high_five/on_apply()
|
||||
if(!iscarbon(owner))
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
var/mob/living/carbon/user = owner
|
||||
var/is_wiz = iswizard(user)
|
||||
for(var/mob/living/carbon/C in orange(1, user))
|
||||
if(!C.has_status_effect(type) || C == user)
|
||||
continue
|
||||
if(is_wiz && iswizard(C))
|
||||
user.visible_message("<span class='biggerdanger'><b>[user.name]</b> and <b>[C.name]</b> [critical_success]</span>")
|
||||
user.status_flags |= GODMODE
|
||||
C.status_flags |= GODMODE
|
||||
explosion(get_turf(user), 5, 2, 1, 3, cause = id)
|
||||
// explosions have a spawn so this makes sure that we don't get gibbed
|
||||
addtimer(CALLBACK(src, PROC_REF(wiz_cleanup), user, C), 1)
|
||||
add_attack_logs(user, C, "caused a wizard [id] explosion")
|
||||
user.remove_status_effect(type)
|
||||
C.remove_status_effect(type)
|
||||
|
||||
user.do_attack_animation(C, no_effect = TRUE)
|
||||
C.do_attack_animation(user, no_effect = TRUE)
|
||||
user.visible_message("<span class='notice'><b>[user.name]</b> and <b>[C.name]</b> [success]</span>")
|
||||
playsound(user, sound_effect, 80)
|
||||
user.remove_status_effect(type)
|
||||
C.remove_status_effect(type)
|
||||
return FALSE
|
||||
|
||||
owner.custom_emote(EMOTE_VISIBLE, request)
|
||||
owner.create_point_bubble_from_path(item_path, FALSE)
|
||||
|
||||
/datum/status_effect/high_five/on_timeout()
|
||||
owner.visible_message("[owner] [get_missed_message()]")
|
||||
|
||||
/datum/status_effect/high_five/proc/get_missed_message()
|
||||
var/list/missed_highfive_messages = list(
|
||||
"it looks like [owner.p_they()] [owner.p_were()] left hanging...",
|
||||
"seeming to wave at nobody in particular.",
|
||||
"moving [owner.p_their()] hand directly to [owner.p_their()] forehead in shame.",
|
||||
"fully committing and high-fiving empty space.",
|
||||
"high-fiving [owner.p_their()] other hand shamefully before wiping away a tear.",
|
||||
"going for a handshake, then a fistbump, before pulling [owner.p_their()] hand back...? What [owner.p_are()] [owner.p_they()] doing?"
|
||||
"lowers [owner.p_their()] hand, it looks like [owner.p_they()] [owner.p_were()] left hanging...",
|
||||
"seems to awkwardly wave at nobody in particular.",
|
||||
"moves [owner.p_their()] hand directly to [owner.p_their()] forehead in shame.",
|
||||
"fully commits and high-fives empty space.",
|
||||
"high-fives [owner.p_their()] other hand shamefully before wiping away a tear.",
|
||||
"goes for a handshake, then a fistbump, before pulling [owner.p_their()] hand back...? <i>What [owner.p_are()] [owner.p_they()] doing?</i>"
|
||||
)
|
||||
|
||||
return pick(missed_highfive_messages)
|
||||
|
||||
/datum/status_effect/high_five/on_timeout()
|
||||
// show some emotionally damaging failure messages
|
||||
// high risk, high reward
|
||||
owner.visible_message("[owner] awkwardly lowers [owner.p_their()] hand, [get_missed_message()]")
|
||||
/datum/status_effect/high_five/dap
|
||||
id = "dap"
|
||||
critical_success = "dap each other up EPICALLY!"
|
||||
success = "dap each other up!"
|
||||
request = "requests someone to dap them up!"
|
||||
sound_effect = 'sound/effects/snap.ogg'
|
||||
item_path = /obj/item/melee/touch_attack/fake_disintegrate // EI-NATH!
|
||||
|
||||
/datum/status_effect/high_five/dap/get_missed_message()
|
||||
return "sadly can't find anybody to give daps to, and daps [owner.p_themselves()]. Shameful."
|
||||
|
||||
/datum/status_effect/high_five/handshake
|
||||
id = "handshake"
|
||||
critical_success = "give each other an EPIC handshake!"
|
||||
success = "give each other a handshake!"
|
||||
request = "requests a handshake!"
|
||||
sound_effect = "sound/weapons/thudswoosh.ogg"
|
||||
|
||||
/datum/status_effect/high_five/handshake/get_missed_message()
|
||||
var/list/missed_messages = list(
|
||||
"drops [owner.p_their()] hand, shamefully.",
|
||||
"grabs [owner.p_their()] outstretched hand with [owner.p_their()] other hand and gives [owner.p_themselves()] a handshake.",
|
||||
"balls [owner.p_their()] hand into a fist, slowly bringing it back in."
|
||||
)
|
||||
|
||||
return pick(missed_messages)
|
||||
|
||||
/datum/status_effect/charging
|
||||
id = "charging"
|
||||
|
||||
@@ -18,6 +18,18 @@
|
||||
if(force)
|
||||
return ..()
|
||||
|
||||
/obj/item/slapper/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(!isliving(user))
|
||||
return
|
||||
var/mob/living/L = user
|
||||
if(!L.has_status_effect(STATUS_EFFECT_HIGHFIVE))
|
||||
L.apply_status_effect(STATUS_EFFECT_HIGHFIVE)
|
||||
L.visible_message(
|
||||
"<span class='notice'[user] raises [user.p_their()] hand for a high-five!</span>",
|
||||
"<span class='notice'>You raise your hand for a high-five!</span>"
|
||||
)
|
||||
|
||||
/obj/item/slapper/attack_obj(obj/O, mob/living/user, params)
|
||||
if(!istype(O, /obj/structure/table))
|
||||
return ..()
|
||||
|
||||
@@ -55,14 +55,6 @@
|
||||
muzzled_noises = list("weak", "pathetic", "sad")
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
/datum/emote/living/carbon/human/dap
|
||||
key = "dap"
|
||||
key_third_person = "daps"
|
||||
message = "sadly can't find anybody to give daps to, and daps themself. Shameful."
|
||||
message_param = "give daps to %t."
|
||||
emote_target_type = EMOTE_TARGET_MOB
|
||||
hands_use_check = TRUE
|
||||
|
||||
/datum/emote/living/carbon/human/eyebrow
|
||||
key = "eyebrow"
|
||||
message = "raises an eyebrow."
|
||||
@@ -283,9 +275,10 @@
|
||||
/datum/emote/living/carbon/human/highfive
|
||||
key = "highfive"
|
||||
key_third_person = "highfives"
|
||||
message = "requests a highfive."
|
||||
hands_use_check = TRUE
|
||||
cooldown = 3 SECONDS
|
||||
cooldown = 5 SECONDS
|
||||
/// Status effect to apply when this emote is used. Should be a subtype
|
||||
var/status = STATUS_EFFECT_HIGHFIVE
|
||||
|
||||
/datum/emote/living/carbon/human/highfive/can_run_emote(mob/user, status_check, intentional)
|
||||
. = ..()
|
||||
@@ -293,81 +286,24 @@
|
||||
if(user_carbon.restrained())
|
||||
return FALSE
|
||||
|
||||
/datum/emote/living/carbon/human/highfive/proc/wiz_cleanup(mob/user, mob/highfived)
|
||||
user.status_flags &= ~GODMODE
|
||||
highfived.status_flags &= ~GODMODE
|
||||
|
||||
/datum/emote/living/carbon/human/highfive/run_emote(mob/user, params, type_override, intentional)
|
||||
var/mob/living/carbon/user_carbon = user
|
||||
if(user_carbon.has_status_effect(STATUS_EFFECT_HIGHFIVE))
|
||||
user.visible_message("[user.name] shakes [user.p_their()] hand around slightly, impatiently waiting for someone to high-five them.")
|
||||
if(user_carbon.has_status_effect(status))
|
||||
user.visible_message("[user.name] shakes [user.p_their()] hand around slightly, impatiently waiting for someone to [key].")
|
||||
return TRUE
|
||||
user_carbon.apply_status_effect(STATUS_EFFECT_HIGHFIVE)
|
||||
for(var/mob/living/L in orange(1))
|
||||
if(L.has_status_effect(STATUS_EFFECT_HIGHFIVE) && L != user)
|
||||
if(iswizard(user) && iswizard(L))
|
||||
user.visible_message("<span class='biggerdanger'><b>[user.name]</b> and <b>[L.name]</b> high-five EPICALLY!</span>")
|
||||
user_carbon.status_flags |= GODMODE
|
||||
L.status_flags |= GODMODE
|
||||
explosion(get_turf(user), 5, 2, 1, 3)
|
||||
// explosions have a spawn so this makes sure that we don't get gibbed
|
||||
addtimer(CALLBACK(src, PROC_REF(wiz_cleanup), user_carbon, L), 1)
|
||||
user_carbon.remove_status_effect(STATUS_EFFECT_HIGHFIVE)
|
||||
L.remove_status_effect(STATUS_EFFECT_HIGHFIVE)
|
||||
return TRUE
|
||||
user.visible_message("<b>[user.name]</b> and <b>[L.name]</b> high-five!")
|
||||
playsound(user, 'sound/effects/snap.ogg', 50)
|
||||
user_carbon.remove_status_effect(STATUS_EFFECT_HIGHFIVE)
|
||||
L.remove_status_effect(STATUS_EFFECT_HIGHFIVE)
|
||||
return TRUE
|
||||
user_carbon.apply_status_effect(status)
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/emote/living/carbon/human/handshake
|
||||
/datum/emote/living/carbon/human/highfive/dap
|
||||
key = "dap"
|
||||
status = STATUS_EFFECT_DAP
|
||||
key_third_person = "daps"
|
||||
|
||||
/datum/emote/living/carbon/human/highfive/handshake
|
||||
key = "handshake"
|
||||
message = "holds out their hand."
|
||||
hands_use_check = TRUE
|
||||
emote_target_type = EMOTE_TARGET_MOB
|
||||
target_behavior = EMOTE_TARGET_BHVR_DEFAULT_TO_BASE
|
||||
|
||||
/datum/emote/living/carbon/human/handshake/act_on_target(mob/user, target)
|
||||
. = ..()
|
||||
if(!target)
|
||||
user.visible_message(
|
||||
"[user] seems to shake hands with empty space.",
|
||||
"You shake the air's hand."
|
||||
)
|
||||
return EMOTE_ACT_STOP_EXECUTION
|
||||
|
||||
if(!user.Adjacent(target) || !ishuman(target))
|
||||
message_param = "extends a hand towards %t."
|
||||
return TRUE
|
||||
|
||||
var/mob/living/carbon/human/human_target = target
|
||||
|
||||
if(!HAS_TRAIT(human_target, TRAIT_HANDS_BLOCKED) && !human_target.r_hand && !human_target.restrained())
|
||||
message_param = "shakes hands with %t."
|
||||
else
|
||||
message_param = "holds out [user.p_their()] hand to %t."
|
||||
|
||||
/datum/emote/living/carbon/human/handshake/run_emote(mob/user, params, type_override, intentional)
|
||||
var/mob/living/target
|
||||
for(var/mob/living/A in oview(5, user))
|
||||
if(params == A.name)
|
||||
target = A
|
||||
|
||||
if(!target)
|
||||
user.visible_message(
|
||||
"[user] seems to shake hands with empty space.",
|
||||
"You shake the air's hand."
|
||||
)
|
||||
return TRUE
|
||||
|
||||
if(!HAS_TRAIT(target, TRAIT_HANDS_BLOCKED) && !target.r_hand && !target.restrained())
|
||||
message_param = "shakes hands with %t."
|
||||
else
|
||||
message_param = "holds out [user.p_their()] hand to %t."
|
||||
|
||||
return ..()
|
||||
key_third_person = "handshakes"
|
||||
status = STATUS_EFFECT_HANDSHAKE
|
||||
|
||||
/datum/emote/living/carbon/human/snap
|
||||
key = "snap"
|
||||
|
||||
+44
-11
@@ -12,7 +12,7 @@
|
||||
return
|
||||
|
||||
if((pointed_atom in src) || (pointed_atom.loc in src))
|
||||
create_point_bubble(pointed_atom)
|
||||
create_point_bubble_from_atom(pointed_atom)
|
||||
return
|
||||
|
||||
var/turf/tile = get_turf(pointed_atom)
|
||||
@@ -24,9 +24,16 @@
|
||||
|
||||
animate(visual, pixel_x = (tile.x - our_tile.x) * world.icon_size + pointed_atom.pixel_x, pixel_y = (tile.y - our_tile.y) * world.icon_size + pointed_atom.pixel_y, time = 1.7, easing = EASE_OUT)
|
||||
|
||||
/atom/movable/proc/create_point_bubble(atom/pointed_atom)
|
||||
/// Create a bubble pointing at a particular icon and icon state.
|
||||
/// See args for create_point_bubble_from_atom.
|
||||
/atom/movable/proc/create_point_bubble(mutable_appearance/pointed_atom_appearance, include_arrow = TRUE)
|
||||
var/obj/effect/thought_bubble_effect = new
|
||||
|
||||
pointed_atom_appearance.layer = POINT_LAYER
|
||||
pointed_atom_appearance.blend_mode = BLEND_INSET_OVERLAY
|
||||
pointed_atom_appearance.pixel_x = 0
|
||||
pointed_atom_appearance.pixel_y = 0
|
||||
|
||||
var/mutable_appearance/thought_bubble = mutable_appearance(
|
||||
'icons/effects/effects.dmi',
|
||||
thought_bubble_image,
|
||||
@@ -34,17 +41,8 @@
|
||||
appearance_flags = KEEP_APART,
|
||||
)
|
||||
|
||||
var/mutable_appearance/pointed_atom_appearance = new(pointed_atom.appearance)
|
||||
pointed_atom_appearance.blend_mode = BLEND_INSET_OVERLAY
|
||||
pointed_atom_appearance.layer = POINT_LAYER
|
||||
pointed_atom_appearance.pixel_x = 0
|
||||
pointed_atom_appearance.pixel_y = 0
|
||||
thought_bubble.overlays += pointed_atom_appearance
|
||||
|
||||
var/hover_outline_index = pointed_atom.get_filter("hover_outline")
|
||||
if (!isnull(hover_outline_index))
|
||||
pointed_atom_appearance.filters.Cut(hover_outline_index, hover_outline_index + 1)
|
||||
|
||||
thought_bubble.pixel_x = 16
|
||||
thought_bubble.pixel_y = 32
|
||||
thought_bubble.alpha = 200
|
||||
@@ -66,6 +64,41 @@
|
||||
|
||||
QDEL_IN(thought_bubble_effect, 2 SECONDS)
|
||||
|
||||
/**
|
||||
* Create a point bubble towards a given item.
|
||||
*
|
||||
* Arguments:
|
||||
* * pointed_atom - Atom to show in the bubble.
|
||||
* * include_arrow - If true, show an arrow pointing downwards.
|
||||
*/
|
||||
/atom/movable/proc/create_point_bubble_from_atom(atom/pointed_atom, include_arrow = TRUE)
|
||||
var/mutable_appearance/pointed_atom_appearance = new(pointed_atom.appearance)
|
||||
|
||||
var/hover_outline_index = pointed_atom.get_filter("hover_outline")
|
||||
if (!isnull(hover_outline_index))
|
||||
pointed_atom_appearance.filters.Cut(hover_outline_index, hover_outline_index + 1)
|
||||
|
||||
create_point_bubble(pointed_atom_appearance, include_arrow)
|
||||
|
||||
/**
|
||||
* Create a point bubble towards a given item, from an icon/icon state.
|
||||
*
|
||||
* Arguments:
|
||||
* * icon - Icon source for the bubble's icon.
|
||||
* * icon_state - Icon state for the bubble's icon.
|
||||
* * include_arrow - If true, show an arrow pointing downwards.
|
||||
*/
|
||||
/atom/movable/proc/create_point_bubble_from_icons(icon, icon_state, include_arrow = TRUE)
|
||||
var/mutable_appearance/pointed_atom_appearance = mutable_appearance(
|
||||
icon,
|
||||
icon_state,
|
||||
)
|
||||
create_point_bubble(pointed_atom_appearance, include_arrow)
|
||||
|
||||
/// See above, this uses an uninstantiated path.
|
||||
/atom/movable/proc/create_point_bubble_from_path(atom/pointed_atom_path, include_arrow = TRUE)
|
||||
create_point_bubble_from_icons(initial(pointed_atom_path.icon), initial(pointed_atom_path.icon_state), include_arrow)
|
||||
|
||||
/obj/effect/temp_visual/point
|
||||
name = "arrow"
|
||||
desc = "It's an arrow hanging in mid-air. There may be a wizard about."
|
||||
|
||||
Reference in New Issue
Block a user