TID AdapterEx::AdaptBuildingForTraining(EntityClassType p_traineeType) { // Gets first building to train entity from type p_traineeType // If no empty building is found, last non-idle building will be returned GamePlayer *pPlayer; GameEntity *pEntity; vector<TID> entityIds; EntityClassType trainerType; TID id = INVALID_TID; trainerType = g_Game->Self()->TechTree()->SourceEntity(p_traineeType); pPlayer = g_Game->Self(); assert(pPlayer); pPlayer->Entities(entityIds); for (size_t i = 0, size = entityIds.size(); i < size; ++i) { pEntity = pPlayer->GetEntity(entityIds[i]); assert(pEntity); if (trainerType == pEntity->Type()) { id = pEntity->Id(); if (pEntity->Attr(EOATTR_State) == OBJSTATE_Idle) { id = pEntity->Id(); break; } } } return id; }
TID AdapterEx::AdaptTargetEntity(EntityClassType p_targetType, const PlanStepParameters& p_parameters) { GamePlayer *pPlayer; GameEntity *pEntity; vector<TID> entityIds; TID adaptedTargetId = INVALID_TID; double bestDistance = numeric_limits<double>::max(); CellFeature *pTarGetCellFeatureFromWorldPosition = new CellFeature(p_parameters); pPlayer = g_Game->Enemy(); assert(pPlayer); pPlayer->Entities(entityIds); for (size_t i = 0, size = entityIds.size(); i < size; ++i) { pEntity = pPlayer->GetEntity(entityIds[i]); assert(pEntity); if (p_targetType == pEntity->Type()) { CellFeature *pCandidateCellFearure = g_Game->Map()->GetCellFeatureFromWorldPosition(pEntity->GetPosition()); double dist = pTarGetCellFeatureFromWorldPosition->GetDistance(pCandidateCellFearure); if (dist <= bestDistance) { bestDistance = dist; adaptedTargetId = pEntity->Id(); } } } return adaptedTargetId; }
void GamePlayer::OnEntityDestroy(Message* p_pMessage) { EntityDestroyMessage *pDestroyMsg = nullptr; GameEntity *pEntity = nullptr; TID entityId; pDestroyMsg = (EntityDestroyMessage*)p_pMessage; if (pDestroyMsg->Data()->OwnerId == m_id) { entityId = pDestroyMsg->Data()->EntityId; assert(m_entities.Contains(entityId)); pEntity = GetEntity(entityId); pDestroyMsg->Data()->EntityType = pEntity->Type(); assert(pEntity); m_entities.erase(entityId); g_IMSysMgr.UnregisterGameObj(entityId); LogInfo("[%s] Unit '%s':%d destroyed", Enums[m_id], Enums[pEntity->Type()], pEntity->Id()); Toolbox::MemoryClean(pEntity); } }
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); } } }
void GamePlayer::OnEntityCreate(Message* p_pMessage) { GameEntity *pEntity = nullptr; TID entityId; EntityCreateMessage *pCreateMsg = nullptr; pCreateMsg = (EntityCreateMessage*)p_pMessage; if (pCreateMsg->Data()->OwnerId == m_id) { entityId = pCreateMsg->Data()->EntityId; if (m_entities.Contains(entityId)) { LogError("Entity %d already exist in Player %s units", entityId, Enums[m_id]); return; } pEntity = FetchEntity(entityId); assert(pEntity); m_entities[entityId] = pEntity; LogInfo("[%s] Unit '%s':%d created at <%d, %d>", Enums[m_id], Enums[pEntity->Type()], pEntity->Id(), pEntity->Attr(EOATTR_PosX), pEntity->Attr(EOATTR_PosY)); g_IMSysMgr.RegisterGameObj(entityId, pCreateMsg->Data()->OwnerId); } }
//-------------------------`--------------------------------------------------------------------- void BuildActionEx::HandleMessage(Message* p_pMsg, bool& p_consumed) { if(State() == ESTATE_Executing && p_pMsg->MessageTypeID() == MSG_EntityCreate) { EntityCreateMessage* pMsg = static_cast<EntityCreateMessage*>(p_pMsg); TID buildingId; GameEntity *pGameBuilding; Vector2 msgBuildPosition; if (pMsg->Data()->OwnerId != PLAYER_Self) return; assert(pMsg && pMsg->Data()); buildingId = pMsg->Data()->EntityId; pGameBuilding = g_Game->Self()->GetEntity(buildingId); assert(pGameBuilding); msgBuildPosition.X = pMsg->Data()->X; msgBuildPosition.Y = pMsg->Data()->Y; if (msgBuildPosition.X == _buildPosition.X && msgBuildPosition.Y == _buildPosition.Y) { _buildingId = pGameBuilding->Id(); _buildStarted = true; } } }
void GamePlayer::OnEntityRenegade(Message* p_pMessage) { EntityRenegadeMessage *pRenMsg = nullptr; GameEntity *pEntity = nullptr; TID entityId; pRenMsg = (EntityRenegadeMessage*)p_pMessage; entityId = pRenMsg->Data()->EntityId; // I am the unit new owner if (pRenMsg->Data()->OwnerId == m_id) { assert(!m_entities.Contains(entityId)); pEntity = FetchEntity(entityId); assert(pEntity); m_entities[entityId] = pEntity; LogInfo("[%s] Unit '%s':%d renegaded TO me", Enums[m_id], Enums[pEntity->Type()], pEntity->Id()); g_IMSysMgr.RegisterGameObj(entityId, pRenMsg->Data()->OwnerId); } // Used to be my unit, but it is not anymore else if (pRenMsg->Data()->OwnerId != m_id && m_entities.Contains(entityId)) { pEntity = GetEntity(entityId); assert(pEntity); m_entities.erase(entityId); g_IMSysMgr.UnregisterGameObj(entityId); LogInfo("[%s] Unit '%s':%d renegaded from me", Enums[m_id], Enums[pEntity->Type()], pEntity->Id()); Toolbox::MemoryClean(pEntity); } }
TID AdapterEx::GetEntityObjectId(EntityClassType p_entityType,const RankedStates& p_rankedStates) { /* Entity Object Adaptation Algorithm: IF player has Type THEN return the entity with the best state (based on input ranked states) ELSE adaptation failed and return nullptr entity Id */ GamePlayer *pPlayer; GameEntity *pEntity; vector<TID> entityIds; EntityClassType entityTypeId; ObjectStateType curEntityState; TID adaptedEntityId = INVALID_TID; vector<UnitEntry> validEntities; if(!IsRankedStatesInitialized) initializePredefinedRankedStates(); pPlayer = g_Game->Self(); assert(pPlayer); pPlayer->Entities(entityIds); for (size_t i = 0, size = entityIds.size(); i < size; ++i) { pEntity = pPlayer->GetEntity(entityIds[i]); assert(pEntity); if (p_entityType == pEntity->Type() && !pEntity->IsLocked()) { curEntityState = (ObjectStateType)pEntity->Attr(EOATTR_State); if (IsValidEntityState(curEntityState,p_rankedStates)) validEntities.push_back(MakePair(pEntity->Id(), curEntityState)); } } if (!validEntities.empty()) { sort(validEntities.begin(), validEntities.end(), [p_rankedStates](UnitEntry leftEntity,UnitEntry rightEntity) { return GetEntityStateIndex(leftEntity.second,p_rankedStates) < GetEntityStateIndex(rightEntity.second,p_rankedStates); }); adaptedEntityId = validEntities[0].first; } return adaptedEntityId; }
void EntityController::CalcCloseMeleeAttacker() { // Finding my attacker is an expensive calculation and its input // is globally computed per army if (m_pController == nullptr) return; m_closeMeleeAttackerId = INVALID_TID; auto& allEnemies = m_pController->EnemyData(); auto& nearEnemies = m_pController->ClosestEnemyEntities(); int minDist = INT_MAX; GameEntity* closestAttacker = nullptr; auto selfPos = Entity()->Position(); for (auto& enemy : nearEnemies) { auto& currEnemy = allEnemies.at(enemy.second); auto pCurrEnemy = g_Game->Enemy()->GetEntity(currEnemy.Id); // Either it is a ranged attacker or it is a melee attacker // but it is not targeting me, Don't Panic at all! if (!pCurrEnemy->Type()->P(TP_IsMelee) || currEnemy.TargetEntityId != m_entityId) continue; int dist = selfPos.Distance(pCurrEnemy->Position()); if (dist < minDist) { minDist = dist; closestAttacker = pCurrEnemy; } } if (closestAttacker != nullptr && minDist <= MeleeAttackerSafetyRadius) { m_closeMeleeAttackerId = closestAttacker->Id(); } }
IStrategizer::TID IStrategizer::AdapterEx::AdaptResourceForGathering(ResourceType p_resourceType, const PlanStepParameters& p_parameters) { GamePlayer *pPlayer; GameEntity *pEntity; vector<TID> entityIds; TID adaptedResourceId = INVALID_TID; double bestDistance = numeric_limits<double>::max(); CellFeature *pResourceCellFeatureFromWorldPosition = new CellFeature(p_parameters); DefinitionCrossMapping pDefinitionCrossMapping = DefinitionCrossMapping::Instance(); pPlayer = g_Game->GetPlayer(PLAYER_Neutral); assert(pPlayer); pPlayer->Entities(entityIds); TID fetchedResourceId; if(pDefinitionCrossMapping.ResourceMapping.TryGetBySecond(p_resourceType, fetchedResourceId) == true) { for (size_t i = 0, size = entityIds.size(); i < size; ++i) { if (fetchedResourceId == entityIds[i]) { pEntity = pPlayer->GetEntity(entityIds[i]); assert(pEntity); CellFeature *pCandidateCellFearure = g_Game->Map()->GetCellFeatureFromWorldPosition(pEntity->GetPosition()); double dist = pResourceCellFeatureFromWorldPosition->GetDistance(pCandidateCellFearure); if (dist <= bestDistance) { bestDistance = dist; adaptedResourceId = pEntity->Id(); } } } } return adaptedResourceId; }
IStrategizer::TID IStrategizer::AdapterEx::GetEntityObjectId(EntityClassType p_entityType ) { GamePlayer *pPlayer; GameEntity *pEntity; vector<TID> entityIds; EntityClassType entityTypeId; TID adaptedEntityId = INVALID_TID; pPlayer = g_Game->Self(); assert(pPlayer); pPlayer->Entities(entityIds); for (size_t i = 0, size = entityIds.size(); i < size; ++i) { pEntity = pPlayer->GetEntity(entityIds[i]); assert(pEntity); if (p_entityType == pEntity->Type() && !pEntity->IsLocked()) { return pEntity->Id(); } } return adaptedEntityId; }
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()); } } }