//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 /* * GAMEMODES (by Rastaf0) * * In the new mode system all special roles are fully supported. * You can have proper wizards/traitors/changelings/cultists during any mode. * Only two things really depends on gamemode: * 1. Starting roles, equipment and preparations * 2. Conditions of finishing the round. * */ /datum/game_mode var/name = "invalid" var/config_tag = null var/intercept_hacked = 0 var/votable = 1 var/probability = 0 var/station_was_nuked = 0 //see nuclearbomb.dm and malfunction.dm var/explosion_in_progress = 0 //sit back and relax var/list/datum/mind/modePlayer = new var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist var/list/protected_jobs = list() // Jobs that can't be traitors var/list/protected_species = list() // Species that can't be traitors var/required_players = 0 var/required_players_secret = 0 //Minimum number of players for that game mode to be chose in Secret var/required_enemies = 0 var/recommended_players = 0 var/recommended_enemies = 0 var/newscaster_announcements = null var/ert_disabled = 0 var/uplink_welcome = "Syndicate Uplink Console:" var/uplink_uses = 10 var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) /datum/game_mode/proc/announce() //to be calles when round starts world << "Notice: [src] did not define announce()" ///can_start() ///Checks to see if the game can be setup and ran with the current number of players or whatnot. /datum/game_mode/proc/can_start() var/playerC = 0 for(var/mob/new_player/player in player_list) if((player.client)&&(player.ready)) playerC++ if(master_mode=="secret") if(playerC >= required_players_secret) return 1 else if(playerC >= required_players) return 1 return 0 //pre_pre_setup() For when you really don't want certain jobs ingame. /datum/game_mode/proc/pre_pre_setup() return 1 ///pre_setup() ///Attempts to select players for special roles the mode might have. /datum/game_mode/proc/pre_setup() return 1 ///post_setup() ///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things /datum/game_mode/proc/post_setup() spawn (ROUNDSTART_LOGOUT_REPORT_TIME) display_roundstart_logout_report() feedback_set_details("round_start","[time2text(world.realtime)]") if(ticker && ticker.mode) feedback_set_details("game_mode","[ticker.mode]") // if(revdata) // feedback_set_details("revision","[revdata.revision]") feedback_set_details("server_ip","[world.internet_address]:[world.port]") start_state = new /datum/station_state() start_state.count() return 1 ///process() ///Called by the gameticker /datum/game_mode/proc/process() return 0 //Called by the gameticker /datum/game_mode/proc/process_job_tasks() var/obj/machinery/message_server/useMS = null if(message_servers) for (var/obj/machinery/message_server/MS in message_servers) if(MS.active) useMS = MS break for(var/mob/M in player_list) if(M.mind) var/obj/item/device/pda/P=null for(var/obj/item/device/pda/check_pda in PDAs) if (check_pda.owner==M.name) P=check_pda break var/count=0 for(var/datum/job_objective/objective in M.mind.job_objectives) count++ var/msg="" var/pay=0 if(objective.per_unit && objective.units_compensated0) if(M.mind.initial_account) M.mind.initial_account.money += objective.completion_payment var/datum/transaction/T = new() T.target_name = "[command_name()] Payroll" T.purpose = "Payment" T.amount = objective.completion_payment T.date = current_date_string T.time = worldtime2text() T.source_terminal = "\[CLASSIFIED\] Terminal #[rand(111,333)]" M.mind.initial_account.transaction_log.Add(T) msg += "You have been sent the $[pay], as agreed." else msg += "However, we were unable to send you the $[pay] you're entitled." if(useMS && P) // THIS SHOULD HAVE DONE EVERYTHING FOR ME useMS.send_pda_message("[P.owner]", "[command_name()] Payroll", msg) // BUT NOPE, NEED TO DO THIS BULLSHIT. P.play_ringtone() //Search for holder of the PDA. var/mob/living/L = null if(P.loc && isliving(P.loc)) L = P.loc //Maybe they are a pAI! else L = get(P, /mob/living/silicon) if(L) L << "\icon[P] Message from [command_name()] (Payroll), \"[msg]\" (Unable to Reply)" break /datum/game_mode/proc/check_finished() //to be called by ticker if(shuttle_master.emergency.mode >= SHUTTLE_ENDGAME || station_was_nuked) return 1 return 0 /datum/game_mode/proc/cleanup() //This is called when the round has ended but not the game, if any cleanup would be necessary in that case. return /datum/game_mode/proc/declare_completion() var/clients = 0 var/surviving_humans = 0 var/surviving_total = 0 var/ghosts = 0 var/escaped_humans = 0 var/escaped_total = 0 var/escaped_on_pod_1 = 0 var/escaped_on_pod_2 = 0 var/escaped_on_pod_3 = 0 var/escaped_on_pod_5 = 0 var/escaped_on_shuttle = 0 var/list/area/escape_locations = list(/area/shuttle/escape, /area/shuttle/escape_pod1/centcom, /area/shuttle/escape_pod2/centcom, /area/shuttle/escape_pod3/centcom, /area/shuttle/escape_pod5/centcom) if(shuttle_master.emergency.mode < SHUTTLE_ENDGAME) //shuttle didn't get to centcom escape_locations -= /area/shuttle/escape for(var/mob/M in player_list) if(M.client) clients++ if(ishuman(M)) if(!M.stat) surviving_humans++ if(M.loc && M.loc.loc && M.loc.loc.type in escape_locations) escaped_humans++ if(!M.stat) surviving_total++ if(M.loc && M.loc.loc && M.loc.loc.type in escape_locations) escaped_total++ if(M.loc && M.loc.loc && M.loc.loc.type == shuttle_master.emergency.areaInstance.type && shuttle_master.emergency.mode >= SHUTTLE_ENDGAME) escaped_on_shuttle++ if(M.loc && M.loc.loc && M.loc.loc.type == /area/shuttle/escape_pod1/centcom) escaped_on_pod_1++ if(M.loc && M.loc.loc && M.loc.loc.type == /area/shuttle/escape_pod2/centcom) escaped_on_pod_2++ if(M.loc && M.loc.loc && M.loc.loc.type == /area/shuttle/escape_pod3/centcom) escaped_on_pod_3++ if(M.loc && M.loc.loc && M.loc.loc.type == /area/shuttle/escape_pod5/centcom) escaped_on_pod_5++ if(isobserver(M)) ghosts++ if(clients > 0) feedback_set("round_end_clients",clients) if(ghosts > 0) feedback_set("round_end_ghosts",ghosts) if(surviving_humans > 0) feedback_set("survived_human",surviving_humans) if(surviving_total > 0) feedback_set("survived_total",surviving_total) if(escaped_humans > 0) feedback_set("escaped_human",escaped_humans) if(escaped_total > 0) feedback_set("escaped_total",escaped_total) if(escaped_on_shuttle > 0) feedback_set("escaped_on_shuttle",escaped_on_shuttle) if(escaped_on_pod_1 > 0) feedback_set("escaped_on_pod_1",escaped_on_pod_1) if(escaped_on_pod_2 > 0) feedback_set("escaped_on_pod_2",escaped_on_pod_2) if(escaped_on_pod_3 > 0) feedback_set("escaped_on_pod_3",escaped_on_pod_3) if(escaped_on_pod_5 > 0) feedback_set("escaped_on_pod_5",escaped_on_pod_5) send2mainirc("A round of [src.name] has ended - [surviving_total] survivors, [ghosts] ghosts.") return 0 /datum/game_mode/proc/check_win() //universal trigger to be called at mob death, nuke explosion, etc. To be called from everywhere. return 0 /datum/game_mode/proc/get_players_for_role(var/role, override_jobbans=0) var/list/players = list() var/list/candidates = list() //var/list/drafted = list() //var/datum/mind/applicant = null var/roletext = get_roletext(role) // Assemble a list of active players without jobbans. for(var/mob/new_player/player in player_list) if(player.client && player.ready) if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, roletext)) if(player_old_enough_antag(player.client,role)) players += player // Shuffle the players list so that it becomes ping-independent. players = shuffle(players) // Get a list of all the people who want to be the antagonist for this round, except those with incompatible species for(var/mob/new_player/player in players) if((role in player.client.prefs.be_special) && !(player.client.prefs.species in protected_species)) log_debug("[player.key] had [roletext] enabled, so we are drafting them.") candidates += player.mind players -= player // If we don't have enough antags, draft people who voted for the round. if(candidates.len < recommended_enemies) for(var/key in round_voters) for(var/mob/new_player/player in players) if(player.ckey == key) log_debug("[player.key] voted for this round, so we are drafting them.") candidates += player.mind players -= player break // Remove candidates who want to be antagonist but have a job that precludes it if(restricted_jobs) for(var/datum/mind/player in candidates) for(var/job in restricted_jobs) if(player.assigned_role == job) candidates -= player return candidates // Returns: The number of people who had the antagonist role set to yes, regardless of recomended_enemies, if that number is greater than recommended_enemies // recommended_enemies if the number of people with that role set to yes is less than recomended_enemies, // Less if there are not enough valid players in the game entirely to make recommended_enemies. /datum/game_mode/proc/latespawn(var/mob) /* /datum/game_mode/proc/check_player_role_pref(var/role, var/mob/player) if(player.preferences.be_special & role) return 1 return 0 */ /datum/game_mode/proc/num_players() . = 0 for(var/mob/new_player/P in player_list) if(P.client && P.ready) .++ /datum/game_mode/proc/num_players_started() . = 0 for(var/mob/living/carbon/human/H in player_list) if(H.client) .++ /////////////////////////////////// //Keeps track of all living heads// /////////////////////////////////// /datum/game_mode/proc/get_living_heads() var/list/heads = list() for(var/mob/living/carbon/human/player in mob_list) if(player.stat!=2 && player.mind && (player.mind.assigned_role in command_positions)) heads += player.mind return heads /datum/game_mode/proc/get_extra_living_heads() var/list/heads = list() var/list/alt_positions = list("Warden", "Magistrate", "Blueshield", "Nanotrasen Representative") for(var/mob/living/carbon/human/player in mob_list) if(player.stat!=2 && player.mind && (player.mind.assigned_role in alt_positions)) heads += player.mind return heads //////////////////////////// //Keeps track of all heads// //////////////////////////// /datum/game_mode/proc/get_all_heads() var/list/heads = list() for(var/mob/player in mob_list) if(player.mind && (player.mind.assigned_role in command_positions)) heads += player.mind return heads /datum/game_mode/proc/get_extra_heads() var/list/heads = list() var/list/alt_positions = list("Warden", "Magistrate", "Blueshield", "Nanotrasen Representative") for(var/mob/player in mob_list) if(player.mind && (player.mind.assigned_role in alt_positions)) heads += player.mind return heads /datum/game_mode/proc/check_antagonists_topic(href, href_list[]) return 0 /datum/game_mode/New() newscaster_announcements = pick(newscaster_standard_feeds) ////////////////////////// //Reports player logouts// ////////////////////////// proc/display_roundstart_logout_report() var/msg = "\blue Roundstart logout report\n\n" for(var/mob/living/L in mob_list) if(L.ckey) var/found = 0 for(var/client/C in clients) if(C.ckey == L.ckey) found = 1 break if(!found) msg += "[L.name] ([L.ckey]), the [L.job] (Disconnected)\n" if(L.ckey && L.client) if(L.client.inactivity >= (ROUNDSTART_LOGOUT_REPORT_TIME / 2)) //Connected, but inactive (alt+tabbed or something) msg += "[L.name] ([L.ckey]), the [L.job] (Connected, Inactive)\n" continue //AFK client if(L.stat) if(L.suiciding) //Suicider msg += "[L.name] ([L.ckey]), the [L.job] (Suicide)\n" job_master.FreeRole(L.job) message_admins("[key_name_admin(L)], the [L.job] has been freed due to (Early Round Suicide)\n") continue //Disconnected client if(L.stat == UNCONSCIOUS) msg += "[L.name] ([L.ckey]), the [L.job] (Dying)\n" continue //Unconscious if(L.stat == DEAD) msg += "[L.name] ([L.ckey]), the [L.job] (Dead)\n" continue //Dead continue //Happy connected client for(var/mob/dead/observer/D in mob_list) if(D.mind && (D.mind.original == L || D.mind.current == L)) if(L.stat == DEAD) if(L.suiciding) //Suicider msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Suicide)\n" continue //Disconnected client else msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Dead)\n" continue //Dead mob, ghost abandoned else if(D.can_reenter_corpse) msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (This shouldn't appear.)\n" continue //Lolwhat else msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Ghosted)\n" job_master.FreeRole(L.job) message_admins("[key_name_admin(L)], the [L.job] has been freed due to (Early Round Ghosted While Alive)\n") continue //Ghosted while alive for(var/mob/M in mob_list) if(M.client && M.client.holder) M << msg proc/get_nt_opposed() var/list/dudes = list() for(var/mob/living/carbon/human/man in player_list) if(man.client) if(man.client.prefs.nanotrasen_relation == "Opposed") dudes += man else if(man.client.prefs.nanotrasen_relation == "Skeptical" && prob(50)) dudes += man if(dudes.len == 0) return null return pick(dudes) //Announces objectives/generic antag text. /proc/show_generic_antag_text(var/datum/mind/player) if(player.current) player.current << \ "You are an antagonist! Within the rules, \ try to act as an opposing force to the crew. Further RP and try to make sure \ other players have fun! If you are confused or at a loss, always adminhelp, \ and before taking extreme actions, please try to also contact the administration! \ Think through your actions and make the roleplay immersive! Please remember all \ rules aside from those without explicit exceptions apply to antagonists." /proc/show_objectives(var/datum/mind/player) if(!player || !player.current) return var/obj_count = 1 player.current << "\blue Your current objectives:" for(var/datum/objective/objective in player.objectives) player.current << "Objective #[obj_count]: [objective.explanation_text]" obj_count++ /proc/get_roletext(var/role) return role /proc/get_nuke_code() var/nukecode = "ERROR" for(var/obj/machinery/nuclearbomb/bomb in world) if(bomb && bomb.r_code && bomb.z == ZLEVEL_STATION) nukecode = bomb.r_code return nukecode