const static float NOTIFICATION_FADE_TIME = 3.0; //! DEPRECATED (moved into NotificationSystem) enum NotificationType { FRIEND_CONNECTED, INVITE_FAIL_SAME_SERVER, JOIN_FAIL_GET_SESSION, CONNECT_FAIL_GENERIC, DISCONNECTED, GENERIC_ERROR, //Please add types before this item NOTIFICATIONS_END } class NotificationRuntimeData { ref NotificationData m_StaticData; float m_NotificationTime; float m_TimeRemaining; string m_DetailText; void NotificationRuntimeData(float time, NotificationData data, string detail_text) { m_NotificationTime = time; m_TimeRemaining = time; m_StaticData = data; if (detail_text != "") m_DetailText = detail_text; else m_DetailText = m_StaticData.m_DescriptionText; } float GetTime() { return m_NotificationTime; } float GetRemainingTime() { return m_TimeRemaining; } string GetIcon() { return m_StaticData.m_Icon; } string GetTitleText() { return m_StaticData.m_TitleText; } string GetDetailText() { return m_DetailText; } void UpdateRemainingTime(float updateInterval) { m_TimeRemaining -= updateInterval; } //! DEPRECATED void SetTime(float time); } class NotificationSystem { const int DEFAULT_TIME_DISPLAYED = 10; const float NOTIFICATION_FADE_TIME = 3.0; protected static const string JSON_FILE_PATH = "scripts/data/notifications.json"; protected static const int MAX_NOTIFICATIONS = 5; private static const float UPDATE_INTERVAL_THRESHOLD = 1.0; protected static ref NotificationSystem m_Instance; protected ref array m_TimeArray; protected ref array m_DeferredArray; protected ref map m_DataArray; protected float m_TimeElapsed; ref ScriptInvoker m_OnNotificationAdded = new ScriptInvoker(); ref ScriptInvoker m_OnNotificationRemoved = new ScriptInvoker(); static void InitInstance() { if (!m_Instance) { m_Instance = new NotificationSystem(); m_Instance.LoadNotificationData(); } } static void CleanupInstance() { m_Instance = null; } static NotificationSystem GetInstance() { return m_Instance; } void NotificationSystem() { m_TimeElapsed = 0.0; m_TimeArray = new array(); m_DeferredArray = new array(); } /** \brief Send custom notification to player from server @param player the target player to send notification to @param show_time amount of time this notification is displayed @param title_text the title text that is displayed in the notification @param detail_text additional text that can be added to the notification under the title - will not display additional text if not set @param icon the icon that is displayed in the notification - will use default icon if not set */ static void SendNotificationToPlayerExtended(Man player, float show_time, string title_text, string detail_text = "", string icon = "") { if (player) { SendNotificationToPlayerIdentityExtended(player.GetIdentity(), show_time, title_text, detail_text, icon); } } /** \brief Send custom notification to player identity from server @param player the target player to send notification to - if null, will send to all players @param show_time amount of time this notification is displayed @param title_text the title text that is displayed in the notification @param detail_text additional text that can be added to the notification under the title - will not display additional text if not set @param icon the icon that is displayed in the notification - will use default icon if not set */ static void SendNotificationToPlayerIdentityExtended(PlayerIdentity player, float show_time, string title_text, string detail_text = "", string icon = "") { ScriptRPC rpc = new ScriptRPC(); rpc.Write(show_time); rpc.Write(title_text); rpc.Write(detail_text); rpc.Write(icon); rpc.Send(null, ERPCs.RPC_SEND_NOTIFICATION_EXTENDED, true, player); } /** \brief Send notification from default types to player from server @param player the target player to send notification to @param type the type of notification to send - these can be viewed in /Scripts/Data/Notifications.json @param show_time amount of time this notification is displayed @param detail_text additional text that can be added to the notification under the title - will not display additional text if not set */ static void SendNotificationToPlayer(Man player, NotificationType type, float show_time, string detail_text = "") { if (player) { SendNotificationToPlayerIdentity(player.GetIdentity(), type, show_time, detail_text); } } /** \brief Send notification from default types to player identity from server @param player the target player to send notification to - if null, will send to all players @param type the type of notification to send - these can be viewed in /Scripts/Data/Notifications.json @param show_time amount of time this notification is displayed @param detail_text additional text that can be added to the notification under the title - will not display additional text if not set */ static void SendNotificationToPlayerIdentity( PlayerIdentity player, NotificationType type, float show_time, string detail_text = "" ) { ScriptRPC rpc = new ScriptRPC(); rpc.Write(type); rpc.Write(show_time); rpc.Write(detail_text); rpc.Send(null, ERPCs.RPC_SEND_NOTIFICATION, true, player); } /** \brief Send notification from default types to local player @param type the type of notification to send - these can be viewed in /Scripts/Data/Notifications.json @param show_time amount of time this notification is displayed @param detail_text additional text that can be added to the notification under the title - will not display additional text if not set */ static void AddNotification(NotificationType type, float show_time, string detail_text = "") { if (m_Instance.m_TimeArray.Count() < MAX_NOTIFICATIONS) { NotificationRuntimeData data = new NotificationRuntimeData(show_time, m_Instance.GetNotificationData(type), detail_text); m_Instance.m_TimeArray.Insert(data); m_Instance.m_OnNotificationAdded.Invoke(data); } else { NotificationRuntimeData dataDeferred = new NotificationRuntimeData(show_time, m_Instance.GetNotificationData(type), detail_text); m_Instance.m_DeferredArray.Insert(dataDeferred); } } /** \brief Send custom notification from to local player @param show_time amount of time this notification is displayed @param title_text the title text that is displayed in the notification @param detail_text additional text that can be added to the notification under the title - will not display additional text if not set @param icon the icon that is displayed in the notification - will use default icon if not set */ static void AddNotificationExtended(float show_time, string title_text, string detail_text = "", string icon = "") { if (m_Instance.m_TimeArray.Count() < MAX_NOTIFICATIONS) { NotificationData tempData = new NotificationData(icon, title_text); NotificationRuntimeData data = new NotificationRuntimeData(show_time, tempData, detail_text); m_Instance.m_TimeArray.Insert(data); m_Instance.m_OnNotificationAdded.Invoke(data); } else { NotificationData tempDataDeferred = new NotificationData(icon, title_text); NotificationRuntimeData dataDeferred = new NotificationRuntimeData(show_time, tempDataDeferred, detail_text); m_Instance.m_DeferredArray.Insert(dataDeferred); } } static void Update(float timeslice) { if (m_Instance) { if (g_Game.GetGameState() != DayZGameState.IN_GAME && g_Game.GetGameState() != DayZGameState.MAIN_MENU) return; m_Instance.m_TimeElapsed += timeslice; if (m_Instance.m_TimeElapsed >= UPDATE_INTERVAL_THRESHOLD) { array expiredNotifications = new array(); foreach (NotificationRuntimeData visibleNotificationData : m_Instance.m_TimeArray) { if (visibleNotificationData.GetRemainingTime() <= 0.0) expiredNotifications.Insert(visibleNotificationData); else visibleNotificationData.UpdateRemainingTime(UPDATE_INTERVAL_THRESHOLD); } foreach (NotificationRuntimeData expiredNotificationData : expiredNotifications) { m_Instance.m_OnNotificationRemoved.Invoke(expiredNotificationData); m_Instance.m_TimeArray.RemoveItem(expiredNotificationData); if (m_Instance.m_DeferredArray.Count() > 0) { int count = m_Instance.m_DeferredArray.Count(); NotificationRuntimeData deferredNotificationData = m_Instance.m_DeferredArray.Get(count - 1); m_Instance.m_TimeArray.Insert(deferredNotificationData); m_Instance.m_OnNotificationAdded.Invoke(deferredNotificationData); m_Instance.m_DeferredArray.Remove(count - 1); } } m_Instance.m_TimeElapsed = 0; } } } protected NotificationData GetNotificationData(NotificationType type) { if (m_DataArray.Contains(type)) return m_DataArray.Get(type); return null; } static void LoadNotificationData() { map dataArray; m_Instance.m_DataArray = new map(); string errorMessage; if (!JsonFileLoader>.LoadFile(JSON_FILE_PATH, dataArray, errorMessage)) ErrorEx(errorMessage); m_Instance.m_DataArray.Copy(dataArray); array notificationTypes = new array(); NotificationType notificationType = 0; while (notificationType != NotificationType.NOTIFICATIONS_END) { notificationTypes.Insert(notificationType); notificationType++; } for (int i = 0; i < m_Instance.m_DataArray.Count(); ++i) { notificationTypes.RemoveItem(m_Instance.m_DataArray.GetKey(i)); } if (notificationTypes.Count() > 0) { foreach (NotificationType notificationType2 : notificationTypes) { NotificationData notificationData = new NotificationData( "please_add_an_icon", "please_add_a_title", "optional_description", ); m_Instance.m_DataArray.Insert(notificationType2, notificationData); } if (!JsonFileLoader>.SaveFile(JSON_FILE_PATH, m_Instance.m_DataArray, errorMessage)) ErrorEx(errorMessage); } } }