private static void DebugDraw()
        {
            foreach (var antennaEntry in m_pirateAntennas)
            {
                MyRadioAntenna antenna = null;
                MyEntities.TryGetEntityById(antennaEntry.Key, out antenna);
                if (antenna != null)
                {
                    var dt = Math.Max(0, antennaEntry.Value.AntennaDefinition.SpawnTimeMs - MySandboxGame.TotalGamePlayTimeInMilliseconds + antennaEntry.Value.LastGenerationGameTime);
                    MyRenderProxy.DebugDrawText3D(antenna.WorldMatrix.Translation, "Time remaining: " + dt.ToString(), Color.Red, 1.0f, false);
                }
            }

            foreach (var value in m_pirateAntennas)
            {
                MyEntity entity;
                MyEntities.TryGetEntityById(value.Key, out entity);
                if (entity != null)
                {
                    MyRenderProxy.DebugDrawSphere(entity.WorldMatrix.Translation, (float)entity.PositionComp.WorldVolume.Radius, Color.BlueViolet, 1.0f, false);
                }
            }

            foreach (var value in m_droneInfos)
            {
                MyEntity entity;
                MyEntities.TryGetEntityById(value.Key, out entity);
                if (entity != null)
                {
                    MyCubeGrid grid = entity as MyCubeGrid;
                    if (grid == null)
                    {
                        var remote = entity as MyRemoteControl;
                        grid = remote.CubeGrid;
                    }
                    MyRenderProxy.DebugDrawSphere(grid.PositionComp.WorldVolume.Center, (float)grid.PositionComp.WorldVolume.Radius, Color.Cyan, 1.0f, false);
                    MyRenderProxy.DebugDrawText3D(grid.PositionComp.WorldVolume.Center, ((value.Value.DespawnTime - MySandboxGame.TotalGamePlayTimeInMilliseconds) / 1000).ToString(), Color.Cyan, 0.7f, false);
                }
            }
        }
        private bool SpawnDrone(MyRadioAntenna antenna, long ownerId, Vector3D position, MySpawnGroupDefinition spawnGroup, Vector3?spawnUp = null, Vector3?spawnForward = null)
        {
            long     antennaEntityId = antenna.EntityId;
            Vector3D antennaPos      = antenna.PositionComp.GetPosition();

            Vector3D upVector;

            var planet = MyGamePruningStructure.GetClosestPlanet(position);

            if (planet != null)
            {
                if (!MyGravityProviderSystem.IsPositionInNaturalGravity(antennaPos))
                {
                    MySandboxGame.Log.WriteLine("Couldn't spawn drone; antenna is not in natural gravity but spawn location is.");
                    return(false);
                }
                planet.CorrectSpawnLocation(ref position, spawnGroup.SpawnRadius * 2.0);
                upVector = position - planet.PositionComp.GetPosition();
                upVector.Normalize();
            }
            else
            {
                var totalGravityInPoint = MyGravityProviderSystem.CalculateTotalGravityInPoint(position);
                if (totalGravityInPoint != Vector3.Zero)
                {
                    upVector = -totalGravityInPoint;
                    upVector.Normalize();
                }
                else if (spawnUp != null)
                {
                    upVector = spawnUp.Value;
                }
                else
                {
                    upVector = MyUtils.GetRandomVector3Normalized();
                }
            }

            Vector3D direction = MyUtils.GetRandomPerpendicularVector(ref upVector);

            if (spawnForward != null)
            {
                // Align forward to up vector.
                Vector3 forward = spawnForward.Value;
                if (Math.Abs(Vector3.Dot(forward, upVector)) >= 0.98f)
                {
                    forward = Vector3.CalculatePerpendicularVector(upVector);
                }
                else
                {
                    Vector3 right = Vector3.Cross(forward, upVector);
                    right.Normalize();
                    forward = Vector3.Cross(upVector, right);
                    forward.Normalize();
                }

                direction = forward;
            }

            MatrixD originMatrix = MatrixD.CreateWorld(position, direction, upVector);

            foreach (var shipPrefab in spawnGroup.Prefabs)
            {
                Vector3D shipPosition = Vector3D.Transform((Vector3D)shipPrefab.Position, originMatrix);

                List <MyCubeGrid> tmpGridList = new List <MyCubeGrid>();

                Stack <Action> callback = new Stack <Action>();
                callback.Push(delegate() { ChangeDroneOwnership(tmpGridList, ownerId, antennaEntityId); });

                MyPrefabManager.Static.SpawnPrefab(
                    resultList: tmpGridList,
                    prefabName: shipPrefab.SubtypeId,
                    position: shipPosition,
                    forward: direction,
                    up: upVector,
                    initialLinearVelocity: default(Vector3),
                    beaconName: null,
                    spawningOptions: VRage.Game.ModAPI.SpawningOptions.None,
                    ownerId: ownerId,
                    updateSync: true, callbacks: callback);
            }
            return(true);
        }
        private void UpdateDroneSpawning()
        {
            int currentTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;

            m_iteratingAntennas = true;
            foreach (var antennaEntry in m_pirateAntennas)
            {
                PirateAntennaInfo antennaInfo = antennaEntry.Value;
                if (!antennaInfo.IsActive)
                {
                    continue;
                }
                if (currentTime - antennaInfo.LastGenerationGameTime <= antennaInfo.AntennaDefinition.SpawnTimeMs)
                {
                    continue;
                }

                MyRadioAntenna antenna = null;
                MyEntities.TryGetEntityById(antennaEntry.Key, out antenna);
                Debug.Assert(antenna != null, "Could not find antenna for spawning enemy drones!");
                if (antennaInfo.AntennaDefinition.SpawnGroupSampler == null)
                {
                    return;
                }

                var spawnGroup = antennaInfo.AntennaDefinition.SpawnGroupSampler.Sample();
                Debug.Assert(spawnGroup != null, "Could not find spawnGroup for spawning enemy drones!");
                if
                (
                    !MySession.Static.Settings.EnableDrones ||
                    antennaInfo.SpawnedDrones >= antennaInfo.AntennaDefinition.MaxDrones ||
                    antenna == null ||
                    spawnGroup == null ||
                    (m_droneInfos.Reader.Count() >= MySession.Static.Settings.MaxDrones)
                )
                {
                    antennaInfo.LastGenerationGameTime = currentTime;
                    continue;
                }

                spawnGroup.ReloadPrefabs();

                BoundingSphereD antennaSphere = new BoundingSphereD(antenna.WorldMatrix.Translation, antenna.GetRadius());

                var  players         = MySession.Static.Players.GetOnlinePlayers();
                bool successfulSpawn = false;
                foreach (var player in players)
                {
                    if (antennaSphere.Contains(player.GetPosition()) == ContainmentType.Contains)
                    {
                        Vector3D?spawnPosition = null;
                        for (int i = 0; i < 10; ++i)
                        {
                            Vector3D position = antenna.WorldMatrix.Translation + MyUtils.GetRandomVector3Normalized() * antennaInfo.AntennaDefinition.SpawnDistance;
                            spawnPosition = MyEntities.FindFreePlace(position, spawnGroup.SpawnRadius);
                            if (spawnPosition.HasValue)
                            {
                                break;
                            }
                        }
                        successfulSpawn = SpawnDrone(antenna, antenna.OwnerId, spawnPosition.Value, spawnGroup);

                        break;
                    }
                }

                // Don't reschedule if there was no player inside
                if (successfulSpawn)
                {
                    antennaInfo.LastGenerationGameTime = currentTime;
                }
            }
            m_pirateAntennas.ApplyChanges();
            m_iteratingAntennas = false;
        }
        private bool SpawnDrone(MyRadioAntenna antenna, long ownerId, Vector3D position, MySpawnGroupDefinition spawnGroup)
        {
            long     antennaEntityId = antenna.EntityId;
            Vector3D antennaPos      = antenna.PositionComp.GetPosition();

            var planet = MyGravityProviderSystem.GetStrongestGravityWell(position);

            Vector3D upVector;

            if (planet != null && planet.IsPositionInGravityWell(position))
            {
                if (!MyGravityProviderSystem.IsPositionInNaturalGravity(antennaPos))
                {
                    MySandboxGame.Log.WriteLine("Couldn't spawn drone; antenna is not in natural gravity but spawn location is.");
                    return(false);
                }
                planet.CorrectSpawnLocation(ref position, spawnGroup.SpawnRadius * 2.0);
                upVector = -planet.GetWorldGravityNormalized(ref position);
            }
            else
            {
                upVector = MyUtils.GetRandomVector3Normalized();
            }

            Vector3D direction    = MyUtils.GetRandomPerpendicularVector(ref upVector);
            MatrixD  originMatrix = MatrixD.CreateWorld(position, direction, upVector);

            foreach (var shipPrefab in spawnGroup.Prefabs)
            {
                Vector3D shipPosition = Vector3D.Transform((Vector3D)shipPrefab.Position, originMatrix);

                m_tmpGridList.Clear();

                MyPrefabManager.Static.SpawnPrefab(
                    resultList: m_tmpGridList,
                    prefabName: shipPrefab.SubtypeId,
                    position: shipPosition,
                    forward: direction,
                    up: upVector,
                    initialLinearVelocity: default(Vector3),
                    beaconName: null,
                    spawningOptions: VRage.Game.ModAPI.SpawningOptions.None,
                    ownerId: ownerId,
                    updateSync: true);

                foreach (var grid in m_tmpGridList)
                {
                    grid.ChangeGridOwnership(ownerId, MyOwnershipShareModeEnum.None);

                    MyRemoteControl firstRemote = null;

                    foreach (var block in grid.CubeBlocks)
                    {
                        if (block.FatBlock == null)
                        {
                            continue;
                        }

                        var pb = block.FatBlock as MyProgrammableBlock;
                        if (pb != null)
                        {
                            pb.SendRecompile();
                        }

                        var remote = block.FatBlock as MyRemoteControl;
                        if (firstRemote == null)
                        {
                            firstRemote = remote;
                        }
                    }

                    // If there's no remote control on the grid, we have to register it as is
                    RegisterDrone(antennaEntityId, (MyEntity)firstRemote ?? (MyEntity)grid);
                }

                m_tmpGridList.Clear();
            }
            return(true);
        }
Exemple #5
0
 public AntennaWrapper(MySlimBlock block) : base(block)
 {
     Block = (MyRadioAntenna)block.FatBlock;
 }
        // ReSharper disable once InconsistentNaming
        private static void InitPatch(MyRadioAntenna __instance)
        {
            var definition = (MyRadioAntennaDefinition)__instance.BlockDefinition;

            _radius.GetSync <float>(__instance).ValueChangedInRange(1, definition.MaxBroadcastRadius);
        }
        private bool SpawnDrone(MyRadioAntenna antenna, long ownerId, Vector3D position, MySpawnGroupDefinition spawnGroup, Vector3?spawnUp = null, Vector3?spawnForward = null)
        {
            long     antennaEntityId = antenna.EntityId;
            Vector3D antennaPos      = antenna.PositionComp.GetPosition();

            Vector3D upVector;

            var planet = MyGamePruningStructure.GetClosestPlanet(position);

            if (planet != null)
            {
                if (!MyGravityProviderSystem.IsPositionInNaturalGravity(antennaPos))
                {
                    MySandboxGame.Log.WriteLine("Couldn't spawn drone; antenna is not in natural gravity but spawn location is.");
                    return(false);
                }
                planet.CorrectSpawnLocation(ref position, spawnGroup.SpawnRadius * 2.0);
                upVector = position - planet.PositionComp.GetPosition();
                upVector.Normalize();
            }
            else
            {
                var totalGravityInPoint = MyGravityProviderSystem.CalculateTotalGravityInPoint(position);
                if (totalGravityInPoint != Vector3.Zero)
                {
                    upVector = -totalGravityInPoint;
                    upVector.Normalize();
                }
                else if (spawnUp != null)
                {
                    upVector = spawnUp.Value;
                }
                else
                {
                    upVector = MyUtils.GetRandomVector3Normalized();
                }
            }

            Vector3D direction = MyUtils.GetRandomPerpendicularVector(ref upVector);

            if (spawnForward != null)
            {
                // Align forward to up vector.
                Vector3 forward = spawnForward.Value;
                if (Math.Abs(Vector3.Dot(forward, upVector)) >= 0.98f)
                {
                    forward = Vector3.CalculatePerpendicularVector(upVector);
                }
                else
                {
                    Vector3 right = Vector3.Cross(forward, upVector);
                    right.Normalize();
                    forward = Vector3.Cross(upVector, right);
                    forward.Normalize();
                }

                direction = forward;
            }

            MatrixD originMatrix = MatrixD.CreateWorld(position, direction, upVector);

            foreach (var shipPrefab in spawnGroup.Prefabs)
            {
                Vector3D shipPosition = Vector3D.Transform((Vector3D)shipPrefab.Position, originMatrix);

                m_tmpGridList.Clear();

                MyPrefabManager.Static.SpawnPrefab(
                    resultList: m_tmpGridList,
                    prefabName: shipPrefab.SubtypeId,
                    position: shipPosition,
                    forward: direction,
                    up: upVector,
                    initialLinearVelocity: default(Vector3),
                    beaconName: null,
                    spawningOptions: VRage.Game.ModAPI.SpawningOptions.None,
                    ownerId: ownerId,
                    updateSync: true);

                foreach (var grid in m_tmpGridList)
                {
                    grid.ChangeGridOwnership(ownerId, MyOwnershipShareModeEnum.None);

                    MyRemoteControl firstRemote = null;

                    foreach (var block in grid.CubeBlocks)
                    {
                        if (block.FatBlock == null)
                        {
                            continue;
                        }

                        var pb = block.FatBlock as MyProgrammableBlock;
                        if (pb != null)
                        {
                            pb.SendRecompile();
                        }

                        var remote = block.FatBlock as MyRemoteControl;
                        if (firstRemote == null)
                        {
                            firstRemote = remote;
                        }
                    }

                    // If there's no remote control on the grid, we have to register it as is
                    RegisterDrone(antennaEntityId, (MyEntity)firstRemote ?? (MyEntity)grid);
                }

                m_tmpGridList.Clear();
            }
            return(true);
        }