Пример #1
1
        /// <summary>
        /// Creates a missile with homing and target finding capabilities.
        /// </summary>
        public GuidedMissile(IMyEntity missile, GuidedMissileLauncher launcher, Target initialTarget)
            : base(missile, launcher.CubeBlock)
        {
            m_launcher = launcher;
            myAmmo     = launcher.loadedAmmo;
            m_entity   = missile;
            m_owner    = launcher.CubeBlock.OwnerId;
            if (myAmmo.Description.HasAntenna)
            {
                myAntenna = new RelayNode(missile, () => m_owner, ComponentRadio.CreateRadio(missile, 0f));
            }
            TryHard = true;
            SEAD    = myAmmo.Description.SEAD;

            Static.AllGuidedMissiles.Add(this);
            Registrar.Add(MyEntity, this);
            MyEntity.OnClose += MyEntity_OnClose;

            acceleration      = myDescr.Acceleration + myAmmo.MissileDefinition.MissileAcceleration;
            addSpeedPerUpdate = myDescr.Acceleration * Globals.UpdateDuration;
            if (!(launcher.CubeBlock is Sandbox.ModAPI.Ingame.IMyLargeTurretBase))
            {
                m_rail = new RailData(Vector3D.Transform(MyEntity.GetPosition(), CubeBlock.WorldMatrixNormalizedInv));
            }

            Options = m_launcher.m_weaponTarget.Options.Clone();
            Options.TargetingRange = myAmmo.Description.TargetRange;

            SetTarget(initialTarget);

            if (myAmmo.RadarDefinition != null)
            {
                Log.DebugLog("Has a radar definiton");
                m_radar = new RadarEquipment(missile, myAmmo.RadarDefinition, launcher.CubeBlock);
                if (myAntenna == null)
                {
                    Log.DebugLog("Creating node for radar");
                    myAntenna = new RelayNode(missile, () => m_owner, null);
                }
            }

            Log.DebugLog("Options: " + Options + ", initial target: " + (CurrentTarget == null ? "null" : CurrentTarget.Entity.getBestName()) + ", entityId: " + missile.EntityId);
            //Log.DebugLog("AmmoDescription: \n" + MyAPIGateway.Utilities.SerializeToXML<Ammo.AmmoDescription>(myDescr), "GuidedMissile()");
        }
Пример #2
0
        /// <summary>
        /// Creates a missile with homing and target finding capabilities.
        /// </summary>
        public GuidedMissile(IMyEntity missile, GuidedMissileLauncher launcher, out Target initialTarget)
            : base(missile, launcher.CubeBlock)
        {
            myLogger = new Logger("GuidedMissile", () => missile.getBestName(), () => m_stage.ToString());
            m_launcher = launcher;
            myAmmo = launcher.loadedAmmo;
            m_owner = launcher.CubeBlock.OwnerId;
            if (myAmmo.Description.HasAntenna)
                myAntenna = new RelayNode(missile, () => m_owner, ComponentRadio.CreateRadio(missile, 0f));
            TryHard = true;
            SEAD = myAmmo.Description.SEAD;

            AllGuidedMissiles.Add(this);
            MyEntity.OnClose += MyEntity_OnClose;

            acceleration = myDescr.Acceleration + myAmmo.MissileDefinition.MissileAcceleration;
            addSpeedPerUpdate = myDescr.Acceleration * Globals.UpdateDuration;
            if (!(launcher.CubeBlock is Sandbox.ModAPI.Ingame.IMyLargeTurretBase))
                m_rail = new RailData(Vector3D.Transform(MyEntity.GetPosition(), CubeBlock.WorldMatrixNormalizedInv));

            Options = m_launcher.m_weaponTarget.Options.Clone();
            Options.TargetingRange = myAmmo.Description.TargetRange;

            RelayStorage storage = launcher.m_relayPart.GetStorage();
            if (storage == null)
            {
                myLogger.debugLog("failed to get storage for launcher", Logger.severity.WARNING);
            }
            else
            {
                myLogger.debugLog("getting initial target from launcher", Logger.severity.DEBUG);
                GetLastSeenTarget(storage, myAmmo.MissileDefinition.MaxTrajectory);
            }
            initialTarget = CurrentTarget;

            if (myAmmo.RadarDefinition != null)
            {
                myLogger.debugLog("Has a radar definiton");
                m_radar = new RadarEquipment(missile, myAmmo.RadarDefinition, launcher.CubeBlock);
                if (myAntenna == null)
                {
                    myLogger.debugLog("Creating node for radar");
                    myAntenna = new RelayNode(missile, () => m_owner, null);
                }
            }

            Registrar.Add(missile, this);

            myLogger.debugLog("Options: " + Options + ", initial target: " + (myTarget == null ? "null" : myTarget.Entity.getBestName()));
            //myLogger.debugLog("AmmoDescription: \n" + MyAPIGateway.Utilities.SerializeToXML<Ammo.AmmoDescription>(myDescr), "GuidedMissile()");
        }
    // 初始化铁轨
    public void InitRails()
    {
        int world_x = (int)transform.position.x, world_z = (int)transform.position.z;

        RailsArray = new GameObject[30, 40];

        int i = 0;

        foreach (Transform rail in transform)
        {
            rail.position = new Vector3(world_x, 1, world_z + i);
            rail.name     = "Rail_" + world_x + "_" + (world_z + i);
            RailsArray[world_x, world_z + i] = rail.gameObject;
            ++i;
        }

        Transform StationRails = GameObject.Find("Terminal").transform.Find("Rails");

        EndRail = new RailData[2];
        i       = 0;
        foreach (Transform rail in StationRails)
        {
            EndRail[i]            = new RailData();
            EndRail[i].pos        = rail.position;
            EndRail[i].faceDirect = FaceDirect.East;
            EndRail[i].turnDirect = TurnDirect.Straight;
            int sx = (int)rail.position.x, sz = (int)rail.position.z;
            RailsArray[sx, sz] = rail.gameObject;
            ++i;
        }

        LastRail            = new RailData();
        LastRail.pos        = new Vector3(world_x, 1, world_z + 9);
        LastRail.faceDirect = FaceDirect.East;
        LastRail.turnDirect = TurnDirect.Straight;

        Finish = false;
    }
Пример #4
0
        /// <summary>
        /// Updates m_stage if guidance starts or stops.
        /// </summary>
        private void CheckGuidance()
        {
            switch (m_stage)
            {
            case Stage.Rail:
                double minDist = (MyEntity.WorldAABB.Max - MyEntity.WorldAABB.Min).AbsMax();
                minDist *= 2;

                if (CubeBlock.WorldAABB.DistanceSquared(MyEntity.GetPosition()) >= minDist * minDist)
                {
                    myGuidanceEnds = Globals.ElapsedTime.Add(TimeSpan.FromSeconds(myDescr.GuidanceSeconds));
                    m_rail         = null;
                    if (myDescr.SemiActiveLaser)
                    {
                        Log.DebugLog("past arming range, semi-active.", Logger.severity.INFO);
                        m_stage = Stage.SemiActive;
                        return;
                    }

                    if (CurrentTarget is GolisTarget)
                    {
                        Log.DebugLog("past arming range, golis active", Logger.severity.INFO);
                        m_stage = Stage.Golis;
                        return;
                    }

                    if (myAmmo.Description.BoostDistance > 1f)
                    {
                        Log.DebugLog("past arming range, starting boost stage", Logger.severity.INFO);
                        StartGravity();
                        m_stage = Stage.Boost;
                        if (m_gravData == null)
                        {
                            Log.DebugLog("no gravity, terminating", Logger.severity.WARNING);
                            m_stage = Stage.Terminated;
                        }
                    }
                    else
                    {
                        Log.DebugLog("past arming range, starting guidance.", Logger.severity.INFO);
                        m_stage = Stage.Guided;
                    }
                }
                return;

            case Stage.Boost:
                if (Vector3D.DistanceSquared(CubeBlock.GetPosition(), MyEntity.GetPosition()) >= myAmmo.Description.BoostDistance * myAmmo.Description.BoostDistance)
                {
                    Log.DebugLog("completed boost stage, starting mid course stage", Logger.severity.INFO);
                    m_stage = Stage.MidCourse;
                }
                return;

            case Stage.MidCourse:
                Target t = CurrentTarget;
                if (t.Entity == null)
                {
                    return;
                }

                double toTarget = Vector3D.Distance(MyEntity.GetPosition(), t.GetPosition());
                double toLaunch = Vector3D.Distance(MyEntity.GetPosition(), CubeBlock.GetPosition());

                if (toTarget < toLaunch)
                {
                    Log.DebugLog("closer to target(" + toTarget + ") than to launch(" + toLaunch + "), starting guidance", Logger.severity.INFO);
                    m_stage        = Stage.Guided;
                    myGuidanceEnds = Globals.ElapsedTime.Add(TimeSpan.FromSeconds(myDescr.GuidanceSeconds));
                    m_gravData     = null;
                }
                return;

            case Stage.SemiActive:
            case Stage.Golis:
            case Stage.Guided:
                if (Globals.ElapsedTime >= myGuidanceEnds)
                {
                    Log.DebugLog("finished guidance", Logger.severity.INFO);
                    m_stage = Stage.Ballistic;
                }
                return;
            }
        }
    public void Grind()
    {
        float sphereRad = 2f;

        // Perform a spherecast. If anything the cast touches has a rail, add it to a list of possible rails.
        Collider[] hitColliders = Physics.OverlapSphere(transform.position, sphereRad);
        if (hitColliders.Length > 0)
        {
            // Look through the list of rails and find the spline that is closest to the player.
            List <RailData> rails = new List <RailData>();

            foreach (var c in hitColliders)
            {
                Transform parent = c.transform;
                while (parent != null)
                {
                    RailData railData = parent.GetComponent <RailData>();
                    if (railData)
                    {
                        bool sameRail = false;
                        foreach (var rail in rails)
                        {
                            if (rail == railData)
                            {
                                sameRail = true;
                                break;
                            }
                        }
                        if (!sameRail)
                        {
                            rails.Add(railData);
                        }
                        break;
                    }
                    else
                    {
                        parent = parent.parent;
                    }
                }
            }

            if (rails.Count > 0)
            {
                // Default to the first rail
                BGCcMath closestRail = rails[0].m_railData[0];
                float    closestDist = Vector3.Distance(transform.position, rails[0].m_railData[0].CalcPositionByClosestPoint(transform.position));

                foreach (var rail in rails)
                {
                    foreach (var r in rail.m_railData)
                    {
                        // Find the coping that is nearest to the player
                        float newClosestDist = Vector3.Distance(transform.position, r.CalcPositionByClosestPoint(transform.position));
                        if (newClosestDist < closestDist)
                        {
                            closestRail = r;
                            closestDist = newClosestDist;
                        }
                    }
                }
                if (closestDist <= sphereRad)
                {
                    // If the player is facing away from its movement vector, change to switch. Otherwise, they are in the regular stance
                    float fwdVelDot = Vector3.Dot(transform.forward, m_rb.velocity);
                    if (m_switch && fwdVelDot > 0)
                    {
                        m_switch = false;
                        TrickManager.GetInstance().WriteToStanceTextBox("Regular");
                    }
                    else if (!m_switch && fwdVelDot < 0)
                    {
                        m_switch = true;
                        TrickManager.GetInstance().WriteToStanceTextBox("Switch");
                    }

                    // Find the vector in front of the player or under the player that best suits
                    m_moveDir     = (m_switch) ? -transform.forward : transform.forward;
                    m_currentRail = closestRail;
                    m_grinding    = true;
                }
            }
        }
    }
Пример #6
0
        /// <summary>
        /// Updates m_stage if guidance starts or stops.
        /// </summary>
        private void CheckGuidance()
        {
            switch (m_stage)
            {
                case Stage.Rail:
                    double minDist = (MyEntity.WorldAABB.Max - MyEntity.WorldAABB.Min).AbsMax();
                    minDist *= 2;

                    if (CubeBlock.WorldAABB.DistanceSquared(MyEntity.GetPosition()) >= minDist * minDist)
                    {
                        m_rail = null;
                        if (myDescr.SemiActiveLaser)
                        {
                            myGuidanceEnds = Globals.ElapsedTime.Add(TimeSpan.FromSeconds(myDescr.GuidanceSeconds));
                            myLogger.debugLog("past arming range, semi-active.", Logger.severity.INFO);
                            m_stage = Stage.SemiActive;
                            return;
                        }

                        if (myAmmo.Description.BoostDistance > 1f)
                        {
                            myLogger.debugLog("past arming range, starting boost stage", Logger.severity.INFO);
                            StartGravity();
                            m_stage = Stage.Boost;
                            if (m_gravData == null)
                            {
                                myLogger.debugLog("no gravity, terminating", Logger.severity.WARNING);
                                m_stage = Stage.Terminated;
                            }
                        }
                        else
                        {
                            myGuidanceEnds = Globals.ElapsedTime.Add(TimeSpan.FromSeconds(myDescr.GuidanceSeconds));
                            myLogger.debugLog("past arming range, starting guidance.", Logger.severity.INFO);
                            m_stage = Stage.Guided;
                        }
                    }
                    return;
                case Stage.Boost:
                    if (Vector3D.DistanceSquared(CubeBlock.GetPosition(), MyEntity.GetPosition()) >= myAmmo.Description.BoostDistance * myAmmo.Description.BoostDistance)
                    {
                        myLogger.debugLog("completed boost stage, starting mid course stage", Logger.severity.INFO);
                        m_stage = Stage.MidCourse;
                    }
                    return;
                case Stage.MidCourse:
                    Target t = CurrentTarget;
                    if (t.Entity == null)
                        return;

                    double toTarget = Vector3D.Distance(MyEntity.GetPosition(), t.GetPosition());
                    double toLaunch = Vector3D.Distance(MyEntity.GetPosition(), CubeBlock.GetPosition());

                    if (toTarget < toLaunch)
                    {
                        myLogger.debugLog("closer to target(" + toTarget + ") than to launch(" + toLaunch + "), starting guidance", Logger.severity.INFO);
                        m_stage = Stage.Guided;
                        myGuidanceEnds = Globals.ElapsedTime.Add(TimeSpan.FromSeconds(myDescr.GuidanceSeconds));
                        m_gravData = null;
                    }
                    return;
                case Stage.SemiActive:
                case Stage.Guided:
                    if (Globals.ElapsedTime >= myGuidanceEnds)
                    {
                        myLogger.debugLog("finished guidance", Logger.severity.INFO);
                        m_stage = Stage.Ballistic;
                    }
                    return;
            }
        }