Files
goonstation-2016/code/datums/objective.dm
ZeWaka acb4d0c027 2018 Mapping Update #2
Carpets are now pathed.
Areas have been updated, along with their icons. Wingrille spawners have been updated.
Access spawner objects have been added, allowing for easy access setting on doors.
Drain placeholders have been added, allowing for pre-placement of drains on maps.
Updated the Map Submission Guidelines in the maps folder.
2018-06-26 17:02:08 -10:00

1137 lines
36 KiB
Plaintext

/datum/objective
var/datum/mind/owner
var/explanation_text
var/medal_name = null // Called by ticker.mode.declare_completion().
var/medal_announce = 1
New(var/text)
if(text)
src.explanation_text = text
proc/check_completion()
return 1
proc/set_up()
return
///////////////////////////////////////////////////
// Regular objectives active in current gameplay //
///////////////////////////////////////////////////
/datum/objective/regular/assassinate
var/datum/mind/target
var/targetname
set_up()
var/list/possible_targets = list()
for(var/datum/mind/possible_target in ticker.minds)
if (possible_target && (possible_target != owner) && istype(possible_target.current, /mob/living/carbon/human))
// 1) Wizard marked as another wizard's target.
// 2) Presence of wizard is revealed to other antagonists at round start.
// Both are bad.
if (possible_target.special_role == "wizard")
continue
if (possible_target.current.mind && possible_target.current.mind.is_target) // Cannot read null.is_target
continue
if (!possible_target.current.client)
continue
possible_targets += possible_target
if(possible_targets.len > 0)
target = pick(possible_targets)
target.current.mind.is_target = 1
create_objective_string(target)
return target
proc/find_target_by_role(var/role)
for(var/datum/mind/possible_target in ticker.minds)
if((possible_target != owner) && istype(possible_target.current, /mob/living/carbon/human) && (possible_target.assigned_role == role || (possible_target.assigned_role == "MODE" && possible_target.special_role == role)))
target = possible_target
break
create_objective_string(target)
return target
check_completion()
if(target && target.current)
if(target.current.stat == 2 || !iscarbon(target.current))
return 1
else
return 0
else
return 1
proc/create_objective_string(var/datum/mind/target)
if(!(target && target.current))
explanation_text = "Go hog wild!"
return
var/add_fluff = prob(50)
var/objective_text = "Assassinate [target.current.real_name], the [target.assigned_role == "MODE" ? target.special_role : target.assigned_role][add_fluff ? " " : "."]"
if(add_fluff)
var/fluff = create_fluff(target)
objective_text += "[fluff]."
explanation_text = objective_text
targetname = target.current.real_name
proc/create_fluff(var/datum/mind/target)
if(!istype(target)) return ""
var/job = target.assigned_role == "MODE" ? target.special_role : target.assigned_role
var/datum/job/J = find_job_in_controller_by_string(job)
var/list/general_fluff = strings("assassination_fluff.txt", "general") //Get a list of objectives matching every job
var/list/special_fluff = list()
if(J) //Ok, we found their job - now to build a list of job-specific stuff
special_fluff += strings("assassination_fluff.txt", ckey(J.name), 1)
if(J.name != J.initial_name) //We got us a case of alt_names
special_fluff += strings("assassination_fluff.txt", ckey(J.initial_name), 1)
//Pick which flufftext we want to use
var/flufftext
if(general_fluff && special_fluff.len)
flufftext = pick(prob(50) ? general_fluff : special_fluff)
else if (general_fluff)
flufftext = pick(general_fluff)
else if (special_fluff.len)
flufftext = pick(special_fluff)
if(flufftext)
//Add pronouns
var/mob/M = target.current
flufftext = replacetext(flufftext, "$HE", he_or_she(M))
flufftext = replacetext(flufftext, "$HIMSELF", himself_or_herself(M))
flufftext = replacetext(flufftext, "$HIM", him_or_her(M))
flufftext = replacetext(flufftext, "$HIS", his_or_her(M))
flufftext = replacetext(flufftext, "$JOB", job)
return flufftext
/datum/objective/regular/borgdeath
explanation_text = "Deactivate or destroy all Cyborgs on the station. If you end up borged, you do not need to kill yourself or be un-borged to win."
check_completion()
for(var/mob/living/silicon/robot/R in mobs)
if (owner.current == R)
continue
if (R.stat != 2 && R.brain)
return 0
return 1
/datum/objective/regular/aikill
explanation_text = "Steal the AI's neural net processor."
check_completion()
if(owner.current && owner.current.check_contents_for(/obj/item/organ/brain/ai))
return 1
else
return 0
/datum/objective/regular/steal
var/obj/item/steal_target
var/target_name
set_up()
var/list/items = list( "head of security\'s jumpsuit", "pair of optical thermal scanners",
"research director\'s jumpsuit", "head of personnel\'s jumpsuit", "hand teleporter", "RCD",
"captain\'s jumpsuit", "computer core master tape")
target_name = pick(items)
switch(target_name)
if("head of security\'s jumpsuit")
steal_target = /obj/item/clothing/under/rank/head_of_securityold
if("pair of optical thermal scanners")
steal_target = /obj/item/clothing/glasses/thermal
if("research director\'s jumpsuit")
steal_target = /obj/item/clothing/under/rank/research_director
if("head of personnel\'s jumpsuit")
steal_target = /obj/item/clothing/under/suit/hop
if("hand teleporter")
steal_target = /obj/item/hand_tele
if("RCD")
steal_target = /obj/item/rcd
if("captain\'s jumpsuit")
steal_target = /obj/item/clothing/under/rank/captain
if("computer core master tape")
steal_target = /obj/item/disk/data/tape/master
explanation_text = "Steal a [target_name]."
return steal_target
check_completion()
if(steal_target)
if(owner.current && owner.current.check_contents_for(steal_target, 1))
return 1
else
return 0
/datum/objective/regular/gimmick
explanation_text = "Go hog wild!"
set_up()
var/list/gimmick_list = list("Try to frame innocent crewmembers for various crimes.",
"Try to sabotage as much station infrastructure as possible without getting caught.",
"Try to ruin a department's productivity with constant annoyances.",
"Get yourself arrested, and then stage a violent jailbreak. The more collateral damage the better!",
"If anyone gets arrested, try to rescue them. The Syndicate values its employees!",
"If anyone gets arrested, try to eliminate them. The Syndicate does not appreciate failure.",
"Try to severely obstruct the flow of traffic around the station with barricades, sabotage, or construction projects.",
"Incite the other crewmembers to violence and chaos without ever doing anything direct.",
"Wage a personal war against all the assistants. Try to eradicate them without attracting the attention of other departments.",
"Play increasingly more dangerous pranks on other crew members. If confronted, insist it was just a joke.",
"Waste Medbay's time by causing a lot of non-fatal injuries around the station.",
"Waste Security's time by committing a lot of minor crimes.",
"Waste the AI's time by deactivating its access to anything you can.",
"Lay various traps around the station. Be dastardly as heck.",
"Start as many petty arguments and fistfights as possible. Be a real jerk.",
"Try to make everyone hate a job department of your choice, through misdirection and slander.",
"Sneak into a department of your choice every once in awhile and mess with all the things inside.",
"Try to deprive the station of medical items and objects.",
"Try to deprive the station of tools and useful items.",
"Try to deprive the station of clothing.",
"Try to deprive the station of their ID cards.",
"Make the station as ugly and visually unpleasant as you can.",
"Try to get the AI declared rogue and shut down.",
"Get your hands on some weapons and then hand them out to the most untrustworthy crew members.",
"Become a literal arms dealer. Harvest as many body parts as possible from the crew.",
"Become a headhunter. Literally. Collect the crew's heads and take them with you.",
"Become a vigilante and violently harass people over the slightest suspicion.",
"Seek out any non-security vigilantes on the station and make their life utter hell.",
"Find another crew member's pet project and subvert it to a more violent purpose.",
"BURN IT ALL DOWN.",
"FUCK THE POLICE.",
"Try to become a supervillain by using costumes, treachery, and a lot of bluster and bravado.")
var/gimmick_text = pick(gimmick_list)
explanation_text = "[gimmick_text] <i>This objective is not tracked and will automatically succeed, so just have fun with it!</i>"
return
check_completion()
return 1
/datum/objective/regular/bonsaitree
// Brought this back as a very rare gimmick objective (Convair880).
explanation_text = "Destroy the Captain's prized bonsai tree."
check_completion()
var/area/cap_quarters = locate(/area/station/crew_quarters/captain)
var/obj/shrub/captainshrub/our_tree
for (var/obj/shrub/captainshrub/T in cap_quarters)
our_tree = T
if (!our_tree)
return 1 // Somebody deleted it somehow, I suppose?
else if (our_tree && our_tree.destroyed == 1)
return 1
else
return 0
/datum/objective/regular/damage_area
var/area/target_area = null
var/area_attempt = 0
var/area_autopass = 0
var/initial_value_score = 0
var/damage_threshold = 50 // 25 was way too strict for larger rooms, causing people to fail the objective most of the time.
set_up()
var/list/target_areas = list(/area/station/chemistry,
/area/station/science/artifact,
/area/station/science/lab,
/area/station/science/teleporter,
/*/area/station/medical/medbay,*/ // On Cogmap 1, medbay is split up into three separate areas.
/area/station/medical/research,
/area/station/medical/robotics,
/area/station/crew_quarters/courtroom,
/area/station/bridge,
/area/station/security/brig,
/area/station/security/main,
/area/station/crew_quarters/quarters,
/area/station/crew_quarters/cafeteria,
/area/station/chapel/main,
/area/station/hydroponics,
/area/station/quartermaster/office,
/area/station/engine/elect,
/area/station/engine/engineering,
/area/station/turret_protected/ai_upload,
/area/station/hallway/secondary/exit)
target_area = get_area_by_type(pick(target_areas))
while (src.area_attempt < 4 && (!target_area || !istype(target_area)))
if (!target_area || !istype(target_area))
target_area = get_area_by_type(pick(target_areas))
src.area_attempt++
if (!target_area || !istype(target_area))
src.area_autopass = 1
explanation_text = "Cause significant damage to...whoops, couldn't find a valid target area. Objective will succeed automatically."
else
initial_value_score = target_area.calculate_area_value()
explanation_text = "Cause significant damage to [target_area]."
check_completion()
if (src.area_autopass == 1)
return 1
var/current_value_score = target_area.calculate_area_value()
var/damage_perc = (max(1,current_value_score) / initial_value_score) * 100
if (damage_perc <= damage_threshold)
return 1
return 0
/datum/objective/regular/destroy_equipment
var/target_equipment = null
var/target_name
set_up()
var/list/choices = list("cryo cells","cloning pods","cyborg recharge stations",
"chem dispensers","plasma canisters","arc smelters","plant pots","large pod vehicles")
target_name = pick(choices)
switch(target_name)
if ("cryo cells")
target_equipment = /obj/machinery/atmospherics/unary/cryo_cell
if ("cloning pods")
target_equipment = /obj/machinery/clonepod
if ("cyborg recharge stations")
target_equipment = /obj/machinery/recharge_station
if ("chem dispensers")
target_equipment = /obj/machinery/chem_dispenser
if ("plasma canisters")
target_equipment = /obj/machinery/portable_atmospherics/canister/toxins
if ("arc smelters")
target_equipment = /obj/machinery/smelter
if ("plant pots")
target_equipment = /obj/machinery/plantpot
if ("large pod vehicles")
target_equipment = /obj/machinery/vehicle/pod_smooth
explanation_text = "Destroy all [target_name] on the station."
check_completion()
for(var/obj/machinery/M in machines)
if (M.z != 1 || get_area_name(M) == "Space")
continue
if (!istype(M,target_equipment))
continue
if (M.stat & BROKEN)
continue
return 0
return 1
/datum/objective/regular/job_genocide
var/target_job = "Staff Assistant"
set_up()
var/list/targets = list("Staff Assistant","Medical Doctor","Engineer","Security Officer",
"Geneticist","Scientist","Roboticist","Mechanic","Quartermaster","Miner","Botanist")
target_job = pick(targets)
explanation_text = "Kill every [target_job] on the station. You do not need to kill yourself if you are a [target_job]."
check_completion()
for (var/datum/mind/M in ticker.minds)
if (!M.current)
continue
if (M.current == owner.current)
continue
if (M.assigned_role != target_job)
continue
if (M.current.stat != 2 && iscarbon(M.current))
return 0
return 1
/datum/objective/regular/kill_heads
explanation_text = "Kill the Captain, Head of Personnel, Head of Security, Chief Engineer, Medical Director and Research Director."
var/list/targets = list("Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Medical Director", "Research Director")
check_completion()
for (var/datum/mind/M in ticker.minds)
if (!M.current)
continue
if (M.current == owner.current)
continue
if (!(M.assigned_role in targets))
continue
if (M.current.stat != 2 && iscarbon(M.current))
return 0
return 1
/datum/objective/regular/no_clones
explanation_text = "Ensure that no cloned personnel survive. You do not need to kill yourself if cloned."
check_completion()
for(var/mob/living/carbon/human/H in mobs)
if (H == owner.current)
continue
if (!H.bioHolder)
continue
if (H.bioHolder.clone_generation < 1)
continue
if (H.stat != 2 && iscarbon(H))
return 0
return 1
/datum/objective/regular/traitor_supremacy
explanation_text = "Eliminate all other syndicate operatives, changelings and other foes on the station."
medal_name = "Untapped Potential"
check_completion()
for (var/datum/mind/M in ticker.mode.traitors + ticker.mode.Agimmicks)
if (!M.current)
continue
if (M.current.stat != 2)
return 0
return 1
///////////////////////////////////////////////////////////////
// Regular objectives not currently used in current gameplay //
///////////////////////////////////////////////////////////////
/datum/objective/regular/force_evac_time
var/time = 45
explanation_text = "Force the crew to evacuate the station before 45 minutes elapse."
check_completion()
if(round(((world.time / 10) / 60)) < time)
return 1
return 0
/datum/objective/regular/destroy_outpost
explanation_text = "Activate the computer mainframe's self-destruct charge."
check_completion()
if (outpost_destroyed == 1) return 1
else return 0
/datum/objective/regular/multigrab
var/obj/item/multigrab_target
var/multigrab_num
var/target_name
set_up()
var/list/items = list(
"tasers",\
"phasers",\
"lasers",\
"riot shotguns",\
"identification cards",\
"security headsets",\
"command headsets",\
"insulated gloves",\
"stun batons",\
"pairs of sunglasses",\
"security helmets",\
"flashes",\
"multitools",\
"space helmets",\
"limbs",\
"brains",\
"hearts"
)
target_name = pick(items)
switch (target_name)
if ("tasers")
multigrab_target = /obj/item/gun/energy/taser_gun
multigrab_num = rand(2, 5)
if ("phasers")
multigrab_target = /obj/item/gun/energy/phaser_gun
multigrab_num = rand(2, 5)
if ("lasers")
multigrab_target = /obj/item/gun/energy/laser_gun
multigrab_num = rand(2, 5)
if ("riot shotguns")
multigrab_target = /obj/item/gun/kinetic/riotgun
multigrab_num = rand(2, 3)
if ("identification cards")
multigrab_target = /obj/item/card/id
multigrab_num = rand(6, 12)
if ("security headsets")
multigrab_target = /obj/item/device/radio/headset/security
multigrab_num = rand(2, 4)
if ("command headsets")
multigrab_target = /obj/item/device/radio/headset/command
multigrab_num = rand(2, 4)
if ("insulated gloves")
multigrab_target = /obj/item/clothing/gloves/yellow
multigrab_num = rand(3, 8)
if ("stun batons")
multigrab_target = /obj/item/baton
multigrab_num = rand(2, 5)
if ("pairs of sunglasses")
multigrab_target = /obj/item/clothing/glasses/sunglasses
multigrab_num = rand(3, 10)
if ("security helmets")
multigrab_target = /obj/item/clothing/head/helmet
multigrab_num = rand(2, 5)
if ("space helmets")
multigrab_target = /obj/item/clothing/head/helmet/space
multigrab_num = rand(2, 4)
if ("flashes")
multigrab_target = /obj/item/device/flash
multigrab_num = rand(3, 12)
if ("multitools")
multigrab_target = /obj/item/device/multitool
multigrab_num = rand(2, 10)
if ("limbs")
multigrab_target = /obj/item/parts/human_parts
multigrab_num = rand(5, 10)
if ("brains")
multigrab_target = /obj/item/organ/brain
multigrab_num = rand(3, 7)
if ("hearts")
multigrab_target = /obj/item/organ/heart
multigrab_num = rand(3, 7)
if (target_name == "hearts")
explanation_text = "You're a real romeo! Steal the hearts of [multigrab_num] crewmembers."
else
explanation_text = "Steal [multigrab_num] [target_name]."
return multigrab_target
check_completion()
if (multigrab_target)
if (owner.current.check_contents_for_num(multigrab_target, multigrab_num, 1))
return 1
else
return 0
else
return 0
/datum/objective/regular/cash
var/target_cash
var/current_cash
set_up()
target_cash = rand(10000,80000)
explanation_text = "Amass [target_cash] space credits."
check_completion()
if (!owner.current)
return 0
current_cash = 0
// Tweaked to make it more reliable (Convair880).
var/list/L = owner.current.get_all_items_on_mob()
if (L && L.len)
for (var/obj/item/card/id/C in L)
current_cash += C.money
for (var/obj/item/device/pda2/PDA in L)
if (PDA.ID_card)
current_cash += PDA.ID_card.money
for (var/obj/item/spacecash/C in L)
current_cash += C.amount
for (var/datum/data/record/Ba in data_core.bank)
if (Ba.fields["name"] == owner.current.real_name)
current_cash += Ba.fields["current_money"]
if (current_cash >= target_cash)
return 1
else
return 0
////////////////////////////////
// Specialist role objectives //
////////////////////////////////
/datum/objective/specialist/nuclear
explanation_text = "Destroy the station with a nuclear device."
medal_name = "Manhattan Project"
check_completion()
if (ticker && ticker.mode && istype(ticker.mode, /datum/game_mode/nuclear))
var/datum/game_mode/nuclear/N = ticker.mode
if (N && istype(N) && (N.finished == -1 || N.finished == -2))
return 1
return 0
/datum/objective/specialist/conspiracy
explanation_text = "Identify and eliminate any competing syndicate operatives on the station. Be careful not to be too obvious yourself, or they'll come after you!"
check_completion()
if (!owner.current || owner.current.stat == 2)
return 0
if (!istype(ticker.mode, /datum/game_mode/spy))
return 0
var/datum/game_mode/spy/spymode = ticker.mode
for (var/datum/mind/mindCheck in spymode.leaders)
if (mindCheck == owner)
continue
if (mindCheck && mindCheck.current && mindCheck.current.stat != 2)
return 0
return 1
/datum/objective/specialist/absorb
var/absorb_count
set_up()
absorb_count = min(10, (ticker.minds.len - 1))
explanation_text = "Absorb the DNA of at least [absorb_count] more crew members in addition to the one you started with, and escape on the shuttle alive."
check_completion()
if(emergency_shuttle.location<2)
return 0
if(!owner.current || owner.current.stat == 2)
return 0
var/turf/location = get_turf(owner.current.loc)
if(!location)
return 0
var/area/check_area = location.loc
if(!istype(check_area, /area/shuttle/escape/centcom))
return 0
if (!owner.is_changeling)
return 0
if (owner.is_changeling.absorbtions >= absorb_count) // You start with 0 DNA these days, not 1.
return 1
/datum/objective/specialist/drinkblood
medal_name = "Dracula Jr."
var/bloodcount
set_up()
bloodcount = rand(60,100) * 10
explanation_text = "Accumulate at least [bloodcount] units of blood in total."
check_completion()
if (owner.current && owner.current.get_vampire_blood(1) >= bloodcount)
return 1
else
return 0
/datum/objective/specialist/predator/trophy
medal_name = "Dangerous Game"
var/trophycount // Added a bit of randomization here (Convair880).
set_up()
trophycount = min(10, (ticker.minds.len - 1))
//DEBUG_MESSAGE("Found [ticker.minds.len] minds.")
explanation_text = "Take at least [trophycount] trophies. The skulls of worthy opponents are more valuable with regard to this objective."
check_completion()
var/trophyvalue = 0
if (owner.current)
trophyvalue = owner.current.get_skull_value()
//DEBUG_MESSAGE("Objective: [trophycount]. Total trophy value: [trophyvalue].")
if (trophyvalue >= trophycount)
return 1
else
return 0
/datum/objective/specialist/stealth
var/min_score
var/score = 0
var/list/datum/mind/safe_minds = list()
set_up()
var/num_players = 0
for(var/mob/living/player in mobs)
if (player.client) num_players++
min_score = min(500, num_players * 10) + (rand(-5,5) * 10)
explanation_text = "Remain out of sight and accumulate [min_score] points."
check_completion()
if(score >= min_score)
return 1
else
return 0
/datum/objective/specialist/gang
explanation_text = "Kill the leaders of every other gang without being killed yourself."
check_completion()
if (!owner.current || owner.current.stat == 2)
return 0
if (!istype(ticker.mode, /datum/game_mode/gang))
return 0
var/datum/game_mode/gang/gangmode = ticker.mode
for (var/datum/mind/mindCheck in gangmode.leaders)
if (mindCheck == owner)
continue
if (mindCheck && mindCheck.current && mindCheck.current.stat != 2)
return 0
return 1
/datum/objective/specialist/blob
explanation_text = "Grow up to at least 500 tiles in size and force the evacuation of the station."
check_completion()
if (!owner)
return 0
if (!owner.current)
return 0
var/mob/living/intangible/blob_overmind/O = owner.current
if (!istype(O))
return 0
if (O.blobs.len >= 500)
return 1
/datum/objective/specialist/wraith
explanation_text = "Go hog wild!"
proc/onAbsorb(var/mob/M)
return
proc/onWeakened()
return
proc/onBanished()
return
proc/Stat()
return
check_completion()
return 1
/datum/objective/specialist/wraith/absorb
var/absorbs = 0
var/absorb_target
onAbsorb(var/mob/M)
absorbs++
onWeakened()
absorbs = 0
Stat()
stat("Currently absorbed:", "[absorbs] souls")
set_up()
absorb_target = max(1, min(7, round((ticker.minds.len - 5) / 2)))
explanation_text = "Absorb and retain the life essence of at least [absorb_target] mortal(s) that inhabit this material structure."
check_completion()
return absorbs >= absorb_target
/datum/objective/specialist/wraith/murder
var/datum/mind/target
var/targetname
proc/setText()
explanation_text = "We sense a large untapped astral force with the mortal [target.current.real_name], the [target.assigned_role == "MODE" ? target.special_role : target.assigned_role]. Trap them in a spiritual form and ensure that they never manifest as a corporeal being again."
targetname = target.current.real_name
set_up()
var/list/possible_targets = list()
for(var/datum/mind/possible_target in ticker.minds)
if((possible_target != owner) && istype(possible_target.current, /mob/living/carbon/human))
if(possible_target.current.mind.is_target) continue
possible_targets += possible_target
if(possible_targets.len > 0)
target = pick(possible_targets)
target.current.mind.is_target = 1
if(target && target.current)
setText()
else
explanation_text = "Go hog wild!"
return target
proc/find_target_by_role(var/role)
for(var/datum/mind/possible_target in ticker.minds)
if((possible_target != owner) && istype(possible_target.current, /mob/living/carbon/human) && (possible_target.assigned_role == role || (possible_target.assigned_role == "MODE" && possible_target.special_role == role)))
target = possible_target
break
if(target && target.current)
setText()
else
explanation_text = "Go hog wild!"
return target
check_completion()
if(target && target.current)
if(target.current.stat == 2 || !iscarbon(target.current))
if (istype(target.current, /mob/dead))
if (!(target.current:corpse))
return 1
return 0
else
return 1
/datum/objective/specialist/wraith/murder/absorb
var/success = 0
setText()
explanation_text = "[target.current.real_name], the [target.assigned_role == "MODE" ? target.special_role : target.assigned_role] is a vessel for astral energies we haven't detected before. Absorb and retain their essence at all costs!"
targetname = target.current.real_name
onAbsorb(var/mob/M)
if (M == target.current)
success = 1
else if (istype(target.current, /mob/dead))
if (M == target.current:corpse)
success = 1
onWeakened()
if (success)
success = 0
boutput(owner.current, "<span style=\"color:red\">You lose the astral essence of your target!</span>")
check_completion()
return success
/datum/objective/specialist/wraith/prevent
var/max_escapees
set_up()
max_escapees = max(min(5, round(ticker.minds.len / 10)), 1)
explanation_text = "Force the mortals to remain stranded on this structure. No more than [max_escapees] may escape!"
check_completion()
var/area/shuttle = locate(/area/shuttle/escape/centcom)
var/escapees = 0
for (var/mob/living/carbon/player in mobs)
if (get_turf(player) in shuttle)
escapees++
return escapees <= max_escapees
/datum/objective/specialist/wraith/travel
explanation_text = "Locate the hive of the mortal infestation by concealing yourself aboard the escape vehicle."
var/failed = 0
onBanished()
failed = 1
check_completion()
var/area/shuttle = locate(/area/shuttle/escape/centcom)
if (failed)
return 0
if (get_turf(owner.current) in shuttle)
return 1
return 0
/datum/objective/specialist/wraith/survive
explanation_text = "Maintain your material presence by avoiding permanent banishment."
var/failed = 0
onBanished()
failed = 1
check_completion()
if (failed)
return 0
return 1
/datum/objective/specialist/wraith/flawless
explanation_text = "Complete your objectives without your material presence being weakened by temporary banishment."
var/failed = 0
onWeakened()
failed = 1
check_completion()
return !failed
/datum/objective/specialist/werewolf/feed
var/feed_count = 0
var/target_feed_count
var/list/mob/mobs_fed_on = list() // Stores bioHolder.Uid of previous victims, so we can't feed on the same person multiple times.
set_up()
target_feed_count = min(10, (ticker.minds.len - 1))
explanation_text = "Feed on at least [target_feed_count] crew members."
check_completion()
if (feed_count >= target_feed_count)
return 1
/datum/objective/specialist/ruin_xmas
explanation_text = "Ruin Christmas for everyone! Make sure Christmas cheer is at or below 20% when the round ends."
medal_name = "You're a mean one..."
check_completion()
if (christmas_cheer <= 20)
return 1
else
return 0
/////////////////////////////
// Round-ending objectives //
/////////////////////////////
/datum/objective/escape
explanation_text = "Escape on the shuttle alive."
check_completion()
if(emergency_shuttle.location<2)
return 0
if(!owner.current || owner.current.stat ==2)
return 0
var/turf/location = get_turf(owner.current.loc)
if(!location)
return 0
var/area/check_area = location.loc
if(istype(check_area, /area/shuttle/escape/centcom))
return 1
else
return 0
/datum/objective/escape/hijack
explanation_text = "Hijack the emergency shuttle by escaping alone."
check_completion()
if(emergency_shuttle.location<2)
return 0
if(!owner.current || owner.current.stat ==2)
return 0
var/area/shuttle = locate(/area/shuttle/escape/centcom)
for(var/mob/living/player in mobs)
if (player.mind && (player.mind != owner))
if (player.stat != 2) //they're not dead
if (get_turf(player) in shuttle)
return 0
return 1
/datum/objective/escape/survive
explanation_text = "Stay alive until the end."
check_completion()
if(!owner.current || owner.current.stat == 2)
return 0
return 1
/datum/objective/escape/kamikaze
explanation_text = "Die a glorious death."
check_completion()
if(!owner.current || owner.current.stat == 2)
return 1
return 0
/datum/objective/escape/hijack_group
explanation_text = "Hijack the emergency shuttle by escaping alone or with your accomplices."
var/list/datum/mind/accomplices = list()
check_completion()
if(emergency_shuttle.location<2)
return 0
if(!owner.current || owner.current.stat ==2)
return 0
var/area/shuttle = locate(/area/shuttle/escape/centcom)
for(var/mob/living/player in mobs)
if (player.mind && (player.mind != owner) && !(player.mind in accomplices))
if (player.stat != 2) //they're not dead
if (get_turf(player) in shuttle)
return 0
return 1
/////////////////////////////////////////////////////////
// Neatly packaged objective sets for your convenience //
/////////////////////////////////////////////////////////
/datum/objective_set
var/list/objective_list = list(/datum/objective/regular/gimmick)
var/list/escape_choices = list(/datum/objective/escape,
/datum/objective/escape/survive,
/datum/objective/escape/hijack,
/datum/objective/escape/kamikaze)
New(var/datum/mind/enemy)
if(!istype(enemy))
return 1
for(var/X in objective_list)
if (!ispath(X))
continue
ticker.mode.bestow_objective(enemy,X)
if (escape_choices.len > 0)
var/escape_path = pick(escape_choices)
if (ispath(escape_path))
ticker.mode.bestow_objective(enemy,escape_path)
spawn(0)
qdel(src)
return 0
// Misc antags
/datum/objective_set/changeling
objective_list = list(/datum/objective/specialist/absorb)
escape_choices = list(/datum/objective/escape,
/datum/objective/escape/hijack)
/datum/objective_set/vampire
objective_list = list(/datum/objective/specialist/drinkblood)
escape_choices = list(/datum/objective/escape,
/datum/objective/escape/hijack)
/datum/objective_set/grinch
objective_list = list(/datum/objective/specialist/ruin_xmas)
escape_choices = list(/datum/objective/escape,
/datum/objective/escape/survive,
/datum/objective/escape/hijack,
/datum/objective/escape/kamikaze)
/datum/objective_set/predator
objective_list = list(/datum/objective/specialist/predator/trophy)
escape_choices = list(/datum/objective/escape/survive)
/datum/objective_set/werewolf
objective_list = list(/datum/objective/specialist/werewolf/feed)
escape_choices = list(/datum/objective/escape/survive)
/datum/objective_set/blob
objective_list = list(/datum/objective/specialist/blob)
escape_choices = list(/datum/objective/escape/survive)
// Wraith not listed since it has its own dedicated proc
// Traitors, easier objectives
/datum/objective_set/traitor/easy/triple_assassinate
objective_list = list(/datum/objective/regular/assassinate,
/datum/objective/regular/assassinate,
/datum/objective/regular/assassinate)
escape_choices = list(/datum/objective/escape,
/datum/objective/escape/survive)
/datum/objective_set/traitor/easy/genocide
objective_list = list(/datum/objective/regular/job_genocide)
escape_choices = list(/datum/objective/escape,
/datum/objective/escape/survive)
/datum/objective_set/traitor/easy/massacre
objective_list = list(/datum/objective/regular/assassinate,
/datum/objective/regular/assassinate,
/datum/objective/regular/assassinate,
/datum/objective/regular/assassinate,
/datum/objective/regular/assassinate,
/datum/objective/regular/assassinate)
escape_choices = list(/datum/objective/escape/kamikaze)
/datum/objective_set/traitor/easy/kill_heads
objective_list = list(/datum/objective/regular/kill_heads)
escape_choices = list(/datum/objective/escape/kamikaze,
/datum/objective/escape/survive)
/datum/objective_set/traitor/easy/sabotage
objective_list = list(/datum/objective/regular/damage_area,
/datum/objective/regular/destroy_equipment)
escape_choices = list(/datum/objective/escape)
/datum/objective_set/traitor/easy/havoc
objective_list = list(/datum/objective/regular/damage_area,
/datum/objective/regular/destroy_equipment,
/datum/objective/regular/job_genocide)
escape_choices = list(/datum/objective/escape/survive,
/datum/objective/escape/kamikaze)
/datum/objective_set/traitor/easy/supremacy_and_hijack
objective_list = list(/datum/objective/regular/traitor_supremacy)
escape_choices = list(/datum/objective/escape/hijack)
/datum/objective_set/traitor/easy/damage_and_hijack
objective_list = list(/datum/objective/regular/damage_area)
escape_choices = list(/datum/objective/escape/hijack)
/datum/objective_set/traitor/easy/steal_and_hijack
objective_list = list(/datum/objective/regular/steal)
escape_choices = list(/datum/objective/escape/hijack)
/datum/objective_set/traitor/easy/noclones_and_hijack
objective_list = list(/datum/objective/regular/no_clones)
escape_choices = list(/datum/objective/escape/hijack)
/datum/objective_set/traitor/easy/steal_ai_brain
objective_list = list(/datum/objective/regular/aikill)
escape_choices = list(/datum/objective/escape)
/datum/objective_set/traitor/easy/borg_death
objective_list = list(/datum/objective/regular/borgdeath)
escape_choices = list(/datum/objective/escape)
/datum/objective_set/traitor/easy/dead_means_dead
objective_list = list(/datum/objective/regular/borgdeath,
/datum/objective/regular/no_clones)
escape_choices = list(/datum/objective/escape/survive,
/datum/objective/escape)
/datum/objective_set/traitor/easy/kill_all_silicons
objective_list = list(/datum/objective/regular/aikill,
/datum/objective/regular/borgdeath)
escape_choices = list(/datum/objective/escape/survive)
/datum/objective_set/traitor/easy/bonsai_tree
objective_list = list(/datum/objective/regular/bonsaitree,
/datum/objective/regular/gimmick)
escape_choices = list(/datum/objective/escape,
/datum/objective/escape/survive)
// More difficult traitor objectives
/datum/objective_set/traitor/hard
objective_list = list(/datum/objective/regular/assassinate,
/datum/objective/regular/gimmick)
escape_choices = list(/datum/objective/escape)
/datum/objective_set/traitor/hard/triple_assassinate_and_hijack
objective_list = list(/datum/objective/regular/assassinate,
/datum/objective/regular/assassinate,
/datum/objective/regular/assassinate,
/datum/objective/regular/no_clones)
escape_choices = list(/datum/objective/escape/hijack)
/datum/objective_set/traitor/hard/double_genocide
objective_list = list(/datum/objective/regular/job_genocide,
/datum/objective/regular/job_genocide)
escape_choices = list(/datum/objective/escape)
/datum/objective_set/traitor/hard/kill_all_silicons
objective_list = list(/datum/objective/regular/aikill,
/datum/objective/regular/borgdeath)
escape_choices = list(/datum/objective/escape)
/datum/objective_set/traitor/hard/rampage
objective_list = list(/datum/objective/regular/assassinate,
/datum/objective/regular/damage_area,
/datum/objective/regular/damage_area,
/datum/objective/regular/destroy_equipment,
/datum/objective/regular/destroy_equipment)
escape_choices = list(/datum/objective/escape)