diff --git a/html/changelogs/archive/2023-01.yml b/html/changelogs/archive/2023-01.yml
index 1598689f18..33d0441fb1 100644
--- a/html/changelogs/archive/2023-01.yml
+++ b/html/changelogs/archive/2023-01.yml
@@ -184,3 +184,17 @@
AshTheDerg:
- tweak: Modified Booze Shaker options
- bugfix: fixed broken Borg Beer Shaker
+2023-01-28:
+ '@Dexxiol':
+ - imageadd: Done some ui sprites for the underwear slots.
+ LeDrascol:
+ - rscadd: Added the Saliith plushie pinpointer
+ - tweak: The Saliith plushie will throw knives instead of deleting them
+ - tweak: The Saliith plushie will appear in a random location on the map
+ - tweak: Only one Saliith plushie can exist in the game at once
+ - balance: The Saliith plushie is now indestructible
+ - balance: The Saliith plushie cannot be destroyed by any means
+ - balance: The Saliith plushie now uses a lightning smite instead of gibbing
+ - balance: The Saliith plushie will no longer smite brainwashed victims
+ - balance: The Saliith plushie will now retaliate against plushmium use
+ - imageadd: Added a green pinpointer sprite
diff --git a/modular_sand/code/_globalvars/lists/objects.dm b/modular_sand/code/_globalvars/lists/objects.dm
index dd737fbe73..bbdfa5207d 100644
--- a/modular_sand/code/_globalvars/lists/objects.dm
+++ b/modular_sand/code/_globalvars/lists/objects.dm
@@ -1,2 +1,3 @@
GLOBAL_LIST_EMPTY(ic_jammers)
GLOBAL_LIST_EMPTY(ic_speakers)
+GLOBAL_DATUM_INIT(saliith_plushie, /obj/item/toy/plush/lizardplushie/saliith, new)
diff --git a/modular_sand/code/game/objects/items/plushes.dm b/modular_sand/code/game/objects/items/plushes.dm
index e18d220d36..9ed4c6f90c 100644
--- a/modular_sand/code/game/objects/items/plushes.dm
+++ b/modular_sand/code/game/objects/items/plushes.dm
@@ -1,74 +1,233 @@
-// Honestly, i was just sad when i made this, if you don't my sadness moment, simply delete the file or comment it out.
+// Honestly, Saliith was just sad when he made this. Leave this file in the game to let people hug him.
-/obj/item/toy/plush/saliith
+/obj/item/toy/plush/lizardplushie/saliith
name = "Saliith plushie"
- desc = "It has seen better days."
+ desc = "He looks like he needs a friend."
icon = 'modular_sand/icons/obj/plushes.dmi'
icon_state = "saliith"
gender = MALE
can_random_spawn = FALSE
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF // Protected by a higher power
+ unstuffable = TRUE // Prevent grenades
-/obj/item/toy/plush/saliith/examine(mob/user)
+/obj/item/toy/plush/lizardplushie/saliith/Initialize(mapload, set_snowflake_id)
+ // Check if plush already exists
+ if(GLOB.saliith_plushie && (GLOB.saliith_plushie != src))
+ return INITIALIZE_HINT_QDEL
+
+ // Return normally
. = ..()
- . += "[p_they(TRUE)] seems depressed."
+
+/obj/item/toy/plush/lizardplushie/saliith/ComponentInitialize()
+ . = ..()
+
+ // Add respawn component
+ AddComponent(/datum/component/stationloving)
+
+ // Define pronouns
+ var/p_they = p_they()
+ var/p_s = p_s()
+
+ // Add custom description
+ normal_desc = "[p_they] look[p_s] like [p_they] need[p_s] a friend."
+
+/obj/item/toy/plush/lizardplushie/saliith/examine(mob/user)
+ . = ..()
+
+ // Define pronouns
+ var/p_them = p_them()
+ //var/p_they = p_they()
+ //var/p_are = p_are()
+
+ // Check for stuffing
if(!stuffed)
+ // Update examine text and return
. += span_deadsay("[p_they(TRUE)] [p_are()] dead.")
- else
- if((length(user?.mind?.antag_datums) >= 1) && user.ckey != "sandpoot")
- . += "[src] looks at you menacingly, patting [p_them()] does NOT look like a good idea."
+ return
-/obj/item/toy/plush/saliith/attack_self(mob/user)
+ // Check if user is Saliith himself
if(user.ckey == "sandpoot")
+ // Update examine text and return
+ . += span_deadsay("You feel a sense of familiarity from [p_them].")
+ return
+
+ // Check for antag datums
+ if((length(user?.mind?.antag_datums) >= 1))
+ // Update examine text
+ . += span_warning("[src] gives you a menacing glare! Patting [p_them] would be a dangerous mistake.")
+
+/obj/item/toy/plush/lizardplushie/saliith/attack_self(mob/living/carbon/human/user)
+ // Check if user exists
+ if(!user)
+ // Return normally
return ..()
- var/special_friend = FALSE
- for(var/datum/antagonist/A in user?.mind?.antag_datums)
- if(istype(A, /datum/antagonist/changeling/xenobio))
- special_friend = TRUE // Doesn't help if they're evil anyways on the else
- continue
+
+ // Check if user has a mind
+ if(!user.mind)
+ // Return normally
+ return ..()
+
+ // Define pronouns
+ var/p_they = p_they()
+ //var/p_their = p_their()
+ var/p_s = p_s()
+
+ // Check if user is Saliith himself
+ if(user.ckey == "sandpoot")
+ // Alert him and return
+ to_chat(user, span_notice("[p_they] give[p_s] you a hesitant gaze, but accept[p_s] the gesture anyhow."))
+ return ..()
+
+ // Check if user is an antagonist role
+ if((length(user?.mind?.antag_datums) >= 1))
+ // Check if user is a xenobio changeling
+ if(user?.mind?.has_antag_datum(/datum/antagonist/changeling/xenobio))
+ // Alert the user
+ to_chat(user, span_notice("[src] senses what you really are, but decides to spare you."))
+
+ // Check if user is a brainwashed victim
+ else if(user?.mind?.has_antag_datum(/datum/antagonist/brainwashed))
+ // Alert the user
+ to_chat(user, span_notice("[src] senses that you're not in control of your actions, and offers [p_their()] sympathy."))
+
+ // User is not a whitelisted antagonist
else
- to_chat(user, span_warning("This was a bad idea."))
- user.gib()
+ // Drop the item
+ user.dropItemToGround(src)
+
+ // Warn user
+ user.visible_message(span_warning("[src] smites [user] with an otherworldly wrath!"), span_boldwarning("You've made a grave mistake."))
+
+ // Get lightning location
+ var/turf/turf_target = get_step(get_step(user, NORTH), NORTH)
+
+ // Perform lightning effect
+ turf_target.Beam(user, icon_state="lightning[rand(1,12)]", time = 5)
+ user.electrocution_animation(40)
+
+ // Play sound effect
+ playsound(get_turf(user), 'sound/magic/lightningbolt.ogg', 50, 1)
+
+ // Add fire damage
+ user.adjustFireLoss(120)
+
+ // Return
return
- if(special_friend)
- to_chat(user, "[src] looks at you hesitantly, but lets you carry on anyhow.")
- if(grenade)
- qdel(grenade)
+
+ // User has no antagonist status
+
+ // Alert the user
+ to_chat(user, span_notice("[p_they] give[p_s] you a hesitant gaze, but accepts the gesture anyhow."))
+
+ // Return
return ..()
-/obj/item/toy/plush/saliith/attackby(obj/item/I, mob/living/user, params)
+/obj/item/toy/plush/lizardplushie/saliith/attackby(obj/item/item_used, mob/living/user, params)
+ // Check for sharp object
+ if(item_used.get_sharpness())
+ // Warn in local chat
+ visible_message(span_warning("[src] knocks \the [item_used] out of [user]'s hands!"), span_warning("[src] knocks \the [item_used] out of your hands!"))
+
+ // Drop the item
+ user.dropItemToGround(item_used)
+
+ // Throw the item away
+ item_used.throw_at(pick(oview(7,get_turf(src))),10,1)
+
+ // Return
+ return
+
+ // Check if user is Saliith himself
if(user.ckey == "sandpoot")
+ // Return with no effects
return ..()
- if(I.get_sharpness())
- to_chat(user, "[src] shatters \the [I]!")
- qdel(I)
- return
- if(istype(I, /obj/item/grenade))
- to_chat(user, "[src] forces \the [I] into your mouth!")
- var/obj/item/grenade/bad_idea = I
- bad_idea.forceMove(user)
- bad_idea.preprime(volume = 10)
+
+ // Check for grenade
+ if(istype(item_used, /obj/item/grenade))
+ // Warn in local chat
+ visible_message(span_warning("[src] forces \the [item_used] into [user]'s mouth!"), span_warning("[src] forces \the [item_used] into your mouth!"))
+
+ // Define the grenade item
+ var/obj/item/grenade/item_grenade = item_used
+
+ // Move grenade to the user
+ item_grenade.forceMove(user)
+
+ // Set the detonation time
+ item_grenade.preprime(volume = 10)
+
+ // Return
return
+
+ // Return normally
return ..()
-/obj/item/toy/plush/saliith/ex_act(severity, target, origin)
+/obj/item/toy/plush/lizardplushie/saliith/ex_act(severity, target, origin)
return
/obj/item/toy/plush/plushling/plushie_absorb(obj/item/toy/plush/victim)
- if(istype(victim, /obj/item/toy/plush/saliith))
- visible_message(span_warning("[victim] violently parries the impostor!"))
+ // Check if target is the Saliith plushie
+ if(istype(victim, /obj/item/toy/plush/lizardplushie/saliith))
+ // Warn in local chat
+ visible_message(span_warning("[victim] violently parries the impostor! [src] is utterly annihilated!"))
+
+ // Create a gib effect
new /obj/effect/gibspawner(get_turf(src))
+
+ // Delete the plushling
qdel(src)
+
+ // Return
return
+
+ // Return normally
return ..()
/obj/item/toy/plush/love(obj/item/toy/plush/Kisser, mob/living/user)
- if(user.ckey != "sandpoot")
- if(istype(src, /obj/item/toy/plush/saliith))
- user.show_message(span_notice("[src] refuses socializing with [Kisser]!"), MSG_VISUAL,
- span_notice("That didn't feel like it worked."), NONE)
- return
- if(istype(Kisser, /obj/item/toy/plush/saliith))
- user.show_message(span_notice("[Kisser] refuses socializing with [src]!"), MSG_VISUAL,
- span_notice("That didn't feel like it worked."), NONE)
- return
+ // Define saliith plush
+ var/plush_saliith = /obj/item/toy/plush/lizardplushie/saliith
+
+ // Check if interaction involves the Saliith plush
+ if(istype(src, plush_saliith) || istype(Kisser, plush_saliith))
+ // Check if user is Saliith himself
+ if(user.ckey == "sandpoot")
+ // Return normally
+ return ..()
+
+ // User is not Saliith
+ // Warn in local chat
+ user.visible_message(span_warning("[user] tried to force [Kisser] to kiss [src] against their will, and has been yeeted!"), span_warning("You try to force [Kisser] to kiss [src], but get yeeted instead!"))
+
+ // Display voice of god message
+ say("YEET", spans = list("colossus","yell"))
+
+ // Play sound
+ playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 200, TRUE, 5)
+
+ // Drop the plushies if held
+ if(src in user.held_items)
+ user.dropItemToGround(src)
+ if(Kisser in user.held_items)
+ user.dropItemToGround(Kisser)
+
+ // Launch user away
+ var/turf/yeet_target = get_edge_target_turf(user, pick(GLOB.alldirs))
+ user.throw_at(yeet_target, 10, 14)
+ log_combat(src, user, "plush yeeted")
+
+ // Return
+ return
+
+ // Interaction does not involve Saliith
+ // Return normally
return ..()
+
+// Pinpointer for plushie toy
+/obj/item/pinpointer/plushie_saliith
+ name = "Saliith plushie pinpointer"
+ desc = "A handheld tracking device that locates Saliith's plushie."
+ icon = 'modular_sand/icons/obj/device.dmi'
+ icon_state = "pinpointer_saliith"
+
+/obj/item/pinpointer/plushie_saliith/scan_for_target()
+ set_target(GLOB.saliith_plushie, src)
diff --git a/modular_sand/code/modules/client/loadout/backpack.dm b/modular_sand/code/modules/client/loadout/backpack.dm
new file mode 100644
index 0000000000..c95cbab2c3
--- /dev/null
+++ b/modular_sand/code/modules/client/loadout/backpack.dm
@@ -0,0 +1,3 @@
+/datum/gear/backpack/pinpointer/plushie_saliith
+ name = "Saliith Plushie Pinpointer"
+ path = /obj/item/pinpointer/plushie_saliith
diff --git a/modular_sand/code/modules/reagents/chemistry/reagents/fermi_reagents.dm b/modular_sand/code/modules/reagents/chemistry/reagents/fermi_reagents.dm
new file mode 100644
index 0000000000..903dbbd43c
--- /dev/null
+++ b/modular_sand/code/modules/reagents/chemistry/reagents/fermi_reagents.dm
@@ -0,0 +1,28 @@
+// Plushmium object reaction
+/datum/reagent/fermi/plushmium/reaction_obj(obj/O, reac_volume)
+ // Check for Saliith plush
+ if(istype(O, /obj/item/toy/plush/lizardplushie/saliith))
+ // Check if a carbon user exists
+ if((!usr) || (!iscarbon(usr)))
+ // Return without any effects
+ return
+
+ // Warn in local chat
+ O.loc.visible_message(span_warning("[src] is sprayed with a strange chemical, and reacts with overwhelming hostility! [usr] is sprayed with a concoction of horrible chemicals!"))
+
+ // Define user mob
+ var/mob/living/carbon/human/spray_user = usr
+
+ // Add chemicals
+ spray_user.reagents.add_reagent(/datum/reagent/toxin/mutagen, 20)
+ spray_user.reagents.add_reagent(/datum/reagent/toxin/mindbreaker, 20)
+ spray_user.reagents.add_reagent(/datum/reagent/toxin/mutetoxin, 20)
+ //spray_user.reagents.add_reagent(/datum/reagent/toxin/histamine, 30)
+ spray_user.reagents.add_reagent(/datum/reagent/toxin/bonehurtingjuice, 30)
+ spray_user.reagents.add_reagent(/datum/reagent/toxin/brainhurtingjuice, 30)
+
+ // Return without further effects
+ return
+
+ // Return normally
+ . = ..()
diff --git a/modular_sand/icons/UI_Icons/inventory/socks.png b/modular_sand/icons/UI_Icons/inventory/socks.png
index 9a5be04056..51ce9251de 100644
Binary files a/modular_sand/icons/UI_Icons/inventory/socks.png and b/modular_sand/icons/UI_Icons/inventory/socks.png differ
diff --git a/modular_sand/icons/UI_Icons/inventory/undershirt.png b/modular_sand/icons/UI_Icons/inventory/undershirt.png
index 3f581ec749..4ff410e90b 100644
Binary files a/modular_sand/icons/UI_Icons/inventory/undershirt.png and b/modular_sand/icons/UI_Icons/inventory/undershirt.png differ
diff --git a/modular_sand/icons/UI_Icons/inventory/underwear.png b/modular_sand/icons/UI_Icons/inventory/underwear.png
index b03245044c..1862bee7ca 100644
Binary files a/modular_sand/icons/UI_Icons/inventory/underwear.png and b/modular_sand/icons/UI_Icons/inventory/underwear.png differ
diff --git a/modular_sand/icons/mob/screen_clockwork.dmi b/modular_sand/icons/mob/screen_clockwork.dmi
index aa72185aeb..eefd18fdc5 100644
Binary files a/modular_sand/icons/mob/screen_clockwork.dmi and b/modular_sand/icons/mob/screen_clockwork.dmi differ
diff --git a/modular_sand/icons/mob/screen_liteweb.dmi b/modular_sand/icons/mob/screen_liteweb.dmi
index 15ad6f42c6..80223eaa84 100644
Binary files a/modular_sand/icons/mob/screen_liteweb.dmi and b/modular_sand/icons/mob/screen_liteweb.dmi differ
diff --git a/modular_sand/icons/mob/screen_midnight.dmi b/modular_sand/icons/mob/screen_midnight.dmi
index 1b991bb960..9366925181 100644
Binary files a/modular_sand/icons/mob/screen_midnight.dmi and b/modular_sand/icons/mob/screen_midnight.dmi differ
diff --git a/modular_sand/icons/mob/screen_operative.dmi b/modular_sand/icons/mob/screen_operative.dmi
index 70824ea898..a435e1bece 100644
Binary files a/modular_sand/icons/mob/screen_operative.dmi and b/modular_sand/icons/mob/screen_operative.dmi differ
diff --git a/modular_sand/icons/mob/screen_plasmafire.dmi b/modular_sand/icons/mob/screen_plasmafire.dmi
index 3a07a34232..61d501dbe2 100644
Binary files a/modular_sand/icons/mob/screen_plasmafire.dmi and b/modular_sand/icons/mob/screen_plasmafire.dmi differ
diff --git a/modular_sand/icons/mob/screen_retro.dmi b/modular_sand/icons/mob/screen_retro.dmi
index ba20a9e8bd..a25def4d11 100644
Binary files a/modular_sand/icons/mob/screen_retro.dmi and b/modular_sand/icons/mob/screen_retro.dmi differ
diff --git a/modular_sand/icons/mob/screen_slimecore.dmi b/modular_sand/icons/mob/screen_slimecore.dmi
index a4854f16c3..1b51613f97 100644
Binary files a/modular_sand/icons/mob/screen_slimecore.dmi and b/modular_sand/icons/mob/screen_slimecore.dmi differ
diff --git a/modular_sand/icons/obj/device.dmi b/modular_sand/icons/obj/device.dmi
index 555e379fb6..28b1b5503e 100644
Binary files a/modular_sand/icons/obj/device.dmi and b/modular_sand/icons/obj/device.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 5c12949cc1..11f0778719 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -4011,6 +4011,7 @@
#include "modular_sand\code\game\objects\items\extinguisher.dm"
#include "modular_sand\code\game\objects\items\fleshlight.dm"
#include "modular_sand\code\game\objects\items\miscellaneous.dm"
+#include "modular_sand\code\game\objects\items\plushes.dm"
#include "modular_sand\code\game\objects\items\circuitboards\computer_circuitboards.dm"
#include "modular_sand\code\game\objects\items\circuitboards\machine_circuitboards.dm"
#include "modular_sand\code\game\objects\items\devices\dogborg_sleeper.dm"
@@ -4082,6 +4083,7 @@
#include "modular_sand\code\modules\client\preferences_savefile.dm"
#include "modular_sand\code\modules\client\loadout\_security.dm"
#include "modular_sand\code\modules\client\loadout\accessories.dm"
+#include "modular_sand\code\modules\client\loadout\backpack.dm"
#include "modular_sand\code\modules\client\loadout\boxers.dm"
#include "modular_sand\code\modules\client\loadout\hands.dm"
#include "modular_sand\code\modules\client\loadout\head.dm"
@@ -4203,6 +4205,7 @@
#include "modular_sand\code\modules\reagents\chemistry\reagents\alcohol_reagents.dm"
#include "modular_sand\code\modules\reagents\chemistry\reagents\cit_reagents.dm"
#include "modular_sand\code\modules\reagents\chemistry\reagents\drink_reagents.dm"
+#include "modular_sand\code\modules\reagents\chemistry\reagents\fermi_reagents.dm"
#include "modular_sand\code\modules\reagents\chemistry\reagents\medicine_reagents.dm"
#include "modular_sand\code\modules\reagents\chemistry\reagents\other_reagents.dm"
#include "modular_sand\code\modules\reagents\chemistry\recipes\others.dm"