/// <summary>Adds +1 Mastery Nodes to end of Selected Mastery stats before applying to node</summary> /// <param name="node">The node.</param> /// <param name="selectedStats">The array of Displayed Stats</param> /// <param name="EffectId">The effect identifier.</param> public static void ApplyMasterySelectionStats(PassiveNodeViewModel node, string[] selectedStats, ushort EffectId) { int LastIndex = selectedStats.Length; int FinalSize = LastIndex + 1; System.Array.Resize(ref selectedStats, FinalSize); selectedStats[LastIndex] = "+1 Mastery Nodes"; node.SetDescription(ref selectedStats); node.Attributes.Clear(); node.InitializeAttributes(); node.ForceChangeSkill(EffectId); }
public void UnhighlightNode(PassiveNodeViewModel node, HighlightState removeFlags) { if (_nodeHighlights.ContainsKey(node)) { // Each flag only remains set if it's not one of the flags to be removed. HighlightState newState = _nodeHighlights[node] & ~removeFlags; if (newState == 0) { _nodeHighlights.Remove(node); } else { _nodeHighlights[node] = newState; } } }
private void Draw(DrawingContext context, PassiveNodeViewModel node) { var rect = _icons.SkillPositions[node.IconKey]; var image = _icons.GetSkillImage(node.IconKey); var imageBrush = new ImageBrush { Stretch = Stretch.Uniform, ImageSource = image, ViewboxUnits = BrushMappingMode.RelativeToBoundingBox, Viewbox = new Rect(rect.X / image.PixelWidth, rect.Y / image.PixelHeight, rect.Width / image.PixelWidth, rect.Height / image.PixelHeight) }; var radius = Math.Sqrt((rect.Width * rect.Height) / Math.PI); context.DrawEllipse(imageBrush, null, node.Position, radius, radius); }
public void HighlightNode(PassiveNodeViewModel node, HighlightState newFlags) { var flags = CleanFlags(node, newFlags); if (flags == 0) { return; } if (_nodeHighlights.ContainsKey(node)) { _nodeHighlights[node] |= flags; } else { _nodeHighlights.Add(node, flags); } }
/// <summary> /// Calculates the total of unallocated target attributes inside jewel area. /// </summary> /// <param name="TargetNode">The target node.</param> /// <param name="AttributeName">Name of Attribute to search for</param> /// <param name="SkilledNodes">The skilled nodes.</param> /// <param name="JewelRadiusType">Jewel Radius Type(Large/Medium/Small)(Default:Large"")</param> /// <returns></returns> static public float CalculateTotalUnallocAttributeInJewelArea(PassiveNodeViewModel TargetNode, string AttributeName, Dictionary <ushort, PassiveNodeViewModel> SkilledNodes, Engine.GameModel.Items.JewelRadius JewelArea = Engine.GameModel.Items.JewelRadius.Large) { float AttributeTotal = 0.0f; IEnumerable <PassiveNodeViewModel>?affectedNodes; var radius = Engine.GameModel.Items.JewelRadiusExtensions.GetRadius(JewelArea, TargetNode.ZoomLevel); affectedNodes = SkilledNodes.Values .Where(n => !n.IsRootNode && !n.IsAscendancyNode) .Where(n => Distance(n.Position, TargetNode.Position) <= radius * 1.2f); foreach (var n in affectedNodes) { if (n.Attributes.ContainsKey(AttributeName) && !SkilledNodes.ContainsValue(n)) { AttributeTotal += n.Attributes[AttributeName][0]; } } return(AttributeTotal); }
private void Draw(DrawingContext context, PassiveNodeViewModel node) { if (!node.IconKey.Contains("Connected")) { return; } if (!_icons.SkillPositions.ContainsKey(node.IconKey)) { return; } var rect = _icons.SkillPositions[node.IconKey]; var radius = Math.Sqrt((rect.Width * rect.Height) / Math.PI); var buttonKey = $"Passive{node.PassiveNodeType}ConnectedButton"; if (_connectedAssets.ContainsKey(buttonKey)) { var connected = _connectedAssets["PassiveMasteryConnectedButton"]; var connectedImageBrush = new ImageBrush { Stretch = Stretch.Uniform, ImageSource = connected, Viewbox = new Rect(0, 0, 1, 1) }; context.DrawEllipse(connectedImageBrush, null, node.Position, connected.PixelWidth * SkillTree.PoESkillTree.MaxImageZoomLevel * 1.5, connected.PixelHeight * SkillTree.PoESkillTree.MaxImageZoomLevel * 1.5); } var image = _icons.GetSkillImage(node.IconKey); var imageBrush = new ImageBrush { Stretch = Stretch.Uniform, ImageSource = image, ViewboxUnits = BrushMappingMode.RelativeToBoundingBox, Viewbox = new Rect(rect.X / image.PixelWidth, rect.Y / image.PixelHeight, rect.Width / image.PixelWidth, rect.Height / image.PixelHeight) }; context.DrawEllipse(imageBrush, null, node.Position, radius, radius); }
// Builds a graph from an adjacency matrix. // Only the lower left half is checked. private static SearchGraph SearchGraphFromData(bool[,] adjacencyMatrix) { int n = adjacencyMatrix.GetUpperBound(0) + 1; // Don't screw this up. Assert.IsTrue(n == adjacencyMatrix.GetUpperBound(1) + 1); List <PassiveNodeViewModel> nodes = new List <PassiveNodeViewModel>(); for (ushort i = 0; i < n; i++) { var node = new PassiveNodeViewModel(i); nodes.Add(node); } for (int i = 0; i < n; i++) { for (int j = 0; j < i; j++) { if (adjacencyMatrix[i, j]) { nodes[i].NeighborPassiveNodes[nodes[j].Id] = nodes[j]; // No directed edges atm. nodes[j].NeighborPassiveNodes[nodes[i].Id] = nodes[i]; } } } SearchGraph graph = new SearchGraph(); foreach (PassiveNodeViewModel node in nodes) { graph.AddNode(node); } return(graph); }
private void CheckLinks(PassiveNodeViewModel node) { if (!NodeDict.ContainsKey(node)) { return; } GraphNode currentNode = NodeDict[node]; foreach (var neighbor in node.NeighborPassiveNodes.Values) { if (NodeDict.ContainsKey(neighbor)) { GraphNode adjacentNode = NodeDict[neighbor]; if (adjacentNode == currentNode) { continue; } adjacentNode.AddNeighbor(currentNode); currentNode.AddNeighbor(adjacentNode); } } }
private IReadOnlyList <Modifier> ParseSkilledNode(PassiveNodeViewModel node) => _parser.ParseSkilledPassiveNode(node.Id).Modifiers;
/// <summary> /// Override to exclude node from the search graph with additional conditions. /// </summary> /// <param name="node">The node in question (not null)</param> /// <returns>false if not overriden</returns> protected virtual bool IncludeNodeInSearchGraph(PassiveNodeViewModel node) { return(true); }
/// <summary> /// Override to force including node groups into the search graph with additional conditions. /// </summary> /// <param name="node">The node in question (not null)</param> /// <returns>true if not overriden</returns> protected virtual bool MustIncludeNodeGroup(PassiveNodeViewModel node) { return(false); }
public static void SetMasteryLabel(PassiveNodeViewModel node) { //19 Count if (node.Name.StartsWith("Life")) { node.SetDescriptionWithStats(ref LifeMDesc, ref LifeMAttributes); } //9 Count else if (node.Name.StartsWith("Mana") && !node.Attributes.ContainsKey(ManaMStat)) { node.SetDescriptionWithStats(ref ManaMDesc, ref ManaMAttributes); } //8 Count else if (node.Name.StartsWith("Attack")) { node.SetDescriptionWithStats(ref AttackMDesc, ref AttackMAttributes); } else if (node.Name.StartsWith("Flask")) { node.SetDescriptionWithStats(ref FlaskMDesc, ref FlaskMAttributes); } else if (node.Name.StartsWith("Leech")) { node.SetDescriptionWithStats(ref LeechMDesc, ref LeechMAttributes); } else if (node.Name.StartsWith("Caster")) { node.SetDescriptionWithStats(ref CasterMDesc, ref CasterMAttributes); } else if (node.Name.StartsWith("Minion Offence")) { node.SetDescriptionWithStats(ref MinionAttackMDesc, ref MinionAttackMAttributes); } //7 Count else if (node.Name.StartsWith("Critical")) { node.SetDescriptionWithStats(ref CritMDesc, ref CritMAttributes); } else if (node.Name.StartsWith("Fire") && !node.Attributes.ContainsKey(FireMStat)) { node.SetDescriptionWithStats(ref FireMDesc, ref FireMAttributes); } //6 Count else if (node.Name.StartsWith("Elemental")) { node.SetDescriptionWithStats(ref ElemMDesc, ref ElemMAttributes); } else if (node.Name.StartsWith("Energy Shield")) { node.SetDescriptionWithStats(ref ESMDesc, ref ESMAttributes); } else if (node.Name.StartsWith("Physical")) { node.SetDescriptionWithStats(ref PhysicalMDesc, ref PhysicalMAttributes); } else if (node.Name.StartsWith("Mine")) { node.SetDescriptionWithStats(ref MineMDesc, ref MineMAttributes); } else if (node.Name.StartsWith("Reservation")) { node.SetDescriptionWithStats(ref AuraMDesc, ref AuraMAttributes); } else if (node.Name.StartsWith("Totem")) { node.SetDescriptionWithStats(ref TotemMDesc, ref TotemMAttributes); } else if (node.Name.StartsWith("Resistance")) { node.SetDescriptionWithStats(ref ResMDesc, ref ResMAttributes); } //5 Count else if (node.Name.StartsWith("Armour")) { node.SetDescriptionWithStats(ref ArmourMDesc, ref ArmourMAttributes); } else if (node.Name.StartsWith("Minion Defence")) { node.SetDescriptionWithStats(ref MinionDefMDesc, ref MinionDefMAttributes); } else if (node.Name.StartsWith("Cold")) { node.SetDescriptionWithStats(ref ColdMDesc, ref ColdMAttributes); } else if (node.Name.StartsWith("Curse")) { node.SetDescriptionWithStats(ref CurseMDesc, ref CurseMAttributes); } else if (node.Name.StartsWith("Bow")) { node.SetDescriptionWithStats(ref BowMDesc, ref BowMAttributes); } else if (node.Name.StartsWith("Evasion")) { node.SetDescriptionWithStats(ref EvasionMDesc, ref EvasionMAttributes); } else if (node.Name.StartsWith("Mace")) { node.SetDescriptionWithStats(ref MaceMDesc, ref MaceMAttributes); } else if (node.Name.StartsWith("Shield")) { node.SetDescriptionWithStats(ref ShieldMDesc, ref ShieldMAttributes); } else if (node.Name.StartsWith("Staff")) { node.SetDescriptionWithStats(ref StaffMDesc, ref StaffMAttributes); } else if (node.Name.StartsWith("Trap")) { node.SetDescriptionWithStats(ref TrapMDesc, ref TrapMAttributes); } //4 Count else if (node.Name.StartsWith("Accuracy")) { node.SetDescriptionWithStats(ref HitMDesc, ref HitMAttributes); } else if (node.Name.StartsWith("Wand")) { node.SetDescriptionWithStats(ref WandMDesc, ref WandMAttributes); } else if (node.Name.StartsWith("Dagger")) { node.SetDescriptionWithStats(ref DaggerMDesc, ref DaggerMAttributes); } else if (node.Name.StartsWith("Poison")) { node.SetDescriptionWithStats(ref PoisonMDesc, ref PoisonMAttributes); } else if (node.Name.StartsWith("Charge")) { node.SetDescriptionWithStats(ref ChargeMDesc, ref ChargeMAttributes); } else if (node.Name.StartsWith("Claw")) { node.SetDescriptionWithStats(ref ClawMDesc, ref ClawMAttributes); } else if (node.Name.StartsWith("Lightning")) { node.SetDescriptionWithStats(ref LightMDesc, ref LightMAttributes); } else if (node.Name.StartsWith("Warcry")) { node.SetDescriptionWithStats(ref WarcryMDesc, ref WarcryMAttributes); } else if (node.Name.StartsWith("Axe")) { node.SetDescriptionWithStats(ref AxeMDesc, ref AxeMAttributes); } else if (node.Name.StartsWith("Sword")) { node.SetDescriptionWithStats(ref SwordMDesc, ref SwordMAttributes); } else if (node.Name.StartsWith("Two Hand")) { node.SetDescriptionWithStats(ref TwoHMDesc, ref TwoHMAttributes); } else if (node.Name.StartsWith("Damage Over Time")) { node.SetDescriptionWithStats(ref DOTMDesc, ref DOTMAttributes); } //3 Count else if (node.Name.StartsWith("Block")) { node.SetDescriptionWithStats(ref BlockMDesc, ref BlockMAttributes); } else if (node.Name.StartsWith("Chaos")) { node.SetDescriptionWithStats(ref ChaosMDesc, ref ChaosMAttributes); } else if (node.Name.StartsWith("Dual")) { node.SetDescriptionWithStats(ref DualMDesc, ref DualMAttributes); } else if (node.Name.StartsWith("Projectile")) { node.SetDescriptionWithStats(ref ProjMDesc, ref ProjMAttributes); } else if (node.Name.StartsWith("Attributes")) { node.SetDescriptionWithStats(ref StatMDesc, ref StatMAttributes); } else if (node.Name.StartsWith("Brand")) { node.SetDescriptionWithStats(ref BrandMDesc, ref BrandMAttributes); } else if (node.Name.StartsWith("Spell Suppression")) { node.SetDescriptionWithStats(ref SpellDefMDesc, ref SpellDefMAttributes); } else if (node.Name.StartsWith("Impale")) { node.SetDescriptionWithStats(ref ImpaleMDesc, ref ImpaleMAttributes); } //2 Count else if (node.Name.StartsWith("Armour and Energy Shield")) { node.SetDescriptionWithStats(ref ArmourESMDesc, ref ArmourESMAttributes); } else if (node.Name.StartsWith("Armour and Evasion")) { node.SetDescriptionWithStats(ref ArmourEvasionMDesc, ref ArmourEvasionMAttributes); } else if (node.Name.StartsWith("Evasion and Energy Shield")) { node.SetDescriptionWithStats(ref EvasionESMDesc, ref EvasionESMAttributes); } else if (node.Name.StartsWith("Fortify")) { node.SetDescriptionWithStats(ref FortifyMDesc, ref FortifyMAttributes); } else if (node.Name.StartsWith("Bleeding")) { node.SetDescriptionWithStats(ref BleedMDesc, ref BleedMAttributes); } else if (node.Name.StartsWith("Mark")) { node.SetDescriptionWithStats(ref MarkMDesc, ref MarkMAttributes); } else if (node.Name.StartsWith("Duration")) { node.SetDescriptionWithStats(ref LifeMDesc, ref DurationMAttributes); } else if (node.Name.StartsWith("Link")) { node.SetDescriptionWithStats(ref LinkMDesc, ref LinkMAttributes); } else if (node.Name.StartsWith("Blind")) { node.SetDescriptionWithStats(ref BlindMDesc, ref BlindMAttributes); } }
protected override bool IncludeNodeInSearchGraph(PassiveNodeViewModel node) { // Keystones can only be included if they are check-tagged. return(node.PassiveNodeType != PassiveNodeType.Keystone); }
protected override bool MustIncludeNodeGroup(PassiveNodeViewModel node) { // If the node has stats and is not a travel node, // the group is included. return(_nodeAttributes[node.Id].Count > 0 && !_areTravelNodes[node.Id]); }
/// <summary>Generates the slot description using PassiveNodeViewModels information from Skill Tree.</summary> /// <param name="NodeId">NodeID for target node</param> public void GenerateSlotDesc(ushort NodeId) { PassiveNodeViewModel NullNode = new PassiveNodeViewModel(0); PassiveNodeViewModel ClosestKeystone = NullNode; PassiveNodeViewModel ClosestNotable = NullNode; PassiveNodeViewModel CurrentNode = NullNode; Vector2D nodePosition; IEnumerable <KeyValuePair <ushort, PassiveNodeViewModel> > affectedNodes; double MinRange = 0.0; double MaxRange = 1200.0; double ClosestKSRange = 99999.0; double ClosestNotableRange = 99999.0; double range; nodePosition = SkillTree.Skillnodes[NodeId].Position; do { affectedNodes = SkillTree.Skillnodes.Where(n => (n.Value.Position - nodePosition).Length <MaxRange && (n.Value.Position - nodePosition).Length> MinRange).ToList(); //Need to update search code here foreach (KeyValuePair <ushort, PassiveNodeViewModel> NodePair in affectedNodes) { CurrentNode = NodePair.Value; if (CurrentNode.PassiveNodeType == PassiveNodeType.Notable) { range = (CurrentNode.Position - nodePosition).Length; if (range < ClosestNotableRange) { ClosestNotable = CurrentNode; ClosestNotableRange = range; } } else if (CurrentNode.PassiveNodeType == PassiveNodeType.Keystone) { range = (CurrentNode.Position - nodePosition).Length; if (range < ClosestKSRange) { ClosestKeystone = CurrentNode; ClosestKSRange = range; } } } if (ClosestNotable == NullNode || ClosestKeystone == NullNode) { MinRange = MaxRange; MaxRange += 600.0; } } while (ClosestNotable == null || ClosestKeystone == null); SlotDesc = "Closest Keystone to jewel-slot is " + ClosestKeystone.Name + "."; SlotDesc += "\nClosest Notable to jewel-slot is " + ClosestNotable.Name + "."; //Detect which class root node belongs to and then display it switch (JewelStatType)//Display Medium Jewel Threshold Type(if have 40+ of attribute(s)) { case ThresholdTypes.Strength: SlotDesc += "\n(Strength Threshold Slot)"; break; case ThresholdTypes.Intelligence: SlotDesc += "\n(Intelligence Threshold Slot)"; break; case ThresholdTypes.Dexterity: SlotDesc += "\n(Dexterity Threshold Slot)"; break; case ThresholdTypes.StrDexHybrid: SlotDesc += "\n(Str+Dex Threshold Slot)"; break; case ThresholdTypes.StrIntHybrid: SlotDesc += "\n(Str+Int Threshold Slot)"; break; case ThresholdTypes.IntDexHybrid: SlotDesc += "\n(Int+Dex Threshold Slot)"; break; case ThresholdTypes.OmniType: SlotDesc += "\n(Omni-Threshold Slot)"; break; default: SlotDesc += "\n(Neutral Threshold Slot)"; break; } }