void ProcessWorldEvent(ZombieAgent zombie, WorldEvent ev) { if (ev == null) { return; } var dist = Vector3.Distance(zombie.pos, ev.Pos); if (dist <= ev.Radius) { Vector3 soundDir = new Vector3(); soundDir.x = _prng.Get(-1.0f, 1.0f); soundDir.z = _prng.Get(-1.0f, 1.0f); // Pick a random position within 75% of the radius. soundDir.Normalize(); soundDir *= (dist * 0.75f); zombie.targetPos = ev.Pos + soundDir; zombie.target = _worldZones.FindByPos2D(zombie.targetPos); zombie.state = ZombieAgent.State.Investigating; } }
void UpdateInactiveZombie(ZombieAgent zombie, float dt, WorldEvent ev) { zombie.simulationTime += dt; ProcessWorldEvent(zombie, ev); UpdateTarget(zombie); UpdateApproachTarget(zombie, dt); }
private void UpdateInactiveZombie(ZombieAgent zombie, float dt, WorldEvent ev) { UpdateTarget(zombie, ev); zombie.dir = zombie.targetPos - zombie.pos; zombie.dir.Normalize(); float speed = _worldState.GetZombieSpeed() * dt; zombie.pos = Vector3.MoveTowards(zombie.pos, zombie.targetPos, speed); }
private void UpdateTarget(ZombieAgent zombie, WorldEvent ev) { if (ev != null) { var dist = Vector3.Distance(zombie.pos, ev.Pos); if (dist <= ev.Radius) { Vector3 soundDir = new Vector3(); soundDir.x = _prng.Get(-1.0f, 1.0f); soundDir.z = _prng.Get(-1.0f, 1.0f); soundDir.Normalize(); soundDir *= (dist * 0.75f); zombie.targetPos = ev.Pos + soundDir; #if DEBUG Log.Out("Reacting to sound at {0}", ev.Pos); #endif return; } } // If we have an activate target wait for arrival. if (!zombie.ReachedTarget()) { return; } if (_worldState.IsBloodMoon()) { zombie.target = _playerZones.GetRandomClosest(zombie.pos, _prng, 200.0f); if (zombie.target == null) { zombie.target = GetNextTarget(zombie); } } else { zombie.target = GetNextTarget(zombie); } zombie.targetPos = GetTargetPos(zombie.target); }
void UpdateInactiveZombies(float dt) { // Repopulate lock (_inactiveZombies) { lock (_inactiveQueue) { while (_inactiveQueue.Count > 0) { var zombie = _inactiveQueue.Dequeue(); _inactiveZombies.Add(zombie); } } } // Simulate int activatedZombies = 0; int maxUpdates = _maxZombies; int maxPerZone = MaxZombiesPerZone(); WorldEvent ev = null; lock (_worldEvents) { if (_worldEvents.Count > 0) { ev = _worldEvents.Dequeue(); } } for (int i = 0; ; i++) { lock (_inactiveZombies) { if (i >= _inactiveZombies.Count) { break; } var world = GameManager.Instance.World; if (world == null) { Log.Out("[WalkerSim] World no longer exists, bailing"); break; } bool removeZombie = false; bool activatedZombie = false; ZombieAgent zombie = _inactiveZombies[i]; UpdateInactiveZombie(zombie, dt, ev); //Log.Out("New Zombie Position: {0}, Target: {1}", zombie.pos, zombie.targetPos); if (!CanSpawnActiveZombie()) { continue; } List <PlayerZone> zones = _playerZones.FindAllByPos2D(zombie.pos); if (zones.Count <= 0) { continue; } foreach (var zone in zones) { var player = world.GetEntity(zone.entityId) as EntityPlayer; // Use players spawn border. if (zone.IsInside2D(zombie.pos)) { if (!zone.InsideSpawnArea2D(zombie.pos)) { removeZombie = true; continue; } } else { continue; } if (zone.numZombies >= maxPerZone) { #if DEBUG Log.Out("[WalkerSim] Zone {0} is full: {1} / {2}", zombie.pos, zone.numZombies, maxPerZone); #endif continue; } RequestActiveZombie(zombie, zone); activatedZombie = true; activatedZombies++; break; } // Zombie inside one or more zones will be always removed. if (activatedZombie) { removeZombie = true; } if (removeZombie) { _inactiveZombies.RemoveAt(i); i--; // If the zombie was not activated begin a new cycle. if (!activatedZombie) { RespawnInactiveZombie(zombie); } // NOTE: This should never happen. if (_inactiveZombies.Count == 0) { Log.Error("Population is empty, this should not happen."); break; } } } } #if DEBUG if (activatedZombies > 0) { Log.Out("[WalkerSim] Activated {0} zombies", activatedZombies); } #endif }