示例#1
0
    void CheckPerimeter()
    {
        if (!perimeter.upToDate)
        {
            perimeter.upToDate = ResetPerimeter();
        }

        // determine enemy heading range etc i.e disposition
        List <GameObject> bogieGOs = new List <GameObject>(bogies.Count);

        for (int i = 0; i < bogies.Count; i++)
        {
            bogieGOs[i] = bogies[i].bogieObject;
        }

        NTools.Slice enemyDisposition = NTools.AnalyseGroupDisposition(
            perimeter.center,
            perimeter.headingFloat,
            bogieGOs
            );

        // Adjust perimeter heading based on enemy positions center of weight

        // Determine green and nongreen population of sectors

        // Compare population to sector importance, compute importanceMet value
        // if needed, add problem of type perimeter
        // if there exists a problem with said sector, but is not relevant anymore, remove problem
    }
示例#2
0
    // untested
    // determine sector by world coordinates, returning 401 means out of perimeter, 404 generic error
    private int DetermineSector(GameObject plot)
    {
        Vector3 plotBearing3D = plot.gameObject.transform.position - perimeter.center;

        float sqrToPlot = Vector3.SqrMagnitude(plotBearing3D);

        if (sqrToPlot > (perimeter.Sectors[12].distanceRange.y * perimeter.Sectors[12].distanceRange.y))
        {
            return(404);
        }               // if the dbogie*dbogie is farther than an outer sector farther distance*distance, return 404, i.e out of perimeter

        float headingToPlot = NTools.HeadingFromVector(new Vector2(plotBearing3D.x, plotBearing3D.y));
        float bearing       = NTools.GetBearingFromHeadings(perimeter.headingFloat, headingToPlot);

        if (bearing > 360 || bearing < 0)
        {
            return(404);
        }                                                           // Sanity check

        // 13 different sectors exist, loop through all, store the one where it is
        for (int i = 0; i <= 12; i++)
        {
            if (sqrToPlot < Mathf.Pow(perimeter.Sectors[i].headingRange.y, 2f) && sqrToPlot > Mathf.Pow(perimeter.Sectors[i].headingRange.x, 2f))
            {
                if (perimeter.Sectors[i].headingRange.x > perimeter.Sectors[i].headingRange.y)
                {
                    if (bearing < perimeter.Sectors[i].headingRange.x && bearing > perimeter.Sectors[i].headingRange.y)
                    {
                        return(i); // i represents the sector index from the sectors array
                    }
                }
                else if (perimeter.Sectors[i].headingRange.x < perimeter.Sectors[i].headingRange.y)
                {
                    if (bearing < perimeter.Sectors[i].headingRange.x || bearing > perimeter.Sectors[i].headingRange.y)
                    {
                        return(i); // i represents the sector index from the sectors array
                    }
                }
            }
        }

        Debug.Log("Determine sector: 404");
        return(404);
    }
示例#3
0
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.Escape) && !LevelManager.isPaused)
        {
            levelManager.PauseGame(menuCanvas);
        }

        if (alive)
        {
            if (!LevelManager.isPaused)
            {
                switch (camSetting)
                {
                case SettingsStatic.CamSettings.player:

                    desiredHeading += Input.GetAxis("Horizontal") * rotationSpeed;
                    float deltaTime = Time.deltaTime;
                    ship.Rotate(desiredHeading, deltaTime);

                    camera.fieldOfView            -= Input.GetAxis("MouseScrollWheel") * zoomSpeed;
                    camera.fieldOfView             = Mathf.Clamp(camera.fieldOfView, 30f, 80f);
                    camera.transform.localPosition = new Vector3(
                        0,
                        camera.fieldOfView * 0.1f,
                        -30f
                        );

                    break;

                case SettingsStatic.CamSettings.north:
                    camera.fieldOfView            -= Input.GetAxis("MouseScrollWheel") * zoomSpeed;
                    camera.fieldOfView             = Mathf.Clamp(camera.fieldOfView, 30f, 80f);
                    camera.transform.localPosition = new Vector3(
                        0,
                        camera.fieldOfView * 0.1f,
                        -30f
                        );

                    aimX -= Input.GetAxis("Horizontal");
                    aimY += Input.GetAxis("Vertical");

                    //Debug.Log("Aimx: " + aimX + " AimY: " + aimY);
                    Vector2 aimChange = new Vector2(aimX, aimY);
                    aimpoint += aimChange;


                    desiredHeading = NTools.HeadingFromVector(aimpoint);
                    ship.Rotate(desiredHeading, Time.deltaTime);

                    //Debug.Log(Input.GetAxis("Horizontal"));

                    aimX = 0f; aimY = 0f;
                    break;
                }

                if (Input.GetKey(KeyCode.W))
                {
                    if (!Input.GetKey(KeyCode.LeftShift))
                    {
                        ship.ThrustForward(1f);
                    }
                    if (Input.GetKey(KeyCode.LeftShift))
                    {
                        ship.ThrustForward(2f);
                    }
                }

                if (Input.GetKey(KeyCode.A))
                {
                    if (!Input.GetKey(KeyCode.LeftShift))
                    {
                        ship.ThrustLeft(1f);
                    }
                    if (Input.GetKey(KeyCode.LeftShift))
                    {
                        ship.ThrustLeft(2f);
                    }
                }

                if (Input.GetKey(KeyCode.S))
                {
                    if (!Input.GetKey(KeyCode.LeftShift))
                    {
                        ship.ThrustBackward(1f);
                    }
                    if (Input.GetKey(KeyCode.LeftShift))
                    {
                        ship.ThrustBackward(2f);
                    }
                }

                if (Input.GetKey(KeyCode.D))
                {
                    if (!Input.GetKey(KeyCode.LeftShift))
                    {
                        ship.ThrustRight(1f);
                    }
                    if (Input.GetKey(KeyCode.LeftShift))
                    {
                        ship.ThrustRight(2f);
                    }
                }

                if (Input.GetKey(KeyCode.X))
                {
                    ship.Stop();
                }

                if (Input.GetKeyDown(KeyCode.C))
                {
                    switch (camSetting)
                    {
                    case SettingsStatic.CamSettings.north:
                        camSetting   = SettingsStatic.CamSettings.player;
                        camPlayerSet = false;
                        break;

                    case SettingsStatic.CamSettings.player:
                        camSetting = SettingsStatic.CamSettings.north;
                        break;
                    }
                }

                if (Input.GetKeyDown(KeyCode.Tab))
                {
                    if (hintsCanvas != null)
                    {
                        hintsCanvas.SetActive(true);
                    }
                }
                if (Input.GetKeyUp(KeyCode.Tab))
                {
                    if (hintsCanvas != null)
                    {
                        hintsCanvas.SetActive(false);
                    }
                }

                if (Input.GetKeyDown(KeyCode.Mouse0))
                {
                    ship.FireWeapon(true);
                }
                if (Input.GetKeyUp(KeyCode.Mouse0))
                {
                    ship.FireWeapon(false);
                }
                if (Input.GetKeyDown(KeyCode.Mouse1))
                {
                    ship.SetNearestTarget();
                }

                if (Input.GetKeyDown(KeyCode.R))
                {
                    ship.ToggleRadar(); SetRadarText();
                }
                if (Input.GetKeyDown(KeyCode.T))
                {
                    ship.SetBoreTarget();
                }
                if (Input.GetKeyDown(KeyCode.Y))
                {
                    ship.SetNearestTarget();
                }

                if (Input.GetKeyDown(KeyCode.Alpha1))
                {
                    SelectWeaponByNumber(1);
                }
                if (Input.GetKeyDown(KeyCode.Alpha2))
                {
                    SelectWeaponByNumber(2);
                }
                if (Input.GetKeyDown(KeyCode.Alpha3))
                {
                    SelectWeaponByNumber(3);
                }
                if (Input.GetKeyDown(KeyCode.Alpha4))
                {
                    SelectWeaponByNumber(4);
                }
            }


            UpdateVelocityVector();
            UpdateTargetIndicator();
            UpdateLeadLine();
            UpdateAimAid();
            UpdateOwnLockIndicator();
            UpdateIncomingLockIndicator();
            UpdateCamera();
        }
    }
示例#4
0
    // returns TRUE when CA has determined a threat and sucessfully added a WP to solve conflict
    // False is returned when either CA failed or no threat was found
    bool CollisionAvoidance()
    {
        Vector2 shipProjectedPos = gameObject.GetComponent <Rigidbody2D>().position
                                   + (wpList[wpIndex].wpCoordinates - gameObject.GetComponent <Rigidbody2D>().position).normalized * desiredSpeed;
        Vector2 shipPos      = new Vector2(gameObject.GetComponent <Rigidbody2D>().position.x, gameObject.GetComponent <Rigidbody2D>().position.y);
        Vector2 headingToWP  = wpList[wpIndex].wpCoordinates - shipPos;
        float   distanceToWP = Mathf.Sqrt(Vector2.SqrMagnitude(wpList[wpIndex].wpCoordinates - gameObject.GetComponent <Rigidbody2D>().position));

        Vector2 closestThreat2D         = new Vector2(0f, 0f);
        Vector2 closestThreatVelocity2D = new Vector2(0f, 0f);
        Vector2 newHeadingVector        = new Vector2(0f, 0f);

        // Variables for use in loops, to avoid repeditive declarations
        float timeToInterWP           = 50f / desiredSpeed;
        float distanceToNearestThreat = 0f;
        float newHeadingLeft          = 0f;
        float newHeadingRight         = 0f;
        bool  leftHeading             = true;
        bool  solutionFound           = false;


        // Setting the travel time, by which we set the threat movement amount
        if (distanceToWP >= 50f)
        {
            timeToInterWP = 50f / desiredSpeed;
        }
        else
        {
            timeToInterWP = distanceToWP / desiredSpeed;
        }

        // Sorting the threats, which also fills in missing bits in the threat list
        SortCollisionThreats((wpList[wpIndex].wpCoordinates - gameObject.GetComponent <Rigidbody2D>().position), timeToInterWP);
        // parsing the POTENTIAL threats for REAL threats, the method also returns a BOOL if there are REAL threats at all
        NTools.CollisionThreatsSorted parsedThreats = CheckHeadingClear(shipProjectedPos, wpList[wpIndex].wpCoordinates);

        // If no threats are found, exit CA, else clear temporary wps from the wp list and start meaty bit of CA
        if (!parsedThreats.realThreatsPresent)
        {
            return(false);
        }

        // Determine distance to closest threat and its coordinates -.-- Why do I do it?
        else if (parsedThreats.realThreatsLeft.Count != 0 && parsedThreats.realThreatsRight.Count != 0)
        {
            ClearTemporaryWaypoints();

            if (parsedThreats.realThreatsLeft[0].sqrDistance < parsedThreats.realThreatsRight[0].sqrDistance)
            {
                distanceToNearestThreat = Vector2.Distance(
                    shipPos,
                    parsedThreats.realThreatsLeft[0].threatCoordinates
                    );
                closestThreat2D         = parsedThreats.realThreatsLeft[0].threatCoordinates;
                closestThreatVelocity2D = parsedThreats.realThreatsLeft[0].threatVelocity;
            }
            else
            {
                distanceToNearestThreat = Vector2.Distance(
                    shipPos,
                    parsedThreats.realThreatsRight[0].threatCoordinates
                    );
                closestThreat2D         = parsedThreats.realThreatsRight[0].threatCoordinates;
                closestThreatVelocity2D = parsedThreats.realThreatsRight[0].threatVelocity;
            }
        }
        else if (parsedThreats.realThreatsLeft.Count == 0 && parsedThreats.realThreatsRight.Count != 0)
        {
            ClearTemporaryWaypoints();

            distanceToNearestThreat = Vector2.Distance(
                shipPos,
                parsedThreats.realThreatsRight[0].threatCoordinates
                );
            closestThreat2D         = parsedThreats.realThreatsRight[0].threatCoordinates;
            closestThreatVelocity2D = parsedThreats.realThreatsRight[0].threatVelocity;
        }
        else if (parsedThreats.realThreatsLeft.Count != 0 && parsedThreats.realThreatsRight.Count == 0)
        {
            ClearTemporaryWaypoints();

            distanceToNearestThreat = Vector2.Distance(
                shipPos,
                parsedThreats.realThreatsLeft[0].threatCoordinates
                );
            closestThreat2D         = parsedThreats.realThreatsLeft[0].threatCoordinates;
            closestThreatVelocity2D = parsedThreats.realThreatsLeft[0].threatVelocity;
        }

        Vector2 vectorToThreat = closestThreat2D - shipPos;

        // statusText.text = vectorToThreat.ToString();

        // Ceck if the WP is closer than the threat, in that case, return and stop CA, return false
        if (distanceToWP < distanceToNearestThreat)
        {
            return(false);
        }

        headingToWP = headingToWP.normalized * distanceToNearestThreat;

        // parse intermittently left and right for a clear initial passage
        int iterations = 0;

        do
        {
            switch (leftHeading)
            {
            case true:
                newHeadingLeft -= 1;

                parsedThreats = CheckHeadingClear(shipPos, shipPos + NTools.RotateVector2(headingToWP, newHeadingLeft));
                if (SettingsStatic.debugEnabled)
                {
                    DrawDebugLine(shipPos, shipPos + NTools.RotateVector2(headingToWP, newHeadingLeft));
                }

                leftHeading = false;
                iterations++;
                break;

            case false:
                newHeadingRight += 1;

                parsedThreats = CheckHeadingClear(shipPos, shipPos + NTools.RotateVector2(headingToWP, newHeadingRight));
                if (SettingsStatic.debugEnabled)
                {
                    DrawDebugLine(shipPos, shipPos + NTools.RotateVector2(headingToWP, newHeadingLeft).normalized);
                }

                leftHeading = true;
                iterations++;
                break;
            }
            // exit failsafes:
            if (newHeadingLeft < -90 || newHeadingRight > 90)
            {
                solutionFound = false;
                break;
            }
        } while (parsedThreats.realThreatsPresent);

        if (newHeadingLeft > -90 && newHeadingRight < 90)
        {
            float newHeading;
            if (leftHeading)
            {
                newHeading = newHeadingRight;
            }
            else
            {
                newHeading = newHeadingLeft;
            }
            solutionFound = true;
            //Debug.Log("Clear relative heading found: " + newHeading.ToString());
        }

        if (!solutionFound)
        {
            Debug.Log("Heading not found in " + iterations + " iterations."); return(false);
        }


        // Determine new direction from projected ship position
        if (leftHeading)
        {
            newHeadingVector = NTools.RotateVector2(headingToWP, newHeadingRight);                   /*Debug.Log("New Heading: " + newHeadingRight);   */
        }
        else
        {
            newHeadingVector = NTools.RotateVector2(headingToWP, newHeadingLeft);                   /*Debug.Log("New Heading: " + newHeadingLeft);    */
        }

        float newWPDistance = 1f;

        do
        {
            newWPDistance += 0.1f;
            parsedThreats  = CheckHeadingClear(shipPos + newHeadingVector * newWPDistance, wpList[wpIndex].wpCoordinates);
            // check to limit the possible distance of the intermittent WP to the distance of the original WP
            if (newWPDistance * newHeadingVector.magnitude > distanceToWP)
            {
                Debug.Log("WP solution not found.");
                break;
            }
        } while (parsedThreats.realThreatsPresent);

        if (newWPDistance < 10f)
        {
            solutionFound = true;
        }


        // This happens, when the collisionAvoidance has done its job and can add a new intermediate waypoint
        // also entering this loop will return true - the method has parsed successfully and added a wp
        if (solutionFound)
        {
            NTools.Waypoint newInbetweenWP = new NTools.Waypoint(shipPos + newHeadingVector * (newWPDistance - 0.2f), 4f, false, true);
            wpList.Add(newInbetweenWP);
            wpIndex = wpList.Count - 1;
            return(true);
        }
        return(false);
    }
示例#5
0
    public static AttackPlanF GetAttackPlanF(AttackTypeF type, Vector3 leadPos, Vector3 enemyPos, List <Vector3> nearbyFriendlies)
    {
        AttackPlanF attackPlan = new AttackPlanF(true);



        switch (type)
        {
        case AttackTypeF.sentry:
            float SQRSep        = 900f;
            float sentryRange   = 30f;
            float searchDegrees = 30f;

            Vector3        offset       = (enemyPos - leadPos).normalized * sentryRange;
            Vector3        sentryPos    = enemyPos + offset;
            List <Vector3> nbfSentryPos = new List <Vector3>(nearbyFriendlies.Count);

            foreach (Vector3 fv in nearbyFriendlies)
            {
                Vector3 fspos = enemyPos + (fv - enemyPos).normalized * sentryRange;
                nbfSentryPos.Add(fspos);
            }

            bool clear = true;
            int  failsafe = 20, i = 1;

            while (!clear)
            {
                foreach (Vector3 fspos in nbfSentryPos)
                {
                    float SQRDist = (fspos - sentryPos).sqrMagnitude;
                    if (SQRDist < SQRSep)
                    {
                        clear = false;
                    }
                }

                if (!clear)
                {
                    float direction = 1f;
                    if ((i + 1) % 2 == 0)
                    {
                        direction = 1;
                    }
                    else
                    {
                        direction = -1;
                    }

                    direction = direction * i * searchDegrees;

                    offset    = NTools.RotateVector3(offset, searchDegrees);
                    sentryPos = enemyPos + offset;
                }

                i++;
                if (i >= failsafe)
                {
                    clear = true;
                }
            }

            break;

        case AttackTypeF.bracket:

            break;

        case AttackTypeF.charge:

            break;

        default:
            break;
        }

        return(attackPlan);
    }
示例#6
0
    private bool ResetPerimeter()
    {
        if (objective.objectiveIsFriendly && objective.objectiveObject)
        {
            perimeter.center = objective.objectiveObject.transform.position;

            perimeter.heading2D = new Vector2(
                enemyGeneralPosition.x - perimeter.center.x,
                enemyGeneralPosition.y - perimeter.center.y
                );
            perimeter.headingFloat = NTools.HeadingFromVector(perimeter.heading2D);

            perimeter.isMoving = objective.isMoving;
        }
        else if (!objective.objectiveIsFriendly && objective.objectiveObject)
        {
            if (capitalShips.Count != 0)
            {
                perimeter.center   = NTools.GetCenterOfObjects3D(capitalShips);
                perimeter.center.z = 0f;

                perimeter.heading2D = new Vector2(
                    enemyGeneralPosition.x - perimeter.center.x,
                    enemyGeneralPosition.y - perimeter.center.y
                    );
                perimeter.headingFloat = NTools.HeadingFromVector(perimeter.heading2D);
                perimeter.isMoving     = objective.isMoving;
            }
            else
            {
                //She-f*****g-nanigans
                List <GameObject> leads = new List <GameObject>(formations.Count);

                for (int i = 0; i < formations.Count; i++)
                {
                    leads[i] = formations[i].Lead;
                }

                perimeter.center   = NTools.GetCenterOfObjects3D(leads);
                perimeter.center.z = 0f;

                perimeter.heading2D = new Vector2(
                    enemyGeneralPosition.x - perimeter.center.x,
                    enemyGeneralPosition.y - perimeter.center.y
                    );
                perimeter.headingFloat = NTools.HeadingFromVector(perimeter.heading2D);
            }
        }

        int mood = (int)teamMood;


        // Adds an importance to each sector based on tabel in LFAI
        switch (teamState)
        {
        case TeamState.Scouting:
            return(AssignSectorPriorities(sectorImportancePresets.scouting[mood]));

        case TeamState.Attacking:
            return(AssignSectorPriorities(sectorImportancePresets.attacking[mood]));

        case TeamState.MaintainPerimeter:
            return(AssignSectorPriorities(sectorImportancePresets.defending[mood]));

        case TeamState.Regrouping:
            return(AssignSectorPriorities(sectorImportancePresets.regrouping[mood]));

        default:
            return(false);
        }
    }
示例#7
0
    // Used to determine for example in which direction the enemy lies and how widespread they are.
    // works in CCW mode
    public static NTools.Slice AnalyseGroupDisposition(Vector3 originPos, float originHeading, List <GameObject> objects)
    {
        NTools.Slice slice = new NTools.Slice(originPos, originHeading, 0, 0, 0, 0, new Vector3(0, 0, 0));

        // sanity check, no objects means return of 000000 !!!
        if (objects.Count == 0)
        {
            return(slice);
        }

        float tempBear, leftBear = 0, rightBear = 0;

        // statistical analysis floats:
        float meanbearing = 0f, sumDiffFromMean = 0f;

        float[] bearings = new float[objects.Count];

        slice.centerOfMass = NTools.GetCenterOfObjects3D(objects);

        for (int i = 0; i < objects.Count; i++)
        {
            // left bearing is positive, right bearing is negative, clamped between -180 to 180

            tempBear = Mathf.Clamp(
                NTools.GetBearingFromHeadings(
                    originHeading,
                    NTools.HeadingFromVector(objects[i].transform.position - originPos)
                    ), -180f, 180f);

            // storing for later analysis
            bearings[i] = tempBear;

            // with the first heading set both left and right bearings
            if (i == 0)
            {
                leftBear = tempBear; rightBear = tempBear;
            }
            else
            {
                if (tempBear > leftBear)
                {
                    leftBear = tempBear;
                }
                else if (tempBear < rightBear)
                {
                    rightBear = tempBear;
                }
            }
        }


        // disperison computation
        for (int i = 0; i < bearings.Length; i++)
        {
            meanbearing += bearings[i];
        }
        meanbearing = meanbearing / bearings.Length;

        for (int i = 0; i < bearings.Length; i++)
        {
            sumDiffFromMean += bearings[i] - meanbearing;
        }


        // Filling the slice !!!
        slice.leftmostBearing  = leftBear;
        slice.rightmostBearing = rightBear;
        slice.bearingRange     = leftBear - rightBear;
        slice.stdDeviation     = Mathf.Sqrt(Mathf.Pow(sumDiffFromMean, 2f) / (bearings.Length - 1));

        return(slice);
    }
示例#8
0
    void CheckPerimeter()
    {
        if (!perimeter.upToDate)
        {
            perimeter.upToDate = ReassignSectorPriorities();
            if (!perimeter.upToDate)
            {
                Debug.Log("Reassigning sector priorities failed.");
            }
        }

        List <GameObject> bogieGOs = new List <GameObject>(bogies.Capacity);

        NTools.Disposition enemyDisposition;

        // determine enemy heading range etc i.e disposition
        if (bogies.Count != 0)
        {
            for (int i = 0; i < bogies.Count; i++)
            {
                if (bogies[i].bogieObject != null)
                {
                    bogieGOs.Add(bogies[i].bogieObject);
                }
            }


            enemyDisposition = NTools.AnalyseGroupDisposition(
                perimeter.center,
                perimeter.headingFloat,
                bogieGOs
                );

            enemyGeneralPosition = enemyDisposition.centerOfMass;
        }
        else
        {
            enemyGeneralPosition = new Vector3(0f, 0f, 0f);
        }


        //TODO Optimize - determines perimeter anchor, heading2D and headingFloat. Is gud.
        if (objective.objectiveSet)
        {
            // If this happens, the game is lost or won, which will be caught by CheckObjective method
            if (!objective.objectiveObject)
            {
                return;
            }

            if (objective.objectiveIsFriendly)
            {
                perimeter.perimeterAnchor = objective.objectiveObject;

                perimeter.heading2D = new Vector2(
                    enemyGeneralPosition.x - perimeter.perimeterAnchor.transform.position.x,
                    enemyGeneralPosition.y - perimeter.perimeterAnchor.transform.position.y
                    );
                perimeter.headingFloat = NTools.HeadingFromVector(perimeter.heading2D);
            }
            else if (!objective.objectiveIsFriendly)
            {
                perimeter.perimeterAnchor = DeterminePerimeterAnchor();
                if (perimeter.perimeterAnchor != null)
                {
                    perimeter.heading2D = new Vector2(
                        enemyGeneralPosition.x - perimeter.perimeterAnchor.transform.position.x,
                        enemyGeneralPosition.y - perimeter.perimeterAnchor.transform.position.y
                        );
                    perimeter.headingFloat = NTools.HeadingFromVector(perimeter.heading2D);
                }
                else
                {
                    missionState = MissionState.lost;
                }
            }
        }
        else
        {
            perimeter.perimeterAnchor = DeterminePerimeterAnchor();
            if (perimeter.perimeterAnchor != null)
            {
                perimeter.heading2D = new Vector2(
                    enemyGeneralPosition.x - perimeter.perimeterAnchor.transform.position.x,
                    enemyGeneralPosition.y - perimeter.perimeterAnchor.transform.position.y
                    );
                perimeter.headingFloat = NTools.HeadingFromVector(perimeter.heading2D);
            }
            else
            {
                missionState = MissionState.lost;
            }
        }
    }