protected void Activate(QuestPin pin) { QuestObjectState state = GetState(pin); if (state.Locked || state.Active != QuestObjectState.ActivationState.Inactive) { return; } bool lockPin = false; if (pin.Type == GraphPin.PinType.Input) { if (pin.Script != null) { GameDebugger.Log(LogLevel.Debug, "QS: Partially activated pin '0x{0:X16}'", pin.Id); GameDebugger.Log(LogLevel.Debug, "QS: Adding pin '0x{0:X16}' to the list of actively checked objects", pin.Id); state.Active = QuestObjectState.ActivationState.PartiallyActive; m_ActivelyChecked.Add(pin.Id, pin); } else { state.Active = QuestObjectState.ActivationState.Active; GameDebugger.Log(LogLevel.Debug, "QS: Activated pin '0x{0:X16}'", pin.Id); if (pin.Node is Quest) { Activate((BaseQuestObject)pin.Node); } else { CheckInputsOnActivation((BaseQuestObject)pin.Node); } } } else { state.Active = QuestObjectState.ActivationState.Active; GameDebugger.Log(LogLevel.Debug, "QS: Activated pin '0x{0:X16}'", pin.Id); if (pin.Node is Quest || pin.Node is QuestObjective) { QuestObjectState nodeState = GetState((IQuestSystemObject)pin.Node); int pinIndex = 0; foreach (QuestPin testPin in pin.Node.Outputs) { if (testPin == pin) { GameDebugger.Log(LogLevel.Debug, "QS: Detected pin index: {0}", pinIndex); break; } pinIndex++; } if (nodeState.Completion == QuestObjectState.CompletionState.Incomplete || nodeState.CompletionOutput != pinIndex) { if (nodeState.Completion != QuestObjectState.CompletionState.Incomplete) { Deactivate((QuestPin)pin.Node.Outputs[nodeState.CompletionOutput]); GameDebugger.Log(LogLevel.Debug, "QS: Switching {0} '0x{1:X16}' completion state from {2} to {3}", pin.Node.GetType().Name, ((IQuestSystemObject)pin.Node).Id, nodeState.CompletionOutput, pinIndex); } else { GameDebugger.Log(LogLevel.Debug, "QS: Setting {0} '0x{1:X16}' completion state to {2}", pin.Node.GetType().Name, ((IQuestSystemObject)pin.Node).Id, pinIndex); } nodeState.CompletionOutput = (byte)pinIndex; nodeState.Completion = pin.IsFailureOutput ? QuestObjectState.CompletionState.Failed : QuestObjectState.CompletionState.Successful; if (pin.Node is Quest) { lockPin = true; GameDebugger.Log(LogLevel.Debug, "QS: event: OnQuestComplete"); if (OnQuestComplete != null) { OnQuestComplete.Invoke(new QuestCompleteEventArgs((Quest)pin.Node, pinIndex, pin.IsFailureOutput)); } } else { GameDebugger.Log(LogLevel.Debug, "QS: event: OnQuestObjectiveComplete"); if (OnQuestObjectiveComplete != null) { OnQuestObjectiveComplete.Invoke(new QuestObjectiveCompleteEventArgs((QuestObjective)pin.Node, pinIndex, pin.IsFailureOutput)); } } } } if (!(pin.Node is QuestObjective)) // quest objectives have conditions instead of instructions on outputs { ExecuteScript(pin); } } // activate all outgoing connections if (state.Active == QuestObjectState.ActivationState.Active) { foreach (QuestConnection connection in pin.Connections) { if (connection.Source == pin) { Activate(connection); } } } // locking the pin must be done in the end otherwise it will not activate connections (they will be already locked) if (lockPin) { Lock(pin); } }
internal void UpdateQuestLog() { //var totalQuests = 0x00BC6F24.ReadAs<int>(); var totalEntrys = 0xBB7478.ReadAs <int>(); var updateTime = Environment.TickCount; for (var i = 0; i < totalEntrys; i++) { var isHeader = (0xBB71C8 + (i << 4)).ReadAs <int>() == 1; if (isHeader) { continue; } var questId = (0xBB71C0 + (i << 4)).ReadAs <int>(); var ptrToRow = ObjectManager.Instance.LookupQuestCachePtr(questId); if (ptrToRow == IntPtr.Zero) { continue; } var questName = ptrToRow.Add(0x9C).ReadString(); var rewards = GetQuestChoiceRewards(ptrToRow); if (rewards == null) { continue; } var realQuestIndex = (0x00BB71C4 + (i << 4)).ReadAs <int>(); var objectives = GetQuestObjectives(ptrToRow, realQuestIndex); var questState = QuestStateByIndex(i); var questEntry = new QuestLogEntryInterface(questId, questName, questState, objectives, rewards, realQuestIndex); if (!_questDic.ContainsKey(questId)) { _questDic.Add(questId, questEntry); questEntry.LastUpdate = updateTime; } else { var oldEntry = _questDic[questId]; if (oldEntry.State != questEntry.State) { switch (questEntry.State) { case Enums.QuestState.Completed: OnQuestComplete?.Invoke(questEntry, new EventArgs()); break; case Enums.QuestState.Failed: OnQuestFailed?.Invoke(questEntry, new EventArgs()); break; } } for (var k = 0; k < oldEntry.Objectives.Count; k++) { var oldObjective = oldEntry.Objectives[k]; var newObjective = questEntry.Objectives[k]; if (oldObjective.Progress != newObjective.Progress) { OnQuestProgress?.Invoke(questEntry, new EventArgs()); } if (oldObjective.IsDone == newObjective.IsDone) { continue; } if (newObjective.IsDone) { OnQuestObjectiveComplete?.Invoke(questEntry, new EventArgs()); } } _questDic[questId] = questEntry; questEntry.LastUpdate = updateTime; } } var invalidQuests = _questDic.Where(i => i.Value.LastUpdate != updateTime).Select(i => i.Key).ToList(); foreach (var item in invalidQuests) { _questDic.Remove(item); } _quests = _questDic.Values.ToList(); }