private static void DrawEntities(List<Guid> drawableEntities, StateSpaceComponents spaceComponents, DungeonTile[,] dungeonGrid, Matrix cameraMatrix, bool inWater, bool inFire, SpriteBatch spriteBatch, Texture2D spriteSheet, SpriteFont font, Camera camera, DungeonColorInfo colorInfo) { foreach (Guid id in drawableEntities) { DisplayComponent display = spaceComponents.DisplayComponents[id]; Vector2 gridPos = spaceComponents.PositionComponents[id].Position; Vector2 position = new Vector2(spaceComponents.PositionComponents[id].Position.X * DevConstants.Grid.CellSize, spaceComponents.PositionComponents[id].Position.Y * DevConstants.Grid.CellSize); if (dungeonGrid[(int)spaceComponents.PositionComponents[id].Position.X, (int)spaceComponents.PositionComponents[id].Position.Y].InRange || display.AlwaysDraw) { Vector2 bottomRight = Vector2.Transform(new Vector2((position.X) + DevConstants.Grid.CellSize, (position.Y) + DevConstants.Grid.CellSize), cameraMatrix); Vector2 topLeft = Vector2.Transform(new Vector2(position.X, position.Y), cameraMatrix); Rectangle cameraBounds = new Rectangle((int)topLeft.X, (int)topLeft.Y, (int)bottomRight.X - (int)topLeft.X, (int)bottomRight.Y - (int)topLeft.Y); if (camera.IsInView(cameraMatrix, cameraBounds)) { //If the item is in water, you need to tint it, and if the player is in water and the object isn't (or vice versa) it must be hidden unless it's the observer. display = dungeonGrid[(int)gridPos.X, (int)gridPos.Y].Type == TileType.TILE_WATER == inWater || (spaceComponents.Entities.Where(x => (x.Id == id)).First().ComponentFlags & ComponentMasks.Observer) == ComponentMasks.Observer ? display : DevConstants.ConstantComponents.UnknownDisplay; Color displayColor = dungeonGrid[(int)gridPos.X, (int)gridPos.Y].Type == TileType.TILE_WATER || inWater ? Color.Lerp(display.Color, colorInfo.WaterInRange, .5f) : display.Color; if(!inWater && dungeonGrid[(int)gridPos.X, (int)gridPos.Y].Type != TileType.TILE_WATER) { displayColor = dungeonGrid[(int)gridPos.X, (int)gridPos.Y].FireIllumination || inFire ? Color.Lerp(display.Color, colorInfo.FireInRange, .5f) : display.Color; } spriteBatch.Draw(spriteSheet, position, display.SpriteSource, displayColor * display.Opacity, display.Rotation, display.Origin, display.Scale, display.SpriteEffect, 0f); if (!string.IsNullOrEmpty(display.Symbol)) { Vector2 size = font.MeasureString(display.Symbol); spriteBatch.DrawString(font, display.Symbol, new Vector2(((int)position.X + (int)display.SpriteSource.Center.X), ((int)position.Y + (int)display.SpriteSource.Center.Y)), display.SymbolColor, 0f, new Vector2((int)(size.X / 2), (int)(size.Y / 2) - 3), 1f, SpriteEffects.None, 0f); } } } } }
public static void DrawDungeonEntities(StateSpaceComponents spaceComponents, Camera camera, SpriteBatch spriteBatch, int cellSize) { IEnumerable<Guid> drawableEntities = spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.Drawable) == ComponentMasks.Drawable).Select(x => x.Id); foreach(Guid id in drawableEntities) { spriteBatch.Draw(spaceComponents.DisplayComponents[id].Texture, new Vector2(spaceComponents.PositionComponents[id].Position.X * cellSize, spaceComponents.PositionComponents[id].Position.Y * cellSize), spaceComponents.DisplayComponents[id].Color); } }
/// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { // TODO: Add your initialization logic here this.IsMouseVisible = true; Window.AllowUserResizing = true; graphics.PreferredBackBufferWidth = (int)_initialSize.X; graphics.PreferredBackBufferHeight = (int)_initialSize.Y; graphics.ApplyChanges(); gameCamera = new Camera(Vector2.Zero, Vector2.Zero, 0.0f, _initialScale, graphics); base.Initialize(); }
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); gameCamera = new Camera(Vector2.Zero, Vector2.Zero, 0.0f, gameSettings.Scale, graphics); this.IsMouseVisible = true; this.Window.IsBorderless = gameSettings.Borderless; Window.AllowUserResizing = false; this.ResetGameSettings(); currentState = new TitleState(gameCamera, Content, graphics); debugText = Content.Load<SpriteFont>("Fonts/InfoText"); }
public static void DrawString(SpriteBatch spriteBatch, StateSpaceComponents spaceComponents, SpriteFont font, Camera camera) { Matrix cameraMatrix = camera.GetMatrix(); foreach (Guid id in spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.DrawableLabel) == ComponentMasks.DrawableLabel).Select(x => x.Id)) { LabelComponent label = spaceComponents.LabelComponents[id]; Vector2 position = new Vector2(spaceComponents.PositionComponents[id].Position.X, spaceComponents.PositionComponents[id].Position.Y); Vector2 stringSize = font.MeasureString(label.Text); Vector2 bottomRight = Vector2.Transform(new Vector2(position.X + stringSize.X, position.Y + stringSize.Y), cameraMatrix); Vector2 topLeft = Vector2.Transform(new Vector2(position.X, position.Y), cameraMatrix); Rectangle cameraBounds = new Rectangle((int)topLeft.X, (int)topLeft.Y, (int)bottomRight.X - (int)topLeft.X, (int)bottomRight.Y - (int)topLeft.Y); if (camera.IsInView(cameraMatrix, cameraBounds)) { spriteBatch.DrawString(font, label.Text, position, label.Color, label.Rotation, label.Origin, label.Scale, label.SpriteEffect, 0f); } } }
public static void DrawDungeonEntities(StateSpaceComponents spaceComponents, Camera camera, SpriteBatch spriteBatch, Texture2D spriteSheet, int cellSize, DungeonTile[,] dungeonGrid, SpriteFont font, DungeonColorInfo colorInfo) { Matrix cameraMatrix = camera.GetMatrix(); List<Entity> drawableEntities = spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.Drawable) == ComponentMasks.Drawable).ToList(); Entity player = spaceComponents.Entities.Where(c => (c.ComponentFlags & ComponentMasks.Player) == ComponentMasks.Player).FirstOrDefault(); bool inWater = false; bool inFire = false; if (player != null) { Vector2 playerPos = spaceComponents.PositionComponents[spaceComponents.Entities.Where(c => (c.ComponentFlags & ComponentMasks.Player) == ComponentMasks.Player).First().Id].Position; inWater = dungeonGrid[(int)playerPos.X, (int)playerPos.Y].Type == TileType.TILE_WATER; inFire = dungeonGrid[(int)playerPos.X, (int)playerPos.Y].Type == TileType.TILE_FIRE; } //Draw items List<Guid> items = drawableEntities.Where(x => (x.ComponentFlags & ComponentMasks.PickupItem) == ComponentMasks.PickupItem).Select(x => x.Id).ToList(); DisplaySystem.DrawEntities(items, spaceComponents, dungeonGrid, cameraMatrix, inWater, inFire, spriteBatch, spriteSheet, font, camera, colorInfo); //Draw everything else List<Guid> nonItems = drawableEntities.Where(x => (x.ComponentFlags & ComponentMasks.PickupItem) != ComponentMasks.PickupItem).Select(x => x.Id).ToList(); DisplaySystem.DrawEntities(nonItems, spaceComponents, dungeonGrid, cameraMatrix, inWater, inFire, spriteBatch, spriteSheet, font, camera, colorInfo); }
public static void UpdateCamera(Camera camera, GameTime gameTime, StateSpaceComponents stateSpaceComponents, int cellSize, KeyboardState prevKey) { if (Mouse.GetState().RightButton == ButtonState.Pressed) { MessageDisplaySystem.SetRandomGlobalMessage(stateSpaceComponents, Messages.CameraDetatchedMessage); camera.Target = Vector2.Transform(Mouse.GetState().Position.ToVector2(), camera.GetInverseMatrix()); camera.AttachedToPlayer = false; } if (Keyboard.GetState().IsKeyDown(Keys.W)) { camera.AttachedToPlayer = false; camera.Position.Y -= camera.Velocity.Y * (float)gameTime.ElapsedGameTime.TotalSeconds; camera.Target = camera.Position; MessageDisplaySystem.SetRandomGlobalMessage(stateSpaceComponents, Messages.CameraDetatchedMessage); } if (Keyboard.GetState().IsKeyDown(Keys.A)) { camera.AttachedToPlayer = false; camera.Position.X -= camera.Velocity.X * (float)gameTime.ElapsedGameTime.TotalSeconds; camera.Target = camera.Position; MessageDisplaySystem.SetRandomGlobalMessage(stateSpaceComponents, Messages.CameraDetatchedMessage); } if (Keyboard.GetState().IsKeyDown(Keys.S)) { camera.AttachedToPlayer = false; camera.Position.Y += camera.Velocity.Y * (float)gameTime.ElapsedGameTime.TotalSeconds; camera.Target = camera.Position; MessageDisplaySystem.SetRandomGlobalMessage(stateSpaceComponents, Messages.CameraDetatchedMessage); } if (Keyboard.GetState().IsKeyDown(Keys.D)) { camera.AttachedToPlayer = false; camera.Position.X += camera.Velocity.X * (float)gameTime.ElapsedGameTime.TotalSeconds; camera.Target = camera.Position; MessageDisplaySystem.SetRandomGlobalMessage(stateSpaceComponents, Messages.CameraDetatchedMessage); } if(Keyboard.GetState().IsKeyDown(Keys.OemPlus) && prevKey.IsKeyUp(Keys.OemPlus)) { if(camera.Scale + .25f < 4.25f) { camera.Scale += .25f; } } if (Keyboard.GetState().IsKeyDown(Keys.OemMinus) && prevKey.IsKeyUp(Keys.OemMinus)) { if (camera.Scale - .25f > 0f) { camera.Scale -= .25f; } } if (Keyboard.GetState().IsKeyDown(Keys.R)) { camera.AttachedToPlayer = true; MessageDisplaySystem.SetRandomGlobalMessage(stateSpaceComponents, new string[] { string.Empty }); } if (camera.AttachedToPlayer) { Entity playerId = stateSpaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.Player) == ComponentMasks.Player).FirstOrDefault(); if(stateSpaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.Observer) == ComponentMasks.Observer).FirstOrDefault() != null) { playerId = stateSpaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.Observer) == ComponentMasks.Observer).FirstOrDefault(); } if (playerId != null) { camera.Target = new Vector2((int)stateSpaceComponents.PositionComponents[playerId.Id].Position.X * cellSize + stateSpaceComponents.DisplayComponents[playerId.Id].SpriteSource.Width / 2, (int)stateSpaceComponents.PositionComponents[playerId.Id].Position.Y * cellSize + stateSpaceComponents.DisplayComponents[playerId.Id].SpriteSource.Height / 2); } if (stateSpaceComponents.PlayerComponent.PlayerJustLoaded) { camera.Position = new Vector2((int)stateSpaceComponents.PositionComponents[playerId.Id].Position.X * cellSize + stateSpaceComponents.DisplayComponents[playerId.Id].SpriteSource.Width / 2, (int)stateSpaceComponents.PositionComponents[playerId.Id].Position.Y * cellSize + stateSpaceComponents.DisplayComponents[playerId.Id].SpriteSource.Height / 2); } } if (Vector2.Distance(camera.Position, camera.Target) > 0) { float distance = Vector2.Distance(camera.Position, camera.Target); Vector2 direction = Vector2.Normalize(camera.Target - camera.Position); float velocity = distance * 2.5f; if (distance > 10f) { camera.Position += direction * velocity * (camera.Scale >= 1 ? camera.Scale : 1) * (float)gameTime.ElapsedGameTime.TotalSeconds; } } }
public static void PrintObserver(StateSpaceComponents spaceComponents, SpriteFont font, SpriteBatch spriteBatch, DungeonTile[,] dungeonGrid, Camera camera, Texture2D UITexture) { ObserverComponent observer = spaceComponents.ObserverComponent; Entity observerInfo = spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.Observer) == ComponentMasks.Observer).FirstOrDefault(); if(observerInfo != null) { //Find out where the observer is PositionComponent observerPosition = spaceComponents.PositionComponents[observerInfo.Id]; //Obtain the list of entities from the observer component List<Entity> observedItems = new List<Entity>(); foreach (Guid id in observer.Observed) { Entity entity = spaceComponents.Entities.Where(x => x.Id == id).FirstOrDefault(); if (entity != null) { observedItems.Add(entity); } } //Set the initial variables int messageSpacing = (int)font.MeasureString("g").Y + 1; int messageLeft = 0; int messageRight = 0; int panelWidth = (int)((camera.DungeonViewport.Width / 2) - (DevConstants.Grid.CellSize * 2)); List<Tuple<Color, string>> leftFindings = new List<Tuple<Color, string>>(); List<Tuple<Color, string>> rightFindings = new List<Tuple<Color, string>>(); //Gather information for the left side if (!dungeonGrid[(int)observerPosition.Position.X, (int)observerPosition.Position.Y].Found) { leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Bad, Messages.Observer.NotFound)); } else { if (dungeonGrid[(int)observerPosition.Position.X, (int)observerPosition.Position.Y].InRange) { leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Good, Messages.Observer.InRange)); } else { leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Bad, Messages.Observer.OutOfRange)); } leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); switch (dungeonGrid[(int)observerPosition.Position.X, (int)observerPosition.Position.Y].Type) { case TileType.TILE_FLOOR: leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, Messages.Observer.Floor)); break; case TileType.TILE_WALL: leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, Messages.Observer.Wall)); break; case TileType.TILE_ROCK: leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, Messages.Observer.Rock)); break; case TileType.TILE_WATER: leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, Messages.Observer.Water)); break; case TileType.TILE_TALLGRASS: leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, Messages.Observer.TallGrass)); break; case TileType.TILE_FLATTENEDGRASS: leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, Messages.Observer.FlatGrass)); break; case TileType.TILE_FIRE: leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, Messages.Observer.Fire)); break; case TileType.TILE_ASH: leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, Messages.Observer.Ash)); break; } } if(observer.SeeUnknown) { leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, Messages.Observer.Unknown)); } if(observer.Observed.Count > 0) { leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); leftFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, "From here you can see the following: ")); } //Gather observed names for the left side foreach(Entity en in observedItems) { string prepend = (en.Id == observer.SelectedItem) ? "> " : string.Empty; Color color = (en.Id == observer.SelectedItem) ? Colors.Messages.LootPickup : Colors.Messages.Normal; leftFindings.Add(new Tuple<Color, string>(color, prepend + spaceComponents.NameComponents[en.Id].Name)); } //Gather information for right side Entity selectedEntity = spaceComponents.Entities.Where(x => x.Id == observer.SelectedItem).FirstOrDefault(); if(selectedEntity != null) { if (spaceComponents.NameComponents[selectedEntity.Id].Name == "You") { rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("You see yourself here."))); } else { rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, spaceComponents.NameComponents[selectedEntity.Id].Name)); } rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, spaceComponents.NameComponents[selectedEntity.Id].Description)); //If the finding is an AI, gather the information for it if((selectedEntity.ComponentFlags & ComponentMasks.ObservableAI) == ComponentMasks.ObservableAI) { AIState state = spaceComponents.AIStateComponents[selectedEntity.Id]; AIAlignment alignment = spaceComponents.AIAlignmentComponents[selectedEntity.Id]; SkillLevelsComponent skills = spaceComponents.SkillLevelsComponents[selectedEntity.Id]; switch (alignment.Alignment) { case AIAlignments.ALIGNMENT_NONE: rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, "Neutral")); break; case AIAlignments.ALIGNMENT_HOSTILE: rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Bad, "Hostile")); break; case AIAlignments.ALIGNMENT_FRIENDLY: rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Good, "Friendly")); break; } switch (state.State) { case AIStates.STATE_SLEEPING: rightFindings.Add(new Tuple<Color, string>(Colors.Messages.StatusChange, "Sleeping")); break; case AIStates.STATE_ROAMING: rightFindings.Add(new Tuple<Color, string>(Colors.Messages.StatusChange, "Roaming")); break; case AIStates.STATE_ATTACKING: rightFindings.Add(new Tuple<Color, string>(Colors.Messages.StatusChange, "Attacking")); break; case AIStates.STATE_FLEEING: rightFindings.Add(new Tuple<Color, string>(Colors.Messages.StatusChange, "Fleeing")); break; } //Status Effects: Statuses statuses = StatusSystem.GetStatusEffectsOfEntity(spaceComponents, selectedEntity.Id, dungeonGrid); if (statuses == Statuses.NONE) { rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, Messages.StatusMessages.Normal)); rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); } //If there are status effects on the player.. else { if ((statuses & Statuses.BURNING) == Statuses.BURNING) { BurningComponent burning = spaceComponents.BurningComponents[selectedEntity.Id]; rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Bad, string.Format(Messages.StatusMessages.Burning, burning.MinDamage, burning.MaxDamage, burning.TurnsLeft))); } if ((statuses & Statuses.UNDERWATER) == Statuses.UNDERWATER) { rightFindings.Add(new Tuple<Color, string>(Colors.Caves.WaterInRange, Messages.StatusMessages.Underwater)); } if ((statuses & Statuses.HEALTHREGEN) == Statuses.HEALTHREGEN) { HealthRegenerationComponent healthRegen = spaceComponents.HealthRegenerationComponents[selectedEntity.Id]; rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Good, string.Format(Messages.StatusMessages.HealthRegen, healthRegen.HealthRegain, healthRegen.RegenerateTurnRate))); } rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); } Entity player = spaceComponents.Entities.Where(x => (x.ComponentFlags & Component.COMPONENT_PLAYER) == Component.COMPONENT_PLAYER).First(); rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Health: {0} / {1}", skills.CurrentHealth, skills.Health))); if (alignment.Alignment != AIAlignments.ALIGNMENT_FRIENDLY) { rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Good, string.Format("You have a {0}% chance to hit.", Math.Ceiling(CombatSystem.CalculateAccuracy(spaceComponents, spaceComponents.SkillLevelsComponents[player.Id], player.Id, skills, selectedEntity.Id))))); rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Bad, string.Format("It has a {0}% chance of hitting you for a maximum of {1}.", Math.Ceiling(CombatSystem.CalculateAccuracy(spaceComponents, skills, selectedEntity.Id, spaceComponents.SkillLevelsComponents[player.Id], player.Id)), skills.MaximumDamage))); } } //If the observed item is an item, gather that information instead if ((selectedEntity.ComponentFlags & ComponentMasks.ObservableItem) == ComponentMasks.ObservableItem) { rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); PickupComponent pickup = spaceComponents.PickupComponents[selectedEntity.Id]; switch (pickup.PickupType) { case ItemType.GOLD: rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Special, "Gold")); break; case ItemType.CONSUMABLE: rightFindings.Add(new Tuple<Color, string>(Colors.Messages.LootPickup, "Consumable")); break; case ItemType.ARTIFACT: rightFindings.Add(new Tuple<Color, string>(Colors.Messages.LootPickup, "Artifact")); break; } if((selectedEntity.ComponentFlags & ComponentMasks.ObservableValue) == ComponentMasks.ObservableValue && pickup.PickupType != ItemType.DOWNSTAIRS) { ValueComponent value = spaceComponents.ValueComponents[selectedEntity.Id]; rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Special, string.Format("This item is worth {0} gold.", value.Gold))); } if ((selectedEntity.ComponentFlags & ComponentMasks.ObservableSkillModifications) == ComponentMasks.ObservableSkillModifications) { StatModificationComponent stats = spaceComponents.StatModificationComponents[selectedEntity.Id]; rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, "This artifact affects the following stats: ")); if (stats.AccuracyChange != 0) { string sign = stats.AccuracyChange > 0 ? "+" : string.Empty; Color color = stats.AccuracyChange > 0 ? Colors.Messages.Good : Colors.Messages.Bad; rightFindings.Add(new Tuple<Color, string>(color, string.Format("Accuracy {0}{1}", sign, stats.AccuracyChange))); } if (stats.DefenseChange != 0) { string sign = stats.DefenseChange > 0 ? "+" : string.Empty; Color color = stats.DefenseChange > 0 ? Colors.Messages.Good : Colors.Messages.Bad; rightFindings.Add(new Tuple<Color, string>(color, string.Format("Defense {0}{1}", sign, stats.DefenseChange))); } if (stats.HealthChange != 0) { string sign = stats.HealthChange > 0 ? "+" : string.Empty; Color color = stats.HealthChange > 0 ? Colors.Messages.Good : Colors.Messages.Bad; rightFindings.Add(new Tuple<Color, string>(color, string.Format("Maximum Health {0}{1}", sign, stats.HealthChange))); } if (stats.DieNumberChange != 0) { string sign = stats.DieNumberChange > 0 ? "+" : string.Empty; Color color = stats.DieNumberChange > 0 ? Colors.Messages.Good : Colors.Messages.Bad; rightFindings.Add(new Tuple<Color, string>(color, string.Format("Dice Number on Attack {0}{1}", sign, stats.DieNumberChange))); } if (stats.MinimumDamageChange != 0) { string sign = stats.MinimumDamageChange > 0 ? "+" : string.Empty; Color color = stats.MinimumDamageChange > 0 ? Colors.Messages.Good : Colors.Messages.Bad; rightFindings.Add(new Tuple<Color, string>(color, string.Format("Minimum Damage {0}{1}", sign, stats.MinimumDamageChange))); } if (stats.MaximumDamageChange != 0) { string sign = stats.MaximumDamageChange > 0 ? "+" : string.Empty; Color color = stats.MaximumDamageChange > 0 ? Colors.Messages.Good : Colors.Messages.Bad; rightFindings.Add(new Tuple<Color, string>(color, string.Format("Maximum Damage {0}{1}", sign, stats.MaximumDamageChange))); } } if((selectedEntity.ComponentFlags & ComponentMasks.ObservableUsage) == ComponentMasks.ObservableUsage) { ItemFunctionsComponent funcs = spaceComponents.ItemFunctionsComponents[selectedEntity.Id]; rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Good, string.Format("This item has {0} uses left.", funcs.Uses))); rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Bad, string.Format("This item loses {0} value per use.", funcs.CostToUse))); if(funcs.Ranged) { rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, "This item is cast at a range.")); } else { rightFindings.Add(new Tuple<Color, string>(Colors.Messages.Normal, "This item is used where you stand.")); } } } } //Draw sections //Left section spriteBatch.Draw(UITexture, new Rectangle(0, 0, panelWidth, (int)camera.DungeonViewport.Height), Color.Black * .5f); foreach (Tuple<Color, string> message in leftFindings) { if (string.IsNullOrEmpty(message.Item2)) { continue; } string text = MessageDisplaySystem.WordWrap(font, message.Item2, panelWidth - messageSpacing); float textHeight = font.MeasureString(message.Item2).Y; spriteBatch.DrawString(font, text, new Vector2(messageSpacing, messageSpacing + (messageLeft * messageSpacing)), message.Item1); messageLeft += Regex.Matches(text, System.Environment.NewLine).Count; messageLeft += 1; } //Right section if (observer.Observed.Count > 0) { spriteBatch.Draw(UITexture, new Rectangle((int)camera.DungeonViewport.Bounds.Right - panelWidth, 0, panelWidth, (int)camera.DungeonViewport.Height), Color.Black * .5f); foreach (Tuple<Color, string> message in rightFindings) { if (string.IsNullOrEmpty(message.Item2)) { continue; } string text = MessageDisplaySystem.WordWrap(font, message.Item2, panelWidth - messageSpacing); float textHeight = font.MeasureString(message.Item2).Y; spriteBatch.DrawString(font, text, new Vector2((int)camera.DungeonViewport.Bounds.Right - panelWidth + messageSpacing, messageSpacing + (messageRight * messageSpacing)), message.Item1); messageRight += Regex.Matches(text, System.Environment.NewLine).Count; messageRight += 1; } } } }
public static void HandleDungeonMovement(StateSpaceComponents spaceComponents, GraphicsDeviceManager graphics, GameTime gameTime, KeyboardState prevKeyboardState, MouseState prevMouseState, GamePadState prevGamepadState, Camera camera, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions) { IEnumerable<Guid> movableEntities = spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.InputMoveable) == ComponentMasks.InputMoveable).Select(x => x.Id); foreach(Guid id in movableEntities) { bool hitWall = false; bool movement = false; KeyboardState keyState = Keyboard.GetState(); PositionComponent pos = spaceComponents.PositionComponents[id]; GameplayInfoComponent gameInfo = spaceComponents.GameplayInfoComponent; InputMovementComponent movementComponent = spaceComponents.InputMovementComponents[id]; if (keyState.IsKeyDown(Keys.NumPad8)) { movement = InputMovementSystem.CalculateMovement(ref pos, 0, -1, ref movementComponent, gameTime, Keys.NumPad8); } else if (keyState.IsKeyDown(Keys.NumPad2)) { movement = InputMovementSystem.CalculateMovement(ref pos, 0, 1, ref movementComponent, gameTime, Keys.NumPad2); } else if (keyState.IsKeyDown(Keys.NumPad6)) { movement = InputMovementSystem.CalculateMovement(ref pos, 1, 0, ref movementComponent, gameTime, Keys.NumPad6); } else if (keyState.IsKeyDown(Keys.NumPad4)) { movement = InputMovementSystem.CalculateMovement(ref pos, -1, 0, ref movementComponent, gameTime, Keys.NumPad4); } else if (keyState.IsKeyDown(Keys.NumPad5)) { movement = InputMovementSystem.CalculateMovement(ref pos, 0, 0, ref movementComponent, gameTime, Keys.NumPad4); } else if (keyState.IsKeyDown(Keys.NumPad7)) { movement = InputMovementSystem.CalculateMovement(ref pos, -1, -1, ref movementComponent, gameTime, Keys.NumPad7); } else if (keyState.IsKeyDown(Keys.NumPad9)) { movement = InputMovementSystem.CalculateMovement(ref pos, 1, -1, ref movementComponent, gameTime, Keys.NumPad9); } else if (keyState.IsKeyDown(Keys.NumPad1)) { movement = InputMovementSystem.CalculateMovement(ref pos, -1, 1, ref movementComponent, gameTime, Keys.NumPad1); } else if (keyState.IsKeyDown(Keys.NumPad3)) { movement = InputMovementSystem.CalculateMovement(ref pos, 1, 1, ref movementComponent, gameTime, Keys.NumPad3); } #region Item else if (keyState.IsKeyDown(Keys.Q) && prevKeyboardState.IsKeyUp(Keys.Q)) { if(spaceComponents.InventoryComponents.ContainsKey(id)) { InventoryComponent invo = spaceComponents.InventoryComponents[id]; if (invo.Consumables.Count > 0) { ItemFunctionsComponent funcs = spaceComponents.ItemFunctionsComponents[invo.Consumables[0]]; InventorySystem.UseItem(spaceComponents, dungeonGrid, dungeonDimensions, invo.Consumables[0], id); } } } else if (keyState.IsKeyDown(Keys.E) && prevKeyboardState.IsKeyUp(Keys.E)) { if (spaceComponents.InventoryComponents.ContainsKey(id)) { InventoryComponent invo = spaceComponents.InventoryComponents[id]; if(invo.Consumables.Count > 1) { ItemFunctionsComponent funcs = spaceComponents.ItemFunctionsComponents[invo.Consumables[1]]; InventorySystem.UseItem(spaceComponents, dungeonGrid, dungeonDimensions, invo.Consumables[1], id); } } } #endregion #region debug else if (keyState.IsKeyDown(Keys.OemPeriod) && prevKeyboardState.IsKeyUp(Keys.OemPeriod)) { TileSystem.CreateFire((int)pos.Position.X, (int)pos.Position.Y, spaceComponents, dungeonGrid); } #endregion //else if (keyState.IsKeyDown(Keys.Z) && prevKeyboardState.IsKeyUp(Keys.Z)) //{ // SightRadiusComponent radius = spaceComponents.SightRadiusComponents[id]; // radius.CurrentRadius -= 1; // spaceComponents.SightRadiusComponents[id] = (radius.CurrentRadius <= 0) ? spaceComponents.SightRadiusComponents[id] : radius; // movement = true; //} //else if (keyState.IsKeyDown(Keys.X) && prevKeyboardState.IsKeyUp(Keys.X)) //{ // SightRadiusComponent radius = spaceComponents.SightRadiusComponents[id]; // radius.CurrentRadius += 1; // spaceComponents.SightRadiusComponents[id] = (radius.CurrentRadius > spaceComponents.SightRadiusComponents[id].MaxRadius) ? spaceComponents.SightRadiusComponents[id] : radius; // movement = true; //} else { movementComponent.IsButtonDown = false; movementComponent.TotalTimeButtonDown = 0f; movementComponent.LastKeyPressed = Keys.None; } bool outOfBounds = false; if(pos.Position.X < 0 || pos.Position.Y < 0 || pos.Position.X >= dungeonDimensions.X || pos.Position.Y >= dungeonDimensions.Y) { outOfBounds = true; } if(!outOfBounds) { hitWall = !dungeonGrid[(int)pos.Position.X, (int)pos.Position.Y].Occupiable && spaceComponents.CollisionComponents[id].Solid; spaceComponents.InputMovementComponents[id] = movementComponent; if (!hitWall && movement) { //Check collisions. If no collisions, move into spot. CollisionSystem.TryToMove(spaceComponents, dungeonGrid, pos, id); if ((spaceComponents.Entities.Where(x => x.Id == id).First().ComponentFlags & Component.COMPONENT_PLAYER) == Component.COMPONENT_PLAYER) { gameInfo.StepsTaken += 1; spaceComponents.GameplayInfoComponent = gameInfo; PlayerComponent player = spaceComponents.PlayerComponent; player.PlayerTookTurn = true; spaceComponents.PlayerComponent = player; } } if (hitWall) { MessageDisplaySystem.GenerateRandomGameMessage(spaceComponents, Messages.WallCollisionMessages, Colors.Messages.Normal); } } } }
public void DrawTiles(Camera camera, SpriteBatch spriteBatch, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions) { for(int i = 0; i < (int)dungeonDimensions.X; i++) { for(int j = 0; j < (int)dungeonDimensions.Y; j++) { Rectangle tile = new Rectangle((int)i * cellSize, (int)j * cellSize, cellSize, cellSize); if (dungeonGrid[i, j].Found && !dungeonGrid[i,j].InRange) { switch (dungeonGrid[i, j].Type) { case TileType.TILE_FLOOR: spriteBatch.Draw(temporaryTile, tile, Color.DarkGreen); break; case TileType.TILE_WALL: spriteBatch.Draw(temporaryTile, tile, Color.DarkViolet); break; } } else if(dungeonGrid[i,j].InRange && !dungeonGrid[i,j].NewlyFound) { switch (dungeonGrid[i, j].Type) { case TileType.TILE_FLOOR: spriteBatch.Draw(temporaryTile, tile, Color.Green); break; case TileType.TILE_WALL: spriteBatch.Draw(temporaryTile, tile, Color.Violet); break; } } else if(dungeonGrid[i,j].NewlyFound) { float opacity = dungeonGrid[i, j].Opacity; switch (dungeonGrid[i, j].Type) { case TileType.TILE_FLOOR: spriteBatch.Draw(temporaryTile, tile, Color.Green * opacity); break; case TileType.TILE_WALL: spriteBatch.Draw(temporaryTile, tile, Color.Violet * opacity); break; } dungeonGrid[i, j].Opacity += .21f; if(dungeonGrid[i,j].Opacity > 1) { dungeonGrid[i, j].NewlyFound = false; dungeonGrid[i, j].Found = true; } } } } }
public static void ShowInventoryMenu(StateSpaceComponents spaceComponents, SpriteBatch spriteBatch, Camera camera, SpriteFont messageFont, SpriteFont optionFont, Texture2D UI) { Entity player = spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.Player) == ComponentMasks.Player).FirstOrDefault(); if (player != null) { int messageSpacing = (int)messageFont.MeasureString("g").Y + 1; int messageNumberLeft = 0; int messageNumberMiddle = 0; int messageNumberRight = 0; int panelWidth = (int)(camera.FullViewport.Width / 3); InventoryMenuComponent menu = spaceComponents.InventoryMenuComponent; InventoryComponent playerInvo = spaceComponents.InventoryComponents[player.Id]; SkillLevelsComponent playerSkills = spaceComponents.SkillLevelsComponents[player.Id]; //Draw background spriteBatch.Draw(UI, camera.FullViewport.Bounds, Color.Black * .7f); //Draw Header Vector2 headerSize = optionFont.MeasureString(Messages.InventoryHeader); int beginningHeight = (int)headerSize.Y + messageSpacing * 2; spriteBatch.Draw(UI, new Rectangle(0, 0, camera.FullViewport.Width, beginningHeight), Color.DarkViolet * .3f); spriteBatch.DrawString(optionFont, Messages.InventoryHeader, new Vector2((int)(camera.FullViewport.Width / 2) - (int)(headerSize.X / 2), messageSpacing), Color.CornflowerBlue); beginningHeight += messageSpacing; //Draw columns //Left spriteBatch.Draw(UI, new Rectangle(0, beginningHeight, panelWidth - messageSpacing, camera.FullViewport.Height), Color.DarkBlue * .25f); //Middle spriteBatch.Draw(UI, new Rectangle(messageSpacing + panelWidth, beginningHeight, panelWidth - messageSpacing, camera.FullViewport.Height), Color.DarkBlue * .25f); //Right spriteBatch.Draw(UI, new Rectangle(messageSpacing * 2 + panelWidth * 2, beginningHeight, panelWidth - messageSpacing, camera.FullViewport.Height), Color.DarkBlue * .25f); //Draw item selection panel spriteBatch.DrawString(messageFont, string.Format("Wealth: {0}", playerSkills.Wealth), new Vector2(messageSpacing, beginningHeight), Colors.Messages.Special); messageNumberLeft += 2; spriteBatch.DrawString(messageFont, string.Format(Messages.InventoryArtifacts + " ({0}/{1})", playerInvo.Artifacts.Count, playerInvo.MaxArtifacts), new Vector2(messageSpacing, beginningHeight + (messageSpacing * messageNumberLeft)), Color.CornflowerBlue); messageNumberLeft += 1; foreach (Guid item in playerInvo.Artifacts) { Color color = (menu.SelectedItem == item) ? Colors.Messages.LootPickup : Color.NavajoWhite; string prepend = (menu.SelectedItem == item) ? "> " : string.Empty; spriteBatch.DrawString(messageFont, prepend + spaceComponents.NameComponents[item].Name, new Vector2(messageSpacing, (messageSpacing * messageNumberLeft) + beginningHeight), color); messageNumberLeft += 1; } spriteBatch.DrawString(messageFont, string.Format(Messages.InventoryConsumables + " ({0}/{1})", playerInvo.Consumables.Count, playerInvo.MaxConsumables), new Vector2(messageSpacing, (messageSpacing * 3) + (messageSpacing * messageNumberLeft) + beginningHeight), Color.CornflowerBlue); messageNumberLeft += 1; foreach (Guid item in playerInvo.Consumables) { Color color = (menu.SelectedItem == item) ? Colors.Messages.LootPickup : Color.NavajoWhite; string prepend = (menu.SelectedItem == item) ? "> " : string.Empty; spriteBatch.DrawString(messageFont, prepend + spaceComponents.NameComponents[item].Name, new Vector2(messageSpacing, (messageSpacing * 3) + (messageSpacing * messageNumberLeft) + beginningHeight), color); messageNumberLeft += 1; } messageNumberLeft += 2; //Gather item information panels if (menu.SelectedItem != Guid.Empty) { PickupComponent itemInfo = spaceComponents.PickupComponents[menu.SelectedItem]; NameComponent itemName = spaceComponents.NameComponents[menu.SelectedItem]; ValueComponent itemValue = spaceComponents.ValueComponents[menu.SelectedItem]; List<Tuple<Color, string>> centerMessages = new List<Tuple<Color, string>>(); List<Tuple<Color, string>> rightMessages = new List<Tuple<Color, string>>(); //Get name, description, and value rightMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, itemName.Name)); rightMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, itemName.Description)); centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Special, string.Format("This item can be scrapped for {0} gold.", itemValue.Gold))); switch (itemInfo.PickupType) { case ItemType.ARTIFACT: //Collect item use stats for right panel //Artifact Stats ArtifactStatsComponent artifactStats = spaceComponents.ArtifactStatsComponents[menu.SelectedItem]; rightMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); rightMessages.Add(new Tuple<Color, string>(Colors.Messages.Special, string.Format("Upgrade Level: {0}", artifactStats.UpgradeLevel))); rightMessages.Add(new Tuple<Color, string>(Colors.Messages.Special, string.Format("Depth found: {0}", artifactStats.FloorFound))); rightMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); rightMessages.Add(new Tuple<Color, string>(Colors.Messages.Good, "STATISTICS WHILE EQUIPPED:")); rightMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Kills: {0}", artifactStats.KillsWith))); rightMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Maximum hit combo: {0}", artifactStats.MaximumComboWith))); rightMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Damage given: {0}", artifactStats.DamageGivenWith))); rightMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Damage taken: {0}", artifactStats.DamageTakenWith))); rightMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Times dodged: {0}", artifactStats.DodgesWith))); rightMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Times missed: {0}", artifactStats.MissesWith))); //Draw commands for artifact on the left panel spriteBatch.DrawString(messageFont, "Commands: ", new Vector2(messageSpacing, (messageSpacing * 3) + (messageSpacing * messageNumberLeft++) + beginningHeight), Colors.Messages.Normal); spriteBatch.DrawString(messageFont, Messages.Upgrade, new Vector2(messageSpacing, (messageSpacing * 3) + (messageSpacing * messageNumberLeft++) + beginningHeight), Colors.Messages.Normal); spriteBatch.DrawString(messageFont, Messages.Scrap, new Vector2(messageSpacing, (messageSpacing * 3) + (messageSpacing * messageNumberLeft++) + beginningHeight), Colors.Messages.Normal); spriteBatch.DrawString(messageFont, Messages.Drop, new Vector2(messageSpacing, (messageSpacing * 3) + (messageSpacing * messageNumberLeft++) + beginningHeight), Colors.Messages.Normal); //Collect info for middle panel StatModificationComponent stats = spaceComponents.StatModificationComponents[menu.SelectedItem]; centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, "This artifact affects the following stats: ")); if (stats.AccuracyChange != 0) { string sign = stats.AccuracyChange > 0 ? "+" : string.Empty; Color color = stats.AccuracyChange > 0 ? Colors.Messages.Good : Colors.Messages.Bad; centerMessages.Add(new Tuple<Color, string>(color, string.Format("Accuracy {0}{1}", sign, stats.AccuracyChange))); } if (stats.DefenseChange != 0) { string sign = stats.DefenseChange > 0 ? "+" : string.Empty; Color color = stats.DefenseChange > 0 ? Colors.Messages.Good : Colors.Messages.Bad; centerMessages.Add(new Tuple<Color, string>(color, string.Format("Defense {0}{1}", sign, stats.DefenseChange))); } if (stats.HealthChange != 0) { string sign = stats.HealthChange > 0 ? "+" : string.Empty; Color color = stats.HealthChange > 0 ? Colors.Messages.Good : Colors.Messages.Bad; centerMessages.Add(new Tuple<Color, string>(color, string.Format("Maximum Health {0}{1}", sign, stats.HealthChange))); } if (stats.DieNumberChange != 0) { string sign = stats.DieNumberChange > 0 ? "+" : string.Empty; Color color = stats.DieNumberChange > 0 ? Colors.Messages.Good : Colors.Messages.Bad; centerMessages.Add(new Tuple<Color, string>(color, string.Format("Dice Number on Attack {0}{1}", sign, stats.DieNumberChange))); } if (stats.MinimumDamageChange != 0) { string sign = stats.MinimumDamageChange > 0 ? "+" : string.Empty; Color color = stats.MinimumDamageChange > 0 ? Colors.Messages.Good : Colors.Messages.Bad; centerMessages.Add(new Tuple<Color, string>(color, string.Format("Minimum Damage {0}{1}", sign, stats.MinimumDamageChange))); } if (stats.MaximumDamageChange != 0) { string sign = stats.MaximumDamageChange > 0 ? "+" : string.Empty; Color color = stats.MaximumDamageChange > 0 ? Colors.Messages.Good : Colors.Messages.Bad; centerMessages.Add(new Tuple<Color, string>(color, string.Format("Maximum Damage {0}{1}", sign, stats.MaximumDamageChange))); } //PLACEHOLDER centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, "This artifact has the following effects: ")); centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Good, "Passive 1: Kills with this item equipped generate 100 gold.")); centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Bad, "Passive 2: Enemies will not flee (LOCKED)")); centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Bad, "Passive 3: Tiles stepped on turn to lava for 5 turns (LOCKED)")); centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Bad, "Bonus: ??? (Kill 40 more enemies with this item to unlock)")); break; case ItemType.CONSUMABLE: //Draw command info on left panel spriteBatch.DrawString(messageFont, "Commands: ", new Vector2(messageSpacing, (messageSpacing * 3) + (messageSpacing * messageNumberLeft++) + beginningHeight), Colors.Messages.Normal); spriteBatch.DrawString(messageFont, Messages.Scrap, new Vector2(messageSpacing, (messageSpacing * 3) + (messageSpacing * messageNumberLeft++) + beginningHeight), Colors.Messages.Normal); spriteBatch.DrawString(messageFont, Messages.Drop, new Vector2(messageSpacing, (messageSpacing * 3) + (messageSpacing * messageNumberLeft++) + beginningHeight), Colors.Messages.Normal); //Collect info for middle panel centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); ItemFunctionsComponent consumableInfo = spaceComponents.ItemFunctionsComponents[menu.SelectedItem]; centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Good, string.Format("This item has {0} uses left.", consumableInfo.Uses))); if (consumableInfo.Uses > 1) { centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Bad, string.Format("This item loses {0} value each use.", consumableInfo.CostToUse))); } if (consumableInfo.Ranged) { centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("This item is cast at a range."))); } else { centerMessages.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("This item is used where you stand."))); } break; } //Print out all the info foreach (Tuple<Color, string> message in centerMessages) { if (string.IsNullOrEmpty(message.Item2)) { continue; } string text = MessageDisplaySystem.WordWrap(messageFont, message.Item2, panelWidth - 30 - DevConstants.Grid.TileSpriteSize); float textHeight = messageFont.MeasureString(message.Item2).Y; spriteBatch.DrawString(messageFont, text, new Vector2(messageSpacing * 2 + panelWidth, (int)beginningHeight + (int)textHeight + 10 + (messageNumberMiddle * messageSpacing)), message.Item1); messageNumberMiddle += Regex.Matches(text, System.Environment.NewLine).Count; messageNumberMiddle += 1; } foreach (Tuple<Color, string> message in rightMessages) { if (string.IsNullOrEmpty(message.Item2)) { continue; } string text = MessageDisplaySystem.WordWrap(messageFont, message.Item2, panelWidth - 30 - DevConstants.Grid.TileSpriteSize); float textHeight = messageFont.MeasureString(message.Item2).Y; spriteBatch.DrawString(messageFont, text, new Vector2(messageSpacing * 3 + panelWidth * 2, (int)beginningHeight + (int)textHeight + 10 + (messageNumberRight * messageSpacing)), message.Item1); if(text != System.Environment.NewLine) { messageNumberRight += Regex.Matches(text, System.Environment.NewLine).Count; } messageNumberRight += 1; } } } }
public static void WriteMessages(StateSpaceComponents spaceComponents, SpriteBatch spriteBatch, Camera camera, SpriteFont font, DungeonTile[,] dungeonGrid) { float opacity = 1.15f; float decrement = .09f; int messageNumber = 0; int messageSpacing = (int)font.MeasureString("g").Y + 1; ; //Draw message log if(spaceComponents.GameMessageComponent.IndexBegin > 0) { float textHeight = font.MeasureString(Messages.ScrollingMessages).Y; spriteBatch.DrawString(font, Messages.ScrollingMessages, new Vector2(10, (int)camera.DungeonUIViewport.Bounds.Bottom -(int)textHeight - 10 - (messageNumber * messageSpacing)), Color.MediumVioletRed); messageNumber += 1; } foreach(Tuple<Color,string> message in spaceComponents.GameMessageComponent.GameMessages.Reverse<Tuple<Color,string>>().Skip(spaceComponents.GameMessageComponent.IndexBegin)) { if(opacity < 0) { break; } opacity -= decrement; string text = MessageDisplaySystem.WordWrap(font, message.Item2, camera.DungeonUIViewport.Width-20); float textHeight = font.MeasureString(text).Y; spriteBatch.DrawString(font,text, new Vector2(10, (int)camera.DungeonUIViewport.Bounds.Bottom - (int)textHeight - 10 - (messageNumber * messageSpacing)), message.Item1 * opacity); messageNumber += Regex.Matches(text, System.Environment.NewLine).Count; messageNumber += 1; } while (spaceComponents.GameMessageComponent.GameMessages.Count > spaceComponents.GameMessageComponent.MaxMessages) { spaceComponents.GameMessageComponent.GameMessages.RemoveAt(0); } spriteBatch.DrawString(font, spaceComponents.GameMessageComponent.GlobalMessage, new Vector2(10, camera.Bounds.Height - messageSpacing), spaceComponents.GameMessageComponent.GlobalColor); messageNumber = 0; //Draw statistics List<Tuple<Color,string>> statsToPrint = new List<Tuple<Color,string>>(); GameplayInfoComponent gameplayInfo = spaceComponents.GameplayInfoComponent; statsToPrint.Add(new Tuple<Color, string>( Colors.Messages.Normal, string.Format("Floor {0}", gameplayInfo.FloorsReached))); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Steps: {0}", gameplayInfo.StepsTaken))); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Kills: {0}", gameplayInfo.Kills))); Entity player = spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.Player) == ComponentMasks.Player).FirstOrDefault(); if (player != null) { SkillLevelsComponent skills = InventorySystem.ApplyStatModifications(spaceComponents, player.Id, spaceComponents.SkillLevelsComponents[player.Id]); InventoryComponent inventory = spaceComponents.InventoryComponents[player.Id]; statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Health: {0} / {1}", skills.CurrentHealth, skills.Health))); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Wealth: {0}", skills.Wealth))); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Damage: {0}-{1}", skills.MinimumDamage, skills.MaximumDamage))); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Accuracy: {0}", skills.Accuracy))); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, string.Format("Defense: {0}", skills.Defense))); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); //Status Effects: Statuses statuses = StatusSystem.GetStatusEffectsOfEntity(spaceComponents, player.Id, dungeonGrid); if(statuses == Statuses.NONE) { statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, Messages.StatusMessages.Normal)); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); } //If there are status effects on the player.. else { if((statuses & Statuses.BURNING) == Statuses.BURNING) { BurningComponent burning = spaceComponents.BurningComponents[player.Id]; statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Bad, string.Format(Messages.StatusMessages.Burning, burning.MinDamage, burning.MaxDamage, burning.TurnsLeft))); } if((statuses & Statuses.UNDERWATER) == Statuses.UNDERWATER) { statsToPrint.Add(new Tuple<Color, string>(Colors.Caves.WaterInRange, Messages.StatusMessages.Underwater)); } if((statuses & Statuses.HEALTHREGEN) == Statuses.HEALTHREGEN) { HealthRegenerationComponent healthRegen = spaceComponents.HealthRegenerationComponents[player.Id]; statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Good, string.Format(Messages.StatusMessages.HealthRegen, healthRegen.HealthRegain, healthRegen.RegenerateTurnRate))); } statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); } statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Special, string.Format(Messages.InventoryArtifacts + " ({0}/{1})", inventory.Artifacts.Count, inventory.MaxArtifacts))); foreach (Guid id in inventory.Artifacts) { NameComponent name = spaceComponents.NameComponents[id]; ArtifactStatsComponent artifactStats = spaceComponents.ArtifactStatsComponents[id]; statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.LootPickup, string.Format("{0} Lv{1}", name.Name, artifactStats.UpgradeLevel))); } statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Special, string.Format(Messages.InventoryConsumables + " ({0}/{1})", inventory.Consumables.Count, inventory.MaxConsumables))); if(inventory.Consumables.Count > 0) { statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); NameComponent name = spaceComponents.NameComponents[inventory.Consumables[0]]; ItemFunctionsComponent funcs = spaceComponents.ItemFunctionsComponents[inventory.Consumables[0]]; statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.LootPickup, string.Format("{0}({1})", name.Name, funcs.Uses))); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, "Q - Use")); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, "X - Throw")); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, System.Environment.NewLine)); if (inventory.Consumables.Count > 1) { name = spaceComponents.NameComponents[inventory.Consumables[1]]; funcs = spaceComponents.ItemFunctionsComponents[inventory.Consumables[1]]; statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.LootPickup, string.Format("{0}({1})", name.Name, funcs.Uses))); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, "E - Use")); statsToPrint.Add(new Tuple<Color, string>(Colors.Messages.Normal, "C - Throw")); } } } if (font != null) { foreach (Tuple<Color,string> stat in statsToPrint) { string text = MessageDisplaySystem.WordWrap(font, stat.Item2, camera.DungeonUIViewportLeft.Width - messageSpacing); Vector2 messageSize = font.MeasureString(stat.Item2); spriteBatch.DrawString(font, text, new Vector2(camera.DungeonUIViewportLeft.X + 10, 10 + (messageSpacing * messageNumber)), stat.Item1); messageNumber += 1; messageNumber += Regex.Matches(text, System.Environment.NewLine).Count; } } }
public static void HandleDungeonMovement(StateSpaceComponents spaceComponents, GraphicsDeviceManager graphics, GameTime gameTime, KeyboardState prevKeyboardState, MouseState prevMouseState, GamePadState prevGamepadState, Camera camera, DungeonTile[,] dungeonGrid) { IEnumerable<Guid> movableEntities = spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.InputMoveable) == ComponentMasks.InputMoveable).Select(x => x.Id); foreach(Guid id in movableEntities) { KeyboardState keyState = Keyboard.GetState(); if (keyState.IsKeyDown(Keys.NumPad8) && !prevKeyboardState.IsKeyDown(Keys.NumPad8)) { PositionComponent pos = spaceComponents.PositionComponents[id]; pos.Position.Y -= 1; if (dungeonGrid[(int)pos.Position.X, (int)pos.Position.Y].Type == TileType.TILE_FLOOR) { spaceComponents.PositionComponents[id] = pos; } } if (keyState.IsKeyDown(Keys.NumPad2) && !prevKeyboardState.IsKeyDown(Keys.NumPad2)) { PositionComponent pos = spaceComponents.PositionComponents[id]; pos.Position.Y += 1; if (dungeonGrid[(int)pos.Position.X, (int)pos.Position.Y].Type == TileType.TILE_FLOOR) { spaceComponents.PositionComponents[id] = pos; } } if (keyState.IsKeyDown(Keys.NumPad6) && !prevKeyboardState.IsKeyDown(Keys.NumPad6)) { PositionComponent pos = spaceComponents.PositionComponents[id]; pos.Position.X += 1; if (dungeonGrid[(int)pos.Position.X, (int)pos.Position.Y].Type == TileType.TILE_FLOOR) { spaceComponents.PositionComponents[id] = pos; } } if (keyState.IsKeyDown(Keys.NumPad4) && !prevKeyboardState.IsKeyDown(Keys.NumPad4)) { PositionComponent pos = spaceComponents.PositionComponents[id]; pos.Position.X -= 1; if (dungeonGrid[(int)pos.Position.X, (int)pos.Position.Y].Type == TileType.TILE_FLOOR) { spaceComponents.PositionComponents[id] = pos; } } if (keyState.IsKeyDown(Keys.NumPad7) && !prevKeyboardState.IsKeyDown(Keys.NumPad7)) { PositionComponent pos = spaceComponents.PositionComponents[id]; pos.Position.X -= 1; pos.Position.Y -= 1; if (dungeonGrid[(int)pos.Position.X, (int)pos.Position.Y].Type == TileType.TILE_FLOOR) { spaceComponents.PositionComponents[id] = pos; } } if (keyState.IsKeyDown(Keys.NumPad9) && !prevKeyboardState.IsKeyDown(Keys.NumPad9)) { PositionComponent pos = spaceComponents.PositionComponents[id]; pos.Position.X += 1; pos.Position.Y -= 1; if (dungeonGrid[(int)pos.Position.X, (int)pos.Position.Y].Type == TileType.TILE_FLOOR) { spaceComponents.PositionComponents[id] = pos; } } if (keyState.IsKeyDown(Keys.NumPad1) && !prevKeyboardState.IsKeyDown(Keys.NumPad1)) { PositionComponent pos = spaceComponents.PositionComponents[id]; pos.Position.X -= 1; pos.Position.Y += 1; if (dungeonGrid[(int)pos.Position.X, (int)pos.Position.Y].Type == TileType.TILE_FLOOR) { spaceComponents.PositionComponents[id] = pos; } } if (keyState.IsKeyDown(Keys.NumPad3) && !prevKeyboardState.IsKeyDown(Keys.NumPad3)) { PositionComponent pos = spaceComponents.PositionComponents[id]; pos.Position.X += 1; pos.Position.Y += 1; if (dungeonGrid[(int)pos.Position.X, (int)pos.Position.Y].Type == TileType.TILE_FLOOR) { spaceComponents.PositionComponents[id] = pos; } } } }
public static void DrawTiles(Camera camera, SpriteBatch spriteBatch, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions, int cellSize, Texture2D spriteSheet, DungeonColorInfo colorInfo, DijkstraMapTile[,] mapToPlayer, SpriteFont font, StateSpaceComponents spaceComponents) { Entity player = spaceComponents.Entities.Where(c => (c.ComponentFlags & ComponentMasks.Player) == ComponentMasks.Player).FirstOrDefault(); bool inWater = false; bool inFire = false; if (player != null) { Vector2 playerPos = spaceComponents.PositionComponents[spaceComponents.Entities.Where(c => (c.ComponentFlags & ComponentMasks.Player) == ComponentMasks.Player).First().Id].Position; inWater = dungeonGrid[(int)playerPos.X, (int)playerPos.Y].Type == TileType.TILE_WATER; inFire = dungeonGrid[(int)playerPos.X, (int)playerPos.Y].Type == TileType.TILE_FIRE || (player.ComponentFlags & ComponentMasks.BurningStatus) == ComponentMasks.BurningStatus; } Matrix cameraMatrix = camera.GetMatrix(); Vector2 origin = new Vector2(DevConstants.Grid.TileBorderSize, DevConstants.Grid.TileBorderSize); for (int i = 0; i < (int)dungeonDimensions.X; i++) { for (int j = 0; j < (int)dungeonDimensions.Y; j++) { bool tintFire = inFire || dungeonGrid[i, j].FireIllumination; Vector2 tile = new Vector2((int)i * cellSize, (int)j * cellSize); Rectangle floor = new Rectangle(0 * cellSize, 0 * cellSize, cellSize, cellSize); //Need to be moved eventually Rectangle wall = new Rectangle(0 * cellSize, 0 * cellSize, cellSize, cellSize); //Need to be moved eventually Vector2 bottomRight = Vector2.Transform(new Vector2((i * cellSize) + cellSize, (j * cellSize) + cellSize), cameraMatrix); Vector2 topLeft = Vector2.Transform(new Vector2(i * cellSize, j * cellSize), cameraMatrix); Rectangle cameraBounds = new Rectangle((int)topLeft.X, (int)topLeft.Y, (int)bottomRight.X - (int)topLeft.X, (int)bottomRight.Y - (int)topLeft.Y); if (camera.IsInView(cameraMatrix, cameraBounds)) // check if in view { if (dungeonGrid[i, j].Found && !dungeonGrid[i, j].InRange) { Color colorToLerp = tintFire ? colorInfo.Fire : colorInfo.Water; //Default to water, if fire then change it. switch (dungeonGrid[i, j].Type) { case TileType.TILE_FLATTENEDGRASS: case TileType.TILE_FLOOR: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater || tintFire ? Color.Lerp(colorInfo.Floor, colorToLerp, .3f) : colorInfo.Floor) * .3f, origin: origin); break; case TileType.TILE_ROCK: case TileType.TILE_WALL: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater || tintFire ? Color.Lerp(colorInfo.Wall, colorToLerp, .3f) : colorInfo.Wall) * .3f, origin: origin); break; case TileType.TILE_TALLGRASS: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater || tintFire ? Color.Lerp(colorInfo.TallGrass, colorToLerp, .3f) : colorInfo.TallGrass) * .3f, origin: origin); break; case TileType.TILE_ASH: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater || tintFire ? Color.Lerp(colorInfo.Ash, colorToLerp, .3f) : colorInfo.Ash) * .3f, origin: origin); break; case TileType.TILE_WATER: spriteBatch.Draw(spriteSheet, position: tile, color: (tintFire ? Color.Lerp(colorInfo.Water, colorToLerp, .3f) : colorInfo.Water) * .3f, origin: origin); break; case TileType.TILE_FIRE: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater ? Color.Lerp(colorInfo.Fire, colorToLerp, .3f) : colorInfo.Fire) * .3f, origin: origin); break; } if (!string.IsNullOrEmpty(dungeonGrid[i, j].Symbol)) { Vector2 size = font.MeasureString(dungeonGrid[i, j].Symbol); spriteBatch.DrawString(font, dungeonGrid[i, j].Symbol, new Vector2(i * DevConstants.Grid.CellSize + (int)(DevConstants.Grid.CellSize / 2), (j * DevConstants.Grid.CellSize + (int)(DevConstants.Grid.CellSize / 2))), dungeonGrid[i, j].SymbolColor * .5f, 0f, new Vector2((int)(size.X / 2), (int)(size.Y / 2)), 1f, SpriteEffects.None, 0f); } } else if (dungeonGrid[i, j].InRange && !dungeonGrid[i, j].NewlyFound) { int weight = mapToPlayer[i, j].Weight; double opacity = 1 - (.035 * weight); opacity = (opacity < .4) ? .4 : opacity; opacity = dungeonGrid[i, j].FireIllumination ? .85f : opacity; bool isWall = false; Color colorToLerp = tintFire ? colorInfo.FireInRange : colorInfo.WaterInRange; //Default to water, if fire then change it. switch (dungeonGrid[i, j].Type) { case TileType.TILE_FLATTENEDGRASS: case TileType.TILE_FLOOR: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater || tintFire ? Color.Lerp(colorInfo.FloorInRange, colorToLerp, .55f) : colorInfo.FloorInRange) * (float)opacity, origin: origin); break; case TileType.TILE_ROCK: case TileType.TILE_WALL: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater || tintFire ? Color.Lerp(colorInfo.WallInRange, colorToLerp, .55f) : colorInfo.WallInRange) * .85f, origin: origin); isWall = true; break; case TileType.TILE_TALLGRASS: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater || tintFire ? Color.Lerp(colorInfo.TallGrassInRange, colorToLerp, .55f) : colorInfo.TallGrassInRange) * (float)opacity, origin: origin); break; case TileType.TILE_WATER: spriteBatch.Draw(spriteSheet, position: tile, color: (tintFire ? Color.Lerp(colorInfo.WaterInRange, colorToLerp, .55f) : colorInfo.WaterInRange) * (float)opacity, origin: origin); break; case TileType.TILE_ASH: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater || tintFire ? Color.Lerp(colorInfo.AshInRange, colorToLerp, .55f) : colorInfo.AshInRange) * (float)opacity, origin: origin); break; case TileType.TILE_FIRE: opacity = 0f + (.1f * dungeonGrid[i, j].TurnsToBurn); opacity = (opacity > 1f) ? 1f : opacity; opacity = (opacity < .3f) ? .3f : opacity; spriteBatch.Draw(spriteSheet, position: tile, color: (inWater ? Color.Lerp(colorInfo.FireInRange, colorToLerp, .55f) : colorInfo.FireInRange) * (float)opacity, origin: origin); break; } if (!isWall) { if (!string.IsNullOrEmpty(dungeonGrid[i, j].Symbol)) { Vector2 size = font.MeasureString(dungeonGrid[i, j].Symbol); spriteBatch.DrawString(font, dungeonGrid[i, j].Symbol, new Vector2(i * DevConstants.Grid.CellSize + (int)(DevConstants.Grid.CellSize / 2), (j * DevConstants.Grid.CellSize + (int)(DevConstants.Grid.CellSize / 2))), dungeonGrid[i, j].SymbolColor * (float)opacity, 0f, new Vector2((int)(size.X / 2), (int)(size.Y / 2)), 1f, SpriteEffects.None, 0f); } } else { if (!string.IsNullOrEmpty(dungeonGrid[i, j].Symbol)) { Vector2 size = font.MeasureString(dungeonGrid[i, j].Symbol); spriteBatch.DrawString(font, dungeonGrid[i, j].Symbol, new Vector2(i * DevConstants.Grid.CellSize + (int)(DevConstants.Grid.CellSize / 2), (j * DevConstants.Grid.CellSize + (int)(DevConstants.Grid.CellSize / 2))), dungeonGrid[i, j].SymbolColor * .85f, 0f, new Vector2((int)(size.X / 2), (int)(size.Y / 2)), 1f, SpriteEffects.None, 0f); } } } else if (dungeonGrid[i, j].NewlyFound) { float opacity = dungeonGrid[i, j].Opacity; Color colorToLerp = tintFire ? colorInfo.FireInRange : colorInfo.WaterInRange; //Default to water, if fire then change it. switch (dungeonGrid[i, j].Type) { case TileType.TILE_FLATTENEDGRASS: case TileType.TILE_FLOOR: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater || tintFire ? Color.Lerp(colorInfo.FloorInRange, colorToLerp, .55f) : colorInfo.FloorInRange) * opacity, origin: origin); break; case TileType.TILE_ROCK: case TileType.TILE_WALL: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater || tintFire ? Color.Lerp(colorInfo.WallInRange, colorToLerp, .55f) : colorInfo.WallInRange) * opacity, origin: origin); break; case TileType.TILE_TALLGRASS: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater || tintFire ? Color.Lerp(colorInfo.TallGrassInRange, colorToLerp, .55f) : colorInfo.TallGrassInRange) * opacity, origin: origin); break; case TileType.TILE_ASH: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater || tintFire ? Color.Lerp(colorInfo.AshInRange, colorToLerp, .55f) : colorInfo.AshInRange) * opacity, origin: origin); break; case TileType.TILE_WATER: spriteBatch.Draw(spriteSheet, position: tile, color: (tintFire ? Color.Lerp(colorInfo.WaterInRange, colorToLerp, .55f) : colorInfo.WaterInRange) * opacity, origin: origin); break; case TileType.TILE_FIRE: spriteBatch.Draw(spriteSheet, position: tile, color: (inWater ? Color.Lerp(colorInfo.FireInRange, colorToLerp, .55f) : colorInfo.FireInRange), origin: origin); break; } if (!string.IsNullOrEmpty(dungeonGrid[i, j].Symbol)) { Vector2 size = font.MeasureString(dungeonGrid[i, j].Symbol); spriteBatch.DrawString(font, dungeonGrid[i, j].Symbol, new Vector2(i * DevConstants.Grid.CellSize + (int)(DevConstants.Grid.CellSize / 2), (j * DevConstants.Grid.CellSize + (int)(DevConstants.Grid.CellSize / 2))), dungeonGrid[i, j].SymbolColor * opacity, 0f, new Vector2((int)(size.X / 2), (int)(size.Y / 2)), 1f, SpriteEffects.None, 0f); } if (dungeonGrid[i, j].Opacity > .5) { dungeonGrid[i, j].NewlyFound = false; dungeonGrid[i, j].Found = true; } } } } } }
public static void DrawAIFieldOfViews(StateSpaceComponents spaceComponents, Camera camera, SpriteBatch spriteBatch, Texture2D rectangleTexture, int cellSize, DungeonTile[,] dungeonGrid) { Matrix cameraMatrix = camera.GetMatrix(); foreach (Guid id in spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.AIView) == ComponentMasks.AIView).Select(x => x.Id)) { AIFieldOfView fovInfo = spaceComponents.AIFieldOfViewComponents[id]; if (fovInfo.DrawField) { foreach (Vector2 tilePosition in fovInfo.SeenTiles) { Vector2 tile = new Vector2((int)tilePosition.X * cellSize, (int)tilePosition.Y * cellSize); Vector2 bottomRight = Vector2.Transform(new Vector2((tile.X + cellSize), (tile.Y + cellSize)), cameraMatrix); Vector2 topLeft = Vector2.Transform(tile, cameraMatrix); Rectangle cameraBounds = new Rectangle((int)topLeft.X, (int)topLeft.Y, (int)bottomRight.X - (int)topLeft.X, (int)bottomRight.Y - (int)topLeft.Y); if (dungeonGrid[(int)tilePosition.X, (int)tilePosition.Y].InRange && camera.IsInView(cameraMatrix, cameraBounds)) { if (spaceComponents.AlternateFOVColorChangeComponents.ContainsKey(id)) { AlternateFOVColorChangeComponent altColorInfo = spaceComponents.AlternateFOVColorChangeComponents[id]; spriteBatch.Draw(rectangleTexture, position: tile, color: Color.Lerp(fovInfo.Color, altColorInfo.AlternateColor, altColorInfo.Seconds / altColorInfo.SwitchAtSeconds) * fovInfo.Opacity, origin: new Vector2(DevConstants.Grid.TileBorderSize, DevConstants.Grid.TileBorderSize)); } else { //origin is 4,4 because the tile texture is 40x40 and the grid is 32x32. If size of grid changes, change this -- and then don't hardcode it anymore!!! spriteBatch.Draw(rectangleTexture, position: tile, color: fovInfo.Color * fovInfo.Opacity, origin: new Vector2(DevConstants.Grid.TileBorderSize, DevConstants.Grid.TileBorderSize)); } } } } } }
public static void DrawOutlines(StateSpaceComponents spaceComponents, Camera camera, SpriteBatch spriteBatch, Texture2D rectangleTexture, DungeonTile[,] dungeonGrid) { Matrix cameraMatrix = camera.GetMatrix(); Entity player = spaceComponents.Entities.Where(c => (c.ComponentFlags & ComponentMasks.Player) == ComponentMasks.Player).FirstOrDefault(); bool inWater = false; if (player != null) { Vector2 playerPos = spaceComponents.PositionComponents[spaceComponents.Entities.Where(c => (c.ComponentFlags & ComponentMasks.Player) == ComponentMasks.Player).First().Id].Position; inWater = dungeonGrid[(int)playerPos.X, (int)playerPos.Y].Type == TileType.TILE_WATER; } foreach (Guid id in spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.DrawableOutline) == ComponentMasks.DrawableOutline).Select(x => x.Id)) { Entity observer = spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.Observer) == ComponentMasks.Observer).FirstOrDefault(); bool isObserver = false; if (observer != null) { isObserver = observer.Id == id; } OutlineComponent outline = spaceComponents.OutlineComponents[id]; PositionComponent position = spaceComponents.PositionComponents[id]; bool outlineInWater = dungeonGrid[(int)position.Position.X, (int)position.Position.Y].Type == TileType.TILE_WATER; Vector2 tile = new Vector2((int)position.Position.X * DevConstants.Grid.CellSize, (int)position.Position.Y * DevConstants.Grid.CellSize); Vector2 bottomRight = Vector2.Transform(new Vector2((tile.X + DevConstants.Grid.CellSize), (tile.Y + DevConstants.Grid.CellSize)), cameraMatrix); Vector2 topLeft = Vector2.Transform(tile, cameraMatrix); Rectangle cameraBounds = new Rectangle((int)topLeft.X, (int)topLeft.Y, (int)bottomRight.X - (int)topLeft.X, (int)bottomRight.Y - (int)topLeft.Y); if (dungeonGrid[(int)position.Position.X, (int)position.Position.Y].InRange && camera.IsInView(cameraMatrix, cameraBounds) && (inWater == outlineInWater || isObserver)) { if (spaceComponents.SecondaryOutlineComponents.ContainsKey(id)) { SecondaryOutlineComponent altColorInfo = spaceComponents.SecondaryOutlineComponents[id]; spriteBatch.Draw(rectangleTexture, position: tile, color: Color.Lerp(outline.Color, altColorInfo.AlternateColor, altColorInfo.Seconds / altColorInfo.SwitchAtSeconds) * outline.Opacity, origin: new Vector2(DevConstants.Grid.TileBorderSize, DevConstants.Grid.TileBorderSize)); } else { //origin is 4,4 because the tile texture is 40x40 and the grid is 32x32. If size of grid changes, change this -- and then don't hardcode it anymore!!! spriteBatch.Draw(rectangleTexture, position: tile, color: outline.Color * outline.Opacity, origin: new Vector2(DevConstants.Grid.TileBorderSize, DevConstants.Grid.TileBorderSize)); } } } }