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 void HandleMeleeCombat(StateSpaceComponents spaceComponents, int cellSize) { IEnumerable <Guid> entities = spaceComponents.GlobalCollisionComponent.EntitiesThatCollided.Distinct(); foreach (Guid id in entities) { Entity collidingObject = spaceComponents.Entities.Where(x => x.Id == id).FirstOrDefault(); if (collidingObject == null || (((collidingObject.ComponentFlags & ComponentMasks.CombatReadyAI) != ComponentMasks.CombatReadyAI) && (collidingObject.ComponentFlags & Component.COMPONENT_PLAYER) != Component.COMPONENT_PLAYER)) { //If the colliding object isn't a combat ready AI or a player, don't try to do combat with it. continue; } foreach (Guid collidedEntity in spaceComponents.CollisionComponents[id].CollidedObjects) { Entity collidedObject = spaceComponents.Entities.Where(x => x.Id == collidedEntity).FirstOrDefault(); if (collidedObject != null && (((collidedObject.ComponentFlags & ComponentMasks.CombatReadyAI) == ComponentMasks.CombatReadyAI) || (collidedObject.ComponentFlags & Component.COMPONENT_PLAYER) == Component.COMPONENT_PLAYER)) { int damageDone = 0; SkillLevelsComponent collidedStats = spaceComponents.SkillLevelsComponents[collidedEntity]; SkillLevelsComponent attackingStats = spaceComponents.SkillLevelsComponents[id]; EntityMessageComponent collidedMessages = spaceComponents.EntityMessageComponents[collidedEntity]; EntityMessageComponent attackingMessages = spaceComponents.EntityMessageComponents[id]; bool isPlayerAttacking = ((spaceComponents.Entities.Where(x => x.Id == id).First().ComponentFlags & Component.COMPONENT_PLAYER) == Component.COMPONENT_PLAYER); bool isPlayerBeingAttacked = ((spaceComponents.Entities.Where(x => x.Id == collidedEntity).First().ComponentFlags & Component.COMPONENT_PLAYER) == Component.COMPONENT_PLAYER); //If the two attacking creatures don't share an alignment, allow the attack to happen. if (spaceComponents.AIAlignmentComponents[id].Alignment != spaceComponents.AIAlignmentComponents[collidedEntity].Alignment && collidedStats.CurrentHealth > 0 && attackingStats.CurrentHealth > 0) { string combatString = "[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] "; combatString += isPlayerBeingAttacked ? string.Format(attackingMessages.AttackPlayerMessages[spaceComponents.random.Next(0, attackingMessages.AttackPlayerMessages.Count())], spaceComponents.NameComponents[id].Name) : string.Format(attackingMessages.AttackNPCMessages[spaceComponents.random.Next(0, attackingMessages.AttackNPCMessages.Count())], spaceComponents.NameComponents[id].Name, spaceComponents.NameComponents[collidedEntity].Name); //Hit if (CombatSystem.WillMeleeAttackHit(spaceComponents.random, CombatSystem.CalculateAccuracy(spaceComponents, attackingStats, id, collidedStats, collidedEntity))) { //Determine weapon strength and die numbers here, then... damageDone = CombatSystem.CalculateMeleeDamage(spaceComponents, attackingStats, id); collidedStats.CurrentHealth -= damageDone; if (attackingStats.TimesMissed > 5) { combatString += string.Format(collidedMessages.BrokenDodgeStreakTakeDamageMessages[spaceComponents.random.Next(0, collidedMessages.BrokenDodgeStreakTakeDamageMessages.Count())], damageDone); } else { combatString += string.Format(collidedMessages.NormalTakeDamageMessages[spaceComponents.random.Next(0, collidedMessages.NormalTakeDamageMessages.Count())], damageDone); } attackingStats.TimesHit += 1; attackingStats.TimesMissed = 0; Color messageColor = (spaceComponents.AIAlignmentComponents[id].Alignment == AIAlignments.ALIGNMENT_HOSTILE) ? Colors.Messages.Bad : Colors.Messages.Good; spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple <Microsoft.Xna.Framework.Color, string>(messageColor, combatString)); InventorySystem.IncrementDamageGivenWithArtifact(spaceComponents, id, damageDone); InventorySystem.UpdateMaxCombo(spaceComponents, id, (int)attackingStats.TimesHit); InventorySystem.IncrementDamageTakenWithArtifact(spaceComponents, collidedEntity, damageDone); if ((spaceComponents.Entities.Where(x => x.Id == collidedEntity).First().ComponentFlags & Component.COMPONENT_AI_STATE) == Component.COMPONENT_AI_STATE) { AIState state = spaceComponents.AIStateComponents[collidedEntity]; if (state.State == AIStates.STATE_ROAMING) { AISystem.AITryToFind(collidedEntity, spaceComponents); } } } //Miss else { attackingStats.TimesMissed += 1; if (attackingStats.TimesMissed > 5) { combatString += string.Format(collidedMessages.StreakDodgeMessages[spaceComponents.random.Next(0, collidedMessages.StreakDodgeMessages.Count())], damageDone); } else { combatString += string.Format(collidedMessages.NormalDodgeMessages[spaceComponents.random.Next(0, collidedMessages.NormalDodgeMessages.Count())], damageDone); } attackingStats.TimesHit = 0; Color messageColor = (spaceComponents.AIAlignmentComponents[id].Alignment == AIAlignments.ALIGNMENT_HOSTILE) ? Colors.Messages.Good : Colors.Messages.Bad; spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple <Microsoft.Xna.Framework.Color, string>(messageColor, combatString)); InventorySystem.IncrementTimesDodgedWithArtifact(spaceComponents, collidedEntity); InventorySystem.IncrementTimesMissesWithArtifact(spaceComponents, id); } if (collidedStats.CurrentHealth <= 0) { Entity deadEntity = spaceComponents.Entities.Where(x => x.Id == collidedEntity).FirstOrDefault(); if (deadEntity != null) { InventorySystem.DropWholeInventory(spaceComponents, deadEntity.Id, spaceComponents.PositionComponents[deadEntity.Id].Position); deadEntity.ComponentFlags &= ~Component.COMPONENT_POSITION; } InventorySystem.IncrementKillsWithArtifact(spaceComponents, id); spaceComponents.EntitiesToDelete.Add(collidedEntity); if (isPlayerAttacking) { spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple <Color, string>(Colors.Messages.Special, string.Format("[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] " + "You killed the {0}!", spaceComponents.NameComponents[collidedEntity].Name))); GameplayInfoComponent gameInfo = spaceComponents.GameplayInfoComponent; gameInfo.Kills += 1; spaceComponents.GameplayInfoComponent = gameInfo; } else if (isPlayerBeingAttacked) { spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple <Color, string>(Colors.Messages.Special, string.Format("[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] " + "You were killed by a {0}!", spaceComponents.NameComponents[id].Name))); //SCORE RECORD } else { spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple <Color, string>(Colors.Messages.Special, string.Format("[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] " + "{0} killed the {1}!", spaceComponents.NameComponents[id].Name, spaceComponents.NameComponents[collidedEntity].Name))); } } spaceComponents.SkillLevelsComponents[id] = attackingStats; spaceComponents.SkillLevelsComponents[collidedEntity] = collidedStats; } } } } }