From e88e6eb37e68c6b0accdc8e1c488b03e290586fa Mon Sep 17 00:00:00 2001 From: Reo Lozzot <84661000+ReoDaProtovali@users.noreply.github.com> Date: Tue, 1 Jul 2025 05:19:31 -0500 Subject: [PATCH] Unglogs Soap and makes it work similar to how it used to (#17868) * real * I forgot to save DMI changes ! epic * Soap names, afterattack() cleanup and lye, Oh my! fnnuy * Better handling of conflicting recipes. oiter --- code/__defines/_reagents.dm | 2 + code/game/objects/items/soap.dm | 183 +++++++++--------- code/game/objects/structures/watercloset.dm | 6 + .../reagents/reactions/instant/instant.dm | 33 ++++ code/modules/reagents/reagents/other.dm | 8 + icons/obj/soap.dmi | Bin 22997 -> 23631 bytes 6 files changed, 138 insertions(+), 94 deletions(-) diff --git a/code/__defines/_reagents.dm b/code/__defines/_reagents.dm index bd947977d7..fb2a736b2b 100644 --- a/code/__defines/_reagents.dm +++ b/code/__defines/_reagents.dm @@ -374,6 +374,8 @@ #define REAGENT_ID_AMMONIA "ammonia" #define REAGENT_DIETHYLAMINE "Diethylamine" #define REAGENT_ID_DIETHYLAMINE "diethylamine" +#define REAGENT_LYE "Lye" +#define REAGENT_ID_LYE "lye" #define REAGENT_FLUOROSURFACTANT "Fluorosurfactant" #define REAGENT_ID_FLUOROSURFACTANT "fluorosurfactant" #define REAGENT_FOAMINGAGENT "Foaming agent" diff --git a/code/game/objects/items/soap.dm b/code/game/objects/items/soap.dm index 041a2b3f32..8d22474d29 100644 --- a/code/game/objects/items/soap.dm +++ b/code/game/objects/items/soap.dm @@ -4,7 +4,7 @@ gender = PLURAL icon = 'icons/obj/soap.dmi' icon_state = "soap" - flags = NOCONDUCT + flags = NOCONDUCT | NOBLUDGEON w_class = ITEMSIZE_SMALL slot_flags = SLOT_HOLSTER throwforce = 0 @@ -14,205 +14,200 @@ var/randomize = TRUE var/square_chance = 10 var/cleanspeed = 35 - var/uses = 100 + var/bites = 0 /obj/item/soap/Initialize(mapload) if(randomize && prob(square_chance)) icon_state = "[icon_state]-alt" create_reagents(5) - wet() . = ..() -/obj/item/soap/examine(mob/user) - . = ..() - var/max_uses = initial(uses) - var/msg = "It looks like it just came out of the package." - if(uses != max_uses) - var/percentage_left = uses / max_uses - switch(percentage_left) - if(0 to 0.15) - msg = "There's just a tiny bit left of what it used to be, you're not sure it'll last much longer." - if(0.15 to 0.30) - msg = "It's dissolved quite a bit, but there's still some life to it." - if(0.30 to 0.50) - msg = "It's past its prime, but it's definitely still good." - if(0.50 to 0.75) - msg = "It's started to get a little smaller than it used to be, but it'll definitely still last for a while." - else - msg = "It's seen some light use, but it's still pretty fresh." - . += span_notice("[msg]") - -/obj/item/soap/proc/wet() - reagents.add_reagent(REAGENT_ID_CLEANER, 5) +/obj/item/soap/proc/wet(var/cleaner = FALSE) + if(cleaner) + reagents.add_reagent(REAGENT_ID_CLEANER, 5) + else + reagents.add_reagent(REAGENT_ID_WATER, 5) //full of wet... /obj/item/soap/Crossed(atom/movable/AM as mob|obj) if(AM.is_incorporeal()) return if(isliving(AM)) var/mob/living/M = AM - M.slip("the [src.name]",3) + M.slip("\the [src.name]",3) /obj/item/soap/afterattack(atom/target, mob/user as mob, proximity) . = ..() + if(ishuman(target) && user.zone_sel.selecting == O_MOUTH) + if(target == user) + to_chat(user, span_warning("You raise the soap to your mouth and prepare to take a bite...")) + if(do_after(user, 5)) //Mercy against accidental chomps + user.visible_message(span_notice("[user] takes a bite out of [src]!"), span_notice("You gnaw on [src]! This can't be good for you...")) + var/mob/living/carbon/C = user + playsound(get_turf(C), 'sound/items/eatfood.ogg', 25, 0) + C.ingested.add_reagent(/datum/reagent/toxin, 0.5) //normally formaldehyde, and 2 units of it. Toxin is being subsituted and is 4 times as toxic, hence a quarter of the normal amount. + C.ingested.add_reagent(/datum/reagent/chloralhydrate, 3) + reagents.trans_to_holder(C.ingested, 1) + bites++ + if(bites >= 5) + qdel(src) + else + user.visible_message(span_danger("\The [user] washes \the [target]'s mouth out with \the [src]!")) + //Add pieface cleaning here if that ever gets ported. + user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) + return if(!proximity) return //I couldn't feasibly fix the overlay bugs caused by cleaning items we are wearing. //So this is a workaround. This also makes more sense from an IC standpoint. ~Carn if(user.client && (target in user.client.screen)) - to_chat(user, span_warning("You need to take that [target.name] off before cleaning it.")) + to_chat(user, span_warning("You need to take that [target] off before cleaning it.")) else if(istype(target,/obj/effect/decal/cleanable)) - user.visible_message("[user] begins to scrub \the [target.name] out with [src].", span_warning("You begin to scrub \the [target.name] out with [src]...")) + user.visible_message("[user] begins to scrub \the [target] out with [src].", span_warning("You begin to scrub \the [target] out with [src]...")) if(do_after(user, src.cleanspeed, target = target)) - to_chat(user, span_notice("You scrub \the [target.name] out.")) + to_chat(user, span_notice("You scrub \the [target] out.")) qdel(target) - decreaseUses(user) - else if(istype(target,/turf)) - user.visible_message("[user] begins to scrub \the [target.name] out with [src].", span_warning("You begin to scrub \the [target.name] out with [src]...")) - if(do_after(user, src.cleanspeed, target = target)) - to_chat(user, span_notice("You scrub \the [target.name] clean.")) - var/turf/T = target - T.wash(CLEAN_SCRUB) - reagents.trans_to_turf(T, 1, 10) - decreaseUses(user) - else if(ishuman(target) && user.zone_sel.selecting == O_MOUTH) - if(target == user) - var/mob/living/carbon/human/H = user - to_chat(user, span_notice("You take a bite of \the [src] and swallow it.")) - reagents.trans_to_holder(H.ingested, 1) - else - user.visible_message(span_danger("\The [user] washes \the [target]'s mouth out with \the [src]!")) - user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) - decreaseUses(user, 5) - else if(istype(target,/obj/structure/sink)) - to_chat(user, span_notice("You wet \the [src] in the sink.")) - wet() else + if(istype(target,/turf)) + if(reagents.has_reagent(REAGENT_ID_WATER, 1) || reagents.has_reagent(REAGENT_ID_CLEANER, 1)) //Instant floorcleaning with wetness + user.visible_message("[user] effortlessly scrubs \the [target] out with wet [src]", span_notice("You effortlessly scrub \the [target]")) + var/turf/T = target + T.wash(CLEAN_SCRUB) + reagents.trans_to_turf(T, 1, 10) + return + user.visible_message("[user] begins to scrub \the [target] out with [src].", span_warning("You begin to scrub \the [target] out with [src]...")) + if(do_after(user, src.cleanspeed, target = target)) + to_chat(user, span_notice("You scrub \the [target] clean.")) + var/turf/T = target + T.wash(CLEAN_SCRUB) + reagents.trans_to_turf(T, 1, 10) + return user.visible_message("[user] begins to clean \the [target.name] with [src]...", span_notice("You begin to clean \the [target.name] with [src]...")) if(do_after(user, src.cleanspeed, target = target)) target.wash(CLEAN_SCRUB) - decreaseUses(user) return -/obj/item/soap/proc/decreaseUses(mob/user, var/used_up = 1) - uses -= used_up - if(uses <= 0) - to_chat(user, span_warning("[src] crumbles into tiny bits!")) - qdel(src) - /obj/item/soap/nanotrasen name = "Soap (Nanotrasen)" - desc = "A NanoTrasen-brand bar of soap. Smells of phoron, a years-old marketing gimmick." + desc = "" icon_state = "soapnt" - cleanspeed = 28 - uses = 300 // Good soap, good soap + cleanspeed = 28 //janitor gets this + +/obj/item/soap/nanotrasen/examine(mob/user) + . = ..() + if(prob(1)) // Mandela effect + . += "A heavy duty bar of Nanotrasen brand soap. Smells of plasma, a years-old marketing gimmick." + else + . += "A heavy duty bar of Nanotrasen brand soap. Smells of phoron, a years-old marketing gimmick." + +/obj/item/soap/homemade + desc = "A homemade bar of soap. Smells of... well..." + icon_state = "soapgibs" + cleanspeed = 30 // faster to reward chemists for going to the effort + randomize = FALSE //No square sprite for it. /obj/item/soap/deluxe name = "Soap (Deluxe)" + desc = "A deluxe Waffle Co. brand bar of soap. Smells of high-class luxury." icon_state = "soapdeluxe" - uses = 150 // Good soap - cleanspeed = 20 // But fast too - -/obj/item/soap/deluxe/Initialize(mapload) - . = ..() - desc = "A deluxe Waffle Co. brand bar of soap. Smells of [pick("lavender", "vanilla", "strawberry", "chocolate" ,"space")]." + cleanspeed = 20 //captain gets one of these /obj/item/soap/syndie name = "Soap (Syndicate)" - desc = "An untrustworthy bar of soap. Smells of fear." + desc = "An untrustworthy bar of soap made of strong chemical agents that dissolve blood faster. Smells of fear." icon_state = "soapsyndie" - cleanspeed = 5 // Nyoom soap + cleanspeed = 5 //faster than mop so it is useful for traitors who want to clean crime scenes /obj/item/soap/space_soap name = "Soap (Space)" - desc = "Smells like hot metal and walnuts." + desc = "A space-like bar of soap. Smells like hot metal and walnuts." icon_state = "space_soap" /obj/item/soap/water_soap name = "Soap (Pool)" - desc = "Smells like chlorine." + desc = "A watery bar of soap. Smells like chlorine." icon_state = "water_soap" /obj/item/soap/fire_soap name = "Soap (Fire)" - desc = "Smells like a campfire." + desc = "A firey bar of soap. Smells like a campfire." icon_state = "fire_soap" /obj/item/soap/rainbow_soap name = "Soap (Rainbow)" - desc = "Smells sickly sweet." + desc = "A rainbow bar of soap. Smells sickly sweet." icon_state = "rainbow_soap" /obj/item/soap/diamond_soap name = "Soap (Diamond)" - desc = "Smells like saffron and vanilla." + desc = "A diamond-like bar of soap. Smells like saffron and vanilla." icon_state = "diamond_soap" /obj/item/soap/uranium_soap name = "Soap (Uranium)" - desc = "Smells not great... Not terrible." + desc = "An irradiated bar of soap. Smells not great... Not terrible." icon_state = "uranium_soap" /obj/item/soap/silver_soap name = "Soap (Silver)" - desc = "Smells like birch and amaranth." + desc = "A silvery bar of soap. Smells like birch and amaranth." icon_state = "silver_soap" /obj/item/soap/brown_soap name = "Soap (Brown)" - desc = "Smells like cinnamon and cognac." + desc = "A brown bar of soap. Smells like cinnamon and cognac." icon_state = "brown_soap" /obj/item/soap/white_soap - name = "Soap (Nutty)" - desc = "Smells like nutmeg and oats." + name = "Soap (White)" + desc = "A white bar of soap. Smells like nutmeg and oats." icon_state = "white_soap" /obj/item/soap/grey_soap name = "Soap (Grey)" - desc = "Smells like bergamot and lilies." + desc = "A grey bar of soap. Smells like bergamot and lilies." icon_state = "grey_soap" /obj/item/soap/pink_soap - name = "Soap (Gum)" - desc = "Smells like bubblegum." + name = "Soap (Pink)" + desc = "A pink bar of soap. Smells like bubblegum." icon_state = "pink_soap" /obj/item/soap/purple_soap - name = "Soap (Lavender)" - desc = "Smells like lavender." + name = "Soap (Purple)" + desc = "A purple bar of soap. Smells like lavender." icon_state = "purple_soap" /obj/item/soap/blue_soap name = "Soap (Blue)" - desc = "Smells like cardamom." + desc = "A blue bar of soap. Smells like cardamom." icon_state = "blue_soap" /obj/item/soap/cyan_soap - name = "Soap (Berries)" - desc = "Smells like bluebells and peaches." + name = "Soap (Cyan)" + desc = "A cyan bar of soap. Smells like bluebells and peaches." icon_state = "cyan_soap" /obj/item/soap/green_soap - name = "Soap (Grass)" - desc = "Smells like a freshly mowed lawn." + name = "Soap (Green)" + desc = "A green bar of soap. Smells like a freshly mowed lawn." icon_state = "green_soap" /obj/item/soap/yellow_soap - name = "Soap (Lemon)" - desc = "Smells like citron and ginger." + name = "Soap (Yellow)" + desc = "A yellow bar of soap. Smells like citron and ginger." icon_state = "yellow_soap" /obj/item/soap/orange_soap name = "Soap (Orange)" - desc = "Smells like oranges and dark chocolate." + desc = "An orange bar of soap. Smells like oranges and dark chocolate." icon_state = "orange_soap" /obj/item/soap/red_soap - name = "Soap (Orange)" - desc = "Smells like cherries." + name = "Soap (Red)" + desc = "A red bar of soap. Smells like cherries." icon_state = "red_soap" /obj/item/soap/golden_soap - name = "Soap (Honey)" - desc = "Smells like honey." + name = "Soap (Gold)" + desc = "A golden bar of soap. Smells like honey." icon_state = "golden_soap" diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 9cb17b244a..95197df87c 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -605,6 +605,12 @@ to_chat(user, span_notice("You wet \the [O] in \the [src].")) playsound(src, 'sound/effects/slosh.ogg', 25, 1) return + else if(istype(O, /obj/item/soap)) + var/obj/item/soap/soap = O + to_chat(user, span_notice("You wet \the [O] in \the [src]")) + soap.wet() + O.wash(CLEAN_SCRUB) + return var/turf/location = user.loc if(!isturf(location)) return diff --git a/code/modules/reagents/reactions/instant/instant.dm b/code/modules/reagents/reactions/instant/instant.dm index 9fb1c92382..50a16b8c9c 100644 --- a/code/modules/reagents/reactions/instant/instant.dm +++ b/code/modules/reagents/reactions/instant/instant.dm @@ -76,6 +76,7 @@ id = REAGENT_ID_WATER result = REAGENT_ID_WATER required_reagents = list(REAGENT_ID_OXYGEN = 1, REAGENT_ID_HYDROGEN = 2) + inhibitors = list(REAGENT_ID_SODIUM = 1) // So it doesnt turn into water when you try to make lye. result_amount = 1 /decl/chemical_reaction/instant/thermite @@ -439,6 +440,13 @@ required_reagents = list (REAGENT_ID_AMMONIA = 1, REAGENT_ID_ETHANOL = 1) result_amount = 2 +/decl/chemical_reaction/instant/lye + name = REAGENT_LYE + id = REAGENT_ID_LYE + result = REAGENT_ID_LYE + required_reagents = list(REAGENT_ID_SODIUM = 1, REAGENT_ID_HYDROGEN = 1, REAGENT_ID_OXYGEN = 1) + result_amount = 3 + /decl/chemical_reaction/instant/left4zed name = "Left4Zed" id = REAGENT_ID_LEFT4ZED @@ -637,6 +645,31 @@ new /obj/item/stack/material/plastic(get_turf(holder.my_atom), created_volume) return +/decl/chemical_reaction/instant/soapification + name = "Soapification" + id = "soapification" + result = null + required_reagents = list(REAGENT_ID_COOKINGOIL = 10, REAGENT_ID_LYE = 2) + result_amount = 1 + +/decl/chemical_reaction/instant/soapification/on_reaction(var/datum/reagents/holder, var/created_volume) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/soap(get_turf(holder.my_atom)) + +/decl/chemical_reaction/instant/soapification/alt + name = "Soapification2" + id = "soapification2" + required_reagents = list(REAGENT_ID_CORNOIL = 10, REAGENT_ID_LYE = 2) + +/decl/chemical_reaction/instant/soapification/gibs // a bit less convinient and grosser, but it makes more potent soap. + name = "Soapification Gibs" + id = "soapificationgibs" + required_reagents = list(REAGENT_ID_PROTEIN = 10, REAGENT_ID_LYE = 10) //Change the protein to liquid gibs if/when those get ported. Thanks. + +/decl/chemical_reaction/instant/soapification/gibs/on_reaction(datum/reagents/holder, created_volume) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/soap/homemade(get_turf(holder.my_atom)) + /*Carpet Creation*/ /decl/chemical_reaction/instant/carpetify diff --git a/code/modules/reagents/reagents/other.dm b/code/modules/reagents/reagents/other.dm index 0805a02b31..53493744f9 100644 --- a/code/modules/reagents/reagents/other.dm +++ b/code/modules/reagents/reagents/other.dm @@ -390,6 +390,14 @@ reagent_state = LIQUID color = "#604030" +/datum/reagent/lye + name = REAGENT_LYE + id = REAGENT_ID_LYE + description = "Also known as sodium hydroxide. As a profession making this is somewhat underwhelming." + taste_description = "acid" + reagent_state = LIQUID + color = "#FFFFD6" // very very light yellow" + /datum/reagent/fluorosurfactant // Foam precursor name = REAGENT_FLUOROSURFACTANT id = REAGENT_ID_FLUOROSURFACTANT diff --git a/icons/obj/soap.dmi b/icons/obj/soap.dmi index 23a7bf2394afbc6a2a872d8818a250268493c3ce..cc31b4a13a7ffa51f86308a61a35ec42d9707dd6 100644 GIT binary patch delta 5077 zcma)AXE-mUG~W zpFDo^`Vb+)A_l)POhQs&NXiB!yU|_Yp(0KRB*cHJXFYbRXn4{+;PF;~Uxgto63X34 z@kve879NO7*MK=IG*&l#(&u}ez&pt`aCoegK-j@N4HT`uZ8T->n#7fGm9pGegga_A zDIEG%U;xI=GchCTP|>}L*=mFc`lZeMifT{ZKg^QO_EwS!!uDt3x`gI}wvUkNR`)aj zJfd)?nB;I*`?61Z_Ps^8sHmv098J%#`GV`{vLB+YYcBIKZWuc;?A_+d<#Z3E* zS<#o;SXg`=X5OUq?Ct4E`5qM&MaOJUz_|9Bb8=IT3mS^z!Pc3^+6?O?TJh1 zwa@8Rnkte77@j;%9*>2^6O$fY-^i}piGks@ z62~ba-AvqkA>vt#NRs(40hc#guOywm(tPMmfdJ^bS)uFK7rz9kx%7s#up*Fv%`tb@ zyK_xtmB1gL%T1kl@Z?lNmT@ja1;UFcXEv&;yic6^)m|%F`QLv0P==|?F4zToF1W5* zO1yKQrAkm{+TCmPB=N{(pNyyTn^FFn`h6%ns)v$~f3Zd}EAPEdo1p2-Cyt*Qiquoo zVj@iJLHHdU9g|X1BfA|ITO+9fwm0g~&}WyrRKrBgYE2y-9hq2IqEN*GT+rqT)!?mQ z9V$ji_$z24v)ll$m@v9Kx?402lC3)?U~VBH`PWxUK_>OMHad88{H4m<2L8<*X84HV%IEtG3_U?J3*s65~uR2vsAPt`1#5+!rO=#X$RG zS&%irxW;#W`{lpyh>XQDHp?r(+{8{u{!(>GpOE!5ElFgQr}vrmA^#>jsGRZh+t`{; z#NE83*-a?$vb0)lnm3rtqPzcaqWQ*sUmP3$j9tyo;LYt=CaTg->gHoUblixkv~ebkzQp(%Y47_8V!{{hU&G-^7?l>`?}wA1Bw}M zigiCrcRt+PDwiKyIXE2ik)=YWIbNtIq+;m;Ca?oMf zlQxR_h6Z5~k=*KPG-%K>HZFiE%bJ;)ftY`L*i5(DpY;{^ua7~?{ji*Ypy+uhT^uqz zBSKYN+gh|e6CFR&T&SN@ZbzV6?K^5Vb{BWHt#nj

MC0T6dj1c{#7g&va&7p^*2>_1@C9b1Rcf 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 M8hYRwHQUJl0>h}liU0rr