231 | | //Autocast |
232 | | HM_NAMESPACE::hash_map<uint32, Unit*> targetMap; |
233 | | targetMap.clear(); |
234 | | SpellCastTargets NULLtargets; |
235 | | |
236 | | for (uint8 i = 0; i < i_pet.GetPetAutoSpellSize(); i++) |
237 | | { |
238 | | uint32 spellID = i_pet.GetPetAutoSpellOnPos(i); |
239 | | if (!spellID) |
240 | | continue; |
241 | | |
242 | | SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID); |
243 | | if (!spellInfo) |
244 | | continue; |
245 | | |
246 | | Spell *spell = new Spell(&i_pet, spellInfo, false, 0); |
247 | | |
248 | | if(!IsPositiveSpell(spellInfo->Id) && i_pet.getVictim() && !_needToStop() && !i_pet.hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(i_pet.getVictim())) |
249 | | targetMap[spellID] = i_pet.getVictim(); |
250 | | else |
251 | | { |
252 | | spell->m_targets = NULLtargets; |
253 | | for(std::set<uint64>::iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar) |
254 | | { |
255 | | Unit* Target = ObjectAccessor::GetUnit(i_pet,*tar); |
256 | | |
257 | | //only buff targets that are in combat, unless the spell can only be cast while out of combat |
258 | | if(!Target || (!Target->isInCombat() && !IsNonCombatSpell(spellInfo))) |
| 199 | if (i_pet.GetGlobalCooldown() == 0 && !i_pet.IsNonMeleeSpellCasted(false)) |
| 200 | { |
| 201 | //Autocast |
| 202 | for (uint8 i = 0; i < i_pet.GetPetAutoSpellSize(); i++) |
| 203 | { |
| 204 | uint32 spellID = i_pet.GetPetAutoSpellOnPos(i); |
| 205 | if (!spellID) |
| 206 | continue; |
| 207 | |
| 208 | SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID); |
| 209 | if (!spellInfo) |
| 210 | continue; |
| 211 | |
| 212 | // ignore some combinations of combat state and combat/noncombat spells |
| 213 | if (!inCombat) |
| 214 | { |
| 215 | if (!IsPositiveSpell(spellInfo->Id)) |
260 | | if(spell->CanAutoCast(Target)) |
261 | | targetMap[spellID] = Target; |
262 | | } |
263 | | } |
264 | | |
265 | | delete spell; |
266 | | } |
267 | | |
268 | | //found units to cast on to |
269 | | if(!targetMap.empty()) |
270 | | { |
271 | | uint32 index = urand(1, targetMap.size()); |
272 | | HM_NAMESPACE::hash_map<uint32, Unit*>::iterator itr; |
273 | | uint32 i; |
274 | | for(itr = targetMap.begin(), i = 1; i < index; ++itr, ++i); |
275 | | |
276 | | SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); |
277 | | |
278 | | Spell *spell = new Spell(&i_pet, spellInfo, false); |
279 | | |
280 | | SpellCastTargets targets; |
281 | | targets.setUnitTarget( itr->second ); |
282 | | |
283 | | if(!i_pet.HasInArc(M_PI, itr->second)) |
284 | | { |
285 | | i_pet.SetInFront(itr->second); |
286 | | if( itr->second->GetTypeId() == TYPEID_PLAYER ) |
287 | | i_pet.SendUpdateToPlayer( (Player*)itr->second ); |
288 | | |
289 | | if(owner && owner->GetTypeId() == TYPEID_PLAYER) |
290 | | i_pet.SendUpdateToPlayer( (Player*)owner ); |
291 | | } |
292 | | |
293 | | i_pet.AddCreatureSpellCooldown(itr->first); |
294 | | if(i_pet.isPet()) |
295 | | ((Pet*)&i_pet)->CheckLearning(itr->first); |
296 | | |
297 | | spell->prepare(&targets); |
298 | | } |
299 | | targetMap.clear(); |
| 217 | } |
| 218 | else |
| 219 | { |
| 220 | if (IsNonCombatSpell(spellInfo)) |
| 221 | continue; |
| 222 | } |
| 223 | |
| 224 | Spell *spell = new Spell(&i_pet, spellInfo, false, 0); |
| 225 | |
| 226 | if(inCombat && !i_pet.hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(i_pet.getVictim())) |
| 227 | { |
| 228 | m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(i_pet.getVictim(), spell)); |
| 229 | continue; |
| 230 | } |
| 231 | else |
| 232 | { |
| 233 | bool spellUsed = false; |
| 234 | for(std::set<uint64>::iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar) |
| 235 | { |
| 236 | Unit* Target = ObjectAccessor::GetUnit(i_pet,*tar); |
| 237 | |
| 238 | //only buff targets that are in combat, unless the spell can only be cast while out of combat |
| 239 | if(!Target) |
| 240 | continue; |
| 241 | |
| 242 | if(spell->CanAutoCast(Target)) |
| 243 | { |
| 244 | m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(Target, spell)); |
| 245 | spellUsed = true; |
| 246 | break; |
| 247 | } |
| 248 | } |
| 249 | if (!spellUsed) |
| 250 | delete spell; |
| 251 | } |
| 252 | } |
| 253 | |
| 254 | //found units to cast on to |
| 255 | if(!m_targetSpellStore.empty()) |
| 256 | { |
| 257 | uint32 index = urand(0, m_targetSpellStore.size() - 1); |
| 258 | |
| 259 | Spell* spell = m_targetSpellStore[index].second; |
| 260 | Unit* target = m_targetSpellStore[index].first; |
| 261 | |
| 262 | m_targetSpellStore.erase(m_targetSpellStore.begin() + index); |
| 263 | |
| 264 | SpellCastTargets targets; |
| 265 | targets.setUnitTarget( target ); |
| 266 | |
| 267 | if( !i_pet.HasInArc(M_PI, target) ) |
| 268 | { |
| 269 | i_pet.SetInFront(target); |
| 270 | if( target->GetTypeId() == TYPEID_PLAYER ) |
| 271 | i_pet.SendUpdateToPlayer( (Player*)target ); |
| 272 | |
| 273 | if(owner && owner->GetTypeId() == TYPEID_PLAYER) |
| 274 | i_pet.SendUpdateToPlayer( (Player*)owner ); |
| 275 | } |
| 276 | |
| 277 | i_pet.AddCreatureSpellCooldown(spell->m_spellInfo->Id); |
| 278 | if(i_pet.isPet()) |
| 279 | ((Pet*)&i_pet)->CheckLearning(spell->m_spellInfo->Id); |
| 280 | |
| 281 | spell->prepare(&targets); |
| 282 | } |
| 283 | while (!m_targetSpellStore.empty()) |
| 284 | { |
| 285 | delete m_targetSpellStore.begin()->second; |
| 286 | m_targetSpellStore.erase(m_targetSpellStore.begin()); |
| 287 | } |
| 288 | } |