[MIRROR] Allows you to offer an item to only one person with Shift+Ctrl+Click [MDB IGNORE] (#12176)

* Allows you to offer an item to only one person with Shift+Ctrl+Click (#65441)

You can click someone directly with shift+ctrl+click to offer an item only to them. This is in contrast with pressing G, which offers the item to every adjacent carbon mob.

Also fixes a runtime where the Give screen alert on a potential recipient was trying to remove itself on proximity loss after the Offering status effect had already done it.

Removes duplicate range check on Give screen alert that was causing the runtime as Offering status effect takes care of it.

Also adds a check after clicking the screen alert to take something to make sure we're not dead or incapacitated, so dead people can no longer take things.

Also adds a screentip for this functionality.

Also adds some more checks to give() to make sure we can do it before sending the message to players that we're offering something.

* Allows you to offer an item to only one person with Shift+Ctrl+Click

Co-authored-by: cacogen <25089914+cacogen@users.noreply.github.com>
This commit is contained in:
SkyratBot
2022-03-22 22:03:06 +01:00
committed by GitHub
parent 4f8cdbcfa2
commit dfc7e7022e
5 changed files with 42 additions and 25 deletions

View File

@@ -331,7 +331,6 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
add_overlay(receiving)
src.receiving = receiving
src.offerer = offerer
RegisterSignal(taker, COMSIG_MOVABLE_MOVED, .proc/check_in_range, override = TRUE) //Override to prevent runtimes when people offer a item multiple times
/atom/movable/screen/alert/give/Click(location, control, params)
. = ..()
@@ -348,14 +347,6 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
var/mob/living/carbon/taker = owner
taker.take(offerer, receiving)
/// Simply checks if the other person is still in range
/atom/movable/screen/alert/give/proc/check_in_range(atom/taker)
SIGNAL_HANDLER
if(!offerer.CanReach(taker))
to_chat(owner, span_warning("You moved out of range of [offerer]!"))
owner.clear_alert("[offerer]")
/atom/movable/screen/alert/give/highfive/setup(mob/living/carbon/taker, mob/living/carbon/offerer, obj/item/receiving)
. = ..()
name = "[offerer] is offering a high-five!"
@@ -415,7 +406,6 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
add_overlay(receiving)
src.receiving = receiving
src.offerer = offerer
RegisterSignal(taker, COMSIG_MOVABLE_MOVED, .proc/check_in_range, override = TRUE) //Override to prevent runtimes when people offer a item multiple times
/// Gives the player the option to succumb while in critical condition
/atom/movable/screen/alert/succumb

View File

@@ -164,7 +164,7 @@
/// The type of alert given to people when offered, in case you need to override some behavior (like for high-fives)
var/give_alert_type = /atom/movable/screen/alert/give
/datum/status_effect/offering/on_creation(mob/living/new_owner, obj/item/offer, give_alert_override)
/datum/status_effect/offering/on_creation(mob/living/new_owner, obj/item/offer, give_alert_override, mob/living/carbon/offered)
. = ..()
if(!.)
return
@@ -172,6 +172,9 @@
if(give_alert_override)
give_alert_type = give_alert_override
if(offered && owner.CanReach(offered) && !IS_DEAD_OR_INCAP(offered) && offered.can_hold_items())
register_candidate(offered)
else
for(var/mob/living/carbon/possible_taker in orange(1, owner))
if(!owner.CanReach(possible_taker) || IS_DEAD_OR_INCAP(possible_taker) || !possible_taker.can_hold_items())
continue
@@ -215,6 +218,7 @@
if(owner.CanReach(taker) && !IS_DEAD_OR_INCAP(taker))
return
to_chat(taker, span_warning("You moved out of range of [owner]!"))
remove_candidate(taker)
/// The offerer moved, see if anyone is out of range now

View File

@@ -85,6 +85,12 @@
return ..()
/mob/living/carbon/CtrlShiftClick(mob/user)
..()
if(iscarbon(user))
var/mob/living/carbon/carbon_user = user
carbon_user.give(src)
/mob/living/carbon/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
. = ..()
var/hurt = TRUE

View File

@@ -2,7 +2,8 @@
. = ..()
if (!isnull(held_item))
return .
context[SCREENTIP_CONTEXT_CTRL_SHIFT_LMB] = "Offer item"
return CONTEXTUAL_SCREENTIP_SET
if (!ishuman(user))
return .

View File

@@ -162,27 +162,40 @@
*
* This handles creating an alert and adding an overlay to it
*/
/mob/living/carbon/proc/give()
var/obj/item/offered_item = get_active_held_item()
if(!offered_item)
to_chat(src, span_warning("You're not holding anything to give!"))
/mob/living/carbon/proc/give(mob/living/carbon/offered)
if(has_status_effect(/datum/status_effect/offering))
to_chat(src, span_warning("You're already offering up something!"))
return
if(IS_DEAD_OR_INCAP(src))
to_chat(src, span_warning("You're unable to offer anything in your current state!"))
return
if(has_status_effect(/datum/status_effect/offering))
to_chat(src, span_warning("You're already offering up something!"))
var/obj/item/offered_item = get_active_held_item()
if(!offered_item)
to_chat(src, span_warning("You're not holding anything to give!"))
return
if(offered)
if(IS_DEAD_OR_INCAP(offered))
to_chat(src, span_warning("They're unable to take anything in their current state!"))
return
if(!CanReach(offered))
to_chat(src, span_warning("You have to be adjacent to offer things!"))
return
else
if(!(locate(/mob/living/carbon) in orange(1, src)))
to_chat(src, span_warning("There's nobody adjacent to offer it to!"))
return
if(offered_item.on_offered(src)) // see if the item interrupts with its own behavior
return
visible_message(span_notice("[src] is offering [offered_item]."), \
span_notice("You offer [offered_item]."), null, 2)
visible_message(span_notice("[src] is offering [offered ? "[offered] " : ""][offered_item]."), \
span_notice("You offer [offered ? "[offered] " : ""][offered_item]."), null, 2)
apply_status_effect(/datum/status_effect/offering, offered_item)
apply_status_effect(/datum/status_effect/offering, offered_item, null, offered)
/**
* Proc called when the player clicks the give alert
@@ -195,6 +208,9 @@
*/
/mob/living/carbon/proc/take(mob/living/carbon/offerer, obj/item/I)
clear_alert("[offerer]")
if(IS_DEAD_OR_INCAP(src))
to_chat(src, span_warning("You're unable to take anything in your current state!"))
return
if(get_dist(src, offerer) > 1)
to_chat(src, span_warning("[offerer] is out of range!"))
return