mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
[MIRROR] Changing changeling (Refactor) (#11142)
Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
9feb91ec4c
commit
a0c273ce1f
@@ -1,22 +0,0 @@
|
||||
/datum/absorbed_dna
|
||||
var/name
|
||||
var/datum/dna/dna
|
||||
var/speciesName
|
||||
var/list/languages
|
||||
var/identifying_gender
|
||||
var/list/flavour_texts
|
||||
var/list/genMods
|
||||
|
||||
/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages, var/newIdentifying_Gender, var/list/newFlavour, var/list/newGenMods)
|
||||
..()
|
||||
name = newName
|
||||
qdel_swap(dna, newDNA)
|
||||
speciesName = newSpecies
|
||||
languages = newLanguages
|
||||
identifying_gender = newIdentifying_Gender
|
||||
flavour_texts = newFlavour ? newFlavour.Copy() : null
|
||||
genMods = newGenMods ? newGenMods.Copy() : null
|
||||
|
||||
/datum/absorbed_dna/Destroy()
|
||||
. = ..()
|
||||
qdel(dna)
|
||||
@@ -1,244 +0,0 @@
|
||||
var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon","Zeta","Eta","Theta","Iota","Kappa","Lambda","Mu","Nu","Xi","Omicron","Pi","Rho","Sigma","Tau","Upsilon","Phi","Chi","Psi","Omega")
|
||||
|
||||
/datum/changeling //stores changeling powers, changeling recharge thingie, changeling absorbed DNA and changeling ID (for changeling hivemind)
|
||||
var/list/datum/absorbed_dna/absorbed_dna = list()
|
||||
var/list/absorbed_languages = list() // Necessary because of set_species stuff
|
||||
var/absorbedcount = 0
|
||||
var/lingabsorbedcount = 1 //Starts at one, because that's us
|
||||
var/chem_charges = 20
|
||||
var/chem_recharge_rate = 0.5
|
||||
var/chem_storage = 50
|
||||
var/sting_range = 1
|
||||
var/changelingID = "Changeling"
|
||||
var/geneticdamage = 0
|
||||
var/isabsorbing = 0
|
||||
var/geneticpoints = 7
|
||||
var/max_geneticpoints = 7
|
||||
var/readapts = 1
|
||||
var/max_readapts = 2
|
||||
var/list/purchased_powers = list()
|
||||
var/mimicing = ""
|
||||
var/cloaked = 0
|
||||
var/armor_deployed = 0 //This is only used for changeling_generic_equip_all_slots() at the moment.
|
||||
var/recursive_enhancement = 0 //Used to power up other abilities from the ling power with the same name.
|
||||
var/list/purchased_powers_history = list() //Used for round-end report, includes respec uses too.
|
||||
var/last_shriek = null // world.time when the ling last used a shriek.
|
||||
var/next_escape = 0 // world.time when the ling can next use Escape Restraints
|
||||
var/thermal_sight = FALSE // Is our Vision Augmented? With thermals?
|
||||
|
||||
/datum/changeling/New(var/gender=FEMALE)
|
||||
..()
|
||||
if(possible_changeling_IDs.len)
|
||||
changelingID = pick(possible_changeling_IDs)
|
||||
possible_changeling_IDs -= changelingID
|
||||
changelingID = "[changelingID]"
|
||||
else
|
||||
changelingID = "[rand(1,999)]"
|
||||
|
||||
/datum/changeling/proc/regenerate()
|
||||
chem_charges = min(max(0, chem_charges+chem_recharge_rate), chem_storage)
|
||||
geneticdamage = max(0, geneticdamage-1)
|
||||
|
||||
/datum/changeling/proc/GetDNA(var/dna_owner)
|
||||
for(var/datum/absorbed_dna/DNA in absorbed_dna)
|
||||
if(dna_owner == DNA.name)
|
||||
return DNA
|
||||
|
||||
/mob/proc/absorbDNA(var/datum/absorbed_dna/newDNA)
|
||||
var/datum/changeling/changeling = null
|
||||
if(src.mind && src.mind.changeling)
|
||||
changeling = src.mind.changeling
|
||||
if(!changeling)
|
||||
return
|
||||
|
||||
for(var/language in newDNA.languages)
|
||||
changeling.absorbed_languages |= language
|
||||
|
||||
changeling_update_languages(changeling.absorbed_languages)
|
||||
|
||||
if(!changeling.GetDNA(newDNA.name)) // Don't duplicate - I wonder if it's possible for it to still be a different DNA? DNA code could use a rewrite
|
||||
changeling.absorbed_dna += newDNA
|
||||
|
||||
//Restores our verbs. It will only restore verbs allowed during lesser (monkey) form if we are not human
|
||||
/mob/proc/make_changeling()
|
||||
|
||||
if(!mind) return
|
||||
if(!mind.changeling) mind.changeling = new /datum/changeling(gender)
|
||||
|
||||
add_verb(src, /datum/changeling/proc/EvolutionMenu)
|
||||
add_verb(src, /mob/proc/changeling_respec)
|
||||
add_language("Changeling")
|
||||
|
||||
var/lesser_form = !ishuman(src)
|
||||
|
||||
if(!powerinstances.len)
|
||||
for(var/P in powers)
|
||||
powerinstances += new P()
|
||||
|
||||
// Code to auto-purchase free powers.
|
||||
for(var/datum/power/changeling/P in powerinstances)
|
||||
if(!P.genomecost) // Is it free?
|
||||
if(!(P in mind.changeling.purchased_powers)) // Do we not have it already?
|
||||
mind.changeling.purchasePower(mind, P.name, 0)// Purchase it. Don't remake our verbs, we're doing it after this.
|
||||
|
||||
for(var/datum/power/changeling/P in mind.changeling.purchased_powers)
|
||||
if(P.isVerb)
|
||||
if(lesser_form && !P.allowduringlesserform) continue
|
||||
if(!(P in src.verbs))
|
||||
add_verb(src, P.verbpath)
|
||||
if(P.make_hud_button)
|
||||
if(!src.ability_master)
|
||||
src.ability_master = new /obj/screen/movable/ability_master(src)
|
||||
src.ability_master.add_ling_ability(
|
||||
object_given = src,
|
||||
verb_given = P.verbpath,
|
||||
name_given = P.name,
|
||||
ability_icon_given = P.ability_icon_state,
|
||||
arguments = list()
|
||||
)
|
||||
|
||||
for(var/language in languages)
|
||||
mind.changeling.absorbed_languages |= language
|
||||
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(istype(H))
|
||||
var/saved_dna = H.dna.Clone() /// Prevent transform from breaking.
|
||||
var/datum/absorbed_dna/newDNA = new(H.real_name, saved_dna, H.species.name, H.languages, H.identifying_gender, H.flavor_texts, H.modifiers)
|
||||
absorbDNA(newDNA)
|
||||
|
||||
return 1
|
||||
|
||||
//removes our changeling verbs
|
||||
/mob/proc/remove_changeling_powers()
|
||||
if(!mind || !mind.changeling) return
|
||||
for(var/datum/power/changeling/P in mind.changeling.purchased_powers)
|
||||
if(P.isVerb)
|
||||
remove_verb(src, P.verbpath)
|
||||
var/obj/screen/ability/verb_based/changeling/C = ability_master.get_ability_by_proc_ref(P.verbpath)
|
||||
if(C)
|
||||
ability_master.remove_ability(C)
|
||||
|
||||
|
||||
//Helper proc. Does all the checks and stuff for us to avoid copypasta
|
||||
/mob/proc/changeling_power(var/required_chems=0, var/required_dna=0, var/max_genetic_damage=100, var/max_stat=0)
|
||||
|
||||
if(!src.mind) return
|
||||
if(!iscarbon(src)) return
|
||||
|
||||
var/datum/changeling/changeling = src.mind.changeling
|
||||
if(!changeling)
|
||||
to_world_log("[src] has the changeling_transform() verb but is not a changeling.")
|
||||
return
|
||||
|
||||
if(src.stat > max_stat)
|
||||
to_chat(src, span_warning("We are incapacitated."))
|
||||
return
|
||||
|
||||
if(changeling.absorbed_dna.len < required_dna)
|
||||
to_chat(src, span_warning("We require at least [required_dna] samples of compatible DNA."))
|
||||
return
|
||||
|
||||
if(changeling.chem_charges < required_chems)
|
||||
to_chat(src, span_warning("We require at least [required_chems] units of chemicals to do that!"))
|
||||
return
|
||||
|
||||
if(changeling.geneticdamage > max_genetic_damage)
|
||||
to_chat(src, span_warning("Our genomes are still reassembling. We need time to recover first."))
|
||||
return
|
||||
|
||||
return changeling
|
||||
|
||||
//Used to dump the languages from the changeling datum into the actual mob.
|
||||
/mob/proc/changeling_update_languages(var/updated_languages)
|
||||
languages = list()
|
||||
for(var/language in updated_languages)
|
||||
languages += language
|
||||
|
||||
//This isn't strictly necessary but just to be safe...
|
||||
add_language("Changeling")
|
||||
|
||||
//////////
|
||||
//STINGS// //They get a pretty header because there's just so fucking many of them ;_;
|
||||
//////////
|
||||
|
||||
/turf/proc/AdjacentTurfsRangedSting()
|
||||
//Yes this is snowflakey, but I couldn't get it to work any other way.. -Luke
|
||||
var/list/allowed = list(
|
||||
/obj/structure/table,
|
||||
/obj/structure/closet,
|
||||
/obj/structure/frame,
|
||||
/obj/structure/target_stake,
|
||||
/obj/structure/cable,
|
||||
/obj/structure/disposalpipe,
|
||||
/obj/machinery,
|
||||
/mob
|
||||
)
|
||||
|
||||
var/L[] = new()
|
||||
for(var/turf/simulated/t in oview(src,1))
|
||||
var/add = 1
|
||||
if(t.density)
|
||||
add = 0
|
||||
if(add && LinkBlocked(src,t))
|
||||
add = 0
|
||||
if(add && TurfBlockedNonWindow(t))
|
||||
add = 0
|
||||
for(var/obj/O in t)
|
||||
if(O.density)
|
||||
add = 0
|
||||
break
|
||||
if(istype(O, /obj/machinery/door))
|
||||
//not sure why this doesn't fire on LinkBlocked()
|
||||
add = 0
|
||||
break
|
||||
for(var/type in allowed)
|
||||
if (istype(O, type))
|
||||
add = 1
|
||||
break
|
||||
if(!add)
|
||||
break
|
||||
if(add)
|
||||
L.Add(t)
|
||||
return L
|
||||
|
||||
|
||||
/mob/proc/sting_can_reach(mob/M as mob, sting_range = 1)
|
||||
if(M.loc == src.loc)
|
||||
return 1 //target and source are in the same thing
|
||||
if(!isturf(src.loc) || !isturf(M.loc))
|
||||
to_chat(src, span_warning("We cannot reach \the [M] with a sting!"))
|
||||
return 0 //One is inside, the other is outside something.
|
||||
// Maximum queued turfs set to 25; I don't *think* anything raises sting_range above 2, but if it does the 25 may need raising
|
||||
if(!SSpathfinder.get_path_jps(src, get_turf(src), get_turf(M), max_path_length = 25)) //CHOMPEdit
|
||||
to_chat(src, span_warning("We cannot find a path to sting \the [M] by!"))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
//Handles the general sting code to reduce on copypasta (seeming as somebody decided to make SO MANY dumb abilities)
|
||||
/mob/proc/changeling_sting(var/required_chems=0, var/verb_path)
|
||||
var/datum/changeling/changeling = changeling_power(required_chems)
|
||||
if(!changeling) return
|
||||
|
||||
var/list/victims = list()
|
||||
for(var/mob/living/carbon/C in oview(changeling.sting_range))
|
||||
victims += C
|
||||
var/mob/living/carbon/T = tgui_input_list(src, "Who will we sting?", "Sting!", victims)
|
||||
|
||||
if(!T)
|
||||
return
|
||||
if(T.isSynthetic())
|
||||
to_chat(src, span_notice("We are unable to pierce the outer shell of [T]."))
|
||||
return
|
||||
if(!(T in view(changeling.sting_range))) return
|
||||
if(!sting_can_reach(T, changeling.sting_range)) return
|
||||
if(!changeling_power(required_chems)) return
|
||||
|
||||
changeling.chem_charges -= required_chems
|
||||
changeling.sting_range = 1
|
||||
remove_verb(src, verb_path)
|
||||
spawn(10) add_verb(src, verb_path)
|
||||
|
||||
to_chat(src, span_notice("We stealthily sting [T]."))
|
||||
if(!T.mind || !T.mind.changeling) return T //T will be affected by the sting
|
||||
to_chat(T, span_warning("You feel a tiny prick."))
|
||||
return
|
||||
@@ -1,254 +0,0 @@
|
||||
//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/boot_type, var/chem_cost)
|
||||
|
||||
if(!ishuman(src))
|
||||
return 0
|
||||
|
||||
var/mob/living/carbon/human/M = src
|
||||
|
||||
if(istype(M.wear_suit, armor_type) || istype(M.head, helmet_type) || istype(M.shoes, boot_type))
|
||||
chem_cost = 0
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(chem_cost, 1, 100, CONSCIOUS)
|
||||
|
||||
if(!changeling)
|
||||
return
|
||||
|
||||
//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) || istype(M.shoes, boot_type))
|
||||
M.visible_message(span_warning("[M] casts off their [M.wear_suit.name]!"),
|
||||
span_warning("We cast off our [M.wear_suit.name]"),
|
||||
span_warningplain("You hear the organic matter ripping and tearing!"))
|
||||
if(istype(M.wear_suit, armor_type))
|
||||
qdel(M.wear_suit)
|
||||
if(istype(M.head, helmet_type))
|
||||
qdel(M.head)
|
||||
if(istype(M.shoes, boot_type))
|
||||
qdel(M.shoes)
|
||||
M.update_inv_wear_suit()
|
||||
M.update_inv_head()
|
||||
M.update_hair()
|
||||
M.update_inv_shoes()
|
||||
return 1
|
||||
|
||||
if(M.head || M.wear_suit) //Make sure our slots aren't full
|
||||
to_chat(src, span_warning("We require nothing to be on our head, and we cannot wear any external suits, or shoes."))
|
||||
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)
|
||||
|
||||
var/obj/item/clothing/shoes/B = new boot_type(src)
|
||||
src.equip_to_slot_or_del(B, slot_shoes)
|
||||
|
||||
src.mind.changeling.chem_charges -= chem_cost
|
||||
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
M.update_inv_wear_suit()
|
||||
M.update_inv_head()
|
||||
M.update_hair()
|
||||
M.update_inv_shoes()
|
||||
return 1
|
||||
|
||||
/mob/proc/changeling_generic_equip_all_slots(var/list/stuff_to_equip, var/cost)
|
||||
var/datum/changeling/changeling = changeling_power(cost,1,100,CONSCIOUS)
|
||||
if(!changeling)
|
||||
return
|
||||
|
||||
if(!ishuman(src))
|
||||
return 0
|
||||
|
||||
var/mob/living/carbon/human/M = src
|
||||
|
||||
var/success = 0
|
||||
|
||||
//First, check if we're already wearing the armor, and if so, take it off.
|
||||
|
||||
if(M.mind.changeling.armor_deployed)
|
||||
if(M.head && stuff_to_equip["head"])
|
||||
if(istype(M.head, stuff_to_equip["head"]))
|
||||
qdel(M.head)
|
||||
success = 1
|
||||
|
||||
if(M.wear_id && stuff_to_equip["wear_id"])
|
||||
if(istype(M.wear_id, stuff_to_equip["wear_id"]))
|
||||
qdel(M.wear_id)
|
||||
success = 1
|
||||
|
||||
if(M.wear_suit && stuff_to_equip["wear_suit"])
|
||||
if(istype(M.wear_suit, stuff_to_equip["wear_suit"]))
|
||||
qdel(M.wear_suit)
|
||||
success = 1
|
||||
|
||||
if(M.gloves && stuff_to_equip["gloves"])
|
||||
if(istype(M.gloves, stuff_to_equip["gloves"]))
|
||||
qdel(M.gloves)
|
||||
success = 1
|
||||
if(M.shoes && stuff_to_equip["shoes"])
|
||||
if(istype(M.shoes, stuff_to_equip["shoes"]))
|
||||
qdel(M.shoes)
|
||||
success = 1
|
||||
|
||||
if(M.belt && stuff_to_equip["belt"])
|
||||
if(istype(M.belt, stuff_to_equip["belt"]))
|
||||
qdel(M.belt)
|
||||
success = 1
|
||||
|
||||
if(M.glasses && stuff_to_equip["glasses"])
|
||||
if(istype(M.glasses, stuff_to_equip["glasses"]))
|
||||
qdel(M.glasses)
|
||||
success = 1
|
||||
|
||||
if(M.wear_mask && stuff_to_equip["wear_mask"])
|
||||
if(istype(M.wear_mask, stuff_to_equip["wear_mask"]))
|
||||
qdel(M.wear_mask)
|
||||
success = 1
|
||||
|
||||
if(M.back && stuff_to_equip["back"])
|
||||
if(istype(M.back, stuff_to_equip["back"]))
|
||||
for(var/atom/movable/AM in M.back.contents) //Dump whatever's in the bag before deleting.
|
||||
AM.forceMove(src.loc)
|
||||
qdel(M.back)
|
||||
success = 1
|
||||
|
||||
if(M.w_uniform && stuff_to_equip["w_uniform"])
|
||||
if(istype(M.w_uniform, stuff_to_equip["w_uniform"]))
|
||||
qdel(M.w_uniform)
|
||||
success = 1
|
||||
|
||||
if(success)
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
visible_message(span_warning("[src] pulls on their clothes, peeling it off along with parts of their skin attached!"),
|
||||
span_notice("We remove and deform our equipment."))
|
||||
M.mind.changeling.armor_deployed = 0
|
||||
return success
|
||||
|
||||
else
|
||||
|
||||
to_chat(M, span_notice("We begin growing our new equipment..."))
|
||||
|
||||
var/list/grown_items_list = list()
|
||||
|
||||
var/t = stuff_to_equip["head"]
|
||||
if(!M.head && t)
|
||||
var/I = new t
|
||||
M.equip_to_slot_or_del(I, slot_head)
|
||||
grown_items_list.Add("a helmet")
|
||||
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
success = 1
|
||||
sleep(1 SECOND)
|
||||
|
||||
t = stuff_to_equip["w_uniform"]
|
||||
if(!M.w_uniform && t)
|
||||
var/I = new t
|
||||
M.equip_to_slot_or_del(I, slot_w_uniform)
|
||||
grown_items_list.Add("a uniform")
|
||||
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
success = 1
|
||||
sleep(1 SECOND)
|
||||
|
||||
t = stuff_to_equip["gloves"]
|
||||
if(!M.gloves && t)
|
||||
var/I = new t
|
||||
M.equip_to_slot_or_del(I, slot_gloves)
|
||||
grown_items_list.Add("some gloves")
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
success = 1
|
||||
sleep(1 SECOND)
|
||||
|
||||
t = stuff_to_equip["shoes"]
|
||||
if(!M.shoes && t)
|
||||
var/I = new t
|
||||
M.equip_to_slot_or_del(I, slot_shoes)
|
||||
grown_items_list.Add("shoes")
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
success = 1
|
||||
sleep(1 SECOND)
|
||||
|
||||
t = stuff_to_equip["belt"]
|
||||
if(!M.belt && t)
|
||||
var/I = new t
|
||||
M.equip_to_slot_or_del(I, slot_belt)
|
||||
grown_items_list.Add("a belt")
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
success = 1
|
||||
sleep(1 SECOND)
|
||||
|
||||
t = stuff_to_equip["glasses"]
|
||||
if(!M.glasses && t)
|
||||
var/I = new t
|
||||
M.equip_to_slot_or_del(I, slot_glasses)
|
||||
grown_items_list.Add("some glasses")
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
success = 1
|
||||
sleep(1 SECOND)
|
||||
|
||||
t = stuff_to_equip["wear_mask"]
|
||||
if(!M.wear_mask && t)
|
||||
var/I = new t
|
||||
M.equip_to_slot_or_del(I, slot_wear_mask)
|
||||
grown_items_list.Add("a mask")
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
success = 1
|
||||
sleep(1 SECOND)
|
||||
|
||||
t = stuff_to_equip["back"]
|
||||
if(!M.back && t)
|
||||
var/I = new t
|
||||
M.equip_to_slot_or_del(I, slot_back)
|
||||
grown_items_list.Add("a backpack")
|
||||
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
success = 1
|
||||
sleep(1 SECOND)
|
||||
|
||||
t = stuff_to_equip["wear_suit"]
|
||||
if(!M.wear_suit && t)
|
||||
var/I = new t
|
||||
M.equip_to_slot_or_del(I, slot_wear_suit)
|
||||
grown_items_list.Add("an exosuit")
|
||||
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
success = 1
|
||||
sleep(1 SECOND)
|
||||
|
||||
t = stuff_to_equip["wear_id"]
|
||||
if(!M.wear_id && t)
|
||||
var/I = new t
|
||||
M.equip_to_slot_or_del(I, slot_wear_id)
|
||||
grown_items_list.Add("an ID card")
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
success = 1
|
||||
sleep(1 SECOND)
|
||||
|
||||
var/feedback = english_list(grown_items_list, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" )
|
||||
|
||||
to_chat(M, span_notice("We have grown [feedback]."))
|
||||
|
||||
if(success)
|
||||
M.mind.changeling.armor_deployed = 1
|
||||
M.mind.changeling.chem_charges -= 10
|
||||
return success
|
||||
|
||||
//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/cost = 20)
|
||||
var/datum/changeling/changeling = changeling_power(cost,1,100,CONSCIOUS)
|
||||
if(!changeling)
|
||||
return
|
||||
|
||||
if(!ishuman(src))
|
||||
return 0
|
||||
|
||||
var/mob/living/carbon/human/M = src
|
||||
|
||||
if(M.hands_are_full()) //Make sure our hands aren't full.
|
||||
to_chat(src, span_warning("Our hands are full. Drop something first."))
|
||||
return 0
|
||||
|
||||
var/obj/item/W = new weapon_type(src)
|
||||
src.put_in_hands(W)
|
||||
|
||||
src.mind.changeling.chem_charges -= cost
|
||||
if(make_sound)
|
||||
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
return 1
|
||||
@@ -1,359 +0,0 @@
|
||||
// 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 = subtypesof(/datum/power/changeling) //needed for the badmin verb for now
|
||||
var/list/datum/power/changeling/powerinstances = list()
|
||||
|
||||
/datum/power //Could be used by other antags too
|
||||
var/name = "Power"
|
||||
var/desc = "Placeholder"
|
||||
var/helptext = ""
|
||||
var/enhancedtext = ""
|
||||
var/isVerb = 1 // Is it an active power, or passive?
|
||||
var/verbpath // Path to a verb that contains the effects.
|
||||
var/make_hud_button = 1 // Is this ability significant enough to dedicate screen space for a HUD button?
|
||||
var/ability_icon_state = null // icon_state for icons for the ability HUD. Must be in screen_spells.dmi.
|
||||
|
||||
/datum/power/changeling
|
||||
var/allowduringlesserform = 0
|
||||
var/genomecost = 500000 // Cost for the changling to evolve this power.
|
||||
|
||||
|
||||
// Modularchangling, totally stolen from the new player panel. YAYY
|
||||
/datum/changeling/proc/EvolutionMenu()//The new one
|
||||
set name = "-Evolution Menu-"
|
||||
set category = "Changeling"
|
||||
set desc = "Adapt yourself carefully."
|
||||
|
||||
if(!usr || !usr.mind || !usr.mind.changeling) return
|
||||
src = usr.mind.changeling
|
||||
|
||||
if(!powerinstances.len)
|
||||
for(var/P in powers)
|
||||
powerinstances += new P()
|
||||
|
||||
var/dat = "<html><head><title>Changling Evolution Menu</title></head>"
|
||||
|
||||
//javascript, the part that does most of the work~
|
||||
dat += {"
|
||||
|
||||
<head>
|
||||
<script type='text/javascript'>
|
||||
|
||||
var locked_tabs = new Array();
|
||||
|
||||
function updateSearch(){
|
||||
|
||||
|
||||
var filter_text = document.getElementById('filter');
|
||||
var filter = filter_text.value.toLowerCase();
|
||||
|
||||
if(complete_list != null && complete_list != ""){
|
||||
var mtbl = document.getElementById("maintable_data_archive");
|
||||
mtbl.innerHTML = complete_list;
|
||||
}
|
||||
|
||||
if(filter.value == ""){
|
||||
return;
|
||||
}else{
|
||||
|
||||
var maintable_data = document.getElementById('maintable_data');
|
||||
var ltr = maintable_data.getElementsByTagName("tr");
|
||||
for ( var i = 0; i < ltr.length; ++i )
|
||||
{
|
||||
try{
|
||||
var tr = ltr\[i\];
|
||||
if(tr.getAttribute("id").indexOf("data") != 0){
|
||||
continue;
|
||||
}
|
||||
var ltd = tr.getElementsByTagName("td");
|
||||
var td = ltd\[0\];
|
||||
var lsearch = td.getElementsByTagName("b");
|
||||
var search = lsearch\[0\];
|
||||
//var inner_span = li.getElementsByTagName("span")\[1\] //Should only ever contain one element.
|
||||
//document.write("<p>"+search.innerText+"<br>"+filter+"<br>"+search.innerText.indexOf(filter))
|
||||
if ( search.innerText.toLowerCase().indexOf(filter) == -1 )
|
||||
{
|
||||
//document.write("a");
|
||||
//ltr.removeChild(tr);
|
||||
td.innerHTML = "";
|
||||
i--;
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
}
|
||||
|
||||
var count = 0;
|
||||
var index = -1;
|
||||
var debug = document.getElementById("debug");
|
||||
|
||||
locked_tabs = new Array();
|
||||
|
||||
}
|
||||
|
||||
function expand(id,name,desc,helptext,enhancedtext,power,ownsthis){
|
||||
|
||||
clearAll();
|
||||
|
||||
var span = document.getElementById(id);
|
||||
|
||||
body = "<table><tr><td>";
|
||||
|
||||
body += "</td><td align='center'>";
|
||||
|
||||
body += "<font size='2'><b>"+desc+"</b></font> <BR>"
|
||||
|
||||
body += "<font size='2'><font color = 'red'><b>"+helptext+"</b></font></font><BR>"
|
||||
|
||||
if(enhancedtext)
|
||||
{
|
||||
body += "<font size='2'><font color = 'blue'>Recursive Enhancement Effect: <b>"+enhancedtext+"</b></font></font><BR>"
|
||||
}
|
||||
|
||||
if(!ownsthis)
|
||||
{
|
||||
body += "<a href='byond://?src=\ref[src];P="+power+"'>Evolve</a>"
|
||||
}
|
||||
|
||||
body += "</td><td align='center'>";
|
||||
|
||||
body += "</td></tr></table>";
|
||||
|
||||
|
||||
span.innerHTML = body
|
||||
}
|
||||
|
||||
function clearAll(){
|
||||
var spans = document.getElementsByTagName('span');
|
||||
for(var i = 0; i < spans.length; i++){
|
||||
var span = spans\[i\];
|
||||
|
||||
var id = span.getAttribute("id");
|
||||
|
||||
if(!(id.indexOf("item")==0))
|
||||
continue;
|
||||
|
||||
var pass = 1;
|
||||
|
||||
for(var j = 0; j < locked_tabs.length; j++){
|
||||
if(locked_tabs\[j\]==id){
|
||||
pass = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(pass != 1)
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
|
||||
span.innerHTML = "";
|
||||
}
|
||||
}
|
||||
|
||||
function addToLocked(id,link_id,notice_span_id){
|
||||
var link = document.getElementById(link_id);
|
||||
var decision = link.getAttribute("name");
|
||||
if(decision == "1"){
|
||||
link.setAttribute("name","2");
|
||||
}else{
|
||||
link.setAttribute("name","1");
|
||||
removeFromLocked(id,link_id,notice_span_id);
|
||||
return;
|
||||
}
|
||||
|
||||
var pass = 1;
|
||||
for(var j = 0; j < locked_tabs.length; j++){
|
||||
if(locked_tabs\[j\]==id){
|
||||
pass = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!pass)
|
||||
return;
|
||||
locked_tabs.push(id);
|
||||
var notice_span = document.getElementById(notice_span_id);
|
||||
notice_span.innerHTML = "<font color='red'>Locked</font> ";
|
||||
//link.setAttribute("onClick","attempt('"+id+"','"+link_id+"','"+notice_span_id+"');");
|
||||
//document.write("removeFromLocked('"+id+"','"+link_id+"','"+notice_span_id+"')");
|
||||
//document.write("aa - "+link.getAttribute("onClick"));
|
||||
}
|
||||
|
||||
function attempt(ab){
|
||||
return ab;
|
||||
}
|
||||
|
||||
function removeFromLocked(id,link_id,notice_span_id){
|
||||
//document.write("a");
|
||||
var index = 0;
|
||||
var pass = 0;
|
||||
for(var j = 0; j < locked_tabs.length; j++){
|
||||
if(locked_tabs\[j\]==id){
|
||||
pass = 1;
|
||||
index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!pass)
|
||||
return;
|
||||
locked_tabs\[index\] = "";
|
||||
var notice_span = document.getElementById(notice_span_id);
|
||||
notice_span.innerHTML = "";
|
||||
//var link = document.getElementById(link_id);
|
||||
//link.setAttribute("onClick","addToLocked('"+id+"','"+link_id+"','"+notice_span_id+"')");
|
||||
}
|
||||
|
||||
function selectTextField(){
|
||||
var filter_text = document.getElementById('filter');
|
||||
filter_text.focus();
|
||||
filter_text.select();
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
"}
|
||||
|
||||
//body tag start + onload and onkeypress (onkeyup) javascript event calls
|
||||
dat += "<body onload='selectTextField(); updateSearch();' onkeyup='updateSearch();'>"
|
||||
|
||||
//title + search bar
|
||||
dat += {"
|
||||
|
||||
<table width='560' align='center' cellspacing='0' cellpadding='5' id='maintable'>
|
||||
<tr id='title_tr'>
|
||||
<td align='center'>
|
||||
<font size='5'><b>Changling Evolution Menu</b></font><br>
|
||||
Hover over a power to see more information<br>
|
||||
Current evolution points left to evolve with: [geneticpoints]<br>
|
||||
Absorb other changelings to acquire more evolution points
|
||||
<p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id='search_tr'>
|
||||
<td align='center'>
|
||||
<b>Search:</b> <input type='text' id='filter' value='' style='width:300px;'>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
"}
|
||||
|
||||
//player table header
|
||||
dat += {"
|
||||
<span id='maintable_data_archive'>
|
||||
<table width='560' align='center' cellspacing='0' cellpadding='5' id='maintable_data'>"}
|
||||
|
||||
var/i = 1
|
||||
for(var/datum/power/changeling/P in powerinstances)
|
||||
var/ownsthis = 0
|
||||
|
||||
if(P in purchased_powers)
|
||||
ownsthis = 1
|
||||
|
||||
|
||||
var/color = "#e6e6e6"
|
||||
if(i%2 == 0)
|
||||
color = "#f2f2f2"
|
||||
|
||||
|
||||
dat += {"
|
||||
|
||||
<tr id='data[i]' name='[i]' onClick="addToLocked('item[i]','data[i]','notice_span[i]')">
|
||||
<td align='center' bgcolor='[color]'>
|
||||
<span id='notice_span[i]'></span>
|
||||
<a id='link[i]'
|
||||
onmouseover='expand("item[i]","[P.name]","[P.desc]","[P.helptext]","[P.enhancedtext]","[P]",[ownsthis])'
|
||||
>
|
||||
<span id='search[i]'><b>Evolve [P] - Cost: [ownsthis ? "Purchased" : P.genomecost]</b></span>
|
||||
</a>
|
||||
<br><span id='item[i]'></span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
"}
|
||||
|
||||
i++
|
||||
|
||||
|
||||
//player table ending
|
||||
dat += {"
|
||||
</table>
|
||||
</span>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var maintable = document.getElementById("maintable_data_archive");
|
||||
var complete_list = maintable.innerHTML;
|
||||
</script>
|
||||
</body></html>
|
||||
"}
|
||||
|
||||
usr << browse(dat, "window=powers;size=900x480")
|
||||
|
||||
|
||||
/datum/changeling/Topic(href, href_list)
|
||||
..()
|
||||
if(!ismob(usr))
|
||||
return
|
||||
|
||||
if(href_list["P"])
|
||||
var/datum/mind/M = usr.mind
|
||||
if(!istype(M))
|
||||
return
|
||||
purchasePower(M, href_list["P"])
|
||||
call(/datum/changeling/proc/EvolutionMenu)()
|
||||
|
||||
|
||||
|
||||
/datum/changeling/proc/purchasePower(var/datum/mind/M, var/Pname, var/remake_verbs = 1)
|
||||
if(!M || !M.changeling)
|
||||
return
|
||||
|
||||
var/datum/power/changeling/Thepower = Pname
|
||||
|
||||
|
||||
for (var/datum/power/changeling/P in powerinstances)
|
||||
//to_world("[P] - [Pname] = [P.name == Pname ? "True" : "False"]")
|
||||
if(P.name == Pname)
|
||||
Thepower = P
|
||||
break
|
||||
|
||||
|
||||
if(Thepower == null)
|
||||
to_chat(M.current, "This is awkward. Changeling power purchase failed, please report this bug to a coder!")
|
||||
return
|
||||
|
||||
if(Thepower in purchased_powers)
|
||||
to_chat(M.current, "We have already evolved this ability!")
|
||||
return
|
||||
|
||||
|
||||
if(geneticpoints < Thepower.genomecost)
|
||||
to_chat(M.current, "We cannot evolve this... yet. We must acquire more DNA.")
|
||||
return
|
||||
|
||||
geneticpoints -= Thepower.genomecost
|
||||
|
||||
purchased_powers += Thepower
|
||||
|
||||
if(Thepower.genomecost > 0)
|
||||
purchased_powers_history.Add("[Pname] ([Thepower.genomecost] points)")
|
||||
|
||||
if(Thepower.make_hud_button && Thepower.isVerb)
|
||||
if(!M.current.ability_master)
|
||||
M.current.ability_master = new /obj/screen/movable/ability_master(M.current)
|
||||
M.current.ability_master.add_ling_ability(
|
||||
object_given = M.current,
|
||||
verb_given = Thepower.verbpath,
|
||||
name_given = Thepower.name,
|
||||
ability_icon_given = Thepower.ability_icon_state,
|
||||
arguments = list()
|
||||
)
|
||||
|
||||
if(!Thepower.isVerb && Thepower.verbpath)
|
||||
call(M.current, Thepower.verbpath)()
|
||||
else if(remake_verbs)
|
||||
M.current.make_changeling()
|
||||
@@ -1,114 +0,0 @@
|
||||
/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 if they were of our kind."
|
||||
ability_icon_state = "ling_absorb_dna"
|
||||
genomecost = 0
|
||||
verbpath = /mob/living/proc/changeling_absorb_dna
|
||||
|
||||
//Absorbs the victim's DNA. Requires a strong grip on the victim.
|
||||
//Doesn't cost anything as it's the most basic ability.
|
||||
/mob/living/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/grab/G = src.get_active_hand()
|
||||
if(!istype(G))
|
||||
to_chat(src, span_warning("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) || T.isSynthetic())
|
||||
to_chat(src, span_warning("\The [T] is not compatible with our biology."))
|
||||
return
|
||||
|
||||
if(T.species.flags & (NO_DNA|NO_SLEEVE))
|
||||
to_chat(src, span_warning("We do not know how to parse this creature's DNA!"))
|
||||
return
|
||||
|
||||
if(HUSK in T.mutations) //Lings can always absorb other lings, unless someone beat them to it first.
|
||||
if(!T.mind.changeling || T.mind.changeling && T.mind.changeling.geneticpoints < 0)
|
||||
to_chat(src, span_warning("This creature's DNA is ruined beyond useability!"))
|
||||
return
|
||||
|
||||
if(G.state != GRAB_KILL)
|
||||
to_chat(src, span_warning("We must have a tighter grip to absorb this creature."))
|
||||
return
|
||||
|
||||
if(changeling.isabsorbing)
|
||||
to_chat(src, span_warning("We are already absorbing!"))
|
||||
return
|
||||
|
||||
changeling.isabsorbing = 1
|
||||
for(var/stage = 1, stage<=3, stage++)
|
||||
switch(stage)
|
||||
if(1)
|
||||
to_chat(src, span_notice("This creature is compatible. We must hold still..."))
|
||||
if(2)
|
||||
to_chat(src, span_notice("We extend a proboscis."))
|
||||
src.visible_message(span_warning("[src] extends a proboscis!"))
|
||||
if(3)
|
||||
to_chat(src, span_notice("We stab [T] with the proboscis."))
|
||||
src.visible_message(span_danger("[src] stabs [T] with the proboscis!"))
|
||||
to_chat(T, span_danger("You feel a sharp stabbing pain!"))
|
||||
add_attack_logs(src,T,"Absorbed (changeling)")
|
||||
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) || G.state != GRAB_KILL)
|
||||
to_chat(src, span_warning("Our absorption of [T] has been interrupted!"))
|
||||
changeling.isabsorbing = 0
|
||||
return
|
||||
|
||||
to_chat(src, span_notice("We have absorbed [T]!"))
|
||||
src.visible_message(span_danger("[src] sucks the fluids from [T]!"))
|
||||
to_chat(T, span_danger("You have been absorbed by the changeling!"))
|
||||
adjust_nutrition(T.nutrition)
|
||||
changeling.chem_charges += 10
|
||||
if(changeling.readapts <= 0)
|
||||
changeling.readapts = 0 //SANITYYYYYY
|
||||
changeling.readapts++
|
||||
if(changeling.readapts > changeling.max_readapts)
|
||||
changeling.readapts = changeling.max_readapts
|
||||
|
||||
to_chat(src, span_notice("We can now re-adapt, reverting our evolution so that we may start anew, if needed."))
|
||||
|
||||
var/saved_dna = T.dna.Clone() /// Prevent transforming bugginess.
|
||||
var/datum/absorbed_dna/newDNA = new(T.real_name, saved_dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts, T.modifiers)
|
||||
absorbDNA(newDNA)
|
||||
|
||||
if(T.mind && T.mind.changeling)
|
||||
if(T.mind.changeling.absorbed_dna)
|
||||
for(var/datum/absorbed_dna/dna_data in T.mind.changeling.absorbed_dna) //steal all their loot
|
||||
if(dna_data in changeling.absorbed_dna)
|
||||
continue
|
||||
absorbDNA(dna_data)
|
||||
changeling.absorbedcount++
|
||||
|
||||
T.mind.changeling.absorbed_dna.len = 1
|
||||
|
||||
// This is where lings get boosts from eating eachother
|
||||
if(T.mind.changeling.lingabsorbedcount)
|
||||
for(var/a = 1 to T.mind.changeling.lingabsorbedcount)
|
||||
changeling.lingabsorbedcount++
|
||||
changeling.geneticpoints += 4
|
||||
changeling.max_geneticpoints += 4
|
||||
|
||||
to_chat(src, span_notice("We absorbed another changeling, and we grow stronger. Our genomes increase."))
|
||||
|
||||
T.mind.changeling.chem_charges = 0
|
||||
T.mind.changeling.geneticpoints = -1
|
||||
T.mind.changeling.max_geneticpoints = -1 //To prevent revival.
|
||||
T.mind.changeling.absorbedcount = 0
|
||||
T.mind.changeling.lingabsorbedcount = 0
|
||||
|
||||
changeling.absorbedcount++
|
||||
changeling.isabsorbing = 0
|
||||
|
||||
T.death(0)
|
||||
T.Drain()
|
||||
return 1
|
||||
@@ -1,168 +0,0 @@
|
||||
/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."
|
||||
enhancedtext = "The blade will have armor peneratration."
|
||||
ability_icon_state = "ling_armblade"
|
||||
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(src.mind.changeling.recursive_enhancement)
|
||||
if(changeling_generic_weapon(/obj/item/melee/changeling/arm_blade/greater))
|
||||
to_chat(src, span_notice("We prepare an extra sharp blade."))
|
||||
return 1
|
||||
|
||||
else
|
||||
if(changeling_generic_weapon(/obj/item/melee/changeling/arm_blade))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//Claws
|
||||
/datum/power/changeling/claw
|
||||
name = "Claw"
|
||||
desc = "We reform one of our arms into a deadly claw."
|
||||
helptext = "We may retract our claw by dropping it."
|
||||
enhancedtext = "The claw will have armor peneratration."
|
||||
ability_icon_state = "ling_claw"
|
||||
genomecost = 1
|
||||
verbpath = /mob/proc/changeling_claw
|
||||
|
||||
//Grows a scary, and powerful claw.
|
||||
/mob/proc/changeling_claw()
|
||||
set category = "Changeling"
|
||||
set name = "Claw (15)"
|
||||
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
if(changeling_generic_weapon(/obj/item/melee/changeling/claw/greater, 1, 15))
|
||||
to_chat(src, span_notice("We prepare an extra sharp claw."))
|
||||
return 1
|
||||
|
||||
else
|
||||
if(changeling_generic_weapon(/obj/item/melee/changeling/claw, 1, 15))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/melee/changeling
|
||||
name = "arm weapon"
|
||||
desc = "A grotesque weapon 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"
|
||||
w_class = ITEMSIZE_HUGE
|
||||
force = 5
|
||||
anchored = TRUE
|
||||
throwforce = 0 //Just to be on the safe side
|
||||
throw_range = 0
|
||||
throw_speed = 0
|
||||
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.
|
||||
var/weapType = "weapon"
|
||||
var/weapLocation = "arm"
|
||||
|
||||
defend_chance = 40 // The base chance for the weapon to parry.
|
||||
projectile_parry_chance = 15 // The base chance for a projectile to be deflected.
|
||||
|
||||
/obj/item/melee/changeling/Initialize(mapload)
|
||||
. = ..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
if(ismob(loc))
|
||||
visible_message(span_warning("A grotesque weapon forms around [loc.name]\'s arm!"),
|
||||
span_warning("Our arm twists and mutates, transforming it into a deadly weapon."),
|
||||
span_warningplain("You hear organic matter ripping and tearing!"))
|
||||
src.creator = loc
|
||||
|
||||
/obj/item/melee/changeling/dropped(mob/user)
|
||||
..()
|
||||
visible_message(span_warning("With a sickening crunch, [creator] reforms their arm!"),
|
||||
span_notice("We assimilate the weapon back into our body."),
|
||||
span_warningplain("You hear organic matter ripping and tearing!"))
|
||||
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
spawn(1)
|
||||
if(src)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/melee/changeling/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
creator = null
|
||||
. = ..()
|
||||
|
||||
/obj/item/melee/changeling/process() //Stolen from ninja swords.
|
||||
if(!creator || loc != creator || !creator.item_is_in_hands(src))
|
||||
// Tidy up a bit.
|
||||
if(isliving(loc))
|
||||
var/mob/living/carbon/human/host = loc
|
||||
if(istype(host))
|
||||
for(var/obj/item/organ/external/organ in host.organs)
|
||||
for(var/obj/item/O in organ.implants)
|
||||
if(O == src)
|
||||
organ.implants -= src
|
||||
host.pinned -= src
|
||||
host.embedded -= src
|
||||
host.drop_from_inventory(src)
|
||||
spawn(1)
|
||||
if(src)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/melee/changeling/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
|
||||
if(default_parry_check(user, attacker, damage_source) && prob(defend_chance))
|
||||
user.visible_message(span_danger("\The [user] parries [attack_text] with \the [src]!"))
|
||||
playsound(src, 'sound/weapons/slash.ogg', 50, 1)
|
||||
return 1
|
||||
if(unique_parry_check(user, attacker, damage_source) && prob(projectile_parry_chance))
|
||||
user.visible_message(span_danger("\The [user] deflects [attack_text] with \the [src]!"))
|
||||
playsound(src, 'sound/weapons/slash.ogg', 50, 1)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/item/melee/changeling/unique_parry_check(mob/user, mob/attacker, atom/damage_source)
|
||||
if(user.incapacitated() || !istype(damage_source, /obj/item/projectile))
|
||||
return 0
|
||||
|
||||
var/bad_arc = reverse_direction(user.dir)
|
||||
if(!check_shield_arc(user, bad_arc, damage_source, attacker))
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/obj/item/melee/changeling/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_state = "arm_blade"
|
||||
force = 40
|
||||
armor_penetration = 15
|
||||
sharp = TRUE
|
||||
edge = TRUE
|
||||
pry = 1
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
defend_chance = 60
|
||||
projectile_parry_chance = 25
|
||||
|
||||
/obj/item/melee/changeling/arm_blade/greater
|
||||
name = "arm greatblade"
|
||||
desc = "A grotesque blade made out of bone and flesh that cleaves through people and armor as a hot knife through butter."
|
||||
armor_penetration = 30
|
||||
defend_chance = 70
|
||||
projectile_parry_chance = 35
|
||||
|
||||
/obj/item/melee/changeling/claw
|
||||
name = "hand claw"
|
||||
desc = "A grotesque claw made out of bone and flesh that cleaves through people as a hot knife through butter."
|
||||
icon_state = "ling_claw"
|
||||
force = 15
|
||||
sharp = TRUE
|
||||
edge = TRUE
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
defend_chance = 50
|
||||
projectile_parry_chance = 15
|
||||
|
||||
/obj/item/melee/changeling/claw/greater
|
||||
name = "hand greatclaw"
|
||||
force = 20
|
||||
armor_penetration = 20
|
||||
pry = 1
|
||||
defend_chance = 60
|
||||
projectile_parry_chance = 25
|
||||
@@ -1,146 +0,0 @@
|
||||
/datum/power/changeling/space_suit
|
||||
name = "Organic Space Suit"
|
||||
desc = "We grow an organic suit to protect ourselves from space exposure."
|
||||
helptext = "To remove the suit, use the ability again."
|
||||
ability_icon_state = "ling_space_suit"
|
||||
genomecost = 1
|
||||
verbpath = /mob/proc/changeling_spacesuit
|
||||
|
||||
/mob/proc/changeling_spacesuit()
|
||||
set category = "Changeling"
|
||||
set name = "Organic Space Suit (20)"
|
||||
if(changeling_generic_armor(/obj/item/clothing/suit/space/changeling,/obj/item/clothing/head/helmet/space/changeling,/obj/item/clothing/shoes/magboots/changeling, 20))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/power/changeling/armor
|
||||
name = "Chitinous Spacearmor"
|
||||
desc = "We turn our skin into tough chitin to protect us from damage and space exposure."
|
||||
helptext = "To remove the armor, use the ability again."
|
||||
ability_icon_state = "ling_armor"
|
||||
genomecost = 3
|
||||
verbpath = /mob/proc/changeling_spacearmor
|
||||
|
||||
/mob/proc/changeling_spacearmor()
|
||||
set category = "Changeling"
|
||||
set name = "Organic Spacearmor (20)"
|
||||
|
||||
if(changeling_generic_armor(/obj/item/clothing/suit/space/changeling/armored,/obj/item/clothing/head/helmet/space/changeling/armored,/obj/item/clothing/shoes/magboots/changeling/armored, 20))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//Space suit
|
||||
|
||||
/obj/item/clothing/suit/space/changeling
|
||||
name = "flesh mass"
|
||||
icon_state = "lingspacesuit"
|
||||
desc = "A huge, bulky mass of pressure and temperature-resistant organic tissue, evolved to facilitate space travel."
|
||||
flags = 0 //Not THICKMATERIAL because it's organic tissue, so if somebody tries to inject something into it,
|
||||
//it still ends up in your blood. (also balance but muh fluff)
|
||||
allowed = list(POCKET_GENERIC, POCKET_ALL_TANKS)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) //No armor at all.
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/clothing/suit/space/changeling/Initialize(mapload)
|
||||
. = ..()
|
||||
if(ismob(loc))
|
||||
loc.visible_message(span_warning("[loc.name]\'s flesh rapidly inflates, forming a bloated mass around their body!"),
|
||||
span_warning("We inflate our flesh, creating a spaceproof suit!"),
|
||||
span_warningplain("You hear organic matter ripping and tearing!"))
|
||||
|
||||
/obj/item/clothing/suit/space/changeling/dropped(mob/user)
|
||||
..()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/changeling
|
||||
name = "flesh mass"
|
||||
icon_state = "lingspacehelmet"
|
||||
desc = "A covering of pressure and temperature-resistant organic tissue with a glass-like chitin front."
|
||||
flags = BLOCKHAIR //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 = FALSE
|
||||
|
||||
/obj/item/clothing/head/helmet/space/changeling/dropped(mob/user)
|
||||
..()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/shoes/magboots/changeling
|
||||
desc = "A suction cupped mass of flesh, shaped like a foot."
|
||||
name = "fleshy grippers"
|
||||
icon_state = "lingspacesuit"
|
||||
actions_types = list(/datum/action/item_action/toggle_grippers)
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/clothing/shoes/magboots/changeling/set_slowdown()
|
||||
slowdown = shoes? max(SHOES_SLOWDOWN, shoes.slowdown): SHOES_SLOWDOWN //So you can't put on magboots to make you walk faster.
|
||||
if (magpulse)
|
||||
slowdown += 1 //It's already tied to a slowdown suit, 6 slowdown is huge.
|
||||
|
||||
/obj/item/clothing/shoes/magboots/changeling/attack_self(mob/user)
|
||||
if(magpulse)
|
||||
item_flags &= ~NOSLIP
|
||||
magpulse = 0
|
||||
set_slowdown()
|
||||
force = 3
|
||||
to_chat(user, "We release our grip on the floor.")
|
||||
else
|
||||
item_flags |= NOSLIP
|
||||
magpulse = 1
|
||||
set_slowdown()
|
||||
force = 5
|
||||
to_chat(user, "We cling to the terrain below us.")
|
||||
|
||||
/obj/item/clothing/shoes/magboots/changeling/dropped(mob/user)
|
||||
..()
|
||||
qdel(src)
|
||||
|
||||
//Armor
|
||||
|
||||
/obj/item/clothing/suit/space/changeling/armored
|
||||
name = "chitinous mass"
|
||||
desc = "A tough, hard covering of black chitin."
|
||||
icon_state = "lingarmor"
|
||||
body_parts_covered = CHEST|LEGS|FEET|ARMS|HANDS
|
||||
armor = list(melee = 75, bullet = 60, laser = 60, energy = 60, bomb = 60, bio = 0, rad = 0) //It costs 3 points, so it should be very protective.
|
||||
siemens_coefficient = 0.3
|
||||
max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
slowdown = 1.5
|
||||
|
||||
/obj/item/clothing/suit/space/changeling/armored/Initialize(mapload)
|
||||
. = ..()
|
||||
if(ismob(loc))
|
||||
loc.visible_message(span_warning("[loc.name]\'s flesh turns black, quickly transforming into a hard, chitinous mass!"),
|
||||
span_warning("We harden our flesh, creating a suit of armor!"),
|
||||
span_warningplain("You hear organic matter ripping and tearing!"))
|
||||
|
||||
/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"
|
||||
armor = list(melee = 75, bullet = 60, laser = 60,energy = 60, bomb = 60, bio = 0, rad = 0)
|
||||
siemens_coefficient = 0.3
|
||||
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
|
||||
/obj/item/clothing/shoes/magboots/changeling/armored
|
||||
desc = "A tough, hard mass of chitin, with long talons for digging into terrain."
|
||||
name = "chitinous talons"
|
||||
icon_state = "lingarmor"
|
||||
actions_types = list(/datum/action/item_action/toggle_talons)
|
||||
|
||||
/obj/item/clothing/gloves/combat/changeling //Combined insulated/fireproof gloves
|
||||
name = "chitinous gauntlets"
|
||||
desc = "Very resilient gauntlets made out of black chitin. It looks very durable, and can probably resist electrical shock in addition to the elements."
|
||||
icon_state = "ling"
|
||||
armor = list(melee = 75, bullet = 60, laser = 60,energy = 60, bomb = 60, bio = 0, rad = 0) //No idea if glove armor gets checked
|
||||
siemens_coefficient = 0
|
||||
|
||||
/obj/item/clothing/shoes/boots/combat/changeling //Noslips
|
||||
name = "chitinous boots"
|
||||
desc = "Footwear made out of a hard, black chitinous material. The bottoms of these appear to have spikes that can protrude or extract itself into and out \
|
||||
of the floor at will, granting the wearer stability."
|
||||
icon_state = "lingarmor"
|
||||
armor = list(melee = 75, bullet = 60, laser = 70,energy = 60, bomb = 60, bio = 0, rad = 0)
|
||||
siemens_coefficient = 0.3
|
||||
min_cold_protection_temperature = SHOE_MIN_COLD_PROTECTION_TEMPERATURE
|
||||
max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
@@ -1,37 +0,0 @@
|
||||
//Augmented Eyesight: Gives you thermal vision. Also, higher 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 thermal vision. It may be toggled on or off. We will become more vulnerable to flash-based devices while active."
|
||||
ability_icon_state = "ling_augmented_eyesight"
|
||||
genomecost = 2
|
||||
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
|
||||
|
||||
var/mob/living/carbon/human/C = src
|
||||
|
||||
changeling.thermal_sight = !changeling.thermal_sight
|
||||
|
||||
var/active = changeling.thermal_sight
|
||||
|
||||
if(active)
|
||||
src.mind.changeling.chem_charges -= 5
|
||||
to_chat(C, span_notice("We feel a minute twitch in our eyes, and a hidden layer to the world is revealed."))
|
||||
C.add_modifier(/datum/modifier/changeling/thermal_sight, 0, src)
|
||||
// C.permanent_sight_flags |= SEE_MOBS
|
||||
// C.dna.species.invis_sight = SEE_INVISIBLE_MINIMUM
|
||||
else
|
||||
to_chat(C, span_notice("Our vision dulls."))
|
||||
C.remove_modifiers_of_type(/datum/modifier/changeling/thermal_sight)
|
||||
// C.permanent_sight_flags &= ~SEE_MOBS
|
||||
// C.dna.species.invis_sight = initial(user.dna.species.invis_sight)
|
||||
return 1
|
||||
@@ -1,213 +0,0 @@
|
||||
/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. \
|
||||
Shocking someone costs ten chemicals per use."
|
||||
enhancedtext = "Shocking biologicals without grabbing only requires five chemicals, and has more disabling power."
|
||||
ability_icon_state = "ling_bioelectrogenesis"
|
||||
genomecost = 2
|
||||
verbpath = /mob/living/carbon/human/proc/changeling_bioelectrogenesis
|
||||
|
||||
//Recharge whatever's in our hand, or shock people.
|
||||
/mob/living/carbon/human/proc/changeling_bioelectrogenesis()
|
||||
set category = "Changeling"
|
||||
set name = "Bioelectrogenesis (20 + 10/shock)"
|
||||
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(src.mind.changeling.recursive_enhancement)
|
||||
if(changeling_generic_weapon(/obj/item/electric_hand/efficent,0))
|
||||
to_chat(src, span_notice("We will shock others more efficently."))
|
||||
return 1
|
||||
else
|
||||
if(changeling_generic_weapon(/obj/item/electric_hand,0)) //Chemical cost is handled in the equip proc.
|
||||
return 1
|
||||
return 0
|
||||
|
||||
else
|
||||
// Handle glove conductivity.
|
||||
var/obj/item/clothing/gloves/gloves = src.gloves
|
||||
var/siemens = 1
|
||||
if(gloves)
|
||||
siemens = gloves.siemens_coefficient
|
||||
|
||||
//If we're grabbing someone, electrocute them.
|
||||
if(istype(held_item,/obj/item/grab))
|
||||
var/obj/item/grab/G = held_item
|
||||
if(G.affecting)
|
||||
G.affecting.electrocute_act(10 * siemens, src, 1.0, BP_TORSO, 0)
|
||||
var/agony = 80 * siemens //Does more than if hit with an electric hand, since grabbing is slower.
|
||||
G.affecting.stun_effect_act(0, agony, BP_TORSO, src)
|
||||
|
||||
add_attack_logs(src,G.affecting,"Changeling shocked")
|
||||
|
||||
if(siemens)
|
||||
visible_message(span_warning("Arcs of electricity strike [G.affecting]!"),
|
||||
span_warning("Our hand channels raw electricity into [G.affecting]."),
|
||||
span_warningplain("You hear sparks!"))
|
||||
else
|
||||
to_chat(src, span_warning("Our gloves block us from shocking \the [G.affecting]."))
|
||||
src.mind.changeling.chem_charges -= 10
|
||||
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/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/cell/cell in held_item.contents)
|
||||
L.Add(cell)
|
||||
|
||||
//Now for the actual recharging.
|
||||
for(var/obj/item/cell/cell in L)
|
||||
visible_message(span_warning("Some sparks fall out from \the [src.name]\'s [held_item]!"),
|
||||
span_warning("Our hand channels raw electricity into \the [held_item]."),
|
||||
span_warningplain("You hear sparks!"))
|
||||
var/i = 10
|
||||
if(siemens)
|
||||
while(i)
|
||||
cell.charge += 100 * siemens //This should be a nice compromise between recharging guns and other batteries.
|
||||
if(cell.charge > cell.maxcharge)
|
||||
cell.charge = cell.maxcharge
|
||||
break
|
||||
if(siemens)
|
||||
var/T = get_turf(src)
|
||||
new /obj/effect/effect/sparks(T)
|
||||
held_item.update_icon()
|
||||
i--
|
||||
sleep(1 SECOND)
|
||||
success = 1
|
||||
if(success == 0) //If we couldn't do anything with the ability, don't deduct the chemicals.
|
||||
to_chat(src, span_warning("We are unable to affect \the [held_item]."))
|
||||
else
|
||||
src.mind.changeling.chem_charges -= 10
|
||||
return success
|
||||
|
||||
/obj/item/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"
|
||||
show_examine = FALSE
|
||||
|
||||
var/shock_cost = 10
|
||||
var/agony_amount = 60
|
||||
var/electrocute_amount = 10
|
||||
|
||||
/obj/item/electric_hand/efficent
|
||||
shock_cost = 5
|
||||
agony_amount = 80
|
||||
electrocute_amount = 20
|
||||
|
||||
/obj/item/electric_hand/Initialize(mapload)
|
||||
. = ..()
|
||||
if(ismob(loc))
|
||||
visible_message(span_warning("Electrical arcs form around [loc.name]\'s hand!"),
|
||||
span_warning("We store a charge of electricity in our hand."),
|
||||
span_warningplain("You hear crackling electricity!"))
|
||||
var/T = get_turf(src)
|
||||
new /obj/effect/effect/sparks(T)
|
||||
|
||||
/obj/item/electric_hand/dropped(mob/user)
|
||||
..()
|
||||
spawn(1)
|
||||
if(src)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/electric_hand/afterattack(var/atom/target, var/mob/living/carbon/human/user, proximity)
|
||||
if(!target)
|
||||
return
|
||||
if(!proximity)
|
||||
return
|
||||
|
||||
// Handle glove conductivity.
|
||||
var/obj/item/clothing/gloves/gloves = user.gloves
|
||||
var/siemens = 1
|
||||
if(gloves)
|
||||
siemens = gloves.siemens_coefficient
|
||||
|
||||
//Excuse the copypasta.
|
||||
if(istype(target,/mob/living/carbon))
|
||||
var/mob/living/carbon/C = target
|
||||
|
||||
if(user.mind.changeling.chem_charges < shock_cost)
|
||||
to_chat(src, span_warning("We require more chemicals to electrocute [C]!"))
|
||||
return 0
|
||||
|
||||
C.electrocute_act(electrocute_amount * siemens,src,1.0,BP_TORSO)
|
||||
C.stun_effect_act(0, agony_amount * siemens, BP_TORSO, src)
|
||||
|
||||
add_attack_logs(user,C,"Shocked with [src]")
|
||||
|
||||
if(siemens)
|
||||
visible_message(span_warning("Arcs of electricity strike [C]!"),
|
||||
span_warning("Our hand channels raw electricity into [C]"),
|
||||
span_warningplain("You hear sparks!"))
|
||||
else
|
||||
to_chat(src, span_warning("Our gloves block us from shocking \the [C]."))
|
||||
//qdel(src) //Since we're no longer a one hit stun, we need to stick around.
|
||||
user.mind.changeling.chem_charges -= shock_cost
|
||||
return 1
|
||||
|
||||
else if(istype(target,/mob/living/silicon))
|
||||
var/mob/living/silicon/S = target
|
||||
|
||||
if(user.mind.changeling.chem_charges < 10)
|
||||
to_chat(src, span_warning("We require more chemicals to electrocute [S]!"))
|
||||
return 0
|
||||
|
||||
S.electrocute_act(60,src,0.75) //If only they had surge protectors.
|
||||
if(siemens)
|
||||
visible_message(span_warning("Arcs of electricity strike [S]!"),
|
||||
span_warning("Our hand channels raw electricity into [S]"),
|
||||
span_warningplain("You hear sparks!"))
|
||||
to_chat(S, span_danger("Warning: Electrical surge detected!"))
|
||||
//qdel(src)
|
||||
user.mind.changeling.chem_charges -= 10
|
||||
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/cell/cell in T.contents)
|
||||
visible_message(span_warning("Some sparks fall out from \the [target]!"),
|
||||
span_warning("Our hand channels raw electricity into \the [target]."),
|
||||
span_warningplain("You hear sparks!"))
|
||||
var/i = 10
|
||||
if(siemens)
|
||||
while(i)
|
||||
cell.charge += 100 * siemens //This should be a nice compromise between recharging guns and other batteries.
|
||||
if(cell.charge > cell.maxcharge)
|
||||
cell.charge = cell.maxcharge
|
||||
break //No point making sparks if the cell's full.
|
||||
// if(!Adjacent(T))
|
||||
// break
|
||||
if(siemens)
|
||||
var/Turf = get_turf(src)
|
||||
new /obj/effect/effect/sparks(Turf)
|
||||
T.update_icon()
|
||||
i--
|
||||
sleep(1 SECOND)
|
||||
success = 1
|
||||
break
|
||||
if(success == 0)
|
||||
to_chat(src, span_warning("We are unable to affect \the [target]."))
|
||||
else
|
||||
qdel(src)
|
||||
return 1
|
||||
@@ -1,30 +0,0 @@
|
||||
/datum/power/changeling/blind_sting
|
||||
name = "Blind Sting"
|
||||
desc = "We silently sting a human, completely blinding them for a short time."
|
||||
enhancedtext = "Duration is extended."
|
||||
ability_icon_state = "ling_sting_blind"
|
||||
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
|
||||
add_attack_logs(src,T,"Blind sting (changeling)")
|
||||
to_chat(T, span_danger("Your eyes burn horrificly!"))
|
||||
T.disabilities |= NEARSIGHTED
|
||||
var/duration = 300
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
duration = duration + 150
|
||||
to_chat(src, span_notice("They will be deprived of sight for longer."))
|
||||
spawn(duration)
|
||||
T.disabilities &= ~NEARSIGHTED
|
||||
T.Blind(10)
|
||||
T.eye_blurry = 20
|
||||
feedback_add_details("changeling_powers","BS")
|
||||
return 1
|
||||
@@ -1,31 +0,0 @@
|
||||
/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."
|
||||
enhancedtext = "The range is extended to five tiles."
|
||||
ability_icon_state = "ling_sting_boost_range"
|
||||
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
|
||||
to_chat(src, span_notice("Your throat adjusts to launch the sting."))
|
||||
var/range = 2
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
range = range + 3
|
||||
to_chat(src, span_notice("We can fire our next sting from five squares away."))
|
||||
changeling.sting_range = range
|
||||
remove_verb(src, /mob/proc/changeling_boost_range)
|
||||
spawn(5)
|
||||
add_verb(src, /mob/proc/changeling_boost_range)
|
||||
feedback_add_details("changeling_powers","RS")
|
||||
return 1
|
||||
@@ -1,31 +0,0 @@
|
||||
/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. Has \
|
||||
a three minute cooldown between uses."
|
||||
enhancedtext = "Increases the amount of chemicals injected."
|
||||
ability_icon_state = "ling_sting_cryo"
|
||||
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(20,/mob/proc/changeling_cryo_sting)
|
||||
if(!T)
|
||||
return 0
|
||||
add_attack_logs(src,T,"Cryo sting (changeling)")
|
||||
var/inject_amount = 10
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
inject_amount = inject_amount * 1.5
|
||||
to_chat(src, span_notice("We inject extra chemicals."))
|
||||
if(T.reagents)
|
||||
T.reagents.add_reagent(REAGENT_ID_CRYOTOXIN, inject_amount)
|
||||
feedback_add_details("changeling_powers","CS")
|
||||
remove_verb(src, /mob/proc/changeling_cryo_sting)
|
||||
spawn(3 MINUTES)
|
||||
to_chat(src, span_notice("Our cryogenic string is ready to be used once more."))
|
||||
add_verb(src, /mob/proc/changeling_cryo_sting)
|
||||
return 1
|
||||
@@ -1,26 +0,0 @@
|
||||
/datum/power/changeling/darksight
|
||||
name = "Dark Sight"
|
||||
desc = "We change the composition of our eyes, banishing the shadows from our vision."
|
||||
helptext = "We will be able to see in the dark."
|
||||
ability_icon_state = "ling_augmented_eyesight"
|
||||
genomecost = 0
|
||||
verbpath = /mob/proc/changeling_darksight
|
||||
|
||||
/mob/proc/changeling_darksight()
|
||||
set category = "Changeling"
|
||||
set name = "Toggle Darkvision"
|
||||
set desc = "We are able see in the dark."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(0,0,100,UNCONSCIOUS)
|
||||
if(!changeling)
|
||||
return 0
|
||||
|
||||
if(istype(src,/mob/living/carbon))
|
||||
var/mob/living/carbon/C = src
|
||||
C.seedarkness = !C.seedarkness
|
||||
if(C.seedarkness)
|
||||
to_chat(C, span_notice("We allow the shadows to return."))
|
||||
else
|
||||
to_chat(C, span_notice("We no longer need light to see."))
|
||||
|
||||
return 0
|
||||
@@ -1,27 +0,0 @@
|
||||
/datum/power/changeling/deaf_sting
|
||||
name = "Deaf Sting"
|
||||
desc = "We silently sting a human, completely deafening them for a short time."
|
||||
enhancedtext = "Deafness duration is extended."
|
||||
ability_icon_state = "ling_sting_deafen"
|
||||
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
|
||||
add_attack_logs(src,T,"Deaf sting (changeling)")
|
||||
var/duration = 300
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
duration = duration + 100
|
||||
to_chat(src, span_notice("They will be unable to hear for a little longer."))
|
||||
to_chat(T, span_danger("Your ears pop and begin ringing loudly!"))
|
||||
T.sdisabilities |= DEAF
|
||||
spawn(duration) T.sdisabilities &= ~DEAF
|
||||
feedback_add_details("changeling_powers","DS")
|
||||
return 1
|
||||
@@ -1,23 +0,0 @@
|
||||
/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."
|
||||
ability_icon_state = "ling_sting_death"
|
||||
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
|
||||
add_attack_logs(src,T,"Death sting (changeling)")
|
||||
to_chat(T, span_danger("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(REAGENT_ID_LEXORIN, 40)
|
||||
feedback_add_details("changeling_powers","DTHS")
|
||||
return 1
|
||||
@@ -1,41 +0,0 @@
|
||||
/datum/power/changeling/delayed_toxic_sting
|
||||
name = "Delayed Toxic Sting"
|
||||
desc = "We silently sting a biological, causing a significant amount of toxins after a few minutes, allowing us to not \
|
||||
implicate ourselves."
|
||||
helptext = "The toxin takes effect in about two minutes. Multiple applications within the two minutes will not cause increased toxicity."
|
||||
enhancedtext = "The toxic damage is doubled."
|
||||
ability_icon_state = "ling_sting_del_toxin"
|
||||
genomecost = 1
|
||||
verbpath = /mob/proc/changeling_delayed_toxic_sting
|
||||
|
||||
/datum/modifier/delayed_toxin_sting
|
||||
name = "delayed toxin injection"
|
||||
hidden = TRUE
|
||||
stacks = MODIFIER_STACK_FORBID
|
||||
on_expired_text = span_danger("You feel a burning sensation flowing through your veins!")
|
||||
|
||||
/datum/modifier/delayed_toxin_sting/on_expire()
|
||||
holder.adjustToxLoss(rand(20, 30))
|
||||
|
||||
/datum/modifier/delayed_toxin_sting/strong/on_expire()
|
||||
holder.adjustToxLoss(rand(40, 60))
|
||||
|
||||
/mob/proc/changeling_delayed_toxic_sting()
|
||||
set category = "Changeling"
|
||||
set name = "Delayed Toxic Sting (20)"
|
||||
set desc = "Injects the target with a toxin that will take effect after a few minutes."
|
||||
|
||||
var/mob/living/carbon/T = changeling_sting(20,/mob/proc/changeling_delayed_toxic_sting)
|
||||
if(!T)
|
||||
return 0
|
||||
add_attack_logs(src,T,"Delayed toxic sting (chagneling)")
|
||||
var/type_to_give = /datum/modifier/delayed_toxin_sting
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
type_to_give = /datum/modifier/delayed_toxin_sting/strong
|
||||
to_chat(src, span_notice("Our toxin will be extra potent, when it strikes."))
|
||||
|
||||
T.add_modifier(type_to_give, 2 MINUTES)
|
||||
|
||||
|
||||
feedback_add_details("changeling_powers","DTS")
|
||||
return 1
|
||||
@@ -1,36 +0,0 @@
|
||||
/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."
|
||||
ability_icon_state = "ling_digital_camo"
|
||||
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)
|
||||
to_chat(C, span_notice("We return to normal."))
|
||||
else
|
||||
to_chat(C, span_notice("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)
|
||||
|
||||
remove_verb(src, /mob/proc/changeling_digitalcamo)
|
||||
spawn(5)
|
||||
add_verb(src, /mob/proc/changeling_digitalcamo)
|
||||
feedback_add_details("changeling_powers","CAM")
|
||||
return 1
|
||||
@@ -1,98 +0,0 @@
|
||||
/datum/power/changeling/electric_lockpick
|
||||
name = "Electric Lockpick"
|
||||
desc = "We discreetly evolve a finger to be able to send a small electric charge. \
|
||||
We can open most electrical locks, but it will be obvious when we do so."
|
||||
helptext = "Use the ability, then touch something that utilizes an electrical locking system, to open it. Each use costs 10 chemicals."
|
||||
ability_icon_state = "ling_electric_lockpick"
|
||||
genomecost = 3
|
||||
verbpath = /mob/proc/changeling_electric_lockpick
|
||||
|
||||
//Emag-lite
|
||||
/mob/proc/changeling_electric_lockpick()
|
||||
set category = "Changeling"
|
||||
set name = "Electric Lockpick (5 + 10/use)"
|
||||
set desc = "Bruteforces open most electrical locking systems, at 10 chemicals per use."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(5,0,100,CONSCIOUS)
|
||||
|
||||
var/obj/held_item = get_active_hand()
|
||||
|
||||
if(!changeling)
|
||||
return 0
|
||||
|
||||
if(held_item == null)
|
||||
if(changeling_generic_weapon(/obj/item/finger_lockpick,0,5)) //Chemical cost is handled in the equip proc.
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/finger_lockpick
|
||||
name = "finger lockpick"
|
||||
desc = "This finger appears to be an organic datajack."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "electric_hand"
|
||||
show_examine = FALSE
|
||||
|
||||
/obj/item/finger_lockpick/Initialize(mapload)
|
||||
. = ..()
|
||||
if(ismob(loc))
|
||||
to_chat(loc, span_notice("We shape our finger to fit inside electronics, and are ready to force them open."))
|
||||
|
||||
/obj/item/finger_lockpick/dropped(mob/user)
|
||||
..()
|
||||
to_chat(user, span_notice("We discreetly shape our finger back to a less suspicious form."))
|
||||
spawn(1)
|
||||
if(src)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/finger_lockpick/afterattack(var/atom/target, var/mob/living/user, proximity)
|
||||
if(!target)
|
||||
return
|
||||
if(!proximity)
|
||||
return
|
||||
if(!user.mind.changeling)
|
||||
return
|
||||
|
||||
var/datum/changeling/ling_datum = user.mind.changeling
|
||||
|
||||
if(ling_datum.chem_charges < 10)
|
||||
to_chat(user, span_warning("We require more chemicals to do that."))
|
||||
return
|
||||
|
||||
//Airlocks require an ugly block of code, but we don't want to just call emag_act(), since we don't want to break airlocks forever.
|
||||
if(istype(target,/obj/machinery/door))
|
||||
var/obj/machinery/door/door = target
|
||||
to_chat(user, span_notice("We send an electrical pulse up our finger, and into \the [target], attempting to open it."))
|
||||
|
||||
if(door.density && door.operable())
|
||||
door.do_animate("spark")
|
||||
sleep(6)
|
||||
//More typechecks, because windoors can't be locked. Fun.
|
||||
if(istype(target,/obj/machinery/door/airlock))
|
||||
var/obj/machinery/door/airlock/airlock = target
|
||||
|
||||
if(airlock.locked) //Check if we're bolted.
|
||||
airlock.unlock()
|
||||
to_chat(user, span_notice("We've unlocked \the [airlock]. Another pulse is requried to open it."))
|
||||
else //We're not bolted, so open the door already.
|
||||
airlock.open()
|
||||
to_chat(user, span_notice("We've opened \the [airlock]."))
|
||||
else
|
||||
door.open() //If we're a windoor, open the windoor.
|
||||
to_chat(user, span_notice("We've opened \the [door]."))
|
||||
else //Probably broken or no power.
|
||||
to_chat(user, span_warning("The door does not respond to the pulse."))
|
||||
door.add_fingerprint(user)
|
||||
log_and_message_admins("finger-lockpicked \an [door].")
|
||||
ling_datum.chem_charges -= 10
|
||||
return 1
|
||||
|
||||
else if(istype(target,/obj/)) //This should catch everything else we might miss, without a million typechecks.
|
||||
var/obj/O = target
|
||||
to_chat(user, span_notice("We send an electrical pulse up our finger, and into \the [O]."))
|
||||
O.add_fingerprint(user)
|
||||
O.emag_act(1,user,src)
|
||||
log_and_message_admins("finger-lockpicked \an [O].")
|
||||
ling_datum.chem_charges -= 10
|
||||
|
||||
return 1
|
||||
return 0
|
||||
@@ -1,22 +0,0 @@
|
||||
/datum/power/changeling/endoarmor
|
||||
name = "Endoarmor"
|
||||
desc = "We grow hard plating underneath our skin, making us more resilient to harm by increasing our maximum health potential by 50 points."
|
||||
helptext = "Our maximum health is increased by 50 points."
|
||||
genomecost = 1
|
||||
isVerb = 0
|
||||
verbpath = /mob/proc/changeling_endoarmor
|
||||
|
||||
/datum/modifier/endoarmor
|
||||
name = "endoarmor"
|
||||
desc = "We have hard plating underneath our skin, making us more durable."
|
||||
|
||||
on_created_text = span_notice("We feel protective plating form underneath our skin.")
|
||||
on_expired_text = span_notice("Our protective armor underneath our skin fades as we absorb it.")
|
||||
max_health_flat = 50
|
||||
|
||||
/mob/proc/changeling_endoarmor()
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
H.add_modifier(/datum/modifier/endoarmor)
|
||||
// H.maxHealth += 50
|
||||
return 1
|
||||
@@ -1,46 +0,0 @@
|
||||
/datum/power/changeling/enfeebling_string
|
||||
name = "Enfeebling String"
|
||||
desc = "We sting a biological with a potent toxin that will greatly weaken them for a short period of time."
|
||||
helptext = "Lowers the maximum health of the victim for a few minutes, as well as making them more frail and weak. This sting will also warn them of this."
|
||||
enhancedtext = "Maximum health and outgoing melee damage is lowered further. Incoming damage is increased."
|
||||
ability_icon_state = "ling_sting_enfeeble"
|
||||
genomecost = 1
|
||||
verbpath = /mob/proc/changeling_enfeebling_string
|
||||
|
||||
/datum/modifier/enfeeble
|
||||
name = "enfeebled"
|
||||
desc = "You feel really weak and frail for some reason."
|
||||
|
||||
stacks = MODIFIER_STACK_EXTEND
|
||||
max_health_percent = 0.7
|
||||
outgoing_melee_damage_percent = 0.75
|
||||
incoming_damage_percent = 1.1
|
||||
on_created_text = span_danger("You feel a small prick and you feel extremly weak!")
|
||||
on_expired_text = span_notice("You no longer feel extremly weak.")
|
||||
|
||||
// Now YOU'RE the Teshari!
|
||||
/datum/modifier/enfeeble/strong
|
||||
max_health_percent = 0.5
|
||||
outgoing_melee_damage_percent = 0.5
|
||||
incoming_damage_percent = 1.35
|
||||
|
||||
/mob/proc/changeling_enfeebling_string()
|
||||
set category = "Changeling"
|
||||
set name = "Enfeebling Sting (30)"
|
||||
set desc = "Reduces the maximum health of a victim for a few minutes.."
|
||||
|
||||
var/mob/living/carbon/T = changeling_sting(30,/mob/proc/changeling_enfeebling_string)
|
||||
if(!T)
|
||||
return 0
|
||||
if(ishuman(T))
|
||||
var/mob/living/carbon/human/H = T
|
||||
|
||||
add_attack_logs(src,T,"Enfeebling sting (changeling)")
|
||||
|
||||
var/type_to_give = /datum/modifier/enfeeble
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
type_to_give = /datum/modifier/enfeeble/strong
|
||||
to_chat(src, span_notice("We make them extremely weak."))
|
||||
H.add_modifier(type_to_give, 2 MINUTES)
|
||||
feedback_add_details("changeling_powers","ES")
|
||||
return 1
|
||||
@@ -1,13 +0,0 @@
|
||||
/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 30 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 += 30
|
||||
src.mind.changeling.chem_recharge_rate *= 2
|
||||
return 1
|
||||
@@ -1,33 +0,0 @@
|
||||
/datum/power/changeling/enrage
|
||||
name = "Enrage"
|
||||
desc = "We evolve modifications to our mind and body, allowing us to call on intense periods of rage for our benefit."
|
||||
helptext = "Berserks us, giving massive bonuses to fighting in close quarters for thirty seconds, and losing the ability to \
|
||||
be accurate at ranged while active. Afterwards, we will suffer extreme amounts of exhaustion for a period of two minutes, \
|
||||
during which we will be much weaker and slower than before. We cannot berserk again while exhausted. This ability requires \
|
||||
a significant amount of nutrition to use, and cannot be used if too hungry. Using this ability will end most forms of disables."
|
||||
enhancedtext = "The length of exhaustion after berserking is reduced to one minute, from two, and requires half as much nutrition."
|
||||
ability_icon_state = "ling_berserk"
|
||||
genomecost = 2
|
||||
allowduringlesserform = 1
|
||||
verbpath = /mob/living/proc/changeling_berserk
|
||||
|
||||
// Makes the ling very upset.
|
||||
/mob/living/proc/changeling_berserk()
|
||||
set category = "Changeling"
|
||||
set name = "Enrage (30)"
|
||||
set desc = "Causes you to go Berserk."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(30,0,100)
|
||||
if(!changeling)
|
||||
return 0
|
||||
|
||||
var/modifier_to_use = /datum/modifier/berserk/changeling
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
modifier_to_use = /datum/modifier/berserk/changeling/recursive
|
||||
to_chat(src, span_notice("We optimize our levels of anger, which will avoid excessive stress on ourselves."))
|
||||
|
||||
if(add_modifier(modifier_to_use, 30 SECONDS))
|
||||
changeling.chem_charges -= 30
|
||||
|
||||
feedback_add_details("changeling_powers","EN")
|
||||
return 1
|
||||
@@ -1,67 +0,0 @@
|
||||
/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."
|
||||
enhancedtext = "Immunity from most disabling effects for 30 seconds."
|
||||
ability_icon_state = "ling_epinepherine_overdose"
|
||||
genomecost = 2
|
||||
verbpath = /mob/proc/changeling_epinephrine_overdose
|
||||
|
||||
/datum/modifier/unstoppable
|
||||
name = "unstoppable"
|
||||
desc = "We feel limitless amounts of energy surge in our veins. Nothing can stop us!"
|
||||
|
||||
stacks = MODIFIER_STACK_EXTEND
|
||||
on_created_text = span_notice("We feel unstoppable!")
|
||||
on_expired_text = span_warning("We feel our newfound energy fade...")
|
||||
disable_duration_percent = 0
|
||||
|
||||
//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
|
||||
to_chat(C, span_notice("Energy rushes through us. [C.lying ? "We arise." : ""]"))
|
||||
C.set_stat(CONSCIOUS)
|
||||
C.SetParalysis(0)
|
||||
C.SetStunned(0)
|
||||
C.SetWeakened(0)
|
||||
C.lying = 0
|
||||
C.update_canmove()
|
||||
// C.reagents.add_reagent(REAGENT_ID_TOXIN, 10)
|
||||
C.reagents.add_reagent("epinephrine", 20)
|
||||
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
C.add_modifier(/datum/modifier/unstoppable, 30 SECONDS)
|
||||
|
||||
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.
|
||||
wiki_flag = WIKI_SPOILER
|
||||
|
||||
/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
|
||||
@@ -1,67 +0,0 @@
|
||||
/datum/power/changeling/escape_restraints
|
||||
name = "Escape Restraints"
|
||||
desc = "We evolve more complex joints"
|
||||
helptext = "We can instantly escape from most restraints and bindings, but we cannot do it often."
|
||||
enhancedtext = "More frequent escapes."
|
||||
ability_icon_state = "ling_escape_restraints"
|
||||
genomecost = 2
|
||||
verbpath = /mob/proc/changeling_escape_restraints
|
||||
|
||||
//Escape Cuffs. By design this does not escape from straight jackets
|
||||
/mob/proc/changeling_escape_restraints()
|
||||
set category = "Changeling"
|
||||
set name = "Escape Restraints (40)"
|
||||
set desc = "Removes handcuffs and legcuffs instantly."
|
||||
|
||||
var/escape_cooldown = 5 MINUTES //This is used later to prevent spamming
|
||||
var/mob/living/carbon/human/C = src
|
||||
var/datum/changeling/changeling = changeling_power(40,0,100,CONSCIOUS)
|
||||
if(!changeling)
|
||||
return 0
|
||||
if(world.time < changeling.next_escape)
|
||||
to_chat(src, span_warning("We are still recovering from our last escape..."))
|
||||
return 0
|
||||
if(!(C.handcuffed || C.legcuffed || istype(C.wear_suit,/obj/item/clothing/suit/straight_jacket))) // No need to waste chems if there's nothing to break out of
|
||||
to_chat(C, span_warning("We are are not restrained in a way we can escape..."))
|
||||
return 0
|
||||
|
||||
changeling.chem_charges -= 40
|
||||
|
||||
to_chat(C,span_notice("We contort our extremities and slip our cuffs."))
|
||||
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
if(C.handcuffed)
|
||||
var/obj/item/W = C.handcuffed
|
||||
C.handcuffed = null
|
||||
if(C.buckled && C.buckled.buckle_require_restraints)
|
||||
C.buckled.unbuckle_mob()
|
||||
C.update_handcuffed()
|
||||
if (C.client)
|
||||
C.client.screen -= W
|
||||
W.forceMove(C.loc)
|
||||
W.dropped(C)
|
||||
if(W)
|
||||
W.layer = initial(W.layer)
|
||||
if(C.legcuffed)
|
||||
var/obj/item/W = C.legcuffed
|
||||
C.legcuffed = null
|
||||
C.update_inv_legcuffed()
|
||||
if(C.client)
|
||||
C.client.screen -= W
|
||||
W.forceMove(C.loc)
|
||||
W.dropped(C)
|
||||
if(W)
|
||||
W.layer = initial(W.layer)
|
||||
if(istype(C.wear_suit, /obj/item/clothing/suit/straight_jacket))
|
||||
var/obj/item/clothing/suit/straight_jacket/SJ = C.wear_suit
|
||||
SJ.forceMove(C.loc)
|
||||
SJ.dropped(C)
|
||||
C.wear_suit = null
|
||||
escape_cooldown *= 1.5 // Straight jackets are tedious compared to cuffs.
|
||||
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
escape_cooldown *= 0.5
|
||||
|
||||
changeling.next_escape = world.time + escape_cooldown //And now we set the timer
|
||||
|
||||
feedback_add_details("changeling_powers","ESR")
|
||||
return 1
|
||||
@@ -1,45 +0,0 @@
|
||||
/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."
|
||||
ability_icon_state = "ling_sting_extract"
|
||||
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
|
||||
|
||||
if(!istype(T) || T.isSynthetic())
|
||||
to_chat(src, span_warning("\The [T] is not compatible with our biology."))
|
||||
return 0
|
||||
|
||||
if(T.species.flags & (NO_DNA|NO_SLEEVE))
|
||||
to_chat(src, span_warning("We do not know how to parse this creature's DNA!"))
|
||||
return 0
|
||||
|
||||
if(HUSK in T.mutations)
|
||||
to_chat(src, span_warning("This creature's DNA is ruined beyond useability!"))
|
||||
return 0
|
||||
|
||||
add_attack_logs(src,T,"DNA extraction sting (changeling)")
|
||||
|
||||
var/saved_dna = T.dna.Clone() /// Prevent transforming bugginess.
|
||||
var/datum/absorbed_dna/newDNA = new(T.real_name, saved_dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts, T.modifiers)
|
||||
absorbDNA(newDNA)
|
||||
|
||||
feedback_add_details("changeling_powers","ED")
|
||||
return 1
|
||||
@@ -1,291 +0,0 @@
|
||||
var/global/list/changeling_fabricated_clothing = list(
|
||||
"w_uniform" = /obj/item/clothing/under/chameleon/changeling,
|
||||
"head" = /obj/item/clothing/head/chameleon/changeling,
|
||||
"wear_suit" = /obj/item/clothing/suit/chameleon/changeling,
|
||||
"shoes" = /obj/item/clothing/shoes/chameleon/changeling,
|
||||
"gloves" = /obj/item/clothing/gloves/chameleon/changeling,
|
||||
"wear_mask" = /obj/item/clothing/mask/chameleon/changeling,
|
||||
"glasses" = /obj/item/clothing/glasses/chameleon/changeling,
|
||||
"back" = /obj/item/storage/backpack/chameleon/changeling,
|
||||
"belt" = /obj/item/storage/belt/chameleon/changeling,
|
||||
"wear_id" = /obj/item/card/id/syndicate/changeling
|
||||
)
|
||||
|
||||
/datum/power/changeling/fabricate_clothing
|
||||
name = "Fabricate Clothing"
|
||||
desc = "We reform our flesh to resemble various cloths, leathers, and other materials, allowing us to quickly create a disguise. \
|
||||
We cannot be relieved of this clothing by others."
|
||||
helptext = "The disguise we create offers no defensive ability. Each equipment slot that is empty will be filled with fabricated equipment. \
|
||||
To remove our new fabricated clothing, use this ability again."
|
||||
ability_icon_state = "ling_fabricate_clothing"
|
||||
genomecost = 1
|
||||
verbpath = /mob/proc/changeling_fabricate_clothing
|
||||
|
||||
//Grows biological versions of chameleon clothes.
|
||||
/mob/proc/changeling_fabricate_clothing()
|
||||
set category = "Changeling"
|
||||
set name = "Fabricate Clothing (10)"
|
||||
|
||||
if(changeling_generic_equip_all_slots(changeling_fabricated_clothing, cost = 10))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/under/chameleon/changeling
|
||||
name = "malformed flesh"
|
||||
icon_state = "lingchameleon"
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_uniforms.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_uniforms.dmi',
|
||||
)
|
||||
item_state = "lingchameleon"
|
||||
worn_state = "lingchameleon"
|
||||
desc = "The flesh all around us has grown a new layer of cells that can shift appearance and create a biological fabric that cannot be distinguished from \
|
||||
ordinary cloth, allowing us to make ourselves appear to wear almost anything."
|
||||
origin_tech = list() //The base chameleon items have origin technology, which we will inherit if we don't null out this variable.
|
||||
canremove = FALSE //Since this is essentially flesh impersonating clothes, tearing someone's skin off as if it were clothing isn't possible.
|
||||
|
||||
/obj/item/clothing/under/chameleon/changeling/emp_act(severity) //As these are purely organic, EMP does nothing to them.
|
||||
return
|
||||
|
||||
/obj/item/clothing/under/chameleon/changeling/verb/shred() //Remove individual pieces if needed.
|
||||
set name = "Shred Jumpsuit"
|
||||
set category = "Chameleon Items"
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/H = loc
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
visible_message(span_warning("[H] tears off [src]!"),
|
||||
span_notice("We remove [src]."))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/head/chameleon/changeling
|
||||
name = "malformed head"
|
||||
icon_state = "lingchameleon"
|
||||
desc = "Our head is swelled with a large quanity of rapidly shifting skin cells. We can reform our head to resemble various hats and \
|
||||
helmets that biologicals are so fond of wearing."
|
||||
origin_tech = list()
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/clothing/head/chameleon/changeling/emp_act(severity)
|
||||
return
|
||||
|
||||
/obj/item/clothing/head/chameleon/changeling/verb/shred() //The copypasta is real.
|
||||
set name = "Shred Helmet"
|
||||
set category = "Chameleon Items"
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/H = loc
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
visible_message(span_warning("[H] tears off [src]!"),
|
||||
span_notice("We remove [src]."))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/suit/chameleon/changeling
|
||||
name = "chitinous chest"
|
||||
icon_state = "lingchameleon"
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_suits.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_suits.dmi',
|
||||
)
|
||||
item_state = "armor"
|
||||
desc = "The cells in our chest are rapidly shifting, ready to reform into material that can resemble most pieces of clothing."
|
||||
origin_tech = list()
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/clothing/suit/chameleon/changeling/emp_act(severity)
|
||||
return
|
||||
|
||||
/obj/item/clothing/suit/chameleon/changeling/verb/shred()
|
||||
set name = "Shred Suit"
|
||||
set category = "Chameleon Items"
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/H = loc
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
visible_message(span_warning("[H] tears off [src]!"),
|
||||
span_notice("We remove [src]."))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/shoes/chameleon/changeling
|
||||
name = "malformed feet"
|
||||
icon_state = "lingchameleon"
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_shoes.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_shoes.dmi',
|
||||
)
|
||||
item_state = "black"
|
||||
desc = "Our feet are overlayed with another layer of flesh and bone on top. We can reform our feet to resemble various boots and shoes."
|
||||
origin_tech = list()
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/clothing/shoes/chameleon/changeling/emp_act()
|
||||
return
|
||||
|
||||
/obj/item/clothing/shoes/chameleon/changeling/verb/shred()
|
||||
set name = "Shred Shoes"
|
||||
set category = "Chameleon Items"
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/H = loc
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
visible_message(span_warning("[H] tears off [src]!"),
|
||||
span_notice("We remove [src]."))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/storage/backpack/chameleon/changeling
|
||||
name = "backpack"
|
||||
icon_state = "backpack"
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_storage.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_storage.dmi',
|
||||
)
|
||||
item_state = "backpack"
|
||||
desc = "A large pouch imbedded in our back, it can shift form to resemble many common backpacks that other biologicals are fond of using."
|
||||
origin_tech = list()
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/storage/backpack/chameleon/changeling/emp_act()
|
||||
return
|
||||
|
||||
/obj/item/storage/backpack/chameleon/changeling/verb/shred()
|
||||
set name = "Shred Backpack"
|
||||
set category = "Chameleon Items"
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/H = loc
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
visible_message(span_warning("[H] tears off [src]!"),
|
||||
span_notice("We remove [src]."))
|
||||
for(var/atom/movable/AM in src.contents) //Dump whatever's in the bag before deleting.
|
||||
AM.forceMove(get_turf(loc))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/gloves/chameleon/changeling
|
||||
name = "malformed hands"
|
||||
icon_state = "ling"
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_gloves.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_gloves.dmi',
|
||||
)
|
||||
item_state = "ling"
|
||||
desc = "Our hands have a second layer of flesh on top. We can reform our hands to resemble a large variety of fabrics and materials that biologicals \
|
||||
tend to wear on their hands. Remember that these won't protect your hands from harm."
|
||||
origin_tech = list()
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/clothing/gloves/chameleon/changeling/emp_act()
|
||||
return
|
||||
|
||||
/obj/item/clothing/gloves/chameleon/changeling/verb/shred()
|
||||
set name = "Shred Gloves"
|
||||
set category = "Chameleon Items"
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/H = loc
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
visible_message(span_warning("[H] tears off [src]!"),
|
||||
span_notice("We remove [src]."))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/mask/chameleon/changeling
|
||||
name = "chitin visor"
|
||||
icon_state = "lingchameleon"
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_masks.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_masks.dmi',
|
||||
)
|
||||
item_state = "gas_alt"
|
||||
desc = "A transparent visor of brittle chitin covers our face. We can reform it to resemble various masks that biologicals use. It can also utilize internal \
|
||||
tanks.."
|
||||
origin_tech = list()
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/clothing/mask/chameleon/changeling/emp_act()
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/chameleon/changeling/verb/shred()
|
||||
set name = "Shred Mask"
|
||||
set category = "Chameleon Items"
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/H = loc
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
visible_message(span_warning("[H] tears off [src]!"),
|
||||
span_notice("We remove [src]."))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/glasses/chameleon/changeling
|
||||
name = "chitin goggles"
|
||||
icon_state = "lingchameleon"
|
||||
item_state = "glasses"
|
||||
desc = "A transparent piece of eyewear made out of brittle chitin. We can reform it to resemble various glasses and goggles."
|
||||
origin_tech = list()
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/clothing/glasses/chameleon/changeling/emp_act()
|
||||
return
|
||||
|
||||
/obj/item/clothing/glasses/chameleon/changeling/verb/shred()
|
||||
set name = "Shred Glasses"
|
||||
set category = "Chameleon Items"
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/H = loc
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
visible_message(span_warning("[H] tears off [src]!"),
|
||||
span_notice("We remove [src]."))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/storage/belt/chameleon/changeling
|
||||
name = "waist pouch"
|
||||
desc = "We can store objects in this, as well as shift it's appearance, so that it resembles various common belts."
|
||||
icon_state = "lingchameleon"
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_storage.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_storage.dmi',
|
||||
)
|
||||
item_state = "utility"
|
||||
origin_tech = list()
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/storage/belt/chameleon/changeling/emp_act()
|
||||
return
|
||||
|
||||
/obj/item/storage/belt/chameleon/changeling/verb/shred()
|
||||
set name = "Shred Belt"
|
||||
set category = "Chameleon Items"
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/H = loc
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
visible_message(span_warning("[H] tears off [src]!"),
|
||||
span_notice("We remove [src]."))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/card/id/syndicate/changeling
|
||||
name = "chitinous card"
|
||||
desc = "A card that we can reform to resemble identification cards. Due to the nature of the material this is made of, it cannot store any access codes."
|
||||
icon_state = "changeling"
|
||||
assignment = "Harvester"
|
||||
origin_tech = list()
|
||||
electronic_warfare = 1 //The lack of RFID stuff makes it hard for AIs to track, I guess. *handwaves*
|
||||
registered_user = null
|
||||
access = null
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/card/id/syndicate/changeling/Initialize(mapload)
|
||||
. = ..()
|
||||
if(ismob(loc))
|
||||
registered_user = loc
|
||||
|
||||
/obj/item/card/id/syndicate/changeling/Initialize(mapload)
|
||||
. = ..()
|
||||
access = null
|
||||
|
||||
/obj/item/card/id/syndicate/changeling/verb/shred()
|
||||
set name = "Shred ID Card"
|
||||
set category = "Chameleon Items"
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/H = loc
|
||||
playsound(src, 'sound/effects/splat.ogg', 30, 1)
|
||||
visible_message(span_warning("[H] tears off [src]!"),
|
||||
span_notice("We remove [src]."))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/card/id/syndicate/changeling/Click() //Since we can't hold it in our hands, and attack_hand() doesn't work if it in inventory...
|
||||
if(!registered_user)
|
||||
registered_user = usr
|
||||
usr.set_id_info(src)
|
||||
tgui_interact(registered_user)
|
||||
..()
|
||||
@@ -1,53 +0,0 @@
|
||||
/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."
|
||||
ability_icon_state = "ling_regenerative_stasis"
|
||||
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(CHANGELING_STASIS_COST,1,100,DEAD)
|
||||
if(!changeling)
|
||||
return
|
||||
|
||||
var/mob/living/carbon/C = src
|
||||
|
||||
if(changeling.max_geneticpoints < 0) //Absorbed by another ling
|
||||
to_chat(src, span_danger("We have no genomes, not even our own, and cannot regenerate."))
|
||||
return 0
|
||||
|
||||
if(!C.stat && tgui_alert(src, "Are we sure we wish to regenerate? We will appear to be dead while doing so.","Revival",list("Yes","No")) != "Yes")
|
||||
return
|
||||
to_chat(C, span_notice("We will attempt to regenerate our form."))
|
||||
|
||||
C.update_canmove()
|
||||
C.remove_changeling_powers()
|
||||
changeling.chem_charges -= CHANGELING_STASIS_COST
|
||||
|
||||
if(C.suiciding)
|
||||
C.suiciding = 0
|
||||
|
||||
if(C.does_not_breathe)
|
||||
C.does_not_breathe = 0 //This means they don't autoheal the oxy damage from the next step
|
||||
|
||||
if(C.stat != DEAD)
|
||||
C.adjustOxyLoss(C.getMaxHealth() * 2)
|
||||
|
||||
C.forbid_seeing_deadchat = TRUE
|
||||
|
||||
spawn(rand(2 MINUTES, 4 MINUTES))
|
||||
//The ling will now be able to choose when to revive
|
||||
add_verb(src, /mob/proc/changeling_revive)
|
||||
|
||||
new /obj/changeling_revive_holder(src)
|
||||
|
||||
to_chat(src, span_notice(span_giant("We are ready to rise. Use the <b>Revive</b> verb when you are ready.")))
|
||||
|
||||
feedback_add_details("changeling_powers","FD")
|
||||
return 1
|
||||
@@ -1,41 +0,0 @@
|
||||
/datum/power/changeling/fleshmend
|
||||
name = "Fleshmend"
|
||||
desc = "Begins a slow regeneration of our form. Does not effect stuns or chemicals."
|
||||
helptext = "Can be used while unconscious."
|
||||
enhancedtext = "Healing is twice as effective."
|
||||
ability_icon_state = "ling_fleshmend"
|
||||
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
|
||||
var/heal_amount = 2
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
heal_amount = heal_amount * 2
|
||||
to_chat(src, span_notice("We will heal much faster."))
|
||||
|
||||
spawn(0)
|
||||
to_chat(src, span_notice("We begin to heal ourselves."))
|
||||
for(var/i = 0, i<50,i++)
|
||||
if(C)
|
||||
C.adjustBruteLoss(-heal_amount)
|
||||
C.adjustOxyLoss(-heal_amount)
|
||||
C.adjustFireLoss(-heal_amount)
|
||||
sleep(1 SECOND)
|
||||
|
||||
remove_verb(src, /mob/proc/changeling_fleshmend)
|
||||
spawn(50 SECONDS)
|
||||
to_chat(src, span_notice("Our regeneration has slowed to normal levels."))
|
||||
add_verb(src, /mob/proc/changeling_fleshmend)
|
||||
feedback_add_details("changeling_powers","FM")
|
||||
return 1
|
||||
@@ -1,80 +0,0 @@
|
||||
// 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
|
||||
make_hud_button = 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
|
||||
make_hud_button = 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/absorbed_dna/DNA in changeling.absorbed_dna)
|
||||
if(!(DNA in hivemind_bank))
|
||||
names += DNA.name
|
||||
|
||||
if(names.len <= 0)
|
||||
to_chat(src, span_notice("The airwaves already have all of our DNA."))
|
||||
return
|
||||
|
||||
var/S = tgui_input_list(src, "Select a DNA to channel:", "Channel DNA", names)
|
||||
if(!S) return
|
||||
|
||||
var/datum/absorbed_dna/chosen_dna = changeling.GetDNA(S)
|
||||
if(!chosen_dna)
|
||||
return
|
||||
|
||||
changeling.chem_charges -= 10
|
||||
hivemind_bank += chosen_dna
|
||||
to_chat(src, span_notice("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/absorbed_dna/DNA in hivemind_bank)
|
||||
if(!(DNA in changeling.absorbed_dna))
|
||||
names[DNA.name] = DNA
|
||||
|
||||
if(names.len <= 0)
|
||||
to_chat(src, span_notice("There's no new DNA to absorb from the air."))
|
||||
return
|
||||
|
||||
var/S = tgui_input_list(src, "Select a DNA to absorb:", "Absorb DNA", names)
|
||||
if(!S) return
|
||||
var/datum/absorbed_dna/chosen_dna = names[S]
|
||||
if(!chosen_dna)
|
||||
return
|
||||
|
||||
changeling.chem_charges -= 20
|
||||
absorbDNA(chosen_dna)
|
||||
to_chat(src, span_notice("We absorb the DNA of [S] from the air."))
|
||||
feedback_add_details("changeling_powers","HD")
|
||||
return 1
|
||||
@@ -1,114 +0,0 @@
|
||||
/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())
|
||||
to_chat(src, span_warning("We cannot perform this ability at the present time!"))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = src
|
||||
|
||||
if(!istype(H) || !H.species.primitive_form)
|
||||
to_chat(src, span_warning("We cannot perform this ability in this form!"))
|
||||
return
|
||||
|
||||
changeling.chem_charges--
|
||||
H.remove_changeling_powers()
|
||||
H.visible_message(span_warning("[H] transforms!"))
|
||||
changeling.geneticdamage = 30
|
||||
to_chat(H, span_warning("Our genes cry out!"))
|
||||
var/list/implants = list() //Try to preserve implants.
|
||||
for(var/obj/item/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 = tgui_input_list(src, "Select the target DNA:", "Target DNA", 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(span_warning("[C] transforms!"))
|
||||
qdel_swap(C.dna, chosen_dna.Clone())
|
||||
|
||||
var/list/implants = list()
|
||||
for (var/obj/item/implant/I in C) //Still preserving implants
|
||||
implants += I
|
||||
|
||||
C.transforming = 1
|
||||
C.canmove = 0
|
||||
C.icon = null
|
||||
C.cut_overlays()
|
||||
C.invisibility = INVISIBILITY_ABSTRACT
|
||||
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
|
||||
qdel_swap(O.dna, C.dna.Clone())
|
||||
QDEL_NULL(C.dna)
|
||||
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.set_stat(C.stat)
|
||||
for (var/obj/item/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
|
||||
@@ -1,20 +0,0 @@
|
||||
//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
|
||||
add_attack_logs(src,T,"Hallucination sting (changeling)")
|
||||
spawn(rand(300,600))
|
||||
if(T) T.hallucination += 400
|
||||
feedback_add_details("changeling_powers","HS")
|
||||
return 1
|
||||
@@ -1,41 +0,0 @@
|
||||
/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"
|
||||
ability_icon_state = "ling_mimic_voice"
|
||||
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 = ""
|
||||
to_chat(src, span_notice("We return our vocal glands to their original location."))
|
||||
return
|
||||
|
||||
var/mimic_voice = sanitize(tgui_input_text(src, "Enter a name to mimic.", "Mimic Voice", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(!mimic_voice)
|
||||
return
|
||||
|
||||
changeling.mimicing = mimic_voice
|
||||
|
||||
to_chat(src, span_notice("We shape our glands to take the voice of <b>[mimic_voice]</b>, this will stop us from regenerating chemicals while active."))
|
||||
to_chat(src, span_notice("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 = ""
|
||||
@@ -1,55 +0,0 @@
|
||||
/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. This will also purge any reagents inside ourselves, both harmful and beneficial."
|
||||
enhancedtext = "We heal more toxins."
|
||||
ability_icon_state = "ling_anatomic_panacea"
|
||||
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
|
||||
|
||||
to_chat(src, span_notice("We cleanse impurities from our form."))
|
||||
|
||||
var/mob/living/carbon/human/C = src
|
||||
|
||||
C.radiation = 0
|
||||
C.sdisabilities = 0
|
||||
C.disabilities = 0
|
||||
C.reagents.clear_reagents()
|
||||
C.ingested.clear_reagents()
|
||||
|
||||
|
||||
var/heal_amount = 5
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
heal_amount = heal_amount * 2
|
||||
to_chat(src, span_notice("We will heal much faster."))
|
||||
|
||||
for(var/i = 0, i<10,i++)
|
||||
if(C)
|
||||
C.adjustToxLoss(-heal_amount)
|
||||
sleep(10)
|
||||
|
||||
for(var/obj/item/organ/external/E in C.organs)
|
||||
var/obj/item/organ/external/G = E
|
||||
if(G.germ_level)
|
||||
var/germ_heal = heal_amount * 100
|
||||
G.germ_level = min(0, G.germ_level - germ_heal)
|
||||
|
||||
for(var/obj/item/organ/internal/I in C.internal_organs)
|
||||
var/obj/item/organ/internal/G = I
|
||||
if(G.germ_level)
|
||||
var/germ_heal = heal_amount * 100
|
||||
G.germ_level = min(0, G.germ_level - germ_heal)
|
||||
|
||||
feedback_add_details("changeling_powers","AP")
|
||||
return 1
|
||||
@@ -1,19 +0,0 @@
|
||||
/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
|
||||
add_attack_logs(src,T,"Paralysis sting (changeling)")
|
||||
to_chat(T, span_danger("Your muscles begin to painfully tighten."))
|
||||
T.Weaken(20)
|
||||
feedback_add_details("changeling_powers","PS")
|
||||
return 1
|
||||
@@ -1,55 +0,0 @@
|
||||
/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."
|
||||
enhancedtext = "Healing increased to heal up to maximum health."
|
||||
ability_icon_state = "ling_rapid_regeneration"
|
||||
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
|
||||
var/healing_amount = 40
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
healing_amount = C.getMaxHealth()
|
||||
to_chat(src, span_notice("We completely heal ourselves."))
|
||||
spawn(0)
|
||||
C.adjustBruteLoss(-healing_amount)
|
||||
C.adjustFireLoss(-healing_amount)
|
||||
C.adjustOxyLoss(-healing_amount)
|
||||
C.adjustCloneLoss(-healing_amount)
|
||||
C.adjustBrainLoss(-healing_amount)
|
||||
C.restore_blood()
|
||||
C.species.create_organs(C)
|
||||
C.restore_all_organs()
|
||||
C.blinded = 0
|
||||
C.SetBlinded(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(span_warning("With a sickening squish, [src] reforms their whole body, casting their old parts on the floor!"),
|
||||
span_notice("We reform our body. We are whole once more."),
|
||||
span_warningplain("You hear organic matter ripping and tearing!"))
|
||||
|
||||
feedback_add_details("changeling_powers","RR")
|
||||
return 1
|
||||
@@ -1,24 +0,0 @@
|
||||
/datum/power/changeling/recursive_enhancement
|
||||
name = "Recursive Enhancement"
|
||||
desc = "We cause our abilities to have increased or additional effects."
|
||||
helptext = "To check the effects for each ability, check the blue text underneath the ability in the evolution menu."
|
||||
ability_icon_state = "ling_recursive_enhancement"
|
||||
genomecost = 3
|
||||
verbpath = /mob/proc/changeling_recursive_enhancement
|
||||
|
||||
//Increases macimum chemical storage
|
||||
/mob/proc/changeling_recursive_enhancement()
|
||||
set category = "Changeling"
|
||||
set name = "Recursive Enhancement"
|
||||
set desc = "Empowers our abilities."
|
||||
var/datum/changeling/changeling = changeling_power(0,0,100,UNCONSCIOUS)
|
||||
if(!changeling)
|
||||
return 0
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
to_chat(src, span_warning("We will no longer empower our abilities."))
|
||||
src.mind.changeling.recursive_enhancement = 0
|
||||
return 0
|
||||
to_chat(src, span_notice("We empower ourselves. Our abilities will now be extra potent."))
|
||||
src.mind.changeling.recursive_enhancement = 1
|
||||
feedback_add_details("changeling_powers","RE")
|
||||
return 1
|
||||
@@ -1,32 +0,0 @@
|
||||
/mob/proc/changeling_respec()
|
||||
set category = "Changeling"
|
||||
set name = "Re-adapt"
|
||||
set desc = "Allows us to refund our purchased abilities."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(0,0,100)
|
||||
if(!changeling)
|
||||
return
|
||||
if(src.mind.changeling.readapts <= 0)
|
||||
to_chat(src, span_warning("We must first absorb another compatible creature!"))
|
||||
src.mind.changeling.readapts = 0
|
||||
return
|
||||
|
||||
src.remove_changeling_powers() //First, remove the verbs.
|
||||
var/datum/changeling/ling_datum = src.mind.changeling
|
||||
ling_datum.readapts--
|
||||
ling_datum.purchased_powers = list() //Then wipe all the powers we bought.
|
||||
ling_datum.geneticpoints = ling_datum.max_geneticpoints //Now refund our points to the maximum.
|
||||
ling_datum.chem_recharge_rate = 0.5 //If glands were bought, revert that upgrade.
|
||||
ling_datum.thermal_sight = FALSE
|
||||
src.mind.changeling.recursive_enhancement = 0 //Ensures this is cleared
|
||||
|
||||
ling_datum.chem_storage = 50
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
// H.does_not_breathe = 0 //If self respiration was bought, revert that too.
|
||||
H.remove_modifiers_of_type(/datum/modifier/endoarmor) //Revert endoarmor too.
|
||||
src.make_changeling() //And give back our freebies.
|
||||
|
||||
to_chat(src, span_notice("We have removed our evolutions from this form, and are now ready to readapt."))
|
||||
|
||||
ling_datum.purchased_powers_history.Add("Re-adapt (Reset to [ling_datum.max_geneticpoints])")
|
||||
@@ -1,109 +0,0 @@
|
||||
//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(changeling.max_geneticpoints < 0) //Absorbed by another ling
|
||||
to_chat(src, span_danger("You have no genomes, not even your own, and cannot revive."))
|
||||
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()
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = src
|
||||
H.species.create_organs(H)
|
||||
H.restore_all_organs(ignore_prosthetic_prefs=1) //Covers things like fractures and other things not covered by the above.
|
||||
H.restore_blood()
|
||||
H.mutations.Remove(HUSK)
|
||||
H.status_flags &= ~DISFIGURED
|
||||
H.update_icons_body()
|
||||
for(var/limb in H.organs_by_name)
|
||||
var/obj/item/organ/external/current_limb = H.organs_by_name[limb]
|
||||
if(current_limb)
|
||||
current_limb.relocate()
|
||||
current_limb.open = 0
|
||||
|
||||
BITSET(H.hud_updateflag, HEALTH_HUD)
|
||||
BITSET(H.hud_updateflag, STATUS_HUD)
|
||||
BITSET(H.hud_updateflag, LIFE_HUD)
|
||||
|
||||
if(H.handcuffed)
|
||||
var/obj/item/W = H.handcuffed
|
||||
H.handcuffed = null
|
||||
if(H.buckled && H.buckled.buckle_require_restraints)
|
||||
H.buckled.unbuckle_mob()
|
||||
H.update_handcuffed()
|
||||
if (H.client)
|
||||
H.client.screen -= W
|
||||
W.forceMove(H.loc)
|
||||
W.dropped(H)
|
||||
if(W)
|
||||
W.layer = initial(W.layer)
|
||||
if(H.legcuffed)
|
||||
var/obj/item/W = H.legcuffed
|
||||
H.legcuffed = null
|
||||
H.update_inv_legcuffed()
|
||||
if(H.client)
|
||||
H.client.screen -= W
|
||||
W.forceMove(H.loc)
|
||||
W.dropped(H)
|
||||
if(W)
|
||||
W.layer = initial(W.layer)
|
||||
if(istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket))
|
||||
var/obj/item/clothing/suit/straight_jacket/SJ = H.wear_suit
|
||||
SJ.forceMove(H.loc)
|
||||
SJ.dropped(H)
|
||||
H.wear_suit = null
|
||||
|
||||
C.halloss = 0
|
||||
C.shock_stage = 0 //Pain
|
||||
to_chat(C, span_notice("We have regenerated."))
|
||||
C.update_canmove()
|
||||
C.mind.changeling.purchased_powers -= C
|
||||
feedback_add_details("changeling_powers","CR")
|
||||
C.set_stat(CONSCIOUS)
|
||||
C.forbid_seeing_deadchat = FALSE
|
||||
C.timeofdeath = null
|
||||
remove_verb(src, /mob/proc/changeling_revive)
|
||||
// re-add our changeling powers
|
||||
C.make_changeling()
|
||||
|
||||
return 1
|
||||
|
||||
//Revive from revival stasis, but one level removed, as the tab refuses to update. Placed in its own tab to avoid hyper-exploding the original tab through the same name being used.
|
||||
|
||||
/obj/changeling_revive_holder
|
||||
name = "strange object"
|
||||
desc = "Please report this object's existence to the dev team! You shouldn't see it."
|
||||
mouse_opacity = FALSE
|
||||
alpha = 1
|
||||
|
||||
/obj/changeling_revive_holder/verb/ling_revive()
|
||||
set src = usr.contents
|
||||
set category = "Regenerate"
|
||||
set name = "Revive"
|
||||
set desc = "We are ready to revive ourselves on command."
|
||||
|
||||
if(iscarbon(usr))
|
||||
var/mob/living/carbon/C = usr
|
||||
C.changeling_revive()
|
||||
|
||||
qdel(src)
|
||||
@@ -1,31 +0,0 @@
|
||||
/datum/power/changeling/self_respiration
|
||||
name = "Self Respiration"
|
||||
desc = "We evolve our body to no longer require drawing oxygen from the atmosphere."
|
||||
helptext = "We will no longer require internals, and we cannot inhale any gas, including harmful ones."
|
||||
ability_icon_state = "ling_toggle_breath"
|
||||
genomecost = 0
|
||||
verbpath = /mob/proc/changeling_self_respiration
|
||||
|
||||
//No breathing required
|
||||
/mob/proc/changeling_self_respiration()
|
||||
set category = "Changeling"
|
||||
set name = "Toggle Breathing"
|
||||
set desc = "We choose whether or not to breathe."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(0,0,100,UNCONSCIOUS)
|
||||
if(!changeling)
|
||||
return 0
|
||||
|
||||
if(istype(src,/mob/living/carbon))
|
||||
var/mob/living/carbon/C = src
|
||||
if(C.suiciding)
|
||||
to_chat(src, "You're committing suicide, this isn't going to work.")
|
||||
return 0
|
||||
if(C.does_not_breathe == 0)
|
||||
C.does_not_breathe = 1
|
||||
to_chat(src, span_notice("We stop breathing, as we no longer need to."))
|
||||
return 1
|
||||
else
|
||||
C.does_not_breathe = 0
|
||||
to_chat(src, span_notice("We resume breathing, as we now need to again."))
|
||||
return 0
|
||||
@@ -1,142 +0,0 @@
|
||||
/datum/power/changeling/resonant_shriek
|
||||
name = "Resonant Shriek"
|
||||
desc = "Our lungs and vocal cords shift, allowing us to briefly emit a noise that deafens and confuses the weak-minded."
|
||||
helptext = "Lights are blown, organics are disoriented, and synthetics act as if they were flashed."
|
||||
enhancedtext = "Range is doubled."
|
||||
ability_icon_state = "ling_resonant_shriek"
|
||||
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."
|
||||
helptext = "Creates a moderate sized EMP."
|
||||
enhancedtext = "Range is doubled."
|
||||
ability_icon_state = "ling_dissonant_shriek"
|
||||
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 organics, blows out nearby lights, and overloads synthetics' sensors."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(20,0,100,CONSCIOUS)
|
||||
if(!changeling) return 0
|
||||
|
||||
if(is_muzzled())
|
||||
to_chat(src, span_danger("Mmmf mrrfff!"))
|
||||
return 0
|
||||
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(H.silent)
|
||||
to_chat(src, span_danger("You can't speak!"))
|
||||
return 0
|
||||
|
||||
if(world.time < (changeling.last_shriek + 10 SECONDS) )
|
||||
to_chat(src, span_warning("We are still recovering from our last shriek..."))
|
||||
return 0
|
||||
|
||||
if(!isturf(loc))
|
||||
to_chat(src, span_warning("Shrieking here would be a bad idea."))
|
||||
return 0
|
||||
|
||||
src.break_cloak() //No more invisible shrieking
|
||||
|
||||
changeling.chem_charges -= 20
|
||||
var/range = 4
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
range = range * 2
|
||||
to_chat(src, span_notice("We are extra loud."))
|
||||
|
||||
visible_message(span_notice("[src] appears to shout."))
|
||||
var/list/affected = list()
|
||||
for(var/mob/living/M in range(range, src))
|
||||
if(iscarbon(M))
|
||||
if(!M.mind || !M.mind.changeling)
|
||||
if(M.get_ear_protection() >= 2)
|
||||
continue
|
||||
to_chat(M, span_danger("You hear an extremely loud screeching sound! It \
|
||||
[pick("confuses","confounds","perturbs","befuddles","dazes","unsettles","disorients")] you."))
|
||||
M.adjustEarDamage(0,30)
|
||||
M.Confuse(20)
|
||||
M << sound('sound/effects/screech.ogg')
|
||||
affected += M
|
||||
else
|
||||
if(M != src)
|
||||
to_chat(M, span_notice("You hear a familiar screech from nearby. It has no effect on you."))
|
||||
M << sound('sound/effects/screech.ogg')
|
||||
|
||||
if(issilicon(M))
|
||||
M << sound('sound/weapons/flash.ogg')
|
||||
to_chat(M, span_notice("Auditory input overloaded. Reinitializing..."))
|
||||
M.Weaken(rand(5,10))
|
||||
affected += M
|
||||
|
||||
for(var/obj/machinery/light/L in range(range, src))
|
||||
L.on = 1
|
||||
L.broken()
|
||||
|
||||
changeling.last_shriek = world.time
|
||||
|
||||
add_attack_logs(src,affected,"Used resonant shriek")
|
||||
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
|
||||
|
||||
if(is_muzzled())
|
||||
to_chat(src, span_danger("Mmmf mrrfff!"))
|
||||
return 0
|
||||
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(H.silent)
|
||||
to_chat(src, span_danger("You can't speak!"))
|
||||
return 0
|
||||
|
||||
if(world.time < (changeling.last_shriek + 10 SECONDS) )
|
||||
to_chat(src, span_warning("We are still recovering from our last shriek..."))
|
||||
return 0
|
||||
|
||||
if(!isturf(loc))
|
||||
to_chat(src, span_warning("Shrieking here would be a bad idea."))
|
||||
return 0
|
||||
|
||||
src.break_cloak() //No more invisible shrieking
|
||||
|
||||
changeling.chem_charges -= 20
|
||||
|
||||
var/range_heavy = 1
|
||||
var/range_med = 2
|
||||
var/range_light = 4
|
||||
var/range_long = 6
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
range_heavy = range_heavy * 2
|
||||
range_med = range_med * 2
|
||||
range_light = range_light * 2
|
||||
range_long = range_long * 2
|
||||
to_chat(src, span_notice("We are extra loud."))
|
||||
src.mind.changeling.recursive_enhancement = 0
|
||||
|
||||
visible_message(span_notice("[src] appears to shout."))
|
||||
|
||||
add_attack_logs(src,null,"Use dissonant shriek")
|
||||
|
||||
for(var/obj/machinery/light/L in range(5, src))
|
||||
L.on = 1
|
||||
L.broken()
|
||||
empulse(get_turf(src), range_heavy, range_light, 1)
|
||||
|
||||
changeling.last_shriek = world.time
|
||||
|
||||
return 1
|
||||
@@ -1,25 +0,0 @@
|
||||
/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."
|
||||
enhancedtext = "Silence duration is extended."
|
||||
ability_icon_state = "ling_sting_mute"
|
||||
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
|
||||
add_attack_logs(src,T,"Silence sting (changeling)")
|
||||
var/duration = 30
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
duration = duration + 10
|
||||
to_chat(src, span_notice("They will be unable to cry out in fear for a little longer."))
|
||||
T.silent += duration
|
||||
feedback_add_details("changeling_powers","SS")
|
||||
return 1
|
||||
@@ -1,65 +0,0 @@
|
||||
/datum/power/changeling/transform
|
||||
name = "Transform"
|
||||
desc = "We take on the appearance and voice of one we have absorbed."
|
||||
ability_icon_state = "ling_transform"
|
||||
genomecost = 0
|
||||
verbpath = /mob/proc/changeling_transform
|
||||
|
||||
//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
|
||||
|
||||
if(!isturf(loc))
|
||||
to_chat(src, span_warning("Transforming here would be a bad idea."))
|
||||
return 0
|
||||
|
||||
var/list/names = list()
|
||||
for(var/datum/absorbed_dna/DNA in changeling.absorbed_dna)
|
||||
names += "[DNA.name]"
|
||||
|
||||
var/S = tgui_input_list(src, "Select the target DNA:", "Target DNA", names)
|
||||
if(!S) return
|
||||
|
||||
var/datum/absorbed_dna/chosen_dna = changeling.GetDNA(S)
|
||||
if(!chosen_dna)
|
||||
return
|
||||
|
||||
changeling.chem_charges -= 5
|
||||
src.visible_message(span_warning("[src] transforms!"))
|
||||
changeling.geneticdamage = 5
|
||||
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/newSpecies = chosen_dna.speciesName
|
||||
H.set_species(newSpecies)
|
||||
|
||||
qdel_swap(src.dna, chosen_dna.dna.Clone())
|
||||
src.dna.b_type = "AB+" //This is needed to avoid blood rejection bugs. The fact that the blood type might not match up w/ records could be a *FEATURE* too.
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
H.identifying_gender = chosen_dna.identifying_gender
|
||||
H.flavor_texts = chosen_dna.flavour_texts ? chosen_dna.flavour_texts.Copy() : null
|
||||
src.real_name = chosen_dna.name
|
||||
src.UpdateAppearance()
|
||||
domutcheck(src, null)
|
||||
UpdateAppearance()
|
||||
changeling_update_languages(changeling.absorbed_languages)
|
||||
if(chosen_dna.genMods)
|
||||
var/mob/living/carbon/human/self = src
|
||||
for(var/datum/modifier/mod in self.modifiers)
|
||||
self.modifiers.Remove(mod.type)
|
||||
|
||||
for(var/datum/modifier/mod in chosen_dna.genMods)
|
||||
self.modifiers.Add(mod.type)
|
||||
|
||||
remove_verb(src, /mob/proc/changeling_transform)
|
||||
spawn(10)
|
||||
add_verb(src, /mob/proc/changeling_transform)
|
||||
src.regenerate_icons()
|
||||
|
||||
feedback_add_details("changeling_powers","TR")
|
||||
return 1
|
||||
@@ -1,44 +0,0 @@
|
||||
//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."
|
||||
ability_icon_state = "ling_sting_transform"
|
||||
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 = tgui_input_list(src, "Select the target DNA:", "Target DNA", 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)))
|
||||
to_chat(src, span_warning("Our sting appears ineffective against its DNA."))
|
||||
return 0
|
||||
add_attack_logs(src,T,"Transformation sting (changeling)")
|
||||
T.visible_message(span_warning("[T] transforms!"))
|
||||
qdel_swap(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
|
||||
@@ -1,18 +0,0 @@
|
||||
/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
|
||||
add_attack_logs(src,T,"Unfat sting (changeling)")
|
||||
to_chat(T, span_danger("you feel a small prick as stomach churns violently and you become to feel skinnier."))
|
||||
T.adjust_nutrition(-100)
|
||||
feedback_add_details("changeling_powers","US")
|
||||
return 1
|
||||
@@ -1,72 +0,0 @@
|
||||
/datum/power/changeling/visible_camouflage
|
||||
name = "Camouflage"
|
||||
desc = "We rapidly shape the color of our skin and secrete easily reversible dye on our clothes, to blend in with our surroundings. \
|
||||
We are undetectable, so long as we move slowly.(Toggle)"
|
||||
helptext = "Running, and performing most acts will reveal us. Our chemical regeneration is halted while we are hidden."
|
||||
enhancedtext = "Can run while hidden."
|
||||
ability_icon_state = "ling_camoflage"
|
||||
genomecost = 3
|
||||
verbpath = /mob/proc/changeling_visible_camouflage
|
||||
|
||||
//Hide us from anyone who would do us harm.
|
||||
/mob/proc/changeling_visible_camouflage()
|
||||
set category = "Changeling"
|
||||
set name = "Visible Camouflage (10)"
|
||||
set desc = "Turns yourself almost invisible, as long as you move slowly."
|
||||
|
||||
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
|
||||
if(H.mind.changeling.cloaked)
|
||||
H.mind.changeling.cloaked = 0
|
||||
return 1
|
||||
|
||||
//We delay the check, so that people can uncloak without needing 10 chemicals to do so.
|
||||
var/datum/changeling/changeling = changeling_power(10,0,100,CONSCIOUS)
|
||||
|
||||
if(!changeling)
|
||||
return 0
|
||||
changeling.chem_charges -= 10
|
||||
var/old_regen_rate = H.mind.changeling.chem_recharge_rate
|
||||
|
||||
to_chat(H, span_notice("We vanish from sight, and will remain hidden, so long as we move carefully."))
|
||||
H.mind.changeling.cloaked = 1
|
||||
H.mind.changeling.chem_recharge_rate = 0
|
||||
animate(src,alpha = 255, alpha = 10, time = 10)
|
||||
|
||||
var/must_walk = TRUE
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
must_walk = FALSE
|
||||
to_chat(src, span_notice("We may move at our normal speed while hidden."))
|
||||
|
||||
if(must_walk)
|
||||
H.set_m_intent(I_WALK)
|
||||
|
||||
var/remain_cloaked = TRUE
|
||||
while(remain_cloaked) //This loop will keep going until the player uncloaks.
|
||||
sleep(1 SECOND) // Sleep at the start so that if something invalidates a cloak, it will drop immediately after the check and not in one second.
|
||||
|
||||
if(H.m_intent != I_WALK && must_walk) // Moving too fast uncloaks you.
|
||||
remain_cloaked = 0
|
||||
if(!H.mind.changeling.cloaked)
|
||||
remain_cloaked = 0
|
||||
if(H.stat) // Dead or unconscious lings can't stay cloaked.
|
||||
remain_cloaked = 0
|
||||
if(H.incapacitated(INCAPACITATION_DISABLED)) // Stunned lings also can't stay cloaked.
|
||||
remain_cloaked = 0
|
||||
|
||||
if(mind.changeling.chem_recharge_rate != 0) //Without this, there is an exploit that can be done, if one buys engorged chem sacks while cloaked.
|
||||
old_regen_rate += mind.changeling.chem_recharge_rate //Unfortunately, it has to occupy this part of the proc. This fixes it while at the same time
|
||||
mind.changeling.chem_recharge_rate = 0 //making sure nobody loses out on their bonus regeneration after they're done hiding.
|
||||
|
||||
|
||||
|
||||
H.invisibility = initial(invisibility)
|
||||
visible_message(span_warning("[src] suddenly fades in, seemingly from nowhere!"),
|
||||
span_notice("We revert our camouflage, revealing ourselves."))
|
||||
H.set_m_intent(I_RUN)
|
||||
H.mind.changeling.cloaked = 0
|
||||
H.mind.changeling.chem_recharge_rate = old_regen_rate
|
||||
|
||||
animate(src,alpha = 10, alpha = 255, time = 10)
|
||||
@@ -614,7 +614,8 @@ GLOBAL_LIST_EMPTY(all_objectives)
|
||||
n_p ++
|
||||
else if (ticker.current_state == GAME_STATE_PLAYING)
|
||||
for(var/mob/living/carbon/human/P in player_list)
|
||||
if(P.client && !(P.mind.changeling) && P.mind!=owner)
|
||||
var/datum/component/antag/changeling/comp = P.GetComponent(/datum/component/antag/changeling)
|
||||
if(P.client && !(comp) && P.mind!=owner)
|
||||
n_p ++
|
||||
target_amount = min(target_amount, n_p)
|
||||
|
||||
@@ -622,8 +623,10 @@ GLOBAL_LIST_EMPTY(all_objectives)
|
||||
return target_amount
|
||||
|
||||
/datum/objective/absorb/check_completion()
|
||||
if(owner && owner.changeling && owner.changeling.absorbed_dna && (owner.changeling.absorbedcount >= target_amount))
|
||||
return 1
|
||||
if(owner)
|
||||
var/datum/component/antag/changeling/comp = owner.GetComponent(/datum/component/antag/changeling)
|
||||
if(comp && comp.absorbed_dna && (comp.absorbedcount >= target_amount))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user