makes xenobio stuff use interact_with_atom (#93918)

## About The Pull Request
Makes slime potions, injector, and cookies use item_interaction.
generizices behavoir that potions typed under
`obj/item/slimepotion/slime/` only affect slimes, moves the handful of
potions that did not do that out of that type.
removed a random type casting for slime cookies to verify there human
before it checks for `TRAIT_AGEUSIA` as there is no reason other mobs
wouldn't be able to taste it.
do to the refactor you wont "bash" a lot of items if the interaction
fails.

## Why It's Good For The Game
<img width="439" height="68" alt="image"
src="https://github.com/user-attachments/assets/f398fb6c-8cbd-4092-9a64-8cccce87f8b6"
/>
This commit is contained in:
FalloutFalcon
2025-11-20 19:06:23 -06:00
committed by GitHub
parent 94dd056a3b
commit 5eeb3e4d53
10 changed files with 210 additions and 179 deletions
@@ -34,6 +34,6 @@
cost_per_order = 525
/datum/orderable_item/toys_drones/drone_sentience
purchase_path = /obj/item/slimepotion/slime/sentience/mining
purchase_path = /obj/item/slimepotion/sentience/mining
cost_per_order = 850
@@ -889,7 +889,7 @@
/obj/item/storage/box/syndicate/horse_box/PopulateContents()
new /obj/item/food/monkeycube/dangerous_horse(src)
new /obj/item/slimepotion/slime/sentience/nuclear/dangerous_horse(src)
new /obj/item/slimepotion/sentience/nuclear/dangerous_horse(src)
new /obj/item/food/grown/apple(src)
/obj/item/storage/box/syndicate/sleeping_carp/PopulateContents()
+1 -1
View File
@@ -51,7 +51,7 @@ GLOBAL_LIST_INIT(high_priority_sentience, typecacheof(list(
priority_announce(sentience_report,"[command_name()] Medium-Priority Update")
/datum/round_event/ghost_role/sentience/spawn_role()
var/list/mob/dead/observer/candidates = SSpolling.poll_ghost_candidates(check_jobban = ROLE_SENTIENCE, role = ROLE_SENTIENCE, alert_pic = /obj/item/slimepotion/slime/sentience, role_name_text = role_name)
var/list/mob/dead/observer/candidates = SSpolling.poll_ghost_candidates(check_jobban = ROLE_SENTIENCE, role = ROLE_SENTIENCE, alert_pic = /obj/item/slimepotion/sentience, role_name_text = role_name)
if(!length(candidates))
return NOT_ENOUGH_PLAYERS
@@ -36,7 +36,7 @@
//AI
/obj/item/slimepotion/slime/sentience/mining
/obj/item/slimepotion/sentience/mining
name = "minebot AI upgrade"
desc = "Can be used to grant sentience to minebots. It's incompatible with minebot armor and melee upgrades, and will override them."
icon_state = "door_electronics"
@@ -51,7 +51,7 @@
///cooldown boost to add
var/base_cooldown_add = 10
/obj/item/slimepotion/slime/sentience/mining/after_success(mob/living/user, mob/living/basic_mob)
/obj/item/slimepotion/sentience/mining/after_success(mob/living/user, mob/living/basic_mob)
if(!istype(basic_mob, /mob/living/basic/mining_drone))
return
var/mob/living/basic/mining_drone/minebot = basic_mob
@@ -409,7 +409,7 @@
required_reagents = list(/datum/reagent/toxin/plasma = 1)
/datum/chemical_reaction/slime/slimepotion2/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/slime/sentience(get_turf(holder.my_atom))
new /obj/item/slimepotion/sentience(get_turf(holder.my_atom))
..()
/datum/chemical_reaction/slime/renaming
@@ -417,7 +417,7 @@
required_reagents = list(/datum/reagent/water = 1)
/datum/chemical_reaction/slime/renaming/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/slime/renaming(holder.my_atom.drop_location())
new /obj/item/slimepotion/renaming(holder.my_atom.drop_location())
..()
@@ -454,7 +454,7 @@
required_container = /obj/item/slime_extract/bluespace
/datum/chemical_reaction/slime/slimeradio/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/slime/slimeradio(get_turf(holder.my_atom))
new /obj/item/slimepotion/slimeradio(get_turf(holder.my_atom))
..()
//Cerulean
@@ -142,24 +142,27 @@ To add a crossbreed:
. = ..()
reagents.flags = DRAWABLE // Cannot be refilled, since it's basically an autoinjector!
/obj/item/slimecrossbeaker/autoinjector/attack(mob/living/M, mob/user)
/obj/item/slimecrossbeaker/autoinjector/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
if(!iscarbon(interacting_with))
return NONE
var/mob/living/carbon/injecting_mob = interacting_with
if(!reagents.total_volume)
to_chat(user, span_warning("[src] is empty!"))
return
if(!iscarbon(M))
return
if(self_use_only && M != user)
return ITEM_INTERACT_BLOCKING
if(self_use_only && injecting_mob != user)
to_chat(user, span_warning("This can only be used on yourself."))
return
if(reagents.total_volume && (ignore_flags || M.try_inject(user, injection_flags = INJECT_TRY_SHOW_ERROR_MESSAGE)))
reagents.trans_to(M, reagents.total_volume, transferred_by = user)
if(user != M)
to_chat(M, span_warning("[user] presses [src] against you!"))
to_chat(user, span_notice("You press [src] against [M], injecting [M.p_them()]."))
return ITEM_INTERACT_BLOCKING
if(reagents.total_volume && (ignore_flags || injecting_mob.try_inject(user, injection_flags = INJECT_TRY_SHOW_ERROR_MESSAGE)))
reagents.trans_to(injecting_mob, reagents.total_volume, transferred_by = user)
if(user != injecting_mob)
to_chat(injecting_mob, span_warning("[user] presses [src] against you!"))
to_chat(user, span_notice("You press [src] against [injecting_mob], injecting [injecting_mob.p_them()]."))
else
to_chat(user, span_notice("You press [src] against yourself, and it flattens against you!"))
return ITEM_INTERACT_SUCCESS
else
to_chat(user, span_warning("There's no place to stick [src]!"))
return ITEM_INTERACT_BLOCKING
/obj/item/slimecrossbeaker/autoinjector/regenpack
ignore_flags = TRUE //It is, after all, intended to heal.
@@ -8,7 +8,6 @@ Slimecrossing Potions
/obj/item/slimepotion/extract_cloner
name = "extract cloning potion"
desc = "A more powerful version of the extract enhancer potion, capable of cloning regular slime extracts."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potgold"
/obj/item/slimepotion/extract_cloner/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
@@ -35,16 +34,19 @@ Slimecrossing Potions
/obj/item/slimepotion/peacepotion
name = "pacification potion"
desc = "A light pink solution of chemicals, smelling like liquid peace. And mercury salts."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potlightpink"
/obj/item/slimepotion/peacepotion/attack(mob/living/peace_target, mob/user)
/obj/item/slimepotion/peacepotion/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
. = ..()
if(. & ITEM_INTERACT_ANY_BLOCKER)
return .
var/mob/living/peace_target = interacting_with
if(!isliving(peace_target) || peace_target.stat == DEAD)
to_chat(user, span_warning("[src] only works on the living."))
return ..()
return ITEM_INTERACT_BLOCKING
if(ismegafauna(peace_target))
to_chat(user, span_warning("[src] does not work on beings of pure evil!"))
return ..()
return ITEM_INTERACT_BLOCKING
if(peace_target != user)
peace_target.visible_message(span_danger("[user] starts to feed [peace_target] [src]!"),
span_userdanger("[user] starts to feed you [src]!"))
@@ -53,7 +55,7 @@ Slimecrossing Potions
span_danger("You start to drink [src]!"))
if(!do_after(user, 10 SECONDS, target = peace_target))
return
return ITEM_INTERACT_BLOCKING
if(peace_target != user)
to_chat(user, span_notice("You feed [peace_target] [src]!"))
else
@@ -64,44 +66,48 @@ Slimecrossing Potions
var/mob/living/carbon/peaceful_carbon = peace_target
peaceful_carbon.gain_trauma(/datum/brain_trauma/severe/pacifism, TRAUMA_RESILIENCE_SURGERY)
qdel(src)
return ITEM_INTERACT_SUCCESS
//Love potion - Charged Pink
/obj/item/slimepotion/lovepotion
name = "love potion"
desc = "A pink chemical mix thought to inspire feelings of love."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potpink"
/obj/item/slimepotion/lovepotion/attack(mob/living/love_target, mob/user)
/obj/item/slimepotion/lovepotion/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
. = ..()
if(. & ITEM_INTERACT_ANY_BLOCKER)
return .
var/mob/living/love_target = interacting_with
if(!isliving(love_target) || love_target.stat == DEAD)
to_chat(user, span_warning("The love potion only works on living things, sicko!"))
return ..()
return ITEM_INTERACT_BLOCKING
if(ismegafauna(love_target))
to_chat(user, span_warning("The love potion does not work on beings of pure evil!"))
return ..()
return ITEM_INTERACT_BLOCKING
if(user == love_target)
to_chat(user, span_warning("You can't drink the love potion. What are you, a narcissist?"))
return ..()
return ITEM_INTERACT_BLOCKING
if(love_target.has_status_effect(/datum/status_effect/in_love))
to_chat(user, span_warning("[love_target] is already lovestruck!"))
return ..()
return ITEM_INTERACT_BLOCKING
love_target.visible_message(span_danger("[user] starts to feed [love_target] a love potion!"),
span_userdanger("[user] starts to feed you a love potion!"))
if(!do_after(user, 5 SECONDS, target = love_target))
return
return ITEM_INTERACT_BLOCKING
to_chat(user, span_notice("You feed [love_target] the love potion!"))
to_chat(love_target, span_notice("You develop feelings for [user], and anyone [user.p_they()] like[user.p_s()]."))
love_target.faction |= "[REF(user)]"
love_target.apply_status_effect(/datum/status_effect/in_love, user)
qdel(src)
return ITEM_INTERACT_SUCCESS
//Pressure potion - Charged Dark Blue
/obj/item/slimepotion/spaceproof
name = "slime pressurization potion"
desc = "A potent chemical sealant that will render any article of clothing airtight. Has two uses."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potblack"
var/uses = 2
@@ -138,14 +144,12 @@ Slimecrossing Potions
/obj/item/slimepotion/enhancer/max
name = "extract maximizer"
desc = "An extremely potent chemical mix that will maximize a slime extract's uses."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potcerulean"
//Lavaproofing potion - Charged Red
/obj/item/slimepotion/lavaproof
name = "slime lavaproofing potion"
desc = "A strange, reddish goo said to repel lava as if it were water, without reducing flammability. Has two uses."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potyellow"
resistance_flags = LAVA_PROOF | FIRE_PROOF
var/uses = 2
@@ -180,7 +184,6 @@ Slimecrossing Potions
/obj/item/slimepotion/slime_reviver
name = "slime revival potion"
desc = "Infused with plasma and compressed gel, this brings dead slimes back to life."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potgrey"
/obj/item/slimepotion/slime_reviver/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
@@ -211,20 +214,17 @@ Slimecrossing Potions
/obj/item/slimepotion/slime/chargedstabilizer
name = "slime omnistabilizer"
desc = "An extremely potent chemical mix that will stop a slime from mutating completely."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potcyan"
/obj/item/slimepotion/slime/chargedstabilizer/attack(mob/living/basic/slime/stabilize_target, mob/user)
if(!isslime(stabilize_target))
to_chat(user, span_warning("The stabilizer only works on slimes!"))
return ..()
if(stabilize_target.stat)
/obj/item/slimepotion/slime/chargedstabilizer/interact_with_slime(mob/living/basic/slime/interacting_slime, mob/living/user, list/modifiers)
if(interacting_slime.stat)
to_chat(user, span_warning("The slime is dead!"))
return
if(stabilize_target.mutation_chance == 0)
return ITEM_INTERACT_BLOCKING
if(interacting_slime.mutation_chance == 0)
to_chat(user, span_warning("The slime already has no chance of mutating!"))
return
return ITEM_INTERACT_BLOCKING
to_chat(user, span_notice("You feed the slime the omnistabilizer. It will not mutate this cycle!"))
stabilize_target.mutation_chance = 0
interacting_slime.mutation_chance = 0
qdel(src)
return ITEM_INTERACT_SUCCESS
@@ -59,28 +59,29 @@ Consuming extracts:
/obj/item/slime_cookie/proc/do_effect(mob/living/M, mob/user)
return
/obj/item/slime_cookie/attack(mob/living/M, mob/user)
/obj/item/slime_cookie/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
if(!isliving(interacting_with))
return NONE
var/mob/living/living_mob = interacting_with
var/fed = FALSE
if(M == user)
M.visible_message(span_notice("[user] eats [src]!"), span_notice("You eat [src]."))
if(living_mob == user)
living_mob.visible_message(span_notice("[user] eats [src]!"), span_notice("You eat [src]."))
fed = TRUE
else
M.visible_message(span_danger("[user] tries to force [M] to eat [src]!"), span_userdanger("[user] tries to force you to eat [src]!"))
if(do_after(user, 2 SECONDS, target = M))
living_mob.visible_message(span_danger("[user] tries to force [living_mob] to eat [src]!"), span_userdanger("[user] tries to force you to eat [src]!"))
if(do_after(user, 2 SECONDS, target = living_mob))
fed = TRUE
M.visible_message(span_danger("[user] forces [M] to eat [src]!"), span_warning("[user] forces you to eat [src]."))
living_mob.visible_message(span_danger("[user] forces [living_mob] to eat [src]!"), span_warning("[user] forces you to eat [src]."))
if(fed)
var/mob/living/carbon/human/H = M
if(!istype(H) || !HAS_TRAIT(H, TRAIT_AGEUSIA))
to_chat(M, span_notice("Tastes like [taste]."))
playsound(get_turf(M), 'sound/items/eatfood.ogg', 20, TRUE)
if(!HAS_TRAIT(living_mob, TRAIT_AGEUSIA))
to_chat(living_mob, span_notice("You can taste [taste]."))
playsound(get_turf(living_mob), 'sound/items/eatfood.ogg', 20, TRUE)
if(nutrition)
M.reagents.add_reagent(/datum/reagent/consumable/nutriment,nutrition)
do_effect(M, user)
living_mob.reagents.add_reagent(/datum/reagent/consumable/nutriment, nutrition)
do_effect(living_mob, user)
qdel(src)
return
..()
return ITEM_INTERACT_SUCCESS
return ITEM_INTERACT_BLOCKING
/obj/item/slimecross/consuming/grey
colour = SLIME_TYPE_GREY
+144 -117
View File
@@ -61,18 +61,20 @@
*
* By using a valid core on a living adult slime, then feeding it nine more of the same type, you can mutate it into more useful items. Not every slime type has an implemented core cross.
*/
/obj/item/slime_extract/attack(mob/living/basic/slime/target_slime, mob/user)
if(!isslime(target_slime))
return ..()
/obj/item/slime_extract/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
var/mob/living/basic/slime/target_slime = interacting_with
if(!istype(target_slime))
return NONE
if(target_slime.stat)
to_chat(user, span_warning("The slime is dead!"))
return
return ITEM_INTERACT_BLOCKING
if(target_slime.life_stage != SLIME_LIFE_STAGE_ADULT)
to_chat(user, span_warning("The slime must be an adult to cross its core!"))
return
return ITEM_INTERACT_BLOCKING
if(target_slime.crossbreed_modification && target_slime.crossbreed_modification != crossbreed_modification)
to_chat(user, span_warning("The slime is already being crossed with a different extract!"))
return
return ITEM_INTERACT_BLOCKING
if(!target_slime.crossbreed_modification)
target_slime.crossbreed_modification = crossbreed_modification
@@ -84,6 +86,7 @@
if(target_slime.applied_crossbreed_amount >= SLIME_EXTRACT_CROSSING_REQUIRED)
target_slime.spawn_corecross()
return ITEM_INTERACT_SUCCESS
/**
* Effect when activated by selfsustaining crossbreed or rainbow slime
@@ -447,7 +450,7 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate
/obj/item/slime_extract/lightpink/activate(mob/living/carbon/human/user, datum/species/jelly/luminescent/species, activation_type)
switch(activation_type)
if(SLIME_ACTIVATE_MINOR)
var/obj/item/slimepotion/slime/renaming/O = new(null, 1)
var/obj/item/slimepotion/renaming/O = new(null, 1)
if(!user.put_in_active_hand(O))
O.forceMove(user.drop_location())
playsound(user, 'sound/effects/splat.ogg', 50, TRUE)
@@ -455,7 +458,7 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate
return 150
if(SLIME_ACTIVATE_MAJOR)
var/obj/item/slimepotion/slime/sentience/O = new(null, 1)
var/obj/item/slimepotion/sentience/O = new(null, 1)
if(!user.put_in_active_hand(O))
O.forceMove(user.drop_location())
playsound(user, 'sound/effects/splat.ogg', 50, TRUE)
@@ -674,49 +677,59 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate
/obj/item/slimepotion
name = "slime potion"
desc = "A hard yet gelatinous capsule excreted by a slime, containing mysterious substances."
icon = 'icons/obj/medical/chemical.dmi'
w_class = WEIGHT_CLASS_TINY
/obj/item/slimepotion/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
if(is_reagent_container(interacting_with))
to_chat(user, span_warning("You cannot transfer [src] to [interacting_with]! \
It appears the potion must be given directly to a slime to absorb.") )
It appears the potion must be given directly to a slime or other object to absorb.") )
return ITEM_INTERACT_BLOCKING
return NONE
/obj/item/slimepotion/slime/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
. = ..()
if(. & ITEM_INTERACT_ANY_BLOCKER)
return .
if(isslime(interacting_with))
return interact_with_slime(interacting_with, user, modifiers)
else
to_chat(user, span_warning("It appears [src] must be given directly to a slime to absorb."))
return NONE
/obj/item/slimepotion/slime/proc/interact_with_slime(mob/living/basic/slime/interacting_slime, mob/living/user, list/modifiers)
return
/obj/item/slimepotion/slime/docility
name = "docility potion"
desc = "A potent chemical mix that nullifies a slime's hunger, causing it to become docile and tame."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potsilver"
/obj/item/slimepotion/slime/docility/attack(mob/living/basic/slime/target_slime, mob/user)
if(!isslime(target_slime))
to_chat(user, span_warning("The potion only works on slimes!"))
return ..()
if(target_slime.stat)
/obj/item/slimepotion/slime/docility/interact_with_slime(mob/living/basic/slime/interacting_slime, mob/living/user, list/modifiers)
if(interacting_slime.stat)
to_chat(user, span_warning("The slime is dead!"))
return
if(target_slime.ai_controller?.clear_blackboard_key(BB_SLIME_RABID)) //Stops being rabid, but doesn't become truly docile.
to_chat(target_slime, span_warning("You absorb the potion, and your rabid hunger finally settles to a normal desire to feed."))
return ITEM_INTERACT_BLOCKING
if(interacting_slime.ai_controller?.clear_blackboard_key(BB_SLIME_RABID)) //Stops being rabid, but doesn't become truly docile.
to_chat(interacting_slime, span_warning("You absorb the potion, and your rabid hunger finally settles to a normal desire to feed."))
to_chat(user, span_notice("You feed the slime the potion, calming its rabid rage."))
target_slime.set_default_behaviour()
interacting_slime.set_default_behaviour()
qdel(src)
return
target_slime.set_pacified_behaviour()
to_chat(target_slime, span_warning("You absorb the potion and feel your intense desire to feed melt away."))
return ITEM_INTERACT_SUCCESS
interacting_slime.set_pacified_behaviour()
to_chat(interacting_slime, span_warning("You absorb the potion and feel your intense desire to feed melt away."))
to_chat(user, span_notice("You feed the slime the potion, removing its hunger and calming it."))
var/newname = sanitize_name(tgui_input_text(user, "Would you like to give the slime a name?", "Name your new pet", "Pet Slime", MAX_NAME_LEN))
if (!newname)
newname = "Pet Slime"
target_slime.name = newname
target_slime.real_name = newname
interacting_slime.name = newname
interacting_slime.real_name = newname
qdel(src)
return ITEM_INTERACT_SUCCESS
/obj/item/slimepotion/slime/sentience
/obj/item/slimepotion/sentience
name = "intelligence potion"
desc = "A miraculous chemical mix that grants human like intelligence to living beings."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potpink"
/// Are we being offered to a mob, and therefore is a ghost poll currently in progress for the sentient mob?
var/being_used = FALSE
@@ -724,34 +737,40 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate
/// Reason for offering potion. This will be displayed in the poll alert to ghosts.
var/potion_reason
/obj/item/slimepotion/slime/sentience/examine(mob/user)
/obj/item/slimepotion/sentience/examine(mob/user)
. = ..()
. += span_notice("Alt-click to set potion offer reason. [potion_reason ? "Current reason: [span_warning(potion_reason)]" : null]")
/obj/item/slimepotion/slime/sentience/Initialize(mapload)
/obj/item/slimepotion/sentience/Initialize(mapload)
register_context()
return ..()
/obj/item/slimepotion/slime/sentience/add_context(atom/source, list/context, obj/item/held_item, mob/user)
/obj/item/slimepotion/sentience/add_context(atom/source, list/context, obj/item/held_item, mob/user)
context[SCREENTIP_CONTEXT_ALT_LMB] = "Set potion offer reason"
return CONTEXTUAL_SCREENTIP_SET
/obj/item/slimepotion/slime/sentience/click_alt(mob/living/user)
/obj/item/slimepotion/sentience/click_alt(mob/living/user)
potion_reason = tgui_input_text(user, "Enter reason for offering potion", "Intelligence Potion", potion_reason, max_length = MAX_MESSAGE_LEN, multiline = TRUE)
return CLICK_ACTION_SUCCESS
/obj/item/slimepotion/slime/sentience/attack(mob/living/dumb_mob, mob/user)
if(being_used || !isliving(dumb_mob))
return
/obj/item/slimepotion/sentience/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
. = ..()
if(. & ITEM_INTERACT_ANY_BLOCKER)
return .
if(!isliving(interacting_with))
return NONE
var/mob/living/dumb_mob = interacting_with
if(being_used)
return ITEM_INTERACT_BLOCKING
if(dumb_mob.ckey) //only works on animals that aren't player controlled
balloon_alert(user, "already sentient!")
return
return ITEM_INTERACT_BLOCKING
if(dumb_mob.stat)
balloon_alert(user, "it's dead!")
return
return ITEM_INTERACT_BLOCKING
if(!dumb_mob.compare_sentience_type(sentience_type)) // Will also return false if not a basic or simple mob, which are the only two we want anyway
balloon_alert(user, "invalid creature!")
return
return ITEM_INTERACT_BLOCKING
balloon_alert(user, "offering...")
being_used = TRUE
var/mob/chosen_one = SSpolling.poll_ghosts_for_target(
@@ -765,9 +784,10 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate
chat_text_border_icon = src,
)
on_poll_concluded(user, dumb_mob, chosen_one)
return ITEM_INTERACT_SUCCESS
/// Assign the chosen ghost to the mob
/obj/item/slimepotion/slime/sentience/proc/on_poll_concluded(mob/user, mob/living/dumb_mob, mob/dead/observer/ghost)
/obj/item/slimepotion/sentience/proc/on_poll_concluded(mob/user, mob/living/dumb_mob, mob/dead/observer/ghost)
if(isnull(ghost))
balloon_alert(user, "try again later!")
being_used = FALSE
@@ -786,19 +806,19 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate
after_success(user, dumb_mob)
qdel(src)
/obj/item/slimepotion/slime/sentience/proc/after_success(mob/living/user, mob/living/smart_mob)
/obj/item/slimepotion/sentience/proc/after_success(mob/living/user, mob/living/smart_mob)
return
/obj/item/slimepotion/slime/sentience/nuclear
/obj/item/slimepotion/sentience/nuclear
name = "syndicate intelligence potion"
desc = "A miraculous chemical mix that grants human like intelligence to living beings. It has been modified with Syndicate technology to also grant an internal radio implant to the target and authenticate with identification systems."
/obj/item/slimepotion/slime/sentience/nuclear/after_success(mob/living/user, mob/living/smart_mob)
/obj/item/slimepotion/sentience/nuclear/after_success(mob/living/user, mob/living/smart_mob)
var/obj/item/implant/radio/syndicate/imp = new(src)
imp.implant(smart_mob, user)
smart_mob.AddComponent(/datum/component/simple_access, list(ACCESS_SYNDICATE, ACCESS_MAINT_TUNNELS))
/obj/item/slimepotion/slime/sentience/nuclear/dangerous_horse
/obj/item/slimepotion/sentience/nuclear/dangerous_horse
name = "dangerous pony potion"
desc = "A miraculous chemical mix that grants human like intelligence to pony beings. It has been modified with Syndicate technology to also grant an internal radio implant to the pony and authenticate with identification systems"
sentience_type = SENTIENCE_PONY
@@ -806,7 +826,6 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate
/obj/item/slimepotion/transference
name = "consciousness transference potion"
desc = "A strange slime-based chemical that, when used, allows the user to transfer their consciousness to a lesser being."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potorange"
var/prompted = 0
var/animal_type = SENTIENCE_ORGANIC
@@ -815,8 +834,10 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate
. = ..()
if(. & ITEM_INTERACT_ANY_BLOCKER)
return .
if(!isliving(interacting_with))
return NONE
var/mob/living/switchy_mob = interacting_with
if(prompted || !isliving(switchy_mob))
if(prompted)
return ITEM_INTERACT_BLOCKING
if(switchy_mob.ckey) //much like sentience, these will not work on something that is already player controlled
balloon_alert(user, "already sentient!")
@@ -861,83 +882,72 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate
/obj/item/slimepotion/slime/steroid
name = "slime steroid"
desc = "A potent chemical mix that will cause a baby slime to generate more extract."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potred"
/obj/item/slimepotion/slime/steroid/attack(mob/living/basic/slime/target, mob/user)
if(!isslime(target))//If target is not a slime.
to_chat(user, span_warning("The steroid only works on baby slimes!"))
return ..()
if(target.life_stage == SLIME_LIFE_STAGE_ADULT) //Can't steroidify adults
/obj/item/slimepotion/slime/steroid/interact_with_slime(mob/living/basic/slime/interacting_slime, mob/living/user, list/modifiers)
if(interacting_slime.life_stage == SLIME_LIFE_STAGE_ADULT) //Can't steroidify adults
to_chat(user, span_warning("Only baby slimes can use the steroid!"))
return
if(target.stat)
return ITEM_INTERACT_BLOCKING
if(interacting_slime.stat)
to_chat(user, span_warning("The slime is dead!"))
return
if(target.cores >= 5)
return ITEM_INTERACT_BLOCKING
if(interacting_slime.cores >= 5)
to_chat(user, span_warning("The slime already has the maximum amount of extract!"))
return
return ITEM_INTERACT_BLOCKING
to_chat(user, span_notice("You feed the slime the steroid. It will now produce one more extract."))
target.cores++
interacting_slime.cores++
qdel(src)
return ITEM_INTERACT_SUCCESS
/obj/item/slimepotion/enhancer
name = "extract enhancer"
desc = "A potent chemical mix that will give a slime extract an additional use."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potpurple"
/obj/item/slimepotion/slime/stabilizer
name = "slime stabilizer"
desc = "A potent chemical mix that will reduce the chance of a slime mutating."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potcyan"
/obj/item/slimepotion/slime/stabilizer/attack(mob/living/basic/slime/target_slime, mob/user)
if(!isslime(target_slime))
to_chat(user, span_warning("The stabilizer only works on slimes!"))
return ..()
if(target_slime.stat)
/obj/item/slimepotion/slime/stabilizer/interact_with_slime(mob/living/basic/slime/interacting_slime, mob/living/user, list/modifiers)
if(interacting_slime.stat)
to_chat(user, span_warning("The slime is dead!"))
return
if(target_slime.mutation_chance == 0)
return ITEM_INTERACT_BLOCKING
if(interacting_slime.mutation_chance == 0)
to_chat(user, span_warning("The slime already has no chance of mutating!"))
return
return ITEM_INTERACT_BLOCKING
to_chat(user, span_notice("You feed the slime the stabilizer. It is now less likely to mutate."))
target_slime.mutation_chance = clamp(target_slime.mutation_chance-15,0,100)
interacting_slime.mutation_chance = clamp(interacting_slime.mutation_chance-15,0,100)
qdel(src)
return ITEM_INTERACT_SUCCESS
/obj/item/slimepotion/slime/mutator
name = "slime mutator"
desc = "A potent chemical mix that will increase the chance of a slime mutating."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potgreen"
/obj/item/slimepotion/slime/mutator/attack(mob/living/basic/slime/target_slime, mob/user)
if(!isslime(target_slime))
to_chat(user, span_warning("The mutator only works on slimes!"))
return ..()
if(target_slime.stat)
/obj/item/slimepotion/slime/mutator/interact_with_slime(mob/living/basic/slime/interacting_slime, mob/living/user, list/modifiers)
if(interacting_slime.stat)
to_chat(user, span_warning("The slime is dead!"))
return
if(target_slime.mutator_used)
return ITEM_INTERACT_BLOCKING
if(interacting_slime.mutator_used)
to_chat(user, span_warning("This slime has already consumed a mutator, any more would be far too unstable!"))
return
if(target_slime.mutation_chance == 100)
return ITEM_INTERACT_BLOCKING
if(interacting_slime.mutation_chance == 100)
to_chat(user, span_warning("The slime is already guaranteed to mutate!"))
return
return ITEM_INTERACT_BLOCKING
to_chat(user, span_notice("You feed the slime the mutator. It is now more likely to mutate."))
target_slime.mutation_chance = clamp(target_slime.mutation_chance+12,0,100)
target_slime.mutator_used = TRUE
interacting_slime.mutation_chance = clamp(interacting_slime.mutation_chance+12,0,100)
interacting_slime.mutator_used = TRUE
qdel(src)
return ITEM_INTERACT_SUCCESS
/obj/item/slimepotion/speed
name = "slime speed potion"
desc = "A potent chemical mix that will remove the slowdown from any item."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potred"
/obj/item/slimepotion/speed/interact_with_atom(obj/interacting_with, mob/living/user, list/modifiers)
@@ -946,7 +956,7 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate
return .
if(!isobj(interacting_with))
to_chat(user, span_warning("The potion can only be used on objects!"))
return ITEM_INTERACT_BLOCKING
return NONE
if(HAS_TRAIT(interacting_with, TRAIT_SPEED_POTIONED))
to_chat(user, span_warning("[interacting_with] can't be made any faster!"))
@@ -978,7 +988,6 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate
/obj/item/slimepotion/fireproof
name = "slime chill potion"
desc = "A potent chemical mix that will fireproof any article of clothing. Has three uses."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potblue"
resistance_flags = FIRE_PROOF
var/uses = 3
@@ -993,7 +1002,7 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate
var/obj/item/clothing/clothing = interacting_with
if(!istype(clothing))
to_chat(user, span_warning("The potion can only be used on clothing!"))
return ITEM_INTERACT_BLOCKING
return NONE
if(clothing.max_heat_protection_temperature >= FIRE_IMMUNITY_MAX_TEMP_PROTECT)
to_chat(user, span_warning("The [clothing] is already fireproof!"))
return ITEM_INTERACT_BLOCKING
@@ -1012,80 +1021,98 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate
/obj/item/slimepotion/genderchange
name = "gender change potion"
desc = "An interesting chemical mix that changes the biological gender of what its applied to. Cannot be used on things that lack gender entirely."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potrainbow"
/obj/item/slimepotion/genderchange/attack(mob/living/L, mob/user)
if(!istype(L) || L.stat == DEAD)
/obj/item/slimepotion/genderchange/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
. = ..()
if(. & ITEM_INTERACT_ANY_BLOCKER)
return .
if(!isliving(interacting_with))
return NONE
var/mob/living/living_mob = interacting_with
if(living_mob.stat == DEAD)
to_chat(user, span_warning("The potion can only be used on living things!"))
return
return ITEM_INTERACT_BLOCKING
if(L.gender != MALE && L.gender != FEMALE)
if(living_mob.gender != MALE && living_mob.gender != FEMALE)
to_chat(user, span_warning("The potion can only be used on gendered things!"))
return
return ITEM_INTERACT_BLOCKING
if(L.gender == MALE)
L.gender = FEMALE
L.visible_message(span_boldnotice("[L] suddenly looks more feminine!"), span_boldwarning("You suddenly feel more feminine!"))
if(living_mob.gender == MALE)
living_mob.gender = FEMALE
living_mob.visible_message(span_boldnotice("[living_mob] suddenly looks more feminine!"), span_boldwarning("You suddenly feel more feminine!"))
else
L.gender = MALE
L.visible_message(span_boldnotice("[L] suddenly looks more masculine!"), span_boldwarning("You suddenly feel more masculine!"))
L.regenerate_icons()
living_mob.gender = MALE
living_mob.visible_message(span_boldnotice("[living_mob] suddenly looks more masculine!"), span_boldwarning("You suddenly feel more masculine!"))
living_mob.regenerate_icons()
qdel(src)
return ITEM_INTERACT_SUCCESS
/obj/item/slimepotion/slime/renaming
/obj/item/slimepotion/renaming
name = "renaming potion"
desc = "A potion that allows a self-aware being to change what name it subconsciously presents to the world."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potbrown"
var/being_used = FALSE
/obj/item/slimepotion/slime/renaming/attack(mob/living/M, mob/user)
if(being_used || !ismob(M))
return
if(!M.ckey) //only works on animals that aren't player controlled
to_chat(user, span_warning("[M] is not self aware, and cannot pick its own name."))
return
/obj/item/slimepotion/renaming/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
. = ..()
if(. & ITEM_INTERACT_ANY_BLOCKER)
return .
if(!isliving(interacting_with))
return NONE
var/mob/living/renaming_mob = interacting_with
if(being_used)
return ITEM_INTERACT_BLOCKING
if(!renaming_mob.ckey) //only works on animals that aren't player controlled
to_chat(user, span_warning("[renaming_mob] is not self aware, and cannot pick its own name."))
return ITEM_INTERACT_BLOCKING
being_used = TRUE
to_chat(user, span_notice("You offer [src] to [user]..."))
var/new_name = sanitize_name(tgui_input_text(M, "What would you like your name to be?", "Input a name", M.real_name, MAX_NAME_LEN))
var/new_name = sanitize_name(tgui_input_text(renaming_mob, "What would you like your name to be?", "Input a name", renaming_mob.real_name, MAX_NAME_LEN))
if(!new_name || QDELETED(src) || QDELETED(M) || new_name == M.real_name || !M.Adjacent(user))
if(!new_name || QDELETED(src) || QDELETED(renaming_mob) || new_name == renaming_mob.real_name || !renaming_mob.Adjacent(user))
being_used = FALSE
return
return ITEM_INTERACT_BLOCKING
M.visible_message(span_notice("[span_name("[M]")] has a new name, [span_name("[new_name]")]."), span_notice("Your old name of [span_name("[M.real_name]")] fades away, and your new name [span_name("[new_name]")] anchors itself in your mind."))
message_admins("[ADMIN_LOOKUPFLW(user)] used [src] on [ADMIN_LOOKUPFLW(M)], letting them rename themselves into [new_name].")
user.log_message("used [src] on [key_name(M)], letting them rename themselves into [new_name].", LOG_GAME)
renaming_mob.visible_message(span_notice("[span_name("[renaming_mob]")] has a new name, [span_name("[new_name]")]."), span_notice("Your old name of [span_name("[renaming_mob.real_name]")] fades away, and your new name [span_name("[new_name]")] anchors itself in your mind."))
message_admins("[ADMIN_LOOKUPFLW(user)] used [src] on [ADMIN_LOOKUPFLW(renaming_mob)], letting them rename themselves into [new_name].")
user.log_message("used [src] on [key_name(renaming_mob)], letting them rename themselves into [new_name].", LOG_GAME)
// pass null as first arg to not update records or ID/PDA
M.fully_replace_character_name(null, new_name)
renaming_mob.fully_replace_character_name(null, new_name)
qdel(src)
return ITEM_INTERACT_SUCCESS
/obj/item/slimepotion/slime/slimeradio
/obj/item/slimepotion/slimeradio
name = "bluespace radio potion"
desc = "A strange chemical that grants those who ingest it the ability to broadcast and receive subscape radio waves."
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "potbluespace"
/obj/item/slimepotion/slime/slimeradio/attack(mob/living/radio_head, mob/user)
if(!isanimal_or_basicmob(radio_head))
to_chat(user, span_warning("[radio_head] is too complex for the potion!"))
return
/obj/item/slimepotion/slimeradio/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
. = ..()
if(. & ITEM_INTERACT_ANY_BLOCKER)
return .
if(!isliving(interacting_with))
return NONE
if(!isanimal_or_basicmob(interacting_with))
to_chat(user, span_warning("[interacting_with] is too complex for the potion!"))
return ITEM_INTERACT_BLOCKING
var/mob/living/radio_head = interacting_with
if(radio_head.stat)
to_chat(user, span_warning("[radio_head] is dead!"))
return
return ITEM_INTERACT_BLOCKING
to_chat(user, span_notice("You feed the potion to [radio_head]."))
to_chat(radio_head, span_notice("Your mind tingles as you are fed the potion. You can hear radio waves now!"))
var/obj/item/implant/radio/slime/imp = new(src)
imp.implant(radio_head, user)
qdel(src)
return ITEM_INTERACT_SUCCESS
///Definitions for slime products that don't have anywhere else to go (Floor tiles, blueprints).
+1 -1
View File
@@ -800,7 +800,7 @@
/datum/uplink_item/device_tools/potion
name = "Syndicate Sentience Potion"
item = /obj/item/slimepotion/slime/sentience/nuclear
item = /obj/item/slimepotion/sentience/nuclear
desc = "A potion recovered at great risk by undercover Syndicate operatives and then subsequently modified with Syndicate technology. \
Using it will make any animal sentient, and bound to serve you, as well as implanting an internal radio for communication and an internal ID card for opening doors."
cost = 4