Page MenuHomeFeedback Tracker

Enable mods to more easily extend ActionManagerClient.FindActionTarget
Assigned, UrgentPublic

Description

The ActionManagerClient class has a FindActionTarget method for finding an action target. However, due to how it is implemented, it is difficult to extend this method to support additional (non-EntityAI, non-WoodBase, non-Rock) target object types.

I request that the DayZ team split the implementation of the FindActionTarget method into two methods. The if statements inside the for loop should be moved to a IsUsableActionTarget method, like so:

class ActionManagerClient: ActionManagerBase 
{
    // ...

    override ActionTarget FindActionTarget()
    {
        if(m_ForceTarget)
            return m_ForceTarget;
        
        ActionTarget action_target;
        action_target = NULL;
        int targetsCount = m_Targets.GetTargetsCount();
        if( targetsCount )
        {
            for( int i = 0; i < targetsCount; ++i )
            {
                action_target = m_Targets.GetTarget(i);

                // ========== BEGINNING OF CHANGE ==========
                if (IsUsableActionTarget(action_target))
                {
                    break;
                }
                // ========== ENDING OF CHANGE ==========
            }
        }
        else
        {
            action_target = new ActionTarget(null, null, -1, vector.Zero, -1 );
        }
        return action_target;
    }

    bool IsUsableActionTarget(ActionTarget action_target)
    {
        Object targetObject = action_target.GetObject();
        Object targetParent = action_target.GetParent();

        if( targetParent && targetParent.IsEntityAI() )
        {
            return true;
        }

        if( targetObject && (targetObject.IsEntityAI() || targetObject.IsWoodBase() || targetObject.IsRock()) )
        {
            return true;
        }

        return false;
    }

    // ...
};

Then, modders who want to enable additional object types to be used as action targets can do something like this:

modded class ActionManagerClient
{
    bool IsUsableActionTarget(ActionTarget action_target)
    {
        if (super.IsUsableActionTarget(action_target))
        {
            return true;
        }

        if (/* ...expression to detect my new object type... */)
        {
            return true;
        }

        return false;
    }
};

This should allow multiple mods to extend IsUsableActionTarget without interfering with each other, as long as they all call super, like in the above example.

Thank you!

Details

Severity
Feature
Resolution
Open
Reproducibility
N/A
Operating System
Windows 10 x64
Category
General
Additional Information

For reference, this is the current implementation of FindActionTarget from DayZ 1.16.154535:

override ActionTarget FindActionTarget()
{
    if(m_ForceTarget)
        return m_ForceTarget;

    ActionTarget action_target;
    action_target = NULL;
    int targetsCount = m_Targets.GetTargetsCount();
    if( targetsCount )
    {
        for( int i = 0; i < targetsCount; ++i )
        {
            action_target = m_Targets.GetTarget(i);
            Object targetObject = action_target.GetObject();
            Object targetParent = action_target.GetParent();

            if( targetParent && targetParent.IsEntityAI() )
            {
                break;
            }

            if( targetObject && (targetObject.IsEntityAI() || targetObject.IsWoodBase() || targetObject.IsRock()) )
            {
                break;
            }
        }
    }
    else
    {
        action_target = new ActionTarget(null, null, -1, vector.Zero, -1 );
    }
    return action_target;
}

Event Timeline

tjensen created this task.Feb 19 2022, 3:55 AM
Liven added a subscriber: Liven.Feb 19 2022, 7:10 AM
Geez changed the task status from New to Assigned.Feb 21 2022, 11:56 AM