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; }
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); } }
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; }
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); } }
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); } }
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; } }
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; } } } }
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); }
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; }
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)); } }