public bool FindSkillForRange(double distance, out uint skill) { for (int i = 0; i < skillinfo.Count; i++) { Factory.Spells.Info info = skillinfo[i]; if (distance > info.minimumrange && distance < info.maximumrange) { if (random.Next(0, 10000) < probabillity[i]) { skill = info.skillid; return(true); } } } skill = 0; return(false); }
/// <summary> /// Occurs when canceling a casted skill /// </summary> /// <param name="cpkt"></param> private void CM_SKILLCASTCANCEL(CMSG_SKILLCASTCANCEL cpkt) { lock (this.character.cooldowncollection) { try { uint skill = cpkt.SkillID; byte skilltype = cpkt.SkillType; Factory.Spells.Info info = null; if (Singleton.SpellManager.TryGetSpell(skill, out info)) { this.character._lastcastedskill = 0; this.character._lastcastedtick = Environment.TickCount; this.character.cooldowncollection.Add(skill, (int)info.delay); this.character.cooldowncollection.Update(); } //Notify all actors that cast is in progress Regiontree tree = this.character.currentzone.Regiontree; foreach (Character regionObject in tree.SearchActors(this.character, SearchFlags.Characters)) { if (!Point.IsInSightRangeByRadius(this.character.Position, regionObject.Position) || regionObject.client.isloaded == false) { continue; } SMSG_SKILLCASTCANCEL spkt = new SMSG_SKILLCASTCANCEL(); spkt.SkillID = skill; spkt.SourceActor = this.character.id; spkt.SkillType = skilltype; spkt.SessionId = this.character.id; regionObject.client.Send((byte[])spkt); } } catch (Exception) { Trace.TraceError("Exception processing the skill cancel"); } } }
/// <summary> /// Occurs when casting a skill /// </summary> /// <param name="cpkt"></param> private void CM_SKILLCAST(CMSG_SKILLCAST cpkt) { lock (this.character.cooldowncollection) { try { MapObject target; uint skill = cpkt.SkillID; byte skilltype = cpkt.SkillType; Factory.Spells.Info info = null; bool cancast = Regiontree.TryFind(cpkt.TargetActor, this.character, out target) && Singleton.SpellManager.TryGetSpell(skill, out info) && this.character._lastcastedskill == 0 && ((long)((uint)Environment.TickCount) - this.character._lastcastedtick) > 0 && (info.delay == 0 || !this.character.cooldowncollection.IsCoolDown(skill)) && (info.maximumrange == 0 || info.IsInRangeOf((int)(Vector.GetDistance2D(this.character.Position, target.Position)))) && info.requiredWeapons[this.character.weapons.GetCurrentWeaponType()] == 1 && this.character.jlvl >= info.requiredJobs[this.character.job - 1] && this.character.Status.CurrentLp >= (info.requiredlp == 6?1:info.requiredlp) && info.IsTarget(this.character, target); if (cancast) { //Set anti-hack variables this.character._lastcastedskill = skill; this.character._lastcastedtick = (Environment.TickCount + (int)info.casttime); this.character.cooldowncollection.Update(); //Notify all actors that cast is in progress Regiontree tree = this.character.currentzone.Regiontree; foreach (Character regionObject in tree.SearchActors(this.character, SearchFlags.Characters)) { if (!Point.IsInSightRangeByRadius(this.character.Position, regionObject.Position) || regionObject.client.isloaded == false) { continue; } SMSG_SKILLCAST spkt = new SMSG_SKILLCAST(); spkt.SourceActor = this.character.id; spkt.TargetActor = target.id; spkt.SkillID = skill; spkt.SkillType = skilltype; spkt.SessionId = regionObject.id; regionObject.client.Send((byte[])spkt); } } else { /*SMSG_SKILLCASTCANCEL spkt = new SMSG_SKILLCASTCANCEL(); * spkt.SkillID = cpkt.SkillID; * spkt.SourceActor = this.character.id; * spkt.SkillType = cpkt.SkillType; * this.Send((byte[])spkt);*/ //Skill failed SMSG_OFFENSIVESKILLFAILED spkt = new SMSG_OFFENSIVESKILLFAILED(); spkt.SkillID = cpkt.SkillID; spkt.SkillType = cpkt.SkillType; spkt.SourceActor = this.character.id; spkt.SessionId = this.character.id; this.Send((byte[])spkt); } } catch (Exception) { Trace.TraceError("Exception processing the skill cast"); } } }