Example #1
0
        /// <summary>
        /// Method used for handling creature targeted spell casts
        /// </summary>
        public void CreateCreatureSpell(ObjectGuid guidTarget, uint spellId)
        {
            Creature creature = CurrentLandblock?.GetObject(Guid) as Creature;

            if (creature.IsBusy == true)
            {
                return;
            }

            creature.IsBusy = true;

            SpellTable spellTable = DatManager.PortalDat.SpellTable;

            if (!spellTable.Spells.ContainsKey(spellId))
            {
                creature.IsBusy = false;
                return;
            }

            SpellBase spell = spellTable.Spells[spellId];

            bool targetSelf = false || (int)Math.Floor(spell.BaseRangeConstant) == 0;
            var  target     = targetSelf ? this : CurrentLandblock?.GetObject(guidTarget);

            Database.Models.World.Spell spellStatMod = DatabaseManager.World.GetCachedSpell(spellId);
            if (spellStatMod == null)
            {
                creature.IsBusy = false;
                return;
            }

            float scale = SpellAttributes(null, spellId, out float castingDelay, out MotionCommand windUpMotion, out MotionCommand spellGesture);

            switch (spell.School)
            {
            case MagicSchool.ItemEnchantment:
                // if (!targetSelf && ResistSpell(Skill.CreatureEnchantment)) break;
                ItemMagic(target, spell, spellStatMod);
                EnqueueBroadcast(new GameMessageScript(target.Guid, (PlayScript)spell.TargetEffect, scale));
                break;

            case MagicSchool.LifeMagic:

                break;

            case MagicSchool.CreatureEnchantment:

                break;

            case MagicSchool.WarMagic:

                break;
            }

            creature.IsBusy = false;
            return;
        }
Example #2
0
 /// <summary>
 /// Void Magic
 /// </summary>
 /// <param name="target"></param>
 /// <param name="spell"></param>
 /// <param name="spellStatMod"></param>
 protected void VoidMagic(WorldObject target, SpellBase spell, Database.Models.World.Spell spellStatMod)
 {
     if (WeenieClassId == 1)
     {
         Player player = (Player)this;
         player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.None),
                                            new GameMessageSystemChat($"{spell.Name} spell not implemented, yet!", ChatMessageType.System));
     }
 }
Example #3
0
        /// <summary>
        /// Item Magic
        /// </summary>
        /// <param name="target"></param>
        /// <param name="spell"></param>
        /// <param name="spellStatMod"></param>
        /// <param name="castByItem"></param>
        protected string ItemMagic(WorldObject target, SpellBase spell, Database.Models.World.Spell spellStatMod, bool castByItem = false)
        {
            Player player = CurrentLandblock.GetObject(Guid) as Player;

            if ((spell.MetaSpellType == SpellType.PortalLink) ||
                (spell.MetaSpellType == SpellType.PortalRecall) ||
                (spell.MetaSpellType == SpellType.PortalSending) ||
                (spell.MetaSpellType == SpellType.PortalSummon))
            {
                switch (spell.MetaSpellId)
                {
                case 2645:     // Portal Recall
                    if (!player.TeleToPosition(PositionType.LastPortal))
                    {
                        // You must link to a portal to recall it!
                        player.Session.Network.EnqueueSend(new GameEventWeenieError(player.Session, WeenieError.YouMustLinkToPortalToRecall));
                    }
                    break;

                case 1635:     // Lifestone Recall
                    if (!player.TeleToPosition(PositionType.LinkedLifestone))
                    {
                        // You must link to a lifestone to recall it!
                        player.Session.Network.EnqueueSend(new GameEventWeenieError(player.Session, WeenieError.YouMustLinkToLifestoneToRecall));
                    }
                    break;

                case 48:     // Primary Portal Recall
                    if (!player.TeleToPosition(PositionType.LinkedPortalOne))
                    {
                        // You must link to a portal to recall it!
                        player.Session.Network.EnqueueSend(new GameEventWeenieError(player.Session, WeenieError.YouMustLinkToPortalToRecall));
                    }
                    break;

                case 2647:     // Secondary Portal Recall
                    if (!player.TeleToPosition(PositionType.LinkedPortalTwo))
                    {
                        // You must link to a portal to recall it!
                        player.Session.Network.EnqueueSend(new GameEventWeenieError(player.Session, WeenieError.YouMustLinkToPortalToRecall));
                    }
                    break;

                default:
                    break;
                }
            }
            else if (spell.MetaSpellType == SpellType.Enchantment)
            {
                return(CreateEnchantment(target, spell, spellStatMod, castByItem));
            }

            return("");
        }
Example #4
0
 /// <summary>
 /// War Magic
 /// </summary>
 /// <param name="target"></param>
 /// <param name="spell"></param>
 /// <param name="spellStatMod"></param>
 protected void WarMagic(WorldObject target, SpellBase spell, Database.Models.World.Spell spellStatMod)
 {
     if (spellStatMod.NumProjectiles == 1)
     {
         CreateSpellProjectile(this, target, spell.MetaSpellId, (uint)spellStatMod.Wcid);
     }
     else
     {
         if (WeenieClassId == 1)
         {
             Player player = (Player)this;
             player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.None),
                                                new GameMessageSystemChat($"{spell.Name} spell not implemented, yet!", ChatMessageType.System));
         }
     }
 }
Example #5
0
        /// <summary>
        /// Add/update an enchantment in this object's registry
        /// </summary>
        public StackType Add(Enchantment enchantment, string castByItem)
        {
            // check for existing spell in this category
            var entry = GetCategory(enchantment.Spell.Category);

            // if none, add new record
            if (entry == null)
            {
                entry         = BuildEntry(enchantment.Spell.SpellId, castByItem);
                entry.LayerId = enchantment.Layer;
                var type = (EnchantmentTypeFlags)entry.StatModType;
                WorldObject.Biota.BiotaPropertiesEnchantmentRegistry.Add(entry);

                return(StackType.Initial);
            }

            if (enchantment.Spell.Power > entry.PowerLevel)
            {
                // surpass existing spell
                Surpass = DatabaseManager.World.GetCachedSpell((uint)entry.SpellId);
                Remove(entry, false);
                entry         = BuildEntry(enchantment.Spell.SpellId, castByItem);
                entry.LayerId = enchantment.Layer;
                WorldObject.Biota.BiotaPropertiesEnchantmentRegistry.Add(entry);

                return(StackType.Surpass);
            }

            if (enchantment.Spell.Power == entry.PowerLevel)
            {
                if (entry.Duration == -1)
                {
                    return(StackType.None);
                }

                // refresh existing spell
                entry.LayerId++;
                entry.StartTime = 0;
                return(StackType.Refresh);
            }

            // superior existing spell
            Surpass = DatabaseManager.World.GetCachedSpell((uint)entry.SpellId);
            return(StackType.Surpassed);
        }
Example #6
0
        public static CreateResult Create(CharacterCreateInfo characterCreateInfo, Weenie weenie, ObjectGuid guid, uint accountId, WeenieType weenieType, out Player player)
        {
            var heritageGroup = DatManager.PortalDat.CharGen.HeritageGroups[(uint)characterCreateInfo.Heritage];

            if (weenieType == WeenieType.Admin)
            {
                player = new Admin(weenie, guid, accountId);
            }
            else if (weenieType == WeenieType.Sentinel)
            {
                player = new Sentinel(weenie, guid, accountId);
            }
            else
            {
                player = new Player(weenie, guid, accountId);
            }

            player.SetProperty(PropertyInt.HeritageGroup, (int)characterCreateInfo.Heritage);
            player.SetProperty(PropertyString.HeritageGroup, heritageGroup.Name);
            player.SetProperty(PropertyInt.Gender, (int)characterCreateInfo.Gender);
            player.SetProperty(PropertyString.Sex, characterCreateInfo.Gender == 1 ? "Male" : "Female");

            //player.SetProperty(PropertyDataId.Icon, cgh.IconImage); // I don't believe this is used anywhere in the client, but it might be used by a future custom launcher

            // pull character data from the dat file
            var sex = heritageGroup.Genders[(int)characterCreateInfo.Gender];

            player.SetProperty(PropertyDataId.MotionTable, sex.MotionTable);
            player.SetProperty(PropertyDataId.SoundTable, sex.SoundTable);
            player.SetProperty(PropertyDataId.PhysicsEffectTable, sex.PhysicsTable);
            player.SetProperty(PropertyDataId.Setup, sex.SetupID);
            player.SetProperty(PropertyDataId.PaletteBase, sex.BasePalette);
            player.SetProperty(PropertyDataId.CombatTable, sex.CombatTable);

            // Check the character scale
            if (sex.Scale != 100)
            {
                player.SetProperty(PropertyFloat.DefaultScale, sex.Scale / 100.0f); // Scale is stored as a percentage
            }
            // Get the hair first, because we need to know if you're bald, and that's the name of that tune!
            var hairstyle = sex.HairStyleList[(int)characterCreateInfo.Appearance.HairStyle];

            // Olthoi and Gear Knights have a "Body Style" instead of a hair style. These styles have multiple model/texture changes, instead of a single head/hairstyle.
            // Storing this value allows us to send the proper appearance ObjDesc
            if (hairstyle.ObjDesc.AnimPartChanges.Count > 1)
            {
                player.SetProperty(PropertyInt.Hairstyle, (int)characterCreateInfo.Appearance.HairStyle);
            }

            // Certain races (Undead, Tumeroks, Others?) have multiple body styles available. This is controlled via the "hair style".
            if (hairstyle.AlternateSetup > 0)
            {
                player.SetProperty(PropertyDataId.Setup, hairstyle.AlternateSetup);
            }

            player.SetProperty(PropertyDataId.EyesTexture, sex.GetEyeTexture(characterCreateInfo.Appearance.Eyes, hairstyle.Bald));
            player.SetProperty(PropertyDataId.DefaultEyesTexture, sex.GetDefaultEyeTexture(characterCreateInfo.Appearance.Eyes, hairstyle.Bald));
            player.SetProperty(PropertyDataId.NoseTexture, sex.GetNoseTexture(characterCreateInfo.Appearance.Nose));
            player.SetProperty(PropertyDataId.DefaultNoseTexture, sex.GetDefaultNoseTexture(characterCreateInfo.Appearance.Nose));
            player.SetProperty(PropertyDataId.MouthTexture, sex.GetMouthTexture(characterCreateInfo.Appearance.Mouth));
            player.SetProperty(PropertyDataId.DefaultMouthTexture, sex.GetDefaultMouthTexture(characterCreateInfo.Appearance.Mouth));
            player.Character.HairTexture        = sex.GetHairTexture(characterCreateInfo.Appearance.HairStyle) ?? 0;
            player.Character.DefaultHairTexture = sex.GetDefaultHairTexture(characterCreateInfo.Appearance.HairStyle) ?? 0;
            // HeadObject can be null if we're dealing with GearKnight or Olthoi
            var headObject = sex.GetHeadObject(characterCreateInfo.Appearance.HairStyle);

            if (headObject != null)
            {
                player.SetProperty(PropertyDataId.HeadObject, (uint)headObject);
            }

            // Skin is stored as PaletteSet (list of Palettes), so we need to read in the set to get the specific palette
            var skinPalSet = DatManager.PortalDat.ReadFromDat <PaletteSet>(sex.SkinPalSet);

            player.SetProperty(PropertyDataId.SkinPalette, skinPalSet.GetPaletteID(characterCreateInfo.Appearance.SkinHue));
            player.SetProperty(PropertyFloat.Shade, characterCreateInfo.Appearance.SkinHue);

            // Hair is stored as PaletteSet (list of Palettes), so we need to read in the set to get the specific palette
            var hairPalSet = DatManager.PortalDat.ReadFromDat <PaletteSet>(sex.HairColorList[(int)characterCreateInfo.Appearance.HairColor]);

            player.SetProperty(PropertyDataId.HairPalette, hairPalSet.GetPaletteID(characterCreateInfo.Appearance.HairHue));

            // Eye Color
            player.SetProperty(PropertyDataId.EyesPalette, sex.EyeColorList[(int)characterCreateInfo.Appearance.EyeColor]);

            // skip over this for olthoi, use the weenie defaults
            if (!player.IsOlthoiPlayer)
            {
                if (characterCreateInfo.Appearance.HeadgearStyle < uint.MaxValue) // No headgear is max UINT
                {
                    var hat = GetClothingObject(sex.GetHeadgearWeenie(characterCreateInfo.Appearance.HeadgearStyle), characterCreateInfo.Appearance.HeadgearColor, characterCreateInfo.Appearance.HeadgearHue);
                    if (hat != null)
                    {
                        player.TryEquipObject(hat, hat.ValidLocations ?? 0);
                    }
                    else
                    {
                        player.TryAddToInventory(CreateIOU(sex.GetHeadgearWeenie(characterCreateInfo.Appearance.HeadgearStyle)));
                    }
                }

                var shirt = GetClothingObject(sex.GetShirtWeenie(characterCreateInfo.Appearance.ShirtStyle), characterCreateInfo.Appearance.ShirtColor, characterCreateInfo.Appearance.ShirtHue);
                if (shirt != null)
                {
                    player.TryEquipObject(shirt, shirt.ValidLocations ?? 0);
                }
                else
                {
                    player.TryAddToInventory(CreateIOU(sex.GetShirtWeenie(characterCreateInfo.Appearance.ShirtStyle)));
                }

                var pants = GetClothingObject(sex.GetPantsWeenie(characterCreateInfo.Appearance.PantsStyle), characterCreateInfo.Appearance.PantsColor, characterCreateInfo.Appearance.PantsHue);
                if (pants != null)
                {
                    player.TryEquipObject(pants, pants.ValidLocations ?? 0);
                }
                else
                {
                    player.TryAddToInventory(CreateIOU(sex.GetPantsWeenie(characterCreateInfo.Appearance.PantsStyle)));
                }

                var shoes = GetClothingObject(sex.GetFootwearWeenie(characterCreateInfo.Appearance.FootwearStyle), characterCreateInfo.Appearance.FootwearColor, characterCreateInfo.Appearance.FootwearHue);
                if (shoes != null)
                {
                    player.TryEquipObject(shoes, shoes.ValidLocations ?? 0);
                }
                else
                {
                    player.TryAddToInventory(CreateIOU(sex.GetFootwearWeenie(characterCreateInfo.Appearance.FootwearStyle)));
                }

                string templateName = heritageGroup.Templates[characterCreateInfo.TemplateOption].Name;
                player.SetProperty(PropertyString.Template, templateName);

                player.AddTitle(heritageGroup.Templates[characterCreateInfo.TemplateOption].Title, true);

                // attributes
                var result = ValidateAttributeCredits(characterCreateInfo, heritageGroup.AttributeCredits);

                if (result != CreateResult.Success)
                {
                    return(result);
                }

                player.Strength.StartingValue     = characterCreateInfo.StrengthAbility;
                player.Endurance.StartingValue    = characterCreateInfo.EnduranceAbility;
                player.Coordination.StartingValue = characterCreateInfo.CoordinationAbility;
                player.Quickness.StartingValue    = characterCreateInfo.QuicknessAbility;
                player.Focus.StartingValue        = characterCreateInfo.FocusAbility;
                player.Self.StartingValue         = characterCreateInfo.SelfAbility;

                // data we don't care about
                //characterCreateInfo.CharacterSlot;
                //characterCreateInfo.ClassId;

                // characters start with max vitals
                player.Health.Current  = player.Health.Base;
                player.Stamina.Current = player.Stamina.Base;
                player.Mana.Current    = player.Mana.Base;

                // set initial skill credit amount. 52 for all but "Olthoi", which have 68
                player.SetProperty(PropertyInt.AvailableSkillCredits, (int)heritageGroup.SkillCredits);
                player.SetProperty(PropertyInt.TotalSkillCredits, (int)heritageGroup.SkillCredits);

                if (characterCreateInfo.SkillAdvancementClasses.Count != 55)
                {
                    return(CreateResult.ClientServerSkillsMismatch);
                }

                for (int i = 0; i < characterCreateInfo.SkillAdvancementClasses.Count; i++)
                {
                    var sac = characterCreateInfo.SkillAdvancementClasses[i];

                    if (sac == SkillAdvancementClass.Inactive)
                    {
                        continue;
                    }

                    if (!DatManager.PortalDat.SkillTable.SkillBaseHash.ContainsKey((uint)i))
                    {
                        log.ErrorFormat("Character {0} tried to create with skill {1} that was not found in Portal dat.", characterCreateInfo.Name, i);
                        return(CreateResult.InvalidSkillRequested);
                    }

                    var skill = DatManager.PortalDat.SkillTable.SkillBaseHash[(uint)i];

                    var trainedCost     = skill.TrainedCost;
                    var specializedCost = skill.UpgradeCostFromTrainedToSpecialized;

                    foreach (var skillGroup in heritageGroup.Skills)
                    {
                        if (skillGroup.SkillNum == i)
                        {
                            trainedCost     = skillGroup.NormalCost;
                            specializedCost = skillGroup.PrimaryCost;
                            break;
                        }
                    }

                    if (sac == SkillAdvancementClass.Specialized)
                    {
                        if (!player.TrainSkill((Skill)i, trainedCost))
                        {
                            return(CreateResult.FailedToTrainSkill);
                        }
                        if (!player.SpecializeSkill((Skill)i, specializedCost))
                        {
                            return(CreateResult.FailedToSpecializeSkill);
                        }
                    }
                    else if (sac == SkillAdvancementClass.Trained)
                    {
                        if (!player.TrainSkill((Skill)i, trainedCost, true))
                        {
                            return(CreateResult.FailedToTrainSkill);
                        }
                    }
                    else if (sac == SkillAdvancementClass.Untrained)
                    {
                        player.UntrainSkill((Skill)i, 0);
                    }
                }

                // Set Heritage based Melee and Ranged Masteries
                GetMasteries(player.HeritageGroup, out WeaponType meleeMastery, out WeaponType rangedMastery);

                player.SetProperty(PropertyInt.MeleeMastery, (int)meleeMastery);
                player.SetProperty(PropertyInt.RangedMastery, (int)rangedMastery);

                // Set innate augs
                SetInnateAugmentations(player);

                var isDualWieldTrainedOrSpecialized = player.Skills.TryGetValue(Skill.DualWield, out var dualWield) && dualWield.AdvancementClass > SkillAdvancementClass.Untrained;

                // grant starter items based on skills
                var starterGearConfig = StarterGearFactory.GetStarterGearConfiguration();
                var grantedWeenies    = new List <uint>();

                foreach (var skillGear in starterGearConfig.Skills)
                {
                    //var charSkill = player.Skills[(Skill)skillGear.SkillId];
                    if (!player.Skills.TryGetValue((Skill)skillGear.SkillId, out var charSkill))
                    {
                        continue;
                    }

                    if (charSkill.AdvancementClass == SkillAdvancementClass.Trained || charSkill.AdvancementClass == SkillAdvancementClass.Specialized)
                    {
                        foreach (var item in skillGear.Gear)
                        {
                            if (grantedWeenies.Contains(item.WeenieId))
                            {
                                var existingItem = player.Inventory.Values.FirstOrDefault(i => i.WeenieClassId == item.WeenieId);
                                if (existingItem == null || (existingItem.MaxStackSize ?? 1) <= 1)
                                {
                                    continue;
                                }

                                existingItem.SetStackSize(existingItem.StackSize + item.StackSize);
                                continue;
                            }

                            var loot = WorldObjectFactory.CreateNewWorldObject(item.WeenieId);
                            if (loot != null)
                            {
                                if (loot.StackSize.HasValue && loot.MaxStackSize.HasValue)
                                {
                                    loot.SetStackSize((item.StackSize <= loot.MaxStackSize) ? item.StackSize : loot.MaxStackSize);
                                }
                            }
                            else
                            {
                                player.TryAddToInventory(CreateIOU(item.WeenieId));
                            }

                            if (loot != null && player.TryAddToInventory(loot))
                            {
                                grantedWeenies.Add(item.WeenieId);
                            }

                            if (isDualWieldTrainedOrSpecialized && loot != null)
                            {
                                if (loot.WeenieType == WeenieType.MeleeWeapon)
                                {
                                    var dualloot = WorldObjectFactory.CreateNewWorldObject(item.WeenieId);
                                    if (dualloot != null)
                                    {
                                        player.TryAddToInventory(dualloot);
                                    }
                                    else
                                    {
                                        player.TryAddToInventory(CreateIOU(item.WeenieId));
                                    }
                                }
                            }
                        }

                        var heritageLoot = skillGear.Heritage.FirstOrDefault(i => i.HeritageId == (ushort)characterCreateInfo.Heritage);
                        if (heritageLoot != null)
                        {
                            foreach (var item in heritageLoot.Gear)
                            {
                                if (grantedWeenies.Contains(item.WeenieId))
                                {
                                    var existingItem = player.Inventory.Values.FirstOrDefault(i => i.WeenieClassId == item.WeenieId);
                                    if (existingItem == null || (existingItem.MaxStackSize ?? 1) <= 1)
                                    {
                                        continue;
                                    }

                                    existingItem.SetStackSize(existingItem.StackSize + item.StackSize);
                                    continue;
                                }

                                var loot = WorldObjectFactory.CreateNewWorldObject(item.WeenieId);
                                if (loot != null)
                                {
                                    if (loot.StackSize.HasValue && loot.MaxStackSize.HasValue)
                                    {
                                        loot.SetStackSize((item.StackSize <= loot.MaxStackSize) ? item.StackSize : loot.MaxStackSize);
                                    }
                                }
                                else
                                {
                                    player.TryAddToInventory(CreateIOU(item.WeenieId));
                                }

                                if (loot != null && player.TryAddToInventory(loot))
                                {
                                    grantedWeenies.Add(item.WeenieId);
                                }

                                if (isDualWieldTrainedOrSpecialized && loot != null)
                                {
                                    if (loot.WeenieType == WeenieType.MeleeWeapon)
                                    {
                                        var dualloot = WorldObjectFactory.CreateNewWorldObject(item.WeenieId);
                                        if (dualloot != null)
                                        {
                                            player.TryAddToInventory(dualloot);
                                        }
                                        else
                                        {
                                            player.TryAddToInventory(CreateIOU(item.WeenieId));
                                        }
                                    }
                                }
                            }
                        }

                        foreach (var spell in skillGear.Spells)
                        {
                            if (charSkill.AdvancementClass == SkillAdvancementClass.Trained && spell.SpecializedOnly == false)
                            {
                                player.AddKnownSpell(spell.SpellId);
                            }
                            else if (charSkill.AdvancementClass == SkillAdvancementClass.Specialized)
                            {
                                player.AddKnownSpell(spell.SpellId);
                            }
                        }
                    }
                }
            }
            else
            {
                if (player.CharacterTitleId > 0)
                {
                    player.AddTitle((uint)player.CharacterTitleId.Value, true);
                }

                if (player.Biota.PropertiesSpellBook?.Count > 0)
                {
                    var i = 0u;
                    foreach (var spell in player.Biota.PropertiesSpellBook)
                    {
                        player.HandleActionAddSpellFavorite((uint)spell.Key, i++, 0);
                    }
                }
            }

            player.Name           = characterCreateInfo.Name;
            player.Character.Name = characterCreateInfo.Name;


            // Index used to determine the starting location
            var startArea = characterCreateInfo.StartArea;

            var starterArea = DatManager.PortalDat.CharGen.StarterAreas[(int)startArea];

            player.Location = new Position(starterArea.Locations[0].ObjCellID,
                                           starterArea.Locations[0].Frame.Origin.X, starterArea.Locations[0].Frame.Origin.Y, starterArea.Locations[0].Frame.Origin.Z,
                                           starterArea.Locations[0].Frame.Orientation.X, starterArea.Locations[0].Frame.Orientation.Y, starterArea.Locations[0].Frame.Orientation.Z, starterArea.Locations[0].Frame.Orientation.W);

            var instantiation = new Position(0xA9B40019, 84, 7.1f, 94, 0, 0, -0.0784591f, 0.996917f); // ultimate fallback.
            var spellFreeRide = new Database.Models.World.Spell();

            switch (starterArea.Name)
            {
            case "OlthoiLair":        //todo: check this when olthoi play is allowed in ace
                spellFreeRide = null; // no training area for olthoi, so they start and fall back to same place.
                instantiation = new Position(player.Location);
                break;

            case "Shoushi":
                spellFreeRide = DatabaseManager.World.GetCachedSpell(3813);     // Free Ride to Shoushi
                break;

            case "Yaraq":
                spellFreeRide = DatabaseManager.World.GetCachedSpell(3814);     // Free Ride to Yaraq
                break;

            case "Sanamar":
                spellFreeRide = DatabaseManager.World.GetCachedSpell(3535);     // Free Ride to Sanamar
                break;

            case "Holtburg":
            default:
                spellFreeRide = DatabaseManager.World.GetCachedSpell(3815);     // Free Ride to Holtburg
                break;
            }
            if (spellFreeRide != null && spellFreeRide.Name != "")
            {
                instantiation = new Position(spellFreeRide.PositionObjCellId.Value, spellFreeRide.PositionOriginX.Value, spellFreeRide.PositionOriginY.Value, spellFreeRide.PositionOriginZ.Value, spellFreeRide.PositionAnglesX.Value, spellFreeRide.PositionAnglesY.Value, spellFreeRide.PositionAnglesZ.Value, spellFreeRide.PositionAnglesW.Value);
            }

            player.Instantiation = new Position(instantiation);

            if (!player.IsOlthoiPlayer)
            {
                player.Sanctuary = new Position(player.Location);
                player.SetProperty(PropertyBool.RecallsDisabled, true);

                if (PropertyManager.GetBool("pk_server").Item)
                {
                    player.SetProperty(PropertyInt.PlayerKillerStatus, (int)PlayerKillerStatus.PK);
                }
                else if (PropertyManager.GetBool("pkl_server").Item)
                {
                    player.SetProperty(PropertyInt.PlayerKillerStatus, (int)PlayerKillerStatus.NPK);
                }

                if ((PropertyManager.GetBool("pk_server").Item || PropertyManager.GetBool("pkl_server").Item) && PropertyManager.GetBool("pk_server_safe_training_academy").Item)
                {
                    player.SetProperty(PropertyFloat.MinimumTimeSincePk, -PropertyManager.GetDouble("pk_new_character_grace_period").Item);
                    player.SetProperty(PropertyInt.PlayerKillerStatus, (int)PlayerKillerStatus.NPK);
                }
            }

            if (player is Sentinel || player is Admin)
            {
                player.Character.IsPlussed = true;
                player.CloakStatus         = CloakStatus.Off;
                player.ChannelsAllowed     = player.ChannelsActive;
            }

            CharacterCreateSetDefaultCharacterOptions(player);

            return(CreateResult.Success);
        }
Example #7
0
        /// <summary>
        /// Creates an enchantment and interacts with the Enchantment registry.
        /// Used by Life, Creature, Item, and Void magic
        /// </summary>
        /// <param name="target"></param>
        /// <param name="spell"></param>
        /// <param name="spellStatMod"></param>
        /// <param name="castByItem"></param>
        /// <returns></returns>
        private string CreateEnchantment(WorldObject target, SpellBase spell, Database.Models.World.Spell spellStatMod, bool castByItem)
        {
            double duration;

            if (castByItem)
            {
                duration = -1;
            }
            else
            {
                duration = spell.Duration;
            }
            // create enchantment
            var enchantment = new Enchantment(target, spellStatMod.SpellId, duration, 1, (uint)EnchantmentMask.CreatureSpells);
            var stackType   = target.EnchantmentManager.Add(enchantment, castByItem);

            var player         = this as Player;
            var playerTarget   = target as Player;
            var creatureTarget = target as Creature;

            // build message
            var suffix = "";

            switch (stackType)
            {
            case StackType.Refresh:
                suffix = $", refreshing {spell.Name}";
                break;

            case StackType.Surpass:
                suffix = $", surpassing {target.EnchantmentManager.Surpass.Name}";
                break;

            case StackType.Surpassed:
                suffix = $", but it is surpassed by {target.EnchantmentManager.Surpass.Name}";
                break;
            }

            var targetName = this == target ? "yourself" : target.Name;

            string message;

            if (castByItem == true)
            {
                message = $"An item casts {spell.Name} on you";
            }
            else
            {
                message = $"You cast {spell.Name} on {targetName}{suffix}";
            }


            if (target is Player)
            {
                if (stackType != StackType.Surpassed)
                {
                    playerTarget.Session.Network.EnqueueSend(new GameEventMagicUpdateEnchantment(playerTarget.Session, enchantment));
                }

                if (playerTarget != this)
                {
                    playerTarget.Session.Network.EnqueueSend(new GameMessageSystemChat($"{Name} cast {spell.Name} on you{suffix}", ChatMessageType.Magic));
                }
            }

            return(message);
        }
Example #8
0
 /// <summary>
 /// Wrapper around CreateEnchantment for Creature Magic
 /// </summary>
 /// <param name="target"></param>
 /// <param name="spell"></param>
 /// <param name="spellStatMod"></param>
 /// <param name="castByItem"></param>
 /// <returns></returns>
 protected string CreatureMagic(WorldObject target, SpellBase spell, Database.Models.World.Spell spellStatMod, bool castByItem = false)
 {
     return(CreateEnchantment(target, spell, spellStatMod, castByItem));
 }
Example #9
0
        /// <summary>
        /// Creates the Life Magic spell
        /// </summary>
        /// <param name="target"></param>
        /// <param name="spell"></param>
        /// <param name="spellStatMod"></param>
        /// <param name="message"></param>
        /// <param name="castByItem"></param>
        /// <returns></returns>
        protected bool LifeMagic(WorldObject target, SpellBase spell, Database.Models.World.Spell spellStatMod, out string message, bool castByItem = false)
        {
            string srcVital, destVital, action;
            string targetMsg = null;

            Player   player   = null;
            Creature creature = null;

            if (WeenieClassId == 1)
            {
                player = (Player)this;
            }
            else if (WeenieType == WeenieType.Creature)
            {
                creature = (Creature)this;
            }

            Creature spellTarget;

            if (spell.BaseRangeConstant == 0)
            {
                spellTarget = (Creature)this;
            }
            else
            {
                spellTarget = (Creature)target;
            }

            int newSpellTargetVital;

            switch (spell.MetaSpellType)
            {
            case SpellType.Boost:
                int minBoostValue, maxBoostValue;
                if ((spellStatMod.BoostVariance + spellStatMod.Boost) < spellStatMod.Boost)
                {
                    minBoostValue = (int)(spellStatMod.BoostVariance + spellStatMod.Boost);
                    maxBoostValue = (int)spellStatMod.Boost;
                }
                else
                {
                    minBoostValue = (int)spellStatMod.Boost;
                    maxBoostValue = (int)(spellStatMod.BoostVariance + spellStatMod.Boost);
                }
                int boost = Physics.Common.Random.RollDice(minBoostValue, maxBoostValue);
                if (boost < 0)
                {
                    action = "drain";
                }
                else
                {
                    action = "restore";
                }
                switch (spellStatMod.DamageType)
                {
                case 512:           // Mana
                    newSpellTargetVital = (int)(spellTarget.Mana.Current + boost);
                    srcVital            = "mana";
                    if (newSpellTargetVital < spellTarget.Mana.MaxValue)
                    {
                        if (newSpellTargetVital <= 0)
                        {
                            spellTarget.UpdateVital(spellTarget.Mana, 0);
                        }
                        else
                        {
                            spellTarget.UpdateVital(spellTarget.Mana, (uint)newSpellTargetVital);
                        }
                    }
                    else
                    {
                        spellTarget.UpdateVital(spellTarget.Mana, spellTarget.Mana.MaxValue);
                    }
                    break;

                case 256:           // Stamina
                    newSpellTargetVital = (int)(spellTarget.Stamina.Current + boost);
                    srcVital            = "stamina";
                    if (newSpellTargetVital < spellTarget.Stamina.MaxValue)
                    {
                        if (newSpellTargetVital <= 0)
                        {
                            spellTarget.UpdateVital(spellTarget.Stamina, 0);
                        }
                        else
                        {
                            spellTarget.UpdateVital(spellTarget.Stamina, (uint)newSpellTargetVital);
                        }
                    }
                    else
                    {
                        spellTarget.UpdateVital(spellTarget.Stamina, spellTarget.Stamina.MaxValue);
                    }
                    break;

                default:           // Health
                    newSpellTargetVital = (int)(spellTarget.Health.Current + boost);
                    srcVital            = "health";
                    if (newSpellTargetVital < spellTarget.Health.MaxValue)
                    {
                        if (newSpellTargetVital <= 0)
                        {
                            spellTarget.UpdateVital(spellTarget.Health, 0);
                        }
                        else
                        {
                            spellTarget.UpdateVital(spellTarget.Health, (uint)newSpellTargetVital);
                        }
                    }
                    else
                    {
                        spellTarget.UpdateVital(spellTarget.Health, spellTarget.Health.MaxValue);
                    }
                    break;
                }
                if (this is Player)
                {
                    if (spell.BaseRangeConstant == 0)
                    {
                        message = $"You {action} {Math.Abs(boost).ToString()} {srcVital}";
                    }
                    else
                    {
                        message = $"You {action} {Math.Abs(boost).ToString()} points of {srcVital} from {spellTarget.Name}";
                    }
                }
                else
                {
                    message = null;
                }

                if (target is Player && spell.BaseRangeConstant > 0)
                {
                    targetMsg = $"{Name} casts {spell.Name} and {action}s {Math.Abs(boost)} points of your {srcVital}.";
                }

                break;

            case SpellType.Transfer:
                // Calculate the change in vitals of the target
                Creature caster;
                if (spell.BaseRangeConstant == 0 && spell.BaseRangeMod == 1)
                {
                    caster = spellTarget;
                }
                else
                {
                    caster = (Creature)this;
                }
                uint           vitalChange, casterVitalChange;
                ResistanceType resistanceDrain, resistanceBoost;
                if (spellStatMod.Source == (int)PropertyAttribute2nd.Mana)
                {
                    resistanceDrain = ResistanceType.ManaDrain;
                }
                else if (spellStatMod.Source == (int)PropertyAttribute2nd.Stamina)
                {
                    resistanceDrain = ResistanceType.StaminaDrain;
                }
                else
                {
                    resistanceDrain = ResistanceType.HealthDrain;
                }
                vitalChange = (uint)((spellTarget.GetCurrentCreatureVital((PropertyAttribute2nd)spellStatMod.Source) * spellStatMod.Proportion) * spellTarget.GetNaturalResistence(resistanceDrain));
                if (spellStatMod.TransferCap != 0)
                {
                    if (vitalChange > spellStatMod.TransferCap)
                    {
                        vitalChange = (uint)spellStatMod.TransferCap;
                    }
                }
                if (spellStatMod.Destination == (int)PropertyAttribute2nd.Mana)
                {
                    resistanceBoost = ResistanceType.ManaDrain;
                }
                else if (spellStatMod.Source == (int)PropertyAttribute2nd.Stamina)
                {
                    resistanceBoost = ResistanceType.StaminaDrain;
                }
                else
                {
                    resistanceBoost = ResistanceType.HealthDrain;
                }
                casterVitalChange   = (uint)((vitalChange * (1.0f - spellStatMod.LossPercent)) * spellTarget.GetNaturalResistence(resistanceBoost));
                vitalChange         = (uint)(casterVitalChange / (1.0f - spellStatMod.LossPercent));
                newSpellTargetVital = (int)(spellTarget.GetCurrentCreatureVital((PropertyAttribute2nd)spellStatMod.Source) - vitalChange);

                // Apply the change in vitals to the target
                switch (spellStatMod.Source)
                {
                case (int)PropertyAttribute2nd.Mana:
                    srcVital = "mana";
                    if (newSpellTargetVital <= 0)
                    {
                        spellTarget.UpdateVital(spellTarget.Mana, 0);
                    }
                    else
                    {
                        spellTarget.UpdateVital(spellTarget.Mana, (uint)newSpellTargetVital);
                    }
                    break;

                case (int)PropertyAttribute2nd.Stamina:
                    srcVital = "stamina";
                    if (newSpellTargetVital <= 0)
                    {
                        spellTarget.UpdateVital(spellTarget.Stamina, 0);
                    }
                    else
                    {
                        spellTarget.UpdateVital(spellTarget.Stamina, (uint)newSpellTargetVital);
                    }
                    break;

                default:           // Health
                    srcVital = "health";
                    if (newSpellTargetVital <= 0)
                    {
                        spellTarget.UpdateVital(spellTarget.Health, 0);
                    }
                    else
                    {
                        spellTarget.UpdateVital(spellTarget.Health, (uint)newSpellTargetVital);
                    }
                    break;
                }

                // Apply the scaled change in vitals to the caster
                uint newCasterVital;
                switch (spellStatMod.Destination)
                {
                case (int)PropertyAttribute2nd.Mana:
                    destVital      = "mana";
                    newCasterVital = caster.Mana.Current + casterVitalChange;
                    caster.UpdateVital(caster.Mana, newCasterVital);
                    break;

                case (int)PropertyAttribute2nd.Stamina:
                    destVital      = "stamina";
                    newCasterVital = caster.Stamina.Current + casterVitalChange;
                    caster.UpdateVital(caster.Stamina, newCasterVital);
                    break;

                default:           // Health
                    destVital      = "health";
                    newCasterVital = caster.Mana.Current + casterVitalChange;
                    caster.UpdateVital(caster.Health, newCasterVital);
                    break;
                }

                if (WeenieClassId == 1)
                {
                    if (target.Guid == Guid)
                    {
                        message = $"You drain {vitalChange.ToString()} points of {srcVital} and apply {casterVitalChange.ToString()} points of {destVital} to yourself";
                    }
                    else
                    {
                        message = $"You drain {vitalChange.ToString()} points of {srcVital} from {spellTarget.Name} and apply {casterVitalChange.ToString()} to yourself";
                    }
                }
                else
                {
                    message = null;
                }

                if (target is Player && target != this)
                {
                    targetMsg = $"You lose {vitalChange} points of {srcVital} due to {Name} casting {spell.Name} on you";
                }

                break;

            case SpellType.LifeProjectile:
                caster = (Creature)this;
                uint damage;
                if (spell.Name.Contains("Blight"))
                {
                    damage         = (uint)(caster.GetCurrentCreatureVital(PropertyAttribute2nd.Mana) * caster.GetNaturalResistence(ResistanceType.ManaDrain));
                    newCasterVital = caster.Mana.Current - damage;
                    if (newCasterVital <= 0)
                    {
                        caster.UpdateVital(caster.Mana, 0);
                    }
                    else
                    {
                        caster.UpdateVital(caster.Mana, (uint)newCasterVital);
                    }
                }
                else if (spell.Name.Contains("Tenacity"))
                {
                    damage         = (uint)(spellTarget.GetCurrentCreatureVital(PropertyAttribute2nd.Stamina) * spellTarget.GetNaturalResistence(ResistanceType.StaminaDrain));
                    newCasterVital = caster.Stamina.Current - damage;
                    if (newCasterVital <= 0)
                    {
                        caster.UpdateVital(caster.Stamina, 0);
                    }
                    else
                    {
                        caster.UpdateVital(caster.Stamina, (uint)newCasterVital);
                    }
                }
                else
                {
                    damage         = (uint)(spellTarget.GetCurrentCreatureVital(PropertyAttribute2nd.Stamina) * spellTarget.GetNaturalResistence(ResistanceType.HealthDrain));
                    newCasterVital = caster.Health.Current - damage;
                    if (newCasterVital <= 0)
                    {
                        caster.UpdateVital(caster.Health, 0);
                    }
                    else
                    {
                        caster.UpdateVital(caster.Health, (uint)newCasterVital);
                    }
                }

                CreateSpellProjectile(this, target, spell.MetaSpellId, (uint)spellStatMod.Wcid, damage);

                if (caster.Health.Current <= 0)
                {
                    caster.Die();

                    if (caster.WeenieClassId == 1)
                    {
                        Strings.DeathMessages.TryGetValue(DamageType.Base, out var messages);
                        player.Session.Network.EnqueueSend(new GameMessageSystemChat("You have killed yourself", ChatMessageType.Broadcast));
                    }
                }
                message = null;
                break;

            case SpellType.Dispel:
                message = "Spell not implemented, yet!";
                break;

            case SpellType.Enchantment:
                message = CreateEnchantment(target, spell, spellStatMod, castByItem);
                break;

            default:
                message = "Spell not implemented, yet!";
                break;
            }

            if (targetMsg != null)
            {
                var playerTarget = target as Player;
                playerTarget.Session.Network.EnqueueSend(new GameMessageSystemChat(targetMsg, ChatMessageType.Magic));
            }

            if (spellTarget.Health.Current == 0)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Example #10
0
        public static bool TryConvert(uint id, Models.SpellValue input, out Database.Models.World.Spell result)
        {
            try
            {
                result = new Database.Models.World.Spell();

                result.Id = id;

                result.Name = input.Name;

                if (input.MetaSpell.Spell.StatMod != null)
                {
                    result.StatModType = input.MetaSpell.Spell.StatMod.Type;
                    result.StatModKey  = input.MetaSpell.Spell.StatMod.Key;
                    result.StatModVal  = (float)input.MetaSpell.Spell.StatMod.Val;
                }

                // Projectile, LifeProjectile
                result.EType                  = input.MetaSpell.Spell.EType;
                result.BaseIntensity          = input.MetaSpell.Spell.BaseIntensity;
                result.Variance               = input.MetaSpell.Spell.Variance;
                result.Wcid                   = input.MetaSpell.Spell.Wcid;
                result.NumProjectiles         = input.MetaSpell.Spell.NumProjectiles;
                result.NumProjectilesVariance = (int?)input.MetaSpell.Spell.NumProjectilesVariance;
                result.SpreadAngle            = input.MetaSpell.Spell.SpreadAngle;
                result.VerticalAngle          = input.MetaSpell.Spell.VerticalAngle;
                result.DefaultLaunchAngle     = input.MetaSpell.Spell.DefaultLaunchAngle;
                result.NonTracking            = input.MetaSpell.Spell.NonTracking;

                if (input.MetaSpell.Spell.CreateOffset != null)
                {
                    result.CreateOffsetOriginX = (float)input.MetaSpell.Spell.CreateOffset.X;
                    result.CreateOffsetOriginY = (float)input.MetaSpell.Spell.CreateOffset.Y;
                    result.CreateOffsetOriginZ = (float)input.MetaSpell.Spell.CreateOffset.Z;
                }

                if (input.MetaSpell.Spell.Padding != null)
                {
                    result.PaddingOriginX = (float)input.MetaSpell.Spell.Padding.X;
                    result.PaddingOriginY = (float)input.MetaSpell.Spell.Padding.Y;
                    result.PaddingOriginZ = (float)input.MetaSpell.Spell.Padding.Z;
                }

                if (input.MetaSpell.Spell.Dims != null)
                {
                    result.DimsOriginX = (float)input.MetaSpell.Spell.Dims.X;
                    result.DimsOriginY = (float)input.MetaSpell.Spell.Dims.Y;
                    result.DimsOriginZ = (float)input.MetaSpell.Spell.Dims.Z;
                }

                if (input.MetaSpell.Spell.Peturbation != null)
                {
                    result.PeturbationOriginX = (float)input.MetaSpell.Spell.Peturbation.X;
                    result.PeturbationOriginY = (float)input.MetaSpell.Spell.Peturbation.Y;
                    result.PeturbationOriginZ = (float)input.MetaSpell.Spell.Peturbation.Z;
                }

                result.ImbuedEffect       = input.MetaSpell.Spell.ImbuedEffect;
                result.SlayerCreatureType = input.MetaSpell.Spell.SlayerCreatureType;
                result.SlayerDamageBonus  = input.MetaSpell.Spell.SlayerDamageBonus;
                result.CritFreq           = input.MetaSpell.Spell.CritFreq;
                result.CritMultiplier     = input.MetaSpell.Spell.CritMultiplier;
                result.IgnoreMagicResist  = input.MetaSpell.Spell.IgnoreMagicResist;
                result.ElementalModifier  = input.MetaSpell.Spell.ElementalModifier;

                // LifeProjectile
                result.DrainPercentage = (float?)input.MetaSpell.Spell.DrainPercentage;
                result.DamageRatio     = (float?)input.MetaSpell.Spell.DamageRatio;

                // Boost, FellowBoost
                result.DamageType    = input.MetaSpell.Spell.DamageType;
                result.Boost         = input.MetaSpell.Spell.Boost;
                result.BoostVariance = input.MetaSpell.Spell.BoostVariance;

                // Transfer
                result.Source           = input.MetaSpell.Spell.Source;
                result.Destination      = input.MetaSpell.Spell.Dest;
                result.Proportion       = (float?)input.MetaSpell.Spell.Proportion;
                result.LossPercent      = (float?)input.MetaSpell.Spell.LossPercent;
                result.SourceLoss       = input.MetaSpell.Spell.SourceLoss;
                result.TransferCap      = input.MetaSpell.Spell.TransferCap;
                result.MaxBoostAllowed  = input.MetaSpell.Spell.MaxBoostAllowed;
                result.TransferBitfield = input.MetaSpell.Spell.Bitfield;

                // PortalLink
                result.Index = input.MetaSpell.Spell.Index;

                // PortalSummon
                result.Link = input.MetaSpell.Spell.Link;

                // PortalSending, FellowPortalSending
                if (input.MetaSpell.Spell.Position != null)
                {
                    result.PositionObjCellId = input.MetaSpell.Spell.Position.ObjCellId;

                    result.PositionOriginX = (float)input.MetaSpell.Spell.Position.Frame.Origin.X;
                    result.PositionOriginY = (float)input.MetaSpell.Spell.Position.Frame.Origin.Y;
                    result.PositionOriginZ = (float)input.MetaSpell.Spell.Position.Frame.Origin.Z;

                    result.PositionAnglesW = (float)input.MetaSpell.Spell.Position.Frame.Angles.W;
                    result.PositionAnglesX = (float)input.MetaSpell.Spell.Position.Frame.Angles.X;
                    result.PositionAnglesY = (float)input.MetaSpell.Spell.Position.Frame.Angles.Y;
                    result.PositionAnglesZ = (float)input.MetaSpell.Spell.Position.Frame.Angles.Z;
                }

                // Dispel, FellowDispel
                result.MinPower      = input.MetaSpell.Spell.MinPower;
                result.MaxPower      = input.MetaSpell.Spell.MaxPower;
                result.PowerVariance = input.MetaSpell.Spell.PowerVariance;
                //result.DispelSchool = input.DispelSchool; // TODO!!!
                result.Align          = input.MetaSpell.Spell.Align;
                result.Number         = input.MetaSpell.Spell.Number;
                result.NumberVariance = (float?)input.MetaSpell.Spell.NumberVariance;

                return(true);
            }
            catch
            {
                result = null;
                return(false);
            }
        }
Example #11
0
        public Database.Models.World.Spell Surpass; // retval

        /// <summary>
        /// Add/update an enchantment in this object's registry
        /// </summary>
        public StackType Add(Enchantment enchantment, bool castByItem)
        {
            // check for existing spell in this category
            var entry = GetCategory(enchantment.Spell.Category);

/*
 *              if (enchantment.Spell.Power > entry.PowerLevel)
 *              {
 *                  // surpass existing spell
 *                  Surpass = DatabaseManager.World.GetCachedSpell((uint)entry.SpellId);
 *                  Remove(entry, false);
 *                  entry = BuildEntry(enchantment.Spell.SpellId);
 *                  entry.Duration = -1;
 *                  entry.StartTime = 0;
 *                  entry.LayerId = enchantment.Layer;
 *                  WorldObject.Biota.BiotaPropertiesEnchantmentRegistry.Add(entry);
 *                  return StackType.Surpass;
 *              }
 *
 *              // TODO: the refresh spell case may need some additional functionality to get working correctly
 *              if (enchantment.Spell.Power == entry.PowerLevel)
 *              {
 *                  if (entry.Duration != -1)
 *                  {
 *                      // refresh existing spell with a no countdown timer
 *                      entry.LayerId++;
 *                      entry.Duration = -1;
 *                      entry.StartTime = 0;
 *                      return StackType.Refresh;
 *                  }
 *
 *                  return StackType.None;
 *              }
 *
 *              // superior existing spell
 *              Surpass = DatabaseManager.World.GetCachedSpell((uint)entry.SpellId);
 *              return StackType.Surpassed;
 *          }
 */
            // if none, add new record
            if (entry == null)
            {
                entry         = BuildEntry(enchantment.Spell.SpellId, castByItem);
                entry.LayerId = enchantment.Layer;
                var type = (EnchantmentTypeFlags)entry.StatModType;
                WorldObject.Biota.BiotaPropertiesEnchantmentRegistry.Add(entry);

                return(StackType.Initial);
            }

            if (enchantment.Spell.Power > entry.PowerLevel)
            {
                // surpass existing spell
                Surpass = DatabaseManager.World.GetCachedSpell((uint)entry.SpellId);
                Remove(entry, false);
                entry         = BuildEntry(enchantment.Spell.SpellId, castByItem);
                entry.LayerId = enchantment.Layer;
                WorldObject.Biota.BiotaPropertiesEnchantmentRegistry.Add(entry);
                return(StackType.Surpass);
            }

            if (enchantment.Spell.Power == entry.PowerLevel)
            {
                if (entry.Duration != -1)
                {
                    // refresh existing spell
                    entry.LayerId++;
                    entry.StartTime = 0;
                    return(StackType.Refresh);
                }

                return(StackType.None);
            }

            // superior existing spell
            Surpass = DatabaseManager.World.GetCachedSpell((uint)entry.SpellId);
            return(StackType.Surpassed);
        }
Example #12
0
        /// <summary>
        /// Method used for handling player untargeted spell casts
        /// </summary>
        public void CreatePlayerSpell(uint spellId)
        {
            if (IsBusy == true)
            {
                Session.Network.EnqueueSend(new GameEventUseDone(Session, errorType: WeenieError.YoureTooBusy));
                return;
            }
            else
            {
                IsBusy = true;
            }

            SpellTable spellTable = DatManager.PortalDat.SpellTable;

            if (!spellTable.Spells.ContainsKey(spellId))
            {
                Session.Network.EnqueueSend(new GameEventUseDone(Session, errorType: WeenieError.MagicInvalidSpellType));
                IsBusy = false;
                return;
            }

            SpellBase spell = spellTable.Spells[spellId];

            Database.Models.World.Spell spellStatMod = DatabaseManager.World.GetCachedSpell(spellId);
            if (spellStatMod == null)
            {
                Session.Network.EnqueueSend(new GameMessageSystemChat($"{spell.Name} spell not implemented, yet!", ChatMessageType.System));
                Session.Network.EnqueueSend(new GameEventUseDone(Session, errorType: WeenieError.MagicInvalidSpellType));
                IsBusy = false;
                return;
            }

            // Grab player's skill level in the spell's Magic School
            var magicSkill = GetCreatureSkill(spell.School);

            float scale   = SpellAttributes(Session.Account, spellId, out float castingDelay, out MotionCommand windUpMotion, out MotionCommand spellGesture);
            var   formula = SpellTable.GetSpellFormula(spellTable, spellId, Session.Account);

            bool spellCastSuccess = false || ((Physics.Common.Random.RollDice(0.0f, 1.0f) > (1.0f - SkillCheck.GetMagicSkillChance((int)magicSkill.Current, (int)spell.Power))) &&
                                              (magicSkill.Current >= (int)spell.Power - 50) && (magicSkill.Current > 0));

            // Calculating mana usage
            #region
            if (spellCastSuccess == true)
            {
                CreatureSkill mc = GetCreatureSkill(Skill.ManaConversion);
                double        z  = mc.Current;
                double        baseManaPercent = 1;
                if (z > spell.Power)
                {
                    baseManaPercent = spell.Power / z;
                }
                double preCost;
                uint   manaUsed;
                if ((int)Math.Floor(baseManaPercent) == 1)
                {
                    preCost  = spell.BaseMana;
                    manaUsed = (uint)preCost;
                }
                else
                {
                    preCost = spell.BaseMana * baseManaPercent;
                    if (preCost < 1)
                    {
                        preCost = 1;
                    }
                    manaUsed = (uint)Physics.Common.Random.RollDice(1, (int)preCost);
                }
                if (spell.MetaSpellType == SpellType.Transfer)
                {
                    uint vitalChange, casterVitalChange;
                    vitalChange = (uint)(GetCurrentCreatureVital((PropertyAttribute2nd)spellStatMod.Source) * spellStatMod.Proportion);
                    if (spellStatMod.TransferCap != 0)
                    {
                        if (vitalChange > spellStatMod.TransferCap)
                        {
                            vitalChange = (uint)spellStatMod.TransferCap;
                        }
                    }
                    casterVitalChange = (uint)(vitalChange * (1.0f - spellStatMod.LossPercent));
                    vitalChange       = (uint)(casterVitalChange / (1.0f - spellStatMod.LossPercent));

                    if (spellStatMod.Source == (int)PropertyAttribute2nd.Mana && (vitalChange + 10 + manaUsed) > Mana.Current)
                    {
                        ActionChain resourceCheckChain = new ActionChain();

                        resourceCheckChain.AddAction(this, () =>
                        {
                            CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, ACE.Entity.Enum.PlayScript.Fizzle, 0.5f));
                        });

                        resourceCheckChain.AddDelaySeconds(2.0f);
                        resourceCheckChain.AddAction(this, () =>
                        {
                            Session.Network.EnqueueSend(new GameEventUseDone(Session, errorType: WeenieError.YouDontHaveEnoughManaToCast));
                            IsBusy = false;
                        });

                        resourceCheckChain.EnqueueChain();

                        return;
                    }

                    if ((vitalChange + 10) > GetCurrentCreatureVital((PropertyAttribute2nd)spellStatMod.Source))
                    {
                        ActionChain resourceCheckChain = new ActionChain();

                        resourceCheckChain.AddAction(this, () =>
                        {
                            CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, ACE.Entity.Enum.PlayScript.Fizzle, 0.5f));
                        });

                        resourceCheckChain.AddDelaySeconds(2.0f);
                        resourceCheckChain.AddAction(this, () => IsBusy = false);
                        resourceCheckChain.EnqueueChain();

                        return;
                    }
                }
                else if (manaUsed > Mana.Current)
                {
                    ActionChain resourceCheckChain = new ActionChain();

                    resourceCheckChain.AddAction(this, () =>
                    {
                        CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, ACE.Entity.Enum.PlayScript.Fizzle, 0.5f));
                    });

                    resourceCheckChain.AddDelaySeconds(2.0f);
                    resourceCheckChain.AddAction(this, () =>
                    {
                        Session.Network.EnqueueSend(new GameEventUseDone(Session, errorType: WeenieError.YouDontHaveEnoughManaToCast));
                        IsBusy = false;
                    });

                    resourceCheckChain.EnqueueChain();

                    return;
                }
                else
                {
                    UpdateVital(Mana, Mana.Current - manaUsed);
                }
            }
            #endregion

            ActionChain spellChain = new ActionChain();

            uint fastCast = (spell.Bitfield >> 14) & 0x1u;
            if (fastCast != 1)
            {
                spellChain.AddAction(this, () =>
                {
                    var motionWindUp = new UniversalMotion(MotionStance.Spellcasting);
                    motionWindUp.MovementData.CurrentStyle   = (ushort)((uint)MotionStance.Spellcasting & 0xFFFF);
                    motionWindUp.MovementData.ForwardCommand = (uint)windUpMotion;
                    motionWindUp.MovementData.ForwardSpeed   = 2;
                    DoMotion(motionWindUp);
                });
            }

            spellChain.AddAction(this, () =>
            {
                CurrentLandblock.EnqueueBroadcast(Location, new GameMessageCreatureMessage(SpellComponentsTable.GetSpellWords(DatManager.PortalDat.SpellComponentsTable,
                                                                                                                              formula), Name, Guid.Full, ChatMessageType.Magic));
            });

            spellChain.AddAction(this, () =>
            {
                var motionCastSpell = new UniversalMotion(MotionStance.Spellcasting);
                motionCastSpell.MovementData.CurrentStyle   = (ushort)((uint)MotionStance.Spellcasting & 0xFFFF);
                motionCastSpell.MovementData.ForwardCommand = (uint)spellGesture;
                motionCastSpell.MovementData.ForwardSpeed   = 2;
                DoMotion(motionCastSpell);
            });

            if (fastCast == 1)
            {
                spellChain.AddDelaySeconds(castingDelay * 0.26f);
            }
            else
            {
                spellChain.AddDelaySeconds(castingDelay);
            }

            if (spellCastSuccess == false)
            {
                spellChain.AddAction(this, () => CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, ACE.Entity.Enum.PlayScript.Fizzle, 0.5f)));
            }
            else
            {
                // TODO - Successful spell casting code goes here for untargeted spells to replace line below
                Session.Network.EnqueueSend(new GameMessageSystemChat("Targeted SpellID " + spellId + " not yet implemented!", ChatMessageType.System));
            }

            spellChain.AddAction(this, () =>
            {
                var motionReturnToCastStance = new UniversalMotion(MotionStance.Spellcasting);
                motionReturnToCastStance.MovementData.CurrentStyle   = (ushort)((uint)MotionStance.Spellcasting & 0xFFFF);
                motionReturnToCastStance.MovementData.ForwardCommand = (uint)MotionCommand.Invalid;
                DoMotion(motionReturnToCastStance);
            });

            spellChain.AddDelaySeconds(1.0f);

            spellChain.AddAction(this, () =>
            {
                Session.Network.EnqueueSend(new GameEventUseDone(Session, errorType: WeenieError.None));
                IsBusy = false;
            });

            spellChain.EnqueueChain();

            return;
        }
Example #13
0
        /// <summary>
        /// Method used for handling player targeted spell casts
        /// </summary>
        public void CreatePlayerSpell(ObjectGuid guidTarget, uint spellId)
        {
            Player         player         = CurrentLandblock.GetObject(Guid) as Player;
            WorldObject    target         = CurrentLandblock.GetObject(guidTarget);
            TargetCategory targetCategory = TargetCategory.WorldObject;

            if (target == null)
            {
                target         = GetWieldedItem(guidTarget);
                targetCategory = TargetCategory.Wielded;
            }
            if (target == null)
            {
                target         = GetInventoryItem(guidTarget);
                targetCategory = TargetCategory.Inventory;
            }
            if (target == null)
            {
                player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.TargetNotAcquired));
                targetCategory = TargetCategory.UnDef;
                return;
            }

            SpellTable spellTable = DatManager.PortalDat.SpellTable;

            if (!spellTable.Spells.ContainsKey(spellId))
            {
                player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.MagicInvalidSpellType));
                return;
            }

            SpellBase spell = spellTable.Spells[spellId];

            if (IsInvalidTarget(spell, target))
            {
                player.Session.Network.EnqueueSend(new GameEventCommunicationTransientString(player.Session, $"{spell.Name} cannot be cast on {target.Name}."));
                player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.None));
                return;
            }

            Database.Models.World.Spell spellStatMod = DatabaseManager.World.GetCachedSpell(spellId);
            if (spellStatMod == null)
            {
                player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{spell.Name} spell not implemented, yet!", ChatMessageType.System));
                player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.MagicInvalidSpellType));
                return;
            }

            if (player.IsBusy == true)
            {
                player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.YoureTooBusy));
                return;
            }
            else
            {
                player.IsBusy = true;
            }

            uint targetEffect = spell.TargetEffect;

            // Grab player's skill level in the spell's Magic School
            var magicSkill = player.GetCreatureSkill(spell.School).Current;

            if (targetCategory == TargetCategory.WorldObject)
            {
                if (guidTarget != Guid)
                {
                    float distanceTo = Location.Distance2D(target.Location);

                    if (distanceTo > spell.BaseRangeConstant + magicSkill * spell.BaseRangeMod)
                    {
                        player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.MagicTargetOutOfRange),
                                                           new GameMessageSystemChat($"{target.Name} is out of range!", ChatMessageType.Magic));
                        player.IsBusy = false;
                        return;
                    }
                }
            }

            // Ensure that a harmful spell isn't being cast on a player target that doesn't have the same PK status
            if (target.WeenieClassId == 1 && player.PlayerKillerStatus != ACE.Entity.Enum.PlayerKillerStatus.NPK)
            {
                bool isSpellHarmful = IsSpellHarmful(spell);
                if (player.PlayerKillerStatus != target.PlayerKillerStatus && isSpellHarmful)
                {
                    player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.InvalidPkStatus));
                    player.IsBusy = false;
                    return;
                }
            }

            float scale   = SpellAttributes(player.Session.Account, spellId, out float castingDelay, out MotionCommand windUpMotion, out MotionCommand spellGesture);
            var   formula = SpellTable.GetSpellFormula(spellTable, spellId, player.Session.Account);

            bool spellCastSuccess = false || ((Physics.Common.Random.RollDice(0.0f, 1.0f) > (1.0f - SkillCheck.GetMagicSkillChance((int)magicSkill, (int)spell.Power))) &&
                                              (magicSkill >= (int)spell.Power - 50) && (magicSkill > 0));

            // Calculating mana usage
            #region
            CreatureSkill mc = player.GetCreatureSkill(Skill.ManaConversion);
            double        z  = mc.Current;
            double        baseManaPercent = 1;
            if (z > spell.Power)
            {
                baseManaPercent = spell.Power / z;
            }
            double preCost;
            uint   manaUsed;
            if ((int)Math.Floor(baseManaPercent) == 1)
            {
                preCost  = spell.BaseMana;
                manaUsed = (uint)preCost;
            }
            else
            {
                preCost = spell.BaseMana * baseManaPercent;
                if (preCost < 1)
                {
                    preCost = 1;
                }
                manaUsed = (uint)Physics.Common.Random.RollDice(1, (int)preCost);
            }
            if (spell.MetaSpellType == SpellType.Transfer)
            {
                uint vitalChange, casterVitalChange;
                vitalChange = (uint)(player.GetCurrentCreatureVital((PropertyAttribute2nd)spellStatMod.Source) * spellStatMod.Proportion);
                if (spellStatMod.TransferCap != 0)
                {
                    if (vitalChange > spellStatMod.TransferCap)
                    {
                        vitalChange = (uint)spellStatMod.TransferCap;
                    }
                }
                casterVitalChange = (uint)(vitalChange * (1.0f - spellStatMod.LossPercent));
                vitalChange       = (uint)(casterVitalChange / (1.0f - spellStatMod.LossPercent));

                if (spellStatMod.Source == (int)PropertyAttribute2nd.Mana && (vitalChange + 10 + manaUsed) > player.Mana.Current)
                {
                    ActionChain resourceCheckChain = new ActionChain();

                    resourceCheckChain.AddAction(this, () =>
                    {
                        CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, ACE.Entity.Enum.PlayScript.Fizzle, 0.5f));
                    });

                    resourceCheckChain.AddDelaySeconds(2.0f);
                    resourceCheckChain.AddAction(this, () =>
                    {
                        player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.YouDontHaveEnoughManaToCast));
                        player.IsBusy = false;
                    });

                    resourceCheckChain.EnqueueChain();

                    return;
                }
                else if ((vitalChange + 10) > player.GetCurrentCreatureVital((PropertyAttribute2nd)spellStatMod.Source))
                {
                    ActionChain resourceCheckChain = new ActionChain();

                    resourceCheckChain.AddAction(this, () =>
                    {
                        CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, ACE.Entity.Enum.PlayScript.Fizzle, 0.5f));
                    });

                    resourceCheckChain.AddDelaySeconds(2.0f);
                    resourceCheckChain.AddAction(this, () => player.IsBusy = false);
                    resourceCheckChain.EnqueueChain();

                    return;
                }
            }
            else if (manaUsed > player.Mana.Current)
            {
                ActionChain resourceCheckChain = new ActionChain();

                resourceCheckChain.AddAction(this, () =>
                {
                    CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, ACE.Entity.Enum.PlayScript.Fizzle, 0.5f));
                });

                resourceCheckChain.AddDelaySeconds(2.0f);
                resourceCheckChain.AddAction(this, () =>
                {
                    player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.YouDontHaveEnoughManaToCast));
                    player.IsBusy = false;
                });

                resourceCheckChain.EnqueueChain();

                return;
            }
            else
            {
                player.UpdateVital(player.Mana, player.Mana.Current - manaUsed);
            }
            #endregion

            ActionChain spellChain = new ActionChain();

            uint fastCast = (spell.Bitfield >> 14) & 0x1u;
            if (fastCast != 1)
            {
                spellChain.AddAction(this, () =>
                {
                    var motionWindUp = new UniversalMotion(MotionStance.Spellcasting);
                    motionWindUp.MovementData.CurrentStyle   = (ushort)((uint)MotionStance.Spellcasting & 0xFFFF);
                    motionWindUp.MovementData.ForwardCommand = (uint)windUpMotion;
                    motionWindUp.MovementData.ForwardSpeed   = 2;
                    DoMotion(motionWindUp);
                });
            }

            spellChain.AddAction(this, () =>
            {
                CurrentLandblock.EnqueueBroadcast(Location, new GameMessageCreatureMessage(SpellComponentsTable.GetSpellWords(DatManager.PortalDat.SpellComponentsTable,
                                                                                                                              formula), Name, Guid.Full, ChatMessageType.Magic));
            });

            spellChain.AddAction(this, () =>
            {
                var motionCastSpell = new UniversalMotion(MotionStance.Spellcasting);
                motionCastSpell.MovementData.CurrentStyle   = (ushort)((uint)MotionStance.Spellcasting & 0xFFFF);
                motionCastSpell.MovementData.ForwardCommand = (uint)spellGesture;
                motionCastSpell.MovementData.ForwardSpeed   = 2;
                DoMotion(motionCastSpell);
            });

            if (fastCast == 1)
            {
                spellChain.AddDelaySeconds(castingDelay * 0.26f);
            }
            else
            {
                spellChain.AddDelaySeconds(castingDelay);
            }

            if (spellCastSuccess == false)
            {
                spellChain.AddAction(this, () => CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, ACE.Entity.Enum.PlayScript.Fizzle, 0.5f)));
            }
            else
            {
                spellChain.AddAction(this, () =>
                {
                    bool targetDeath;
                    string message;

                    switch (spell.School)
                    {
                    case MagicSchool.WarMagic:
                        WarMagic(target, spell, spellStatMod);
                        break;

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

                    case MagicSchool.CreatureEnchantment:
                        if (IsSpellHarmful(spell))
                        {
                            // Retrieve player's skill level in the Magic School
                            var playerMagicSkill = player.GetCreatureSkill(spell.School).Current;

                            // Retrieve target's Magic Defense Skill
                            Creature creature           = (Creature)target;
                            var targetMagicDefenseSkill = creature.GetCreatureSkill(Skill.MagicDefense).Current;

                            if (MagicDefenseCheck(playerMagicSkill, targetMagicDefenseSkill))
                            {
                                CurrentLandblock.EnqueueBroadcastSound(player, Sound.ResistSpell);
                                player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{creature.Name} resists {spell.Name}", ChatMessageType.Magic));
                                break;
                            }
                        }
                        CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(target.Guid, (PlayScript)spell.TargetEffect, scale));
                        message = CreatureMagic(target, spell, spellStatMod);
                        if (message != "")
                        {
                            player.Session.Network.EnqueueSend(new GameMessageSystemChat(message, ChatMessageType.Magic));
                        }
                        break;

                    case MagicSchool.LifeMagic:
                        if (spell.MetaSpellType != SpellType.LifeProjectile)
                        {
                            if (IsSpellHarmful(spell))
                            {
                                // Retrieve player's skill level in the Magic School
                                var playerMagicSkill = player.GetCreatureSkill(spell.School).Current;

                                // Retrieve target's Magic Defense Skill
                                Creature creature           = (Creature)target;
                                var targetMagicDefenseSkill = creature.GetCreatureSkill(Skill.MagicDefense).Current;

                                if (MagicDefenseCheck(playerMagicSkill, targetMagicDefenseSkill))
                                {
                                    CurrentLandblock.EnqueueBroadcastSound(player, Sound.ResistSpell);
                                    player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{creature.Name} resists {spell.Name}", ChatMessageType.Magic));
                                    break;
                                }
                            }
                        }
                        CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(target.Guid, (PlayScript)spell.TargetEffect, scale));
                        targetDeath = LifeMagic(target, spell, spellStatMod, out message);
                        if (message != null)
                        {
                            player.Session.Network.EnqueueSend(new GameMessageSystemChat(message, ChatMessageType.Magic));
                        }
                        if (targetDeath == true)
                        {
                            Creature creatureTarget = (Creature)target;
                            creatureTarget.Die();
                            Strings.DeathMessages.TryGetValue(DamageType.Base, out var messages);
                            player.Session.Network.EnqueueSend(new GameMessageSystemChat(string.Format(messages[0], target.Name), ChatMessageType.Broadcast));
                            player.EarnXP((long)target.XpOverride);
                        }
                        break;

                    case MagicSchool.ItemEnchantment:
                        if (guidTarget == Guid)
                        {
                            CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, (PlayScript)spell.CasterEffect, scale));
                        }
                        else
                        {
                            CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(target.Guid, (PlayScript)spell.TargetEffect, scale));
                        }
                        message = ItemMagic(target, spell, spellStatMod);
                        if (message != "")
                        {
                            player.Session.Network.EnqueueSend(new GameMessageSystemChat(message, ChatMessageType.Magic));
                        }
                        break;

                    default:
                        break;
                    }
                });
            }

            spellChain.AddAction(this, () =>
            {
                var motionReturnToCastStance = new UniversalMotion(MotionStance.Spellcasting);
                motionReturnToCastStance.MovementData.CurrentStyle   = (ushort)((uint)MotionStance.Spellcasting & 0xFFFF);
                motionReturnToCastStance.MovementData.ForwardCommand = (uint)MotionCommand.Invalid;
                DoMotion(motionReturnToCastStance);
            });

            spellChain.AddDelaySeconds(1.0f);

            spellChain.AddAction(this, () =>
            {
                player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.None));
                player.IsBusy = false;
            });

            spellChain.EnqueueChain();

            return;
        }
Example #14
0
        /// <summary>
        /// Method used for handling items casting spells on the player equiping the item
        /// </summary>
        /// <param name="guidItem"></param>
        /// <param name="spellId"></param>
        public void CreateItemSpell(ObjectGuid guidItem, uint spellId)
        {
            Player      player = CurrentLandblock.GetObject(Guid) as Player;
            WorldObject item   = player.GetWieldedItem(guidItem);

            if (item == null)
            {
                item = player.GetInventoryItem(guidItem);
                if (item == null)
                {
                    return;
                }
                if (item.WeenieType != WeenieType.Gem)
                {
                    return;
                }
            }

            CreatureSkill arcaneLore     = player.GetCreatureSkill(Skill.ArcaneLore);
            CreatureSkill meleeDefense   = player.GetCreatureSkill(Skill.MeleeDefense);
            CreatureSkill missileDefense = player.GetCreatureSkill(Skill.MissileDefense);
            CreatureSkill magicDefense   = player.GetCreatureSkill(Skill.MagicDefense);

            if (arcaneLore.Current >= item.ItemDifficulty || item.ItemDifficulty == null)
            {
                if (item.AppraisalItemSkill != 0 || item.AppraisalItemSkill != null)
                {
                    switch (item.AppraisalItemSkill)
                    {
                    case 6:
                        if (meleeDefense.Current < item.ItemSkillLevelLimit)
                        {
                            return;
                        }
                        break;

                    case 7:
                        if (missileDefense.Current < item.ItemSkillLevelLimit)
                        {
                            return;
                        }
                        break;

                    case 8:
                        if (magicDefense.Current < item.ItemSkillLevelLimit)
                        {
                            return;
                        }
                        break;
                    }
                }

                SpellTable spellTable = DatManager.PortalDat.SpellTable;
                if (!spellTable.Spells.ContainsKey(spellId))
                {
                    player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.MagicInvalidSpellType));
                    return;
                }

                SpellBase spell = spellTable.Spells[spellId];

                Database.Models.World.Spell spellStatMod = DatabaseManager.World.GetCachedSpell(spellId);
                if (spellStatMod == null)
                {
                    player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{spell.Name} spell not implemented, yet!", ChatMessageType.System));
                    return;
                }

                float scale = SpellAttributes(player.Session.Account, spellId, out float castingDelay, out MotionCommand windUpMotion, out MotionCommand spellGesture);

                string message;
                switch (spell.School)
                {
                case MagicSchool.CreatureEnchantment:
                    if (IsSpellHarmful(spell))
                    {
                        break;
                    }
                    CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(player.Guid, (PlayScript)spell.TargetEffect, scale));
                    message = CreatureMagic(player, spell, spellStatMod, item.Name);
                    if (message != "")
                    {
                        player.Session.Network.EnqueueSend(new GameMessageSystemChat(message, ChatMessageType.Magic));
                    }
                    break;

                case MagicSchool.LifeMagic:
                    if (spell.MetaSpellType != SpellType.LifeProjectile)
                    {
                        if (IsSpellHarmful(spell))
                        {
                            break;
                        }
                    }
                    CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(player.Guid, (PlayScript)spell.TargetEffect, scale));
                    LifeMagic(player, spell, spellStatMod, out message, item.Name);
                    if (message != null)
                    {
                        player.Session.Network.EnqueueSend(new GameMessageSystemChat(message, ChatMessageType.Magic));
                    }
                    break;

                case MagicSchool.ItemEnchantment:
                    CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(item.Guid, (PlayScript)spell.TargetEffect, scale));
                    message = ItemMagic(item, spell, spellStatMod, item.Name);
                    if (message != "")
                    {
                        player.Session.Network.EnqueueSend(new GameMessageSystemChat(message, ChatMessageType.Magic));
                    }
                    break;

                default:
                    break;
                }
            }
        }
Example #15
0
        /// <summary>
        /// Add/update an enchantment in this object's registry
        /// </summary>
        public StackType Add(Enchantment enchantment, WorldObject caster)
        {
            StackType result = StackType.Undef;

            // check for existing spell in this category
            var entries = GetCategory(enchantment.SpellBase.Category);

            // if none, add new record
            if (entries.Count == 0)
            {
                var newEntry = BuildEntry(enchantment.Spell.Id, caster);
                newEntry.LayerId = enchantment.Layer;

                WorldObject.Biota.AddEnchantment(newEntry, WorldObject.BiotaDatabaseLock);
                WorldObject.ChangesDetected = true;

                return(StackType.Initial);
            }

            // Check for existing spells in registry that are superior
            foreach (var entry in entries)
            {
                if (enchantment.SpellBase.Power < entry.PowerLevel)
                {
                    // superior existing spell
                    Surpass = DatabaseManager.World.GetCachedSpell((uint)entry.SpellId);

                    result = StackType.Surpassed;
                }
            }

            if (result != StackType.Surpassed)
            {
                // Check for existing spells in registry that are equal to
                foreach (var entry in entries)
                {
                    if (enchantment.SpellBase.Power == entry.PowerLevel)
                    {
                        if (entry.Duration == -1)
                        {
                            result = StackType.None;

                            break;
                        }

                        // item cast spell of equal power should override an existing spell, especially one with a duration
                        if ((caster as Creature) == null)
                        {
                            enchantment.Layer = entry.LayerId; // Should be a higher layer than existing enchant

                            var newEntry = BuildEntry(enchantment.Spell.Id, caster);
                            newEntry.LayerId = enchantment.Layer;
                            WorldObject.Biota.AddEnchantment(newEntry, WorldObject.BiotaDatabaseLock);
                            WorldObject.ChangesDetected = true;
                            result = StackType.Refresh;
                            break;
                        }

                        // refresh existing spell
                        entry.StartTime = 0;

                        result = StackType.Refresh;

                        break;
                    }
                }

                // Previous check didn't return any result
                if (result == StackType.Undef)
                {
                    ushort layerBuffer = 1;
                    // Check for highest existing spell in registry that is inferior
                    foreach (var entry in entries)
                    {
                        if (enchantment.SpellBase.Power > entry.PowerLevel)
                        {
                            // surpass existing spell
                            Surpass     = DatabaseManager.World.GetCachedSpell((uint)entry.SpellId);
                            layerBuffer = entry.LayerId;
                        }
                    }

                    enchantment.Layer = (ushort)(layerBuffer + 1); // Should be a higher layer than existing enchant

                    var newEntry = BuildEntry(enchantment.Spell.Id, caster);
                    newEntry.LayerId = enchantment.Layer;
                    WorldObject.Biota.AddEnchantment(newEntry, WorldObject.BiotaDatabaseLock);
                    WorldObject.ChangesDetected = true;
                    result = StackType.Surpass;
                }
            }

            return(result);
        }