public void Handle(Skill skill, Character caster, ICombatEntity target) { if (skill.SpendSp > 0) { caster.ModifySp(-skill.SpendSp); } skill.IncreaseOverheat(); if (target == null) { Send.ZC_SKILL_FORCE_TARGET(caster, null, skill, 0); return; } var damage = caster.GetRandomAtk(skill); target.TakeDamage(damage, caster); Send.ZC_SKILL_FORCE_TARGET(caster, target, skill, damage); if (target.IsDead) { Send.ZC_SKILL_CAST_CANCEL(caster, target); } }
/// <summary> /// Initializes a new instance of the <see cref="AttackCommandBase"/> class. /// </summary> /// <param name="attacker"> /// The attacker. /// </param> /// <param name="target"> /// The target. /// </param> protected AttackCommandBase(ICombatEntity attacker, ICombatEntity target) { this.random = new Random(); this.Description = string.Empty; this.Attacker = attacker; this.Target = target; this.BaseHitChance = attacker.BaseHitChance; }
/// <summary> /// Returns attackable monsters in the given radius around position. /// </summary> /// <param name="position"></param> /// <param name="radius"></param> /// <returns></returns> public List <ICombatEntity> GetAttackableEntitiesInRange(ICombatEntity attacker, Position position, int radius) { var result = new List <ICombatEntity>(); lock (_combatEntities) { var entities = _combatEntities.Values.Where(a => a.Position.InRange2D(position, radius) && attacker.CanAttack(a)); result.AddRange(entities); } return(result); }
void unit_OnAttackMade(ICombatEntity arg1, IEntity arg2) { Vector3 o = arg1.WorldPosition + Vector3.Up; Vector3 d = arg2.WorldPosition + Vector3.Up; d -= o; d.Normalize(); BulletParticle bp = new BulletParticle(o, d, 0.05f, 1.4f, 0.1f); bp.Tint = Color.Red; AddParticle(bp); }
/// <summary> /// Starts the buff with the given id. If the buff is already active, /// it gets overbuffed. Returns the created or modified buff. /// </summary> /// <param name="buffId"></param> /// <param name="caster">The entity that casted the buff.</param> /// <param name="duration">Custom duration of the buff.</param> /// <returns></returns> public Buff Start(BuffId buffId, ICombatEntity caster, TimeSpan duration) { if (!this.TryGet(buffId, out var buff)) { buff = new Buff(caster, this.Entity, buffId, duration); this.Add(buff); } else { this.Overbuff(buff); } return(buff); }
/// <summary> /// Called when a monster spawned by this spawner died. /// </summary> /// <param name="monster"></param> /// <param name="killer"></param> private void OnMonsterDied(Monster monster, ICombatEntity killer) { _spawnCount = Interlocked.Decrement(ref _spawnCount); // Use the spawner's respawn delay as the base, but add // a few random milliseconds on top, to make it appear // more dynamic. var delay = this.RespawnDelay; if (delay > TimeSpan.Zero) { delay = delay.Add(TimeSpan.FromMilliseconds(_rnd.Next(250, 2000))); } Task.Delay(delay).ContinueWith(_ => this.Respawn()); }
/// <summary> /// Returns the AI's current target if it's still on the same map. /// </summary> /// <param name="target"></param> /// <returns></returns> private bool TryGetTarget(out ICombatEntity target) { var targetHandle = this.TargetHandle; target = null; if (targetHandle == 0) { return(false); } if (!this.Entity.Map.TryGetCombatEntity(targetHandle, out target)) { return(false); } return(true); }
void unit_OnAttackMade(ICombatEntity arg1, IEntity arg2) { Vector2 cpvd = new Vector2(arg1.ViewDirection.Y, -arg1.ViewDirection.X); Vector2 o2 = cpvd * initArgs.BulletOffset.X + arg1.ViewDirection * initArgs.BulletOffset.Z; Vector3 o = new Vector3(o2.X, initArgs.BulletOffset.Y, o2.Y); o += arg1.WorldPosition; Vector2 d2 = cpvd * initArgs.BulletDirection.X + arg1.ViewDirection * initArgs.BulletDirection.Z; Vector3 d = new Vector3(d2.X, initArgs.BulletDirection.Y, d2.Y); d.Normalize(); BulletParticle bp = new BulletParticle(o, d, 0.05f, 1.4f, 0.1f); bp.Tint = initArgs.BulletTint; AddParticle(bp); }
/// <summary> /// Returns attackable monsters in the given radius around position. /// </summary> /// <param name="position"></param> /// <param name="radius"></param> /// <returns></returns> public List <ICombatEntity> GetAttackableEntitiesInRectangle(ICombatEntity attacker, Position attackerPos, Position targetPos, int rectWidth) { var result = new List <ICombatEntity>(); var rectPoints = GetRectangle(attackerPos, targetPos, rectWidth); // Debugging //foreach (var point in rectPoints) //{ // var monster = new Monster(10005, NpcType.Friendly); // monster.Position = new Position(point.X, attackerPos.Y, point.Z); // monster.DisappearTime = DateTime.Now.AddSeconds(5); // attacker.Map.AddMonster(monster); //} lock (_combatEntities) { var entities = _combatEntities.Values.Where(a => attacker.CanAttack(a) && a.Position.InPolygon2D(rectPoints)); result.AddRange(entities); } return(result); }
/// <summary> /// Creates new component. /// </summary> /// <param name="entity"></param> public Recovery(ICombatEntity entity) { this.Entity = entity; }
/// <summary> /// Returns true if the monster can attack the entity. /// </summary> /// <param name="entity"></param> /// <returns></returns> public bool CanAttack(ICombatEntity entity) { // For now, let's specify that monsters can attack characters. return(entity is Character); }
/// <summary> /// Returns combat entity by handle via out. Returns false if the /// handle wasn't found. /// </summary> /// <param name="handle"></param> /// <param name="entity"></param> /// <returns></returns> public bool TryGetCombatEntity(int handle, out ICombatEntity entity) { entity = this.GetCombatEntity(handle); return(entity != null); }
/// <summary> /// Initializes a new instance of the <see cref="BasicAttack"/> class. /// </summary> /// <param name="attacker"> /// The attacker. /// </param> /// <param name="target"> /// The target. /// </param> public BasicAttack(ICombatEntity attacker, ICombatEntity target) : base(attacker, target) { this.Description = "Basic CalculateAttack"; this.BaseHitChance = attacker.BaseHitChance; }
/// <summary> /// Creates new instance for character. /// </summary> /// <param name="entity"></param> public BuffCollection(ICombatEntity entity) { this.Entity = entity; }
/// <summary> /// Returns true if the character can attack the entity. /// </summary> /// <param name="entity"></param> /// <returns></returns> public bool CanAttack(ICombatEntity entity) { // For now, let's specify that characters can attack actual // monsters. return(entity is Monster monster && monster.NpcType == NpcType.Monster); }
public AttackAction(ICombatEntity source, ICombatEntity target) { _source = source; _target = target; }
public ICombatAction GenerateCombatAction(ICombatEntity source, List <ICombatEntity> potentialTargets) { int targetIdx = _randomGenerator.Next(0, potentialTargets.Count); return(new AttackAction(source, potentialTargets[targetIdx])); }