void AddNodeBonuses(dynamic node, Saint.GatheringPoint sGatheringPoint) { if (sGatheringPoint.GatheringPointBonus.Length == 0) { return; } if (node.bonus == null) { node.bonus = new JArray(); } JArray bonuses = node.bonus; foreach (var sGatheringPointBonus in sGatheringPoint.GatheringPointBonus) { if (!bonuses.Any(j => (int)j == sGatheringPointBonus.Key)) { bonuses.Add(sGatheringPointBonus.Key); } } }
void AddPointToNode(dynamic node, Saint.GatheringPoint sGatheringPoint) { // Add subpoint to the node dynamic point = new JObject(); point.id = sGatheringPoint.Key; point.count = sGatheringPoint.AsInt32("Count"); var sGatheringPointTransient = _transientById[sGatheringPoint.Key]; var sStartTime = sGatheringPointTransient.As <UInt16>("EphemeralStartTime"); var sEndTime = sGatheringPointTransient.As <UInt16>("EphemeralEndTime"); var sTimeTable = sGatheringPointTransient["GatheringRarePopTimeTable"]; if (sStartTime != 65535 && !(sEndTime == 0 && sStartTime == 0)) { node.limitType = "Ephemeral"; if (sEndTime == 0) { sEndTime = 2400; } point.times = new JArray() { sStartTime / 100 }; point.uptime = ((sEndTime / 100) - (sStartTime / 100)) * 60; } else if (sTimeTable != null && ((Saint.XivRow)sTimeTable).Key != 0) { node.limitType = "Unspoiled"; var sTimeTableRow = sTimeTable as Saint.XivRow; var times = new JArray(); for (int i = 0; i < 3; i++) { if (sTimeTableRow.As <UInt16>($"StartTime[{i}]") != 65535) { times.Add(sTimeTableRow.As <UInt16>($"StartTime[{i}]") / 100); } else { break; } } // All three duration is same, we just take first one. var sUptime = sTimeTableRow.As <UInt16>("Duration(m)[0]"); // This is confusing switch (sUptime) { case 300: point.uptime = 180; break; case 160: point.uptime = 120; break; case 0: break; default: DatabaseBuilder.PrintLine($"Bad duration time {sUptime} for node {node.name}."); break; } if (times.Count > 0) { point.times = times; } } // Add coords for point if (_levelByGatheringPointId.TryGetValue(sGatheringPoint.Key, out var sLevel)) { if (sLevel.Map.Key != 0) { point.zoneid = sLevel.Map.PlaceName.Key; point.coords = new JArray() { sLevel.MapX, sLevel.MapY }; } } node.points.Add(point); }
dynamic BuildNode(Saint.GatheringPoint sGatheringPoint, dynamic lastNode) { dynamic node = new JObject(); node.id = sGatheringPoint.Base.Key; node.name = "Node"; node.patch = PatchDatabase.Get("node", sGatheringPoint.Base.Key); node.type = sGatheringPoint.Base.Type.Key; node.lvl = sGatheringPoint.Base.GatheringLevel; node.points = new JArray(); node.items = new JArray(); AddPointToNode(node, sGatheringPoint); if (sGatheringPoint.Base.IsLimited) { node.limited = 1; } // Special case for concealed nodes - take the name of the last node, // as these are in order in the files. var nameModifier = (byte)sGatheringPoint[0]; if (nameModifier == 6) { node.limitType = "Concealed"; node.name = lastNode.name; } // Folklore books dynamic folkloreItem = null; if (sGatheringPoint.GatheringSubCategory != null && _builder.Db.ItemsById.ContainsKey(sGatheringPoint.GatheringSubCategory.Item.Key)) { folkloreItem = _builder.Db.ItemsById[sGatheringPoint.GatheringSubCategory.Item.Key]; if (folkloreItem.unlocks == null) { folkloreItem.unlocks = new JArray(); } node.unlockId = sGatheringPoint.GatheringSubCategory.Item.Key; _builder.Db.AddReference(node, "item", sGatheringPoint.GatheringSubCategory.Item.Key, false); } // Items var sGatheringItemBases = sGatheringPoint.Base.Items .Where(gi => gi != null && gi.Key != 0 && gi.Item is Saint.Item) .ToArray(); if (sGatheringItemBases.Length == 0) { return(null); } int maxStars = 0; foreach (var sGatheringItemBase in sGatheringItemBases) { var sGatheringItemLevelConvertTable = (Saint.XivRow)sGatheringItemBase["GatheringItemLevel"]; var stars = (byte)sGatheringItemLevelConvertTable["Stars"]; maxStars = Math.Max(stars, maxStars); var sItem = sGatheringItemBase.Item; dynamic nodeItem = new JObject(); nodeItem.id = sItem.Key; node.items.Add(nodeItem); if (folkloreItem != null) { var folkloreItemId = (int)folkloreItem.id; var item = _builder.Db.ItemsById[sItem.Key]; item.unlockId = folkloreItemId; folkloreItem.unlocks.Add(sItem.Key); _builder.Db.AddReference(folkloreItem, "item", sItem.Key, false); _builder.Db.AddReference(item, "item", folkloreItemId, false); } } if (maxStars > 0) { node.stars = maxStars; } // Lookup coordinates for spearfishing nodes. if (sGatheringPoint.Base.Type.Key == 4) { foreach (var sSpearfishingNotebook in _builder.Sheet("SpearfishingNotebook")) { var sGatheringPointBase = (Saint.XivRow)sSpearfishingNotebook["GatheringPointBase"]; if (sGatheringPointBase == null || sGatheringPointBase.Key != sGatheringPoint.Base.Key) { continue; } node.name = Utils.SanitizeTags(sSpearfishingNotebook.As <Saint.PlaceName>().Name); node.radius = sSpearfishingNotebook.AsInt32("Radius"); var sTerritoryType = sSpearfishingNotebook.As <Saint.TerritoryType>(); node.coords = new JArray { Math.Round(sTerritoryType.Map.ToMapCoordinate2d(sSpearfishingNotebook.AsInt32("X"), 0), 2), Math.Round(sTerritoryType.Map.ToMapCoordinate2d(sSpearfishingNotebook.AsInt32("Y"), 0), 2) }; break; } string keyName = node.name; if (keyName == "Node") { keyName = "Node #" + (int)node.id; } _builder.Db.SpearfishingNodesByName[keyName] = node; } // Store and return! _builder.Db.Nodes.Add(node); _builder.Db.NodesById[sGatheringPoint.Base.Key] = node; return(node); }