/// <summary> /// Marks all nodes under <see cref="Water"/> deeper than <see cref="Water.TraversableDepth"/> /// </summary> private void MarkUntraversableWaters(bool[,] obstructionMap) { foreach (var water in Positionables.OfType <Water>()) { var xStart = (int)Math.Floor(water.Position.X / Terrain.Size.StretchH); var xEnd = (int)Math.Ceiling((water.Position.X + water.Size.X) / Terrain.Size.StretchH); var yStart = (int)Math.Floor(water.Position.Y / Terrain.Size.StretchH); var yEnd = (int)Math.Ceiling((water.Position.Y + water.Size.Y) / Terrain.Size.StretchH); if (xEnd > Terrain.Size.X - 1) { xEnd = Terrain.Size.X - 1; } if (yEnd > Terrain.Size.Y - 1) { yEnd = Terrain.Size.Y - 1; } for (int x = xStart; x <= xEnd; x++) { for (int y = yStart; y <= yEnd; y++) { obstructionMap[x, y] |= (Terrain.HeightMap[x, y] * Terrain.Size.StretchV) < (water.Height - water.TraversableDepth); } } } }
/// <summary> /// Moves <see cref="Waypoint"/> from <see cref="Entity.Waypoints"/> to <see cref="UniverseBase{TCoordinates}.Positionables"/>. /// Call to prepare for editing. /// </summary> public void UnwrapWaypoints() { foreach (var entity in Positionables.OfType <Entity>().ToList()) { Positionables.AddMany(entity.Waypoints.Cast <Positionable <Vector2> >()); entity.Waypoints.Clear(); } }
/// <inheritdoc/> public virtual void Update(double elapsedGameTime) { GameTime += elapsedGameTime; foreach (var updateable in Positionables.OfType <IUpdateable>()) { Update(updateable, elapsedGameTime); } }
/// <summary> /// Marks all nodes blocked by <see cref="Entity"/>s with no <see cref="Movement"/>. /// </summary> private void MarkUnmoveableEntities(bool[,] obstructionMap) { foreach (var entity in Positionables.OfType <Entity>().Where(x => x.TemplateData.Movement == null && x.TemplateData.Collision != null)) { for (int x = 0; x < obstructionMap.GetLength(0); x++) { for (int y = 0; y < obstructionMap.GetLength(1); y++) { obstructionMap[x, y] |= entity.CollisionTest(new Vector2(x, y) * Terrain.Size.StretchH); } } } }
/// <summary> /// Turns all <see cref="Entity"/>s into NPCs. /// </summary> public void MakeAllNpc() { foreach (var entity in Positionables.OfType <Entity>().Where(x => x.IsPlayerControlled)) { entity.IsPlayerControlled = false; // Prevent characters from finishing last pathfinding command after player control was removed foreach (var openWaypoint in entity.Waypoints.Where(x => !x.ArrivalTimeSpecified)) { openWaypoint.ArrivalTime = GameTime; openWaypoint.Position = entity.Position; } } }
/// <summary> /// Turns a specific <see cref="Entity"/> into a player-controlled character. /// </summary> public void MakePlayerControlled(string name) { var entity = GetEntity(name); // Remove any recorded paths entity.Waypoints.RemoveAll(x => (x.ArrivalTimeSpecified ? x.ArrivalTime : x.ActivationTime) >= GameTime); entity.CurrentPath = null; // Reactivates all associated triggers foreach (var trigger in Positionables.OfType <Trigger>() .Where(x => x.TargetEntity == name && x.DueTime > GameTime)) { trigger.WasTriggered = false; } entity.IsPlayerControlled = true; }
/// <summary> /// Moves <see cref="Waypoint"/> from <see cref="UniverseBase{TCoordinates}.Positionables"/> to <see cref="Entity.Waypoints"/>. /// Call to prepare for gameplay. /// </summary> private void WrapWaypoints() { var toRemove = new List <Waypoint>(); foreach (var waypoint in Positionables.OfType <Waypoint>().OrderBy(x => x.ActivationTime)) { var entity = GetEntity(waypoint.TargetEntity); if (entity != null) { entity.Waypoints.Add(waypoint); toRemove.Add(waypoint); } } foreach (var waypoint in toRemove) { Positionables.Remove(waypoint); } }