protected internal void UpdateAdditions() { //PROCESS ADDITION if (this._additions._skipcheck == false) { List <AdditionState> appliedadditions = this._additions.timed_additions; for (int i = 0; i < appliedadditions.Count; i++) { AdditionState state = appliedadditions[i]; if (state.IsExpired) { Singleton.Additions.DeapplyAddition(state.Addition, this); Common.Skills.SendDeleteStatus(this, state.Addition); appliedadditions.RemoveAt(i); i--; } else { state.Update(this, Target); } } if (_status.Updates > 0) { Character character = this as Character; if (character != null) { LifeCycle.Update(character); _status.Updates = 0; } } } }
/// <summary> /// Use a offensive skills /// </summary> /// <param name="target"></param> /// <param name="source"></param> /// <param name="skillid"></param> /// <param name="skilltype"></param> /// <remarks> /// This functions is invoked by mob ai. The character has it's own skill handler /// inside the network client. /// </remarks> public static void OffensiveSkillUse(MapObject target, MapObject source, uint skillid, byte skilltype) { try { SkillUsageEventArgs argument = null; if (SkillUsageEventArgs.Create(skillid, source, target, out argument) && argument.Use()) { Predicate <Character> SendToCharacter = delegate(Character forwardTarget) { //Skill sucess SMSG_OFFENSIVESKILL spkt = new SMSG_OFFENSIVESKILL(); spkt.SkillID = skillid; spkt.SkillType = 1; spkt.TargetActor = target.id; spkt.SourceActor = source.id; spkt.IsCritical = (forwardTarget.id == source.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); } if (forwardTarget.id == target.id) { LifeCycle.Update(forwardTarget); } return(true); }; Regiontree tree = source.currentzone.Regiontree; foreach (Character forwardTarget in tree.SearchActors(source, SearchFlags.Characters)) { SendToCharacter(forwardTarget); } } } catch (Exception e) { Console.WriteLine(e); } }
/// <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); } } }
public static void Kill(Character character, Match match) { Regiontree tree = character.currentzone.Regiontree; MapObject regionObject; if (character.SelectedTarget > 0 && Regiontree.TryFind(character.SelectedTarget, character, out regionObject) && regionObject is Monster) { /***** * //Make the Object die *****/ Actor btarget = regionObject as Actor; btarget.Status.CurrentHp = 0; btarget.OnDie(character); character.OnEnemyDie(regionObject); btarget.stance = 7; btarget.Status.Updates |= 1; /***** * //Forcing updates to all surrounding objects (flusing) *****/ Predicate <Character> SendToCharacter = delegate(Character forwardTarget) { //Process some general updates if (forwardTarget.SelectedTarget == regionObject.id) { Common.Actions.SelectActor(forwardTarget, regionObject as Actor); } Common.Actions.UpdateStance(forwardTarget, regionObject as Actor); Common.Actions.UpdateIcon(forwardTarget, regionObject as BaseMob); return(true); }; /***** * //Forcing updates to all surrounding objects (searching) *****/ SendToCharacter(character); foreach (Character forwardTarget in tree.SearchActors(character, SearchFlags.Characters)) { if (forwardTarget.id == character.id) { continue; } SendToCharacter(forwardTarget); } /***** * //Update lifecycle *****/ LifeCycle.Update(character); if (MapObject.IsPlayer(regionObject)) { LifeCycle.Update(regionObject as Character); } /*** * Check Quest ***/ if (MapObject.IsNpc(btarget)) { Quests.QuestBase.UserEliminateTarget(btarget.ModelId, character); } } else { CommonFunctions.Broadcast(character, character, "No target selected or incorrect target"); } }