diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 4c8d060708..c9e97726b3 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -282,11 +282,13 @@
return
/mob/living/carbon/MiddleClickOn(atom/A)
- if(!src.stat && src.mind && src.mind.changeling && src.mind.changeling.chosen_sting && (iscarbon(A)) && (A != src))
- next_click = world.time + 5
- mind.changeling.chosen_sting.try_to_sting(src, A)
- else
- swap_hand()
+ if(!stat && mind && iscarbon(A) && A != src)
+ var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling)
+ if(C && C.chosen_sting)
+ C.chosen_sting.try_to_sting(src,A)
+ next_click = world.time + 5
+ return
+ swap_hand()
/mob/living/simple_animal/drone/MiddleClickOn(atom/A)
swap_hand()
@@ -344,11 +346,13 @@
return
/mob/living/carbon/AltClickOn(atom/A)
- if(!src.stat && src.mind && src.mind.changeling && src.mind.changeling.chosen_sting && (iscarbon(A)) && (A != src))
- next_click = world.time + 5
- mind.changeling.chosen_sting.try_to_sting(src, A)
- else
- ..()
+ if(!stat && mind && iscarbon(A) && A != src)
+ var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling)
+ if(C && C.chosen_sting)
+ C.chosen_sting.try_to_sting(src,A)
+ next_click = world.time + 5
+ return
+ ..()
/atom/proc/AltClick(mob/user)
SendSignal(COMSIG_CLICK_ALT, user)
diff --git a/code/datums/antagonists/changeling.dm b/code/datums/antagonists/changeling.dm
index 7a3dba2cf3..d72cb64b81 100644
--- a/code/datums/antagonists/changeling.dm
+++ b/code/datums/antagonists/changeling.dm
@@ -80,7 +80,7 @@
. = ..()
/datum/antagonist/changeling/on_removal()
- remove_changeling_powers()
+ remove_changeling_powers(FALSE)
owner.objectives -= objectives
. = ..()
@@ -102,11 +102,11 @@
chem_recharge_slowdown = initial(chem_recharge_slowdown)
mimicing = ""
-/datum/antagonist/changeling/proc/remove_changeling_powers()
+/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.always_keep)
+ if((p.dna_cost == 0 && keep_free_powers) || p.always_keep)
continue
purchasedpowers -= p
p.on_refund(owner.current)
@@ -118,13 +118,13 @@
/datum/antagonist/changeling/proc/reset_powers()
if(purchasedpowers)
- remove_changeling_powers()
- //Repurchase free powers.
+ 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
+ purchasedpowers+=S
S.on_purchase(owner.current,TRUE)
/datum/antagonist/changeling/proc/has_sting(obj/effect/proc_holder/changeling/power)
@@ -480,4 +480,4 @@
/datum/antagonist/changeling/xenobio
name = "Xenobio Changeling"
give_objectives = FALSE
- you_are_greet = FALSE
\ No newline at end of file
+ you_are_greet = FALSE
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 284841676d..bd5742ad36 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -192,15 +192,10 @@
qdel(O)
/datum/mind/proc/remove_changeling()
- if(src in SSticker.mode.changelings)
- SSticker.mode.changelings -= src
- current.remove_changeling_powers()
- if(changeling)
- qdel(changeling)
- changeling = null
- special_role = null
- remove_antag_equip()
- SSticker.mode.update_changeling_icons_removed(src)
+ var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
+ if(C)
+ remove_antag_datum(/datum/antagonist/changeling)
+ special_role = null
/datum/mind/proc/remove_traitor()
if(src in SSticker.mode.traitors)
@@ -255,7 +250,6 @@
remove_wizard()
remove_cultist()
remove_rev()
- SSticker.mode.update_changeling_icons_removed(src)
SSticker.mode.update_traitor_icons_removed(src)
SSticker.mode.update_cult_icons_removed(src)
@@ -448,17 +442,12 @@
if (SSticker.mode.config_tag=="changeling" || SSticker.mode.config_tag=="traitorchan")
text = uppertext(text)
text = "[text]: "
- if ((src in SSticker.mode.changelings) && special_role)
- text += "YES | no"
+ var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
+ if(C)
+ text += "[C.name] | No"
if (objectives.len==0)
text += "
Objectives are empty! Randomize!"
- if(changeling && changeling.stored_profiles.len && (current.real_name != changeling.first_prof.name) )
- text += "
Transform to initial appearance."
- else if(src in SSticker.mode.changelings) //Station Aligned Changeling
- text += "YES (but not an antag) | no"
- if (objectives.len==0)
- text += "
Objectives are empty! Randomize!"
- 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 += "
Transform to initial appearance."
else
text += "yes | NO"
@@ -1050,30 +1039,29 @@
else if (href_list["changeling"])
switch(href_list["changeling"])
if("clear")
- remove_changeling()
+ remove_antag_datum(/datum/antagonist/changeling)
+ special_role = null
to_chat(current, "You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!")
message_admins("[key_name_admin(usr)] has de-changeling'ed [current].")
log_admin("[key_name(usr)] has de-changeling'ed [current].")
if("changeling")
- if(!(src in SSticker.mode.changelings))
- SSticker.mode.changelings += src
- current.make_changeling()
- special_role = "Changeling"
- to_chat(current, "Your powers are awoken. A flash of memory returns to us...we are [changeling.changelingID], a changeling!")
- 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)
+ var/datum/antagonist/changeling/C = make_Changling()
+ to_chat(current, "Your powers are awoken. A flash of memory returns to us...we are [C.changelingID], a changeling!")
+ message_admins("[key_name_admin(usr)] has changeling'ed [current].")
+ log_admin("[key_name(usr)] has changeling'ed [current].")
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, "The objectives for changeling [key] have been generated. You can edit them and anounce manually.")
-
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, "Resetting DNA failed!")
else
var/mob/living/carbon/C = current
- changeling.first_prof.dna.transfer_identity(C, transfer_SE=1)
- C.real_name = changeling.first_prof.name
+ ling.first_prof.dna.transfer_identity(C, transfer_SE=1)
+ C.real_name = ling.first_prof.name
C.updateappearance(mutcolor_update=1)
C.domutcheck()
@@ -1408,13 +1396,11 @@
current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]"
/datum/mind/proc/make_Changling()
- if(!(src in SSticker.mode.changelings))
- SSticker.mode.changelings += src
- current.make_changeling()
+ var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
+ if(!C)
+ C = add_antag_datum(/datum/antagonist/changeling)
special_role = "Changeling"
- SSticker.mode.forge_changeling_objectives(src)
- SSticker.mode.greet_changeling(src)
- SSticker.mode.update_changeling_icons_added(src)
+ return C
/datum/mind/proc/make_Wizard()
if(!has_antag_datum(/datum/antagonist/wizard))
diff --git a/code/game/gamemodes/changeling/cellular_emporium.dm b/code/game/gamemodes/changeling/cellular_emporium.dm
index aaba09c87c..df92212181 100644
--- a/code/game/gamemodes/changeling/cellular_emporium.dm
+++ b/code/game/gamemodes/changeling/cellular_emporium.dm
@@ -3,7 +3,7 @@
/datum/cellular_emporium
var/name = "cellular emporium"
- var/datum/changeling/changeling
+ var/datum/antagonist/changeling/changeling
/datum/cellular_emporium/New(my_changeling)
. = ..()
@@ -32,7 +32,7 @@
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/dna_cost = initial(ability.dna_cost)
@@ -61,10 +61,10 @@
switch(action)
if("readapt")
if(changeling.canrespec)
- changeling.lingRespec(usr)
+ changeling.readapt()
if("evolve")
var/sting_name = params["name"]
- changeling.purchasePower(usr, sting_name)
+ changeling.purchase_power(sting_name)
/datum/action/innate/cellular_emporium
name = "Cellular Emporium"
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index 653beed98c..e84477b2cb 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -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(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(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))
-
-
-/datum/game_mode
- var/list/datum/mind/changelings = list()
+GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our this objective to all lings
/datum/game_mode/changeling
@@ -29,26 +22,8 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
Changelings: Accomplish the objectives assigned to you.\n\
Crew: 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/changeling_team_objective_type = null //If this is not null, we hand our this objective to all lings
+ var/list/changelings = list()
/datum/game_mode/changeling/pre_setup()
@@ -80,7 +55,6 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
return 0
/datum/game_mode/changeling/post_setup()
-
//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
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
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)
log_game("[changeling.key] (ckey) has been selected as a changeling")
- changeling.current.make_changeling()
- forge_changeling_objectives(changeling)
- greet_changeling(changeling)
- SSticker.mode.update_changeling_icons_added(changeling)
+ var/datum/antagonist/changeling/new_antag = new(changeling)
+ new_antag.team_mode = TRUE
+ changeling.add_antag_datum(new_antag)
..()
/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/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
- 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(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate"))
if(age_check(character.client))
if(!(character.job in restricted_jobs))
character.mind.make_Changling()
-
-/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)
+ changelings += character.mind
/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 - \
@@ -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, \
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, "You are [changeling.changeling.changelingID], a changeling! You have absorbed and taken the form of a human.")
- to_chat(changeling.current, "Use say \":g message\" to communicate with your fellow changelings.")
- to_chat(changeling.current, "You must complete the following tasks:")
- 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, "Objective #[obj_count]: [objective.explanation_text]")
- obj_count++
- return
-
/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)
var/text = "
The changelings were:"
for(var/datum/mind/changeling in changelings)
+ var/datum/antagonist/changeling/ling = changeling.has_antag_datum(/datum/antagonist/changeling)
var/changelingwin = 1
if(!changeling.current)
changelingwin = 0
@@ -239,8 +107,8 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
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.
- text += "
Changeling ID: [changeling.changeling.changelingID]."
- text += "
Genomes Extracted: [changeling.changeling.absorbedcount]"
+ text += "
Changeling ID: [ling.changelingID]."
+ text += "
Genomes Extracted: [ling.absorbedcount]"
if(changeling.objectives.len)
var/count = 1
@@ -272,176 +140,8 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
to_chat(world, text)
-
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, "We have reached our capacity to store genetic information! We must transform before absorbing more.")
- return
- if(!target)
- return
- if(NO_DNA_COPY in target.dna.species.species_traits)
- if(verbose)
- to_chat(user, "[target] is not compatible with our biology.")
- return
- if((target.disabilities & NOCLONE) || (target.disabilities & HUSK))
- if(verbose)
- to_chat(user, "DNA of [target] is ruined beyond usability!")
- 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, "We could gain no benefit from absorbing a lesser creature.")
- return
- if(has_dna(target.dna))
- if(verbose)
- to_chat(user, "We already have this DNA in storage!")
- return
- if(!target.has_dna())
- if(verbose)
- to_chat(user, "[target] is not compatible with our biology.")
- 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)
var/datum/dna/chosen_dna = chosen_prof.dna
user.real_name = chosen_prof.name
@@ -481,50 +181,4 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
if(equip)
user.equip_to_slot_or_del(C, GLOB.slot2slot[slot])
- 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)
+ user.regenerate_icons()
\ No newline at end of file
diff --git a/code/game/gamemodes/changeling/changeling_power.dm b/code/game/gamemodes/changeling/changeling_power.dm
index 1abd58854b..ee6a0bee8c 100644
--- a/code/game/gamemodes/changeling/changeling_power.dm
+++ b/code/game/gamemodes/changeling/changeling_power.dm
@@ -26,14 +26,14 @@
/obj/effect/proc_holder/changeling/Click()
var/mob/user = usr
- if(!user || !user.mind || !user.mind.changeling)
+ if(!user || !user.mind || !user.mind.has_antag_datum(/datum/antagonist/changeling))
return
try_to_sting(user)
/obj/effect/proc_holder/changeling/proc/try_to_sting(mob/user, mob/target)
if(!can_sting(user, target))
return
- var/datum/changeling/c = user.mind.changeling
+ var/datum/antagonist/changeling/c = user.mind.has_antag_datum(/datum/antagonist/changeling)
if(sting_action(user, target))
SSblackbox.add_details("changeling_powers",name)
sting_feedback(user, target)
@@ -52,7 +52,7 @@
if(req_human && !ishuman(user))
to_chat(user, "We cannot do that in this form!")
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)
to_chat(user, "We require at least [chemical_cost] unit\s of chemicals to do that!")
return 0
diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm
deleted file mode 100644
index 76a37f9bb1..0000000000
--- a/code/game/gamemodes/changeling/evolution_menu.dm
+++ /dev/null
@@ -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, "We can't remove our evolutions in this form!")
- return
- if(canrespec)
- to_chat(user, "We have removed our evolutions from this form, and are now ready to readapt.")
- user.remove_changeling_powers(1)
- canrespec = 0
- user.make_changeling(TRUE)
- return 1
- else
- to_chat(user, "You lack the power to readapt your evolutions!")
- 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
diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm
index c7b02a3224..d7ef971406 100644
--- a/code/game/gamemodes/changeling/powers/absorb.dm
+++ b/code/game/gamemodes/changeling/powers/absorb.dm
@@ -9,7 +9,7 @@
if(!..())
return
- var/datum/changeling/changeling = user.mind.changeling
+ var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
if(changeling.isabsorbing)
to_chat(user, "We are already absorbing!")
return
@@ -22,12 +22,12 @@
return
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)
- 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
changeling.isabsorbing = 1
for(var/i in 1 to 3)
@@ -52,7 +52,7 @@
to_chat(target, "You are absorbed by the changeling!")
if(!changeling.has_dna(target.dna))
- changeling.add_new_profile(target, user)
+ changeling.add_new_profile(target)
if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)
@@ -84,12 +84,14 @@
user.mind.store_memory("We have no more knowledge of [target]'s speech patterns.")
to_chat(user, "We have no more knowledge of [target]'s speech patterns.")
- 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
- target.mind.changeling.absorbedcount = 0
+ var/datum/antagonist/changeling/target_ling = target.mind.has_antag_datum(/datum/antagonist/changeling)
+ if(target_ling)//If the target was a changeling, suck out their extra juice and objective points!
+ 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)
diff --git a/code/game/gamemodes/changeling/powers/fakedeath.dm b/code/game/gamemodes/changeling/powers/fakedeath.dm
index e35f04d9e7..330488f6da 100644
--- a/code/game/gamemodes/changeling/powers/fakedeath.dm
+++ b/code/game/gamemodes/changeling/powers/fakedeath.dm
@@ -1,35 +1,37 @@
-/obj/effect/proc_holder/changeling/fakedeath
- name = "Reviving Stasis"
- desc = "We fall into a stasis, allowing us to regenerate and trick our enemies."
- chemical_cost = 15
- dna_cost = 0
- req_dna = 1
- req_stat = DEAD
-
-//Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay.
-/obj/effect/proc_holder/changeling/fakedeath/sting_action(mob/living/user)
- to_chat(user, "We begin our stasis, preparing energy to arise once more.")
- if(user.stat != DEAD)
- user.emote("deathgasp")
- user.tod = worldtime2text()
- user.status_flags |= FAKEDEATH //play dead
- user.update_stat()
- user.update_canmove()
-
- addtimer(CALLBACK(src, .proc/ready_to_regenerate, user), LING_FAKEDEATH_TIME, TIMER_UNIQUE)
- return TRUE
-
-/obj/effect/proc_holder/changeling/fakedeath/proc/ready_to_regenerate(mob/user)
- if(user && user.mind && user.mind.changeling && user.mind.changeling.purchasedpowers)
- to_chat(user, "We are ready to revive.")
- user.mind.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/revive(null)
-
-/obj/effect/proc_holder/changeling/fakedeath/can_sting(mob/user)
- if(user.status_flags & FAKEDEATH)
- to_chat(user, "We are already reviving.")
- return
- if(!user.stat) //Confirmation for living changelings if they want to fake their death
- switch(alert("Are we sure we wish to fake our own death?",,"Yes", "No"))
- if("No")
- return
- return ..()
+/obj/effect/proc_holder/changeling/fakedeath
+ name = "Reviving Stasis"
+ desc = "We fall into a stasis, allowing us to regenerate and trick our enemies."
+ chemical_cost = 15
+ dna_cost = 0
+ req_dna = 1
+ req_stat = DEAD
+
+//Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay.
+/obj/effect/proc_holder/changeling/fakedeath/sting_action(mob/living/user)
+ to_chat(user, "We begin our stasis, preparing energy to arise once more.")
+ if(user.stat != DEAD)
+ user.emote("deathgasp")
+ user.tod = worldtime2text()
+ user.status_flags |= FAKEDEATH //play dead
+ user.update_stat()
+ user.update_canmove()
+
+ addtimer(CALLBACK(src, .proc/ready_to_regenerate, user), LING_FAKEDEATH_TIME, TIMER_UNIQUE)
+ return TRUE
+
+/obj/effect/proc_holder/changeling/fakedeath/proc/ready_to_regenerate(mob/user)
+ if(user && user.mind)
+ var/datum/antagonist/changeling/C = user.mind.has_antag_datum(/datum/antagonist/changeling)
+ if(C && C.purchasedpowers)
+ to_chat(user, "We are ready to revive.")
+ C.purchasedpowers += new /obj/effect/proc_holder/changeling/revive(null)
+
+/obj/effect/proc_holder/changeling/fakedeath/can_sting(mob/user)
+ if(user.status_flags & FAKEDEATH)
+ to_chat(user, "We are already reviving.")
+ return
+ if(!user.stat) //Confirmation for living changelings if they want to fake their death
+ switch(alert("Are we sure we wish to fake our own death?",,"Yes", "No"))
+ if("No")
+ return
+ return ..()
diff --git a/code/game/gamemodes/changeling/powers/hivemind.dm b/code/game/gamemodes/changeling/powers/hivemind.dm
index 0a78adaf33..5d79a757ec 100644
--- a/code/game/gamemodes/changeling/powers/hivemind.dm
+++ b/code/game/gamemodes/changeling/powers/hivemind.dm
@@ -1,93 +1,93 @@
-//HIVEMIND COMMUNICATION (:g)
-/obj/effect/proc_holder/changeling/hivemind_comms
- name = "Hivemind Communication"
- desc = "We tune our senses to the airwaves to allow us to discreetly communicate and exchange DNA with other changelings."
- helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives."
- dna_cost = 0
- chemical_cost = -1
-
-/obj/effect/proc_holder/changeling/hivemind_comms/on_purchase(mob/user, is_respec)
- ..()
- var/datum/changeling/changeling=user.mind.changeling
- changeling.changeling_speak = 1
- to_chat(user, "Use say \":g message\" to communicate with the other changelings.")
- var/obj/effect/proc_holder/changeling/hivemind_upload/S1 = new
- if(!changeling.has_sting(S1))
- changeling.purchasedpowers+=S1
- var/obj/effect/proc_holder/changeling/hivemind_download/S2 = new
- if(!changeling.has_sting(S2))
- changeling.purchasedpowers+=S2
-
-// HIVE MIND UPLOAD/DOWNLOAD DNA
-GLOBAL_LIST_EMPTY(hivemind_bank)
-
-/obj/effect/proc_holder/changeling/hivemind_upload
- name = "Hive Channel DNA"
- desc = "Allows us to channel DNA in the airwaves to allow other changelings to absorb it."
- chemical_cost = 10
- dna_cost = -1
-
-/obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/user)
- var/datum/changeling/changeling = user.mind.changeling
- var/list/names = list()
- for(var/datum/changelingprofile/prof in changeling.stored_profiles)
- if(!(prof in GLOB.hivemind_bank))
- names += prof.name
-
- if(names.len <= 0)
- to_chat(user, "The airwaves already have all of our DNA.")
- return
-
- var/chosen_name = input("Select a DNA to channel: ", "Channel DNA", null) as null|anything in names
- if(!chosen_name)
- return
-
- var/datum/changelingprofile/chosen_dna = changeling.get_dna(chosen_name)
- if(!chosen_dna)
- return
-
- var/datum/changelingprofile/uploaded_dna = new chosen_dna.type
- chosen_dna.copy_profile(uploaded_dna)
- GLOB.hivemind_bank += uploaded_dna
- to_chat(user, "We channel the DNA of [chosen_name] to the air.")
- return TRUE
-
-/obj/effect/proc_holder/changeling/hivemind_download
- name = "Hive Absorb DNA"
- desc = "Allows us to absorb DNA that has been channeled to the airwaves. Does not count towards absorb objectives."
- chemical_cost = 10
- dna_cost = -1
-
-/obj/effect/proc_holder/changeling/hivemind_download/can_sting(mob/living/carbon/user)
- if(!..())
- return
- var/datum/changeling/changeling = user.mind.changeling
- 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.
- to_chat(user, "We have reached our capacity to store genetic information! We must transform before absorbing more.")
- return
- return 1
-
-/obj/effect/proc_holder/changeling/hivemind_download/sting_action(mob/user)
- var/datum/changeling/changeling = user.mind.changeling
- var/list/names = list()
- for(var/datum/changelingprofile/prof in GLOB.hivemind_bank)
- if(!(prof in changeling.stored_profiles))
- names[prof.name] = prof
-
- if(names.len <= 0)
- to_chat(user, "There's no new DNA to absorb from the air.")
- return
-
- var/S = input("Select a DNA absorb from the air: ", "Absorb DNA", null) as null|anything in names
- if(!S)
- return
- var/datum/changelingprofile/chosen_prof = names[S]
- if(!chosen_prof)
- return
-
- var/datum/changelingprofile/downloaded_prof = new chosen_prof.type
- chosen_prof.copy_profile(downloaded_prof)
- changeling.add_profile(downloaded_prof)
- to_chat(user, "We absorb the DNA of [S] from the air.")
- return TRUE
+//HIVEMIND COMMUNICATION (:g)
+/obj/effect/proc_holder/changeling/hivemind_comms
+ name = "Hivemind Communication"
+ desc = "We tune our senses to the airwaves to allow us to discreetly communicate and exchange DNA with other changelings."
+ helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives."
+ dna_cost = 0
+ chemical_cost = -1
+
+/obj/effect/proc_holder/changeling/hivemind_comms/on_purchase(mob/user, is_respec)
+ ..()
+ var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
+ changeling.changeling_speak = 1
+ to_chat(user, "Use say \":g message\" to communicate with the other changelings.")
+ var/obj/effect/proc_holder/changeling/hivemind_upload/S1 = new
+ if(!changeling.has_sting(S1))
+ changeling.purchasedpowers+=S1
+ var/obj/effect/proc_holder/changeling/hivemind_download/S2 = new
+ if(!changeling.has_sting(S2))
+ changeling.purchasedpowers+=S2
+
+// HIVE MIND UPLOAD/DOWNLOAD DNA
+GLOBAL_LIST_EMPTY(hivemind_bank)
+
+/obj/effect/proc_holder/changeling/hivemind_upload
+ name = "Hive Channel DNA"
+ desc = "Allows us to channel DNA in the airwaves to allow other changelings to absorb it."
+ chemical_cost = 10
+ dna_cost = -1
+
+/obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/user)
+ var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
+ var/list/names = list()
+ for(var/datum/changelingprofile/prof in changeling.stored_profiles)
+ if(!(prof in GLOB.hivemind_bank))
+ names += prof.name
+
+ if(names.len <= 0)
+ to_chat(user, "The airwaves already have all of our DNA.")
+ return
+
+ var/chosen_name = input("Select a DNA to channel: ", "Channel DNA", null) as null|anything in names
+ if(!chosen_name)
+ return
+
+ var/datum/changelingprofile/chosen_dna = changeling.get_dna(chosen_name)
+ if(!chosen_dna)
+ return
+
+ var/datum/changelingprofile/uploaded_dna = new chosen_dna.type
+ chosen_dna.copy_profile(uploaded_dna)
+ GLOB.hivemind_bank += uploaded_dna
+ to_chat(user, "We channel the DNA of [chosen_name] to the air.")
+ return TRUE
+
+/obj/effect/proc_holder/changeling/hivemind_download
+ name = "Hive Absorb DNA"
+ desc = "Allows us to absorb DNA that has been channeled to the airwaves. Does not count towards absorb objectives."
+ chemical_cost = 10
+ dna_cost = -1
+
+/obj/effect/proc_holder/changeling/hivemind_download/can_sting(mob/living/carbon/user)
+ if(!..())
+ return
+ var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
+ 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.
+ to_chat(user, "We have reached our capacity to store genetic information! We must transform before absorbing more.")
+ return
+ return 1
+
+/obj/effect/proc_holder/changeling/hivemind_download/sting_action(mob/user)
+ var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
+ var/list/names = list()
+ for(var/datum/changelingprofile/prof in GLOB.hivemind_bank)
+ if(!(prof in changeling.stored_profiles))
+ names[prof.name] = prof
+
+ if(names.len <= 0)
+ to_chat(user, "There's no new DNA to absorb from the air.")
+ return
+
+ var/S = input("Select a DNA absorb from the air: ", "Absorb DNA", null) as null|anything in names
+ if(!S)
+ return
+ var/datum/changelingprofile/chosen_prof = names[S]
+ if(!chosen_prof)
+ return
+
+ var/datum/changelingprofile/downloaded_prof = new chosen_prof.type
+ chosen_prof.copy_profile(downloaded_prof)
+ changeling.add_profile(downloaded_prof)
+ to_chat(user, "We absorb the DNA of [S] from the air.")
+ return TRUE
diff --git a/code/game/gamemodes/changeling/powers/humanform.dm b/code/game/gamemodes/changeling/powers/humanform.dm
index d92e622c2d..90ddfb0115 100644
--- a/code/game/gamemodes/changeling/powers/humanform.dm
+++ b/code/game/gamemodes/changeling/powers/humanform.dm
@@ -1,30 +1,30 @@
-/obj/effect/proc_holder/changeling/humanform
- name = "Human Form"
- desc = "We change into a human."
- chemical_cost = 5
- req_dna = 1
-
-//Transform into a human.
-/obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user)
- var/datum/changeling/changeling = user.mind.changeling
- var/list/names = list()
- for(var/datum/changelingprofile/prof in changeling.stored_profiles)
- names += "[prof.name]"
-
- var/chosen_name = input("Select the target DNA: ", "Target DNA", null) as null|anything in names
- if(!chosen_name)
- return
-
- var/datum/changelingprofile/chosen_prof = changeling.get_dna(chosen_name)
- if(!chosen_prof)
- return
- if(!user || user.notransform)
- return 0
- to_chat(user, "We transform our appearance.")
-
- changeling.purchasedpowers -= src
-
- var/newmob = user.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS)
-
- changeling_transform(newmob, chosen_prof)
- return TRUE
+/obj/effect/proc_holder/changeling/humanform
+ name = "Human Form"
+ desc = "We change into a human."
+ chemical_cost = 5
+ req_dna = 1
+
+//Transform into a human.
+/obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user)
+ var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
+ var/list/names = list()
+ for(var/datum/changelingprofile/prof in changeling.stored_profiles)
+ names += "[prof.name]"
+
+ var/chosen_name = input("Select the target DNA: ", "Target DNA", null) as null|anything in names
+ if(!chosen_name)
+ return
+
+ var/datum/changelingprofile/chosen_prof = changeling.get_dna(chosen_name)
+ if(!chosen_prof)
+ return
+ if(!user || user.notransform)
+ return 0
+ to_chat(user, "We transform our appearance.")
+
+ changeling.purchasedpowers -= src
+
+ var/newmob = user.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS)
+
+ changeling_transform(newmob, chosen_prof)
+ return TRUE
diff --git a/code/game/gamemodes/changeling/powers/linglink.dm b/code/game/gamemodes/changeling/powers/linglink.dm
index e3b9e6c02c..7a93306785 100644
--- a/code/game/gamemodes/changeling/powers/linglink.dm
+++ b/code/game/gamemodes/changeling/powers/linglink.dm
@@ -8,7 +8,7 @@
/obj/effect/proc_holder/changeling/linglink/can_sting(mob/living/carbon/user)
if(!..())
return
- var/datum/changeling/changeling = user.mind.changeling
+ var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
if(changeling.islinking)
to_chat(user, "We have already formed a link with the victim!")
return
@@ -19,22 +19,23 @@
to_chat(user, "We cannot link with this creature!")
return
var/mob/living/carbon/target = user.pulling
+
if(!target.mind)
to_chat(user, "The victim has no mind to link to!")
return
if(target.stat == DEAD)
to_chat(user, "The victim is dead, you cannot link to a dead mind!")
return
- if(target.mind.changeling)
+ if(target.mind.has_antag_datum(/datum/antagonist/changeling))
to_chat(user, "The victim is already a part of the hivemind!")
return
if(user.grab_state <= GRAB_AGGRESSIVE)
to_chat(user, "We must have a tighter grip to link with this creature!")
return
- return changeling.can_absorb_dna(user,target)
+ return changeling.can_absorb_dna(target)
/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
changeling.islinking = 1
for(var/i in 1 to 3)
diff --git a/code/game/gamemodes/changeling/powers/mimic_voice.dm b/code/game/gamemodes/changeling/powers/mimic_voice.dm
index f422be20a9..9c0d79e233 100644
--- a/code/game/gamemodes/changeling/powers/mimic_voice.dm
+++ b/code/game/gamemodes/changeling/powers/mimic_voice.dm
@@ -1,27 +1,27 @@
-/obj/effect/proc_holder/changeling/mimicvoice
- name = "Mimic Voice"
- desc = "We shape our vocal glands to sound like a desired voice."
- helptext = "Will turn your voice into the name that you enter. We must constantly expend chemicals to maintain our form like this."
- chemical_cost = 0 //constant chemical drain hardcoded
- dna_cost = 1
- req_human = 1
-
-
-// Fake Voice
-/obj/effect/proc_holder/changeling/mimicvoice/sting_action(mob/user)
- var/datum/changeling/changeling=user.mind.changeling
- if(changeling.mimicing)
- changeling.mimicing = ""
- changeling.chem_recharge_slowdown -= 0.5
- to_chat(user, "We return our vocal glands to their original position.")
- return
-
- var/mimic_voice = stripped_input(user, "Enter a name to mimic.", "Mimic Voice", null, MAX_NAME_LEN)
- if(!mimic_voice)
- return
-
- changeling.mimicing = mimic_voice
- changeling.chem_recharge_slowdown += 0.5
- to_chat(user, "We shape our glands to take the voice of [mimic_voice], this will slow down regenerating chemicals while active.")
- to_chat(user, "Use this power again to return to our original voice and return chemical production to normal levels.")
- return TRUE
+/obj/effect/proc_holder/changeling/mimicvoice
+ name = "Mimic Voice"
+ desc = "We shape our vocal glands to sound like a desired voice."
+ helptext = "Will turn your voice into the name that you enter. We must constantly expend chemicals to maintain our form like this."
+ chemical_cost = 0 //constant chemical drain hardcoded
+ dna_cost = 1
+ req_human = 1
+
+
+// Fake Voice
+/obj/effect/proc_holder/changeling/mimicvoice/sting_action(mob/user)
+ var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
+ if(changeling.mimicing)
+ changeling.mimicing = ""
+ changeling.chem_recharge_slowdown -= 0.5
+ to_chat(user, "We return our vocal glands to their original position.")
+ return
+
+ var/mimic_voice = stripped_input(user, "Enter a name to mimic.", "Mimic Voice", null, MAX_NAME_LEN)
+ if(!mimic_voice)
+ return
+
+ changeling.mimicing = mimic_voice
+ changeling.chem_recharge_slowdown += 0.5
+ to_chat(user, "We shape our glands to take the voice of [mimic_voice], this will slow down regenerating chemicals while active.")
+ to_chat(user, "Use this power again to return to our original voice and return chemical production to normal levels.")
+ return TRUE
diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm
index f8b25afa5e..ec0f4ea025 100644
--- a/code/game/gamemodes/changeling/powers/mutations.dm
+++ b/code/game/gamemodes/changeling/powers/mutations.dm
@@ -83,7 +83,7 @@
//checks if we already have an organic suit and casts it off.
/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)
return 1
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 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
return TRUE
@@ -385,7 +385,7 @@
weapon_name_simple = "shield"
/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)
return
diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm
index 71c052c39f..716b41a837 100644
--- a/code/game/gamemodes/changeling/powers/revive.dm
+++ b/code/game/gamemodes/changeling/powers/revive.dm
@@ -1,35 +1,37 @@
-/obj/effect/proc_holder/changeling/revive
- name = "Revive"
- desc = "We regenerate, healing all damage from our form."
- helptext = "Does not regrow lost organs or a missing head."
- req_stat = DEAD
- always_keep = TRUE
- ignores_fakedeath = TRUE
-
-//Revive from revival stasis
-/obj/effect/proc_holder/changeling/revive/sting_action(mob/living/carbon/user)
- user.status_flags &= ~(FAKEDEATH)
- user.tod = null
- user.revive(full_heal = 1)
- var/list/missing = user.get_missing_limbs()
- missing -= "head" // headless changelings are funny
- if(missing.len)
- playsound(user, 'sound/magic/demon_consume.ogg', 50, 1)
- user.visible_message("[user]'s missing limbs \
- reform, making a loud, grotesque sound!",
- "Your limbs regrow, making a \
- loud, crunchy sound and giving you great pain!",
- "You hear organic matter ripping \
- and tearing!")
- user.emote("scream")
- user.regenerate_limbs(0, list("head"))
+/obj/effect/proc_holder/changeling/revive
+ name = "Revive"
+ desc = "We regenerate, healing all damage from our form."
+ helptext = "Does not regrow lost organs or a missing head."
+ req_stat = DEAD
+ always_keep = TRUE
+ ignores_fakedeath = TRUE
+
+//Revive from revival stasis
+/obj/effect/proc_holder/changeling/revive/sting_action(mob/living/carbon/user)
+ user.status_flags &= ~(FAKEDEATH)
+ user.tod = null
+ user.revive(full_heal = 1)
+ var/list/missing = user.get_missing_limbs()
+ missing -= "head" // headless changelings are funny
+ if(missing.len)
+ playsound(user, 'sound/magic/demon_consume.ogg', 50, 1)
+ user.visible_message("[user]'s missing limbs \
+ reform, making a loud, grotesque sound!",
+ "Your limbs regrow, making a \
+ loud, crunchy sound and giving you great pain!",
+ "You hear organic matter ripping \
+ and tearing!")
+ user.emote("scream")
+ user.regenerate_limbs(0, list("head"))
user.regenerate_organs()
- to_chat(user, "We have revived ourselves.")
- user.mind.changeling.purchasedpowers -= src
- return TRUE
-
-/obj/effect/proc_holder/changeling/revive/can_be_used_by(mob/user)
- if((user.stat != DEAD) && !(user.status_flags & FAKEDEATH))
- user.mind.changeling.purchasedpowers -= src
- return 0
- . = ..()
+ to_chat(user, "We have revived ourselves.")
+ var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
+ changeling.purchasedpowers -= src
+ return TRUE
+
+/obj/effect/proc_holder/changeling/revive/can_be_used_by(mob/user)
+ if((user.stat != DEAD) && !(user.status_flags & FAKEDEATH))
+ var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
+ changeling.purchasedpowers -= src
+ return 0
+ . = ..()
diff --git a/code/game/gamemodes/changeling/powers/shriek.dm b/code/game/gamemodes/changeling/powers/shriek.dm
index dd066bf71b..667dc06daf 100644
--- a/code/game/gamemodes/changeling/powers/shriek.dm
+++ b/code/game/gamemodes/changeling/powers/shriek.dm
@@ -11,7 +11,7 @@
for(var/mob/living/M in get_hearers_in_view(4, user))
if(iscarbon(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.confused += 25
C.Jitter(50)
diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm
index c23074c506..4fdd84040e 100644
--- a/code/game/gamemodes/changeling/powers/tiny_prick.dm
+++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm
@@ -5,9 +5,12 @@
/obj/effect/proc_holder/changeling/sting/Click()
var/mob/user = usr
- if(!user || !user.mind || !user.mind.changeling)
+ if(!user || !user.mind)
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)
else
unset_sting(user)
@@ -15,41 +18,48 @@
/obj/effect/proc_holder/changeling/sting/proc/set_sting(mob/user)
to_chat(user, "We prepare our sting, use alt+click or middle mouse button on target to sting them.")
- 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.invisibility = 0
/obj/effect/proc_holder/changeling/sting/proc/unset_sting(mob/user)
to_chat(user, "We retract our sting, we can't sting anyone for now.")
- 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.invisibility = INVISIBILITY_ABSTRACT
/mob/living/carbon/proc/unset_sting()
- if(mind && mind.changeling && mind.changeling.chosen_sting)
- src.mind.changeling.chosen_sting.unset_sting(src)
+ if(mind)
+ 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)
if(!..())
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!")
if(!iscarbon(target))
return
if(!isturf(user.loc))
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
- if(target.mind && target.mind.changeling)
+ if(target.mind && target.mind.has_antag_datum(/datum/antagonist/changeling))
sting_feedback(user, target)
- user.mind.changeling.chem_charges -= chemical_cost
+ changeling.chem_charges -= chemical_cost //??
return 1
/obj/effect/proc_holder/changeling/sting/sting_feedback(mob/user, mob/target)
if(!target)
return
to_chat(user, "We stealthily sting [target.name].")
- if(target.mind && target.mind.changeling)
+ if(target.mind && target.mind.has_antag_datum(/datum/antagonist/changeling))
to_chat(target, "You feel a tiny prick.")
return 1
@@ -65,7 +75,7 @@
/obj/effect/proc_holder/changeling/sting/transformation/Click()
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)
unset_sting(user)
return
@@ -163,12 +173,14 @@
/obj/effect/proc_holder/changeling/sting/extract_dna/can_sting(mob/user, mob/target)
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)
add_logs(user, target, "stung", "extraction sting")
- if(!(user.mind.changeling.has_dna(target.dna)))
- user.mind.changeling.add_new_profile(target, user)
+ var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
+ if(!(changeling.has_dna(target.dna)))
+ changeling.add_new_profile(target)
return TRUE
/obj/effect/proc_holder/changeling/sting/mute
diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm
index 6b627870a4..a977bab3e0 100644
--- a/code/game/gamemodes/changeling/powers/transform.dm
+++ b/code/game/gamemodes/changeling/powers/transform.dm
@@ -1,126 +1,129 @@
-/obj/effect/proc_holder/changeling/transform
- name = "Transform"
- desc = "We take on the appearance and voice of one we have absorbed."
- chemical_cost = 5
- dna_cost = 0
- req_dna = 1
- req_human = 1
-
-/obj/item/clothing/glasses/changeling
- name = "flesh"
+/obj/effect/proc_holder/changeling/transform
+ name = "Transform"
+ desc = "We take on the appearance and voice of one we have absorbed."
+ chemical_cost = 5
+ dna_cost = 0
+ req_dna = 1
+ req_human = 1
+
+/obj/item/clothing/glasses/changeling
+ name = "flesh"
flags_1 = NODROP_1
-
-/obj/item/clothing/glasses/changeling/attack_hand(mob/user)
- if(loc == user && user.mind && user.mind.changeling)
- to_chat(user, "You reabsorb [src] into your body.")
- qdel(src)
- return
- ..()
-
-/obj/item/clothing/under/changeling
- name = "flesh"
+
+/obj/item/clothing/glasses/changeling/attack_hand(mob/user)
+ if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
+ to_chat(user, "You reabsorb [src] into your body.")
+ qdel(src)
+ return
+ ..()
+
+/obj/item/clothing/under/changeling
+ name = "flesh"
flags_1 = NODROP_1
-
-/obj/item/clothing/under/changeling/attack_hand(mob/user)
- if(loc == user && user.mind && user.mind.changeling)
- to_chat(user, "You reabsorb [src] into your body.")
- qdel(src)
- return
- ..()
-
-/obj/item/clothing/suit/changeling
- name = "flesh"
+
+/obj/item/clothing/under/changeling/attack_hand(mob/user)
+ if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
+ to_chat(user, "You reabsorb [src] into your body.")
+ qdel(src)
+ return
+ ..()
+
+/obj/item/clothing/suit/changeling
+ name = "flesh"
flags_1 = NODROP_1
- allowed = list(/obj/item/changeling)
-
-/obj/item/clothing/suit/changeling/attack_hand(mob/user)
- if(loc == user && user.mind && user.mind.changeling)
- to_chat(user, "You reabsorb [src] into your body.")
- qdel(src)
- return
- ..()
-
-/obj/item/clothing/head/changeling
- name = "flesh"
+ allowed = list(/obj/item/changeling)
+
+/obj/item/clothing/suit/changeling/attack_hand(mob/user)
+ if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
+ to_chat(user, "You reabsorb [src] into your body.")
+ qdel(src)
+ return
+ ..()
+
+/obj/item/clothing/head/changeling
+ name = "flesh"
flags_1 = NODROP_1
-
-/obj/item/clothing/head/changeling/attack_hand(mob/user)
- if(loc == user && user.mind && user.mind.changeling)
- to_chat(user, "You reabsorb [src] into your body.")
- qdel(src)
- return
- ..()
-
-/obj/item/clothing/shoes/changeling
- name = "flesh"
+
+/obj/item/clothing/head/changeling/attack_hand(mob/user)
+ if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
+ to_chat(user, "You reabsorb [src] into your body.")
+ qdel(src)
+ return
+ ..()
+
+/obj/item/clothing/shoes/changeling
+ name = "flesh"
flags_1 = NODROP_1
-
-/obj/item/clothing/shoes/changeling/attack_hand(mob/user)
- if(loc == user && user.mind && user.mind.changeling)
- to_chat(user, "You reabsorb [src] into your body.")
- qdel(src)
- return
- ..()
-
-/obj/item/clothing/gloves/changeling
- name = "flesh"
+
+/obj/item/clothing/shoes/changeling/attack_hand(mob/user)
+ if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
+ to_chat(user, "You reabsorb [src] into your body.")
+ qdel(src)
+ return
+ ..()
+
+/obj/item/clothing/gloves/changeling
+ name = "flesh"
flags_1 = NODROP_1
-
-/obj/item/clothing/gloves/changeling/attack_hand(mob/user)
- if(loc == user && user.mind && user.mind.changeling)
- to_chat(user, "You reabsorb [src] into your body.")
- qdel(src)
- return
- ..()
-
-/obj/item/clothing/mask/changeling
- name = "flesh"
+
+/obj/item/clothing/gloves/changeling/attack_hand(mob/user)
+ if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
+ to_chat(user, "You reabsorb [src] into your body.")
+ qdel(src)
+ return
+ ..()
+
+/obj/item/clothing/mask/changeling
+ name = "flesh"
flags_1 = NODROP_1
-
-/obj/item/clothing/mask/changeling/attack_hand(mob/user)
- if(loc == user && user.mind && user.mind.changeling)
- to_chat(user, "You reabsorb [src] into your body.")
- qdel(src)
- return
- ..()
-
-/obj/item/changeling
- name = "flesh"
+
+/obj/item/clothing/mask/changeling/attack_hand(mob/user)
+ if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
+ to_chat(user, "You reabsorb [src] into your body.")
+ qdel(src)
+ return
+ ..()
+
+/obj/item/changeling
+ name = "flesh"
flags_1 = NODROP_1
- slot_flags = ALL
- allowed = list(/obj/item/changeling)
-
-/obj/item/changeling/attack_hand(mob/user)
- if(loc == user && user.mind && user.mind.changeling)
- to_chat(user, "You reabsorb [src] into your body.")
- qdel(src)
- return
- ..()
-
-//Change our DNA to that of somebody we've absorbed.
-/obj/effect/proc_holder/changeling/transform/sting_action(mob/living/carbon/human/user)
- var/datum/changeling/changeling = user.mind.changeling
- var/datum/changelingprofile/chosen_prof = changeling.select_dna("Select the target DNA: ", "Target DNA", user)
-
- if(!chosen_prof)
- return
-
- changeling_transform(user, chosen_prof)
- return TRUE
-
-/datum/changeling/proc/select_dna(var/prompt, var/title, var/mob/living/carbon/user)
- var/list/names = list("Drop Flesh Disguise")
- for(var/datum/changelingprofile/prof in stored_profiles)
- names += "[prof.name]"
-
- var/chosen_name = input(prompt, title, null) as null|anything in names
- if(!chosen_name)
- return
-
- if(chosen_name == "Drop Flesh Disguise")
- for(var/slot in GLOB.slots)
- if(istype(user.vars[slot], GLOB.slot2type[slot]))
- qdel(user.vars[slot])
-
- var/datum/changelingprofile/prof = get_dna(chosen_name)
- return prof
+ slot_flags = ALL
+ allowed = list(/obj/item/changeling)
+
+/obj/item/changeling/attack_hand(mob/user)
+ if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
+ to_chat(user, "You reabsorb [src] into your body.")
+ qdel(src)
+ return
+ ..()
+
+//Change our DNA to that of somebody we've absorbed.
+/obj/effect/proc_holder/changeling/transform/sting_action(mob/living/carbon/human/user)
+ 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")
+
+ if(!chosen_prof)
+ return
+
+ changeling_transform(user, chosen_prof)
+ return TRUE
+
+/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")
+ for(var/datum/changelingprofile/prof in stored_profiles)
+ names += "[prof.name]"
+
+ var/chosen_name = input(prompt, title, null) as null|anything in names
+ if(!chosen_name)
+ return
+
+ if(chosen_name == "Drop Flesh Disguise")
+ for(var/slot in GLOB.slots)
+ if(istype(user.vars[slot], GLOB.slot2type[slot]))
+ qdel(user.vars[slot])
+
+ var/datum/changelingprofile/prof = get_dna(chosen_name)
+ return prof
diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm
index 8da88e18d7..6287e707f2 100644
--- a/code/game/gamemodes/changeling/traitor_chan.dm
+++ b/code/game/gamemodes/changeling/traitor_chan.dm
@@ -10,6 +10,7 @@
reroll_friendly = 1
var/list/possible_changelings = list()
+ var/list/changelings = list()
var/const/changeling_amount = 1 //hard limit on changelings if scaling is turned off
/datum/game_mode/traitor/changeling/announce()
@@ -57,25 +58,22 @@
/datum/game_mode/traitor/changeling/post_setup()
for(var/datum/mind/changeling in changelings)
- changeling.current.make_changeling()
- forge_changeling_objectives(changeling)
- greet_changeling(changeling)
- SSticker.mode.update_changeling_icons_added(changeling)
- ..()
- return
+ changeling.add_antag_datum(/datum/antagonist/changeling)
+ return ..()
/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/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
- 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(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate"))
if(age_check(character.client))
if(!(character.job in restricted_jobs))
character.mind.make_Changling()
+ changelings += character.mind
..()
/datum/game_mode/traitor/changeling/generate_report()
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
index 8fead855b2..f136abdfcb 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
@@ -477,7 +477,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
if(ishuman(L))
var/mob/living/carbon/human/H = L
species = "[H.dna.species.name]"
- if(L.mind && L.mind.changeling)
+ if(L.mind && L.mind.has_antag_datum(/datum/antagonist/changeling))
species = "Changeling lifeform"
var/obj/item/organ/heart/gland/temp = locate() in H.internal_organs
if(temp)
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index cd3b2ba2b2..d1c8d0193d 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -586,7 +586,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
n_p ++
else if (SSticker.IsRoundInProgress())
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 ++
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/absorbedcount = 0
for(var/datum/mind/M in owners)
- if(!owner || !owner.changeling || !owner.changeling.stored_profiles)
+ if(!M)
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
@@ -696,10 +699,11 @@ GLOBAL_LIST_EMPTY(possible_items_special)
if("Chief Medical Officer")
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)
- if(M in SSticker.mode.changelings)
+ if(M in lings)
continue
if(department_head in get_department_heads(M.assigned_role))
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
//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
-
+ var/list/lings = get_antagonists(/datum/antagonist/changeling,TRUE)
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()
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
if(needed_heads)
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
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
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
var/success = 0
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!
return 1
if(ishuman(changeling.current))
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 865a7f4efa..9b35f06acc 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -162,11 +162,6 @@
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)
if(efficiency > 2)
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 26bfb80860..fa6e184ab4 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -442,12 +442,15 @@
dat += "
PM | "
dat += ""
- if(SSticker.mode.changelings.len > 0)
+
+ var/list/lings = get_antagonists(/datum/antagonist/changeling)
+ if(lings.len > 0)
dat += "
| Changelings | | |
"
- 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
if(M)
- dat += "| [M.mind.changeling.changelingID] as [M.real_name][M.client ? "" : " (No Client)"][M.stat == DEAD ? " (DEAD)" : ""] | "
+ dat += "
| [lingantag.changelingID]([lingantag.name]) as [M.real_name][M.client ? "" : " (No Client)"][M.stat == DEAD ? " (DEAD)" : ""] | "
dat += "PM | "
dat += "FLW | "
dat += "Show Objective |
"
@@ -607,20 +610,6 @@
dat += "PM | "
dat += "
"
-
- var/list/pirates = get_antagonists(/datum/antagonist/pirate)
- if(pirates.len > 0)
- dat += "
| Pirates | |
"
- for(var/datum/mind/N in pirates)
- var/mob/M = N.current
- if(!M)
- dat += "| [N.name]([N.key])No body. | "
- dat += "PM |
"
- else
- dat += "| [M.real_name][M.client ? "" : " (No Client)"][M.stat == DEAD ? " (DEAD)" : ""] | "
- dat += "PM | "
- dat += "FLW |
"
- dat += "
"
if(istype(SSticker.mode, /datum/game_mode/monkey))
var/datum/game_mode/monkey/mode = SSticker.mode
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index e8e643595d..9923e19803 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -106,8 +106,6 @@
/obj/item/clothing/Destroy()
- if(isliving(loc))
- dropped(loc)
if(pockets)
qdel(pockets)
pockets = null
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index a3642684db..55f0c0b681 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -23,7 +23,7 @@
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)))
to_chat(brainmob, "You can't feel your body! You're still just a brain!")
loc = C
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 6cb5436df8..95a134d38f 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -770,7 +770,7 @@
/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
/mob/living/carbon/harvest(mob/living/user)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index a27c9a1eb9..7d4c62d9e1 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -60,9 +60,10 @@
stat("Chemicals", B.chemicals)
if(mind)
- if(mind.changeling)
- stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
- stat("Absorbed DNA", mind.changeling.absorbedcount)
+ var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
+ if(changeling)
+ stat("Chemical Storage", "[changeling.chem_charges]/[changeling.chem_storage]")
+ stat("Absorbed DNA", changeling.absorbedcount)
//NINJACODE
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index 1374b391ce..c601f1445c 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -39,8 +39,10 @@
return real_name
else
return real_name
- if(mind && mind.changeling && mind.changeling.mimicing)
- return mind.changeling.mimicing
+ if(mind)
+ var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
+ if(changeling && changeling.mimicing )
+ return changeling.mimicing
if(GetSpecialVoice())
return GetSpecialVoice()
return real_name
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index f69a1973b3..f9b13dd24f 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -251,12 +251,14 @@
if(stat != DEAD)
D.stage_act()
+//todo generalize this and move hud out
/mob/living/carbon/proc/handle_changeling()
if(mind && hud_used && hud_used.lingchemdisplay)
- if(mind.changeling)
- mind.changeling.regenerate(src)
+ var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
+ if(changeling)
+ changeling.regenerate()
hud_used.lingchemdisplay.invisibility = 0
- hud_used.lingchemdisplay.maptext = "[round(mind.changeling.chem_charges)]
"
+ hud_used.lingchemdisplay.maptext = "[round(changeling.chem_charges)]
"
else
hud_used.lingchemdisplay.invisibility = INVISIBILITY_ABSTRACT
diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm
index 779e7f2f90..7c65e4a604 100644
--- a/code/modules/mob/living/carbon/monkey/monkey.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey.dm
@@ -74,9 +74,10 @@
stat(null, "Intent: [a_intent]")
stat(null, "Move Mode: [m_intent]")
if(client && mind)
- if(mind.changeling)
- stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
- stat("Absorbed DNA", mind.changeling.absorbedcount)
+ var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
+ if(changeling)
+ stat("Chemical Storage", "[changeling.chem_charges]/[changeling.chem_storage]")
+ stat("Absorbed DNA", changeling.absorbedcount)
return
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index c141460731..a2fdb9d2b0 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -336,8 +336,9 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(prob(40))
to_chat(M, "We can faintly sense an outsider trying to communicate through the hivemind...")
if(2)
- var/msg = "[mind.changeling.changelingID]: [message]"
- log_talk(src,"[mind.changeling.changelingID]/[key] : [message]",LOGSAY)
+ var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
+ var/msg = "[changeling.changelingID]: [message]"
+ log_talk(src,"[changeling.changelingID]/[key] : [message]",LOGSAY)
for(var/_M in GLOB.mob_list)
var/mob/M = _M
if(M in GLOB.dead_mob_list)
@@ -413,10 +414,12 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return 0
/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.changeling.changeling_speak)
- return 2
- return 1
+ if(mind)
+ var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
+ if(changeling)
+ if(changeling.changeling_speak)
+ return 2
+ return 1
if(mind && mind.linglink)
return 3
return 0
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm
index 1829a85344..222369dd55 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm
@@ -486,7 +486,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
if(guardians.len && !allowmultiple)
to_chat(user, "You already have a [mob_name]!")
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]")
return
if(used == TRUE)
diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm
index 2839ac5ea0..831cd471d3 100644
--- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm
+++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm
@@ -74,12 +74,13 @@
if(origin && origin.current && (origin.current.stat == DEAD))
origin.transfer_to(M)
- if(!origin.changeling)
- M.make_changeling()
- if(origin.changeling.can_absorb_dna(M, owner))
- origin.changeling.add_new_profile(owner, M)
+ var/datum/antagonist/changeling/C = origin.has_antag_datum(/datum/antagonist/changeling)
+ if(!C)
+ C = origin.add_antag_datum(/datum/antagonist/changeling/xenobio)
+ 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
owner.gib()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 0e49c8f6d4..fed9be6d75 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -651,8 +651,9 @@
if(mind)
add_spells_to_statpanel(mind.spell_list)
- if(mind.changeling)
- add_stings_to_statpanel(mind.changeling.purchasedpowers)
+ var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
+ if(changeling)
+ add_stings_to_statpanel(changeling.purchasedpowers)
add_spells_to_statpanel(mob_spell_list)
/mob/proc/add_spells_to_statpanel(list/spells)
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 1aa162d92e..30bdaa6716 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -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)
return 2
if("changeling")
- if(M.mind in SSticker.mode.changelings)
+ if(M.mind.has_antag_datum(/datum/antagonist/changeling,TRUE))
return 2
if("wizard")
if(iswizard(M))
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 18ca605965..51ad83e758 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -94,8 +94,9 @@
if(mind)
mind.transfer_to(O)
- if(O.mind.changeling)
- O.mind.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null)
+ var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling)
+ if(changeling)
+ changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null)
for(var/X in internal_organs)
var/obj/item/organ/I = X
@@ -118,7 +119,7 @@
for(var/X in O.internal_organs)
var/obj/item/organ/G = X
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
qdel(G) //we lose the organs in the missing limbs
qdel(BP)
@@ -126,8 +127,9 @@
//transfer mind if we didn't yet
if(mind)
mind.transfer_to(O)
- if(O.mind.changeling)
- O.mind.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null)
+ var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling)
+ if(changeling)
+ changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null)
if (tr_flags & TR_DEFAULTMSG)
@@ -248,9 +250,10 @@
if(mind)
mind.transfer_to(O)
- if(O.mind.changeling)
- for(var/obj/effect/proc_holder/changeling/humanform/HF in O.mind.changeling.purchasedpowers)
- O.mind.changeling.purchasedpowers -= HF
+ var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling)
+ if(changeling)
+ for(var/obj/effect/proc_holder/changeling/humanform/HF in changeling.purchasedpowers)
+ changeling.purchasedpowers -= HF
for(var/X in internal_organs)
var/obj/item/organ/I = X
@@ -274,16 +277,17 @@
for(var/X in O.internal_organs)
var/obj/item/organ/G = X
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
qdel(G) //we lose the organs in the missing limbs
qdel(BP)
if(mind)
mind.transfer_to(O)
- if(O.mind.changeling)
- for(var/obj/effect/proc_holder/changeling/humanform/HF in O.mind.changeling.purchasedpowers)
- O.mind.changeling.purchasedpowers -= HF
+ var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling)
+ if(changeling)
+ for(var/obj/effect/proc_holder/changeling/humanform/HF in changeling.purchasedpowers)
+ changeling.purchasedpowers -= HF
O.a_intent = INTENT_HELP
if (tr_flags & TR_DEFAULTMSG)
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index cc91819611..9321c6b015 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -957,9 +957,11 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "A stingy drink."
/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.
- M.mind.changeling.chem_charges += metabolization_rate
- M.mind.changeling.chem_charges = Clamp(M.mind.changeling.chem_charges, 0, M.mind.changeling.chem_storage)
+ if(M.mind) //Changeling Sting assists in the recharging of changeling chemicals.
+ var/datum/antagonist/changeling/changeling = M.mind.has_antag_datum(/datum/antagonist/changeling)
+ if(changeling)
+ changeling.chem_charges += metabolization_rate
+ changeling.chem_charges = Clamp(changeling.chem_charges, 0, changeling.chem_storage)
return ..()
/datum/reagent/consumable/ethanol/irishcarbomb
diff --git a/tgstation.dme b/tgstation.dme
index 4a605cbd1a..b68ee744a2 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -318,6 +318,7 @@
#include "code\datums\antagonists\abductor.dm"
#include "code\datums\antagonists\antag_datum.dm"
#include "code\datums\antagonists\brother.dm"
+#include "code\datums\antagonists\changeling.dm"
#include "code\datums\antagonists\clockcult.dm"
#include "code\datums\antagonists\cult.dm"
#include "code\datums\antagonists\datum_traitor.dm"
@@ -483,7 +484,6 @@
#include "code\game\gamemodes\changeling\cellular_emporium.dm"
#include "code\game\gamemodes\changeling\changeling.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\powers\absorb.dm"
#include "code\game\gamemodes\changeling\powers\adrenaline.dm"