//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_enemies = 0 var/recommended_enemies = 0 var/newscaster_announcements = null var/ert_disabled = 0 var/uplink_welcome = "Syndicate Uplink Console:" var/uplink_uses = 20 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 to_chat(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(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 += pay var/datum/transaction/T = new() T.target_name = "[command_name()] Payroll" T.purpose = "Payment" T.amount = pay 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) useMS.send_pda_message("[P.owner]", "[command_name()] Payroll", msg) var/datum/data/pda/app/messenger/PM = P.find_program(/datum/data/pda/app/messenger) PM.notify("Message from [command_name()] (Payroll), \"[msg]\" (Unable to Reply)", 0) 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() . = list() for(var/mob/living/carbon/human/player in mob_list) if(player.stat != DEAD && player.mind && (player.mind.assigned_role in command_positions)) . |= player.mind //////////////////////////// //Keeps track of all heads// //////////////////////////// /datum/game_mode/proc/get_all_heads() . = list() for(var/mob/player in mob_list) if(player.mind && (player.mind.assigned_role in command_positions)) . |= player.mind ////////////////////////////////////////////// //Keeps track of all living security members// ////////////////////////////////////////////// /datum/game_mode/proc/get_living_sec() . = list() for(var/mob/living/carbon/human/player in mob_list) if(player.stat != DEAD && player.mind && (player.mind.assigned_role in security_positions)) . |= player.mind //////////////////////////////////////// //Keeps track of all security members// //////////////////////////////////////// /datum/game_mode/proc/get_all_sec() . = list() for(var/mob/living/carbon/human/player in mob_list) if(player.mind && (player.mind.assigned_role in security_positions)) . |= player.mind /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 = "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) to_chat(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) to_chat(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 to_chat(player.current, "\blue Your current objectives:") for(var/datum/objective/objective in player.objectives) to_chat(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 /datum/game_mode/proc/replace_jobbaned_player(mob/living/M, role_type) var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as a [role_type]?", role_type, 0, 100) var/mob/dead/observer/theghost = null if(candidates.len) theghost = pick(candidates) to_chat(M, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!") message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(M)]) to replace a jobbanned player.") M.ghostize() M.key = theghost.key else message_admins("[M] ([M.key] has been converted into [role_type] with an active antagonist jobban for said role since no ghost has volunteered to take their place.") to_chat(M, "You have been converted into [role_type] with an active jobban. Any further violations of the rules on your part are likely to result in a permanent ban.") /datum/game_mode/proc/printplayer(datum/mind/ply, fleecheck) var/text = "
[ply.key] was [ply.name] the [ply.assigned_role] and" if(ply.current) if(ply.current.stat == DEAD) text += " died" else text += " survived" if(fleecheck && ply.current.z > ZLEVEL_STATION) text += " while fleeing the station" if(ply.current.real_name != ply.name) text += " as [ply.current.real_name]" else text += " had their body destroyed" return text /datum/game_mode/proc/printobjectives(datum/mind/ply) var/text = "" var/count = 1 for(var/datum/objective/objective in ply.objectives) if(objective.check_completion()) text += "
Objective #[count]: [objective.explanation_text] Success!" else text += "
Objective #[count]: [objective.explanation_text] Fail." count++ return text