Merge pull request #2935 from Citadel-Station-13/upstream-merge-30893

[MIRROR] Datum abductors refactor
This commit is contained in:
LetterJay
2017-09-27 16:31:53 -04:00
committed by GitHub
14 changed files with 196 additions and 310 deletions
+3
View File
@@ -19,3 +19,6 @@
#define ANTAG_DATUM_IAA_AI_CUSTOM /datum/antagonist/traitor/AI/internal_affairs/custom
#define ANTAG_DATUM_IAA_AI /datum/antagonist/traitor/AI/internal_affairs
#define ANTAG_DATUM_BROTHER /datum/antagonist/brother
#define ANTAG_DATUM_ABDUCTOR /datum/antagonist/abductor
#define ANTAG_DATUM_ABDUCTOR_SCIENTIST /datum/antagonist/abductor/scientist
#define ANTAG_DATUM_ABDUCTOR_AGENT /datum/antagonist/abductor/agent
+60
View File
@@ -0,0 +1,60 @@
/datum/antagonist/abductor
name = "Abductor"
var/datum/objective_team/abductor_team/team
var/sub_role
var/outfit
var/landmark_type
var/greet_text
/datum/antagonist/abductor/agent
sub_role = "Agent"
outfit = /datum/outfit/abductor/agent
landmark_type = /obj/effect/landmark/abductor/agent
greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve."
/datum/antagonist/abductor/scientist
sub_role = "Scientist"
outfit = /datum/outfit/abductor/scientist
landmark_type = /obj/effect/landmark/abductor/scientist
greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve."
/datum/antagonist/abductor/New(datum/mind/new_owner, datum/objective_team/abductor_team/T)
team = T
return ..()
/datum/antagonist/abductor/on_gain()
SSticker.mode.abductors += owner
owner.special_role = "[name] [sub_role]"
owner.objectives += team.objectives
finalize_abductor()
return ..()
/datum/antagonist/abductor/on_removal()
SSticker.mode.abductors -= owner
team.members -= owner
owner.objectives -= team.objectives
if(owner.current)
to_chat(owner.current,"<span class='userdanger'>You are no longer the [owner.special_role]!</span>")
owner.special_role = null
return ..()
/datum/antagonist/abductor/greet()
to_chat(owner.current, "<span class='notice'>You are the [owner.special_role]!</span>")
to_chat(owner.current, "<span class='notice'>With the help of your teammate, kidnap and experiment on station crew members!</span>")
to_chat(owner.current, "<span class='notice'>[greet_text]</span>")
owner.announce_objectives()
/datum/antagonist/abductor/proc/finalize_abductor()
//Equip
var/mob/living/carbon/human/H = owner.current
H.set_species(/datum/species/abductor)
H.real_name = "[team.name] [sub_role]"
H.equipOutfit(outfit)
//Teleport to ship
for(var/obj/effect/landmark/abductor/LM in GLOB.landmarks_list)
if(istype(LM, landmark_type) && LM.team_number == team.team_number)
H.forceMove(LM.loc)
break
SSticker.mode.update_abductor_icons_added(owner)
+1 -55
View File
@@ -590,8 +590,6 @@
if(src in SSticker.mode.abductors)
text += "<b>Abductor</b> | <a href='?src=\ref[src];abductor=clear'>human</a>"
text += " | <a href='?src=\ref[src];common=undress'>undress</a> | <a href='?src=\ref[src];abductor=equip'>equip</a>"
else
text += "<a href='?src=\ref[src];abductor=abductor'>abductor</a> | <b>human</b>"
if(current && current.client && (ROLE_ABDUCTOR in current.client.prefs.be_special))
text += " | Enabled in Prefs"
@@ -1244,13 +1242,6 @@
if("clear")
to_chat(usr, "Not implemented yet. Sorry!")
//SSticker.mode.update_abductor_icons_removed(src)
if("abductor")
if(!ishuman(current))
to_chat(usr, "<span class='warning'>This only works on humans!</span>")
return
make_Abductor()
log_admin("[key_name(usr)] turned [current] into abductor.")
SSticker.mode.update_abductor_icons_added(src)
if("equip")
if(!ishuman(current))
to_chat(usr, "<span class='warning'>This only works on humans!</span>")
@@ -1496,52 +1487,7 @@
take_uplink()
var/fail = 0
fail |= !SSticker.mode.equip_revolutionary(current)
/datum/mind/proc/make_Abductor()
var/role = alert("Abductor Role ?","Role","Agent","Scientist")
var/team = input("Abductor Team ?","Team ?") in list(1,2,3,4)
var/teleport = alert("Teleport to ship ?","Teleport","Yes","No")
if(!role || !team || !teleport)
return
if(!ishuman(current))
return
SSticker.mode.abductors |= src
var/datum/objective/experiment/O = new
O.owner = src
objectives += O
var/mob/living/carbon/human/H = current
H.set_species(/datum/species/abductor)
var/datum/species/abductor/S = H.dna.species
if(role == "Scientist")
S.scientist = TRUE
S.team = team
var/list/obj/effect/landmark/abductor/agent_landmarks = new
var/list/obj/effect/landmark/abductor/scientist_landmarks = new
agent_landmarks.len = 4
scientist_landmarks.len = 4
for(var/obj/effect/landmark/abductor/A in GLOB.landmarks_list)
if(istype(A, /obj/effect/landmark/abductor/agent))
agent_landmarks[text2num(A.team)] = A
else if(istype(A, /obj/effect/landmark/abductor/scientist))
scientist_landmarks[text2num(A.team)] = A
var/obj/effect/landmark/L
if(teleport=="Yes")
switch(role)
if("Agent")
L = agent_landmarks[team]
if("Scientist")
L = scientist_landmarks[team]
H.forceMove(L.loc)
/datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/S)
spell_list += S
S.action.Grant(current)
@@ -1,5 +1,17 @@
/datum/objective_team/abductor_team
member_name = "abductor"
var/list/objectives = list()
var/team_number
/datum/objective_team/abductor_team/is_solo()
return FALSE
/datum/objective_team/abductor_team/proc/add_objective(datum/objective/O)
O.team = src
O.update_explanation_text()
objectives += O
/datum/game_mode
var/abductor_teams = 0
var/list/datum/mind/abductors = list()
var/list/datum/mind/abductees = list()
@@ -12,12 +24,8 @@
required_players = 15
maximum_players = 50
var/max_teams = 4
abductor_teams = 1
var/list/datum/mind/scientists = list()
var/list/datum/mind/agents = list()
var/list/datum/objective/team_objectives = list()
var/list/team_names = list()
var/finished = 0
var/list/datum/objective_team/abductor_team/abductor_teams = list()
var/finished = FALSE
/datum/game_mode/abduction/announce()
to_chat(world, "<B>The current game mode is - Abduction!</B>")
@@ -26,163 +34,78 @@
to_chat(world, "<b>Crew</b> - don't get abducted and stop the abductors.")
/datum/game_mode/abduction/pre_setup()
abductor_teams = max(1, min(max_teams,round(num_players()/config.abductor_scaling_coeff)))
var/possible_teams = max(1,round(antag_candidates.len / 2))
abductor_teams = min(abductor_teams,possible_teams)
var/num_teams = max(1, min(max_teams, round(num_players() / config.abductor_scaling_coeff)))
var/possible_teams = max(1, round(antag_candidates.len / 2))
num_teams = min(num_teams, possible_teams)
abductors.len = 2*abductor_teams
scientists.len = abductor_teams
agents.len = abductor_teams
team_objectives.len = abductor_teams
team_names.len = abductor_teams
for(var/i = 1 to num_teams)
if(!make_abductor_team())
return FALSE
return TRUE
for(var/i=1,i<=abductor_teams,i++)
if(!make_abductor_team(i))
return 0
/datum/game_mode/abduction/proc/make_abductor_team(datum/mind/agent, datum/mind/scientist)
var/team_number = abductor_teams.len+1
return 1
var/datum/objective_team/abductor_team/team = new
team.team_number = team_number
team.name = "Mothership [pick(GLOB.possible_changeling_IDs)]" //TODO Ensure unique and actual alieny names
team.add_objective(new/datum/objective/experiment)
/datum/game_mode/abduction/proc/make_abductor_team(team_number,preset_agent=null,preset_scientist=null)
//Team Name
team_names[team_number] = "Mothership [pick(GLOB.possible_changeling_IDs)]" //TODO Ensure unique and actual alieny names
//Team Objective
var/datum/objective/experiment/team_objective = new
team_objective.team_number = team_number
team_objectives[team_number] = team_objective
//Team Members
if(antag_candidates.len < (!agent + !scientist))
return
if(!preset_agent || !preset_scientist)
if(antag_candidates.len <=2)
return 0
var/datum/mind/scientist
var/datum/mind/agent
if(!preset_scientist)
if(!scientist)
scientist = pick(antag_candidates)
antag_candidates -= scientist
else
scientist = preset_scientist
antag_candidates -= scientist
team.members |= scientist
scientist.assigned_role = "Abductor Scientist"
log_game("[scientist.key] (ckey) has been selected as [team.name] abductor scientist.")
if(!preset_agent)
if(!agent)
agent = pick(antag_candidates)
antag_candidates -= agent
else
agent = preset_agent
antag_candidates -= agent
team.members |= agent
agent.assigned_role = "Abductor Agent"
log_game("[agent.key] (ckey) has been selected as [team.name] abductor agent.")
scientist.assigned_role = "abductor scientist"
scientist.special_role = "abductor scientist"
log_game("[scientist.key] (ckey) has been selected as an abductor team [team_number] scientist.")
agent.assigned_role = "abductor agent"
agent.special_role = "abductor agent"
log_game("[agent.key] (ckey) has been selected as an abductor team [team_number] agent.")
abductors |= agent
abductors |= scientist
scientists[team_number] = scientist
agents[team_number] = agent
return 1
abductor_teams += team
return team
/datum/game_mode/abduction/post_setup()
for(var/team_number=1,team_number<=abductor_teams,team_number++)
post_setup_team(team_number)
for(var/datum/objective_team/abductor_team/team in abductor_teams)
post_setup_team(team)
return ..()
//Used for create antag buttons
/datum/game_mode/abduction/proc/post_setup_team(team_number)
var/list/obj/effect/landmark/abductor/agent_landmarks = list()
var/list/obj/effect/landmark/abductor/scientist_landmarks = list()
agent_landmarks.len = max_teams
scientist_landmarks.len = max_teams
for(var/obj/effect/landmark/abductor/A in GLOB.landmarks_list)
if(istype(A, /obj/effect/landmark/abductor/agent))
agent_landmarks[text2num(A.team)] = A
else if(istype(A, /obj/effect/landmark/abductor/scientist))
scientist_landmarks[text2num(A.team)] = A
var/team_name = team_names[team_number]
var/datum/mind/agent
var/obj/effect/landmark/L
var/datum/mind/scientist
var/mob/living/carbon/human/H
var/datum/species/abductor/S
agent = agents[team_number]
H = agent.current
L = agent_landmarks[team_number]
H.forceMove(L.loc)
H.set_species(/datum/species/abductor)
S = H.dna.species
S.team = team_number
H.real_name = team_name + " Agent"
H.equipOutfit(/datum/outfit/abductor/agent)
greet_agent(agent,team_number)
scientist = scientists[team_number]
H = scientist.current
L = scientist_landmarks[team_number]
H.forceMove(L.loc)
H.set_species(/datum/species/abductor)
S = H.dna.species
S.scientist = TRUE
S.team = team_number
H.real_name = team_name + " Scientist"
H.equipOutfit(/datum/outfit/abductor/scientist)
greet_scientist(scientist,team_number)
/datum/game_mode/abduction/proc/greet_agent(datum/mind/abductor,team_number)
abductor.objectives += team_objectives[team_number]
var/team_name = team_names[team_number]
to_chat(abductor.current, "<span class='notice'>You are an agent of [team_name]!</span>")
to_chat(abductor.current, "<span class='notice'>With the help of your teammate, kidnap and experiment on station crew members!</span>")
to_chat(abductor.current, "<span class='notice'>Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve.</span>")
abductor.announce_objectives()
/datum/game_mode/abduction/proc/greet_scientist(datum/mind/abductor,team_number)
abductor.objectives += team_objectives[team_number]
var/team_name = team_names[team_number]
to_chat(abductor.current, "<span class='notice'>You are a scientist of [team_name]!</span>")
to_chat(abductor.current, "<span class='notice'>With the help of your teammate, kidnap and experiment on station crew members!</span>")
to_chat(abductor.current, "<span class='notice'>Use your tool and ship consoles to support the agent and retrieve human specimens.</span>")
abductor.announce_objectives()
/datum/game_mode/abduction/proc/get_team_console(team_number)
for(var/obj/machinery/abductor/console/C in GLOB.machines)
if(C.team == team_number)
return C
/datum/game_mode/abduction/proc/post_setup_team(datum/objective_team/abductor_team/team)
for(var/datum/mind/M in team.members)
if(M.assigned_role == "Abductor Scientist")
M.add_antag_datum(ANTAG_DATUM_ABDUCTOR_SCIENTIST, team)
else
M.add_antag_datum(ANTAG_DATUM_ABDUCTOR_AGENT, team)
/datum/game_mode/abduction/check_finished()
if(!finished)
for(var/team_number=1,team_number<=abductor_teams,team_number++)
var/obj/machinery/abductor/console/con = get_team_console(team_number)
var/datum/objective/objective = team_objectives[team_number]
if (con.experiment.points >= objective.target_amount)
SSshuttle.emergency.request(null, set_coefficient = 0.5)
finished = 1
return ..()
for(var/datum/objective_team/abductor_team/team in abductor_teams)
for(var/datum/objective/O in team.objectives)
if(O.check_completion())
SSshuttle.emergency.request(null, set_coefficient = 0.5)
finished = TRUE
return ..()
return ..()
/datum/game_mode/abduction/declare_completion()
for(var/team_number=1,team_number<=abductor_teams,team_number++)
var/obj/machinery/abductor/console/console = get_team_console(team_number)
var/datum/objective/objective = team_objectives[team_number]
var/team_name = team_names[team_number]
if(console.experiment.points >= objective.target_amount)
to_chat(world, "<span class='greenannounce'>[team_name] team fulfilled its mission!</span>")
for(var/datum/objective_team/abductor_team/team in abductor_teams)
var/won = TRUE
for(var/datum/objective/O in team.objectives)
if(!O.check_completion())
won = FALSE
if(won)
to_chat(world, "<span class='greenannounce'>[team.name] team fulfilled its mission!</span>")
else
to_chat(world, "<span class='boldannounce'>[team_name] team failed its mission.</span>")
to_chat(world, "<span class='boldannounce'>[team.name] team failed its mission.</span>")
..()
return 1
return TRUE
/datum/game_mode/proc/auto_declare_completion_abduction()
var/text = ""
@@ -200,40 +123,28 @@
text += "<br>"
to_chat(world, text)
//Landmarks
// TODO: Split into separate landmarks for prettier ships
// LANDMARKS
/obj/effect/landmark/abductor
var/team = 1
var/team_number = 1
/obj/effect/landmark/abductor/agent
/obj/effect/landmark/abductor/scientist
// OBJECTIVES
/datum/objective/experiment
target_amount = 6
var/team_number
/datum/objective/experiment/New()
explanation_text = "Experiment on [target_amount] humans."
/datum/objective/experiment/check_completion()
var/ab_team = team_number
if(owner)
if(!owner.current || !ishuman(owner.current))
return 0
var/mob/living/carbon/human/H = owner.current
if(H.dna.species.id != "abductor")
return 0
var/datum/species/abductor/S = H.dna.species
ab_team = S.team
for(var/obj/machinery/abductor/experiment/E in GLOB.machines)
if(E.team == ab_team)
if(E.points >= target_amount)
return 1
else
return 0
return 0
if(!istype(team, /datum/objective_team/abductor_team))
return FALSE
var/datum/objective_team/abductor_team/T = team
if(E.team_number == T.team_number)
return E.points >= target_amount
return FALSE
/datum/game_mode/proc/update_abductor_icons_added(datum/mind/alien_mind)
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_ABDUCTOR]
@@ -5,20 +5,14 @@
back = /obj/item/storage/backpack
ears = /obj/item/device/radio/headset/abductor
/datum/outfit/abductor/proc/get_team_console(team_number)
for(var/obj/machinery/abductor/console/C in GLOB.machines)
if(C.team == team_number)
return C
/datum/outfit/abductor/proc/link_to_console(mob/living/carbon/human/H, team_number)
if(!team_number && isabductor(H))
var/datum/species/abductor/S = H.dna.species
team_number = S.team
var/datum/antagonist/abductor/A = H.mind.has_antag_datum(ANTAG_DATUM_ABDUCTOR)
if(!team_number && A)
team_number = A.team.team_number
if(!team_number)
team_number = 1
var/obj/machinery/abductor/console/console = get_team_console(team_number)
var/obj/machinery/abductor/console/console = get_abductor_console(team_number)
if(console)
var/obj/item/clothing/suit/armor/abductor/vest/V = locate() in H
if(V)
@@ -1,6 +1,6 @@
/obj/machinery/computer/camera_advanced/abductor
name = "Human Observation Console"
var/team = 0
var/team_number = 0
networks = list("SS13","Abductor")
var/datum/action/innate/teleport_in/tele_in_action = new
var/datum/action/innate/teleport_out/tele_out_action = new
@@ -1,8 +1,13 @@
/proc/get_abductor_console(team_number)
for(var/obj/machinery/abductor/console/C in GLOB.machines)
if(C.team_number == team_number)
return C
//Common
/obj/machinery/abductor
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/team = 0
var/team_number = 0
//Console
@@ -139,21 +144,21 @@
return INITIALIZE_HINT_LATELOAD
/obj/machinery/abductor/console/LateInitialize()
if(!team)
if(!team_number)
return
for(var/obj/machinery/abductor/pad/p in GLOB.machines)
if(p.team == team)
if(p.team_number == team_number)
pad = p
break
for(var/obj/machinery/abductor/experiment/e in GLOB.machines)
if(e.team == team)
if(e.team_number == team_number)
experiment = e
e.console = src
for(var/obj/machinery/computer/camera_advanced/abductor/c in GLOB.machines)
if(c.team == team)
if(c.team_number == team_number)
camera = c
c.console = src
@@ -26,21 +26,15 @@
if(..())
var/obj/machinery/abductor/console/console
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.dna.species.id == "abductor")
var/datum/species/abductor/S = H.dna.species
console = get_team_console(S.team)
var/datum/antagonist/abductor/A = target.mind.has_antag_datum(ANTAG_DATUM_ABDUCTOR)
if(A)
console = get_abductor_console(A.team.team_number)
home = console.pad
if(!home)
console = get_team_console(pick(1, 2, 3, 4))
var/list/consoles = list()
for(var/obj/machinery/abductor/console/C in GLOB.machines)
consoles += C
console = pick(consoles)
home = console.pad
return 1
/obj/item/implant/abductor/proc/get_team_console(var/team)
var/obj/machinery/abductor/console/console
for(var/obj/machinery/abductor/console/c in GLOB.machines)
if(c.team == team)
console = c
break
return console
return TRUE
+6 -31
View File
@@ -3,9 +3,7 @@
typepath = /datum/round_event/ghost_role/abductor
weight = 10
max_occurrences = 1
min_players = 20
gamemode_blacklist = list("nuclear","wizard","revolution","abduction")
/datum/round_event/ghost_role/abductor
@@ -17,40 +15,17 @@
if(candidates.len < 2)
return NOT_ENOUGH_PLAYERS
//Oh god why we can't have static functions
// I feel your pain, bro
var/number = SSticker.mode.abductor_teams + 1
var/datum/game_mode/abduction/temp
var/datum/game_mode/abduction/GM
if(SSticker.mode.config_tag == "abduction")
temp = SSticker.mode
GM = SSticker.mode
else
temp = new
GM = new
var/agent_mind = pick_n_take(candidates)
var/scientist_mind = pick_n_take(candidates)
var/mob/living/carbon/human/agent = makeBody(pick_n_take(candidates))
var/mob/living/carbon/human/scientist = makeBody(pick_n_take(candidates))
var/mob/living/carbon/human/agent = makeBody(agent_mind)
var/mob/living/carbon/human/scientist = makeBody(scientist_mind)
agent_mind = agent.mind
scientist_mind = scientist.mind
temp.scientists.len = number
temp.agents.len = number
temp.abductors.len = 2*number
temp.team_objectives.len = number
temp.team_names.len = number
temp.scientists[number] = scientist_mind
temp.agents[number] = agent_mind
temp.abductors |= list(agent_mind,scientist_mind)
temp.make_abductor_team(number,preset_scientist=scientist_mind,preset_agent=agent_mind)
temp.post_setup_team(number)
SSticker.mode.abductor_teams++
if(SSticker.mode.config_tag != "abduction")
SSticker.mode.abductors |= temp.abductors
GM.post_setup_team(GM.make_abductor_team(agent.mind, scientist.mind))
spawned_mobs += list(agent, scientist)
return SUCCESSFUL_SPAWN
@@ -2,12 +2,10 @@
name = "Abductor"
id = "abductor"
say_mod = "gibbers"
sexes = 0
sexes = FALSE
species_traits = list(NOBLOOD,NOBREATH,VIRUSIMMUNE,NOGUNS,NOHUNGER)
mutanttongue = /obj/item/organ/tongue/abductor
var/scientist = 0 // vars to not pollute spieces list with castes
var/team = 1
var/scientist = FALSE // vars to not pollute spieces list with castes
/datum/species/abductor/copy_properties_from(datum/species/abductor/old_species)
scientist = old_species.scientist
team = old_species.team
+3 -4
View File
@@ -85,10 +85,9 @@
var/obj/item/organ/tongue/T = H.getorganslot("tongue")
if(!T || T.type != type)
continue
else if(H.dna && H.dna.species.id == "abductor" && user.dna && user.dna.species.id == "abductor")
var/datum/species/abductor/Ayy = user.dna.species
var/datum/species/abductor/Byy = H.dna.species
if(Ayy.team != Byy.team)
if(H.dna && H.dna.species.id == "abductor" && user.dna && user.dna.species.id == "abductor")
var/datum/antagonist/abductor/A = user.mind.has_antag_datum(ANTAG_DATUM_ABDUCTOR)
if(!A || !(H.mind in A.team.members))
continue
to_chat(H, rendered)
for(var/mob/M in GLOB.dead_mob_list)