void CTFObjectiveResource::setup () { CClassInterface::getTF2ObjectiveResource(this); memset(m_pControlPoints,0,sizeof(edict_t*)*MAX_CONTROL_POINTS); memset(m_iControlPointWpt,0xFF,sizeof(int)*MAX_CONTROL_POINTS); memset(m_fLastCaptureTime,0,sizeof(float)*MAX_CONTROL_POINTS); // Find control point entities edict_t *pent; Vector vOrigin; int i = gpGlobals->maxClients; memset(m_IndexToWaypointAreaTranslation,0,sizeof(int)*MAX_CONTROL_POINTS); memset(m_WaypointAreaToIndexTranslation,0xFF,sizeof(int)*(MAX_CONTROL_POINTS+1)); // find visible flags -- with a model while ( ++i < gpGlobals->maxEntities ) { pent = INDEXENT(i); if ( !pent || pent->IsFree() ) continue; if ( strcmp(pent->GetClassName(),"team_control_point") == 0 ) { vOrigin = CBotGlobals::entityOrigin(pent); for ( int j = 0; j < *m_iNumControlPoints; j ++ ) { if ( m_pControlPoints[j].get() != NULL ) continue; if ( vOrigin == m_vCPPositions[j] ) { m_pControlPoints[j] = MyEHandle(pent); //m_pControlPointClass[j] = CTeamControlPoint::getPoint(pent); } } } } CWaypoint *pWaypoint; int iWpt; for ( int j = 0; j < *m_iNumControlPoints; j ++ ) { vOrigin = m_vCPPositions[j]; if ( m_iControlPointWpt[j] == -1 ) { iWpt = CWaypointLocations::NearestWaypoint(vOrigin,1024.0f,-1,false,false,false,NULL,false,0,false,false,Vector(0,0,0),CWaypointTypes::W_FL_CAPPOINT); pWaypoint = CWaypoints::getWaypoint(iWpt); m_iControlPointWpt[j] = iWpt; // For compatibility -- old waypoints are already set with an area, so take the area from the waypoint here // in the future waypoints will automatically be set to the waypoint area anyway if ( pWaypoint ) { int iArea = pWaypoint->getArea(); m_IndexToWaypointAreaTranslation[j] = iArea; if ( ( iArea >= 1 ) && ( iArea < MAX_CONTROL_POINTS ) ) m_WaypointAreaToIndexTranslation[iArea] = j; } else { m_IndexToWaypointAreaTranslation[j] = 0; m_WaypointAreaToIndexTranslation[j+1] = -1; } } } m_bInitialised = true; }
bool CCollision::AStar(vec2 Start, vec2 End) { vector<CWaypoint*> path; // Define points to work with CWaypoint *StartWP = GetClosestWaypoint(Start); CWaypoint *EndWP = GetClosestWaypoint(End); CWaypoint *CurrentWP = NULL; CWaypoint *ChildWP = NULL; if (!StartWP || !EndWP) return false; for (int i = 0; i < m_WaypointCount; i++) { if (m_apWaypoint[i]) m_apWaypoint[i]->ClearForAStar(); } // Define the open and the close list list<CWaypoint*> openList; list<CWaypoint*> closedList; list<CWaypoint*>::iterator i; unsigned int n = 0; // Add the start point to the openList openList.push_back(StartWP); StartWP->m_Opened = true; // while (n == 0 || (CurrentWP != EndWP && n < 400)) while (n < 2000) { // Look for the smallest F value in the openList and make it the current point for (i = openList.begin(); i != openList.end(); ++ i) { if (i == openList.begin() || (*i)->m_F <= CurrentWP->m_F) { CurrentWP = (*i); } } // Stop if we reached the end if (CurrentWP == EndWP) break; // Remove the current point from the openList openList.remove(CurrentWP); CurrentWP->m_Opened = false; // Add the current point to the closedList closedList.push_back(CurrentWP); CurrentWP->m_Closed = true; // Get all current's adjacent walkable points for (int w = 0; w < CurrentWP->m_ConnectionCount; w++) { // Get this point ChildWP = CurrentWP->m_apConnection[w]; if (!ChildWP) continue; if (ChildWP->m_Closed) continue; // If it's already in the openList if (ChildWP->m_Opened) { // If it has a worse g score than the one that pass through the current point // then its path is improved when it's parent is the current point if (ChildWP->m_G > ChildWP->GetGScore(CurrentWP, EndWP->m_Pos)) { // Change its parent and g score ChildWP->m_pParent = CurrentWP; ChildWP->ComputeScores(EndWP->m_Pos); } } else { // Add it to the openList with current point as parent openList.push_back(ChildWP); ChildWP->m_Opened = true; // Compute it's g, h and f score ChildWP->m_pParent = CurrentWP; ChildWP->ComputeScores(EndWP->m_Pos); } } n++; } // Reset for (i = openList.begin(); i != openList.end(); ++ i) { (*i)->m_Opened = false; } for (i = closedList.begin(); i != closedList.end(); ++ i) { (*i)->m_Closed = false; } if (m_pPath) { delete m_pPath; m_pPath = NULL; } // Resolve the path starting from the end point while (CurrentWP->m_pParent && CurrentWP != StartWP) { /* if (!m_pPath) m_pPath = new CWaypointPath(CurrentWP->m_Pos); else m_pPath->PushBack(new CWaypointPath(CurrentWP->m_Pos)); */ m_pPath = new CWaypointPath(CurrentWP->m_Pos, m_pPath); //path.push_back(CurrentWP->getPosition()); CurrentWP = CurrentWP->m_pParent; n++; } // for displaying the chosen waypoints for (int w = 0; w < 99; w++) m_aPath[w] = vec2(0, 0); if (m_pPath) { CWaypointPath *Wp = m_pPath; for (int w = 0; w < 80; w++) { m_PathLen = w; m_aPath[w] = vec2(Wp->m_Pos.x, Wp->m_Pos.y); if (Wp->m_pNext) Wp = Wp->m_pNext; else break; } } if (m_pPath) return true; else return false; }
// from the bots UTILITIES , execute the given action bool CHLDMBot :: executeAction ( eBotAction iAction ) { switch ( iAction ) { case BOT_UTIL_HL2DM_USE_CRATE: // check if it is worth it first { const char *szModel; char type; CBotWeapon *pWeapon = NULL; /* possible models 0000000000111111111122222222223333 0123456789012345678901234567890123 models/items/ammocrate_ar2.mdl models/items/ammocrate_grenade.mdl models/items/ammocrate_rockets.mdl models/items/ammocrate_smg1.mdl */ szModel = m_pAmmoCrate.get()->GetIServerEntity()->GetModelName().ToCStr(); type = szModel[23]; if ( type == 'a' ) // ar2 { pWeapon = m_pWeapons->getWeapon(CWeapons::getWeapon(HL2DM_WEAPON_AR2)); } else if ( type == 'g' ) // grenade { pWeapon = m_pWeapons->getWeapon(CWeapons::getWeapon(HL2DM_WEAPON_FRAG)); } else if ( type == 'r' ) // rocket { pWeapon = m_pWeapons->getWeapon(CWeapons::getWeapon(HL2DM_WEAPON_RPG)); } else if ( type == 's' ) // smg { pWeapon = m_pWeapons->getWeapon(CWeapons::getWeapon(HL2DM_WEAPON_SMG1)); } if ( pWeapon && (pWeapon->getAmmo(this) < 1) ) { CBotSchedule *pSched = new CBotSchedule(); pSched->addTask(new CFindPathTask(m_pAmmoCrate)); pSched->addTask(new CBotHL2DMUseButton(m_pAmmoCrate)); m_pSchedules->add(pSched); m_fUtilTimes[iAction] = engine->Time() + randomFloat(5.0f,10.0f); return true; } } return false; case BOT_UTIL_PICKUP_WEAPON: m_pSchedules->add(new CBotPickupSched(m_pNearbyWeapon.get())); return true; case BOT_UTIL_FIND_NEAREST_HEALTH: m_pSchedules->add(new CBotPickupSched(m_pHealthKit.get())); return true; case BOT_UTIL_HL2DM_FIND_ARMOR: m_pSchedules->add(new CBotPickupSched(m_pBattery.get())); return true; case BOT_UTIL_FIND_NEAREST_AMMO: m_pSchedules->add(new CBotPickupSched(m_pAmmoKit.get())); m_fUtilTimes[iAction] = engine->Time() + randomFloat(5.0f,10.0f); return true; case BOT_UTIL_HL2DM_USE_HEALTH_CHARGER: { CBotSchedule *pSched = new CBotSchedule(); pSched->addTask(new CFindPathTask(m_pHealthCharger)); pSched->addTask(new CBotHL2DMUseCharger(m_pHealthCharger,CHARGER_HEALTH)); m_pSchedules->add(pSched); m_fUtilTimes[BOT_UTIL_HL2DM_USE_HEALTH_CHARGER] = engine->Time() + randomFloat(5.0f,10.0f); return true; } case BOT_UTIL_HL2DM_USE_CHARGER: { CBotSchedule *pSched = new CBotSchedule(); pSched->addTask(new CFindPathTask(m_pCharger)); pSched->addTask(new CBotHL2DMUseCharger(m_pCharger,CHARGER_ARMOR)); m_pSchedules->add(pSched); m_fUtilTimes[BOT_UTIL_HL2DM_USE_CHARGER] = engine->Time() + randomFloat(5.0f,10.0f); return true; } case BOT_UTIL_HL2DM_GRAVIGUN_PICKUP: { CBotSchedule *pSched = new CBotSchedule(new CBotGravGunPickup(m_pCurrentWeapon,m_NearestPhysObj)); pSched->setID(SCHED_GRAVGUN_PICKUP); m_pSchedules->add(pSched); return true; } case BOT_UTIL_FIND_LAST_ENEMY: { Vector vVelocity = Vector(0,0,0); CClient *pClient = CClients::get(m_pLastEnemy); CBotSchedule *pSchedule = new CBotSchedule(); CFindPathTask *pFindPath = new CFindPathTask(m_vLastSeeEnemy); pFindPath->setCompleteInterrupt(CONDITION_SEE_CUR_ENEMY); if ( !CClassInterface::getVelocity(m_pLastEnemy,&vVelocity) ) { if ( pClient ) vVelocity = pClient->getVelocity(); } pSchedule->addTask(pFindPath); pSchedule->addTask(new CFindLastEnemy(m_vLastSeeEnemy,vVelocity)); ////////////// pFindPath->setNoInterruptions(); m_pSchedules->add(pSchedule); m_bLookedForEnemyLast = true; return true; } case BOT_UTIL_THROW_GRENADE: { // find hide waypoint CWaypoint *pWaypoint = CWaypoints::getWaypoint(CWaypointLocations::GetCoverWaypoint(getOrigin(),m_vLastSeeEnemy,NULL)); if ( pWaypoint ) { CBotSchedule *pSched = new CBotSchedule(); pSched->addTask(new CThrowGrenadeTask(m_pWeapons->getWeapon(CWeapons::getWeapon(HL2DM_WEAPON_FRAG)),getAmmo(CWeapons::getWeapon(HL2DM_WEAPON_FRAG)->getAmmoIndex1()),m_vLastSeeEnemyBlastWaypoint)); // first - throw pSched->addTask(new CFindPathTask(pWaypoint->getOrigin())); // 2nd -- hide m_pSchedules->add(pSched); return true; } } case BOT_UTIL_SNIPE: { // roam CWaypoint *pWaypoint = CWaypoints::randomWaypointGoal(CWaypointTypes::W_FL_SNIPER); if ( pWaypoint ) { CBotSchedule *snipe = new CBotSchedule(); CBotTask *findpath = new CFindPathTask(CWaypoints::getWaypointIndex(pWaypoint)); CBotTask *snipetask; // use DOD task snipetask = new CBotHL2DMSnipe(m_pWeapons->getWeapon(CWeapons::getWeapon(HL2DM_WEAPON_CROSSBOW)),pWaypoint->getOrigin(),pWaypoint->getAimYaw(),false,0); findpath->setCompleteInterrupt(CONDITION_PUSH); snipetask->setCompleteInterrupt(CONDITION_PUSH); snipe->setID(SCHED_DEFENDPOINT); snipe->addTask(findpath); snipe->addTask(snipetask); m_pSchedules->add(snipe); return true; } break; } case BOT_UTIL_ROAM: // roam CWaypoint *pWaypoint = CWaypoints::getWaypoint(CWaypoints::randomFlaggedWaypoint(getTeam())); if ( pWaypoint ) { m_pSchedules->add(new CBotGotoOriginSched(pWaypoint->getOrigin())); return true; } break; } return false; }