From 3008281e3c8e41e8da00b6cd889c5fe366a8f369 Mon Sep 17 00:00:00 2001 From: "rastaf.zero@gmail.com" Date: Fri, 8 Jul 2011 16:35:36 +0000 Subject: [PATCH] Gamemodes bugfix: - heads, security officers, wardens and detectives cannot be cultists or revs again. - chaplain cannot be cultist. - players with unfilled preferences wouldn't huddle together in same departments. - fixed bug in get_players_for_role caused to players jobbanned from syndicate get special roles. Fixed major bug with reagents not adding when same reagent is already present in container. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@1802 316c924e-a436-60f5-8080-3fe189b3f50e --- code/WorkInProgress/Chemistry-Holder.dm | 2 +- code/defines/procs/helpers.dm | 14 ++ code/game/gamemodes/changeling/changeling.dm | 5 +- .../game/gamemodes/changeling/traitor_chan.dm | 5 +- code/game/gamemodes/cult/cult.dm | 6 +- code/game/gamemodes/game_mode.dm | 8 +- code/game/gamemodes/revolution/revolution.dm | 6 +- code/game/jobs/jobprocs.dm | 124 ++++++------------ code/modules/mob/new_player/new_player.dm | 1 + 9 files changed, 69 insertions(+), 102 deletions(-) diff --git a/code/WorkInProgress/Chemistry-Holder.dm b/code/WorkInProgress/Chemistry-Holder.dm index cfac34e7bb9..ce8385d9939 100644 --- a/code/WorkInProgress/Chemistry-Holder.dm +++ b/code/WorkInProgress/Chemistry-Holder.dm @@ -276,7 +276,7 @@ datum my_atom.on_reagent_change() // mix dem viruses - if(R.data["viruses"] || data["viruses"]) + if(R.data && R.data["viruses"] || data &&data["viruses"]) var/list/this = R.data["viruses"] var/list/that = data["viruses"] this += that // combine the two diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm index 1f69320aa8d..eb546958e27 100644 --- a/code/defines/procs/helpers.dm +++ b/code/defines/procs/helpers.dm @@ -1139,3 +1139,17 @@ proc/listclearnulls(list/list) else result = first ^ second return result + +/proc/pick_n_take(list/listfrom) + if (listfrom.len > 0) + var/picked = pick(listfrom) + listfrom -= picked + return picked + return null + +/proc/pop(list/listfrom) + if (listfrom.len > 0) + var/picked = listfrom[listfrom.len] + listfrom.len-- + return picked + return null diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index c31df252ebe..645cdfd7e87 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -61,10 +61,11 @@ /datum/game_mode/changeling/pre_setup() var/list/datum/mind/possible_changelings = get_players_for_role(BE_CHANGELING) if(possible_changelings.len>0) - var/changeling = pick(possible_changelings) + var/datum/mind/changeling = pick(possible_changelings) //possible_changelings-=changeling changelings += changeling - must_be_human += changeling + var/mob/new_player/player = changeling.current + player.jobs_restricted_by_gamemode = nonhuman_positions modePlayer += changelings return 1 else diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm index 7d39ac5fe21..98c08113535 100644 --- a/code/game/gamemodes/changeling/traitor_chan.dm +++ b/code/game/gamemodes/changeling/traitor_chan.dm @@ -19,10 +19,11 @@ /datum/game_mode/traitor/changeling/pre_setup() var/list/datum/mind/possible_changelings = get_players_for_role(BE_CHANGELING) if(possible_changelings.len>0) - var/changeling = pick(possible_changelings) + var/datum/mind/changeling = pick(possible_changelings) //possible_changelings-=changeling changelings += changeling - must_be_human += changeling + var/mob/new_player/player = changeling.current + player.jobs_restricted_by_gamemode = nonhuman_positions modePlayer += changelings return ..() else diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index cd4761d277f..c5b2fcf28e1 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -59,11 +59,11 @@ var/list/allwords = list("travel","self","see","hell","blood","join","tech","des var/list/cultists_possible = get_players_for_role(BE_CULTIST) for(var/cultists_number = 1 to max_cultists_to_start) - var/cultist = pick(cultists_possible) + var/datum/mind/cultist = pick(cultists_possible) cultists_possible -= cultist cult += cultist - must_be_human += cultist - can_not_be_head += cultist + var/mob/new_player/player = cultist.current + player.jobs_restricted_by_gamemode = list("Chaplain", "Security Officer", "Warden", "Detective")+nonhuman_positions+head_positions return (cult.len>0) /datum/game_mode/cult/post_setup() diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index ba48b87b6ec..9f4b0eaf3d6 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -19,8 +19,6 @@ var/probability = 1 var/station_was_nuked = 0 //see nuclearbomb.dm and malfunction.dm var/explosion_in_progress = 0 //sit back and relax - var/tmp/list/datum/mind/must_be_human = new - var/tmp/list/datum/mind/can_not_be_head = new /datum/game_mode/proc/announce() //to be calles when round starts world << "Notice: [src] did not define announce()" @@ -32,8 +30,7 @@ return 1 /datum/game_mode/proc/post_setup() //do irreversible preparations - del(must_be_human) //free some memory - del(can_not_be_head) + return 1 /datum/game_mode/proc/process() @@ -88,7 +85,8 @@ for(var/mob/new_player/player in world) if (player.client && player.ready) if(player.preferences.be_special & role) - candidates += player.mind + if(!jobban_isbanned(player, "Syndicate")) + candidates += player.mind if(candidates.len == 0) for(var/mob/new_player/player in world) diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 4933b3cb4ca..b48b8d22935 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -62,8 +62,8 @@ var/datum/mind/lenin = pick(possible_headrevs) possible_headrevs -= lenin head_revolutionaries += lenin - must_be_human += lenin - can_not_be_head += lenin + var/mob/new_player/player = lenin.current + player.jobs_restricted_by_gamemode = list("Security Officer", "Warden", "Detective")+nonhuman_positions+head_positions if(head_revolutionaries.len==0) return 0 @@ -76,8 +76,6 @@ break if (headless) head_revolutionaries.len = 0 - must_be_human.len = 0 - can_not_be_head.len = 0 ResetOccupations() //clean up return 0 return 1 diff --git a/code/game/jobs/jobprocs.dm b/code/game/jobs/jobprocs.dm index 50421fdf7ac..c345d93ba24 100644 --- a/code/game/jobs/jobprocs.dm +++ b/code/game/jobs/jobprocs.dm @@ -3,70 +3,57 @@ var/list/candidates = list() for (var/mob/new_player/player in unassigned) - if ( player.preferences.occupation[level] == job && \ - ! jobban_isbanned(player, job) && \ - ! ((player.mind in ticker.mode.must_be_human) && (job in nonhuman_positions)) && \ - ! ((player.mind in ticker.mode.can_not_be_head) && (job in head_positions))) + if (player.preferences.occupation[level] == job) + 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/PickOccupationCandidate(list/candidates) - if (candidates.len > 0) - var/picked = pick(candidates) - candidates -= picked - return picked - return null - /proc/ResetOccupations() for (var/mob/new_player/player in world) player.mind.assigned_role = null + player.jobs_restricted_by_gamemode = null return /** 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() var/list/unassigned = list() - var/list/occupation_choices = occupations.Copy() var/list/occupation_eligible = occupations.Copy() - occupation_choices = shuffle(occupation_choices) + + if(ticker.mode.name == "AI malfunction") + occupation_eligible["AI"] = 0 for (var/mob/new_player/player in world) if (player.client && player.ready && !player.mind.assigned_role) unassigned += player + for (var/level = 1 to 3) + if (jobban_isbanned(player, player.preferences.occupation[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) - if (player.preferences.occupation[1] == "AI") - player.preferences.occupation[1] = "Captain" - if (player.preferences.occupation[2] == "AI") - player.preferences.occupation[2] = "Captain" - if (player.preferences.occupation[3] == "AI") - player.preferences.occupation[3] = "Captain" - if (jobban_isbanned(player, player.preferences.occupation[1])) - player.preferences.occupation[1] = "Assistant" - if (jobban_isbanned(player, player.preferences.occupation[2])) - player.preferences.occupation[2] = "Assistant" - if (jobban_isbanned(player, player.preferences.occupation[3])) - player.preferences.occupation[3] = "Assistant" + for (var/level = 1 to 3) + if (player.preferences.occupation[level] == "AI") + player.preferences.occupation[level] = "Captain" if (unassigned.len == 0) return 0 - var/mob/new_player/captain_choice = null - for (var/level = 1 to 3) - var/list/captains = FindOccupationCandidates(unassigned, "Captain", level) - var/mob/new_player/candidate = PickOccupationCandidate(captains) + var/list/candidates = FindOccupationCandidates(unassigned, "Captain", level) - if (candidate != null) - captain_choice = candidate - unassigned -= captain_choice + if (candidates.len) + var/mob/new_player/candidate = pick(candidates) + unassigned -= candidate + candidate.mind.assigned_role = "Captain" break /* // Not forcing a Captain -- TLE @@ -80,19 +67,7 @@ break unassigned -= captain_choice */ - - - - - if (captain_choice == null) - //world << "Captainship not forced on anyone."//moved to gameticker/proc/distribute_jobs - else - captain_choice.mind.assigned_role = "Captain" - - for (var/level = 1 to 3) - if (unassigned.len == 0) //everyone is assigned - break - + for (var/level = 1 to 3) //players with preferences set for (var/occupation in assistant_occupations) if (unassigned.len == 0) break @@ -101,52 +76,31 @@ candidate.mind.assigned_role = occupation unassigned -= candidate - for (var/occupation in occupation_choices) + for (var/occupation in occupation_eligible) if (unassigned.len == 0) break - if(ticker.mode.name == "AI malfunction" && occupation == "AI") - continue - var/eligible = occupation_eligible[occupation] - if (eligible == 0) + if (occupation_eligible[occupation] == 0) continue var/list/candidates = FindOccupationCandidates(unassigned, occupation, level) - var/eligiblechange = 0 - while (eligible--) - var/mob/new_player/candidate = PickOccupationCandidate(candidates) - if (candidate == null) - break + 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 - eligiblechange++ - occupation_eligible[occupation] -= eligiblechange + + if (unassigned.len) //unlucky players with preferences and players without preferences + var/list/vacancies = list() + for (var/occ in occupation_eligible) + for (var/i = 1 to occupation_eligible[occ]) + vacancies += occ + + while (unassigned.len && vacancies.len) + var/mob/new_player/candidate = pick_n_take(unassigned) + var/occupation = pick_n_take(vacancies) + candidate.mind.assigned_role = occupation - if (unassigned.len) - unassigned = shuffle(unassigned) - for (var/occupation in occupation_choices) - if (unassigned.len == 0) - break - if(ticker.mode.name == "AI malfunction" && occupation == "AI") - continue - var/eligible = occupation_eligible[occupation] - - while (eligible-- && unassigned.len > 0) - var/n = 1 - var/mob/new_player/candidate = unassigned[1] - if (occupation in nonhuman_positions) - while (candidate.mind in ticker.mode.must_be_human) - n++ - if (n <= unassigned.len) - candidate = unassigned[n] - else - candidate = null - break - if (candidate == null) - break - candidate.mind.assigned_role = occupation - unassigned -= candidate - - for (var/mob/new_player/player in unassigned) - player.mind.assigned_role = pick(assistant_occupations) + for (var/mob/new_player/player in unassigned) + player.mind.assigned_role = pick(assistant_occupations) return 1 diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index a5fe5a1b991..26f6d5a7d93 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -10,6 +10,7 @@ mob/new_player canmove = 0 anchored = 1 // don't get pushed around + var/list/jobs_restricted_by_gamemode Login() //Next line is commented out because seem it does nothing helpful and on the other hand it calls mob/new_player/Move() to EACH turf in the world. --rastaf0