mirror of
https://github.com/fulpstation/fulpstation.git
synced 2025-12-10 10:01:40 +00:00
Ling datum antag standarization. (#32183)
* Ling datum standarization. * Removal of redundant file * Ok
This commit is contained in:
@@ -282,11 +282,13 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
/mob/living/carbon/MiddleClickOn(atom/A)
|
/mob/living/carbon/MiddleClickOn(atom/A)
|
||||||
if(!src.stat && src.mind && src.mind.changeling && src.mind.changeling.chosen_sting && (iscarbon(A)) && (A != src))
|
if(!stat && mind && iscarbon(A) && A != src)
|
||||||
next_click = world.time + 5
|
var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
mind.changeling.chosen_sting.try_to_sting(src, A)
|
if(C && C.chosen_sting)
|
||||||
else
|
C.chosen_sting.try_to_sting(src,A)
|
||||||
swap_hand()
|
next_click = world.time + 5
|
||||||
|
return
|
||||||
|
swap_hand()
|
||||||
|
|
||||||
/mob/living/simple_animal/drone/MiddleClickOn(atom/A)
|
/mob/living/simple_animal/drone/MiddleClickOn(atom/A)
|
||||||
swap_hand()
|
swap_hand()
|
||||||
@@ -344,11 +346,13 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
/mob/living/carbon/AltClickOn(atom/A)
|
/mob/living/carbon/AltClickOn(atom/A)
|
||||||
if(!src.stat && src.mind && src.mind.changeling && src.mind.changeling.chosen_sting && (iscarbon(A)) && (A != src))
|
if(!stat && mind && iscarbon(A) && A != src)
|
||||||
next_click = world.time + 5
|
var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
mind.changeling.chosen_sting.try_to_sting(src, A)
|
if(C && C.chosen_sting)
|
||||||
else
|
C.chosen_sting.try_to_sting(src,A)
|
||||||
..()
|
next_click = world.time + 5
|
||||||
|
return
|
||||||
|
..()
|
||||||
|
|
||||||
/atom/proc/AltClick(mob/user)
|
/atom/proc/AltClick(mob/user)
|
||||||
SendSignal(COMSIG_CLICK_ALT, user)
|
SendSignal(COMSIG_CLICK_ALT, user)
|
||||||
|
|||||||
483
code/datums/antagonists/changeling.dm
Normal file
483
code/datums/antagonists/changeling.dm
Normal file
@@ -0,0 +1,483 @@
|
|||||||
|
#define LING_FAKEDEATH_TIME 400 //40 seconds
|
||||||
|
#define LING_DEAD_GENETICDAMAGE_HEAL_CAP 50 //The lowest value of geneticdamage handle_changeling() can take it to while dead.
|
||||||
|
#define LING_ABSORB_RECENT_SPEECH 8 //The amount of recent spoken lines to gain on absorbing a mob
|
||||||
|
|
||||||
|
/datum/antagonist/changeling
|
||||||
|
name = "Changeling"
|
||||||
|
job_rank = ROLE_CHANGELING
|
||||||
|
|
||||||
|
var/you_are_greet = TRUE
|
||||||
|
var/give_objectives = TRUE
|
||||||
|
var/list/objectives = list()
|
||||||
|
var/team_mode = FALSE //Should assign team objectives ?
|
||||||
|
|
||||||
|
//Changeling Stuff
|
||||||
|
|
||||||
|
var/list/stored_profiles = list() //list of datum/changelingprofile
|
||||||
|
var/datum/changelingprofile/first_prof = null
|
||||||
|
//var/list/absorbed_dna = list()
|
||||||
|
//var/list/protected_dna = list() //dna that is not lost when capacity is otherwise full
|
||||||
|
var/dna_max = 6 //How many extra DNA strands the changeling can store for transformation.
|
||||||
|
var/absorbedcount = 0
|
||||||
|
var/chem_charges = 20
|
||||||
|
var/chem_storage = 75
|
||||||
|
var/chem_recharge_rate = 1
|
||||||
|
var/chem_recharge_slowdown = 0
|
||||||
|
var/sting_range = 2
|
||||||
|
var/changelingID = "Changeling"
|
||||||
|
var/geneticdamage = 0
|
||||||
|
var/isabsorbing = 0
|
||||||
|
var/islinking = 0
|
||||||
|
var/geneticpoints = 10
|
||||||
|
var/purchasedpowers = list()
|
||||||
|
var/mimicing = ""
|
||||||
|
var/canrespec = 0
|
||||||
|
var/changeling_speak = 0
|
||||||
|
var/datum/dna/chosen_dna
|
||||||
|
var/obj/effect/proc_holder/changeling/sting/chosen_sting
|
||||||
|
var/datum/cellular_emporium/cellular_emporium
|
||||||
|
var/datum/action/innate/cellular_emporium/emporium_action
|
||||||
|
|
||||||
|
// wip stuff
|
||||||
|
var/static/list/all_powers = typecacheof(/obj/effect/proc_holder/changeling,TRUE)
|
||||||
|
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/New()
|
||||||
|
. = ..()
|
||||||
|
generate_name()
|
||||||
|
create_actions()
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/Destroy()
|
||||||
|
QDEL_NULL(cellular_emporium)
|
||||||
|
QDEL_NULL(emporium_action)
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/generate_name()
|
||||||
|
var/honorific
|
||||||
|
if(owner.current.gender == FEMALE)
|
||||||
|
honorific = "Ms."
|
||||||
|
else
|
||||||
|
honorific = "Mr."
|
||||||
|
if(GLOB.possible_changeling_IDs.len)
|
||||||
|
changelingID = pick(GLOB.possible_changeling_IDs)
|
||||||
|
GLOB.possible_changeling_IDs -= changelingID
|
||||||
|
changelingID = "[honorific] [changelingID]"
|
||||||
|
else
|
||||||
|
changelingID = "[honorific] [rand(1,999)]"
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/create_actions()
|
||||||
|
cellular_emporium = new(src)
|
||||||
|
emporium_action = new(cellular_emporium)
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/on_gain()
|
||||||
|
reset_powers()
|
||||||
|
create_initial_profile()
|
||||||
|
if(give_objectives)
|
||||||
|
if(team_mode)
|
||||||
|
forge_team_objectives()
|
||||||
|
forge_objectives()
|
||||||
|
remove_clownmut()
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/on_removal()
|
||||||
|
remove_changeling_powers(FALSE)
|
||||||
|
owner.objectives -= objectives
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/remove_clownmut()
|
||||||
|
if (owner)
|
||||||
|
var/mob/living/carbon/human/H = owner.current
|
||||||
|
if(istype(H) && owner.assigned_role == "Clown")
|
||||||
|
to_chat(H, "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself.")
|
||||||
|
H.dna.remove_mutation(CLOWNMUT)
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/reset_properties()
|
||||||
|
changeling_speak = 0
|
||||||
|
chosen_sting = null
|
||||||
|
geneticpoints = initial(geneticpoints)
|
||||||
|
sting_range = initial(sting_range)
|
||||||
|
chem_storage = initial(chem_storage)
|
||||||
|
chem_recharge_rate = initial(chem_recharge_rate)
|
||||||
|
chem_charges = min(chem_charges, chem_storage)
|
||||||
|
chem_recharge_slowdown = initial(chem_recharge_slowdown)
|
||||||
|
mimicing = ""
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/remove_changeling_powers(keep_free_powers=0)
|
||||||
|
if(ishuman(owner.current) || ismonkey(owner.current))
|
||||||
|
reset_properties()
|
||||||
|
for(var/obj/effect/proc_holder/changeling/p in purchasedpowers)
|
||||||
|
if((p.dna_cost == 0 && keep_free_powers) || p.always_keep)
|
||||||
|
continue
|
||||||
|
purchasedpowers -= p
|
||||||
|
p.on_refund(owner.current)
|
||||||
|
|
||||||
|
//MOVE THIS
|
||||||
|
if(owner.current.hud_used)
|
||||||
|
owner.current.hud_used.lingstingdisplay.icon_state = null
|
||||||
|
owner.current.hud_used.lingstingdisplay.invisibility = INVISIBILITY_ABSTRACT
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/reset_powers()
|
||||||
|
if(purchasedpowers)
|
||||||
|
remove_changeling_powers(TRUE)
|
||||||
|
//Purchase free powers.
|
||||||
|
for(var/path in all_powers)
|
||||||
|
var/obj/effect/proc_holder/changeling/S = new path()
|
||||||
|
if(!S.dna_cost)
|
||||||
|
if(!has_sting(S))
|
||||||
|
purchasedpowers+=S
|
||||||
|
S.on_purchase(owner.current,TRUE)
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/has_sting(obj/effect/proc_holder/changeling/power)
|
||||||
|
for(var/obj/effect/proc_holder/changeling/P in purchasedpowers)
|
||||||
|
if(initial(power.name) == P.name)
|
||||||
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/purchase_power(sting_name)
|
||||||
|
var/obj/effect/proc_holder/changeling/thepower = null
|
||||||
|
|
||||||
|
for(var/path in all_powers)
|
||||||
|
var/obj/effect/proc_holder/changeling/S = path
|
||||||
|
if(initial(S.name) == sting_name)
|
||||||
|
thepower = new path()
|
||||||
|
break
|
||||||
|
|
||||||
|
if(!thepower)
|
||||||
|
to_chat(owner.current, "This is awkward. Changeling power purchase failed, please report this bug to a coder!")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(absorbedcount < thepower.req_dna)
|
||||||
|
to_chat(owner.current, "We lack the energy to evolve this ability!")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(has_sting(thepower))
|
||||||
|
to_chat(owner.current, "We have already evolved this ability!")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(thepower.dna_cost < 0)
|
||||||
|
to_chat(owner.current, "We cannot evolve this ability.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(geneticpoints < thepower.dna_cost)
|
||||||
|
to_chat(owner.current, "We have reached our capacity for abilities.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(owner.current.status_flags & FAKEDEATH)//To avoid potential exploits by buying new powers while in stasis, which clears your verblist.
|
||||||
|
to_chat(owner.current, "We lack the energy to evolve new abilities right now.")
|
||||||
|
return
|
||||||
|
|
||||||
|
geneticpoints -= thepower.dna_cost
|
||||||
|
purchasedpowers += thepower
|
||||||
|
thepower.on_purchase(owner.current)
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/readapt()
|
||||||
|
if(!ishuman(owner.current))
|
||||||
|
to_chat(owner.current, "<span class='danger'>We can't remove our evolutions in this form!</span>")
|
||||||
|
return
|
||||||
|
if(canrespec)
|
||||||
|
to_chat(owner.current, "<span class='notice'>We have removed our evolutions from this form, and are now ready to readapt.</span>")
|
||||||
|
reset_powers()
|
||||||
|
canrespec = 0
|
||||||
|
SSblackbox.add_details("changeling_power_purchase","Readapt")
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
to_chat(owner.current, "<span class='danger'>You lack the power to readapt your evolutions!</span>")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
//Called in life()
|
||||||
|
/datum/antagonist/changeling/proc/regenerate()
|
||||||
|
var/mob/living/carbon/the_ling = owner.current
|
||||||
|
if(istype(the_ling))
|
||||||
|
emporium_action.Grant(the_ling)
|
||||||
|
if(the_ling.stat == DEAD)
|
||||||
|
chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), (chem_storage*0.5))
|
||||||
|
geneticdamage = max(LING_DEAD_GENETICDAMAGE_HEAL_CAP,geneticdamage-1)
|
||||||
|
else //not dead? no chem/geneticdamage caps.
|
||||||
|
chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), chem_storage)
|
||||||
|
geneticdamage = max(0, geneticdamage-1)
|
||||||
|
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/get_dna(dna_owner)
|
||||||
|
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||||
|
if(dna_owner == prof.name)
|
||||||
|
return prof
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/has_dna(datum/dna/tDNA)
|
||||||
|
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||||
|
if(tDNA.is_same_as(prof.dna))
|
||||||
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/can_absorb_dna(mob/living/carbon/human/target, var/verbose=1)
|
||||||
|
var/mob/living/carbon/user = owner.current
|
||||||
|
if(!istype(user))
|
||||||
|
return
|
||||||
|
if(stored_profiles.len)
|
||||||
|
var/datum/changelingprofile/prof = stored_profiles[1]
|
||||||
|
if(prof.dna == user.dna && stored_profiles.len >= dna_max)//If our current DNA is the stalest, we gotta ditch it.
|
||||||
|
if(verbose)
|
||||||
|
to_chat(user, "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>")
|
||||||
|
return
|
||||||
|
if(!target)
|
||||||
|
return
|
||||||
|
if(NO_DNA_COPY in target.dna.species.species_traits)
|
||||||
|
if(verbose)
|
||||||
|
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
|
||||||
|
return
|
||||||
|
if((target.disabilities & NOCLONE) || (target.disabilities & HUSK))
|
||||||
|
if(verbose)
|
||||||
|
to_chat(user, "<span class='warning'>DNA of [target] is ruined beyond usability!</span>")
|
||||||
|
return
|
||||||
|
if(!ishuman(target))//Absorbing monkeys is entirely possible, but it can cause issues with transforming. That's what lesser form is for anyway!
|
||||||
|
if(verbose)
|
||||||
|
to_chat(user, "<span class='warning'>We could gain no benefit from absorbing a lesser creature.</span>")
|
||||||
|
return
|
||||||
|
if(has_dna(target.dna))
|
||||||
|
if(verbose)
|
||||||
|
to_chat(user, "<span class='warning'>We already have this DNA in storage!</span>")
|
||||||
|
return
|
||||||
|
if(!target.has_dna())
|
||||||
|
if(verbose)
|
||||||
|
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
|
||||||
|
return
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/create_profile(mob/living/carbon/human/H, protect = 0)
|
||||||
|
var/datum/changelingprofile/prof = new
|
||||||
|
|
||||||
|
H.dna.real_name = H.real_name //Set this again, just to be sure that it's properly set.
|
||||||
|
var/datum/dna/new_dna = new H.dna.type
|
||||||
|
H.dna.copy_dna(new_dna)
|
||||||
|
prof.dna = new_dna
|
||||||
|
prof.name = H.real_name
|
||||||
|
prof.protected = protect
|
||||||
|
|
||||||
|
prof.underwear = H.underwear
|
||||||
|
prof.undershirt = H.undershirt
|
||||||
|
prof.socks = H.socks
|
||||||
|
|
||||||
|
var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store")
|
||||||
|
for(var/slot in slots)
|
||||||
|
if(slot in H.vars)
|
||||||
|
var/obj/item/I = H.vars[slot]
|
||||||
|
if(!I)
|
||||||
|
continue
|
||||||
|
prof.name_list[slot] = I.name
|
||||||
|
prof.appearance_list[slot] = I.appearance
|
||||||
|
prof.flags_cover_list[slot] = I.flags_cover
|
||||||
|
prof.item_color_list[slot] = I.item_color
|
||||||
|
prof.item_state_list[slot] = I.item_state
|
||||||
|
prof.exists_list[slot] = 1
|
||||||
|
else
|
||||||
|
continue
|
||||||
|
|
||||||
|
return prof
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/add_profile(datum/changelingprofile/prof)
|
||||||
|
if(stored_profiles.len > dna_max)
|
||||||
|
if(!push_out_profile())
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!first_prof)
|
||||||
|
first_prof = prof
|
||||||
|
|
||||||
|
stored_profiles += prof
|
||||||
|
absorbedcount++
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/add_new_profile(mob/living/carbon/human/H, protect = 0)
|
||||||
|
var/datum/changelingprofile/prof = create_profile(H, protect)
|
||||||
|
add_profile(prof)
|
||||||
|
return prof
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/remove_profile(mob/living/carbon/human/H, force = 0)
|
||||||
|
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||||
|
if(H.real_name == prof.name)
|
||||||
|
if(prof.protected && !force)
|
||||||
|
continue
|
||||||
|
stored_profiles -= prof
|
||||||
|
qdel(prof)
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/get_profile_to_remove()
|
||||||
|
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||||
|
if(!prof.protected)
|
||||||
|
return prof
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/push_out_profile()
|
||||||
|
var/datum/changelingprofile/removeprofile = get_profile_to_remove()
|
||||||
|
if(removeprofile)
|
||||||
|
stored_profiles -= removeprofile
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/create_initial_profile()
|
||||||
|
var/mob/living/carbon/C = owner.current //only carbons have dna now, so we have to typecaste
|
||||||
|
if(ishuman(C))
|
||||||
|
add_new_profile(C)
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/apply_innate_effects()
|
||||||
|
//Brains optional.
|
||||||
|
var/mob/living/carbon/C = owner.current
|
||||||
|
if(istype(C))
|
||||||
|
var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN)
|
||||||
|
if(B)
|
||||||
|
B.vital = FALSE
|
||||||
|
B.decoy_override = TRUE
|
||||||
|
update_changeling_icons_added()
|
||||||
|
return
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/remove_innate_effects()
|
||||||
|
update_changeling_icons_removed()
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/greet()
|
||||||
|
if (you_are_greet)
|
||||||
|
to_chat(owner.current, "<span class='boldannounce'>You are [changelingID], a changeling! You have absorbed and taken the form of a human.</span>")
|
||||||
|
to_chat(owner.current, "<span class='boldannounce'>Use say \":g message\" to communicate with your fellow changelings.</span>")
|
||||||
|
to_chat(owner.current, "<b>You must complete the following tasks:</b>")
|
||||||
|
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ling_aler.ogg', 100, FALSE, pressure_affected = FALSE)
|
||||||
|
|
||||||
|
owner.announce_objectives()
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/forge_team_objectives()
|
||||||
|
if(GLOB.changeling_team_objective_type)
|
||||||
|
var/datum/objective/changeling_team_objective/team_objective = new GLOB.changeling_team_objective_type
|
||||||
|
team_objective.owner = owner
|
||||||
|
objectives += team_objective
|
||||||
|
return
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/forge_objectives()
|
||||||
|
//OBJECTIVES - random traitor objectives. Unique objectives "steal brain" and "identity theft".
|
||||||
|
//No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting
|
||||||
|
//If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone
|
||||||
|
|
||||||
|
var/escape_objective_possible = TRUE
|
||||||
|
|
||||||
|
//if there's a team objective, check if it's compatible with escape objectives
|
||||||
|
for(var/datum/objective/changeling_team_objective/CTO in objectives)
|
||||||
|
if(!CTO.escape_objective_compatible)
|
||||||
|
escape_objective_possible = FALSE
|
||||||
|
break
|
||||||
|
|
||||||
|
var/datum/objective/absorb/absorb_objective = new
|
||||||
|
absorb_objective.owner = owner
|
||||||
|
absorb_objective.gen_amount_goal(6, 8)
|
||||||
|
objectives += absorb_objective
|
||||||
|
|
||||||
|
if(prob(60))
|
||||||
|
if(prob(85))
|
||||||
|
var/datum/objective/steal/steal_objective = new
|
||||||
|
steal_objective.owner = owner
|
||||||
|
steal_objective.find_target()
|
||||||
|
objectives += steal_objective
|
||||||
|
else
|
||||||
|
var/datum/objective/download/download_objective = new
|
||||||
|
download_objective.owner = owner
|
||||||
|
download_objective.gen_amount_goal()
|
||||||
|
objectives += download_objective
|
||||||
|
|
||||||
|
var/list/active_ais = active_ais()
|
||||||
|
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
|
||||||
|
var/datum/objective/destroy/destroy_objective = new
|
||||||
|
destroy_objective.owner = owner
|
||||||
|
destroy_objective.find_target()
|
||||||
|
objectives += destroy_objective
|
||||||
|
else
|
||||||
|
if(prob(70))
|
||||||
|
var/datum/objective/assassinate/kill_objective = new
|
||||||
|
kill_objective.owner = owner
|
||||||
|
if(team_mode) //No backstabbing while in a team
|
||||||
|
kill_objective.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
|
||||||
|
else
|
||||||
|
kill_objective.find_target()
|
||||||
|
objectives += kill_objective
|
||||||
|
else
|
||||||
|
var/datum/objective/maroon/maroon_objective = new
|
||||||
|
maroon_objective.owner = owner
|
||||||
|
if(team_mode)
|
||||||
|
maroon_objective.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
|
||||||
|
else
|
||||||
|
maroon_objective.find_target()
|
||||||
|
objectives += maroon_objective
|
||||||
|
|
||||||
|
if (!(locate(/datum/objective/escape) in objectives) && escape_objective_possible)
|
||||||
|
var/datum/objective/escape/escape_with_identity/identity_theft = new
|
||||||
|
identity_theft.owner = owner
|
||||||
|
identity_theft.target = maroon_objective.target
|
||||||
|
identity_theft.update_explanation_text()
|
||||||
|
objectives += identity_theft
|
||||||
|
escape_objective_possible = FALSE
|
||||||
|
|
||||||
|
if (!(locate(/datum/objective/escape) in objectives) && escape_objective_possible)
|
||||||
|
if(prob(50))
|
||||||
|
var/datum/objective/escape/escape_objective = new
|
||||||
|
escape_objective.owner = owner
|
||||||
|
objectives += escape_objective
|
||||||
|
else
|
||||||
|
var/datum/objective/escape/escape_with_identity/identity_theft = new
|
||||||
|
identity_theft.owner = owner
|
||||||
|
if(team_mode)
|
||||||
|
identity_theft.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
|
||||||
|
else
|
||||||
|
identity_theft.find_target()
|
||||||
|
objectives += identity_theft
|
||||||
|
escape_objective_possible = FALSE
|
||||||
|
|
||||||
|
owner.objectives |= objectives
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/update_changeling_icons_added()
|
||||||
|
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING]
|
||||||
|
hud.join_hud(owner.current)
|
||||||
|
set_antag_hud(owner.current, "changling")
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/proc/update_changeling_icons_removed()
|
||||||
|
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING]
|
||||||
|
hud.leave_hud(owner.current)
|
||||||
|
set_antag_hud(owner.current, null)
|
||||||
|
|
||||||
|
// Profile
|
||||||
|
|
||||||
|
/datum/changelingprofile
|
||||||
|
var/name = "a bug"
|
||||||
|
|
||||||
|
var/protected = 0
|
||||||
|
|
||||||
|
var/datum/dna/dna = null
|
||||||
|
var/list/name_list = list() //associative list of slotname = itemname
|
||||||
|
var/list/appearance_list = list()
|
||||||
|
var/list/flags_cover_list = list()
|
||||||
|
var/list/exists_list = list()
|
||||||
|
var/list/item_color_list = list()
|
||||||
|
var/list/item_state_list = list()
|
||||||
|
|
||||||
|
var/underwear
|
||||||
|
var/undershirt
|
||||||
|
var/socks
|
||||||
|
|
||||||
|
/datum/changelingprofile/Destroy()
|
||||||
|
qdel(dna)
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
/datum/changelingprofile/proc/copy_profile(datum/changelingprofile/newprofile)
|
||||||
|
newprofile.name = name
|
||||||
|
newprofile.protected = protected
|
||||||
|
newprofile.dna = new dna.type
|
||||||
|
dna.copy_dna(newprofile.dna)
|
||||||
|
newprofile.name_list = name_list.Copy()
|
||||||
|
newprofile.appearance_list = appearance_list.Copy()
|
||||||
|
newprofile.flags_cover_list = flags_cover_list.Copy()
|
||||||
|
newprofile.exists_list = exists_list.Copy()
|
||||||
|
newprofile.item_color_list = item_color_list.Copy()
|
||||||
|
newprofile.item_state_list = item_state_list.Copy()
|
||||||
|
newprofile.underwear = underwear
|
||||||
|
newprofile.undershirt = undershirt
|
||||||
|
newprofile.socks = socks
|
||||||
|
|
||||||
|
|
||||||
|
/datum/antagonist/changeling/xenobio
|
||||||
|
name = "Xenobio Changeling"
|
||||||
|
give_objectives = FALSE
|
||||||
|
you_are_greet = FALSE
|
||||||
@@ -187,15 +187,10 @@
|
|||||||
qdel(O)
|
qdel(O)
|
||||||
|
|
||||||
/datum/mind/proc/remove_changeling()
|
/datum/mind/proc/remove_changeling()
|
||||||
if(src in SSticker.mode.changelings)
|
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
|
||||||
SSticker.mode.changelings -= src
|
if(C)
|
||||||
current.remove_changeling_powers()
|
remove_antag_datum(/datum/antagonist/changeling)
|
||||||
if(changeling)
|
special_role = null
|
||||||
qdel(changeling)
|
|
||||||
changeling = null
|
|
||||||
special_role = null
|
|
||||||
remove_antag_equip()
|
|
||||||
SSticker.mode.update_changeling_icons_removed(src)
|
|
||||||
|
|
||||||
/datum/mind/proc/remove_traitor()
|
/datum/mind/proc/remove_traitor()
|
||||||
if(src in SSticker.mode.traitors)
|
if(src in SSticker.mode.traitors)
|
||||||
@@ -251,7 +246,6 @@
|
|||||||
remove_wizard()
|
remove_wizard()
|
||||||
remove_cultist()
|
remove_cultist()
|
||||||
remove_rev()
|
remove_rev()
|
||||||
SSticker.mode.update_changeling_icons_removed(src)
|
|
||||||
SSticker.mode.update_traitor_icons_removed(src)
|
SSticker.mode.update_traitor_icons_removed(src)
|
||||||
SSticker.mode.update_cult_icons_removed(src)
|
SSticker.mode.update_cult_icons_removed(src)
|
||||||
|
|
||||||
@@ -444,17 +438,12 @@
|
|||||||
if (SSticker.mode.config_tag=="changeling" || SSticker.mode.config_tag=="traitorchan")
|
if (SSticker.mode.config_tag=="changeling" || SSticker.mode.config_tag=="traitorchan")
|
||||||
text = uppertext(text)
|
text = uppertext(text)
|
||||||
text = "<i><b>[text]</b></i>: "
|
text = "<i><b>[text]</b></i>: "
|
||||||
if ((src in SSticker.mode.changelings) && special_role)
|
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
|
||||||
text += "<b>YES</b> | <a href='?src=[REF(src)];changeling=clear'>no</a>"
|
if(C)
|
||||||
|
text += "<b>[C.name]</b> | <a href='?src=[REF(src)];changeling=clear'>No</a>"
|
||||||
if (objectives.len==0)
|
if (objectives.len==0)
|
||||||
text += "<br>Objectives are empty! <a href='?src=[REF(src)];changeling=autoobjectives'>Randomize!</a>"
|
text += "<br>Objectives are empty! <a href='?src=[REF(src)];changeling=autoobjectives'>Randomize!</a>"
|
||||||
if(changeling && changeling.stored_profiles.len && (current.real_name != changeling.first_prof.name) )
|
if(C.stored_profiles.len && (current.real_name != C.first_prof.name) )
|
||||||
text += "<br><a href='?src=[REF(src)];changeling=initialdna'>Transform to initial appearance.</a>"
|
|
||||||
else if(src in SSticker.mode.changelings) //Station Aligned Changeling
|
|
||||||
text += "<b>YES (but not an antag)</b> | <a href='?src=[REF(src)];changeling=clear'>no</a>"
|
|
||||||
if (objectives.len==0)
|
|
||||||
text += "<br>Objectives are empty! <a href='?src=[REF(src)];changeling=autoobjectives'>Randomize!</a>"
|
|
||||||
if(changeling && changeling.stored_profiles.len && (current.real_name != changeling.first_prof.name) )
|
|
||||||
text += "<br><a href='?src=[REF(src)];changeling=initialdna'>Transform to initial appearance.</a>"
|
text += "<br><a href='?src=[REF(src)];changeling=initialdna'>Transform to initial appearance.</a>"
|
||||||
else
|
else
|
||||||
text += "<a href='?src=[REF(src)];changeling=changeling'>yes</a> | <b>NO</b>"
|
text += "<a href='?src=[REF(src)];changeling=changeling'>yes</a> | <b>NO</b>"
|
||||||
@@ -1040,30 +1029,29 @@
|
|||||||
else if (href_list["changeling"])
|
else if (href_list["changeling"])
|
||||||
switch(href_list["changeling"])
|
switch(href_list["changeling"])
|
||||||
if("clear")
|
if("clear")
|
||||||
remove_changeling()
|
remove_antag_datum(/datum/antagonist/changeling)
|
||||||
|
special_role = null
|
||||||
to_chat(current, "<span class='userdanger'>You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!</span>")
|
to_chat(current, "<span class='userdanger'>You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!</span>")
|
||||||
message_admins("[key_name_admin(usr)] has de-changeling'ed [current].")
|
message_admins("[key_name_admin(usr)] has de-changeling'ed [current].")
|
||||||
log_admin("[key_name(usr)] has de-changeling'ed [current].")
|
log_admin("[key_name(usr)] has de-changeling'ed [current].")
|
||||||
if("changeling")
|
if("changeling")
|
||||||
if(!(src in SSticker.mode.changelings))
|
var/datum/antagonist/changeling/C = make_Changling()
|
||||||
SSticker.mode.changelings += src
|
to_chat(current, "<span class='boldannounce'>Your powers are awoken. A flash of memory returns to us...we are [C.changelingID], a changeling!</span>")
|
||||||
current.make_changeling()
|
message_admins("[key_name_admin(usr)] has changeling'ed [current].")
|
||||||
special_role = "Changeling"
|
log_admin("[key_name(usr)] has changeling'ed [current].")
|
||||||
to_chat(current, "<span class='boldannounce'>Your powers are awoken. A flash of memory returns to us...we are [changeling.changelingID], a changeling!</span>")
|
|
||||||
message_admins("[key_name_admin(usr)] has changeling'ed [current].")
|
|
||||||
log_admin("[key_name(usr)] has changeling'ed [current].")
|
|
||||||
SSticker.mode.update_changeling_icons_added(src)
|
|
||||||
if("autoobjectives")
|
if("autoobjectives")
|
||||||
SSticker.mode.forge_changeling_objectives(src)
|
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
|
||||||
|
if(C)
|
||||||
|
C.forge_objectives()
|
||||||
to_chat(usr, "<span class='notice'>The objectives for changeling [key] have been generated. You can edit them and anounce manually.</span>")
|
to_chat(usr, "<span class='notice'>The objectives for changeling [key] have been generated. You can edit them and anounce manually.</span>")
|
||||||
|
|
||||||
if("initialdna")
|
if("initialdna")
|
||||||
if( !changeling || !changeling.stored_profiles.len || !iscarbon(current))
|
var/datum/antagonist/changeling/ling = has_antag_datum(/datum/antagonist/changeling)
|
||||||
|
if( !ling || !ling.stored_profiles.len || !iscarbon(current))
|
||||||
to_chat(usr, "<span class='danger'>Resetting DNA failed!</span>")
|
to_chat(usr, "<span class='danger'>Resetting DNA failed!</span>")
|
||||||
else
|
else
|
||||||
var/mob/living/carbon/C = current
|
var/mob/living/carbon/C = current
|
||||||
changeling.first_prof.dna.transfer_identity(C, transfer_SE=1)
|
ling.first_prof.dna.transfer_identity(C, transfer_SE=1)
|
||||||
C.real_name = changeling.first_prof.name
|
C.real_name = ling.first_prof.name
|
||||||
C.updateappearance(mutcolor_update=1)
|
C.updateappearance(mutcolor_update=1)
|
||||||
C.domutcheck()
|
C.domutcheck()
|
||||||
|
|
||||||
@@ -1398,13 +1386,11 @@
|
|||||||
current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]"
|
current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]"
|
||||||
|
|
||||||
/datum/mind/proc/make_Changling()
|
/datum/mind/proc/make_Changling()
|
||||||
if(!(src in SSticker.mode.changelings))
|
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
|
||||||
SSticker.mode.changelings += src
|
if(!C)
|
||||||
current.make_changeling()
|
C = add_antag_datum(/datum/antagonist/changeling)
|
||||||
special_role = "Changeling"
|
special_role = "Changeling"
|
||||||
SSticker.mode.forge_changeling_objectives(src)
|
return C
|
||||||
SSticker.mode.greet_changeling(src)
|
|
||||||
SSticker.mode.update_changeling_icons_added(src)
|
|
||||||
|
|
||||||
/datum/mind/proc/make_Wizard()
|
/datum/mind/proc/make_Wizard()
|
||||||
if(!has_antag_datum(/datum/antagonist/wizard))
|
if(!has_antag_datum(/datum/antagonist/wizard))
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
/datum/cellular_emporium
|
/datum/cellular_emporium
|
||||||
var/name = "cellular emporium"
|
var/name = "cellular emporium"
|
||||||
var/datum/changeling/changeling
|
var/datum/antagonist/changeling/changeling
|
||||||
|
|
||||||
/datum/cellular_emporium/New(my_changeling)
|
/datum/cellular_emporium/New(my_changeling)
|
||||||
. = ..()
|
. = ..()
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
var/list/abilities = list()
|
var/list/abilities = list()
|
||||||
|
|
||||||
for(var/path in subtypesof(/obj/effect/proc_holder/changeling))
|
for(var/path in changeling.all_powers)
|
||||||
var/obj/effect/proc_holder/changeling/ability = path
|
var/obj/effect/proc_holder/changeling/ability = path
|
||||||
|
|
||||||
var/dna_cost = initial(ability.dna_cost)
|
var/dna_cost = initial(ability.dna_cost)
|
||||||
@@ -61,10 +61,10 @@
|
|||||||
switch(action)
|
switch(action)
|
||||||
if("readapt")
|
if("readapt")
|
||||||
if(changeling.canrespec)
|
if(changeling.canrespec)
|
||||||
changeling.lingRespec(usr)
|
changeling.readapt()
|
||||||
if("evolve")
|
if("evolve")
|
||||||
var/sting_name = params["name"]
|
var/sting_name = params["name"]
|
||||||
changeling.purchasePower(usr, sting_name)
|
changeling.purchase_power(sting_name)
|
||||||
|
|
||||||
/datum/action/innate/cellular_emporium
|
/datum/action/innate/cellular_emporium
|
||||||
name = "Cellular Emporium"
|
name = "Cellular Emporium"
|
||||||
|
|||||||
@@ -1,15 +1,8 @@
|
|||||||
#define LING_FAKEDEATH_TIME 400 //40 seconds
|
|
||||||
#define LING_DEAD_GENETICDAMAGE_HEAL_CAP 50 //The lowest value of geneticdamage handle_changeling() can take it to while dead.
|
|
||||||
#define LING_ABSORB_RECENT_SPEECH 8 //The amount of recent spoken lines to gain on absorbing a mob
|
|
||||||
|
|
||||||
GLOBAL_LIST_INIT(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"))
|
GLOBAL_LIST_INIT(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"))
|
||||||
GLOBAL_LIST_INIT(slots, list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store"))
|
GLOBAL_LIST_INIT(slots, list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store"))
|
||||||
GLOBAL_LIST_INIT(slot2slot, list("head" = slot_head, "wear_mask" = slot_wear_mask, "neck" = slot_neck, "back" = slot_back, "wear_suit" = slot_wear_suit, "w_uniform" = slot_w_uniform, "shoes" = slot_shoes, "belt" = slot_belt, "gloves" = slot_gloves, "glasses" = slot_glasses, "ears" = slot_ears, "wear_id" = slot_wear_id, "s_store" = slot_s_store))
|
GLOBAL_LIST_INIT(slot2slot, list("head" = slot_head, "wear_mask" = slot_wear_mask, "neck" = slot_neck, "back" = slot_back, "wear_suit" = slot_wear_suit, "w_uniform" = slot_w_uniform, "shoes" = slot_shoes, "belt" = slot_belt, "gloves" = slot_gloves, "glasses" = slot_glasses, "ears" = slot_ears, "wear_id" = slot_wear_id, "s_store" = slot_s_store))
|
||||||
GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "wear_mask" = /obj/item/clothing/mask/changeling, "back" = /obj/item/changeling, "wear_suit" = /obj/item/clothing/suit/changeling, "w_uniform" = /obj/item/clothing/under/changeling, "shoes" = /obj/item/clothing/shoes/changeling, "belt" = /obj/item/changeling, "gloves" = /obj/item/clothing/gloves/changeling, "glasses" = /obj/item/clothing/glasses/changeling, "ears" = /obj/item/changeling, "wear_id" = /obj/item/changeling, "s_store" = /obj/item/changeling))
|
GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "wear_mask" = /obj/item/clothing/mask/changeling, "back" = /obj/item/changeling, "wear_suit" = /obj/item/clothing/suit/changeling, "w_uniform" = /obj/item/clothing/under/changeling, "shoes" = /obj/item/clothing/shoes/changeling, "belt" = /obj/item/changeling, "gloves" = /obj/item/clothing/gloves/changeling, "glasses" = /obj/item/clothing/glasses/changeling, "ears" = /obj/item/changeling, "wear_id" = /obj/item/changeling, "s_store" = /obj/item/changeling))
|
||||||
|
GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our this objective to all lings
|
||||||
|
|
||||||
/datum/game_mode
|
|
||||||
var/list/datum/mind/changelings = list()
|
|
||||||
|
|
||||||
|
|
||||||
/datum/game_mode/changeling
|
/datum/game_mode/changeling
|
||||||
@@ -29,26 +22,8 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
|||||||
<span class='green'>Changelings</span>: Accomplish the objectives assigned to you.\n\
|
<span class='green'>Changelings</span>: Accomplish the objectives assigned to you.\n\
|
||||||
<span class='notice'>Crew</span>: Root out and eliminate the changeling menace."
|
<span class='notice'>Crew</span>: Root out and eliminate the changeling menace."
|
||||||
|
|
||||||
var/const/prob_int_murder_target = 50 // intercept names the assassination target half the time
|
|
||||||
var/const/prob_right_murder_target_l = 25 // lower bound on probability of naming right assassination target
|
|
||||||
var/const/prob_right_murder_target_h = 50 // upper bound on probability of naimg the right assassination target
|
|
||||||
|
|
||||||
var/const/prob_int_item = 50 // intercept names the theft target half the time
|
|
||||||
var/const/prob_right_item_l = 25 // lower bound on probability of naming right theft target
|
|
||||||
var/const/prob_right_item_h = 50 // upper bound on probability of naming the right theft target
|
|
||||||
|
|
||||||
var/const/prob_int_sab_target = 50 // intercept names the sabotage target half the time
|
|
||||||
var/const/prob_right_sab_target_l = 25 // lower bound on probability of naming right sabotage target
|
|
||||||
var/const/prob_right_sab_target_h = 50 // upper bound on probability of naming right sabotage target
|
|
||||||
|
|
||||||
var/const/prob_right_killer_l = 25 //lower bound on probability of naming the right operative
|
|
||||||
var/const/prob_right_killer_h = 50 //upper bound on probability of naming the right operative
|
|
||||||
var/const/prob_right_objective_l = 25 //lower bound on probability of determining the objective correctly
|
|
||||||
var/const/prob_right_objective_h = 50 //upper bound on probability of determining the objective correctly
|
|
||||||
|
|
||||||
var/const/changeling_amount = 4 //hard limit on changelings if scaling is turned off
|
var/const/changeling_amount = 4 //hard limit on changelings if scaling is turned off
|
||||||
|
var/list/changelings = list()
|
||||||
var/changeling_team_objective_type = null //If this is not null, we hand our this objective to all lings
|
|
||||||
|
|
||||||
/datum/game_mode/changeling/pre_setup()
|
/datum/game_mode/changeling/pre_setup()
|
||||||
|
|
||||||
@@ -80,7 +55,6 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
/datum/game_mode/changeling/post_setup()
|
/datum/game_mode/changeling/post_setup()
|
||||||
|
|
||||||
//Decide if it's ok for the lings to have a team objective
|
//Decide if it's ok for the lings to have a team objective
|
||||||
//And then set it up to be handed out in forge_changeling_objectives
|
//And then set it up to be handed out in forge_changeling_objectives
|
||||||
var/list/team_objectives = subtypesof(/datum/objective/changeling_team_objective)
|
var/list/team_objectives = subtypesof(/datum/objective/changeling_team_objective)
|
||||||
@@ -92,116 +66,27 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
|||||||
possible_team_objectives += T
|
possible_team_objectives += T
|
||||||
|
|
||||||
if(possible_team_objectives.len && prob(20*changelings.len))
|
if(possible_team_objectives.len && prob(20*changelings.len))
|
||||||
changeling_team_objective_type = pick(possible_team_objectives)
|
GLOB.changeling_team_objective_type = pick(possible_team_objectives)
|
||||||
|
|
||||||
for(var/datum/mind/changeling in changelings)
|
for(var/datum/mind/changeling in changelings)
|
||||||
log_game("[changeling.key] (ckey) has been selected as a changeling")
|
log_game("[changeling.key] (ckey) has been selected as a changeling")
|
||||||
changeling.current.make_changeling()
|
var/datum/antagonist/changeling/new_antag = new(changeling)
|
||||||
forge_changeling_objectives(changeling)
|
new_antag.team_mode = TRUE
|
||||||
greet_changeling(changeling)
|
changeling.add_antag_datum(new_antag)
|
||||||
SSticker.mode.update_changeling_icons_added(changeling)
|
|
||||||
..()
|
..()
|
||||||
|
|
||||||
/datum/game_mode/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners
|
/datum/game_mode/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners
|
||||||
var/csc = CONFIG_GET(number/changeling_scaling_coeff)
|
var/csc = CONFIG_GET(number/changeling_scaling_coeff)
|
||||||
var/changelingcap = min(round(GLOB.joined_player_list.len / (csc * 2)) + 2, round(GLOB.joined_player_list.len / csc))
|
var/changelingcap = min(round(GLOB.joined_player_list.len / (csc * 2)) + 2, round(GLOB.joined_player_list.len / csc))
|
||||||
if(SSticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists
|
if(changelings.len >= changelingcap) //Caps number of latejoin antagonists
|
||||||
return
|
return
|
||||||
if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 - (csc * 2)))
|
if(changelings.len <= (changelingcap - 2) || prob(100 - (csc * 2)))
|
||||||
if(ROLE_CHANGELING in character.client.prefs.be_special)
|
if(ROLE_CHANGELING in character.client.prefs.be_special)
|
||||||
if(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate"))
|
if(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate"))
|
||||||
if(age_check(character.client))
|
if(age_check(character.client))
|
||||||
if(!(character.job in restricted_jobs))
|
if(!(character.job in restricted_jobs))
|
||||||
character.mind.make_Changling()
|
character.mind.make_Changling()
|
||||||
|
changelings += character.mind
|
||||||
/datum/game_mode/proc/forge_changeling_objectives(datum/mind/changeling, var/team_mode = 0)
|
|
||||||
//OBJECTIVES - random traitor objectives. Unique objectives "steal brain" and "identity theft".
|
|
||||||
//No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting
|
|
||||||
//If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone
|
|
||||||
|
|
||||||
var/escape_objective_possible = TRUE
|
|
||||||
|
|
||||||
//if there's a team objective, check if it's compatible with escape objectives
|
|
||||||
for(var/datum/objective/changeling_team_objective/CTO in changeling.objectives)
|
|
||||||
if(!CTO.escape_objective_compatible)
|
|
||||||
escape_objective_possible = FALSE
|
|
||||||
break
|
|
||||||
|
|
||||||
var/datum/objective/absorb/absorb_objective = new
|
|
||||||
absorb_objective.owner = changeling
|
|
||||||
absorb_objective.gen_amount_goal(6, 8)
|
|
||||||
changeling.objectives += absorb_objective
|
|
||||||
|
|
||||||
if(prob(60))
|
|
||||||
if(prob(85))
|
|
||||||
var/datum/objective/steal/steal_objective = new
|
|
||||||
steal_objective.owner = changeling
|
|
||||||
steal_objective.find_target()
|
|
||||||
changeling.objectives += steal_objective
|
|
||||||
else
|
|
||||||
var/datum/objective/download/download_objective = new
|
|
||||||
download_objective.owner = changeling
|
|
||||||
download_objective.gen_amount_goal()
|
|
||||||
changeling.objectives += download_objective
|
|
||||||
|
|
||||||
var/list/active_ais = active_ais()
|
|
||||||
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
|
|
||||||
var/datum/objective/destroy/destroy_objective = new
|
|
||||||
destroy_objective.owner = changeling
|
|
||||||
destroy_objective.find_target()
|
|
||||||
changeling.objectives += destroy_objective
|
|
||||||
else
|
|
||||||
if(prob(70))
|
|
||||||
var/datum/objective/assassinate/kill_objective = new
|
|
||||||
kill_objective.owner = changeling
|
|
||||||
if(team_mode) //No backstabbing while in a team
|
|
||||||
kill_objective.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
|
|
||||||
else
|
|
||||||
kill_objective.find_target()
|
|
||||||
changeling.objectives += kill_objective
|
|
||||||
else
|
|
||||||
var/datum/objective/maroon/maroon_objective = new
|
|
||||||
maroon_objective.owner = changeling
|
|
||||||
if(team_mode)
|
|
||||||
maroon_objective.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
|
|
||||||
else
|
|
||||||
maroon_objective.find_target()
|
|
||||||
changeling.objectives += maroon_objective
|
|
||||||
|
|
||||||
if (!(locate(/datum/objective/escape) in changeling.objectives) && escape_objective_possible)
|
|
||||||
var/datum/objective/escape/escape_with_identity/identity_theft = new
|
|
||||||
identity_theft.owner = changeling
|
|
||||||
identity_theft.target = maroon_objective.target
|
|
||||||
identity_theft.update_explanation_text()
|
|
||||||
changeling.objectives += identity_theft
|
|
||||||
escape_objective_possible = FALSE
|
|
||||||
|
|
||||||
if (!(locate(/datum/objective/escape) in changeling.objectives) && escape_objective_possible)
|
|
||||||
if(prob(50))
|
|
||||||
var/datum/objective/escape/escape_objective = new
|
|
||||||
escape_objective.owner = changeling
|
|
||||||
changeling.objectives += escape_objective
|
|
||||||
else
|
|
||||||
var/datum/objective/escape/escape_with_identity/identity_theft = new
|
|
||||||
identity_theft.owner = changeling
|
|
||||||
if(team_mode)
|
|
||||||
identity_theft.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
|
|
||||||
else
|
|
||||||
identity_theft.find_target()
|
|
||||||
changeling.objectives += identity_theft
|
|
||||||
escape_objective_possible = FALSE
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/datum/game_mode/changeling/forge_changeling_objectives(datum/mind/changeling)
|
|
||||||
if(changeling_team_objective_type)
|
|
||||||
var/datum/objective/changeling_team_objective/team_objective = new changeling_team_objective_type
|
|
||||||
team_objective.owner = changeling
|
|
||||||
changeling.objectives += team_objective
|
|
||||||
|
|
||||||
..(changeling,1)
|
|
||||||
else
|
|
||||||
..(changeling,0)
|
|
||||||
|
|
||||||
/datum/game_mode/changeling/generate_report()
|
/datum/game_mode/changeling/generate_report()
|
||||||
return "The Gorlex Marauders have announced the successful raid and destruction of Central Command containment ship #S-[rand(1111, 9999)]. This ship housed only a single prisoner - \
|
return "The Gorlex Marauders have announced the successful raid and destruction of Central Command containment ship #S-[rand(1111, 9999)]. This ship housed only a single prisoner - \
|
||||||
@@ -209,29 +94,12 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
|||||||
of the Thing being sent to a station in this sector is highly likely. It may be in the guise of any crew member. Trust nobody - suspect everybody. Do not announce this to the crew, \
|
of the Thing being sent to a station in this sector is highly likely. It may be in the guise of any crew member. Trust nobody - suspect everybody. Do not announce this to the crew, \
|
||||||
as paranoia may spread and inhibit workplace efficiency."
|
as paranoia may spread and inhibit workplace efficiency."
|
||||||
|
|
||||||
/datum/game_mode/proc/greet_changeling(datum/mind/changeling, you_are=1)
|
|
||||||
if (you_are)
|
|
||||||
to_chat(changeling.current, "<span class='boldannounce'>You are [changeling.changeling.changelingID], a changeling! You have absorbed and taken the form of a human.</span>")
|
|
||||||
to_chat(changeling.current, "<span class='boldannounce'>Use say \":g message\" to communicate with your fellow changelings.</span>")
|
|
||||||
to_chat(changeling.current, "<b>You must complete the following tasks:</b>")
|
|
||||||
changeling.current.playsound_local(get_turf(changeling.current), 'sound/ambience/antag/ling_aler.ogg', 100, FALSE, pressure_affected = FALSE)
|
|
||||||
|
|
||||||
if (changeling.current.mind)
|
|
||||||
var/mob/living/carbon/human/H = changeling.current
|
|
||||||
if(H.mind.assigned_role == "Clown")
|
|
||||||
to_chat(H, "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself.")
|
|
||||||
H.dna.remove_mutation(CLOWNMUT)
|
|
||||||
|
|
||||||
var/obj_count = 1
|
|
||||||
for(var/datum/objective/objective in changeling.objectives)
|
|
||||||
to_chat(changeling.current, "<b>Objective #[obj_count]</b>: [objective.explanation_text]")
|
|
||||||
obj_count++
|
|
||||||
return
|
|
||||||
|
|
||||||
/datum/game_mode/proc/auto_declare_completion_changeling()
|
/datum/game_mode/proc/auto_declare_completion_changeling()
|
||||||
|
var/list/changelings = get_antagonists(/datum/antagonist/changeling,TRUE) //Only real lings get a mention
|
||||||
if(changelings.len)
|
if(changelings.len)
|
||||||
var/text = "<br><font size=3><b>The changelings were:</b></font>"
|
var/text = "<br><font size=3><b>The changelings were:</b></font>"
|
||||||
for(var/datum/mind/changeling in changelings)
|
for(var/datum/mind/changeling in changelings)
|
||||||
|
var/datum/antagonist/changeling/ling = changeling.has_antag_datum(/datum/antagonist/changeling)
|
||||||
var/changelingwin = 1
|
var/changelingwin = 1
|
||||||
if(!changeling.current)
|
if(!changeling.current)
|
||||||
changelingwin = 0
|
changelingwin = 0
|
||||||
@@ -239,8 +107,8 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
|||||||
text += printplayer(changeling)
|
text += printplayer(changeling)
|
||||||
|
|
||||||
//Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed.
|
//Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed.
|
||||||
text += "<br><b>Changeling ID:</b> [changeling.changeling.changelingID]."
|
text += "<br><b>Changeling ID:</b> [ling.changelingID]."
|
||||||
text += "<br><b>Genomes Extracted:</b> [changeling.changeling.absorbedcount]"
|
text += "<br><b>Genomes Extracted:</b> [ling.absorbedcount]"
|
||||||
|
|
||||||
if(changeling.objectives.len)
|
if(changeling.objectives.len)
|
||||||
var/count = 1
|
var/count = 1
|
||||||
@@ -264,176 +132,8 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
|||||||
|
|
||||||
to_chat(world, text)
|
to_chat(world, text)
|
||||||
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
/datum/changeling //stores changeling powers, changeling recharge thingie, changeling absorbed DNA and changeling ID (for changeling hivemind)
|
|
||||||
var/list/stored_profiles = list() //list of datum/changelingprofile
|
|
||||||
var/datum/changelingprofile/first_prof = null
|
|
||||||
//var/list/absorbed_dna = list()
|
|
||||||
//var/list/protected_dna = list() //dna that is not lost when capacity is otherwise full
|
|
||||||
var/dna_max = 6 //How many extra DNA strands the changeling can store for transformation.
|
|
||||||
var/absorbedcount = 0
|
|
||||||
var/chem_charges = 20
|
|
||||||
var/chem_storage = 75
|
|
||||||
var/chem_recharge_rate = 1
|
|
||||||
var/chem_recharge_slowdown = 0
|
|
||||||
var/sting_range = 2
|
|
||||||
var/changelingID = "Changeling"
|
|
||||||
var/geneticdamage = 0
|
|
||||||
var/isabsorbing = 0
|
|
||||||
var/islinking = 0
|
|
||||||
var/geneticpoints = 10
|
|
||||||
var/purchasedpowers = list()
|
|
||||||
var/mimicing = ""
|
|
||||||
var/canrespec = 0
|
|
||||||
var/changeling_speak = 0
|
|
||||||
var/datum/dna/chosen_dna
|
|
||||||
var/obj/effect/proc_holder/changeling/sting/chosen_sting
|
|
||||||
var/datum/cellular_emporium/cellular_emporium
|
|
||||||
var/datum/action/innate/cellular_emporium/emporium_action
|
|
||||||
|
|
||||||
/datum/changeling/New(var/gender=FEMALE)
|
|
||||||
..()
|
|
||||||
var/honorific
|
|
||||||
if(gender == FEMALE)
|
|
||||||
honorific = "Ms."
|
|
||||||
else
|
|
||||||
honorific = "Mr."
|
|
||||||
if(GLOB.possible_changeling_IDs.len)
|
|
||||||
changelingID = pick(GLOB.possible_changeling_IDs)
|
|
||||||
GLOB.possible_changeling_IDs -= changelingID
|
|
||||||
changelingID = "[honorific] [changelingID]"
|
|
||||||
else
|
|
||||||
changelingID = "[honorific] [rand(1,999)]"
|
|
||||||
|
|
||||||
cellular_emporium = new(src)
|
|
||||||
emporium_action = new(cellular_emporium)
|
|
||||||
|
|
||||||
/datum/changeling/Destroy()
|
|
||||||
qdel(cellular_emporium)
|
|
||||||
cellular_emporium = null
|
|
||||||
qdel(emporium_action)
|
|
||||||
emporium_action = null
|
|
||||||
. = ..()
|
|
||||||
|
|
||||||
/datum/changeling/proc/regenerate(var/mob/living/carbon/the_ling)
|
|
||||||
if(istype(the_ling))
|
|
||||||
emporium_action.Grant(the_ling)
|
|
||||||
if(the_ling.stat == DEAD)
|
|
||||||
chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), (chem_storage*0.5))
|
|
||||||
geneticdamage = max(LING_DEAD_GENETICDAMAGE_HEAL_CAP,geneticdamage-1)
|
|
||||||
else //not dead? no chem/geneticdamage caps.
|
|
||||||
chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), chem_storage)
|
|
||||||
geneticdamage = max(0, geneticdamage-1)
|
|
||||||
|
|
||||||
|
|
||||||
/datum/changeling/proc/get_dna(dna_owner)
|
|
||||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
|
||||||
if(dna_owner == prof.name)
|
|
||||||
return prof
|
|
||||||
|
|
||||||
/datum/changeling/proc/has_dna(datum/dna/tDNA)
|
|
||||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
|
||||||
if(tDNA.is_same_as(prof.dna))
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/datum/changeling/proc/can_absorb_dna(mob/living/carbon/user, mob/living/carbon/human/target, var/verbose=1)
|
|
||||||
if(stored_profiles.len)
|
|
||||||
var/datum/changelingprofile/prof = stored_profiles[1]
|
|
||||||
if(prof.dna == user.dna && stored_profiles.len >= dna_max)//If our current DNA is the stalest, we gotta ditch it.
|
|
||||||
if(verbose)
|
|
||||||
to_chat(user, "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>")
|
|
||||||
return
|
|
||||||
if(!target)
|
|
||||||
return
|
|
||||||
if(NO_DNA_COPY in target.dna.species.species_traits)
|
|
||||||
if(verbose)
|
|
||||||
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
|
|
||||||
return
|
|
||||||
if((target.disabilities & NOCLONE) || (target.disabilities & HUSK))
|
|
||||||
if(verbose)
|
|
||||||
to_chat(user, "<span class='warning'>DNA of [target] is ruined beyond usability!</span>")
|
|
||||||
return
|
|
||||||
if(!ishuman(target))//Absorbing monkeys is entirely possible, but it can cause issues with transforming. That's what lesser form is for anyway!
|
|
||||||
if(verbose)
|
|
||||||
to_chat(user, "<span class='warning'>We could gain no benefit from absorbing a lesser creature.</span>")
|
|
||||||
return
|
|
||||||
if(has_dna(target.dna))
|
|
||||||
if(verbose)
|
|
||||||
to_chat(user, "<span class='warning'>We already have this DNA in storage!</span>")
|
|
||||||
return
|
|
||||||
if(!target.has_dna())
|
|
||||||
if(verbose)
|
|
||||||
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
|
|
||||||
return
|
|
||||||
return 1
|
|
||||||
|
|
||||||
/datum/changeling/proc/create_profile(mob/living/carbon/human/H, mob/living/carbon/human/user, protect = 0)
|
|
||||||
var/datum/changelingprofile/prof = new
|
|
||||||
|
|
||||||
H.dna.real_name = H.real_name //Set this again, just to be sure that it's properly set.
|
|
||||||
var/datum/dna/new_dna = new H.dna.type
|
|
||||||
H.dna.copy_dna(new_dna)
|
|
||||||
prof.dna = new_dna
|
|
||||||
prof.name = H.real_name
|
|
||||||
prof.protected = protect
|
|
||||||
|
|
||||||
prof.underwear = H.underwear
|
|
||||||
prof.undershirt = H.undershirt
|
|
||||||
prof.socks = H.socks
|
|
||||||
|
|
||||||
var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store")
|
|
||||||
for(var/slot in slots)
|
|
||||||
if(slot in H.vars)
|
|
||||||
var/obj/item/I = H.vars[slot]
|
|
||||||
if(!I)
|
|
||||||
continue
|
|
||||||
prof.name_list[slot] = I.name
|
|
||||||
prof.appearance_list[slot] = I.appearance
|
|
||||||
prof.flags_cover_list[slot] = I.flags_cover
|
|
||||||
prof.item_color_list[slot] = I.item_color
|
|
||||||
prof.item_state_list[slot] = I.item_state
|
|
||||||
prof.exists_list[slot] = 1
|
|
||||||
else
|
|
||||||
continue
|
|
||||||
|
|
||||||
return prof
|
|
||||||
|
|
||||||
/datum/changeling/proc/add_profile(datum/changelingprofile/prof)
|
|
||||||
if(stored_profiles.len > dna_max)
|
|
||||||
if(!push_out_profile())
|
|
||||||
return
|
|
||||||
|
|
||||||
stored_profiles += prof
|
|
||||||
absorbedcount++
|
|
||||||
|
|
||||||
/datum/changeling/proc/add_new_profile(mob/living/carbon/human/H, mob/living/carbon/human/user, protect = 0)
|
|
||||||
var/datum/changelingprofile/prof = create_profile(H, protect)
|
|
||||||
add_profile(prof)
|
|
||||||
return prof
|
|
||||||
|
|
||||||
/datum/changeling/proc/remove_profile(mob/living/carbon/human/H, force = 0)
|
|
||||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
|
||||||
if(H.real_name == prof.name)
|
|
||||||
if(prof.protected && !force)
|
|
||||||
continue
|
|
||||||
stored_profiles -= prof
|
|
||||||
qdel(prof)
|
|
||||||
|
|
||||||
/datum/changeling/proc/get_profile_to_remove()
|
|
||||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
|
||||||
if(!prof.protected)
|
|
||||||
return prof
|
|
||||||
|
|
||||||
/datum/changeling/proc/push_out_profile()
|
|
||||||
var/datum/changelingprofile/removeprofile = get_profile_to_remove()
|
|
||||||
if(removeprofile)
|
|
||||||
stored_profiles -= removeprofile
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/proc/changeling_transform(mob/living/carbon/human/user, datum/changelingprofile/chosen_prof)
|
/proc/changeling_transform(mob/living/carbon/human/user, datum/changelingprofile/chosen_prof)
|
||||||
var/datum/dna/chosen_dna = chosen_prof.dna
|
var/datum/dna/chosen_dna = chosen_prof.dna
|
||||||
user.real_name = chosen_prof.name
|
user.real_name = chosen_prof.name
|
||||||
@@ -474,49 +174,3 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
|||||||
user.equip_to_slot_or_del(C, GLOB.slot2slot[slot])
|
user.equip_to_slot_or_del(C, GLOB.slot2slot[slot])
|
||||||
|
|
||||||
user.regenerate_icons()
|
user.regenerate_icons()
|
||||||
|
|
||||||
/datum/changelingprofile
|
|
||||||
var/name = "a bug"
|
|
||||||
|
|
||||||
var/protected = 0
|
|
||||||
|
|
||||||
var/datum/dna/dna = null
|
|
||||||
var/list/name_list = list() //associative list of slotname = itemname
|
|
||||||
var/list/appearance_list = list()
|
|
||||||
var/list/flags_cover_list = list()
|
|
||||||
var/list/exists_list = list()
|
|
||||||
var/list/item_color_list = list()
|
|
||||||
var/list/item_state_list = list()
|
|
||||||
|
|
||||||
var/underwear
|
|
||||||
var/undershirt
|
|
||||||
var/socks
|
|
||||||
|
|
||||||
/datum/changelingprofile/Destroy()
|
|
||||||
qdel(dna)
|
|
||||||
. = ..()
|
|
||||||
|
|
||||||
/datum/changelingprofile/proc/copy_profile(datum/changelingprofile/newprofile)
|
|
||||||
newprofile.name = name
|
|
||||||
newprofile.protected = protected
|
|
||||||
newprofile.dna = new dna.type
|
|
||||||
dna.copy_dna(newprofile.dna)
|
|
||||||
newprofile.name_list = name_list.Copy()
|
|
||||||
newprofile.appearance_list = appearance_list.Copy()
|
|
||||||
newprofile.flags_cover_list = flags_cover_list.Copy()
|
|
||||||
newprofile.exists_list = exists_list.Copy()
|
|
||||||
newprofile.item_color_list = item_color_list.Copy()
|
|
||||||
newprofile.item_state_list = item_state_list.Copy()
|
|
||||||
newprofile.underwear = underwear
|
|
||||||
newprofile.undershirt = undershirt
|
|
||||||
newprofile.socks = socks
|
|
||||||
|
|
||||||
/datum/game_mode/proc/update_changeling_icons_added(datum/mind/changling_mind)
|
|
||||||
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING]
|
|
||||||
hud.join_hud(changling_mind.current)
|
|
||||||
set_antag_hud(changling_mind.current, "changling")
|
|
||||||
|
|
||||||
/datum/game_mode/proc/update_changeling_icons_removed(datum/mind/changling_mind)
|
|
||||||
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING]
|
|
||||||
hud.leave_hud(changling_mind.current)
|
|
||||||
set_antag_hud(changling_mind.current, null)
|
|
||||||
|
|||||||
@@ -26,14 +26,14 @@
|
|||||||
|
|
||||||
/obj/effect/proc_holder/changeling/Click()
|
/obj/effect/proc_holder/changeling/Click()
|
||||||
var/mob/user = usr
|
var/mob/user = usr
|
||||||
if(!user || !user.mind || !user.mind.changeling)
|
if(!user || !user.mind || !user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
return
|
return
|
||||||
try_to_sting(user)
|
try_to_sting(user)
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/proc/try_to_sting(mob/user, mob/target)
|
/obj/effect/proc_holder/changeling/proc/try_to_sting(mob/user, mob/target)
|
||||||
if(!can_sting(user, target))
|
if(!can_sting(user, target))
|
||||||
return
|
return
|
||||||
var/datum/changeling/c = user.mind.changeling
|
var/datum/antagonist/changeling/c = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
if(sting_action(user, target))
|
if(sting_action(user, target))
|
||||||
SSblackbox.add_details("changeling_powers",name)
|
SSblackbox.add_details("changeling_powers",name)
|
||||||
sting_feedback(user, target)
|
sting_feedback(user, target)
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
if(req_human && !ishuman(user))
|
if(req_human && !ishuman(user))
|
||||||
to_chat(user, "<span class='warning'>We cannot do that in this form!</span>")
|
to_chat(user, "<span class='warning'>We cannot do that in this form!</span>")
|
||||||
return 0
|
return 0
|
||||||
var/datum/changeling/c = user.mind.changeling
|
var/datum/antagonist/changeling/c = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
if(c.chem_charges < chemical_cost)
|
if(c.chem_charges < chemical_cost)
|
||||||
to_chat(user, "<span class='warning'>We require at least [chemical_cost] unit\s of chemicals to do that!</span>")
|
to_chat(user, "<span class='warning'>We require at least [chemical_cost] unit\s of chemicals to do that!</span>")
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -1,112 +0,0 @@
|
|||||||
/datum/changeling/proc/purchasePower(mob/living/carbon/user, sting_name)
|
|
||||||
|
|
||||||
var/obj/effect/proc_holder/changeling/thepower = null
|
|
||||||
|
|
||||||
for(var/path in subtypesof(/obj/effect/proc_holder/changeling))
|
|
||||||
var/obj/effect/proc_holder/changeling/S = path
|
|
||||||
if(initial(S.name) == sting_name)
|
|
||||||
thepower = new path()
|
|
||||||
break
|
|
||||||
|
|
||||||
if(!thepower)
|
|
||||||
to_chat(user, "This is awkward. Changeling power purchase failed, please report this bug to a coder!")
|
|
||||||
return
|
|
||||||
|
|
||||||
if(absorbedcount < thepower.req_dna)
|
|
||||||
to_chat(user, "We lack the energy to evolve this ability!")
|
|
||||||
return
|
|
||||||
|
|
||||||
if(has_sting(thepower))
|
|
||||||
to_chat(user, "We have already evolved this ability!")
|
|
||||||
return
|
|
||||||
|
|
||||||
if(thepower.dna_cost < 0)
|
|
||||||
to_chat(user, "We cannot evolve this ability.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if(geneticpoints < thepower.dna_cost)
|
|
||||||
to_chat(user, "We have reached our capacity for abilities.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if(user.status_flags & FAKEDEATH)//To avoid potential exploits by buying new powers while in stasis, which clears your verblist.
|
|
||||||
to_chat(user, "We lack the energy to evolve new abilities right now.")
|
|
||||||
return
|
|
||||||
|
|
||||||
geneticpoints -= thepower.dna_cost
|
|
||||||
purchasedpowers += thepower
|
|
||||||
thepower.on_purchase(user)
|
|
||||||
|
|
||||||
//Reselect powers
|
|
||||||
/datum/changeling/proc/lingRespec(mob/user)
|
|
||||||
if(!ishuman(user))
|
|
||||||
to_chat(user, "<span class='danger'>We can't remove our evolutions in this form!</span>")
|
|
||||||
return
|
|
||||||
if(canrespec)
|
|
||||||
to_chat(user, "<span class='notice'>We have removed our evolutions from this form, and are now ready to readapt.</span>")
|
|
||||||
user.remove_changeling_powers(1)
|
|
||||||
canrespec = 0
|
|
||||||
user.make_changeling(TRUE)
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
to_chat(user, "<span class='danger'>You lack the power to readapt your evolutions!</span>")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/mob/proc/make_changeling(is_respec)
|
|
||||||
if(!mind)
|
|
||||||
return
|
|
||||||
if(!ishuman(src) && !ismonkey(src))
|
|
||||||
return
|
|
||||||
if(!mind.changeling)
|
|
||||||
mind.changeling = new /datum/changeling(gender)
|
|
||||||
if(mind.changeling.purchasedpowers)
|
|
||||||
remove_changeling_powers(1)
|
|
||||||
// purchase free powers.
|
|
||||||
for(var/path in subtypesof(/obj/effect/proc_holder/changeling))
|
|
||||||
var/obj/effect/proc_holder/changeling/S = new path()
|
|
||||||
if(!S.dna_cost)
|
|
||||||
if(!mind.changeling.has_sting(S))
|
|
||||||
mind.changeling.purchasedpowers+=S
|
|
||||||
S.on_purchase(src, is_respec)
|
|
||||||
if(is_respec)
|
|
||||||
SSblackbox.add_details("changeling_power_purchase","Readapt")
|
|
||||||
|
|
||||||
var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste
|
|
||||||
if(ishuman(C))
|
|
||||||
var/datum/changelingprofile/prof = mind.changeling.add_new_profile(C, src)
|
|
||||||
mind.changeling.first_prof = prof
|
|
||||||
|
|
||||||
var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN)
|
|
||||||
if(B)
|
|
||||||
B.vital = FALSE
|
|
||||||
B.decoy_override = TRUE
|
|
||||||
return 1
|
|
||||||
|
|
||||||
/datum/changeling/proc/reset()
|
|
||||||
chosen_sting = null
|
|
||||||
geneticpoints = initial(geneticpoints)
|
|
||||||
sting_range = initial(sting_range)
|
|
||||||
chem_storage = initial(chem_storage)
|
|
||||||
chem_recharge_rate = initial(chem_recharge_rate)
|
|
||||||
chem_charges = min(chem_charges, chem_storage)
|
|
||||||
chem_recharge_slowdown = initial(chem_recharge_slowdown)
|
|
||||||
mimicing = ""
|
|
||||||
|
|
||||||
/mob/proc/remove_changeling_powers(keep_free_powers=0)
|
|
||||||
if(ishuman(src) || ismonkey(src))
|
|
||||||
if(mind && mind.changeling)
|
|
||||||
mind.changeling.changeling_speak = 0
|
|
||||||
mind.changeling.reset()
|
|
||||||
for(var/obj/effect/proc_holder/changeling/p in mind.changeling.purchasedpowers)
|
|
||||||
if((p.dna_cost == 0 && keep_free_powers) || p.always_keep)
|
|
||||||
continue
|
|
||||||
mind.changeling.purchasedpowers -= p
|
|
||||||
p.on_refund(src)
|
|
||||||
if(hud_used)
|
|
||||||
hud_used.lingstingdisplay.icon_state = null
|
|
||||||
hud_used.lingstingdisplay.invisibility = INVISIBILITY_ABSTRACT
|
|
||||||
|
|
||||||
/datum/changeling/proc/has_sting(obj/effect/proc_holder/changeling/power)
|
|
||||||
for(var/obj/effect/proc_holder/changeling/P in purchasedpowers)
|
|
||||||
if(initial(power.name) == P.name)
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
if(!..())
|
if(!..())
|
||||||
return
|
return
|
||||||
|
|
||||||
var/datum/changeling/changeling = user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
if(changeling.isabsorbing)
|
if(changeling.isabsorbing)
|
||||||
to_chat(user, "<span class='warning'>We are already absorbing!</span>")
|
to_chat(user, "<span class='warning'>We are already absorbing!</span>")
|
||||||
return
|
return
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
var/mob/living/carbon/target = user.pulling
|
var/mob/living/carbon/target = user.pulling
|
||||||
return changeling.can_absorb_dna(user,target)
|
return changeling.can_absorb_dna(target)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/absorbDNA/sting_action(mob/user)
|
/obj/effect/proc_holder/changeling/absorbDNA/sting_action(mob/user)
|
||||||
var/datum/changeling/changeling = user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
var/mob/living/carbon/human/target = user.pulling
|
var/mob/living/carbon/human/target = user.pulling
|
||||||
changeling.isabsorbing = 1
|
changeling.isabsorbing = 1
|
||||||
for(var/i in 1 to 3)
|
for(var/i in 1 to 3)
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
to_chat(target, "<span class='userdanger'>You are absorbed by the changeling!</span>")
|
to_chat(target, "<span class='userdanger'>You are absorbed by the changeling!</span>")
|
||||||
|
|
||||||
if(!changeling.has_dna(target.dna))
|
if(!changeling.has_dna(target.dna))
|
||||||
changeling.add_new_profile(target, user)
|
changeling.add_new_profile(target)
|
||||||
|
|
||||||
if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
|
if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
|
||||||
user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)
|
user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)
|
||||||
@@ -84,12 +84,14 @@
|
|||||||
user.mind.store_memory("<B>We have no more knowledge of [target]'s speech patterns.</B>")
|
user.mind.store_memory("<B>We have no more knowledge of [target]'s speech patterns.</B>")
|
||||||
to_chat(user, "<span class='boldnotice'>We have no more knowledge of [target]'s speech patterns.</span>")
|
to_chat(user, "<span class='boldnotice'>We have no more knowledge of [target]'s speech patterns.</span>")
|
||||||
|
|
||||||
if(target.mind.changeling)//If the target was a changeling, suck out their extra juice and objective points!
|
|
||||||
changeling.chem_charges += min(target.mind.changeling.chem_charges, changeling.chem_storage)
|
|
||||||
changeling.absorbedcount += (target.mind.changeling.absorbedcount)
|
|
||||||
|
|
||||||
target.mind.changeling.stored_profiles.len = 1
|
var/datum/antagonist/changeling/target_ling = target.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
target.mind.changeling.absorbedcount = 0
|
if(target_ling)//If the target was a changeling, suck out their extra juice and objective points!
|
||||||
|
changeling.chem_charges += min(target_ling.chem_charges, changeling.chem_storage)
|
||||||
|
changeling.absorbedcount += (target_ling.absorbedcount)
|
||||||
|
|
||||||
|
target_ling.stored_profiles.len = 1
|
||||||
|
target_ling.absorbedcount = 0
|
||||||
|
|
||||||
|
|
||||||
changeling.chem_charges=min(changeling.chem_charges+10, changeling.chem_storage)
|
changeling.chem_charges=min(changeling.chem_charges+10, changeling.chem_storage)
|
||||||
|
|||||||
@@ -20,9 +20,11 @@
|
|||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/fakedeath/proc/ready_to_regenerate(mob/user)
|
/obj/effect/proc_holder/changeling/fakedeath/proc/ready_to_regenerate(mob/user)
|
||||||
if(user && user.mind && user.mind.changeling && user.mind.changeling.purchasedpowers)
|
if(user && user.mind)
|
||||||
to_chat(user, "<span class='notice'>We are ready to revive.</span>")
|
var/datum/antagonist/changeling/C = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
user.mind.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/revive(null)
|
if(C && C.purchasedpowers)
|
||||||
|
to_chat(user, "<span class='notice'>We are ready to revive.</span>")
|
||||||
|
C.purchasedpowers += new /obj/effect/proc_holder/changeling/revive(null)
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/fakedeath/can_sting(mob/user)
|
/obj/effect/proc_holder/changeling/fakedeath/can_sting(mob/user)
|
||||||
if(user.status_flags & FAKEDEATH)
|
if(user.status_flags & FAKEDEATH)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
/obj/effect/proc_holder/changeling/hivemind_comms/on_purchase(mob/user, is_respec)
|
/obj/effect/proc_holder/changeling/hivemind_comms/on_purchase(mob/user, is_respec)
|
||||||
..()
|
..()
|
||||||
var/datum/changeling/changeling=user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
changeling.changeling_speak = 1
|
changeling.changeling_speak = 1
|
||||||
to_chat(user, "<i><font color=#800080>Use say \":g message\" to communicate with the other changelings.</font></i>")
|
to_chat(user, "<i><font color=#800080>Use say \":g message\" to communicate with the other changelings.</font></i>")
|
||||||
var/obj/effect/proc_holder/changeling/hivemind_upload/S1 = new
|
var/obj/effect/proc_holder/changeling/hivemind_upload/S1 = new
|
||||||
@@ -28,7 +28,7 @@ GLOBAL_LIST_EMPTY(hivemind_bank)
|
|||||||
dna_cost = -1
|
dna_cost = -1
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/user)
|
/obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/user)
|
||||||
var/datum/changeling/changeling = user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
var/list/names = list()
|
var/list/names = list()
|
||||||
for(var/datum/changelingprofile/prof in changeling.stored_profiles)
|
for(var/datum/changelingprofile/prof in changeling.stored_profiles)
|
||||||
if(!(prof in GLOB.hivemind_bank))
|
if(!(prof in GLOB.hivemind_bank))
|
||||||
@@ -61,7 +61,7 @@ GLOBAL_LIST_EMPTY(hivemind_bank)
|
|||||||
/obj/effect/proc_holder/changeling/hivemind_download/can_sting(mob/living/carbon/user)
|
/obj/effect/proc_holder/changeling/hivemind_download/can_sting(mob/living/carbon/user)
|
||||||
if(!..())
|
if(!..())
|
||||||
return
|
return
|
||||||
var/datum/changeling/changeling = user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
var/datum/changelingprofile/first_prof = changeling.stored_profiles[1]
|
var/datum/changelingprofile/first_prof = changeling.stored_profiles[1]
|
||||||
if(first_prof.name == user.real_name)//If our current DNA is the stalest, we gotta ditch it.
|
if(first_prof.name == user.real_name)//If our current DNA is the stalest, we gotta ditch it.
|
||||||
to_chat(user, "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>")
|
to_chat(user, "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>")
|
||||||
@@ -69,7 +69,7 @@ GLOBAL_LIST_EMPTY(hivemind_bank)
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/hivemind_download/sting_action(mob/user)
|
/obj/effect/proc_holder/changeling/hivemind_download/sting_action(mob/user)
|
||||||
var/datum/changeling/changeling = user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
var/list/names = list()
|
var/list/names = list()
|
||||||
for(var/datum/changelingprofile/prof in GLOB.hivemind_bank)
|
for(var/datum/changelingprofile/prof in GLOB.hivemind_bank)
|
||||||
if(!(prof in changeling.stored_profiles))
|
if(!(prof in changeling.stored_profiles))
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
//Transform into a human.
|
//Transform into a human.
|
||||||
/obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user)
|
/obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user)
|
||||||
var/datum/changeling/changeling = user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
var/list/names = list()
|
var/list/names = list()
|
||||||
for(var/datum/changelingprofile/prof in changeling.stored_profiles)
|
for(var/datum/changelingprofile/prof in changeling.stored_profiles)
|
||||||
names += "[prof.name]"
|
names += "[prof.name]"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
/obj/effect/proc_holder/changeling/linglink/can_sting(mob/living/carbon/user)
|
/obj/effect/proc_holder/changeling/linglink/can_sting(mob/living/carbon/user)
|
||||||
if(!..())
|
if(!..())
|
||||||
return
|
return
|
||||||
var/datum/changeling/changeling = user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
if(changeling.islinking)
|
if(changeling.islinking)
|
||||||
to_chat(user, "<span class='warning'>We have already formed a link with the victim!</span>")
|
to_chat(user, "<span class='warning'>We have already formed a link with the victim!</span>")
|
||||||
return
|
return
|
||||||
@@ -19,22 +19,23 @@
|
|||||||
to_chat(user, "<span class='warning'>We cannot link with this creature!</span>")
|
to_chat(user, "<span class='warning'>We cannot link with this creature!</span>")
|
||||||
return
|
return
|
||||||
var/mob/living/carbon/target = user.pulling
|
var/mob/living/carbon/target = user.pulling
|
||||||
|
|
||||||
if(!target.mind)
|
if(!target.mind)
|
||||||
to_chat(user, "<span class='warning'>The victim has no mind to link to!</span>")
|
to_chat(user, "<span class='warning'>The victim has no mind to link to!</span>")
|
||||||
return
|
return
|
||||||
if(target.stat == DEAD)
|
if(target.stat == DEAD)
|
||||||
to_chat(user, "<span class='warning'>The victim is dead, you cannot link to a dead mind!</span>")
|
to_chat(user, "<span class='warning'>The victim is dead, you cannot link to a dead mind!</span>")
|
||||||
return
|
return
|
||||||
if(target.mind.changeling)
|
if(target.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
to_chat(user, "<span class='warning'>The victim is already a part of the hivemind!</span>")
|
to_chat(user, "<span class='warning'>The victim is already a part of the hivemind!</span>")
|
||||||
return
|
return
|
||||||
if(user.grab_state <= GRAB_AGGRESSIVE)
|
if(user.grab_state <= GRAB_AGGRESSIVE)
|
||||||
to_chat(user, "<span class='warning'>We must have a tighter grip to link with this creature!</span>")
|
to_chat(user, "<span class='warning'>We must have a tighter grip to link with this creature!</span>")
|
||||||
return
|
return
|
||||||
return changeling.can_absorb_dna(user,target)
|
return changeling.can_absorb_dna(target)
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/linglink/sting_action(mob/user)
|
/obj/effect/proc_holder/changeling/linglink/sting_action(mob/user)
|
||||||
var/datum/changeling/changeling = user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
var/mob/living/carbon/human/target = user.pulling
|
var/mob/living/carbon/human/target = user.pulling
|
||||||
changeling.islinking = 1
|
changeling.islinking = 1
|
||||||
for(var/i in 1 to 3)
|
for(var/i in 1 to 3)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
// Fake Voice
|
// Fake Voice
|
||||||
/obj/effect/proc_holder/changeling/mimicvoice/sting_action(mob/user)
|
/obj/effect/proc_holder/changeling/mimicvoice/sting_action(mob/user)
|
||||||
var/datum/changeling/changeling=user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
if(changeling.mimicing)
|
if(changeling.mimicing)
|
||||||
changeling.mimicing = ""
|
changeling.mimicing = ""
|
||||||
changeling.chem_recharge_slowdown -= 0.5
|
changeling.chem_recharge_slowdown -= 0.5
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
|
|
||||||
//checks if we already have an organic suit and casts it off.
|
//checks if we already have an organic suit and casts it off.
|
||||||
/obj/effect/proc_holder/changeling/suit/proc/check_suit(mob/user)
|
/obj/effect/proc_holder/changeling/suit/proc/check_suit(mob/user)
|
||||||
var/datum/changeling/changeling = user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
if(!ishuman(user) || !changeling)
|
if(!ishuman(user) || !changeling)
|
||||||
return 1
|
return 1
|
||||||
var/mob/living/carbon/human/H = user
|
var/mob/living/carbon/human/H = user
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
user.equip_to_slot_if_possible(new suit_type(user), slot_wear_suit, 1, 1, 1)
|
user.equip_to_slot_if_possible(new suit_type(user), slot_wear_suit, 1, 1, 1)
|
||||||
user.equip_to_slot_if_possible(new helmet_type(user), slot_head, 1, 1, 1)
|
user.equip_to_slot_if_possible(new helmet_type(user), slot_head, 1, 1, 1)
|
||||||
|
|
||||||
var/datum/changeling/changeling = user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
changeling.chem_recharge_slowdown += recharge_slowdown
|
changeling.chem_recharge_slowdown += recharge_slowdown
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
@@ -385,7 +385,7 @@
|
|||||||
weapon_name_simple = "shield"
|
weapon_name_simple = "shield"
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/weapon/shield/sting_action(mob/user)
|
/obj/effect/proc_holder/changeling/weapon/shield/sting_action(mob/user)
|
||||||
var/datum/changeling/changeling = user.mind.changeling //So we can read the absorbedcount.
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) //So we can read the absorbedcount.
|
||||||
if(!changeling)
|
if(!changeling)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -25,11 +25,13 @@
|
|||||||
user.regenerate_limbs(0, list("head"))
|
user.regenerate_limbs(0, list("head"))
|
||||||
user.regenerate_organs()
|
user.regenerate_organs()
|
||||||
to_chat(user, "<span class='notice'>We have revived ourselves.</span>")
|
to_chat(user, "<span class='notice'>We have revived ourselves.</span>")
|
||||||
user.mind.changeling.purchasedpowers -= src
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
|
changeling.purchasedpowers -= src
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/revive/can_be_used_by(mob/user)
|
/obj/effect/proc_holder/changeling/revive/can_be_used_by(mob/user)
|
||||||
if((user.stat != DEAD) && !(user.status_flags & FAKEDEATH))
|
if((user.stat != DEAD) && !(user.status_flags & FAKEDEATH))
|
||||||
user.mind.changeling.purchasedpowers -= src
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
|
changeling.purchasedpowers -= src
|
||||||
return 0
|
return 0
|
||||||
. = ..()
|
. = ..()
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
for(var/mob/living/M in get_hearers_in_view(4, user))
|
for(var/mob/living/M in get_hearers_in_view(4, user))
|
||||||
if(iscarbon(M))
|
if(iscarbon(M))
|
||||||
var/mob/living/carbon/C = M
|
var/mob/living/carbon/C = M
|
||||||
if(!C.mind || !C.mind.changeling)
|
if(!C.mind || !C.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
C.adjustEarDamage(0, 30)
|
C.adjustEarDamage(0, 30)
|
||||||
C.confused += 25
|
C.confused += 25
|
||||||
C.Jitter(50)
|
C.Jitter(50)
|
||||||
|
|||||||
@@ -5,9 +5,12 @@
|
|||||||
|
|
||||||
/obj/effect/proc_holder/changeling/sting/Click()
|
/obj/effect/proc_holder/changeling/sting/Click()
|
||||||
var/mob/user = usr
|
var/mob/user = usr
|
||||||
if(!user || !user.mind || !user.mind.changeling)
|
if(!user || !user.mind)
|
||||||
return
|
return
|
||||||
if(!(user.mind.changeling.chosen_sting))
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
|
if(!changeling)
|
||||||
|
return
|
||||||
|
if(!changeling.chosen_sting)
|
||||||
set_sting(user)
|
set_sting(user)
|
||||||
else
|
else
|
||||||
unset_sting(user)
|
unset_sting(user)
|
||||||
@@ -15,41 +18,48 @@
|
|||||||
|
|
||||||
/obj/effect/proc_holder/changeling/sting/proc/set_sting(mob/user)
|
/obj/effect/proc_holder/changeling/sting/proc/set_sting(mob/user)
|
||||||
to_chat(user, "<span class='notice'>We prepare our sting, use alt+click or middle mouse button on target to sting them.</span>")
|
to_chat(user, "<span class='notice'>We prepare our sting, use alt+click or middle mouse button on target to sting them.</span>")
|
||||||
user.mind.changeling.chosen_sting = src
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
|
changeling.chosen_sting = src
|
||||||
|
|
||||||
user.hud_used.lingstingdisplay.icon_state = sting_icon
|
user.hud_used.lingstingdisplay.icon_state = sting_icon
|
||||||
user.hud_used.lingstingdisplay.invisibility = 0
|
user.hud_used.lingstingdisplay.invisibility = 0
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/sting/proc/unset_sting(mob/user)
|
/obj/effect/proc_holder/changeling/sting/proc/unset_sting(mob/user)
|
||||||
to_chat(user, "<span class='warning'>We retract our sting, we can't sting anyone for now.</span>")
|
to_chat(user, "<span class='warning'>We retract our sting, we can't sting anyone for now.</span>")
|
||||||
user.mind.changeling.chosen_sting = null
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
|
changeling.chosen_sting = null
|
||||||
|
|
||||||
user.hud_used.lingstingdisplay.icon_state = null
|
user.hud_used.lingstingdisplay.icon_state = null
|
||||||
user.hud_used.lingstingdisplay.invisibility = INVISIBILITY_ABSTRACT
|
user.hud_used.lingstingdisplay.invisibility = INVISIBILITY_ABSTRACT
|
||||||
|
|
||||||
/mob/living/carbon/proc/unset_sting()
|
/mob/living/carbon/proc/unset_sting()
|
||||||
if(mind && mind.changeling && mind.changeling.chosen_sting)
|
if(mind)
|
||||||
src.mind.changeling.chosen_sting.unset_sting(src)
|
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
|
if(changeling && changeling.chosen_sting)
|
||||||
|
changeling.chosen_sting.unset_sting(src)
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/sting/can_sting(mob/user, mob/target)
|
/obj/effect/proc_holder/changeling/sting/can_sting(mob/user, mob/target)
|
||||||
if(!..())
|
if(!..())
|
||||||
return
|
return
|
||||||
if(!user.mind.changeling.chosen_sting)
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
|
if(!changeling.chosen_sting)
|
||||||
to_chat(user, "We haven't prepared our sting yet!")
|
to_chat(user, "We haven't prepared our sting yet!")
|
||||||
if(!iscarbon(target))
|
if(!iscarbon(target))
|
||||||
return
|
return
|
||||||
if(!isturf(user.loc))
|
if(!isturf(user.loc))
|
||||||
return
|
return
|
||||||
if(!AStar(user, target.loc, /turf/proc/Distance, user.mind.changeling.sting_range, simulated_only = 0))
|
if(!AStar(user, target.loc, /turf/proc/Distance, changeling.sting_range, simulated_only = 0))
|
||||||
return
|
return
|
||||||
if(target.mind && target.mind.changeling)
|
if(target.mind && target.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
sting_feedback(user, target)
|
sting_feedback(user, target)
|
||||||
user.mind.changeling.chem_charges -= chemical_cost
|
changeling.chem_charges -= chemical_cost //??
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/sting/sting_feedback(mob/user, mob/target)
|
/obj/effect/proc_holder/changeling/sting/sting_feedback(mob/user, mob/target)
|
||||||
if(!target)
|
if(!target)
|
||||||
return
|
return
|
||||||
to_chat(user, "<span class='notice'>We stealthily sting [target.name].</span>")
|
to_chat(user, "<span class='notice'>We stealthily sting [target.name].</span>")
|
||||||
if(target.mind && target.mind.changeling)
|
if(target.mind && target.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
to_chat(target, "<span class='warning'>You feel a tiny prick.</span>")
|
to_chat(target, "<span class='warning'>You feel a tiny prick.</span>")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -65,7 +75,7 @@
|
|||||||
|
|
||||||
/obj/effect/proc_holder/changeling/sting/transformation/Click()
|
/obj/effect/proc_holder/changeling/sting/transformation/Click()
|
||||||
var/mob/user = usr
|
var/mob/user = usr
|
||||||
var/datum/changeling/changeling = user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
if(changeling.chosen_sting)
|
if(changeling.chosen_sting)
|
||||||
unset_sting(user)
|
unset_sting(user)
|
||||||
return
|
return
|
||||||
@@ -163,12 +173,14 @@
|
|||||||
|
|
||||||
/obj/effect/proc_holder/changeling/sting/extract_dna/can_sting(mob/user, mob/target)
|
/obj/effect/proc_holder/changeling/sting/extract_dna/can_sting(mob/user, mob/target)
|
||||||
if(..())
|
if(..())
|
||||||
return user.mind.changeling.can_absorb_dna(user, target)
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
|
return changeling.can_absorb_dna(target)
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/sting/extract_dna/sting_action(mob/user, mob/living/carbon/human/target)
|
/obj/effect/proc_holder/changeling/sting/extract_dna/sting_action(mob/user, mob/living/carbon/human/target)
|
||||||
add_logs(user, target, "stung", "extraction sting")
|
add_logs(user, target, "stung", "extraction sting")
|
||||||
if(!(user.mind.changeling.has_dna(target.dna)))
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
user.mind.changeling.add_new_profile(target, user)
|
if(!(changeling.has_dna(target.dna)))
|
||||||
|
changeling.add_new_profile(target)
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
/obj/effect/proc_holder/changeling/sting/mute
|
/obj/effect/proc_holder/changeling/sting/mute
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
flags_1 = NODROP_1
|
flags_1 = NODROP_1
|
||||||
|
|
||||||
/obj/item/clothing/glasses/changeling/attack_hand(mob/user)
|
/obj/item/clothing/glasses/changeling/attack_hand(mob/user)
|
||||||
if(loc == user && user.mind && user.mind.changeling)
|
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
return
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
flags_1 = NODROP_1
|
flags_1 = NODROP_1
|
||||||
|
|
||||||
/obj/item/clothing/under/changeling/attack_hand(mob/user)
|
/obj/item/clothing/under/changeling/attack_hand(mob/user)
|
||||||
if(loc == user && user.mind && user.mind.changeling)
|
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
return
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
allowed = list(/obj/item/changeling)
|
allowed = list(/obj/item/changeling)
|
||||||
|
|
||||||
/obj/item/clothing/suit/changeling/attack_hand(mob/user)
|
/obj/item/clothing/suit/changeling/attack_hand(mob/user)
|
||||||
if(loc == user && user.mind && user.mind.changeling)
|
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
return
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
flags_1 = NODROP_1
|
flags_1 = NODROP_1
|
||||||
|
|
||||||
/obj/item/clothing/head/changeling/attack_hand(mob/user)
|
/obj/item/clothing/head/changeling/attack_hand(mob/user)
|
||||||
if(loc == user && user.mind && user.mind.changeling)
|
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
return
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
flags_1 = NODROP_1
|
flags_1 = NODROP_1
|
||||||
|
|
||||||
/obj/item/clothing/shoes/changeling/attack_hand(mob/user)
|
/obj/item/clothing/shoes/changeling/attack_hand(mob/user)
|
||||||
if(loc == user && user.mind && user.mind.changeling)
|
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
return
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
flags_1 = NODROP_1
|
flags_1 = NODROP_1
|
||||||
|
|
||||||
/obj/item/clothing/gloves/changeling/attack_hand(mob/user)
|
/obj/item/clothing/gloves/changeling/attack_hand(mob/user)
|
||||||
if(loc == user && user.mind && user.mind.changeling)
|
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
return
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
flags_1 = NODROP_1
|
flags_1 = NODROP_1
|
||||||
|
|
||||||
/obj/item/clothing/mask/changeling/attack_hand(mob/user)
|
/obj/item/clothing/mask/changeling/attack_hand(mob/user)
|
||||||
if(loc == user && user.mind && user.mind.changeling)
|
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
return
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
allowed = list(/obj/item/changeling)
|
allowed = list(/obj/item/changeling)
|
||||||
|
|
||||||
/obj/item/changeling/attack_hand(mob/user)
|
/obj/item/changeling/attack_hand(mob/user)
|
||||||
if(loc == user && user.mind && user.mind.changeling)
|
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
return
|
||||||
@@ -99,8 +99,8 @@
|
|||||||
|
|
||||||
//Change our DNA to that of somebody we've absorbed.
|
//Change our DNA to that of somebody we've absorbed.
|
||||||
/obj/effect/proc_holder/changeling/transform/sting_action(mob/living/carbon/human/user)
|
/obj/effect/proc_holder/changeling/transform/sting_action(mob/living/carbon/human/user)
|
||||||
var/datum/changeling/changeling = user.mind.changeling
|
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
var/datum/changelingprofile/chosen_prof = changeling.select_dna("Select the target DNA: ", "Target DNA", user)
|
var/datum/changelingprofile/chosen_prof = changeling.select_dna("Select the target DNA: ", "Target DNA")
|
||||||
|
|
||||||
if(!chosen_prof)
|
if(!chosen_prof)
|
||||||
return
|
return
|
||||||
@@ -108,7 +108,10 @@
|
|||||||
changeling_transform(user, chosen_prof)
|
changeling_transform(user, chosen_prof)
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
/datum/changeling/proc/select_dna(var/prompt, var/title, var/mob/living/carbon/user)
|
/datum/antagonist/changeling/proc/select_dna(var/prompt, var/title)
|
||||||
|
var/mob/living/carbon/user = owner.current
|
||||||
|
if(!istype(user))
|
||||||
|
return
|
||||||
var/list/names = list("Drop Flesh Disguise")
|
var/list/names = list("Drop Flesh Disguise")
|
||||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||||
names += "[prof.name]"
|
names += "[prof.name]"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
reroll_friendly = 1
|
reroll_friendly = 1
|
||||||
|
|
||||||
var/list/possible_changelings = list()
|
var/list/possible_changelings = list()
|
||||||
|
var/list/changelings = list()
|
||||||
var/const/changeling_amount = 1 //hard limit on changelings if scaling is turned off
|
var/const/changeling_amount = 1 //hard limit on changelings if scaling is turned off
|
||||||
|
|
||||||
/datum/game_mode/traitor/changeling/announce()
|
/datum/game_mode/traitor/changeling/announce()
|
||||||
@@ -57,25 +58,22 @@
|
|||||||
|
|
||||||
/datum/game_mode/traitor/changeling/post_setup()
|
/datum/game_mode/traitor/changeling/post_setup()
|
||||||
for(var/datum/mind/changeling in changelings)
|
for(var/datum/mind/changeling in changelings)
|
||||||
changeling.current.make_changeling()
|
changeling.add_antag_datum(/datum/antagonist/changeling)
|
||||||
forge_changeling_objectives(changeling)
|
return ..()
|
||||||
greet_changeling(changeling)
|
|
||||||
SSticker.mode.update_changeling_icons_added(changeling)
|
|
||||||
..()
|
|
||||||
return
|
|
||||||
|
|
||||||
/datum/game_mode/traitor/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners
|
/datum/game_mode/traitor/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners
|
||||||
var/csc = CONFIG_GET(number/changeling_scaling_coeff)
|
var/csc = CONFIG_GET(number/changeling_scaling_coeff)
|
||||||
var/changelingcap = min( round(GLOB.joined_player_list.len / (csc * 4)) + 2, round(GLOB.joined_player_list.len / (csc * 2)))
|
var/changelingcap = min( round(GLOB.joined_player_list.len / (csc * 4)) + 2, round(GLOB.joined_player_list.len / (csc * 2)))
|
||||||
if(SSticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists
|
if(changelings.len >= changelingcap) //Caps number of latejoin antagonists
|
||||||
..()
|
..()
|
||||||
return
|
return
|
||||||
if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 / (csc * 4)))
|
if(changelings.len <= (changelingcap - 2) || prob(100 / (csc * 4)))
|
||||||
if(ROLE_CHANGELING in character.client.prefs.be_special)
|
if(ROLE_CHANGELING in character.client.prefs.be_special)
|
||||||
if(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate"))
|
if(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate"))
|
||||||
if(age_check(character.client))
|
if(age_check(character.client))
|
||||||
if(!(character.job in restricted_jobs))
|
if(!(character.job in restricted_jobs))
|
||||||
character.mind.make_Changling()
|
character.mind.make_Changling()
|
||||||
|
changelings += character.mind
|
||||||
..()
|
..()
|
||||||
|
|
||||||
/datum/game_mode/traitor/changeling/generate_report()
|
/datum/game_mode/traitor/changeling/generate_report()
|
||||||
|
|||||||
@@ -477,7 +477,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
|||||||
if(ishuman(L))
|
if(ishuman(L))
|
||||||
var/mob/living/carbon/human/H = L
|
var/mob/living/carbon/human/H = L
|
||||||
species = "<span class='notice'>[H.dna.species.name]</span>"
|
species = "<span class='notice'>[H.dna.species.name]</span>"
|
||||||
if(L.mind && L.mind.changeling)
|
if(L.mind && L.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||||
species = "<span class='warning'>Changeling lifeform</span>"
|
species = "<span class='warning'>Changeling lifeform</span>"
|
||||||
var/obj/item/organ/heart/gland/temp = locate() in H.internal_organs
|
var/obj/item/organ/heart/gland/temp = locate() in H.internal_organs
|
||||||
if(temp)
|
if(temp)
|
||||||
|
|||||||
@@ -586,7 +586,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
|||||||
n_p ++
|
n_p ++
|
||||||
else if (SSticker.IsRoundInProgress())
|
else if (SSticker.IsRoundInProgress())
|
||||||
for(var/mob/living/carbon/human/P in GLOB.player_list)
|
for(var/mob/living/carbon/human/P in GLOB.player_list)
|
||||||
if(P.client && !(P.mind in SSticker.mode.changelings) && !(P.mind in owners))
|
if(P.client && !(P.mind.has_antag_datum(/datum/antagonist/changeling)) && !(P.mind in owners))
|
||||||
n_p ++
|
n_p ++
|
||||||
target_amount = min(target_amount, n_p)
|
target_amount = min(target_amount, n_p)
|
||||||
|
|
||||||
@@ -597,9 +597,12 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
|||||||
var/list/datum/mind/owners = get_owners()
|
var/list/datum/mind/owners = get_owners()
|
||||||
var/absorbedcount = 0
|
var/absorbedcount = 0
|
||||||
for(var/datum/mind/M in owners)
|
for(var/datum/mind/M in owners)
|
||||||
if(!owner || !owner.changeling || !owner.changeling.stored_profiles)
|
if(!M)
|
||||||
continue
|
continue
|
||||||
absorbedcount += M.changeling.absorbedcount
|
var/datum/antagonist/changeling/changeling = M.has_antag_datum(/datum/antagonist/changeling)
|
||||||
|
if(!changeling || !changeling.stored_profiles)
|
||||||
|
continue
|
||||||
|
absorbedcount += changeling.absorbedcount
|
||||||
return absorbedcount >= target_amount
|
return absorbedcount >= target_amount
|
||||||
|
|
||||||
|
|
||||||
@@ -696,10 +699,11 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
|||||||
if("Chief Medical Officer")
|
if("Chief Medical Officer")
|
||||||
department_string = "medical"
|
department_string = "medical"
|
||||||
|
|
||||||
var/ling_count = SSticker.mode.changelings
|
var/list/lings = get_antagonists(/datum/antagonist/changeling,TRUE)
|
||||||
|
var/ling_count = lings.len
|
||||||
|
|
||||||
for(var/datum/mind/M in SSticker.minds)
|
for(var/datum/mind/M in SSticker.minds)
|
||||||
if(M in SSticker.mode.changelings)
|
if(M in lings)
|
||||||
continue
|
continue
|
||||||
if(department_head in get_department_heads(M.assigned_role))
|
if(department_head in get_department_heads(M.assigned_role))
|
||||||
if(ling_count)
|
if(ling_count)
|
||||||
@@ -723,13 +727,13 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
|||||||
//Needed heads is between min_lings and the maximum possible amount of command roles
|
//Needed heads is between min_lings and the maximum possible amount of command roles
|
||||||
//So at the time of writing, rand(3,6), it's also capped by the amount of lings there are
|
//So at the time of writing, rand(3,6), it's also capped by the amount of lings there are
|
||||||
//Because you can't fill 6 head roles with 3 lings
|
//Because you can't fill 6 head roles with 3 lings
|
||||||
|
var/list/lings = get_antagonists(/datum/antagonist/changeling,TRUE)
|
||||||
var/needed_heads = rand(min_lings,GLOB.command_positions.len)
|
var/needed_heads = rand(min_lings,GLOB.command_positions.len)
|
||||||
needed_heads = min(SSticker.mode.changelings.len,needed_heads)
|
needed_heads = min(lings.len,needed_heads)
|
||||||
|
|
||||||
var/list/heads = SSjob.get_living_heads()
|
var/list/heads = SSjob.get_living_heads()
|
||||||
for(var/datum/mind/head in heads)
|
for(var/datum/mind/head in heads)
|
||||||
if(head in SSticker.mode.changelings) //Looking at you HoP.
|
if(head in lings) //Looking at you HoP.
|
||||||
continue
|
continue
|
||||||
if(needed_heads)
|
if(needed_heads)
|
||||||
department_minds += head
|
department_minds += head
|
||||||
@@ -789,7 +793,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
|||||||
|
|
||||||
//Check each department member's mind to see if any of them made it to centcom alive, if they did it's an automatic fail
|
//Check each department member's mind to see if any of them made it to centcom alive, if they did it's an automatic fail
|
||||||
for(var/datum/mind/M in department_minds)
|
for(var/datum/mind/M in department_minds)
|
||||||
if(M in SSticker.mode.changelings) //Lings aren't picked for this, but let's be safe
|
if(M.has_antag_datum(/datum/antagonist/changeling)) //Lings aren't picked for this, but let's be safe
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if(M.current)
|
if(M.current)
|
||||||
@@ -800,7 +804,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
|||||||
//Check each staff member has been replaced, by cross referencing changeling minds, changeling current dna, the staff minds and their original DNA names
|
//Check each staff member has been replaced, by cross referencing changeling minds, changeling current dna, the staff minds and their original DNA names
|
||||||
var/success = 0
|
var/success = 0
|
||||||
changelings:
|
changelings:
|
||||||
for(var/datum/mind/changeling in SSticker.mode.changelings)
|
for(var/datum/mind/changeling in get_antagonists(/datum/antagonist/changeling,TRUE))
|
||||||
if(success >= department_minds.len) //We did it, stop here!
|
if(success >= department_minds.len) //We did it, stop here!
|
||||||
return 1
|
return 1
|
||||||
if(ishuman(changeling.current))
|
if(ishuman(changeling.current))
|
||||||
|
|||||||
@@ -162,11 +162,6 @@
|
|||||||
|
|
||||||
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
|
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
|
||||||
|
|
||||||
if(clonemind.changeling)
|
|
||||||
var/obj/item/organ/brain/B = H.getorganslot(ORGAN_SLOT_BRAIN)
|
|
||||||
B.vital = FALSE
|
|
||||||
B.decoy_override = TRUE
|
|
||||||
|
|
||||||
H.hardset_dna(ui, se, H.real_name, null, mrace, features)
|
H.hardset_dna(ui, se, H.real_name, null, mrace, features)
|
||||||
|
|
||||||
if(efficiency > 2)
|
if(efficiency > 2)
|
||||||
|
|||||||
@@ -442,12 +442,15 @@
|
|||||||
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
|
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
|
||||||
dat += "</table>"
|
dat += "</table>"
|
||||||
|
|
||||||
if(SSticker.mode.changelings.len > 0)
|
|
||||||
|
var/list/lings = get_antagonists(/datum/antagonist/changeling)
|
||||||
|
if(lings.len > 0)
|
||||||
dat += "<br><table cellspacing=5><tr><td><B>Changelings</B></td><td></td><td></td></tr>"
|
dat += "<br><table cellspacing=5><tr><td><B>Changelings</B></td><td></td><td></td></tr>"
|
||||||
for(var/datum/mind/changeling in SSticker.mode.changelings)
|
for(var/datum/mind/changeling in lings)
|
||||||
|
var/datum/antagonist/changeling/lingantag = changeling.has_antag_datum(/datum/antagonist/changeling)
|
||||||
var/mob/M = changeling.current
|
var/mob/M = changeling.current
|
||||||
if(M)
|
if(M)
|
||||||
dat += "<tr><td>[M.mind.changeling.changelingID] as <a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(M)]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
dat += "<tr><td>[lingantag.changelingID]([lingantag.name]) as <a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(M)]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(M)]'>FLW</a></td>"
|
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(M)]'>FLW</a></td>"
|
||||||
dat += "<td><A HREF='?_src_=holder;[HrefToken()];traitor=[REF(M)]'>Show Objective</A></td></tr>"
|
dat += "<td><A HREF='?_src_=holder;[HrefToken()];traitor=[REF(M)]'>Show Objective</A></td></tr>"
|
||||||
|
|||||||
@@ -106,8 +106,6 @@
|
|||||||
|
|
||||||
|
|
||||||
/obj/item/clothing/Destroy()
|
/obj/item/clothing/Destroy()
|
||||||
if(isliving(loc))
|
|
||||||
dropped(loc)
|
|
||||||
if(pockets)
|
if(pockets)
|
||||||
qdel(pockets)
|
qdel(pockets)
|
||||||
pockets = null
|
pockets = null
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
name = "brain"
|
name = "brain"
|
||||||
|
|
||||||
if(C.mind && C.mind.changeling && !no_id_transfer) //congrats, you're trapped in a body you don't control
|
if(C.mind && C.mind.has_antag_datum(/datum/antagonist/changeling) && !no_id_transfer) //congrats, you're trapped in a body you don't control
|
||||||
if(brainmob && !(C.stat == DEAD || (C.status_flags & FAKEDEATH)))
|
if(brainmob && !(C.stat == DEAD || (C.status_flags & FAKEDEATH)))
|
||||||
to_chat(brainmob, "<span class = danger>You can't feel your body! You're still just a brain!</span>")
|
to_chat(brainmob, "<span class = danger>You can't feel your body! You're still just a brain!</span>")
|
||||||
loc = C
|
loc = C
|
||||||
|
|||||||
@@ -770,7 +770,7 @@
|
|||||||
|
|
||||||
/mob/living/carbon/can_be_revived()
|
/mob/living/carbon/can_be_revived()
|
||||||
. = ..()
|
. = ..()
|
||||||
if(!getorgan(/obj/item/organ/brain) && (!mind || !mind.changeling))
|
if(!getorgan(/obj/item/organ/brain) && (!mind || !mind.has_antag_datum(/datum/antagonist/changeling)))
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
/mob/living/carbon/harvest(mob/living/user)
|
/mob/living/carbon/harvest(mob/living/user)
|
||||||
|
|||||||
@@ -56,9 +56,10 @@
|
|||||||
stat("Distribution Pressure", internal.distribute_pressure)
|
stat("Distribution Pressure", internal.distribute_pressure)
|
||||||
|
|
||||||
if(mind)
|
if(mind)
|
||||||
if(mind.changeling)
|
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
|
if(changeling)
|
||||||
stat("Absorbed DNA", mind.changeling.absorbedcount)
|
stat("Chemical Storage", "[changeling.chem_charges]/[changeling.chem_storage]")
|
||||||
|
stat("Absorbed DNA", changeling.absorbedcount)
|
||||||
|
|
||||||
|
|
||||||
//NINJACODE
|
//NINJACODE
|
||||||
|
|||||||
@@ -39,8 +39,10 @@
|
|||||||
return real_name
|
return real_name
|
||||||
else
|
else
|
||||||
return real_name
|
return real_name
|
||||||
if(mind && mind.changeling && mind.changeling.mimicing)
|
if(mind)
|
||||||
return mind.changeling.mimicing
|
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
|
if(changeling && changeling.mimicing )
|
||||||
|
return changeling.mimicing
|
||||||
if(GetSpecialVoice())
|
if(GetSpecialVoice())
|
||||||
return GetSpecialVoice()
|
return GetSpecialVoice()
|
||||||
return real_name
|
return real_name
|
||||||
|
|||||||
@@ -251,12 +251,14 @@
|
|||||||
if(stat != DEAD)
|
if(stat != DEAD)
|
||||||
D.stage_act()
|
D.stage_act()
|
||||||
|
|
||||||
|
//todo generalize this and move hud out
|
||||||
/mob/living/carbon/proc/handle_changeling()
|
/mob/living/carbon/proc/handle_changeling()
|
||||||
if(mind && hud_used && hud_used.lingchemdisplay)
|
if(mind && hud_used && hud_used.lingchemdisplay)
|
||||||
if(mind.changeling)
|
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
mind.changeling.regenerate(src)
|
if(changeling)
|
||||||
|
changeling.regenerate()
|
||||||
hud_used.lingchemdisplay.invisibility = 0
|
hud_used.lingchemdisplay.invisibility = 0
|
||||||
hud_used.lingchemdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#dd66dd'>[round(mind.changeling.chem_charges)]</font></div>"
|
hud_used.lingchemdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#dd66dd'>[round(changeling.chem_charges)]</font></div>"
|
||||||
else
|
else
|
||||||
hud_used.lingchemdisplay.invisibility = INVISIBILITY_ABSTRACT
|
hud_used.lingchemdisplay.invisibility = INVISIBILITY_ABSTRACT
|
||||||
|
|
||||||
|
|||||||
@@ -74,9 +74,10 @@
|
|||||||
stat(null, "Intent: [a_intent]")
|
stat(null, "Intent: [a_intent]")
|
||||||
stat(null, "Move Mode: [m_intent]")
|
stat(null, "Move Mode: [m_intent]")
|
||||||
if(client && mind)
|
if(client && mind)
|
||||||
if(mind.changeling)
|
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
|
if(changeling)
|
||||||
stat("Absorbed DNA", mind.changeling.absorbedcount)
|
stat("Chemical Storage", "[changeling.chem_charges]/[changeling.chem_storage]")
|
||||||
|
stat("Absorbed DNA", changeling.absorbedcount)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -336,8 +336,9 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
|||||||
if(prob(40))
|
if(prob(40))
|
||||||
to_chat(M, "<i><font color=#800080>We can faintly sense an outsider trying to communicate through the hivemind...</font></i>")
|
to_chat(M, "<i><font color=#800080>We can faintly sense an outsider trying to communicate through the hivemind...</font></i>")
|
||||||
if(2)
|
if(2)
|
||||||
var/msg = "<i><font color=#800080><b>[mind.changeling.changelingID]:</b> [message]</font></i>"
|
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
log_talk(src,"[mind.changeling.changelingID]/[key] : [message]",LOGSAY)
|
var/msg = "<i><font color=#800080><b>[changeling.changelingID]:</b> [message]</font></i>"
|
||||||
|
log_talk(src,"[changeling.changelingID]/[key] : [message]",LOGSAY)
|
||||||
for(var/_M in GLOB.mob_list)
|
for(var/_M in GLOB.mob_list)
|
||||||
var/mob/M = _M
|
var/mob/M = _M
|
||||||
if(M in GLOB.dead_mob_list)
|
if(M in GLOB.dead_mob_list)
|
||||||
@@ -413,10 +414,12 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
/mob/living/lingcheck() //1 is ling w/ no hivemind. 2 is ling w/hivemind. 3 is ling victim being linked into hivemind.
|
/mob/living/lingcheck() //1 is ling w/ no hivemind. 2 is ling w/hivemind. 3 is ling victim being linked into hivemind.
|
||||||
if(mind && mind.changeling)
|
if(mind)
|
||||||
if(mind.changeling.changeling_speak)
|
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
return 2
|
if(changeling)
|
||||||
return 1
|
if(changeling.changeling_speak)
|
||||||
|
return 2
|
||||||
|
return 1
|
||||||
if(mind && mind.linglink)
|
if(mind && mind.linglink)
|
||||||
return 3
|
return 3
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -485,7 +485,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
|||||||
if(guardians.len && !allowmultiple)
|
if(guardians.len && !allowmultiple)
|
||||||
to_chat(user, "<span class='holoparasite'>You already have a [mob_name]!</span>")
|
to_chat(user, "<span class='holoparasite'>You already have a [mob_name]!</span>")
|
||||||
return
|
return
|
||||||
if(user.mind && user.mind.changeling && !allowling)
|
if(user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling) && !allowling)
|
||||||
to_chat(user, "[ling_failure]")
|
to_chat(user, "[ling_failure]")
|
||||||
return
|
return
|
||||||
if(used == TRUE)
|
if(used == TRUE)
|
||||||
|
|||||||
@@ -74,12 +74,13 @@
|
|||||||
|
|
||||||
if(origin && origin.current && (origin.current.stat == DEAD))
|
if(origin && origin.current && (origin.current.stat == DEAD))
|
||||||
origin.transfer_to(M)
|
origin.transfer_to(M)
|
||||||
if(!origin.changeling)
|
var/datum/antagonist/changeling/C = origin.has_antag_datum(/datum/antagonist/changeling)
|
||||||
M.make_changeling()
|
if(!C)
|
||||||
if(origin.changeling.can_absorb_dna(M, owner))
|
C = origin.add_antag_datum(/datum/antagonist/changeling/xenobio)
|
||||||
origin.changeling.add_new_profile(owner, M)
|
if(C.can_absorb_dna(owner))
|
||||||
|
C.add_new_profile(owner)
|
||||||
|
|
||||||
origin.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null)
|
C.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null)
|
||||||
M.key = origin.key
|
M.key = origin.key
|
||||||
owner.gib()
|
owner.gib()
|
||||||
|
|
||||||
|
|||||||
@@ -644,8 +644,9 @@
|
|||||||
|
|
||||||
if(mind)
|
if(mind)
|
||||||
add_spells_to_statpanel(mind.spell_list)
|
add_spells_to_statpanel(mind.spell_list)
|
||||||
if(mind.changeling)
|
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
add_stings_to_statpanel(mind.changeling.purchasedpowers)
|
if(changeling)
|
||||||
|
add_stings_to_statpanel(changeling.purchasedpowers)
|
||||||
add_spells_to_statpanel(mob_spell_list)
|
add_spells_to_statpanel(mob_spell_list)
|
||||||
|
|
||||||
/mob/proc/add_spells_to_statpanel(list/spells)
|
/mob/proc/add_spells_to_statpanel(list/spells)
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
|||||||
if(M.mind in SSticker.mode.syndicates)
|
if(M.mind in SSticker.mode.syndicates)
|
||||||
return 2
|
return 2
|
||||||
if("changeling")
|
if("changeling")
|
||||||
if(M.mind in SSticker.mode.changelings)
|
if(M.mind.has_antag_datum(/datum/antagonist/changeling,TRUE))
|
||||||
return 2
|
return 2
|
||||||
if("wizard")
|
if("wizard")
|
||||||
if(iswizard(M))
|
if(iswizard(M))
|
||||||
|
|||||||
@@ -94,8 +94,9 @@
|
|||||||
|
|
||||||
if(mind)
|
if(mind)
|
||||||
mind.transfer_to(O)
|
mind.transfer_to(O)
|
||||||
if(O.mind.changeling)
|
var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
O.mind.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null)
|
if(changeling)
|
||||||
|
changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null)
|
||||||
|
|
||||||
for(var/X in internal_organs)
|
for(var/X in internal_organs)
|
||||||
var/obj/item/organ/I = X
|
var/obj/item/organ/I = X
|
||||||
@@ -118,7 +119,7 @@
|
|||||||
for(var/X in O.internal_organs)
|
for(var/X in O.internal_organs)
|
||||||
var/obj/item/organ/G = X
|
var/obj/item/organ/G = X
|
||||||
if(BP.body_zone == check_zone(G.zone))
|
if(BP.body_zone == check_zone(G.zone))
|
||||||
if(mind && mind.changeling && istype(G, /obj/item/organ/brain))
|
if(mind && mind.has_antag_datum(/datum/antagonist/changeling) && istype(G, /obj/item/organ/brain))
|
||||||
continue //so headless changelings don't lose their brain when transforming
|
continue //so headless changelings don't lose their brain when transforming
|
||||||
qdel(G) //we lose the organs in the missing limbs
|
qdel(G) //we lose the organs in the missing limbs
|
||||||
qdel(BP)
|
qdel(BP)
|
||||||
@@ -126,8 +127,9 @@
|
|||||||
//transfer mind if we didn't yet
|
//transfer mind if we didn't yet
|
||||||
if(mind)
|
if(mind)
|
||||||
mind.transfer_to(O)
|
mind.transfer_to(O)
|
||||||
if(O.mind.changeling)
|
var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
O.mind.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null)
|
if(changeling)
|
||||||
|
changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null)
|
||||||
|
|
||||||
|
|
||||||
if (tr_flags & TR_DEFAULTMSG)
|
if (tr_flags & TR_DEFAULTMSG)
|
||||||
@@ -248,9 +250,10 @@
|
|||||||
|
|
||||||
if(mind)
|
if(mind)
|
||||||
mind.transfer_to(O)
|
mind.transfer_to(O)
|
||||||
if(O.mind.changeling)
|
var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
for(var/obj/effect/proc_holder/changeling/humanform/HF in O.mind.changeling.purchasedpowers)
|
if(changeling)
|
||||||
O.mind.changeling.purchasedpowers -= HF
|
for(var/obj/effect/proc_holder/changeling/humanform/HF in changeling.purchasedpowers)
|
||||||
|
changeling.purchasedpowers -= HF
|
||||||
|
|
||||||
for(var/X in internal_organs)
|
for(var/X in internal_organs)
|
||||||
var/obj/item/organ/I = X
|
var/obj/item/organ/I = X
|
||||||
@@ -274,16 +277,17 @@
|
|||||||
for(var/X in O.internal_organs)
|
for(var/X in O.internal_organs)
|
||||||
var/obj/item/organ/G = X
|
var/obj/item/organ/G = X
|
||||||
if(BP.body_zone == check_zone(G.zone))
|
if(BP.body_zone == check_zone(G.zone))
|
||||||
if(mind && mind.changeling && istype(G, /obj/item/organ/brain))
|
if(mind && mind.has_antag_datum(/datum/antagonist/changeling) && istype(G, /obj/item/organ/brain))
|
||||||
continue //so headless changelings don't lose their brain when transforming
|
continue //so headless changelings don't lose their brain when transforming
|
||||||
qdel(G) //we lose the organs in the missing limbs
|
qdel(G) //we lose the organs in the missing limbs
|
||||||
qdel(BP)
|
qdel(BP)
|
||||||
|
|
||||||
if(mind)
|
if(mind)
|
||||||
mind.transfer_to(O)
|
mind.transfer_to(O)
|
||||||
if(O.mind.changeling)
|
var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
for(var/obj/effect/proc_holder/changeling/humanform/HF in O.mind.changeling.purchasedpowers)
|
if(changeling)
|
||||||
O.mind.changeling.purchasedpowers -= HF
|
for(var/obj/effect/proc_holder/changeling/humanform/HF in changeling.purchasedpowers)
|
||||||
|
changeling.purchasedpowers -= HF
|
||||||
|
|
||||||
O.a_intent = INTENT_HELP
|
O.a_intent = INTENT_HELP
|
||||||
if (tr_flags & TR_DEFAULTMSG)
|
if (tr_flags & TR_DEFAULTMSG)
|
||||||
|
|||||||
@@ -957,9 +957,11 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
|||||||
glass_desc = "A stingy drink."
|
glass_desc = "A stingy drink."
|
||||||
|
|
||||||
/datum/reagent/consumable/ethanol/changelingsting/on_mob_life(mob/living/M)
|
/datum/reagent/consumable/ethanol/changelingsting/on_mob_life(mob/living/M)
|
||||||
if(M.mind && M.mind.changeling) //Changeling Sting assists in the recharging of changeling chemicals.
|
if(M.mind) //Changeling Sting assists in the recharging of changeling chemicals.
|
||||||
M.mind.changeling.chem_charges += metabolization_rate
|
var/datum/antagonist/changeling/changeling = M.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||||
M.mind.changeling.chem_charges = Clamp(M.mind.changeling.chem_charges, 0, M.mind.changeling.chem_storage)
|
if(changeling)
|
||||||
|
changeling.chem_charges += metabolization_rate
|
||||||
|
changeling.chem_charges = Clamp(changeling.chem_charges, 0, changeling.chem_storage)
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/datum/reagent/consumable/ethanol/irishcarbomb
|
/datum/reagent/consumable/ethanol/irishcarbomb
|
||||||
|
|||||||
@@ -266,6 +266,7 @@
|
|||||||
#include "code\datums\antagonists\abductor.dm"
|
#include "code\datums\antagonists\abductor.dm"
|
||||||
#include "code\datums\antagonists\antag_datum.dm"
|
#include "code\datums\antagonists\antag_datum.dm"
|
||||||
#include "code\datums\antagonists\brother.dm"
|
#include "code\datums\antagonists\brother.dm"
|
||||||
|
#include "code\datums\antagonists\changeling.dm"
|
||||||
#include "code\datums\antagonists\clockcult.dm"
|
#include "code\datums\antagonists\clockcult.dm"
|
||||||
#include "code\datums\antagonists\cult.dm"
|
#include "code\datums\antagonists\cult.dm"
|
||||||
#include "code\datums\antagonists\datum_traitor.dm"
|
#include "code\datums\antagonists\datum_traitor.dm"
|
||||||
@@ -426,7 +427,6 @@
|
|||||||
#include "code\game\gamemodes\changeling\cellular_emporium.dm"
|
#include "code\game\gamemodes\changeling\cellular_emporium.dm"
|
||||||
#include "code\game\gamemodes\changeling\changeling.dm"
|
#include "code\game\gamemodes\changeling\changeling.dm"
|
||||||
#include "code\game\gamemodes\changeling\changeling_power.dm"
|
#include "code\game\gamemodes\changeling\changeling_power.dm"
|
||||||
#include "code\game\gamemodes\changeling\evolution_menu.dm"
|
|
||||||
#include "code\game\gamemodes\changeling\traitor_chan.dm"
|
#include "code\game\gamemodes\changeling\traitor_chan.dm"
|
||||||
#include "code\game\gamemodes\changeling\powers\absorb.dm"
|
#include "code\game\gamemodes\changeling\powers\absorb.dm"
|
||||||
#include "code\game\gamemodes\changeling\powers\adrenaline.dm"
|
#include "code\game\gamemodes\changeling\powers\adrenaline.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user