/* * This roundtype is a replacement for the meteor round on upstream BS12 - players * expressed the desire for quick, chaotic and violent rounds, preferrably without * dependancy on other players. * I wanted to call it clusterfuck, but I figure that's a bit too overt. Think of * the children. * ~ Zuhayr */ /datum/game_mode/calamity name = "calamity" config_tag = "calamity" required_players = 1 votable = 0 //Remove after testing. //Possible roundstart antag types. var/list/atypes = list("syndi","ling","tater","wiz","ninja","vox","cult") //Readd slug when borer spawn is fixed. var/list/chosen_atypes = list() var/list/chosen_candidates = list() var/list/already_assigned_candidates = list() //At one antagonist group per 10 players we are just going to go with tiny groups. var/max_antags = 5 // Antag groups spawn with this many members. var/antag_type_ratio = 8 // 1 antag type per this many players. var/const/waittime_l = 600 var/const/waittime_h = 1800 /datum/game_mode/calamity/announce() world << "The current game mode is - Calamity!" world << "This must be a Thursday. You never could get the hang of Thursdays..." /datum/game_mode/calamity/can_start() if(!..()) return 0 var/antag_count = player_list.len/antag_type_ratio if(!antag_count) return 1 for(var/i=0;i" for(var/datum/mind/P in L) text += "
[P.key] was [P.name] (" if(P.current) if(P.current.stat == DEAD) text += "died" else text += "survived" if(P.current.real_name != P.name) text += " as [P.current.real_name]" else text += "body destroyed" text += ")" if(M.objectives.len) text += "
Their objectives were:" var/num = 1 for(var/datum/objective/O in M.objectives) text += "
Objective [num]: [O.explanation_text]" num++ //Single antag objective completion. for(var/list/L in list(src.changelings, src.ninjas, src.borers, src.traitors)) if(L.len) var/datum/mind/M = L[1] text = "
The [M.special_role][L.len == 1 ? " was" : "s were"]:" for(var/datum/mind/P in L) var/num = 1 text += "
[P.key] was [P.name]." if(P.objectives.len) for(var/datum/objective/O in P.objectives) text += "
Objective [num]: [O.explanation_text]" num++ ..() return 1 //Converts chosen atype to an actual role string. /datum/game_mode/calamity/proc/get_candidate_role_text(var/role) var/role_text switch(role) if("syndi") role_text = "Mercenary" if("ling") role_text = "Changeling" if("tater") role_text = "Traitor" if("wiz") role_text = "Cabalist" if("ninja") role_text = "Ninja" if("vox") role_text = "Vox Raider" if("slug") role_text = "Cortical Borer" if("cult") role_text = "Cultist" return role_text //Grabs candidate lists for various atypes. /datum/game_mode/calamity/proc/get_role_candidates(var/role) var/list/possible_antags = list() switch(role) if("syndi") possible_antags = get_players_for_role(BE_OPERATIVE) if("ling") possible_antags = get_players_for_role(BE_CHANGELING) var/list/unsuitable_players = list() for(var/datum/mind/player in possible_antags) if(player && (player.assigned_role == "Cyborg" || player.assigned_role == "AI")) unsuitable_players |= player if(unsuitable_players.len) possible_antags -= unsuitable_players if("tater") possible_antags = get_players_for_role(BE_TRAITOR) if("wiz") possible_antags = get_players_for_role(BE_WIZARD) if("ninja") possible_antags = get_players_for_role(BE_NINJA) if("vox") possible_antags = get_players_for_role(BE_RAIDER) if("slug") possible_antags = get_players_for_role(BE_ALIEN) if("cult") possible_antags = get_players_for_role(BE_CULTIST) var/list/filtered_antags = list() if(possible_antags) for(var/datum/mind/candidate in possible_antags) if(!(candidate in already_assigned_candidates)) filtered_antags |= candidate already_assigned_candidates |= candidate if(filtered_antags && islist(filtered_antags)) return filtered_antags else return list(filtered_antags) //Spawning procs for the various antag types. //A LOT OF THE FOLLOWING IS COPYPASTED FROM OTHER MODES AND NEEDS //TO BE FIXED UP. NINJA, NUKE AND CULT IN PARTICULAR ARE FUCKING AWFUL. ~ Z /datum/game_mode/calamity/proc/spawn_syndicate(var/list/candidates) var/obj/effect/landmark/uplinkdevice = locate("landmark*Syndicate-Uplink") var/obj/effect/landmark/nuke_spawn = locate("landmark*Nuclear-Bomb") var/nuke_code = "[rand(10000, 99999)]" var/spawnpos = 1 var/datum/mind/leader = null for(var/datum/mind/player in candidates) syndicates |= player if(spawnpos > synd_spawn.len) spawnpos = 1 player.current.loc = synd_spawn[spawnpos] player.current.real_name = "[syndicate_name()] Operative" spawn(0) NukeNameAssign(player) forge_syndicate_objectives(player) greet_syndicate(player) equip_syndicate(player.current) if(!leader) prepare_syndicate_leader(player, nuke_code) leader = player spawnpos++ update_synd_icons_added(player) update_all_synd_icons() if(uplinkdevice) var/obj/item/device/radio/uplink/U = new(uplinkdevice.loc) if(leader) U.hidden_uplink.uplink_owner = leader U.hidden_uplink.uses = 40 if(nuke_spawn && synd_spawn.len > 0) var/obj/machinery/nuclearbomb/the_bomb = new /obj/machinery/nuclearbomb(nuke_spawn.loc) the_bomb.r_code = nuke_code /datum/game_mode/calamity/proc/spawn_changelings(var/list/candidates) for(var/datum/mind/player in candidates) changelings |= player grant_changeling_powers(player.current) player.special_role = "Changeling" if(!config.objectives_disabled) player.objectives += new /datum/objective/escape() player.objectives += new /datum/objective/survive() show_objectives(player) greet_changeling(player) /datum/game_mode/calamity/proc/spawn_traitors(var/list/candidates) for(var/datum/mind/player in candidates) traitors |= player if(!config.objectives_disabled) player.objectives += new /datum/objective/escape() player.objectives += new /datum/objective/survive() show_objectives(player) finalize_traitor(player) greet_traitor(player) /datum/game_mode/calamity/proc/spawn_cabal(var/list/candidates) for(var/datum/mind/player in candidates) wizards |= player if(!config.objectives_disabled) player.objectives += new /datum/objective/escape() player.objectives += new /datum/objective/survive() show_objectives(player) player.current.loc = pick(wizardstart) equip_wizard(player.current) name_wizard(player.current) greet_wizard(player) /datum/game_mode/calamity/proc/spawn_ninja(var/list/candidates) //I hate that this is necessary. ~Z for(var/obj/effect/landmark/L in landmarks_list) if(L.name == "carpspawn") ninjastart.Add(L) for(var/datum/mind/player in candidates) ninjas |= player player.current << browse(null, "window=playersetup") player.current = create_space_ninja(pick(ninjastart)) player.current.ckey = player.key if(player.current && !(istype(player.current,/mob/living/carbon/human))) return 0 //Ninja intro crawl goes here. if(!config.objectives_disabled) player.objectives += new /datum/objective/ninja_highlander() player.objectives += new /datum/objective/survive() show_objectives(player) //Ninja objective announcement goes here. //Set ninja internals. var/mob/living/carbon/human/N = player.current N.internal = N.s_store N.internals.icon_state = "internal1" /datum/game_mode/calamity/proc/spawn_vox_raiders(var/list/candidates) //Create objectives. var/list/raid_objectives = forge_vox_objectives() //Create raiders. for(var/datum/mind/player in candidates) raiders |= player //Place them on the shuttle. var/index = 1 if(index > raider_spawn.len) index = 1 player.current.loc = raider_spawn[index] index++ if(!config.objectives_disabled) player.objectives = raid_objectives //Equip them. create_vox(player) greet_vox(player) player.current << "Your crew is transporting cortical stacks and critical resources back to the Shoal.\ No delay or concession can be tolerated. Even putting holes in the station pales in comparison to failure." spawn (rand(waittime_l, waittime_h)) send_intercept() ..() /datum/game_mode/calamity/proc/spawn_borers(var/list/candidates) var/list/possible_hosts = list() for(var/mob/living/carbon/human/H in mob_list) if(!(H.species.flags & IS_SYNTHETIC)) possible_hosts |= H spawn(10) for(var/datum/mind/player in candidates) if(!possible_hosts || possible_hosts.len) break borers |= player var/mob/living/carbon/human/target_host = pick(possible_hosts) possible_hosts -= target_host var/mob/living/simple_animal/borer/roundstart/B = new(target_host) player.current = B B.mind = player B.key = player.key player.assigned_role = "Cortical Borer" player.special_role = "Cortical Borer" B.host = target_host B.host_brain.name = target_host.name B.host_brain.real_name = target_host.real_name var/datum/organ/external/head = target_host.get_organ("head") head.implants += B player.current << "\blue You are a cortical borer! You are a brain slug that worms its way \ into the head of its victim, lurking out of sight until it needs to take control." player.current << "You can speak to your victim with say, to other borers with say ;, and use your Alien tab for abilities." if(!config.objectives_disabled) player.objectives += new /datum/objective/borer_survive() player.objectives += new /datum/objective/borer_reproduce() player.objectives += new /datum/objective/escape() show_objectives(player) /datum/game_mode/calamity/proc/spawn_cultists(var/list/candidates) //Prune the list. var/list/jobs_to_skip = list("Chaplain","AI", "Cyborg", "Lawyer", "Head of Security", "Captain") if(config.protect_roles_from_antagonist) jobs_to_skip += list("Security Officer", "Warden", "Detective") //Make cult objectives. var/cult_objectives = list() cult_objectives += new /datum/objective/cult_summon() //Actually spawn cultists. for(var/datum/mind/player in candidates) for(var/job in jobs_to_skip) if(player.assigned_role == job) continue cult |= player equip_cultist(player.current) grant_runeword(player.current) update_cult_icons_added(player) player.current << "\blue You are a member of the cult! Your dark masters have sent you forth to serve their vile will." player.current << "\red This station sails above a weeping tear in the Cosmos. Bring the Geometer of Blood forth." if(!config.objectives_disabled) for(var/datum/objective/O in cult_objectives) player.objectives += O player.objectives += new /datum/objective/escape() player.objectives += new /datum/objective/survive() show_objectives(player) player.special_role = "Cultist"