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; } } }
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; }
//---------------------------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------------------------- 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; }
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); } } }
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; }
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; }
//---------------------------------------------------------------------------------------------- bool WinGameGoal::SuccessConditionsSatisfied(RtsGame& game) { EntityList enemyEntities; game.Enemy()->Entities(enemyEntities); // All enemy units are destroyed, win game! return enemyEntities.empty(); }
//---------------------------------------------------------------------------------------------- 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); }
//--------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------------------------- 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); } } } }
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; }
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; } }
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); } }
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()); } } }
//---------------------------------------------------------------------------------------------- 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; } }
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); } }
//---------------------------------------------------------------------------------------------- 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; }
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; }
//---------------------------------------------------------------------------------------------- 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; } }
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; }
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; }
//---------------------------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------------------------- 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; }
bool ResearchAction::SuccessConditionsSatisfied(RtsGame& game) { return game.Self()->TechTree()->ResearchDone((ResearchType)_params[PARAM_ResearchId]); }
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; }