コード例 #1
0
ファイル: Mobbing.cs プロジェクト: alexturpin/Zombles
        private static bool ShouldMob(Entity self, EntityBeliefs ent)
        {
            var trace = new TraceLine(self.World);
            trace.Origin = ent.LastPos;
            trace.HitGeometry = true;
            trace.HitEntities = false;
            trace.HullSize = self.GetComponent<Collision>().Size;

            int survivors = 1;
            int zombies = 1;

            var it = new NearbyEntityEnumerator(self.World, ent.LastPos, MobRadius);
            while (it.MoveNext()) {
                var cur = it.Current;

                if (cur == self || cur == ent.Entity) continue;

                if (!cur.HasComponent<Human>() || !cur.HasComponent<Health>()) continue;
                if (!cur.GetComponent<Health>().IsAlive) continue;

                trace.Target = cur.Position2D;

                if (trace.GetResult().Hit) continue;

                if (cur.HasComponent<Survivor>()) {
                    survivors += cur.GetComponent<Health>().Value;
                } else {
                    zombies += cur.GetComponent<Health>().Value;
                }
            }

            return zombies <= MaxMobRatio * survivors;
        }
コード例 #2
0
ファイル: OriginalAI.cs プロジェクト: alexturpin/Zombles
        public override void OnThink(double dt)
        {
            if (MainWindow.Time - _lastSearch > TargetSearchInterval) {
                _lastSearch = MainWindow.Time + Tools.Random.NextSingle() * TargetSearchInterval;

                _fleePos = new Vector2();

                var trace = new TraceLine(World);
                trace.Origin = Position2D;
                trace.HitGeometry = true;
                trace.HitEntities = false;

                NearbyEntityEnumerator it = SearchNearbyEnts(_fleeRadius);
                while (it.MoveNext()) {
                    Entity cur = it.Current;
                    if (cur.HasComponent<Zombie>() && cur.GetComponent<Health>().IsAlive) {
                        Vector2 diff = World.Difference(Position2D, cur.Position2D);
                        float dist2 = diff.LengthSquared;

                        if (dist2 > 0) {
                            trace.Target = cur.Position2D;

                            if (!trace.GetResult().Hit) {
                                if (dist2 < _fightRadius * _fightRadius) {
                                    _fleePos += diff / dist2;

                                    if (dist2 < 0.75f) {
                                        Human.Attack(diff);
                                        Human.StopMoving();
                                        return;
                                    }
                                } else {
                                    _fleePos -= diff / dist2;
                                }

                                if (dist2 < _runRadius * _runRadius)
                                    (Human as Survivor).StartRunning();
                            }
                        }
                    }
                }

                if (_fleePos.LengthSquared == 0.0f) {
                    _fleePos.X = Tools.Random.NextSingle() * 2.0f - 1.0f;
                    _fleePos.Y = Tools.Random.NextSingle() * 2.0f - 1.0f;
                }

                Human.StartMoving(_fleePos);
            }
        }
コード例 #3
0
ファイル: Wander.cs プロジェクト: alexturpin/Zombles
        private void Randomize()
        {
            _curDest = Entity.Position2D;

            var trace = new TraceLine(World) {
                HitEntities = false,
                HitGeometry = true
            };

            float best = 0f;
            for (int i = 0; i < 16; ++i) {
                var ang = Tools.Random.NextSingle(0f, MathHelper.TwoPi);
                trace.Vector = new Vector2((float) Math.Cos(ang), (float) Math.Sin(ang)) * 4f;
                var res = trace.GetResult();

                if (res.Vector.LengthSquared > best) {
                    _curDest = Entity.Position2D + res.Vector;
                }
            }

            _nextRandomize = MainWindow.Time + 1.0 + Tools.Random.NextDouble() * 2.0;
        }
コード例 #4
0
ファイル: Mobbing.cs プロジェクト: alexturpin/Zombles
        public override IEnumerable<Action> GetActions()
        {
            yield return new DropItemAction(3f);

            var diff = Entity.World.Difference(Entity.Position2D, Target.LastPos);

            var trace = new TraceLine(World);
            trace.Origin = Target.LastPos;
            trace.HitGeometry = true;
            trace.HitEntities = false;
            trace.HullSize = Entity.GetComponent<Collision>().Size;

            bool closest = true;

            var it = new NearbyEntityEnumerator(World, Target.LastPos, diff.Length);
            while (it.MoveNext()) {
                var cur = it.Current;

                if (cur == Entity || !cur.HasComponent<Human>() || !cur.GetComponent<Health>().IsAlive) continue;

                trace.Target = cur.Position2D;

                if (trace.GetResult().Hit) continue;

                closest = false;
                break;
            }

            if (!closest) {
                yield return new MovementAction(diff.Normalized() * 128f);
            }

            if (diff.LengthSquared < 1.5f) {
                yield return new AttackAction(Target.Entity);
            }
        }
コード例 #5
0
ファイル: Beliefs.cs プロジェクト: alexturpin/Zombles
        public void Update()
        {
            var trace = new TraceLine(Entity.World) {
                Origin = Entity.Position2D,
                HitGeometry = true,
                HitEntities = true
            };

            var nearBlocks = _blockKB.Keys.Where(x =>
                Entity.World.Difference(x.GetNearestPosition(Entity.Position2D),
                    Entity.Position2D).LengthSquared <= VisibleRange2);

            foreach (var block in nearBlocks) {
                _blockKB[block].Update();

                foreach (var ent in block) {
                    if (Entity.World.Difference(ent.Position2D, Entity.Position2D).LengthSquared > VisibleRange2) {
                        continue;
                    }

                    var hp = ent.GetComponentOrNull<Health>();
                    if (hp != null && !hp.IsAlive) {
                        if (_entityKB.ContainsKey(ent)) {
                            _entityKB.Remove(ent);
                        }
                        continue;
                    }

                    trace.Target = ent.Position2D;
                    trace.HitEntityPredicate = x => x == ent;

                    var res = trace.GetResult();
                    if (res.HitWorld) continue;

                    ReceivePercept(ent);
                }
            }

            var old = _entityKB.Values.Where(x => MainWindow.Time - x.LastSeen > 10.0 || !x.Entity.IsValid).ToArray();

            foreach (var beliefs in old) {
                _entityKB.Remove(beliefs.Entity);
                _blockKB[beliefs.LastBlock].Remember(beliefs);
            }
        }
コード例 #6
0
ファイル: Beliefs.cs プロジェクト: alexturpin/Zombles
        public void Update()
        {
            LastSeen = MainWindow.Time;

            var trace = new TraceLine(Beliefs.Entity.World) {
                Origin = Beliefs.Entity.Position2D,
                HitGeometry = true,
                HitEntities = false
            };

            var toRemove = new List<EntityBeliefs>();

            foreach (var beliefs in _remembered) {
                if (beliefs.Entity.World.Difference(beliefs.LastPos, Beliefs.Entity.Position2D).LengthSquared > Beliefs.VisibleRange2)
                    continue;

                trace.Target = beliefs.LastPos;

                if (!beliefs.Entity.IsValid || !trace.GetResult().HitWorld) {
                    toRemove.Add(beliefs);
                }
            }

            foreach (var beliefs in toRemove) {
                _remembered.Remove(beliefs);
                _utilityChanged = true;
            }
        }
コード例 #7
0
ファイル: RouteNavigator.cs プロジェクト: alexturpin/Zombles
        private void ScanAhead()
        {
            if (_ended || _disposed) return;
            if (!_entity.HasComponent<Collision>()) return;

            _lastScan = MainWindow.Time;

            TraceLine trace = new TraceLine(_entity.World) {
                Origin = _entity.Position2D,
                Target = _curPath.Current,
                HitEntities = false,
                HitGeometry = true,
                HullSize = _entity.GetComponent<Collision>().Size * 0.95f
            };

            if (!trace.GetResult().Hit) {
                MoveNext();
            } else {
                trace.Target = _curWaypoint;
                if (trace.GetResult().Hit) {
                    if (_entity.World.IsPositionNavigable(CurrentTarget)) {
                        NavigateTo(CurrentTarget);
                    } else {
                        _ended = true;
                    }
                }
            }
        }
コード例 #8
0
ファイル: Human.cs プロジェクト: alexturpin/Zombles
        public virtual void Attack(Vector2 dir)
        {
            if (!Health.IsAlive || !CanAttack)
                return;

            _nextAttack = MainWindow.Time + AttackPeriod;

            FaceDirection(dir);

            TraceLine trace = new TraceLine(World);
            trace.HitGeometry = true;
            trace.HitEntities = true;
            trace.HitEntityPredicate = (x => x != Entity
                && (!x.HasComponent<Zombie>() || !Entity.HasComponent<Zombie>())
                && (!x.HasComponent<Survivor>() || !Entity.HasComponent<Survivor>()));
            trace.Origin = Position2D;
            trace.Normal = dir;
            trace.Length = 1.0f;

            TraceResult res = trace.GetResult();
            if (!res.HitEntity || !res.Entity.HasComponent<Health>()) return;

            res.Entity.GetComponent<Health>().Damage(Tools.Random.Next(MinAttackDamage, MaxAttackDamage + 1), Entity);
        }
コード例 #9
0
ファイル: ZombieAI.cs プロジェクト: alexturpin/Zombles
        private void FindTarget()
        {
            TraceLine trace = new TraceLine(World);
            trace.Origin = Position2D;
            trace.HitGeometry = true;
            trace.HitEntities = false;
            trace.HullSize = Entity.GetComponent<Collision>().Size;

            Entity closest = null;
            float bestDist2 = _viewRadius * _viewRadius;

            NearbyEntityEnumerator it = SearchNearbyEnts(_viewRadius);
            while (it.MoveNext()) {
                if (!it.Current.HasComponent<Survivor>())
                    continue;

                if (!it.Current.GetComponent<Health>().IsAlive)
                    continue;

                Vector2 diff = World.Difference(Position2D, it.Current.Position2D);

                float dist2 = diff.LengthSquared;
                if (dist2 < bestDist2) {
                    trace.Target = it.Current.Position2D;

                    if (!trace.GetResult().Hit) {
                        closest = it.Current;
                        bestDist2 = dist2;
                    }
                }
            }

            _curTarget = closest;
            _lastSearch = MainWindow.Time;
        }
コード例 #10
0
ファイル: ZombieAI.cs プロジェクト: alexturpin/Zombles
        public override void OnThink(double dt)
        {
            if (!Human.Health.IsAlive)
                return;

            if (MainWindow.Time - _lastSearch > TargetSearchInterval)
                FindTarget();

            if (_curTarget != null) {
                Vector2 diff = World.Difference(Position2D, _curTarget.Position2D);

                Health targHealth = _curTarget.GetComponent<Health>();

                if (!_curTarget.HasComponent<Survivor>() || !targHealth.IsAlive || diff.LengthSquared > _viewRadius * _viewRadius)
                    _curTarget = null;
                else {
                    _lastSeenPos = _curTarget.Position2D;
                    _lastSeen = MainWindow.Time;

                    if (Human.CanAttack) {
                        if (diff.LengthSquared < 0.75f) {
                            Human.Attack(diff);
                            Human.StopMoving();
                        } else {
                            Human.StartMoving(diff);
                        }
                    }
                }
            } else {
                if ((MainWindow.Time - _lastSeen) > 10.0 ||
                    World.Difference(Position2D, _lastSeenPos).LengthSquared <= 1.0f) {
                    int attempts = 0;
                    while (attempts++ < 16) {
                        float rad = 2.0f + Tools.Random.NextSingle() * 6.0f;
                        double ang = Tools.Random.NextDouble() * Math.PI * 2.0;

                        _lastSeenPos = new Vector2(
                            Position2D.X + (float) Math.Cos(ang) * rad,
                            Position2D.Y + (float) Math.Sin(ang) * rad
                        );

                        TraceLine trace = new TraceLine(World);
                        trace.Origin = Position2D;
                        trace.Target = _lastSeenPos;
                        trace.HitGeometry = true;
                        trace.HitEntities = false;
                        trace.HullSize = Entity.GetComponent<Collision>().Size;

                        if (!trace.GetResult().Hit)
                            break;
                    }

                    if (attempts == 16)
                        _lastSeen = MainWindow.Time + Tools.Random.NextDouble() * 1.0 + 9.0;
                    else
                        _lastSeen = MainWindow.Time;
                }

                Human.StartMoving(World.Difference(Position2D, _lastSeenPos));
            }
        }