diff --git a/code/modules/mob/living/carbon/alien/diona/diona_nymph.dm b/code/modules/mob/living/carbon/alien/diona/diona_nymph.dm index a6fe6b88681..bfc02df877a 100644 --- a/code/modules/mob/living/carbon/alien/diona/diona_nymph.dm +++ b/code/modules/mob/living/carbon/alien/diona/diona_nymph.dm @@ -31,8 +31,6 @@ var/flower_color var/image/flower_image - var/list/sampled_DNA - var/list/language_progress var/obj/item/clothing/head/hat var/datum/reagents/vessel var/energy_duration = 144 // The time in seconds that this diona can exist in total darkness before its energy runs out @@ -101,8 +99,6 @@ eat_types |= TYPE_ORGANIC nutrition = 0 //We dont start with biomass update_verbs() - sampled_DNA = list() - language_progress = list() /mob/living/carbon/alien/diona/verb/check_light() @@ -244,7 +240,7 @@ verbs -= /mob/living/carbon/alien/diona/proc/grow verbs -= /mob/living/carbon/alien/diona/proc/merge verbs -= /mob/living/carbon/proc/absorb_nymph - verbs -= /mob/living/carbon/alien/diona/proc/sample + verbs -= /mob/living/carbon/proc/sample verbs -= /mob/living/carbon/alien/diona/proc/remove_hat verbs |= /mob/living/carbon/alien/diona/proc/split else @@ -253,7 +249,7 @@ verbs |= /mob/living/carbon/alien/diona/proc/grow verbs |= /mob/living/proc/ventcrawl verbs |= /mob/living/proc/hide - verbs |= /mob/living/carbon/alien/diona/proc/sample + verbs |= /mob/living/carbon/proc/sample verbs |= /mob/living/carbon/alien/diona/proc/remove_hat verbs -= /mob/living/carbon/alien/diona/proc/split // we want to remove this one diff --git a/code/modules/mob/living/carbon/alien/diona/diona_powers.dm b/code/modules/mob/living/carbon/alien/diona/diona_powers.dm index 87eac170a15..792da2fd642 100644 --- a/code/modules/mob/living/carbon/alien/diona/diona_powers.dm +++ b/code/modules/mob/living/carbon/alien/diona/diona_powers.dm @@ -165,7 +165,7 @@ update_verbs() //Draws a sizeable blood sample from a victim to read their DNA and learn languages -/mob/living/carbon/alien/diona/proc/sample() +/mob/living/carbon/proc/sample() set category = "Abilities" set name = "Sample DNA" set desc = "Learn languages by draining some blood from a nearby lifeform. You will partially learn any language it knows." @@ -184,101 +184,29 @@ if(!length(choices)) to_chat(src, SPAN_WARNING("There are no life forms nearby to sample!")) return - else - choices += "Cancel" - var/mob/living/donor = input(src, "Who do you wish to sample?") in null|choices - - if(!donor || donor == "Cancel") //they cancelled + var/mob/living/donor = input(src, "Who do you wish to sample?", "Blood Sampling") as null|anything in choices + if(!donor || !Adjacent(donor)) return face_atom(donor) var/types = donor.find_type() if(types & TYPE_SYNTHETIC) - src.visible_message(SPAN_DANGER("[src] attempts to bite into [donor.name] but leaps back in surprise as its fangs hit metal."), SPAN_DANGER("You attempt to sink your fangs into [donor.name] and get a faceful of unyielding steel as the force breaks several fine protrusions in your mouth.")) + visible_message(SPAN_DANGER("[src] attempts to bite into [donor.name] but leaps back in surprise as its fangs hit metal."), SPAN_DANGER("You attempt to sink your fangs into [donor.name] and get a faceful of unyielding steel as the force breaks several fine protrusions in your mouth.")) donor.adjustBruteLoss(2) - src.adjustBruteLoss(15) //biting metal hurts! - return - + adjustBruteLoss(15) //biting metal hurts! else if (isanimal(donor) && (types & TYPE_ORGANIC) && donor.stat != DEAD) - src.visible_message(SPAN_DANGER("[src] bites into [donor.name] and drains some of their blood."), SPAN_DANGER("You bite into [donor.name] and drain some of their blood.")) + visible_message(SPAN_DANGER("[src] bites into [donor.name] and drains some of their blood."), SPAN_DANGER("You bite into [donor.name] and drain some of their blood.")) to_chat(src, SPAN_DANGER("This simple creature has insufficient intelligence for you to learn anything!")) donor.adjustBruteLoss(4) adjustNutritionLoss(-20) - return else if (types & TYPE_WEIRD) - src.visible_message(SPAN_DANGER("[src] attempts to bite into [donor.name] but passes right through it!."), SPAN_DANGER("You attempt to sink your fangs into [donor.name] but pass right through it!")) - return + visible_message(SPAN_DANGER("[src] attempts to bite into [donor.name] but passes right through it!."), SPAN_DANGER("You attempt to sink your fangs into [donor.name] but pass right through it!")) else if (iscarbon(donor)) - var/mob/living/carbon/D = donor - //If we get here, it's -probably- valid - - src.visible_message(SPAN_DANGER("[src] is trying to bite [D.name]."), SPAN_DANGER("You start biting [D.name], you both must stay still!")) - face_atom(get_turf(D)) - if(do_mob(src, D, 40, needhand = FALSE)) - //Attempt to find the blood vessel, but don't create a fake one if its not there. - //If the target doesn't have a vessel its probably due to someone not implementing it properly, like xenos - //We'll still allow it - var/datum/reagents/vessel = D.get_vessel(1) - var/newDNA - var/datum/reagent/blood/B = vessel.get_master_reagent() - var/total_blood = B.volume - var/remove_amount = total_blood * 0.05 - if(ishuman(D)) - var/mob/living/carbon/human/H = D - remove_amount = H.species.blood_volume * 0.05 - if(remove_amount > 0) - vessel.remove_reagent(/datum/reagent/blood, remove_amount, TRUE) - adjustNutritionLoss(-remove_amount * 0.5) - var/list/data = vessel.get_data(/datum/reagent/blood) - newDNA = data["blood_DNA"] - - if(!newDNA) //Fallback. Adminspawned mobs, and possibly some others, have null dna. - newDNA = md5("\ref[D]") - - D.adjustBruteLoss(4) - src.visible_message(SPAN_NOTICE("[src] sucks some blood from [D.name].") , SPAN_NOTICE("You extract a delicious mouthful of blood from [D.name]!")) - - if(newDNA in sampled_DNA) - to_chat(src, SPAN_DANGER("You have already sampled the DNA of this creature before, you can learn nothing new. Move onto something else.")) - return - else - sampled_DNA.Add(newDNA) - - var/learned = 0 - //Learned var: - //0 = The target has no languages - //1 = We already everything they know or can't learn - //2 = We learned something! - - //Now we sample their languages! - for(var/datum/language/L in D.languages) - learned = max(learned, 1) - if (!(L in languages) && !(L in diona_banned_languages)) - //We don't know this language, and we can learn it! - var/current_progress = language_progress[L.name] - current_progress += 1 - language_progress[L.name] = current_progress - to_chat(src, SPAN_NOTICE("You come a little closer to learning [L.name]!")) - learned = 2 - - if(!learned) - to_chat(src, SPAN_DANGER("This creature doesn't know any languages at all!")) - else if (learned == 1) - to_chat(src, SPAN_DANGER("We have nothing more to learn from this creature. Perhaps try a different sample?")) - - update_languages() - else - to_chat(src, SPAN_WARNING("Something went wrong while trying to sample [D], both you and the target must remain still.")) - -//Checks progress on learned languages -/mob/living/carbon/alien/diona/proc/update_languages() - for(var/i in language_progress) - if(language_progress[i] >= LANGUAGE_POINTS_TO_LEARN) - add_language(i) - to_chat(src, SPAN_NOTICE("You have mastered the [i] language!")) - language_progress.Remove(i) + var/datum/dionastats/DS = get_dionastats() + if(DS) + DS.do_blood_suck(src, donor) /mob/living/carbon/alien/diona/proc/transferMind(var/atom/A) set category = "Abilities" diff --git a/code/modules/mob/living/carbon/diona_base.dm b/code/modules/mob/living/carbon/diona_base.dm index 7282f33d1f3..3d1cacd0f83 100644 --- a/code/modules/mob/living/carbon/diona_base.dm +++ b/code/modules/mob/living/carbon/diona_base.dm @@ -616,6 +616,9 @@ var/list/diona_banned_languages = list( var/restrictedlight_factor = 0.8 //A value between 0 and 1 that determines how much we nerf the strength of certain worn lights //1 means flashlights work normally., 0 means they do nothing + var/list/sampled_DNA = list() + var/list/language_progress = list() + var/obj/item/organ/internal/diona/node/light_organ = null //The organ this gestalt uses to receive light. This is left null for nymphs var/obj/item/organ/internal/diona/nutrients/nutrient_organ = null //Organ var/LMS = 1 //Lightmessage state. Switching between states gives the user a message @@ -626,6 +629,83 @@ var/list/diona_banned_languages = list( var/regen_limb_progress var/pause_regen = FALSE +/datum/dionastats/proc/do_blood_suck(var/mob/living/carbon/user, var/mob/living/carbon/D) + user.visible_message(SPAN_DANGER("[user] is trying to bite [D.name]."), SPAN_DANGER("You start biting \the [D], you both must stay still!")) + user.face_atom(get_turf(D)) + if(do_mob(user, D, 40, needhand = FALSE)) + //Attempt to find the blood vessel, but don't create a fake one if its not there. + //If the target doesn't have a vessel its probably due to someone not implementing it properly, like xenos + //We'll still allow it + var/datum/reagents/vessel = D.get_vessel(1) + var/newDNA + var/datum/reagent/blood/B = vessel.get_master_reagent() + var/total_blood = B.volume + var/remove_amount = total_blood * 0.05 + if(ishuman(D)) + var/mob/living/carbon/human/H = D + remove_amount = H.species.blood_volume * 0.05 + if(remove_amount > 0) + vessel.remove_reagent(/datum/reagent/blood, remove_amount, TRUE) + user.adjustNutritionLoss(-remove_amount * 0.5) + var/list/data = vessel.get_data(/datum/reagent/blood) + newDNA = data["blood_DNA"] + + if(!newDNA) //Fallback. Adminspawned mobs, and possibly some others, have null dna. + newDNA = md5("\ref[D]") + + D.adjustBruteLoss(4) + user.visible_message(SPAN_NOTICE("[user] sucks some blood from \the [D].") , SPAN_NOTICE("You extract a delicious mouthful of blood from \the [D]!")) + to_chat(D, SPAN_NOTICE("You feel some liquid being injected at the bite site.")) + D.reagents.add_reagent(/datum/reagent/mortaphenyl/aphrodite, 5) + if(D.client) + INVOKE_ASYNC(src, .proc/memory_transfer, user, D) + if(newDNA in sampled_DNA) + to_chat(user, SPAN_DANGER("You have already sampled the DNA of this creature before, you can learn nothing new. Move onto something else.")) + return + else + sampled_DNA.Add(newDNA) + + var/learned = 0 + //Learned var: + //0 = The target has no languages + //1 = We already everything they know or can't learn + //2 = We learned something! + + //Now we sample their languages! + for(var/datum/language/L in D.languages) + learned = max(learned, 1) + if (!(L in user.languages) && !(L in diona_banned_languages)) + //We don't know this language, and we can learn it! + var/current_progress = language_progress[L.name] + current_progress += 1 + language_progress[L.name] = current_progress + to_chat(user, SPAN_NOTICE("You come a little closer to learning [L.name]!")) + learned = 2 + + if(!learned) + to_chat(user, SPAN_DANGER("This creature doesn't know any languages at all!")) + else if (learned == 1) + to_chat(user, SPAN_DANGER("We have nothing more to learn from this creature. Perhaps try a different sample?")) + + update_languages(user) + else + to_chat(user, SPAN_WARNING("Something went wrong while trying to sample [D], both you and the target must remain still.")) + +/datum/dionastats/proc/memory_transfer(var/mob/user, var/mob/donor) + var/memory_drain = input(donor, "[user] just drained some of your blood, including some of your memory. What was on your mind?", "Diona Memory Transfer") as null|text + if(!memory_drain || memory_drain == "") + to_chat(user, SPAN_WARNING("\The [donor] had nothing swimming around in their brain.")) + else + memory_drain = capitalize(sanitize(memory_drain)) + to_chat(user, SPAN_NOTICE("You gather the following knowledge from \the [donor]: [memory_drain]")) + +/datum/dionastats/proc/update_languages(var/mob/user) + for(var/i in language_progress) + if(language_progress[i] >= LANGUAGE_POINTS_TO_LEARN) + user.add_language(i) + to_chat(user, SPAN_NOTICE("You have mastered the [i] language!")) + language_progress.Remove(i) + /datum/dionastats/Destroy() light_organ = null //Nulling out these references to prevent GC errors nutrient_organ = null diff --git a/code/modules/mob/living/carbon/human/species/station/diona/diona.dm b/code/modules/mob/living/carbon/human/species/station/diona/diona.dm index c22e6db31a3..feeda9c2149 100644 --- a/code/modules/mob/living/carbon/human/species/station/diona/diona.dm +++ b/code/modules/mob/living/carbon/human/species/station/diona/diona.dm @@ -20,7 +20,8 @@ ) inherent_verbs = list( /mob/living/carbon/human/proc/consume_nutrition_from_air, - /mob/living/carbon/human/proc/create_structure + /mob/living/carbon/human/proc/create_structure, + /mob/living/carbon/proc/sample ) //primitive_form = "Nymph" slowdown = 7 diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index 10f02b9c173..dedd576909f 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -310,7 +310,21 @@ M.add_chemical_effect(CE_EMETIC, dose/6) if(M.losebreath < 15) M.losebreath++ - + +/datum/reagent/mortaphenyl/aphrodite + name = "Aphrodite" + description = "Aphrodite is the name given to the chemical diona inject into organics soon after biting them. It serves a dual purpose of dulling the pain of the wound, and gathering deep-seated fragments of learned skills and memories, such as languages." + color = "#a59153" + overdose = 10 + scannable = TRUE + fallback_specific_heat = 1 + taste_description = "euphoric acid" + +/datum/reagent/mortaphenyl/aphrodite/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + M.add_chemical_effect(CE_PAINKILLER, 70) + M.eye_blurry = max(M.eye_blurry, 3) + M.confused = max(M.confused, 6) + /datum/reagent/oxycomorphine name = "Oxycomorphine" description = "Oxycomorphine is a highly advanced, powerful analgesic medication which is extremely effective at treating severe-agonising pain as a result of injuries usually incompatible with life. The drug is highly addictive and sense-numbing. Oxycomorphine is not effective when inhaled." diff --git a/html/changelogs/geeves-diona_succ.yml b/html/changelogs/geeves-diona_succ.yml new file mode 100644 index 00000000000..4930c60f17e --- /dev/null +++ b/html/changelogs/geeves-diona_succ.yml @@ -0,0 +1,8 @@ +author: Geeves + +delete-after: True + +changes: + - rscadd: "Diona now absorb knowledge along with language when sucking blood, this is a user prompt that the suckee must enter, and will probably fail to." + - rscadd: "Diona gestalts can now also sample DNA to learn languages and gain knowledge." + - rscadd: "Diona now inject a medium painkiller when sucking blood, called 'Aphrodite'." \ No newline at end of file