/// <summary> /// Hits the specified target by the specified player. /// </summary> /// <param name="player">The player.</param> /// <param name="target">The target.</param> /// <param name="attackAnimation">The attack animation.</param> /// <param name="lookingDirection">The looking direction.</param> public void Hit(Player player, IAttackable target, byte attackAnimation, Direction lookingDirection) { if (target is IObservable targetAsObservable) { targetAsObservable.ObserverLock.EnterReadLock(); try { if (!targetAsObservable.Observers.Contains(player)) { // Target out of range return; } } finally { targetAsObservable.ObserverLock.ExitReadLock(); } } player.Rotation = lookingDirection; target.AttackBy(player, null); player.ObserverLock.EnterReadLock(); try { player.Observers.ForEach(observer => observer.WorldView.ShowAnimation(player, attackAnimation, target, lookingDirection)); } finally { player.ObserverLock.ExitReadLock(); } }
/// <summary> /// Attacks the specified player. /// </summary> /// <param name="player">The player.</param> public void Attack(IAttackable player) { // need to find specific animation // Maybe add SpecificAnimation and AttackWhenPlayerOn properties to MonsterDefinition?? or create new TrapDefinition? player.AttackBy(this, null); this.ForEachWorldObserver(p => p.ViewPlugIns.GetPlugIn <IShowAnimationPlugIn>()?.ShowAnimation(this, TrapAttackAnimation, player, this.Rotation), true); }
/// <summary> /// Hits the specified target by the specified player. /// </summary> /// <param name="player">The player.</param> /// <param name="target">The target.</param> /// <param name="attackAnimation">The attack animation.</param> /// <param name="lookingDirection">The looking direction.</param> public void Hit(Player player, IAttackable target, byte attackAnimation, Direction lookingDirection) { if (target is IObservable targetAsObservable) { targetAsObservable.ObserverLock.EnterReadLock(); try { if (!targetAsObservable.Observers.Contains(player)) { // Target out of range return; } } finally { targetAsObservable.ObserverLock.ExitReadLock(); } } player.Rotation = lookingDirection; target.AttackBy(player, null); if (player.Attributes?[Stats.TransformationSkin] is { } skin and not 0 && this.ApplySkinnedMonstersSkill(player, target, (short)skin) is var(skill, effectApplied)) { player.ForEachWorldObserver(observer => observer.ViewPlugIns.GetPlugIn <IShowSkillAnimationPlugIn>()?.ShowSkillAnimation(player, target, skill, effectApplied), true); return; } player.ForEachObservingPlayer(observer => observer.ViewPlugIns.GetPlugIn <IShowAnimationPlugIn>()?.ShowAnimation(player, attackAnimation, target, lookingDirection), false); }
private void ApplySkill(Player player, SkillEntry skillEntry, Skill skill, IAttackable target) { if (target.CheckSkillTargetRestrictions(player, skill)) { target.AttackBy(player, skillEntry); target.ApplyElementalEffects(player, skillEntry); } }
/// <summary> /// Performs the skill. /// </summary> /// <param name="player">The player.</param> /// <param name="target">The target.</param> /// <param name="skillId">The skill identifier.</param> public void PerformSkill(Player player, IAttackable target, ushort skillId) { SkillEntry skillEntry = player.SkillList.GetSkill(skillId); var skill = skillEntry.Skill; if (skill.SkillType == SkillType.PassiveBoost) { Logger.WarnFormat("Skill is a passive boost"); return; } if (target == null) { Logger.WarnFormat("Skill has no target"); return; } if (!target.Alive) { Logger.WarnFormat("Skill target is already dead"); return; } var targetPlayer = target as Player; bool targetIsPlayer = targetPlayer != null; // is it a player? // enough mana, ag etc? if (!player.TryConsumeForSkill(skill)) { Logger.WarnFormat("Skill not enough resources"); return; } player.ForEachObservingPlayer(obs => obs.PlayerView.WorldView.ShowSkillAnimation(player, target, skill), true); if (!player.IsInRange(target.X, target.Y, skill.Range + 2)) { Logger.WarnFormat("Skill target is out of range"); return; } if (skill.SkillType == SkillType.DirectHit || skill.SkillType == SkillType.CastleSiegeSkill) { Logger.WarnFormat("Skill perform direct hit or castle siege skill"); target.AttackBy(player, skillEntry); } if (skill.SkillType == SkillType.Buff && skill.MagicEffectDef != null && targetIsPlayer) { // TODO: Summoned Monsters should be able to receive a buff too - add an interface ICanReceiveBuff which contains the MagicEffectList if (skillEntry.BuffPowerUp == null) { this.CreateBuffPowerUp(player, skillEntry); } var magicEffect = new MagicEffect(skillEntry.BuffPowerUp, skill.MagicEffectDef, new TimeSpan(0, 0, 0, 0, (int)skillEntry.PowerUpDuration.Value)); targetPlayer.MagicEffectList.AddEffect(magicEffect); } }
private void ApplySkill(Player player, SkillEntry skillEntry, IAttackable target, Point targetAreaCenter) { if (target.CheckSkillTargetRestrictions(player, skillEntry.Skill)) { target.AttackBy(player, skillEntry); target.ApplyElementalEffects(player, skillEntry); player.GameContext.PlugInManager.GetStrategy <short, IAreaSkillPlugIn>(skillEntry.Skill.Number)?.AfterTargetGotAttacked(player, target, skillEntry, targetAreaCenter); } }
/// <summary> /// Attacks the target by the player with the specified skill. /// </summary> /// <param name="player">The player who is performing the skill.</param> /// <param name="target">The target.</param> /// <param name="skill">The skill.</param> public void AttackTarget(Player player, IAttackable target, SkillEntry skill) { if (skill.Skill.SkillType != SkillType.AreaSkillExplicitHits || target == null || !target.Alive) { return; } target.AttackBy(player, skill); }
/// <summary> /// Attacks the target by the player with the specified skill. /// </summary> /// <param name="player">The player who is performing the skill.</param> /// <param name="target">The target.</param> /// <param name="skill">The skill.</param> public void AttackTarget(Player player, IAttackable target, SkillEntry skill) { if (skill.Skill.SkillType != SkillType.AreaSkillExplicitHits || target is null || !target.IsAlive) { return; } if (target.CheckSkillTargetRestrictions(player, skill.Skill)) { target.AttackBy(player, skill); target.ApplyElementalEffects(player, skill); } }
/// <summary> /// Hits the specified target by the specified player. /// </summary> /// <param name="player">The player.</param> /// <param name="target">The target.</param> /// <param name="attackAnimation">The attack animation.</param> /// <param name="lookingDirection">The looking direction.</param> public void Hit(Player player, IAttackable target, byte attackAnimation, Direction lookingDirection) { if (target is IObservable targetAsObservable) { targetAsObservable.ObserverLock.EnterReadLock(); try { if (!targetAsObservable.Observers.Contains(player)) { // Target out of range return; } } finally { targetAsObservable.ObserverLock.ExitReadLock(); } } player.Rotation = lookingDirection; target.AttackBy(player, null); player.ForEachObservingPlayer(observer => observer.ViewPlugIns.GetPlugIn <IShowAnimationPlugIn>()?.ShowAnimation(player, attackAnimation, target, lookingDirection), false); }