/// <summary> /// Retuns the requested target /// /// Since the mission in progress is needed for the target we return that as well to avoid further lookups /// </summary> /// <returns></returns> private bool GetTargetInProgress_and_missionInProgress(Character character, int targetId, int missionId, Guid missionGuid, out MissionTargetInProgress targetInProgress, out MissionInProgress missionInProgress) { targetInProgress = null; // oldschool version // //myMissionAdministrator.FindMissionInProgressByMissionId(character, missionId, out missionInProgress); MissionAdministrator.FindMissionInProgressByMissionGuid(character, missionGuid, out missionInProgress); if (missionInProgress == null) { Logger.Warning("mission was not found for character: " + character.Id + " missionID:" + missionId); return(false); } if (missionInProgress.MissionId != missionId) { Logger.Warning("WTF??!!! " + missionInProgress); } if (!missionInProgress.GetTargetInProgress(targetId, out targetInProgress)) { Logger.Error("mission target was not found for caharcter: " + character.Id + " missionID:" + missionId + " targetID:" + targetId); return(false); } if (targetInProgress.completed) { Logger.Info("target already completed. missionID: " + missionId + " targetID:" + targetId + " characterID:" + character.Id); return(false); } return(true); }
/// <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); }
private void AdvanceBonusInGang(List <Character> charactersToSpread, MissionInProgress missionInProgress) { foreach (var character in charactersToSpread) { var missionBonus = MissionAdministrator.GetOrAddMissionBonus(character, missionInProgress.myMission.missionCategory, missionInProgress.MissionLevel, missionInProgress.myLocation.Agent); missionBonus.AdvanceBonus(); MissionAdministrator.SetMissionBonus(missionBonus); } }
// the system triggers a mission public bool TriggeredMissionStart(Character character, bool spreadInGang, int missionId, MissionLocation location, int level, out MissionInProgress missionInProgress) { Logger.Info("trying to trigger missionId: " + missionId + " characterId:" + character.Id); Mission mission; _missionDataCache.GetMissionById(missionId, out mission).ThrowIfFalse(ErrorCodes.ItemNotFound); var resolved = MissionAdministrator.StartMission(character, spreadInGang, mission, location, level, out missionInProgress); return(resolved); }
public void AbortMissionByRequest(Character character, Guid missionGuid, ErrorCodes errorToInfo) { Logger.Info("Aborting mission " + missionGuid + " character: " + character.Id); (MissionAdministrator.RunningMissionsCount(character) == 0).ThrowIfTrue(ErrorCodes.ItemNotFound); MissionInProgress missionInProgress; MissionAdministrator.FindMissionInProgressByMissionGuid(character, missionGuid, out missionInProgress).ThrowIfFalse(ErrorCodes.ItemNotFound); missionInProgress?.OnMissionAbort(this, errorToInfo); }
public bool StartMission(Character character, bool spreadInGang, Mission mission, MissionLocation location, int level, out Dictionary <string, object> info) { //add the new mission in progress, set things in motion MissionInProgress missionInProgress; var resolved = MissionAdministrator.StartMission(character, spreadInGang, mission, location, level, out missionInProgress); if (!resolved) { info = new Dictionary <string, object>(); return(false); } Transaction.Current.OnCommited(() => GetOptionsByRequest(character, missionInProgress.myLocation)); info = new Dictionary <string, object> { { k.mission, missionInProgress.ToDictionary() }, }; return(true); }
public MissionProcessor(MissionDataCache missionDataCache, MissionAdministrator.Factory missionAdministratorFactory, IStandingHandler standingHandler) { MissionAdministrator = missionAdministratorFactory(this); _missionDataCache = missionDataCache; _standingHandler = standingHandler; }
/// <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; } } }
private IList <Item> TryFinishMission(MissionInProgress missionInProgress) { if (!missionInProgress.IsMissionFinished) { return(null); } lock (LockObject) { //mission is finished var mission = missionInProgress.myMission; var missionBonus = MissionAdministrator.GetOrAddMissionBonus(missionInProgress.character, mission.missionCategory, missionInProgress.MissionLevel, missionInProgress.myLocation.Agent); Logger.Info("++ Mission is finished " + missionInProgress); var successData = new Dictionary <string, object> { { k.bonusMultiplier, missionBonus.BonusMultiplier }, { "rawBonusMultiplier", (int)Math.Round(missionBonus.RawMultiplier * 100.0) }, { "bonusLevel", missionBonus.Bonus } }; var rewardItems = missionInProgress.SpawnRewardItems(out MissionLocation locationUsed); //online gang members var charactersToInform = missionInProgress.GetAffectedCharacters(); //mission participants var participants = missionInProgress.GetParticipantsVerbose().ToList(); participants = missionInProgress.FilterParticipants(participants); var ep = missionInProgress.CalculateEp(); var epDict = new Dictionary <string, object>(); var count = 0; foreach (var participant in participants) { var oneMansEp = 0; if (ep > 0) { oneMansEp = participant.AddExtensionPointsBoostAndLog(EpForActivityType.Mission, ep); } var oneEpEntry = new Dictionary <string, object> { { k.characterID, participant.Id }, { k.points, oneMansEp } }; epDict.Add("ep" + count++, oneEpEntry); } missionInProgress.GetRewardDivider(participants, out double rewardFraction, out int rewardDivider); successData.Add(k.nofGangMembers, participants.Count); missionInProgress.IncreaseStanding(rewardFraction, participants, charactersToInform, successData); //pay the fee missionInProgress.PayOutMission(rewardFraction, participants, charactersToInform, successData); var isTempTeleportEnabled = false; if (mission.MissionLevel == -1 || mission.behaviourType == MissionBehaviourType.Random) { //set teleport timer missionInProgress.EnableTeleportOnSuccess(participants, missionInProgress.myLocation.ZoneConfig.Id); isTempTeleportEnabled = true; } missionInProgress.WriteSuccessLogAllTargets(); missionInProgress.CleanUpAllTargets(); ArtifactRepository.DeleteArtifactsByMissionGuid(missionInProgress.missionGuid); //write mission log - mission completed missionInProgress.SetSuccessToMissionLog(true).ThrowIfError(); AdvanceBonusInGang(participants, missionInProgress); //remove mission MissionAdministrator.RemoveMissionInProgress(missionInProgress); if (mission.ValidSuccessMissionIdSet) { Logger.Info("++ Begin triggering a mission on success. triggered missionId:" + mission.MissionIdOnSuccess); Transaction.Current.OnCommited(() => { //trigger a new mission with the current location StartAsync(missionInProgress.character, missionInProgress.spreadInGang, mission.MissionIdOnSuccess, missionInProgress.myLocation, missionInProgress.MissionLevel); }); } //add to ram cache AddToFinishedMissions(missionInProgress.character, missionInProgress.MissionId); var resultDict = new Dictionary <string, object> { { k.mission, missionInProgress.ToDictionary() }, { "successData", successData }, { "teleportEnabled", (isTempTeleportEnabled ? 1 : 0) }, { k.extensionPoints, epDict }, }; //reply mission status if (rewardItems.Any()) { resultDict.Add(k.reward, rewardItems.ToDictionary("r", r => r.BaseInfoToDictionary())); if (locationUsed != null) { resultDict.Add("rewardLocation", locationUsed.id); } } missionInProgress.DeleteParticipants(); Transaction.Current.OnCommited(() => Message.Builder.SetCommand(Commands.MissionDone).WithData(resultDict).ToCharacters(charactersToInform).Send()); Logger.Info("++ mission is finished. " + missionInProgress); return(rewardItems); } }