Exemplo n.º 1
0
void BuildActionEx::FreeResources(RtsGame &game)
{
    if (_builderId != INVALID_TID)
    {
        if (!_buildArea.IsNull() && _buildArea.IsLocked())
        {
            // Special buildings (for example addons) are not associated with build positions so no need to assert in that case.
            _ASSERTE(game.GetEntityType((EntityClassType)_params[PARAM_EntityClassId])->P(TP_IsSpecialBuilding) || !_buildArea.IsNull());
            _buildArea.Unlock(this);
        }

        if (!_requiredResources.IsNull() && _requiredResources.IsLocked())
        {
            _requiredResources.Unlock(this);
        }

        if (_builderId != INVALID_TID)
        {
            GameEntity *pEntity = game.Self()->GetEntity(_builderId);

            if (pEntity && pEntity->IsLocked())
            {
                pEntity->Unlock(this);
            }

            _builderId = INVALID_TID;
        }
    }
}
Exemplo n.º 2
0
bool ResearchAction::Execute(RtsGame& game, const WorldClock& p_clock)
{
	// FIXME: because we don't have a goal for Research for now, we can use the action as a goal
	// at the same time, by not issuing the research action if it is already done
	if (game.Self()->TechTree()->ResearchDone((ResearchType)_params[PARAM_ResearchId]))
		return true;

	ResearchType researchType = (ResearchType)_params[PARAM_ResearchId];
	GameEntity *pGameResearcher;
	AbstractAdapter *pAdapter = g_OnlineCaseBasedPlanner->Reasoner()->Adapter();

    bool executed = false;

	// Adapt researcher
	m_researcherId = pAdapter->AdaptBuildingForResearch(researchType);

    if (m_researcherId != INVALID_TID)
    {
        // Issue research order
        pGameResearcher = game.Self()->GetEntity(m_researcherId);
        _ASSERTE(pGameResearcher);

        executed = pGameResearcher->Research(researchType);

        if (executed)
        {
            pGameResearcher->Lock(this);
        }
    }

    return executed;
}
Exemplo n.º 3
0
//----------------------------------------------------------------------------------------------
bool TrainAction::AliveConditionsSatisfied(RtsGame& game)
{
    bool trainerExist = false;
    bool traineeExist = false;
    bool trainerBusy = false;
    bool traineeBeingTrained = false;
    bool success = false;

    // 1. Trainer building exist
    trainerExist = g_Assist.DoesEntityObjectExist(m_trainerId);

    if (trainerExist)
    {
        if (m_trainStarted)
        {
            // 2. Trainer building is busy or in the training state
            GameEntity* pTrainer = game.Self()->GetEntity(m_trainerId);
            _ASSERTE(pTrainer);
            ObjectStateType trainerState = (ObjectStateType)pTrainer->Attr(EOATTR_State);
            trainerBusy = trainerState == OBJSTATE_Training;
            // 3. The trainee unit object exist, i.e not cancel
            traineeExist = g_Assist.DoesEntityObjectExist(m_traineeId);

            if (traineeExist && !trainerBusy)
            {
                success = true;
            }
            else if (trainerBusy)
            {
                if (traineeExist)
                {
                    // 4. Trainee is still being trained
                    GameEntity* pTrainee = game.Self()->GetEntity(m_traineeId);
                    _ASSERTE(pTrainee);
                    ObjectStateType traineeState = (ObjectStateType)pTrainee->Attr(EOATTR_State);
                    traineeBeingTrained = traineeState == OBJSTATE_BeingConstructed;

                    if (traineeBeingTrained || traineeState == OBJSTATE_Idle)
                        success = true;
                }
            }
        }
        else
        {
            success = true;
        }
    }
    else
    {
        ConditionEx* failedCondition = new EntityClassExist(PLAYER_Self, m_trainerType, 1);
        m_history.Add(ESTATE_Failed, failedCondition);
    }

    return success;
}
Exemplo n.º 4
0
//----------------------------------------------------------------------------------------------
void AttackEntityAction::OnFailure(RtsGame& game, const WorldClock& p_clock)
{
    GameEntity* pAttacker = game.Self()->GetEntity(m_attackerId);

    if (pAttacker && pAttacker->IsLocked() && pAttacker->Owner() == this)
        pAttacker->Unlock(this);
}
Exemplo n.º 5
0
//----------------------------------------------------------------------------------------------
bool TrainAction::SuccessConditionsSatisfied(RtsGame& game)
{
    bool success = false;
    bool traineeBeingTrained = false;

    if (m_trainStarted)
    {
        // 1. Trainee unit object exist
        bool traineeExist = g_Assist.DoesEntityObjectExist(m_traineeId);

        if (traineeExist)
        {
            // 2. Trainee is ready and no more being constructed
            GameEntity* pTrainee = game.Self()->GetEntity(m_traineeId);
            _ASSERTE(pTrainee);
            ObjectStateType traineeState = (ObjectStateType)pTrainee->Attr(EOATTR_State);
            traineeBeingTrained = traineeState == OBJSTATE_BeingConstructed;

            if (!traineeBeingTrained)
            {
                LogInfo("Action %s succeeded to train trainee=%d from trainer=%d", ToString().c_str(), m_traineeId, m_trainerId);
                success = true;
            }
        }
    }

    return success;
}
Exemplo n.º 6
0
//----------------------------------------------------------------------------------------------
bool AttackEntityAction::Execute(RtsGame& game, const WorldClock& p_clock)
{
    EntityClassType attackerType = (EntityClassType)_params[PARAM_EntityClassId];
    EntityClassType targetType = (EntityClassType)_params[PARAM_TargetEntityClassId];
    AbstractAdapter *pAdapter = g_OnlineCaseBasedPlanner->Reasoner()->Adapter();
    bool executed = false;

    // Adapt attacker
    m_attackerId = pAdapter->GetEntityObjectId(attackerType,AdapterEx::AttackerStatesRank);

    if (m_attackerId != INVALID_TID)
    {
        m_targetId = pAdapter->AdaptTargetEntity(targetType, Parameters());

        if (m_targetId != INVALID_TID)
        {
            GameEntity* pAttacker = game.Self()->GetEntity(m_attackerId);
            _ASSERTE(pAttacker);

            pAttacker->Lock(this);
            executed = pAttacker->AttackEntity(m_targetId);
        }
    }

    return executed;
}
Exemplo n.º 7
0
void BuildActionEx::HandleMessage(RtsGame& game, Message* p_msg, bool& p_consumed)
{
    if(PlanStepEx::State() == ESTATE_Executing && p_msg->MessageTypeID() == MSG_EntityCreate) 
    {
        EntityCreateMessage* pMsg = static_cast<EntityCreateMessage*>(p_msg);
        TID buildingId;
        GameEntity *pGameBuilding;
        Vector2 msgBuildPosition;

        if (pMsg->Data()->OwnerId != PLAYER_Self)
            return;

        assert(pMsg && pMsg->Data());
        buildingId = pMsg->Data()->EntityId;

        pGameBuilding = game.Self()->GetEntity(buildingId);
        assert(pGameBuilding);

        msgBuildPosition.X = pMsg->Data()->X;
        msgBuildPosition.Y = pMsg->Data()->Y;

        if (msgBuildPosition.X == _buildArea.Pos().X &&
            msgBuildPosition.Y == _buildArea.Pos().Y &&
            pGameBuilding->Type() == _params[PARAM_EntityClassId])
        {
            _buildingId = pGameBuilding->Id();
            _buildStarted = true;
            assert(!_requiredResources.IsNull());
            _requiredResources.Unlock(this);
        }
    }
}
Exemplo n.º 8
0
bool BuildActionEx::Execute(RtsGame& game, const WorldClock& p_clock)
{
    EntityClassType buildingType = (EntityClassType)_params[PARAM_EntityClassId];
    GameEntity *pGameBuilder;
    AbstractAdapter *pAdapter = g_OnlineCaseBasedPlanner->Reasoner()->Adapter();
    bool bOk = false;

    //// Adapt builder
    //_builderId = pAdapter->AdaptBuilder(buildingType, true);
    //// Adapt build position
    //_buildArea = pAdapter->AdaptPositionForBuilding(buildingType);

    // Adapt builder
    // Adapt build position
    auto adaptedParams = pAdapter->AdaptBuilderAndPosition(buildingType, true);
    _builderId = adaptedParams.first;
    _buildArea = adaptedParams.second;

    if (_builderId != INVALID_TID)
    {
        // Initialize build state
        _buildStarted = false;

        // Issue build order
        pGameBuilder = game.Self()->GetEntity(_builderId);

        LogInfo("Builder=%s was selected to execute build", pGameBuilder->ToString().c_str());

        pGameBuilder->Lock(this);

        // Special buildings (for example addons) are not associated with build positions so no need to assert in that case.
        if (!game.GetEntityType(buildingType)->P(TP_IsSpecialBuilding))
        {
            _ASSERTE(!_buildArea.IsNull());
            _buildArea.Lock(this);
        }

        _ASSERTE(!_requiredResources.IsNull());
        _requiredResources.Lock(this);
        bOk = pGameBuilder->Build(buildingType, _buildArea.Pos());

        if (bOk)
            _buildIssued = true;
    }

    return bOk;
}
Exemplo n.º 9
0
bool ResearchDone::Evaluate(RtsGame& game)
{
   _isSatisfied = game.GetPlayer((PlayerType)m_params[PARAM_PlayerId])->TechTree()->ResearchDone((ResearchType)m_params[PARAM_ResearchId]);

    _isEvaluated = true;

    return _isEvaluated && _isSatisfied;
}
Exemplo n.º 10
0
//----------------------------------------------------------------------------------------------
bool WinGameGoal::SuccessConditionsSatisfied(RtsGame& game)
{
    EntityList enemyEntities;
    game.Enemy()->Entities(enemyEntities);

    // All enemy units are destroyed, win game!
    return enemyEntities.empty();
}
Exemplo n.º 11
0
//----------------------------------------------------------------------------------------------
bool AttackGroundAction::SuccessConditionsSatisfied(RtsGame& game)
{
    _ASSERTE(PlanStepEx::GetState() == ESTATE_Executing);

    GameEntity* pGameAttacker = game.Self()->GetEntity(_attackerId);
    _ASSERTE(pGameAttacker);
    ObjectStateType attackerState = (ObjectStateType)pGameAttacker->P(OP_State);
    return (attackerState == OBJSTATE_Attacking) || (attackerState == OBJSTATE_UnderAttack);
}
Exemplo n.º 12
0
//---------------------------------------------------------------------------
bool EntityClassNearArea::Evaluate(RtsGame& pRtsGame)
{
    vector<TID> entityIds;
    pRtsGame.Self()->Entities((EntityClassType)_conditionParameters[PARAM_EntityClassId], entityIds);
    Vector2 position = Vector2::Null();
    
    ConditionEx::Evaluate(pRtsGame);
    for (size_t i = 0; i < entityIds.size(); ++i)
    {
        position = pRtsGame.Map()->GetNearestCell(new CellFeature(_conditionParameters));

        if (!position.IsNull())
        {
            _isSatisfied = true;
            break;
        }
    }

    return _isEvaluated && _isSatisfied;
}
Exemplo n.º 13
0
//----------------------------------------------------------------------------------------------
void TrainAction::HandleMessage(RtsGame& game, Message* pMsg, bool& consumed)
{
    if (PlanStepEx::State() == ESTATE_Executing && pMsg->MessageTypeID() == MSG_EntityCreate)
    {
        EntityCreateMessage* pEntityMsg = static_cast<EntityCreateMessage*>(pMsg);
        _ASSERTE(pEntityMsg && pEntityMsg->Data());

        if (pEntityMsg->Data()->OwnerId != PLAYER_Self)
            return;

        TID entityId = pEntityMsg->Data()->EntityId;
        GameEntity *pEntity = game.Self()->GetEntity(entityId);
        _ASSERTE(pEntity);

        // We are interested only in free trainees that have not been locked before
        if (!m_trainStarted &&
			m_traineeId == INVALID_TID &&
			pEntity->Type() == _params[PARAM_EntityClassId] &&
            !pEntity->IsLocked())
        {
            // Check if the trainer is training that entity
            GameEntity* pTrainer = game.Self()->GetEntity(m_trainerId);
            _ASSERTE(pTrainer);

            if (pTrainer->IsTraining(entityId))
            {
                m_trainStarted = true;
                m_traineeId = entityId;

                m_pTrainee = pEntity;

                // Lock that trainee and bound it to this action because if we don't
                // other ready actions in the same update cycle will receive the same message
                // and they may bind to the same trainee
                pEntity->Lock(this);
                consumed = true;
                LogInfo("Action %s has bound trainee=%d to trainer=%d", ToString().c_str(), m_traineeId, m_trainerId);
            }
        }
    }
}
Exemplo n.º 14
0
bool BuildActionEx::ExecuteAux(RtsGame& game, const WorldClock& p_clock)
{
    EntityClassType buildingType;
    GameEntity *pGameBuilder;
    AbstractAdapter *pAdapter = g_OnlineCaseBasedPlanner->Reasoner()->Adapter();
    bool bOk = false;

    // Adapt builder
    _builderId = pAdapter->GetEntityObjectId(game.Self()->GetWorkerType(),AdapterEx::WorkerStatesRankVector);

    if (_builderId != INVALID_TID)
    {

        buildingType = (EntityClassType)_params[PARAM_EntityClassId];

        // Initialize build state
        _buildStarted = false;

        // Adapt build position
        assert(pAdapter);
        _buildArea = pAdapter->AdaptPositionForBuilding(buildingType);

        // Issue build order
        pGameBuilder = game.Self()->GetEntity(_builderId);
        assert(pGameBuilder);

        bOk = pGameBuilder->Build(buildingType, _buildArea.Pos());

        if (bOk)
        {
            _buildIssued = true;
            pGameBuilder->Lock(this);
            assert(!_buildArea.IsNull());
            _buildArea.Lock(this);
            assert(!_requiredResources.IsNull());
            _requiredResources.Lock(this);
        }
    }

    return bOk;
}
Exemplo n.º 15
0
void ResearchAction::FreeResources(RtsGame& game)
{
    if (m_researcherId != INVALID_TID)
    {
        GameEntity* pResearcher = game.Self()->GetEntity(m_researcherId);

        if (pResearcher && pResearcher->IsLocked())
            pResearcher->Unlock(this);

        m_researcherId = INVALID_TID;
    }
}
Exemplo n.º 16
0
void BuildActionEx::OnSucccess(RtsGame& game, const WorldClock& p_clock)
{
    if (_buildIssued)
    {
        assert(!_buildArea.IsNull());
        _buildArea.Unlock(this);

        GameEntity *pEntity = game.Self()->GetEntity(_builderId);

        if (pEntity)
            pEntity->Unlock(this);
    }
}
Exemplo n.º 17
0
void BuildActionEx::HandleMessage(RtsGame& game, Message* p_msg, bool& p_consumed)
{
    if (PlanStepEx::GetState() == ESTATE_Executing &&
        (p_msg->TypeId() == MSG_EntityCreate ||
        p_msg->TypeId() == MSG_EntityRenegade))
    {
        EntityCreateMessage* pMsg = static_cast<EntityCreateMessage*>(p_msg);
        TID buildingId;
        GameEntity *pGameBuilding;
        Vector2 msgBuildPosition;

        if (pMsg->Data()->OwnerId != PLAYER_Self)
            return;

        _ASSERTE(pMsg && pMsg->Data());
        buildingId = pMsg->Data()->EntityId;

        pGameBuilding = game.Self()->GetEntity(buildingId);
        _ASSERTE(pGameBuilding);

        msgBuildPosition.X = pMsg->Data()->X;
        msgBuildPosition.Y = pMsg->Data()->Y;

        if (pGameBuilding->TypeId() == _params[PARAM_EntityClassId] &&
            ((msgBuildPosition.X == _buildArea.Pos().X && msgBuildPosition.Y == _buildArea.Pos().Y) ||
            game.GetEntityType(pGameBuilding->TypeId())->P(TP_IsSpecialBuilding)))
        {
            _buildingId = pGameBuilding->Id();
            _buildStarted = true;
            _ASSERTE(!_requiredResources.IsNull());
            _requiredResources.Unlock(this);
            p_consumed = true;
            LogInfo("%s started actual building of %s", ToString().c_str(), pGameBuilding->ToString().c_str());
        }
    }
}
Exemplo n.º 18
0
//----------------------------------------------------------------------------------------------
void TrainAction::FreeResources(RtsGame& game)
{
    if (m_traineeId != INVALID_TID)
    {
        GameEntity* pTrainee = game.Self()->GetEntity(m_traineeId);

        if (pTrainee && pTrainee->IsLocked())
            pTrainee->Unlock(this);

        if (!m_requiredResources.IsNull() && m_requiredResources.IsLocked())
            m_requiredResources.Unlock(this);
        m_traineeId = INVALID_TID;
		m_trainerId = INVALID_TID;
    }
}
Exemplo n.º 19
0
void BuildActionEx::OnFailure(RtsGame& game, const WorldClock& p_clock)
{
    if (_buildIssued)
    {
        assert(!_buildArea.IsNull());
        _buildArea.Unlock(this);
        assert(!_requiredResources.IsNull());
        _requiredResources.Unlock(this);

        GameEntity *pEntity = game.Self()->GetEntity(_builderId);

        if (pEntity)
            pEntity->Unlock(this);
    }
}
Exemplo n.º 20
0
//----------------------------------------------------------------------------------------------
vector<GoalEx*> WinGameGoal::GetSucceededInstances(RtsGame &game)
{
    vector<GoalEx*> succeededGoals;
    EntityList enemyEntities;
    game.Enemy()->Entities(enemyEntities);

    if (enemyEntities.empty())
    {
        PlanStepParameters params;
        params[PARAM_StrategyTypeId] = STRTYPE_EarlyTierRush;
        succeededGoals.push_back(g_GoalFactory.GetGoal(GOALEX_WinGame, params, true));
        LogInfo("WinGameGoal succeeded with strategt type='%s'", Enums[params[PARAM_StrategyTypeId]]);
    }

    return succeededGoals;
}
Exemplo n.º 21
0
bool BuildActionEx::SuccessConditionsSatisfied(RtsGame& game)
{
    assert(PlanStepEx::State() == ESTATE_Executing);

    if (_buildStarted)
    {
        int            entityState;
        GameEntity    *pEntity;

        pEntity = game.Self()->GetEntity(_buildingId);    
        entityState = pEntity->Attr(EOATTR_State);

        return entityState != OBJSTATE_BeingConstructed;
    }

    return false;
}
Exemplo n.º 22
0
//----------------------------------------------------------------------------------------------
bool AttackEntityAction::SuccessConditionsSatisfied(RtsGame& game)
{
    _ASSERTE(PlanStepEx::GetState() == ESTATE_Executing);
    bool targetExists = g_Assist.DoesEntityObjectExist(m_targetId, PLAYER_Enemy);

    if (targetExists)
    {
        GameEntity* pGameTarget = game.Enemy()->GetEntity(m_targetId);
        _ASSERTE(pGameTarget);

        ObjectStateType targetState = (ObjectStateType)pGameTarget->P(OP_State);
        return targetState == OBJSTATE_UnderAttack;
    }
    else
    {
        return true;
    }
}
Exemplo n.º 23
0
bool BuildActionEx::AliveConditionsSatisfied(RtsGame& game)
{
    bool builderExist = false;
    bool buildingExist = false;
    bool isBuilderConstructing = false;
    bool success = false;
    GameEntity *pEntity = nullptr;

    assert(PlanStepEx::State() == ESTATE_Executing);

    builderExist = g_Assist.DoesEntityObjectExist(_builderId);

    if (builderExist)
    {
        success = true;
        pEntity = game.Self()->GetEntity(_builderId);

        assert(pEntity);
        isBuilderConstructing = (pEntity->Attr(EOATTR_State) == OBJSTATE_Constructing);

        if (!isBuilderConstructing)
        {
            LogInfo("Builder with ID=%d of action %s is not in the constructing state", _builderId, ToString().c_str());
        }
        else
        {
            if (_buildStarted)
            {
                buildingExist = g_Assist.DoesEntityObjectExist(_buildingId);

                if (!buildingExist)
                {
                    success = false;
                }
            }
        }
    }
    else
    {
        LogInfo("Builder with ID=%d of action %s does not exist", _builderId, ToString().c_str());
    }

    return success;
}
Exemplo n.º 24
0
bool BuildActionEx::SuccessConditionsSatisfied(RtsGame& game)
{
    _ASSERTE(PlanStepEx::GetState() == ESTATE_Executing);

    if (_buildStarted)
    {
        GameEntity *pEntity = game.Self()->GetEntity(_buildingId);

        if (pEntity)
        {
            int entityState = pEntity->P(OP_State);
            return entityState != OBJSTATE_BeingConstructed;
        }
        else
            return false;
    }

    return false;
}
Exemplo n.º 25
0
//----------------------------------------------------------------------------------------------
bool MoveAction::ExecuteAux(RtsGame& game, const WorldClock& p_clock)
{
    AbstractAdapter *pAdapter = g_OnlineCaseBasedPlanner->Reasoner()->Adapter();
    EntityClassType entityType = (EntityClassType)_params[PARAM_EntityClassId];

    //Adapt Entity
    _entityId = pAdapter->GetEntityObjectId(entityType, AdapterEx::EntityToMoveStatesRank);
    bool executed = false;

    if(_entityId != INVALID_TID)
    {
        //Adapt position
        _position = pAdapter->AdaptPosition(Parameters());
        _pEntity  = game.Self()->GetEntity(_entityId);
        _pEntity->Lock(this);
        _ASSERTE(_pEntity);
        executed = _pEntity->Move(_position);
    }
    return executed;
}
Exemplo n.º 26
0
//----------------------------------------------------------------------------------------------
bool MoveAction::AliveConditionsSatisfied(RtsGame& game)
{
    bool satisfied = false;

    if (g_Assist.DoesEntityObjectExist(_entityId))
    {
        GameEntity* pEntity = game.Self()->GetEntity(_entityId);
        _ASSERTE(pEntity);
        satisfied = (pEntity->Attr(EOATTR_IsMoving) > 0 ? true : false);
    }
    else
    {
        ConditionEx* failedCondition = new EntityClassExist(
            PLAYER_Self,
            (EntityClassType)_params[PARAM_EntityClassId],
            1);
        m_history.Add(ESTATE_Failed, failedCondition);
    }

    return satisfied;
}
Exemplo n.º 27
0
//----------------------------------------------------------------------------------------------
bool AttackGroundAction::Execute(RtsGame& game, const WorldClock& p_clock)
{
    EntityClassType attackerType = (EntityClassType)_params[PARAM_EntityClassId];
    AbstractAdapter *pAdapter = g_OnlineCaseBasedPlanner->Reasoner()->Adapter();
    bool executed = false;

    // Adapt attacker
    _attackerId = pAdapter->GetEntityObjectId(attackerType,AdapterEx::AttackerStatesRank);

    if (_attackerId != INVALID_TID)
    {
        GameEntity* pGameAttacker = game.Self()->GetEntity(_attackerId);
        _ASSERTE(pGameAttacker);
        pGameAttacker->Lock(this);

        // Adapt attack position
        _position = pAdapter->AdaptEnemyBorder();
        executed = pGameAttacker->AttackGround(_position);
    }
    
    return executed;
}
Exemplo n.º 28
0
//----------------------------------------------------------------------------------------------
bool TrainAction::ExecuteAux(RtsGame& game, const WorldClock& clock)
{
	LogActivity(ExecuteAux);

    EntityClassType traineeType = (EntityClassType)_params[PARAM_EntityClassId];
    GameEntity *pGameTrainer;
    AbstractAdapter *pAdapter = g_OnlineCaseBasedPlanner->Reasoner()->Adapter();
    bool executed = false;

    // Adapt trainer
    m_trainerId = pAdapter->AdaptBuildingForTraining(traineeType);

    if (m_trainerId != INVALID_TID)
    {
        // Issue train order
        pGameTrainer = game.Self()->GetEntity(m_trainerId);
        _ASSERTE(pGameTrainer);
        _ASSERTE(!m_requiredResources.IsNull());
        m_requiredResources.Lock(this);
        executed = pGameTrainer->Train(traineeType);
    }

    return executed;
}
Exemplo n.º 29
0
bool ResearchAction::SuccessConditionsSatisfied(RtsGame& game)
{
	return game.Self()->TechTree()->ResearchDone((ResearchType)_params[PARAM_ResearchId]);
}
Exemplo n.º 30
0
bool BuildActionEx::AliveConditionsSatisfied(RtsGame& game)
{
    bool builderExist = false;
    bool buildingExist = false;
    bool success = false;
    GameEntity *pEntity = nullptr;

    _ASSERTE(PlanStepEx::GetState() == ESTATE_Executing);

    builderExist = g_Assist.DoesEntityObjectExist(_builderId);

    if (builderExist)
    {
        success = true;
        pEntity = game.Self()->GetEntity(_builderId);

        _ASSERTE(pEntity);
        auto pBuilderType = g_Game->GetEntityType(pEntity->TypeId());


        if (pBuilderType->P((TP_IsBuilding)))
        {
            LogDebugInfo("Checking state of builder %s", pEntity->ToString().c_str());
            ObjectStateType state = (ObjectStateType)pEntity->P(OP_State);

            if (state != OBJSTATE_Constructing)
            {
                LogInfo("Builder %s of action %s is not constructing an expansion, something wrong happened, failing the build", pEntity->ToString().c_str(), ToString().c_str());
                success = false;
            }
        }
        // For workers, check if the worker is stuck, otherwise 
        // If a building is building another building, then no need to check
        // for stucking
        else
        {
            if (pEntity->P(OP_State) == OBJSTATE_Idle)
            {
                LogInfo("Builder %s of action %s is standing idle, something wrong happened, failing the build", pEntity->ToString().c_str(), ToString().c_str());
                success = false;
            }
            else if (pEntity->P(OP_State) == OBJSTATE_Constructing)
            {
                if (_buildStarted)
                {
                    buildingExist = g_Assist.DoesEntityObjectExist(_buildingId);

                    if (!buildingExist)
                    {
                        success = false;
                    }
                }
            }
            else if (pEntity->P(OP_State) == OBJSTATE_GatheringPrimary ||
                pEntity->P(OP_State) == OBJSTATE_GatheringSecondary)
            {
                LogInfo("Builder %s of action %s is gathering, something wrong happened, failing the build", pEntity->ToString().c_str(), ToString().c_str());
                success = false;
            }
            else
            {
                LogInfo("Builder %s of action %s is not in the constructing state, didn't start actual constructing yet", pEntity->ToString().c_str(), ToString().c_str());
            }
        }
    }
    else
    {
        ConditionEx* failedCondition = new EntityClassExist(
            PLAYER_Self,
            game.Self()->Race()->GetWorkerType(),
            1);
        m_history.Add(ESTATE_Failed, failedCondition);

        LogInfo("Builder with ID=%d of action %s does not exist", _builderId, ToString().c_str());
    }

    return success;
}