void HandleUseToy(UseToy packet) { uint itemId = packet.Cast.Misc[0]; ItemTemplate item = Global.ObjectMgr.GetItemTemplate(itemId); if (item == null) { return; } if (!_collectionMgr.HasToy(itemId)) { return; } var effect = item.Effects.Find(eff => packet.Cast.SpellID == eff.SpellID); if (effect == null) { return; } SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(packet.Cast.SpellID); if (spellInfo == null) { Log.outError(LogFilter.Network, "HandleUseToy: unknown spell id: {0} used by Toy Item entry {1}", packet.Cast.SpellID, itemId); return; } if (_player.isPossessing()) { return; } SpellCastTargets targets = new SpellCastTargets(_player, packet.Cast); Spell spell = new Spell(_player, spellInfo, TriggerCastFlags.None, ObjectGuid.Empty, false); SpellPrepare spellPrepare = new SpellPrepare(); spellPrepare.ClientCastID = packet.Cast.CastID; spellPrepare.ServerCastID = spell.m_castId; SendPacket(spellPrepare); spell.m_fromClient = true; spell.m_castItemEntry = itemId; spell.m_misc.Data0 = packet.Cast.Misc[0]; spell.m_misc.Data1 = packet.Cast.Misc[1]; spell.m_castFlagsEx |= SpellCastFlagsEx.UseToySpell; spell.prepare(targets); }
void HandleCastSpell(CastSpell cast) { // ignore for remote control state (for player case) Unit mover = GetPlayer().m_unitMovedByMe; if (mover != GetPlayer() && mover.IsTypeId(TypeId.Player)) { return; } SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(cast.Cast.SpellID); if (spellInfo == null) { Log.outError(LogFilter.Network, "WORLD: unknown spell id {0}", cast.Cast.SpellID); return; } if (spellInfo.IsPassive()) { return; } Unit caster = mover; if (caster.IsTypeId(TypeId.Unit) && !caster.ToCreature().HasSpell(spellInfo.Id)) { // If the vehicle creature does not have the spell but it allows the passenger to cast own spells // change caster to player and let him cast if (!GetPlayer().IsOnVehicle(caster) || spellInfo.CheckVehicle(GetPlayer()) != SpellCastResult.SpellCastOk) { return; } caster = GetPlayer(); } // check known spell or raid marker spell (which not requires player to know it) if (caster.IsTypeId(TypeId.Player) && !caster.ToPlayer().HasActiveSpell(spellInfo.Id) && !spellInfo.HasEffect(SpellEffectName.ChangeRaidMarker) && !spellInfo.HasAttribute(SpellAttr8.RaidMarker)) { return; } // Check possible spell cast overrides spellInfo = caster.GetCastSpellInfo(spellInfo); // Client is resending autoshot cast opcode when other spell is casted during shoot rotation // Skip it to prevent "interrupt" message if (spellInfo.IsAutoRepeatRangedSpell() && GetPlayer().GetCurrentSpell(CurrentSpellTypes.AutoRepeat) != null && GetPlayer().GetCurrentSpell(CurrentSpellTypes.AutoRepeat).m_spellInfo == spellInfo) { return; } // can't use our own spells when we're in possession of another unit, if (GetPlayer().isPossessing()) { return; } // client provided targets SpellCastTargets targets = new SpellCastTargets(caster, cast.Cast); // auto-selection buff level base at target level (in spellInfo) if (targets.GetUnitTarget() != null) { SpellInfo actualSpellInfo = spellInfo.GetAuraRankForLevel(targets.GetUnitTarget().GetLevelForTarget(caster)); // if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message if (actualSpellInfo != null) { spellInfo = actualSpellInfo; } } if (cast.Cast.MoveUpdate.HasValue) { HandleMovementOpcode(ClientOpcodes.MoveStop, cast.Cast.MoveUpdate.Value); } Spell spell = new Spell(caster, spellInfo, TriggerCastFlags.None, ObjectGuid.Empty, false); SpellPrepare spellPrepare = new SpellPrepare(); spellPrepare.ClientCastID = cast.Cast.CastID; spellPrepare.ServerCastID = spell.m_castId; SendPacket(spellPrepare); spell.m_fromClient = true; spell.m_misc.Data0 = cast.Cast.Misc[0]; spell.m_misc.Data1 = cast.Cast.Misc[1]; spell.prepare(targets); }
void HandlePetCastSpell(PetCastSpell petCastSpell) { SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(petCastSpell.Cast.SpellID); if (spellInfo == null) { Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: unknown spell id {0} tried to cast by {1}", petCastSpell.Cast.SpellID, petCastSpell.PetGUID.ToString()); return; } Unit caster = Global.ObjAccessor.GetUnit(GetPlayer(), petCastSpell.PetGUID); if (!caster) { Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: Caster {0} not found.", petCastSpell.PetGUID.ToString()); return; } // This opcode is also sent from charmed and possessed units (players and creatures) if (caster != GetPlayer().GetGuardianPet() && caster != GetPlayer().GetCharm()) { Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: {0} isn't pet of player {1} ({2}).", petCastSpell.PetGUID.ToString(), GetPlayer().GetName(), GetPlayer().GetGUID().ToString()); return; } // do not cast not learned spells if (!caster.HasSpell(spellInfo.Id) || spellInfo.IsPassive()) { return; } SpellCastTargets targets = new SpellCastTargets(caster, petCastSpell.Cast); caster.ClearUnitState(UnitState.Follow); Spell spell = new Spell(caster, spellInfo, TriggerCastFlags.None); spell.m_fromClient = true; spell.m_misc.Data0 = petCastSpell.Cast.Misc[0]; spell.m_misc.Data1 = petCastSpell.Cast.Misc[1]; spell.m_targets = targets; SpellCastResult result = spell.CheckPetCast(null); if (result == SpellCastResult.SpellCastOk) { Creature creature = caster.ToCreature(); if (creature) { Pet pet = creature.ToPet(); if (pet) { // 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() == PetType.Summon && (RandomHelper.IRand(0, 100) < 10)) { pet.SendPetTalk(PetTalk.SpecialSpell); } else { pet.SendPetAIReaction(petCastSpell.PetGUID); } } } SpellPrepare spellPrepare = new SpellPrepare(); spellPrepare.ClientCastID = petCastSpell.Cast.CastID; spellPrepare.ServerCastID = spell.m_castId; SendPacket(spellPrepare); spell.prepare(targets); } else { spell.SendPetCastResult(result); if (!caster.GetSpellHistory().HasCooldown(spellInfo.Id)) { caster.GetSpellHistory().ResetCooldown(spellInfo.Id, true); } spell.finish(false); spell.Dispose(); } }