public static SkillLevelsComponent ApplyStatModifications(StateSpaceComponents spaceComponents, Guid entity, SkillLevelsComponent originalStats) { SkillLevelsComponent newStats = originalStats; //See if the entity has an inventory to check for artifact modifications if(spaceComponents.InventoryComponents.ContainsKey(entity)) { InventoryComponent entityInventory = spaceComponents.InventoryComponents[entity]; //For each artifact in the entity' inventory, look for the statmodificationcomponent, and modify stats accordingly. foreach (Guid id in entityInventory.Artifacts) { Entity inventoryItem = spaceComponents.Entities.Where(x => x.Id == id).FirstOrDefault(); if (inventoryItem != null && (inventoryItem.ComponentFlags & ComponentMasks.Artifact) == ComponentMasks.Artifact) { StatModificationComponent statsMods = spaceComponents.StatModificationComponents[id]; newStats.Accuracy = (newStats.Accuracy + statsMods.AccuracyChange < 0) ? 0 : newStats.Accuracy + statsMods.AccuracyChange; newStats.Defense = (newStats.Defense + statsMods.DefenseChange < 0) ? 0 : newStats.Defense + statsMods.DefenseChange; newStats.DieNumber = (newStats.DieNumber + statsMods.DieNumberChange < 1) ? 1 : newStats.DieNumber + statsMods.DieNumberChange; newStats.Health = (newStats.Health + statsMods.HealthChange < 0) ? 0 : newStats.Health + statsMods.HealthChange; newStats.MaximumDamage = (newStats.MaximumDamage + statsMods.MaximumDamageChange < 1) ? 1 : newStats.MaximumDamage + statsMods.MaximumDamageChange; newStats.MinimumDamage = (newStats.MinimumDamage + statsMods.MinimumDamageChange < 1) ? 1 : newStats.MinimumDamage + statsMods.MinimumDamageChange; } } } return newStats; }
public void LoadLevel(ContentManager content, GraphicsDeviceManager graphics, Camera camera, StateComponents stateComponents, bool createEntities = true) { this.stateComponents = stateComponents; if(stateComponents.StateSpaceComponents != null) { this.stateSpaceComponents = stateComponents.StateSpaceComponents; } sprites = content.Load<Texture2D>(DevConstants.Graphics.SpriteSheet); dungeonSprites = content.Load<Texture2D>(dungeonSpriteFile); messageFont = content.Load<SpriteFont>(DevConstants.Graphics.MessageFont); asciiDisplay = content.Load<SpriteFont>(DevConstants.Graphics.AsciiFont); optionFont = content.Load<SpriteFont>(DevConstants.Graphics.OptionFont); UI = content.Load<Texture2D>(DevConstants.Graphics.UISheet); camera.AttachedToPlayer = true; if(createEntities) { LevelChangeSystem.CreateGameplayInfo(stateComponents, stateSpaceComponents); DungeonCreationSystem.TallGrassGeneration(ref dungeonGrid, dungeonDimensions, stateSpaceComponents.random, freeTiles, stateSpaceComponents); DungeonCreationSystem.WaterGeneration(ref dungeonGrid, dungeonDimensions, stateSpaceComponents.random, freeTiles, stateSpaceComponents, waterTiles); DungeonCreationSystem.CreateDungeonDrops(stateSpaceComponents, dungeonGrid, dungeonDimensions, freeTiles); DungeonCreationSystem.CreateDungeonMonsters(stateSpaceComponents, dungeonGrid, dungeonDimensions, DevConstants.Grid.CellSize, freeTiles); LevelChangeSystem.LoadPlayerSkillset(stateComponents, stateSpaceComponents); LevelChangeSystem.CreateMessageLog(stateSpaceComponents); } mapToPlayer = new DijkstraMapTile[(int)dungeonDimensions.X, (int)dungeonDimensions.Y]; }
public RandomlyGeneratedStateSpace(IGenerationAlgorithm dungeonGeneration, int worldMin, int worldMax) { stateSpaceComponents = new StateSpaceComponents(); freeTiles = new List<Vector2>(); waterTiles = new List<Vector2>(); dungeonDimensions = dungeonGeneration.GenerateDungeon(ref dungeonGrid, worldMin, worldMax, stateSpaceComponents.random, freeTiles); dungeonSpriteFile = dungeonGeneration.GetDungeonSpritesheetFileName(); dungeonColorInfo = dungeonGeneration.GetColorInfo(); }
public RandomlyGeneratedStateSpace(DungeonInfo data) { stateSpaceComponents = data.stateSpaceComponents; dungeonSpriteFile = data.dungeonSpriteFile; dungeonGrid = data.dungeonGrid; dungeonColorInfo = data.dungeonColorInfo; dungeonDimensions = data.dungeonDimensions; freeTiles = data.freeTiles; PlayerComponent player = stateSpaceComponents.PlayerComponent; player.PlayerJustLoaded = true; stateSpaceComponents.PlayerComponent = player; }
public static void UseItem(StateSpaceComponents spaceComponents, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions, Guid item, Guid user) { ItemFunctionsComponent itemInfo = spaceComponents.ItemFunctionsComponents[item]; Vector2 target = spaceComponents.PositionComponents[user].Position; bool cancelledCast = false; if(itemInfo.Ranged) { //Call a function to get the target position. If they cancel during this part, set cancelledCast to true. } //If the item use is successful, remove the item from inventory and delete the item Func<StateSpaceComponents, DungeonTile[,], Vector2, Guid, Guid, Vector2, bool> useFunction = ItemUseFunctionLookup.GetUseFunction(itemInfo.UseFunctionValue); if (!cancelledCast && useFunction!= null && useFunction(spaceComponents, dungeonGrid, dungeonDimensions, item, user, target)) { NameComponent itemName = spaceComponents.NameComponents[item]; itemInfo.Uses -= 1; //If the items' out of uses, remove it if(itemInfo.Uses <= 0) { InventoryComponent inventory = spaceComponents.InventoryComponents[user]; inventory.Consumables.Remove(item); spaceComponents.InventoryComponents[user] = inventory; spaceComponents.EntitiesToDelete.Add(item); spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple<Color, string>(Colors.Messages.Bad, string.Format("[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] " + "{0} has used the last of the {1}", spaceComponents.NameComponents[user].Name, spaceComponents.NameComponents[item].Name))); } //otherwise, just report how many uses it has left. else { ValueComponent itemValue = spaceComponents.ValueComponents[item]; itemValue.Gold = (itemValue.Gold - itemInfo.CostToUse < 0) ? 0 : itemValue.Gold - itemInfo.CostToUse; spaceComponents.ValueComponents[item] = itemValue; spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple<Color, string>(Colors.Messages.Bad, string.Format("[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] " + "{0} has {1} charge(s) left.", spaceComponents.NameComponents[item].Name, itemInfo.Uses))); } PlayerComponent player = spaceComponents.PlayerComponent; player.PlayerTookTurn = true; spaceComponents.PlayerComponent = player; spaceComponents.ItemFunctionsComponents[item] = itemInfo; } }
public static void DropWholeInventory(StateSpaceComponents spaceComponents, Guid droppingEntity, Vector2 entityPos) { Entity entity = spaceComponents.Entities.Where(x => x.Id == droppingEntity).FirstOrDefault(); if(entity != null && (entity.ComponentFlags & Component.COMPONENT_INVENTORY) == Component.COMPONENT_INVENTORY) { InventoryComponent invo = spaceComponents.InventoryComponents[entity.Id]; foreach(Guid artifact in invo.Artifacts) { Entity item = spaceComponents.Entities.Where(x => x.Id == artifact).FirstOrDefault(); if (item != null) { item.ComponentFlags |= Component.COMPONENT_POSITION; spaceComponents.PositionComponents[item.Id] = new PositionComponent() { Position = entityPos }; invo.Artifacts.Remove(item.Id); } } foreach(Guid consumable in invo.Consumables) { Entity item = spaceComponents.Entities.Where(x => x.Id == consumable).FirstOrDefault(); if (item != null) { item.ComponentFlags |= Component.COMPONENT_POSITION; spaceComponents.PositionComponents[item.Id] = new PositionComponent() { Position = entityPos }; invo.Consumables.Remove(item.Id); } } if((entity.ComponentFlags & Component.COMPONENT_SKILL_LEVELS) == Component.COMPONENT_SKILL_LEVELS) { SkillLevelsComponent skills = spaceComponents.SkillLevelsComponents[entity.Id]; if(skills.Wealth > 0) { spaceComponents.DelayedActions.Add(new Action(() => { Guid id = spaceComponents.CreateEntity(); spaceComponents.Entities.Where(x => x.Id == id).First().ComponentFlags = ComponentMasks.Drawable | ComponentMasks.GlowingOutline | ComponentMasks.PickupItem; spaceComponents.DisplayComponents[id] = new DisplayComponent() { AlwaysDraw = false, Color = Colors.Messages.Special, Opacity = 1f, Origin = Vector2.Zero, Rotation = 0f, Scale = 1f, SpriteEffect = SpriteEffects.None, SpriteSource = new Rectangle(0 * DevConstants.Grid.CellSize, 0 * DevConstants.Grid.CellSize, DevConstants.Grid.CellSize, DevConstants.Grid.CellSize), Symbol = "$", SymbolColor = Color.White }; Vector2 position = entityPos; spaceComponents.PositionComponents[id] = new PositionComponent() { Position = position }; spaceComponents.OutlineComponents[id] = new OutlineComponent() { Color = Color.Purple, Opacity = 1f }; spaceComponents.SecondaryOutlineComponents[id] = new SecondaryOutlineComponent() { AlternateColor = Color.LightBlue, Seconds = 0f, SwitchAtSeconds = .75f }; spaceComponents.PickupComponents[id] = new PickupComponent() { PickupType = ItemType.GOLD }; spaceComponents.ValueComponents[id] = new ValueComponent() { Gold = skills.Wealth }; spaceComponents.NameComponents[id] = new NameComponent() { Name = "Gold", Description = "Some people try and use fancy names for this mass of wealth. Credits, Stardust, Gil... it buys shelter and women all the same." }; spaceComponents.CollisionComponents[id] = new CollisionComponent() { CollidedObjects = new List<Guid>(), Solid = false }; })); } } } }
public void GenerateDungeonEntities(StateSpaceComponents spaceComponents) { throw new NotImplementedException(); }
public static void TryPickupItems(StateSpaceComponents spaceComponents, DungeonTile[,] dungeongrid) { IEnumerable<Guid> entitiesThatCollided = spaceComponents.GlobalCollisionComponent.EntitiesThatCollided.Distinct(); foreach(Guid collidingEntity in entitiesThatCollided) { Entity colliding = spaceComponents.Entities.Where(x => x.Id == collidingEntity).FirstOrDefault(); //If the colliding entity has an inventory and messages, place the item inside the inventory. if(colliding != null && (colliding.ComponentFlags & ComponentMasks.InventoryPickup) == ComponentMasks.InventoryPickup) { CollisionComponent collidingEntityCollisions = spaceComponents.CollisionComponents[collidingEntity]; InventoryComponent collidingEntityInventory = spaceComponents.InventoryComponents[collidingEntity]; NameComponent collidingEntityName = spaceComponents.NameComponents[collidingEntity]; PositionComponent collidingEntityPosition = spaceComponents.PositionComponents[collidingEntity]; EntityMessageComponent collidingEntityMessages = spaceComponents.EntityMessageComponents[collidingEntity]; foreach(Guid collidedEntity in collidingEntityCollisions.CollidedObjects) { //Check to see if the collidedEntity is a pickup item, if it is, try to place it in the inventory if it fits. Entity collided = spaceComponents.Entities.Where(x => x.Id == collidedEntity).FirstOrDefault(); //If the collideditem is a pickup item, handle it based on pickup type. if(collided != null && (collided.ComponentFlags & ComponentMasks.PickupItem) == ComponentMasks.PickupItem) { PickupComponent itemPickup = spaceComponents.PickupComponents[collidedEntity]; ValueComponent itemValue = spaceComponents.ValueComponents[collidedEntity]; NameComponent itemName = spaceComponents.NameComponents[collidedEntity]; switch(itemPickup.PickupType) { case ItemType.GOLD: if(spaceComponents.SkillLevelsComponents.ContainsKey(collidingEntity)) { SkillLevelsComponent skills = spaceComponents.SkillLevelsComponents[collidingEntity]; skills.Wealth += itemValue.Gold; spaceComponents.SkillLevelsComponents[collidingEntity] = skills; if(dungeongrid[(int)collidingEntityPosition.Position.X, (int)collidingEntityPosition.Position.Y].InRange) { spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple<Color, string>(Colors.Messages.Special, string.Format("[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] " + "{0} picked up {1} gold.", collidingEntityName.Name, itemValue.Gold))); } spaceComponents.EntitiesToDelete.Add(collidedEntity); } break; case ItemType.CONSUMABLE: //If the entity has room in their inventory, place the item in it if(collidingEntityInventory.Consumables.Count < collidingEntityInventory.MaxConsumables) { //Remove the position component flag and add the guid to the inventory of the entity collided.ComponentFlags &= ~Component.COMPONENT_POSITION; collidingEntityInventory.Consumables.Add(collided.Id); if(dungeongrid[(int)collidingEntityPosition.Position.X, (int)collidingEntityPosition.Position.Y].InRange && collidingEntityMessages.PickupItemMessages.Length > 0) { spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple<Color, string>(Colors.Messages.LootPickup, string.Format("[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] " + collidingEntityMessages.PickupItemMessages[spaceComponents.random.Next(0, collidingEntityMessages.PickupItemMessages.Length)], collidingEntityName.Name, itemName.Name))); } } //If it can't fit in, and the entity has a message for the situation, display it. else if(spaceComponents.EntityMessageComponents[collidingEntity].ConsumablesFullMessages != null && spaceComponents.EntityMessageComponents[collidingEntity].ConsumablesFullMessages.Length > 0) { spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple<Color, string>(Colors.Messages.Bad, "[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] " + spaceComponents.EntityMessageComponents[collidingEntity].ConsumablesFullMessages[spaceComponents.random.Next(0, spaceComponents.EntityMessageComponents[collidingEntity].ConsumablesFullMessages.Length)])); } break; case ItemType.ARTIFACT: //If the entity has room in their inventory, place the item in it if (collidingEntityInventory.Artifacts.Count < collidingEntityInventory.MaxArtifacts) { //Remove the position component flag and add the guid to the inventory of the entity collided.ComponentFlags &= ~Component.COMPONENT_POSITION; collidingEntityInventory.Artifacts.Add(collided.Id); if (dungeongrid[(int)collidingEntityPosition.Position.X, (int)collidingEntityPosition.Position.Y].InRange && collidingEntityMessages.PickupItemMessages.Length > 0) { spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple<Color, string>(Colors.Messages.LootPickup, string.Format("[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] " + collidingEntityMessages.PickupItemMessages[spaceComponents.random.Next(0, collidingEntityMessages.PickupItemMessages.Length)], collidingEntityName.Name, itemName.Name))); } } //If it can't fit in, and the entity has a message for the situation, display it. else if (spaceComponents.EntityMessageComponents[collidingEntity].ArtifactsFullMessages != null && spaceComponents.EntityMessageComponents[collidingEntity].ArtifactsFullMessages.Length > 0) { spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple<Color, string>(Colors.Messages.Bad, "[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] " + spaceComponents.EntityMessageComponents[collidingEntity].ArtifactsFullMessages[spaceComponents.random.Next(0, spaceComponents.EntityMessageComponents[collidingEntity].ArtifactsFullMessages.Length)])); } break; case ItemType.DOWNSTAIRS: //Tell the game to go to the next level if((spaceComponents.Entities.Where(x => x.Id == collidingEntity).FirstOrDefault().ComponentFlags & Component.COMPONENT_PLAYER) == Component.COMPONENT_PLAYER) { PlayerComponent player = spaceComponents.PlayerComponent; player.GoToNextFloor = true; spaceComponents.PlayerComponent = player; } break; } } } } } }
public static bool SpawnTestConsumable(StateSpaceComponents spaceComponents, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions, List<Vector2> freeTiles) { Guid id = spaceComponents.CreateEntity(); spaceComponents.Entities.Where(x => x.Id == id).First().ComponentFlags = ComponentMasks.Drawable | ComponentMasks.GlowingOutline | ComponentMasks.PickupItem | ComponentMasks.Consumable; spaceComponents.DisplayComponents[id] = new DisplayComponent() { AlwaysDraw = false, Color = Colors.Messages.LootPickup, Opacity = 1f, Origin = Vector2.Zero, Rotation = 0f, Scale = 1f, SpriteEffect = SpriteEffects.None, SpriteSource = new Rectangle(0 * DevConstants.Grid.CellSize, 0 * DevConstants.Grid.CellSize, DevConstants.Grid.CellSize, DevConstants.Grid.CellSize), Symbol = "!", SymbolColor = Color.White }; Vector2 position = freeTiles[spaceComponents.random.Next(0, freeTiles.Count)]; freeTiles.Remove(position); spaceComponents.PositionComponents[id] = new PositionComponent() { Position = position }; spaceComponents.OutlineComponents[id] = new OutlineComponent() { Color = Color.Purple, Opacity = 1f }; spaceComponents.SecondaryOutlineComponents[id] = new SecondaryOutlineComponent() { AlternateColor = Color.LightBlue, Seconds = 0f, SwitchAtSeconds = .75f }; spaceComponents.PickupComponents[id] = new PickupComponent() { PickupType = ItemType.CONSUMABLE }; spaceComponents.ValueComponents[id] = new ValueComponent() { Gold = spaceComponents.random.Next(0, 231) }; spaceComponents.NameComponents[id] = new NameComponent() { Name = "Test Potion", Description = "It is... green." }; spaceComponents.ItemFunctionsComponents[id] = new ItemFunctionsComponent() { Ranged = false, UseFunctionValue = ItemUseFunctions.TESTUSE, Uses = 3, CostToUse = 20 }; spaceComponents.CollisionComponents[id] = new CollisionComponent() { CollidedObjects = new List<Guid>(), Solid = false }; return true; }
public static void UpdateMaxCombo(StateSpaceComponents spaceComponents, Guid entityWithInventory, int hitCombo) { if (spaceComponents.InventoryComponents.ContainsKey(entityWithInventory)) { InventoryComponent inventory = spaceComponents.InventoryComponents[entityWithInventory]; foreach (Guid id in inventory.Artifacts) { ArtifactStatsComponent stats = spaceComponents.ArtifactStatsComponents[id]; stats.MaximumComboWith = (stats.MaximumComboWith >= hitCombo) ? stats.MaximumComboWith : hitCombo; spaceComponents.ArtifactStatsComponents[id] = stats; } } }
public static bool SpawnDownStairway(StateSpaceComponents spaceComponents, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions, List<Vector2> freeTiles) { Guid id = spaceComponents.CreateEntity(); spaceComponents.Entities.Where(x => x.Id == id).First().ComponentFlags = ComponentMasks.Drawable | ComponentMasks.GlowingOutline | ComponentMasks.PickupItem; spaceComponents.DisplayComponents[id] = new DisplayComponent() { AlwaysDraw = false, Color = Color.Black, Opacity = 1f, Origin = Vector2.Zero, Rotation = 0f, Scale = 1f, SpriteEffect = SpriteEffects.None, SpriteSource = new Rectangle(0 * DevConstants.Grid.CellSize, 0 * DevConstants.Grid.CellSize, DevConstants.Grid.CellSize, DevConstants.Grid.CellSize), Symbol = "<", SymbolColor = Color.White }; Vector2 position = freeTiles[spaceComponents.random.Next(0, freeTiles.Count)]; freeTiles.Remove(position); spaceComponents.PositionComponents[id] = new PositionComponent() { Position = position }; spaceComponents.OutlineComponents[id] = new OutlineComponent() { Color = Color.Goldenrod, Opacity = 1f }; spaceComponents.SecondaryOutlineComponents[id] = new SecondaryOutlineComponent() { AlternateColor = Color.White, Seconds = 0f, SwitchAtSeconds = 2f }; spaceComponents.PickupComponents[id] = new PickupComponent() { PickupType = ItemType.DOWNSTAIRS }; spaceComponents.ValueComponents[id] = new ValueComponent() { Gold = spaceComponents.random.Next(0, 231) }; spaceComponents.NameComponents[id] = new NameComponent() { Name = "A Path Downward", Description = "A small passageway leading deeper into this cave system. There's no telling what waits at the other end, but you have a feeling there's no going back once you descend." }; spaceComponents.CollisionComponents[id] = new CollisionComponent() { CollidedObjects = new List<Guid>(), Solid = true }; return true; }
public static bool CrazedMiner(StateSpaceComponents spaceComponents, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions, int cellSize, List<Vector2> freeTiles) { Guid id = spaceComponents.CreateEntity(); spaceComponents.Entities.Where(x => x.Id == id).First().ComponentFlags = ComponentMasks.Drawable | ComponentMasks.CombatReadyAI | ComponentMasks.AIView | ComponentMasks.InventoryPickup; int tileIndex = spaceComponents.random.Next(0, freeTiles.Count); spaceComponents.PositionComponents[id] = new PositionComponent() { Position = freeTiles[tileIndex] }; freeTiles.RemoveAt(tileIndex); spaceComponents.DisplayComponents[id] = new DisplayComponent() { Color = Color.MediumPurple, // Color.DarkRed, Origin = Vector2.Zero, Rotation = 0f, Scale = 1f, SpriteEffect = SpriteEffects.None, SpriteSource = new Rectangle(0 * cellSize, 0 * cellSize, cellSize, cellSize), Symbol = "C", SymbolColor = Color.White, Opacity = 1f }; spaceComponents.SkillLevelsComponents[id] = new SkillLevelsComponent() { CurrentHealth = 25, DieNumber = 1, Health = 25, Defense = 4, Accuracy = 80, Wealth = 100, MinimumDamage = 2, MaximumDamage = 7 }; spaceComponents.CollisionComponents[id] = new CollisionComponent() { Solid = true, CollidedObjects = new List<Guid>() }; spaceComponents.NameComponents[id] = new NameComponent() { Name = "CRAZED MINER", Description = "An injured, shambling husk of a man. He clutches a pickaxe in his hands and precious gems are stuffed in his pockets. It looks like greed got the better of his mind long ago." }; spaceComponents.AIAlignmentComponents[id] = new AIAlignment() { Alignment = AIAlignments.ALIGNMENT_HOSTILE }; spaceComponents.AICombatComponents[id] = new AICombat() { AttackType = AIAttackTypes.ATTACK_TYPE_NORMAL, FleesWhenLowHealth = true }; spaceComponents.AIStateComponents[id] = new AIState() { State = AIStates.STATE_ROAMING }; spaceComponents.AIFieldOfViewComponents[id] = new AIFieldOfView() { DrawField = false, Opacity = .3f, radius = 3, SeenTiles = new List<Vector2>(), Color = FOVColors.Roaming }; spaceComponents.AISleepComponents[id] = new AISleep() { ChanceToWake = 10, FOVRadiusChangeOnWake = 1 }; spaceComponents.AIRoamComponents[id] = new AIRoam() { ChanceToDetect = 25 }; spaceComponents.AIFleeComponents[id] = new AIFlee() { DoesFlee = false, FleeAtHealthPercent = 25, FleeUntilHealthPercent = 30 }; spaceComponents.EntityMessageComponents[id] = new EntityMessageComponent() { AttackNPCMessages = new string[] { "{0} swings its pickaxe at {1}", "{0} shambles toward {1}", "{0} claws madly at {1}", }, AttackPlayerMessages = new string[] { "{0} swings its pickaxe at you", "{0} shambles toward you", "{0} claws madly at you", }, NormalDodgeMessages = new string[] { " but the attack missed!", " and the creature dodges the attack.", " but the creature's defense protects it.", }, StreakDodgeMessages = new string[] { " and, as always, the attack misses.", " and it misses again!", " and it laughs madly.", " and taunts at the attack. \"Give up!\"" }, NormalTakeDamageMessages = new string[] { " and it takes {0} damage.", " and it cries out, {0} health weaker.", " for {0} damage." }, BrokenDodgeStreakTakeDamageMessages = new string[] { " and against all odds deals {0} damage!", " and the cocky creature allows {0} damage to go through!", ", breaking impossible odds, landing {0} damage!!", } }; spaceComponents.InventoryComponents[id] = new InventoryComponent() { Artifacts = new List<Guid>(), Consumables = new List<Guid>(), MaxArtifacts = 0, MaxConsumables = 0 }; return true; }
public static bool SpawnTestEnemyNPC(StateSpaceComponents spaceComponents, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions, int cellSize, List<Vector2> freeTiles) { Guid id = spaceComponents.CreateEntity(); spaceComponents.Entities.Where(x => x.Id == id).First().ComponentFlags = ComponentMasks.Drawable | ComponentMasks.CombatReadyAI | ComponentMasks.AIView | ComponentMasks.InventoryPickup; int tileIndex = spaceComponents.random.Next(0, freeTiles.Count); spaceComponents.PositionComponents[id] = new PositionComponent() { Position = freeTiles[tileIndex] }; freeTiles.RemoveAt(tileIndex); spaceComponents.DisplayComponents[id] = new DisplayComponent() { Color = Colors.Monsters.Red, //Color.DarkRed, Origin = Vector2.Zero, Rotation = 0f, Scale = 1f, SpriteEffect = SpriteEffects.None, SpriteSource = new Rectangle(0 * cellSize, 0 * cellSize, cellSize, cellSize), Symbol = "t", SymbolColor = Color.White, Opacity = 1f }; spaceComponents.SkillLevelsComponents[id] = new SkillLevelsComponent() { CurrentHealth = 25, DieNumber = 1, Health = 25, Defense = 1, Accuracy = 100, Wealth = 25, MinimumDamage = 1, MaximumDamage = 2 }; spaceComponents.CollisionComponents[id] = new CollisionComponent() { Solid = true, CollidedObjects = new List<Guid>() }; spaceComponents.NameComponents[id] = new NameComponent() { Name = "TEST ENEMY NPC", Description = "It seems harmless enough. How dangerous could a red square be?" }; spaceComponents.AIAlignmentComponents[id] = new AIAlignment() { Alignment = AIAlignments.ALIGNMENT_HOSTILE }; spaceComponents.AICombatComponents[id] = new AICombat() { AttackType = AIAttackTypes.ATTACK_TYPE_NORMAL, FleesWhenLowHealth = true }; spaceComponents.AIStateComponents[id] = new AIState() { State = AIStates.STATE_SLEEPING }; spaceComponents.AIFieldOfViewComponents[id] = new AIFieldOfView() { DrawField = false, Opacity = .3f, radius = 2, SeenTiles = new List<Vector2>(), Color = FOVColors.Sleeping }; spaceComponents.AISleepComponents[id] = new AISleep() { ChanceToWake = 15, FOVRadiusChangeOnWake = 2 }; spaceComponents.AIRoamComponents[id] = new AIRoam() { ChanceToDetect = 25 }; spaceComponents.AIFleeComponents[id] = new AIFlee() { DoesFlee = true, FleeAtHealthPercent = 25, FleeUntilHealthPercent = 30 }; spaceComponents.EntityMessageComponents[id] = new EntityMessageComponent() { AttackNPCMessages = new string[] { "{0} swings at the {1}", "{0} applies fury to the {1}'s face", "{0} attempts brute force against {1}", "{0} uses a walking attack fearlessly at {1}" }, AttackPlayerMessages = new string[] { "{0} tests a mighty attack on you", "The {0} glitches out against you", "Watch out! {0} tries to attack you" }, NormalDodgeMessages = new string[] { " but the attack missed!", " and the creature dodges the attack.", " but the creature's defense protects it.", " and the defense test is a success.", " but the combat system test makes the attack miss." }, StreakDodgeMessages = new string[] { " and, as always, the attack misses.", " and it misses again!", " and shows how advanced its AI is by dodging again.", " and taunts at the attack. \"Give up!\"" }, NormalTakeDamageMessages = new string[] { " and it takes {0} damage.", " and it cries out, {0} health weaker.", " and it glitches out, health dropping by {0}.", " for {0} damage." }, BrokenDodgeStreakTakeDamageMessages = new string[] { " and against all odds deals {0} damage!", " and the cocky creature allows {0} damage to go through!", ", breaking impossible odds, landing {0} damage!!", " and the test is broken! It takes {0} damage!" } }; spaceComponents.InventoryComponents[id] = new InventoryComponent() { Artifacts = new List<Guid>(), Consumables = new List<Guid>(), MaxArtifacts = 0, MaxConsumables = 0 }; return true; }
public static bool HandleInventoryInput(StateSpaceComponents spaceComponents, GameTime gameTime, KeyboardState prevKey, KeyboardState key) { bool keepInventory = true; Entity player = spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.Player) == ComponentMasks.Player).FirstOrDefault(); if (player != null) { InventoryMenuComponent menu = spaceComponents.InventoryMenuComponent; InventoryComponent playerInventory = spaceComponents.InventoryComponents[player.Id]; //Construct array of all inventory items List<Guid> items = new List<Guid>(); items.AddRange(playerInventory.Artifacts); items.AddRange(playerInventory.Consumables); int itemSelection = items.IndexOf(menu.SelectedItem); if (itemSelection < 0) { itemSelection = 0; } //Item selection //If nothing is selected, select the first item if ((menu.SelectedItem == Guid.Empty && items.Count > 0) || (items.Count > 0 && !items.Contains(menu.SelectedItem))) { menu.SelectedItem = items[itemSelection]; } if (key.IsKeyDown(Keys.Down) && prevKey.IsKeyUp(Keys.Down)) { itemSelection += 1; if (itemSelection >= items.Count) { itemSelection = 0; } } else if (key.IsKeyDown(Keys.Up) && prevKey.IsKeyUp(Keys.Up)) { itemSelection -= 1; if (itemSelection < 0) { itemSelection = items.Count - 1; } } else if (key.IsKeyDown(Keys.D) && prevKey.IsKeyUp(Keys.D)) { //Drop the selected item. PositionComponent playerPos = spaceComponents.PositionComponents[player.Id]; Entity item = spaceComponents.Entities.Where(x => x.Id == items[itemSelection]).FirstOrDefault(); if(item != null) { item.ComponentFlags |= Component.COMPONENT_POSITION; spaceComponents.PositionComponents[item.Id] = playerPos; playerInventory.Artifacts.Remove(item.Id); playerInventory.Consumables.Remove(item.Id); itemSelection = 0; items.Remove(item.Id); } } else if (key.IsKeyDown(Keys.S) && prevKey.IsKeyUp(Keys.S)) { //Scrap the selected item Entity item = spaceComponents.Entities.Where(x => x.Id == items[itemSelection]).FirstOrDefault(); if (item != null) { SkillLevelsComponent playerSkills = spaceComponents.SkillLevelsComponents[player.Id]; ValueComponent itemValue = spaceComponents.ValueComponents[item.Id]; playerSkills.Wealth += itemValue.Gold; playerInventory.Artifacts.Remove(item.Id); playerInventory.Consumables.Remove(item.Id); spaceComponents.EntitiesToDelete.Add(item.Id); spaceComponents.SkillLevelsComponents[player.Id] = playerSkills; itemSelection = 0; items.Remove(item.Id); } } //Set new selections if (items.Count > 0) { menu.SelectedItem = items[itemSelection]; spaceComponents.InventoryMenuComponent = menu; } else { menu.SelectedItem = Guid.Empty; spaceComponents.InventoryMenuComponent = menu; } } return keepInventory; }
public RandomlyGeneratedStateSpace(IGenerationAlgorithm dungeonGeneration, int worldMin, int worldMax) { stateSpaceComponents = new StateSpaceComponents(); dungeonAlgorithm = dungeonGeneration; dungeonDimensions = dungeonGeneration.GenerateDungeon(ref dungeonGrid, worldMin, worldMax, random); }
public static bool TestUse(StateSpaceComponents spaceComponents, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions, Guid item, Guid user, Vector2 targetPosition) { spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple<Color, string>(Colors.Messages.StatusChange, "You use this item and something happens.")); spaceComponents.DelayedActions.Add(new Action(() => { Guid id = spaceComponents.CreateEntity(); spaceComponents.Entities.Where(c => c.Id == id).First().ComponentFlags = ComponentMasks.DrawableOutline | Component.COMPONENT_TIME_TO_LIVE | ComponentMasks.GlowingOutline; spaceComponents.PositionComponents[id] = new PositionComponent() { Position = targetPosition }; spaceComponents.OutlineComponents[id] = new OutlineComponent() { Color = Color.CornflowerBlue, Opacity = .8f }; spaceComponents.TimeToLiveComponents[id] = new TimeToLiveComponent() { CurrentSecondsAlive = 0f, SecondsToLive = 4f }; spaceComponents.SecondaryOutlineComponents[id] = new SecondaryOutlineComponent() { AlternateColor = Color.Red, Seconds = 0f, SwitchAtSeconds = .6f }; })); return true; }
public static bool SpawnTestArtifact(StateSpaceComponents spaceComponents, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions, List<Vector2> freeTiles) { Guid id = spaceComponents.CreateEntity(); spaceComponents.Entities.Where(x => x.Id == id).First().ComponentFlags = ComponentMasks.Drawable | ComponentMasks.GlowingOutline | ComponentMasks.PickupItem | ComponentMasks.Artifact; spaceComponents.DisplayComponents[id] = new DisplayComponent() { AlwaysDraw = false, Color = Colors.Messages.LootPickup, Opacity = 1f, Origin = Vector2.Zero, Rotation = 0f, Scale = 1f, SpriteEffect = SpriteEffects.None, SpriteSource = new Rectangle(0 * DevConstants.Grid.CellSize, 0 * DevConstants.Grid.CellSize, DevConstants.Grid.CellSize, DevConstants.Grid.CellSize), Symbol = "{}", SymbolColor = Color.White }; Vector2 position = freeTiles[spaceComponents.random.Next(0, freeTiles.Count)]; freeTiles.Remove(position); spaceComponents.PositionComponents[id] = new PositionComponent() { Position = position }; spaceComponents.OutlineComponents[id] = new OutlineComponent() { Color = Color.Purple, Opacity = 1f }; spaceComponents.SecondaryOutlineComponents[id] = new SecondaryOutlineComponent() { AlternateColor = Color.LightBlue, Seconds = 0f, SwitchAtSeconds = .75f }; spaceComponents.PickupComponents[id] = new PickupComponent() { PickupType = ItemType.ARTIFACT }; spaceComponents.ValueComponents[id] = new ValueComponent() { Gold = 10 }; spaceComponents.StatModificationComponents[id] = new StatModificationComponent() { AccuracyChange = 10, DefenseChange = 25, DieNumberChange = 1, HealthChange = 50, MaximumDamageChange = 5, MinimumDamageChange = -2, }; spaceComponents.NameComponents[id] = new NameComponent() { Name = "Test Artifact", Description = "FORGED IN THE FIERY PITS OF HELL, THIS MESH OF STEEL AND MAGIC HAS ONLY ONE PURPOSE: THE UTTER DECIMATION OF ALL WHO WAGE WAR AGAINST ITS OWNER. AS YOU EQUIP THIS ITEM YOU FEEL A FORBODING PULSE ALONG YOUR SPINE WHICH RIPPLES OUTWARD INTO EVERY INCH OF YOUR FLESH. IS IT MADNESS THAT SEEKS A NEW HOME, OR SIMPLY THE GUILT OF DONNING SUCH AN EVIL DEFENSE?" }; spaceComponents.CollisionComponents[id] = new CollisionComponent() { CollidedObjects = new List<Guid>(), Solid = false }; spaceComponents.ArtifactStatsComponents[id] = new ArtifactStatsComponent() { UpgradeLevel = 1, FloorFound = spaceComponents.GameplayInfoComponent.FloorsReached }; return 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 IncrementDamageTakenWithArtifact(StateSpaceComponents spaceComponents, Guid entityWithInventory, int damage) { if (spaceComponents.InventoryComponents.ContainsKey(entityWithInventory)) { InventoryComponent inventory = spaceComponents.InventoryComponents[entityWithInventory]; foreach (Guid id in inventory.Artifacts) { ArtifactStatsComponent stats = spaceComponents.ArtifactStatsComponents[id]; stats.DamageTakenWith += damage; spaceComponents.ArtifactStatsComponents[id] = stats; } } }
public static bool SpawnWildVines(StateSpaceComponents spaceComponents, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions, int cellSize, List<Vector2> freeTiles) { Guid id = spaceComponents.CreateEntity(); spaceComponents.Entities.Where(x => x.Id == id).First().ComponentFlags = ComponentMasks.Drawable | ComponentMasks.CombatReadyAI | ComponentMasks.AIView | ComponentMasks.InventoryPickup; int tileIndex = spaceComponents.random.Next(0, freeTiles.Count); spaceComponents.PositionComponents[id] = new PositionComponent() { Position = freeTiles[tileIndex] }; freeTiles.RemoveAt(tileIndex); spaceComponents.DisplayComponents[id] = new DisplayComponent() { Color = Colors.Monsters.Red, // Color.DarkRed, Origin = Vector2.Zero, Rotation = 0f, Scale = 1f, SpriteEffect = SpriteEffects.None, SpriteSource = new Rectangle(0 * cellSize, 0 * cellSize, cellSize, cellSize), Symbol = "W", SymbolColor = Color.White, Opacity = 1f }; spaceComponents.SkillLevelsComponents[id] = new SkillLevelsComponent() { CurrentHealth = 45, DieNumber = 2, Health = 45, Defense = 10, Accuracy = 135, Wealth = 25, MinimumDamage = 5, MaximumDamage = 14 }; spaceComponents.CollisionComponents[id] = new CollisionComponent() { Solid = true, CollidedObjects = new List<Guid>() }; spaceComponents.NameComponents[id] = new NameComponent() { Name = "WILD ROOTS", Description = "Imported fresh from Japan." }; spaceComponents.AIAlignmentComponents[id] = new AIAlignment() { Alignment = AIAlignments.ALIGNMENT_HOSTILE }; spaceComponents.AICombatComponents[id] = new AICombat() { AttackType = AIAttackTypes.ATTACK_TYPE_NORMAL, FleesWhenLowHealth = true }; spaceComponents.AIStateComponents[id] = new AIState() { State = AIStates.STATE_ROAMING }; spaceComponents.AIFieldOfViewComponents[id] = new AIFieldOfView() { DrawField = false, Opacity = .3f, radius = 5, SeenTiles = new List<Vector2>(), Color = FOVColors.Roaming }; spaceComponents.AISleepComponents[id] = new AISleep() { ChanceToWake = 10, FOVRadiusChangeOnWake = 2 }; spaceComponents.AIRoamComponents[id] = new AIRoam() { ChanceToDetect = 40 }; spaceComponents.AIFleeComponents[id] = new AIFlee() { DoesFlee = false, FleeAtHealthPercent = 25, FleeUntilHealthPercent = 30 }; spaceComponents.EntityMessageComponents[id] = new EntityMessageComponent() { AttackNPCMessages = new string[] { "{0} swings its tentacles toward {1}", "{0} applies fury to the {1}'s face", "{0} attempts brute force against {1}", "{0} uses a walking attack fearlessly at {1}" }, AttackPlayerMessages = new string[] { "{0} wiggles its tentacles at you", "The {0} swipes at you multiple times", "Gross.. the tentacles of {0} smear around you" }, NormalDodgeMessages = new string[] { " but the attack missed!", " and the creature dodges the attack.", " but the creature's defense protects it.", " but it uses its tentacle vines to protect itself.", " but the vines are too thick for the attack!" }, StreakDodgeMessages = new string[] { " and, as always, the attack misses.", " and it misses again!", " and it slithers around, cackling", " and taunts at the attack. \"Give up!\"" }, NormalTakeDamageMessages = new string[] { " and it takes {0} damage.", " and it cries out, {0} health weaker.", " and takes {0}, some of its vines dropping dead", " for {0} damage." }, BrokenDodgeStreakTakeDamageMessages = new string[] { " and against all odds deals {0} damage!", " and the cocky creature allows {0} damage to go through!", ", breaking impossible odds, landing {0} damage!!", " and the test is broken! It takes {0} damage!" } }; spaceComponents.InventoryComponents[id] = new InventoryComponent() { Artifacts = new List<Guid>(), Consumables = new List<Guid>(), MaxArtifacts = 0, MaxConsumables = 0 }; return true; }
public static void IncrementTimesMissesWithArtifact(StateSpaceComponents spaceComponents, Guid entityWithInventory) { if (spaceComponents.InventoryComponents.ContainsKey(entityWithInventory)) { InventoryComponent inventory = spaceComponents.InventoryComponents[entityWithInventory]; foreach (Guid id in inventory.Artifacts) { ArtifactStatsComponent stats = spaceComponents.ArtifactStatsComponents[id]; stats.MissesWith += 1; spaceComponents.ArtifactStatsComponents[id] = stats; } } }
public static bool SpawnPlayer(StateSpaceComponents stateSpaceComponents, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions, int cellSize, List<Vector2> freeTiles) { Entity player = stateSpaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.Player) == ComponentMasks.Player).FirstOrDefault(); if(player == null) { Guid id = stateSpaceComponents.CreateEntity(); stateSpaceComponents.Entities.Where(x => x.Id == id).First().ComponentFlags = ComponentMasks.Player | Component.COMPONENT_INPUTMOVEMENT | ComponentMasks.InventoryPickup; //Set Position int tileIndex = stateSpaceComponents.random.Next(0, freeTiles.Count); stateSpaceComponents.PositionComponents[id] = new PositionComponent() { Position = freeTiles[tileIndex] }; freeTiles.RemoveAt(tileIndex); dungeonGrid[(int)stateSpaceComponents.PositionComponents[id].Position.X, (int)stateSpaceComponents.PositionComponents[id].Position.Y].Occupiable = true; //Set Display stateSpaceComponents.DisplayComponents[id] = new DisplayComponent() { Color = Color.White, SpriteSource = new Rectangle(0 * cellSize, 0 * cellSize, cellSize, cellSize), Origin = Vector2.Zero, SpriteEffect = SpriteEffects.None, Scale = 1f, Rotation = 0f, Opacity = 1f, AlwaysDraw = true }; //Set Sightradius stateSpaceComponents.SightRadiusComponents[id] = new SightRadiusComponent() { CurrentRadius = 15, MaxRadius = 15, DrawRadius = true }; //Set first turn stateSpaceComponents.PlayerComponent = new PlayerComponent() { PlayerJustLoaded = true }; //Collision information stateSpaceComponents.CollisionComponents[id] = new CollisionComponent() { CollidedObjects = new List<Guid>(), Solid = true }; //Set name of player stateSpaceComponents.NameComponents[id] = new NameComponent() { Name = "You", Description = "This is me. I came to these caves to find my fortune." }; //Set Input of the player stateSpaceComponents.InputMovementComponents[id] = new InputMovementComponent() { TimeIntervalBetweenMovements = .09f, TimeSinceLastMovement = 0f, InitialWait = .5f, TotalTimeButtonDown = 0f, LastKeyPressed = Keys.None }; //Set an alignment for AI to communicate with stateSpaceComponents.AIAlignmentComponents[id] = new AIAlignment() { Alignment = AIAlignments.ALIGNMENT_FRIENDLY }; //Set combat messages stateSpaceComponents.EntityMessageComponents[id] = new EntityMessageComponent() { NormalDodgeMessages = new string[] { " and the attack misses you!", " but nothing happened.", " ... but it failed!", " and your defense protects you.", " but it fails to connect." }, StreakDodgeMessages = new string[] { " but you don't even notice.", " and you laugh at the attempt.", " but you easily dodge it again.", " and misses you. Again!" }, AttackNPCMessages = new string[] { "{0} attack the {1}", "{0} take a swing at the {1}", "{0} swipe at {1}", "{0} try to damage the {1}", "{0} slash viciously at the {1}" }, NormalTakeDamageMessages = new string[] { " and you take {0} damage.", " and it hurts! You take {0} damage.", "! Ow. You lose {0} health.", " and hits you for {0} damage." }, BrokenDodgeStreakTakeDamageMessages = new string[] { " and you finally take {0} damage.", " and this time you lose {0} health! Ow!", " and hits you for {0} THIS time.", "! {0} damage taken! Don't get cocky..." }, PickupItemMessages = new string[] { "{0} pick up the {1}.", "{0} find a {1}.", "{0} got a {1}!" }, ConsumablesFullMessages = new string[] { "You cannot carry any more consumables.", "Your consumable slots are full!", "You don't have any place to store this consumable." }, ArtifactsFullMessages = new string[] { "Your artifact slots are too full for another.", "Drop or scrap one of your artifacts to pick this up.", "You can't pick up this artifact; you already have enough." } }; //Inventory stateSpaceComponents.InventoryComponents[id] = new InventoryComponent() { Artifacts = new List<Guid>(), Consumables = new List<Guid>(), MaxArtifacts = 3, MaxConsumables = 2 }; } else { //If there's already a player, just make a new starting location on the floor //Set Position int tileIndex = stateSpaceComponents.random.Next(0, freeTiles.Count); stateSpaceComponents.PositionComponents[player.Id] = new PositionComponent() { Position = freeTiles[tileIndex] }; freeTiles.RemoveAt(tileIndex); dungeonGrid[(int)stateSpaceComponents.PositionComponents[player.Id].Position.X, (int)stateSpaceComponents.PositionComponents[player.Id].Position.Y].Occupiable = true; } return true; }
public static bool SpawnGold(StateSpaceComponents spaceComponents, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions, List<Vector2> freeTiles) { Guid id = spaceComponents.CreateEntity(); spaceComponents.Entities.Where(x => x.Id == id).First().ComponentFlags = ComponentMasks.Drawable | ComponentMasks.GlowingOutline | ComponentMasks.PickupItem; spaceComponents.DisplayComponents[id] = new DisplayComponent() { AlwaysDraw = false, Color = Colors.Messages.Special, Opacity = 1f, Origin = Vector2.Zero, Rotation = 0f, Scale = 1f, SpriteEffect = SpriteEffects.None, SpriteSource = new Rectangle(0 * DevConstants.Grid.CellSize, 0 * DevConstants.Grid.CellSize, DevConstants.Grid.CellSize, DevConstants.Grid.CellSize), Symbol = "$", SymbolColor = Color.White }; Vector2 position = freeTiles[spaceComponents.random.Next(0, freeTiles.Count)]; freeTiles.Remove(position); spaceComponents.PositionComponents[id] = new PositionComponent() { Position = position }; spaceComponents.OutlineComponents[id] = new OutlineComponent() { Color = Color.Purple, Opacity = 1f }; spaceComponents.SecondaryOutlineComponents[id] = new SecondaryOutlineComponent() { AlternateColor = Color.LightBlue, Seconds = 0f, SwitchAtSeconds = .75f }; spaceComponents.PickupComponents[id] = new PickupComponent() { PickupType = ItemType.GOLD }; spaceComponents.ValueComponents[id] = new ValueComponent() { Gold = spaceComponents.random.Next(0, 231) }; spaceComponents.NameComponents[id] = new NameComponent() { Name = "Gold", Description = "Some people try and use fancy names for this mass of wealth. Credits, Stardust, Gil... it buys shelter and women all the same." }; spaceComponents.CollisionComponents[id] = new CollisionComponent() { CollidedObjects = new List<Guid>(), Solid = false }; return true; }