public RTSCameraAgentComponent(Agent agent) : base(agent)
        {
            for (int i = 0; i < _colors.Length; ++i)
            {
                _colors[i] = new Contour(null, false);
            }

            CurrentTargetPosition = new QueryData <WorldPosition>(() =>
            {
                try
                {
                    var unit      = Agent;
                    var formation = unit.Formation;
                    if (formation == null)
                    {
                        return(WorldPosition.Invalid);
                    }
                    var targetFormation = QueryDataStore.Get(formation.TargetFormation);

                    if (QueryLibrary.IsRangedCavalry(unit))
                    {
                        var targetAgent = unit.GetTargetAgent();
                        if (targetAgent == null || targetAgent.Formation != formation.TargetFormation)
                        {
                            Vec2 unitPosition = unit.Position.AsVec2;
                            targetAgent       = targetFormation.NearestAgent(unitPosition);
                        }

                        return(targetAgent?.GetWorldPosition() ?? new WorldPosition());
                    }

                    if (QueryLibrary.IsCavalry(unit))
                    {
                        var targetAgent = unit.GetTargetAgent();
                        if (targetAgent == null || targetAgent.Formation != formation.TargetFormation)
                        {
                            Vec2 unitPosition = formation.GetCurrentGlobalPositionOfUnit(unit, true) * 0.2f +
                                                unit.Position.AsVec2 * 0.8f;
                            targetAgent = targetFormation.NearestOfAverageOfNearestPosition(unitPosition, 7);
                        }

                        if (targetAgent != null)
                        {
                            if (targetAgent.HasMount)
                            {
                                return(targetAgent.GetWorldPosition());
                            }

                            var targetPosition  = targetAgent.GetWorldPosition();
                            var targetDirection = targetPosition.AsVec2 - unit.Position.AsVec2;
                            var distance        = targetDirection.Normalize();
                            var result          = targetPosition;

                            // new
                            if (distance > 20)
                            {
                                CurrentDirection = targetDirection;
                                result.SetVec2(targetDirection * 10 + targetPosition.AsVec2);
                            }
                            else if (distance > 5 && targetDirection.DotProduct(CurrentDirection) < 0)
                            {
                                result.SetVec2(
                                    (CurrentDirection.DotProduct(targetDirection * distance) + 50) * CurrentDirection +
                                    unit.Position.AsVec2);
                            }
                            else
                            {
                                result.SetVec2(CurrentDirection * 10 + targetPosition.AsVec2);
                            }


                            // old
                            //if (distance < 3)
                            //{
                            //    result = unit.GetWorldPosition();
                            //    result.SetVec2(CurrentDirection * 20 + result.AsVec2);
                            //}
                            //else
                            //{
                            //    if (distance < 20 && targetDirection.DotProduct(CurrentDirection) < 0)
                            //    {
                            //        result.SetVec2(-targetDirection * 50 + result.AsVec2);
                            //    }
                            //    else
                            //    {
                            //        CurrentDirection = targetDirection;
                            //        result.SetVec2(targetDirection * 10 + result.AsVec2);
                            //    }

                            //}


                            return(result.GetNavMesh() == UIntPtr.Zero ||
                                   !Mission.Current.IsPositionInsideBoundaries(result.AsVec2)
                                ? targetPosition
                                : result);
                        }

                        return(WorldPosition.Invalid);
                    }
                    else
                    {
                        var targetAgent = unit.GetTargetAgent();
                        if (targetAgent == null || targetAgent.Formation != formation.TargetFormation)
                        {
                            Vec2 unitPosition = formation.GetCurrentGlobalPositionOfUnit(unit, true) * 0.2f +
                                                unit.Position.AsVec2 * 0.8f;
                            targetAgent = targetFormation.NearestAgent(unitPosition);
                        }

                        return(targetAgent?.GetWorldPosition() ?? new WorldPosition());
                    }
                }
                catch (Exception e)
                {
                    Utility.DisplayMessage(e.ToString());
                }

                return(WorldPosition.Invalid);
            }, 0.2f);
        }
Exemple #2
0
        private WorldPosition GetTargetPosition(Agent agent)
        {
            try
            {
                var unit = agent;
                if (!unit.IsActive())
                {
                    return(WorldPosition.Invalid);
                }
                var formation = unit.Formation;
                if (formation == null)
                {
                    return(WorldPosition.Invalid);
                }
                var targetFormation = QueryDataStore.Get(formation.TargetFormation);

                Vec2 offset;
                if (QueryLibrary.IsCavalry(unit) || QueryLibrary.IsRangedCavalry(unit) &&
                    formation.FiringOrder.OrderType == OrderType.HoldFire)
                {
                    var averageOfTargetAgents = QueryDataStore.Get(formation).AverageOfTargetAgents.Value;

                    offset = averageOfTargetAgents.IsValid ? formation.TargetFormation.QuerySystem.AveragePosition * 0.2f + averageOfTargetAgents * 0.8f - formation.QuerySystem.AveragePosition : Vec2.Zero;
                }
                else if (QueryLibrary.IsInfantry(unit) || QueryLibrary.IsRanged(unit) &&
                         formation.FiringOrder.OrderType == OrderType.HoldFire)
                {
                    var targetCenterAgent =
                        targetFormation.NearestAgent(formation.CurrentPosition);
                    if (targetCenterAgent == null)
                    {
                        return(WorldPosition.Invalid);
                    }
                    offset = targetCenterAgent.Position.AsVec2 - formation.CurrentPosition;
                }
                else
                {
                    return(WorldPosition.Invalid);
                }

                Vec2 targetPosition = formation.GetCurrentGlobalPositionOfUnit(unit, true) + offset;

                var targetAgent = targetFormation.NearestAgent(targetPosition);
                var result      = targetAgent?.GetWorldPosition() ?? WorldPosition.Invalid;
                PositionOfTargetAgent.SetValue(result.AsVec2, MBCommon.GetTime(MBCommon.TimeType.Mission));
                if (targetAgent == null || !result.IsValid || result.GetNavMesh() == UIntPtr.Zero)
                {
                    result = unit.GetWorldPosition();
                    result.SetVec2(result.AsVec2 + unit.GetMovementDirection().AsVec2 * 0.1f);
                    return(result);
                }

                if (QueryLibrary.IsInfantry(unit) || QueryLibrary.IsRanged(unit) &&
                    formation.FiringOrder.OrderType == OrderType.HoldFire)
                {
                    result.SetVec2((unit.Position.AsVec2 - result.AsVec2).Normalized() * 0.8f + result.AsVec2 +
                                   targetAgent.Velocity.AsVec2 * 1);
                }
                else if (QueryLibrary.IsCavalry(unit) || QueryLibrary.IsRangedCavalry(unit) &&
                         formation.FiringOrder.OrderType == OrderType.HoldFire)
                {
                    result.SetVec2((result.AsVec2 - unit.Position.AsVec2).Normalized() * 3f + result.AsVec2 +
                                   targetAgent.Velocity.AsVec2 * 1 + unit.Velocity.AsVec2 * 1);
                }
                else
                {
                    return(WorldPosition.Invalid);
                }
                return(result);
            }
            catch (Exception e)
            {
                Utility.DisplayMessage(e.ToString());
            }

            return(WorldPosition.Invalid);
        }