/// <summary> /// Handles when another Entity collides into us. Not synonymous CollideInto since the /// <paramref name="collider"/> Entity is the one who collided into us. For example, if the /// two entities in question were a moving Character and a stationary wall, this Entity would be /// the Wall and <paramref name="collider"/> would be the Character. /// </summary> /// <param name="collider">Entity that collided into us.</param> /// <param name="displacement">Displacement between the two Entities.</param> public override void CollideFrom(Entity collider, SFML.Graphics.Vector2 displacement) { // When a character touches this, teleport the character to the destination Character character = collider as Character; if (character == null) return; // Only let users use teleports if (character is NPC) return; // Teleport to a new map if (DestinationMap > 0) { if (character.Map.ID != DestinationMap) { var newMap = character.World.GetMap(DestinationMap); if (newMap == null) { const string errmsg = "Failed to teleport Character `{0}` - Invalid DestMap `{1}`."; Debug.Fail(string.Format(errmsg, character, this)); if (log.IsErrorEnabled) log.ErrorFormat(errmsg, character, this); return; } character.Teleport(newMap, Destination); } } // Teleport the CharacterEntity to our predefined location character.Position = Destination; }
static IEnumerable<Entity> CreateEntities(int amount, Vector2 minPos, Vector2 maxPos) { var ret = new Entity[amount]; for (var i = 0; i < amount; i++) { ret[i] = new TestEntity { Position = RandomHelper.NextVector2(minPos, maxPos) }; } return ret; }
/// <summary> /// Draws an Entity. /// </summary> /// <param name="sb"><see cref="ISpriteBatch"/> to draw to.</param> /// <param name="camera">The <see cref="ICamera2D"/> that describes the current view.</param> /// <param name="entity">Entity to draw.</param> public static void Draw(ISpriteBatch sb, ICamera2D camera, Entity entity) { WallEntityBase wallEntity; TeleportEntity teleportEntity; // Check for a different entity type if ((wallEntity = entity as WallEntityBase) != null) Draw(sb, camera, wallEntity); else if ((teleportEntity = entity as TeleportEntity) != null) Draw(sb, camera, teleportEntity); else { // Draw a normal entity using the CollisionBox Draw(sb, entity, _entityColor); } }
/// <summary> /// Activates the DamageText. /// </summary> /// <param name="damage">Damage value to display.</param> /// <param name="entity">Entity the damage was done to.</param> /// <param name="currTime">Current time.</param> public void Activate(int damage, Entity entity, TickCount currTime) { if (entity == null) { Debug.Fail("entity is null."); return; } // Set the starting values _alpha = 255; _pos = entity.Position; _lastUpdate = currTime; _text = damage.ToString(); // Get a random velocity _velocity = new Vector2(-1.0f + (float)_random.NextDouble() * 2.0f, -2.0f - (float)_random.NextDouble() * 0.25f); }
static IEnumerable<SpatialAggregate> GetSpatials(out Entity someEntity) { var aEntities = CreateEntities(64, new Vector2(32), SpatialSize - new Vector2(32)); var bEntities = CreateEntities(64, new Vector2(32), SpatialSize - new Vector2(32)); var cEntities = CreateEntities(64, new Vector2(32), SpatialSize - new Vector2(32)); someEntity = aEntities.First(); var a = new LinearSpatialCollection(); a.SetAreaSize(SpatialSize); a.Add(aEntities); var b = new DynamicGridSpatialCollection(); b.SetAreaSize(SpatialSize); b.Add(bEntities); var c = new DynamicGridSpatialCollection(); c.SetAreaSize(SpatialSize); c.Add(cEntities); return new SpatialAggregate[] { new SpatialAggregate(new ISpatialCollection[] { a, b, c }) }; }
/// <summary> /// Handles collision against other entities. /// </summary> /// <param name="collideWith">Entity the character collided with.</param> /// <param name="displacement">Displacement between the character and entity.</param> public override void CollideInto(Entity collideWith, Vector2 displacement) { }
/// <summary> /// Gets a <see cref="Rectangle"/> that describes all of the potential area that /// a ranged attack can reach. /// </summary> /// <param name="c">The <see cref="Entity"/> that is attacking.</param> /// <param name="range">The range of the attack.</param> /// <returns>A <see cref="Rectangle"/> that describes all of the potential area that /// a ranged attack can reach.</returns> public static Rectangle GetRangedAttackArea(Entity c, ushort range) { return c.ToRectangle().Inflate(range); }
/// <summary> /// Gets a <see cref="Rectangle"/> that describes all of the potential area that /// a ranged attack can reach. /// </summary> /// <param name="c">The <see cref="Entity"/> that is attacking.</param> /// <param name="range">The range of the attack.</param> /// <returns>A <see cref="Rectangle"/> that describes all of the potential area that /// a ranged attack can reach.</returns> public static Rectangle GetRangedAttackArea(Entity c, ushort range) { var vrange = new Vector2(range); var min = c.Position - vrange; var max = c.Max + vrange; return new Rectangle((int)min.X, (int)min.Y, (int)max.X, (int)max.Y); }
/// <summary> /// Creates a new <see cref="DamageText"/> and places it into the pool. /// </summary> /// <param name="damage">Damage value.</param> /// <param name="entity"><see cref="Entity"/> that was damaged.</param> /// <param name="currTime">Current time.</param> public void Create(int damage, Entity entity, TickCount currTime) { var obj = _pool.Acquire(); obj.Activate(damage, entity, currTime); }
/// <summary> /// Initializes a new instance of the <see cref="GameChatBubble"/> class. /// </summary> /// <param name="parent">The parent <see cref="Control"/>.</param> /// <param name="owner">The <see cref="Entity"/> that this <see cref="ChatBubble"/> is for.</param> /// <param name="text">The text to display.</param> public GameChatBubble(Control parent, Entity owner, string text) : base(parent, owner, text) { }
/// <summary> /// Handles collision for when this wall is a wall. /// </summary> /// <param name="map">The map that the <see cref="WallEntityBase"/> is on.</param> /// <param name="other">The <see cref="Entity"/> that collided into this <see cref="WallEntityBase"/>.</param> /// <param name="displacement">The minimum transitional displacement to move the <paramref name="other"/> /// to make it no longer overlap this wall.</param> void HandleCollideIntoWall(IMap map, Entity other, Vector2 displacement) { var displaced = false; #if !TOPDOWN // Allow entities to walk up very small inclines. Makes no sense in top-down, so its used in sidescroller only. // Check if we have a displacement just on the X axis if (displacement.Y == 0) { // Check how far the "other" is from being on top of "this" var distFromThis = other.Max.Y - Position.Y; // If they are not that far away from being on top of "this", then instead of displacing them horizontally away // from us, pop them up on top of us, effectively "stepping" up if (distFromThis > 0 && distFromThis < _maxWallStepUpHeight) { var horizontalOffset = (int)distFromThis + 1; var otherRect = other.ToRectangle(); otherRect.Y -= horizontalOffset; // Make sure that if we move them up on top of us, that they will not be colliding with any walls. If they will // be colliding with any walls, do NOT let them up here if (!map.Spatial.Contains<WallEntityBase>(otherRect, x => !x.IsPlatform)) { other.Move(new Vector2(0, -horizontalOffset)); displaced = true; } } } #endif // Move the other entity away from the wall using the MTD if (!displaced) other.Move(displacement); // Check for vertical collision if (displacement.Y != 0) { if (other.Velocity.Y >= 0 && displacement.Y < 0) { // Collision from falling (land on feet) other.SetVelocity(new Vector2(other.Velocity.X, 0.0f)); other.StandingOn = this; } else if (other.Velocity.Y < 0 && displacement.Y > 0) { // Collision from rising (hit head) other.SetVelocity(new Vector2(other.Velocity.X, 0.0f)); } } }
/// <summary> /// Handles collision for when this wall is a platform. /// </summary> /// <param name="other">The <see cref="Entity"/> that collided into this <see cref="WallEntityBase"/>.</param> /// <param name="displacement">The minimum transitional displacement to move the <paramref name="other"/> /// to make it no longer overlap this wall.</param> void HandleCollideIntoPlatform(Entity other, Vector2 displacement) { if (other.Velocity.Y <= 0 || displacement.Y >= 0 || ((other.LastPosition.Y + other.Size.Y) > Position.Y + _platformYPositionLeniency)) return; // Move the other entity away from the wall displacement.X = 0; other.Move(displacement); // Collision from falling (land on feet) other.SetVelocity(new Vector2(other.Velocity.X, 0.0f)); other.StandingOn = this; }
/// <summary> /// Performs the collision handling for an <see cref="Entity"/> colliding into this <see cref="WallEntityBase"/>. /// </summary> /// <param name="map">The map that the <see cref="WallEntityBase"/> is on.</param> /// <param name="other">The <see cref="Entity"/> that collided into this <see cref="WallEntityBase"/>.</param> /// <param name="displacement">The minimum transitional displacement to move the <paramref name="other"/> /// to make it no longer overlap this wall.</param> public void HandleCollideInto(IMap map, Entity other, Vector2 displacement) { Debug.Assert(map != null); Debug.Assert(other != null); if (IsPlatform) HandleCollideIntoPlatform(other, displacement); else HandleCollideIntoWall(map, other, displacement); }
/// <summary> /// Handles when another Entity collides into us. Not synonymous CollideInto since the /// <paramref name="collider"/> Entity is the one who collided into us. For example, if the /// two entities in question were a moving Character and a stationary wall, this Entity would be /// the Wall and <paramref name="collider"/> would be the Character. /// </summary> /// <param name="collider">Entity that collided into us.</param> /// <param name="displacement">Displacement between the two Entities.</param> public override void CollideFrom(Entity collider, SFML.Graphics.Vector2 displacement) { // When a character touches this, teleport the character to the destination User character = collider as User; if (character == null) return; // Teleport to a new map if (DestinationMap > 0) { if (character.Map.ID != DestinationMap) { var newMap = character.World.GetMap(DestinationMap); if (newMap == null) { const string errmsg = "Failed to teleport Character `{0}` - Invalid DestMap `{1}`."; Debug.Fail(string.Format(errmsg, character, this)); if (log.IsErrorEnabled) log.ErrorFormat(errmsg, character, this); return; } // Teleport the CharacterEntity to our predefined location character.Teleport(newMap, Destination); character.Position = Destination; } } // Teleport to an instanced map else if (DestinationMapInstance > 0) { // Check for a valid map var newMapInstance = character.World.GetMap(DestinationMapInstance); if (newMapInstance == null) { const string errmsg = "Failed to teleport Character `{0}` - Invalid DestMap Instance `{1}`."; Debug.Fail(string.Format(errmsg, character, this)); if (log.IsErrorEnabled) log.ErrorFormat(errmsg, character, this); return; } // Try to create the map MapInstance instance; try { instance = new MapInstance(newMapInstance.ID, character.World); } catch (System.Exception ex) { string errmsg = "Failed to create instance: " + ex; Debug.Fail(errmsg); if (log.IsErrorEnabled) log.ErrorFormat(errmsg); return; } // Check if the map placement is valid if (instance.IsValidPlacementPosition(Destination, character.Size)) { // Add the user to the map character.Teleport(instance, Destination); character.Position = Destination; } else { string errmsg = "Failed to create instance: Not a valid map placement."; Debug.Fail(errmsg); if (log.IsErrorEnabled) log.ErrorFormat(errmsg); return; } // Does this entity also teleport group members? if (TeleportGroupMembers) { // Check if the user is in a group if (character.Group == null) return; if (!character.Group.Members.IsEmpty()) { // If yes, teleport those users too foreach (var groupMember in character.Group.Members.OfType<User>()) { groupMember.Teleport(instance, Destination); groupMember.Position = Destination; } } } } }
public static void Test(ActionDisplay actionDisplay, IMap map, Entity source, Entity target) { i = 50; }