diff --git a/code/modules/antagonists/changeling/cellular_emporium.dm b/code/modules/antagonists/changeling/cellular_emporium.dm index df92212181..2a37a3885d 100644 --- a/code/modules/antagonists/changeling/cellular_emporium.dm +++ b/code/modules/antagonists/changeling/cellular_emporium.dm @@ -25,6 +25,7 @@ var/can_readapt = changeling.canrespec var/genetic_points_remaining = changeling.geneticpoints var/absorbed_dna_count = changeling.absorbedcount + var/true_absorbs = changeling.trueabsorbs data["can_readapt"] = can_readapt data["genetic_points_remaining"] = genetic_points_remaining @@ -45,8 +46,9 @@ AL["helptext"] = initial(ability.helptext) AL["owned"] = changeling.has_sting(ability) var/req_dna = initial(ability.req_dna) + var/req_absorbs = initial(ability.req_absorbs) AL["dna_cost"] = dna_cost - AL["can_purchase"] = ((req_dna <= absorbed_dna_count) && (dna_cost <= genetic_points_remaining)) + AL["can_purchase"] = ((req_absorbs <= true_absorbs) && (req_dna <= absorbed_dna_count) && (dna_cost <= genetic_points_remaining)) abilities += list(AL) diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index fae342e93d..8c6d7f52bd 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -19,6 +19,7 @@ var/datum/changelingprofile/first_prof = null var/dna_max = 6 //How many extra DNA strands the changeling can store for transformation. var/absorbedcount = 0 + var/trueabsorbs = 0//dna gained using absorb, not dna sting var/chem_charges = 20 var/chem_storage = 75 var/chem_recharge_rate = 1 diff --git a/code/modules/antagonists/changeling/changeling_power.dm b/code/modules/antagonists/changeling/changeling_power.dm index 0b4f015824..92c8a3c069 100644 --- a/code/modules/antagonists/changeling/changeling_power.dm +++ b/code/modules/antagonists/changeling/changeling_power.dm @@ -1,78 +1,81 @@ -/* - * Don't use the apostrophe in name or desc. Causes script errors. - * TODO: combine atleast some of the functionality with /proc_holder/spell - */ - -/obj/effect/proc_holder/changeling - panel = "Changeling" - name = "Prototype Sting" - desc = "" // Fluff - var/helptext = "" // Details - var/chemical_cost = 0 // negative chemical cost is for passive abilities (chemical glands) - var/dna_cost = -1 //cost of the sting in dna points. 0 = auto-purchase, -1 = cannot be purchased - var/req_dna = 0 //amount of dna needed to use this ability. Changelings always have atleast 1 - var/req_human = 0 //if you need to be human to use this ability - var/req_stat = CONSCIOUS // CONSCIOUS, UNCONSCIOUS or DEAD - var/always_keep = 0 // important for abilities like revive that screw you if you lose them. - var/ignores_fakedeath = FALSE // usable with the FAKEDEATH flag - - -/obj/effect/proc_holder/changeling/proc/on_purchase(mob/user, is_respec) - if(!is_respec) - SSblackbox.record_feedback("tally", "changeling_power_purchase", 1, name) - -/obj/effect/proc_holder/changeling/proc/on_refund(mob/user) - return - -/obj/effect/proc_holder/changeling/Click() - var/mob/user = usr - if(!user || !user.mind || !user.mind.has_antag_datum(/datum/antagonist/changeling)) - return - try_to_sting(user) - -/obj/effect/proc_holder/changeling/proc/try_to_sting(mob/user, mob/target) - if(!can_sting(user, target)) - return - var/datum/antagonist/changeling/c = user.mind.has_antag_datum(/datum/antagonist/changeling) - if(sting_action(user, target)) - SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]")) - sting_feedback(user, target) - c.chem_charges -= chemical_cost - -/obj/effect/proc_holder/changeling/proc/sting_action(mob/user, mob/target) - return 0 - -/obj/effect/proc_holder/changeling/proc/sting_feedback(mob/user, mob/target) - return 0 - -//Fairly important to remember to return 1 on success >.< -/obj/effect/proc_holder/changeling/proc/can_sting(mob/living/user, mob/target) - if(!ishuman(user) && !ismonkey(user)) //typecast everything from mob to carbon from this point onwards - return 0 - if(req_human && !ishuman(user)) - to_chat(user, "We cannot do that in this form!") - return 0 - var/datum/antagonist/changeling/c = user.mind.has_antag_datum(/datum/antagonist/changeling) - if(c.chem_charges < chemical_cost) - to_chat(user, "We require at least [chemical_cost] unit\s of chemicals to do that!") - return 0 - if(c.absorbedcount < req_dna) - to_chat(user, "We require at least [req_dna] sample\s of compatible DNA.") - return 0 - if(req_stat < user.stat) - to_chat(user, "We are incapacitated.") - return 0 - if((user.has_trait(TRAIT_FAKEDEATH)) && (!ignores_fakedeath)) - to_chat(user, "We are incapacitated.") - return 0 - return 1 - -//used in /mob/Stat() -/obj/effect/proc_holder/changeling/proc/can_be_used_by(mob/user) - if(!user || QDELETED(user)) - return 0 - if(!ishuman(user) && !ismonkey(user)) - return 0 - if(req_human && !ishuman(user)) - return 0 - return 1 +/* + * Don't use the apostrophe in name or desc. Causes script errors. + * TODO: combine atleast some of the functionality with /proc_holder/spell + */ + +/obj/effect/proc_holder/changeling + panel = "Changeling" + name = "Prototype Sting" + desc = "" // Fluff + var/helptext = "" // Details + var/chemical_cost = 0 // negative chemical cost is for passive abilities (chemical glands) + var/dna_cost = -1 //cost of the sting in dna points. 0 = auto-purchase, -1 = cannot be purchased + var/req_dna = 0 //amount of dna needed to use this ability. Changelings always have atleast 1 + var/req_human = 0 //if you need to be human to use this ability + var/req_absorbs = 0 //similar to req_dna, but only gained from absorbing, not DNA sting + var/req_stat = CONSCIOUS // CONSCIOUS, UNCONSCIOUS or DEAD + var/always_keep = 0 // important for abilities like revive that screw you if you lose them. + var/ignores_fakedeath = FALSE // usable with the FAKEDEATH flag + + +/obj/effect/proc_holder/changeling/proc/on_purchase(mob/user, is_respec) + if(!is_respec) + SSblackbox.record_feedback("tally", "changeling_power_purchase", 1, name) + +/obj/effect/proc_holder/changeling/proc/on_refund(mob/user) + return + +/obj/effect/proc_holder/changeling/Click() + var/mob/user = usr + if(!user || !user.mind || !user.mind.has_antag_datum(/datum/antagonist/changeling)) + return + try_to_sting(user) + +/obj/effect/proc_holder/changeling/proc/try_to_sting(mob/user, mob/target) + if(!can_sting(user, target)) + return + var/datum/antagonist/changeling/c = user.mind.has_antag_datum(/datum/antagonist/changeling) + if(sting_action(user, target)) + SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]")) + sting_feedback(user, target) + c.chem_charges -= chemical_cost + +/obj/effect/proc_holder/changeling/proc/sting_action(mob/user, mob/target) + return 0 + +/obj/effect/proc_holder/changeling/proc/sting_feedback(mob/user, mob/target) + return 0 + +//Fairly important to remember to return 1 on success >.< +/obj/effect/proc_holder/changeling/proc/can_sting(mob/living/user, mob/target) + if(!ishuman(user) && !ismonkey(user)) //typecast everything from mob to carbon from this point onwards + return 0 + if(req_human && !ishuman(user)) + to_chat(user, "We cannot do that in this form!") + return 0 + var/datum/antagonist/changeling/c = user.mind.has_antag_datum(/datum/antagonist/changeling) + if(c.chem_charges < chemical_cost) + to_chat(user, "We require at least [chemical_cost] unit\s of chemicals to do that!") + return 0 + if(c.absorbedcount < req_dna) + to_chat(user, "We require at least [req_dna] sample\s of compatible DNA.") + return 0 + if(c.trueabsorbs < req_absorbs) + to_chat(user, "We require at least [req_absorbs] sample\s of DNA gained through our Absorb ability.") + if(req_stat < user.stat) + to_chat(user, "We are incapacitated.") + return 0 + if((user.has_trait(TRAIT_FAKEDEATH)) && (!ignores_fakedeath)) + to_chat(user, "We are incapacitated.") + return 0 + return 1 + +//used in /mob/Stat() +/obj/effect/proc_holder/changeling/proc/can_be_used_by(mob/user) + if(!user || QDELETED(user)) + return 0 + if(!ishuman(user) && !ismonkey(user)) + return 0 + if(req_human && !ishuman(user)) + return 0 + return 1 diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm index c3d9d4e9f0..047056cac4 100644 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ b/code/modules/antagonists/changeling/powers/absorb.dm @@ -1,120 +1,121 @@ -/obj/effect/proc_holder/changeling/absorbDNA - name = "Absorb DNA" - desc = "Absorb the DNA of our victim." - chemical_cost = 0 - dna_cost = 0 - req_human = 1 - -/obj/effect/proc_holder/changeling/absorbDNA/can_sting(mob/living/carbon/user) - if(!..()) - return - - var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) - if(changeling.isabsorbing) - to_chat(user, "We are already absorbing!") - return - - if(!user.pulling || !iscarbon(user.pulling)) - to_chat(user, "We must be grabbing a creature to absorb them!") - return - if(user.grab_state <= GRAB_NECK) - to_chat(user, "We must have a tighter grip to absorb this creature!") - return - - var/mob/living/carbon/target = user.pulling - return changeling.can_absorb_dna(target) - - - -/obj/effect/proc_holder/changeling/absorbDNA/sting_action(mob/user) - var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) - var/mob/living/carbon/human/target = user.pulling - changeling.isabsorbing = 1 - for(var/i in 1 to 3) - switch(i) - if(1) - to_chat(user, "This creature is compatible. We must hold still...") - if(2) - user.visible_message("[user] extends a proboscis!", "We extend a proboscis.") - if(3) - user.visible_message("[user] stabs [target] with the proboscis!", "We stab [target] with the proboscis.") - to_chat(target, "You feel a sharp stabbing pain!") - target.take_overall_damage(40) - - SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("Absorb DNA", "[i]")) - if(!do_mob(user, target, 150)) - to_chat(user, "Our absorption of [target] has been interrupted!") - changeling.isabsorbing = 0 - return - - SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("Absorb DNA", "4")) - user.visible_message("[user] sucks the fluids from [target]!", "We have absorbed [target].") - to_chat(target, "You are absorbed by the changeling!") - - if(!changeling.has_dna(target.dna)) - changeling.add_new_profile(target) - - if(user.nutrition < NUTRITION_LEVEL_WELL_FED) - user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED) - - if(target.mind)//if the victim has got a mind - // Absorb a lizard, speak Draconic. - user.copy_known_languages_from(target) - - target.mind.show_memory(user, 0) //I can read your mind, kekeke. Output all their notes. - - //Some of target's recent speech, so the changeling can attempt to imitate them better. - //Recent as opposed to all because rounds tend to have a LOT of text. - var/list/recent_speech = list() - - var/list/say_log = target.logging[INDIVIDUAL_SAY_LOG] - - if(LAZYLEN(say_log) > LING_ABSORB_RECENT_SPEECH) - recent_speech = say_log.Copy(say_log.len-LING_ABSORB_RECENT_SPEECH+1,0) //0 so len-LING_ARS+1 to end of list - else - for(var/spoken_memory in say_log) - if(recent_speech.len >= LING_ABSORB_RECENT_SPEECH) - break - recent_speech[spoken_memory] = say_log[spoken_memory] - - if(recent_speech.len) - changeling.antag_memory += "Some of [target]'s speech patterns, we should study these to better impersonate them!
" - to_chat(user, "Some of [target]'s speech patterns, we should study these to better impersonate them!") - for(var/spoken_memory in recent_speech) - changeling.antag_memory += "\"[recent_speech[spoken_memory]]\"
" - to_chat(user, "\"[recent_speech[spoken_memory]]\"") - changeling.antag_memory += "We have no more knowledge of [target]'s speech patterns.
" - to_chat(user, "We have no more knowledge of [target]'s speech patterns.") - - - var/datum/antagonist/changeling/target_ling = target.mind.has_antag_datum(/datum/antagonist/changeling) - if(target_ling)//If the target was a changeling, suck out their extra juice and objective points! - to_chat(user, "[target] was one of us. We have absorbed their power.") - target_ling.remove_changeling_powers() - changeling.geneticpoints += round(target_ling.geneticpoints/2) - target_ling.geneticpoints = 0 - target_ling.canrespec = 0 - changeling.chem_storage += round(target_ling.chem_storage/2) - changeling.chem_charges += min(target_ling.chem_charges, changeling.chem_storage) - target_ling.chem_charges = 0 - target_ling.chem_storage = 0 - changeling.absorbedcount += (target_ling.absorbedcount) - target_ling.stored_profiles.len = 1 - target_ling.absorbedcount = 0 - - - changeling.chem_charges=min(changeling.chem_charges+10, changeling.chem_storage) - - changeling.isabsorbing = 0 - changeling.canrespec = 1 - - target.death(0) - target.Drain() - return TRUE - - - -//Absorbs the target DNA. -//datum/changeling/proc/absorb_dna(mob/living/carbon/T, mob/user) - -//datum/changeling/proc/store_dna(datum/dna/new_dna, mob/user) +/obj/effect/proc_holder/changeling/absorbDNA + name = "Absorb DNA" + desc = "Absorb the DNA of our victim." + chemical_cost = 0 + dna_cost = 0 + req_human = 1 + +/obj/effect/proc_holder/changeling/absorbDNA/can_sting(mob/living/carbon/user) + if(!..()) + return + + var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) + if(changeling.isabsorbing) + to_chat(user, "We are already absorbing!") + return + + if(!user.pulling || !iscarbon(user.pulling)) + to_chat(user, "We must be grabbing a creature to absorb them!") + return + if(user.grab_state <= GRAB_NECK) + to_chat(user, "We must have a tighter grip to absorb this creature!") + return + + var/mob/living/carbon/target = user.pulling + return changeling.can_absorb_dna(target) + + + +/obj/effect/proc_holder/changeling/absorbDNA/sting_action(mob/user) + var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) + var/mob/living/carbon/human/target = user.pulling + changeling.isabsorbing = 1 + for(var/i in 1 to 3) + switch(i) + if(1) + to_chat(user, "This creature is compatible. We must hold still...") + if(2) + user.visible_message("[user] extends a proboscis!", "We extend a proboscis.") + if(3) + user.visible_message("[user] stabs [target] with the proboscis!", "We stab [target] with the proboscis.") + to_chat(target, "You feel a sharp stabbing pain!") + target.take_overall_damage(40) + + SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("Absorb DNA", "[i]")) + if(!do_mob(user, target, 150)) + to_chat(user, "Our absorption of [target] has been interrupted!") + changeling.isabsorbing = 0 + return + + SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("Absorb DNA", "4")) + user.visible_message("[user] sucks the fluids from [target]!", "We have absorbed [target].") + to_chat(target, "You are absorbed by the changeling!") + + if(!changeling.has_dna(target.dna)) + changeling.add_new_profile(target) + changeling.trueabsorbs++ + + if(user.nutrition < NUTRITION_LEVEL_WELL_FED) + user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED) + + if(target.mind)//if the victim has got a mind + // Absorb a lizard, speak Draconic. + user.copy_known_languages_from(target) + + target.mind.show_memory(user, 0) //I can read your mind, kekeke. Output all their notes. + + //Some of target's recent speech, so the changeling can attempt to imitate them better. + //Recent as opposed to all because rounds tend to have a LOT of text. + var/list/recent_speech = list() + + var/list/say_log = target.logging[INDIVIDUAL_SAY_LOG] + + if(LAZYLEN(say_log) > LING_ABSORB_RECENT_SPEECH) + recent_speech = say_log.Copy(say_log.len-LING_ABSORB_RECENT_SPEECH+1,0) //0 so len-LING_ARS+1 to end of list + else + for(var/spoken_memory in say_log) + if(recent_speech.len >= LING_ABSORB_RECENT_SPEECH) + break + recent_speech[spoken_memory] = say_log[spoken_memory] + + if(recent_speech.len) + changeling.antag_memory += "Some of [target]'s speech patterns, we should study these to better impersonate them!
" + to_chat(user, "Some of [target]'s speech patterns, we should study these to better impersonate them!") + for(var/spoken_memory in recent_speech) + changeling.antag_memory += "\"[recent_speech[spoken_memory]]\"
" + to_chat(user, "\"[recent_speech[spoken_memory]]\"") + changeling.antag_memory += "We have no more knowledge of [target]'s speech patterns.
" + to_chat(user, "We have no more knowledge of [target]'s speech patterns.") + + + var/datum/antagonist/changeling/target_ling = target.mind.has_antag_datum(/datum/antagonist/changeling) + if(target_ling)//If the target was a changeling, suck out their extra juice and objective points! + to_chat(user, "[target] was one of us. We have absorbed their power.") + target_ling.remove_changeling_powers() + changeling.geneticpoints += round(target_ling.geneticpoints/2) + target_ling.geneticpoints = 0 + target_ling.canrespec = 0 + changeling.chem_storage += round(target_ling.chem_storage/2) + changeling.chem_charges += min(target_ling.chem_charges, changeling.chem_storage) + target_ling.chem_charges = 0 + target_ling.chem_storage = 0 + changeling.absorbedcount += (target_ling.absorbedcount) + target_ling.stored_profiles.len = 1 + target_ling.absorbedcount = 0 + + + changeling.chem_charges=min(changeling.chem_charges+10, changeling.chem_storage) + + changeling.isabsorbing = 0 + changeling.canrespec = 1 + + target.death(0) + target.Drain() + return TRUE + + + +//Absorbs the target DNA. +//datum/changeling/proc/absorb_dna(mob/living/carbon/T, mob/user) + +//datum/changeling/proc/store_dna(datum/dna/new_dna, mob/user) diff --git a/code/modules/antagonists/changeling/powers/spiders.dm b/code/modules/antagonists/changeling/powers/spiders.dm index b378f18c47..685767f601 100644 --- a/code/modules/antagonists/changeling/powers/spiders.dm +++ b/code/modules/antagonists/changeling/powers/spiders.dm @@ -1,12 +1,12 @@ -/obj/effect/proc_holder/changeling/spiders - name = "Spread Infestation" - desc = "Our form divides, creating arachnids which will grow into deadly beasts." - helptext = "The spiders are thoughtless creatures, and may attack their creators when fully grown. Requires at least 5 DNA absorptions." - chemical_cost = 45 - dna_cost = 1 - req_dna = 5 - -//Makes some spiderlings. Good for setting traps and causing general trouble. -/obj/effect/proc_holder/changeling/spiders/sting_action(mob/user) - spawn_atom_to_turf(/obj/structure/spider/spiderling/hunter, user, 2, FALSE) - return TRUE +/obj/effect/proc_holder/changeling/spiders + name = "Spread Infestation" + desc = "Our form divides, creating arachnids which will grow into deadly beasts." + helptext = "The spiders are thoughtless creatures, and may attack their creators when fully grown. Requires at least 3 DNA gained through Absorb, and not through DNA sting." + chemical_cost = 45 + dna_cost = 1 + req_absorbs = 3 + +//Makes some spiderlings. Good for setting traps and causing general trouble. +/obj/effect/proc_holder/changeling/spiders/sting_action(mob/user) + spawn_atom_to_turf(/obj/structure/spider/spiderling/hunter, user, 2, FALSE) + return TRUE