/// <summary> /// Get all targets with the given type in pairs to process advancement /// /// Since the target is wrapped into mission and mission wrapped into collectors getting a target is always: /// get collector by character, get mission, get target /// /// </summary> /// <param name="character"></param> /// <param name="targetType"></param> /// <returns></returns> private List <KeyValuePair <MissionTargetInProgress, MissionInProgress> > GetTargetInProgress_and_missionInProgressByTargetType(Character character, MissionTargetType targetType) { var resultList = new List <KeyValuePair <MissionTargetInProgress, MissionInProgress> >(); if (!MissionAdministrator.GetMissionInProgressCollector(character, out MissionInProgressCollector collector)) { return(resultList); } foreach (var missionInProgress in collector.GetMissionsInProgress()) { var list = missionInProgress.CollectIncompleteTargetsByType(targetType).ToArray(); if (list.IsNullOrEmpty()) { continue; } foreach (var missionTargetInProgress in list) { resultList.Add(new KeyValuePair <MissionTargetInProgress, MissionInProgress>(missionTargetInProgress, missionInProgress)); } } return(resultList); }
/// <summary> /// Multideliver /// Collects all deliverable targets and tries to look up the items they require /// </summary> public void DeliverMissionByRequest(Character character, int locationId = 0) { Logger.Info("++ Deliver targets begins. characterId:" + character.Id); //var deliveryState = DeliverResult.nothingHappened; //get the affected characters from the gang var charactersToProcess = GetGangMembersCached(character); var isDocked = character.IsDocked; MissionLocation location; if (isDocked) { location = _missionDataCache.GetLocationByEid(character.CurrentDockingBaseEid); } else { //ok, let's use the optional parameter locationId.ThrowIfEqual(0, ErrorCodes.WTFErrorMedicalAttentionSuggested); if (!_missionDataCache.GetLocationById(locationId, out location)) { throw new PerpetuumException(ErrorCodes.InvalidMissionLocation); } } //safety location.ThrowIfNull(ErrorCodes.WTFErrorMedicalAttentionSuggested); var interestingTargets = new List <MissionTargetInProgress>(); //let's collect the targets foreach (var processedCharacter in charactersToProcess) { if (MissionAdministrator.RunningMissionsCount(processedCharacter) == 0) { continue; } MissionInProgressCollector collector; if (MissionAdministrator.GetMissionInProgressCollector(processedCharacter, out collector)) { foreach (var mip in collector.GetMissionsInProgress()) { if (mip.IsMissionFinished) { continue; } interestingTargets.AddRange(mip.CollectTargetsWithDefinitionsToDeliverInCurrentState(location)); } } } DeliverMissionByTargetList(interestingTargets, character, location); }
/// <summary> /// Deliver items to a single mission /// </summary> public void DeliverSingleMission(Character character, Guid missionGuid, int locationId = 0) { Logger.Info($"++ Deliver starts for character:{character} missionGuid:{missionGuid}"); var isDocked = character.IsDocked; MissionLocation location; if (isDocked) { location = _missionDataCache.GetLocationByEid(character.CurrentDockingBaseEid); } else { //ok, let's use the optional parameter locationId.ThrowIfEqual(0, ErrorCodes.WTFErrorMedicalAttentionSuggested); if (!_missionDataCache.GetLocationById(locationId, out location)) { throw new PerpetuumException(ErrorCodes.InvalidMissionLocation); } } //safety location.ThrowIfNull(ErrorCodes.WTFErrorMedicalAttentionSuggested); //get the affected characters from the gang var charactersToProcess = GetGangMembersCached(character); MissionInProgress missionInProgress = null; //let's collect the targets foreach (var processedCharacter in charactersToProcess) { if (MissionAdministrator.RunningMissionsCount(processedCharacter) == 0) { continue; } MissionInProgressCollector collector; if (MissionAdministrator.GetMissionInProgressCollector(processedCharacter, out collector)) { foreach (var mip in collector.GetMissionsInProgress()) { if (mip.missionGuid == missionGuid) { missionInProgress = mip; break; } } } } var result = new Dictionary <string, object>(); if (missionInProgress == null) { // mission was not found Message.Builder.SetCommand(Commands.MissionDeliver) .WithError(ErrorCodes.MissionNotFound) .ToCharacter(character) .Send(); return; } if (missionInProgress.IsMissionFinished) { Message.Builder.SetCommand(Commands.MissionDeliver) .WithError(ErrorCodes.MissionAlreadyDone) .ToCharacter(character) .Send(); return; } var interestingTargets = missionInProgress.CollectTargetsWithDefinitionsToDeliverInCurrentState(location).ToList(); DeliverMissionByTargetList(interestingTargets, character, location); }
private void MissionTargetAdvanced(Character character, MissionTargetType targetType, bool explicitGangHandling, Dictionary <string, object> originalData) { //explicit gang handling not set if (!explicitGangHandling) { MissionTargetAdvancedSingle(originalData); if (WasProgress(originalData)) { SendRunningMissionListAsync(character); } return; } //ok, lets get deeper, we must use the gang //first enqueue for myself, we are the priority here MissionTargetAdvancedSingle(originalData); if (WasProgress(originalData)) { //yes, this request advanced one of my targets, we are done here, send running list if all done. SendRunningMissionListAsync(character); return; } //do gang var others = GetGangMembersCached(character).Where(m => m.Id != character.Id); foreach (var other in others) { //any mission running? if (!MissionAdministrator.GetMissionInProgressCollector(other, out MissionInProgressCollector collector)) { continue; } //any targets waiting? if (!collector.GetMissionsInProgress().SelectMany(m => m.CollectIncompleteTargetsByType(targetType)).Any(t => t.IsMyTurn)) { continue; } var info = originalData.Clone(); //fake the source character info[k.characterID] = other.Id; //force add participation info info[k.assistingCharacterID] = character.Id; MissionTargetAdvancedSingle(info); //if event got used up => end of its life if (WasProgress(originalData)) { return; } } }