/// <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); }