Ability Integration

How Ability Sets Are Granted

When a piece of equipment is applied, the manager calls AddEntry on the FCrimsonEquipmentList. The list discovers the pawn's UAbilitySystemComponent via IAbilitySystemInterface::GetAbilitySystemComponent() - the engine standard interface. It then calls UCrimsonAbilitySet::GiveToAbilitySystem() for each set in AbilitySetsToGrant, storing the returned FCrimsonAbilitySet_GrantedHandles. When the item is unequipped, the manager calls TakeFromAbilitySystem() on those handles, cleanly revoking all abilities, effects, and attributes.

ASC Discovery via Engine Interface
The equipment manager uses IAbilitySystemInterface (the engine module), not any CrimsonAbilitySystem type. Any ASC implementation - including Epic's own - works as long as the owner implements IAbilitySystemInterface.

UCrimsonGameplayAbility_FromEquipment

Base class for abilities granted by equipment. Extends UGameplayAbility (engine) directly with two accessors that navigate back to the granting equipment and its source object.

FunctionReturnsDescription
GetAssociatedEquipment()UCrimsonEquipmentInstance*The equipment instance that granted this ability. Reads SourceObject from the ability spec - valid only while the ability is active.
GetSourceObject()UObject*The source object on the equipment instance. Cast to your item type (e.g. UCrimsonInventoryItemInstance).
Must Be Instanced
UCrimsonGameplayAbility_FromEquipment requires an instanced ability policy (InstancedPerActor or InstancedPerExecution). NonInstanced is blocked by IsDataValid in the editor.

Combining With UCrimsonGameplayAbility

If your project uses UCrimsonGameplayAbility (from CrimsonAbilitySystem) as its base, UCrimsonGameplayAbility_FromEquipment cannot inherit from both. The recommended pattern is to create a single project-level combined base class:

cpp
// In your project - not in any Crimson plugin
// Combine CrimsonAbilitySystem base with the equipment accessors
#include "Abilities/CrimsonGameplayAbility.h" // CrimsonAbilitySystem
#include "CrimsonEquipmentInstance.h"
UCLASS(Abstract, Blueprintable)
class UMyGameplayAbility_FromEquipment : public UCrimsonGameplayAbility
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "Ability")
UCrimsonEquipmentInstance* GetAssociatedEquipment() const
{
// Copy the ~5-line body from UCrimsonGameplayAbility_FromEquipment::GetAssociatedEquipment
return Cast<UCrimsonEquipmentInstance>(GetCurrentSourceObject());
}
UFUNCTION(BlueprintCallable, Category = "Ability")
UObject* GetSourceObject() const
{
if (UCrimsonEquipmentInstance* Inst = GetAssociatedEquipment())
return Inst->GetSourceObject();
return nullptr;
}
};