Table of Contents

Class DefenderAttackingState

Namespace
FishMMO.Shared
Assembly
FishMMO.Shared.dll

Defender / tank archetype. Fights in melee, keeps its taunts on cooldown to hold threat, and physically interposes itself between the enemy and whoever it is protecting.

[CreateAssetMenu(fileName = "New AI Defender Attacking State", menuName = "FishMMO/Character/NPC/AI/Defender Attacking State", order = 5)]
public class DefenderAttackingState : BaseAttackingState, ICachedObject
Inheritance
Object
ScriptableObject
DefenderAttackingState
Implements
Inherited Members
ScriptableObject.SetDirty()
ScriptableObject.CreateInstance<T>()
Object.GetEntityId()
Object.GetInstanceID()
Object.GetHashCode()
Object.InstantiateAsync<T>(T)
Object.InstantiateAsync<T>(T, Transform)
Object.InstantiateAsync<T>(T, Vector3, Quaternion)
Object.InstantiateAsync<T>(T, Transform, Vector3, Quaternion)
Object.Instantiate(Object, Vector3, Quaternion)
Object.Instantiate(Object, Vector3, Quaternion, Transform)
Object.Instantiate(Object)
Object.Instantiate(Object, Scene)
Object.Instantiate<T>(T, InstantiateParameters)
Object.Instantiate<T>(T, Vector3, Quaternion, InstantiateParameters)
Object.Instantiate(Object, Transform)
Object.Instantiate<T>(T)
Object.Instantiate<T>(T, Vector3, Quaternion)
Object.Instantiate<T>(T, Vector3, Quaternion, Transform)
Object.Instantiate<T>(T, Transform)
Object.Destroy(Object)
Object.DestroyImmediate(Object)
Object.DontDestroyOnLoad(Object)
Object.DestroyObject(Object)
Object.FindObjectsOfType<T>()
Object.FindObjectsByType<T>(FindObjectsSortMode)
Object.FindObjectsByType<T>(FindObjectsInactive, FindObjectsSortMode)
Object.FindObjectOfType<T>()
Object.FindFirstObjectByType<T>()
Object.FindAnyObjectByType<T>()
Object.FindFirstObjectByType<T>(FindObjectsInactive)
Object.FindAnyObjectByType<T>(FindObjectsInactive)
Object.FindObjectsByType<T>()
Object.FindObjectsByType<T>(FindObjectsInactive)
Object.ToString()
Object.name
Object.hideFlags

Remarks

This needs code rather than tuning for two reasons: taunts have to be prioritised over raw damage regardless of what the scoring picker thinks, and body-blocking means walking to a position derived from a third character rather than from the target.

As a pet this is the "defender" stance made concrete — the pet plants itself between its owner and whatever is trying to reach them.

Fields

BlockRepositionTolerance

The defender only bothers repositioning when it is further than this from its ideal blocking spot. Prevents jitter.

[Tooltip("Only reposition when further than this from the ideal blocking spot.")]
public float BlockRepositionTolerance

Field Value

float

BlockStandoffDistance

How far in front of the protected character the defender plants itself, in world units.

[Tooltip("Distance in front of the protected character to hold the line.")]
public float BlockStandoffDistance

Field Value

float

BodyBlock

When true the defender positions itself on the line between the enemy and the character it is protecting, rather than simply closing on the enemy.

[Tooltip("Stand between the enemy and the protected character.")]
public bool BodyBlock

Field Value

bool

TauntAbilityTemplateIDs

Optional escape hatch: template IDs to treat as taunts in addition to whatever AIAbilityClassifier identifies.

[Header("Defender Behavior")]
[Tooltip("Optional. Extra AbilityTemplate IDs to force-treat as taunts. Normally empty — taunts are detected from the ability's ECA actions.")]
public List<int> TauntAbilityTemplateIDs

Field Value

List<int>

Remarks

Normally empty. A taunt is recognised by the threat-manipulating action in its own ECA graph — ApplyTauntAction or ApplyThreatAction — so a defender asset works for any creature whose spellbook contains one, and picks up a taunt added later without being edited.

Methods

Enter(AIController)

Called when entering the attacking state. Sets agent speed to run.

public override void Enter(AIController controller)

Parameters

controller AIController

The AI controller.

ExecutePlan(AIController, IAbilityController, ICharacter, AICombatPlan, in AICombatContext, Ability)

Holds the line in front of the protected character instead of simply walking at the enemy, when body-blocking is enabled and there is somebody to protect.

protected override void ExecutePlan(AIController controller, IAbilityController abilityController, ICharacter targetCharacter, AICombatPlan plan, in AICombatContext context, Ability chosenAbility)

Parameters

controller AIController

The AI controller.

abilityController IAbilityController

The NPC's ability controller.

targetCharacter ICharacter

The target character.

plan AICombatPlan

The decision to execute.

context AICombatContext

The context the decision was made from.

chosenAbility Ability

The ability the picker returned, or null.

PickAbility(AIController)

Prefers an available taunt over anything else, then falls back to the normal picker.

protected override Ability PickAbility(AIController controller)

Parameters

controller AIController

The AI controller.

Returns

Ability

The chosen ability, or null.

ResolveProtectedTransform(AIController)

Resolves who this defender is protecting: a pet protects its owner, a grouped NPC protects the group's most wounded member.

protected virtual Transform ResolveProtectedTransform(AIController controller)

Parameters

controller AIController

The AI controller.

Returns

Transform

The protected character's transform, or null when there is nobody to protect.