Пример #1
0
        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);
            }
        }
Пример #2
0
 /// <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;
 }
Пример #3
0
        /// <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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        /// <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());
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        /// <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);
        }
Пример #10
0
 /// <summary>
 /// Creates new component.
 /// </summary>
 /// <param name="entity"></param>
 public Recovery(ICombatEntity entity)
 {
     this.Entity = entity;
 }
Пример #11
0
 /// <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);
 }
Пример #12
0
 /// <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);
 }
Пример #13
0
 /// <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;
 }
Пример #14
0
 /// <summary>
 /// Creates new instance for character.
 /// </summary>
 /// <param name="entity"></param>
 public BuffCollection(ICombatEntity entity)
 {
     this.Entity = entity;
 }
Пример #15
0
 /// <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);
 }
Пример #16
0
        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);
        }
Пример #17
0
 public AttackAction(ICombatEntity source, ICombatEntity target)
 {
     _source = source;
     _target = target;
 }
Пример #18
0
 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);
 }
Пример #19
0
        public ICombatAction GenerateCombatAction(ICombatEntity source, List <ICombatEntity> potentialTargets)
        {
            int targetIdx = _randomGenerator.Next(0, potentialTargets.Count);

            return(new AttackAction(source, potentialTargets[targetIdx]));
        }