Last active
January 20, 2026 18:13
-
-
Save Seb105/140b49394c96ed993531c07a85164d84 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public static BuildTask Heal() => () => { | |
| StrongBox<VehicleTaskManager.ChainHealPoint?> healPoint = new(); | |
| VehicleBody? GetVehicle(AITask _) => healPoint.Value?.Vehicle; | |
| Vector3 GetPos(AITask _) => healPoint.Value?.Healer.Component.GlobalPosition ?? Vector3.Zero; | |
| IInteractable? HealPoint(AITask _) => healPoint.Value?.Healer.Interactable; | |
| return Fallback("Heal", [ | |
| Periodic(Task("Is full health?", | |
| task => task.Character.DamageComponent.Hitpoints.Proportion.EqualsApprox(1) | |
| ? TaskResult.Success | |
| : TaskResult.Fail) | |
| ), | |
| Sequence("Heal", [ | |
| Periodic(Task("Locate healer", task => { | |
| var character = task.Character; | |
| var pos = character.GlobalPosition; | |
| healPoint.Value = task.Manager.HealPointsInChain | |
| .Where(x => x.Healer.Interactable.InteractionAllowed(character)) | |
| .OrderBy(x => x.Healer.Component.GlobalPosition.DistanceSquaredTo(pos)) | |
| .FirstOrDefault(); | |
| return healPoint.Value is not null ? TaskResult.Success : TaskResult.Fail; | |
| })), | |
| GotoAndInteract(GetPos, HealPoint, GetVehicle), | |
| ]), | |
| ])(); | |
| }; | |
| public static BuildTask GotoAndInteract( | |
| Func<AITask, Vector3> getPos, | |
| Func<AITask, IInteractable?> interactable, | |
| Func<AITask, VehicleBody?> getVehicle, | |
| Func<AITask, bool>? shouldInteract = null) => () => { | |
| shouldInteract ??= _ => true; | |
| // var interactionAllowed = InteractionAllowed(interactable); | |
| return Fallback("Go to interaction point and interact", [ | |
| SuccessCooldown(Task("Try interact with", task => { | |
| var interactableValue = interactable(task); | |
| if (interactableValue is not null) { | |
| if (shouldInteract(task)) { | |
| task.CharInput.Aiming.LookAtNode(interactableValue.Node); | |
| return task.CharInput.TryInteractWith(interactableValue) ? TaskResult.Success : TaskResult.Fail; | |
| } else { | |
| // Fail so we still try to go to the interaction point | |
| // Should interact is evaluated after the go to point | |
| return TaskResult.Fail; | |
| } | |
| } else { | |
| task.Character.PushError("Interactable is null"); | |
| return TaskResult.Fail; | |
| } | |
| })), | |
| Sequence("Go to and interact", [ | |
| GoToPosition(getPos, getVehicle), | |
| Task("Should interact", task => shouldInteract(task) ? TaskResult.Success : TaskResult.Running), | |
| Task("Failed to interact", task => { | |
| var interactableObj = interactable(task)!; | |
| var isInRange = task.Character.Interaction.InRangeOf(interactableObj); | |
| var canInteract = interactableObj.InteractionAllowed(task.Character); | |
| if (isInRange && canInteract) { | |
| task.Assigned.Character.Log( | |
| "Failed interact even though is in range and should be able to. This should be unreachable!", | |
| LoggingLevel.Warning); | |
| return TaskResult.Fail; | |
| } | |
| if (isInRange) { | |
| task.Assigned.Character.Log( | |
| "Interaction is not allowed even though we're in range", LoggingLevel.Warning); | |
| return TaskResult.Fail; | |
| } | |
| if (canInteract) { | |
| task.Assigned.Character.Log("Reached interaction point but still can't interact", | |
| LoggingLevel.Warning); | |
| return TaskResult.Fail; | |
| } | |
| task.Assigned.Character.Log("Failed to interact. This error should be unreachable", | |
| LoggingLevel.Warning); | |
| return TaskResult.Fail; | |
| }), | |
| ]), | |
| ])(); | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment