This repository has been archived on 2025-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
project-undercover/Project Undercover/Assets/Scripts/MissionTracker.cs

290 lines
9.7 KiB
C#
Executable file

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MissionTracker : Photon.PunBehaviour
{
const string COMPLETED_TEXT = "(COMPLETED) ";
const string MISSION_LOG_TEXT = "Mission Log: _";
const string GUARD_MISSION_STATEMENT =
"Greetings, Overseer,\n\n" +
"You are tasked with ensuring the security of this peace summit. We know that " +
"various foreign forces are determined to undermine our progress here, but you " +
"must make sure they do not succeed. Several enemies of the state will most " +
"likely be infiltrating the party tonight, and it is your task to watch for " +
"suspicious behavior and arrest these agents.\n\n" +
"The security of our great nation rests in your hands. Good luck.";
const string SPY_MISSION_STATEMENT =
"Greetings, Agent,\n\n" +
"You are tasked with infiltrating the party of Tel Nikiri, the tyrant dictator of " +
"the nation Rhaedoria. Once there, you must perform several covert operations to " +
"destabilize the political climate enough to bring freedom to this oppressed country.\n\n" +
"As always, should you be caught or killed, the Secretary will disavow any knowledge " +
"of your actions. Good luck.";
const int MAX_GUARD_POINTS = 5;
const float GUARD_NOTIFICATION_DELAY = 5.0f;
const float GUARD_NOTIFICATION_TIME = 10.0f;
const float MISSION_NOTIFICATION_TIME = 10.0f;
private static MissionTracker mSingleton;
public Text spyMissionLogText;
public GameObject guardNotificationPanel;
public Text guardNotificationText;
private IDictionary<string, Mission> mMissionLog; // map interaction to mission
private int mCompletedMissions;
private int mGuardPoints;
private int mGuardIncorrectGuesses;
private class Mission
{
private string mAlertText; // text shown to overseers after mission completes
private string mDescription; // description of the mission for agents
public string AlertText { get { return mAlertText; } }
public bool Completed { get; set; }
public string Description { get { return mDescription; } }
public Mission(string description, string alertText)
{
mAlertText = alertText;
mDescription = description;
Completed = false;
}
}
/**
* The Singleton instance of the MissionTracker.
*/
public static MissionTracker Singleton { get { return mSingleton; } }
public static bool IsGuard { get; set; }
/**
* Guard caught a spy.
*/
public void CaughtAgent(int agentId)
{
photonView.RPC("CaughtAgentRPC", PhotonTargets.All, agentId);
}
/**
* Guard caught a partygoer and must be punished.
*/
public void CaughtIncorrect()
{
photonView.RPC("CaughtIncorrectRPC", PhotonTargets.All);
}
/**
* Complete a mission, maybe.
*/
public void CompleteMission(string interactionName)
{
// if the interactionName is invalid, cry I guess
if (!mMissionLog.ContainsKey(interactionName))
{
Debug.LogError("Invalid interactionName passed to MissionTracker: " + interactionName);
return;
}
// grab the mission - if it's already complete, do nothing
Mission m = mMissionLog[interactionName];
if (m.Completed)
{
return;
}
// mark it as completed, then update the score and UI
photonView.RPC("CompleteMissionRPC", PhotonTargets.All, interactionName);
}
/**
* Initialize the MissionTracker with all missions.
*/
void Start()
{
// set the singleton
if (mSingleton)
{
Debug.Log("Multiple MissionTrackers in scene - please limit to one.");
}
mSingleton = this;
// populate missions and set initial values
mMissionLog = new Dictionary<string, Mission>();
mCompletedMissions = 0;
mGuardPoints = 0;
mGuardIncorrectGuesses = 0;
/*mMissionLog["statue_swap"] = new Mission(
"Replace the marked statue with a bugged replica.",
"We're picking up some electromagnetic interference. " +
"Enemy forces have planted listening devices somewhere on the premises!"
);*/
mMissionLog["HideMessageInBookshelf"] = new Mission(
"Plant critical intelligence in the designated book.",
"One of the staff saw someone suspicious over by the bookcases. " +
"The enemy moves among us."
);
mMissionLog["BugBust"] = new Mission(
"Plant a bug on the bust.",
"One of the staff saw someone suspicious over by the bookcases. " +
"The enemy moves among us."
);
mMissionLog["CheckPlant"] = new Mission(
"Check for secrets hidden in the plant.",
"One of the staff saw someone suspicious over by the bookcases. " +
"The enemy moves among us."
);
/*mMissionLog["bathroom_kill"] = new Mission(
"Assassinate Knight-Captain Brystol in the bathroom.",
"Our men found Knight-Captain Brystol dead in the bathroom. " +
"The enemy must be stopped!"
);*/
/*mMissionLog["npc_dance"] = new Mission(
"Dance with Duchess Castra to distract her momentarily.",
"The peace talks progress poorly. Duchess Castra keeps getting distracted on the dance floor. " +
"Could this be a strategy of our enemies?"
);*/
mMissionLog["TellSecret"] = new Mission(
"Trade intelligence with another spy at the party.",
"One of our staff members spotted two individuals exchanging a secret. " +
"Enemy infiltrators abound."
);
/*mMissionLog["spike_punch"] = new Mission(
"spike_punch",
"Lower the inhibitions of those in attendance by spiking the punch.",
"Several of our guests have become extremely intoxicated. Our catering staff insist " +
"that the punch was non-alcoholic, so we have determined that this must be the plot of " +
"enemy agents."
);*/
UpdateMissionLog();
StartCoroutine(DisplayMission());
}
/**
* Update the Mission Log UI element.
*/
private void UpdateMissionLog()
{
string text = MISSION_LOG_TEXT;
foreach (KeyValuePair<string, Mission> pair in mMissionLog)
{
text += "\n\n";
if (pair.Value.Completed)
{
text += COMPLETED_TEXT;
}
text += pair.Value.Description;
}
spyMissionLogText.text = text;
}
#region coroutines
IEnumerator DisplayMission()
{
// pause for two seconds
yield return new WaitForSeconds(1.0f);
// set the mission text and render
if (IsGuard)
{
guardNotificationText.text = GUARD_MISSION_STATEMENT;
}
else
{
guardNotificationText.text = SPY_MISSION_STATEMENT;
}
guardNotificationPanel.SetActive(true);
// hide the panel after a certain amount of time
yield return new WaitForSeconds(MISSION_NOTIFICATION_TIME);
guardNotificationPanel.SetActive(false);
}
IEnumerator DisplayNotification(string text)
{
// only display for guards...
if (!IsGuard)
{
yield break;
}
// wait before displaying notification
yield return new WaitForSeconds(GUARD_NOTIFICATION_DELAY);
// set the text and show the panel
guardNotificationText.text = text;
guardNotificationPanel.SetActive(true);
// hide the panel after a certain amount of time
yield return new WaitForSeconds(GUARD_NOTIFICATION_TIME);
guardNotificationPanel.SetActive(false);
yield return null;
}
#endregion
#region rpc
[PunRPC]
void CompleteMissionRPC(string interactionName)
{
if (mCompletedMissions + mGuardIncorrectGuesses >= mMissionLog.Count)
return;
Mission m = mMissionLog[interactionName];
m.Completed = true;
mCompletedMissions++;
float score = mCompletedMissions + mGuardIncorrectGuesses;
ScorePanelController.Singleton.UpdateSpyScore(score / mMissionLog.Count);
StartCoroutine(DisplayNotification(m.AlertText));
UpdateMissionLog();
}
[PunRPC]
void CaughtAgentRPC(int spyId)
{
if (mGuardPoints >= mMissionLog.Count)
return;
mGuardPoints++;
ScorePanelController.Singleton.UpdateGuardScore((float) mGuardPoints / MAX_GUARD_POINTS);
// Get Random NPC
var npcs = GameManager.ActiveManager.GetNpcs();
int randInt = (int)(UnityEngine.Random.value * npcs.Count);
if (PhotonNetwork.isMasterClient)
GameManager.ActiveManager.photonView.RPC("ReplaceNPCWithSpyRPC", PhotonTargets.All, spyId, npcs[randInt].photonView.viewID);
}
[PunRPC]
void CaughtIncorrectRPC()
{
if (mCompletedMissions + mGuardIncorrectGuesses >= MAX_GUARD_POINTS)
return;
mGuardIncorrectGuesses++;
float score = mCompletedMissions + mGuardIncorrectGuesses;
ScorePanelController.Singleton.UpdateSpyScore(score / mMissionLog.Count);
}
#endregion
}