| | 262 | } |
| | 263 | |
| | 264 | struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool> |
| | 265 | { |
| | 266 | const Unit* me; |
| | 267 | TargetDistanceOrder(const Unit* Target) : me(Target) {}; |
| | 268 | // functor for operator ">" |
| | 269 | bool operator()(const Unit* _Left, const Unit* _Right) const |
| | 270 | { |
| | 271 | return (me->GetDistance(_Left) < me->GetDistance(_Right)); |
| | 272 | } |
| | 273 | }; |
| | 274 | |
| | 275 | Unit* ScriptedAI::SelectUnit(SelectAggroTarget targetType, uint32 position, float dist, bool playerOnly) |
| | 276 | { |
| | 277 | if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) |
| | 278 | { |
| | 279 | std::list<HostilReference*> &m_threatlist = m_creature->getThreatManager().getThreatList(); |
| | 280 | if(m_threatlist.empty()) return NULL; |
| | 281 | std::list<Unit*> targetList; |
| | 282 | std::list<HostilReference*>::iterator itr = m_threatlist.begin(); |
| | 283 | for(; itr!= m_threatlist.end(); ++itr) |
| | 284 | { |
| | 285 | Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); |
| | 286 | if(!target |
| | 287 | || playerOnly && target->GetTypeId() != TYPEID_PLAYER |
| | 288 | || dist && !m_creature->IsWithinDistInMap(target, dist)) |
| | 289 | { |
| | 290 | continue; |
| | 291 | } |
| | 292 | targetList.push_back(target); |
| | 293 | } |
| | 294 | if(position >= targetList.size()) |
| | 295 | return NULL; |
| | 296 | targetList.sort(TargetDistanceOrder(m_creature)); |
| | 297 | if(targetType == SELECT_TARGET_NEAREST) |
| | 298 | { |
| | 299 | std::list<Unit*>::iterator i = targetList.begin(); |
| | 300 | advance(i, position); |
| | 301 | return *i; |
| | 302 | } |
| | 303 | else |
| | 304 | { |
| | 305 | std::list<Unit*>::reverse_iterator i = targetList.rbegin(); |
| | 306 | advance(i, position); |
| | 307 | return *i; |
| | 308 | } |
| | 309 | } |
| | 310 | else |
| | 311 | { |
| | 312 | std::list<HostilReference*> m_threatlist = m_creature->getThreatManager().getThreatList(); |
| | 313 | std::list<HostilReference*>::iterator i; |
| | 314 | Unit *target; |
| | 315 | while(position < m_threatlist.size()) |
| | 316 | { |
| | 317 | if(targetType == SELECT_TARGET_BOTTOMAGGRO) |
| | 318 | { |
| | 319 | i = m_threatlist.end(); |
| | 320 | advance(i, - (int32)position - 1); |
| | 321 | } |
| | 322 | else |
| | 323 | { |
| | 324 | i = m_threatlist.begin(); |
| | 325 | if(targetType == SELECT_TARGET_TOPAGGRO) |
| | 326 | advance(i, position); |
| | 327 | else // random |
| | 328 | advance(i, position + rand()%(m_threatlist.size() - position)); |
| | 329 | } |
| | 330 | |
| | 331 | target = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()); |
| | 332 | if(!target |
| | 333 | || playerOnly && target->GetTypeId() != TYPEID_PLAYER |
| | 334 | || dist && !m_creature->IsWithinDistInMap(target, dist)) |
| | 335 | { |
| | 336 | m_threatlist.erase(i); |
| | 337 | } |
| | 338 | else |
| | 339 | { |
| | 340 | return target; |
| | 341 | } |
| | 342 | } |
| | 343 | } |
| | 344 | |
| | 345 | return NULL; |
| | 346 | } |
| | 347 | |
| | 348 | void ScriptedAI::SelectUnitList(std::list<Unit*> &targetList, uint32 num, SelectAggroTarget targetType, float dist, bool playerOnly) |
| | 349 | { |
| | 350 | if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) |
| | 351 | { |
| | 352 | std::list<HostilReference*> &m_threatlist = m_creature->getThreatManager().getThreatList(); |
| | 353 | if(m_threatlist.empty()) return; |
| | 354 | std::list<HostilReference*>::iterator itr = m_threatlist.begin(); |
| | 355 | for(; itr!= m_threatlist.end(); ++itr) |
| | 356 | { |
| | 357 | Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); |
| | 358 | if(!target |
| | 359 | || playerOnly && target->GetTypeId() != TYPEID_PLAYER |
| | 360 | || dist && !m_creature->IsWithinDistInMap(target, dist)) |
| | 361 | { |
| | 362 | continue; |
| | 363 | } |
| | 364 | targetList.push_back(target); |
| | 365 | } |
| | 366 | targetList.sort(TargetDistanceOrder(m_creature)); |
| | 367 | targetList.resize(num); |
| | 368 | if(targetType == SELECT_TARGET_FARTHEST) |
| | 369 | targetList.reverse(); |
| | 370 | } |
| | 371 | else |
| | 372 | { |
| | 373 | std::list<HostilReference*> m_threatlist = m_creature->getThreatManager().getThreatList(); |
| | 374 | std::list<HostilReference*>::iterator i; |
| | 375 | Unit *target; |
| | 376 | while(m_threatlist.size()) |
| | 377 | { |
| | 378 | if(targetType == SELECT_TARGET_BOTTOMAGGRO) |
| | 379 | { |
| | 380 | i = m_threatlist.end(); |
| | 381 | --i; |
| | 382 | } |
| | 383 | else |
| | 384 | { |
| | 385 | i = m_threatlist.begin(); |
| | 386 | if(targetType == SELECT_TARGET_RANDOM) |
| | 387 | advance(i, rand()%m_threatlist.size()); |
| | 388 | } |
| | 389 | |
| | 390 | target = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()); |
| | 391 | m_threatlist.erase(i); |
| | 392 | if(!target |
| | 393 | || playerOnly && target->GetTypeId() != TYPEID_PLAYER |
| | 394 | || dist && !m_creature->IsWithinDistInMap(target, dist)) |
| | 395 | { |
| | 396 | continue; |
| | 397 | } |
| | 398 | targetList.push_back(target); |
| | 399 | } |
| | 400 | } |