/// <summary>
        /// Builds the inventory
        /// </summary>
        /// <param name="itemCode">Code for the items to repeat</param>
        /// <param name="npc">Npc</param>
        /// <returns>Inventory of the npc</returns>
        private string BuildInventory(string itemCode, KortistoNpc npc)
        {
            if (npc.Inventory == null)
            {
                return(string.Empty);
            }

            int    itemIndex     = 0;
            string inventoryCode = string.Empty;

            foreach (KortistoInventoryItem curItem in npc.Inventory)
            {
                string curItemCode = ExportUtil.BuildPlaceholderRegex(Placeholder_CurItem_Index).Replace(itemCode, itemIndex.ToString());
                curItemCode = ExportUtil.RenderPlaceholderIfTrue(curItemCode, Placeholder_CurItem_Is_Equipped_Start, Placeholder_CurItem_Is_Equipped_End, curItem.IsEquipped);
                curItemCode = ExportUtil.RenderPlaceholderIfTrue(curItemCode, Placeholder_CurItem_Quantity_Not_Equal_One_Start, Placeholder_CurItem_Quantity_Not_Equal_One_End, curItem.Quantity != 1);
                curItemCode = ExportUtil.BuildPlaceholderRegex(Placeholder_CurItem_Quantity).Replace(curItemCode, curItem.Quantity.ToString());

                StyrItem item = _cachedDbAccess.GetItemById(curItem.ItemId).Result;
                if (item != null)
                {
                    ExportObjectData itemExportData = new ExportObjectData();
                    itemExportData.ExportData.Add(ExportConstants.ExportDataObject, item);
                    itemExportData.ExportData.Add(ExportConstants.ExportDataObjectType, ExportConstants.ExportObjectTypeItem);
                    curItemCode = _itemPlaceholderResolver.FillPlaceholders(curItemCode, itemExportData).Result;
                }

                inventoryCode += curItemCode;
                ++itemIndex;
            }

            return(inventoryCode);
        }
        /// <summary>
        /// Builds a condition element from parsed data
        /// </summary>
        /// <param name="template">Export template to use</param>
        /// <param name="parsedData">Parsed data</param>
        /// <param name="project">Project</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param>
        /// <param name="exportSettings">Export Settings</param>
        /// <returns>Condition string</returns>
        public override async Task <string> BuildConditionElementFromParsedData(ExportTemplate template, InventoryConditionData parsedData, GoNorthProject project, ExportPlaceholderErrorCollection errorCollection, FlexFieldObject flexFieldObject, ExportSettings exportSettings)
        {
            StyrItem item = await _cachedDbAccess.GetItemById(parsedData.ItemId);

            if (item == null)
            {
                errorCollection.AddDialogItemNotFoundError();
                return(string.Empty);
            }

            ExportObjectData itemExportData = new ExportObjectData();

            itemExportData.ExportData.Add(ExportConstants.ExportDataObject, item);
            itemExportData.ExportData.Add(ExportConstants.ExportDataObjectType, ExportConstants.ExportObjectTypeItem);

            string conditionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_Operator).Replace(template.Code, await ConditionRenderingUtil.GetItemCompareOperatorFromTemplate(_defaultTemplateProvider, project, parsedData.Operator, errorCollection));

            conditionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_Quantity).Replace(conditionCode, parsedData.Quantity.ToString());
            conditionCode = ExportUtil.RenderPlaceholderIfTrue(conditionCode, Placeholder_Operator_IsAtLeast_Start, Placeholder_Operator_IsAtLeast_End, parsedData.Operator == InventoryConditionData.CompareOperator_AtLeast);
            conditionCode = ExportUtil.RenderPlaceholderIfTrue(conditionCode, Placeholder_Operator_IsAtMaximum_Start, Placeholder_Operator_IsAtMaximum_End, parsedData.Operator == InventoryConditionData.CompareOperator_AtMaximum);

            _itemPlaceholderResolver.SetErrorMessageCollection(errorCollection);
            conditionCode = await _itemPlaceholderResolver.FillPlaceholders(conditionCode, itemExportData);

            return(conditionCode);
        }
        /// <summary>
        /// Builds a condition element from parsed data
        /// </summary>
        /// <param name="parsedData">Parsed data</param>
        /// <param name="project">Project</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <param name="npc">Npc to which the dialog belongs</param>
        /// <param name="exportSettings">Export Settings</param>
        /// <returns>Condition string</returns>
        public override string BuildConditionElementFromParsedData(InventoryConditionResolver.InventoryConditionData parsedData, GoNorthProject project, ExportPlaceholderErrorCollection errorCollection, KortistoNpc npc, ExportSettings exportSettings)
        {
            ExportTemplate conditionTemplate = _defaultTemplateProvider.GetDefaultTemplateByType(project.Id, _isPlayer ? TemplateType.TaleConditionPlayerInventory : TemplateType.TaleConditionNpcInventory).Result;

            StyrItem item = _cachedDbAccess.GetItemById(parsedData.ItemId).Result;

            if (item == null)
            {
                errorCollection.AddDialogItemNotFoundError();
                return(string.Empty);
            }

            ExportObjectData itemExportData = new ExportObjectData();

            itemExportData.ExportData.Add(ExportConstants.ExportDataObject, item);
            itemExportData.ExportData.Add(ExportConstants.ExportDataObjectType, ExportConstants.ExportObjectTypeItem);

            string conditionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_Operator).Replace(conditionTemplate.Code, GetOperatorFromTemplate(project, parsedData.Operator, errorCollection));

            conditionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_Quantity).Replace(conditionCode, parsedData.Quantity.ToString());
            conditionCode = ExportUtil.RenderPlaceholderIfTrue(conditionCode, Placeholder_Operator_IsAtLeast_Start, Placeholder_Operator_IsAtLeast_End, parsedData.Operator == CompareOperator_AtLeast);
            conditionCode = ExportUtil.RenderPlaceholderIfTrue(conditionCode, Placeholder_Operator_IsAtMaximum_Start, Placeholder_Operator_IsAtMaximum_End, parsedData.Operator == CompareOperator_AtMaximum);

            _itemPlaceholderResolver.SetErrorMessageCollection(errorCollection);
            conditionCode = _itemPlaceholderResolver.FillPlaceholders(conditionCode, itemExportData).Result;

            return(conditionCode);
        }
        /// <summary>
        /// Returns the value object to use for scriban exporting
        /// </summary>
        /// <param name="parsedData">Parsed data</param>
        /// <param name="project">Project</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param>
        /// <param name="exportSettings">Export Settings</param>
        /// <returns>Value Object</returns>
        protected override async Task <ScribanInventoryConditionData> GetExportObject(InventoryConditionData parsedData, GoNorthProject project, ExportPlaceholderErrorCollection errorCollection, FlexFieldObject flexFieldObject, ExportSettings exportSettings)
        {
            KortistoNpc npc = await ConditionRenderingUtil.GetExportNpc(_cachedDbAccess, project, flexFieldObject, errorCollection, _isPlayer);

            if (npc == null)
            {
                errorCollection.AddDialogNpcNotFoundError();
                return(null);
            }

            StyrItem item = await _cachedDbAccess.GetItemById(parsedData.ItemId);

            if (item == null)
            {
                errorCollection.AddDialogItemNotFoundError();
                return(null);
            }

            ScribanInventoryConditionData conditionData = new ScribanInventoryConditionData();
            ScribanExportNpc convertedNpc = FlexFieldValueCollectorUtil.BuildFlexFieldValueObject <ScribanExportNpc>(null, null, npc, exportSettings, errorCollection);

            convertedNpc.IsPlayer = npc.IsPlayerNpc;
            conditionData.Npc     = convertedNpc;

            conditionData.SelectedItem = FlexFieldValueCollectorUtil.BuildFlexFieldValueObject <ScribanExportItem>(null, null, item, exportSettings, errorCollection);

            conditionData.OriginalOperator = parsedData.Operator == InventoryConditionData.CompareOperator_AtLeast ? "AtLeast" : "AtMaximum";
            conditionData.Operator         = await ConditionRenderingUtil.GetItemCompareOperatorFromTemplate(_defaultTemplateProvider, project, parsedData.Operator, errorCollection);

            conditionData.Quantity = parsedData.Quantity;

            return(conditionData);
        }
        /// <summary>
        /// Returns the item use
        /// </summary>
        /// <param name="parsedData">Parsed data</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <returns>Value Object</returns>
        private async Task <IFlexFieldExportable> GetItem(InventoryActionData parsedData, ExportPlaceholderErrorCollection errorCollection)
        {
            StyrItem item = await _cachedDbAccess.GetItemById(parsedData.ItemId);

            if (item == null)
            {
                errorCollection.AddDialogItemNotFoundError();
                return(null);
            }

            return(item);
        }
        /// <summary>
        /// Loads the reference node data
        /// </summary>
        /// <param name="referenceNode">Reference node</param>
        /// <returns>Reference node data</returns>
        private async Task <ReferenceNodeData> GetReferenceNodeData(ReferenceNode referenceNode)
        {
            ReferenceNodeData referenceNodeData = new ReferenceNodeData();

            referenceNodeData.ReferenceText = referenceNode.ReferenceText;
            referenceNodeData.ObjectType    = referenceNode.ReferencedObjects.Any() ? referenceNode.ReferencedObjects[0].ObjectType : ExportConstants.ExportObjectTypeNone;
            switch (referenceNodeData.ObjectType.ToLowerInvariant())
            {
            case ExportConstants.ExportObjectTypeNpc:
                referenceNodeData.Npc = await _exportCachedDbAccess.GetNpcById(referenceNode.ReferencedObjects[0].ObjectId);

                break;

            case ExportConstants.ExportObjectTypeItem:
                referenceNodeData.Item = await _exportCachedDbAccess.GetItemById(referenceNode.ReferencedObjects[0].ObjectId);

                break;

            case ExportConstants.ExportObjectTypeSkill:
                referenceNodeData.Skill = await _exportCachedDbAccess.GetSkillById(referenceNode.ReferencedObjects[0].ObjectId);

                break;

            case ExportConstants.ExportObjectTypeQuest:
                referenceNodeData.Quest = await _exportCachedDbAccess.GetQuestById(referenceNode.ReferencedObjects[0].ObjectId);

                break;

            case ExportConstants.ExportObjectTypeWikiPage:
                referenceNodeData.WikiPage = await _exportCachedDbAccess.GetWikiPageById(referenceNode.ReferencedObjects[0].ObjectId);

                break;

            case ExportConstants.ExportObjectTypeMapMarker:
                referenceNodeData.Marker = await _exportCachedDbAccess.GetMarkerById(referenceNode.ReferencedObjects[1].ObjectId, referenceNode.ReferencedObjects[0].ObjectId);

                break;

            case ExportConstants.ExportObjectTypeDailyRoutineEvent:
                referenceNodeData.Npc = await _exportCachedDbAccess.GetNpcById(referenceNode.ReferencedObjects[1].ObjectId);

                referenceNodeData.DailyRoutineEvent = referenceNodeData.Npc.DailyRoutine != null?referenceNodeData.Npc.DailyRoutine.FirstOrDefault(d => d.EventId == referenceNode.ReferencedObjects[0].ObjectId) : null;

                break;
            }

            return(referenceNodeData);
        }