diff --git a/code/datums/spells/alien_spells/build_resin_structure.dm b/code/datums/spells/alien_spells/build_resin_structure.dm
index b64925e0b263..60bc6bbfa121 100644
--- a/code/datums/spells/alien_spells/build_resin_structure.dm
+++ b/code/datums/spells/alien_spells/build_resin_structure.dm
@@ -58,33 +58,33 @@
desc = "The hunger..."
icon_state = "alien_acid"
-/obj/item/melee/touch_attack/alien/consume_resin/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity)
+/obj/item/melee/touch_attack/alien/consume_resin/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
if(target == user)
to_chat(user, "You stop trying to consume resin.")
- ..()
return
- if(!proximity || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ if(!proximity_flag || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
+ var/mob/living/carbon/C = user
if(istype(target, /obj/structure/alien/weeds))
qdel(target)
if(istype(target, /obj/structure/alien/weeds/node))
- user.add_plasma(50)
- user.visible_message("[user] rips and tears into [target] with their teeth!", "You viciously rip apart and consume [target]!")
+ C.add_plasma(50)
+ C.visible_message("[C] rips and tears into [target] with their teeth!", "You viciously rip apart and consume [target]!")
return
- if(!plasma_check(10, user))
- to_chat(user, "You don't have enough plasma to perform this action!")
+ if(!plasma_check(10, C))
+ to_chat(C, "You don't have enough plasma to perform this action!")
return
var/static/list/resin_objects = list(/obj/structure/alien/resin, /obj/structure/alien/egg, /obj/structure/bed/nest, /obj/structure/bed/revival_nest)
for(var/resin_type in resin_objects)
if(!istype(target, resin_type))
continue
- user.visible_message("[user] rips and tears into [target] with their teeth!")
- if(!do_after(user, 3 SECONDS, target = target))
+ C.visible_message("[C] rips and tears into [target] with their teeth!")
+ if(!do_after(C, 3 SECONDS, target = target))
return
- to_chat(user, "You viciously rip apart and consume [target]!")
- user.add_plasma(-10)
+ to_chat(C, "You viciously rip apart and consume [target]!")
+ C.add_plasma(-10)
qdel(target)
- ..()
#undef RESIN_WALL
#undef RESIN_NEST
diff --git a/code/datums/spells/alien_spells/corrosive_acid_spit.dm b/code/datums/spells/alien_spells/corrosive_acid_spit.dm
index 20593bdd3756..b74af9fe38ca 100644
--- a/code/datums/spells/alien_spells/corrosive_acid_spit.dm
+++ b/code/datums/spells/alien_spells/corrosive_acid_spit.dm
@@ -11,26 +11,26 @@
desc = "A fistfull of death."
icon_state = "alien_acid"
-/obj/item/melee/touch_attack/alien/corrosive_acid/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity)
+/obj/item/melee/touch_attack/alien/corrosive_acid/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
if(target == user)
to_chat(user, "You withdraw your readied acid.")
- ..()
return
- if(!proximity || isalien(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) // Don't want xenos ditching out of cuffs
+ if(!proximity_flag || isalien(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) // Don't want xenos ditching out of cuffs
return
- if(!plasma_check(200, user))
- to_chat(user, "You don't have enough plasma to perform this action!")
+ var/mob/living/carbon/C = user
+ if(!plasma_check(200, C))
+ to_chat(C, "You don't have enough plasma to perform this action!")
return
var/acid_damage_modifier = 100
if(isliving(target))
acid_damage_modifier = 50
if(target.acid_act(2 * acid_damage_modifier, acid_damage_modifier))
- visible_message("[user] vomits globs of vile stuff all over [target]. It begins to sizzle and melt under the bubbling mess of acid!")
- add_attack_logs(user, target, "Applied corrosive acid") // Want this logged
- user.add_plasma(-200)
+ visible_message("[C] vomits globs of vile stuff all over [target]. It begins to sizzle and melt under the bubbling mess of acid!")
+ add_attack_logs(C, target, "Applied corrosive acid") // Want this logged
+ C.add_plasma(-200)
else
- to_chat(user, "You cannot dissolve this object.")
- ..()
+ to_chat(C, "You cannot dissolve this object.")
/datum/spell/touch/alien_spell/burning_touch
name = "Blazing touch"
@@ -45,31 +45,30 @@
desc = "The air warps around your hand, somehow the heat doesn't hurt."
icon_state = "alien_acid"
-/obj/item/melee/touch_attack/alien/burning_touch/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity)
+/obj/item/melee/touch_attack/alien/burning_touch/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
if(target == user)
to_chat(user, "You cool down your boiled aid.")
- ..()
return
- if(!proximity || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ if(!proximity_flag || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
- if(!plasma_check(100, user))
- to_chat(user, "You don't have enough plasma to perform this action!")
+ var/mob/living/carbon/C = user
+ if(!plasma_check(100, C))
+ to_chat(C, "You don't have enough plasma to perform this action!")
return
if(isliving(target))
var/mob/living/guy_to_burn = target
- add_attack_logs(user, target, "Applied blazing touch") // Want this logged
+ add_attack_logs(C, target, "Applied blazing touch") // Want this logged
guy_to_burn.adjustFireLoss(60)
guy_to_burn.adjust_fire_stacks(3)
guy_to_burn.IgniteMob()
- user.visible_message("[user] touches [target] and a fireball erupts on contact!")
- user.add_plasma(-100)
- ..()
+ C.visible_message("[C] touches [target] and a fireball erupts on contact!")
+ C.add_plasma(-100)
else
var/static/list/resin_objects = list(/obj/structure/alien/resin, /obj/structure/alien/egg, /obj/structure/bed/nest, /obj/structure/bed/revival_nest)
for(var/resin_type in resin_objects)
if(!istype(target, resin_type))
continue
- user.visible_message("[user] touches [target] and burns right through it!")
- user.add_plasma(-100)
+ C.visible_message("[C] touches [target] and burns right through it!")
+ C.add_plasma(-100)
qdel(target)
- ..()
diff --git a/code/datums/spells/banana_touch.dm b/code/datums/spells/banana_touch.dm
index 052e657e807d..6f7de00bd5ae 100644
--- a/code/datums/spells/banana_touch.dm
+++ b/code/datums/spells/banana_touch.dm
@@ -24,14 +24,15 @@
/obj/item/melee/touch_attack/banana/apprentice
-/obj/item/melee/touch_attack/banana/apprentice/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity)
+/obj/item/melee/touch_attack/banana/apprentice/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
if(iswizard(target) && target != user)
to_chat(user, "Seriously?! Honk THEM, not me!")
return
- ..()
-/obj/item/melee/touch_attack/banana/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity)
- if(!proximity || target == user || !ishuman(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+/obj/item/melee/touch_attack/banana/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!proximity_flag || target == user || !ishuman(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
var/datum/effect_system/smoke_spread/s = new
@@ -41,7 +42,6 @@
to_chat(user, "HONK")
var/mob/living/carbon/human/H = target
H.bananatouched()
- ..()
/mob/living/carbon/human/proc/bananatouched()
to_chat(src, "HONK")
diff --git a/code/datums/spells/mime_malaise.dm b/code/datums/spells/mime_malaise.dm
index 8ce906e055a7..f012431d6476 100644
--- a/code/datums/spells/mime_malaise.dm
+++ b/code/datums/spells/mime_malaise.dm
@@ -19,8 +19,9 @@
icon_state = "fleshtostone"
item_state = "fleshtostone"
-/obj/item/melee/touch_attack/mime_malaise/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity)
- if(!proximity || target == user || !ishuman(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+/obj/item/melee/touch_attack/mime_malaise/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!proximity_flag || target == user || !ishuman(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
var/datum/effect_system/smoke_spread/s = new
@@ -29,7 +30,6 @@
var/mob/living/carbon/human/H = target
H.mimetouched()
- ..()
/mob/living/carbon/human/proc/mimetouched()
Weaken(14 SECONDS)
diff --git a/code/datums/spells/touch_attacks.dm b/code/datums/spells/touch_attacks.dm
index 455bbdf5b0b0..87a9e7c91edf 100644
--- a/code/datums/spells/touch_attacks.dm
+++ b/code/datums/spells/touch_attacks.dm
@@ -71,3 +71,15 @@
cooldown_min = 200 //100 deciseconds reduction per rank
action_icon_state = "statue"
+
+/datum/spell/touch/plushify
+ name = "Plushify"
+ desc = "This spell charges your hand with the power to turn your victims into marketable plushies!"
+ hand_path = /obj/item/melee/touch_attack/plushify
+
+ school = "transmutation"
+ base_cooldown = 600
+ clothes_req = TRUE
+ cooldown_min = 200 //100 deciseconds reduction per rank
+
+ action_icon_state = "plush"
diff --git a/code/game/gamemodes/wizard/godhand.dm b/code/game/gamemodes/wizard/godhand.dm
index 7481db80dc9e..9c5246972a9a 100644
--- a/code/game/gamemodes/wizard/godhand.dm
+++ b/code/game/gamemodes/wizard/godhand.dm
@@ -15,6 +15,7 @@
throwforce = 0
throw_range = 0
throw_speed = 0
+ new_attack_chain = TRUE
/obj/item/melee/touch_attack/New(spell)
attached_spell = spell
@@ -29,15 +30,15 @@
/obj/item/melee/touch_attack/customised_abstract_text(mob/living/carbon/owner)
return "[owner.p_their(TRUE)] [owner.l_hand == src ? "left hand" : "right hand"] is burning in magic fire."
-/obj/item/melee/touch_attack/attack__legacy__attackchain(mob/target, mob/living/carbon/user)
- if(!iscarbon(user)) //Look ma, no hands
- return
+/obj/item/melee/touch_attack/attack(mob/living/target, mob/living/carbon/human/user)
+ if(..() || !iscarbon(user)) //Look ma, no hands
+ return FINISH_ATTACK
if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, "You can't reach out!")
- return
- ..()
+ return FINISH_ATTACK
-/obj/item/melee/touch_attack/afterattack__legacy__attackchain(atom/target, mob/user, proximity)
+/obj/item/melee/touch_attack/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
if(catchphrase)
user.say(catchphrase)
playsound(get_turf(user), on_use_sound, 50, 1)
@@ -53,13 +54,13 @@
icon_state = "disintegrate"
item_state = "disintegrate"
-/obj/item/melee/touch_attack/disintegrate/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity)
- if(!proximity || target == user || !ismob(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //exploding after touching yourself would be bad
+/obj/item/melee/touch_attack/disintegrate/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!proximity_flag || target == user || !ismob(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //exploding after touching yourself would be bad
return
var/mob/M = target
do_sparks(4, 0, M.loc) //no idea what the 0 is
M.gib()
- ..()
/obj/item/melee/touch_attack/fleshtostone
name = "petrifying touch"
@@ -69,13 +70,29 @@
icon_state = "fleshtostone"
item_state = "fleshtostone"
-/obj/item/melee/touch_attack/fleshtostone/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity)
- if(!proximity || target == user || !isliving(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //getting hard after touching yourself would also be bad
+/obj/item/melee/touch_attack/fleshtostone/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!proximity_flag || target == user || !isliving(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //getting hard after touching yourself would also be bad
return
var/mob/living/L = target
L.Stun(4 SECONDS)
new /obj/structure/closet/statue(L.loc, L)
- ..()
+
+/obj/item/melee/touch_attack/plushify
+ name = "fabric touch"
+ desc = "The power to sew your foes into a doom cut from the fabric of fate."
+ catchphrase = "MAHR-XET 'ABL"
+ on_use_sound = 'sound/magic/smoke.ogg'
+ icon_state = "disintegrate"
+ item_state = "disintegrate"
+ color = COLOR_PURPLE
+
+/obj/item/melee/touch_attack/plushify/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!proximity_flag || target == user || !isliving(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //There are better ways to get a good nights sleep in a bed.
+ return
+ var/mob/living/L = target
+ L.plushify()
/obj/item/melee/touch_attack/fake_disintegrate
name = "toy plastic hand"
@@ -86,12 +103,12 @@
item_state = "disintegrate"
needs_permit = FALSE
-/obj/item/melee/touch_attack/fake_disintegrate/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity)
- if(!proximity || target == user || !ismob(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //not exploding after touching yourself would be bad
+/obj/item/melee/touch_attack/fake_disintegrate/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!proximity_flag || target == user || !ismob(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //not exploding after touching yourself would be bad
return
do_sparks(4, 0, target.loc)
playsound(target.loc, 'sound/goonstation/effects/gib.ogg', 50, 1)
- ..()
/obj/item/melee/touch_attack/cluwne
name = "cluwne touch"
@@ -101,8 +118,9 @@
icon_state = "cluwnecurse"
item_state = "cluwnecurse"
-/obj/item/melee/touch_attack/cluwne/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity)
- if(!proximity || target == user || !ishuman(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //clowning around after touching yourself would unsurprisingly, be bad
+/obj/item/melee/touch_attack/cluwne/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!proximity_flag || target == user || !ishuman(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //clowning around after touching yourself would unsurprisingly, be bad
return
if(iswizard(target))
@@ -119,4 +137,3 @@
H.makeCluwne()
else
H.makeAntiCluwne()
- ..()
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index 60b8ac422dd8..ab14142c562f 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -152,6 +152,11 @@
spell_type = /datum/spell/touch/flesh_to_stone
category = "Offensive"
+/datum/spellbook_entry/plushify
+ name = "Plushify"
+ spell_type = /datum/spell/touch/plushify
+ category = "Offensive"
+
/datum/spellbook_entry/mutate
name = "Mutate"
spell_type = /datum/spell/genetic/mutate
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 5dda16a4f6ce..7c5ecf95a9c4 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -33,6 +33,8 @@
var/preset_message
/// The index of the character in the message that will be drawn next.
var/preset_message_index = 0
+ /// Can this crayon be consumed or not
+ var/consumable = TRUE
/obj/item/toy/crayon/suicide_act(mob/user)
user.visible_message("[user] is jamming the [name] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide!")
@@ -42,7 +44,9 @@
..()
drawtype = pick(pick(graffiti), pick(letters), "rune[rand(1, 8)]")
-/obj/item/toy/crayon/attack_self__legacy__attackchain(mob/living/user as mob)
+/obj/item/toy/crayon/activate_self(mob/user)
+ if(..())
+ return
update_window(user)
/obj/item/toy/crayon/proc/update_window(mob/living/user as mob)
@@ -105,9 +109,12 @@
drawtype = temp
update_window(usr)
-/obj/item/toy/crayon/afterattack__legacy__attackchain(atom/target, mob/user, proximity)
- if(!proximity) return
- if(busy) return
+/obj/item/toy/crayon/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!proximity_flag)
+ return
+ if(busy)
+ return
if(is_type_in_list(target,validSurfaces))
var/temp = "rune"
if(preset_message_index > 0)
@@ -137,8 +144,10 @@
qdel(src)
busy = FALSE
-/obj/item/toy/crayon/attack__legacy__attackchain(mob/M, mob/user)
- if(M == user)
+/obj/item/toy/crayon/attack(mob/living/target, mob/living/carbon/human/user)
+ if(..() || !consumable)
+ return FINISH_ATTACK
+ if(target == user)
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(!H.check_has_mouth())
@@ -152,8 +161,6 @@
else
to_chat(user, "There is no more of [name] left!")
qdel(src)
- else
- ..()
/obj/item/toy/crayon/examine(mob/user)
. = ..()
@@ -255,9 +262,6 @@
dye_color = DYE_MIME
uses = 0
-/obj/item/toy/crayon/mime/attack_self__legacy__attackchain(mob/living/user as mob)
- update_window(user)
-
/obj/item/toy/crayon/mime/update_window(mob/living/user as mob)
dat += "
Change color"
..()
@@ -281,9 +285,6 @@
dye_color = DYE_RAINBOW
uses = 0
-/obj/item/toy/crayon/rainbow/attack_self__legacy__attackchain(mob/living/user as mob)
- update_window(user)
-
/obj/item/toy/crayon/rainbow/update_window(mob/living/user as mob)
dat += " Change color"
..()
@@ -312,15 +313,15 @@
instant = TRUE
validSurfaces = list(/turf/simulated/floor,/turf/simulated/wall)
dye_color = null // not technically a crayon, so we're not gonna have it dye stuff in the laundry machine
+ consumable = FALSE // To stop you from eating spraycans. It's TOO SILLY!
/obj/item/toy/crayon/spraycan/New()
..()
update_icon()
-/obj/item/toy/crayon/spraycan/attack__legacy__attackchain(mob/M, mob/user)
- return // To stop you from eating spraycans. It's TOO SILLY!
-
-/obj/item/toy/crayon/spraycan/attack_self__legacy__attackchain(mob/living/user)
+/obj/item/toy/crayon/spraycan/activate_self(mob/user)
+ if(..())
+ return
var/choice = tgui_input_list(user, "Do you want to...", "Spraycan Options", list("Toggle Cap","Change Drawing", "Change Color"))
switch(choice)
if("Toggle Cap")
@@ -335,9 +336,9 @@
return
update_icon()
-/obj/item/toy/crayon/spraycan/afterattack__legacy__attackchain(atom/target, mob/user as mob, proximity)
+/obj/item/toy/crayon/spraycan/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
- if(!proximity)
+ if(!proximity_flag)
return
if(capped)
to_chat(user, "You cannot spray [target] while the cap is still on!")
diff --git a/code/game/objects/items/dehy_carp.dm b/code/game/objects/items/dehy_carp.dm
index 35c1a5082d6b..8638ee8335dd 100644
--- a/code/game/objects/items/dehy_carp.dm
+++ b/code/game/objects/items/dehy_carp.dm
@@ -14,7 +14,9 @@
return ..()
// Attack self
-/obj/item/toy/plushie/carpplushie/dehy_carp/attack_self__legacy__attackchain(mob/user as mob)
+/obj/item/toy/plushie/carpplushie/dehy_carp/activate_self(mob/user)
+ if(..())
+ return
src.add_fingerprint(user) // Anyone can add their fingerprints to it with this
if(owned)
to_chat(user, "[src] stares up at you with friendly eyes.")
@@ -27,14 +29,15 @@
if(volume >= 1)
Swell()
-/obj/item/toy/plushie/carpplushie/dehy_carp/afterattack__legacy__attackchain(obj/O, mob/user,proximity)
- if(!proximity) return
- if(istype(O,/obj/structure/sink))
+/obj/item/toy/plushie/carpplushie/dehy_carp/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!proximity_flag)
+ return
+ if(istype(target,/obj/structure/sink))
to_chat(user, "You place [src] under a stream of water...")
user.drop_item()
- loc = get_turf(O)
+ loc = get_turf(target)
return Swell()
- ..()
/obj/item/toy/plushie/carpplushie/dehy_carp/proc/Swell()
desc = "It's growing!"
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 46a634c7f844..f5e82de9b870 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -24,6 +24,7 @@
throw_speed = 4
throw_range = 20
force = 0
+ new_attack_chain = TRUE
/*
@@ -40,21 +41,23 @@
..()
create_reagents(10)
-/obj/item/toy/balloon/attack__legacy__attackchain(mob/living/carbon/human/M as mob, mob/user as mob)
- return
+/obj/item/toy/balloon/pre_attack(atom/target, mob/living/user, params)
+ ..()
+ return FINISH_ATTACK
-/obj/item/toy/balloon/afterattack__legacy__attackchain(atom/A, mob/user, proximity)
- if(!proximity)
+/obj/item/toy/balloon/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!proximity_flag)
return
- if(istype(A, /obj/structure/reagent_dispensers))
- var/obj/structure/reagent_dispensers/RD = A
+ if(istype(target, /obj/structure/reagent_dispensers))
+ var/obj/structure/reagent_dispensers/RD = target
if(RD.reagents.total_volume <= 0)
to_chat(user, "[RD] is empty.")
else if(reagents.total_volume >= 10)
to_chat(user, "[src] is full.")
else
- A.reagents.trans_to(src, 10)
- to_chat(user, "You fill the balloon with the contents of [A].")
+ target.reagents.trans_to(src, 10)
+ to_chat(user, "You fill the balloon with the contents of [target].")
desc = "A translucent balloon with some form of liquid sloshing around in it."
update_icon()
@@ -66,20 +69,22 @@
update_icon()
return
-/obj/item/toy/balloon/attackby__legacy__attackchain(obj/O as obj, mob/user as mob, params)
- if(istype(O, /obj/item/reagent_containers/glass) || istype(O, /obj/item/reagent_containers/drinks/drinkingglass))
- if(O.reagents)
- if(O.reagents.total_volume < 1)
- to_chat(user, "[O] is empty.")
- else if(O.reagents.total_volume >= 1)
- if(O.reagents.has_reagent("facid", 1))
+/obj/item/toy/balloon/attack_by(obj/item/attacking, mob/user, params)
+ if(..())
+ return FINISH_ATTACK
+ if(istype(attacking, /obj/item/reagent_containers/glass) || istype(attacking, /obj/item/reagent_containers/drinks/drinkingglass))
+ if(attacking.reagents)
+ if(attacking.reagents.total_volume < 1)
+ to_chat(user, "[attacking] is empty.")
+ else if(attacking.reagents.total_volume >= 1)
+ if(attacking.reagents.has_reagent("facid", 1))
to_chat(user, "The acid chews through the balloon!")
- O.reagents.reaction(user)
+ attacking.reagents.reaction(user)
qdel(src)
else
desc = "A translucent balloon with some form of liquid sloshing around in it."
- to_chat(user, "You fill the balloon with the contents of [O].")
- O.reagents.trans_to(src, 10)
+ to_chat(user, "You fill the balloon with the contents of [attacking].")
+ attacking.reagents.trans_to(src, 10)
update_icon()
return
@@ -115,8 +120,8 @@
w_class = WEIGHT_CLASS_BULKY
var/lastused = null
-/obj/item/toy/syndicateballoon/attack_self__legacy__attackchain(mob/user)
- if(world.time - lastused < CLICK_CD_MELEE)
+/obj/item/toy/syndicateballoon/activate_self(mob/user)
+ if(..() || world.time - lastused < CLICK_CD_MELEE)
return
var/playverb = pick("bat [src]", "tug on [src]'s string", "play with [src]")
user.visible_message("[user] plays with [src].", "You [playverb].")
@@ -184,7 +189,9 @@
w_class = WEIGHT_CLASS_SMALL
attack_verb = list("attacked", "struck", "hit")
-/obj/item/toy/sword/attack_self__legacy__attackchain(mob/user)
+/obj/item/toy/sword/activate_self(mob/user)
+ if(..())
+ return
active = !active
if(active)
to_chat(user, "You extend the plastic blade with a quick flick of your wrist.")
@@ -204,24 +211,24 @@
H.update_inv_l_hand()
H.update_inv_r_hand()
add_fingerprint(user)
- return
-// Copied from /obj/item/melee/energy/sword/attackby
-/obj/item/toy/sword/attackby__legacy__attackchain(obj/item/W, mob/living/user, params)
- ..()
- if(istype(W, /obj/item/toy/sword))
- if(W == src)
+/obj/item/toy/sword/attack_by(obj/item/attacking, mob/user, params)
+ if(..())
+ return FINISH_ATTACK
+ if(istype(attacking, /obj/item/toy/sword))
+ if(attacking == src)
to_chat(user, "You try to attach the end of the plastic sword to... Itself. You're not very smart, are you?")
if(ishuman(user))
- user.adjustBrainLoss(10)
- else if((W.flags & NODROP) || (flags & NODROP))
- to_chat(user, "\the [flags & NODROP ? src : W] is stuck to your hand, you can't attach it to \the [flags & NODROP ? W : src]!")
+ var/mob/living/carbon/human/H = user
+ H.adjustBrainLoss(10)
+ else if((attacking.flags & NODROP) || (flags & NODROP))
+ to_chat(user, "\the [flags & NODROP ? src : attacking] is stuck to your hand, you can't attach it to \the [flags & NODROP ? attacking : src]!")
else
to_chat(user, "You attach the ends of the two plastic swords, making a single double-bladed toy! You're fake-cool.")
new /obj/item/dualsaber/toy(user.loc)
- user.unEquip(W)
+ user.unEquip(attacking)
user.unEquip(src)
- qdel(W)
+ qdel(attacking)
qdel(src)
/obj/item/toy/sword/chaosprank
@@ -229,9 +236,9 @@
/// Sets to TRUE once the character using it hits something and realises it's not a real energy sword
var/pranked = FALSE
-/obj/item/toy/sword/attack__legacy__attackchain(mob/target, mob/living/user)
- if(!cigarette_lighter_act(user, target))
- return ..()
+/obj/item/toy/sword/attack(mob/living/target, mob/living/carbon/human/user)
+ if(..() || cigarette_lighter_act(user, target))
+ return FINISH_ATTACK
/obj/item/toy/sword/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item)
var/obj/item/clothing/mask/cigarette/cig = ..()
@@ -283,8 +290,8 @@
target.unEquip(cig, TRUE)
return TRUE
-/obj/item/toy/sword/chaosprank/afterattack__legacy__attackchain(mob/living/target, mob/living/user, proximity)
- ..()
+/obj/item/toy/sword/chaosprank/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
if(!pranked)
to_chat(user, "Oh... It's a fake.")
name = "toy sword"
@@ -430,7 +437,9 @@
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
-/obj/item/toy/nuke/attack_self__legacy__attackchain(mob/user)
+/obj/item/toy/nuke/activate_self(mob/user)
+ if(..())
+ return
if(cooldown < world.time)
cooldown = world.time + 1800 //3 minutes
user.visible_message("[user] presses a button on [src]", "You activate [src], it plays a loud noise!", "You hear the click of a button.")
@@ -462,11 +471,12 @@
desc += " This one is [item_color]."
icon_state = "therapy[item_color]"
-/obj/item/toy/therapy/attack_self__legacy__attackchain(mob/user)
- if(cooldown < world.time - 8)
- to_chat(user, "You relieve some stress with \the [src].")
- playsound(user, 'sound/items/squeaktoy.ogg', 20, 1)
- cooldown = world.time
+/obj/item/toy/therapy/activate_self(mob/user)
+ if(..() || !(cooldown < world.time - 8))
+ return
+ to_chat(user, "You relieve some stress with \the [src].")
+ playsound(user, 'sound/items/squeaktoy.ogg', 20, TRUE)
+ cooldown = world.time
/obj/random/therapy
name = "Random Therapy Doll"
@@ -585,20 +595,33 @@
var/list/poof_sound = list('sound/weapons/thudswoosh.ogg' = 1)
var/has_stuffing = TRUE //If the plushie has stuffing in it
var/obj/item/grenade/grenade //You can remove the stuffing from a plushie and add a grenade to it for *nefarious uses*
+ var/sound/rare_hug_sound
+ var/rare_hug_word
+ /// This is a variable that stores a mob that has been cursed into a plushie inside it.
+ var/mob/living/cursed_plushie_victim
+ COOLDOWN_DECLARE(rare_hug_cooldown)
-/obj/item/toy/plushie/attack__legacy__attackchain(mob/M as mob, mob/user as mob)
+/obj/item/toy/plushie/attack(mob/living/target, mob/living/carbon/human/user)
+ if(..())
+ return FINISH_ATTACK
playsound(loc, pickweight(poof_sound), 20, 1) // Play the whoosh sound in local area
- if(iscarbon(M))
+ if(iscarbon(target))
if(prob(10))
- M.reagents.add_reagent("hugs", 10)
- return ..()
+ target.reagents.add_reagent("hugs", 10)
-/obj/item/toy/plushie/attack_self__legacy__attackchain(mob/user as mob)
+/obj/item/toy/plushie/activate_self(mob/user as mob)
+ if(..())
+ return
if(has_stuffing || grenade)
- var/cuddle_verb = pick("hugs", "cuddles", "snugs")
- user.visible_message("[user] [cuddle_verb] [src].")
- playsound(get_turf(src), poof_sound, 50, TRUE, -1)
+ if(rare_hug_sound && rare_hug_word && COOLDOWN_FINISHED(src, rare_hug_cooldown))
+ playsound(src, rare_hug_sound , 10, FALSE)
+ visible_message("[rare_hug_word]")
+ COOLDOWN_START(src, rare_hug_cooldown, 3 SECONDS)
+ else
+ var/cuddle_verb = pick("hugs", "cuddles", "snugs")
+ user.visible_message("[user] [cuddle_verb] [src].")
+ playsound(get_turf(src), pickweight(poof_sound), 50, TRUE, -1)
if(grenade && !grenade.active)
add_attack_logs(user, user, "activated a hidden grenade in [src].", ATKLOG_MOST)
playsound(loc, 'sound/weapons/armbomb.ogg', 10, TRUE, -3)
@@ -606,48 +629,67 @@
addtimer(CALLBACK(src, PROC_REF(explosive_betrayal), grenade), rand(1, 3) SECONDS)
else
to_chat(user, "You try to pet [src], but it has no stuffing. Aww...")
- return ..()
/obj/item/toy/plushie/proc/explosive_betrayal(obj/item/grenade/grenade_callback)
+ var/grenade_inside = FALSE //Any grenade, even non-explosive, will destroy the plushie.
+ if(grenade)
+ grenade_inside = TRUE
grenade_callback.prime()
+ if(grenade_inside && !QDELETED(src))
+ qdel(src)
/obj/item/toy/plushie/Destroy()
QDEL_NULL(grenade)
+ QDEL_NULL(cursed_plushie_victim)
return ..()
-/obj/item/toy/plushie/attackby__legacy__attackchain(obj/item/I, mob/living/user, params)
- if(I.sharp)
+/obj/item/toy/plushie/attack_by(obj/item/attacking, mob/user, params)
+ if(..())
+ return FINISH_ATTACK
+ if(attacking.sharp)
if(!grenade)
if(!has_stuffing)
to_chat(user, "You already murdered it!")
- return
+ return FINISH_ATTACK
user.visible_message("[user] tears out the stuffing from [src]!", "You rip a bunch of the stuffing from [src]. Murderer.")
- I.play_tool_sound(src)
+ attacking.play_tool_sound(src)
has_stuffing = FALSE
else
to_chat(user, "You remove the grenade from [src].")
grenade.forceMove(get_turf(src))
user.put_in_hands(grenade)
grenade = null
- return
- if(istype(I, /obj/item/grenade))
+ return FINISH_ATTACK
+ if(istype(attacking, /obj/item/grenade))
if(has_stuffing)
to_chat(user, "You need to remove some stuffing first!")
- return
+ return FINISH_ATTACK
if(grenade)
to_chat(user, "[src] already has a grenade!")
- return
+ return FINISH_ATTACK
if(!user.drop_item())
- to_chat(user, "[I] is stuck to you and cannot be placed into [src].")
- return
- user.visible_message("[user] slides [I] into [src].", \
- "You slide [I] into [src].")
- I.forceMove(src)
- grenade = I
+ to_chat(user, "[attacking] is stuck to you and cannot be placed into [src].")
+ return FINISH_ATTACK
+ user.visible_message("[user] slides [attacking] into [src].", \
+ "You slide [attacking] into [src].")
+ attacking.forceMove(src)
+ grenade = attacking
add_attack_logs(user, user, "placed a hidden grenade in [src].", ATKLOG_ALMOSTALL)
+ return FINISH_ATTACK
+
+/obj/item/toy/plushie/proc/un_plushify()
+ if(!cursed_plushie_victim)
return
- return ..()
+ cursed_plushie_victim.forceMove(get_turf(src))
+ cursed_plushie_victim.status_flags &= ~GODMODE
+ cursed_plushie_victim.notransform = FALSE
+
+ for(var/mob/living/simple_animal/shade/sword/generic_item/B in contents)
+ cursed_plushie_victim.key = B.key
+ break
+ cursed_plushie_victim = null
+ qdel(src)
/obj/random/plushie
name = "Random Plushie"
@@ -803,9 +845,8 @@
/obj/item/toy/plushie/greyplushie/proc/reset_hugdown()
hug_cooldown = FALSE //Resets the hug interaction cooldown.
-/obj/item/toy/plushie/greyplushie/attack_self__legacy__attackchain(mob/user)//code for talking when hugged.
- . = ..()
- if(hug_cooldown)
+/obj/item/toy/plushie/greyplushie/activate_self(mob/user)//code for talking when hugged.
+ if(..() || hug_cooldown)
return
hug_cooldown = TRUE
addtimer(CALLBACK(src, PROC_REF(reset_hugdown)), 5 SECONDS) //Hug interactions only put the plushie on a 5 second cooldown.
@@ -819,16 +860,8 @@
desc = "A stitched-together vox, fresh from the skipjack. Press its belly to hear it skree!"
icon_state = "plushie_vox"
item_state = "plushie_vox"
- var/cooldown = 0
-
-/obj/item/toy/plushie/voxplushie/attack_self__legacy__attackchain(mob/user)
- if(!cooldown)
- playsound(user, 'sound/voice/shriek1.ogg', 10, 0)
- visible_message("Skreee!")
- cooldown = 1
- spawn(30) cooldown = 0
- return
- ..()
+ rare_hug_sound = 'sound/voice/shriek1.ogg'
+ rare_hug_word = "Skreee!"
/obj/item/toy/plushie/ipcplushie
name = "IPC plushie"
@@ -836,14 +869,15 @@
icon_state = "plushie_ipc"
item_state = "plushie_ipc"
-/obj/item/toy/plushie/ipcplushie/attackby__legacy__attackchain(obj/item/B, mob/user, params)
- if(istype(B, /obj/item/food/breadslice))
+/obj/item/toy/plushie/ipcplushie/attack_by(obj/item/attacking, mob/user, params)
+ if(..())
+ return FINISH_ATTACK
+ if(istype(attacking, /obj/item/food/breadslice))
new /obj/item/food/toast(get_turf(loc))
to_chat(user, "You insert bread into the toaster.")
playsound(loc, 'sound/machines/ding.ogg', 50, 1)
- qdel(B)
- else
- return ..()
+ qdel(attacking)
+ return FINISH_ATTACK
//New generation TG plushies
@@ -876,23 +910,15 @@
desc = "A silky nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian"
item_state = "plushie_nian"
- var/cooldown = FALSE
-
-/obj/item/toy/plushie/nianplushie/attack_self__legacy__attackchain(mob/user)
- if(cooldown)
- return ..()
+ rare_hug_sound = 'sound/voice/scream_moth.ogg'
+ rare_hug_word = "Buzzzz!"
- playsound(src, 'sound/voice/scream_moth.ogg', 10, 0)
- visible_message("Buzzzz!")
- cooldown = TRUE
- addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 3 SECONDS)
-
/obj/item/toy/plushie/nianplushie/monarch
name = "monarch nian plushie"
desc = "A monarch nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_monarch"
item_state = "plushie_nian_monarch"
-
+
/obj/item/toy/plushie/nianplushie/luna
name = "luna nian plushie"
desc = "A luna nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
@@ -904,31 +930,31 @@
desc = "An atlas nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_atlas"
item_state = "plushie_nian_atlas"
-
+
/obj/item/toy/plushie/nianplushie/reddish
name = "reddish nian plushie"
desc = "A reddish nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_reddish"
item_state = "plushie_nian_reddish"
-
+
/obj/item/toy/plushie/nianplushie/royal
name = "royal nian plushie"
desc = "A royal nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_royal"
item_state = "plushie_nian_royal"
-
+
/obj/item/toy/plushie/nianplushie/gothic
name = "gothic nian plushie"
desc = "A gothic nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_gothic"
item_state = "plushie_nian_gothic"
-
+
/obj/item/toy/plushie/nianplushie/lovers
name = "lovers nian plushie"
desc = "A lovers nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_lovers"
item_state = "plushie_nian_lovers"
-
+
/obj/item/toy/plushie/nianplushie/whitefly
name = "whitefly nian plushie"
desc = "A whitefly nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
@@ -940,7 +966,7 @@
desc = "A punnished nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_punished"
item_state = "plushie_nian_punished"
-
+
/obj/item/toy/plushie/nianplushie/firewatch
name = "firewatch nian plushie"
desc = "A firewtach nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
@@ -952,43 +978,43 @@
desc = "A deathshead nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_deadhead"
item_state = "plushie_nian_deadhead"
-
+
/obj/item/toy/plushie/nianplushie/poison
name = "poison nian plushie"
desc = "A poison nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_poison"
item_state = "plushie_nian_poison"
-
+
/obj/item/toy/plushie/nianplushie/ragged
name = "ragged nian plushie"
desc = "A ragged nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_ragged"
item_state = "plushie_nian_ragged"
-
+
/obj/item/toy/plushie/nianplushie/snow
name = "snow nian plushie"
desc = "A snow nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_snow"
item_state = "plushie_nian_snow"
-
+
/obj/item/toy/plushie/nianplushie/clockwork
name = "clockwork nian plushie"
desc = "A clockwork nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_clockwork"
item_state = "plushie_nian_clockwork"
-
+
/obj/item/toy/plushie/nianplushie/moonfly
name = "moonfly nian plushie"
desc = "A moonfly nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_moonfly"
item_state = "plushie_nian_moonfly"
-
+
/obj/item/toy/plushie/nianplushie/rainbow
name = "rainbow nian plushie"
desc = "A rainbow nian plushie, straight from the nebula. Pull its antenna to hear it buzz!"
icon_state = "plushie_nian_rainbow"
item_state = "plushie_nian_rainbow"
-
+
/obj/item/toy/plushie/shark
name = "shark plushie"
desc = "A plushie depicting a somewhat cartoonish shark. The tag calls it a 'hákarl', noting that it was made by an obscure furniture manufacturer in old Scandinavia."
@@ -1013,6 +1039,215 @@
'sound/weapons/cablecuff.ogg' = 1,
)
+/obj/item/toy/plushie/skrellplushie
+ name = "skrell plushie"
+ desc = "The latest from 'SoftSkrells.net', features its very own headpocket! Warble!"
+ icon_state = "plushie_skrell"
+ rare_hug_sound = 'sound/effects/warble.ogg'
+ rare_hug_word = "Warble!"
+ var/obj/item/headpocket_item
+
+/obj/item/toy/plushie/skrellplushie/examine(mob/user)
+ . = ..()
+ . += "Alt-click to put something small inside the headpocket, or take an item out."
+
+/obj/item/toy/plushie/skrellplushie/AltClick(mob/user)
+ if(!Adjacent(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return
+ var/obj/item/I = user.get_active_hand()
+ if(I == src)
+ return
+ if(!I)
+ if(!headpocket_item)
+ return
+ to_chat(user, "You remove [headpocket_item] from [src].")
+ headpocket_item.forceMove(get_turf(src))
+ user.put_in_hands(headpocket_item)
+ headpocket_item = null
+ return
+ if(I.w_class > WEIGHT_CLASS_SMALL)
+ to_chat(user, "You cannot fit [I] in [src]!")
+ return
+ if(!iscarbon(user))
+ return
+ if(headpocket_item)
+ to_chat(user, "[src] already has an item in its headpocket!")
+ return
+ if(!user.drop_item())
+ to_chat(user, "You cannot slip [I] inside [src]!")
+ return
+ user.visible_message("[user] places [I] into [src].", "You place [I] into [src].")
+ add_fingerprint(user)
+ I.forceMove(src)
+ headpocket_item = I
+
+/obj/item/toy/plushie/skrellplushie/Destroy()
+ headpocket_item.forceMove(get_turf(src))
+ headpocket_item = null
+ return ..()
+
+/obj/item/toy/plushie/humanplushie
+ name = "human plushie"
+ desc = "This plushie is slightly less popular than its counterparts. The designers obviously didn't find humans that endearing..."
+ icon_state = "plushie_human"
+ poof_sound = list('sound/weapons/thudswoosh.ogg' = 30,
+ 'sound/goonstation/voice/male_scream.ogg' = 1)
+
+/obj/item/toy/plushie/borgplushie
+ name = "borg plushie"
+ desc = "The synthetic backbone of the station, rendered in plush form. Inbuilt flashlight included!"
+ icon_state = "plushie_borg"
+ var/borg_plushie_overlay
+ var/on = FALSE
+
+/obj/item/toy/plushie/borgplushie/Initialize(mapload)
+ . = ..()
+ borg_plushie_overlay = (pick("plushie_borgjan", "plushie_borgsec", "plushie_borgmed", "plushie_borgmine", "plushie_borgserv", "plushie_borgassist", "plushie_borgengi"))
+ update_icon()
+
+/obj/item/toy/plushie/borgplushie/activate_self(mob/user)
+ if(..())
+ return
+ on = !on
+ update_brightness()
+
+/obj/item/toy/plushie/borgplushie/proc/update_brightness()
+ if(on)
+ set_light(4)
+ else
+ set_light(0)
+ update_icon()
+
+/obj/item/toy/plushie/borgplushie/update_overlays()
+ . = ..()
+ add_overlay(borg_plushie_overlay)
+ if(on)
+ add_overlay("borglights")
+ else
+ cut_overlay("borglights")
+
+/obj/item/toy/plushie/borgplushie/extinguish_light(force = FALSE)
+ if(!force)
+ if(on)
+ visible_message("[src]'s light grows dim...")
+ on = !on
+ update_brightness()
+ else
+ atom_say("Self-destruct command received!")
+ visible_message("[src] explodes!")
+ var/turf/T = get_turf(src)
+ playsound(T, 'sound/goonstation/effects/robogib.ogg', 50, TRUE)
+ robogibs(T)
+ if(grenade)
+ explosive_betrayal(grenade)
+ if(!QDELETED(src))
+ qdel(src)
+
+/obj/item/toy/plushie/dionaplushie
+ name = "diona plushie"
+ desc = "This plushy is seemingly comprised of other, smaller, nymph plushies. They really went all out on the realism! Keep away from plantkiller."
+ icon_state = "plushie_diona"
+ rare_hug_sound = 'sound/voice/dionatalk1.ogg'
+ rare_hug_word = "Creak..."
+
+/obj/item/toy/plushie/nymphplushie
+ name = "nymph plushie"
+ desc = "Life-sized plushie of a diona nymph, perhaps if you find another you could make a diona!"
+ icon_state = "plushie_nymph"
+ rare_hug_sound = 'sound/creatures/nymphchirp.ogg'
+ rare_hug_word = "Chirp!"
+
+/obj/item/toy/plushie/nymphplushie/attack_by(obj/item/attacking, mob/user, params)
+ if(..())
+ return FINISH_ATTACK
+ if(istype(attacking, /obj/item/toy/plushie/nymphplushie))
+ var/obj/item/toy/plushie/nymphplushie/NP = attacking
+ var/found_grenade = FALSE
+ if(grenade)
+ found_grenade = TRUE
+ explosive_betrayal(grenade)
+ if(NP.grenade)
+ found_grenade = TRUE
+ NP.explosive_betrayal(NP.grenade)
+ if(found_grenade)
+ return FINISH_ATTACK
+ new /obj/item/toy/plushie/dionaplushie(get_turf(loc))
+ to_chat(user, "The nymph plushies combine seamlessly into an diona plushie!")
+ playsound(loc, 'sound/voice/dionatalk1.ogg', 50, TRUE)
+ qdel(NP)
+ qdel(src)
+ return FINISH_ATTACK
+
+/obj/item/toy/plushie/plasmamanplushie
+ name = "plasmaman plushie"
+ desc = "A freindly plasma-being in plush form. WARNING: KEEP AWAY FROM OPEN FLAME!"
+ icon_state = "plushie_plasma"
+ rare_hug_sound = 'sound/voice/plas_rattle.ogg'
+ rare_hug_word = "Rattle!"
+
+/obj/item/toy/plushie/plasmamanplushie/welder_act(mob/user, obj/item/I)
+ if(I.use_tool(src, user, volume = I.tool_volume))
+ bakoom()
+ return TRUE
+
+/obj/item/toy/plushie/plasmamanplushie/attack_by(obj/item/attacking, mob/user, params)
+ if(..())
+ return FINISH_ATTACK
+ if(attacking.get_heat())
+ bakoom()
+ return FINISH_ATTACK
+
+/obj/item/toy/plushie/plasmamanplushie/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
+ ..()
+ bakoom()
+
+/obj/item/toy/plushie/plasmamanplushie/proc/bakoom()
+ visible_message("[src] explodes!")
+ if(grenade)
+ explosive_betrayal(grenade)
+ explosion(get_turf(src), -1, 0, 1, 1, flame_range = 1)
+ if(!QDELETED(src))
+ qdel(src)
+
+/obj/item/toy/plushie/draskplushie
+ name = "drask plushie"
+ desc = "This plushie is cool as a cucumber, featuring realistic soap-munching action."
+ icon_state = "plushie_drask"
+ rare_hug_sound = 'sound/voice/drasktalk.ogg'
+ rare_hug_word = "Ruuuumble..."
+
+/obj/item/toy/plushie/draskplushie/attack_by(obj/item/attacking, mob/user, params)
+ if(..())
+ return FINISH_ATTACK
+ if(istype(attacking, /obj/item/soap))
+ if(prob(20))
+ visible_message("[src] consumes the soap...")
+ qdel(attacking)
+ return FINISH_ATTACK
+ visible_message("[src] munches the soap...")
+ playsound(loc, 'sound/items/eatfood.ogg', 50, TRUE)
+
+/obj/item/toy/plushie/kidanplushie
+ name = "kidan plushie"
+ desc = "F-ANT-asticly fun kidan plushie! Exoskeleton has never been so soft. The label says to keep it away from insecticides"
+ icon_state = "plushie_kidan"
+ var/sadbug = FALSE
+ rare_hug_sound = 'sound/effects/Kidanclack.ogg'
+ rare_hug_word = "Click clack!"
+
+/obj/item/toy/plushie/kidanplushie/activate_self(mob/user)
+ if(..())
+ return
+ if(prob(10) && sadbug)
+ visible_message("[src] begins to cheer up!")
+ icon_state = "plushie_kidan"
+ sadbug = FALSE
+
+/obj/item/toy/plushie/kidanplushie/proc/make_cry()
+ visible_message("[src] starts to cry...")
+ icon_state = "plushie_kidansad"
+ sadbug = TRUE
+
/*
* Foam Armblade
*/
@@ -1054,7 +1289,9 @@
else
. += "single_latch"
-/obj/item/toy/windup_toolbox/attack_self__legacy__attackchain(mob/user)
+/obj/item/toy/windup_toolbox/activate_self(mob/user)
+ if(..())
+ return
if(!active)
to_chat(user, "You wind up [src], it begins to rumble.")
active = TRUE
@@ -1083,10 +1320,12 @@
item_state = "flashtool"
w_class = WEIGHT_CLASS_TINY
-/obj/item/toy/flash/attack__legacy__attackchain(mob/living/M, mob/user)
+/obj/item/toy/flash/attack(mob/living/target, mob/living/carbon/human/user)
+ if(..())
+ return FINISH_ATTACK
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
flick("[initial(icon_state)]2", src)
- user.visible_message("[user] blinds [M] with the flash!")
+ user.visible_message("[user] blinds [target] with the flash!")
/*
@@ -1100,7 +1339,9 @@
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
-/obj/item/toy/redbutton/attack_self__legacy__attackchain(mob/user)
+/obj/item/toy/redbutton/activate_self(mob/user)
+ if(..())
+ return
if(cooldown >= world.time)
to_chat(user, "Nothing happens.")
return
@@ -1125,16 +1366,15 @@
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
-/obj/item/toy/ai/attack_self__legacy__attackchain(mob/user)
- if(!cooldown) //for the sanity of everyone
- var/message = generate_ion_law()
- to_chat(user, "You press the button on [src].")
- playsound(user, 'sound/machines/click.ogg', 20, 1)
- visible_message("[bicon(src)] [message]")
- cooldown = 1
- spawn(30) cooldown = 0
+/obj/item/toy/ai/activate_self(mob/user)
+ if(..() || cooldown) //for the sanity of everyone
return
- ..()
+ var/message = generate_ion_law()
+ to_chat(user, "You press the button on [src].")
+ playsound(user, 'sound/machines/click.ogg', 20, TRUE)
+ visible_message("[bicon(src)] [message]")
+ cooldown = 1
+ spawn(30) cooldown = 0
/obj/item/toy/codex_gigas
name = "Toy Codex Gigas"
@@ -1145,18 +1385,19 @@
var/list/messages = list("You must challenge the devil to a dance-off!", "The devils true name is Ian", "The devil hates salt!", "Would you like infinite power?", "Would you like infinite wisdom?", " Would you like infinite healing?")
var/cooldown = FALSE
-/obj/item/toy/codex_gigas/attack_self__legacy__attackchain(mob/user)
- if(!cooldown)
- user.visible_message(
- "[user] presses the button on \the [src].",
- "You press the button on \the [src].",
- "You hear a soft click.")
- playsound(loc, 'sound/machines/click.ogg', 20, TRUE)
- cooldown = TRUE
- addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 60)
- for(var/message in pick(messages))
- user.loc.visible_message("[bicon(src)] [message]")
- sleep(10)
+/obj/item/toy/codex_gigas/activate_self(mob/user)
+ if(..() || cooldown)
+ return
+ user.visible_message(
+ "[user] presses the button on \the [src].",
+ "You press the button on \the [src].",
+ "You hear a soft click.")
+ playsound(loc, 'sound/machines/click.ogg', 20, TRUE)
+ cooldown = TRUE
+ addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 60)
+ for(var/message in pick(messages))
+ user.loc.visible_message("[bicon(src)] [message]")
+ sleep(10)
// DND Character minis. Use the naming convention (type)character for the icon states.
/obj/item/toy/character
@@ -1205,7 +1446,8 @@
attack_verb = list("attacked", "bashed", "smashed", "stoned")
hitsound = "swing_hit"
-/obj/item/toy/pet_rock/attack_self__legacy__attackchain(mob/user)
+/obj/item/toy/pet_rock/activate_self(mob/user)
+ . = ..()
var/cuddle_verb = pick("admires", "respects", "cherises", "appreciates")
user.visible_message("[user] [cuddle_verb] [src].")
@@ -1230,8 +1472,9 @@
var/cooldown = 0
var/obj/stored_minature = null
-/obj/item/toy/minigibber/attack_self__legacy__attackchain(mob/user)
-
+/obj/item/toy/minigibber/activate_self(mob/user)
+ if(..())
+ return
if(stored_minature)
to_chat(user, "\The [src] makes a violent grinding noise as it tears apart the miniature figure inside!")
QDEL_NULL(stored_minature)
@@ -1243,20 +1486,22 @@
playsound(user, 'sound/goonstation/effects/gib.ogg', 20, 1)
cooldown = world.time
-/obj/item/toy/minigibber/attackby__legacy__attackchain(obj/O, mob/user, params)
- if(istype(O,/obj/item/toy/character) && O.loc == user)
- to_chat(user, "You start feeding \the [O] [bicon(O)] into \the [src]'s mini-input.")
+/obj/item/toy/minigibber/attack_by(obj/item/attacking, mob/user, params)
+ if(..())
+ return FINISH_ATTACK
+ if(istype(attacking,/obj/item/toy/character) && attacking.loc == user)
+ to_chat(user, "You start feeding \the [attacking] [bicon(attacking)] into \the [src]'s mini-input.")
if(do_after(user, 10, target = src))
- if(O.loc != user)
- to_chat(user, "\The [O] is too far away to feed into \the [src]!")
+ if(attacking.loc != user)
+ to_chat(user, "\The [attacking] is too far away to feed into \the [src]!")
else
- to_chat(user, "You feed \the [O] [bicon(O)] into \the [src]!")
- user.unEquip(O)
- O.forceMove(src)
- stored_minature = O
+ to_chat(user, "You feed \the [attacking] [bicon(attacking)] into \the [src]!")
+ user.unEquip(attacking)
+ attacking.forceMove(src)
+ stored_minature = attacking
else
- to_chat(user, "You stop feeding \the [O] into \the [src]'s mini-input.")
- else ..()
+ to_chat(user, "You stop feeding \the [attacking] into \the [src]'s mini-input.")
+ return FINISH_ATTACK
/obj/item/toy/russian_revolver
name = "russian revolver"
@@ -1289,7 +1534,9 @@
..()
spin_cylinder()
-/obj/item/toy/russian_revolver/attack_self__legacy__attackchain(mob/user)
+/obj/item/toy/russian_revolver/activate_self(mob/user)
+ if(..())
+ return
if(!bullets_left)
user.visible_message("[user] loads a bullet into [src]'s cylinder before spinning it.")
spin_cylinder()
@@ -1297,11 +1544,12 @@
user.visible_message("[user] spins the cylinder on [src]!")
spin_cylinder()
-/obj/item/toy/russian_revolver/attack__legacy__attackchain(mob/M, mob/living/user)
- return
+/obj/item/toy/russian_revolver/interact_with_atom(atom/target, mob/living/user, list/modifiers)
+ return ITEM_INTERACT_SKIP_TO_AFTER_ATTACK
-/obj/item/toy/russian_revolver/afterattack__legacy__attackchain(atom/target, mob/user, flag, params)
- if(flag)
+/obj/item/toy/russian_revolver/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(proximity_flag)
if(target in user.contents)
return
if(!ismob(target))
@@ -1368,7 +1616,9 @@
to_chat(user, "You go to spin the chamber... and it goes off in your face!")
shoot_gun(user)
-/obj/item/toy/russian_revolver/trick_revolver/attack_self__legacy__attackchain(mob/user)
+/obj/item/toy/russian_revolver/trick_revolver/activate_self(mob/user)
+ if(..())
+ return
if(!bullets_left) //You can re-arm the trap...
user.visible_message("[user] loads a bullet into [src]'s cylinder before spinning it.")
spin_cylinder()
@@ -1376,17 +1626,18 @@
user.visible_message("[user] tries to empty [src], but it goes off in their face!")
shoot_gun(user)
-/obj/item/toy/russian_revolver/trick_revolver/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(is_pen(I))
+/obj/item/toy/russian_revolver/trick_revolver/attack_by(obj/item/attacking, mob/user, params)
+ if(..())
+ return FINISH_ATTACK
+ if(is_pen(attacking))
to_chat(user, "You go to write on [src].. and it goes off in your face!")
shoot_gun(user)
- if(istype(I, /obj/item/ammo_casing/a357))
+ if(istype(attacking, /obj/item/ammo_casing/a357))
to_chat(user, "You go to load a bullet into [src].. and it goes off in your face!")
shoot_gun(user)
- if(istype(I, /obj/item/ammo_box/a357))
+ if(istype(attacking, /obj/item/ammo_box/a357))
to_chat(user, "You go to speedload [src].. and it goes off in your face!")
shoot_gun(user)
- return ..()
/obj/item/toy/russian_revolver/trick_revolver/run_pointed_on_item(mob/pointer_mob, atom/target_atom)
if(target_atom != src)
@@ -1456,8 +1707,9 @@
var/cooldown = 0
var/cooldown_time = 3 SECONDS
-/obj/item/toy/figure/attack_self__legacy__attackchain(mob/user)
- ..()
+/obj/item/toy/figure/activate_self(mob/user)
+ if(..())
+ return
if(cooldown < world.time)
cooldown = world.time + cooldown_time
activate(user)
@@ -1839,14 +2091,14 @@
var/cooldown = 0
var/list/possible_answers = list("Definitely", "All signs point to yes.", "Most likely.", "Yes.", "Ask again later.", "Better not tell you now.", "Future Unclear.", "Maybe.", "Doubtful.", "No.", "Don't count on it.", "Never.")
-/obj/item/toy/eight_ball/attack_self__legacy__attackchain(mob/user as mob)
- if(!cooldown)
- var/answer = pick(possible_answers)
- user.visible_message("[user] focuses on [user.p_their()] question and [use_action]...")
- user.visible_message("[bicon(src)] [src] says \"[answer]\"")
- spawn(30)
- cooldown = 0
+/obj/item/toy/eight_ball/activate_self(mob/user as mob)
+ if(..() || cooldown)
return
+ var/answer = pick(possible_answers)
+ user.visible_message("[user] focuses on [user.p_their()] question and [use_action]...")
+ user.visible_message("[bicon(src)] [src] says \"[answer]\"")
+ spawn(30)
+ cooldown = 0
/obj/item/toy/eight_ball/conch
name = "\improper Magic Conch Shell"
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 79b00cf173c1..9c8f042264c2 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -2076,7 +2076,7 @@
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob/living")
return
- var/ptypes = list("Lightning bolt", "Fire Death", "Gib", "Dust")
+ var/ptypes = list("Lightning bolt", "Fire Death", "Gib", "Dust", "Plushify")
if(ishuman(M))
H = M
ptypes += "Brain Damage"
@@ -2121,6 +2121,9 @@
if("Dust")
M.dust()
logmsg = "dust"
+ if("Plushify")
+ M.plushify(curse_time = -1)
+ logmsg = "plushified"
// These smiting types are only valid for ishuman() mobs
if("Brain Damage")
@@ -2220,12 +2223,13 @@
addtimer(CALLBACK(H, TYPE_PROC_REF(/mob/living/carbon/human, make_nugget)), 6 SECONDS)
logmsg = "nugget"
if("Bread")
- var/mob/living/simple_animal/shade/sword/bread/breadshade = new(H.loc)
+ var/mob/living/simple_animal/shade/sword/generic_item/breadshade = new(H.loc)
var/bready = pick(/obj/item/food/customizable/cook/bread, /obj/item/food/sliceable/meatbread, /obj/item/food/sliceable/xenomeatbread, /obj/item/food/sliceable/spidermeatbread, /obj/item/food/sliceable/bananabread, /obj/item/food/sliceable/tofubread, /obj/item/food/sliceable/bread, /obj/item/food/sliceable/creamcheesebread, /obj/item/food/sliceable/banarnarbread, /obj/item/food/flatbread, /obj/item/food/baguette)
var/obj/item/bread = new bready(get_turf(H))
breadshade.forceMove(bread)
breadshade.key = H.key
- breadshade.RegisterSignal(bread, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/mob/living/simple_animal/shade/sword/bread, handle_bread_deletion))
+ breadshade.name = "Bread spirit"
+ breadshade.RegisterSignal(bread, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/mob/living/simple_animal/shade/sword/generic_item, handle_item_deletion))
qdel(H)
logmsg = "baked"
to_chat(breadshade, "Get bready for combat, you've been baked into a piece of bread! Before you break down and rye thinking that your life is over, people are after you waiting for a snack! If you'd rather not be toast, lunge away from any hungry crew else you bite the crust. At the yeast you may survive a little longer...")
diff --git a/code/modules/arcade/arcade_prize.dm b/code/modules/arcade/arcade_prize.dm
index 992f8be59870..e17d803d5ff9 100644
--- a/code/modules/arcade/arcade_prize.dm
+++ b/code/modules/arcade/arcade_prize.dm
@@ -14,8 +14,8 @@
. = ..()
icon_state = pick("prizeball_1","prizeball_2","prizeball_3")
-/obj/item/toy/prizeball/attack_self__legacy__attackchain(mob/user as mob)
- if(opening)
+/obj/item/toy/prizeball/activate_self(mob/user)
+ if(..() || opening)
return
opening = 1
playsound(loc, 'sound/items/bubblewrap.ogg', 30, TRUE)
diff --git a/code/modules/client/preference/loadout/loadout_general.dm b/code/modules/client/preference/loadout/loadout_general.dm
index 8bd4d52e9283..004b8eca3cf2 100644
--- a/code/modules/client/preference/loadout/loadout_general.dm
+++ b/code/modules/client/preference/loadout/loadout_general.dm
@@ -89,6 +89,34 @@
display_name = "Nian plushie"
path = /obj/item/toy/plushie/nianplushie
+/datum/gear/ipcplushie
+ display_name = "IPC plushie"
+ path = /obj/item/toy/plushie/ipcplushie
+
+/datum/gear/kidanplushie
+ display_name = "Kidan plushie"
+ path = /obj/item/toy/plushie/kidanplushie
+
+/datum/gear/plasmaplushie
+ display_name = "Plasmaman plushie"
+ path = /obj/item/toy/plushie/plasmamanplushie
+
+/datum/gear/skrellplushie
+ display_name = "Skrell plushie"
+ path = /obj/item/toy/plushie/skrellplushie
+
+/datum/gear/draskplushie
+ display_name = "Drask plushie"
+ path = /obj/item/toy/plushie/draskplushie
+
+/datum/gear/borgplushie
+ display_name = "Borg plushie"
+ path = /obj/item/toy/plushie/borgplushie
+
+/datum/gear/nymphplushie
+ display_name = "Diona nymph plushie"
+ path = /obj/item/toy/plushie/nymphplushie
+
/datum/gear/sharkplushie
display_name = "Shark plushie"
path = /obj/item/toy/plushie/shark
diff --git a/code/modules/holiday/christmas.dm b/code/modules/holiday/christmas.dm
index 34e6972bada4..ad1d28023318 100644
--- a/code/modules/holiday/christmas.dm
+++ b/code/modules/holiday/christmas.dm
@@ -33,7 +33,9 @@
desc = "Directions for use: Requires two people, one to pull each end."
var/cracked = 0
-/obj/item/toy/xmas_cracker/attack__legacy__attackchain(mob/target, mob/user)
+/obj/item/toy/xmas_cracker/attack(mob/living/target, mob/living/carbon/human/user)
+ if(..())
+ return FINISH_ATTACK
if(!cracked && ishuman(target) && (target.stat == CONSCIOUS) && !target.get_active_hand())
target.visible_message("[user] and [target] pop \an [src]! *pop*", "You pull \an [src] with [target]! *pop*", "You hear a *pop*.")
var/obj/item/paper/Joke = new /obj/item/paper(user.loc)
diff --git a/code/modules/mob/living/carbon/alien/alien_base.dm b/code/modules/mob/living/carbon/alien/alien_base.dm
index 92152327c4c7..557757b751e7 100644
--- a/code/modules/mob/living/carbon/alien/alien_base.dm
+++ b/code/modules/mob/living/carbon/alien/alien_base.dm
@@ -256,3 +256,6 @@ and carry the owner just to make sure*/
if(health <= HEALTH_THRESHOLD_CRIT && stat == CONSCIOUS)
KnockOut()
return ..()
+
+/mob/living/carbon/alien/plushify(plushie_override, curse_time)
+ . = ..(/obj/item/toy/plushie/face_hugger, curse_time)
diff --git a/code/modules/mob/living/carbon/human/human_mob.dm b/code/modules/mob/living/carbon/human/human_mob.dm
index 436ae3a25849..7586049bf701 100644
--- a/code/modules/mob/living/carbon/human/human_mob.dm
+++ b/code/modules/mob/living/carbon/human/human_mob.dm
@@ -2071,6 +2071,10 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
var/obj/item/organ/internal/brain/brain_organ = get_int_organ(/obj/item/organ/internal/brain)
return brain_organ.damage >= (brain_organ.max_damage * threshold_level)
+
+/mob/living/carbon/human/plushify(plushie_override, curse_time)
+ . = ..(dna.species.plushie_type, curse_time)
+
/*
* Invokes a hallucination on the mob. Hallucination must be a path or a string of a path
*/
@@ -2081,3 +2085,4 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
return
hallucination_to_make = string_path
new hallucination_to_make(get_turf(src), src)
+
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index 086d8272ac53..4925c604c402 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -196,6 +196,9 @@
var/list/autohiss_extra_map = null
var/list/autohiss_exempt = null
+ /// What plushie the species will turn into if turned into a plushie.
+ var/plushie_type = /obj/item/toy/plushie/humanplushie
+
/datum/species/New()
unarmed = new unarmed_type()
if(!sprite_sheet_name)
diff --git a/code/modules/mob/living/carbon/human/species/abductor_species.dm b/code/modules/mob/living/carbon/human/species/abductor_species.dm
index 37ccc57546a1..101204ba00a0 100644
--- a/code/modules/mob/living/carbon/human/species/abductor_species.dm
+++ b/code/modules/mob/living/carbon/human/species/abductor_species.dm
@@ -26,6 +26,7 @@
female_scream_sound = 'sound/goonstation/voice/male_scream.ogg'
female_cough_sounds = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg')
female_sneeze_sound = 'sound/effects/mob_effects/sneeze.ogg' //Abductors always scream like guys
+ plushie_type = /obj/item/toy/plushie/abductor
var/team = 1
var/scientist = FALSE // vars to not pollute spieces list with castes
diff --git a/code/modules/mob/living/carbon/human/species/diona_species.dm b/code/modules/mob/living/carbon/human/species/diona_species.dm
index 0bd8e688321f..1d0e3e2e0218 100644
--- a/code/modules/mob/living/carbon/human/species/diona_species.dm
+++ b/code/modules/mob/living/carbon/human/species/diona_species.dm
@@ -61,6 +61,8 @@
"pulls out a secret stash of herbicide and takes a hearty swig!",
"is pulling themselves apart!")
+ plushie_type = /obj/item/toy/plushie/dionaplushie
+
/datum/species/diona/can_understand(mob/other)
if(isnymph(other))
return TRUE
diff --git a/code/modules/mob/living/carbon/human/species/drask.dm b/code/modules/mob/living/carbon/human/species/drask.dm
index ab37c5ceb0a5..47831972d437 100644
--- a/code/modules/mob/living/carbon/human/species/drask.dm
+++ b/code/modules/mob/living/carbon/human/species/drask.dm
@@ -29,6 +29,8 @@
"is sucking in warm air!",
"is holding their breath!")
+ plushie_type = /obj/item/toy/plushie/draskplushie
+
species_traits = list(LIPS, NO_HAIR)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT
bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS | BALD | SHAVED
diff --git a/code/modules/mob/living/carbon/human/species/grey.dm b/code/modules/mob/living/carbon/human/species/grey.dm
index 4e178a534797..f831ce0d44f0 100644
--- a/code/modules/mob/living/carbon/human/species/grey.dm
+++ b/code/modules/mob/living/carbon/human/species/grey.dm
@@ -30,6 +30,8 @@
flesh_color = "#a598ad"
blood_color = "#A200FF"
+ plushie_type = /obj/item/toy/plushie/greyplushie
+
/datum/species/grey/handle_dna(mob/living/carbon/human/H, remove)
..()
H.dna.SetSEState(GLOB.remotetalkblock, !remove, TRUE)
diff --git a/code/modules/mob/living/carbon/human/species/kidan.dm b/code/modules/mob/living/carbon/human/species/kidan.dm
index 95a5470753bb..70eb61d77a9d 100644
--- a/code/modules/mob/living/carbon/human/species/kidan.dm
+++ b/code/modules/mob/living/carbon/human/species/kidan.dm
@@ -55,3 +55,5 @@
"s" = list("z", "zs", "zzz", "zzsz")
)
autohiss_exempt = list("Chittin")
+
+ plushie_type = /obj/item/toy/plushie/kidanplushie
diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm
index 9243510ddb41..2d5ee49e0e0b 100644
--- a/code/modules/mob/living/carbon/human/species/machine.dm
+++ b/code/modules/mob/living/carbon/human/species/machine.dm
@@ -74,6 +74,8 @@
"is frying their own circuits!",
"is blocking their ventilation port!")
+ plushie_type = /obj/item/toy/plushie/ipcplushie
+
/datum/species/machine/on_species_gain(mob/living/carbon/human/H)
..()
diff --git a/code/modules/mob/living/carbon/human/species/moth.dm b/code/modules/mob/living/carbon/human/species/moth.dm
index 690096f8e7b7..be74a62e4dff 100644
--- a/code/modules/mob/living/carbon/human/species/moth.dm
+++ b/code/modules/mob/living/carbon/human/species/moth.dm
@@ -59,6 +59,9 @@
"is ripping their wings off!",
"is holding their breath!"
)
+
+ plushie_type = /obj/item/toy/plushie/nianplushie
+
/datum/species/moth/updatespeciescolor(mob/living/carbon/human/H, owner_sensitive = 1) //Handling species-specific skin-tones for the nian race.
if(H.dna.species.bodyflags & HAS_ICON_SKIN_TONE)
var/new_icobase = 'icons/mob/human_races/nian/r_moth.dmi' //Default nian.
diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm
index 74a2e22ff0de..774181c27857 100644
--- a/code/modules/mob/living/carbon/human/species/plasmaman.dm
+++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm
@@ -51,6 +51,8 @@
"s" = list("ss", "sss", "ssss")
)
+ plushie_type = /obj/item/toy/plushie/plasmamanplushie
+
/datum/species/plasmaman/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE)
var/current_job = J.title
var/datum/outfit/plasmaman/O = new /datum/outfit/plasmaman
diff --git a/code/modules/mob/living/carbon/human/species/skrell.dm b/code/modules/mob/living/carbon/human/species/skrell.dm
index 873864b78e44..28b593effdfd 100644
--- a/code/modules/mob/living/carbon/human/species/skrell.dm
+++ b/code/modules/mob/living/carbon/human/species/skrell.dm
@@ -43,3 +43,5 @@
"is twisting their own neck!",
"makes like a fish and suffocates!",
"is strangling themselves with their own tendrils!")
+
+ plushie_type = /obj/item/toy/plushie/skrellplushie
diff --git a/code/modules/mob/living/carbon/human/species/slimepeople.dm b/code/modules/mob/living/carbon/human/species/slimepeople.dm
index bcf0f0f9b64f..536eb744765e 100644
--- a/code/modules/mob/living/carbon/human/species/slimepeople.dm
+++ b/code/modules/mob/living/carbon/human/species/slimepeople.dm
@@ -59,6 +59,8 @@
var/reagent_skin_coloring = FALSE
+ plushie_type = /obj/item/toy/plushie/slimeplushie
+
/datum/species/slime/on_species_gain(mob/living/carbon/human/H)
..()
var/datum/action/innate/regrow/grow = new()
diff --git a/code/modules/mob/living/carbon/human/species/tajaran.dm b/code/modules/mob/living/carbon/human/species/tajaran.dm
index 6a71141a991e..799503547c86 100644
--- a/code/modules/mob/living/carbon/human/species/tajaran.dm
+++ b/code/modules/mob/living/carbon/human/species/tajaran.dm
@@ -56,5 +56,7 @@
)
autohiss_exempt = list("Siik'tajr")
+ plushie_type = /obj/item/toy/plushie/grey_cat
+
/datum/species/tajaran/handle_death(gibbed, mob/living/carbon/human/H)
H.stop_tail_wagging()
diff --git a/code/modules/mob/living/carbon/human/species/unathi.dm b/code/modules/mob/living/carbon/human/species/unathi.dm
index d0102489d666..9d39401ccf25 100644
--- a/code/modules/mob/living/carbon/human/species/unathi.dm
+++ b/code/modules/mob/living/carbon/human/species/unathi.dm
@@ -62,6 +62,8 @@
)
autohiss_exempt = list("Sinta'unathi")
+ plushie_type = /obj/item/toy/plushie/lizardplushie
+
/datum/species/unathi/on_species_gain(mob/living/carbon/human/H)
..()
var/datum/action/innate/unathi_ignite/fire = new()
diff --git a/code/modules/mob/living/carbon/human/species/vox.dm b/code/modules/mob/living/carbon/human/species/vox.dm
index f3dd78b2f717..38ee100d642c 100644
--- a/code/modules/mob/living/carbon/human/species/vox.dm
+++ b/code/modules/mob/living/carbon/human/species/vox.dm
@@ -72,6 +72,8 @@
speciesbox = /obj/item/storage/box/survival_vox
+ plushie_type = /obj/item/toy/plushie/voxplushie
+
/datum/species/vox/handle_death(gibbed, mob/living/carbon/human/H)
H.stop_tail_wagging()
diff --git a/code/modules/mob/living/carbon/human/species/vulpkanin.dm b/code/modules/mob/living/carbon/human/species/vulpkanin.dm
index f98b03002e22..a6ba75e80e5e 100644
--- a/code/modules/mob/living/carbon/human/species/vulpkanin.dm
+++ b/code/modules/mob/living/carbon/human/species/vulpkanin.dm
@@ -47,5 +47,7 @@
"is twisting their own neck!",
"is holding their breath!")
+ plushie_type = /obj/item/toy/plushie/red_fox
+
/datum/species/vulpkanin/handle_death(gibbed, mob/living/carbon/human/H)
H.stop_tail_wagging()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 3fd7184bf154..267343b767b8 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1184,5 +1184,26 @@
/mob/living/proc/can_remote_apc_interface(obj/machinery/power/apc/ourapc)
return FALSE
+/mob/living/proc/plushify(plushie_override, curse_time = 10 MINUTES)
+ var/mob/living/simple_animal/shade/sword/generic_item/plushvictim = new(get_turf(src))
+ var/obj/item/toy/plushie/plush_type = pick(subtypesof(/obj/item/toy/plushie) - typesof(/obj/item/toy/plushie/fluff) - typesof(/obj/item/toy/plushie/carpplushie)) //exclude the base type.
+ if(plushie_override)
+ plush_type = plushie_override
+ var/obj/item/toy/plushie/plush_outcome = new plush_type(get_turf(src))
+ plushvictim.forceMove(plush_outcome)
+ plushvictim.key = key
+ plushvictim.RegisterSignal(plush_outcome, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/mob/living/simple_animal/shade/sword/generic_item, handle_item_deletion))
+ plushvictim.name = name
+ plush_outcome.name = "[name] plushie"
+ if(curse_time == -1)
+ qdel(src)
+ else
+ plush_outcome.cursed_plushie_victim = src
+ forceMove(plush_outcome)
+ notransform = TRUE
+ status_flags |= GODMODE
+ addtimer(CALLBACK(plush_outcome, TYPE_PROC_REF(/obj/item/toy/plushie, un_plushify)), curse_time)
+ to_chat(plushvictim, "You have been cursed into an enchanted plush doll! At least you can still move around a bit...")
+
/mob/living/proc/sec_hud_set_ID()
return
diff --git a/code/modules/mob/living/silicon/robot/robot_mob.dm b/code/modules/mob/living/silicon/robot/robot_mob.dm
index 3e1b5940227c..f04f23f86df6 100644
--- a/code/modules/mob/living/silicon/robot/robot_mob.dm
+++ b/code/modules/mob/living/silicon/robot/robot_mob.dm
@@ -1809,3 +1809,8 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if(ourapc.malfai && !(src in ourapc.malfai.connected_robots))
return FALSE
return TRUE
+
+/mob/living/silicon/robot/plushify(plushie_override, curse_time)
+ if(curse_time == -1)
+ QDEL_NULL(mmi)
+ return ..()
diff --git a/code/modules/mob/living/silicon/silicon_mob.dm b/code/modules/mob/living/silicon/silicon_mob.dm
index feb6cc0a6384..a0997ce25e3c 100644
--- a/code/modules/mob/living/silicon/silicon_mob.dm
+++ b/code/modules/mob/living/silicon/silicon_mob.dm
@@ -594,3 +594,6 @@
if(silicon_hat)
. += "They are wearing a [bicon(silicon_hat)] [silicon_hat.name]."
. += "Use an empty hand on [src] on grab mode to remove [silicon_hat]."
+
+/mob/living/silicon/plushify(plushie_override, curse_time)
+ . = ..(/obj/item/toy/plushie/borgplushie, curse_time)
diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm
index 7bc00e3cf489..260c85782487 100644
--- a/code/modules/mob/living/simple_animal/shade.dm
+++ b/code/modules/mob/living/simple_animal/shade.dm
@@ -69,13 +69,13 @@
if(istype(host_sword))
health = host_sword.obj_integrity
-/mob/living/simple_animal/shade/sword/bread
- name = "Bread spirit"
+/mob/living/simple_animal/shade/sword/generic_item
+ name = "Trapped spirit"
-/mob/living/simple_animal/shade/sword/bread/update_runechat_msg_location()
+/mob/living/simple_animal/shade/sword/generic_item/update_runechat_msg_location()
runechat_msg_location = loc.UID()
-/mob/living/simple_animal/shade/sword/bread/proc/handle_bread_deletion(source)
+/mob/living/simple_animal/shade/sword/generic_item/proc/handle_item_deletion(source)
SIGNAL_HANDLER
qdel(src)
diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm
index 272f363aef90..ace0353d07b4 100644
--- a/code/modules/reagents/chemistry/reagents/toxins.dm
+++ b/code/modules/reagents/chemistry/reagents/toxins.dm
@@ -1075,6 +1075,16 @@
else if(istype(O, /obj/structure/spacevine))
var/obj/structure/spacevine/SV = O
SV.on_chem_effect(src)
+ else if(istype(O, /obj/item/toy/plushie/dionaplushie))
+ var/turf/T = get_turf(O)
+ var/obj/item/toy/plushie/dionaplushie/DP = O
+ if(DP.grenade)
+ DP.explosive_betrayal(DP.grenade)
+ return
+ new /obj/item/toy/plushie/nymphplushie(T)
+ new /obj/item/toy/plushie/nymphplushie(T)
+ DP.visible_message("The diona plushie splits apart!")
+ qdel(DP)
/datum/reagent/glyphosate/reaction_mob(mob/living/M, method = REAGENT_TOUCH, volume)
if(isliving(M))
@@ -1118,6 +1128,9 @@
if(istype(O, /obj/effect/decal/cleanable/ants))
O.visible_message("The ants die.")
qdel(O)
+ if(istype(O, /obj/item/toy/plushie/kidanplushie))
+ var/obj/item/toy/plushie/kidanplushie/stupidbug = O
+ stupidbug.make_cry()
/datum/reagent/pestkiller/reaction_mob(mob/living/M, method = REAGENT_TOUCH, volume)
if(isliving(M))
diff --git a/icons/mob/actions/actions.dmi b/icons/mob/actions/actions.dmi
index e33b6ed74bf1..7119185eb41d 100644
Binary files a/icons/mob/actions/actions.dmi and b/icons/mob/actions/actions.dmi differ
diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi
index 61edc4f91069..19d97b69b54e 100644
Binary files a/icons/obj/toy.dmi and b/icons/obj/toy.dmi differ