Beispiel #1
0
        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;
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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;
        }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
        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);
            }
        }
Beispiel #6
0
        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;
            }
        }
Beispiel #7
0
 internal TraceResult(TraceLine trace, Vector2 vec, Face face)
     : this(trace, vec)
 {
     HitWorld = true;
     Face = face;
 }
Beispiel #8
0
 internal TraceResult(TraceLine trace, Vector2 vec, Entity ent)
     : this(trace, vec)
 {
     HitEntity = true;
     Entity = ent;
 }
Beispiel #9
0
        internal TraceResult(TraceLine trace, Vector2 vec)
        {
            World = trace.World;

            Origin = trace.Origin;
            Target = trace.Target;
            Normal = trace.Normal;

            Vector = vec;
        }
Beispiel #10
0
        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;
                    }
                }
            }
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        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;
        }
Beispiel #13
0
        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));
            }
        }
Beispiel #14
0
        public override void OnRenderFrame(FrameEventArgs e)
        {
            float x0 = 0.0f;
            float x1 = (Camera.X < WorldSize / 2) ? -WorldSize : WorldSize;
            float y0 = 0.0f;
            float y1 = (Camera.Z < WorldSize / 2) ? -WorldSize : WorldSize;

            float hullSize = .5f;

            TraceResult trace = null;

            if (_drawTestTrace) {
                trace = new Zombles.Geometry.TraceLine(World) {
                    Origin = Camera.Position2D,
                    HullSize = new Vector2(hullSize, hullSize),
                    HitGeometry = true,
                    HitEntities = false,
                    Length = 32f,
                    Normal = World.Difference(Camera.Position2D,
                        Camera.ScreenToWorld(new Vector2(Mouse.X, Mouse.Y) / _upScale, 0.5f))
                }.GetResult();
            }

            var hs = hullSize / 2f;

            GL.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit);

            for (int i = 0; i < 4; ++i) {
                Camera.WorldOffsetX = (i & 0x1) == 0x0 ? x0 : x1;
                Camera.WorldOffsetY = (i & 0x2) == 0x0 ? y0 : y1;

                World.RenderGeometry(GeoShader, _hideTop);

                FlatEntShader.Begin();
                World.RenderEntities(FlatEntShader);
                FlatEntShader.End();

                ModelEntShader.Begin();
                World.RenderEntities(ModelEntShader);
                ModelEntShader.End();

                _traceShader.Begin(true);

                if (_drawPathNetwork) {
                    World.RenderIntersectionNetwork(_traceShader);
                }

                if (_drawTestTrace) {
                    _traceShader.Render(trace);
                    _traceShader.Render(trace.End.X - hs, trace.End.Y - hs, trace.End.X + hs, trace.End.Y - hs);
                    _traceShader.Render(trace.End.X + hs, trace.End.Y - hs, trace.End.X + hs, trace.End.Y + hs);
                    _traceShader.Render(trace.End.X + hs, trace.End.Y + hs, trace.End.X - hs, trace.End.Y + hs);
                    _traceShader.Render(trace.End.X - hs, trace.End.Y + hs, trace.End.X - hs, trace.End.Y - hs);
                }

                if (_isSelecting) {
                    var pos = Camera.ScreenToWorld(new Vector2(Mouse.X, Mouse.Y) / _upScale, .5f);
                    var diff = World.Difference(pos, _selectionStart);
                    _traceShader.Render(pos.X, pos.Y, pos.X + diff.X, pos.Y);
                    _traceShader.Render(pos.X + diff.X, pos.Y, pos.X + diff.X, pos.Y + diff.Y);
                    _traceShader.Render(pos.X + diff.X, pos.Y + diff.Y, pos.X, pos.Y + diff.Y);
                    _traceShader.Render(pos.X, pos.Y + diff.Y, pos.X, pos.Y);
                }

                _traceShader.End();
            }
            
            base.OnRenderFrame(e);

            _totalFrameTime += _frameTimer.ElapsedTicks;
            ++_framesCompleted;
            _frameTimer.Restart();
        }