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