Files
Bubberstation/code/modules/reagents/reagent_containers/patch.dm
massaheartsu 50499dba9a Adds opium and meth rocks! (#92699)
## About The Pull Request


![demo2](https://github.com/user-attachments/assets/26223fa6-6eb8-43eb-ba87-54be7d2c19b3)<img
width="612" height="185" alt="dreamseeker_SNMvxqCRiR"
src="https://github.com/user-attachments/assets/1d3103e9-edc1-4e50-8793-c8c2ace53aea"
/>

This is a small expansion to narcotics, their production, and presence
in the game! For my esteemed Terry and Manuel/Sybil sector colleagues
I've added:
- 2 new solid drug items: **crystal meth and opium**!
- A **precipitation reaction** for meth after it's been cooled,
producing a solid crystal form, 2u sulfuric acid, 10u meth. **Above 90%
purity, the meth will gain an increasingly blue tint!**
- A production method for opium! Slice a well developed poppy pod with
any sharp item, **before it's fully mature and flowered** to extract a
small amount of opium to enjoy! It's a small container for morphine. Can
be pressed together to combine the concentrations up to 10u, as each
extraction contains trace amounts. Scales off poppy's potency.
- Populated narcotics/contraband spawners with new items, and items that
really should have been on there.
- Added a brand new smoking apparatus, the glass pipe! Can be crafted.
Fixed the transparent pixel.
- **Fixed methsplosions so that now spacemen can finally smoke meth
without exploding!!!** Omegaweed too. Normal methsplosions are
untouched!
- **Expanded the ability for players to insert all drug items into
pipes**, so now players can smoke moon rocks, SaturnX, and my new items!
Previously, only 'dried' items were.
- Fentanyl patch box for narcotics spawner, also for a new ruin I've
made.
- **Expanded these changes to the black market uplink.** 
<img width="640" height="256" alt="demo"
src="https://github.com/user-attachments/assets/c8a0eb2c-b0fa-4e70-b6c1-2e741cd170a2"
/>

Now, players can precipitate meth into a solid form, and produce opium.
I added a lot of these substances and the ones that didn't exist into
spawners that they were partially in, or could reasonably be in. The
opium poppy extraction required a new variable that can be used for
similar interactions too. Crystal sprites are transparent, smoked sprite
has a nice little animation and glow.

These items are now on the black market uplink, in both expensive dealer
shipments of varying rarities for different narcotics, as well as
personal use quantities on a different rotation, at a steeper price.
Expanded randomized spawners to give the black market and ruins more
teeth and edge, without adding another weapon.

Credit to the moon rock guy, I'm just happy I made your stuff smokable!!
<img width="219" height="201" alt="dreamseeker_N8x9bsN3kS"
src="https://github.com/user-attachments/assets/64d23c27-92b9-423b-91ac-903b8476d0b4"
/>


tl;dr added opium and meth
## Why It's Good For The Game
For **too long**, narcotics, chems and stims have been mere integers or
buffs/debuffs in pills or syringes, so I introduced two new methods for
making them and populated niche, criminal vectors with them. These are
real items now, with more interactions. Allowing these to be smoked also
allowed moon rocks and SaturnX to be smoked too, including them into
this and enticing players to have another reason to make them as well.
Buffs with drawbacks, addictions and problems are actually great.

It's a new venue for flavor. I've put thought into the balance for
addition and quantity. It'll add a criminal, or exotic tone to a round,
provide new business opportunities, and new access to stims and chems
without going over the top. Perhaps something peaceful antagonists can
do. More proverbial floor pills give security or command something to
selectively enforce, and absolutely provide novel opportunities for
medical staff!

Also, methsplosions now don't happen in cigarette items! You can smoke
omegaweed without fucking dying!
## Changelog
🆑
add: Added meth, opium, and their production! Also added to black market
uplink.
add: Added a craftable glass pipe.
add: Added to contraband spawners. 
qol: Can now insert any drug item into a pipe.
fix: Spacemen can now smoke meth without exploding!!
/🆑

---------

Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
Co-authored-by: tattle <66640614+dragomagol@users.noreply.github.com>
2025-09-09 01:13:46 +00:00

263 lines
9.7 KiB
Plaintext

/obj/item/reagent_containers/applicator/patch
name = "patch"
desc = "A chemical patch for touch based applications."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "bandaid_blank"
inhand_icon_state = null
possible_transfer_amounts = list()
volume = 40
apply_method = "apply"
embed_type = /datum/embedding/med_patch
// Quick to apply
application_delay = 1.5 SECONDS
self_delay = 1.5 SECONDS
/obj/item/reagent_containers/applicator/patch/canconsume(mob/eater, mob/user)
if(!iscarbon(eater))
return FALSE
var/mob/living/carbon/carbon_eater = eater
var/obj/item/bodypart/affecting = carbon_eater.get_bodypart(check_zone(user.zone_selected))
if(!affecting)
to_chat(user, span_warning("The limb is missing!"))
return FALSE
if(!IS_ORGANIC_LIMB(affecting))
to_chat(user, span_notice("Medicine won't work on an inorganic limb!"))
return FALSE
return TRUE
/obj/item/reagent_containers/applicator/patch/on_consumption(mob/living/carbon/consumer, mob/giver, list/modifiers)
consumer.log_message("Had \a [src] patch applied by [giver], containing the following reagents: [english_list(reagents.reagent_list)].", LOG_GAME)
var/clicked_x = LAZYACCESS(modifiers, ICON_X)
var/clicked_y = LAZYACCESS(modifiers, ICON_Y)
if (isnull(clicked_x))
clicked_x = ICON_SIZE_X * (0.5 + rand(-5, 5) * 0.05)
else
clicked_x = text2num(clicked_x)
if (isnull(clicked_y))
clicked_y = ICON_SIZE_Y * (0.5 + rand(-5, 5) * 0.05)
else
clicked_y = text2num(clicked_y)
giver.do_attack_animation(consumer, used_item = src)
var/datum/embedding/med_patch/embed = get_embed()
if (!istype(embed))
embed = set_embed(/datum/embedding/med_patch)
embed.overlay_x = clicked_x - ICON_SIZE_X * 0.5
embed.overlay_y = clicked_y - ICON_SIZE_Y * 0.5
force_embed(consumer, consumer.get_bodypart(check_zone(giver.zone_selected)) || consumer.get_bodypart(BODY_ZONE_CHEST))
/datum/embedding/med_patch
embed_chance = 10
fall_chance = 0
pain_chance = 0
jostle_chance = 0
pain_mult = 0
jostle_pain_mult = 0
// Quick to rip off
rip_time = 0.25 SECONDS
ignore_throwspeed_threshold = TRUE
immune_traits = null
/// How many units are transferred per second
var/transfer_per_second = 0.75
/// Cooldown for reagent messages, prevents spam
COOLDOWN_DECLARE(reagent_message_cd)
// pixel_x and pixel_y for our overlay
var/overlay_x = 0
var/overlay_y = 0
/// Direction in which mob was facing when the patch was applied, used for layering and positional adjustments
var/applied_dir = NONE
/// Patch overlay applied to the mob
var/mutable_appearance/patch_overlay
/datum/embedding/med_patch/set_owner(mob/living/carbon/victim, obj/item/bodypart/target_limb)
. = ..()
overlay_setup()
RegisterSignal(owner, COMSIG_LIVING_IGNITED, PROC_REF(on_ignited))
RegisterSignal(owner, COMSIG_ATOM_DIR_CHANGE, PROC_REF(on_dir_change))
/datum/embedding/med_patch/stop_embedding()
if (owner)
UnregisterSignal(owner, list(COMSIG_LIVING_IGNITED, COMSIG_ATOM_DIR_CHANGE))
if (patch_overlay)
owner.cut_overlay(patch_overlay)
QDEL_NULL(patch_overlay)
return ..()
/datum/embedding/med_patch/can_embed(atom/movable/source, mob/living/carbon/victim, hit_zone, datum/thrownthing/throwingdatum)
. = ..()
if (!.)
return
var/obj/item/bodypart/affecting = victim.get_bodypart(hit_zone) || victim.bodyparts[1]
if (!IS_ORGANIC_LIMB(affecting))
return FALSE
return TRUE
/datum/embedding/med_patch/proc/on_ignited(datum/source)
SIGNAL_HANDLER
if (!(parent.resistance_flags & FLAMMABLE))
return
if (ishuman(owner))
var/mob/living/carbon/human/as_human = owner
if (as_human.get_thermal_protection() >= FIRE_IMMUNITY_MAX_TEMP_PROTECT)
return
INVOKE_ASYNC(src, PROC_REF(fall_out))
qdel(parent)
/// Create a patch overlay and add it to the mob
/datum/embedding/med_patch/proc/overlay_setup()
applied_dir = owner.dir
patch_overlay = mutable_appearance(parent.icon, parent.icon_state, FLOAT_LAYER, parent, appearance_flags = KEEP_APART|RESET_COLOR)
patch_overlay.color = parent.color
if (parent.cached_color_filter)
patch_overlay = filter_appearance_recursive(patch_overlay, parent.cached_color_filter)
patch_overlay.transform *= 0.5
patch_overlay.pixel_w = overlay_x
patch_overlay.pixel_z = overlay_y
owner.add_overlay(patch_overlay)
/// Changes visual position of the patch based on owner's rotation
/datum/embedding/med_patch/proc/on_dir_change(datum/source, old_dir, new_dir)
SIGNAL_HANDLER
owner.cut_overlay(patch_overlay)
if (new_dir == applied_dir)
patch_overlay.pixel_w = overlay_x
patch_overlay.layer = FLOAT_LAYER
owner.add_overlay(patch_overlay)
return
if (new_dir == REVERSE_DIR(applied_dir))
patch_overlay.pixel_w = -overlay_x
patch_overlay.layer = BELOW_MOB_LAYER
owner.add_overlay(patch_overlay)
return
var/check_dir = EAST
var/check_new_dir = SOUTH
if (applied_dir & (NORTH|SOUTH))
check_dir = NORTH
check_new_dir = EAST
// Turn ourselves based on how we were placed originally
var/dir_sign = (applied_dir & check_dir)
if (overlay_x >= 0)
dir_sign = !dir_sign
if (new_dir & check_new_dir)
dir_sign = !dir_sign
// 0.5 multiplier to fake perspective
patch_overlay.pixel_w = overlay_x * (dir_sign ? 0.5 : -0.5)
patch_overlay.layer = dir_sign ? FLOAT_LAYER : BELOW_MOB_LAYER
owner.add_overlay(patch_overlay)
return
/datum/embedding/med_patch/process_effect(seconds_per_tick)
if (HAS_TRAIT(owner, TRAIT_STASIS))
return
if (!parent.reagents.total_volume)
fall_out()
qdel(parent)
return TRUE
var/show_message = FALSE
if (COOLDOWN_FINISHED(src, reagent_message_cd))
show_message = TRUE
COOLDOWN_START(src, reagent_message_cd, PATCH_MESSAGE_COOLDOWN)
parent.reagents.trans_to(owner, transfer_per_second, methods = PATCH, show_message = show_message)
// delivers all of the patch's contents at once
/datum/embedding/med_patch/instant
transfer_per_second = /obj/item/reagent_containers/applicator/patch::volume
/obj/item/reagent_containers/applicator/patch/libital
name = "libital patch (brute)"
desc = "A pain reliever. Does minor liver damage. Diluted with Granibitaluri."
list_reagents = list(/datum/reagent/medicine/c2/libital = 2, /datum/reagent/medicine/granibitaluri = 8) //10 iterations
icon_state = "bandaid_brute"
/obj/item/reagent_containers/applicator/patch/aiuri
name = "aiuri patch (burn)"
desc = "Helps with burn injuries. Does minor eye damage. Diluted with Granibitaluri."
list_reagents = list(/datum/reagent/medicine/c2/aiuri = 2, /datum/reagent/medicine/granibitaluri = 8)
icon_state = "bandaid_burn"
/obj/item/reagent_containers/applicator/patch/fent
name = "unmarked patch"
desc = "An unmarked, unlabeled transdermal patch for you to wear!"
list_reagents = list(/datum/reagent/toxin/fentanyl = 2)
/obj/item/reagent_containers/applicator/patch/synthflesh
name = "synthflesh patch"
desc = "Helps with brute and burn injuries. Slightly toxic. Three patches applied can restore a corpse husked by burns."
list_reagents = list(/datum/reagent/medicine/c2/synthflesh = 20)
list_reagents_purity = 1
icon_state = "bandaid_both"
embed_type = /datum/embedding/med_patch/instant //synthflesh effects occur on the initial apply only, so we need to apply it all at once
/obj/item/reagent_containers/applicator/patch/canconsume(mob/eater, mob/user)
. = ..()
if(!iscarbon(eater))
return
var/datum/reagent/medicine/c2/synthflesh/synthflesh_patch = reagents.has_reagent(/datum/reagent/medicine/c2/synthflesh)
if(!synthflesh_patch)
return
// Check mob damage for synthflesh unhusking
var/mob/living/carbon/carbies = eater
if(HAS_TRAIT_FROM(carbies, TRAIT_HUSK, BURN) && carbies.getFireLoss() > UNHUSK_DAMAGE_THRESHOLD * 2.5)
// give them a warning if the mob is a husk but synthflesh won't unhusk yet
carbies.visible_message(span_boldwarning("[carbies]'s burns need to be repaired first before synthflesh will unhusk it!"))
/obj/item/reagent_containers/applicator/patch/ondansetron
name = "ondansetron patch"
desc = "Alleviates nausea. May cause drowsiness."
list_reagents = list(/datum/reagent/medicine/ondansetron = 10)
icon_state = "bandaid_toxin"
// Patch styles for chem master
/obj/item/reagent_containers/applicator/patch/style
icon_state = "bandaid_blank"
/obj/item/reagent_containers/applicator/patch/style/brute
icon_state = "bandaid_brute_2"
/obj/item/reagent_containers/applicator/patch/style/burn
icon_state = "bandaid_burn_2"
/obj/item/reagent_containers/applicator/patch/style/bruteburn
icon_state = "bandaid_both"
/obj/item/reagent_containers/applicator/patch/style/toxin
icon_state = "bandaid_toxin_2"
/obj/item/reagent_containers/applicator/patch/style/oxygen
icon_state = "bandaid_suffocation_2"
/obj/item/reagent_containers/applicator/patch/style/omni
icon_state = "bandaid_mix"
/obj/item/reagent_containers/applicator/patch/style/bruteplus
icon_state = "bandaid_brute"
/obj/item/reagent_containers/applicator/patch/style/burnplus
icon_state = "bandaid_burn"
/obj/item/reagent_containers/applicator/patch/style/toxinplus
icon_state = "bandaid_toxin"
/obj/item/reagent_containers/applicator/patch/style/oxygenplus
icon_state = "bandaid_suffocation"
/obj/item/reagent_containers/applicator/patch/style/monkey
icon_state = "bandaid_monke"
/obj/item/reagent_containers/applicator/patch/style/clown
icon_state = "bandaid_clown"
/obj/item/reagent_containers/applicator/patch/style/one
icon_state = "bandaid_1"
/obj/item/reagent_containers/applicator/patch/style/two
icon_state = "bandaid_2"
/obj/item/reagent_containers/applicator/patch/style/three
icon_state = "bandaid_3"
/obj/item/reagent_containers/applicator/patch/style/four
icon_state = "bandaid_4"
/obj/item/reagent_containers/applicator/patch/style/exclamation
icon_state = "bandaid_exclaimationpoint"
/obj/item/reagent_containers/applicator/patch/style/question
icon_state = "bandaid_questionmark"
/obj/item/reagent_containers/applicator/patch/style/colonthree
icon_state = "bandaid_colonthree"