void DFBB_BuildOrderStackSearch::generateLegalActions(const GameState & state, ActionSet & legalActions)
{
    legalActions.clear();
    DFBB_BuildOrderSearchGoal & goal = _params.goal;
    const ActionType & worker = ActionTypes::GetWorker(state.getRace());
    
    // add all legal relevant actions that are in the goal
    for (size_t a(0); a < _params.relevantActions.size(); ++a)
    {
        const ActionType & actionType = _params.relevantActions[a];

        if (state.isLegal(actionType))
        {
            // if there's none of this action in the goal it's not legal
            if (!goal.getGoal(actionType) && !goal.getGoalMax(actionType))
            {
                continue;
            }

            // if we alread have more than the goal it's not legal
            if (goal.getGoal(actionType) && (state.getUnitData().getNumTotal(actionType) >= goal.getGoal(actionType)))
            {
                continue;
            }

            // if we already have more than the goal max it's not legal
            if (goal.getGoalMax(actionType) && (state.getUnitData().getNumTotal(actionType) >= goal.getGoalMax(actionType)))
            {
                continue;
            }
            
            legalActions.add(_params.relevantActions[a]);
        }
    }

    // don't make anything until we have 8 workers
    if (state.getUnitData().getNumTotal(worker) < 8)
    {
        legalActions.clear();
        legalActions.add(worker);
        return;
    }

    // if we enabled the supply bounding flag
    if (_params.useSupplyBounding)
    {
        UnitCountType supplySurplus = state.getUnitData().getMaxSupply() + state.getUnitData().getSupplyInProgress() - state.getUnitData().getCurrentSupply();
        UnitCountType threshold = (UnitCountType)(ActionTypes::GetSupplyProvider(state.getRace()).supplyProvided() * _params.supplyBoundingThreshold);

        if (supplySurplus >= threshold)
        {
            legalActions.remove(ActionTypes::GetSupplyProvider(state.getRace()));
        }
    }
    
    // if we enabled the always make workers flag, and workers are legal
    if (_params.useAlwaysMakeWorkers && legalActions.contains(worker))
    {
        bool actionLegalBeforeWorker = false;
        ActionSet legalEqualWorker;
        FrameCountType workerReady = state.whenCanPerform(worker);

        for (size_t a(0); a < legalActions.size(); ++a)
        {
            const ActionType & actionType = legalActions[a];
            const FrameCountType whenCanPerformAction = state.whenCanPerform(actionType);
            if (whenCanPerformAction < workerReady)
            {
                actionLegalBeforeWorker = true;
                break;
            }

            if ((whenCanPerformAction == workerReady) && (actionType.mineralPrice() == worker.mineralPrice()))
            {
                legalEqualWorker.add(actionType);
            }
        }

        if (actionLegalBeforeWorker)
        {
            legalActions.remove(worker);
        }
        else
        {
            legalActions = legalEqualWorker;
        }
    }
}