/// <summary> /// Gets the nearest path graph vertex from the specified position. /// </summary> /// <param name="from"></param> /// <returns></returns> public PathGraphVertex FindNearestPathGraphVertex(Vector2 from) { PathGraphVertex res = null; PathGraphVertex fallDownResult = null; float minDistance = float.MaxValue; foreach (GridField field in fields) { foreach (PathGraphVertex vertex in field.PathGraphVertices) { if (fallDownResult == null) { fallDownResult = vertex; } Vector2 way = (from - vertex.Position.PositionInQuarter); float direction = (way.GetAngle() + 1 * MathHelper.PiOver2) % MathHelper.TwoPi; Quadrangle pathObj = Quadrangle.CreateBand(vertex.Position.PositionInQuarter, direction, 0.5f, way.Length()); //Quadrangle pathObj = new Quadrangle(vertex.Position.PositionInQuarter, vertex.Position.PositionInQuarter, from, from); if ((vertex.Position.PositionInQuarter - from).Length() < minDistance && !IsInCollision(pathObj, x => !(x is Human))) { res = vertex; minDistance = (vertex.Position.PositionInQuarter - from).Length(); } } } if (res != null) { return(res); } return(fallDownResult); }
/// <summary> /// Updates the kill task logic. It navigates the holder to the target and waits for him to shoot the target. If the holder has not a usable gun, it leads him to search for a toolbox. It can also lead him to for a healbox if it is needed. /// </summary> /// <param name="gameTime">Game time</param> public override void Update(GameTime gameTime) { if (Holder.SelectedTool is Gun && ((Gun)Holder.SelectedTool).Type.Range < TownQuarter.SquareWidth) { Box nearestToolBox = Holder.Position.Quarter.GetNearestBox(Holder.Position, true); if (nearestToolBox != null) { Holder.AddUrgentTask(new MoveTask(Holder, nearestToolBox.Pivot)); } } int neededHealth = target.Health - (Holder.SelectedTool is Gun ? ((Gun)Holder.SelectedTool).Type.Damage : 0); if (Holder.Health < neededHealth) { Box nearestHealBox = Holder.Position.Quarter.GetNearestBox(Holder.Position, false); if (nearestHealBox != null) { Holder.AddUrgentTask(new MoveTask(Holder, nearestHealBox.Pivot)); } } if (gameTime.TotalGameTime - lastUpdatedWaypoints > RecomputeWaypointsTimeout && (lastTargetQuarter != target.Position.Quarter || target.Position.Quarter == Holder.Position.Quarter)) { lastTargetQuarter = target.Position.Quarter; goStraightToTarget = false; if (Holder.Position.Quarter == target.Position.Quarter) { Vector2 wayVect = (target.Position.PositionInQuarter - Holder.Position.PositionInQuarter); float direction = (wayVect.GetAngle() + 1 * MathHelper.PiOver2) % MathHelper.TwoPi; Quadrangle viewLine = Quadrangle.CreateBand(Holder.Pivot.PositionInQuarter, direction, Holder.Size.X, wayVect.Length()); goStraightToTarget = !Grid.IsInCollision(viewLine, c => !(c is Human)); } if (!goStraightToTarget) { RecomputeWaypoints(Holder.Position, target.Position); } lastUpdatedWaypoints = gameTime.TotalGameTime; } if (goStraightToTarget) { if (Holder.Position.MinimalDistanceTo(target.Position) > TownQuarter.SquareWidth) { Holder.GoThisWay(target.Position, (float)gameTime.ElapsedGameTime.TotalSeconds); } else { Holder.TurnThisWay(target.Position, (float)gameTime.ElapsedGameTime.TotalSeconds); } } else { base.Update(gameTime); } }
/// <summary> /// Updates the task logic. Leads the human toward the action object and then lets him perform the action. /// </summary> /// <param name="gameTime">Game time</param> public override void Update(GameTime gameTime) { if (gameTime.TotalGameTime - lastUpdatedWaypoints > RecomputeWaypointsTimeout && actionObject.Position.Quarter == Holder.Position.Quarter) { goStraightToObject = false; Vector2 wayVect = (actionObject.Position.PositionInQuarter - Holder.Position.PositionInQuarter); float direction = (wayVect.GetAngle() + 1 * MathHelper.PiOver2) % MathHelper.TwoPi; Quadrangle viewLine = Quadrangle.CreateBand(Holder.Pivot.PositionInQuarter, direction, Holder.Size.X, wayVect.Length()); goStraightToObject = !Grid.IsInCollision(viewLine, c => !(c is Human)); if (!goStraightToObject) { RecomputeWaypoints(Holder.Position, actionObject.Position); } lastUpdatedWaypoints = gameTime.TotalGameTime; } if (goStraightToObject) { Holder.GoThisWay(actionObject.Position, (float)gameTime.ElapsedGameTime.TotalSeconds); } else { base.Update(gameTime); } if (actionObject.IsAvailableFor(Holder)) { if (!started) { actionObject.StartAction(Holder, gameTime); actionStart = gameTime.TotalGameTime; started = true; } else { if (gameTime.TotalGameTime - actionStart > actionObject.ActionDuration) { actionObject.EndAction(Holder, gameTime); complete = true; } } } else { if (WayPoints.Count == 0 && !IsComplete()) { RecomputeWaypoints(Holder.Position, actionObject.Position); lastUpdatedWaypoints = gameTime.TotalGameTime; } } }