Пример #1
0
        public void Attack(ISkill skill)
        {
            if (!Skills.Contains(skill))
            {
                Logger.Warn($"Can't found skill {skill.SkillKey}");
                return;
            }

            if (skill.IsOnCooldown)
            {
                Logger.Trace("Skill is in cooldown");
                return;
            }

            if (skill.Target == SkillTarget.Target)
            {
                Logger.Warn($"Invalid target {skill.CastId} {skill.Category} {skill.Target} {skill.HitType}");
                return;
            }

            Logger.Debug($"Using skill with id {skill.SkillKey} on self");

            Client.SendPacket($"u_s {skill.CastId} {EntityType.AsString()} {Id}");

            Thread.Sleep(skill.CastTime * 200);
        }
Пример #2
0
        /// <summary>
        ///     Use a skill on target (walk to target if not in range)
        ///     Skill wont be used if
        ///     - Skill is not in your skills
        ///     - Skill is on cooldown
        ///     - If this skill has no target
        /// </summary>
        /// <param name="skill">Skill to use</param>
        /// <param name="target">Target to hit with skill</param>
        public async Task UseSkillOn(Skill skill, LivingEntity target)
        {
            if (!Skills.Contains(skill))
            {
                _logger.Info("Attack cancelled : Skill is not in skill list");
                return;
            }

            if (skill.IsOnCooldown)
            {
                return;
            }

            if (skill.TargetType == TargetType.SELF)
            {
                await UseSkill(skill).ConfigureAwait(false);

                return;
            }

            if (target.Equals(this))
            {
                return;
            }

            if (skill.TargetType == TargetType.NO_TARGET)
            {
                return;
            }

            await WalkInRange(target.Position, skill.Range).ConfigureAwait(false);

            Client.SendPacket($"u_s {skill.CastId} {(int)target.EntityType} {target.Id}");
            await Task.Delay(skill.CastTime * 200).ConfigureAwait(false);
        }
Пример #3
0
        private void LookForJob()
        {
            if (JobQueue.Peek() != null && Skills.Contains(JobQueue.Peek().JobType))
            {
                _job = JobQueue.Dequeue();
            }

            // No job
            if (_job == null)
            {
                return;
            }

            DestinationTile = _job.Tile;

            _job.JobStopped += OnJobStopped;

            _aStar = new AStar(CurrentTile, DestinationTile);

            // The first tile can be ignored, because that's where the minion currently is in
            _nextTile = _aStar.Pop();

            // No path was found
            if (_aStar.Length() == 0)
            {
                AbandonJob();
            }
        }
Пример #4
0
        /// <summary>
        /// Attack selected entity with selected skill
        /// </summary>
        /// <param name="entity">Entity who is targeted by your skill</param>
        /// <param name="skill">Skill used</param>
        public void Attack(LivingEntity entity, Skill skill)
        {
            if (!Skills.Contains(skill))
            {
                Log.Warning("Trying to use a skill not present in character skills");
                return;
            }

            if (CantAttack)
            {
                return;
            }

            if (skill.IsOnCooldown())
            {
                Log.Warning("Attack on cooldown");
                return;
            }

            if (skill.MpCost > Mp)
            {
                Log.Warning("Mp cost to high");
                return;
            }

            switch (skill.Target)
            {
            case SkillTarget.Self:
                if (!entity.Equals(this))
                {
                    Log.Warning("Trying to use a self skill on a target");
                    return;
                }
                break;

            case SkillTarget.Target:
                if (entity.Equals(this))
                {
                    Log.Warning("Trying to use skill on self but skill need a target.");
                    return;
                }
                break;

            case SkillTarget.NoTarget:
                Attack(skill, entity.Position);
                return;
            }

            if (!this.IsInSkillRange(entity.Position, skill) && !entity.Equals(this))
            {
                Log.Warning($"Trying to attack entity at {entity.Position} from {Position} but it's out of range");
                return;
            }

            skill.LastUse = DateTime.Now.AddMilliseconds(skill.CastTime * 100);

            Session.SendPacket($"u_s {skill.CastId} {(int)entity.EntityType} {entity.Id}");
            Log.Information($"Attacking {entity.Name} with skill {skill.Name}");
        }
 public bool TryAddSkill(ISkill skill)
 {
     if (!Skills.Contains(skill))
     {
         Skills.Add(skill);
         return(true);
     }
     Debug.Log("Spell allready exists");
     return(false);
 }
Пример #6
0
 public ISkill LoseSkill(ISkill skill)
 {
     if (!Skills.Contains(skill))
     {
         return(null);
     }
     Skills.Remove(skill);
     OnPropertyChanged("Skills");
     skill.HeroTag = null;
     skill.Owner   = null;
     return(skill);
 }
Пример #7
0
        private int GetSkillModifier(Ability ability, Skill skill)
        {
            var proficiencyBonus = 0;

            if (Skills.Contains(skill))
            {
                proficiencyBonus = Proficiency;
            }
            if (Expertise.Contains(skill))
            {
                proficiencyBonus = Proficiency * 2;
            }

            return(AbilityScores[ability].Modifier + proficiencyBonus);
        }
Пример #8
0
        /// <summary>
        ///     Use a skill on yourself
        ///     Skill wont be used if
        ///     - Skill is not in your skills
        ///     - Skill is on cooldown
        ///     - If this skill can't target you
        /// </summary>
        /// <param name="skill">Skill to use</param>
        public async Task UseSkill(Skill skill)
        {
            if (!Skills.Contains(skill))
            {
                _logger.Info("Attack cancelled : Skill is not in skill list");
                return;
            }

            if (skill.IsOnCooldown)
            {
                return;
            }

            if (skill.TargetType == TargetType.TARGET)
            {
                return;
            }

            Client.SendPacket($"u_s {skill.CastId} {(int)EntityType} {Id}");
            await Task.Delay(skill.CastTime * 200).ConfigureAwait(false);
        }
Пример #9
0
        /// <summary>
        /// Attack at defined position (used by skill without target)
        /// </summary>
        /// <param name="skill">Skill to cast</param>
        /// <param name="position">Position where you want to hit</param>
        public void Attack(Skill skill, Position position)
        {
            if (!Skills.Contains(skill))
            {
                Log.Warning("Trying to use a skill not present in character skills");
                return;
            }

            if (CantAttack)
            {
                return;
            }

            if (skill.IsOnCooldown())
            {
                return;
            }

            if (skill.MpCost > Mp)
            {
                return;
            }

            if (skill.Target != SkillTarget.NoTarget)
            {
                Log.Warning($"Trying to use a skill at defined position when target should be {skill.Target}");
                return;
            }

            if (!this.IsInSkillRange(position, skill))
            {
                Log.Warning($"Trying to attack at {position} from {Position} but it's out of range");
                return;
            }

            skill.LastUse = DateTime.Now.AddMilliseconds(skill.CastTime * 100);

            Session.SendPacket($"u_as {skill.CastId} {position.X} {position.Y}");
            Log.Debug($"Use skill {skill.CastId} at {position}");
        }
Пример #10
0
        public void Attack(ISkill skill, ILivingEntity entity)
        {
            Logger.Trace($"Trying to attack {entity.Id}");
            if (!Skills.Contains(skill))
            {
                Logger.Warn("Can't found skill in Skills");
                return;
            }

            if (skill.IsOnCooldown)
            {
                Logger.Trace("Skill is in cooldown");
                return;
            }

            if (skill.Target == SkillTarget.Self)
            {
                Attack(skill);
                return;
            }

            if (entity.Equals(this))
            {
                Logger.Warn($"Can't target self ({Name}) (Skill: {skill.CastId} {skill.Target} {skill.HitType})");
                return;
            }

            if (skill.Target == SkillTarget.NoTarget)
            {
                Logger.Warn("Incorrect target type");
                return;
            }

            WalkInRange(entity.Position, skill.Range);
            Logger.Debug($"Attacking {entity.EntityType} with id {entity.Id} using {skill.SkillKey}");

            Client.SendPacket($"u_s {skill.CastId} {entity.EntityType.AsString()} {entity.Id}");
            Thread.Sleep(skill.CastTime * 200);
        }
Пример #11
0
        /// <summary>
        ///     Use a skill at position (walk to position range if not in range)
        ///     Skill wont be used if
        ///     - Skill is not in your skills
        ///     - Skill is on cooldown
        ///     - Skill need a target
        /// </summary>
        /// <param name="skill">Skill to use</param>
        /// <param name="position">Position where you want to use the skill</param>
        public async Task UseSkillAt(Skill skill, Position position)
        {
            if (!Skills.Contains(skill))
            {
                return;
            }

            if (skill.IsOnCooldown)
            {
                return;
            }

            if (skill.TargetType != TargetType.NO_TARGET)
            {
                return;
            }

            await WalkInRange(position, skill.Range).ConfigureAwait(false);

            Client.SendPacket($"u_as {skill.CastId} {position.X} {position.Y}");
            await Task.Delay(skill.CastTime * 100).ConfigureAwait(false);
        }
Пример #12
0
 public ActionType?ChoseBestAttackMethod()
 {
     if (Skills.Contains(SkillType.Fireball))
     {
         int  remainingFrostBoltTicks = RemainingCooldownTicksByAction[(int)ActionType.Fireball];
         bool enoghMana = _game.FireballManacost < Mana;
         if (remainingFrostBoltTicks == 0 && enoghMana)
         {
             return(ActionType.Fireball);
         }
     }
     if (Skills.Contains(SkillType.FrostBolt))
     {
         int  remainingFrostBoltTicks = RemainingCooldownTicksByAction[(int)ActionType.FrostBolt];
         bool enoghMana = _game.FrostBoltManacost < Mana;
         if (remainingFrostBoltTicks == 0 && enoghMana)
         {
             return(ActionType.FrostBolt);
         }
     }
     return(ActionType.MagicMissile);
 }
Пример #13
0
        internal void Load(XmlNode skillNode, bool legacy = false)
        {
            if (skillNode == null)
            {
                return;
            }
            Timekeeper.Start("load_char_skills");

            if (!legacy)
            {
                Timekeeper.Start("load_char_skills_groups");
                List <SkillGroup> loadingSkillGroups = new List <SkillGroup>();
                foreach (XmlNode node in skillNode.SelectNodes("groups/group"))
                {
                    SkillGroup skillgroup = SkillGroup.Load(_character, node);
                    if (skillgroup != null)
                    {
                        loadingSkillGroups.Add(skillgroup);
                    }
                }
                loadingSkillGroups.Sort((i1, i2) => String.Compare(i2.DisplayName, i1.DisplayName, StringComparison.Ordinal));
                foreach (SkillGroup skillgroup in loadingSkillGroups)
                {
                    SkillGroups.Add(skillgroup);
                }
                Timekeeper.Finish("load_char_skills_groups");

                Timekeeper.Start("load_char_skills_normal");
                //Load skills. Because sorting a BindingList is complicated we use a temporery normal list
                List <Skill> loadingSkills = new List <Skill>();
                foreach (XmlNode node in skillNode.SelectNodes("skills/skill"))
                {
                    Skill skill = Skill.Load(_character, node);
                    if (skill != null)
                    {
                        loadingSkills.Add(skill);
                    }
                }
                loadingSkills.Sort(CompareSkills);


                foreach (Skill skill in loadingSkills)
                {
                    _skills.Add(skill);
                }
                Timekeeper.Finish("load_char_skills_normal");

                Timekeeper.Start("load_char_skills_kno");
                foreach (XmlNode node in skillNode.SelectNodes("knoskills/skill"))
                {
                    KnowledgeSkill skill = Skill.Load(_character, node) as KnowledgeSkill;
                    if (skill != null)
                    {
                        KnowledgeSkills.Add(skill);
                    }
                }
                Timekeeper.Finish("load_char_skills_kno");

                Timekeeper.Start("load_char_knowsoft_buffer");
                // Knowsoft Buffer.
                foreach (XmlNode objXmlSkill in skillNode.SelectNodes("skilljackknowledgeskills/skill"))
                {
                    string strName = string.Empty;
                    if (objXmlSkill.TryGetStringFieldQuickly("name", ref strName))
                    {
                        KnowsoftSkills.Add(new KnowledgeSkill(_character, strName));
                    }
                }
                Timekeeper.Finish("load_char_knowsoft_buffer");
            }
            else
            {
                List <Skill> tempSkillList = new List <Skill>();
                foreach (XmlNode node in skillNode.SelectNodes("skills/skill"))
                {
                    Skill skill = Skill.LegacyLoad(_character, node);
                    if (skill != null)
                    {
                        tempSkillList.Add(skill);
                    }
                }

                List <Skill> unsoredSkills = new List <Skill>();

                //Variable/Anon method as to not clutter anywhere else. Not sure if clever or stupid
                Predicate <Skill> oldSkillFilter = skill =>
                {
                    if (skill.Rating > 0)
                    {
                        return(true);
                    }

                    if (skill.SkillCategory == "Resonance Active" && !_character.RESEnabled)
                    {
                        return(false);
                    }

                    //This could be more fine grained, but frankly i don't care
                    if (skill.SkillCategory == "Magical Active" && !_character.MAGEnabled)
                    {
                        return(false);
                    }

                    return(true);
                };

                foreach (Skill skill in tempSkillList)
                {
                    KnowledgeSkill knoSkill = skill as KnowledgeSkill;
                    if (knoSkill != null)
                    {
                        KnowledgeSkills.Add(knoSkill);
                    }
                    else if (oldSkillFilter(skill))
                    {
                        unsoredSkills.Add(skill);
                    }
                }

                unsoredSkills.Sort(CompareSkills);

                unsoredSkills.ForEach(x => _skills.Add(x));

                UpdateUndoList(skillNode);
            }

            //This might give subtle bugs in the future,
            //but right now it needs to be run once when upgrading or it might crash.
            //As some didn't they crashed on loading skills.
            //After this have run, it won't (for the crash i'm aware)
            //TODO: Move it to the other side of the if someday?

            //remove skillgroups whose skills did not make the final cut
            for (var i = SkillGroups.Count - 1; i >= 0; i--)
            {
                if (!SkillGroups[i].GetEnumerable().Any(x => Skills.Contains(x)))
                {
                    SkillGroups.RemoveAt(i);
                    i--;
                }
            }

            //Workaround for probably breaking compability between earlier beta builds
            if (skillNode["skillptsmax"] == null)
            {
                skillNode = skillNode.OwnerDocument["character"];
            }

            int intTmp = 0;

            if (skillNode.TryGetInt32FieldQuickly("skillptsmax", ref intTmp))
            {
                SkillPointsMaximum = intTmp;
            }
            if (skillNode.TryGetInt32FieldQuickly("skillgrpsmax", ref intTmp))
            {
                SkillGroupPointsMaximum = intTmp;
            }
            skillNode.TryGetBoolFieldQuickly("uneducated", ref _blnUneducated);
            skillNode.TryGetBoolFieldQuickly("uncouth", ref _blnUncouth);
            skillNode.TryGetBoolFieldQuickly("schoolofhardknocks", ref _blnSchoolOfHardKnocks);
            skillNode.TryGetBoolFieldQuickly("collegeeducation", ref _blnCollegeEducation);
            skillNode.TryGetBoolFieldQuickly("jackofalltrades", ref _blnJackOfAllTrades);
            skillNode.TryGetBoolFieldQuickly("techschool", ref _blnTechSchool);
            skillNode.TryGetBoolFieldQuickly("linguist", ref _blnLinguist);

            Timekeeper.Finish("load_char_skills");
        }
Пример #14
0
 private void GetBackgroundSkills()
 {
     if (Skills.Contains("Acrobatics"))
     {
         Acrobatics = true;
     }
     if (Skills.Contains("Animal Handling"))
     {
         AnimalHandling = true;
     }
     if (Skills.Contains("Arcaba"))
     {
         Arcana = true;
     }
     if (Skills.Contains("Athletics"))
     {
         Athletics = true;
     }
     if (Skills.Contains("Deception"))
     {
         Deception = true;
     }
     if (Skills.Contains("History"))
     {
         History = true;
     }
     if (Skills.Contains("Insight"))
     {
         Insight = true;
     }
     if (Skills.Contains("Intimidation"))
     {
         Intimidation = true;
     }
     if (Skills.Contains("Investigation"))
     {
         Investigation = true;
     }
     if (Skills.Contains("Medicine"))
     {
         Medicine = true;
     }
     if (Skills.Contains("Nature"))
     {
         Nature = true;
     }
     if (Skills.Contains("Perception"))
     {
         Perception = true;
     }
     if (Skills.Contains("Performance"))
     {
         Performance = true;
     }
     if (Skills.Contains("Persuasion"))
     {
         Persuasion = true;
     }
     if (Skills.Contains("Religion"))
     {
         Religion = true;
     }
     if (Skills.Contains("Sleight of Hand"))
     {
         SleightOfHand = true;
     }
     if (Skills.Contains("Stealth"))
     {
         Stealth = true;
     }
     if (Skills.Contains("Survival"))
     {
         Survival = true;
     }
 }
Пример #15
0
 public bool HasSkill(Skill skill)
 {
     return(Skills.Contains(skill));
 }
Пример #16
0
        internal void Load(XmlNode skillNode, bool legacy = false)
        {
            Timekeeper.Start("load_char_skills");

            if (!legacy)
            {
                Timekeeper.Start("load_char_skills_groups");
                (from XmlNode node in skillNode.SelectNodes("groups/group") let @group = SkillGroup.Load(_character, node) where @group != null orderby @group.DisplayName descending select @group).ForEach(x => SkillGroups.Add(x));

                Timekeeper.Finish("load_char_skills_groups");

                Timekeeper.Start("load_char_skills_normal");
                //Load skills. Because sorting a BindingList is complicated we use a temporery normal list
                List <Skill> loadingSkills = (from XmlNode node in skillNode.SelectNodes("skills/skill") let skill = Skill.Load(_character, node) where skill != null select skill).ToList();

                loadingSkills.Sort(CompareSkills);


                foreach (Skill skill in loadingSkills)
                {
                    _skills.Add(skill);
                }
                Timekeeper.Finish("load_char_skills_normal");

                Timekeeper.Start("load_char_skills_kno");
                List <KnowledgeSkill> knoSkills = (from XmlNode node in skillNode.SelectNodes("knoskills/skill") let skill = (KnowledgeSkill)Skill.Load(_character, node) where skill != null select skill).ToList();


                foreach (KnowledgeSkill skill in knoSkills)
                {
                    KnowledgeSkills.Add(skill);
                }
                Timekeeper.Finish("load_char_skills_kno");

                Timekeeper.Start("load_char_knowsoft_buffer");
                // Knowsoft Buffer.
                XmlNodeList objXmlKnowsoftBuffer = skillNode.SelectNodes("skilljackknowledgeskills/skill");
                foreach (XmlNode objXmlSkill in objXmlKnowsoftBuffer)
                {
                    string strName = objXmlSkill["name"].InnerText;
                    KnowsoftSkills.Add(new KnowledgeSkill(_character, strName));
                }
                Timekeeper.Finish("load_char_knowsoft_buffer");
            }
            else
            {
                XmlNodeList oldskills = skillNode.SelectNodes("skills/skill");

                List <Skill> tempoerySkillList = (from XmlNode node in oldskills let skill = Skill.LegacyLoad(_character, node) where skill != null select skill).ToList();

                List <Skill> unsoredSkills = new List <Skill>();

                //Variable/Anon method as to not clutter anywhere else. Not sure if clever or stupid
                Predicate <Skill> oldSkillFilter = skill =>
                {
                    if (skill.Rating > 0)
                    {
                        return(true);
                    }

                    if (skill.SkillCategory == "Resonance Active" && !_character.RESEnabled)
                    {
                        return(false);
                    }

                    //This could be more fine grained, but frankly i don't care
                    if (skill.SkillCategory == "Magical Active" && !_character.MAGEnabled)
                    {
                        return(false);
                    }


                    return(true);
                };

                foreach (Skill skill in tempoerySkillList)
                {
                    KnowledgeSkill knoSkill = skill as KnowledgeSkill;
                    if (knoSkill != null)
                    {
                        KnowledgeSkills.Add(knoSkill);
                    }
                    else if (oldSkillFilter(skill))
                    {
                        unsoredSkills.Add(skill);
                    }
                }

                unsoredSkills.Sort(CompareSkills);

                unsoredSkills.ForEach(x => _skills.Add(x));

                UpdateUndoList(skillNode);

                //remove skillgroups whose skills did not make the final cut
                for (var i = SkillGroups.Count - 1; i >= 0; i--)
                {
                    if (SkillGroups[i].GetEnumerable().Any(x => Skills.Contains(x)))
                    {
                        continue;
                    }

                    SkillGroups.RemoveAt(i);
                }
            }

            //Workaround for probably breaking compability between earlier beta builds
            if (skillNode["skillptsmax"] == null)
            {
                skillNode = skillNode.OwnerDocument["character"];
            }

            SkillPointsMaximum      = Convert.ToInt32(skillNode["skillptsmax"].InnerText);
            SkillGroupPointsMaximum = Convert.ToInt32(skillNode["skillgrpsmax"].InnerText);
            skillNode.TryGetField("uneducated", out _blnUneducated);
            skillNode.TryGetField("uncouth", out _blnUncouth);
            skillNode.TryGetField("schoolofhardknocks", out _blnSchoolOfHardKnocks);
            skillNode.TryGetField("collegeeducation", out _blnCollegeEducation);
            skillNode.TryGetField("jackofalltrades", out _blnJackOfAllTrades);
            skillNode.TryGetField("techschool", out _blnTechSchool);
            skillNode.TryGetField("linguist", out _blnLinguist);

            Timekeeper.Finish("load_char_skills");
        }