Skip to content

Instantly share code, notes, and snippets.

@Seb105
Last active January 20, 2026 18:13
Show Gist options
  • Select an option

  • Save Seb105/140b49394c96ed993531c07a85164d84 to your computer and use it in GitHub Desktop.

Select an option

Save Seb105/140b49394c96ed993531c07a85164d84 to your computer and use it in GitHub Desktop.
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