/// <summary>Looks at a player's future segments.</summary> public Element IsTravelingToSegment(ActionSet actionSet, Element targetPlayer, Element segment) { IndexReference result = actionSet.VarCollection.Assign("Lookahead: Result", actionSet.IsGlobal, true); actionSet.AddAction(result.SetVariable(new V_False())); IndexReference look = actionSet.VarCollection.Assign("Pathfind: Lookahead", actionSet.IsGlobal, true); actionSet.AddAction(look.SetVariable(Current.Get(targetPlayer))); // Get the path. actionSet.AddAction(Element.Part <A_While>(Element.Part <V_And>(new V_Compare( ParentArray.Get(targetPlayer)[look.Get()] - 1, Operators.GreaterThanOrEqual, new V_Number(0) ), !result.Get()))); Element currentNode = PathmapInstance.Nodes.Get()[PathmapReference.Get(targetPlayer)][look.Get()]; Element nextNode = PathmapInstance.Nodes.Get()[PathmapReference.Get(targetPlayer)][ParentArray.Get(targetPlayer)[look.Get()] - 1]; actionSet.AddAction(result.SetVariable(new V_Compare( segment, Operators.Equal, Element.Part <V_FirstOf>(PathmapInstance.SegmentsFromNodes(PathmapReference.Get(targetPlayer), look.Get(), ParentArray.Get(targetPlayer)[look.Get()] - 1)) ))); actionSet.AddAction(look.SetVariable(ParentArray.Get(targetPlayer)[look.Get()] - 1)); actionSet.AddAction(new A_End()); return(result.Get()); }
void GetNextNodeRule() { // The 'next' rule will set current to the next node index when the current node is reached. TranslateRule next = new TranslateRule(DeltinScript, "Pathfinder: Resolve Next", RuleEvent.OngoingPlayer); next.Conditions.Add(NodeReachedCondition(next.ActionSet)); next.Conditions.Add(new Condition(ParentArray.Get(), Operator.NotEqual, Element.Null())); GetNextNode(next.ActionSet, EventPlayer()); // Loop the next rule if the condition is true. next.ActionSet.AddAction(LoopIfConditionIsTrue()); // Add rule DeltinScript.WorkshopRules.Add(next.GetRule()); }
public void GetNextNode(ActionSet actionSet, Element player) { if (OnPathCompleted == null || !OnPathCompleted.EmptyBlock) { actionSet.AddAction(If(Compare(Current.Get(player), Operator.NotEqual, Num(-1)))); } // Get last attribute. actionSet.AddAction(CurrentAttribute.SetVariable(GetCurrentSegmentAttribute(player), targetPlayer: player)); if (TrackNextAttribute) { actionSet.AddAction(NextAttribute.SetVariable(GetNextSegmentAttribute(player), targetPlayer: player)); } // Set current as the current's parent. actionSet.AddAction(Current.SetVariable(ParentArray.Get(player)[Current.Get(player)] - 1, targetPlayer: player)); // Update stuck UpdateStuckDetector(actionSet, player); // Invoke OnNodeReached OnNodeReached?.Invoke(actionSet); if (OnPathCompleted == null || !OnPathCompleted.EmptyBlock) { actionSet.AddAction(Else()); } if (OnPathCompleted == null) { actionSet.AddAction(Part("Stop Throttle In Direction", player)); StopPathfinding(actionSet, player); } else if (!OnPathCompleted.EmptyBlock) { OnPathCompleted.Invoke(actionSet); } if (OnPathCompleted == null || !OnPathCompleted.EmptyBlock) { actionSet.AddAction(End()); } }
/// <summary>Looks at a player's future nodes.</summary> public Element IsTravelingToAttribute(ActionSet actionSet, Element targetPlayer, Element attribute) { IndexReference result = actionSet.VarCollection.Assign("Lookahead: Result", actionSet.IsGlobal, true); actionSet.AddAction(result.SetVariable(new V_False())); IndexReference look = actionSet.VarCollection.Assign("Pathfind: Lookahead", actionSet.IsGlobal, true); actionSet.AddAction(look.SetVariable(Current.Get(targetPlayer))); // Get the path. actionSet.AddAction(Element.Part <A_While>(Element.Part <V_And>(new V_Compare( look.GetVariable(), Operators.GreaterThanOrEqual, new V_Number(0) ), !result.Get()))); actionSet.AddAction(result.SetVariable(new V_Compare(attribute, Operators.Equal, AttributeArray.Get(targetPlayer)[look.Get()]))); actionSet.AddAction(look.SetVariable(ParentArray.Get(targetPlayer)[look.Get()] - 1)); actionSet.AddAction(new A_End()); return(result.Get()); }
private void GetResolveRoutine() { // Create the rule that will get the closest node. TranslateRule getResolveRule = new TranslateRule(DeltinScript, "Pathfinder: Resolve Current", RuleEvent.OngoingPlayer); // The rule will activate when DoGetCurrent is set to true. getResolveRule.Conditions.Add(new Condition((Element)DoGetCurrent.GetVariable(), Operators.Equal, new V_True())); // Set the Current variable to the closest node. getResolveRule.ActionSet.AddAction(Current.SetVariable(ClosestNode(getResolveRule.ActionSet, PlayerPosition()))); // If the OnPathStart hook is null, do the default which is throttling the player to the next node. if (OnPathStart == null) { // Start throttle to the current node. ThrottleEventPlayerToNextNode(getResolveRule.ActionSet); } // Otherwise, use the hook. else { OnPathStart.Invoke(getResolveRule.ActionSet); } // Update IsPathfindStuck data. UpdateStuckDetector(getResolveRule.ActionSet); // Reset DoGetCurrent to false. getResolveRule.ActionSet.AddAction(DoGetCurrent.SetVariable(new V_False())); // Add the rule. DeltinScript.WorkshopRules.Add(getResolveRule.GetRule()); // Resolve the rule that increments the current node. // The 'next' rule will set current to the next node index when the current node is reached. TranslateRule next = new TranslateRule(DeltinScript, "Pathfinder: Resolve Next", RuleEvent.OngoingPlayer); next.Conditions.Add(NodeReachedCondition(next.ActionSet)); next.Conditions.Add(new Condition(ParentArray.Get(), Operators.NotEqual, new V_Null())); if (OnPathCompleted == null || !OnPathCompleted.EmptyBlock) { next.ActionSet.AddAction(Element.Part <A_If>(new V_Compare(Current.Get(), Operators.NotEqual, new V_Number(-1)))); } // Get last attribute. next.ActionSet.AddAction(CurrentAttribute.SetVariable(NextSegmentAttribute(new V_EventPlayer()))); // Set current as the current's parent. next.ActionSet.AddAction(Current.SetVariable(ParentArray.Get()[Current.Get()] - 1)); // Update stuck UpdateStuckDetector(next.ActionSet); // Invoke OnNodeReached OnNodeReached?.Invoke(next.ActionSet); if (OnPathCompleted == null || !OnPathCompleted.EmptyBlock) { next.ActionSet.AddAction(Element.Part <A_Else>()); } if (OnPathCompleted == null) { next.ActionSet.AddAction(Element.Part <A_StopThrottleInDirection>(new V_EventPlayer())); StopPathfinding(next.ActionSet, new V_EventPlayer()); } else if (!OnPathCompleted.EmptyBlock) { OnPathCompleted.Invoke(next.ActionSet); } if (OnPathCompleted == null || !OnPathCompleted.EmptyBlock) { next.ActionSet.AddAction(Element.Part <A_End>()); } // Add rule DeltinScript.WorkshopRules.Add(next.GetRule()); }
/// <summary>Gets the next pathfinding attribute.</summary> // public Element NextSegmentAttribute(Element player) => Element.TernaryConditional( // Element.Part<V_And>(IsPathfinding(player), new V_Compare(Current.GetVariable(player), Operators.NotEqual, new V_Number(-1))), // AttributeArray.Get(player)[Current.Get(player)], // new V_Number(-1) // ); public Element NextSegmentAttribute(Element player) => Element.Part <V_MappedArray>(Element.Part <V_FilteredArray>( PathmapInstance.Attributes.Get()[PathmapReference.Get(player)], Element.Part <V_And>( new V_Compare(Element.Part <V_XOf>(Element.Part <V_ArrayElement>()), Operators.Equal, Current.Get(player)), new V_Compare(Element.Part <V_YOf>(Element.Part <V_ArrayElement>()), Operators.Equal, ParentArray.Get()[Current.Get()] - 1) ) ), Element.Part <V_ZOf>(Element.Part <V_ArrayElement>()));
Element GetNextSegmentAttribute(Element player) => Element.Map(Element.Filter( PathmapInstance.Attributes.Get(_toWorkshop, PathmapReference.Get(player)), Element.And( Element.Compare(Element.XOf(Element.ArrayElement()), Operator.Equal, ParentArray.Get(player)[Current.Get(player)] - 1), Element.Compare(Element.YOf(Element.ArrayElement()), Operator.Equal, ParentArray.Get(player)[ParentArray.Get(player)[Current.Get(player)] - 1] - 1) ) ), Element.ZOf(Element.ArrayElement()));
public Element NextPositionWithDestination(Element player = null) => PositionAtOrDestination(ParentArray.Get(player)[Current.GetVariable(player)] - 1, player);