private Dictionary <string, object> GenerateRandomMissionOptions(MissionLocation location, Character character, List <int> missionsDone, Dictionary <int, DateTime> periodicMissions, List <Mission> solvableMissions) { var availabilityDict = new Dictionary <string, object>(); var missionAgent = location.Agent; var missionFilter = new MissionFilter(character, periodicMissions, missionsDone, this, location, _missionDataCache); int[] missionIdsByAgent; if (!_missionDataCache.GetMissionIdsByAgent(missionAgent, out missionIdsByAgent)) { //no random mission defined for this agent return(availabilityDict); } var rndMissionsHere = solvableMissions.Where(m => missionFilter.IsRandomMissionAvailable(m)).ToList(); var counter = 0; foreach (var missionCategory in Enum.GetValues(typeof(MissionCategory)).Cast <MissionCategory>()) { if (rndMissionsHere.All(m => m.missionCategory != missionCategory)) { continue; } //one mission per category if (missionFilter.IsMissionRunningWithThisCategory(missionCategory)) { continue; } for (var missionLevel = 0; missionLevel <= location.maxMissionLevel; missionLevel++) { var oneEntry = new Dictionary <string, object>() { { k.missionCategory, (int)missionCategory }, { k.missionLevel, missionLevel }, { k.oke, 1 }, }; availabilityDict.Add("r" + counter++, oneEntry); } } return(availabilityDict); }
/// <summary> /// Selects a template and starts it... Random mission start /// </summary> /// <param name="character"></param> /// <param name="spreadInGang"></param> /// <param name="location"></param> /// <param name="level"></param> /// <param name="category"></param> /// <returns></returns> public Dictionary <string, object> SelectAndStartRandomMission(Character character, bool spreadInGang, MissionLocation location, int level, MissionCategory category) { if (location.Zone == null) { Logger.Error("zone config was not found for zoneId:" + location.zoneId); throw new PerpetuumException(ErrorCodes.ZoneNotFound); } var missionAgent = location.Agent; GetFinishedAndLastMissions(character, out List <int> missionsDone, out Dictionary <int, DateTime> periodicMissions).ThrowIfError(); var missionFilter = new MissionFilter(character, periodicMissions, missionsDone, this, location, _missionDataCache); missionFilter.IsMissionRunningWithThisCategoryAndLevel(category, level, missionAgent).ThrowIfTrue(ErrorCodes.MissionRunningWithCategoryAndLevel); MissionHelper.GetStandingData(character, missionAgent.OwnerAlliance.Eid, out double standing, out int playerLevel); //at this location this is the maximum level playerLevel = playerLevel.Clamp(0, location.maxMissionLevel); //not higher pls level = level.Clamp(0, playerLevel); var solvableMissions = location.GetSolvableRandomMissionsAtLocation(); var rndMissionsHere = solvableMissions .Where(m => m.missionCategory == category && missionFilter.IsRandomMissionAvailable(m) ).ToList(); if (rndMissionsHere.Count == 0) { character.CreateErrorMessage(Commands.MissionStart, ErrorCodes.NoMissionAvailableWithConditions) .SetExtraInfo(d => d[k.message] = "no mission was found") .Send(); return(null); } var mission = rndMissionsHere.RandomElement(); mission.ThrowIfNull(ErrorCodes.WTFErrorMedicalAttentionSuggested); var resolveInfo = _missionDataCache.GetAllResolveInfos.FirstOrDefault(ri => ri.missionId == mission.id && ri.locationId == location.id); resolveInfo.ThrowIfNull(ErrorCodes.ConsistencyError); var attempts = resolveInfo.attempts; Dictionary <string, object> info = new Dictionary <string, object>(); var resolved = false; while (attempts-- > 0 && !resolved) { resolved = StartMission(character, spreadInGang, mission, location, level, out info); if (!resolved) { Logger.Warning("mission resolve attempts left " + attempts + " " + mission); } } resolved.ThrowIfFalse(ErrorCodes.WTFErrorMedicalAttentionSuggested); return(info); }