void RotateMovementGenerator::Initialize(Unit& owner) { if (owner.HasUnitState(UNIT_STAT_MOVE)) owner.StopMoving(); if (owner.getVictim()) owner.SetInFront(owner.getVictim()); owner.AddUnitState(UNIT_STAT_ROTATING); }
void HandleDummyTick(AuraEffect const* /*aurEff*/) { Unit* caster = GetCaster(); Unit* target = GetTarget(); if (caster && target) { if (target->HasUnitState(UNIT_STATE_CASTING)) { caster->CastSpell(target, SPELL_MISTRESS_KISS_DAMAGE_SILENCE, true); target->RemoveAurasDueToSpell(GetSpellInfo()->Id); } } }
void HandleEffect(SpellEffIndex /* effIndex */) { uint32 spellId = 0; if (GetCaster()->HasAura(SPELL_UNRELENTING_ASSAULT_RANK_1)) spellId = SPELL_UNRELENTING_ASSAULT_TRIGGER_1; else if (GetCaster()->HasAura(SPELL_UNRELENTING_ASSAULT_RANK_2)) spellId = SPELL_UNRELENTING_ASSAULT_TRIGGER_2; if (!spellId) return; Unit* target = GetHitUnit(); if (target->HasUnitState(UNIT_STATE_CASTING)) GetCaster()->CastSpell(target, spellId, true); }
SpellCastResult CheckCast() { Unit* caster = GetCaster(); // Death Grip should not be castable while jumping/falling if (caster->HasUnitState(UNIT_STATE_JUMPING) || caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING)) return SPELL_FAILED_MOVING; // Patch 3.3.3 (2010-03-23): Minimum range has been changed to 8 yards in PvP. Unit* target = GetExplTargetUnit(); if (target && target->GetTypeId() == TYPEID_PLAYER) if (caster->GetDistance(target) < 8.f) return SPELL_FAILED_TOO_CLOSE; return SPELL_CAST_OK; }
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* caster = GetCaster(); Unit* target = GetTarget(); if (caster && target) { // Glyph of Silencing Shot energize on spell interruption if (caster->HasAura(SPELL_HUNTER_GLYPH_OF_SILENCING_SHOT) && target->HasUnitState(UNIT_STATE_CASTING)) { // Fixed value int32 bp0 = 10; caster->CastCustomSpell(caster, SPELL_HUNTER_FOCUS_ENERGIZE, &bp0, NULL, NULL, true); } } }
bool TimedFleeingMovementGenerator::Update(Unit & owner, const uint32 time_diff) { if (!owner.isAlive()) return false; if (owner.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED)) return true; i_totalFleeTime.Update(time_diff); if (i_totalFleeTime.Passed()) return false; // This calls grant-parent Update method hiden by FleeingMovementGenerator::Update(Creature &, const uint32) version // This is done instead of casting Unit& to Creature& and call parent method, then we can use Unit directly return MovementGeneratorMedium< Creature, FleeingMovementGenerator<Creature> >::Update(owner, time_diff); }
void HandleDummy(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); // Shapeshifting into an animal form or mounting cancels the effect if (caster->GetCreatureType() == CREATURE_TYPE_BEAST || caster->IsMounted()) { if (SpellInfo const* spellInfo = GetTriggeringSpell()) caster->RemoveAurasDueToSpell(spellInfo->Id); return; } // Any effect which causes you to lose control of your character will supress the starfall effect. if (caster->HasUnitState(UNIT_STATE_CONTROLLED)) return; caster->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true); }
void EffectMovementGenerator::Finalize(Unit& unit) { if (unit.GetTypeId() != TYPEID_UNIT) return; // Need restore previous movement since we have no proper states system if (unit.IsAlive() && !unit.HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING | UNIT_STATE_DISTRACTED)) { if (Unit* victim = unit.getVictim()) unit.GetMotionMaster()->MoveChase(victim); else unit.GetMotionMaster()->Initialize(); } if (unit.ToCreature()->AI()) unit.ToCreature()->AI()->MovementInform(EFFECT_MOTION_TYPE, m_Id); }
void IdleMovementGenerator::Reset(Unit& owner) { if (owner.HasUnitState(UNIT_STAT_MOVE)) owner.StopMoving(); }
void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket) { ;//sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_PET_CAST_SPELL"); uint64 guid; uint8 castCount; uint32 spellId; uint8 castFlags; recvPacket >> guid >> castCount >> spellId >> castFlags; ;//sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_PET_CAST_SPELL, guid: " UI64FMTD ", castCount: %u, spellId %u, castFlags %u", guid, castCount, spellId, castFlags); // This opcode is also sent from charmed and possessed units (players and creatures) if (!_player->GetGuardianPet() && !_player->GetCharm()) return; Unit* caster = ObjectAccessor::GetUnit(*_player, guid); if (!caster || (caster != _player->GetGuardianPet() && caster != _player->GetCharm())) { sLog->outError("HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)), GetPlayer()->GetName().c_str()); return; } SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) { sLog->outError("WORLD: unknown PET spell id %i", spellId); return; } // do not cast not learned spells if (!caster->HasSpell(spellId) || spellInfo->IsPassive()) return; SpellCastTargets targets; targets.Read(recvPacket, caster); HandleClientCastFlags(recvPacket, castFlags, targets); bool SetFollow = caster->HasUnitState(UNIT_STATE_FOLLOW); caster->ClearUnitState(UNIT_STATE_FOLLOW); Spell* spell = new Spell(caster, spellInfo, TRIGGERED_NONE); spell->m_cast_count = castCount; // probably pending spell cast spell->m_targets = targets; spell->LoadScripts(); // Xinef: Send default target, fixes return on NeedExplicitUnitTarget Unit* target = targets.GetUnitTarget(); if (!target && spell->m_spellInfo->NeedsExplicitUnitTarget()) target = _player->GetSelectedUnit(); SpellCastResult result = spell->CheckPetCast(target); if (result == SPELL_CAST_OK) { if (Creature* creature = caster->ToCreature()) { creature->AddSpellCooldown(spellId, 0, 0); if (Pet* pet = creature->ToPet()) { // 10% chance to play special pet attack talk, else growl // actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell if (pet->getPetType() == SUMMON_PET && (urand(0, 100) < 10)) pet->SendPetTalk(PET_TALK_SPECIAL_SPELL); else pet->SendPetAIReaction(guid); } } spell->prepare(&(spell->m_targets)); } else { if (!caster->GetCharmInfo() || !caster->GetCharmInfo()->GetForcedSpell()) spell->SendPetCastResult(result); if (caster->GetTypeId() == TYPEID_PLAYER) { if (!caster->ToPlayer()->HasSpellCooldown(spellId)) GetPlayer()->SendClearCooldown(spellId, caster); } else { if (!caster->ToCreature()->HasSpellCooldown(spellId)) GetPlayer()->SendClearCooldown(spellId, caster); // reset specific flags in case of spell fail. AI will reset other flags if (caster->IsPet()) caster->PetSpellFail(spellInfo, targets.GetUnitTarget(), result); } spell->finish(false); delete spell; } if (SetFollow && !caster->IsInCombat()) caster->AddUnitState(UNIT_STATE_FOLLOW); }
// StopMoving is needed to make unit stop if its last movement generator expires // But it should not be sent otherwise there are many redundent packets void IdleMovementGenerator::Initialize(Unit& owner) { if (owner.HasUnitState(UNIT_STATE_MOVE)) owner.StopMoving(); }