| 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 | } |