diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index 5bd9632355..81d8593d4e 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -220,7 +220,7 @@
/obj/screen/alert/shiver
name = "Shivering"
- desc = "You're shivering! Get somewhere warmer and take off any insulating clothing like a space suit."
+ desc = "You're shivering! Get somewhere warmer and take off any insulating clothing like a space suit."
/obj/screen/alert/lowpressure
name = "Low Pressure"
@@ -306,6 +306,39 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
if(CHECK_MOBILITY(L, MOBILITY_MOVE))
return L.resist_fire() //I just want to start a flame in your hearrrrrrtttttt.
+/obj/screen/alert/give // information set when the give alert is made
+ icon_state = "default"
+ var/mob/living/carbon/giver
+ var/obj/item/receiving
+
+/**
+ * Handles assigning most of the variables for the alert that pops up when an item is offered
+ *
+ * Handles setting the name, description and icon of the alert and tracking the person giving
+ * and the item being offered, also registers a signal that removes the alert from anyone who moves away from the giver
+ * Arguments:
+ * * taker - The person receiving the alert
+ * * giver - The person giving the alert and item
+ * * receiving - The item being given by the giver
+ */
+/obj/screen/alert/give/proc/setup(mob/living/carbon/taker, mob/living/carbon/giver, obj/item/receiving)
+ name = "[giver] is offering [receiving]"
+ desc = "[giver] is offering [receiving]. Click this alert to take it."
+ icon_state = "template"
+ cut_overlays()
+ add_overlay(receiving)
+ src.receiving = receiving
+ src.giver = giver
+ RegisterSignal(taker, COMSIG_MOVABLE_MOVED, .proc/removeAlert)
+
+/obj/screen/alert/give/proc/removeAlert()
+ to_chat(usr, "You moved out of range of [giver]!")
+ usr.clear_alert("[giver]")
+
+/obj/screen/alert/give/Click(location, control, params)
+ . = ..()
+ var/mob/living/carbon/C = usr
+ C.take(giver, receiving)
//ALIENS
diff --git a/code/_onclick/right_click.dm b/code/_onclick/right_click.dm
index 4b2480eb8c..9a99bbd20b 100644
--- a/code/_onclick/right_click.dm
+++ b/code/_onclick/right_click.dm
@@ -51,7 +51,11 @@
//Standard reach turf to turf or reaching inside storage
if(CanReach(A,W))
if(W)
- return W.rightclick_melee_attack_chain(src, A, params)
+ if(a_intent == INTENT_HELP && iscarbon(src))
+ var/mob/living/carbon/C = src
+ C.give()
+ else
+ return W.rightclick_melee_attack_chain(src, A, params)
else
if(!AltUnarmedAttack(A, TRUE))
. = UnarmedAttack(A, TRUE, a_intent)
diff --git a/code/modules/keybindings/keybind/carbon.dm b/code/modules/keybindings/keybind/carbon.dm
index 46cb5cd0ac..50ec29ff5e 100644
--- a/code/modules/keybindings/keybind/carbon.dm
+++ b/code/modules/keybindings/keybind/carbon.dm
@@ -60,3 +60,14 @@
/datum/keybinding/carbon/select_harm_intent/down(client/user)
user.mob?.a_intent_change(INTENT_HARM)
return TRUE
+
+/datum/keybinding/carbon/give
+ hotkey_keys = list("CtrlG")
+ name = "Give_Item"
+ full_name = "Give item"
+ description = "Give the item you're currently holding"
+
+/datum/keybinding/carbon/give/down(client/user)
+ var/mob/living/carbon/C = user.mob
+ C.give()
+ return TRUE
diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm
index 96dab9e95d..e5ba022277 100644
--- a/code/modules/mob/living/carbon/inventory.dm
+++ b/code/modules/mob/living/carbon/inventory.dm
@@ -159,3 +159,57 @@
/mob/living/carbon/proc/get_holding_bodypart_of_item(obj/item/I)
var/index = get_held_index_of_item(I)
return index && hand_bodyparts[index]
+
+/**
+ * Proc called when giving an item to another player
+ *
+ * This handles creating an alert and adding an overlay to it
+ */
+/mob/living/carbon/proc/give(target)
+ var/obj/item/receiving = get_active_held_item()
+ if(!receiving)
+ to_chat(src, "You're not holding anything to give!")
+ return
+ visible_message("[src] is offering [receiving]", \
+ "You offer [receiving]", null, 2)
+ var/mob/living/carbon/targets = list()
+ if(!target)
+ for(var/mob/living/carbon/C in orange(1, src))
+ if(!CanReach(C))
+ return
+ targets += C
+ else
+ targets += target
+ if(!targets)
+ return
+ for(var/mob/living/carbon/C in targets)
+ var/obj/screen/alert/give/G = C.throw_alert("[src]", /obj/screen/alert/give)
+ if(!G)
+ return
+ G.setup(C, src, receiving)
+
+/**
+ * Proc called when the player clicks the give alert
+ *
+ * Handles checking if the player taking the item has open slots and is in range of the giver
+ * Also deals with the actual transferring of the item to the players hands
+ * Arguments:
+ * * giver - The person giving the original item
+ * * I - The item being given by the giver
+ */
+/mob/living/carbon/proc/take(mob/living/carbon/giver, obj/item/I)
+ clear_alert("[giver]")
+ if(get_dist(src, giver) > 1)
+ to_chat(src, "[giver] is out of range! ")
+ return
+ if(!I || giver.get_active_held_item() != I)
+ to_chat(src, "[giver] is no longer holding the item they were offering! ")
+ return
+ if(!get_empty_held_indexes())
+ to_chat(src, "You have no empty hands!")
+ return
+ if(!giver.temporarilyRemoveItemFromInventory(I))
+ visible_message("[src] tries to hand over [I] but it's stuck to them....", \
+ " You make a fool of yourself trying to give away an item stuck to your hands")
+ return
+ put_in_hands(I)