Files
Bubberstation/code/game/objects/items/toys.dm
SkyratBot 42b17d088b [MIRROR] Suicicide -> Suicide [MDB IGNORE] (#9292)
* Suicicide -> Suicide (#62614)

This PR just fixes a small spelling error in the suicide message for the singulo toy, probably a waste of a pr but hey, I'm trying to remember how to do these and figured I'd do a quick and easy one.

* Suicicide -> Suicide

Co-authored-by: Toastgoats <63932673+Toastgoats@users.noreply.github.com>
2021-11-07 10:17:48 -05:00

1846 lines
58 KiB
Plaintext

/* Toys!
* Contains
* Balloons
* Fake singularity
* Toy gun
* Toy crossbow
* Toy swords
* Crayons
* Snap pops
* AI core prizes
* Toy codex gigas
* Skeleton toys
* Cards
* Toy nuke
* Fake meteor
* Foam armblade
* Toy big red button
* Beach ball
* Toy xeno
* Kitty toys!
* Snowballs
* Clockwork Watches
* Toy Daggers
* Squeaky Brain
* Broken Radio
* Fake heretic codex
* Fake Pierced Reality
* Intento
*/
/obj/item/toy
throwforce = 0
throw_speed = 3
throw_range = 7
force = 0
/*
* Balloons
*/
/obj/item/toy/waterballoon
name = "water balloon"
desc = "A translucent balloon. There's nothing in it."
icon = 'icons/obj/toy.dmi'
icon_state = "waterballoon-e"
inhand_icon_state = "balloon-empty"
/obj/item/toy/waterballoon/Initialize(mapload)
. = ..()
create_reagents(10)
/obj/item/toy/waterballoon/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
/obj/item/toy/waterballoon/attack(mob/living/carbon/human/M, mob/user)
return
/obj/item/toy/waterballoon/afterattack(atom/A as mob|obj, mob/user, proximity)
. = ..()
if(!proximity)
return
if (istype(A, /obj/structure/reagent_dispensers))
var/obj/structure/reagent_dispensers/RD = A
if(RD.reagents.total_volume <= 0)
to_chat(user, span_warning("[RD] is empty."))
else if(reagents.total_volume >= 10)
to_chat(user, span_warning("[src] is full."))
else
A.reagents.trans_to(src, 10, transfered_by = user)
to_chat(user, span_notice("You fill the balloon with the contents of [A]."))
desc = "A translucent balloon with some form of liquid sloshing around in it."
update_appearance()
/obj/item/toy/waterballoon/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers/glass))
if(I.reagents)
if(I.reagents.total_volume <= 0)
to_chat(user, span_warning("[I] is empty."))
else if(reagents.total_volume >= 10)
to_chat(user, span_warning("[src] is full."))
else
desc = "A translucent balloon with some form of liquid sloshing around in it."
to_chat(user, span_notice("You fill the balloon with the contents of [I]."))
I.reagents.trans_to(src, 10, transfered_by = user)
update_appearance()
else if(I.get_sharpness())
balloon_burst()
else
return ..()
/obj/item/toy/waterballoon/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..()) //was it caught by a mob?
balloon_burst(hit_atom)
/obj/item/toy/waterballoon/proc/balloon_burst(atom/AT)
if(reagents.total_volume >= 1)
var/turf/T
if(AT)
T = get_turf(AT)
else
T = get_turf(src)
T.visible_message(span_danger("[src] bursts!"),span_hear("You hear a pop and a splash."))
reagents.expose(T)
for(var/atom/A in T)
reagents.expose(A)
icon_state = "burst"
qdel(src)
/obj/item/toy/waterballoon/update_icon_state()
if(reagents.total_volume >= 1)
icon_state = "waterballoon"
inhand_icon_state = "balloon"
else
icon_state = "waterballoon-e"
inhand_icon_state = "balloon-empty"
return ..()
#define BALLOON_COLORS list("red", "blue", "green", "yellow")
/obj/item/toy/balloon
name = "balloon"
desc = "No birthday is complete without it."
icon = 'icons/obj/balloons.dmi'
icon_state = "balloon"
inhand_icon_state = "balloon"
lefthand_file = 'icons/mob/inhands/balloons_lefthand.dmi'
righthand_file = 'icons/mob/inhands/balloons_righthand.dmi'
w_class = WEIGHT_CLASS_BULKY
throwforce = 0
throw_speed = 3
throw_range = 7
force = 0
var/random_color = TRUE
/obj/item/toy/balloon/Initialize(mapload)
. = ..()
if(random_color)
var/chosen_balloon_color = pick(BALLOON_COLORS)
name = "[chosen_balloon_color] [name]"
icon_state = "[icon_state]_[chosen_balloon_color]"
inhand_icon_state = icon_state
/obj/item/toy/balloon/corgi
name = "corgi balloon"
desc = "A balloon with a corgi face on it. For the all year good boys."
icon_state = "corgi"
inhand_icon_state = "corgi"
random_color = FALSE
/obj/item/toy/balloon/syndicate
name = "syndicate balloon"
desc = "There is a tag on the back that reads \"FUK NT!11!\"."
icon_state = "syndballoon"
inhand_icon_state = "syndballoon"
random_color = FALSE
/obj/item/toy/balloon/syndicate/pickup(mob/user)
. = ..()
if(user && user.mind && user.mind.has_antag_datum(/datum/antagonist, TRUE))
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "badass_antag", /datum/mood_event/badass_antag)
/obj/item/toy/balloon/syndicate/dropped(mob/user)
if(user)
SEND_SIGNAL(user, COMSIG_CLEAR_MOOD_EVENT, "badass_antag", /datum/mood_event/badass_antag)
. = ..()
/obj/item/toy/balloon/syndicate/Destroy()
if(ismob(loc))
var/mob/M = loc
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "badass_antag", /datum/mood_event/badass_antag)
. = ..()
/obj/item/toy/balloon/arrest
name = "arreyst balloon"
desc = "A half inflated balloon about a boyband named Arreyst that was popular about ten years ago, famous for making fun of red jumpsuits as unfashionable."
icon_state = "arrestballoon"
inhand_icon_state = "arrestballoon"
random_color = FALSE
#undef BALLOON_COLORS
/*
* Fake singularity
*/
/obj/item/toy/spinningtoy
name = "gravitational singularity"
desc = "\"Singulo\" brand spinning toy."
icon = 'icons/obj/singularity.dmi'
icon_state = "singularity_s1"
item_flags = NO_PIXEL_RANDOM_DROP
/obj/item/toy/spinningtoy/suicide_act(mob/living/carbon/human/user)
var/obj/item/bodypart/head/myhead = user.get_bodypart(BODY_ZONE_HEAD)
if(!myhead)
user.visible_message(span_suicide("[user] tries consuming [src]... but [user.p_they()] [user.p_have()] no mouth!")) // and i must scream
return SHAME
user.visible_message(span_suicide("[user] consumes [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
playsound(user, 'sound/items/eatfood.ogg', 50, TRUE)
user.adjust_nutrition(50) // mmmm delicious
addtimer(CALLBACK(src, .proc/manual_suicide, user), (3SECONDS))
return MANUAL_SUICIDE
/**
* Internal function used in the toy singularity suicide
*
* Cavity implants the toy singularity into the body of the user (arg1), and kills the user.
* Makes the user vomit and receive 120 suffocation damage if there already is a cavity implant in the user.
* Throwing the singularity away will cause the user to start choking themself to death.
* Arguments:
* * user - Whoever is doing the suiciding
*/
/obj/item/toy/spinningtoy/proc/manual_suicide(mob/living/carbon/human/user)
if(!user)
return
if(!user.is_holding(src)) // Half digestion? Start choking to death
user.visible_message(span_suicide("[user] panics and starts choking [user.p_them()]self to death!"))
user.adjustOxyLoss(200)
user.death(FALSE) // unfortunately you have to handle the suiciding yourself with a manual suicide
user.ghostize(FALSE) // get the fuck out of our body
return
var/obj/item/bodypart/chest/CH = user.get_bodypart(BODY_ZONE_CHEST)
if(CH.cavity_item) // if he's (un)bright enough to have a round and full belly...
user.visible_message(span_danger("[user] regurgitates [src]!")) // I swear i dont have a fetish
user.vomit(100, TRUE, distance = 0)
user.adjustOxyLoss(120)
user.dropItemToGround(src) // incase the crit state doesn't drop the singulo to the floor
user.set_suicide(FALSE)
return
user.transferItemToLoc(src, user, TRUE)
CH.cavity_item = src // The mother came inside and found Andy, dead with a HUGE belly full of toys
user.adjustOxyLoss(200) // You know how most small toys in the EU have that 3+ onion head icon and a warning that says "Unsuitable for children under 3 years of age due to small parts - choking hazard"? This is why.
user.death(FALSE)
user.ghostize(FALSE)
/*
* Toy gun: Why isn't this an /obj/item/gun?
*/
/obj/item/toy/gun
name = "cap gun"
desc = "Looks almost like the real thing! Ages 8 and up. Please recycle in an autolathe when you're out of caps."
icon = 'icons/obj/guns/ballistic.dmi'
icon_state = "revolver"
inhand_icon_state = "gun"
worn_icon_state = "gun"
lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_NORMAL
custom_materials = list(/datum/material/iron=10, /datum/material/glass=10)
attack_verb_continuous = list("strikes", "pistol whips", "hits", "bashes")
attack_verb_simple = list("strike", "pistol whip", "hit", "bash")
var/bullets = 7
/obj/item/toy/gun/examine(mob/user)
. = ..()
. += "There [bullets == 1 ? "is" : "are"] [bullets] cap\s left."
/obj/item/toy/gun/attackby(obj/item/toy/ammo/gun/A, mob/user, params)
if(istype(A, /obj/item/toy/ammo/gun))
if (src.bullets >= 7)
to_chat(user, span_warning("It's already fully loaded!"))
return 1
if (A.amount_left <= 0)
to_chat(user, span_warning("There are no more caps!"))
return 1
if (A.amount_left < (7 - src.bullets))
src.bullets += A.amount_left
to_chat(user, span_notice("You reload [A.amount_left] cap\s."))
A.amount_left = 0
else
to_chat(user, span_notice("You reload [7 - src.bullets] cap\s."))
A.amount_left -= 7 - src.bullets
src.bullets = 7
A.update_appearance()
return 1
else
return ..()
/obj/item/toy/gun/afterattack(atom/target as mob|obj|turf|area, mob/user, flag)
. = ..()
if (flag)
return
if (!ISADVANCEDTOOLUSER(user))
to_chat(user, span_warning("You don't have the dexterity to do this!"))
return
src.add_fingerprint(user)
if (src.bullets < 1)
user.show_message(span_warning("*click*"), MSG_AUDIBLE)
playsound(src, 'sound/weapons/gun/revolver/dry_fire.ogg', 30, TRUE)
return
playsound(user, 'sound/weapons/gun/revolver/shot.ogg', 100, TRUE)
src.bullets--
user.visible_message(span_danger("[user] fires [src] at [target]!"), \
span_danger("You fire [src] at [target]!"), \
span_hear("You hear a gunshot!"))
/obj/item/toy/ammo/gun
name = "capgun ammo"
desc = "Make sure to recyle the box in an autolathe when it gets empty."
icon = 'icons/obj/guns/ammo.dmi'
icon_state = "357OLD-7"
w_class = WEIGHT_CLASS_TINY
custom_materials = list(/datum/material/iron=10, /datum/material/glass=10)
var/amount_left = 7
/obj/item/toy/ammo/gun/update_icon_state()
icon_state = "357OLD-[amount_left]"
return ..()
/obj/item/toy/ammo/gun/examine(mob/user)
. = ..()
. += "There [amount_left == 1 ? "is" : "are"] [amount_left] cap\s left."
/*
* Toy swords
*/
/obj/item/toy/sword
name = "toy sword"
desc = "A cheap, plastic replica of an energy sword. Realistic sounds! Ages 8 and up."
icon_state = "e_sword"
icon = 'icons/obj/transforming_energy.dmi'
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
attack_verb_continuous = list("attacks", "strikes", "hits")
attack_verb_simple = list("attack", "strike", "hit")
/// Whether our sword has been multitooled to rainbow
var/hacked = FALSE
/// The color of our fake energy sword
var/saber_color = "blue"
/obj/item/toy/sword/Initialize(mapload)
. = ..()
AddComponent(/datum/component/transforming, \
throw_speed_on = throw_speed, \
hitsound_on = hitsound, \
clumsy_check = FALSE)
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, .proc/on_transform)
/*
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].
*
* Updates our icon to have the correct color, and give some feedback.
*/
/obj/item/toy/sword/proc/on_transform(obj/item/source, mob/user, active)
SIGNAL_HANDLER
if(active)
icon_state = "[icon_state]_[saber_color]"
balloon_alert(user, "[active ? "flicked out":"pushed in"] [src]")
playsound(user ? user : src, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 20, TRUE)
return COMPONENT_NO_DEFAULT_MESSAGE
// Copied from /obj/item/melee/energy/sword/attackby
/obj/item/toy/sword/attackby(obj/item/weapon, mob/living/user, params)
if(istype(weapon, /obj/item/toy/sword))
var/obj/item/toy/sword/attatched_sword = weapon
if(HAS_TRAIT(weapon, TRAIT_NODROP))
to_chat(user, span_warning("[weapon] is stuck to your hand, you can't attach it to [src]!"))
return
else if(HAS_TRAIT(src, TRAIT_NODROP))
to_chat(user, span_warning("[src] is stuck to your hand, you can't attach it to [weapon]!"))
return
else
to_chat(user, span_notice("You attach the ends of the two plastic swords, making a single double-bladed toy! You're fake-cool."))
var/obj/item/dualsaber/toy/new_saber = new /obj/item/dualsaber/toy(user.loc)
if(attatched_sword.hacked || hacked)
new_saber.hacked = TRUE
new_saber.saber_color = "rainbow"
qdel(weapon)
qdel(src)
user.put_in_hands(new_saber)
else if(weapon.tool_behaviour == TOOL_MULTITOOL)
if(hacked)
to_chat(user, span_warning("It's already fabulous!"))
else
hacked = TRUE
saber_color = "rainbow"
to_chat(user, span_warning("RNBW_ENGAGE"))
else
return ..()
/*
* Foam armblade
*/
/obj/item/toy/foamblade
name = "foam armblade"
desc = "It says \"Sternside Changs #1 fan\" on it."
icon = 'icons/obj/toy.dmi'
icon_state = "foamblade"
inhand_icon_state = "arm_blade"
lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi'
righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi'
attack_verb_continuous = list("pricks", "absorbs", "gores")
attack_verb_simple = list("prick", "absorb", "gore")
w_class = WEIGHT_CLASS_SMALL
resistance_flags = FLAMMABLE
/obj/item/toy/windup_toolbox
name = "windup toolbox"
desc = "A replica toolbox that rumbles when you turn the key."
icon = 'icons/obj/storage.dmi'
icon_state = "green"
inhand_icon_state = "artistic_toolbox"
lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi'
hitsound = 'sound/weapons/smash.ogg'
drop_sound = 'sound/items/handling/toolbox_drop.ogg'
pickup_sound = 'sound/items/handling/toolbox_pickup.ogg'
attack_verb_continuous = list("robusts")
attack_verb_simple = list("robust")
var/active = FALSE
/obj/item/toy/windup_toolbox/Initialize(mapload)
. = ..()
update_appearance()
/obj/item/toy/windup_toolbox/update_overlays()
. = ..()
if(active)
. += "single_latch_open"
else
. += "single_latch"
/obj/item/toy/windup_toolbox/attack_self(mob/user)
if(!active)
to_chat(user, span_notice("You wind up [src], it begins to rumble."))
active = TRUE
update_appearance()
playsound(src, 'sound/effects/pope_entry.ogg', 100)
Rumble()
addtimer(CALLBACK(src, .proc/stopRumble), 600)
else
to_chat(user, span_warning("[src] is already active!"))
/obj/item/toy/windup_toolbox/proc/Rumble()
var/static/list/transforms
if(!transforms)
var/matrix/M1 = matrix()
var/matrix/M2 = matrix()
var/matrix/M3 = matrix()
var/matrix/M4 = matrix()
M1.Translate(-1, 0)
M2.Translate(0, 1)
M3.Translate(1, 0)
M4.Translate(0, -1)
transforms = list(M1, M2, M3, M4)
animate(src, transform=transforms[1], time=0.2, loop=-1)
animate(transform=transforms[2], time=0.1)
animate(transform=transforms[3], time=0.2)
animate(transform=transforms[4], time=0.3)
/obj/item/toy/windup_toolbox/proc/stopRumble()
active = FALSE
update_appearance()
visible_message(span_warning("[src] slowly stops rattling and falls still, its latch snapping shut.")) //subtle difference
playsound(loc, 'sound/weapons/batonextend.ogg', 100, TRUE)
animate(src, transform = matrix())
/*
* Subtype of Double-Bladed Energy Swords
*/
/obj/item/dualsaber/toy
name = "double-bladed toy sword"
desc = "A cheap, plastic replica of TWO energy swords. Double the fun!"
force = 0
throwforce = 0
throw_speed = 3
throw_range = 5
two_hand_force = 0
attack_verb_continuous = list("attacks", "strikes", "hits")
attack_verb_simple = list("attack", "strike", "hit")
/obj/item/dualsaber/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
/obj/item/dualsaber/toy/IsReflect() //Stops Toy Dualsabers from reflecting energy projectiles
return 0
/obj/item/dualsaber/toy/impale(mob/living/user)//Stops Toy Dualsabers from injuring clowns
to_chat(user, span_warning("You twirl around a bit before losing your balance and impaling yourself on [src]."))
user.adjustStaminaLoss(25)
/obj/item/toy/katana
name = "replica katana"
desc = "Woefully underpowered in D20."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "katana"
inhand_icon_state = "katana"
worn_icon_state = "katana"
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK
force = 5
throwforce = 5
w_class = WEIGHT_CLASS_NORMAL
attack_verb_continuous = list("attacks", "slashes", "stabs", "slices")
attack_verb_simple = list("attack", "slash", "stab", "slice")
hitsound = 'sound/weapons/bladeslice.ogg'
/*
* Snap pops
*/
/obj/item/toy/snappop
name = "snap pop"
desc = "Wow!"
icon = 'icons/obj/toy.dmi'
icon_state = "snappop"
w_class = WEIGHT_CLASS_TINY
var/ash_type = /obj/effect/decal/cleanable/ash
/obj/item/toy/snappop/proc/pop_burst(n=3, c=1)
var/datum/effect_system/spark_spread/s = new()
s.set_up(n, c, src)
s.start()
new ash_type(loc)
visible_message(span_warning("[src] explodes!"),
span_hear("You hear a snap!"))
playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
qdel(src)
/obj/item/toy/snappop/fire_act(exposed_temperature, exposed_volume)
pop_burst()
/obj/item/toy/snappop/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..())
pop_burst()
/obj/item/toy/snappop/Initialize(mapload)
. = ..()
var/static/list/loc_connections = list(
COMSIG_ATOM_ENTERED = .proc/on_entered,
)
AddElement(/datum/element/connect_loc, loc_connections)
/obj/item/toy/snappop/proc/on_entered(datum/source, H as mob|obj)
SIGNAL_HANDLER
if(ishuman(H) || issilicon(H)) //i guess carp and shit shouldn't set them off
var/mob/living/carbon/M = H
if(issilicon(H) || M.m_intent == MOVE_INTENT_RUN)
to_chat(M, span_danger("You step on the snap pop!"))
pop_burst(2, 0)
/obj/item/toy/snappop/phoenix
name = "phoenix snap pop"
desc = "Wow! And wow! And wow!"
ash_type = /obj/effect/decal/cleanable/ash/snappop_phoenix
/obj/effect/decal/cleanable/ash/snappop_phoenix
var/respawn_time = 300
/obj/effect/decal/cleanable/ash/snappop_phoenix/Initialize(mapload)
. = ..()
addtimer(CALLBACK(src, .proc/respawn), respawn_time)
/obj/effect/decal/cleanable/ash/snappop_phoenix/proc/respawn()
new /obj/item/toy/snappop/phoenix(get_turf(src))
qdel(src)
/obj/item/toy/talking
name = "talking action figure"
desc = "A generic action figure modeled after nothing in particular."
icon = 'icons/obj/toy.dmi'
icon_state = "owlprize"
w_class = WEIGHT_CLASS_SMALL
var/cooldown = FALSE
var/messages = list("I'm super generic!", "Mathematics class is of variable difficulty!")
var/span = "danger"
var/recharge_time = 30
var/chattering = FALSE
var/phomeme
// Talking toys are language universal, and thus all species can use them
/obj/item/toy/talking/attack_alien(mob/user, list/modifiers)
return attack_hand(user, modifiers)
/obj/item/toy/talking/attack_self(mob/user)
if(!cooldown)
activation_message(user)
playsound(loc, 'sound/machines/click.ogg', 20, TRUE)
INVOKE_ASYNC(src, .proc/do_toy_talk, user)
cooldown = TRUE
addtimer(VARSET_CALLBACK(src, cooldown, FALSE), recharge_time)
return
..()
/obj/item/toy/talking/proc/activation_message(mob/user)
user.visible_message(
span_notice("[user] pulls the string on \the [src]."),
span_notice("You pull the string on \the [src]."),
span_notice("You hear a string being pulled."))
/obj/item/toy/talking/proc/generate_messages()
return list(pick(messages))
/obj/item/toy/talking/proc/do_toy_talk(mob/user)
for(var/message in generate_messages())
toy_talk(user, message)
sleep(10)
/obj/item/toy/talking/proc/toy_talk(mob/user, message)
user.loc.visible_message("<span class='[span]'>[icon2html(src, viewers(user.loc))] [message]</span>")
if(chattering)
chatter(message, phomeme, user)
/*
* AI core prizes
*/
/obj/item/toy/talking/ai
name = "toy AI"
desc = "A little toy model AI core with real law announcing action!"
icon_state = "AI"
w_class = WEIGHT_CLASS_SMALL
/obj/item/toy/talking/ai/generate_messages()
return list(generate_ion_law())
/obj/item/toy/talking/codex_gigas
name = "Toy Codex Gigas"
desc = "A tool to help you write fictional devils!"
icon = 'icons/obj/library.dmi'
icon_state = "demonomicon"
lefthand_file = 'icons/mob/inhands/misc/books_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/books_righthand.dmi'
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?")
w_class = WEIGHT_CLASS_SMALL
recharge_time = 60
/obj/item/toy/talking/codex_gigas/activation_message(mob/user)
user.visible_message(
span_notice("[user] presses the button on \the [src]."),
span_notice("You press the button on \the [src]."),
span_notice("You hear a soft click."))
/obj/item/toy/talking/owl
name = "owl action figure"
desc = "An action figure modeled after 'The Owl', defender of justice."
icon_state = "owlprize"
messages = list("You won't get away this time, Griffin!", "Stop right there, criminal!", "Hoot! Hoot!", "I am the night!")
chattering = TRUE
phomeme = "owl"
w_class = WEIGHT_CLASS_SMALL
/obj/item/toy/talking/griffin
name = "griffin action figure"
desc = "An action figure modeled after 'The Griffin', criminal mastermind."
icon_state = "griffinprize"
messages = list("You can't stop me, Owl!", "My plan is flawless! The vault is mine!", "Caaaawwww!", "You will never catch me!")
chattering = TRUE
phomeme = "griffin"
w_class = WEIGHT_CLASS_SMALL
/*
|| A Deck of Cards for playing various games of chance ||
*/
/obj/item/toy/cards
resistance_flags = FLAMMABLE
max_integrity = 50
var/parentdeck = null
var/deckstyle = "nanotrasen"
var/card_hitsound = null
var/card_force = 0
var/card_throwforce = 0
var/card_throw_speed = 3
var/card_throw_range = 7
var/list/card_attack_verb_continuous = list("attacks")
var/list/card_attack_verb_simple = list("attack")
/obj/item/toy/cards/Initialize(mapload)
. = ..()
if(card_attack_verb_continuous)
card_attack_verb_continuous = string_list(card_attack_verb_continuous)
if(card_attack_verb_simple)
card_attack_verb_simple = string_list(card_attack_verb_simple)
/obj/item/toy/cards/suicide_act(mob/living/carbon/user)
user.visible_message(span_suicide("[user] is slitting [user.p_their()] wrists with \the [src]! It looks like [user.p_they()] [user.p_have()] a crummy hand!"))
playsound(src, 'sound/items/cardshuffle.ogg', 50, TRUE)
return BRUTELOSS
/obj/item/toy/cards/proc/apply_card_vars(obj/item/toy/cards/newobj, obj/item/toy/cards/sourceobj) // Applies variables for supporting multiple types of card deck
if(!istype(sourceobj))
return
/obj/item/toy/cards/deck
name = "deck of cards"
desc = "A deck of space-grade playing cards."
icon = 'icons/obj/toy.dmi'
deckstyle = "nanotrasen"
icon_state = "deck_nanotrasen_full"
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
var/obj/machinery/computer/holodeck/holo = null // Holodeck cards should not be infinite
var/list/cards = list()
/obj/item/toy/cards/deck/Initialize(mapload)
. = ..()
AddElement(/datum/element/drag_pickup)
populate_deck()
///Generates all the cards within the deck.
/obj/item/toy/cards/deck/proc/populate_deck()
icon_state = "deck_[deckstyle]_full"
for(var/suit in list("Hearts", "Spades", "Clubs", "Diamonds"))
cards += "Ace of [suit]"
for(var/i in 2 to 10)
cards += "[i] of [suit]"
for(var/person in list("Jack", "Queen", "King"))
cards += "[person] of [suit]"
//ATTACK HAND IGNORING PARENT RETURN VALUE
//ATTACK HAND NOT CALLING PARENT
/obj/item/toy/cards/deck/attack_hand(mob/user, list/modifiers)
draw_card(user)
/obj/item/toy/cards/deck/proc/draw_card(mob/user)
if(isliving(user))
var/mob/living/L = user
if(!(L.mobility_flags & MOBILITY_PICKUP))
return
var/choice = null
if(cards.len == 0)
to_chat(user, span_warning("There are no more cards to draw!"))
return
var/obj/item/toy/cards/singlecard/H = new/obj/item/toy/cards/singlecard(user.loc)
if(holo)
holo.spawned += H // track them leaving the holodeck
choice = cards[1]
H.cardname = choice
H.parentdeck = src
var/O = src
H.apply_card_vars(H,O)
popleft(cards)
H.pickup(user)
user.put_in_hands(H)
user.visible_message(span_notice("[user] draws a card from the deck."), span_notice("You draw a card from the deck."))
update_appearance()
return H
/obj/item/toy/cards/deck/update_icon_state()
switch(cards.len)
if(27 to INFINITY)
icon_state = "deck_[deckstyle]_full"
if(11 to 27)
icon_state = "deck_[deckstyle]_half"
if(1 to 11)
icon_state = "deck_[deckstyle]_low"
else
icon_state = "deck_[deckstyle]_empty"
return ..()
/obj/item/toy/cards/deck/attack_self(mob/user)
if(cooldown < world.time - 50)
cards = shuffle(cards)
playsound(src, 'sound/items/cardshuffle.ogg', 50, TRUE)
user.visible_message(span_notice("[user] shuffles the deck."), span_notice("You shuffle the deck."))
cooldown = world.time
/obj/item/toy/cards/deck/attackby(obj/item/I, mob/living/user, params)
if(istype(I, /obj/item/toy/cards/singlecard))
var/obj/item/toy/cards/singlecard/SC = I
if(SC.parentdeck == src)
if(!user.temporarilyRemoveItemFromInventory(SC))
to_chat(user, span_warning("The card is stuck to your hand, you can't add it to the deck!"))
return
cards += SC.cardname
user.visible_message(span_notice("[user] adds a card to the bottom of the deck."),span_notice("You add the card to the bottom of the deck."))
qdel(SC)
else
to_chat(user, span_warning("You can't mix cards from other decks!"))
update_appearance()
else if(istype(I, /obj/item/toy/cards/cardhand))
var/obj/item/toy/cards/cardhand/CH = I
if(CH.parentdeck == src)
if(!user.temporarilyRemoveItemFromInventory(CH))
to_chat(user, span_warning("The hand of cards is stuck to your hand, you can't add it to the deck!"))
return
cards += CH.currenthand
user.visible_message(span_notice("[user] puts [user.p_their()] hand of cards in the deck."), span_notice("You put the hand of cards in the deck."))
qdel(CH)
else
to_chat(user, span_warning("You can't mix cards from other decks!"))
update_appearance()
else
return ..()
/obj/item/toy/cards/cardhand
name = "hand of cards"
desc = "A number of cards not in a deck, customarily held in ones hand."
icon = 'icons/obj/toy.dmi'
icon_state = "none"
w_class = WEIGHT_CLASS_TINY
var/list/currenthand = list()
var/choice = null
/obj/item/toy/cards/cardhand/attack_self(mob/user)
var/list/handradial = list()
interact(user)
for(var/t in currenthand)
handradial[t] = image(icon = src.icon, icon_state = "sc_[t]_[deckstyle]")
if(usr.stat || !ishuman(usr))
return
var/mob/living/carbon/human/cardUser = usr
if(!(cardUser.mobility_flags & MOBILITY_USE))
return
var/O = src
var/choice = show_radial_menu(usr,src, handradial, custom_check = CALLBACK(src, .proc/check_menu, user), radius = 36, require_near = TRUE)
if(!choice)
return FALSE
var/obj/item/toy/cards/singlecard/C = new/obj/item/toy/cards/singlecard(cardUser.loc)
currenthand -= choice
handradial -= choice
C.parentdeck = parentdeck
C.cardname = choice
C.apply_card_vars(C,O)
C.pickup(cardUser)
cardUser.put_in_hands(C)
cardUser.visible_message(span_notice("[cardUser] draws a card from [cardUser.p_their()] hand."), span_notice("You take the [C.cardname] from your hand."))
interact(cardUser)
if(length(currenthand) == 1)
var/obj/item/toy/cards/singlecard/N = new/obj/item/toy/cards/singlecard(loc)
N.parentdeck = parentdeck
N.cardname = currenthand[1]
N.apply_card_vars(N,O)
qdel(src)
N.pickup(cardUser)
cardUser.put_in_hands(N)
to_chat(cardUser, span_notice("You also take [N.cardname] and hold it."))
else
update_sprite()
/obj/item/toy/cards/cardhand/attackby(obj/item/toy/cards/singlecard/C, mob/living/user, params)
if(istype(C))
if(C.parentdeck == src.parentdeck)
src.currenthand += C.cardname
user.visible_message(span_notice("[user] adds a card to [user.p_their()] hand."), span_notice("You add the [C.cardname] to your hand."))
qdel(C)
interact(user)
update_sprite(src)
else
to_chat(user, span_warning("You can't mix cards from other decks!"))
else
return ..()
/obj/item/toy/cards/cardhand/apply_card_vars(obj/item/toy/cards/newobj,obj/item/toy/cards/sourceobj)
..()
newobj.deckstyle = sourceobj.deckstyle
update_sprite()
newobj.card_hitsound = sourceobj.card_hitsound
newobj.card_force = sourceobj.card_force
newobj.card_throwforce = sourceobj.card_throwforce
newobj.card_throw_speed = sourceobj.card_throw_speed
newobj.card_throw_range = sourceobj.card_throw_range
newobj.card_attack_verb_continuous = sourceobj.card_attack_verb_continuous //null or unique list made by string_list()
newobj.card_attack_verb_simple = sourceobj.card_attack_verb_simple //null or unique list made by string_list()
newobj.resistance_flags = sourceobj.resistance_flags
/**
* check_menu: Checks if we are allowed to interact with a radial menu
*
* Arguments:
* * user The mob interacting with a menu
*/
/obj/item/toy/cards/cardhand/proc/check_menu(mob/living/user)
if(!istype(user))
return FALSE
if(user.incapacitated())
return FALSE
return TRUE
/**
* This proc updates the sprite for when you create a hand of cards
*/
/obj/item/toy/cards/cardhand/proc/update_sprite()
cut_overlays()
var/overlay_cards = currenthand.len
var/k = overlay_cards == 2 ? 1 : overlay_cards - 2
for(var/i = k; i <= overlay_cards; i++)
var/card_overlay = image(icon=src.icon,icon_state="sc_[currenthand[i]]_[deckstyle]",pixel_x=(1-i+k)*3,pixel_y=(1-i+k)*3)
add_overlay(card_overlay)
/obj/item/toy/cards/singlecard
name = "card"
desc = "A playing card used to play card games like poker."
icon = 'icons/obj/toy.dmi'
icon_state = "singlecard_down_nanotrasen"
w_class = WEIGHT_CLASS_TINY
var/cardname = null
var/flipped = 0
pixel_x = -5
/obj/item/toy/cards/singlecard/examine(mob/user)
. = ..()
if(ishuman(user))
var/mob/living/carbon/human/cardUser = user
if(cardUser.is_holding(src))
cardUser.visible_message(span_notice("[cardUser] checks [cardUser.p_their()] card."), span_notice("The card reads: [cardname]."))
else
. += span_warning("You need to have the card in your hand to check it!")
/obj/item/toy/cards/singlecard/verb/Flip()
set name = "Flip Card"
set category = "Object"
set src in range(1)
if(!ishuman(usr) || !usr.canUseTopic(src, BE_CLOSE))
return
if(!flipped)
src.flipped = 1
if (cardname)
src.icon_state = "sc_[cardname]_[deckstyle]"
src.name = src.cardname
else
src.icon_state = "sc_Ace of Spades_[deckstyle]"
src.name = "What Card"
src.pixel_x = 5
else if(flipped)
src.flipped = 0
src.icon_state = "singlecard_down_[deckstyle]"
src.name = "card"
src.pixel_x = -5
/obj/item/toy/cards/singlecard/attackby(obj/item/I, mob/living/user, params)
if(istype(I, /obj/item/toy/cards/singlecard/))
var/obj/item/toy/cards/singlecard/C = I
if(C.parentdeck == src.parentdeck)
var/obj/item/toy/cards/cardhand/H = new/obj/item/toy/cards/cardhand(user.loc)
H.currenthand += C.cardname
H.currenthand += src.cardname
H.parentdeck = C.parentdeck
H.apply_card_vars(H,C)
to_chat(user, span_notice("You combine the [C.cardname] and the [src.cardname] into a hand."))
qdel(C)
qdel(src)
H.pickup(user)
user.put_in_active_hand(H)
else
to_chat(user, span_warning("You can't mix cards from other decks!"))
if(istype(I, /obj/item/toy/cards/cardhand/))
var/obj/item/toy/cards/cardhand/H = I
if(H.parentdeck == parentdeck)
H.currenthand += cardname
user.visible_message(span_notice("[user] adds a card to [user.p_their()] hand."), span_notice("You add the [cardname] to your hand."))
qdel(src)
H.interact(user)
H.update_sprite()
else
to_chat(user, span_warning("You can't mix cards from other decks!"))
else
return ..()
/obj/item/toy/cards/singlecard/attack_self(mob/living/carbon/human/user)
if(!ishuman(user) || !(user.mobility_flags & MOBILITY_USE))
return
Flip()
/obj/item/toy/cards/singlecard/apply_card_vars(obj/item/toy/cards/singlecard/newobj,obj/item/toy/cards/sourceobj)
..()
newobj.deckstyle = sourceobj.deckstyle
newobj.icon_state = "singlecard_down_[deckstyle]" // Without this the card is invisible until flipped. It's an ugly hack, but it works.
newobj.card_hitsound = sourceobj.card_hitsound
newobj.hitsound = newobj.card_hitsound
newobj.card_force = sourceobj.card_force
newobj.force = newobj.card_force
newobj.card_throwforce = sourceobj.card_throwforce
newobj.throwforce = newobj.card_throwforce
newobj.card_throw_speed = sourceobj.card_throw_speed
newobj.throw_speed = newobj.card_throw_speed
newobj.card_throw_range = sourceobj.card_throw_range
newobj.throw_range = newobj.card_throw_range
newobj.attack_verb_continuous = newobj.card_attack_verb_continuous = sourceobj.card_attack_verb_continuous //null or unique list made by string_list()
newobj.attack_verb_simple = newobj.card_attack_verb_simple = sourceobj.card_attack_verb_simple //null or unique list made by string_list()
/*
|| Syndicate playing cards, for pretending you're Gambit and playing poker for the nuke disk. ||
*/
/obj/item/toy/cards/deck/syndicate
name = "suspicious looking deck of cards"
desc = "A deck of space-grade playing cards. They seem unusually rigid."
icon_state = "deck_syndicate_full"
deckstyle = "syndicate"
card_hitsound = 'sound/weapons/bladeslice.ogg'
card_force = 5
card_throwforce = 10
card_throw_speed = 3
card_throw_range = 7
card_attack_verb_continuous = list("attacks", "slices", "dices", "slashes", "cuts")
card_attack_verb_simple = list("attack", "slice", "dice", "slash", "cut")
resistance_flags = NONE
/*
* Fake nuke
*/
/obj/item/toy/nuke
name = "\improper Nuclear Fission Explosive toy"
desc = "A plastic model of a Nuclear Fission Explosive."
icon = 'icons/obj/toy.dmi'
icon_state = "nuketoyidle"
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
/obj/item/toy/nuke/attack_self(mob/user)
if (obj_flags & EMAGGED && cooldown < world.time)
cooldown = world.time + 600
user.visible_message(span_hear("You hear the click of a button."), span_notice("You activate [src], it plays a loud noise!"))
sleep(5)
playsound(src, 'sound/machines/alarm.ogg', 20, FALSE)
sleep(140)
user.visible_message(span_alert("[src] violently explodes!"))
explosion(src, light_impact_range = 1)
qdel(src)
else if (cooldown < world.time)
cooldown = world.time + 600 //1 minute
user.visible_message(span_warning("[user] presses a button on [src]."), span_notice("You activate [src], it plays a loud noise!"), span_hear("You hear the click of a button."))
sleep(5)
icon_state = "nuketoy"
playsound(src, 'sound/machines/alarm.ogg', 20, FALSE)
sleep(135)
icon_state = "nuketoycool"
sleep(cooldown - world.time)
icon_state = "nuketoyidle"
else
var/timeleft = (cooldown - world.time)
to_chat(user, span_alert("Nothing happens, and '</span>[round(timeleft/10)]<span class='alert'>' appears on the small display."))
sleep(5)
/obj/item/toy/nuke/emag_act(mob/user)
if (obj_flags & EMAGGED)
return
to_chat(user, "<span class = 'notice'> You short-circuit \the [src].</span>")
obj_flags |= EMAGGED
/*
* Fake meteor
*/
/obj/item/toy/minimeteor
name = "\improper Mini-Meteor"
desc = "Relive the excitement of a meteor shower! SweetMeat-eor Co. is not responsible for any injuries, headaches or hearing loss caused by Mini-Meteor."
icon = 'icons/obj/toy.dmi'
icon_state = "minimeteor"
w_class = WEIGHT_CLASS_SMALL
/obj/item/toy/minimeteor/emag_act(mob/user)
if (obj_flags & EMAGGED)
return
to_chat(user, "<span class = 'notice'> You short-circuit whatever electronics exist inside \the [src], if there even are any.</span>")
obj_flags |= EMAGGED
/obj/item/toy/minimeteor/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if (obj_flags & EMAGGED)
playsound(src, 'sound/effects/meteorimpact.ogg', 40, TRUE)
explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 1)
for(var/mob/M in urange(10, src))
if(!M.stat && !isAI(M))
shake_camera(M, 3, 1)
else
playsound(src, 'sound/effects/meteorimpact.ogg', 40, TRUE)
for(var/mob/M in urange(10, src))
if(!M.stat && !isAI(M))
shake_camera(M, 3, 1)
/*
* Toy big red button
*/
/obj/item/toy/redbutton
name = "big red button"
desc = "A big, plastic red button. Reads 'From HonkCo Pranks!' on the back."
icon = 'icons/obj/assemblies.dmi'
icon_state = "bigred"
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
/obj/item/toy/redbutton/attack_self(mob/user)
if (cooldown < world.time)
cooldown = (world.time + 300) // Sets cooldown at 30 seconds
user.visible_message(span_warning("[user] presses the big red button."), span_notice("You press the button, it plays a loud noise!"), span_hear("The button clicks loudly."))
playsound(src, 'sound/effects/explosionfar.ogg', 50, FALSE)
for(var/mob/M in urange(10, src)) // Checks range
if(!M.stat && !isAI(M)) // Checks to make sure whoever's getting shaken is alive/not the AI
// Short delay to match up with the explosion sound
// Shakes player camera 2 squares for 1 second.
addtimer(CALLBACK(GLOBAL_PROC, .proc/shake_camera, M, 2, 1), 0.8 SECONDS)
else
to_chat(user, span_alert("Nothing happens."))
/*
* Snowballs
*/
/obj/item/toy/snowball
name = "snowball"
desc = "A compact ball of snow. Good for throwing at people."
icon = 'icons/obj/toy.dmi'
icon_state = "snowball"
throwforce = 20 //the same damage as a disabler shot
damtype = STAMINA //maybe someday we can add stuffing rocks (or perhaps ore?) into snowballs to make them deal brute damage
/obj/item/toy/snowball/afterattack(atom/target as mob|obj|turf|area, mob/user)
. = ..()
if(user.dropItemToGround(src))
throw_at(target, throw_range, throw_speed)
/obj/item/toy/snowball/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..())
playsound(src, 'sound/effects/pop.ogg', 20, TRUE)
qdel(src)
/*
* Beach ball
*/
/obj/item/toy/beach_ball
name = "beach ball"
icon = 'icons/misc/beach.dmi'
icon_state = "ball"
inhand_icon_state = "beachball"
w_class = WEIGHT_CLASS_BULKY //Stops people from hiding it in their bags/pockets
/obj/item/toy/beach_ball/branded
name = "\improper Nanotrasen-brand beach ball"
desc = "The simple beach ball is one of Nanotrasen's most popular products. 'Why do we make beach balls? Because we can! (TM)' - Nanotrasen"
/*
* Clockwork Watch
*/
/obj/item/toy/clockwork_watch
name = "steampunk watch"
desc = "A stylish steampunk watch made out of thousands of tiny cogwheels."
icon = 'icons/obj/clockwork_objects.dmi'
icon_state = "dread_ipad"
worn_icon_state = "dread_ipad"
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
/obj/item/toy/clockwork_watch/attack_self(mob/user)
if (cooldown < world.time)
cooldown = world.time + 1800 //3 minutes
user.visible_message(span_warning("[user] rotates a cogwheel on [src]."), span_notice("You rotate a cogwheel on [src], it plays a loud noise!"), span_hear("You hear cogwheels turning."))
playsound(src, 'sound/magic/clockwork/ark_activation.ogg', 50, FALSE)
else
to_chat(user, span_alert("The cogwheels are already turning!"))
/obj/item/toy/clockwork_watch/examine(mob/user)
. = ..()
. += span_info("Station Time: [station_time_timestamp()]")
/*
* Toy Dagger
*/
/obj/item/toy/toy_dagger
name = "toy dagger"
desc = "A cheap plastic replica of a dagger. Produced by THE ARM Toys, Inc."
icon = 'icons/obj/wizard.dmi'
icon_state = "render"
inhand_icon_state = "cultdagger"
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
/*
* Xenomorph action figure
*/
/obj/item/toy/toy_xeno
icon = 'icons/obj/toy.dmi'
icon_state = "toy_xeno"
name = "xenomorph action figure"
desc = "MEGA presents the new Xenos Isolated action figure! Comes complete with realistic sounds! Pull back string to use."
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
/obj/item/toy/toy_xeno/attack_self(mob/user)
if(cooldown <= world.time)
cooldown = (world.time + 50) //5 second cooldown
user.visible_message(span_notice("[user] pulls back the string on [src]."))
icon_state = "[initial(icon_state)]_used"
sleep(5)
audible_message(span_danger("[icon2html(src, viewers(src))] Hiss!"))
var/list/possible_sounds = list('sound/voice/hiss1.ogg', 'sound/voice/hiss2.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss4.ogg')
var/chosen_sound = pick(possible_sounds)
playsound(get_turf(src), chosen_sound, 50, TRUE)
addtimer(VARSET_CALLBACK(src, icon_state, "[initial(icon_state)]"), 4.5 SECONDS)
else
to_chat(user, span_warning("The string on [src] hasn't rewound all the way!"))
return
// TOY MOUSEYS :3 :3 :3
/obj/item/toy/cattoy
name = "toy mouse"
desc = "A colorful toy mouse!"
icon = 'icons/obj/toy.dmi'
icon_state = "toy_mouse"
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
resistance_flags = FLAMMABLE
/*
* Action Figures
*/
/obj/item/toy/figure
name = "\improper Non-Specific Action Figure action figure"
icon = 'icons/obj/toy.dmi'
icon_state = "nuketoy"
var/cooldown = 0
var/toysay = "What the fuck did you do?"
var/toysound = 'sound/machines/click.ogg'
w_class = WEIGHT_CLASS_SMALL
/obj/item/toy/figure/Initialize(mapload)
. = ..()
desc = "A \"Space Life\" brand [src]."
/obj/item/toy/figure/attack_self(mob/user as mob)
if(cooldown <= world.time)
cooldown = world.time + 50
to_chat(user, span_notice("[src] says \"[toysay]\""))
playsound(user, toysound, 20, TRUE)
/obj/item/toy/figure/cmo
name = "\improper Chief Medical Officer action figure"
icon_state = "cmo"
toysay = "Suit sensors!"
/obj/item/toy/figure/assistant
name = "\improper Assistant action figure"
icon_state = "assistant"
inhand_icon_state = "assistant"
toysay = "Greytide world wide!"
/obj/item/toy/figure/atmos
name = "\improper Atmospheric Technician action figure"
icon_state = "atmos"
toysay = "Glory to Atmosia!"
/obj/item/toy/figure/bartender
name = "\improper Bartender action figure"
icon_state = "bartender"
toysay = "Where is Pun Pun?"
/obj/item/toy/figure/borg
name = "\improper Cyborg action figure"
icon_state = "borg"
toysay = "I. LIVE. AGAIN."
toysound = 'sound/voice/liveagain.ogg'
/obj/item/toy/figure/botanist
name = "\improper Botanist action figure"
icon_state = "botanist"
toysay = "Blaze it!"
/obj/item/toy/figure/captain
name = "\improper Captain action figure"
icon_state = "captain"
toysay = "Any heads of staff?"
/obj/item/toy/figure/cargotech
name = "\improper Cargo Technician action figure"
icon_state = "cargotech"
toysay = "For Cargonia!"
/obj/item/toy/figure/ce
name = "\improper Chief Engineer action figure"
icon_state = "ce"
toysay = "Wire the solars!"
/obj/item/toy/figure/chaplain
name = "\improper Chaplain action figure"
icon_state = "chaplain"
toysay = "Praise Space Jesus!"
/obj/item/toy/figure/chef
name = "\improper Cook action figure"
icon_state = "chef"
toysay = "I'll make you into a burger!"
/obj/item/toy/figure/chemist
name = "\improper Chemist action figure"
icon_state = "chemist"
toysay = "Get your pills!"
/obj/item/toy/figure/clown
name = "\improper Clown action figure"
icon_state = "clown"
toysay = "Honk!"
toysound = 'sound/items/bikehorn.ogg'
/obj/item/toy/figure/ian
name = "\improper Ian action figure"
icon_state = "ian"
toysay = "Arf!"
/obj/item/toy/figure/detective
name = "\improper Detective action figure"
icon_state = "detective"
toysay = "This airlock has grey jumpsuit and insulated glove fibers on it."
/obj/item/toy/figure/dsquad
name = "\improper Deathsquad Officer action figure"
icon_state = "dsquad"
toysay = "Kill 'em all!"
/obj/item/toy/figure/engineer
name = "\improper Station Engineer action figure"
icon_state = "engineer"
toysay = "Oh god, the singularity is loose!"
/obj/item/toy/figure/geneticist
name = "\improper Geneticist action figure"
icon_state = "geneticist"
toysay = "Smash!"
/obj/item/toy/figure/hop
name = "\improper Head of Personnel action figure"
icon_state = "hop"
toysay = "Giving out all access!"
/obj/item/toy/figure/hos
name = "\improper Head of Security action figure"
icon_state = "hos"
toysay = "Go ahead, make my day."
/obj/item/toy/figure/qm
name = "\improper Quartermaster action figure"
icon_state = "qm"
toysay = "Please sign this form in triplicate and we will see about geting you a welding mask within 3 business days."
/obj/item/toy/figure/janitor
name = "\improper Janitor action figure"
icon_state = "janitor"
toysay = "Look at the signs, you idiot."
/obj/item/toy/figure/lawyer
name = "\improper Lawyer action figure"
icon_state = "lawyer"
toysay = "My client is a dirty traitor!"
/obj/item/toy/figure/curator
name = "\improper Curator action figure"
icon_state = "curator"
toysay = "One day while..."
/obj/item/toy/figure/md
name = "\improper Medical Doctor action figure"
icon_state = "md"
toysay = "The patient is already dead!"
/obj/item/toy/figure/paramedic
name = "\improper Paramedic action figure"
icon_state = "paramedic"
toysay = "And the best part? I'm not even a real doctor!"
/obj/item/toy/figure/psychologist
name = "\improper Psychologist action figure"
icon_state = "psychologist"
toysay = "Alright, just take these happy pills!"
/obj/item/toy/figure/prisoner
name = "\improper Prisoner action figure"
icon_state = "prisoner"
toysay = "I did not hit her! I did not!"
/obj/item/toy/figure/mime
name = "\improper Mime action figure"
icon_state = "mime"
toysay = "..."
toysound = null
/obj/item/toy/figure/miner
name = "\improper Shaft Miner action figure"
icon_state = "miner"
toysay = "COLOSSUS RIGHT OUTSIDE THE BASE!"
/obj/item/toy/figure/ninja
name = "\improper Space Ninja action figure"
icon_state = "ninja"
toysay = "I am the shadow warrior!"
/obj/item/toy/figure/wizard
name = "\improper Wizard action figure"
icon_state = "wizard"
toysay = "EI NATH!"
toysound = 'sound/magic/disintegrate.ogg'
/obj/item/toy/figure/rd
name = "\improper Research Director action figure"
icon_state = "rd"
toysay = "Blowing all of the borgs!"
/obj/item/toy/figure/roboticist
name = "\improper Roboticist action figure"
icon_state = "roboticist"
toysay = "Big stompy mechs!"
toysound = 'sound/mecha/mechstep.ogg'
/obj/item/toy/figure/scientist
name = "\improper Scientist action figure"
icon_state = "scientist"
toysay = "I call ordnance."
toysound = 'sound/effects/explosionfar.ogg'
/obj/item/toy/figure/syndie
name = "\improper Nuclear Operative action figure"
icon_state = "syndie"
toysay = "Get that fucking disk!"
/obj/item/toy/figure/secofficer
name = "\improper Security Officer action figure"
icon_state = "secofficer"
toysay = "I am the law!"
toysound = 'sound/runtime/complionator/dredd.ogg'
/obj/item/toy/figure/virologist
name = "\improper Virologist action figure"
icon_state = "virologist"
toysay = "The cure is potassium!"
/obj/item/toy/figure/warden
name = "\improper Warden action figure"
icon_state = "warden"
toysay = "Seventeen minutes for coughing at an officer!"
/obj/item/toy/dummy
name = "ventriloquist dummy"
desc = "It's a dummy, dummy."
icon = 'icons/obj/toy.dmi'
icon_state = "puppet"
inhand_icon_state = "puppet"
var/doll_name = "Dummy"
//Add changing looks when i feel suicidal about making 20 inhands for these.
/obj/item/toy/dummy/attack_self(mob/user)
var/new_name = stripped_input(usr,"What would you like to name the dummy?","Input a name",doll_name,MAX_NAME_LEN)
if(!new_name)
return
doll_name = new_name
to_chat(user, span_notice("You name the dummy as \"[doll_name]\"."))
name = "[initial(name)] - [doll_name]"
/obj/item/toy/dummy/talk_into(atom/movable/A, message, channel, list/spans, datum/language/language, list/message_mods)
var/mob/M = A
if (istype(M))
M.log_talk(message, LOG_SAY, tag="dummy toy")
say(message, language, sanitize = FALSE)
return NOPASS
/obj/item/toy/dummy/GetVoice()
return doll_name
/obj/item/toy/seashell
name = "seashell"
desc = "May you always have a shell in your pocket and sand in your shoes. Whatever that's supposed to mean."
icon = 'icons/misc/beach.dmi'
icon_state = "shell1"
var/static/list/possible_colors = list("" = 2, COLOR_PURPLE_GRAY = 1, COLOR_OLIVE = 1, COLOR_PALE_BLUE_GRAY = 1, COLOR_RED_GRAY = 1)
/obj/item/toy/seashell/Initialize(mapload)
. = ..()
pixel_x = rand(-5, 5)
pixel_y = rand(-5, 5)
icon_state = "shell[rand(1,3)]"
color = pick_weight(possible_colors)
setDir(pick(GLOB.cardinals))
/obj/item/toy/brokenradio
name = "broken radio"
desc = "An old radio that produces nothing but static when turned on."
icon = 'icons/obj/toy.dmi'
icon_state = "broken_radio"
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
/obj/item/toy/brokenradio/attack_self(mob/user)
if(cooldown <= world.time)
cooldown = (world.time + 300)
user.visible_message(span_notice("[user] adjusts the dial on [src]."))
addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/items/radiostatic.ogg', 50, FALSE), 0.5 SECONDS)
else
to_chat(user, span_warning("The dial on [src] jams up"))
return
/obj/item/toy/braintoy
name = "squeaky brain"
desc = "A Mr. Monstrous brand toy made to imitate a human brain in smell and texture."
icon = 'icons/obj/surgery.dmi'
icon_state = "brain-old"
var/cooldown = 0
/obj/item/toy/braintoy/attack_self(mob/user)
if(cooldown <= world.time)
cooldown = (world.time + 10)
addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/effects/blobattack.ogg', 50, FALSE), 0.5 SECONDS)
/*
* Eldritch Toys
*/
/obj/item/toy/eldritch_book
name = "Codex Cicatrix"
desc = "A toy book that closely resembles the Codex Cicatrix. Covered in fake polyester human flesh and has a huge goggly eye attached to the cover. The runes are gibberish and cannot be used to summon demons... Hopefully?"
icon = 'icons/obj/eldritch.dmi'
icon_state = "book"
w_class = WEIGHT_CLASS_SMALL
attack_verb_continuous = list("sacrifices", "transmutes", "graspes", "curses")
attack_verb_simple = list("sacrifice", "transmute", "grasp", "curse")
/// Helps determine the icon state of this item when it's used on self.
var/book_open = FALSE
/obj/item/toy/eldritch_book/attack_self(mob/user)
book_open = !book_open
update_appearance()
/obj/item/toy/eldritch_book/update_icon_state()
icon_state = book_open ? "book_open" : "book"
return ..()
/*
* Fake tear
*/
/obj/item/toy/reality_pierce
name = "Pierced reality"
desc = "Hah. You thought it was the real deal!"
icon = 'icons/effects/eldritch.dmi'
icon_state = "pierced_illusion"
item_flags = NO_PIXEL_RANDOM_DROP
/obj/item/storage/box/heretic_box
name = "box of pierced realities"
desc = "A box containing toys resembling pierced realities."
/obj/item/storage/box/heretic_box/PopulateContents()
for(var/i in 1 to rand(1,4))
new /obj/item/toy/reality_pierce(src)
/obj/item/toy/foamfinger
name = "foam finger"
desc = "root for the home team! wait, does this station even have a sports team?"
icon = 'icons/obj/guns/ballistic.dmi'
icon_state = "foamfinger"
inhand_icon_state = "foamfinger_inhand"
lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
w_class = WEIGHT_CLASS_NORMAL
COOLDOWN_DECLARE(foamfinger_cooldown)
/obj/item/toy/foamfinger/attack_self(mob/living/carbon/human/user)
if(!COOLDOWN_FINISHED(src, foamfinger_cooldown))
return
COOLDOWN_START(src, foamfinger_cooldown, 5 SECONDS)
user.manual_emote("waves around the foam finger.")
var/direction = prob(50) ? -1 : 1
if(NSCOMPONENT(user.dir)) //So signs are waved horizontally relative to what way the player waving it is facing.
animate(user, pixel_x = user.pixel_x + (1 * direction), time = 1, easing = SINE_EASING)
animate(pixel_x = user.pixel_x - (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_x = user.pixel_x + (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_x = user.pixel_x - (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_x = user.pixel_x + (1 * direction), time = 1, easing = SINE_EASING)
else
animate(user, pixel_y = user.pixel_y + (1 * direction), time = 1, easing = SINE_EASING)
animate(pixel_y = user.pixel_y - (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_y = user.pixel_y + (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_y = user.pixel_y - (2 * direction), time = 1, easing = SINE_EASING)
animate(pixel_y = user.pixel_y + (1 * direction), time = 1, easing = SINE_EASING)
user.changeNext_move(CLICK_CD_MELEE)
///All people who have used an Intento this round along with their high scores.
GLOBAL_LIST_EMPTY(intento_players)
#define HELP "help"
#define DISARM "disarm"
#define GRAB "grab"
#define HARM "harm"
#define ICON_SPLIT world.icon_size/2
// These states do not have any associated processing.
#define STATE_AWAITING_PLAYER_INPUT "awaiting_player_input"
#define STATE_OFF "off"
// When the Intento is in one of these four states, it has an accompanying
// set of code that runs in processing()
#define STATE_STARTING "starting"
#define STATE_DEMO "demo"
#define STATE_END_OF_GAME "end_of_game"
#define STATE_RETALIATION "retaliation"
#define TIME_TO_BEGIN 1.6 SECONDS
#define TIME_PER_DEMO_STEP 0.6 SECONDS
#define TIME_TO_RESET_ICON 0.5 SECONDS
/obj/item/toy/intento
name = "\improper Intento"
desc = "Fundamentally useless for all intentsive purposes."
icon = 'icons/obj/intents.dmi'
icon_state = "blank"
/// Current sequence of intents
var/list/current_sequence = list()
/// Sequence player inputs
var/list/player_sequence = list()
/// Score of the player
var/score = 0
/// Associated list of intents to their sounds
var/static/list/sound_by_intent = list(
HELP = 'sound/items/intents/Help.ogg',
DISARM = 'sound/items/intents/Disarm.ogg',
GRAB = 'sound/items/intents/Grab.ogg',
HARM = 'sound/items/intents/Harm.ogg',
)
/// What state the toy is in.
var/state = STATE_OFF
/// Index used for iteration of steps for both demo and retaliation states
var/index
/// Time to delay until we start processing whatever state we're in
COOLDOWN_DECLARE(next_process)
/// Time until we reset the icon of the Intento
COOLDOWN_DECLARE(next_icon_reset)
/obj/item/toy/intento/attack_self(mob/user, modifiers) //added params to attack_self, the alternative is registering a signal on clickon but i was advised not to
..()
if(state == STATE_OFF)
boot()
return
if(!modifiers)
return
if(state != STATE_AWAITING_PLAYER_INPUT)
return
var/input
var/icon_x = text2num(modifiers["icon-x"])
var/icon_y = text2num(modifiers["icon-y"])
if(icon_x > ICON_SPLIT && icon_y > ICON_SPLIT)
input = DISARM
if(icon_x < ICON_SPLIT && icon_y > ICON_SPLIT)
input = HELP
if(icon_x > ICON_SPLIT && icon_y < ICON_SPLIT)
input = GRAB
if(icon_x < ICON_SPLIT && icon_y < ICON_SPLIT)
input = HARM
player_input(user, input)
/obj/item/toy/intento/proc/boot()
say("Game starting!")
playsound(src, 'sound/machines/synth_yes.ogg', 50, FALSE)
state = STATE_STARTING
COOLDOWN_START(src, next_process, TIME_TO_BEGIN)
START_PROCESSING(SSfastprocess, src)
/obj/item/toy/intento/proc/player_input(mob/player, intent)
// All branches of this proc lead to us wanting to process
START_PROCESSING(SSfastprocess, src)
render(intent)
player_sequence += intent
for(var/i in 1 to player_sequence.len)
if(player_sequence[i] != current_sequence[i])
state = STATE_END_OF_GAME
COOLDOWN_START(src, next_process, TIME_TO_RESET_ICON)
return
if(player_sequence.len == current_sequence.len)
score++
state = STATE_STARTING
COOLDOWN_START(src, next_process, TIME_TO_BEGIN)
/obj/item/toy/intento/process()
if(next_icon_reset && next_icon_reset <= world.time)
icon_state = initial(icon_state)
COOLDOWN_RESET(src, next_icon_reset)
if(next_process && next_process > world.time)
return
switch(state)
if(STATE_STARTING)
process_start()
if(STATE_DEMO)
process_demo()
if(STATE_END_OF_GAME)
process_end(isliving(loc) ? loc : null)
if(STATE_RETALIATION)
process_retaliation()
if(!next_process && !next_icon_reset)
return PROCESS_KILL
/obj/item/toy/intento/proc/process_start()
player_sequence.Cut()
current_sequence += pick(list(HELP, DISARM, GRAB, HARM))
state = STATE_DEMO
next_process = world.time
index = 1
/obj/item/toy/intento/proc/process_demo()
if(index > length(current_sequence))
state = STATE_AWAITING_PLAYER_INPUT
COOLDOWN_RESET(src, next_process)
return
var/intent = current_sequence[index]
render(intent)
index += 1
COOLDOWN_START(src, next_process, TIME_PER_DEMO_STEP)
/obj/item/toy/intento/proc/process_end(mob/user)
if(user && GLOB.intento_players[user.ckey] < score)
GLOB.intento_players[user.ckey] = score
var/award_status = user.client.get_award_status(/datum/award/score/intento_score)
var/award_score = score - award_status
if(award_score > 0)
user.client.give_award(/datum/award/score/intento_score, user, award_score)
say("GAME OVER. Your score was [score]!")
playsound(src, 'sound/machines/synth_no.ogg', 50, FALSE)
if(user && loc == user && obj_flags & EMAGGED)
ADD_TRAIT(src, TRAIT_NODROP, type)
to_chat(user, span_userdanger("Bad mistake."))
state = STATE_RETALIATION
next_process = world.time
index = 1
else
cleanup()
/obj/item/toy/intento/proc/process_retaliation()
var/mob/living/victim = loc
if(!isliving(victim) || index > length(current_sequence))
cleanup()
return
var/intent = current_sequence[index]
render(intent)
switch(intent)
if(HELP)
to_chat(victim, span_danger("[src] hugs you to make you feel better!"))
SEND_SIGNAL(victim, COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug)
if(DISARM)
to_chat(victim, span_danger("You're knocked down from a shove by [src]!"))
victim.Knockdown(2 SECONDS)
if(GRAB)
to_chat(victim, span_danger("[src] grabs you aggressively!"))
victim.Stun(2 SECONDS)
if(HARM)
to_chat(victim, span_danger("You're punched by [src]!"))
victim.apply_damage(rand(20, 30), BRUTE)
index += 1
COOLDOWN_START(src, next_process, TIME_PER_DEMO_STEP)
/obj/item/toy/intento/proc/cleanup()
score = 0
index = 1
player_sequence.Cut()
current_sequence.Cut()
state = STATE_OFF
COOLDOWN_RESET(src, next_process)
REMOVE_TRAIT(src, TRAIT_NODROP, type)
/obj/item/toy/intento/proc/render(input)
icon_state = input
playsound(src, sound_by_intent[input], 50, FALSE)
START_PROCESSING(SSfastprocess, src)
COOLDOWN_START(src, next_icon_reset, TIME_TO_RESET_ICON)
/obj/item/toy/intento/emag_act(mob/user)
if(obj_flags & EMAGGED)
return
obj_flags |= EMAGGED
to_chat(user, span_notice("You short-circuit [src], activating the negative feedback loop."))
/obj/item/toy/intento/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
#undef HELP
#undef DISARM
#undef GRAB
#undef HARM
#undef ICON_SPLIT
#undef STATE_AWAITING_PLAYER_INPUT
#undef STATE_OFF
#undef STATE_STARTING
#undef STATE_DEMO
#undef STATE_END_OF_GAME
#undef STATE_RETALIATION
#undef TIME_TO_BEGIN
#undef TIME_PER_DEMO_STEP
#undef TIME_TO_RESET_ICON