Пример #1
0
        public void Analyze(List <FFXIVAetheryte> iAetherytes, List <FFXIVGatheringNode> iNodes, ref Dictionary <string, double> dictionaryClosestAetherytes)
        {
            Status  = "Unknown";
            IsValid = false;
            try
            {
                string contentGrid = File.ReadAllText(GridFile.FullName);
                if (contentGrid == "")
                {
                    Status = "Empty Grid";
                    return;
                }

                ParseFromLine(contentGrid);

                //Finding item gathering nodes
                bool noGatheringNodeMode = false;
                List <FFXIVGatheringNode> correspondingNodes = new List <FFXIVGatheringNode>();
                foreach (FFXIVGatheringNode node in iNodes)
                {
                    if (null == node)
                    {
                        continue;
                    }

                    string foundItemName = node.NodeItems.Find(x => x != null && x.ToLower().Trim() == ItemName.ToLower().Trim());
                    if (foundItemName != null && foundItemName != "")
                    {
                        correspondingNodes.Add(node);
                    }
                }
                if (correspondingNodes.Count <= 0 && ItemName != "")
                {
                    List <FFXIVSearchItem> resultGarlandTools = GarlandTool.Search(ItemName, null, FFXIVItem.TypeItem.Gathered);
                    if (resultGarlandTools.Count > 0)
                    {
                        List <FFXIVGatheringNode> correspondingNodesFromGarland = GarlandTool.GetGatheringNodesFromItem(resultGarlandTools[0].ID);

                        foreach (FFXIVGatheringNode garlandNode in correspondingNodesFromGarland)
                        {
                            string foundItemName = garlandNode.NodeItems.Find(x => x != null && x.ToLower().Trim() == ItemName.ToLower().Trim());
                            if (foundItemName != null && foundItemName != "")
                            {
                                correspondingNodes.Add(garlandNode);
                            }

                            /*
                             *  FFXIVGatheringNode bestNode = null;
                             *  double maxCorrespondance = -1;
                             *  foreach (FFXIVGatheringNode node in iNodes)
                             *  {
                             *      if(node.Zone.ToLower().Trim() != garlandNode.Zone.ToLower().Trim())
                             *      {
                             *          continue;
                             *      }
                             *
                             *      double nbSameItem = 0;
                             *      double nbTotalItem = node.NodeItems.Count;
                             *
                             *      foreach(string itemName in node.NodeItems)
                             *      {
                             *          if (null != garlandNode.NodeItems.Find(x => x != null && x.ToLower().Trim() == itemName.ToLower().Trim()))
                             *          {
                             *              nbSameItem += 1.0;
                             *          }
                             *      }
                             *      double correspondance = 100.0 * nbSameItem / nbTotalItem;
                             *      if(maxCorrespondance < correspondance)
                             *      {
                             *          maxCorrespondance = correspondance;
                             *          bestNode = node;
                             *      }
                             *  }
                             *  if (maxCorrespondance < 0) continue;
                             *  if (null == bestNode) continue;
                             *  correspondingNodes.Add(bestNode);
                             */
                        }
                    }
                    noGatheringNodeMode = correspondingNodes.Count > 0;
                }
                AllNodes = correspondingNodes;

                //Finding closest node
                double minDistance = -1;
                if (!noGatheringNodeMode)
                {
                    foreach (FFXIVGatheringNode node in correspondingNodes)
                    {
                        if (null == node)
                        {
                            continue;
                        }

                        double nodeDistance = -1;
                        foreach (FFXIVPosition point in Points)
                        {
                            double distance = node.Position.PlanarDistanceTo(point);
                            if (minDistance < 0 || distance < minDistance)
                            {
                                minDistance         = distance;
                                ClosestNode         = node;
                                ClosestNodeDistance = minDistance;
                            }
                            if (nodeDistance < 0 || distance < nodeDistance)
                            {
                                nodeDistance = distance;
                            }
                        }
                        AllNodesDistance.Add(nodeDistance);
                    }
                    if (minDistance > 50)
                    {
                        Status = "Too far from closest gathering node.";
                        return;
                    }
                    if (null == ClosestNode)
                    {
                        Status = "No gathering node.";
                        return;
                    }
                }
                else
                {
                    if (AllNodes.Count == 1)
                    {
                        ClosestNode = AllNodes[0];
                    }
                    foreach (FFXIVGatheringNode node in correspondingNodes)
                    {
                        AllNodesDistance.Add(-1);
                    }
                }

                string statusPrefix = "";
                if (noGatheringNodeMode)
                {
                    statusPrefix = "[No-Node] ";
                }
                //Finding zone aetherytes
                List <FFXIVAetheryte> listZoneAetherytes = new List <FFXIVAetheryte>();
                foreach (FFXIVAetheryte aetherythe in iAetherytes)
                {
                    if (noGatheringNodeMode)
                    {
                        foreach (FFXIVGatheringNode node in correspondingNodes)
                        {
                            if (aetherythe.Zone == node.Zone)
                            {
                                listZoneAetherytes.Add(aetherythe);
                            }
                        }
                    }
                    else
                    {
                        if (aetherythe.Zone == ClosestNode.Zone)
                        {
                            listZoneAetherytes.Add(aetherythe);
                        }
                    }
                }

                //Finding closest aetheryte
                double minDistanceAetheryte = -1;
                List <FFXIVPosition> listAetheryteClosePoints = new List <FFXIVPosition>();
                foreach (FFXIVAetheryte aetherythe in listZoneAetherytes)
                {
                    if (null == aetherythe)
                    {
                        continue;
                    }

                    double distanceAetheryte = -1;
                    foreach (FFXIVPosition point in Points)
                    {
                        double distance = aetherythe.Position.PlanarDistanceTo(point);
                        if (minDistanceAetheryte < 0 || distance < minDistanceAetheryte)
                        {
                            minDistanceAetheryte     = distance;
                            ClosestAetheryte         = aetherythe;
                            ClosestAetheryteDistance = minDistanceAetheryte;
                        }
                        if (distanceAetheryte < 0 || distance < distanceAetheryte)
                        {
                            distanceAetheryte = distance;
                        }
                        if (distance < 50)
                        {
                            listAetheryteClosePoints.Add(point);
                        }
                    }
                    ZoneAetherytes.Add(aetherythe);
                    ZoneAetherytesDistance.Add(distanceAetheryte);
                }
                if (minDistanceAetheryte > 40)
                {
                    Status = statusPrefix + "Too far from closest aetheryte.";
                    return;
                }
                if (null == ClosestAetheryte)
                {
                    Status = statusPrefix + "No Aetheryte.";
                    return;
                }
                if (listAetheryteClosePoints.Count < 1)
                {
                    Status = statusPrefix + "Not enough close points.";
                    return;
                }
                ListAetheryteClosePoints = listAetheryteClosePoints;
                if (dictionaryClosestAetherytes.ContainsKey(ItemName))
                {
                    double distance = dictionaryClosestAetherytes[ItemName];
                    if (distance < minDistanceAetheryte)
                    {
                        Status = statusPrefix + "Other grid is closer to grid points.";
                        return;
                    }
                }
                dictionaryClosestAetherytes[ItemName] = minDistanceAetheryte;

                Status  = statusPrefix + "OK";
                IsValid = true;
            }
            catch (Exception e)
            {
                Status = e.Message;
            }
        }
Пример #2
0
        public static string GenerateScenario(List <FFXIVItem> iItemToGenerate, MiqobotScenarioOption iOptions, System.Windows.Forms.TextBox iLogBox, out string fullScenario)
        {
            fullScenario = "";
            if (null == iOptions)
            {
                Service_Misc.LogText(iLogBox, "Whoooops wrong options selected...");
                return(null);
            }
            Service_Misc.LogText(iLogBox, "Let's whisper to miqobot ears...");

            MiqoCraftOptions options = new MiqoCraftOptions();

            options.Load(OptionLocation.UserOption);

            //Login to miqobot forums
            CookieCollection logMiqobotCookies = Miqobot.LogInForum();

            if (null != logMiqobotCookies)
            {
                Service_Misc.LogText(iLogBox, "I'm logged into miqobot forum !");
            }
            else
            {
                Service_Misc.LogText(iLogBox, "Failed to log into miqobot forum... well you'll have to manually gather stuff, sorry !");
            }

            //Listing items
            List <FFXIVItem> allItems         = new List <FFXIVItem>();
            List <int>       allItemsQuantity = new List <int>();
            string           scenarioName     = "";

            foreach (FFXIVItem iItem in iItemToGenerate)
            {
                if (null == iItem)
                {
                    continue;
                }
                if (scenarioName != "")
                {
                    scenarioName += ",";
                }
                scenarioName += iItem.Name;
                RecFindItems(iItem, iOptions.Quantity, ref allItems, ref allItemsQuantity, iOptions.CustomQuantities);
            }
            if (iItemToGenerate.Count > 5)
            {
                scenarioName = iItemToGenerate.Count + " Items";
            }

            fullScenario = "";
            string allGrids     = "";
            string allRotations = "";
            string allPreset    = "";

            List <string> catalysts = GetCatalysts();

            if (!iOptions.IgnoreCatalysts)
            {
                catalysts.Clear();
            }

            //Creating rotations
            allRotations += "gatherrotation.Collect Gathering +15%" + Environment.NewLine;
            allRotations += "[31,9,22,26,25,[34,[35,29,36,26]],25,[34,[35,29,36,26]],23,1,32]" + Environment.NewLine;
            allRotations += "gatherrotation.Collect Gathering +5%" + Environment.NewLine;
            allRotations += "[31,9,22,26,25,[34,[35,29,36,26]],25,[34,[35,29,36,26]],23,0]" + Environment.NewLine;
            allRotations += "gatherrotation.Gathering +15%/HQ +10%" + Environment.NewLine;
            allRotations += "[31,1,3]" + Environment.NewLine;
            allRotations += "gatherrotation.HQ +10%" + Environment.NewLine;
            allRotations += "[31,3]" + Environment.NewLine;
            allRotations += "gatherrotation.Gathering +5%/HQ +10%" + Environment.NewLine;
            allRotations += "[31,0,3]" + Environment.NewLine;
            allRotations += MiqoCraftCore.GetCacheRotations() + Environment.NewLine;;

            //Creating default preset
            allPreset += "solverpreset.recommended" + Environment.NewLine;
            allPreset += "{\"cpchunk\":4,\"skillinnovation\":true,\"skillmanipulation\":false,\"skillwastenot1\":false,\"skillwastenot2\":false,\"skillwhistle\":false,\"progresssolver\":true,\"enforcebb100\":true,\"enforcepbp100\":true,\"ignorequality\":false,\"reclaimhqon\":false,\"reclaimhqvalue\":85,\"reclaimqualityon\":false,\"reclaimqualityvalue\":4000}" + Environment.NewLine;
            allPreset += MiqoCraftCore.GetCacheSolverPresets() + Environment.NewLine;;

            //Header
            Service_Misc.LogText(iLogBox, "Creating scenario header...");
            fullScenario += "\"";
            fullScenario += "//--------------------------------------------------------------" + Environment.NewLine;
            fullScenario += "// " + scenarioName + Environment.NewLine;
            fullScenario += "// Script Generated by MiqoCrafter" + Environment.NewLine;
            fullScenario += "//--------------------------------------------------------------" + Environment.NewLine;
            fullScenario += "// Copyright 2019 - Shishio Valentine" + Environment.NewLine;
            fullScenario += "// [email protected]" + Environment.NewLine;
            fullScenario += "// http://patreon.com/miqocrafter" + Environment.NewLine;
            fullScenario += "//--------------------------------------------------------------" + Environment.NewLine;

            //Prerequisite
            fullScenario += Environment.NewLine;
            fullScenario += Environment.NewLine;
            fullScenario += "// Prerequisite" + Environment.NewLine;
            fullScenario += "//--------------------------------------------------------------" + Environment.NewLine;
            fullScenario += "//" + Environment.NewLine;
            if (iOptions.IgnoreCatalysts)
            {
                fullScenario += "// You will need to buy or obtain those items using external means, cause Miqocrafter can't automate it [Yet], or they are ignored catalysts" + Environment.NewLine;
            }
            else
            {
                fullScenario += "// You will need to buy or obtain those items using external means, cause Miqocrafter can't automate it [Yet]" + Environment.NewLine;
            }
            for (int i = 0; i < allItems.Count && i < allItemsQuantity.Count; i++)
            {
                FFXIVItem iItem = allItems[i];
                if (null == iItem)
                {
                    continue;
                }
                int quantity = allItemsQuantity[i];

                FFXIVCraftingOptions itemOptions = options.GetOption(iItem);

                if (iItem.Type == FFXIVItem.TypeItem.NPC || iItem.Type == FFXIVItem.TypeItem.Unkwown || null != catalysts.Find(x => x != null && x.ToLower() == iItem.Name.ToLower()) || (null != itemOptions && itemOptions.IgnoreItem))
                {
                    fullScenario += "//    - " + quantity + "x " + iItem.Name + " (see " + iItem.UrlGarland + ")" + Environment.NewLine;
                }
            }

            //Reduced
            fullScenario += Environment.NewLine;
            fullScenario += Environment.NewLine;
            fullScenario += "// Reduced Items" + Environment.NewLine;
            fullScenario += "//--------------------------------------------------------------" + Environment.NewLine;
            fullScenario += "//" + Environment.NewLine;
            fullScenario += "// You will need to manually reduce those items, cause Miqocrafter can't automate it [Yet]" + Environment.NewLine;
            fullScenario += "// However Miqocrafter will try to gather/craft/retrieve the items that need to be reduced." + Environment.NewLine;
            for (int i = 0; i < allItems.Count && i < allItemsQuantity.Count; i++)
            {
                FFXIVItem iItem = allItems[i];
                if (null == iItem)
                {
                    continue;
                }
                int quantity = allItemsQuantity[i];
                FFXIVReducedItem reducedItem = null;
                if (iItem is FFXIVReducedItem)
                {
                    reducedItem = iItem as FFXIVReducedItem;
                }
                if (null != reducedItem)
                {
                    if (null != reducedItem.ReducedFrom)
                    {
                        fullScenario += "//    - " + iItem.Name + " (Reduced from " + reducedItem.ReducedFrom + " - " + iItem.UrlGarland + ")" + Environment.NewLine;
                    }
                    else
                    {
                        fullScenario += "//    - " + quantity + "x " + iItem.Name + " (see " + iItem.UrlGarland + ")" + Environment.NewLine;
                    }
                }
            }

            //Errors
            fullScenario += "ERRORS_ITEMS_DUMMY";

            fullScenario += "\",";

            //Getting miqo preset content
            string miqoPresetContent = "";

            if (null != iOptions.MiqoPresetPath && "" != iOptions.MiqoPresetPath)
            {
                FileInfo presetFile = new FileInfo(Path.Combine(iOptions.MiqoPresetPath, "presets.miqo"));
                if (presetFile.Exists)
                {
                    miqoPresetContent = File.ReadAllText(presetFile.FullName);
                }
            }
            if (miqoPresetContent == "" && null != options.MiqoPresetPath && "" != options.MiqoPresetPath)
            {
                FileInfo presetFile = new FileInfo(Path.Combine(options.MiqoPresetPath, "presets.miqo"));
                if (presetFile.Exists)
                {
                    miqoPresetContent = File.ReadAllText(presetFile.FullName);
                }
            }

            //Gathering stuff
            string lastTeleport = "";
            string errorContent = "";

            Service_Misc.LogText(iLogBox, "Creating gathering grids...");
            fullScenario += "\"";
            fullScenario += Environment.NewLine;
            fullScenario += Environment.NewLine;
            fullScenario += "// Gathered Items" + Environment.NewLine;
            fullScenario += "//--------------------------------------------------------------" + Environment.NewLine;
            fullScenario += "//" + Environment.NewLine;
            fullScenario += "// Miqocrafter will use the gathering scenario from https://miqobot.com/forum/forums/topic/index-gathering-grids/ to retrieve those." + Environment.NewLine;
            for (int i = 0; i < allItems.Count && i < allItemsQuantity.Count; i++)
            {
                FFXIVItem iItem = allItems[i];
                if (null == iItem)
                {
                    continue;
                }
                int quantity = allItemsQuantity[i] / iOptions.NbPerNode + 1;

                if (!(iItem is FFXIVGatheredItem))
                {
                    continue;
                }
                FFXIVGatheredItem gatheredItem = iItem as FFXIVGatheredItem;

                if (null != catalysts.Find(x => x != null && x.ToLower() == iItem.Name.ToLower()))
                {
                    continue;
                }
                FFXIVCraftingOptions itemOptions = options.GetOption(iItem);
                if (null != itemOptions && itemOptions.IgnoreItem)
                {
                    continue;
                }

                if (null != gatheredItem)
                {
                    Service_Misc.LogText(iLogBox, "Searching for item grid : " + iItem + "");
                    if (gatheredItem.Slot.Count <= 0)
                    {
                        errorContent += "//    - " + quantity + "x " + iItem.Name + " (see " + iItem.UrlGarland + ")" + Environment.NewLine;
                        fullScenario += "// Failed to retrieve item gathering slot from FGarlandTool, can't gather this item " + iItem.Name + " (see " + iItem.UrlGarland + ")" + Environment.NewLine;
                        continue;
                    }
                    if (null != logMiqobotCookies)
                    {
                        List <MiqoItemPage> listItemPage = Miqobot.GetURLItem(iItem.Name, logMiqobotCookies, null);
                        if (listItemPage.Count <= 0)
                        {
                            errorContent += "//    - " + quantity + "x " + iItem.Name + " (see " + iItem.UrlGarland + ")" + Environment.NewLine;
                            fullScenario += "// Failed to retrieve item gathering scenario from miqobot forums, can't gather this item " + iItem.Name + " (see " + iItem.UrlGarland + ")" + Environment.NewLine;
                        }
                        else
                        {
                            string initName = "";
                            string grid     = null;
                            for (int j = 0; j < listItemPage.Count && null == grid; j++)
                            {
                                grid = Miqobot.GetLastGrid(iItem.Name, logMiqobotCookies, listItemPage[j], out initName);
                            }
                            if (null != grid)
                            {
                                //Finding right zone
                                string zone          = "";
                                string type          = "";
                                string slot          = "";
                                string time          = "";
                                string gatheringType = "";

                                if (gatheredItem.Slot.Count == 1)
                                {
                                    //No ambiguity
                                    zone          = gatheredItem.Zones[0];
                                    type          = gatheredItem.Types[0];
                                    slot          = gatheredItem.Slot[0];
                                    time          = gatheredItem.Times[0];
                                    gatheringType = gatheredItem.GatheringTypes[0];
                                }
                                else
                                {
                                    if (zone == "")
                                    {
                                        foreach (string zoneName in gatheredItem.Zones)
                                        {
                                            string initNameCorrected = initName.Replace(" ", "").ToLower();
                                            string gridDataCorrected = grid.Replace(" ", "").ToLower();
                                            string zoneNameCorrected = zoneName.ToLower().Replace("the ", "").Replace(" ", "").Trim();
                                            if (initNameCorrected.Contains(zoneNameCorrected))
                                            {
                                                int index = gatheredItem.Zones.IndexOf(zoneName);

                                                zone          = gatheredItem.Zones[index];
                                                type          = gatheredItem.Types[index];
                                                slot          = gatheredItem.Slot[index];
                                                time          = gatheredItem.Times[index];
                                                gatheringType = gatheredItem.GatheringTypes[index];
                                                break;
                                            }
                                            if (gridDataCorrected.Contains(zoneNameCorrected))
                                            {
                                                int index = gatheredItem.Zones.IndexOf(zoneName);

                                                zone          = gatheredItem.Zones[index];
                                                type          = gatheredItem.Types[index];
                                                slot          = gatheredItem.Slot[index];
                                                time          = gatheredItem.Times[index];
                                                gatheringType = gatheredItem.GatheringTypes[index];
                                                break;
                                            }
                                        }
                                    }
                                }
                                if (zone == "")
                                {
                                    errorContent += "//    - " + quantity + "x " + iItem.Name + " (see " + iItem.UrlGarland + ")" + Environment.NewLine;
                                    fullScenario += "// Failed to retrieve item gathering zone from miqobot grid, can't gather this item " + iItem.Name + " (see " + iItem.UrlGarland + ")" + Environment.NewLine;
                                    continue;
                                }

                                //Find teleport item
                                string teleportTo = GarlandTool.GetTeleportName(zone, grid, gatheredItem);

                                //Compute grid name from miqo presets, to avoid duplicates
                                string gridName  = iItem.Name + " Grid";
                                int    indexGrid = 1;
                                while (miqoPresetContent.Contains("grid." + gridName + Environment.NewLine))
                                {
                                    string oldGridName = gridName;
                                    gridName = iItem.Name + " Grid" + indexGrid;
                                    grid     = grid.Replace("grid." + oldGridName + Environment.NewLine, "grid." + gridName + Environment.NewLine);
                                    indexGrid++;
                                }

                                //Embed grid
                                allGrids += grid + Environment.NewLine;

                                //Get preset
                                string preset = MiqoCraftCore.GetCraftingPreset(gatheringType, slot, gatheredItem, iOptions.GatheringRotation, gridName, time);

                                //Compute preset name from miqo presets, to avoid duplicates
                                string presetName  = iItem.Name + " preset";
                                int    indexpreset = 1;
                                while (miqoPresetContent.Contains("gatherpreset." + presetName + Environment.NewLine))
                                {
                                    string oldpresetName = presetName;
                                    presetName = iItem.Name + " preset" + indexpreset;
                                    preset     = preset.Replace("gatherpreset." + oldpresetName + Environment.NewLine, "gatherpreset." + presetName + Environment.NewLine);
                                    indexpreset++;
                                }

                                //Embed a new preset
                                allPreset += preset;

                                //Add gathering rotation to scenario
                                //Add gathering rotation to scenario
                                //teleportIf(Black Brush Station)\r\nunstealth()\r\nchangeJob(Miner)\r\nselectGrid(Min5-Copper Ore)\r\nselectGatherPreset(Metal Worm Jar- Copper Ore)\r\nstartGathering(4)
                                //teleportIfNotThere
                                fullScenario += "// Gathering " + iItem.Name + Environment.NewLine;
                                if (lastTeleport == "" || lastTeleport == teleportTo)
                                {
                                    fullScenario += "teleport(" + teleportTo + ")" + Environment.NewLine;
                                }
                                else
                                {
                                    fullScenario += "teleportIfNotThere(" + teleportTo + ")" + Environment.NewLine;
                                }
                                lastTeleport = teleportTo;

                                //Adding custom scenario after teleport
                                DirectoryInfo customDirectory = new DirectoryInfo(Path.Combine(Service_Misc.GetExecutionPath(), "CustomTeleport"));
                                if (!customDirectory.Exists)
                                {
                                    customDirectory.Create();
                                }
                                FileInfo customTeleportScenarioFile = new FileInfo(Path.Combine(customDirectory.FullName, teleportTo + " Scenario.txt"));
                                if (customTeleportScenarioFile.Exists)
                                {
                                    fullScenario += File.ReadAllText(customTeleportScenarioFile.FullName) + Environment.NewLine;
                                }

                                FileInfo customTeleportGridFile = new FileInfo(Path.Combine(customDirectory.FullName, teleportTo + " Grid.txt"));
                                if (customTeleportGridFile.Exists)
                                {
                                    allGrids += File.ReadAllText(customTeleportGridFile.FullName) + Environment.NewLine;
                                }


                                //fullScenario += "unstealth()" + Environment.NewLine;
                                fullScenario += "changeJob(" + GarlandTool.GetGatheringJobName(gatheringType, iItem) + ")" + Environment.NewLine;
                                fullScenario += "selectGrid(" + gridName + ")" + Environment.NewLine;
                                fullScenario += "selectGatherPreset(" + presetName + ")" + Environment.NewLine;
                                if (null != gatheredItem && gatheredItem.AsCollectable)
                                {
                                    fullScenario += "rotationIfGP(470 Collect 5% Gathering)" + Environment.NewLine;
                                    fullScenario += "rotationIfGP(470 Collect 15% Gathering)" + Environment.NewLine;
                                }
                                else
                                {
                                    fullScenario += "rotationIfGP(" + iOptions.GatheringRotation + ")" + Environment.NewLine;
                                }
                                fullScenario += "startGathering(" + quantity + ")" + Environment.NewLine;
                                fullScenario += Environment.NewLine;
                            }
                            else
                            {
                                errorContent += "//    - " + quantity + "x " + iItem.Name + " (see " + iItem.UrlGarland + ")" + Environment.NewLine;
                                fullScenario += "// Failed to retrieve the grid from miqobot forums, can't gather this item " + iItem.Name + " (see " + iItem.UrlGarland + ")" + Environment.NewLine;
                            }
                        }
                    }
                    else
                    {
                        errorContent += "//    - " + quantity + "x " + iItem.Name + " (see " + iItem.UrlGarland + ")" + Environment.NewLine;
                        fullScenario += "// Failed to log into miqobot forums, can't gather this item " + iItem.Name + " (see " + iItem.UrlGarland + ")" + Environment.NewLine;
                    }
                }
            }
            fullScenario += "\",";

            //Crafting stuff
            Service_Misc.LogText(iLogBox, "Generating craft scenario...");
            fullScenario += "\"";
            fullScenario += Environment.NewLine;
            fullScenario += Environment.NewLine;
            fullScenario += "// Crafted Items" + Environment.NewLine;
            fullScenario += "//--------------------------------------------------------------" + Environment.NewLine;
            fullScenario += "//" + Environment.NewLine;
            fullScenario += "solverPreset(" + iOptions.CraftPreset + ")" + Environment.NewLine;
            fullScenario += "nqhq(" + iOptions.NQHQPreset + ")" + Environment.NewLine;
            fullScenario += "reclaimOff()" + Environment.NewLine;

            string teleportCraft = iOptions.CustomTeleport;

            if (teleportCraft != "")
            {
                fullScenario += "teleport(" + teleportCraft + ")" + Environment.NewLine;
            }

            List <FFXIVCraftedItem> listAllCraftedItems = new List <FFXIVCraftedItem>();

            for (int i = 0; i < allItems.Count && i < allItemsQuantity.Count; i++)
            {
                FFXIVItem iItem = allItems[i];
                if (null == iItem)
                {
                    continue;
                }
                int quantity = allItemsQuantity[i];
                FFXIVCraftedItem craftedItem = null;
                if (iItem is FFXIVCraftedItem)
                {
                    craftedItem = iItem as FFXIVCraftedItem;
                }
                if (null != craftedItem)
                {
                    listAllCraftedItems.Add(craftedItem);
                }
            }
            for (int i = 0; i < allItems.Count && i < allItemsQuantity.Count; i++)
            {
                FFXIVItem iItem = allItems[i];
                if (null == iItem)
                {
                    continue;
                }
                int quantity = allItemsQuantity[i];
                FFXIVCraftedItem craftedItem = null;
                if (iItem is FFXIVCraftedItem)
                {
                    craftedItem = iItem as FFXIVCraftedItem;
                }
                FFXIVCraftingOptions itemOptions = options.GetOption(iItem);
                if (null != itemOptions && itemOptions.IgnoreItem)
                {
                    continue;
                }

                if (null != craftedItem)
                {
                    fullScenario += "// " + craftedItem + Environment.NewLine;

                    int indexCraftedItem = listAllCraftedItems.IndexOf(craftedItem);
                    if (listAllCraftedItems.IndexOf(craftedItem) >= listAllCraftedItems.Count - 1 && iOptions.Collectable)
                    {
                        fullScenario += "setCraftCollect(on)" + Environment.NewLine;
                    }
                    else
                    {
                        fullScenario += "setCraftCollect(off)" + Environment.NewLine;
                    }

                    fullScenario += "job(" + craftedItem.Class + ")" + Environment.NewLine;
                    fullScenario += "recipe(" + craftedItem.Name + ")" + Environment.NewLine;

                    if (null != itemOptions && itemOptions.CustomCraftingMacro != "")
                    {
                        fullScenario += "selectCraftMacro(" + itemOptions.CustomCraftingMacro + ")" + Environment.NewLine;
                    }

                    fullScenario += "craft(" + quantity + ")" + Environment.NewLine;

                    if (listAllCraftedItems.IndexOf(craftedItem) >= listAllCraftedItems.Count - 1 && iOptions.Collectable)
                    {
                        fullScenario += "setCraftCollect(off)" + Environment.NewLine;
                    }

                    if (null != itemOptions && itemOptions.CustomCraftingMacro != "")
                    {
                        fullScenario += "solverPreset(" + iOptions.CraftPreset + ")" + Environment.NewLine;
                    }
                    fullScenario += Environment.NewLine;
                }
            }
            fullScenario += "\"";

            if (errorContent == "")
            {
                fullScenario = fullScenario.Replace("ERRORS_ITEMS_DUMMY", "");
            }
            else
            {
                string scenarioError = "";
                scenarioError += Environment.NewLine;
                scenarioError += Environment.NewLine;
                scenarioError += "// Items without grid / Miqocrafter couldn't automate" + Environment.NewLine;
                scenarioError += "//--------------------------------------------------------------" + Environment.NewLine;
                scenarioError += "//" + Environment.NewLine;
                scenarioError += "// You will need to buy or obtain those items using external means, cause Miqocrafter can't automate it [Yet]" + Environment.NewLine;
                scenarioError += errorContent;
                scenarioError += Environment.NewLine;
                fullScenario   = fullScenario.Replace("ERRORS_ITEMS_DUMMY", scenarioError);
            }

            string textFileContent = "scenario.Craft " + scenarioName + Environment.NewLine;

            textFileContent += "{ \"chapters\":[";
            textFileContent += fullScenario.Replace(Environment.NewLine, "\\r\\n").Replace("/", "\\/");
            textFileContent += "]}" + Environment.NewLine;

            textFileContent += allRotations + Environment.NewLine;
            textFileContent += allGrids + Environment.NewLine;
            textFileContent += allPreset + Environment.NewLine;

            while (textFileContent.Contains(Environment.NewLine + Environment.NewLine))
            {
                textFileContent = textFileContent.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
            }

            return(textFileContent);
        }