diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm
index 34a81b4d61..9a90a26971 100644
--- a/code/game/gamemodes/changeling/changeling_powers.dm
+++ b/code/game/gamemodes/changeling/changeling_powers.dm
@@ -13,6 +13,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
var/geneticdamage = 0
var/isabsorbing = 0
var/geneticpoints = 5
+ var/max_geneticpoints = 5
var/purchasedpowers = list()
var/mimicing = ""
@@ -126,547 +127,6 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
return
-//Used to switch species based on the changeling datum.
-/mob/proc/changeling_change_species()
-
- set category = "Changeling"
- set name = "Change Species (5)"
-
- var/mob/living/carbon/human/H = src
- if(!istype(H))
- src << "We may only use this power while in humanoid form."
- return
-
- var/datum/changeling/changeling = changeling_power(5,1,0)
- if(!changeling) return
-
- if(changeling.absorbed_species.len < 2)
- src << "We do not know of any other species genomes to use."
- return
-
- var/S = input("Select the target species: ", "Target Species", null) as null|anything in changeling.absorbed_species
- if(!S) return
-
- domutcheck(src, null)
-
- changeling.chem_charges -= 5
- changeling.geneticdamage = 30
-
- src.visible_message("[src] transforms!")
-
- src.verbs -= /mob/proc/changeling_change_species
- H.set_species(S,1) //Until someone moves body colour into DNA, they're going to have to use the default.
-
- spawn(10)
- src.verbs += /mob/proc/changeling_change_species
- src.regenerate_icons()
-
- changeling_update_languages(changeling.absorbed_languages)
- feedback_add_details("changeling_powers","TR")
-
- return 1
-
-//Absorbs the victim's DNA making them uncloneable. Requires a strong grip on the victim.
-//Doesn't cost anything as it's the most basic ability.
-/mob/proc/changeling_absorb_dna()
- set category = "Changeling"
- set name = "Absorb DNA"
-
- var/datum/changeling/changeling = changeling_power(0,0,100)
- if(!changeling) return
-
- var/obj/item/weapon/grab/G = src.get_active_hand()
- if(!istype(G))
- src << "We must be grabbing a creature in our active hand to absorb them."
- return
-
- var/mob/living/carbon/human/T = G.affecting
- if(!istype(T))
- src << "[T] is not compatible with our biology."
- return
-
- if(T.species.flags & NO_SCAN)
- src << "We do not know how to parse this creature's DNA!"
- return
-
- if(HUSK in T.mutations)
- src << "This creature's DNA is ruined beyond useability!"
- return
-
- if(G.state != GRAB_KILL)
- src << "We must have a tighter grip to absorb this creature."
- return
-
- if(changeling.isabsorbing)
- src << "We are already absorbing!"
- return
-
- changeling.isabsorbing = 1
- for(var/stage = 1, stage<=3, stage++)
- switch(stage)
- if(1)
- src << "This creature is compatible. We must hold still..."
- if(2)
- src << "We extend a proboscis."
- src.visible_message("[src] extends a proboscis!")
- if(3)
- src << "We stab [T] with the proboscis."
- src.visible_message("[src] stabs [T] with the proboscis!")
- T << "You feel a sharp stabbing pain!"
- var/obj/item/organ/external/affecting = T.get_organ(src.zone_sel.selecting)
- if(affecting.take_damage(39,0,1,0,"large organic needle"))
- T:UpdateDamageIcon()
-
- feedback_add_details("changeling_powers","A[stage]")
- if(!do_mob(src, T, 150))
- src << "Our absorption of [T] has been interrupted!"
- changeling.isabsorbing = 0
- return
-
- src << "We have absorbed [T]!"
- src.visible_message("[src] sucks the fluids from [T]!")
- T << "You have been absorbed by the changeling!"
-
- T.dna.real_name = T.real_name //Set this again, just to be sure that it's properly set.
- changeling.absorbed_dna |= T.dna
- if(src.nutrition < 400) src.nutrition = min((src.nutrition + T.nutrition), 400)
- changeling.chem_charges += 10
- changeling.geneticpoints += 2
-
- //Steal all of their languages!
- for(var/language in T.languages)
- if(!(language in changeling.absorbed_languages))
- changeling.absorbed_languages += language
-
- changeling_update_languages(changeling.absorbed_languages)
-
- //Steal their species!
- if(T.species && !(T.species.name in changeling.absorbed_species))
- changeling.absorbed_species += T.species.name
-
- if(T.mind && T.mind.changeling)
- if(T.mind.changeling.absorbed_dna)
- for(var/dna_data in T.mind.changeling.absorbed_dna) //steal all their loot
- if(dna_data in changeling.absorbed_dna)
- continue
- changeling.absorbed_dna += dna_data
- changeling.absorbedcount++
- T.mind.changeling.absorbed_dna.len = 1
-
- if(T.mind.changeling.purchasedpowers)
- for(var/datum/power/changeling/Tp in T.mind.changeling.purchasedpowers)
- if(Tp in changeling.purchasedpowers)
- continue
- else
- changeling.purchasedpowers += Tp
-
- if(!Tp.isVerb)
- call(Tp.verbpath)()
- else
- src.make_changeling()
-
- changeling.chem_charges += T.mind.changeling.chem_charges
- changeling.geneticpoints += T.mind.changeling.geneticpoints
- T.mind.changeling.chem_charges = 0
- T.mind.changeling.geneticpoints = 0
- T.mind.changeling.absorbedcount = 0
-
- changeling.absorbedcount++
- changeling.isabsorbing = 0
-
- T.death(0)
- T.Drain()
- return 1
-
-
-//Change our DNA to that of somebody we've absorbed.
-/mob/proc/changeling_transform()
- set category = "Changeling"
- set name = "Transform (5)"
-
- var/datum/changeling/changeling = changeling_power(5,1,0)
- if(!changeling) return
-
- var/list/names = list()
- for(var/datum/dna/DNA in changeling.absorbed_dna)
- names += "[DNA.real_name]"
-
- var/S = input("Select the target DNA: ", "Target DNA", null) as null|anything in names
- if(!S) return
-
- var/datum/dna/chosen_dna = changeling.GetDNA(S)
- if(!chosen_dna)
- return
-
- changeling.chem_charges -= 5
- src.visible_message("[src] transforms!")
- changeling.geneticdamage = 30
- src.dna = chosen_dna.Clone()
- src.real_name = chosen_dna.real_name
- src.flavor_text = ""
- src.UpdateAppearance()
- domutcheck(src, null)
-
- src.verbs -= /mob/proc/changeling_transform
- spawn(10) src.verbs += /mob/proc/changeling_transform
-
- feedback_add_details("changeling_powers","TR")
- return 1
-
-
-//Transform into a monkey.
-/mob/proc/changeling_lesser_form()
- set category = "Changeling"
- set name = "Lesser Form (1)"
-
- var/datum/changeling/changeling = changeling_power(1,0,0)
- if(!changeling) return
-
- if(src.has_brain_worms())
- src << "We cannot perform this ability at the present time!"
- return
-
- var/mob/living/carbon/human/H = src
-
- if(!istype(H) || !H.species.primitive_form)
- src << "We cannot perform this ability in this form!"
- return
-
- changeling.chem_charges--
- H.remove_changeling_powers()
- H.visible_message("[H] transforms!")
- changeling.geneticdamage = 30
- H << "Our genes cry out!"
- var/list/implants = list() //Try to preserve implants.
- for(var/obj/item/weapon/implant/W in H)
- implants += W
- H.monkeyize()
- feedback_add_details("changeling_powers","LF")
- return 1
-
-//Transform into a human
-/mob/proc/changeling_lesser_transform()
- set category = "Changeling"
- set name = "Transform (1)"
-
- var/datum/changeling/changeling = changeling_power(1,1,0)
- if(!changeling) return
-
- var/list/names = list()
- for(var/datum/dna/DNA in changeling.absorbed_dna)
- names += "[DNA.real_name]"
-
- var/S = input("Select the target DNA: ", "Target DNA", null) as null|anything in names
- if(!S) return
-
- var/datum/dna/chosen_dna = changeling.GetDNA(S)
- if(!chosen_dna)
- return
-
- var/mob/living/carbon/C = src
-
- changeling.chem_charges--
- C.remove_changeling_powers()
- C.visible_message("[C] transforms!")
- C.dna = chosen_dna.Clone()
-
- var/list/implants = list()
- for (var/obj/item/weapon/implant/I in C) //Still preserving implants
- implants += I
-
- C.transforming = 1
- C.canmove = 0
- C.icon = null
- C.overlays.Cut()
- C.invisibility = 101
- var/atom/movable/overlay/animation = new /atom/movable/overlay( C.loc )
- animation.icon_state = "blank"
- animation.icon = 'icons/mob/mob.dmi'
- animation.master = src
- flick("monkey2h", animation)
- sleep(48)
- qdel(animation)
-
- for(var/obj/item/W in src)
- C.drop_from_inventory(W)
-
- var/mob/living/carbon/human/O = new /mob/living/carbon/human( src )
- if (C.dna.GetUIState(DNA_UI_GENDER))
- O.gender = FEMALE
- else
- O.gender = MALE
- O.dna = C.dna.Clone()
- C.dna = null
- O.real_name = chosen_dna.real_name
-
- for(var/obj/T in C)
- qdel(T)
-
- O.loc = C.loc
-
- O.UpdateAppearance()
- domutcheck(O, null)
- O.setToxLoss(C.getToxLoss())
- O.adjustBruteLoss(C.getBruteLoss())
- O.setOxyLoss(C.getOxyLoss())
- O.adjustFireLoss(C.getFireLoss())
- O.stat = C.stat
- for (var/obj/item/weapon/implant/I in implants)
- I.loc = O
- I.implanted = O
-
- C.mind.transfer_to(O)
- O.make_changeling()
- O.changeling_update_languages(changeling.absorbed_languages)
-
- feedback_add_details("changeling_powers","LFT")
- qdel(C)
- return 1
-
-
-//Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay.
-/mob/proc/changeling_fakedeath()
- set category = "Changeling"
- set name = "Regenerative Stasis (20)"
-
- var/datum/changeling/changeling = changeling_power(20,1,100,DEAD)
- if(!changeling) return
-
- var/mob/living/carbon/C = src
- if(!C.stat && alert("Are we sure we wish to fake our death?",,"Yes","No") == "No")//Confirmation for living changelings if they want to fake their death
- return
- C << "We will attempt to regenerate our form."
-
- C.status_flags |= FAKEDEATH //play dead
- C.update_canmove()
- C.remove_changeling_powers()
-
- C.emote("gasp")
- C.tod = worldtime2text()
-
- spawn(rand(800,2000))
- if(changeling_power(20,1,100,DEAD))
- // charge the changeling chemical cost for stasis
- changeling.chem_charges -= 20
-
- // restore us to health
- C.revive()
-
- // remove our fake death flag
- C.status_flags &= ~(FAKEDEATH)
-
- // let us move again
- C.update_canmove()
-
- // re-add out changeling powers
- C.make_changeling()
-
- // sending display messages
- C << "We have regenerated."
-
-
- feedback_add_details("changeling_powers","FD")
- return 1
-
-
-//Boosts the range of your next sting attack by 1
-/mob/proc/changeling_boost_range()
- set category = "Changeling"
- set name = "Ranged Sting (10)"
- set desc="Your next sting ability can be used against targets 2 squares away."
-
- var/datum/changeling/changeling = changeling_power(10,0,100)
- if(!changeling) return 0
- changeling.chem_charges -= 10
- src << "Your throat adjusts to launch the sting."
- changeling.sting_range = 2
- src.verbs -= /mob/proc/changeling_boost_range
- spawn(5) src.verbs += /mob/proc/changeling_boost_range
- feedback_add_details("changeling_powers","RS")
- return 1
-
-
-//Recover from stuns.
-/mob/proc/changeling_unstun()
- set category = "Changeling"
- set name = "Epinephrine Sacs (45)"
- set desc = "Removes all stuns"
-
- var/datum/changeling/changeling = changeling_power(45,0,100,UNCONSCIOUS)
- if(!changeling) return 0
- changeling.chem_charges -= 45
-
- var/mob/living/carbon/human/C = src
- C.stat = 0
- C.SetParalysis(0)
- C.SetStunned(0)
- C.SetWeakened(0)
- C.lying = 0
- C.update_canmove()
-
- src.verbs -= /mob/proc/changeling_unstun
- spawn(5) src.verbs += /mob/proc/changeling_unstun
- feedback_add_details("changeling_powers","UNS")
- return 1
-
-
-//Speeds up chemical regeneration
-/mob/proc/changeling_fastchemical()
- src.mind.changeling.chem_recharge_rate *= 2
- return 1
-
-//Increases macimum chemical storage
-/mob/proc/changeling_engorgedglands()
- src.mind.changeling.chem_storage += 25
- return 1
-
-
-//Prevents AIs tracking you but makes you easily detectable to the human-eye.
-/mob/proc/changeling_digitalcamo()
- set category = "Changeling"
- set name = "Toggle Digital Camoflague"
- set desc = "The AI can no longer track us, but we will look different if examined. Has a constant cost while active."
-
- var/datum/changeling/changeling = changeling_power()
- if(!changeling) return 0
-
- var/mob/living/carbon/human/C = src
- if(C.digitalcamo) C << "We return to normal."
- else C << "We distort our form to prevent AI-tracking."
- C.digitalcamo = !C.digitalcamo
-
- spawn(0)
- while(C && C.digitalcamo && C.mind && C.mind.changeling)
- C.mind.changeling.chem_charges = max(C.mind.changeling.chem_charges - 1, 0)
- sleep(40)
-
- src.verbs -= /mob/proc/changeling_digitalcamo
- spawn(5) src.verbs += /mob/proc/changeling_digitalcamo
- feedback_add_details("changeling_powers","CAM")
- return 1
-
-
-//Starts healing you every second for 10 seconds. Can be used whilst unconscious.
-/mob/proc/changeling_rapidregen()
- set category = "Changeling"
- set name = "Rapid Regeneration (30)"
- set desc = "Begins rapidly regenerating. Does not effect stuns or chemicals."
-
- var/datum/changeling/changeling = changeling_power(30,0,100,UNCONSCIOUS)
- if(!changeling) return 0
- src.mind.changeling.chem_charges -= 30
-
- var/mob/living/carbon/human/C = src
- spawn(0)
- for(var/i = 0, i<10,i++)
- if(C)
- C.adjustBruteLoss(-10)
- C.adjustToxLoss(-10)
- C.adjustOxyLoss(-10)
- C.adjustFireLoss(-10)
- sleep(10)
-
- src.verbs -= /mob/proc/changeling_rapidregen
- spawn(5) src.verbs += /mob/proc/changeling_rapidregen
- feedback_add_details("changeling_powers","RR")
- return 1
-
-// HIVE MIND UPLOAD/DOWNLOAD DNA
-
-var/list/datum/dna/hivemind_bank = list()
-
-/mob/proc/changeling_hiveupload()
- set category = "Changeling"
- set name = "Hive Channel (10)"
- set desc = "Allows you to channel DNA in the airwaves to allow other changelings to absorb it."
-
- var/datum/changeling/changeling = changeling_power(10,1)
- if(!changeling) return
-
- var/list/names = list()
- for(var/datum/dna/DNA in changeling.absorbed_dna)
- if(!(DNA in hivemind_bank))
- names += DNA.real_name
-
- if(names.len <= 0)
- src << "The airwaves already have all of our DNA."
- return
-
- var/S = input("Select a DNA to channel: ", "Channel DNA", null) as null|anything in names
- if(!S) return
-
- var/datum/dna/chosen_dna = changeling.GetDNA(S)
- if(!chosen_dna)
- return
-
- changeling.chem_charges -= 10
- hivemind_bank += chosen_dna
- src << "We channel the DNA of [S] to the air."
- feedback_add_details("changeling_powers","HU")
- return 1
-
-/mob/proc/changeling_hivedownload()
- set category = "Changeling"
- set name = "Hive Absorb (20)"
- set desc = "Allows you to absorb DNA that is being channeled in the airwaves."
-
- var/datum/changeling/changeling = changeling_power(20,1)
- if(!changeling) return
-
- var/list/names = list()
- for(var/datum/dna/DNA in hivemind_bank)
- if(!(DNA in changeling.absorbed_dna))
- names[DNA.real_name] = DNA
-
- if(names.len <= 0)
- src << "There's no new DNA to absorb from the air."
- return
-
- var/S = input("Select a DNA absorb from the air: ", "Absorb DNA", null) as null|anything in names
- if(!S) return
- var/datum/dna/chosen_dna = names[S]
- if(!chosen_dna)
- return
-
- changeling.chem_charges -= 20
- changeling.absorbed_dna += chosen_dna
- src << "We absorb the DNA of [S] from the air."
- feedback_add_details("changeling_powers","HD")
- return 1
-
-// Fake Voice
-
-/mob/proc/changeling_mimicvoice()
- set category = "Changeling"
- set name = "Mimic Voice"
- set desc = "Shape our vocal glands to form a voice of someone we choose. We cannot regenerate chemicals when mimicing."
-
-
- var/datum/changeling/changeling = changeling_power()
- if(!changeling) return
-
- if(changeling.mimicing)
- changeling.mimicing = ""
- src << "We return our vocal glands to their original location."
- return
-
- var/mimic_voice = sanitize(input(usr, "Enter a name to mimic.", "Mimic Voice", null), MAX_NAME_LEN)
- if(!mimic_voice)
- return
-
- changeling.mimicing = mimic_voice
-
- src << "We shape our glands to take the voice of [mimic_voice], this will stop us from regenerating chemicals while active."
- src << "Use this power again to return to our original voice and reproduce chemicals again."
-
- feedback_add_details("changeling_powers","MV")
-
- spawn(0)
- while(src && src.mind && src.mind.changeling && src.mind.changeling.mimicing)
- src.mind.changeling.chem_charges = max(src.mind.changeling.chem_charges - 1, 0)
- sleep(40)
- if(src && src.mind && src.mind.changeling)
- src.mind.changeling.mimicing = ""
//////////
//STINGS// //They get a pretty header because there's just so fucking many of them ;_;
//////////
@@ -709,149 +169,7 @@ var/list/datum/dna/hivemind_bank = list()
return
-/mob/proc/changeling_lsdsting()
- set category = "Changeling"
- set name = "Hallucination Sting (15)"
- set desc = "Causes terror in the target."
-
- var/mob/living/carbon/T = changeling_sting(15,/mob/proc/changeling_lsdsting)
- if(!T) return 0
- spawn(rand(300,600))
- if(T) T.hallucination += 400
- feedback_add_details("changeling_powers","HS")
- return 1
-
-/mob/proc/changeling_silence_sting()
- set category = "Changeling"
- set name = "Silence sting (10)"
- set desc="Sting target"
-
- var/mob/living/carbon/T = changeling_sting(10,/mob/proc/changeling_silence_sting)
- if(!T) return 0
- T.silent += 30
- feedback_add_details("changeling_powers","SS")
- return 1
-
-/mob/proc/changeling_blind_sting()
- set category = "Changeling"
- set name = "Blind sting (20)"
- set desc="Sting target"
-
- var/mob/living/carbon/T = changeling_sting(20,/mob/proc/changeling_blind_sting)
- if(!T) return 0
- T << "Your eyes burn horrificly!"
- T.disabilities |= NEARSIGHTED
- spawn(300) T.disabilities &= ~NEARSIGHTED
- T.eye_blind = 10
- T.eye_blurry = 20
- feedback_add_details("changeling_powers","BS")
- return 1
-
-/mob/proc/changeling_deaf_sting()
- set category = "Changeling"
- set name = "Deaf sting (5)"
- set desc="Sting target:"
-
- var/mob/living/carbon/T = changeling_sting(5,/mob/proc/changeling_deaf_sting)
- if(!T) return 0
- T << "Your ears pop and begin ringing loudly!"
- T.sdisabilities |= DEAF
- spawn(300) T.sdisabilities &= ~DEAF
- feedback_add_details("changeling_powers","DS")
- return 1
-
-/mob/proc/changeling_paralysis_sting()
- set category = "Changeling"
- set name = "Paralysis sting (30)"
- set desc="Sting target"
-
- var/mob/living/carbon/T = changeling_sting(30,/mob/proc/changeling_paralysis_sting)
- if(!T) return 0
- T << "Your muscles begin to painfully tighten."
- T.Weaken(20)
- feedback_add_details("changeling_powers","PS")
- return 1
-
-/mob/proc/changeling_transformation_sting()
- set category = "Changeling"
- set name = "Transformation sting (40)"
- set desc="Sting target"
-
- var/datum/changeling/changeling = changeling_power(40)
- if(!changeling) return 0
- var/list/names = list()
- for(var/datum/dna/DNA in changeling.absorbed_dna)
- names += "[DNA.real_name]"
- var/S = input("Select the target DNA: ", "Target DNA", null) as null|anything in names
- if(!S) return
-
- var/datum/dna/chosen_dna = changeling.GetDNA(S)
- if(!chosen_dna)
- return
-
- var/mob/living/carbon/T = changeling_sting(40,/mob/proc/changeling_transformation_sting)
- if(!T) return 0
- if((HUSK in T.mutations) || (!ishuman(T) && !issmall(T)))
- src << "Our sting appears ineffective against its DNA."
- return 0
- T.visible_message("[T] transforms!")
- T.dna = chosen_dna.Clone()
- T.real_name = chosen_dna.real_name
- T.UpdateAppearance()
- domutcheck(T, null)
- feedback_add_details("changeling_powers","TS")
- return 1
-
-/mob/proc/changeling_unfat_sting()
- set category = "Changeling"
- set name = "Unfat sting (5)"
- set desc = "Sting target"
-
- var/mob/living/carbon/T = changeling_sting(5,/mob/proc/changeling_unfat_sting)
- if(!T) return 0
- T << "you feel a small prick as stomach churns violently and you become to feel skinnier."
- T.overeatduration = 0
- T.nutrition -= 100
- feedback_add_details("changeling_powers","US")
- return 1
-
-/mob/proc/changeling_DEATHsting()
- set category = "Changeling"
- set name = "Death Sting (40)"
- set desc = "Causes spasms onto death."
-
- var/mob/living/carbon/T = changeling_sting(40,/mob/proc/changeling_DEATHsting)
- if(!T) return 0
- T << "You feel a small prick and your chest becomes tight."
- T.silent = 10
- T.Paralyse(10)
- T.make_jittery(1000)
- if(T.reagents) T.reagents.add_reagent("lexorin", 40)
- feedback_add_details("changeling_powers","DTHS")
- return 1
-
-/mob/proc/changeling_extract_dna_sting()
- set category = "Changeling"
- set name = "Extract DNA Sting (40)"
- set desc="Stealthily sting a target to extract their DNA."
-
- var/datum/changeling/changeling = null
- if(src.mind && src.mind.changeling)
- changeling = src.mind.changeling
- if(!changeling)
- return 0
-
- var/mob/living/carbon/human/T = changeling_sting(40, /mob/proc/changeling_extract_dna_sting)
- if(!T) return 0
-
- T.dna.real_name = T.real_name
- changeling.absorbed_dna |= T.dna
- if(T.species && !(T.species.name in changeling.absorbed_species))
- changeling.absorbed_species += T.species.name
-
- feedback_add_details("changeling_powers","ED")
- return 1
diff --git a/code/game/gamemodes/changeling/generic_equip_procs.dm b/code/game/gamemodes/changeling/generic_equip_procs.dm
new file mode 100644
index 0000000000..638bd59930
--- /dev/null
+++ b/code/game/gamemodes/changeling/generic_equip_procs.dm
@@ -0,0 +1,62 @@
+//This is a generic proc that should be called by other ling armor procs to equip them.
+/mob/proc/changeling_generic_armor(var/armor_type, var/helmet_type)
+ var/datum/changeling/changeling = changeling_power(20,1,100,CONSCIOUS)
+ if(!changeling)
+ return
+
+ if(!ishuman(src))
+ return 0
+
+ var/mob/living/carbon/human/M = src
+
+ //First, check if we're already wearing the armor, and if so, take it off.
+ if(istype(M.wear_suit, armor_type) || istype(M.head, helmet_type))
+ M.visible_message("[M] casts off their [M.wear_suit.name]!",
+ "We cast off our [M.wear_suit.name]",
+ "You hear the organic matter ripping and tearing!")
+ qdel(M.wear_suit)
+ qdel(M.head)
+ M.update_inv_wear_suit()
+ M.update_inv_head()
+ M.update_hair()
+ return 1
+
+ if(M.head || M.wear_suit) //Make sure our slots aren't full
+ src << "We require nothing to be on our head, and we cannot wear any external suits."
+ return 0
+
+ var/obj/item/clothing/suit/A = new armor_type(src)
+ src.equip_to_slot_or_del(A, slot_wear_suit)
+
+ var/obj/item/clothing/suit/H = new helmet_type(src)
+ src.equip_to_slot_or_del(H, slot_head)
+
+ src.mind.changeling.chem_charges -= 20
+ playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
+ M.update_inv_wear_suit()
+ M.update_inv_head()
+ M.update_hair()
+ return 1
+
+//This is a generic proc that should be called by other ling weapon procs to equip them.
+/mob/proc/changeling_generic_weapon(var/weapon_type, var/make_sound = 1)
+ var/datum/changeling/changeling = changeling_power(20,1,100,CONSCIOUS)
+ if(!changeling)
+ return
+
+ if(!ishuman(src))
+ return 0
+
+ var/mob/living/carbon/human/M = src
+
+ if(M.l_hand && M.r_hand) //Make sure our hands aren't full.
+ src << "Our hands are full. Drop something first."
+ return 0
+
+ var/obj/item/weapon/W = new weapon_type(src)
+ src.put_in_hands(W)
+
+ src.mind.changeling.chem_charges -= 20
+ if(make_sound)
+ playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
+ return 1
\ No newline at end of file
diff --git a/code/game/gamemodes/changeling/modularchangling.dm b/code/game/gamemodes/changeling/modularchangling.dm
index 5048977789..89cb92f28f 100644
--- a/code/game/gamemodes/changeling/modularchangling.dm
+++ b/code/game/gamemodes/changeling/modularchangling.dm
@@ -1,5 +1,7 @@
// READ: Don't use the apostrophe in name or desc. Causes script errors.
+//Ling power's evolution menu entry datum should be contained alongside the mob proc for the actual power, in their own file.
+
var/list/powers = typesof(/datum/power/changeling) - /datum/power/changeling //needed for the badmin verb for now
var/list/datum/power/changeling/powerinstances = list()
@@ -14,177 +16,6 @@ var/list/datum/power/changeling/powerinstances = list()
var/allowduringlesserform = 0
var/genomecost = 500000 // Cost for the changling to evolve this power.
-/datum/power/changeling/absorb_dna
- name = "Absorb DNA"
- desc = "Permits us to syphon the DNA from a human. They become one with us, and we become stronger."
- genomecost = 0
- verbpath = /mob/proc/changeling_absorb_dna
-
-/datum/power/changeling/transform
- name = "Transform"
- desc = "We take on the apperance and voice of one we have absorbed."
- genomecost = 0
- verbpath = /mob/proc/changeling_transform
-
-/datum/power/changeling/change_species
- name = "Change Species"
- desc = "We take on the apperance of a species that we have absorbed."
- genomecost = 0
- verbpath = /mob/proc/changeling_change_species
-
-/datum/power/changeling/fakedeath
- name = "Regenerative Stasis"
- desc = "We become weakened to a death-like state, where we will rise again from death."
- helptext = "Can be used before or after death. Duration varies greatly."
- genomecost = 0
- allowduringlesserform = 1
- verbpath = /mob/proc/changeling_fakedeath
-
-// Hivemind
-
-/datum/power/changeling/hive_upload
- name = "Hive Channel"
- desc = "We can channel a DNA into the airwaves, allowing our fellow changelings to absorb it and transform into it as if they acquired the DNA themselves."
- helptext = "Allows other changelings to absorb the DNA you channel from the airwaves. Will not help them towards their absorb objectives."
- genomecost = 0
- verbpath = /mob/proc/changeling_hiveupload
-
-/datum/power/changeling/hive_download
- name = "Hive Absorb"
- desc = "We can absorb a single DNA from the airwaves, allowing us to use more disguises with help from our fellow changelings."
- helptext = "Allows you to absorb a single DNA and use it. Does not count towards your absorb objective."
- genomecost = 0
- verbpath = /mob/proc/changeling_hivedownload
-
-/datum/power/changeling/lesser_form
- name = "Lesser Form"
- desc = "We debase ourselves and become lesser. We become a monkey."
- genomecost = 4
- verbpath = /mob/proc/changeling_lesser_form
-
-/datum/power/changeling/deaf_sting
- name = "Deaf Sting"
- desc = "We silently sting a human, completely deafening them for a short time."
- genomecost = 1
- allowduringlesserform = 1
- verbpath = /mob/proc/changeling_deaf_sting
-
-/datum/power/changeling/blind_sting
- name = "Blind Sting"
- desc = "We silently sting a human, completely blinding them for a short time."
- genomecost = 2
- allowduringlesserform = 1
- verbpath = /mob/proc/changeling_blind_sting
-
-/datum/power/changeling/silence_sting
- name = "Silence Sting"
- desc = "We silently sting a human, completely silencing them for a short time."
- helptext = "Does not provide a warning to a victim that they have been stung, until they try to speak and cannot."
- genomecost = 3
- allowduringlesserform = 1
- verbpath = /mob/proc/changeling_silence_sting
-
-/datum/power/changeling/mimicvoice
- name = "Mimic Voice"
- desc = "We shape our vocal glands to sound like a desired voice."
- helptext = "Will turn your voice into the name that you enter. We must constantly expend chemicals to maintain our form like this"
- genomecost = 1
- verbpath = /mob/proc/changeling_mimicvoice
-
-/datum/power/changeling/extractdna
- name = "Extract DNA"
- desc = "We stealthily sting a target and extract the DNA from them."
- helptext = "Will give you the DNA of your target, allowing you to transform into them. Does not count towards absorb objectives."
- genomecost = 2
- allowduringlesserform = 1
- verbpath = /mob/proc/changeling_extract_dna_sting
-
-/datum/power/changeling/transformation_sting
- name = "Transformation Sting"
- desc = "We silently sting a human, injecting a retrovirus that forces them to transform into another."
- helptext = "Does not provide a warning to others. The victim will transform much like a changeling would."
- genomecost = 3
- verbpath = /mob/proc/changeling_transformation_sting
-
-/datum/power/changeling/paralysis_sting
- name = "Paralysis Sting"
- desc = "We silently sting a human, paralyzing them for a short time."
- genomecost = 8
- verbpath = /mob/proc/changeling_paralysis_sting
-
-/datum/power/changeling/LSDSting
- name = "Hallucination Sting"
- desc = "We evolve the ability to sting a target with a powerful hallunicationary chemical."
- helptext = "The target does not notice they have been stung. The effect occurs after 30 to 60 seconds."
- genomecost = 3
- verbpath = /mob/proc/changeling_lsdsting
-
-/datum/power/changeling/DeathSting
- name = "Death Sting"
- desc = "We silently sting a human, filling him with potent chemicals. His rapid death is all but assured."
- genomecost = 10
- verbpath = /mob/proc/changeling_DEATHsting
-
-///datum/power/changeling/unfat_sting
-// name = "Unfat Sting"
-// desc = "We silently sting a human, forcing them to rapidly metabolize their fat."
-// genomecost = 1
-// verbpath = /mob/proc/changeling_unfat_sting
-
-/datum/power/changeling/boost_range
- name = "Boost Range"
- desc = "We evolve the ability to shoot our stingers at humans, with some preperation."
- genomecost = 2
- allowduringlesserform = 1
- verbpath = /mob/proc/changeling_boost_range
-
-/datum/power/changeling/Epinephrine
- name = "Epinephrine sacs"
- desc = "We evolve additional sacs of adrenaline throughout our body."
- helptext = "Gives the ability to instantly recover from stuns. High chemical cost."
- genomecost = 3
- verbpath = /mob/proc/changeling_unstun
-
-/datum/power/changeling/ChemicalSynth
- name = "Rapid Chemical-Synthesis"
- desc = "We evolve new pathways for producing our necessary chemicals, permitting us to naturally create them faster."
- helptext = "Doubles the rate at which we naturally recharge chemicals."
- genomecost = 4
- isVerb = 0
- verbpath = /mob/proc/changeling_fastchemical
-/*
-/datum/power/changeling/AdvChemicalSynth
- name = "Advanced Chemical-Synthesis"
- desc = "We evolve new pathways for producing our necessary chemicals, permitting us to naturally create them faster."
- helptext = "Doubles the rate at which we naturally recharge chemicals."
- genomecost = 8
- isVerb = 0
- verbpath = /mob/proc/changeling_fastchemical
-*/
-/datum/power/changeling/EngorgedGlands
- name = "Engorged Chemical Glands"
- desc = "Our chemical glands swell, permitting us to store more chemicals inside of them."
- helptext = "Allows us to store an extra 25 units of chemicals."
- genomecost = 4
- isVerb = 0
- verbpath = /mob/proc/changeling_engorgedglands
-
-/datum/power/changeling/DigitalCamoflague
- name = "Digital Camoflauge"
- desc = "We evolve the ability to distort our form and proprtions, defeating common altgorthms used to detect lifeforms on cameras."
- helptext = "We cannot be tracked by camera while using this skill. However, humans looking at us will find us.. uncanny. We must constantly expend chemicals to maintain our form like this."
- genomecost = 1
- allowduringlesserform = 1
- verbpath = /mob/proc/changeling_digitalcamo
-
-/datum/power/changeling/rapidregeneration
- name = "Rapid Regeneration"
- desc = "We evolve the ability to rapidly regenerate, negating the need for stasis."
- helptext = "Heals a moderate amount of damage every tick."
- genomecost = 7
- verbpath = /mob/proc/changeling_rapidregen
-
-
// Modularchangling, totally stolen from the new player panel. YAYY
/datum/changeling/proc/EvolutionMenu()//The new one
@@ -389,7 +220,7 @@ var/list/datum/power/changeling/powerinstances = list()
Changling Evolution Menu
Hover over a power to see more information
Current evolution points left to evolve with: [geneticpoints]
- Absorb genomes to acquire more evolution points
+ Absorb other changelings to acquire more evolution points
diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm new file mode 100644 index 0000000000..7d5a42e7e8 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -0,0 +1,126 @@ +/datum/power/changeling/absorb_dna + name = "Absorb DNA" + desc = "Permits us to syphon the DNA from a human. They become one with us, and we become stronger." + genomecost = 0 + verbpath = /mob/proc/changeling_absorb_dna + +//Absorbs the victim's DNA making them uncloneable. Requires a strong grip on the victim. +//Doesn't cost anything as it's the most basic ability. +/mob/proc/changeling_absorb_dna() + set category = "Changeling" + set name = "Absorb DNA" + + var/datum/changeling/changeling = changeling_power(0,0,100) + if(!changeling) return + + var/obj/item/weapon/grab/G = src.get_active_hand() + if(!istype(G)) + src << "We must be grabbing a creature in our active hand to absorb them." + return + + var/mob/living/carbon/human/T = G.affecting + if(!istype(T)) + src << "[T] is not compatible with our biology." + return + + if(T.species.flags & NO_SCAN) + src << "We do not know how to parse this creature's DNA!" + return + + if(HUSK in T.mutations) + src << "This creature's DNA is ruined beyond useability!" + return + + if(G.state != GRAB_KILL) + src << "We must have a tighter grip to absorb this creature." + return + + if(changeling.isabsorbing) + src << "We are already absorbing!" + return + + changeling.isabsorbing = 1 + for(var/stage = 1, stage<=3, stage++) + switch(stage) + if(1) + src << "This creature is compatible. We must hold still..." + if(2) + src << "We extend a proboscis." + src.visible_message("[src] extends a proboscis!") + if(3) + src << "We stab [T] with the proboscis." + src.visible_message("[src] stabs [T] with the proboscis!") + T << "You feel a sharp stabbing pain!" + var/obj/item/organ/external/affecting = T.get_organ(src.zone_sel.selecting) + if(affecting.take_damage(39,0,1,0,"large organic needle")) + T:UpdateDamageIcon() + + feedback_add_details("changeling_powers","A[stage]") + if(!do_mob(src, T, 150)) + src << "Our absorption of [T] has been interrupted!" + changeling.isabsorbing = 0 + return + + src << "We have absorbed [T]!" + src.visible_message("[src] sucks the fluids from [T]!") + T << "You have been absorbed by the changeling!" + + T.dna.real_name = T.real_name //Set this again, just to be sure that it's properly set. + changeling.absorbed_dna |= T.dna + if(src.nutrition < 400) + src.nutrition = min((src.nutrition + T.nutrition), 400) + changeling.chem_charges += 10 +// changeling.geneticpoints += 2 + src.verbs += /mob/proc/changeling_respec + src << "We can now re-adapt, reverting our evolution so that we may start anew, if needed." + + //Steal all of their languages! + for(var/language in T.languages) + if(!(language in changeling.absorbed_languages)) + changeling.absorbed_languages += language + + changeling_update_languages(changeling.absorbed_languages) + + //Steal their species! + if(T.species && !(T.species.name in changeling.absorbed_species)) + changeling.absorbed_species += T.species.name + + if(T.mind && T.mind.changeling) + if(T.mind.changeling.absorbed_dna) + for(var/dna_data in T.mind.changeling.absorbed_dna) //steal all their loot + if(dna_data in changeling.absorbed_dna) + continue + changeling.absorbed_dna += dna_data + changeling.absorbedcount++ + T.mind.changeling.absorbed_dna.len = 1 + + changeling.geneticpoints += 5 + changeling.max_geneticpoints += 5 + src << "We absorbed another changeling, and we grow stronger. Our genomes increase." + +/* + if(T.mind.changeling.purchasedpowers) + for(var/datum/power/changeling/Tp in T.mind.changeling.purchasedpowers) + if(Tp in changeling.purchasedpowers) + continue + else + changeling.purchasedpowers += Tp + + if(!Tp.isVerb) + call(Tp.verbpath)() + else + src.make_changeling() + + changeling.chem_charges += T.mind.changeling.chem_charges + changeling.geneticpoints += T.mind.changeling.geneticpoints +*/ + T.mind.changeling.chem_charges = 0 + T.mind.changeling.geneticpoints = 0 + T.mind.changeling.absorbedcount = 0 + + changeling.absorbedcount++ + changeling.isabsorbing = 0 + + T.death(0) + T.Drain() + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/armblade.dm b/code/game/gamemodes/changeling/powers/armblade.dm new file mode 100644 index 0000000000..53438797f8 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/armblade.dm @@ -0,0 +1,75 @@ +/datum/power/changeling/arm_blade + name = "Arm Blade" + desc = "We reform one of our arms into a deadly blade." + helptext = "We may retract our armblade by dropping it. It can deflect projectiles. Cannot be used while in lesser form." + genomecost = 2 + verbpath = /mob/proc/changeling_arm_blade + +//Grows a scary, and powerful arm blade. +/mob/proc/changeling_arm_blade() + set category = "Changeling" + set name = "Arm Blade (20)" + + if(changeling_generic_weapon(/obj/item/weapon/melee/arm_blade)) + return 1 + return 0 + +/obj/item/weapon/melee/arm_blade + name = "arm blade" + desc = "A grotesque blade made out of bone and flesh that cleaves through people as a hot knife through butter." + icon = 'icons/obj/weapons.dmi' + icon_state = "arm_blade" + item_state = "arm_blade" + w_class = 5.0 + force = 40 + sharp = 1 + edge = 1 + anchored = 1 + throwforce = 0 //Just to be on the safe side + throw_range = 0 + throw_speed = 0 + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + var/mob/living/creator //This is just like ninja swords, needed to make sure dumb shit that removes the sword doesn't make it stay around. + +/obj/item/weapon/melee/arm_blade/IsShield() + return 1 + +/obj/item/weapon/melee/arm_blade/New(location) + ..() + processing_objects |= src + if(ismob(loc)) + visible_message("A grotesque blade forms around [loc.name]\'s arm!", + "Our arm twists and mutates, transforming it into a deadly blade.", + "You hear organic matter ripping and tearing!") + src.creator = loc + +/obj/item/weapon/melee/arm_blade/dropped(mob/user) + visible_message("With a sickening crunch, [creator] reforms their arm blade into an arm!", + "We assimilate the weapon back into our body.", + "[loc.name]\'s flesh rapidly inflates, forming a bloated mass around their body!", + "We inflate our flesh, creating a spaceproof suit!", + "You hear organic matter ripping and tearing!") + +/obj/item/clothing/suit/space/changeling/dropped() + qdel(src) + +/obj/item/clothing/head/helmet/space/changeling + name = "flesh mass" + icon_state = "lingspacehelmet" + item_state = "lingspacehelmet" + desc = "A covering of pressure and temperature-resistant organic tissue with a glass-like chitin front." + flags = BLOCKHAIR | STOPPRESSUREDAMAGE //Again, no THICKMATERIAL. + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) + body_parts_covered = HEAD|FACE|EYES + canremove = 0 + +/obj/item/clothing/head/helmet/space/changeling/dropped() + qdel(src) + +//Armor + +/obj/item/clothing/suit/space/changeling/armored + name = "chitinous mass" + desc = "A tough, hard covering of black chitin." + icon_state = "lingarmor" + item_state = "lingarmor" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS + armor = list(melee = 85, bullet = 70, laser = 70, energy = 70, bomb = 70, bio = 0, rad = 0) //It costs 3 points, so it should be very protective. + siemens_coefficient = 0.1 + slowdown = 3 + +/obj/item/clothing/suit/space/changeling/armored/New() + ..() + if(ismob(loc)) + loc.visible_message("[loc.name]\'s flesh turns black, quickly transforming into a hard, chitinous mass!", + "We harden our flesh, creating a suit of armor!", + "You hear organic matter ripping and tearing!") + +/obj/item/clothing/suit/space/changeling/armored/dropped() + qdel(src) + +/obj/item/clothing/head/helmet/space/changeling/armored + name = "chitinous mass" + desc = "A tough, hard covering of black chitin with transparent chitin in front." + icon_state = "lingarmorhelmet" + item_state = "lingarmorhelmet" + armor = list(melee = 85, bullet = 70, laser = 70,energy = 70, bomb = 70, bio = 0, rad = 0) + +/obj/item/clothing/head/helmet/space/changeling/armored/dropped() + qdel(src) diff --git a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm new file mode 100644 index 0000000000..0e8d061a4e --- /dev/null +++ b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm @@ -0,0 +1,38 @@ +//Augmented Eyesight: Gives you thermal and night vision - bye bye, flashlights. Also, high DNA cost because of how powerful it is. + +/datum/power/changeling/augmented_eyesight + name = "Augmented Eyesight" + desc = "Creates heat receptors in our eyes and dramatically increases light sensing ability." + helptext = "Grants us night vision and thermal vision. It may be toggled on or off. We will become more vulnerable to flash-based devices while active." + genomecost = 2 + var/active = 0 //Whether or not vision is enhanced + verbpath = /mob/proc/changeling_augmented_eyesight + +/mob/proc/changeling_augmented_eyesight() + set category = "Changeling" + set name = "Augmented Eyesight (5)" + set desc = "We evolve our eyes to sense the infrared." + + var/datum/changeling/changeling = changeling_power(5,0,100,CONSCIOUS) + if(!changeling) + return 0 + src.mind.changeling.chem_charges -= 5 + src.sight |= SEE_MOBS + /* + var/mob/living/carbon/human/C = src + + active = !active + if(active) + C << "We feel a minute twitch in our eyes, and darkness creeps away." + C.sight |= SEE_MOBS + C.permanent_sight_flags |= SEE_MOBS + C.see_in_dark = 8 + C.dna.species.invis_sight = SEE_INVISIBLE_MINIMUM + else + C << "Our vision dulls. Shadows gather." + C.sight &= ~SEE_MOBS + C.permanent_sight_flags &= ~SEE_MOBS + C.see_in_dark = 0 + C.dna.species.invis_sight = initial(user.dna.species.invis_sight) + return 1 + */ \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm b/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm new file mode 100644 index 0000000000..f704558e29 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm @@ -0,0 +1,134 @@ +/datum/power/changeling/bioelectrogenesis + name = "Bioelectrogenesis" + desc = "We reconfigure a large number of cells in our body to generate an electric charge. \ + On demand, we can attempt to recharge anything in our active hand, or we can touch someone with an electrified hand, shocking them." + helptext = "We can shock someone by grabbing them and using this ability, or using the ability with an empty hand and touching them." + genomecost = 3 + verbpath = /mob/proc/changeling_bioelectrogenesis + +//Recharge whatever's in our hand, or shock people. +/mob/proc/changeling_bioelectrogenesis() + set category = "Changeling" + set name = "Bioelectrogenesis (20)" + set desc = "Recharges anything in your hand, or shocks people." + + var/datum/changeling/changeling = changeling_power(20,0,100,CONSCIOUS) + + var/obj/held_item = get_active_hand() + + if(!changeling) + return 0 + + if(held_item == null) + if(changeling_generic_weapon(/obj/item/weapon/electric_hand,0)) //Chemical cost is handled in the equip proc. + return 1 + return 0 + + else + //If we're grabbing someone, electrocute them. + if(istype(held_item,/obj/item/weapon/grab)) + var/obj/item/weapon/grab/G = held_item + if(G.affecting) + G.affecting.electrocute_act(25,src,1.0,"chest") + visible_message("Arcs of electricity strike [G.affecting]!", + "Our hand channels raw electricity into [G.affecting].", + "You hear sparks!") + src.mind.changeling.chem_charges -= 20 + return 1 + + //Otherwise, charge up whatever's in their hand. + else + //This checks both the active hand, and the contents of the active hand's held item. + var/success = 0 + var/list/L = new() //We make a new list to avoid copypasta. + + //Check our hand. + if(istype(held_item,/obj/item/weapon/cell)) + L.Add(held_item) + + //Now check our hand's item's contents, so we can recharge guns and other stuff. + for(var/obj/item/weapon/cell/cell in held_item.contents) + L.Add(cell) + + //Now for the actual recharging. + for(var/obj/item/weapon/cell/cell in L) + cell.charge += 1000 //This should be a nice compromise between recharging guns and other batteries. + if(cell.charge > cell.maxcharge) + cell.charge = cell.maxcharge + visible_message("Some sparks fall out from \the [src.name]\'s [held_item]!", + "Our hand channels raw electricity into \the [held_item].", + "You hear sparks!") + var/T = get_turf(src) + new /obj/effect/effect/sparks(T) + held_item.update_icon() + success = 1 + if(success == 0) //If we couldn't do anything with the ability, don't deduct the chemicals. + src << "We are unable to affect \the [held_item]." + else + src.mind.changeling.chem_charges -= 20 + return success + +/obj/item/weapon/electric_hand + name = "electrified hand" + desc = "You could probably shock someone badly if you touched them, or recharge something." + icon = 'icons/obj/weapons.dmi' + icon_state = "electric_hand" + +/obj/item/weapon/electric_hand/New() + if(ismob(loc)) + visible_message("Electrical arcs form around [loc.name]\'s hand!", + "We store a charge of electricity in our hand.", + "You hear crackling electricity!") + var/T = get_turf(src) + new /obj/effect/effect/sparks(T) + +/obj/item/weapon/electric_hand/dropped(mob/user) + spawn(1) + if(src) + qdel(src) + +/obj/item/weapon/electric_hand/afterattack(var/atom/target, var/mob/living/user, proximity) + if(!target) + return + if(!proximity) + return + //Excuse the copypasta. + if(istype(target,/mob/living/carbon)) + var/mob/living/carbon/C = target + C.electrocute_act(25,src,1.0,"chest") + visible_message("Arcs of electricity strike [C]!", + "Our hand channels raw electricity into [C]", + "You hear sparks!") + qdel(src) + return 1 + + else if(istype(target,/mob/living/silicon)) + var/mob/living/silicon/S = target + S.electrocute_act(25,src,1.0) + visible_message("Arcs of electricity strike [S]!", + "Our hand channels raw electricity into [S]", + "You hear sparks!") + qdel(src) + return 1 + + else + if(istype(target,/obj/)) + var/success = 0 + var/obj/T = target + //We can also recharge things we touch, such as APCs or hardsuits. + for(var/obj/item/weapon/cell/cell in T.contents) + cell.charge += 1000 + if(cell.charge > cell.maxcharge) + cell.charge = cell.maxcharge + visible_message("Some sparks fall out from \the [target]!", + "Our hand channels raw electricity into \the [target].", + "You hear sparks!") + var/Turf = get_turf(src) + new /obj/effect/effect/sparks(Turf) + T.update_icon() + success = 1 + if(success == 0) + src << "We are unable to affect \the [target]." + else + qdel(src) + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/blind_sting.dm b/code/game/gamemodes/changeling/powers/blind_sting.dm new file mode 100644 index 0000000000..a009e8cd83 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/blind_sting.dm @@ -0,0 +1,23 @@ +/datum/power/changeling/blind_sting + name = "Blind Sting" + desc = "We silently sting a human, completely blinding them for a short time." + genomecost = 2 + allowduringlesserform = 1 + verbpath = /mob/proc/changeling_blind_sting + +/mob/proc/changeling_blind_sting() + set category = "Changeling" + set name = "Blind sting (20)" + set desc="Sting target" + + var/mob/living/carbon/T = changeling_sting(20,/mob/proc/changeling_blind_sting) + if(!T) + return 0 + T << "Your eyes burn horrificly!" + T.disabilities |= NEARSIGHTED + spawn(300) + T.disabilities &= ~NEARSIGHTED + T.eye_blind = 10 + T.eye_blurry = 20 + feedback_add_details("changeling_powers","BS") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/boost_range.dm b/code/game/gamemodes/changeling/powers/boost_range.dm new file mode 100644 index 0000000000..b8638e741f --- /dev/null +++ b/code/game/gamemodes/changeling/powers/boost_range.dm @@ -0,0 +1,25 @@ +/datum/power/changeling/boost_range + name = "Boost Range" + desc = "We evolve the ability to shoot our stingers at humans, with some preperation." + helptext = "Allows us to prepare the next sting to have a range of two tiles." + genomecost = 1 + allowduringlesserform = 1 + verbpath = /mob/proc/changeling_boost_range + +//Boosts the range of your next sting attack by 1 +/mob/proc/changeling_boost_range() + set category = "Changeling" + set name = "Ranged Sting (10)" + set desc="Your next sting ability can be used against targets 2 squares away." + + var/datum/changeling/changeling = changeling_power(10,0,100) + if(!changeling) + return 0 + changeling.chem_charges -= 10 + src << "Your throat adjusts to launch the sting." + changeling.sting_range = 2 + src.verbs -= /mob/proc/changeling_boost_range + spawn(5) + src.verbs += /mob/proc/changeling_boost_range + feedback_add_details("changeling_powers","RS") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/cryo_sting.dm b/code/game/gamemodes/changeling/powers/cryo_sting.dm new file mode 100644 index 0000000000..c691b1601a --- /dev/null +++ b/code/game/gamemodes/changeling/powers/cryo_sting.dm @@ -0,0 +1,19 @@ +/datum/power/changeling/cryo_sting + name = "Cryogenic Sting" + desc = "We silently sting a biological with a cocktail of chemicals that freeze them." + helptext = "Does not provide a warning to the victim, though they will likely realize they are suddenly freezing." + genomecost = 1 + verbpath = /mob/proc/changeling_cryo_sting + +/mob/proc/changeling_cryo_sting() + set category = "Changeling" + set name = "Cryogenic Sting (20)" + set desc = "Chills and freezes a biological creature." + + var/mob/living/carbon/T = changeling_sting(40,/mob/proc/changeling_cryo_sting) + if(!T) + return 0 + if(T.reagents) + T.reagents.add_reagent("frostoil", 10) + feedback_add_details("changeling_powers","CS") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/deaf_sting.dm b/code/game/gamemodes/changeling/powers/deaf_sting.dm new file mode 100644 index 0000000000..1cb027f63e --- /dev/null +++ b/code/game/gamemodes/changeling/powers/deaf_sting.dm @@ -0,0 +1,20 @@ +/datum/power/changeling/deaf_sting + name = "Deaf Sting" + desc = "We silently sting a human, completely deafening them for a short time." + genomecost = 1 + allowduringlesserform = 1 + verbpath = /mob/proc/changeling_deaf_sting + + +/mob/proc/changeling_deaf_sting() + set category = "Changeling" + set name = "Deaf sting (5)" + set desc="Sting target:" + + var/mob/living/carbon/T = changeling_sting(5,/mob/proc/changeling_deaf_sting) + if(!T) return 0 + T << "Your ears pop and begin ringing loudly!" + T.sdisabilities |= DEAF + spawn(300) T.sdisabilities &= ~DEAF + feedback_add_details("changeling_powers","DS") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/death_sting.dm b/code/game/gamemodes/changeling/powers/death_sting.dm new file mode 100644 index 0000000000..d143bad484 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/death_sting.dm @@ -0,0 +1,21 @@ +/datum/power/changeling/DeathSting + name = "Death Sting" + desc = "We silently sting a human, filling him with potent chemicals. His rapid death is all but assured." + genomecost = 10 + verbpath = /mob/proc/changeling_DEATHsting + +/mob/proc/changeling_DEATHsting() + set category = "Changeling" + set name = "Death Sting (40)" + set desc = "Causes spasms onto death." + + var/mob/living/carbon/T = changeling_sting(40,/mob/proc/changeling_DEATHsting) + if(!T) + return 0 + T << "You feel a small prick and your chest becomes tight." + T.silent = 10 + T.Paralyse(10) + T.make_jittery(100) + if(T.reagents) T.reagents.add_reagent("lexorin", 40) + feedback_add_details("changeling_powers","DTHS") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/digital_camo.dm b/code/game/gamemodes/changeling/powers/digital_camo.dm new file mode 100644 index 0000000000..207d9ec68a --- /dev/null +++ b/code/game/gamemodes/changeling/powers/digital_camo.dm @@ -0,0 +1,35 @@ +/datum/power/changeling/DigitalCamoflague + name = "Digital Camoflauge" + desc = "We evolve the ability to distort our form and proprtions, defeating common altgorthms used to detect lifeforms on cameras." + helptext = "We cannot be tracked by camera while using this skill. However, humans looking at us will find us.. uncanny. We must constantly expend chemicals to maintain our form like this." + genomecost = 1 + allowduringlesserform = 1 + verbpath = /mob/proc/changeling_digitalcamo + +//Prevents AIs tracking you but makes you easily detectable to the human-eye. +/mob/proc/changeling_digitalcamo() + set category = "Changeling" + set name = "Toggle Digital Camoflague" + set desc = "The AI can no longer track us, but we will look different if examined. Has a constant cost while active." + + var/datum/changeling/changeling = changeling_power() + if(!changeling) + return 0 + + var/mob/living/carbon/human/C = src + if(C.digitalcamo) + C << "We return to normal." + else + C << "We distort our form to prevent AI-tracking." + C.digitalcamo = !C.digitalcamo + + spawn(0) + while(C && C.digitalcamo && C.mind && C.mind.changeling) + C.mind.changeling.chem_charges = max(C.mind.changeling.chem_charges - 1, 0) + sleep(40) + + src.verbs -= /mob/proc/changeling_digitalcamo + spawn(5) + src.verbs += /mob/proc/changeling_digitalcamo + feedback_add_details("changeling_powers","CAM") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/engorged_glands.dm b/code/game/gamemodes/changeling/powers/engorged_glands.dm new file mode 100644 index 0000000000..7f95fdf371 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/engorged_glands.dm @@ -0,0 +1,13 @@ +/datum/power/changeling/EngorgedGlands + name = "Engorged Chemical Glands" + desc = "Our chemical glands swell, permitting us to store more chemicals inside of them." + helptext = "Allows us to store an extra 25 units of chemicals, and doubles production rate." + genomecost = 1 + isVerb = 0 + verbpath = /mob/proc/changeling_engorgedglands + +//Increases macimum chemical storage +/mob/proc/changeling_engorgedglands() + src.mind.changeling.chem_storage += 25 + src.mind.changeling.chem_recharge_rate *= 2 + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/epinephrine_overdose.dm b/code/game/gamemodes/changeling/powers/epinephrine_overdose.dm new file mode 100644 index 0000000000..6946ab23a1 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/epinephrine_overdose.dm @@ -0,0 +1,52 @@ +/datum/power/changeling/epinephrine_overdose + name = "Epinephrine Overdose" + desc = "We evolve additional sacs of adrenaline throughout our body." + helptext = "We can instantly recover from stuns and reduce the effect of future stuns, but we will suffer toxicity in the long term. Can be used while unconscious." + genomecost = 2 + verbpath = /mob/proc/changeling_epinephrine_overdose + +//Recover from stuns. +/mob/proc/changeling_epinephrine_overdose() + set category = "Changeling" + set name = "Epinephrine Overdose (30)" + set desc = "Removes all stuns instantly, and reduces future stuns." + + var/datum/changeling/changeling = changeling_power(30,0,100,UNCONSCIOUS) + if(!changeling) + return 0 + changeling.chem_charges -= 30 + + var/mob/living/carbon/human/C = src + C << "Energy rushes through us. [C.lying ? "We arise." : ""]" + C.stat = 0 + C.SetParalysis(0) + C.SetStunned(0) + C.SetWeakened(0) + C.lying = 0 + C.update_canmove() +// C.reagents.add_reagent("toxin", 10) + C.reagents.add_reagent("epinephrine", 20) + + feedback_add_details("changeling_powers","UNS") + return 1 + +/datum/reagent/epinephrine + name = "Epinephrine" + id = "epinephrine" + description = "Reduces stun times, but causing toxicity due to high concentration." + reagent_state = LIQUID + color = "#C8A5DC" + metabolism = REM * 2 + overdose = 5 //This is intentionally low, as we want the ling to take some tox damage, to discourage spamming the ability. + +/datum/reagent/epinephrine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(alien == IS_DIONA) + return + M.add_chemical_effect(CE_SPEEDBOOST, 3) + M.add_chemical_effect(CE_PAINKILLER, 60) + M.adjustHalLoss(-30) + M.AdjustParalysis(-2) + M.AdjustStunned(-2) + M.AdjustWeakened(-2) + ..() + return \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/extract_dna_sting.dm b/code/game/gamemodes/changeling/powers/extract_dna_sting.dm new file mode 100644 index 0000000000..d273cc9c33 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/extract_dna_sting.dm @@ -0,0 +1,29 @@ +/datum/power/changeling/extractdna + name = "Extract DNA" + desc = "We stealthily sting a target and extract the DNA from them." + helptext = "Will give you the DNA of your target, allowing you to transform into them. Does not count towards absorb objectives." + genomecost = 0 + allowduringlesserform = 1 + verbpath = /mob/proc/changeling_extract_dna_sting + +/mob/proc/changeling_extract_dna_sting() + set category = "Changeling" + set name = "Extract DNA Sting (40)" + set desc="Stealthily sting a target to extract their DNA." + + var/datum/changeling/changeling = null + if(src.mind && src.mind.changeling) + changeling = src.mind.changeling + if(!changeling) + return 0 + + var/mob/living/carbon/human/T = changeling_sting(40, /mob/proc/changeling_extract_dna_sting) + if(!T) return 0 + + T.dna.real_name = T.real_name + changeling.absorbed_dna |= T.dna + if(T.species && !(T.species.name in changeling.absorbed_species)) + changeling.absorbed_species += T.species.name + + feedback_add_details("changeling_powers","ED") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/fake_death.dm b/code/game/gamemodes/changeling/powers/fake_death.dm new file mode 100644 index 0000000000..3c273b3953 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/fake_death.dm @@ -0,0 +1,56 @@ +/datum/power/changeling/fakedeath + name = "Regenerative Stasis" + desc = "We become weakened to a death-like state, where we will rise again from death." + helptext = "Can be used before or after death. Duration varies greatly." + genomecost = 0 + allowduringlesserform = 1 + verbpath = /mob/proc/changeling_fakedeath + +//Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay. +/mob/proc/changeling_fakedeath() + set category = "Changeling" + set name = "Regenerative Stasis (20)" + + var/datum/changeling/changeling = changeling_power(20,1,100,DEAD) + if(!changeling) + return + + var/mob/living/carbon/C = src + if(!C.stat && alert("Are we sure we wish to fake our death?",,"Yes","No") == "No")//Confirmation for living changelings if they want to fake their death + return + C << "We will attempt to regenerate our form." + + C.status_flags |= FAKEDEATH //play dead + C.update_canmove() + C.remove_changeling_powers() + + if(C.stat != DEAD) + C.emote("deathgasp") + C.tod = worldtime2text() + + spawn(rand(800,2000)) + //The ling will now be able to choose when to revive + src.verbs += /mob/proc/changeling_revive + src << "We are ready to rise. Use the Revive verb when you are ready." + /* + // charge the changeling chemical cost for stasis + changeling.chem_charges -= 20 + + // restore us to health + C.revive() + + // remove our fake death flag + C.status_flags &= ~(FAKEDEATH) + + // let us move again + C.update_canmove() + + // re-add out changeling powers + C.make_changeling() + + // sending display messages + C << "We have regenerated." + */ + + feedback_add_details("changeling_powers","FD") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/fleshmend.dm b/code/game/gamemodes/changeling/powers/fleshmend.dm new file mode 100644 index 0000000000..d6cdabdc03 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/fleshmend.dm @@ -0,0 +1,33 @@ +/datum/power/changeling/fleshmend + name = "Fleshmend" + desc = "Begins a slow rengeration of our form. Does not effect stuns or chemicals." + genomecost = 1 + verbpath = /mob/proc/changeling_fleshmend + +//Starts healing you every second for 50 seconds. Can be used whilst unconscious. +/mob/proc/changeling_fleshmend() + set category = "Changeling" + set name = "Fleshmend (10)" + set desc = "Begins a slow rengeration of our form. Does not effect stuns or chemicals." + + var/datum/changeling/changeling = changeling_power(10,0,100,UNCONSCIOUS) + if(!changeling) + return 0 + src.mind.changeling.chem_charges -= 10 + + var/mob/living/carbon/human/C = src + spawn(0) + src << "We begin to heal ourselves." + for(var/i = 0, i<50,i++) + if(C) + C.adjustBruteLoss(-2) + C.adjustOxyLoss(-2) + C.adjustFireLoss(-2) + sleep(10) + + src.verbs -= /mob/proc/changeling_fleshmend + spawn(500) + src << "Our regeneration has slowed to normal levels." + src.verbs += /mob/proc/changeling_fleshmend + feedback_add_details("changeling_powers","FM") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/hivemind.dm b/code/game/gamemodes/changeling/powers/hivemind.dm new file mode 100644 index 0000000000..940df49cd9 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/hivemind.dm @@ -0,0 +1,78 @@ +// Hivemind + +/datum/power/changeling/hive_upload + name = "Hive Channel" + desc = "We can channel a DNA into the airwaves, allowing our fellow changelings to absorb it and transform into it as if they acquired the DNA themselves." + helptext = "Allows other changelings to absorb the DNA you channel from the airwaves. Will not help them towards their absorb objectives." + genomecost = 0 + verbpath = /mob/proc/changeling_hiveupload + +/datum/power/changeling/hive_download + name = "Hive Absorb" + desc = "We can absorb a single DNA from the airwaves, allowing us to use more disguises with help from our fellow changelings." + helptext = "Allows you to absorb a single DNA and use it. Does not count towards your absorb objective." + genomecost = 0 + verbpath = /mob/proc/changeling_hivedownload + +// HIVE MIND UPLOAD/DOWNLOAD DNA + +var/list/datum/dna/hivemind_bank = list() + +/mob/proc/changeling_hiveupload() + set category = "Changeling" + set name = "Hive Channel (10)" + set desc = "Allows you to channel DNA in the airwaves to allow other changelings to absorb it." + + var/datum/changeling/changeling = changeling_power(10,1) + if(!changeling) return + + var/list/names = list() + for(var/datum/dna/DNA in changeling.absorbed_dna) + if(!(DNA in hivemind_bank)) + names += DNA.real_name + + if(names.len <= 0) + src << "The airwaves already have all of our DNA." + return + + var/S = input("Select a DNA to channel: ", "Channel DNA", null) as null|anything in names + if(!S) return + + var/datum/dna/chosen_dna = changeling.GetDNA(S) + if(!chosen_dna) + return + + changeling.chem_charges -= 10 + hivemind_bank += chosen_dna + src << "We channel the DNA of [S] to the air." + feedback_add_details("changeling_powers","HU") + return 1 + +/mob/proc/changeling_hivedownload() + set category = "Changeling" + set name = "Hive Absorb (20)" + set desc = "Allows you to absorb DNA that is being channeled in the airwaves." + + var/datum/changeling/changeling = changeling_power(20,1) + if(!changeling) return + + var/list/names = list() + for(var/datum/dna/DNA in hivemind_bank) + if(!(DNA in changeling.absorbed_dna)) + names[DNA.real_name] = DNA + + if(names.len <= 0) + src << "There's no new DNA to absorb from the air." + return + + var/S = input("Select a DNA absorb from the air: ", "Absorb DNA", null) as null|anything in names + if(!S) return + var/datum/dna/chosen_dna = names[S] + if(!chosen_dna) + return + + changeling.chem_charges -= 20 + changeling.absorbed_dna += chosen_dna + src << "We absorb the DNA of [S] from the air." + feedback_add_details("changeling_powers","HD") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/lesser_form.dm b/code/game/gamemodes/changeling/powers/lesser_form.dm new file mode 100644 index 0000000000..f2742490f6 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/lesser_form.dm @@ -0,0 +1,114 @@ +/datum/power/changeling/lesser_form + name = "Lesser Form" + desc = "We debase ourselves and become lesser. We become a monkey." + genomecost = 1 + verbpath = /mob/proc/changeling_lesser_form + +//Transform into a monkey. +/mob/proc/changeling_lesser_form() + set category = "Changeling" + set name = "Lesser Form (1)" + + var/datum/changeling/changeling = changeling_power(1,0,0) + if(!changeling) return + + if(src.has_brain_worms()) + src << "We cannot perform this ability at the present time!" + return + + var/mob/living/carbon/human/H = src + + if(!istype(H) || !H.species.primitive_form) + src << "We cannot perform this ability in this form!" + return + + changeling.chem_charges-- + H.remove_changeling_powers() + H.visible_message("[H] transforms!") + changeling.geneticdamage = 30 + H << "Our genes cry out!" + var/list/implants = list() //Try to preserve implants. + for(var/obj/item/weapon/implant/W in H) + implants += W + H.monkeyize() + feedback_add_details("changeling_powers","LF") + return 1 + +//Transform into a human +/mob/proc/changeling_lesser_transform() + set category = "Changeling" + set name = "Transform (1)" + + var/datum/changeling/changeling = changeling_power(1,1,0) + if(!changeling) return + + var/list/names = list() + for(var/datum/dna/DNA in changeling.absorbed_dna) + names += "[DNA.real_name]" + + var/S = input("Select the target DNA: ", "Target DNA", null) as null|anything in names + if(!S) return + + var/datum/dna/chosen_dna = changeling.GetDNA(S) + if(!chosen_dna) + return + + var/mob/living/carbon/C = src + + changeling.chem_charges-- + C.remove_changeling_powers() + C.visible_message("[C] transforms!") + C.dna = chosen_dna.Clone() + + var/list/implants = list() + for (var/obj/item/weapon/implant/I in C) //Still preserving implants + implants += I + + C.transforming = 1 + C.canmove = 0 + C.icon = null + C.overlays.Cut() + C.invisibility = 101 + var/atom/movable/overlay/animation = new /atom/movable/overlay( C.loc ) + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = src + flick("monkey2h", animation) + sleep(48) + qdel(animation) + + for(var/obj/item/W in src) + C.drop_from_inventory(W) + + var/mob/living/carbon/human/O = new /mob/living/carbon/human( src ) + if (C.dna.GetUIState(DNA_UI_GENDER)) + O.gender = FEMALE + else + O.gender = MALE + O.dna = C.dna.Clone() + C.dna = null + O.real_name = chosen_dna.real_name + + for(var/obj/T in C) + qdel(T) + + O.loc = C.loc + + O.UpdateAppearance() + domutcheck(O, null) + O.setToxLoss(C.getToxLoss()) + O.adjustBruteLoss(C.getBruteLoss()) + O.setOxyLoss(C.getOxyLoss()) + O.adjustFireLoss(C.getFireLoss()) + O.stat = C.stat + for (var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O + + C.mind.transfer_to(O) + O.make_changeling() + O.changeling_update_languages(changeling.absorbed_languages) + + feedback_add_details("changeling_powers","LFT") + qdel(C) + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/lsd_sting.dm b/code/game/gamemodes/changeling/powers/lsd_sting.dm new file mode 100644 index 0000000000..275ebf5bad --- /dev/null +++ b/code/game/gamemodes/changeling/powers/lsd_sting.dm @@ -0,0 +1,19 @@ +//This only exists to be abused, so it's highly recommended to ensure this file is unchecked. +/datum/power/changeling/LSDSting + name = "Hallucination Sting" + desc = "We evolve the ability to sting a target with a powerful hallunicationary chemical." + helptext = "The target does not notice they have been stung. The effect occurs after 30 to 60 seconds." + genomecost = 3 + verbpath = /mob/proc/changeling_lsdsting + +/mob/proc/changeling_lsdsting() + set category = "Changeling" + set name = "Hallucination Sting (15)" + set desc = "Causes terror in the target." + + var/mob/living/carbon/T = changeling_sting(15,/mob/proc/changeling_lsdsting) + if(!T) return 0 + spawn(rand(300,600)) + if(T) T.hallucination += 400 + feedback_add_details("changeling_powers","HS") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/mimic_voice.dm b/code/game/gamemodes/changeling/powers/mimic_voice.dm new file mode 100644 index 0000000000..93c0ad619f --- /dev/null +++ b/code/game/gamemodes/changeling/powers/mimic_voice.dm @@ -0,0 +1,40 @@ +/datum/power/changeling/mimicvoice + name = "Mimic Voice" + desc = "We shape our vocal glands to sound like a desired voice." + helptext = "Will turn your voice into the name that you enter. We must constantly expend chemicals to maintain our form like this" + genomecost = 1 + verbpath = /mob/proc/changeling_mimicvoice + +// Fake Voice + +/mob/proc/changeling_mimicvoice() + set category = "Changeling" + set name = "Mimic Voice" + set desc = "Shape our vocal glands to form a voice of someone we choose. We cannot regenerate chemicals when mimicing." + + + var/datum/changeling/changeling = changeling_power() + if(!changeling) return + + if(changeling.mimicing) + changeling.mimicing = "" + src << "We return our vocal glands to their original location." + return + + var/mimic_voice = sanitize(input(usr, "Enter a name to mimic.", "Mimic Voice", null), MAX_NAME_LEN) + if(!mimic_voice) + return + + changeling.mimicing = mimic_voice + + src << "We shape our glands to take the voice of [mimic_voice], this will stop us from regenerating chemicals while active." + src << "Use this power again to return to our original voice and reproduce chemicals again." + + feedback_add_details("changeling_powers","MV") + + spawn(0) + while(src && src.mind && src.mind.changeling && src.mind.changeling.mimicing) + src.mind.changeling.chem_charges = max(src.mind.changeling.chem_charges - 1, 0) + sleep(40) + if(src && src.mind && src.mind.changeling) + src.mind.changeling.mimicing = "" \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/panacea.dm b/code/game/gamemodes/changeling/powers/panacea.dm new file mode 100644 index 0000000000..766547e12f --- /dev/null +++ b/code/game/gamemodes/changeling/powers/panacea.dm @@ -0,0 +1,37 @@ +/datum/power/changeling/panacea + name = "Anatomic Panacea" + desc = "Expels impurifications from our form; curing diseases, removing toxins, chemicals, radiation, and resetting our genetic code completely." + helptext = "Can be used while unconscious." + genomecost = 1 + verbpath = /mob/proc/changeling_panacea + +//Heals the things that the other regenerative abilities don't. +/mob/proc/changeling_panacea() + set category = "Changeling" + set name = "Anatomic Panacea (20)" + set desc = "Clense ourselves of impurities." + + var/datum/changeling/changeling = changeling_power(20,0,100,UNCONSCIOUS) + if(!changeling) + return 0 + src.mind.changeling.chem_charges -= 20 + + src << "We cleanse impurities from our form." + + for(var/datum/disease/D in src.viruses) + D.cure() + + var/mob/living/carbon/human/C = src + + C.radiation = 0 + C.sdisabilities = 0 + C.disabilities = 0 + C.reagents.clear_reagents() + + for(var/i = 0, i<10,i++) + if(C) + C.adjustToxLoss(-5) + sleep(10) + + feedback_add_details("changeling_powers","AP") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/para_sting.dm b/code/game/gamemodes/changeling/powers/para_sting.dm new file mode 100644 index 0000000000..37c31f5d00 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/para_sting.dm @@ -0,0 +1,18 @@ +/datum/power/changeling/paralysis_sting + name = "Paralysis Sting" + desc = "We silently sting a human, paralyzing them for a short time." + genomecost = 3 + verbpath = /mob/proc/changeling_paralysis_sting + +/mob/proc/changeling_paralysis_sting() + set category = "Changeling" + set name = "Paralysis sting (30)" + set desc="Sting target" + + var/mob/living/carbon/T = changeling_sting(30,/mob/proc/changeling_paralysis_sting) + if(!T) + return 0 + T << "Your muscles begin to painfully tighten." + T.Weaken(20) + feedback_add_details("changeling_powers","PS") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/rapid_regen.dm b/code/game/gamemodes/changeling/powers/rapid_regen.dm new file mode 100644 index 0000000000..2dc2fa3e9b --- /dev/null +++ b/code/game/gamemodes/changeling/powers/rapid_regen.dm @@ -0,0 +1,48 @@ +/datum/power/changeling/rapid_regen + name = "Rapid Regeneration" + desc = "We quickly heal ourselves, removing most advanced injuries, at a high chemical cost." + helptext = "This will heal a significant amount of brute, fire, oxy, clone, and brain damage, and heal broken bones, internal bleeding, low blood, \ + and organ damage. The process is fast, but anyone who sees us do this will likely realize we are not what we seem." + genomecost = 2 + verbpath = /mob/proc/changeling_rapid_regen + +//Gives a big heal, removing various injuries that might shut down normal people, like IB or fractures. +/mob/proc/changeling_rapid_regen() + set category = "Changeling" + set name = "Rapid Regeneration (50)" + set desc = "Heal ourselves of most injuries instantly." + + var/datum/changeling/changeling = changeling_power(50,0,100,UNCONSCIOUS) + if(!changeling) + return 0 + src.mind.changeling.chem_charges -= 50 + + if(ishuman(src)) + var/mob/living/carbon/human/C = src + spawn(0) + C.adjustBruteLoss(-40) + C.adjustFireLoss(-40) + C.adjustOxyLoss(-40) + C.adjustCloneLoss(-40) + C.adjustBrainLoss(-40) + C.restore_blood() + C.restore_all_organs() + C.blinded = 0 + C.eye_blind = 0 + C.eye_blurry = 0 + C.ear_deaf = 0 + C.ear_damage = 0 + + // make the icons look correct + C.regenerate_icons() + + // now make it obvious that we're not human (or whatever xeno race they are impersonating) + playsound(src, 'sound/effects/blobattack.ogg', 30, 1) + var/T = get_turf(src) + new /obj/effect/gibspawner/human(T) + visible_message("With a sickening squish, [src] reforms their whole body, casting their old parts on the floor!", + "We reform our body. We are whole once more.", + "We have removed our evolutions from this form, and are now ready to readapt." + + //Now to lose the verb, so no unlimited resets. + src.verbs -= /mob/proc/changeling_respec \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm new file mode 100644 index 0000000000..865896eade --- /dev/null +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -0,0 +1,39 @@ +//Revive from revival stasis +/mob/proc/changeling_revive() + set category = "Changeling" + set name = "Revive" + set desc = "We are ready to revive ourselves on command." + + var/datum/changeling/changeling = changeling_power(0,0,100,DEAD) + if(!changeling) + return 0 + + if(src.stat == DEAD) + dead_mob_list -= src + living_mob_list += src + var/mob/living/carbon/C = src + + C.tod = null + C.setToxLoss(0) + C.setOxyLoss(0) + C.setCloneLoss(0) + C.SetParalysis(0) + C.SetStunned(0) + C.SetWeakened(0) + C.radiation = 0 + C.heal_overall_damage(C.getBruteLoss(), C.getFireLoss()) + C.reagents.clear_reagents() + C.restore_all_organs() //Covers things like fractures and other things not covered by the above. + if(ishuman(C)) + var/mob/living/carbon/human/H = src + H.restore_blood() + C << "We have regenerated." + C.status_flags &= ~(FAKEDEATH) + C.update_canmove() + C.mind.changeling.purchasedpowers -= C + feedback_add_details("changeling_powers","CR") + C.stat = CONSCIOUS + src.verbs -= /mob/proc/changeling_revive + // re-add out changeling powers + C.make_changeling() + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/shriek.dm b/code/game/gamemodes/changeling/powers/shriek.dm new file mode 100644 index 0000000000..c93105d806 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/shriek.dm @@ -0,0 +1,56 @@ +/datum/power/changeling/resonant_shriek + name = "Resonant Shriek" + desc = "Our lungs and vocal chords shift, allowing us to briefly emit a noise that deafens and confuses the weak-minded biologicals and synthetics." + genomecost = 2 + verbpath = /mob/proc/changeling_resonant_shriek + +/datum/power/changeling/dissonant_shriek + name = "Dissonant Shriek" + desc = "We shift our vocal cords to release a high-frequency sound that overloads nearby electronics." + genomecost = 2 + verbpath = /mob/proc/changeling_dissonant_shriek + +//A flashy ability, good for crowd control and sewing chaos. +/mob/proc/changeling_resonant_shriek() + set category = "Changeling" + set name = "Resonant Shriek (20)" + set desc = "Emits a high-frequency sound that confuses and deafens humans, blows out nearby lights and overloads cyborg sensors." + + var/datum/changeling/changeling = changeling_power(20,0,100,CONSCIOUS) + if(!changeling) return 0 + changeling.chem_charges -= 20 + + for(var/mob/living/M in range(4, src)) + if(iscarbon(M)) + if(!M.mind || !M.mind.changeling) + M.adjustEarDamage(0,30) + M.confused += 20 + else + M << sound('sound/effects/screech.ogg') + + if(issilicon(M)) + M << sound('sound/weapons/flash.ogg') + M.Weaken(rand(5,10)) + + for(var/obj/machinery/light/L in range(4, src)) + L.on = 1 + L.broken() + + feedback_add_details("changeling_powers","RS") + return 1 + +//EMP version +/mob/proc/changeling_dissonant_shriek() + set category = "Changeling" + set name = "Dissonant Shriek (20)" + set desc = "We shift our vocal cords to release a high-frequency sound that overloads nearby electronics." + + var/datum/changeling/changeling = changeling_power(20,0,100,CONSCIOUS) + if(!changeling) return 0 + changeling.chem_charges -= 20 + + for(var/obj/machinery/light/L in range(5, src)) + L.on = 1 + L.broken() + empulse(get_turf(src), 2, 5, 1) + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/silence_sting.dm b/code/game/gamemodes/changeling/powers/silence_sting.dm new file mode 100644 index 0000000000..6bd0541259 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/silence_sting.dm @@ -0,0 +1,18 @@ +/datum/power/changeling/silence_sting + name = "Silence Sting" + desc = "We silently sting a human, completely silencing them for a short time." + helptext = "Does not provide a warning to a victim that they have been stung, until they try to speak and cannot." + genomecost = 2 + allowduringlesserform = 1 + verbpath = /mob/proc/changeling_silence_sting + +/mob/proc/changeling_silence_sting() + set category = "Changeling" + set name = "Silence sting (10)" + set desc="Sting target" + + var/mob/living/carbon/T = changeling_sting(10,/mob/proc/changeling_silence_sting) + if(!T) return 0 + T.silent += 30 + feedback_add_details("changeling_powers","SS") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm new file mode 100644 index 0000000000..06e330d173 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/transform.dm @@ -0,0 +1,85 @@ +/datum/power/changeling/transform + name = "Transform" + desc = "We take on the apperance and voice of one we have absorbed." + genomecost = 0 + verbpath = /mob/proc/changeling_transform + +/datum/power/changeling/change_species + name = "Change Species" + desc = "We take on the apperance of a species that we have absorbed." + genomecost = 0 + verbpath = /mob/proc/changeling_change_species + +//Change our DNA to that of somebody we've absorbed. +/mob/proc/changeling_transform() + set category = "Changeling" + set name = "Transform (5)" + + var/datum/changeling/changeling = changeling_power(5,1,0) + if(!changeling) return + + var/list/names = list() + for(var/datum/dna/DNA in changeling.absorbed_dna) + names += "[DNA.real_name]" + + var/S = input("Select the target DNA: ", "Target DNA", null) as null|anything in names + if(!S) return + + var/datum/dna/chosen_dna = changeling.GetDNA(S) + if(!chosen_dna) + return + + changeling.chem_charges -= 5 + src.visible_message("[src] transforms!") + changeling.geneticdamage = 30 + src.dna = chosen_dna.Clone() + src.real_name = chosen_dna.real_name + src.flavor_text = "" + src.UpdateAppearance() + domutcheck(src, null) + + src.verbs -= /mob/proc/changeling_transform + spawn(10) src.verbs += /mob/proc/changeling_transform + + feedback_add_details("changeling_powers","TR") + return 1 + +//Used to switch species based on the changeling datum. +/mob/proc/changeling_change_species() + + set category = "Changeling" + set name = "Change Species (5)" + + var/mob/living/carbon/human/H = src + if(!istype(H)) + src << "We may only use this power while in humanoid form." + return + + var/datum/changeling/changeling = changeling_power(5,1,0) + if(!changeling) return + + if(changeling.absorbed_species.len < 2) + src << "We do not know of any other species genomes to use." + return + + var/S = input("Select the target species: ", "Target Species", null) as null|anything in changeling.absorbed_species + if(!S) return + + domutcheck(src, null) + + changeling.chem_charges -= 5 + changeling.geneticdamage = 30 + + src.visible_message("[src] transforms!") + + src.verbs -= /mob/proc/changeling_change_species + H.set_species(S,1) //Until someone moves body colour into DNA, they're going to have to use the default. + + spawn(10) + src.verbs += /mob/proc/changeling_change_species + src.regenerate_icons() + + changeling_update_languages(changeling.absorbed_languages) + feedback_add_details("changeling_powers","TR") + + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/transform_sting.dm b/code/game/gamemodes/changeling/powers/transform_sting.dm new file mode 100644 index 0000000000..f88fbaca89 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/transform_sting.dm @@ -0,0 +1,44 @@ +//Suggested to leave unchecked because this is why we can't have nice things. +/datum/power/changeling/transformation_sting + name = "Transformation Sting" + desc = "We silently sting a human, injecting a retrovirus that forces them to transform into another." + helptext = "Does not provide a warning to others. The victim will transform much like a changeling would." + genomecost = 3 + verbpath = /mob/proc/changeling_transformation_sting + +/mob/proc/changeling_transformation_sting() + set category = "Changeling" + set name = "Transformation sting (40)" + set desc="Sting target" + + var/datum/changeling/changeling = changeling_power(40) + if(!changeling) + return 0 + + + + var/list/names = list() + for(var/datum/dna/DNA in changeling.absorbed_dna) + names += "[DNA.real_name]" + + var/S = input("Select the target DNA: ", "Target DNA", null) as null|anything in names + if(!S) + return + + var/datum/dna/chosen_dna = changeling.GetDNA(S) + if(!chosen_dna) + return + + var/mob/living/carbon/T = changeling_sting(40,/mob/proc/changeling_transformation_sting) + if(!T) + return 0 + if((HUSK in T.mutations) || (!ishuman(T) && !issmall(T))) + src << "Our sting appears ineffective against its DNA." + return 0 + T.visible_message("[T] transforms!") + T.dna = chosen_dna.Clone() + T.real_name = chosen_dna.real_name + T.UpdateAppearance() + domutcheck(T, null) + feedback_add_details("changeling_powers","TS") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/unfat_sting.dm b/code/game/gamemodes/changeling/powers/unfat_sting.dm new file mode 100644 index 0000000000..d0248cf94e --- /dev/null +++ b/code/game/gamemodes/changeling/powers/unfat_sting.dm @@ -0,0 +1,18 @@ +/datum/power/changeling/unfat_sting + name = "Unfat Sting" + desc = "We silently sting a human, forcing them to rapidly metabolize their fat." + genomecost = 1 + verbpath = /mob/proc/changeling_unfat_sting + +/mob/proc/changeling_unfat_sting() + set category = "Changeling" + set name = "Unfat sting (5)" + set desc = "Sting target" + + var/mob/living/carbon/T = changeling_sting(5,/mob/proc/changeling_unfat_sting) + if(!T) return 0 + T << "you feel a small prick as stomach churns violently and you become to feel skinnier." + T.overeatduration = 0 + T.nutrition -= 100 + feedback_add_details("changeling_powers","US") + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 534c77c2a1..476bce5718 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -114,7 +114,7 @@ playsound(loc, "sparks", 50, 1, -1) if (shock_damage > 15) src.visible_message( - "\red [src] was shocked by the [source]!", \ + "\red [src] was shocked by \the [source]!", \ "\red You feel a powerful shock course through your body!", \ "\red You hear a heavy electrical crack." \ ) @@ -122,7 +122,7 @@ Weaken(10) else src.visible_message( - "\red [src] was mildly shocked by the [source].", \ + "\red [src] was mildly shocked by \the [source].", \ "\red You feel a mild shock course through your body.", \ "\red You hear a light zapping." \ ) diff --git a/code/modules/tables/interactions.dm b/code/modules/tables/interactions.dm index 5996d5ddc1..53c8c4ad40 100644 --- a/code/modules/tables/interactions.dm +++ b/code/modules/tables/interactions.dm @@ -127,6 +127,11 @@ break_to_parts() return + if(istype(W, /obj/item/weapon/melee/arm_blade)) + user.visible_message("\The [src] was sliced apart by [user]!") + break_to_parts() + return + if(can_plate && !material) user << "There's nothing to put \the [W] on! Try adding plating to \the [src] first." return diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 4a53984c48..56b4cbd884 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/items/lefthand.dmi b/icons/mob/items/lefthand.dmi index 90d89ad52f..eb4356854f 100644 Binary files a/icons/mob/items/lefthand.dmi and b/icons/mob/items/lefthand.dmi differ diff --git a/icons/mob/items/righthand.dmi b/icons/mob/items/righthand.dmi index d5b1cfd6cd..e1fa146196 100644 Binary files a/icons/mob/items/righthand.dmi and b/icons/mob/items/righthand.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 45677bc4a1..86deb07191 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 479c28a185..052979d365 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 986d509eb6..b98c5491fe 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi index 1dfa399993..cea357dcfd 100644 Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ diff --git a/polaris.dme b/polaris.dme index ed2a7da136..1b7026b03a 100644 --- a/polaris.dme +++ b/polaris.dme @@ -287,7 +287,33 @@ #include "code\game\gamemodes\calamity\calamity.dm" #include "code\game\gamemodes\changeling\changeling.dm" #include "code\game\gamemodes\changeling\changeling_powers.dm" +#include "code\game\gamemodes\changeling\generic_equip_procs.dm" #include "code\game\gamemodes\changeling\modularchangling.dm" +#include "code\game\gamemodes\changeling\powers\absorb.dm" +#include "code\game\gamemodes\changeling\powers\armblade.dm" +#include "code\game\gamemodes\changeling\powers\armor.dm" +#include "code\game\gamemodes\changeling\powers\bioelectrogenesis.dm" +#include "code\game\gamemodes\changeling\powers\blind_sting.dm" +#include "code\game\gamemodes\changeling\powers\boost_range.dm" +#include "code\game\gamemodes\changeling\powers\cryo_sting.dm" +#include "code\game\gamemodes\changeling\powers\deaf_sting.dm" +#include "code\game\gamemodes\changeling\powers\digital_camo.dm" +#include "code\game\gamemodes\changeling\powers\engorged_glands.dm" +#include "code\game\gamemodes\changeling\powers\epinephrine_overdose.dm" +#include "code\game\gamemodes\changeling\powers\extract_dna_sting.dm" +#include "code\game\gamemodes\changeling\powers\fake_death.dm" +#include "code\game\gamemodes\changeling\powers\fleshmend.dm" +#include "code\game\gamemodes\changeling\powers\hivemind.dm" +#include "code\game\gamemodes\changeling\powers\lesser_form.dm" +#include "code\game\gamemodes\changeling\powers\mimic_voice.dm" +#include "code\game\gamemodes\changeling\powers\panacea.dm" +#include "code\game\gamemodes\changeling\powers\para_sting.dm" +#include "code\game\gamemodes\changeling\powers\rapid_regen.dm" +#include "code\game\gamemodes\changeling\powers\respec.dm" +#include "code\game\gamemodes\changeling\powers\revive.dm" +#include "code\game\gamemodes\changeling\powers\shriek.dm" +#include "code\game\gamemodes\changeling\powers\silence_sting.dm" +#include "code\game\gamemodes\changeling\powers\transform.dm" #include "code\game\gamemodes\cult\cult.dm" #include "code\game\gamemodes\cult\cult_items.dm" #include "code\game\gamemodes\cult\cult_structures.dm"