mirror of
https://github.com/fulpstation/fulpstation.git
synced 2025-12-10 01:57:01 +00:00
Removes changeling teams and hivemind channel (#54054)
* Removes changeling teams and hivemind channel. * More cleanup * some more stuff
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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>")
|
||||
@@ -19,9 +19,6 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/brain/lingcheck()
|
||||
return LINGHIVE_NONE
|
||||
|
||||
/mob/living/brain/treat_message(message)
|
||||
message = capitalize(message)
|
||||
return message
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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(.)
|
||||
|
||||
@@ -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
|
||||
/**
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user