mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-13 10:23:15 +00:00
* Completely removes `proc_holders` from existence. Refactors all wizard, xeno, spider, and genetics powers to be actions. Also refactors and sorts ton of accompanying code. * our changes * yes * 0 * Update blackmesa.dmm Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com>
140 lines
5.2 KiB
Plaintext
140 lines
5.2 KiB
Plaintext
/datum/mutation/human/olfaction
|
|
name = "Transcendent Olfaction"
|
|
desc = "Your sense of smell is comparable to that of a canine."
|
|
quality = POSITIVE
|
|
difficulty = 12
|
|
text_gain_indication = "<span class='notice'>Smells begin to make more sense...</span>"
|
|
text_lose_indication = "<span class='notice'>Your sense of smell goes back to normal.</span>"
|
|
power_path = /datum/action/cooldown/spell/olfaction
|
|
instability = 30
|
|
synchronizer_coeff = 1
|
|
|
|
/datum/mutation/human/olfaction/modify()
|
|
. = ..()
|
|
var/datum/action/cooldown/spell/olfaction/to_modify = .
|
|
if(!istype(to_modify)) // null or invalid
|
|
return
|
|
|
|
to_modify.sensitivity = GET_MUTATION_SYNCHRONIZER(src)
|
|
|
|
/datum/action/cooldown/spell/olfaction
|
|
name = "Remember the Scent"
|
|
desc = "Get a scent off of the item you're currently holding to track it. \
|
|
With an empty hand, you'll track the scent you've remembered."
|
|
button_icon_state = "nose"
|
|
|
|
cooldown_time = 10 SECONDS
|
|
spell_requirements = NONE
|
|
|
|
/// Weakref to the mob we're tracking
|
|
var/datum/weakref/tracking_ref
|
|
/// Our nose's sensitivity
|
|
var/sensitivity = 1
|
|
|
|
/datum/action/cooldown/spell/olfaction/is_valid_target(atom/cast_on)
|
|
if(!isliving(cast_on))
|
|
return FALSE
|
|
|
|
var/mob/living/living_cast_on = cast_on
|
|
if(ishuman(living_cast_on) && !living_cast_on.get_bodypart(BODY_ZONE_HEAD))
|
|
to_chat(owner, span_warning("You have no nose!"))
|
|
return FALSE
|
|
|
|
return TRUE
|
|
|
|
/datum/action/cooldown/spell/olfaction/cast(mob/living/cast_on)
|
|
. = ..()
|
|
// Can we sniff? is there miasma in the air?
|
|
var/datum/gas_mixture/air = cast_on.loc.return_air()
|
|
var/list/cached_gases = air.gases
|
|
|
|
if(cached_gases[/datum/gas/miasma])
|
|
cast_on.adjust_disgust(sensitivity * 45)
|
|
to_chat(cast_on, span_warning("With your overly sensitive nose, \
|
|
you get a whiff of stench and feel sick! Try moving to a cleaner area!"))
|
|
return
|
|
|
|
var/atom/sniffed = cast_on.get_active_held_item()
|
|
if(sniffed)
|
|
pick_up_target(cast_on, sniffed)
|
|
else
|
|
follow_target(cast_on)
|
|
|
|
/// Attempt to pick up a new target based on the fingerprints on [sniffed].
|
|
/datum/action/cooldown/spell/olfaction/proc/pick_up_target(mob/living/caster, atom/sniffed)
|
|
var/mob/living/carbon/old_target = tracking_ref?.resolve()
|
|
var/list/possibles = list()
|
|
var/list/prints = GET_ATOM_FINGERPRINTS(sniffed)
|
|
if(prints)
|
|
for(var/mob/living/carbon/to_check as anything in GLOB.carbon_list)
|
|
if(prints[md5(to_check.dna?.unique_identity)])
|
|
possibles |= to_check
|
|
|
|
// There are no finger prints on the atom, so nothing to track
|
|
if(!length(possibles))
|
|
to_chat(caster, span_warning("Despite your best efforts, there are no scents to be found on [sniffed]..."))
|
|
return
|
|
|
|
var/mob/living/carbon/new_target = tgui_input_list(caster, "Scent to remember", "Scent Tracking", sort_names(possibles))
|
|
if(QDELETED(src) || QDELETED(caster))
|
|
return
|
|
|
|
if(QDELETED(new_target))
|
|
// We don't have a new target OR an old target
|
|
if(QDELETED(old_target))
|
|
to_chat(caster, span_warning("You decide against remembering any scents. \
|
|
Instead, you notice your own nose in your peripheral vision. \
|
|
This goes on to remind you of that one time you started breathing manually and couldn't stop. \
|
|
What an awful day that was."))
|
|
tracking_ref = null
|
|
|
|
// We don't have a new target, but we have an old target to fall back on
|
|
else
|
|
to_chat(caster, span_notice("You return to tracking [old_target]. The hunt continues."))
|
|
on_the_trail(caster)
|
|
return
|
|
|
|
// We have a new target to track
|
|
to_chat(caster, span_notice("You pick up the scent of [new_target]. The hunt begins."))
|
|
tracking_ref = WEAKREF(new_target)
|
|
on_the_trail(caster)
|
|
|
|
/// Attempt to follow our current tracking target.
|
|
/datum/action/cooldown/spell/olfaction/proc/follow_target(mob/living/caster)
|
|
var/mob/living/carbon/current_target = tracking_ref?.resolve()
|
|
// Either our weakref failed to resolve (our target's gone),
|
|
// or we never had a target in the first place
|
|
if(QDELETED(current_target))
|
|
to_chat(caster, span_warning("You're not holding anything to smell, \
|
|
and you haven't smelled anything you can track. You smell your skin instead; it's kinda salty."))
|
|
tracking_ref = null
|
|
return
|
|
|
|
on_the_trail(caster)
|
|
|
|
/// Actually go through and give the user a hint of the direction our target is.
|
|
/datum/action/cooldown/spell/olfaction/proc/on_the_trail(mob/living/caster)
|
|
var/mob/living/carbon/current_target = tracking_ref?.resolve()
|
|
if(!current_target)
|
|
to_chat(caster, span_warning("You're not tracking a scent, but the game thought you were. \
|
|
Something's gone wrong! Report this as a bug."))
|
|
stack_trace("[type] - on_the_trail was called when no tracking target was set.")
|
|
tracking_ref = null
|
|
return
|
|
|
|
if(current_target == caster)
|
|
to_chat(caster, span_warning("You smell out the trail to yourself. Yep, it's you."))
|
|
return
|
|
|
|
if(caster.z < current_target.z)
|
|
to_chat(caster, span_warning("The trail leads... way up above you? Huh. They must be really, really far away."))
|
|
return
|
|
|
|
else if(caster.z > current_target.z)
|
|
to_chat(caster, span_warning("The trail leads... way down below you? Huh. They must be really, really far away."))
|
|
return
|
|
|
|
var/direction_text = span_bold("[dir2text(get_dir(caster, current_target))]")
|
|
if(direction_text)
|
|
to_chat(caster, span_notice("You consider [current_target]'s scent. The trail leads [direction_text]."))
|