mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-30 16:47:13 +01:00
still gotta figure out how to update embedding stats on the fly
This commit is contained in:
@@ -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("<span class='danger'>[weapon] sticks itself to [victim]'s [L.name]!</span>","<span class='userdanger'>[weapon] sticks itself to your [L.name]!</span>")
|
||||
@@ -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("<span class='danger'>[weapon] embeds itself in [hit]!</span>")
|
||||
@@ -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("<span class='notice'>[us] begins unwedging [weapon] from [parent].</span>", "<span class='notice'>You begin unwedging [weapon] from [parent]...</span>")
|
||||
if(do_after(us, 30, target = parent))
|
||||
us.put_in_hands(weapon)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, "<span class='warning'>[I] is already coated in [src]!</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] begins wrapping [I] with [src].</span>", "<span class='notice'>You begin wrapping [I] with [src].</span>")
|
||||
|
||||
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, "<span class='notice'>You finish wrapping [I] with [src].</span>")
|
||||
use(1)
|
||||
I.name = "[prefix] [I.name]"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, "<span class='warning'>[src] can now be concealed.</span>")
|
||||
@@ -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, "<span class='warning'>[src] is now active.</span>")
|
||||
|
||||
@@ -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("<span class='danger'>[C]'s spinal cord is obliterated with a sickening crunch!</span>", ignored_mobs = list(C))
|
||||
|
||||
Reference in New Issue
Block a user