diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index 2cee9b53b65..6facc15a3eb 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -510,10 +510,12 @@
return parts.Join()
-/proc/printobjectives(datum/mind/ply)
+/proc/printobjectives(list/objectives)
+ if(!objectives || !objectives.len)
+ return
var/list/objective_parts = list()
var/count = 1
- for(var/datum/objective/objective in ply.objectives)
+ for(var/datum/objective/objective in objectives)
if(objective.check_completion())
objective_parts += "Objective #[count]: [objective.explanation_text] Success!"
else
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index b8f376cc336..e4bb0f891fa 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -41,8 +41,6 @@
var/special_role
var/list/restricted_roles = list()
- var/list/datum/objective/objectives = list()
-
var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button.
var/linglink
@@ -347,13 +345,15 @@
output += memory
+ var/list/all_objectives = list()
for(var/datum/antagonist/A in antag_datums)
output += A.antag_memory
+ all_objectives |= A.objectives
- if(objectives.len)
+ if(all_objectives.len)
output += "Objectives:"
var/obj_count = 1
- for(var/datum/objective/objective in objectives)
+ for(var/datum/objective/objective in all_objectives)
output += "
Objective #[obj_count++]: [objective.explanation_text]"
var/list/datum/mind/other_owners = objective.get_owners() - src
if(other_owners.len)
@@ -364,7 +364,7 @@
if(window)
recipient << browse(output,"window=memory")
- else if(objectives.len || memory)
+ else if(all_objectives.len || memory)
to_chat(recipient, "[output]")
/datum/mind/Topic(href, href_list)
@@ -395,34 +395,23 @@
memory = new_memo
else if (href_list["obj_edit"] || href_list["obj_add"])
- var/datum/objective/objective
- var/objective_pos
+ var/objective_pos //Edited objectives need to keep same order in antag objective list
var/def_value
-
var/datum/antagonist/target_antag
+ var/datum/objective/old_objective //The old objective we're replacing/editing
+ var/datum/objective/new_objective //New objective we're be adding
- if (href_list["obj_edit"])
- objective = locate(href_list["obj_edit"])
- if (!objective)
- return
-
+ if(href_list["obj_edit"])
for(var/datum/antagonist/A in antag_datums)
- if(objective in A.objectives)
+ old_objective = locate(href_list["obj_edit"]) in A.objectives
+ if(old_objective)
target_antag = A
- objective_pos = A.objectives.Find(objective)
+ objective_pos = A.objectives.Find(old_objective)
break
-
- if(!target_antag) //Shouldn't happen anymore
- stack_trace("objective without antagonist found")
- objective_pos = objectives.Find(objective)
-
- //Text strings are easy to manipulate. Revised for simplicity.
- var/temp_obj_type = "[objective.type]"//Convert path into a text string.
- def_value = copytext(temp_obj_type, 19)//Convert last part of path into an objective keyword.
- if(!def_value)//If it's a custom objective, it will be an empty string.
- def_value = "custom"
+ if(!old_objective)
+ to_chat(usr,"Invalid objective.")
+ return
else
- //We're adding this objective
if(href_list["target_antag"])
var/datum/antagonist/X = locate(href_list["target_antag"]) in antag_datums
if(X)
@@ -434,7 +423,7 @@
if(1)
target_antag = antag_datums[1]
else
- var/datum/antagonist/target = input("Which antagonist gets the objective:", "Antagonist", def_value) as null|anything in antag_datums + "(new custom antag)"
+ var/datum/antagonist/target = input("Which antagonist gets the objective:", "Antagonist", "(new custom antag)") as null|anything in antag_datums + "(new custom antag)"
if (QDELETED(target))
return
else if(target == "(new custom antag)")
@@ -442,149 +431,89 @@
else
target_antag = target
- var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom")
- if (!new_obj_type)
+
+
+ var/static/list/choices
+ if(!choices)
+ choices = list()
+
+ var/list/allowed_types = list(
+ /datum/objective/assassinate,
+ /datum/objective/maroon,
+ /datum/objective/debrain,
+ /datum/objective/protect,
+ /datum/objective/destroy,
+ /datum/objective/hijack,
+ /datum/objective/escape,
+ /datum/objective/survive,
+ /datum/objective/martyr,
+ /datum/objective/steal,
+ /datum/objective/download,
+ /datum/objective/nuclear,
+ /datum/objective/capture,
+ /datum/objective/absorb,
+ /datum/objective/custom
+ )
+
+ for(var/T in allowed_types)
+ var/datum/objective/X = T
+ choices[initial(X.name)] = T
+
+ if(old_objective)
+ if(old_objective.name in choices)
+ def_value = old_objective.name
+
+ var/selected_type = input("Select objective type:", "Objective type", def_value) as null|anything in choices
+ selected_type = choices[selected_type]
+ if (!selected_type)
return
- var/datum/objective/new_objective = null
-
- switch (new_obj_type)
- if ("assassinate","protect","debrain","maroon")
- var/list/possible_targets = list("Free objective")
- for(var/datum/mind/possible_target in SSticker.minds)
- if ((possible_target != src) && ishuman(possible_target.current))
- possible_targets += possible_target.current
-
- var/mob/def_target = null
- var/list/objective_list = typecacheof(list(/datum/objective/assassinate, /datum/objective/protect, /datum/objective/debrain, /datum/objective/maroon))
- if (is_type_in_typecache(objective, objective_list) && objective.target)
- def_target = objective.target.current
-
- var/mob/new_target = input("Select target:", "Objective target", def_target) as null|anything in possible_targets
- if (!new_target)
- return
-
- var/objective_path = text2path("/datum/objective/[new_obj_type]")
- if (new_target == "Free objective")
- new_objective = new objective_path
- new_objective.owner = src
- new_objective.target = null
- new_objective.explanation_text = "Free objective"
- else
- new_objective = new objective_path
- new_objective.owner = src
- new_objective.target = new_target.mind
- //Will display as special role if the target is set as MODE. Ninjas/commandos/nuke ops.
- new_objective.update_explanation_text()
-
- if ("destroy")
- var/list/possible_targets = active_ais(1)
- if(possible_targets.len)
- var/mob/new_target = input("Select target:", "Objective target") as null|anything in possible_targets
- new_objective = new /datum/objective/destroy
- new_objective.target = new_target.mind
- new_objective.owner = src
- new_objective.update_explanation_text()
- else
- to_chat(usr, "No active AIs with minds")
-
- if ("prevent")
- new_objective = new /datum/objective/block
- new_objective.owner = src
-
- if ("hijack")
- new_objective = new /datum/objective/hijack
- new_objective.owner = src
-
- if ("escape")
- new_objective = new /datum/objective/escape
- new_objective.owner = src
-
- if ("survive")
- new_objective = new /datum/objective/survive
- new_objective.owner = src
-
- if("martyr")
- new_objective = new /datum/objective/martyr
- new_objective.owner = src
-
- if ("nuclear")
- new_objective = new /datum/objective/nuclear
- new_objective.owner = src
-
- if ("steal")
- if (!istype(objective, /datum/objective/steal))
- new_objective = new /datum/objective/steal
- new_objective.owner = src
- else
- new_objective = objective
- var/datum/objective/steal/steal = new_objective
- if (!steal.select_target())
- return
-
- if("download","capture","absorb")
- var/def_num
- if(objective&&objective.type==text2path("/datum/objective/[new_obj_type]"))
- def_num = objective.target_amount
-
- var/target_number = input("Input target number:", "Objective", def_num) as num | null
- if (isnull(target_number))//Ordinarily, you wouldn't need isnull. In this case, the value may already exist.
- return
-
- switch(new_obj_type)
- if("download")
- new_objective = new /datum/objective/download
- new_objective.explanation_text = "Download [target_number] research node\s."
- if("capture")
- new_objective = new /datum/objective/capture
- new_objective.explanation_text = "Capture [target_number] lifeforms with an energy net. Live, rare specimens are worth more."
- if("absorb")
- new_objective = new /datum/objective/absorb
- new_objective.explanation_text = "Absorb [target_number] compatible genomes."
- new_objective.owner = src
- new_objective.target_amount = target_number
-
- if ("custom")
- var/expl = stripped_input(usr, "Custom objective:", "Objective", objective ? objective.explanation_text : "")
- if (!expl)
- return
- new_objective = new /datum/objective
- new_objective.owner = src
- new_objective.explanation_text = expl
-
- if (!new_objective)
- return
-
- if (objective)
- if(target_antag)
- target_antag.objectives -= objective
- objectives -= objective
- target_antag.objectives.Insert(objective_pos, new_objective)
- message_admins("[key_name_admin(usr)] edited [current]'s objective to [new_objective.explanation_text]")
- log_admin("[key_name(usr)] edited [current]'s objective to [new_objective.explanation_text]")
- else
- if(target_antag)
- target_antag.objectives += new_objective
- objectives += new_objective
+ if(!old_objective)
+ //Add new one
+ new_objective = new selected_type
+ new_objective.owner = src
+ new_objective.admin_edit(usr)
+ target_antag.objectives += new_objective
message_admins("[key_name_admin(usr)] added a new objective for [current]: [new_objective.explanation_text]")
log_admin("[key_name(usr)] added a new objective for [current]: [new_objective.explanation_text]")
+ else
+ if(old_objective.type == selected_type)
+ //Edit the old
+ old_objective.admin_edit(usr)
+ new_objective = old_objective
+ else
+ //Replace the old
+ new_objective = new selected_type
+ new_objective.owner = src
+ new_objective.admin_edit(usr)
+ target_antag.objectives -= old_objective
+ target_antag.objectives.Insert(objective_pos, new_objective)
+ message_admins("[key_name_admin(usr)] edited [current]'s objective to [new_objective.explanation_text]")
+ log_admin("[key_name(usr)] edited [current]'s objective to [new_objective.explanation_text]")
else if (href_list["obj_delete"])
- var/datum/objective/objective = locate(href_list["obj_delete"])
- if(!istype(objective))
- return
-
+ var/datum/objective/objective
for(var/datum/antagonist/A in antag_datums)
- if(objective in A.objectives)
+ objective = locate(href_list["obj_delete"]) in A.objectives
+ if(istype(objective))
A.objectives -= objective
break
- objectives -= objective
+ if(!objective)
+ to_chat(usr,"Invalid objective.")
+ return
+ //qdel(objective) Needs cleaning objective destroys
message_admins("[key_name_admin(usr)] removed an objective for [current]: [objective.explanation_text]")
log_admin("[key_name(usr)] removed an objective for [current]: [objective.explanation_text]")
else if(href_list["obj_completed"])
- var/datum/objective/objective = locate(href_list["obj_completed"])
- if(!istype(objective))
+ var/datum/objective/objective
+ for(var/datum/antagonist/A in antag_datums)
+ objective = locate(href_list["obj_completed"]) in A.objectives
+ if(istype(objective))
+ objective = objective
+ break
+ if(!objective)
+ to_chat(usr,"Invalid objective.")
return
objective.completed = !objective.completed
log_admin("[key_name(usr)] toggled the win state for [current]'s objective: [objective.explanation_text]")
@@ -639,10 +568,17 @@
usr = current
traitor_panel()
+
+/datum/mind/proc/get_all_objectives()
+ var/list/all_objectives = list()
+ for(var/datum/antagonist/A in antag_datums)
+ all_objectives |= A.objectives
+ return all_objectives
+
/datum/mind/proc/announce_objectives()
var/obj_count = 1
to_chat(current, "Your current objectives:")
- for(var/objective in objectives)
+ for(var/objective in get_all_objectives())
var/datum/objective/O = objective
to_chat(current, "Objective #[obj_count]: [O.explanation_text]")
obj_count++
diff --git a/code/game/gamemodes/devil/devil agent/devil_agent.dm b/code/game/gamemodes/devil/devil agent/devil_agent.dm
index ec09bfc739b..789cff5c8f3 100644
--- a/code/game/gamemodes/devil/devil agent/devil_agent.dm
+++ b/code/game/gamemodes/devil/devil agent/devil_agent.dm
@@ -34,11 +34,12 @@
//If you override this method, have it return the number of objectives added.
if(devil_target_list.len && devil_target_list[devil]) // Is a double agent
var/datum/mind/target_mind = devil_target_list[devil]
+ var/datum/antagonist/devil/D = target_mind.has_antag_datum(/datum/antagonist/devil)
var/datum/objective/devil/outsell/outsellobjective = new
outsellobjective.owner = devil
outsellobjective.target = target_mind
outsellobjective.update_explanation_text()
- devil.objectives += outsellobjective
+ D.objectives += outsellobjective
return 1
return 0
diff --git a/code/game/gamemodes/devil/game_mode.dm b/code/game/gamemodes/devil/game_mode.dm
index 2255766e749..208a24f3e51 100644
--- a/code/game/gamemodes/devil/game_mode.dm
+++ b/code/game/gamemodes/devil/game_mode.dm
@@ -4,11 +4,12 @@
/datum/game_mode/proc/add_devil_objectives(datum/mind/devil_mind, quantity)
var/list/validtypes = list(/datum/objective/devil/soulquantity, /datum/objective/devil/soulquality, /datum/objective/devil/sintouch, /datum/objective/devil/buy_target)
+ var/datum/antagonist/devil/D = devil_mind.has_antag_datum(/datum/antagonist/devil)
for(var/i = 1 to quantity)
var/type = pick(validtypes)
var/datum/objective/devil/objective = new type(null)
objective.owner = devil_mind
- devil_mind.objectives += objective
+ D.objectives += objective
if(!istype(objective, /datum/objective/devil/buy_target))
validtypes -= type //prevent duplicate objectives, EXCEPT for buy_target.
else
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 517876d0cf3..88dbc6bfb9b 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -1,6 +1,7 @@
/datum/objective
var/datum/mind/owner //The primary owner of the objective. !!SOMEWHAT DEPRECATED!! Prefer using 'team' for new code.
- var/datum/team/team //An alternative to 'owner': a team. Use this when writing new code.
+ var/datum/team/team //An alternative to 'owner': a team. Use this when writing new code.
+ var/name = "generic objective" //Name for admin prompts
var/explanation_text = "Nothing" //What that person is supposed to do.
var/team_explanation_text //For when there are multiple owners.
var/datum/mind/target = null //If they are focused on a particular person.
@@ -17,6 +18,32 @@
if(owner)
. += owner
+/datum/objective/proc/admin_edit(mob/admin)
+ return
+
+//Shared by few objective types
+/datum/objective/proc/admin_simple_target_pick(mob/admin)
+ var/list/possible_targets = list("Free objective")
+ var/def_value
+ for(var/datum/mind/possible_target in SSticker.minds)
+ if ((possible_target != src) && ishuman(possible_target.current))
+ possible_targets += possible_target.current
+
+
+ if(target && target.current)
+ def_value = target.current
+
+ var/mob/new_target = input(admin,"Select target:", "Objective target", def_value) as null|anything in possible_targets
+ if (!new_target)
+ return
+
+ if (new_target == "Free objective")
+ target = null
+ else
+ target = new_target.mind
+
+ update_explanation_text()
+
/datum/objective/proc/considered_escaped(datum/mind/M)
if(!considered_alive(M))
return FALSE
@@ -37,7 +64,7 @@
/datum/objective/proc/is_unique_objective(possible_target)
var/list/datum/mind/owners = get_owners()
for(var/datum/mind/M in owners)
- for(var/datum/objective/O in M.objectives)
+ for(var/datum/objective/O in M.get_all_objectives()) //This scope is debatable, probably should be passed in by caller.
if(istype(O, type) && O.get_target() == possible_target)
return FALSE
return TRUE
@@ -115,6 +142,7 @@
H.equip_in_one_of_slots(O, slots)
/datum/objective/assassinate
+ name = "assasinate"
var/target_role_type=0
martyr_compatible = 1
@@ -134,6 +162,9 @@
else
explanation_text = "Free Objective"
+/datum/objective/assassinate/admin_edit(mob/admin)
+ admin_simple_target_pick(admin)
+
/datum/objective/assassinate/internal
var/stolen = 0 //Have we already eliminated this target?
@@ -143,6 +174,7 @@
explanation_text = "Assassinate [target.name], who was obliterated"
/datum/objective/mutiny
+ name = "mutiny"
var/target_role_type=0
martyr_compatible = 1
@@ -166,6 +198,7 @@
explanation_text = "Free Objective"
/datum/objective/maroon
+ name = "maroon"
var/target_role_type=0
martyr_compatible = 1
@@ -184,7 +217,11 @@
else
explanation_text = "Free Objective"
+/datum/objective/maroon/admin_edit(mob/admin)
+ admin_simple_target_pick(admin)
+
/datum/objective/debrain
+ name = "debrain"
var/target_role_type=0
/datum/objective/debrain/find_target_by_role(role, role_type=0, invert=0)
@@ -215,7 +252,11 @@
else
explanation_text = "Free Objective"
+/datum/objective/debrain/admin_edit(mob/admin)
+ admin_simple_target_pick(admin)
+
/datum/objective/protect//The opposite of killing a dude.
+ name = "protect"
martyr_compatible = 1
var/target_role_type = 0
var/human_check = TRUE
@@ -236,10 +277,15 @@
else
explanation_text = "Free Objective"
+/datum/objective/protect/admin_edit(mob/admin)
+ admin_simple_target_pick(admin)
+
/datum/objective/protect/nonhuman
+ name = "protect nonhuman"
human_check = FALSE
/datum/objective/hijack
+ name = "hijack"
explanation_text = "Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody."
team_explanation_text = "Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody. Leave no team member behind."
martyr_compatible = 0 //Technically you won't get both anyway.
@@ -254,6 +300,7 @@
return SSshuttle.emergency.is_hijacked()
/datum/objective/block
+ name = "no organics on shuttle"
explanation_text = "Do not allow any organic lifeforms to escape on the shuttle alive."
martyr_compatible = 1
@@ -267,6 +314,7 @@
return TRUE
/datum/objective/purge
+ name = "no mutants on shuttle"
explanation_text = "Ensure no mutant humanoid species are present aboard the escape shuttle."
martyr_compatible = 1
@@ -281,6 +329,7 @@
return TRUE
/datum/objective/robot_army
+ name = "robot army"
explanation_text = "Have at least eight active cyborgs synced to you."
martyr_compatible = 0
@@ -297,6 +346,7 @@
return counter >= 8
/datum/objective/escape
+ name = "escape"
explanation_text = "Escape on the shuttle or an escape pod alive and without being in custody."
team_explanation_text = "Have all members of your team escape on a shuttle or pod alive, without being in custody."
@@ -309,6 +359,7 @@
return TRUE
/datum/objective/escape/escape_with_identity
+ name = "escape with identity"
var/target_real_name // Has to be stored because the target's real_name can change over the course of the round
var/target_missing_id
@@ -344,7 +395,11 @@
return TRUE
return FALSE
+/datum/objective/escape/escape_with_identity/admin_edit(mob/admin)
+ admin_simple_target_pick(admin)
+
/datum/objective/survive
+ name = "survive"
explanation_text = "Stay alive until the end."
/datum/objective/survive/check_completion()
@@ -355,6 +410,7 @@
return TRUE
/datum/objective/survive/exist //Like survive, but works for silicons and zombies and such.
+ name = "survive nonhuman"
/datum/objective/survive/exist/check_completion()
var/list/datum/mind/owners = get_owners()
@@ -364,6 +420,7 @@
return TRUE
/datum/objective/martyr
+ name = "martyr"
explanation_text = "Die a glorious death."
/datum/objective/martyr/check_completion()
@@ -374,6 +431,7 @@
return TRUE
/datum/objective/nuclear
+ name = "nuclear"
explanation_text = "Destroy the station with a nuclear device."
martyr_compatible = 1
@@ -384,6 +442,7 @@
GLOBAL_LIST_EMPTY(possible_items)
/datum/objective/steal
+ name = "steal"
var/datum/objective_item/targetinfo = null //Save the chosen item datum so we can access it later.
var/obj/item/steal_target = null //Needed for custom objectives (they're just items, not datums).
martyr_compatible = 0
@@ -421,18 +480,18 @@ GLOBAL_LIST_EMPTY(possible_items)
explanation_text = "Free objective"
return
-/datum/objective/steal/proc/select_target() //For admins setting objectives manually.
+/datum/objective/steal/admin_edit(mob/admin)
var/list/possible_items_all = GLOB.possible_items+"custom"
- var/new_target = input("Select target:", "Objective target", steal_target) as null|anything in possible_items_all
+ var/new_target = input(admin,"Select target:", "Objective target", steal_target) as null|anything in possible_items_all
if (!new_target)
return
if (new_target == "custom") //Can set custom items.
- var/obj/item/custom_target = input("Select type:","Type") as null|anything in typesof(/obj/item)
+ var/obj/item/custom_target = input(admin,"Select type:","Type") as null|anything in typesof(/obj/item)
if (!custom_target)
return
var/custom_name = initial(custom_target.name)
- custom_name = stripped_input("Enter target name:", "Objective target", custom_name)
+ custom_name = stripped_input(admin,"Enter target name:", "Objective target", custom_name)
if (!custom_name)
return
steal_target = custom_target
@@ -440,7 +499,6 @@ GLOBAL_LIST_EMPTY(possible_items)
else
set_target(new_target)
- return steal_target
/datum/objective/steal/check_completion()
var/list/datum/mind/owners = get_owners()
@@ -464,9 +522,9 @@ GLOBAL_LIST_EMPTY(possible_items)
return TRUE
return FALSE
-
GLOBAL_LIST_EMPTY(possible_items_special)
/datum/objective/steal/special //ninjas are so special they get their own subtype good for them
+ name = "steal special"
/datum/objective/steal/special/New()
..()
@@ -478,8 +536,12 @@ GLOBAL_LIST_EMPTY(possible_items_special)
return set_target(pick(GLOB.possible_items_special))
/datum/objective/steal/exchange
+ name = "exchange"
martyr_compatible = 0
+/datum/objective/steal/exchange/admin_edit(mob/admin)
+ return
+
/datum/objective/steal/exchange/proc/set_faction(faction,otheragent)
target = otheragent
if(faction == "red")
@@ -499,6 +561,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
/datum/objective/steal/exchange/backstab
+ name = "prevent exchange"
/datum/objective/steal/exchange/backstab/set_faction(faction)
if(faction == "red")
@@ -510,12 +573,17 @@ GLOBAL_LIST_EMPTY(possible_items_special)
/datum/objective/download
+ name = "download"
/datum/objective/download/proc/gen_amount_goal()
target_amount = rand(20,40)
- explanation_text = "Download [target_amount] research node\s."
+ update_explanation_text()
return target_amount
+/datum/objective/download/update_explanation_text()
+ ..()
+ explanation_text = "Download [target_amount] research node\s."
+
/datum/objective/download/check_completion()
var/datum/techweb/checking = new
var/list/datum/mind/owners = get_owners()
@@ -532,12 +600,23 @@ GLOBAL_LIST_EMPTY(possible_items_special)
TD.stored_research.copy_research_to(checking)
return checking.researched_nodes.len >= target_amount
+/datum/objective/download/admin_edit(mob/admin)
+ var/count = input(admin,"How many nodes ?","Nodes",target_amount) as num|null
+ if(count)
+ target_amount = count
+ update_explanation_text()
+
/datum/objective/capture
+ name = "capture"
/datum/objective/capture/proc/gen_amount_goal()
- target_amount = rand(5,10)
- explanation_text = "Capture [target_amount] lifeform\s with an energy net. Live, rare specimens are worth more."
- return target_amount
+ target_amount = rand(5,10)
+ update_explanation_text()
+ return target_amount
+
+/datum/objective/capture/update_explanation_text()
+ . = ..()
+ explanation_text = "Capture [target_amount] lifeform\s with an energy net. Live, rare specimens are worth more."
/datum/objective/capture/check_completion()//Basically runs through all the mobs in the area to determine how much they are worth.
var/captured_amount = 0
@@ -567,10 +646,16 @@ GLOBAL_LIST_EMPTY(possible_items_special)
captured_amount+=2
return captured_amount >= target_amount
+/datum/objective/capture/admin_edit(mob/admin)
+ var/count = input(admin,"How many mobs to capture ?","capture",target_amount) as num|null
+ if(count)
+ target_amount = count
+ update_explanation_text()
//Changeling Objectives
/datum/objective/absorb
+ name = "absorb"
/datum/objective/absorb/proc/gen_amount_goal(lowbound = 4, highbound = 6)
target_amount = rand (lowbound,highbound)
@@ -586,9 +671,19 @@ GLOBAL_LIST_EMPTY(possible_items_special)
n_p ++
target_amount = min(target_amount, n_p)
- explanation_text = "Extract [target_amount] compatible genome\s."
+ update_explanation_text()
return target_amount
+/datum/objective/absorb/update_explanation_text()
+ . = ..()
+ explanation_text = "Extract [target_amount] compatible genome\s."
+
+/datum/objective/absorb/admin_edit(mob/admin)
+ var/count = input(admin,"How many people to absorb?","absorb",target_amount) as num|null
+ if(count)
+ target_amount = count
+ update_explanation_text()
+
/datum/objective/absorb/check_completion()
var/list/datum/mind/owners = get_owners()
var/absorbedcount = 0
@@ -602,6 +697,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
return absorbedcount >= target_amount
/datum/objective/absorb_most
+ name = "absorb most"
explanation_text = "Extract more compatible genomes than any other Changeling."
/datum/objective/absorb_most/check_completion()
@@ -622,6 +718,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
return TRUE
/datum/objective/absorb_changeling
+ name = "absorb changeling"
explanation_text = "Absorb another Changeling."
/datum/objective/absorb_changeling/check_completion()
@@ -644,6 +741,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
//End Changeling Objectives
/datum/objective/destroy
+ name = "destroy AI"
martyr_compatible = 1
/datum/objective/destroy/find_target()
@@ -665,10 +763,20 @@ GLOBAL_LIST_EMPTY(possible_items_special)
else
explanation_text = "Free Objective"
+/datum/objective/destroy/admin_edit(mob/admin)
+ var/list/possible_targets = active_ais(1)
+ if(possible_targets.len)
+ var/mob/new_target = input(admin,"Select target:", "Objective target") as null|anything in possible_targets
+ target = new_target.mind
+ else
+ to_chat(admin, "No active AIs with minds")
+ update_explanation_text()
+
/datum/objective/destroy/internal
var/stolen = FALSE //Have we already eliminated this target?
/datum/objective/steal_five_of_type
+ name = "steal five of"
explanation_text = "Steal at least five items!"
var/list/wanted_items = list(/obj/item)
@@ -677,10 +785,12 @@ GLOBAL_LIST_EMPTY(possible_items_special)
wanted_items = typecacheof(wanted_items)
/datum/objective/steal_five_of_type/summon_guns
+ name = "steal guns"
explanation_text = "Steal at least five guns!"
wanted_items = list(/obj/item/gun)
/datum/objective/steal_five_of_type/summon_magic
+ name = "steal magic"
explanation_text = "Steal at least five magical artefacts!"
wanted_items = list(/obj/item/spellbook, /obj/item/gun/magic, /obj/item/clothing/suit/space/hardsuit/wizard, /obj/item/scrying, /obj/item/antag_spawner/contract, /obj/item/necromantic_stone)
@@ -696,6 +806,14 @@ GLOBAL_LIST_EMPTY(possible_items_special)
stolen_count++
return stolen_count >= 5
+//Created by admin tools
+/datum/objective/custom
+ name = "custom"
+
+/datum/objective/custom/admin_edit(mob/admin)
+ var/expl = stripped_input(admin, "Custom objective:", "Objective", explanation_text)
+ if(expl)
+ explanation_text = expl
////////////////////////////////
// Changeling team objectives //
diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm
index aa91af1dd85..3bb47139e0c 100644
--- a/code/modules/antagonists/_common/antag_datum.dm
+++ b/code/modules/antagonists/_common/antag_datum.dm
@@ -96,7 +96,6 @@ GLOBAL_LIST_EMPTY(antagonists)
LAZYREMOVE(owner.antag_datums, src)
if(!silent && owner.current)
farewell()
- owner.objectives -= objectives
var/datum/team/team = get_team()
if(team)
team.remove_member(owner)
@@ -132,14 +131,14 @@ GLOBAL_LIST_EMPTY(antagonists)
report += printplayer(owner)
var/objectives_complete = TRUE
- if(owner.objectives.len)
- report += printobjectives(owner)
- for(var/datum/objective/objective in owner.objectives)
+ if(objectives.len)
+ report += printobjectives(objectives)
+ for(var/datum/objective/objective in objectives)
if(!objective.check_completion())
objectives_complete = FALSE
break
- if(owner.objectives.len == 0 || objectives_complete)
+ if(objectives.len == 0 || objectives_complete)
report += "The [name] was successful!"
else
report += "The [name] has failed!"
@@ -216,25 +215,6 @@ GLOBAL_LIST_EMPTY(antagonists)
return
antag_memory = new_memo
-//This datum will autofill the name with special_role
-//Used as placeholder for minor antagonists, please create proper datums for these
-/datum/antagonist/auto_custom
- show_in_antagpanel = FALSE
- antagpanel_category = "Other"
- show_name_in_check_antagonists = TRUE
-
-/datum/antagonist/auto_custom/on_gain()
- ..()
- name = owner.special_role
- //Add all objectives not already owned by other datums to this one.
- var/list/already_registered_objectives = list()
- for(var/datum/antagonist/A in owner.antag_datums)
- if(A == src)
- continue
- else
- already_registered_objectives |= A.objectives
- objectives = owner.objectives - already_registered_objectives
-
//This one is created by admin tools for custom objectives
/datum/antagonist/custom
antagpanel_category = "Custom"
diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm
index 8e29b38fe15..d15957881f3 100644
--- a/code/modules/antagonists/abductor/abductor.dm
+++ b/code/modules/antagonists/abductor/abductor.dm
@@ -42,12 +42,11 @@
/datum/antagonist/abductor/on_gain()
owner.special_role = "[name] [sub_role]"
owner.assigned_role = "[name] [sub_role]"
- owner.objectives += team.objectives
+ objectives += team.objectives
finalize_abductor()
return ..()
/datum/antagonist/abductor/on_removal()
- owner.objectives -= team.objectives
if(owner.current)
to_chat(owner.current,"You are no longer the [owner.special_role]!")
owner.special_role = null
@@ -146,7 +145,7 @@
result += "The abductors of [name] were:"
for(var/datum/mind/abductor_mind in members)
result += printplayer(abductor_mind)
- result += printobjectives(abductor_mind)
+ result += printobjectives(objectives)
return "