From dfa53390dfda9e4b967d55ef346658b4d34f0f68 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:12:26 -0600 Subject: [PATCH] Update nuclear.dm --- code/game/gamemodes/nuclear/nuclear.dm | 306 +++++++++++++++++++------ 1 file changed, 242 insertions(+), 64 deletions(-) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index f131046cac..94c372ef23 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -1,3 +1,7 @@ +/datum/game_mode + var/list/datum/mind/syndicates = list() + var/nukeops_lastname = "" + /datum/game_mode/nuclear name = "nuclear emergency" config_tag = "nuclear" @@ -14,10 +18,11 @@ Crew: Defend the nuclear authentication disk and ensure that it leaves with you on the emergency shuttle." var/const/agents_possible = 5 //If we ever need more syndicate agents. - var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer! - var/list/pre_nukeops = list() - var/datum/team/nuclear/nuke_team + var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer! + var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station + var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level + var/list/pre_nukeops = list() /datum/game_mode/nuclear/pre_setup() var/n_agents = min(round(num_players() / 10), antag_candidates.len, agents_possible) @@ -28,23 +33,120 @@ new_op.special_role = "Nuclear Operative" log_game("[new_op.key] (ckey) has been selected as a nuclear operative") return TRUE + +//////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// +/datum/game_mode/proc/update_synd_icons_added(datum/mind/synd_mind) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.join_hud(synd_mind.current) + set_antag_hud(synd_mind.current, "synd") + +/datum/game_mode/proc/update_synd_icons_removed(datum/mind/synd_mind) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.leave_hud(synd_mind.current) + set_antag_hud(synd_mind.current, null) + //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// /datum/game_mode/nuclear/post_setup() - //Assign leader - var/datum/mind/leader_mind = pre_nukeops[1] - var/datum/antagonist/nukeop/L = leader_mind.add_antag_datum(/datum/antagonist/nukeop/leader) - nuke_team = L.nuke_team - //Assign the remaining operatives - for(var/i = 2 to pre_nukeops.len) - var/datum/mind/nuke_mind = pre_nukeops[i] - nuke_mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team) + var/nuke_code = random_nukecode() + var/agent_number = 1 + var/datum/mind/leader = pick(pre_nukeops) + syndicates += pre_nukeops + for(var/i = 1 to pre_nukeops.len) + var/datum/mind/op = pre_nukeops[i] + + forge_syndicate_objectives(op) + greet_syndicate(op) + equip_syndicate(op.current) + + if(nuke_code) + op.store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) + to_chat(op.current, "The nuclear authorization code is: [nuke_code]") + + if(op == leader) + op.current.forceMove(pick(GLOB.nukeop_leader_start)) + prepare_syndicate_leader(op, nuke_code) + else + op.current.forceMove(GLOB.nukeop_start[((i - 1) % GLOB.nukeop_start.len) + 1]) + op.current.real_name = "[syndicate_name()] Operative #[agent_number++]" + + update_synd_icons_added(op) + op.current.playsound_local(get_turf(op.current), 'sound/ambience/antag/ops.ogg',100,0) + + var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list + if(nuke) + nuke.r_code = nuke_code return ..() +/datum/game_mode/proc/prepare_syndicate_leader(datum/mind/synd_mind, nuke_code) + var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") + addtimer(CALLBACK(src, .proc/nuketeam_name_assign, synd_mind), 1) + synd_mind.current.real_name = "[syndicate_name()] [leader_title]" + to_chat(synd_mind.current, "You are the Syndicate [leader_title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") + to_chat(synd_mind.current, "If you feel you are not up to this task, give your ID to another operative.") + to_chat(synd_mind.current, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") + + var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge + synd_mind.current.put_in_hands(challenge, TRUE) + + var/static/id_cache = typecacheof(/obj/item/card/id) + var/list/foundIDs = typecache_filter_list(synd_mind.current.GetAllContents(), id_cache) + if(foundIDs.len) + for(var/i in 1 to foundIDs.len) + var/obj/item/card/id/ID = foundIDs[i] + ID.name = "lead agent card" + ID.access += ACCESS_SYNDICATE_LEADER + else + message_admins("Warning: Nuke Ops spawned without access to leave their spawn area!") + + var/obj/item/device/radio/headset/syndicate/alt/A = locate() in synd_mind.current + if(A) + A.command = TRUE + + if(nuke_code) + var/obj/item/paper/P = new + P.info = "The nuclear authorization code is: [nuke_code]" + P.name = "nuclear bomb code" + var/mob/living/carbon/human/H = synd_mind.current + H.put_in_hands(P, TRUE) + H.update_icons() + else + nuke_code = "code will be provided later" + return + +/datum/game_mode/proc/nuketeam_name_assign(datum/mind/synd_mind) + nukeops_lastname = nukelastname(synd_mind.current) + NukeNameAssign(nukeops_lastname, syndicates) + + +/datum/game_mode/proc/forge_syndicate_objectives(datum/mind/syndicate) + var/datum/objective/nuclear/syndobj = new + syndobj.owner = syndicate + syndicate.objectives += syndobj + + +/datum/game_mode/proc/greet_syndicate(datum/mind/syndicate, you_are=1) + if(you_are) + to_chat(syndicate.current, "You are a [syndicate_name()] agent!") + syndicate.announce_objectives() + +/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob, telecrystals = TRUE) + synd_mob.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs + + if(telecrystals) + synd_mob.equipOutfit(/datum/outfit/syndicate) + else + synd_mob.equipOutfit(/datum/outfit/syndicate/no_crystals) + return TRUE + /datum/game_mode/nuclear/OnNukeExplosion(off_station) ..() nukes_left-- + var/obj/docking_port/mobile/Shuttle = SSshuttle.getShuttle("syndicate") + syndies_didnt_escape = (Shuttle && (Shuttle.z == ZLEVEL_CENTCOM || Shuttle.z == ZLEVEL_TRANSIT)) ? 0 : 1 + nuke_off_station = off_station /datum/game_mode/nuclear/check_win() if (nukes_left == 0) @@ -52,8 +154,8 @@ return ..() /datum/game_mode/proc/are_operatives_dead() - for(var/datum/mind/operative_mind in get_antagonists(/datum/antagonist/nukeop)) - if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD)) + for(var/datum/mind/operative_mind in syndicates) + if(ishuman(operative_mind.current) && (operative_mind.current.stat!=2)) return FALSE return TRUE @@ -62,55 +164,142 @@ return replacementmode.check_finished() if((SSshuttle.emergency.mode == SHUTTLE_ENDGAME) || station_was_nuked) return TRUE - if(nuke_team.operatives_dead()) + if(are_operatives_dead()) var/obj/machinery/nuclearbomb/N pass(N) //suppress unused warning if(N.bomb_set) //snaaaaaaaaaake! It's not over yet! return FALSE //its a static var btw ..() -/datum/game_mode/nuclear/set_round_result() +/datum/game_mode/nuclear/declare_completion() + var/disk_rescued = 1 + for(var/obj/item/disk/nuclear/D in GLOB.poi_list) + if(!D.onCentCom()) + disk_rescued = 0 + break + var/crew_evacuated = (SSshuttle.emergency.mode == SHUTTLE_ENDGAME) + + if(nuke_off_station == NUKE_SYNDICATE_BASE) + SSticker.mode_result = "loss - syndicate nuked - disk secured" + to_chat(world, "Humiliating Syndicate Defeat") + to_chat(world, "The crew of [station_name()] gave [syndicate_name()] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!") + + SSticker.news_report = NUKE_SYNDICATE_BASE + + else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) + SSticker.mode_result = "win - syndicate nuke" + to_chat(world, "Syndicate Major Victory!") + to_chat(world, "[syndicate_name()] operatives have destroyed [station_name()]!") + + SSticker.news_report = STATION_NUKED + + else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) + SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" + to_chat(world, "Total Annihilation") + to_chat(world, "[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!") + + SSticker.news_report = STATION_NUKED + + else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape) + SSticker.mode_result = "halfwin - blew wrong station" + to_chat(world, "Crew Minor Victory") + to_chat(world, "[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!") + + SSticker.news_report = NUKE_MISS + + else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) + SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" + to_chat(world, "[syndicate_name()] operatives have earned Darwin Award!") + to_chat(world, "[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!") + + SSticker.news_report = NUKE_MISS + + else if ((disk_rescued || SSshuttle.emergency.mode != SHUTTLE_ENDGAME) && are_operatives_dead()) + SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" + to_chat(world, "Crew Major Victory!") + to_chat(world, "The Research Staff has saved the disk and killed the [syndicate_name()] Operatives") + + SSticker.news_report = OPERATIVES_KILLED + + else if (disk_rescued) + SSticker.mode_result = "loss - evacuation - disk secured" + to_chat(world, "Crew Major Victory") + to_chat(world, "The Research Staff has saved the disk and stopped the [syndicate_name()] Operatives!") + + SSticker.news_report = OPERATIVES_KILLED + + else if (!disk_rescued && are_operatives_dead()) + SSticker.mode_result = "halfwin - evacuation - disk not secured" + to_chat(world, "Neutral Victory!") + to_chat(world, "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!") + + SSticker.news_report = OPERATIVE_SKIRMISH + + else if (!disk_rescued && crew_evacuated) + SSticker.mode_result = "halfwin - detonation averted" + to_chat(world, "Syndicate Minor Victory!") + to_chat(world, "[syndicate_name()] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!") + + SSticker.news_report = OPERATIVE_SKIRMISH + + else if (!disk_rescued && !crew_evacuated) + SSticker.mode_result = "halfwin - interrupted" + to_chat(world, "Neutral Victory") + to_chat(world, "Round was mysteriously interrupted!") + + SSticker.news_report = OPERATIVE_SKIRMISH + ..() - var result = nuke_team.get_result() - switch(result) - if(NUKE_RESULT_FLUKE) - SSticker.mode_result = "loss - syndicate nuked - disk secured" - SSticker.news_report = NUKE_SYNDICATE_BASE - if(NUKE_RESULT_NUKE_WIN) - SSticker.mode_result = "win - syndicate nuke" - SSticker.news_report = STATION_NUKED - if(NUKE_RESULT_NOSURVIVORS) - SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" - SSticker.news_report = STATION_NUKED - if(NUKE_RESULT_WRONG_STATION) - SSticker.mode_result = "halfwin - blew wrong station" - SSticker.news_report = NUKE_MISS - if(NUKE_RESULT_WRONG_STATION_DEAD) - SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" - SSticker.news_report = NUKE_MISS - if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) - SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" - SSticker.news_report = OPERATIVES_KILLED - if(NUKE_RESULT_CREW_WIN) - SSticker.mode_result = "loss - evacuation - disk secured" - SSticker.news_report = OPERATIVES_KILLED - if(NUKE_RESULT_DISK_LOST) - SSticker.mode_result = "halfwin - evacuation - disk not secured" - SSticker.news_report = OPERATIVE_SKIRMISH - if(NUKE_RESULT_DISK_STOLEN) - SSticker.mode_result = "halfwin - detonation averted" - SSticker.news_report = OPERATIVE_SKIRMISH - else - SSticker.mode_result = "halfwin - interrupted" - SSticker.news_report = OPERATIVE_SKIRMISH + return /datum/game_mode/nuclear/generate_report() return "One of Central Command's trading routes was recently disrupted by a raid carried out by the Gorlex Marauders. They seemed to only be after one ship - a highly-sensitive \ transport containing a nuclear fission explosive, although it is useless without the proper code and authorization disk. While the code was likely found in minutes, the only disk that \ can activate this explosive is on your station. Ensure that it is protected at all times, and remain alert for possible intruders." +/datum/game_mode/proc/auto_declare_completion_nuclear() + if( syndicates.len || (SSticker && istype(SSticker.mode, /datum/game_mode/nuclear)) ) + var/text = "
The syndicate operatives were:" + var/purchases = "" + var/TC_uses = 0 + for(var/datum/mind/syndicate in syndicates) + text += printplayer(syndicate) + for(var/datum/component/uplink/H in GLOB.uplinks) + if(H.purchase_log) + purchases += H.purchase_log.generate_render() + else + stack_trace("WARNING: Uplink with no purchase_log in nuclear mode! Owner: [H.owner]") + text += "
" + text += "(Syndicates used [TC_uses] TC) [purchases]" + if(TC_uses == 0 && station_was_nuked && !are_operatives_dead()) + text += "[icon2html('icons/badass.dmi', world, "badass")]" + to_chat(world, text) + return TRUE + + +/proc/nukelastname(mob/M) //--All praise goes to NEO|Phyte, all blame goes to DH, and it was Cindi-Kate's idea. Also praise Urist for copypasta ho. + var/randomname = pick(GLOB.last_names) + var/newname = copytext(sanitize(input(M,"You are the nuke operative [pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")]. Please choose a last name for your family.", "Name change",randomname)),1,MAX_NAME_LEN) + + if (!newname) + newname = randomname + + else + if (newname == "Unknown" || newname == "floor" || newname == "wall" || newname == "rwall" || newname == "_") + to_chat(M, "That name is reserved.") + return nukelastname(M) + + return capitalize(newname) + +/proc/NukeNameAssign(lastname,list/syndicates) + for(var/datum/mind/synd_mind in syndicates) + var/mob/living/carbon/human/H = synd_mind.current + synd_mind.name = H.dna.species.random_name(H.gender,0,lastname) + synd_mind.current.real_name = synd_mind.name + return + /proc/is_nuclear_operative(mob/M) - return M && istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/nukeop) + return M && istype(M) && M.mind && SSticker && SSticker.mode && M.mind in SSticker.mode.syndicates /datum/outfit/syndicate name = "Syndicate Operative - Basic" @@ -123,28 +312,18 @@ l_pocket = /obj/item/pinpointer/nuke/syndicate id = /obj/item/card/id/syndicate belt = /obj/item/gun/ballistic/automatic/pistol - backpack_contents = list(/obj/item/storage/box/syndie=1,\ - /obj/item/kitchen/knife/combat/survival) + backpack_contents = list(/obj/item/storage/box/syndie=1) var/tc = 25 - var/command_radio = FALSE - - -/datum/outfit/syndicate/leader - name = "Syndicate Leader - Basic" - id = /obj/item/card/id/syndicate/nuke_leader - r_hand = /obj/item/device/nuclear_challenge - command_radio = TRUE /datum/outfit/syndicate/no_crystals tc = 0 + /datum/outfit/syndicate/post_equip(mob/living/carbon/human/H) var/obj/item/device/radio/R = H.ears - R.set_frequency(FREQ_SYNDICATE) - R.freqlock = TRUE - if(command_radio) - R.command = TRUE + R.set_frequency(GLOB.SYND_FREQ) + R.freqlock = 1 if(tc) var/obj/item/device/radio/uplink/nuclear/U = new(H, H.key, tc) @@ -169,5 +348,4 @@ r_hand = /obj/item/gun/ballistic/automatic/shotgun/bulldog backpack_contents = list(/obj/item/storage/box/syndie=1,\ /obj/item/tank/jetpack/oxygen/harness=1,\ - /obj/item/gun/ballistic/automatic/pistol=1,\ - /obj/item/kitchen/knife/combat/survival) + /obj/item/gun/ballistic/automatic/pistol=1)