/// <summary> /// Occurs when toggling between skills (aka stances) /// </summary> /// <param name="cpkt"></param> private void CM_SKILLTOGGLE(CMSG_SKILLTOGLE cpkt) { lock (this.character.cooldowncollection) { try { uint skillid = cpkt.SkillID; byte skilltype = cpkt.SkillType; SkillToggleEventArgs argument = null; bool cancast = SkillToggleEventArgs.Create(skillid, this.character, this.character, out argument) && argument.SpellInfo.casttime > -1 && (argument.SpellInfo.casttime == 0 || this.character._lastcastedskill == skillid) && Environment.TickCount - this.character._lastcastedtick > 0 && (argument.SpellInfo.delay == 0 || !this.character.cooldowncollection.IsCoolDown(skillid)) && (argument.SpellInfo.maximumrange == 0 || argument.SpellInfo.IsInRangeOf((int)(Vector.GetDistance2D(this.character.Position, this.character.Position)))) && argument.SpellInfo.requiredWeapons[this.character.weapons.GetCurrentWeaponType()] == 1 && this.character.jlvl >= argument.SpellInfo.requiredJobs[this.character.job - 1] && argument.SpellInfo.IsTarget(this.character, this.character); if (cancast && argument.Use()) { int delay = (int)(argument.SpellInfo.delay - ((character.stats.Dexterity * 2) + (character.stats.Concentration * 2))); if (delay > 0) { this.character.cooldowncollection.Add(skillid, delay); } this.character.cooldowncollection.Update(); SMSG_SKILLTOGLE spkt2 = new SMSG_SKILLTOGLE(); spkt2.SkillID = cpkt.SkillID; spkt2.SkillType = cpkt.SkillType; spkt2.SessionId = this.character.id; spkt2.Toggle = argument.Failed; this.Send((byte[])spkt2); if (character._status.Updates > 0) { LifeCycle.Update(character); character._status.Updates = 0; } Regiontree tree = this.character.currentzone.Regiontree; foreach (Character regionObject in tree.SearchActors(this.character, SearchFlags.Characters)) { SMSG_OFFENSIVESKILL spkt = new SMSG_OFFENSIVESKILL(); spkt.Damage = argument.Damage; spkt.SourceActor = this.character.id; spkt.TargetActor = this.character.id; spkt.SessionId = regionObject.id; spkt.SkillID = cpkt.SkillID; regionObject.client.Send((byte[])spkt); } } else { Console.WriteLine("Stance failed"); SMSG_SKILLTOGLE spkt2 = new SMSG_SKILLTOGLE(); spkt2.SkillID = cpkt.SkillID; spkt2.SkillType = cpkt.SkillType; spkt2.SessionId = this.character.id; spkt2.Toggle = true; this.Send((byte[])spkt2); } } catch (Exception e) { Trace.TraceError("Exception processing the skill {0}", e.ToString()); //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); } } }
/// <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"); } } }
/// <summary> /// Occurs when using an offensive skill /// </summary> /// <param name="cpkt"></param> private void CM_USEOFFENSIVESKILL(CMSG_OFFENSIVESKILL cpkt) { lock (this.character.cooldowncollection) { try { MapObject target; uint skillid = cpkt.SkillID; byte skilltype = cpkt.SkillType; SkillUsageEventArgs argument = null; bool cancast = Regiontree.TryFind(cpkt.TargetActor, this.character, out target) && SkillUsageEventArgs.Create(skillid, this.character, target, out argument) && argument.SpellInfo.casttime > -1 && (argument.SpellInfo.casttime == 0 || this.character._lastcastedskill == skillid) && ((long)((uint)Environment.TickCount) - this.character._lastcastedtick) > 0 && (argument.SpellInfo.delay == 0 || !this.character.cooldowncollection.IsCoolDown(skillid)) && (argument.SpellInfo.maximumrange == 0 || argument.SpellInfo.IsInRangeOf((int)(Vector.GetDistance2D(this.character.Position, target.Position)))) && argument.SpellInfo.requiredWeapons[this.character.weapons.GetCurrentWeaponType()] == 1 && this.character.jlvl >= argument.SpellInfo.requiredJobs[this.character.job - 1] && this.character.Status.CurrentLp >= (argument.SpellInfo.requiredlp == 6?1:argument.SpellInfo.requiredlp) && argument.SpellInfo.IsTarget(this.character, target); if (cancast && argument.Use()) { //Clear casted skill this.character._lastcastedskill = 0; this.character._lastcastedtick = Environment.TickCount; //Set cooldown timer int delay = (int)(argument.SpellInfo.delay - ((character.stats.Dexterity * 2) + (character.stats.Concentration * 2))); if (delay > 0) { this.character.cooldowncollection.Add(skillid, delay); } this.character.cooldowncollection.Update(); //Use required sp points if (argument.SpellInfo.SP > -1) { this.character.LASTSP_TICK = Environment.TickCount; this.character.SP = (ushort)(this.character.SP - argument.SpellInfo.SP); } //Set sp to 0 else if (argument.SpellInfo.SP == -1) { this.character.LASTSP_TICK = Environment.TickCount; this.character.SP = 0; } //Use required lp points if (argument.SpellInfo.requiredlp == 6) { this.character._status.CurrentLp = 0; this.character._status.Updates |= 1; } else if (argument.SpellInfo.requiredlp > 0) { this.character._status.CurrentLp -= argument.SpellInfo.requiredlp; this.character._status.Updates |= 1; } //Add intergrated durabillity checks if (argument.CanCheckWeaponDurabillity) { Common.Durabillity.DoWeapon(this.character); } //Skill sucess Predicate <Character> SendToCharacter = delegate(Character forwardTarget) { //Skill sucess SMSG_OFFENSIVESKILL spkt = new SMSG_OFFENSIVESKILL(); spkt.SkillID = cpkt.SkillID; spkt.SkillType = cpkt.SkillType; spkt.TargetActor = cpkt.TargetActor; spkt.SourceActor = this.character.id; spkt.IsCritical = (forwardTarget.id == this.character.id || forwardTarget.id == target.id) ? (byte)argument.Result : (byte)7; spkt.Damage = argument.Damage; spkt.SessionId = forwardTarget.id; forwardTarget.client.Send((byte[])spkt); //Process some general updates if (forwardTarget._targetid == target.id) { Common.Actions.SelectActor(forwardTarget, target as Actor); } if (argument.TargetHasDied) { Common.Actions.UpdateStance(forwardTarget, target as Actor); } if (argument.TargetHasDied && MapObject.IsNpc(target)) { Common.Actions.UpdateIcon(forwardTarget, target as BaseMob); } return(true); }; SendToCharacter(this.character); Regiontree tree = this.character.currentzone.Regiontree; foreach (Character forwardTarget in tree.SearchActors(this.character, SearchFlags.Characters)) { if (forwardTarget.id == this.character.id) { continue; } SendToCharacter(forwardTarget); } //Always update myself and oponent if it's character LifeCycle.Update(this.character); if (MapObject.IsPlayer(target)) { LifeCycle.Update(target as Character); } } else { //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 e) { Trace.TraceError("Exception processing the skill {0}", e.ToString()); //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); } } }
/// <summary> /// Occurs when using an offensive skill /// </summary> /// <param name="cpkt"></param> private void CM_USEOFFENSIVESKILL(CMSG_OFFENSIVESKILL cpkt) { lock (this.character.cooldowncollection) { try { MapObject target; uint skillid = cpkt.SkillID; byte skilltype = cpkt.SkillType; SkillUsageEventArgs argument = null; bool cancast = Regiontree.TryFind(cpkt.TargetActor, this.character, out target) && SkillUsageEventArgs.Create(skillid, this.character, target, out argument) && argument.SpellInfo.casttime > -1 && (argument.SpellInfo.casttime == 0 || this.character._lastcastedskill == skillid) && ((long)((uint)Environment.TickCount) - this.character._lastcastedtick) > 0 && (argument.SpellInfo.delay == 0 || !this.character.cooldowncollection.IsCoolDown(skillid)) && (argument.SpellInfo.maximumrange == 0 || argument.SpellInfo.IsInRangeOf((int)(Vector.GetDistance2D(this.character.Position, target.Position)))) && argument.SpellInfo.requiredWeapons[this.character.weapons.GetCurrentWeaponType()] == 1 && this.character.jlvl >= argument.SpellInfo.requiredJobs[this.character.job - 1] && this.character.Status.CurrentLp >= (argument.SpellInfo.requiredlp == 6 ? 1 : argument.SpellInfo.requiredlp) && argument.SpellInfo.IsTarget(this.character, target); if (cancast && argument.Use()) { //Clear casted skill this.character._lastcastedskill = 0; this.character._lastcastedtick = Environment.TickCount; //Set cooldown timer int delay = (int)(argument.SpellInfo.delay - ((character.stats.Dexterity * 2) + (character.stats.Concentration * 2))); if (delay > 0) this.character.cooldowncollection.Add(skillid, delay); this.character.cooldowncollection.Update(); //Use required sp points if (argument.SpellInfo.SP > -1) { this.character.LASTSP_TICK = Environment.TickCount; this.character.SP = (ushort)(this.character.SP - argument.SpellInfo.SP); } //Set sp to 0 else if (argument.SpellInfo.SP == -1) { this.character.LASTSP_TICK = Environment.TickCount; this.character.SP = 0; } //Use required lp points if (argument.SpellInfo.requiredlp == 6) { this.character._status.CurrentLp = 0; this.character._status.Updates |= 1; } else if (argument.SpellInfo.requiredlp > 0) { this.character._status.CurrentLp -= argument.SpellInfo.requiredlp; this.character._status.Updates |= 1; } //Add intergrated durabillity checks if (argument.CanCheckWeaponDurabillity) Common.Durabillity.DoWeapon(this.character); //Skill sucess Predicate<Character> SendToCharacter = delegate(Character forwardTarget) { //Skill sucess SMSG_OFFENSIVESKILL spkt = new SMSG_OFFENSIVESKILL(); spkt.SkillID = cpkt.SkillID; spkt.SkillType = cpkt.SkillType; spkt.TargetActor = cpkt.TargetActor; spkt.SourceActor = this.character.id; spkt.IsCritical = (forwardTarget.id == this.character.id || forwardTarget.id == target.id) ? (byte)argument.Result : (byte)7; spkt.Damage = argument.Damage; spkt.SessionId = forwardTarget.id; forwardTarget.client.Send((byte[])spkt); //Process some general updates if (forwardTarget._targetid == target.id) Common.Actions.SelectActor(forwardTarget, target as Actor); if (argument.TargetHasDied) Common.Actions.UpdateStance(forwardTarget, target as Actor); if (argument.TargetHasDied && MapObject.IsNpc(target)) Common.Actions.UpdateIcon(forwardTarget, target as BaseMob); return true; }; SendToCharacter(this.character); Regiontree tree = this.character.currentzone.Regiontree; foreach (Character forwardTarget in tree.SearchActors(this.character, SearchFlags.Characters)) { if (forwardTarget.id == this.character.id) continue; SendToCharacter(forwardTarget); } //Always update myself and oponent if it's character LifeCycle.Update(this.character); if (MapObject.IsPlayer(target)) { LifeCycle.Update(target as Character); } } else { //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 e) { Trace.TraceError("Exception processing the skill {0}", e.ToString()); //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); } } }
/// <summary> /// Occurs when toggling between skills (aka stances) /// </summary> /// <param name="cpkt"></param> private void CM_SKILLTOGGLE(CMSG_SKILLTOGLE cpkt) { lock (this.character.cooldowncollection) { try { uint skillid = cpkt.SkillID; byte skilltype = cpkt.SkillType; SkillToggleEventArgs argument = null; bool cancast = SkillToggleEventArgs.Create(skillid, this.character, this.character, out argument) && argument.SpellInfo.casttime > -1 && (argument.SpellInfo.casttime == 0 || this.character._lastcastedskill == skillid) && Environment.TickCount - this.character._lastcastedtick > 0 && (argument.SpellInfo.delay == 0 || !this.character.cooldowncollection.IsCoolDown(skillid)) && (argument.SpellInfo.maximumrange == 0 || argument.SpellInfo.IsInRangeOf((int)(Vector.GetDistance2D(this.character.Position, this.character.Position)))) && argument.SpellInfo.requiredWeapons[this.character.weapons.GetCurrentWeaponType()] == 1 && this.character.jlvl >= argument.SpellInfo.requiredJobs[this.character.job - 1] && argument.SpellInfo.IsTarget(this.character, this.character); if (cancast && argument.Use()) { int delay = (int)(argument.SpellInfo.delay - ((character.stats.Dexterity * 2) + (character.stats.Concentration * 2))); if (delay > 0) this.character.cooldowncollection.Add(skillid, delay); this.character.cooldowncollection.Update(); SMSG_SKILLTOGLE spkt2 = new SMSG_SKILLTOGLE(); spkt2.SkillID = cpkt.SkillID; spkt2.SkillType = cpkt.SkillType; spkt2.SessionId = this.character.id; spkt2.Toggle = argument.Failed; this.Send((byte[])spkt2); if (character._status.Updates > 0) { LifeCycle.Update(character); character._status.Updates = 0; } Regiontree tree = this.character.currentzone.Regiontree; foreach (Character regionObject in tree.SearchActors(this.character, SearchFlags.Characters)) { SMSG_OFFENSIVESKILL spkt = new SMSG_OFFENSIVESKILL(); spkt.Damage = argument.Damage; spkt.SourceActor = this.character.id; spkt.TargetActor = this.character.id; spkt.SessionId = regionObject.id; spkt.SkillID = cpkt.SkillID; regionObject.client.Send((byte[])spkt); } } else { Console.WriteLine("Stance failed"); SMSG_SKILLTOGLE spkt2 = new SMSG_SKILLTOGLE(); spkt2.SkillID = cpkt.SkillID; spkt2.SkillType = cpkt.SkillType; spkt2.SessionId = this.character.id; spkt2.Toggle = true; this.Send((byte[])spkt2); } } catch (Exception e) { Trace.TraceError("Exception processing the skill {0}", e.ToString()); //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); } } }
/// <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"); } } }