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); }
/// <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); }
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(); } }
/// <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); }
public ISkill LoseSkill(ISkill skill) { if (!Skills.Contains(skill)) { return(null); } Skills.Remove(skill); OnPropertyChanged("Skills"); skill.HeroTag = null; skill.Owner = null; return(skill); }
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); }
/// <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); }
/// <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}"); }
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); }
/// <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); }
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); }
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"); }
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; } }
public bool HasSkill(Skill skill) { return(Skills.Contains(skill)); }
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"); }