diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm
index f2fd53403a..29e3b59d3f 100644
--- a/code/game/objects/items/plushes.dm
+++ b/code/game/objects/items/plushes.dm
@@ -9,13 +9,91 @@
var/list/squeak_override //Weighted list; If you want your plush to have different squeak sounds use this
var/stuffed = 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*
+ //--love ~<3--
+ gender = NEUTER
+ var/obj/item/toy/plush/lover
+ var/obj/item/toy/plush/partner
+ var/obj/item/toy/plush/plush_child
+ var/obj/item/toy/plush/paternal_parent //who initiated creation
+ var/obj/item/toy/plush/maternal_parent //who owns, see love()
+ var/list/scorned = list() //who the plush hates
+ var/list/scorned_by = list() //who hates the plush, to remove external references on Destroy()
+ var/heartbroken = FALSE
+ var/vowbroken = FALSE
+ var/young = FALSE
+ var/mood_message
+ var/list/love_message
+ var/list/partner_message
+ var/list/heartbroken_message
+ var/list/vowbroken_message
+ var/list/parent_message
+ var/normal_desc
+ //--end of love :'(--
/obj/item/toy/plush/Initialize()
. = ..()
AddComponent(/datum/component/squeak, squeak_override)
+ //have we decided if Pinocchio goes in the blue or pink aisle yet?
+ if(gender == NEUTER)
+ if(prob(50))
+ gender = FEMALE
+ else
+ gender = MALE
+
+ love_message = list("\n[src] is so happy, \he could rip a seam!")
+ partner_message = list("\n[src] has a ring on \his finger! It says bound to my dear [partner].")
+ heartbroken_message = list("\n[src] looks so sad.")
+ vowbroken_message = list("\n[src] lost \his ring...")
+ parent_message = list("\n[src] can't remember what sleep is.")
+
+ normal_desc = desc
+
/obj/item/toy/plush/Destroy()
QDEL_NULL(grenade)
+
+ //inform next of kin and... acquaintances
+ if(partner)
+ partner.bad_news(src)
+ partner = null
+ lover = null
+ else if(lover)
+ lover.bad_news(src)
+ lover = null
+
+ if(paternal_parent)
+ paternal_parent.bad_news(src)
+ paternal_parent = null
+
+ if(maternal_parent)
+ maternal_parent.bad_news(src)
+ maternal_parent = null
+
+ if(plush_child)
+ plush_child.bad_news(src)
+ plush_child = null
+
+ var/i
+ var/obj/item/toy/plush/P
+ for(i=1, i<=scorned.len, i++)
+ P = scorned[i]
+ P.bad_news(src)
+ scorned = null
+
+ for(i=1, i<=scorned_by.len, i++)
+ P = scorned_by[i]
+ P.bad_news(src)
+ scorned_by = null
+
+ //null remaining lists
+ squeak_override = null
+
+ love_message = null
+ partner_message = null
+ heartbroken_message = null
+ vowbroken_message = null
+ parent_message = null
+
return ..()
/obj/item/toy/plush/handle_atom_del(atom/A)
@@ -66,8 +144,221 @@
var/turf/T = get_turf(user)
log_game("[key_name(user)] added a grenade ([I.name]) to [src] at [COORD(T)].")
return
+ if(istype(I, /obj/item/toy/plush))
+ love(I, user)
+ return
return ..()
+/obj/item/toy/plush/proc/love(obj/item/toy/plush/Kisser, mob/living/user) //~<3
+ var/chance = 100 //to steal a kiss, surely there's a 100% chance no-one would reject a plush such as I?
+ var/concern = 20 //perhaps something might cloud true love with doubt
+ var/loyalty = 30 //why should another get between us?
+ var/duty = 50 //conquering another's is what I live for
+
+ //we are not catholic
+ if(young == TRUE || Kisser.young == TRUE)
+ user.show_message("[src] plays tag with [Kisser].", 1,
+ "They're happy.", 0)
+ Kisser.cheer_up()
+ cheer_up()
+
+ //never again
+ else if(Kisser in scorned)
+ //message, visible, alternate message, neither visible nor audible
+ user.show_message("[src] rejects the advances of [Kisser]!", 1,
+ "That didn't feel like it worked.", 0)
+ else if(src in Kisser.scorned)
+ user.show_message("[Kisser] realises who [src] is and turns away.", 1,
+ "That didn't feel like it worked.", 0)
+
+ //first comes love
+ else if(Kisser.lover != src && Kisser.partner != src) //cannot be lovers or married
+ if(Kisser.lover) //if the initiator has a lover
+ Kisser.lover.heartbreak(Kisser) //the old lover can get over the kiss-and-run whilst the kisser has some fun
+ chance -= concern //one heart already broken, what does another mean?
+ if(lover) //if the recipient has a lover
+ chance -= loyalty //mustn't... but those lips
+ if(partner) //if the recipient has a partner
+ chance -= duty //do we mate for life?
+
+ if(prob(chance)) //did we bag a date?
+ user.visible_message("[user] makes [Kisser] kiss [src]!",
+ "You make [Kisser] kiss [src]!")
+ if(lover) //who cares for the past, we live in the present
+ lover.heartbreak(src)
+ new_lover(Kisser)
+ Kisser.new_lover(src)
+ else
+ user.show_message("[src] rejects the advances of [Kisser], maybe next time?", 1,
+ "That didn't feel like it worked, this time.", 0)
+
+ //then comes marriage
+ else if(Kisser.lover == src && Kisser.partner != src) //need to be lovers (assumes loving is a two way street) but not married (also assumes similar)
+ user.visible_message("[user] pronounces [Kisser] and [src] married! D'aw.",
+ "You pronounce [Kisser] and [src] married!")
+ new_partner(Kisser)
+ Kisser.new_partner(src)
+
+ //then comes a baby in a baby's carriage, or an adoption in an adoption's orphanage
+ else if(Kisser.partner == src && !plush_child) //the one advancing does not take ownership of the child and we have a one child policy in the toyshop
+ user.visible_message("[user] is going to break [Kisser] and [src] by bashing them like that.",
+ "[Kisser] passionately embraces [src] in your hands. Look away you perv!")
+ plop(Kisser)
+ user.visible_message("Something drops at the feet of [user].",
+ "The miracle of oh god did that just come out of [src]?!")
+
+ //then comes protection, or abstinence if we are catholic
+ else if(Kisser.partner == src && plush_child)
+ user.visible_message("[user] makes [Kisser] nuzzle [src]!",
+ "You make [Kisser] nuzzle [src]!")
+
+ //then oh fuck something unexpected happened
+ else
+ user.show_message("[Kisser] and [src] don't know what to do with one another.", 0)
+
+/obj/item/toy/plush/proc/heartbreak(obj/item/toy/plush/Brutus)
+ if(lover != Brutus)
+ to_chat(world, "lover != Brutus")
+ return //why are we considering someone we don't love?
+
+ scorned.Add(Brutus)
+ Brutus.scorned_by(src)
+
+ lover = null
+ Brutus.lover = null //feeling's mutual
+
+ heartbroken = TRUE
+ mood_message = pick(heartbroken_message)
+
+ if(partner == Brutus) //oh dear...
+ partner = null
+ Brutus.partner = null //it'd be weird otherwise
+ vowbroken = TRUE
+ mood_message = pick(vowbroken_message)
+
+ update_desc()
+
+/obj/item/toy/plush/proc/scorned_by(obj/item/toy/plush/Outmoded)
+ scorned_by.Add(Outmoded)
+
+/obj/item/toy/plush/proc/new_lover(obj/item/toy/plush/Juliet)
+ if(lover == Juliet)
+ return //nice try
+ lover = Juliet
+
+ cheer_up()
+ lover.cheer_up()
+
+ mood_message = pick(love_message)
+ update_desc()
+
+ if(partner) //who?
+ partner = null //more like who cares
+
+/obj/item/toy/plush/proc/new_partner(obj/item/toy/plush/Apple_of_my_eye)
+ if(partner == Apple_of_my_eye)
+ return //double marriage is just insecurity
+ if(lover != Apple_of_my_eye)
+ return //union not born out of love will falter
+
+ partner = Apple_of_my_eye
+
+ heal_memories()
+ partner.heal_memories()
+
+ mood_message = pick(partner_message)
+ update_desc()
+
+/obj/item/toy/plush/proc/plop(obj/item/toy/plush/Daddy)
+ if(partner != Daddy)
+ return //we do not have bastards in our toyshop
+
+ if(prob(50)) //it has my eyes
+ plush_child = new type(get_turf(loc))
+ else //it has your eyes
+ plush_child = new Daddy.type(get_turf(loc))
+
+ plush_child.make_young(src, Daddy)
+
+/obj/item/toy/plush/proc/make_young(obj/item/toy/plush/Mama, obj/item/toy/plush/Dada)
+ if(Mama == Dada)
+ return //cloning is reserved for plants and spacemen
+
+ maternal_parent = Mama
+ paternal_parent = Dada
+ young = TRUE
+ name = "[Mama] Jr" //Icelandic naming convention pending
+ normal_desc = "[src] is a little baby of [maternal_parent] and [paternal_parent]!" //original desc won't be used so the child can have moods
+ update_desc()
+
+ Mama.mood_message = pick(Mama.parent_message)
+ Mama.update_desc()
+ Dada.mood_message = pick(Dada.parent_message)
+ Dada.update_desc()
+
+/obj/item/toy/plush/proc/bad_news(obj/item/toy/plush/Deceased) //cotton to cotton, sawdust to sawdust
+ var/is_that_letter_for_me = FALSE
+ if(partner == Deceased) //covers marriage
+ is_that_letter_for_me = TRUE
+ partner = null
+ lover = null
+ else if(lover == Deceased) //covers lovers
+ is_that_letter_for_me = TRUE
+ lover = null
+
+ //covers children
+ if(maternal_parent == Deceased)
+ is_that_letter_for_me = TRUE
+ maternal_parent = null
+
+ if(paternal_parent == Deceased)
+ is_that_letter_for_me = TRUE
+ paternal_parent = null
+
+ //covers parents
+ if(plush_child == Deceased)
+ is_that_letter_for_me = TRUE
+ plush_child = null
+
+ //covers bad memories
+ if(Deceased in scorned)
+ scorned.Remove(Deceased)
+ cheer_up() //what cold button eyes you have
+
+ if(Deceased in scorned_by)
+ scorned_by.Remove(Deceased)
+
+ //all references to the departed should be cleaned up by now
+
+ if(is_that_letter_for_me)
+ heartbroken = TRUE
+ mood_message = pick(heartbroken_message)
+ update_desc()
+
+/obj/item/toy/plush/proc/cheer_up() //it'll be all right
+ if(!heartbroken)
+ return //you cannot make smile what is already
+ if(vowbroken)
+ return //it's a pretty big deal
+
+ heartbroken = !heartbroken
+
+ if(mood_message in heartbroken_message)
+ mood_message = null
+ update_desc()
+
+/obj/item/toy/plush/proc/heal_memories() //time fixes all wounds
+ if(!vowbroken)
+ vowbroken = !vowbroken
+ if(mood_message in vowbroken_message)
+ mood_message = null
+ cheer_up()
+
+/obj/item/toy/plush/proc/update_desc()
+ desc = normal_desc
+ if(mood_message)
+ desc += mood_message
+
/obj/item/toy/plush/carpplushie
name = "space carp plushie"
desc = "An adorable stuffed toy that resembles a space carp."
@@ -88,6 +379,7 @@
desc = "An adorable plushie of the clockwork justiciar himself with new and improved spring arm action."
icon_state = "plushvar"
var/obj/item/toy/plush/narplush/clash_target
+ gender = MALE //he's a boy, right?
/obj/item/toy/plush/plushvar/Moved()
. = ..()
@@ -173,6 +465,7 @@
desc = "A small stuffed doll of the elder god nar'sie. Who thought this was a good children's toy?"
icon_state = "narplush"
var/clashing
+ gender = FEMALE //it's canon if the toy is
/obj/item/toy/plush/narplush/Moved()
. = ..()
@@ -198,7 +491,7 @@
/obj/item/toy/plush/nukeplushie
name = "operative plushie"
- desc = "An stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious."
+ desc = "A stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious."
icon_state = "plushie_nuke"
item_state = "plushie_nuke"
attack_verb = list("shot", "nuked", "detonated")
@@ -210,4 +503,9 @@
icon_state = "plushie_slime"
item_state = "plushie_slime"
attack_verb = list("blorbled", "slimed", "absorbed")
- squeak_override = list('sound/effects/blobattack.ogg' = 1)
\ No newline at end of file
+<<<<<<< HEAD
+ squeak_override = list('sound/effects/blobattack.ogg' = 1)
+=======
+ squeak_override = list('sound/effects/blobattack.ogg' = 1)
+ gender = FEMALE //given all the jokes and drawings, I'm not sure the xenobiologists would make a slimeboy
+>>>>>>> 502905f... Plushie relationships! (#33184)