diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm
index eb1d4d106fd..d1b4ebf3d05 100644
--- a/code/datums/components/embedded.dm
+++ b/code/datums/components/embedded.dm
@@ -3,7 +3,7 @@
and when it impacts and meets the requirements to stick into something, it instantiates an embedded component. Once the item falls out, the component is destroyed, while the
element survives to embed another day.
- There are 2 different things that can be embedded presently: humans, and turfs (walls)
+ There are 2 different things that can be embedded presently: humans, and closed turfs (see: walls)
- Human embedding has all the classical embedding behavior, and tracks more events and signals. The main behaviors and hooks to look for are:
-- Every process tick, there is a chance to randomly proc pain, controlled by pain_chance. There may also be a chance for the object to fall out randomly, per fall_chance
@@ -19,7 +19,7 @@
- Embedding involves harmful and dangerous embeds, whether they cause brute damage, stamina damage, or a mix. This is the default behavior for embeddings, for when something is "pointy"
- Sticking occurs when an item should not cause any harm while embedding (imagine throwing a sticky ball of tape at someone, rather than a shuriken). An item is considered "sticky"
- when it has 0 random pain chance and 0 jostling chance. It's a bit arbitrary, but fairly straightforward. See /obj/item/is_embed_harmless()
+ when it has 0 random pain chance and 0 jostling chance. It's a bit arbitrary, but fairly straightforward.
Stickables differ from embeds in the following ways:
-- Text descriptors use phrasing like "X is stuck to Y" rather than "X is embedded in Y"
@@ -39,6 +39,7 @@
var/fall_chance
var/pain_chance
var/pain_mult
+ var/impact_pain_mult
var/remove_pain_mult
var/rip_time
var/ignore_throwspeed_threshold
@@ -50,8 +51,7 @@
var/mutable_appearance/overlay
// figure out if im gonna drop args
-/datum/component/embedded/Initialize(datum/parent,
- obj/item/I,
+/datum/component/embedded/Initialize(obj/item/I,
datum/thrownthing/throwingdatum,
embed_chance = EMBED_CHANCE,
fall_chance = EMBEDDED_ITEM_FALLOUT,
@@ -67,10 +67,9 @@
jostle_pain_mult = EMBEDDED_JOSTLE_PAIN_MULTIPLIER,
pain_stam_pct = EMBEDDED_PAIN_STAM_PCT)
-
. = ..()
- if((!ishuman(parent) && !isturf(parent)) || !isitem(weapon))
+ if((!ishuman(parent) && !isclosedturf(parent)) || !isitem(I))
return COMPONENT_INCOMPATIBLE
src.embed_chance = embed_chance
@@ -94,7 +93,6 @@
else if(isturf(parent))
initTurf(throwingdatum)
-
/datum/component/embedded/RegisterWithParent()
if(ishuman(parent))
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/jostleCheck)
@@ -115,7 +113,6 @@
UnregisterSignal(parent, COMSIG_TOPIC)
UnregisterSignal(parent, COMSIG_PARENT_QDELETING)
-
/datum/component/embedded/process()
if(ishuman(parent))
processHuman()
@@ -124,12 +121,21 @@
return ..()
+/datum/component/embedded/Destroy()
+ if(overlay)
+ var/atom/A = parent
+ A.cut_overlay(overlay, TRUE)
+ qdel(overlay)
+
+ return ..()
+
////////////////////////////////////////
/////////////HUMAN PROCS////////////////
////////////////////////////////////////
/// Harmful embeds have some extra behavior over harmless sticks, like creating blood, playing a slice, and dealing damage.
/datum/component/embedded/proc/initHuman()
+ START_PROCESSING(SSdcs, src)
var/mob/living/carbon/human/victim = parent
L = pick(victim.bodyparts)
L.embedded_objects |= weapon // on the inside... on the inside...
@@ -140,8 +146,8 @@
victim.throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
playsound(victim,'sound/weapons/bladeslice.ogg', 40)
weapon.add_mob_blood(victim)//it embedded itself in you, of course it's bloody!
- //var/damage = weapon.w_class * impact_pain_mult
- //L.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage)
+ var/damage = weapon.w_class * impact_pain_mult
+ L.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage)
SEND_SIGNAL(victim, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded)
else
victim.visible_message("[weapon] sticks itself to [victim]'s [L.name]!","[weapon] sticks itself to your [L.name]!")
@@ -197,6 +203,7 @@
/// This proc handles the final step and actual removal of an embedded/stuck item from a human, whether or not it was actually removed safely.
+/// Pass TRUE for to_hands if we want it to go to the victim's hands when they pull it out
/datum/component/embedded/proc/safeRemoveHuman(to_hands)
var/mob/living/carbon/human/victim = parent
L.embedded_objects -= weapon
@@ -247,30 +254,30 @@
weapon.invisibility = INVISIBILITY_ABSTRACT
RegisterSignal(weapon, COMSIG_MOVABLE_MOVED, .proc/itemMoved)
- var/pixelX = rand(-6, 6)
- var/pixelY = rand(-6, 6)
+ // bias these upwards since in-hands are usually on the lower end of the sprite
+ var/pixelX = rand(-1, 3)
+ var/pixelY = rand(-1, 3)
// can probably do this with a ? :
switch(throwingdatum.init_dir)
if(NORTH)
- pixelY -= 4
+ pixelY -= 2
if(SOUTH)
- pixelY += 4
+ pixelY += 2
if(WEST)
- pixelX -= 4
+ pixelX -= 2
if(EAST)
- pixelX += 4
+ pixelX += 2
if(throwingdatum.init_dir in list(NORTH, WEST, NORTHWEST, SOUTHWEST))
- overlay = mutable_appearance(icon=weapon.lefthand_file,icon_state=weapon.item_state)
- else
overlay = mutable_appearance(icon=weapon.righthand_file,icon_state=weapon.item_state)
+ else
+ overlay = mutable_appearance(icon=weapon.lefthand_file,icon_state=weapon.item_state)
- hit.add_overlay(overlay)
var/matrix/M = matrix()
M.Translate(pixelX, pixelY)
- M.Scale(2.5)
overlay.transform = M
+ hit.add_overlay(overlay, TRUE)
if(harmful)
hit.visible_message("[weapon] embeds itself in [hit]!")
@@ -294,7 +301,7 @@
/// Someone is ripping out the item from the turf by hand
/datum/component/embedded/proc/ripOutTurf(datum/source, user, href_list)
var/mob/living/us = user
- if(locate(href_list["embedded_object"]) == weapon)
+ if(in_range(us, parent) && locate(href_list["embedded_object"]) == weapon)
us.visible_message("[us] begins unwedging [weapon] from [parent].", "You begin unwedging [weapon] from [parent]...")
if(do_after(us, 30, target = parent))
us.put_in_hands(weapon)
diff --git a/code/datums/elements/embed.dm b/code/datums/elements/embed.dm
index ad731dedb6d..021cd65baef 100644
--- a/code/datums/elements/embed.dm
+++ b/code/datums/elements/embed.dm
@@ -21,43 +21,16 @@
var/pain_chance
var/pain_mult
var/remove_pain_mult
- //src.impact_pain_mult
- //src.rip_pain_mult
+ var/impact_pain_mult
var/rip_time
var/ignore_throwspeed_threshold
var/jostle_chance
var/jostle_pain_mult
var/pain_stam_pct
-/datum/element/embed/Attach(datum/target,
- embed_chance = EMBED_CHANCE,
- fall_chance = EMBEDDED_ITEM_FALLOUT,
- pain_chance = EMBEDDED_PAIN_CHANCE,
- pain_mult = EMBEDDED_PAIN_MULTIPLIER,
- remove_pain_mult = EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER,
- //also fall pain
- //impact_pain_mult = EMBEDDED_IMPACT_PAIN_MULTIPLIER,
- //rip_pain_mult = EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER,
- rip_time = EMBEDDED_UNSAFE_REMOVAL_TIME,
- ignore_throwspeed_threshold = FALSE,
- jostle_chance = EMBEDDED_JOSTLE_CHANCE,
- jostle_pain_mult = EMBEDDED_JOSTLE_PAIN_MULTIPLIER,
- pain_stam_pct = EMBEDDED_PAIN_STAM_PCT)
-
- src.embed_chance = embed_chance
- src.fall_chance = fall_chance
- src.pain_chance = pain_chance
- src.pain_mult = pain_mult
- src.remove_pain_mult = remove_pain_mult
- //src.impact_pain_mult = impact_pain_mult
- //src.rip_pain_mult = rip_pain_mult
- src.rip_time = rip_time
- src.ignore_throwspeed_threshold = ignore_throwspeed_threshold
- src.jostle_chance = jostle_chance
- src.jostle_pain_mult = jostle_pain_mult
- src.pain_stam_pct = pain_stam_pct
-
+/datum/element/embed/Attach(datum/target, list/embedArgs)
. = ..()
+ parseArgs(arglist(embedArgs))
if(!isitem(target))
return ELEMENT_INCOMPATIBLE
@@ -78,19 +51,18 @@
if(((throwingdatum ? throwingdatum.speed : weapon.throw_speed) >= EMBED_THROWSPEED_THRESHOLD) || ignore_throwspeed_threshold)
if(prob(embed_chance) && !HAS_TRAIT(victim, TRAIT_PIERCEIMMUNE))
- victim.AddComponent(/datum/component/embedded,
- weapon,
- throwingdatum,
- embed_chance = embed_chance,
- fall_chance = fall_chance,
- pain_chance = pain_chance,
- pain_mult = pain_mult,
- remove_pain_mult = remove_pain_mult,
- //rip_pain_mult = rip_pain_mult,
- rip_time = rip_time,
- ignore_throwspeed_threshold = ignore_throwspeed_threshold,
- jostle_chance = jostle_chance,
- jostle_pain_mult = jostle_pain_mult,
+ victim.AddComponent(/datum/component/embedded,\
+ weapon,\
+ throwingdatum,\
+ embed_chance = embed_chance,\
+ fall_chance = fall_chance,\
+ pain_chance = pain_chance,\
+ pain_mult = pain_mult,\
+ remove_pain_mult = remove_pain_mult,\
+ rip_time = rip_time,\
+ ignore_throwspeed_threshold = ignore_throwspeed_threshold,\
+ jostle_chance = jostle_chance,\
+ jostle_pain_mult = jostle_pain_mult,\
pain_stam_pct = pain_stam_pct)
@@ -101,17 +73,41 @@
if(((throwingdatum ? throwingdatum.speed : weapon.throw_speed) >= EMBED_THROWSPEED_THRESHOLD) || ignore_throwspeed_threshold)
if(prob(embed_chance))
- hit.AddComponent(/datum/component/embedded,
- weapon,
- throwingdatum,
- embed_chance = embed_chance,
- fall_chance = fall_chance,
- pain_chance = pain_chance,
- pain_mult = pain_mult,
- remove_pain_mult = remove_pain_mult,
- //rip_pain_mult = rip_pain_mult,
- rip_time = rip_time,
- ignore_throwspeed_threshold = ignore_throwspeed_threshold,
- jostle_chance = jostle_chance,
- jostle_pain_mult = jostle_pain_mult,
+ hit.AddComponent(/datum/component/embedded,\
+ weapon,\
+ throwingdatum,\
+ embed_chance = embed_chance,\
+ fall_chance = fall_chance,\
+ pain_chance = pain_chance,\
+ pain_mult = pain_mult,\
+ remove_pain_mult = remove_pain_mult,\
+ rip_time = rip_time,\
+ ignore_throwspeed_threshold = ignore_throwspeed_threshold,\
+ jostle_chance = jostle_chance,\
+ jostle_pain_mult = jostle_pain_mult,\
pain_stam_pct = pain_stam_pct)
+
+/datum/element/embed/proc/parseArgs(embed_chance = EMBED_CHANCE,
+ fall_chance = EMBEDDED_ITEM_FALLOUT,
+ pain_chance = EMBEDDED_PAIN_CHANCE,
+ pain_mult = EMBEDDED_PAIN_MULTIPLIER,
+ remove_pain_mult = EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER,
+ rip_time = EMBEDDED_UNSAFE_REMOVAL_TIME,
+ impact_pain_mult = EMBEDDED_IMPACT_PAIN_MULTIPLIER,
+ ignore_throwspeed_threshold = FALSE,
+ jostle_chance = EMBEDDED_JOSTLE_CHANCE,
+ jostle_pain_mult = EMBEDDED_JOSTLE_PAIN_MULTIPLIER,
+ pain_stam_pct = EMBEDDED_PAIN_STAM_PCT)
+
+ src.embed_chance = embed_chance
+ src.fall_chance = fall_chance
+ src.pain_chance = pain_chance
+ src.pain_mult = pain_mult
+ src.remove_pain_mult = remove_pain_mult
+ src.impact_pain_mult = impact_pain_mult
+ //src.rip_pain_mult = rip_pain_mult
+ src.rip_time = rip_time
+ src.ignore_throwspeed_threshold = ignore_throwspeed_threshold
+ src.jostle_chance = jostle_chance
+ src.jostle_pain_mult = jostle_pain_mult
+ src.pain_stam_pct = pain_stam_pct
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 268a07c952f..bb0c2884d61 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -88,7 +88,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
mouse_drag_pointer = MOUSE_ACTIVE_POINTER //the icon to indicate this object is being dragged
- var/datum/embedding_behavior/embedding
+ var/list/embedding = NONE
var/flags_cover = 0 //for flags such as GLASSESCOVERSEYES
var/heat = 0
@@ -153,23 +153,16 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
hitsound = "swing_hit"
if(embedding)
- var/list/temp = embedding
- temp.Insert(0, /datum/element/embed) // i dunno about this
- AddElement(arglist(temp))
+ AddElement(/datum/element/embed, embedding)
else if(GLOB.embedpocalypse)
embedding = EMBED_POINTY
- var/list/temp = embedding
- temp.Insert(0, /datum/element/embed)
- AddElement(arglist(temp))
+ AddElement(/datum/element/embed, embedding)
name = "pointy [name]"
else if(GLOB.stickpocalypse)
embedding = EMBED_HARMLESS
- var/list/temp = embedding
- temp.Insert(0, /datum/element/embed)
- AddElement(arglist(temp))
+ AddElement(/datum/element/embed, embedding)
name = "sticky [name]"
-
if(sharpness) //give sharp objects butchering functionality, for consistency
AddComponent(/datum/component/butchering, 80 * toolspeed)
@@ -885,5 +878,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
return owner.dropItemToGround(src)
/obj/item/proc/is_embed_harmless()
- if(embedding)
- return (embedding.pain_mult == 0 && embedding.jostle_pain_mult == 0)
+ return
+ //if(embedding)
+ //return (!embedding.pain_mult && !embedding.jostle_pain_mult)
diff --git a/code/game/objects/items/stacks/tape.dm b/code/game/objects/items/stacks/tape.dm
index 5c23c42c30b..9674e477b5c 100644
--- a/code/game/objects/items/stacks/tape.dm
+++ b/code/game/objects/items/stacks/tape.dm
@@ -13,19 +13,21 @@
resistance_flags = FLAMMABLE
grind_results = list(/datum/reagent/cellulose = 5)
- var/datum/embedding_behavior/conferred_embed = EMBED_HARMLESS
+ var/list/conferred_embed = EMBED_HARMLESS
var/overwrite_existing = FALSE
/obj/item/stack/sticky_tape/afterattack(obj/item/I, mob/living/user)
- if(I.embedding && I.embedding == getEmbeddingBehavior(arglist(conferred_embed)))
+ if(I.embedding && I.embedding == conferred_embed)
to_chat(user, "[I] is already coated in [src]!")
return
user.visible_message("[user] begins wrapping [I] with [src].", "You begin wrapping [I] with [src].")
if(do_after(user, 30, target=I))
- I.embedding = getEmbeddingBehavior(arglist(conferred_embed))
- I.AddElement(/datum/element/embed)
+ I.embedding = conferred_embed
+ var/list/temp = I.embedding
+ temp.Insert(0, /datum/element/embed)
+ I._AddElement(temp)
to_chat(user, "You finish wrapping [I] with [src].")
use(1)
I.name = "[prefix] [I.name]"
diff --git a/code/modules/events/wizard/embeddies.dm b/code/modules/events/wizard/embeddies.dm
index 3571e457847..087bf68627a 100644
--- a/code/modules/events/wizard/embeddies.dm
+++ b/code/modules/events/wizard/embeddies.dm
@@ -14,9 +14,7 @@
if(!I.embedding || I.embedding == EMBED_HARMLESS)
I.embedding = EMBED_POINTY
- var/list/temp = I.embedding
- temp.Insert(0, /datum/element/embed)
- I.AddElement(arglist(temp))
+ I.AddElement(/datum/element/embed, I.embedding)
I.name = "pointy [I.name]"
GLOB.embedpocalypse = TRUE
@@ -42,9 +40,7 @@
if(!I.embedding)
I.embedding = EMBED_HARMLESS
- var/list/temp = I.embedding
- temp.Insert(0, /datum/element/embed)
- I.AddElement(arglist(temp))
+ I.AddElement(/datum/element/embed, I.embedding)
I.name = "sticky [I.name]"
GLOB.stickpocalypse = TRUE
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
index 7070a709191..fa97a2882e9 100644
--- a/code/modules/paperwork/pen.dm
+++ b/code/modules/paperwork/pen.dm
@@ -219,7 +219,7 @@
w_class = initial(w_class)
name = initial(name)
hitsound = initial(hitsound)
- embedding = embedding.setRating(embed_chance = EMBED_CHANCE)
+ //embedding = embedding.setRating(embed_chance = EMBED_CHANCE)
throwforce = initial(throwforce)
playsound(user, 'sound/weapons/saberoff.ogg', 5, TRUE)
to_chat(user, "[src] can now be concealed.")
@@ -230,7 +230,7 @@
w_class = WEIGHT_CLASS_NORMAL
name = "energy dagger"
hitsound = 'sound/weapons/blade1.ogg'
- embedding = embedding.setRating(embed_chance = 100) //rule of cool
+ //embedding = embedding.setRating(embed_chance = 100) //rule of cool
throwforce = 35
playsound(user, 'sound/weapons/saberon.ogg', 5, TRUE)
to_chat(user, "[src] is now active.")
diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm
index 149b3b15659..aa15cacddaa 100644
--- a/code/modules/vending/_vending.dm
+++ b/code/modules/vending/_vending.dm
@@ -504,9 +504,11 @@ GLOBAL_LIST_EMPTY(vending_products)
crit_rebate = 50
for(var/i = 0, i < num_shards, i++)
var/obj/item/shard/shard = new /obj/item/shard(get_turf(C))
- shard.embedding = shard.embedding.setRating(embed_chance = 100, embedded_ignore_throwspeed_threshold = TRUE, embedded_impact_pain_multiplier=1,embedded_pain_chance=5)
+ //shard.embedding = list(embed_chance = 100, ignore_throwspeed_threshold = TRUE, impact_pain_multiplier=1, pain_chance=5)
+ //shard.AddElement(/datum/element/embed, shard.embedding)
C.hitby(shard, skipcatch = TRUE, hitpush = FALSE)
- shard.embedding = shard.embedding.setRating(embed_chance = EMBED_CHANCE, embedded_ignore_throwspeed_threshold = FALSE)
+ //shard.embedding = initial(shard.embedding)
+ //shard.AddElement(/datum/element/embed, shard.embedding)
if(4) // paralyze this binch
// the new paraplegic gets like 4 lines of losing their legs so skip them
visible_message("[C]'s spinal cord is obliterated with a sickening crunch!", ignored_mobs = list(C))