// Use this for initialization void Start() { if (gameObject.tag == "virus") { fov = GetComponent <AIFieldOfView> (); } }
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)); } } } } } }
private static void AITryToWake(Guid entity, StateSpaceComponents spaceComponents) { AIFieldOfView entityFOV = spaceComponents.AIFieldOfViewComponents[entity]; AIAlignment entityAlignment = spaceComponents.AIAlignmentComponents[entity]; AISleep entitySleep = spaceComponents.AISleepComponents[entity]; AIState entityState = spaceComponents.AIStateComponents[entity]; foreach (Guid id in spaceComponents.Entities.Where(x => ((x.ComponentFlags & Component.COMPONENT_PLAYER) == Component.COMPONENT_PLAYER) || ((x.ComponentFlags & ComponentMasks.CombatReadyAI) == ComponentMasks.CombatReadyAI)).Select(x => x.Id)) { PositionComponent position = spaceComponents.PositionComponents[id]; AIAlignment alignment = spaceComponents.AIAlignmentComponents[id]; if (entityFOV.SeenTiles.Contains(position.Position) && entityAlignment.Alignment != alignment.Alignment && spaceComponents.random.Next(1, 101) <= entitySleep.ChanceToWake) { entityState.State = AIStates.STATE_ROAMING; entityFOV.radius += entitySleep.FOVRadiusChangeOnWake; entityFOV.Color = FOVColors.Roaming; spaceComponents.AIStateComponents[entity] = entityState; spaceComponents.AIFieldOfViewComponents[entity] = entityFOV; spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple <Color, string>(Colors.Messages.StatusChange, string.Format("[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] " + Messages.AwokenBySight[spaceComponents.random.Next(0, Messages.AwokenBySight.Count())], spaceComponents.NameComponents[entity].Name))); return; } } }
void OnSceneGUI() { //get enemy object AIFieldOfView fov = (AIFieldOfView)target; //set wire color to white Handles.color = Color.green; //draw the circle based on the radius in fov script Handles.DrawWireArc(fov.transform.position, Vector3.up, Vector3.forward, 360.0f, fov.standingViewRadius); // make two lines that show the area of view Vector3 viewAngleA = fov.DirFromAngle(-fov.viewAngle / 2, false); Vector3 viewAngleB = fov.DirFromAngle(fov.viewAngle / 2, false); // draw the field of view lines Handles.DrawLine(fov.transform.position, fov.transform.position + viewAngleA * fov.standingViewRadius); Handles.DrawLine(fov.transform.position, fov.transform.position + viewAngleB * fov.standingViewRadius); Handles.DrawLine(fov.transform.position + Vector3.down * fov.viewHeight, fov.transform.position + Vector3.up * fov.viewHeight); //change color to red for line of sight line Handles.color = Color.red; //set each line to red foreach (Transform visibleTarget in fov._visibleTargets) { Handles.DrawLine(fov.transform.position, visibleTarget.position); } }
public static void AICheckFleeing(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]; if (state.State == AIStates.STATE_ATTACKING) { AIFlee flee = spaceComponents.AIFleeComponents[id]; if (flee.DoesFlee) { AIFieldOfView FOV = spaceComponents.AIFieldOfViewComponents[id]; SkillLevelsComponent skills = spaceComponents.SkillLevelsComponents[id]; AIAlignment alignment = spaceComponents.AIAlignmentComponents[id]; double healthPercent = ((double)skills.CurrentHealth / (double)skills.Health) * 100; if (healthPercent <= flee.FleeAtHealthPercent) { state.State = AIStates.STATE_FLEEING; FOV.Color = FOVColors.Fleeing; spaceComponents.AIStateComponents[id] = state; spaceComponents.AIFieldOfViewComponents[id] = FOV; spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple <Color, string>(Colors.Messages.StatusChange, string.Format("[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] " + Messages.Flee[spaceComponents.random.Next(0, Messages.Flee.Count())], spaceComponents.NameComponents[id].Name))); } } } else if (state.State == AIStates.STATE_FLEEING) { AIFlee flee = spaceComponents.AIFleeComponents[id]; AIFieldOfView FOV = spaceComponents.AIFieldOfViewComponents[id]; SkillLevelsComponent skills = spaceComponents.SkillLevelsComponents[id]; double healthPercent = ((double)skills.CurrentHealth / (double)skills.Health) * 100; AIAlignment alignment = spaceComponents.AIAlignmentComponents[id]; if (healthPercent >= flee.FleeUntilHealthPercent) { state.State = AIStates.STATE_ATTACKING; spaceComponents.AIStateComponents[id] = state; FOV.Color = FOVColors.Fleeing; spaceComponents.AIStateComponents[id] = state; spaceComponents.AIFieldOfViewComponents[id] = FOV; spaceComponents.GameMessageComponent.GameMessages.Add(new Tuple <Color, string>(Colors.Messages.StatusChange, string.Format("[TURN " + spaceComponents.GameplayInfoComponent.StepsTaken + "] " + Messages.Flee[spaceComponents.random.Next(0, Messages.Flee.Count())], spaceComponents.NameComponents[id].Name))); } } } } }
public static void UpdateFovColors(StateSpaceComponents spaceComponents, GameTime gameTime) { foreach (Guid id in spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.FOVColorChange) == ComponentMasks.FOVColorChange).Select(x => x.Id)) { AlternateFOVColorChangeComponent altColorInfo = spaceComponents.AlternateFOVColorChangeComponents[id]; altColorInfo.Seconds += (float)gameTime.ElapsedGameTime.TotalSeconds; if (altColorInfo.Seconds >= altColorInfo.SwitchAtSeconds) { AIFieldOfView fovInfo = spaceComponents.AIFieldOfViewComponents[id]; Color temp = fovInfo.Color; fovInfo.Color = altColorInfo.AlternateColor; altColorInfo.AlternateColor = temp; altColorInfo.Seconds = 0f; spaceComponents.AIFieldOfViewComponents[id] = fovInfo; } spaceComponents.AlternateFOVColorChangeComponents[id] = altColorInfo; } }
public static void AIUpdateVision(StateSpaceComponents spaceComponents, DungeonTile[,] dungeonGrid, Vector2 dungeonDimensions) { foreach (Guid id in spaceComponents.Entities.Where(x => (x.ComponentFlags & ComponentMasks.AIView) == ComponentMasks.AIView).Select(x => x.Id)) { AIFieldOfView fieldOfViewInfo = spaceComponents.AIFieldOfViewComponents[id]; //Reset seen tiles fieldOfViewInfo.SeenTiles = new List <Vector2>(); if (fieldOfViewInfo.radius >= 0) { Vector2 position = spaceComponents.PositionComponents[id].Position; int radius = fieldOfViewInfo.radius; int initialX, x0, initialY, y0; initialX = x0 = (int)position.X; initialY = y0 = (int)position.Y; List <Vector2> visionRange = new List <Vector2>(); int x = radius; int y = 0; int decisionOver2 = 1 - x; // Decision criterion divided by 2 evaluated at x=r, y=0 while (y <= x) { if (-x + x0 >= 0 && -y + y0 >= 0) { // Octant 5 visionRange.Add(new Vector2(-x + x0, -y + y0)); } else { int newX = -x + x0 >= 0 ? -x + x0 : 0; int newY = -y + y0 >= 0 ? -y + y0 : 0; visionRange.Add(new Vector2(newX, newY)); } if (-y + x0 >= 0 && -x + y0 >= 0) { // Octant 6 visionRange.Add(new Vector2(-y + x0, -x + y0)); } else { int newX = -y + x0 >= 0 ? -y + x0 : 0; int newY = -x + y0 >= 0 ? -x + y0 : 0; visionRange.Add(new Vector2(newX, newY)); } if (x + x0 < dungeonDimensions.X && -y + y0 >= 0) { // Octant 8 visionRange.Add(new Vector2(x + x0, -y + y0)); } else { int newX = x + x0 < dungeonDimensions.X ? x + x0 : (int)dungeonDimensions.X - 1; int newY = -y + y0 >= 0 ? -y + y0 : 0; visionRange.Add(new Vector2(newX, newY)); } if (y + x0 < dungeonDimensions.X && -x + y0 >= 0) { // Octant 7 visionRange.Add(new Vector2(y + x0, -x + y0)); } else { int newX = y + x0 < dungeonDimensions.X ? y + x0 : (int)dungeonDimensions.X - 1; int newY = -x + y0 >= 0 ? -x + y0 : 0; visionRange.Add(new Vector2(newX, newY)); } if (x + x0 < dungeonDimensions.X && y + y0 < dungeonDimensions.Y) { // Octant 1 visionRange.Add(new Vector2(x + x0, y + y0)); } else { int newX = x + x0 < dungeonDimensions.X ? x + x0 : (int)dungeonDimensions.X - 1; int newY = y + y0 < dungeonDimensions.Y ? y + y0 : (int)dungeonDimensions.Y - 1; visionRange.Add(new Vector2(newX, newY)); } if (y + x0 < dungeonDimensions.X && x + y0 < dungeonDimensions.Y) { // Octant 2 visionRange.Add(new Vector2(y + x0, x + y0)); } else { int newX = y + x0 < dungeonDimensions.X ? y + x0 : (int)dungeonDimensions.X - 1; int newY = x + y0 < dungeonDimensions.Y ? x + y0 : (int)dungeonDimensions.Y - 1; visionRange.Add(new Vector2(newX, newY)); } if (-y + x0 >= 0 && x + y0 < dungeonDimensions.Y) { // Octant 3 visionRange.Add(new Vector2(-y + x0, x + y0)); } else { int newX = -y + x0 >= 0 ? -y + x0 : 0; int newY = x + y0 < dungeonDimensions.Y ? x + y0 : (int)dungeonDimensions.Y - 1; visionRange.Add(new Vector2(newX, newY)); } if (-x + x0 >= 0 && y + y0 < dungeonDimensions.Y) { // Octant 4 visionRange.Add(new Vector2(-x + x0, y + y0)); } else { int newX = -x + x0 >= 0 ? -x + x0 : 0; int newY = y + y0 < dungeonDimensions.Y ? y + y0 : (int)dungeonDimensions.Y - 1; visionRange.Add(new Vector2(newX, newY)); } y++; if (decisionOver2 <= 0) { decisionOver2 += 2 * y + 1; // Change in decision criterion for y -> y+1 } else { x--; decisionOver2 += 2 * (y - x) + 1; // Change for y -> y+1, x -> x-1 } } //Fill the circle foreach (var visionLine in visionRange.GroupBy(z => z.Y)) { int smallestX = -1; int largestX = -1; foreach (var point in visionLine) { smallestX = smallestX == -1 ? (int)point.X : smallestX; largestX = largestX == -1 ? (int)point.X : largestX; if ((int)point.X < smallestX) { smallestX = (int)point.X; } if ((int)point.X > largestX) { largestX = (int)point.X; } } //Build a line of points from smallest to largest x for (int z = smallestX; z <= largestX; z++) { visionRange.Add(new Vector2(z, visionLine.Key)); } } foreach (Vector2 point in visionRange) { x0 = initialX; y0 = initialY; int dx = Math.Abs((int)point.X - x0), sx = x0 < (int)point.X ? 1 : -1; int dy = -Math.Abs((int)point.Y - y0), sy = y0 < (int)point.Y ? 1 : -1; int err = dx + dy, e2; /* error value e_xy */ for (;;) { /* loop */ if (dungeonGrid[x0, y0].Occupiable) { fieldOfViewInfo.SeenTiles.Add(new Vector2(x0, y0)); } else { break; } if (x0 == (int)point.X && y0 == (int)point.Y) { break; } e2 = 2 * err; if (e2 >= dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */ if (e2 <= dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */ } } fieldOfViewInfo.SeenTiles = fieldOfViewInfo.SeenTiles.Distinct().ToList(); spaceComponents.AIFieldOfViewComponents[id] = fieldOfViewInfo; } } }
private static GameObject CreateAI(AIProperties properties) { // Instantiate AI object GameObject ai = GameObject.Instantiate(properties.GetModel(), Vector3.zero, Quaternion.identity); // Set tag and layer ai.name = properties.GetName(); ai.tag = TNC.AI; switch (properties.GetAIType()) { case AIProperties.AIType.AgainstAll: ai.layer = LayerMask.NameToLayer(LNC.AI); break; case AIProperties.AIType.Friendly: ai.layer = LayerMask.NameToLayer(LNC.AI_FRIENDLY); break; case AIProperties.AIType.Enemy: ai.layer = LayerMask.NameToLayer(LNC.AI_ENEMY); break; } // Set components Animator animator = ai.GetComponent <Animator>(); if (animator == null) { animator = ai.AddComponent <Animator>(); } if (properties.GetController() != null) { animator.runtimeAnimatorController = properties.GetController(); } AIController controller = ai.GetComponent <AIController>(); if (controller == null) { controller = ai.AddComponent <AIController>(); } AIHealth health = ai.GetComponent <AIHealth>(); if (health == null) { health = ai.AddComponent <AIHealth>(); } AIFieldOfView fieldOfView = ai.GetComponent <AIFieldOfView>(); if (fieldOfView == null) { fieldOfView = ai.AddComponent <AIFieldOfView>(); } AIAttackSystem attackSystem = ai.GetComponent <AIAttackSystem>(); if (attackSystem == null) { attackSystem = ai.AddComponent <AIAttackSystem>(); } AIReloadSystem reloadSystem = ai.GetComponent <AIReloadSystem>(); if (reloadSystem == null) { reloadSystem = ai.AddComponent <AIReloadSystem>(); } AIAnimatorHandler animatorHandler = ai.GetComponent <AIAnimatorHandler>(); if (animatorHandler == null) { animatorHandler = ai.AddComponent <AIAnimatorHandler>(); } CharacterRagdollSystem ragdollSystem = ai.GetComponent <CharacterRagdollSystem>(); if (ragdollSystem == null) { ragdollSystem = ai.AddComponent <CharacterRagdollSystem>(); } NavMeshAgent navMeshAgent = ai.GetComponent <NavMeshAgent>(); if (navMeshAgent == null) { navMeshAgent = ai.AddComponent <NavMeshAgent>(); } CapsuleCollider capsuleCollider = ai.GetComponent <CapsuleCollider>(); if (capsuleCollider == null) { capsuleCollider = ai.AddComponent <CapsuleCollider>(); } AudioSource audioSource = ai.GetComponent <AudioSource>(); if (audioSource == null) { audioSource = ai.AddComponent <AudioSource>(); } // Set component positions UEditorInternal.MoveComponentBottom <Animator>(ai.transform); UEditorInternal.MoveComponentBottom <AIController>(ai.transform); UEditorInternal.MoveComponentBottom <AIHealth>(ai.transform); UEditorInternal.MoveComponentBottom <AIFieldOfView>(ai.transform); UEditorInternal.MoveComponentBottom <AIAttackSystem>(ai.transform); UEditorInternal.MoveComponentBottom <AIReloadSystem>(ai.transform); UEditorInternal.MoveComponentBottom <AIAnimatorHandler>(ai.transform); UEditorInternal.MoveComponentBottom <CharacterRagdollSystem>(ai.transform); UEditorInternal.MoveComponentBottom <NavMeshAgent>(ai.transform); UEditorInternal.MoveComponentBottom <CapsuleCollider>(ai.transform); UEditorInternal.MoveComponentBottom <AudioSource>(ai.transform); // Set properties settings fieldOfView.SetTargetMask(properties.GetTargets()); fieldOfView.SetObstacleMask(properties.GetObstacles()); return(ai); }