Beispiel #1
0
        /// <summary>
        /// Performs the skill by the player at the specified area. Additionally to the target area, a target object can be specified.
        /// </summary>
        /// <param name="player">The player.</param>
        /// <param name="extraTargetId">The extra target identifier.</param>
        /// <param name="skillId">The skill identifier.</param>
        /// <param name="targetAreaCenterX">The x coordinate of the center of the target area.</param>
        /// <param name="targetAreaCenterY">The y coordinate of the center of the target area.</param>
        /// <param name="rotation">The rotation in which the player is looking. It's not really relevant for the hitted objects yet, but for some directed skills in the future it might be.</param>
        public void Attack(Player player, ushort extraTargetId, ushort skillId, byte targetAreaCenterX, byte targetAreaCenterY, byte rotation)
        {
            SkillEntry skillEntry = player.SkillList.GetSkill(skillId);
            var        skill      = skillEntry.Skill;

            if (skill.SkillType == SkillType.PassiveBoost)
            {
                Logger.WarnFormat("AreaSkill is a passive boost");
                return;
            }

            if (!player.TryConsumeForSkill(skill))
            {
                Logger.WarnFormat("AreaSkill not enough resources");
                return;
            }

            if (skill.SkillType == SkillType.AreaSkillAutomaticHits)
            {
                Logger.WarnFormat("AreaSkill perform automatic hits");
                this.PerformAutomaticHits(player, extraTargetId, targetAreaCenterX, targetAreaCenterY, skillEntry, skill);
            }

            player.ForEachObservingPlayer(p => p.PlayerView.WorldView.ShowAreaSkillAnimation(player, skill, targetAreaCenterX, targetAreaCenterY, rotation), true);
        }
Beispiel #2
0
        private void AddLearnedSkill(SkillEntry skill)
        {
            this.availableSkills.Add(skill.Skill.Number.ToUnsigned(), skill);
            this.learnedSkills.Add(skill);

            this.player.PlayerView.AddSkill(skill.Skill);
        }
        /// <inheritdoc/>
        public void HandlePacket(Player player, Span <byte> packet)
        {
            if (packet.Length < 11)
            {
                return;
            }

            ushort skillId = NumberConversionExtensions.MakeWord(packet[4], packet[3]);

            if (!player.SkillList.ContainsSkill(skillId))
            {
                return;
            }

            SkillEntry skillEntry = player.SkillList.GetSkill(skillId);
            ushort     targetId   = NumberConversionExtensions.MakeWord(packet[10], packet[9]);

            if (player.GetObject(targetId) is IAttackable target)
            {
                if (target is IObservable observable && observable.Observers.Contains(player))
                {
                    this.skillHitAction.AttackTarget(player, target, skillEntry);
                }
                else
                {
                    // Client may be out of sync (or it's an hacker attempt),
                    // so we tell him the object is out of scope - this should prevent further attempts to attack it.
                    player.ViewPlugIns.GetPlugIn <IObjectsOutOfScopePlugIn>()?.ObjectsOutOfScope(target.GetAsEnumerable());
                }
            }
Beispiel #4
0
        /// <summary>
        /// Returns the base damage if the attacker, using a specific skill.
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="skill">Skill which is used.</param>
        /// <param name="basemin">Minimum base damage.</param>
        /// <param name="basemax">Maximum base damage.</param>
        private static void GetBaseDmg(this IAttackable attacker, SkillEntry skill, out int basemin, out int basemax)
        {
            basemin = 0;
            basemax = 0;
            var        attackerStats = attacker.Attributes;
            DamageType damageType    = DamageType.Physical;

            if (skill != null)
            {
                damageType = skill.Skill.DamageType;
                var skillDamage = skill.Skill.AttackDamage.Where(d => d.Level == skill.Level).Select(d => d.Damage).FirstOrDefault();
                basemin += skillDamage;
                basemax += skillDamage;
            }

            if (damageType == DamageType.Physical)
            {
                basemin = (int)attackerStats[Stats.MinimumPhysBaseDmg];
                basemax = (int)attackerStats[Stats.MaximumPhysBaseDmg];
            }
            else if (damageType == DamageType.Wizardry)
            {
                basemin = (int)attackerStats[Stats.MinimumWizBaseDmg];
                basemax = (int)attackerStats[Stats.MaximumWizBaseDmg];
            }
            else if (damageType == DamageType.Curse)
            {
                basemin = (int)attackerStats[Stats.MinimumCurseBaseDmg];
                basemax = (int)attackerStats[Stats.MaximumCurseBaseDmg];
            }
        }
Beispiel #5
0
        public UseSkillButtonGump(SkillEntry skill)
            : base(skill.ID, 0)
        {
            while (UserInterface.GetControl <UseSkillButtonGump>(skill.ID) != null)
            {
                UserInterface.GetControl <UseSkillButtonGump>(skill.ID).Dispose();
            }

            m_Skill = skill;
            m_World = Service.Get <WorldModel>();

            IsMoveable        = true;
            HandlesMouseInput = true;

            m_BG      = new ResizePic[3];
            m_BG[0]   = (ResizePic)AddControl(new ResizePic(this, 0, 0, 0x24B8, 120, 40));
            m_BG[1]   = (ResizePic)AddControl(new ResizePic(this, 0, 0, 0x24EA, 120, 40));
            m_BG[2]   = (ResizePic)AddControl(new ResizePic(this, 0, 0, 0x251C, 120, 40));
            m_Caption = (HtmlGumpling)AddControl(new HtmlGumpling(this, 0, 10, 120, 20, 0, 0, "<center>" + m_Skill.Name));

            for (int i = 0; i < 3; i++)
            {
                m_BG[i].MouseDownEvent  += EventMouseDown;
                m_BG[i].MouseUpEvent    += EventMouseUp;
                m_BG[i].MouseClickEvent += EventMouseClick;
            }
        }
        private void ApplySkill(Player player, IAttackable targetedTarget, SkillEntry skillEntry)
        {
            var skill   = skillEntry.Skill;
            var targets = this.DetermineTargets(player, targetedTarget, skill);

            foreach (var target in targets)
            {
                if (skill.SkillType == SkillType.DirectHit || skill.SkillType == SkillType.CastleSiegeSkill)
                {
                    target.AttackBy(player, skillEntry);
                    target.ApplyElementalEffects(player, skillEntry);
                }
                else if (skill.MagicEffectDef != null)
                {
                    if (skill.SkillType == SkillType.Buff)
                    {
                        target.ApplyMagicEffect(player, skillEntry);
                    }
                    else if (skill.SkillType == SkillType.Regeneration)
                    {
                        target.ApplyRegeneration(player, skill);
                    }
                    else
                    {
                        Log.Warn($"Skill.MagicEffectDef isn't null, but it's not a buff or regeneration skill. skill: {skill.Name} ({skill.Number}), skillType: {skill.SkillType}.");
                    }
                }
                else
                {
                    Log.Warn($"Skill.MagicEffectDef is null, skill: {skill.Name} ({skill.Number}), skillType: {skill.SkillType}.");
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Applies the regeneration of the players skill to the target.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <param name="player">The player.</param>
        /// <param name="skillEntry">The skill entry.</param>
        public static void ApplyRegeneration(this IAttackable target, Player player, SkillEntry skillEntry)
        {
            if (player.Attributes is null)
            {
                return;
            }

            skillEntry.ThrowNotInitializedProperty(skillEntry.Skill is null, nameof(skillEntry.Skill));

            var skill        = skillEntry.Skill;
            var regeneration = Stats.IntervalRegenerationAttributes.FirstOrDefault(r => r.CurrentAttribute == skill.MagicEffectDef?.PowerUpDefinition?.TargetAttribute);

            if (regeneration != null)
            {
                var powerUpDefinition = skill.MagicEffectDef !.PowerUpDefinition !;
                var regenerationValue = player.Attributes.CreateElement(powerUpDefinition.Boost ?? throw Error.NotInitializedProperty(powerUpDefinition, nameof(powerUpDefinition.Boost)));
                var value             = skillEntry.Level == 0 ? regenerationValue.Value : regenerationValue.Value + skillEntry.CalculateValue();
                target.Attributes[regeneration.CurrentAttribute] = Math.Min(
                    target.Attributes[regeneration.CurrentAttribute] + value,
                    target.Attributes[regeneration.MaximumAttribute]);
            }
            else
            {
                player.Logger.LogWarning(
                    $"Regeneration skill {skill.Name} is configured to regenerate a non-regeneration-able target attribute {skill.MagicEffectDef?.PowerUpDefinition?.TargetAttribute}.");
            }
        }
Beispiel #8
0
    protected override void OnCreat()
    {
        SkillEntry entry = new SkillEntry();
        var        node  = AddNode(entry, new Rect(Vector2.zero, new Vector2(80, 80)));

        node.Name = "Entry";
    }
        private GuildSkill TransformGuildSkill(Data.Repositories.Contracts.Classes.GuildSkill skill)
        {
            if (skill == null)
            {
                return(null);
            }

            var ret = new GuildSkill {
                Point = skill.Point
            };

            using (var ms = new MemoryStream(skill.Skill))
            {
                using (var br = new BinaryReader(ms))
                {
                    var l = new List <SkillEntry>();
                    for (var i = 0; i < ms.Length / 4; i++)
                    {
                        var se = new SkillEntry
                        {
                            SkillId = br.ReadInt16(),
                            Level   = br.ReadInt16()
                        };

                        l.Add(se);
                    }

                    ret.Skills = l.ToArray();
                }
            }

            return(ret);
        }
        public void Render(SkillEntry skill)
        {
            var currentRank = GameWorld.Instance.Character.Allocations.GetPoints(AllocationType.Skill, skill.Name);

            _rankText.text = $"{currentRank}/{skill.MaxRank}";
            _skillName     = skill.Name;
        }
Beispiel #11
0
        /// <inheritdoc />
        public void AfterTargetGotAttacked(IAttackable attacker, IAttackable target, SkillEntry skillEntry, Point targetAreaCenter)
        {
            if (!target.Alive || !(target is IMovable movableTarget))
            {
                return;
            }

            var startingPoint = attacker.Position;
            var currentTarget = target.Position;
            var direction     = startingPoint.GetDirectionTo(currentTarget);

            if (direction == Direction.Undefined)
            {
                direction = (Direction)Rand.NextInt(1, 9);
            }

            var currentDistance = startingPoint.EuclideanDistanceTo(currentTarget);

            while (currentDistance < skillEntry.Skill.Range)
            {
                var nextTarget = currentTarget.CalculateTargetPoint(direction);
                if (!target.CurrentMap.Terrain.WalkMap[nextTarget.X, nextTarget.Y] ||
                    (target is NonPlayerCharacter && target.CurrentMap.Terrain.SafezoneMap[nextTarget.X, nextTarget.Y]))
                {
                    // we don't want to push the target into a non-reachable area, through walls or monsters into the safe zone.
                    break;
                }

                currentTarget   = nextTarget;
                currentDistance = startingPoint.EuclideanDistanceTo(currentTarget);
            }

            movableTarget.Move(currentTarget);
        }
Beispiel #12
0
 private void CreatePowerUpWrappers(SkillEntry skillEntry)
 {
     if (skillEntry.Skill.PassivePowerUps.TryGetValue(skillEntry.Level, out PowerUpDefinition powerUp))
     {
         this.passiveSkillPowerUps.Add(skillEntry, PowerUpWrapper.CreateByPowerUpDefintion(powerUp, this.player.Attributes).ToList());
     }
 }
Beispiel #13
0
 private void ApplySkill(Player player, SkillEntry skillEntry, Skill skill, IAttackable target)
 {
     if (target.CheckSkillTargetRestrictions(player, skill))
     {
         target.AttackBy(player, skillEntry);
         target.ApplyElementalEffects(player, skillEntry);
     }
 }
Beispiel #14
0
        public static string SkillState(string name)
        {
            SkillManager manager = SkillManager.GetInstance();

            SkillEntry s = manager.Items.FirstOrDefault(se => se.Skill.Name.ToLower().Contains(name.ToLower()));

            return(s?.LockStatus.ToString().ToLower() ?? "up");
        }
Beispiel #15
0
        public static double SkillCap(string name)
        {
            SkillManager manager = SkillManager.GetInstance();

            SkillEntry s = manager.Items.FirstOrDefault(se => se.Skill.Name.ToLower().Contains(name.ToLower()));

            return(s?.Cap ?? 0);
        }
        private void CreateBuffPowerUp(Player player, SkillEntry skillEntry)
        {
            var skill      = skillEntry.Skill;
            var powerUpDef = skill.MagicEffectDef.PowerUpDefinition;

            skillEntry.BuffPowerUp     = this.GetElement(player, powerUpDef.Boost);
            skillEntry.PowerUpDuration = this.GetElement(player, powerUpDef.Duration);
        }
        /// <summary>
        /// Performs the skill.
        /// </summary>
        /// <param name="player">The player.</param>
        /// <param name="target">The target.</param>
        /// <param name="skillId">The skill identifier.</param>
        public void PerformSkill(Player player, IAttackable target, ushort skillId)
        {
            SkillEntry skillEntry = player.SkillList.GetSkill(skillId);
            var        skill      = skillEntry.Skill;

            if (skill.SkillType == SkillType.PassiveBoost)
            {
                Logger.WarnFormat("Skill is a passive boost");
                return;
            }

            if (target == null)
            {
                Logger.WarnFormat("Skill has no target");
                return;
            }

            if (!target.Alive)
            {
                Logger.WarnFormat("Skill target is already dead");
                return;
            }

            var  targetPlayer   = target as Player;
            bool targetIsPlayer = targetPlayer != null; // is it a player?

            // enough mana, ag etc?
            if (!player.TryConsumeForSkill(skill))
            {
                Logger.WarnFormat("Skill not enough resources");
                return;
            }

            player.ForEachObservingPlayer(obs => obs.PlayerView.WorldView.ShowSkillAnimation(player, target, skill), true);
            if (!player.IsInRange(target.X, target.Y, skill.Range + 2))
            {
                Logger.WarnFormat("Skill target is out of range");
                return;
            }

            if (skill.SkillType == SkillType.DirectHit || skill.SkillType == SkillType.CastleSiegeSkill)
            {
                Logger.WarnFormat("Skill perform direct hit or castle siege skill");
                target.AttackBy(player, skillEntry);
            }

            if (skill.SkillType == SkillType.Buff && skill.MagicEffectDef != null && targetIsPlayer)
            {
                // TODO: Summoned Monsters should be able to receive a buff too - add an interface ICanReceiveBuff which contains the MagicEffectList
                if (skillEntry.BuffPowerUp == null)
                {
                    this.CreateBuffPowerUp(player, skillEntry);
                }

                var magicEffect = new MagicEffect(skillEntry.BuffPowerUp, skill.MagicEffectDef, new TimeSpan(0, 0, 0, 0, (int)skillEntry.PowerUpDuration.Value));
                targetPlayer.MagicEffectList.AddEffect(magicEffect);
            }
        }
Beispiel #18
0
 private void UpdateSkillPassivePowerUp(SkillEntry skillEntry)
 {
     if (this.passiveSkillPowerUps.TryGetValue(skillEntry, out IEnumerable <PowerUpWrapper> powerUps))
     {
         this.passiveSkillPowerUps.Remove(skillEntry);
         powerUps.ForEach(p => p.Dispose());
         this.CreatePowerUpWrappers(skillEntry);
     }
 }
Beispiel #19
0
        private void AddItemSkill(Skill skill)
        {
            var skillEntry = new SkillEntry(); // Create by repository manager? Probably not, but I'm not sure...

            skillEntry.Skill = skill;
            skillEntry.Level = 0;
            this.itemSkills.Add(skillEntry);
            this.availableSkills.Add(skill.SkillID.ToUnsigned(), skillEntry);
        }
Beispiel #20
0
 private void ApplySkill(Player player, SkillEntry skillEntry, IAttackable target, Point targetAreaCenter)
 {
     if (target.CheckSkillTargetRestrictions(player, skillEntry.Skill))
     {
         target.AttackBy(player, skillEntry);
         target.ApplyElementalEffects(player, skillEntry);
         player.GameContext.PlugInManager.GetStrategy <short, IAreaSkillPlugIn>(skillEntry.Skill.Number)?.AfterTargetGotAttacked(player, target, skillEntry, targetAreaCenter);
     }
 }
Beispiel #21
0
 public ChangeSkillLock(SkillEntry skill, LockStatus lockStatus)
 {
     _writer = new PacketWriter(6);
     _writer.Write((byte)0x3A);
     _writer.Write((short)6);
     _writer.Write((byte)0);
     _writer.Write((byte)skill.Skill.ID);
     _writer.Write((byte)lockStatus);
 }
Beispiel #22
0
        /// <summary>
        /// Performs the skill.
        /// </summary>
        /// <param name="player">The player.</param>
        /// <param name="target">The target.</param>
        /// <param name="skillId">The skill identifier.</param>
        public void PerformSkill(Player player, IAttackable target, ushort skillId)
        {
            using var loggerScope = player.Logger.BeginScope(this.GetType());
            SkillEntry skillEntry = player.SkillList.GetSkill(skillId);
            var        skill      = skillEntry.Skill;

            if (skill.SkillType == SkillType.PassiveBoost)
            {
                return;
            }

            if (target is null)
            {
                return;
            }

            if (!target.IsActive())
            {
                return;
            }

            if (!target.CheckSkillTargetRestrictions(player, skill))
            {
                return;
            }

            if (!player.IsInRange(target.Position, skill.Range + 2))
            {
                // target position might be out of sync so we send the current coordinates to the client again.
                if (!(target is ISupportWalk walker && walker.IsWalking))
                {
                    player.ViewPlugIns.GetPlugIn <IObjectMovedPlugIn>()?.ObjectMoved(target, MoveType.Instant);
                }

                return;
            }

            // enough mana, ag etc?
            if (!player.TryConsumeForSkill(skill))
            {
                return;
            }

            player.ForEachWorldObserver(obs => obs.ViewPlugIns.GetPlugIn <IShowSkillAnimationPlugIn>()?.ShowSkillAnimation(player, target, skill), true);
            if (skill.MovesToTarget)
            {
                player.Move(target.Position);
            }

            if (skill.MovesTarget)
            {
                target.MoveRandomly();
            }

            this.ApplySkill(player, target, skillEntry);
        }
Beispiel #23
0
        public static void Start()
        {
            ConsoleUtils.Write(ConsoleMsgType.Status, "Loading Skill Database...\n");

            DB = new Dictionary <int, SkillEntry>();
            Database        db     = new Database(Server.GameDbConString);
            MySqlDataReader reader =
                db.ReaderQuery(
                    "SELECT `skill_id`, `name`, `max_level` " +
                    "FROM `skill_db`", null, null
                    );

            while (reader.Read())
            {
                SkillEntry skill = new SkillEntry();

                int skillId = (int)reader["skill_id"];

                skill.MaxLevel     = (byte)reader["max_level"];
                skill.RequiredJp   = new int[skill.MaxLevel + 1];
                skill.CooldownTime = 1000;

                Database        db2     = new Database(Server.GameDbConString);
                MySqlDataReader reader2 =
                    db2.ReaderQuery(
                        "SELECT `skill_id`, `level`, `jp` " +
                        "FROM `skill_jp_db` " +
                        "WHERE `skill_id`=@sid",
                        new string[] { "sid" },
                        new object[] { skillId }
                        );

                while (reader2.Read())
                {
                    byte lv = (byte)reader2["level"];
                    int  jp = (int)reader2["jp"];

                    if (lv > skill.MaxLevel)
                    {
                        ConsoleUtils.Write(
                            ConsoleMsgType.Warning,
                            "Defined JP cost for skill {1} level {2}, that's higher than the max level ({3})\r\n",
                            skillId, lv, skill.MaxLevel
                            );

                        continue;
                    }

                    skill.RequiredJp[lv] = jp;
                }

                DB.Add(skillId, skill);
            }

            ConsoleUtils.Write(ConsoleMsgType.Status, "Skill Database Loaded.\n");
        }
 /// <inheritdoc />
 public void AfterTargetGotAttacked(IAttacker attacker, IAttackable target, SkillEntry skillEntry, Point targetAreaCenter)
 {
     if (target is Player targetPlayer &&
         Rand.NextRandomBool(25) &&
         targetPlayer.Inventory.EquippedItems.SelectRandom() is Item randomItem)
     {
         randomItem.Durability /= 2;
         targetPlayer.ViewPlugIns.GetPlugIn <IItemDurabilityChangedPlugIn>()?.ItemDurabilityChanged(randomItem, false);
     }
 }
        private void AddMasterPointToLearnedSkill(Player player, SkillEntry learnedSkill)
        {
            if (player.SelectedCharacter.MasterLevelUpPoints > 0 && learnedSkill.Level < MaximumSkillLevel)
            {
                learnedSkill.Level++;
                player.SelectedCharacter.MasterLevelUpPoints--;

                // TODO: Send response, see protocol documentation
            }
        }
Beispiel #26
0
        private SkillEntry CreateSkillEntry(ushort skillId)
        {
            var skillEntry = new SkillEntry {
                Skill = new OpenMU.DataModel.Configuration.Skill {
                    SkillID = skillId.ToSigned()
                }
            };

            return(skillEntry);
        }
Beispiel #27
0
        public static void ChangeSkillLock(SkillEntry skill, LockStatus lockStatus, bool requery = true)
        {
            Engine.SendPacketToServer(new ChangeSkillLock(skill, lockStatus));

            if (requery)
            {
                Engine.SendPacketToServer(
                    new MobileQuery(Engine.Player?.Serial ?? 0, MobileQueryType.SkillsRequest));
            }
        }
Beispiel #28
0
        private static int GetDamage(this SkillEntry skill)
        {
            var result = skill.Skill.AttackDamage;

            if (skill.Skill.MasterDefinition != null)
            {
                result += (int)skill.CalculateValue();
            }

            return(result);
        }
Beispiel #29
0
        /// <summary>
        /// Applies the magic effect of the players skill to the target.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <param name="player">The player.</param>
        /// <param name="skillEntry">The skill entry.</param>
        public static void ApplyMagicEffect(this IAttackable target, Player player, SkillEntry skillEntry)
        {
            if (skillEntry.BuffPowerUp == null)
            {
                player.CreateMagicEffectPowerUp(skillEntry);
            }

            var magicEffect = new MagicEffect(skillEntry.BuffPowerUp, skillEntry.Skill.MagicEffectDef, TimeSpan.FromSeconds(skillEntry.PowerUpDuration.Value));

            target.MagicEffectList.AddEffect(magicEffect);
        }
Beispiel #30
0
        /// <summary>
        /// Attacks the target by the player with the specified skill.
        /// </summary>
        /// <param name="player">The player who is performing the skill.</param>
        /// <param name="target">The target.</param>
        /// <param name="skill">The skill.</param>
        public void AttackTarget(Player player, IAttackable target, SkillEntry skill)
        {
            if (skill.Skill.SkillType != SkillType.AreaSkillExplicitHits ||
                target == null ||
                !target.Alive)
            {
                return;
            }

            target.AttackBy(player, skill);
        }