//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 because 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_enemies = 0 var/newscaster_announcements = null var/uplink_welcome = "Syndicate Uplink Console:" var/uplink_uses = 10 var/uplink_items = {"Highly Visible and Dangerous Weapons; /obj/item/weapon/gun/projectile:6:Revolver; /obj/item/ammo_magazine/a357:2:Ammo-357; /obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow; /obj/item/weapon/melee/energy/sword:4:Energy Sword; /obj/item/weapon/storage/box/syndicate:10:Syndicate Bundle; /obj/item/weapon/storage/box/emps:3:5 EMP Grenades; Whitespace:Seperator; Stealthy and Inconspicuous Weapons; /obj/item/weapon/pen/paralysis:3:Paralysis Pen; /obj/item/weapon/soap/syndie:1:Syndicate Soap; /obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge; Whitespace:Seperator; Stealth and Camouflage Items; /obj/item/weapon/storage/box/syndie_kit/chameleon:3:Chameleon Kit; /obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes; /obj/item/weapon/card/id/syndicate:2:Agent ID card; /obj/item/clothing/mask/gas/voice:4:Voice Changer; /obj/item/device/chameleon:4:Chameleon-Projector; Whitespace:Seperator; Devices and Tools; /obj/item/weapon/card/emag:3:Cryptographic Sequencer; /obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox; /obj/item/weapon/storage/box/syndie_kit/space:3:Space Suit; /obj/item/clothing/glasses/thermal/syndi:3:Thermal Imaging Glasses; /obj/item/device/encryptionkey/binary:3:Binary Translator Key; /obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module; /obj/item/weapon/plastique:2:C-4 (Destroys walls); /obj/item/device/powersink:5:Powersink (DANGER!); /obj/item/device/radio/beacon/syndicate:7:Singularity Beacon (DANGER!); /obj/item/weapon/circuitboard/teleporter:20:Teleporter Circuit Board; Whitespace:Seperator; Implants; /obj/item/weapon/storage/box/syndie_kit/imp_freedom:3:Freedom Implant; /obj/item/weapon/storage/box/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals); /obj/item/weapon/storage/box/syndie_kit/imp_explosive:6:Explosive Implant (DANGER!); /obj/item/weapon/storage/box/syndie_kit/imp_compress:4:Compressed Matter Implant;Whitespace:Seperator; (Pointless) Badassery; /obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"} // Items removed from above: /* /obj/item/weapon/cloaking_device:4:Cloaking Device; //Replacing cloakers with thermals. -Pete */ /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_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]") return 1 ///process() ///Called by the gameticker /datum/game_mode/proc/process() return 0 /datum/game_mode/proc/check_finished() //to be called by ticker if(emergency_shuttle.location==2 || station_was_nuked) return 1 return 0 /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/centcom, /area/shuttle/escape_pod1/centcom, /area/shuttle/escape_pod2/centcom, /area/shuttle/escape_pod3/centcom, /area/shuttle/escape_pod5/centcom) 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 == /area/shuttle/escape/centcom) 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/send_intercept() var/intercepttext = "Cent. Com. Update Requested status information:
" intercepttext += " In case you have misplaced your copy, attached is a list of personnel whom reliable sources™ suspect may be affiliated with the Syndicate:
" var/list/suspects = list() for(var/mob/living/carbon/human/man in player_list) if(man.client && man.mind) // NT relation option var/special_role = man.mind.special_role if (special_role == "Wizard" || special_role == "Ninja" || special_role == "Syndicate" || special_role == "Vox Raider") continue //NT intelligence ruled out possiblity that those are too classy to pretend to be a crew. if(man.client.prefs.nanotrasen_relation == "Opposed" && prob(50) || \ man.client.prefs.nanotrasen_relation == "Skeptical" && prob(20)) suspects += man // Antags else if(special_role == "traitor" && prob(40) || \ special_role == "Changeling" && prob(50) || \ special_role == "Cultist" && prob(30) || \ special_role == "Head Revolutionary" && prob(30)) suspects += man // If they're a traitor or likewise, give them extra TC in exchange. var/obj/item/device/uplink/hidden/suplink = man.mind.find_syndicate_uplink() if(suplink) var/extra = 4 suplink.uses += extra man << "\red We have received notice that enemy intelligence suspects you to be linked with us. We have thus invested significant resources to increase your uplink's capacity." else // Give them a warning! man << "\red They are on to you!" // Some poor people who were just in the wrong place at the wrong time.. else if(prob(10)) suspects += man for(var/mob/M in suspects) switch(rand(1, 100)) if(1 to 50) intercepttext += "Someone with the job of [M.mind.assigned_role]
" else intercepttext += "[M.name], the [M.mind.assigned_role]
" for (var/obj/machinery/computer/communications/comm in machines) if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) intercept.name = "paper - 'Cent. Com. Status Summary'" intercept.info = intercepttext comm.messagetitle.Add("Cent. Com. Status Summary") comm.messagetext.Add(intercepttext) world << sound('sound/AI/commandreport.ogg') /* command_alert("Summary downloaded and printed out at all communications consoles.", "Enemy communication intercept. Security Level Elevated.") for(var/mob/M in player_list) if(!istype(M,/mob/new_player)) M << sound('sound/AI/intercept.ogg') if(security_level < SEC_LEVEL_BLUE) set_security_level(SEC_LEVEL_BLUE)*/ /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 switch(role) if(BE_CHANGELING) roletext="changeling" if(BE_TRAITOR) roletext="traitor" if(BE_OPERATIVE) roletext="operative" if(BE_WIZARD) roletext="wizard" if(BE_REV) roletext="revolutionary" if(BE_CULTIST) roletext="cultist" if(BE_NINJA) roletext="ninja" if(BE_RAIDER) roletext="raider" // 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)) 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 for(var/mob/new_player/player in players) if(player.client.prefs.be_special & role) 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 /*if(candidates.len < recommended_enemies) for(var/mob/new_player/player in players) if(player.client && player.ready) if(!(player.client.prefs.be_special & role)) // We don't have enough people who want to be antagonist, make a seperate list of people who don't want to be one if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, roletext)) //Nodrak/Carn: Antag Job-bans drafted += player.mind if(restricted_jobs) for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist for(var/job in restricted_jobs) if(player.assigned_role == job) drafted -= player drafted = shuffle(drafted) // Will hopefully increase randomness, Donkie while(candidates.len < recommended_enemies) // Pick randomlly just the number of people we need and add them to our list of candidates if(drafted.len > 0) applicant = pick(drafted) if(applicant) candidates += applicant log_debug("[applicant.key] was force-drafted as [roletext], because there aren't enough candidates.") drafted.Remove(applicant) else // Not enough scrubs, ABORT ABORT ABORT break if(candidates.len < recommended_enemies && override_jobbans) //If we still don't have enough people, we're going to start drafting banned people. for(var/mob/new_player/player in players) if (player.client && player.ready) if(jobban_isbanned(player, "Syndicate") || jobban_isbanned(player, roletext)) //Nodrak/Carn: Antag Job-bans drafted += player.mind if(restricted_jobs) for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist for(var/job in restricted_jobs) if(player.assigned_role == job) drafted -= player drafted = shuffle(drafted) // Will hopefully increase randomness, Donkie while(candidates.len < recommended_enemies) // Pick randomlly just the number of people we need and add them to our list of candidates if(drafted.len > 0) applicant = pick(drafted) if(applicant) candidates += applicant drafted.Remove(applicant) log_debug("[applicant.key] was force-drafted as [roletext], because there aren't enough candidates.") else // Not enough scrubs, ABORT ABORT ABORT break */ 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/new_player/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) . ++ /////////////////////////////////// //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 //////////////////////////// //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/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" 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" 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)