Changeling additions:

* Changelings now have a chance to roll a special team objective (only 1 at the moment) the chance is 20*number_of_lings
* Changelings have no chance to roll a "backstab" (Ling vs Ling) objective if they have a team objective
* Debrain objective has been removed (it still exists, but is not handed out) as it's basically broken
* Engorged glands stats are now the default, engorged glands still functions as normal, adding 25 chem cap and doubling production
* Armblades may now break open powered doors after a 10 second wait (With progress bar)
* Changelings can now purchase Chameleon skin, which allows them to toggle on or off the genetics mutation "Chameleon skin" which slowly makes them invisible while stood still
* Minor adjustments to mimic voice text to line up with changes to chem stats
This commit is contained in:
Remie Richards
2015-08-11 09:22:27 +01:00
parent fcbd841b60
commit ef952cfe29
6 changed files with 186 additions and 31 deletions

View File

@@ -40,6 +40,8 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
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
/datum/game_mode/changeling/announce()
world << "<b>The current game mode is - Changeling!</b>"
world << "<b>There are alien changelings on the station. Do not let the changelings succeed!</b>"
@@ -72,6 +74,18 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
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 = typesof(/datum/objective/changeling_team_objective) - /datum/objective/changeling_team_objective
var/list/possible_team_objectives = list()
for(var/datum/objective/changeling_team_objective/T in team_objectives)
if(changelings.len > initial(T.min_lings))
possible_team_objectives += T
if(possible_team_objectives.len && prob(20*changelings.len))
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()
@@ -92,12 +106,11 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
if(!(character.job in restricted_jobs))
character.mind.make_Changling()
/datum/game_mode/proc/forge_changeling_objectives(datum/mind/changeling)
/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/datum/objective/absorb/absorb_objective = new
absorb_objective.owner = changeling
absorb_objective.gen_amount_goal(6, 8)
@@ -108,12 +121,6 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
steal_objective.owner = changeling
steal_objective.find_target()
changeling.objectives += steal_objective
else
var/datum/objective/debrain/debrain_objective = new
debrain_objective.owner = changeling
debrain_objective.find_target()
changeling.objectives += debrain_objective
var/list/active_ais = active_ais()
if(active_ais.len && prob(100/joined_player_list.len))
@@ -125,11 +132,17 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
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
@@ -150,7 +163,17 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
identity_theft.owner = changeling
identity_theft.find_target()
changeling.objectives += identity_theft
return
/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)
/datum/game_mode/proc/greet_changeling(datum/mind/changeling, you_are=1)
if (you_are)
@@ -237,8 +260,8 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
var/dna_max = 4 //How many extra DNA strands the changeling can store for transformation.
var/absorbedcount = 1 //We would require at least 1 sample of compatible DNA to have taken on the form of a human.
var/chem_charges = 20
var/chem_storage = 50
var/chem_recharge_rate = 0.5
var/chem_storage = 75
var/chem_recharge_rate = 1
var/chem_recharge_slowdown = 0
var/sting_range = 2
var/changelingID = "Changeling"

View File

@@ -0,0 +1,26 @@
/obj/effect/proc_holder/changeling/chameleon_skin
name = "Chameleon Skin"
desc = "Our skin pigmentation rapidly changes to suit our current environment."
helptext = "Allows us to become invisible after a few seconds of standing still. Can be toggled on and off."
dna_cost = 2
chemical_cost = 25
req_human = 1
genetic_damage = 10
max_genetic_damage = 50
/obj/effect/proc_holder/changeling/chameleon_skin/sting_action(mob/user)
var/mob/living/carbon/human/H = user //SHOULD always be human, because req_human = 1
if(!istype(H))
return
var/datum/mutation/human/HM = mutations_list[CHAMELEON]
if(H.dna && H.dna.mutations)
if(HM in H.dna.mutations)
HM.force_lose(H)
else
HM.force_give(H)
feedback_add_details("changeling_powers","CS")
return 1

View File

@@ -22,7 +22,7 @@
changeling.mimicing = mimic_voice
changeling.chem_recharge_slowdown += 0.5
user << "<span class='notice'>We shape our glands to take the voice of <b>[mimic_voice]</b>, this will stop us from regenerating chemicals while active.</span>"
user << "<span class='notice'>Use this power again to return to our original voice and reproduce chemicals again.</span>"
user << "<span class='notice'>We shape our glands to take the voice of <b>[mimic_voice]</b>, this will slow down regenerating chemicals while active.</span>"
user << "<span class='notice'>Use this power again to return to our original voice and return chemical production to normal levels.</span>"
feedback_add_details("changeling_powers","MV")

View File

@@ -159,7 +159,12 @@
return
if(A.hasPower())
user << "<span class='warning'>The airlock's motors resist our efforts to force it!</span>"
if(A.locked)
user << "<span class='warning'>The airlock's bolts prevent it from being forced!</span>"
return
user << "<span class='warning'>The airlock's motors are resisting, this may take time...</span>"
if(do_after(user, 100, target = A))
A.open(2)
return
else if(A.locked)

View File

@@ -33,11 +33,26 @@
update_explanation_text()
return target
/datum/objective/proc/find_target_by_role(role, role_type=0)//Option sets either to check assigned role or special role. Default to assigned.
/datum/objective/proc/find_target_by_role(role, role_type=0, invert=0)//Option sets either to check assigned role or special role. Default to assigned., invert inverts the check, eg: "Don't choose a Ling"
for(var/datum/mind/possible_target in ticker.minds)
if((possible_target != owner) && ishuman(possible_target.current) && ((role_type ? possible_target.special_role : possible_target.assigned_role) == role) )
if((possible_target != owner) && ishuman(possible_target.current))
var/is_role = 0
if(role_type)
if(possible_target.special_role == role)
is_role++
else
if(possible_target.assigned_role == role)
is_role++
if(invert)
if(is_role)
continue
target = possible_target
break
else if(is_role)
target = possible_target
break
update_explanation_text()
/datum/objective/proc/update_explanation_text()
@@ -50,7 +65,8 @@
dangerrating = 10
martyr_compatible = 1
/datum/objective/assassinate/find_target_by_role(role, role_type=0)
/datum/objective/assassinate/find_target_by_role(role, role_type=0, invert=0)
if(!invert)
target_role_type = role_type
..(role, role_type)
return target
@@ -70,12 +86,12 @@
explanation_text = "Free Objective"
/datum/objective/mutiny
var/target_role_type=0
martyr_compatible = 1
/datum/objective/mutiny/find_target_by_role(role, role_type=0)
/datum/objective/mutiny/find_target_by_role(role, role_type=0,invert=0)
if(!invert)
target_role_type = role_type
..(role, role_type)
return target
@@ -104,7 +120,8 @@
dangerrating = 5
martyr_compatible = 1
/datum/objective/maroon/find_target_by_role(role, role_type=0)
/datum/objective/maroon/find_target_by_role(role, role_type=0, invert=0)
if(!invert)
target_role_type = role_type
..(role, role_type)
return target
@@ -129,7 +146,8 @@
var/target_role_type=0
dangerrating = 20
/datum/objective/debrain/find_target_by_role(role, role_type=0)
/datum/objective/debrain/find_target_by_role(role, role_type=0, invert=0)
if(!invert)
target_role_type = role_type
..(role, role_type)
return target
@@ -162,7 +180,8 @@
dangerrating = 10
martyr_compatible = 1
/datum/objective/protect/find_target_by_role(role, role_type=0)
/datum/objective/protect/find_target_by_role(role, role_type=0, invert=0)
if(!invert)
target_role_type = role_type
..(role, role_type)
return target
@@ -640,3 +659,84 @@ var/global/list/possible_items_special = list()
return 0
////////////////////////////////
// Changeling team objectives //
////////////////////////////////
/datum/objective/changeling_team_objective //Abstract type
martyr_compatible = 0 //Suicide is not teamwork!
explanation_text = "Changeling Friendship!"
var/min_lings = 3 //Minimum amount of lings for this team objective to be possible
/datum/objective/changeling_team_objective/impersonate_heads
explanation_text = "Have X or more heads of staff escape on the shuttle disguised as heads, while the real heads are dead"
var/list/head_minds = list()
var/list/head_real_names = list()
/datum/objective/changeling_team_objective/impersonate_heads/New(var/text)
..()
var/needed_heads = 0
//Heads amount is between min lings and the amount of heads possible
var/max_lings = ticker.mode.changelings.len
needed_heads = Clamp(needed_heads,min_lings,max_lings)
needed_heads = min(command_positions.len,needed_heads)
for(var/datum/mind/possible_head in ticker.minds)
if(possible_head.assigned_job.title in command_positions)
if(needed_heads)
head_minds += possible_head
head_real_names += possible_head.current.real_name
needed_heads--
if(!head_minds.len) //No heads, bail, you saw nothing, you never had a team objective, hahaha!
owner.objectives -= src
qdel(src)
return
explanation_text = "Ensure changelings impersonate and escape as the following heads of staff: "
var/first = 1
for(var/datum/mind/M in head_minds)
var/string = "[M.name] the [M.assigned_role]" //John the Head of Personnel
if(!first)
string = ", [M.name] the [M.assigned_role]" //Fred the Head of Security
else
first--
explanation_text += string
explanation_text += ", while the real heads are dead. This is a team objective."
/datum/objective/changeling_team_objective/impersonate_heads/check_completion()
//Check each head mind to see if any of them made it to centcomm alive, if they did it's an automatic fail
for(var/datum/mind/HM in head_minds)
if(HM.current)
var/turf/hloc = get_turf(HM.current)
if(hloc.onCentcom() && (HM.current.stat != DEAD))
return 0 //A Non-ling living head-target got to centcom, fail
//Check each head has been replaced, by cross referencing changeling minds, changeling current dna, the heads minds and their original DNA names
var/success = 0
changelings:
for(var/datum/mind/changeling in ticker.mode.changelings)
if(success >= head_minds.len) //We did it, stop here!
return 1
if(ishuman(changeling.current))
var/mob/living/carbon/human/H = changeling.current
var/turf/cloc = get_turf(changeling.current)
if(cloc && cloc.onCentcom() && (changeling.current.stat != DEAD)) //Living changeling on centcomm....
for(var/name in head_real_names) //Is he (disguised as) a head?
if(H.dna && H.dna.real_name == name)
head_real_names -= name //This head is accounted for, remove them, so the team don't succeed by escape as 7 John the HoPs
success++ //A living changeling head made it to centcomm
continue changelings
if(success >= head_minds.len)
return 1
return 0

View File

@@ -308,6 +308,7 @@
#include "code\game\gamemodes\changeling\powers\absorb.dm"
#include "code\game\gamemodes\changeling\powers\adrenaline.dm"
#include "code\game\gamemodes\changeling\powers\augmented_eyesight.dm"
#include "code\game\gamemodes\changeling\powers\chameleon_skin.dm"
#include "code\game\gamemodes\changeling\powers\digitalcamo.dm"
#include "code\game\gamemodes\changeling\powers\fakedeath.dm"
#include "code\game\gamemodes\changeling\powers\fleshmend.dm"