Removes changeling teams and hivemind channel (#54054)

* Removes changeling teams and hivemind channel.

* More cleanup

* some more stuff
This commit is contained in:
skoglol
2020-10-28 19:51:34 +01:00
committed by GitHub
parent 48e0d4eba9
commit cc03593d12
16 changed files with 12 additions and 455 deletions

View File

@@ -42,10 +42,6 @@
#define MODE_ALIEN "alientalk"
#define MODE_HOLOPAD "holopad"
#define MODE_CHANGELING "changeling"
#define MODE_KEY_CHANGELING "g"
#define MODE_TOKEN_CHANGELING ":g"
#define MODE_VOCALCORDS "cords"
#define MODE_KEY_VOCALCORDS "x"
@@ -80,11 +76,6 @@
#define TURF_LINK(alice, turfy) "<a href=?src=[REF(alice)];x=[turfy.x];y=[turfy.y];z=[turfy.z]>(T)</a>"
#define FOLLOW_OR_TURF_LINK(alice, bob, turfy) "<a href=?src=[REF(alice)];follow=[REF(bob)];x=[turfy.x];y=[turfy.y];z=[turfy.z]>(F)</a>"
#define LINGHIVE_NONE 0
#define LINGHIVE_OUTSIDER 1
#define LINGHIVE_LING 2
#define LINGHIVE_LINK 3
//Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam
#define MAX_MESSAGE_LEN 1024
#define MAX_NAME_LEN 42

View File

@@ -44,7 +44,6 @@
var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button.
var/linglink
var/datum/martial_art/martial_art
var/static/default_martial_art = new/datum/martial_art
var/miming = FALSE // Mime's vow of silence

View File

@@ -9,59 +9,6 @@
/datum/saymode/proc/handle_message(mob/living/user, message, datum/language/language)
return TRUE
/datum/saymode/changeling
key = MODE_KEY_CHANGELING
mode = MODE_CHANGELING
/datum/saymode/changeling/handle_message(mob/living/user, message, datum/language/language)
switch(user.lingcheck())
if(LINGHIVE_LINK)
var/msg = "<span class='changeling'><b>[user.mind]:</b> [message]</span>"
for(var/_M in GLOB.player_list)
var/mob/M = _M
if(M in GLOB.dead_mob_list)
var/link = FOLLOW_LINK(M, user)
to_chat(M, "[link] [msg]")
else
switch(M.lingcheck())
if (LINGHIVE_LING)
var/mob/living/L = M
if (!HAS_TRAIT(L, CHANGELING_HIVEMIND_MUTE))
to_chat(M, msg)
if(LINGHIVE_LINK)
to_chat(M, msg)
if(LINGHIVE_OUTSIDER)
if(prob(40))
to_chat(M, "<span class='changeling'>We can faintly sense an outsider trying to communicate through the hivemind...</span>")
if(LINGHIVE_LING)
if (HAS_TRAIT(user, CHANGELING_HIVEMIND_MUTE))
to_chat(user, "<span class='warning'>The poison in the air hinders our ability to interact with the hivemind.</span>")
return FALSE
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
var/msg = "<span class='changeling'><b>[changeling.changelingID]:</b> [message]</span>"
user.log_talk(message, LOG_SAY, tag="changeling [changeling.changelingID]")
for(var/_M in GLOB.player_list)
var/mob/M = _M
if(M in GLOB.dead_mob_list)
var/link = FOLLOW_LINK(M, user)
to_chat(M, "[link] [msg]")
else
switch(M.lingcheck())
if(LINGHIVE_LINK)
to_chat(M, msg)
if(LINGHIVE_LING)
var/mob/living/L = M
if (!HAS_TRAIT(L, CHANGELING_HIVEMIND_MUTE))
to_chat(M, msg)
if(LINGHIVE_OUTSIDER)
if(prob(40))
to_chat(M, "<span class='changeling'>We can faintly sense another of our kind trying to communicate through the hivemind...</span>")
if(LINGHIVE_OUTSIDER)
to_chat(user, "<span class='changeling'>Our senses have not evolved enough to be able to communicate this way...</span>")
return FALSE
/datum/saymode/xeno
key = "a"
mode = MODE_ALIEN

View File

@@ -1,8 +1,6 @@
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" = ITEM_SLOT_HEAD, "wear_mask" = ITEM_SLOT_MASK, "neck" = ITEM_SLOT_NECK, "back" = ITEM_SLOT_BACK, "wear_suit" = ITEM_SLOT_OCLOTHING, "w_uniform" = ITEM_SLOT_ICLOTHING, "shoes" = ITEM_SLOT_FEET, "belt" = ITEM_SLOT_BELT, "gloves" = ITEM_SLOT_GLOVES, "glasses" = ITEM_SLOT_EYES, "ears" = ITEM_SLOT_EARS, "wear_id" = ITEM_SLOT_ID, "s_store" = ITEM_SLOT_SUITSTORE))
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/changeling
@@ -15,7 +13,7 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th
protected_jobs = list("Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain")
required_players = 15
required_enemies = 1
recommended_enemies = 4
recommended_enemies = 3
reroll_friendly = 1
announce_span = "green"
@@ -58,23 +56,9 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th
return FALSE
/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)
var/list/possible_team_objectives = list()
for(var/T in team_objectives)
var/datum/objective/changeling_team_objective/CTO = T
if(changelings.len >= initial(CTO.min_lings))
possible_team_objectives += T
if(possible_team_objectives.len && prob(20*changelings.len))
GLOB.changeling_team_objective_type = pick(possible_team_objectives)
for(var/datum/mind/changeling in changelings)
log_game("[key_name(changeling)] has been selected as a changeling")
var/datum/antagonist/changeling/new_antag = new()
new_antag.team_mode = TRUE
changeling.add_antag_datum(new_antag)
GLOB.pre_setup_antags -= changeling
..()

View File

@@ -109,7 +109,6 @@
scaling_cost = 15
requirements = list(70,70,60,50,40,20,20,10,10,10)
antag_cap = list(1,1,1,1,1,2,2,2,2,3)
var/team_mode_probability = 30
/datum/dynamic_ruleset/roundstart/changeling/pre_execute()
. = ..()
@@ -123,21 +122,8 @@
return TRUE
/datum/dynamic_ruleset/roundstart/changeling/execute()
var/team_mode = FALSE
if(prob(team_mode_probability))
team_mode = TRUE
var/list/team_objectives = subtypesof(/datum/objective/changeling_team_objective)
var/list/possible_team_objectives = list()
for(var/T in team_objectives)
var/datum/objective/changeling_team_objective/CTO = T
if(assigned.len >= initial(CTO.min_lings))
possible_team_objectives += T
if(possible_team_objectives.len && prob(20*assigned.len))
GLOB.changeling_team_objective_type = pick(possible_team_objectives)
for(var/datum/mind/changeling in assigned)
var/datum/antagonist/changeling/new_antag = new antag_datum()
new_antag.team_mode = team_mode
changeling.add_antag_datum(new_antag)
GLOB.pre_setup_antags -= changeling
return TRUE

View File

@@ -919,176 +919,6 @@ GLOBAL_LIST_EMPTY(possible_items_special)
if(expl)
explanation_text = expl
////////////////////////////////
// Changeling team objectives //
////////////////////////////////
/datum/objective/changeling_team_objective //Abstract type
martyr_compatible = FALSE //Suicide is not teamwork!
explanation_text = "Changeling Friendship!"
var/min_lings = 3 //Minimum amount of lings for this team objective to be possible
var/escape_objective_compatible = FALSE
/datum/objective/changeling_team_objective/proc/prepare()
return FALSE
//Impersonate department
//Picks as many people as it can from a department (Security,Engineer,Medical,Science)
//and tasks the lings with killing and replacing them
/datum/objective/changeling_team_objective/impersonate_department
explanation_text = "Ensure X department are killed, impersonated, and replaced by Changelings"
var/command_staff_only = FALSE //if this is true, it picks command staff instead
var/list/department_minds = list()
var/list/department_real_names = list()
var/department_string = ""
/datum/objective/changeling_team_objective/impersonate_department/prepare()
var/result = FALSE
if(command_staff_only)
result = get_heads()
else
result = get_department_staff()
if(result)
update_explanation_text()
return TRUE
else
return FALSE
/datum/objective/changeling_team_objective/impersonate_department/proc/get_department_staff()
department_minds = list()
department_real_names = list()
var/list/departments = list("Head of Security","Research Director","Chief Engineer","Chief Medical Officer")
var/department_head = pick(departments)
switch(department_head)
if("Head of Security")
department_string = "security"
if("Research Director")
department_string = "science"
if("Chief Engineer")
department_string = "engineering"
if("Chief Medical Officer")
department_string = "medical"
var/list/lings = get_antag_minds(/datum/antagonist/changeling,TRUE)
var/ling_count = lings.len
for(var/datum/mind/M in SSticker.minds)
if(M in lings)
continue
if(department_head in get_department_heads(M.assigned_role))
if(ling_count)
ling_count--
department_minds += M
department_real_names += M.current.real_name
else
break
if(!department_minds.len)
log_game("[type] has failed to find department staff, and has removed itself. the round will continue normally")
return FALSE
return TRUE
/datum/objective/changeling_team_objective/impersonate_department/proc/get_heads()
department_minds = list()
department_real_names = list()
//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_antag_minds(/datum/antagonist/changeling,TRUE)
var/needed_heads = rand(min_lings,GLOB.command_positions.len)
needed_heads = min(lings.len,needed_heads)
var/list/heads = SSjob.get_living_heads()
for(var/datum/mind/head in heads)
if(head in lings) //Looking at you HoP.
continue
if(needed_heads)
department_minds += head
department_real_names += head.current.real_name
needed_heads--
else
break
if(!department_minds.len)
log_game("[type] has failed to find department heads, and has removed itself. the round will continue normally")
return FALSE
return TRUE
/datum/objective/changeling_team_objective/impersonate_department/update_explanation_text()
..()
if(!department_real_names.len || !department_minds.len)
explanation_text = "Free Objective"
return //Something fucked up, give them a win
if(command_staff_only)
explanation_text = "Ensure changelings impersonate and escape as the following heads of staff: "
else
explanation_text = "Ensure changelings impersonate and escape as the following members of \the [department_string] department: "
var/first = 1
for(var/datum/mind/M in department_minds)
var/string = "[M.name] the [M.assigned_role]"
if(!first)
string = ", [M.name] the [M.assigned_role]"
else
first--
explanation_text += string
if(command_staff_only)
explanation_text += ", while the real heads are dead. This is a team objective."
else
explanation_text += ", while the real members are dead. This is a team objective."
/datum/objective/changeling_team_objective/impersonate_department/check_completion()
if(!department_real_names.len || !department_minds.len)
return TRUE //Something fucked up, give them a win
var/list/check_names = department_real_names.Copy()
//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.has_antag_datum(/datum/antagonist/changeling)) //Lings aren't picked for this, but let's be safe
continue
if(M.current)
var/turf/mloc = get_turf(M.current)
if(mloc.onCentCom() && (M.current.stat != DEAD))
return FALSE //A Non-ling living target got to centcom, fail
//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 get_antag_minds(/datum/antagonist/changeling,TRUE))
if(success >= department_minds.len) //We did it, stop here!
return TRUE
if(ishuman(changeling.current))
var/mob/living/carbon/human/H = changeling.current
var/turf/cloc = get_turf(changeling.current)
if(cloc?.onCentCom() && (changeling.current.stat != DEAD)) //Living changeling on centcom....
for(var/name in check_names) //Is he (disguised as) one of the staff?
if(H.dna.real_name == name)
check_names -= name //This staff member is accounted for, remove them, so the team don't succeed by escape as 7 of the same engineer
success++ //A living changeling staff member made it to centcom
continue changelings
if(success >= department_minds.len)
return TRUE
return FALSE
//A subtype of impersonate_department
//This subtype always picks as many command staff as it can (HoS,HoP,Cap,CE,CMO,RD)
//and tasks the lings with killing and replacing them
/datum/objective/changeling_team_objective/impersonate_department/impersonate_heads
explanation_text = "Have X or more heads of staff escape on the shuttle disguised as heads, while the real heads are dead"
command_staff_only = TRUE
//Ideally this would be all of them but laziness and unusual subtypes
/proc/generate_admin_objective_list()
GLOB.admin_objective_list = list()

View File

@@ -1,4 +1,5 @@
#define ABDUCTOR_MAX_TEAMS 4
GLOBAL_LIST_INIT(possible_abductor_names, list("Alpha","Beta","Gamma","Delta","Epsilon","Zeta","Eta","Theta","Iota","Kappa","Lambda","Mu","Nu","Xi","Omicron","Pi","Rho","Sigma","Tau","Upsilon","Phi","Chi","Psi","Omega"))
/datum/antagonist/abductor
name = "Abductor"
@@ -135,7 +136,7 @@
/datum/team/abductor_team/New()
..()
team_number = team_count++
name = "Mothership [pick(GLOB.possible_changeling_IDs)]" //TODO Ensure unique and actual alieny names
name = "Mothership [pick(GLOB.possible_abductor_names)]" //TODO Ensure unique and actual alieny names
add_objective(new/datum/objective/experiment)
/datum/team/abductor_team/is_solo()

View File

@@ -13,7 +13,6 @@
hijack_speed = 0.5
var/you_are_greet = TRUE
var/give_objectives = TRUE
var/team_mode = FALSE //Should assign team objectives ?
var/competitive_objectives = FALSE //Should we assign objectives in competition with other lings?
//Changeling Stuff
@@ -28,7 +27,6 @@
var/chem_recharge_rate = 1
var/chem_recharge_slowdown = 0
var/sting_range = 2
var/changelingID = "Changeling"
var/geneticdamage = 0
var/was_absorbed = FALSE //if they were absorbed by another ling already.
var/isabsorbing = FALSE
@@ -63,34 +61,16 @@
QDEL_NULL(emporium_action)
. = ..()
/datum/antagonist/changeling/proc/generate_name()
var/honorific
if(owner.current.gender == FEMALE)
honorific = "Ms."
else if(owner.current.gender == MALE)
honorific = "Mr."
else
honorific = "Mx."
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)
emporium_action.Grant(owner.current)
/datum/antagonist/changeling/on_gain()
generate_name()
create_actions()
reset_powers()
create_initial_profile()
if(give_objectives)
if(team_mode)
forge_team_objectives()
forge_objectives()
owner.current.grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue. We are able to transform our body after all.
. = ..()
@@ -386,8 +366,7 @@
/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 \"[MODE_TOKEN_CHANGELING] message\" to communicate with your fellow changelings.</span>")
to_chat(owner.current, "<span class='boldannounce'>You are a changeling! You have absorbed and taken the form of a human.</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)
@@ -396,15 +375,6 @@
/datum/antagonist/changeling/farewell()
to_chat(owner.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>")
/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
if(team_objective.prepare())//Setting up succeeded
objectives += team_objective
else
qdel(team_objective)
return
/datum/antagonist/changeling/proc/forge_objectives()
//OBJECTIVES - random traitor objectives. Unique objectives "steal brain" and "identity theft".
@@ -413,13 +383,7 @@
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
switch(competitive_objectives ? (team_mode ? rand(1,2) : rand(1,3)) : 1)
switch(competitive_objectives ? rand(1,3) : 1)
if(1)
var/datum/objective/absorb/absorb_objective = new
absorb_objective.owner = owner
@@ -429,7 +393,7 @@
var/datum/objective/absorb_most/ac = new
ac.owner = owner
objectives += ac
if(3) //only give the murder other changelings goal if they're not in a team.
if(3)
var/datum/objective/absorb_changeling/ac = new
ac.owner = owner
objectives += ac
@@ -456,18 +420,12 @@
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 = ROLE_CHANGELING, role_type = TRUE, invert = TRUE)
else
kill_objective.find_target()
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 = ROLE_CHANGELING, role_type = TRUE, invert = TRUE)
else
maroon_objective.find_target()
maroon_objective.find_target()
objectives += maroon_objective
if (!(locate(/datum/objective/escape) in objectives) && escape_objective_possible)
@@ -486,17 +444,14 @@
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 = ROLE_CHANGELING, role_type = TRUE, invert = TRUE)
else
identity_theft.find_target()
identity_theft.find_target()
objectives += identity_theft
escape_objective_possible = FALSE
/datum/antagonist/changeling/admin_add(datum/mind/new_owner,mob/admin)
. = ..()
to_chat(new_owner.current, "<span class='boldannounce'>Our powers have awoken. A flash of memory returns to us...we are [changelingID], a changeling!</span>")
to_chat(new_owner.current, "<span class='boldannounce'>Our powers have awoken. A flash of memory returns to us...we are a changeling!</span>")
/datum/antagonist/changeling/get_admin_commands()
. = ..()
@@ -580,7 +535,6 @@
parts += printplayer(owner)
//Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed.
parts += "<b>Changeling ID:</b> [changelingID]."
parts += "<b>Genomes Extracted:</b> [absorbedcount]"
parts += " "
if(objectives.len)
@@ -600,8 +554,5 @@
return parts.Join("<br>")
/datum/antagonist/changeling/antag_listing_name()
return ..() + "([changelingID])"
/datum/antagonist/changeling/xenobio/antag_listing_name()
return ..() + "(Xenobio)"

View File

@@ -1,38 +1,3 @@
//HIVEMIND COMMUNICATION (:g)
/datum/action/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."
needs_button = FALSE
dna_cost = 0
chemical_cost = -1
/datum/action/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, "<i><font color=#800080>Use say \"[MODE_TOKEN_CHANGELING] message\" to communicate with the other changelings.</font></i>")
var/datum/action/changeling/hivemind_upload/S1 = new
if(!changeling.has_sting(S1))
S1.Grant(user)
changeling.purchasedpowers+=S1
var/datum/action/changeling/hivemind_download/S2 = new
if(!changeling.has_sting(S2))
S2.Grant(user)
changeling.purchasedpowers+=S2
/datum/action/changeling/hivemind_comms/Remove(mob/user)
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
if(changeling.changeling_speak)
changeling.changeling_speak = FALSE
for(var/p in changeling.purchasedpowers)
var/datum/action/changeling/otherpower = p
if(istype(otherpower, /datum/action/changeling/hivemind_upload) || istype(otherpower, /datum/action/changeling/hivemind_download))
changeling.purchasedpowers -= otherpower
otherpower.Remove(changeling.owner.current)
..()
// HIVE MIND UPLOAD/DOWNLOAD DNA
GLOBAL_LIST_EMPTY(hivemind_bank)

View File

@@ -1,75 +0,0 @@
/datum/action/changeling/linglink
name = "Hivemind Link"
desc = "We link our victim's mind into the hivemind for personal interrogation."
helptext = "If we find a human mad enough to support our cause, this can be a helpful tool to stay in touch."
button_icon_state = "hivemind_link"
chemical_cost = 0
dna_cost = 0
req_human = 1
/datum/action/changeling/linglink/can_sting(mob/living/carbon/user)
if(!..())
return
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
if(changeling.islinking)
to_chat(user, "<span class='warning'>We have already formed a link with the victim!</span>")
return
if(!user.pulling)
to_chat(user, "<span class='warning'>We must be tightly grabbing a creature to link with them!</span>")
return
if(!iscarbon(user.pulling))
to_chat(user, "<span class='warning'>We cannot link with this creature!</span>")
return
var/mob/living/carbon/target = user.pulling
if(!target.mind)
to_chat(user, "<span class='warning'>The victim has no mind to link to!</span>")
return
if(target.stat == DEAD)
to_chat(user, "<span class='warning'>The victim is dead, you cannot link to a dead mind!</span>")
return
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>")
return
if(user.grab_state <= GRAB_AGGRESSIVE)
to_chat(user, "<span class='warning'>We must have a tighter grip to link with this creature!</span>")
return
return changeling.can_absorb_dna(target)
/datum/action/changeling/linglink/sting_action(mob/user)
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)
switch(i)
if(1)
to_chat(user, "<span class='notice'>This creature is compatible. We must hold still...</span>")
if(2)
to_chat(user, "<span class='notice'>We stealthily stab [target] with a minor proboscis...</span>")
to_chat(target, "<span class='userdanger'>You experience a stabbing sensation and your ears begin to ring...</span>")
if(3)
to_chat(user, "<span class='notice'>We mold the [target]'s mind like clay, granting [target.p_them()] the ability to speak in the hivemind!</span>")
to_chat(target, "<span class='userdanger'>A migraine throbs behind your eyes, you hear yourself screaming - but your mouth has not opened!</span>")
for(var/mi in GLOB.mob_list)
var/mob/M = mi
if(M.lingcheck() == LINGHIVE_LING)
to_chat(M, "<span class='changeling'>We can sense a foreign presence in the hivemind...</span>")
target.mind.linglink = 1
target.say("[MODE_TOKEN_CHANGELING] AAAAARRRRGGGGGHHHHH!!")
to_chat(target, "<span class='changeling bold'>You can now communicate in the changeling hivemind, say \"[MODE_TOKEN_CHANGELING] message\" to communicate!</span>")
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]", "[i]"))
if(!do_mob(user, target, 20))
to_chat(user, "<span class='warning'>Our link with [target] has ended!</span>")
changeling.islinking = 0
target.mind.linglink = 0
return
to_chat(user, "<span class='notice'>We must keep holding on to [target] to sustain the link. </span>")
while(user.pulling && user.grab_state >= GRAB_NECK)
target.reagents.add_reagent(/datum/reagent/medicine/salbutamol, 0.5) // So they don't choke to death while you interrogate them
do_mob(user, target, 10 SECONDS, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM))
changeling.islinking = 0
target.mind.linglink = 0
to_chat(user, "<span class='notice'>You cannot sustain the connection any longer, your victim fades from the hivemind!</span>")
to_chat(target, "<span class='userdanger'>The link cannot be sustained any longer, your connection to the hivemind has faded!</span>")

View File

@@ -19,9 +19,6 @@
else
return ..()
/mob/living/brain/lingcheck()
return LINGHIVE_NONE
/mob/living/brain/treat_message(message)
message = capitalize(message)
return message

View File

@@ -1257,17 +1257,6 @@
L[++L.len] = list("[A.panel]",A.get_panel_text(),A.name,"[REF(A)]")
return L
/mob/living/lingcheck()
if(mind)
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
if(changeling)
if(changeling.changeling_speak)
return LINGHIVE_LING
return LINGHIVE_OUTSIDER
if(mind?.linglink)
return LINGHIVE_LINK
return LINGHIVE_NONE
/mob/living/forceMove(atom/destination)
stop_pulling()
if(buckled)

View File

@@ -121,10 +121,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(SOFT_CRIT)
message_mods[WHISPER_MODE] = MODE_WHISPER
if(UNCONSCIOUS)
if(!(message_mods[MODE_CHANGELING] || message_mods[MODE_ALIEN]))
if(!message_mods[MODE_ALIEN])
return
if(HARD_CRIT)
if(!(message_mods[WHISPER_MODE] || message_mods[MODE_CHANGELING] || message_mods[MODE_ALIEN]))
if(!(message_mods[WHISPER_MODE] || message_mods[MODE_ALIEN]))
return
if(DEAD)
say_dead(original_message)

View File

@@ -26,9 +26,6 @@
/mob/living/silicon/binarycheck()
return TRUE
/mob/living/silicon/lingcheck()
return FALSE //Borged or AI'd lings can't speak on the ling channel.
/mob/living/silicon/radio(message, list/message_mods = list(), list/spans, language)
. = ..()
if(.)

View File

@@ -95,10 +95,6 @@
/mob/proc/hivecheck()
return FALSE
///Check if the mob has a ling hivemind
/mob/proc/lingcheck()
return LINGHIVE_NONE
///The amount of items we are looking for in the message
#define MESSAGE_MODS_LENGTH 6
/**

View File

@@ -1492,7 +1492,6 @@
#include "code\modules\antagonists\changeling\powers\hivemind.dm"
#include "code\modules\antagonists\changeling\powers\humanform.dm"
#include "code\modules\antagonists\changeling\powers\lesserform.dm"
#include "code\modules\antagonists\changeling\powers\linglink.dm"
#include "code\modules\antagonists\changeling\powers\mimic_voice.dm"
#include "code\modules\antagonists\changeling\powers\mutations.dm"
#include "code\modules\antagonists\changeling\powers\panacea.dm"