using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Numerics; using System.Security.Cryptography; namespace F4SD.Gamification.Services { public class LevelService { private static readonly List<(int MinimumTotalExperiencePoints, int Level)> _experienceToLevelMap = new() { (0,1), (1128,2), (2400,3), (3832,4), (5440,5), (7240,6), (9248,7), (11480,8), (13952,9), (16680,10), (19680,11), (22968,12), (26560,13), (30472,14), (34720,15), (39320,16), (44288,17), (49640,18), (55392,19), (61560,20), (68160,21), (75208,22), (82720,23), (90712,24), (99200,25), (108200,26), (117728,27), (127800,28), (138432,29), (149640,30), (161440,31), (173848,32), (186880,33), (200552,34), (214880,35), (229880,36), (245568,37), (261960,38), (279072,39), (296920,40), (315520,41), (334888,42), (355040,43), (375992,44), (397760,45), (420360,46), (443808,47), (468120,48), (493312,49), (519400,50), }; private int _totalExperiencePoints = 0; private int _currentExperiencePoints; private int _level; internal void InitializeAction(CockpitAction action) { AddExperiencePoints(GetExperiencePointsFor(action), true); } internal void TrackAction(CockpitAction type, params object[] args) { AddExperiencePoints(GetExperiencePointsFor(type)); } private void AddExperiencePoints(int points, bool isInitialization = false) { _totalExperiencePoints += points; UpdateLevel(isInitialization); UpdateCurrentExperiencePoints(); if (isInitialization) return; ExperiencePointsChanged?.Invoke(null, new LevelEventArgs() { CurrentLevel = _level, LevelTitle = GetTitle(_level), CurrentXp = _currentExperiencePoints, XpRequiredForLevelUp = GetXpRequiredForNextLevel() }); } private void UpdateCurrentExperiencePoints() { int xpForCurrentLevel = _experienceToLevelMap.FirstOrDefault(mapEntry => mapEntry.Level == _level).MinimumTotalExperiencePoints; _currentExperiencePoints = _totalExperiencePoints - xpForCurrentLevel; } private void UpdateLevel(bool isInitialization) { int previousLevel = _level; _level = _experienceToLevelMap.FirstOrDefault(mapEntry => _totalExperiencePoints < mapEntry.MinimumTotalExperiencePoints).Level - 1; if (!isInitialization && previousLevel < _level) LevelChanged?.Invoke(null, new LevelEventArgs() { CurrentLevel = _level, LevelTitle = GetTitle(_level) }); } private int GetXpRequiredForNextLevel() { int totalXpForNextLevel = _experienceToLevelMap.FirstOrDefault(mapEntry => mapEntry.Level == _level + 1).MinimumTotalExperiencePoints; int totalXpForCurrentLevel = _experienceToLevelMap.FirstOrDefault(mapEntry => mapEntry.Level == _level).MinimumTotalExperiencePoints; return totalXpForNextLevel - totalXpForCurrentLevel; } private int GetExperiencePointsFor(CockpitAction action) { switch (action) { case CockpitAction.CaseOpened: break; case CockpitAction.CaseClosed: return 10; case CockpitAction.QuickActionExecuted: return 20; case CockpitAction.CopyTemplateClicked: return 5; case CockpitAction.BuiltDirectConnection: break; case CockpitAction.AddNotes: break; case CockpitAction.StartRemoteConnection: return 50; default: break; } return 1; } private static string GetTitle(int level) { switch (level) { case <= 5: return "Support Trainee"; case <= 10: return "Response Assistant"; case <= 15: return "Service Aider"; case <= 20: return "Ticket Resolver"; case <= 25: return "Customer Navigator"; case <= 30: return "Incident Coordinator"; case <= 35: return "IT Guy"; case <= 40: return "Support Specialist"; case <= 45: return "Service Mentor"; case <= 49: return "Operations Lead"; case > 49: return "Ticket Titan"; } } public static event EventHandler ExperiencePointsChanged; public static event EventHandler LevelChanged; } }