[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:
CHOMPStation2StaffMirrorBot
2025-07-04 19:54:55 -07:00
committed by GitHub
parent 9feb91ec4c
commit a0c273ce1f
83 changed files with 1385 additions and 1382 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)
..()

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 = ""

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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])")

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)