Пример #1
0
 public void Reset()
 {
     Entity          = EcsEntity.Null;
     Target          = EcsEntity.Null;
     Character       = null;
     CombatEntity    = null;
     Connection      = null;
     CurrentCooldown = 0f;
     HeadId          = 0;
     HeadFacing      = HeadFacing.Center;
     IsMale          = true;
     QueueAttack     = false;
 }
Пример #2
0
        public void Reset()
        {
            Entity       = EcsEntity.Null;
            Character    = null;
            aiEntries    = null;
            SpawnEntry   = null;
            CombatEntity = null;
            searchTarget = null;
            aiTickRate   = 0.1f;
            nextAiUpdate = Time.ElapsedTimeFloat + GameRandom.NextFloat(0, aiTickRate);

            target = EcsEntity.Null;
        }
Пример #3
0
        private bool OutPerformAttack()
        {
            var targetEntity = targetCharacter.Entity.Get <CombatEntity>();

            if (!targetEntity.IsValidTarget(CombatEntity))
            {
                return(false);
            }

            CombatEntity.PerformMeleeAttack(targetEntity);

            nextAiUpdate += MonsterBase.AttackTime;

            return(true);
        }
Пример #4
0
        public void Initialize(ref EcsEntity e, Character character, CombatEntity combat, MonsterDatabaseInfo monData, MonsterAiType type, MapSpawnEntry spawnEntry, string mapName)
        {
            Entity          = e;
            Character       = character;
            this.SpawnEntry = spawnEntry;
            CombatEntity    = combat;
            MonsterBase     = monData;
            aiType          = type;
            SpawnMap        = mapName;
            aiEntries       = DataManager.GetAiStateMachine(aiType);
            nextAiUpdate    = Time.ElapsedTimeFloat + 1f;

            if (Character.ClassId >= 4000 && SpawnEntry == null)
            {
                throw new Exception("Monster created without spawn entry");                 //remove when arbitrary monster spawning is added
            }
            UpdateStats();

            currentState = MonsterAiState.StateIdle;
        }
Пример #5
0
 public bool IsValidTarget(CombatEntity source)
 {
     if (this == source)
     {
         return(false);
     }
     if (Entity.IsNull() || !Entity.IsAlive())
     {
         return(false);
     }
     if (!Character.IsActive || Character.State == CharacterState.Dead)
     {
         return(false);
     }
     if (Character.Map == null)
     {
         return(false);
     }
     if (source.Character.Map != Character.Map)
     {
         return(false);
     }
     if (Character.SpawnImmunity > 0f)
     {
         return(false);
     }
     if (source.Character.ClassId == Character.ClassId)
     {
         return(false);
     }
     if (Character.ClassId == 1000)
     {
         return(false);                //hack
     }
     return(true);
 }
Пример #6
0
        public void PerformMeleeAttack(CombatEntity target)
        {
#if DEBUG
            if (!target.IsValidTarget(this))
            {
                throw new Exception("Entity attempting to attack an invalid target! This should be checked before calling PerformMeleeAttack.");
            }
#endif
            if (Character.AttackCooldown + Time.DeltaTimeFloat + 0.005f < Time.ElapsedTimeFloat)
            {
                Character.AttackCooldown = Time.ElapsedTimeFloat + Stats.AttackMotionTime;                 //they are consecutively attacking
            }
            else
            {
                Character.AttackCooldown += Stats.AttackMotionTime;
            }

            Character.FacingDirection = DistanceCache.Direction(Character.Position, target.Character.Position);

            var atk1 = Stats.Atk;
            var atk2 = Stats.Atk2;
            if (atk1 <= 0)
            {
                atk1 = 1;
            }
            if (atk2 < atk1)
            {
                atk2 = atk1;
            }

            var damage = (short)GameRandom.Next(Stats.Atk, Stats.Atk2);

            var di = new DamageInfo()
            {
                Damage    = damage,
                HitCount  = 1,
                KnockBack = 0,
                Source    = Entity,
                Target    = target.Entity,
                Time      = Time.ElapsedTimeFloat + Stats.SpriteAttackTiming
            };

            //ServerLogger.Log($"{aiCooldown} {character.AttackCooldown} {angle} {dir}");

            Character.Map.GatherPlayersForMultiCast(ref Entity, Character);
            CommandBuilder.AttackMulti(Character, target.Character, di);
            CommandBuilder.ClearRecipients();

            target.QueueDamage(di);

            if (target.Character.Type == CharacterType.Monster && di.Damage > target.Stats.Hp)
            {
                var mon = target.Entity.Get <Monster>();
                mon.AddDelay(Stats.SpriteAttackTiming);                 //make sure it stops acting until it dies
            }

            if (Character.Type == CharacterType.Player && di.Damage > target.Stats.Hp)
            {
                var player = Entity.Get <Player>();
                player.ClearTarget();
            }
        }