Пример #1
0
        public bool CalculateManaUsage(CastingPreCheckStatus castingPreCheckStatus, Spell spell, WorldObject target, bool isWeaponSpell, out uint manaUsed)
        {
            manaUsed = 0;
            if (castingPreCheckStatus == CastingPreCheckStatus.Success)
            {
                manaUsed = CalculateManaUsage(this, spell, target);
            }
            else if (castingPreCheckStatus == CastingPreCheckStatus.CastFailed)
            {
                manaUsed = 5;   // todo: verify with retail
            }
            var currentMana = Mana.Current;

            if (isWeaponSpell)
            {
                var caster = GetEquippedWand();
                currentMana = (uint)(caster.ItemCurMana ?? 0);
            }

            if (manaUsed > currentMana)
            {
                SendUseDoneEvent(WeenieError.YouDontHaveEnoughManaToCast);
                return(false);
            }

            Proficiency.OnSuccessUse(this, GetCreatureSkill(Skill.ManaConversion), spell.PowerMod);

            return(true);
        }
Пример #2
0
        public void DoCastSpell_Inner(Spell spell, bool isWeaponSpell, uint manaUsed, WorldObject target, CastingPreCheckStatus castingPreCheckStatus)
        {
            // consume mana
            if (!isWeaponSpell)
            {
                UpdateVitalDelta(Mana, -(int)manaUsed);
            }
            else
            {
                var caster = GetEquippedWand();     // TODO: persist this from the beginning, since this is done with delay
                caster.ItemCurMana -= (int)manaUsed;
            }

            // consume spell components
            if (!isWeaponSpell)
            {
                TryBurnComponents(spell);
            }

            // check windup move distance cap
            var endPos = new Position(Location);
            var dist   = StartPos.DistanceTo(endPos);

            bool movedTooFar = false;

            // only PKs affected by these caps?
            if (dist > Windup_MaxMove && PlayerKillerStatus != PlayerKillerStatus.NPK)
            {
                castingPreCheckStatus = CastingPreCheckStatus.CastFailed;
                movedTooFar           = true;
            }

            var pk_error = CheckPKStatusVsTarget(this, target, spell);

            if (pk_error != null)
            {
                castingPreCheckStatus = CastingPreCheckStatus.InvalidPKStatus;
            }

            var useDone = WeenieError.None;

            switch (castingPreCheckStatus)
            {
            case CastingPreCheckStatus.Success:

                if ((spell.Flags & SpellFlags.FellowshipSpell) == 0)
                {
                    CreatePlayerSpell(target, spell);
                }
                else
                {
                    var fellows = GetFellowshipTargets();
                    foreach (var fellow in fellows)
                    {
                        CreatePlayerSpell(fellow, spell);
                    }
                }

                // handle self procs
                if (spell.IsHarmful && target != this)
                {
                    TryProcEquippedItems(this, true);
                }

                break;

            case CastingPreCheckStatus.InvalidPKStatus:

                if (spell.NumProjectiles > 0)
                {
                    switch (spell.School)
                    {
                    case MagicSchool.WarMagic:
                        WarMagic(target, spell);
                        break;

                    case MagicSchool.VoidMagic:
                        VoidMagic(target, spell);
                        break;

                    case MagicSchool.LifeMagic:
                        LifeMagic(spell, out uint damage, out bool critical, out var enchantmentStatus, target);
                        break;
                    }
                }
                break;

            default:
                useDone = WeenieError.YourSpellFizzled;
                EnqueueBroadcast(new GameMessageScript(Guid, PlayScript.Fizzle, 0.5f));
                break;
            }


            if (pk_error != null && spell.NumProjectiles == 0)
            {
                Session.Network.EnqueueSend(new GameEventWeenieErrorWithString(Session, pk_error[0], target.Name));

                if (target is Player targetPlayer)
                {
                    targetPlayer.Session.Network.EnqueueSend(new GameEventWeenieErrorWithString(targetPlayer.Session, pk_error[1], Name));
                }
            }

            if (movedTooFar)
            {
                //player.Session.Network.EnqueueSend(new GameEventWeenieError(player.Session, WeenieError.YouHaveMovedTooFar));
                Session.Network.EnqueueSend(new GameMessageSystemChat("Your movement disrupted spell casting!", ChatMessageType.Magic));
            }

            FinishCast(useDone);
        }
Пример #3
0
        public void DoCastSpell(Spell spell, bool isWeaponSpell, uint magicSkill, uint manaUsed, WorldObject target, CastingPreCheckStatus castingPreCheckStatus)
        {
            //var actionChain = new ActionChain();

            if (target != null)
            {
                // verify target still exists
                var targetCategory = GetTargetCategory(target.Guid.Full, spell.Id, out target);

                if (target == null)
                {
                    FinishCast(WeenieError.TargetNotAcquired);
                    return;
                }

                // do second rotate, if applicable
                // TODO: investigate this more, difference for GetAngle() between ACE and ac physics engine

                /*var angle = 0.0f;
                 * if (target != this)
                 * {
                 *  if (target.CurrentLandblock == null)
                 *  {
                 *      FindObject(target.Guid.Full, SearchLocations.Everywhere, out _, out var rootOwner, out _);
                 *
                 *      if (rootOwner == null)
                 *          log.Error($"{Name}.DoCastSpell({spell.Name}, {isWeaponSpell}, {manaUsed}, {target.Name} ({target.Guid}), {castingPreCheckStatus}) - couldn't find rootTarget");
                 *
                 *      else if (rootOwner != this)
                 *      {
                 *          angle = GetAngle(rootOwner.Location);
                 *          target = rootOwner;
                 *      }
                 *  }
                 *  else
                 *      angle = GetAngle(target.Location);
                 * }
                 *
                 * if (angle > MaxAngle)
                 * {
                 *  var rotateTime = Rotate(target);
                 *  actionChain.AddDelaySeconds(rotateTime);
                 * }*/

                // verify spell range
                if (!VerifySpellRange(target, targetCategory, spell, magicSkill))
                {
                    FinishCast(WeenieError.None);
                    return;
                }
            }

            //actionChain.AddAction(this, () => DoCastSpell_Inner(spell, isWeaponSpell, manaUsed, target, castingPreCheckStatus));
            //actionChain.EnqueueChain();

            DoCastSpell_Inner(spell, isWeaponSpell, manaUsed, target, castingPreCheckStatus);
        }