From e782d47580de8b5bf75946649e8ae2a61cdeb73f Mon Sep 17 00:00:00 2001 From: "mport2004@gmail.com" Date: Thu, 29 Sep 2011 05:20:33 +0000 Subject: [PATCH] Few runtime fixes. Cleaned up the job selection code. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@2289 316c924e-a436-60f5-8080-3fe189b3f50e --- code/WorkInProgress/jobs.dm | 291 ++++++++++++ code/datums/mind.dm | 4 +- code/game/gamemodes/changeling/changeling.dm | 33 +- code/game/gamemodes/game_mode.dm | 4 +- code/game/gamemodes/intercept_report.dm | 2 +- code/game/gamemodes/objective.dm | 8 +- code/game/gamemodes/revolution/revolution.dm | 6 +- code/game/jobs/jobprocs.dm | 227 +++++---- code/game/jobs/jobs.dm | 461 +++++-------------- code/modules/admin/banjob.dm | 2 +- code/modules/admin/newbanjob.dm | 2 +- code/modules/mob/new_player/preferences.dm | 107 ++--- data/mode.txt | 2 +- tgstation.dme | 1 + 14 files changed, 589 insertions(+), 561 deletions(-) create mode 100644 code/WorkInProgress/jobs.dm diff --git a/code/WorkInProgress/jobs.dm b/code/WorkInProgress/jobs.dm new file mode 100644 index 00000000000..157982a274f --- /dev/null +++ b/code/WorkInProgress/jobs.dm @@ -0,0 +1,291 @@ +//WORK IN PROGRESS CONTENT + +//Project coder: Errorage + +//Readme: As part of the UI upgrade project, the intention here is for each job to have +//somewhat customizable loadouts. Players will be able to pick between jumpsuits, shoes, +//and other items. This datum will be used for all jobs and code will reference it. +//adding new jobs will be a matter of adding this datum.to a list of jobs. + +#define VITAL_PRIORITY_JOB 5 +#define HIGH_PRIORITY_JOB 4 +#define PRIORITY_JOB 3 +#define LOW_PRIORITY_JOB 2 +#define ASSISTANT_PRIORITY_JOB 1 +#define NO_PRIORITY_JOB 0 + +/datum/job + //Basic information + var/title = "Untitled" //The main (default) job title/name + var/list/alternative_titles = list() //Alternative job titles/names (alias) + var/job_number_at_round_start = 0 //Number of jobs that can be assigned at round start + var/job_number_total = 0 //Number of jobs that can be assigned total + var/list/bosses = list() //List of jobs which have authority over this job by default. + var/admin_only = 0 //If this is set to 1, the job is not available on the spawn screen + var/description = "" //A description of the job to be displayed when requested on the spawn screen + var/guides = "" //A string with links to relevent guides (likely the wiki) + var/department = "" //This is used to group jobs into departments, which means that if you don't get your desired jobs, you get another job from the same department + var/job_type = "SS13" //SS13, NT or ANTAGONIST + var/can_be_traitor = 1 + var/can_be_changeling = 1 + var/can_be_wizard = 1 + var/can_be_cultist = 1 + var/can_be_rev_head = 1 + var/is_head_position = 0 + + //Job conditions + var/change_to_mob = "Human" //The type of mob which this job will change you to (alien,cyborg,human...) + var/change_to_mutantrace = "" //What mutantrace you will be once you get this job + + //Random job assignment priority + var/assignment_priority = NO_PRIORITY_JOB //This variable determins the priority of assignment + //VITAL_PRIORITY_JOB = Absolutely vital (Someone will get assigned every round) - Use VERY, VERY lightly + //HIGH_PRIORITY_JOB = High priority - Assibned before the other jobs, candidates compete on equal terms + //PRIORITY_JOB = Priorized (Standard priority) - Candidates compete by virtue of priority (choice 1 > choice 2 > choice 3...) + //LOW_PRIORITY_JOB = Low priority (Low-priority (librarian)) + //ASSISTANT_PRIORITY_JOB = Assistant-level (Only filled when all the other jobs have been assigned) + //NO_PRIORITY_JOB = Skipped om assignment (Admin-only jobs should have this level) + + + + //Available equipment - The first thing listed is understood as the default setup. + var/list/equipment_ears = list() //list of possible ear-wear items + var/list/equipment_glasses = list() //list of possible glasses + var/list/equipment_gloves = list() //list of possible gloves + var/list/equipment_head = list() //list of possible headgear/helmets/hats + var/list/equipment_mask = list() //list of possible masks + var/list/equipment_shoes = list() //list of possible shoes + var/list/equipment_suit = list() //list of possible suits + var/list/equipment_under = list() //list of possible jumpsuits + var/list/equipment_belt = list() //list of possible belt-slot items + var/list/equipment_back = list() //list of possible back-slot items + var/obj/equipment_pda //default pda type + var/obj/equipment_id //default id type + + New(var/param_title, var/list/param_alternative_titles = list(), var/param_jobs_at_round_start = 0, var/param_global_max = 0, var/list/param_bosses = list(), var/param_admin_only = 0) + title = param_title + alternative_titles = param_alternative_titles + job_number_at_round_start = param_jobs_at_round_start + job_number_total = param_global_max + bosses = param_bosses + admin_only = param_admin_only + + //This proc tests to see if the given alias (job title/alternative job title) corresponds to this job. + //Returns 1 if it is, else returns 0 + proc/is_job_alias(var/alias) + if(alias == title) + return 1 + if(alias in alternative_titles) + return 1 + return 0 + +/datum/jobs + var/list/datum/job/all_jobs = list() + + proc/get_all_jobs() + return all_jobs + + //This proc returns all the jobs which are NOT admin only + proc/get_normal_jobs() + var/list/datum/job/normal_jobs = list() + for(var/datum/job/J in all_jobs) + if(!J.admin_only) + normal_jobs += J + return normal_jobs + + //This proc returns all the jobs which are admin only + proc/get_admin_jobs() + var/list/datum/job/admin_jobs = list() + for(var/datum/job/J in all_jobs) + if(J.admin_only) + admin_jobs += J + return admin_jobs + + //This proc returns the job datum of the job with the alias or job title given as the argument. Returns an empty string otherwise. + proc/get_job(var/alias) + for(var/datum/job/J in all_jobs) + if(J.is_job_alias(alias)) + return J + return "" + + //This proc returns a string with the default job title for the job with the given alias. Returns an empty string otherwise. + proc/get_job_title(var/alias) + for(var/datum/job/J in all_jobs) + if(J.is_job_alias(alias)) + return J.title + return "" + + //This proc returns all the job datums of the workers whose boss has the alias provided. (IE Engineer under Chief Engineer, etc.) + proc/get_jobs_under(var/boss_alias) + var/boss_title = get_job_title(boss_alias) + var/list/datum/job/employees = list() + for(var/datum/job/J in all_jobs) + if(boss_title in J.bosses) + employees += J + return employees + + //This proc returns the chosen vital and high priority jobs that the person selected. It goes from top to bottom of the list, until it finds a job which does not have such priority. + //Example: Choosing (in this order): CE, Captain, Engineer, RD will only return CE and Captain, as RD is assumed as being an unwanted choice. + //This proc is used in the allocation algorithm when deciding vital and high priority jobs. + proc/get_prefered_high_priority_jobs() + var/list/datum/job/hp_jobs = list() + for(var/datum/job/J in all_jobs) + if(J.assignment_priority == HIGH_PRIORITY_JOB || J.assignment_priority == VITAL_PRIORITY_JOB) + hp_jobs += J + else + break + return hp_jobs + + //If only priority is given, it will return the jobs of only that priority, if end_priority is set it will return the jobs with their priority higher or equal to var/priority and lower or equal to end_priority. end_priority must be higher than 0. + proc/get_jobs_by_priority(var/priority, var/end_priority = 0) + var/list/datum/job/priority_jobs = list() + if(end_priority) + if(end_priority < priority) + return + for(var/datum/job/J in all_jobs) + if(J.assignment_priority >= priority && J.assignment_priority <= end_priority) + priority_jobs += J + else + for(var/datum/job/J in all_jobs) + if(J.assignment_priority == priority) + priority_jobs += J + return priority_jobs + +//This datum is used in the plb allocation algorithm to make life easier, not used anywhere else. +/datum/player_jobs + var/mob/new_player/player + var/datum/jobs/selected_jobs + +var/datum/jobs/jobs = new/datum/jobs() + +proc/setup_jobs() + var/datum/job/JOB + + JOB = new/datum/job("Station Engineer") + JOB.alternative_titles = list("Structural Engineer","Engineer","Student of Engineering") + JOB.job_number_at_round_start = 5 + JOB.job_number_total = 5 + JOB.bosses = list("Chief Engineer") + JOB.admin_only = 0 + JOB.description = "Engineers are tasked with the maintenance of the station. Be it maintaining the power grid or rebuilding damaged sections." + JOB.guides = "" + JOB.equipment_ears = list(/obj/item/device/radio/headset/headset_eng) + JOB.equipment_glasses = list() + JOB.equipment_gloves = list() + JOB.equipment_head = list(/obj/item/clothing/head/helmet/hardhat) + JOB.equipment_mask = list() + JOB.equipment_shoes = list(/obj/item/clothing/shoes/orange,/obj/item/clothing/shoes/brown,/obj/item/clothing/shoes/black) + JOB.equipment_suit = list(/obj/item/clothing/suit/hazardvest) + JOB.equipment_under = list(/obj/item/clothing/under/rank/engineer,/obj/item/clothing/under/color/yellow) + JOB.equipment_belt = list(/obj/item/weapon/storage/belt/utility/full) + JOB.equipment_back = list(/obj/item/weapon/storage/backpack/industrial,/obj/item/weapon/storage/backpack) + JOB.equipment_pda = /obj/item/device/pda/engineering + JOB.equipment_id = /obj/item/weapon/card/id + + jobs.all_jobs += JOB + +//This proc will dress the mob (employee) in the default way for the specified job title/job alias +proc/dress_for_job_default(var/mob/living/carbon/human/employee as mob, var/job_alias) + if(!ishuman(employee)) + return + + //TODO ERRORAGE - UNFINISHED + var/datum/job/JOB = jobs.get_job(job_alias) + if(JOB) + var/item = JOB.equipment_ears[1] + employee.equip_if_possible(new item(employee), employee.slot_ears) + item = JOB.equipment_under[1] + employee.equip_if_possible(new item(employee), employee.slot_w_uniform) + + + /* + src.equip_if_possible(new /obj/item/weapon/storage/backpack/industrial (src), slot_back) + src.equip_if_possible(new /obj/item/weapon/storage/box/engineer(src), slot_in_backpack) + src.equip_if_possible(new /obj/item/device/radio/headset/headset_eng (src), slot_ears) // -- TLE + src.equip_if_possible(new /obj/item/device/pda/engineering(src), slot_belt) + src.equip_if_possible(new /obj/item/clothing/under/rank/engineer(src), slot_w_uniform) + src.equip_if_possible(new /obj/item/clothing/shoes/orange(src), slot_shoes) + src.equip_if_possible(new /obj/item/clothing/head/helmet/hardhat(src), slot_head) + src.equip_if_possible(new /obj/item/weapon/storage/utilitybelt/full(src), slot_l_hand) //currently spawns in hand due to traitor assignment requiring a PDA to be on the belt. --Errorage + //src.equip_if_possible(new /obj/item/clothing/gloves/yellow(src), slot_gloves) removed as part of Dangercon 2011, approved by Urist_McDorf --Errorage + src.equip_if_possible(new /obj/item/device/t_scanner(src), slot_r_store) + */ + + +//This algorithm works in 5 steps: +//1: Assignment of wizard / nuke members (if appropriate game mode) +//2: Assignment of jobs based on preferenes +// 2.1: Assignment of vital and high priority jobs. Candidates compete on equal terms. If the vital jobs are not filled, a random candidate is chosen to fill them, +// 2.2: Assignment of the rest of the jobs based on player preference, +//3: Assignment of remaining jobs for remaining players based on chosen departments +//4: Random assignment of remaining jobs for remaining players based on assignment priority +//5: Assignment of traitor / changeling to assigned roles (if appropriate game mode) +proc/assignment_algorithm(var/list/mob/new_player/players) + for(var/mob/new_player/PLAYER in players) + if(!PLAYER.client) + players -= PLAYER + continue + if(!PLAYER.ready) + players -= PLAYER + continue + + var/list/datum/job/vital_jobs = list() + var/list/datum/job/high_priority_jobs = list() + var/list/datum/job/priority_jobs = list() + var/list/datum/job/low_priority_jobs = list() + var/list/datum/job/assistant_jobs = list() + var/list/datum/job/not_assigned_jobs = list() + + for(var/datum/job/J in jobs) + switch(J.assignment_priority) + if(5) + vital_jobs += J + if(4) + high_priority_jobs += J + if(3) + priority_jobs += J + if(2) + low_priority_jobs += J + if(1) + assistant_jobs += J + if(0) + not_assigned_jobs += J + + var/list/datum/player_jobs/player_jobs = list() //This datum only holds a mob/new_player and a datum/jobs. The first is the player, the 2nd is the player's selected jobs, from the preferences datum. + + for(var/mob/new_player/NP in players) + var/datum/player_jobs/PJ = new/datum/player_jobs + PJ.player = NP + PJ.selected_jobs = NP.preferences.wanted_jobs + player_jobs += PJ + + //At this point we have the player_jobs list filled. Next up we have to assign all vital and high priority positions. + + var/list/datum/job/hp_jobs = jobs.get_jobs_by_priority( HIGH_PRIORITY_JOB, VITAL_PRIORITY_JOB ) + + for(var/datum/job/J in hp_jobs) + var/list/mob/new_player/candidates = list() + for(var/datum/player_jobs/PJ in player_jobs) + if(J in PJ.selected_jobs) + candidates += PJ.player + var/mob/new_player/chosen_player + if(candidates) + chosen_player = pick(candidates) + else + if(J.assignment_priority == VITAL_PRIORITY_JOB) + if(players) //Just in case there are more vital jobs than there are players. + chosen_player = pick(players) + if(chosen_player) + chosen_player.mind.assigned_job = J + players -= chosen_player + //TODO ERRORAGE - add capability for hp jobs with more than one slots. + + + + + //1: vital and high priority jobs, assigned on equal terms + + //TODO ERRORAGE - UNFINISHED + + +//END OF WORK IN PROGRESS CONTENT diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 9bc55a7212e..8cb9972e4d1 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -66,7 +66,7 @@ datum/mind if (ticker.mode.config_tag=="revolution") text = uppertext(text) text = "[text]: " - if (assigned_role in head_positions) + if (assigned_role in command_positions) text += "HEAD|officer|employee|headrev|rev" else if (assigned_role in list("Security Officer", "Detective", "Warden")) text += "head|OFFICER|employee|headre|rev" @@ -98,7 +98,7 @@ datum/mind if (ticker.mode.config_tag=="cult") text = uppertext(text) text = "[text]: " - if (assigned_role in head_positions) + if (assigned_role in command_positions) text += "HEAD|officer|employee|cultist" else if (assigned_role in list("Security Officer", "Detective", "Warden")) text += "head|OFFICER|employee|cultist" diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index bd3cf2cd17f..02a049dcc68 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -168,25 +168,24 @@ var/changeling_name var/totalabsorbed = 0 if((changeling.current) && (changeling.current.changeling)) - totalabsorbed = changeling.current.changeling.absorbed_dna.len - 1 - - if(changeling.current) + totalabsorbed = ((changeling.current.changeling.absorbed_dna.len) - 1) changeling_name = "[changeling.current.real_name] (played by [changeling.key])" + world << "The changeling was [changeling_name]." + world << "[changeling.current.gender=="male"?"His":"Her"] changeling ID was [changeling.current.gender=="male"?"Mr.":"Mrs."] [changeling.current.changeling.changelingID]." + world << "Genomes absorbed: [totalabsorbed]" + + var/count = 1 + for(var/datum/objective/objective in changeling.objectives) + if(objective.check_completion()) + world << "Objective #[count]: [objective.explanation_text] \green Success" + else + world << "Objective #[count]: [objective.explanation_text] \red Failed" + changelingwin = 0 + count++ + else changeling_name = "[changeling.key] (character destroyed)" - - world << "The changeling was [changeling_name]." - if(changeling.current) world << "[changeling.current.gender=="male"?"His":"Her"] changeling ID was [changeling.current.gender=="male"?"Mr.":"Mrs."] [changeling.current.changeling.changelingID]." - world << "Genomes absorbed: [totalabsorbed]" - - var/count = 1 - for(var/datum/objective/objective in changeling.objectives) - if(objective.check_completion()) - world << "Objective #[count]: [objective.explanation_text] \green Success" - else - world << "Objective #[count]: [objective.explanation_text] \red Failed" - changelingwin = 0 - count++ + changelingwin = 0 if(changelingwin) world << "The changeling was successful!" @@ -200,7 +199,7 @@ var/changeling_fakedeath = 0 var/chem_charges = 20.00 var/sting_range = 1 - var/changelingID = null + var/changelingID = "none" var/mob/living/host = null /datum/changeling/New() diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 18c775db56e..844f1c11ea5 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -149,7 +149,7 @@ /datum/game_mode/proc/get_living_heads() var/list/heads = list() for(var/mob/living/carbon/human/player in world) - if(player.stat!=2 && player.mind && (player.mind.assigned_role in head_positions)) + if(player.stat!=2 && player.mind && (player.mind.assigned_role in command_positions)) heads += player.mind return heads @@ -160,6 +160,6 @@ /datum/game_mode/proc/get_all_heads() var/list/heads = list() for(var/mob/player in world) - if(player.mind && (player.mind.assigned_role in head_positions)) + if(player.mind && (player.mind.assigned_role in command_positions)) heads += player.mind return heads diff --git a/code/game/gamemodes/intercept_report.dm b/code/game/gamemodes/intercept_report.dm index 6d7e880aa69..2f9bb95a1b4 100644 --- a/code/game/gamemodes/intercept_report.dm +++ b/code/game/gamemodes/intercept_report.dm @@ -182,7 +182,7 @@ else var/list/job_tmp = get_all_jobs() job_tmp-=nonhuman_positions - job_tmp-=head_positions + job_tmp-=command_positions job_tmp.Remove("Security Officer", "Detective", "Warden", "MODE") traitor_job = pick(job_tmp) if(prob(prob_right_dude) && ticker.mode.config_tag == "revolution") diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index e1340074c8a..94e6c0736dc 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -1,9 +1,9 @@ datum/objective var - datum/mind/owner//Who owns the objective. - explanation_text//What that person is supposed to do. - datum/mind/target//If they are focused on a particular person. - target_amount//If they are focused on a particular number. Steal objectives have their own counter. + datum/mind/owner = null //Who owns the objective. + explanation_text = "Nothing" //What that person is supposed to do. + datum/mind/target = null //If they are focused on a particular person. + target_amount = 0 //If they are focused on a particular number. Steal objectives have their own counter. New(var/text) if(text) diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 1daa61a137c..e77a3981d20 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -39,7 +39,7 @@ var/head_check = 0 for(var/mob/new_player/player in world) - if(player.mind.assigned_role in head_positions) + if(player.mind.assigned_role in command_positions) head_check = 1 break @@ -156,7 +156,7 @@ //Deals with converting players to the revolution// /////////////////////////////////////////////////// /datum/game_mode/proc/add_revolutionary(datum/mind/rev_mind) - if((rev_mind.assigned_role in head_positions) || (rev_mind.assigned_role in list("Security Officer", "Detective", "Warden"))) + if((rev_mind.assigned_role in command_positions) || (rev_mind.assigned_role in list("Security Officer", "Detective", "Warden"))) return 0 if((rev_mind in revolutionaries) || (rev_mind in head_revolutionaries)) return 0 @@ -371,5 +371,5 @@ /proc/is_convertable_to_rev(datum/mind/mind) return istype(mind) && \ istype(mind.current, /mob/living/carbon/human) && \ - !(mind.assigned_role in head_positions) && \ + !(mind.assigned_role in command_positions) && \ !(mind.assigned_role in list("Security Officer", "Detective", "Warden")) diff --git a/code/game/jobs/jobprocs.dm b/code/game/jobs/jobprocs.dm index 0dd8a220cbd..748f23c93d5 100644 --- a/code/game/jobs/jobprocs.dm +++ b/code/game/jobs/jobprocs.dm @@ -1,160 +1,141 @@ /proc/FindOccupationCandidates(list/unassigned, job, level) var/list/candidates = list() - - for (var/mob/new_player/player in unassigned) - if (player.preferences.occupation[job] == level) - if (jobban_isbanned(player, job)) + if((job == "AI") && (config) && (!config.allow_ai)) return candidates + for(var/mob/new_player/player in unassigned) + if(player.preferences.occupation[job] == level) + if(jobban_isbanned(player, job)) continue -// if (player.jobs_restricted_by_gamemode && (job in player.jobs_restricted_by_gamemode)) -// continue candidates += player - return candidates + /proc/ResetOccupations() for(var/mob/new_player/player in world) - if(player) - if(player.mind) - player.mind.assigned_role = null - player.mind.special_role = null + if((player) && (player.mind)) + player.mind.assigned_role = null + player.mind.special_role = null return -/proc/FillHeadPosition(list/unassigned, job) - for (var/level = 1 to 3) - var/list/candidates = FindOccupationCandidates(unassigned, job, 4-level) - if (candidates.len) + +/proc/Assign_Role(var/mob/new_player/player, var/job) + if((player) && (player.mind) && (job)) + player.mind.assigned_role = job + return 1 + return 0 + + +/proc/FillHeadPosition(list/unassigned, list/jobs) + for(var/level = 1 to 3) + for(var/command_position in command_positions) + var/list/candidates = FindOccupationCandidates(unassigned, command_position, level) + if(!candidates.len) continue var/mob/new_player/candidate = pick(candidates) unassigned -= candidate - candidate.mind.assigned_role = job - return + if(Assign_Role(candidate, command_position)) + jobs[command_position]-- + return 1 + return 0 + + +/proc/FillAIPosition(list/unassigned, list/jobs) + var/ai_selected = 0 + for(var/level = 1 to 3) + var/list/candidates = FindOccupationCandidates(unassigned, "AI", level) + if(ticker.mode.name == "AI malfunction")//Make sure they want to malf if its malf + for(var/mob/new_player/player in candidates) + if(!player.preferences.be_special & BE_MALF) + candidates -= player + if(candidates.len) + var/mob/new_player/candidate = pick(candidates) + unassigned -= candidate + if(Assign_Role(candidate, "AI")) + jobs["AI"]-- + ai_selected++ + break + //Malf NEEDS an AI so force one if we didn't get a player who wanted it + if((ticker.mode.name == "AI malfunction")&&(!ai_selected)) + unassigned = shuffle(unassigned) + for(var/mob/new_player/player in unassigned) + if(jobban_isbanned(player, "AI")) + continue + unassigned -= player + if(Assign_Role(player, "AI")) + jobs["AI"]-- + ai_selected++ + break + if(ai_selected) return 1 + return 0 + /** Proc DivideOccupations * fills var "assigned_role" for all ready players. * This proc must not have any side effects besides of modifying "assigned_role". **/ /proc/DivideOccupations() + //Setup new player list and get the jobs list var/list/unassigned = list() - var/list/occupation_eligible = occupations.Copy() + var/list/occupations_available = occupations.Copy() - for (var/mob/new_player/player in world) - if (player.client && player.ready && !player.mind.assigned_role) + //Get the players who are ready + for(var/mob/new_player/player in world) + if((player) && (player.client) && (player.ready) && (player.mind) && (!player.mind.assigned_role)) unassigned += player -// for (var/level = 1 to 3) -// if (jobban_isbanned(player, player.preferences.occupation[4-level])) -// player.preferences.occupation[level] = "Assistant" - // If someone picked AI before it was disabled, or has a saved profile with it - // on a game that now lacks it, this will make sure they don't become the AI, - // by changing that choice to Captain. -// if (!config.allow_ai) -// for (var/level = 1 to 3) -// if (player.preferences.occupation[level] == "AI") -// player.preferences.occupation[level] = "Captain" + if(unassigned.len == 0) return 0 + //Shuffle players and jobs + unassigned = shuffle(unassigned) +// occupations_available = shuffle(occupations_available) - if (unassigned.len == 0) - return 0 + //Select one head + FillHeadPosition(unassigned, occupations_available) - //Fill head positions, first Captain than heads from least to most popular - for(var/occ in head_positions) - FillHeadPosition(unassigned, occ) + //Check for an AI + FillAIPosition(unassigned, occupations_available) - //Then check for an AI - for (var/level = 1 to 3)//Malf is a bit special as it replaces a normal job - var/list/candidates = FindOccupationCandidates(unassigned, "AI", 4-level) - if(ticker.mode.name == "AI malfunction") - for(var/mob/new_player/player in candidates) - if(!player.preferences.be_special & BE_MALF) - candidates -= player - if (candidates.len) - var/mob/new_player/candidate = pick(candidates) - unassigned -= candidate - candidate.mind.assigned_role = "AI" - break - //Malf NEEDS an AI so force one - if((ticker.mode.name == "AI malfunction")&&(occupation_eligible["AI"] > 0)) - unassigned = shuffle(unassigned) - for(var/mob/new_player/player in unassigned) - if(jobban_isbanned(player, "AI")) - continue - else - player.mind.assigned_role = "AI" - unassigned -= player - break + //Assistants are checked first + for(var/mob/new_player/player in unassigned) + if(player.preferences.occupation["Assistant"] == 0) continue + unassigned -= player + Assign_Role(player, "Assistant") - // Now for most positions. Shuffle the list of unassigned players and go through it, giving them - // what they want. Easy for "best", more complicated for "okay" and "good" because we have to - // select randomly from their list of okay or good jobs. - for (var/level = 1 to 3) // Wish this could be from 3 to 1, but whatever. "Good" to "okay". - unassigned = shuffle(unassigned) // Maybe unnecessary to shuffle each time, but it's cheap. - for(var/mob/new_player/player in unassigned) - var/list/wantedJobs = list() - for(var/job in player.preferences.occupation) - if(player.preferences.occupation[job] == 4-level) - if(!(job in head_positions) && job != "AI" && occupation_eligible[job] != 0 && !jobban_isbanned(player,job)) - wantedJobs += job - if(length(wantedJobs) > 0) - player.mind.assigned_role = pick(wantedJobs) - occupation_eligible[player.mind.assigned_role]-- - unassigned -= player - else - player.mind.assigned_role = "Assistant" - - -/* //Now we can go though the rest of the jobs and players who set prefs - for (var/level = 1 to 3) - //Assistants are checked first - for (var/occupation in assistant_occupations) - if (unassigned.len == 0) - break - var/list/candidates = FindOccupationCandidates(unassigned, occupation, 4-level) - while(candidates.len && assistant_occupations[occupation]) - assistant_occupations[occupation]-- - var/mob/new_player/candidate = pick_n_take(candidates) - candidate.mind.assigned_role = occupation + //Other jobs are now checked + for(var/level = 1 to 3) + for(var/occupation in occupations_available) + if(!unassigned.len) break + if(occupations_available[occupation] == 0) continue + var/list/candidates = FindOccupationCandidates(unassigned, occupation, level) + while(candidates.len && occupations_available[occupation]) + var/mob/new_player/candidate = pick(candidates) unassigned -= candidate - //Now everyone else - for (var/occupation in occupation_eligible) - if (unassigned.len == 0) - break - if (occupation_eligible[occupation] == 0) - continue - var/list/candidates = FindOccupationCandidates(unassigned, occupation, 4-level) - while (candidates.len && occupation_eligible[occupation]) - occupation_eligible[occupation]-- - var/mob/new_player/candidate = pick_n_take(candidates) - candidate.mind.assigned_role = occupation - unassigned -= candidate - //Last try to fill in any leftover jobs with leftover players - if (unassigned.len) - var/list/vacancies = list() - for (var/occ in occupation_eligible) - for (var/i = 1 to occupation_eligible[occ]) - vacancies += occ + if(Assign_Role(candidate, occupation)) + occupations_available[occupation]-- - for(var/mob/new_player/candidate in unassigned) - if(!unassigned.len || !vacancies.len) break - var/occupation = pick(vacancies) - if(!jobban_isbanned(candidate, occupation)) - candidate.mind.assigned_role = occupation - unassigned -= candidate - vacancies -= occupation + if(!unassigned.len) return 1 + //Set all remaining players to an assistant job + var/list/vacancies = list() + for(var/assist_job in assistant_occupations) + if(!occupations_available[assist_job] > 0) continue + for(var/i = 1 to occupations_available[assist_job]) + vacancies += assist_job + + for(var/mob/new_player/player in unassigned) + if((!unassigned.len) || (!vacancies.len)) break + unassigned -= player + var/assist_job = pick(vacancies) + if(Assign_Role(player, assist_job)) + vacancies -= assist_job + + if(unassigned.len) for(var/mob/new_player/player in unassigned) - if (unassigned.len == 0) - break - var/list/occupationsPossible = list() - for(var/occ in assistant_occupations) - if(assistant_occupations[occ]) - occupationsPossible += occ - player.mind.assigned_role = pick(occupationsPossible) - assistant_occupations[player.mind.assigned_role]-- -// player.mind.assigned_role = pick(assistant_occupations) -*/ + if(!unassigned.len) break + Assign_Role(player, "Assistant") + //If anyone still has no job then something is fucked up with their mob and they will currently spawn at spawn but the runtimes should no longer dump several people here return 1 -/mob/living/carbon/human/proc/Equip_Rank(rank, joined_late) +/mob/living/carbon/human/proc/Equip_Rank(rank, joined_late) switch(rank) if ("Chaplain") var/obj/item/weapon/storage/bible/B = new /obj/item/weapon/storage/bible/booze(src) diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm index 415c100dcb5..57a8dd5528e 100644 --- a/code/game/jobs/jobs.dm +++ b/code/game/jobs/jobs.dm @@ -1,375 +1,136 @@ -//WORK IN PROGRESS CONTENT - -//Project coder: Errorage - -//Readme: As part of the UI upgrade project, the intention here is for each job to have -//somewhat customizable loadouts. Players will be able to pick between jumpsuits, shoes, -//and other items. This datum will be used for all jobs and code will reference it. -//adding new jobs will be a matter of adding this datum.to a list of jobs. - -#define VITAL_PRIORITY_JOB 5 -#define HIGH_PRIORITY_JOB 4 -#define PRIORITY_JOB 3 -#define LOW_PRIORITY_JOB 2 -#define ASSISTANT_PRIORITY_JOB 1 -#define NO_PRIORITY_JOB 0 - -/datum/job - //Basic information - var/title = "Untitled" //The main (default) job title/name - var/list/alternative_titles = list() //Alternative job titles/names (alias) - var/job_number_at_round_start = 0 //Number of jobs that can be assigned at round start - var/job_number_total = 0 //Number of jobs that can be assigned total - var/list/bosses = list() //List of jobs which have authority over this job by default. - var/admin_only = 0 //If this is set to 1, the job is not available on the spawn screen - var/description = "" //A description of the job to be displayed when requested on the spawn screen - var/guides = "" //A string with links to relevent guides (likely the wiki) - var/department = "" //This is used to group jobs into departments, which means that if you don't get your desired jobs, you get another job from the same department - var/job_type = "SS13" //SS13, NT or ANTAGONIST - var/can_be_traitor = 1 - var/can_be_changeling = 1 - var/can_be_wizard = 1 - var/can_be_cultist = 1 - var/can_be_rev_head = 1 - var/is_head_position = 0 - - //Job conditions - var/change_to_mob = "Human" //The type of mob which this job will change you to (alien,cyborg,human...) - var/change_to_mutantrace = "" //What mutantrace you will be once you get this job - - //Random job assignment priority - var/assignment_priority = NO_PRIORITY_JOB //This variable determins the priority of assignment - //VITAL_PRIORITY_JOB = Absolutely vital (Someone will get assigned every round) - Use VERY, VERY lightly - //HIGH_PRIORITY_JOB = High priority - Assibned before the other jobs, candidates compete on equal terms - //PRIORITY_JOB = Priorized (Standard priority) - Candidates compete by virtue of priority (choice 1 > choice 2 > choice 3...) - //LOW_PRIORITY_JOB = Low priority (Low-priority (librarian)) - //ASSISTANT_PRIORITY_JOB = Assistant-level (Only filled when all the other jobs have been assigned) - //NO_PRIORITY_JOB = Skipped om assignment (Admin-only jobs should have this level) - - - - //Available equipment - The first thing listed is understood as the default setup. - var/list/equipment_ears = list() //list of possible ear-wear items - var/list/equipment_glasses = list() //list of possible glasses - var/list/equipment_gloves = list() //list of possible gloves - var/list/equipment_head = list() //list of possible headgear/helmets/hats - var/list/equipment_mask = list() //list of possible masks - var/list/equipment_shoes = list() //list of possible shoes - var/list/equipment_suit = list() //list of possible suits - var/list/equipment_under = list() //list of possible jumpsuits - var/list/equipment_belt = list() //list of possible belt-slot items - var/list/equipment_back = list() //list of possible back-slot items - var/obj/equipment_pda //default pda type - var/obj/equipment_id //default id type - - New(var/param_title, var/list/param_alternative_titles = list(), var/param_jobs_at_round_start = 0, var/param_global_max = 0, var/list/param_bosses = list(), var/param_admin_only = 0) - title = param_title - alternative_titles = param_alternative_titles - job_number_at_round_start = param_jobs_at_round_start - job_number_total = param_global_max - bosses = param_bosses - admin_only = param_admin_only - - //This proc tests to see if the given alias (job title/alternative job title) corresponds to this job. - //Returns 1 if it is, else returns 0 - proc/is_job_alias(var/alias) - if(alias == title) - return 1 - if(alias in alternative_titles) - return 1 - return 0 - -/datum/jobs - var/list/datum/job/all_jobs = list() - - proc/get_all_jobs() - return all_jobs - - //This proc returns all the jobs which are NOT admin only - proc/get_normal_jobs() - var/list/datum/job/normal_jobs = list() - for(var/datum/job/J in all_jobs) - if(!J.admin_only) - normal_jobs += J - return normal_jobs - - //This proc returns all the jobs which are admin only - proc/get_admin_jobs() - var/list/datum/job/admin_jobs = list() - for(var/datum/job/J in all_jobs) - if(J.admin_only) - admin_jobs += J - return admin_jobs - - //This proc returns the job datum of the job with the alias or job title given as the argument. Returns an empty string otherwise. - proc/get_job(var/alias) - for(var/datum/job/J in all_jobs) - if(J.is_job_alias(alias)) - return J - return "" - - //This proc returns a string with the default job title for the job with the given alias. Returns an empty string otherwise. - proc/get_job_title(var/alias) - for(var/datum/job/J in all_jobs) - if(J.is_job_alias(alias)) - return J.title - return "" - - //This proc returns all the job datums of the workers whose boss has the alias provided. (IE Engineer under Chief Engineer, etc.) - proc/get_jobs_under(var/boss_alias) - var/boss_title = get_job_title(boss_alias) - var/list/datum/job/employees = list() - for(var/datum/job/J in all_jobs) - if(boss_title in J.bosses) - employees += J - return employees - - //This proc returns the chosen vital and high priority jobs that the person selected. It goes from top to bottom of the list, until it finds a job which does not have such priority. - //Example: Choosing (in this order): CE, Captain, Engineer, RD will only return CE and Captain, as RD is assumed as being an unwanted choice. - //This proc is used in the allocation algorithm when deciding vital and high priority jobs. - proc/get_prefered_high_priority_jobs() - var/list/datum/job/hp_jobs = list() - for(var/datum/job/J in all_jobs) - if(J.assignment_priority == HIGH_PRIORITY_JOB || J.assignment_priority == VITAL_PRIORITY_JOB) - hp_jobs += J - else - break - return hp_jobs - - //If only priority is given, it will return the jobs of only that priority, if end_priority is set it will return the jobs with their priority higher or equal to var/priority and lower or equal to end_priority. end_priority must be higher than 0. - proc/get_jobs_by_priority(var/priority, var/end_priority = 0) - var/list/datum/job/priority_jobs = list() - if(end_priority) - if(end_priority < priority) - return - for(var/datum/job/J in all_jobs) - if(J.assignment_priority >= priority && J.assignment_priority <= end_priority) - priority_jobs += J - else - for(var/datum/job/J in all_jobs) - if(J.assignment_priority == priority) - priority_jobs += J - return priority_jobs - -//This datum is used in the plb allocation algorithm to make life easier, not used anywhere else. -/datum/player_jobs - var/mob/new_player/player - var/datum/jobs/selected_jobs - -var/datum/jobs/jobs = new/datum/jobs() - -proc/setup_jobs() - var/datum/job/JOB - - JOB = new/datum/job("Station Engineer") - JOB.alternative_titles = list("Structural Engineer","Engineer","Student of Engineering") - JOB.job_number_at_round_start = 5 - JOB.job_number_total = 5 - JOB.bosses = list("Chief Engineer") - JOB.admin_only = 0 - JOB.description = "Engineers are tasked with the maintenance of the station. Be it maintaining the power grid or rebuilding damaged sections." - JOB.guides = "" - JOB.equipment_ears = list(/obj/item/device/radio/headset/headset_eng) - JOB.equipment_glasses = list() - JOB.equipment_gloves = list() - JOB.equipment_head = list(/obj/item/clothing/head/helmet/hardhat) - JOB.equipment_mask = list() - JOB.equipment_shoes = list(/obj/item/clothing/shoes/orange,/obj/item/clothing/shoes/brown,/obj/item/clothing/shoes/black) - JOB.equipment_suit = list(/obj/item/clothing/suit/hazardvest) - JOB.equipment_under = list(/obj/item/clothing/under/rank/engineer,/obj/item/clothing/under/color/yellow) - JOB.equipment_belt = list(/obj/item/weapon/storage/belt/utility/full) - JOB.equipment_back = list(/obj/item/weapon/storage/backpack/industrial,/obj/item/weapon/storage/backpack) - JOB.equipment_pda = /obj/item/device/pda/engineering - JOB.equipment_id = /obj/item/weapon/card/id - - jobs.all_jobs += JOB - -//This proc will dress the mob (employee) in the default way for the specified job title/job alias -proc/dress_for_job_default(var/mob/living/carbon/human/employee as mob, var/job_alias) - if(!ishuman(employee)) - return - - //TODO ERRORAGE - UNFINISHED - var/datum/job/JOB = jobs.get_job(job_alias) - if(JOB) - var/item = JOB.equipment_ears[1] - employee.equip_if_possible(new item(employee), employee.slot_ears) - item = JOB.equipment_under[1] - employee.equip_if_possible(new item(employee), employee.slot_w_uniform) - - - /* - src.equip_if_possible(new /obj/item/weapon/storage/backpack/industrial (src), slot_back) - src.equip_if_possible(new /obj/item/weapon/storage/box/engineer(src), slot_in_backpack) - src.equip_if_possible(new /obj/item/device/radio/headset/headset_eng (src), slot_ears) // -- TLE - src.equip_if_possible(new /obj/item/device/pda/engineering(src), slot_belt) - src.equip_if_possible(new /obj/item/clothing/under/rank/engineer(src), slot_w_uniform) - src.equip_if_possible(new /obj/item/clothing/shoes/orange(src), slot_shoes) - src.equip_if_possible(new /obj/item/clothing/head/helmet/hardhat(src), slot_head) - src.equip_if_possible(new /obj/item/weapon/storage/utilitybelt/full(src), slot_l_hand) //currently spawns in hand due to traitor assignment requiring a PDA to be on the belt. --Errorage - //src.equip_if_possible(new /obj/item/clothing/gloves/yellow(src), slot_gloves) removed as part of Dangercon 2011, approved by Urist_McDorf --Errorage - src.equip_if_possible(new /obj/item/device/t_scanner(src), slot_r_store) - */ - - -//This algorithm works in 5 steps: -//1: Assignment of wizard / nuke members (if appropriate game mode) -//2: Assignment of jobs based on preferenes -// 2.1: Assignment of vital and high priority jobs. Candidates compete on equal terms. If the vital jobs are not filled, a random candidate is chosen to fill them, -// 2.2: Assignment of the rest of the jobs based on player preference, -//3: Assignment of remaining jobs for remaining players based on chosen departments -//4: Random assignment of remaining jobs for remaining players based on assignment priority -//5: Assignment of traitor / changeling to assigned roles (if appropriate game mode) -proc/assignment_algorithm(var/list/mob/new_player/players) - for(var/mob/new_player/PLAYER in players) - if(!PLAYER.client) - players -= PLAYER - continue - if(!PLAYER.ready) - players -= PLAYER - continue - - var/list/datum/job/vital_jobs = list() - var/list/datum/job/high_priority_jobs = list() - var/list/datum/job/priority_jobs = list() - var/list/datum/job/low_priority_jobs = list() - var/list/datum/job/assistant_jobs = list() - var/list/datum/job/not_assigned_jobs = list() - - for(var/datum/job/J in jobs) - switch(J.assignment_priority) - if(5) - vital_jobs += J - if(4) - high_priority_jobs += J - if(3) - priority_jobs += J - if(2) - low_priority_jobs += J - if(1) - assistant_jobs += J - if(0) - not_assigned_jobs += J - - var/list/datum/player_jobs/player_jobs = list() //This datum only holds a mob/new_player and a datum/jobs. The first is the player, the 2nd is the player's selected jobs, from the preferences datum. - - for(var/mob/new_player/NP in players) - var/datum/player_jobs/PJ = new/datum/player_jobs - PJ.player = NP - PJ.selected_jobs = NP.preferences.wanted_jobs - player_jobs += PJ - - //At this point we have the player_jobs list filled. Next up we have to assign all vital and high priority positions. - - var/list/datum/job/hp_jobs = jobs.get_jobs_by_priority( HIGH_PRIORITY_JOB, VITAL_PRIORITY_JOB ) - - for(var/datum/job/J in hp_jobs) - var/list/mob/new_player/candidates = list() - for(var/datum/player_jobs/PJ in player_jobs) - if(J in PJ.selected_jobs) - candidates += PJ.player - var/mob/new_player/chosen_player - if(candidates) - chosen_player = pick(candidates) - else - if(J.assignment_priority == VITAL_PRIORITY_JOB) - if(players) //Just in case there are more vital jobs than there are players. - chosen_player = pick(players) - if(chosen_player) - chosen_player.mind.assigned_job = J - players -= chosen_player - //TODO ERRORAGE - add capability for hp jobs with more than one slots. - - - - - //1: vital and high priority jobs, assigned on equal terms - - //TODO ERRORAGE - UNFINISHED - - -//END OF WORK IN PROGRESS CONTENT - - - var/list/occupations = list( - "Captain" = 1, - //Civilian jobs - "Head of Personnel" = 1, + "Captain" = 1, - //soul - "Clown" = 1, - "Mime" = 1, - "Chaplain" = 1, - "Librarian" = 1, + //civilian + "Head of Personnel" = 1, + + "Bartender" = 1, + "Botanist" = 2, + "Chef" = 1, + "Janitor" = 1, + "Librarian" = 1, + "Quartermaster" = 1, + "Cargo Technician" = 3, + "Shaft Miner" = 3, + "Lawyer" = 2, + "Chaplain" = 1, + "Clown" = 1, + "Mime" = 1, - //body - "Bartender" = 1, - "Chef" = 1, - "Botanist" = 2, - "Janitor" = 1, - "Quartermaster" = 1, - "Cargo Technician" = 3, - "Shaft Miner" = 3, //engineering - "Chief Engineer" = 1, - "Station Engineer" = 5, - "Roboticist" = 1, + "Chief Engineer" = 1, - //red shirts - "Head of Security" = 1, - "Warden" = 1, - "Detective" = 1, - "Security Officer" = 5, - "Lawyer" = 2, + "Station Engineer" = 5, + "Atmospheric Technician"= 4, + "Roboticist" = 1, - //medbay - "Chief Medical Officer" = 1, - "Medical Doctor" = 5, - "Geneticist" = 2, - "Chemist" = 2, + //medical + "Chief Medical Officer" = 1, - //science dept - "Research Director" = 1, - "Scientist" = 3, - "Virologist" = 1, + "Medical Doctor" = 5, + "Geneticist" = 2, + "Virologist" = 1, - //I afraid I can't do that, Dave - "AI" = 1, - "Cyborg" = 1, - "Assistant" = -1 + //science + "Research Director" = 1, + "Scientist" = 3, + "Chemist" = 2, + + + //security + "Head of Security" = 1, + + "Warden" = 1, + "Detective" = 1, + "Security Officer" = 5, + + + //silicon + "AI" = 1, + "Cyborg" = 1, + + "Assistant" = -1 ) + var/list/assistant_occupations = list( - "Assistant" = -1, - "Chaplain" = 1, - "Librarian" = 1, - "Lawyer" = 2, - "Atmospheric Technician" = 4 - //"Tourist", //I am not going to implement these jobs at the moment. Just listed it as examples. --rastaf0 - //"Monkey", - //"Prisoneer", - //"Lizard" + "Assistant", + "Atmospheric Technician", + "Cargo Technician", + "Chaplain", + "Lawyer", + "Librarian" ) -var/list/head_positions = list( + +var/list/command_positions = list( "Captain", - "Chief Medical Officer", - "Chief Engineer", "Head of Personnel", + "Head of Security", + "Chief Engineer", "Research Director", - "Head of Security" + "Chief Medical Officer" ) + +var/list/engineering_positions = list( + "Chief Engineer", + "Station Engineer", + "Atmospheric Technician", + "Roboticist" +) + + +var/list/medical_positions = list( + "Chief Medical Officer", + "Medical Doctor", + "Geneticist", + "Virologist" +) + + +var/list/science_positions = list( + "Research Director", + "Scientist", + "Chemist" +) + + +var/list/civilian_positions = list( + "Head of Personnel", + "Bartender", + "Botanist", + "Chef", + "Janitor", + "Librarian", + "Quartermaster", + "Cargo Technician", + "Shaft Miner", + "Lawyer", + "Chaplain", + "Clown", + "Mime", + "Assistant" +) + + +var/list/security_positions = list( + "Head of Security", + "Warden", + "Detective", + "Security Officer" +) + + var/list/nonhuman_positions = list( "AI", - "Cyborg" - //"Monkey", - //"Lizard", + "Cyborg", + "pAI" ) -/proc/is_important_job(var/job) - return (job in head_positions) || (job in list("AI", "Cyborg", "Warden", "Detective", "pAI"))//pAI is in here to prevent guest pAI's as they can easily ruin rounds + +/proc/guest_jobbans(var/job) + return ((job in command_positions) || (job in nonhuman_positions) || (job in security_positions)) diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm index bfae7336d98..4f37d15adce 100644 --- a/code/modules/admin/banjob.dm +++ b/code/modules/admin/banjob.dm @@ -10,7 +10,7 @@ var /proc/jobban_isbanned(mob/M, rank) if(_jobban_isbanned(M, rank)) return 1//for old jobban if(M) - if (is_important_job(rank)) + if (guest_jobbans(rank)) if(config.guest_jobban && IsGuestKey(M.key)) return 1 if(config.usewhitelist && !check_whitelist(M)) diff --git a/code/modules/admin/newbanjob.dm b/code/modules/admin/newbanjob.dm index ee55fd85385..e06a91b015b 100644 --- a/code/modules/admin/newbanjob.dm +++ b/code/modules/admin/newbanjob.dm @@ -6,7 +6,7 @@ var/savefile/Banlistjob ClearTempbansjob() var/id = clientvar.computer_id var/key = clientvar.ckey - if (is_important_job(rank)) + if (guest_jobbans(rank)) if(config.guest_jobban && IsGuestKey(key)) return 1 Banlistjob.cd = "/base" diff --git a/code/modules/mob/new_player/preferences.dm b/code/modules/mob/new_player/preferences.dm index 85470ab0aa2..55bcc5a96c9 100644 --- a/code/modules/mob/new_player/preferences.dm +++ b/code/modules/mob/new_player/preferences.dm @@ -381,7 +381,6 @@ datum/preferences update_preview_icon() user << browse_rsc(preview_icon, "previewicon.png") -// var/list/destructive = list("Assistant") //only the actual assistants should terminate the list var/dat = "" dat += "Name: " dat += "[real_name] " @@ -397,59 +396,43 @@ datum/preferences dat += "Play admin midis: [midis == 1 ? "Yes" : "No"]
" dat += "Show chat bubbles: [bubbles == 1 ? "Yes" : "No"]
" - if(user.client) - if(user.client.holder) - if(user.client.holder.rank) - if(user.client.holder.rank == "Game Master") - dat += "
OOC
" - dat += "Change colour
__
" + if((user.client) && (user.client.holder) && (user.client.holder.rank) && (user.client.holder.rank == "Game Master")) + dat += "
OOC
" + dat += "Change colour
__
" dat += "
Occupation Choices
" dat += "\tSet Preferences
" - dat += "
Body " dat += "(®)" // Random look dat += "
" dat += "Blood Type: [b_type]
" dat += "Skin Tone: [-s_tone + 35]/220
" - if (!IsGuestKey(user.key)) + if(!IsGuestKey(user.key)) dat += "Underwear: [underwear == 1 ? "Yes" : "No"]
" dat += "
Preview
" dat += "
Hair
" dat += "Change Color
__
" -/* - dat += " Red - [r_hair]" - dat += " Green - [g_hair]" - dat += " Blue - [b_hair]
" -*/ + dat += "Style: [h_style]" dat += "
Facial
" dat += "Change Color
__
" -/* - dat += " Red - [r_facial]" - dat += " Green - [g_facial]" - dat += " Blue - [b_facial]
" -*/ + dat += "Style: [f_style]" dat += "
Eyes
" dat += "Change Color
__
" -/* - dat += " Red - [r_eyes]" - dat += " Green - [g_eyes]" - dat += " Blue - [b_eyes]" -*/ + dat += "
" if(!jobban_isbanned(user, "Syndicate")) var/n = 0 for (var/i in special_roles) - if (special_roles[i]) //if mode is available on the server + if(special_roles[i]) //if mode is available on the server dat += "Be [i]: [src.be_special&(1<
" n++ else @@ -469,33 +452,38 @@ datum/preferences proc/SetChoices(mob/user, changedjob) var/HTML = "" HTML += "
" - HTML += "Choose occupations
Unavailable occupations are in red.
" - for(var/job in occupations ) - if ((job!="AI" || config.allow_ai)) - if(jobban_isbanned(user, job)) - HTML += "" - if(job in head_positions || job=="AI") - HTML += "[job]" + HTML += "Choose occupation chances
Unavailable occupations are in red.
" + for(var/job in occupations) + if(jobban_isbanned(user, job)) + HTML += "[job]
" + continue + if((job in command_positions) || (job=="AI"))//Bold head jobs + HTML += "[job]
" + else + HTML += "[job]" + + if(!occupation[job]) + occupation[job] = 0 + + if(job=="Assistant")//Assistant is special + if(occupation[job] != 0) + HTML += "\[Yes]" else - HTML += "[job]" - if(jobban_isbanned(user, job)) - HTML += "
" - if (!occupation[job]) - occupation[job]=0 - switch(occupation[job]) - if(0) - if(job=="Assistant") - HTML += "\[PleaseNo]" - else - HTML += "\[NEVER]" - if(1) - HTML += "\[Okay]" - if(2) - HTML += "\[Good]" - if(3) - HTML += "\[Best!]" - else HTML += "*"+occupation[job]+"*" + HTML += "\[No]" HTML += "
" + continue + + switch(occupation[job]) + if(0) + HTML += "\[NEVER]" + if(1) + HTML += "\[High]" + if(2) + HTML += "\[Medium]" + if(3) + HTML += "\[Low]" + else HTML += "*"+occupation[job]+"*" + HTML += "
" HTML += "
" HTML += "\[Done\]" @@ -506,18 +494,25 @@ datum/preferences return proc/SetJob(mob/user, job="Captain") - if ((!( occupations.Find(job) ) && !( assistant_occupations.Find(job) ) && (job != "No Preference"))) + if((!(occupations.Find(job)) && !(assistant_occupations.Find(job)) && (job != "No Preference"))) user << browse(null, "window=mob_occupation") ShowChoices(user) return - if(occupation[job] == 2) // If it's going from good to best + if(job == "Assistant") + if(occupation[job] == 0) + occupation[job] = 4 + else + occupation[job] = 0 + + if(occupation[job] == 0)//Only one job may be set to "High" for(var/j in occupation) - if(occupation[j] == 3) + if(occupation[j] == 1) occupation[j] = 2 - occupation[job] = (occupation[job]+1)%4 - + occupation[job] = (occupation[job]-1) + if(occupation[job] < 0) + occupation[job] = 3 SetChoices(user) @@ -545,7 +540,7 @@ datum/preferences var/list/bad_characters = list("_", "'", "\"", "<", ">", ";", "[", "]", "{", "}", "|", "\\") for(var/c in bad_characters) new_name = dd_replacetext(new_name, c, "") - if(!new_name || (new_name == "Unknown")) + if(!new_name || (new_name == "Unknown") || (new_name == "floor") || (new_name == "wall") || (new_name == "r-wall")) alert("Don't do this") return diff --git a/data/mode.txt b/data/mode.txt index ae791fed369..bd81a61cbfd 100644 --- a/data/mode.txt +++ b/data/mode.txt @@ -1 +1 @@ -extended +traitor diff --git a/tgstation.dme b/tgstation.dme index 9a99f89bde2..5c5459932c4 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -889,6 +889,7 @@ #include "code\modules\research\server.dm" #include "code\WorkInProgress\buildmode.dm" #include "code\WorkInProgress\explosion_particles.dm" +#include "code\WorkInProgress\jobs.dm" #include "code\WorkInProgress\mapload\dmm_suite.dm" #include "code\WorkInProgress\mapload\reader.dm" #include "code\WorkInProgress\organs\organs.dm"