public static void AICheckDetection(StateSpaceComponents spaceComponents) { if (spaceComponents.PlayerComponent.PlayerTookTurn) { foreach (Guid id in spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.CombatReadyAI) == ComponentMasks.CombatReadyAI).Select(x => x.Id)) { AIState state = spaceComponents.AIStateComponents[id]; switch (state.State) { case AIStates.STATE_SLEEPING: AISystem.AITryToWake(id, spaceComponents); break; case AIStates.STATE_ROAMING: AISystem.AITryToFind(id, spaceComponents); 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; } } } } }