public override bool HandleCommand( ulong userId, string[] words )
        {
            Essentials.Log.Info( "Asteroid cleanup" );
            HashSet<IMyEntity> entities = new HashSet<IMyEntity>( );
            Wrapper.GameAction( ( ) =>
                                {
                                    MyAPIGateway.Entities.GetEntities( entities );
                                    foreach ( IMyEntity entity in entities )
                                    {
                                        if ( entity == null )
                                            continue;

                                        if ( entity is IMyVoxelMap )
                                            asteroidPositions.Add( entity.PositionComp.GetPosition( ), (IMyVoxelMap)entity );
                                        else
                                            entityPositions.Add( entity.PositionComp.GetPosition( ) );
                                    }
                                } );
            //TODO: Use a thread pool to speed this up?
            DateTime profile = DateTime.Now;
            Communication.SendPrivateInformation( userId, $"Found {asteroidPositions.Count} asteroids." );
            foreach ( var asteroid in asteroidPositions )
            {
                bool found = false;
                BoundingSphereD bound = new BoundingSphereD( asteroid.Key, 1000 );
                foreach ( Vector3D checkPosition in entityPositions )
                {
                    if ( bound.Contains( checkPosition ) == ContainmentType.Contains )
                    {
                        found = true;
                        break;
                    }
                }

                if ( !found )
                    toRemove.Add( asteroid.Value );
            }
            Communication.SendPrivateInformation( userId, $"Found {toRemove.Count} asteroids to remove." );
            int count = 0;
            foreach ( IMyVoxelMap asteroid in toRemove )
            {
                if ( asteroid == null || asteroid.Closed )
                    continue;

                count++;

                Wrapper.GameAction( ( ) => asteroid.Close( ) );
            }
            Communication.SendPrivateInformation( userId, $"Removed {count} asteroids." );
            Essentials.Log.Info( "Asteroid cleanup elapsed time: " + (DateTime.Now - profile) );
            return true;
        }
예제 #2
0
            public void NextPosition(ref Vector3D nextDirection, Vector3D headingDir, double safetyMargin = 1.25)
            {
                CreateSphereFromEntities(headingDir);

                Vector3D position    = rc.CubeGrid.WorldVolume.Center;
                Vector3D movementDir = rc.GetShipVelocities().LinearVelocity;

                movementDir.Normalize();

                RayD movementRay = new RayD(position, movementDir);
                RayD headingRay  = new RayD(rc.CubeGrid.WorldVolume.Center, headingDir);

                BoundingSphereD sphere = boundingSphere;

                sphere.Radius += rc.CubeGrid.WorldVolume.Radius;

                if (sphere.Contains(position) != ContainmentType.Disjoint)
                {
                    Vector3D dodgeDirection = Vector3D.Normalize(position - sphere.Center);

                    nextDirection = sphere.Center + dodgeDirection * sphere.Radius * safetyMargin;
                    return;
                }

                double?movementDist = sphere.Intersects(movementRay);
                double?headingDist  = sphere.Intersects(headingRay);

                if (movementDist.HasValue || headingDist.HasValue)
                {
                    Vector3D pointOnSphere;
                    Vector3D dodgeDirection;
                    if (movementDist.HasValue)
                    {
                        pointOnSphere  = position + movementDir * movementDist.Value;
                        dodgeDirection = GetAvoidanceVector(pointOnSphere, sphere, movementDir);
                    }
                    else
                    {
                        pointOnSphere  = position + headingDir * headingDist.Value;
                        dodgeDirection = GetAvoidanceVector(pointOnSphere, sphere, headingDir);
                    }

                    nextDirection = dodgeDirection;
                }
            }
예제 #3
0
        private void MarkCellsDirty(BoundingSphereD toMark, BoundingSphereD toExclude)
        {
            ProfilerShort.Begin("Mark dirty cells");
            Vector3I cellId = Vector3I.Floor((toMark.Center - toMark.Radius) / CELL_SIZE);

            for (var iter = GetCellsIterator(toMark); iter.IsValid(); iter.GetNext(out cellId))
            {
                MyProceduralCell cell;
                if (m_cells.TryGetValue(cellId, out cell))
                {
                    if (toExclude.Contains(cell.BoundingVolume) == ContainmentType.Disjoint)
                    {
                        m_dirtyCellsToAdd.Add(cell);
                    }
                }
            }
            ProfilerShort.End();
        }
        /// <summary>
        /// Unloads all cells that have been marked to be unloaded. It will remove all objects inside the sphere from
        /// the world. It will not unload cells that are still in the tracking volume of a tracked entity.
        /// </summary>
        /// <param name="trackedEntities">List of tracked entities</param>
        public void UnloadCells(Dictionary <MyEntity, MyEntityTracker> trackedEntities)
        {
            m_toUnloadCells.ApplyAdditions();
            if (m_toUnloadCells.Count == 0)
            {
                return;
            }

            List <MyObjectSeed> cellObjects = new List <MyObjectSeed>();

            foreach (MyProceduralCell cell in m_toUnloadCells)
            {
                foreach (MyEntityTracker tracker in trackedEntities.Values)
                {
                    BoundingSphereD boundingVolume = tracker.BoundingVolume;
                    if (boundingVolume.Contains(cell.BoundingVolume) != ContainmentType.Disjoint)
                    {
                        m_toUnloadCells.Remove(cell);
                        break;
                    }
                }
            }
            m_toUnloadCells.ApplyRemovals();
            foreach (var cell in m_toUnloadCells)
            {
                cell.GetAll(cellObjects);

                foreach (MyObjectSeed obj in cellObjects)
                {
                    if (obj.Params.Generated)
                    {
                        CloseObject(obj);
                    }
                }
                cellObjects.Clear();
            }
            foreach (MyProceduralCell cell in m_toUnloadCells)
            {
                m_cells.Remove(cell.CellId);
                m_cellsTree.RemoveProxy(cell.proxyId);
            }
            m_toUnloadCells.Clear();
        }
        public override bool HandleCommand(ulong userId, string[] words)
        {
            var entities = MyEntities.GetEntities( ).ToArray( );
            var planets = new HashSet<MyPlanet>( );
            int count = 0;
            foreach (var entity in entities)
            {
                MyPlanet item = entity as MyPlanet;
                if (item != null)
                    planets.Add( item );
            }

            foreach (var planet in planets)
            {
                var sphere25 = new BoundingSphereD(planet.PositionComp.GetPosition(), planet.MinimumRadius * 0.25);
                var sphere75 = new BoundingSphereD(planet.PositionComp.GetPosition(), planet.MinimumRadius * 0.75);
                foreach (var entity in entities)
                {
                    if (entity.MarkedForClose || entity.Physics == null || entity is MyCharacter)
                        continue;

                    if (sphere25.Contains(entity.PositionComp.GetPosition()) != ContainmentType.Disjoint)
                    {
                        count++;
                        Wrapper.BeginGameAction( entity.Close, null, null );
                        continue;
                    }

                    if (Vector3.IsZero(entity.Physics.LinearVelocity))
                        continue;

                    if (sphere75.Contains(entity.PositionComp.GetPosition()) == ContainmentType.Disjoint)
                        continue;

                    count++;
                    Wrapper.BeginGameAction(entity.Close, null, null);
                }
            }

            Communication.SendPrivateInformation( userId, $"Deleted {count} entities trapped in planets." );
            return true;
        }
예제 #6
0
        void CalculatePlayers(MyDefinitionId blockId, IMyEntity ent, IMyPlayer pl)
        {
            if (settings.UseLearnFaction)
            {
                var players = new List <IMyPlayer>();
                MyAPIGateway.Players.GetPlayers(players);

                var faction = MyAPIGateway.Session.Factions.TryGetPlayerFaction(pl.IdentityId);
                if (faction != null)
                {
                    foreach (var player in players)
                    {
                        var f = MyAPIGateway.Session.Factions.TryGetPlayerFaction(player.IdentityId);
                        if (f != null && f.FactionId == faction.FactionId)
                        {
                            UnlockById(blockId, player.IdentityId);
                        }
                    }
                }
            }
            else if (settings.UseLearnRadius && settings.LearnRadius > 0)
            {
                var sphere  = new BoundingSphereD(ent.GetPosition(), settings.LearnRadius);
                var players = new List <IMyPlayer>();
                MyAPIGateway.Players.GetPlayers(players, p =>
                {
                    return(sphere.Contains(p.GetPosition()) != ContainmentType.Disjoint);
                });
                foreach (var player in players)
                {
                    UnlockById(blockId, player.IdentityId);
                }
            }
            else
            {
                if (pl != null)
                {
                    UnlockById(blockId, pl.IdentityId);
                }
            }
        }
예제 #7
0
        public bool InZone(Vector3D coords)
        {
            if (SafeZone.Shape == MySafeZoneShape.Sphere)
            {
                var newSphere = new BoundingSphereD(SafeZone.PositionComp.WorldAABB.Center, SafeZone.Radius);

                if (newSphere.Contains(coords) == ContainmentType.Contains)
                {
                    return(true);
                }
            }
            else
            {
                if (SafeZone.PositionComp.WorldAABB.Contains(coords) == ContainmentType.Contains)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #8
0
            bool SimulateTrajectory()
            {
                //Init Simulation environment
                CurrentProjectileLocation = projectileStartPosition;
                CurrentProjectileVelocity = CurrentFiringDirection * projectileSpeed;
                currentSimulationTime     = 0;

                do
                {
                    CurrentProjectileLocation += CurrentProjectileVelocity;

                    Vector3D acceleration = (Vector3D.Normalize(planet.Position - CurrentProjectileLocation) * GetGravityAtAltitude(Vector3D.Distance(planet.Position, CurrentProjectileLocation))) + (projectileForward * projectileAcceleration);
                    CurrentProjectileVelocity = AccelVelocityClamped(CurrentProjectileVelocity, acceleration);
                } while (planetSphere.Contains(CurrentProjectileLocation) == ContainmentType.Disjoint && currentSimulationTime++ <= timeLimit);

                if (Vector3D.DistanceSquared(CurrentProjectileLocation, targetPosition) <= tolerance * tolerance)
                {
                    return(true);
                }

                return(false);
            }
        /// <summary>
        /// Marks cells to load or keep loaded inside the bounds
        /// </summary>
        /// <param name="bounds">Spherical bounds</param>
        public void MarkToLoadCellsInBounds(BoundingSphereD bounds)
        {
            BoundingBoxD box    = BoundingBoxD.CreateFromSphere(bounds);
            Vector3I     cellId = Vector3I.Floor(box.Min / m_cellSize);

            for (var it = GetCellsIterator(box); it.IsValid(); it.GetNext(out cellId))
            {
                if (m_toLoadCells.Contains(cellId))
                {
                    continue;
                }

                BoundingBoxD cellBounds = new BoundingBoxD(cellId * m_cellSize, (cellId + 1) * m_cellSize);
                if (bounds.Contains(cellBounds) == ContainmentType.Disjoint)
                {
                    continue;
                }

                m_toLoadCells.Add(cellId);
            }

            m_toLoadCells.ApplyAdditions();
        }
예제 #10
0
        /// <summary>
        /// Finds all available markets that are within range that can be traded with.
        /// </summary>
        /// <param name="position"></param>
        /// <returns></returns>
        public static List<MarketStruct> FindMarketsFromLocation(Vector3D position)
        {
            var list = new List<MarketStruct>();
            foreach (var market in EconomyScript.Instance.Data.Markets)
            {
                if (!market.Open)
                    continue;

                switch (market.MarketZoneType)
                {
                    case MarketZoneType.EntitySphere:
                        if (!EconomyScript.Instance.ServerConfig.EnablePlayerTradezones)
                            continue;
                        if (market.EntityId == 0 || !MyAPIGateway.Entities.EntityExists(market.EntityId))
                            continue;
                        IMyEntity entity;
                        if (!MyAPIGateway.Entities.TryGetEntityById(market.EntityId, out entity))
                        {
                            // Close the market, because the cube no longer exists.
                            market.Open = false;
                            continue;
                        }
                        if (entity.Closed || entity.MarkedForClose)
                        {
                            // Close the market, because the cube no longer exists.
                            market.Open = false;
                            continue;
                        }
                        IMyBeacon beacon = entity as IMyBeacon;
                        if (beacon == null)
                            continue;
                        if (!beacon.IsWorking)
                            continue;

                        // TODO: I'm not sure if these two commands will impact perfomance.

                        // player will be null if the player is not online.
                        // I'm not sure if there is a way to may a steamId to a playerId without them been online.
                        var player = MyAPIGateway.Players.FindPlayerBySteamId(market.MarketId);
                        if (player != null && beacon.GetUserRelationToOwner(player.PlayerID) != MyRelationsBetweenPlayerAndBlock.Owner)
                        {
                            // Close the market, because it's no longer owner by the player.
                            market.Open = false;
                            continue;
                        }

                        var sphere = new BoundingSphereD(entity.WorldMatrix.Translation, market.MarketZoneSphere.HasValue ? market.MarketZoneSphere.Value.Radius : 1);
                        if (sphere.Contains(position) == ContainmentType.Contains)
                            list.Add(market);
                        break;

                    case MarketZoneType.FixedSphere:
                        if (!EconomyScript.Instance.ServerConfig.EnableNpcTradezones)
                            continue;
                        if (!market.MarketZoneSphere.HasValue)
                            continue;
                        if (market.MarketZoneSphere.Value.Contains(position) == ContainmentType.Contains)
                            list.Add(market);
                        break;

                    case MarketZoneType.FixedBox:
                        if (!EconomyScript.Instance.ServerConfig.EnableNpcTradezones)
                            continue;
                        if (!market.MarketZoneBox.HasValue)
                            continue;
                        if (market.MarketZoneBox.Value.Contains(position) == ContainmentType.Contains)
                            list.Add(market);
                        break;
                }
            }
            return list;
        }
 public void MarkCellsDirty(BoundingSphereD toMark, BoundingSphereD? toExclude = null)
 {
     BoundingSphereD toMarkScaled = new BoundingSphereD(toMark.Center, toMark.Radius * RADIUS_MULTIPLIER);
     BoundingSphereD toExcludeScaled = new BoundingSphereD();
     if (toExclude.HasValue)
     {
         toExcludeScaled = toExclude.Value;
         toExcludeScaled.Radius *= RADIUS_MULTIPLIER;
     }
     ProfilerShort.Begin("Mark dirty cells");
     Vector3I cellId = Vector3I.Floor((toMark.Center - toMark.Radius) / CELL_SIZE);
     for (var iter = GetCellsIterator(toMark); iter.IsValid(); iter.GetNext(out cellId))
     {
         MyProceduralCell cell;
         if (m_cells.TryGetValue(cellId, out cell))
         {
             if (!toExclude.HasValue || toExcludeScaled.Contains(cell.BoundingVolume) == ContainmentType.Disjoint)
             {
                 m_dirtyCells.Add(cell);
             }
         }
     }
     ProfilerShort.End();
 }
예제 #12
0
        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!");

                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;
                        }

                        if (spawnPosition.HasValue)
                        {
                            successfulSpawn = SpawnDrone(antenna.EntityId, antenna.OwnerId, spawnPosition.Value, spawnGroup);
                            break;
                        }

                        break;
                    }
                }

                // Don't reschedule if there was no player inside
                if (successfulSpawn)
                {
                    antennaInfo.LastGenerationGameTime = currentTime;
                }
            }
            m_pirateAntennas.ApplyChanges();
            m_iteratingAntennas = false;
        }
예제 #13
0
            private bool EvaluateCondition()
            {
                switch (currentCondition)
                {
                case Conditions.NONE:
                    return(true);

                case Conditions.PGRA:
                    double currentPGravity = control.GetNaturalGravity().Length();
                    switch (currentOperator)
                    {
                    case Operators.EQUAL:
                        return(currentPGravity == value);

                    case Operators.LESS:
                        return(currentPGravity < value);

                    case Operators.MORE:
                        return(currentPGravity > value);
                    }
                    break;

                case Conditions.AGRA:
                    double currentAGravity = control.GetArtificialGravity().Length();
                    switch (currentOperator)
                    {
                    case Operators.EQUAL:
                        return(currentAGravity == value);

                    case Operators.LESS:
                        return(currentAGravity < value);

                    case Operators.MORE:
                        return(currentAGravity > value);
                    }
                    break;

                case Conditions.SPEED:
                    double currentSpeed = control.GetShipSpeed();
                    switch (currentOperator)
                    {
                    case Operators.EQUAL:
                        return(currentSpeed == value);

                    case Operators.LESS:
                        return(currentSpeed < value);

                    case Operators.MORE:
                        return(currentSpeed > value);
                    }
                    break;

                case Conditions.TIME:
                    if (time == -1)
                    {
                        time = DateTime.Now.Millisecond;
                    }
                    if (DateTime.Now.Millisecond - time > value * 1000)
                    {
                        time = -1;
                        return(true);
                    }
                    return(false);

                case Conditions.LOCATION:
                    BoundingSphereD boundaries = control.CubeGrid.WorldVolume;
                    return(boundaries.Contains(conditionGPS) != ContainmentType.Disjoint);
                }
                return(false);
            }
예제 #14
0
        private Vector3D AvoidCollisions(Vector3D delta)
        {
            if (m_collisionCtr <= 0)
            {
                m_collisionCtr = 0;
            }
            else
            {
                m_collisionCtr--;
                return m_oldCollisionDelta;
            }

            bool drawDebug = MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_DRONES;

            Vector3D originalDelta = delta;

            Vector3D origin = this.CubeGrid.Physics.CenterOfMassWorld;
            double shipRadius = this.CubeGrid.PositionComp.WorldVolume.Radius * 1.3f;

            Vector3D linVel = this.CubeGrid.Physics.LinearVelocity;

            double vel = linVel.Length();
            double detectionRadius = this.CubeGrid.PositionComp.WorldVolume.Radius * 10.0f + (vel * vel) * 0.05;
            BoundingSphereD sphere = new BoundingSphereD(origin, detectionRadius);

            if (drawDebug)
            {
                MyRenderProxy.DebugDrawSphere(sphere.Center, (float)shipRadius, Color.HotPink, 1.0f, false);
                MyRenderProxy.DebugDrawSphere(sphere.Center + linVel, 1.0f, Color.HotPink, 1.0f, false);
                MyRenderProxy.DebugDrawSphere(sphere.Center, (float)detectionRadius, Color.White, 1.0f, false);
            }

            Vector3D steeringVector = Vector3D.Zero;
            Vector3D avoidanceVector = Vector3D.Zero;
            int n = 0;

            double maxAvCoeff = 0.0f;

            var entities = MyEntities.GetTopMostEntitiesInSphere(ref sphere);
            for (int i = 0; i < entities.Count; ++i)
            {
                var entity = entities[i];

                if (!(entity is MyCubeGrid) && !(entity is MyVoxelMap)) continue;
                if (entity == this.Parent) continue;

                var otherSphere = entity.PositionComp.WorldVolume;
                otherSphere.Radius += shipRadius;
                Vector3D offset = otherSphere.Center - sphere.Center;

                if (Vector3D.Dot(delta, this.CubeGrid.Physics.LinearVelocity) < 0) continue;

                // Collision avoidance
                double dist = offset.Length();
                BoundingSphereD forbiddenSphere = new BoundingSphereD(otherSphere.Center + linVel, otherSphere.Radius + vel);
                Vector3D testPoint = sphere.Center + linVel * 2.0f;
                if (forbiddenSphere.Contains(testPoint) == ContainmentType.Contains)
                {
                    m_autopilotSpeedLimit = 2.0f;
                    if (drawDebug)
                    {
                        MyRenderProxy.DebugDrawSphere(forbiddenSphere.Center, (float)forbiddenSphere.Radius, Color.Red, 1.0f, false);
                    }
                }
                else
                {
                    if (Vector3D.Dot(offset, linVel) < 0)
                    {
                        if (drawDebug)
                        {
                            MyRenderProxy.DebugDrawSphere(forbiddenSphere.Center, (float)forbiddenSphere.Radius, Color.Red, 1.0f, false);
                        }
                    }
                    else if (drawDebug)
                    {
                        MyRenderProxy.DebugDrawSphere(forbiddenSphere.Center, (float)forbiddenSphere.Radius, Color.DarkOrange, 1.0f, false);
                    }
                }

                // 0.693 is log(2), because we want svLength(otherSphere.radius) -> 1 and svLength(0) -> 2
                double exponent = -0.693 * dist / (otherSphere.Radius + this.CubeGrid.PositionComp.WorldVolume.Radius + vel);
                double svLength = 2 * Math.Exp(exponent);
                double avCoeff = Math.Min(1.0f, Math.Max(0.0f, -(forbiddenSphere.Center - sphere.Center).Length() / forbiddenSphere.Radius + 2));
                maxAvCoeff = Math.Max(maxAvCoeff, avCoeff);

                Vector3D normOffset = offset / dist;
                steeringVector -= normOffset * svLength;
                avoidanceVector -= normOffset * avCoeff;
                n++;
            }
            entities.Clear();

            /*if (minTmin < vel)
            {
                delta = origin + minTmin * vel;
            }*/

            if (n > 0)
            {
                double l = delta.Length();
                delta = delta / l;
                steeringVector *= (1.0f - maxAvCoeff) * 0.1f / n;

                Vector3D debugDraw = steeringVector + delta;

                delta += steeringVector + avoidanceVector;
                delta *= l;

                if (drawDebug)
                {
                    MyRenderProxy.DebugDrawArrow3D(origin, origin + delta / l * 100.0f, Color.Green, Color.Green, false);
                    MyRenderProxy.DebugDrawArrow3D(origin, origin + avoidanceVector * 100.0f, Color.Red, Color.Red, false);
                    MyRenderProxy.DebugDrawSphere(origin, 100.0f, Color.Gray, 0.5f, false);
                }
            }

            m_oldCollisionDelta = delta;
            return delta;
        }
예제 #15
0
        public override void UpdateBeforeSimulation10()
        {
            if (!IsBeaconSecurity)
                return;

            base.UpdateBeforeSimulation10();

            if (Core.Settings == null || MyAPIGateway.Session == null || MyAPIGateway.Utilities == null || MyAPIGateway.Multiplayer == null)
            {
                Logger.Log.Debug("UpdateBeforeSimulation10() - Exit early");
                return;
            }

            if (!Core.Settings.Enabled) // if some on just turn off the switch, try to turn off all BS
            {
                if (Core.IsServer && m_block.Enabled)
                {
                    Logger.Log.Debug("Beacon Security is EMERGENCY deactivated {0} ownerid {1}...", m_block.EntityId, m_block.OwnerId);
                    RequestEnable(false);
                }
                return;
            }

            // skip noowner BeaconSecurity
            if (m_block.OwnerId == 0)
            {
                if (m_block.Enabled)
                    RequestEnable(false);
                return;
            }

            if (!Core.IsServer)
            {
                Logger.Log.Debug("UpdateBeforeSimulation10() - Exit !Core.IsServer");
                return;
            }

            try
            {
                DateTime DTNow = DateTime.Now;
                MyCubeGrid grid = Entity.GetTopMostParent() as MyCubeGrid;

                // calculations only server side, that way i'm sync it with clients...
                if (Frame++ % 3 != 0) // every 3*10 frame check
                    return;

                // First of all, check the share mode...
                if ((Entity as MyCubeBlock).IDModule.Owner != 0 && (Entity as MyCubeBlock).IDModule.ShareMode != MyOwnershipShareModeEnum.Faction)
                {  // share it to faction, this request auto sync by game
                    (Entity as MyCubeBlock).ChangeBlockOwnerRequest(m_block.OwnerId, MyOwnershipShareModeEnum.Faction);
                    Logger.Log.Debug("BeaconSecurity changed share mode {0} {1}", m_block.EntityId, m_block.OwnerId);
                }

                // the next step, check whether the the ship is moving, if the appropriate flag
                if (Core.Settings.OnlyWithZeroSpeed)
                {
                    if (grid != null)
                    {
                        bool movingNow = (grid.Physics.LinearVelocity.Length() > 0.2f || grid.Physics.AngularVelocity.Length() > 0.01f) ? true : false;

                        Logger.Log.Debug("BeaconSecurity: grid with BS {0} MOVING CHECKS: LV:{1} LA:{2} AV:{3} AA:{4}", Entity.EntityId,
                            grid.Physics.LinearVelocity.Length(), grid.Physics.LinearAcceleration.Length(), grid.Physics.AngularVelocity.Length(), grid.Physics.AngularAcceleration.Length()
                            );

                        if (movingNow == true)
                        {   // ship is moving
                            TimeSpan ts = DTNow - m_lastNotInMotion;
                            if (ts.TotalSeconds > Core.Settings.MotionShutdownDelay)
                            {   // if still moving, after N secs, just shutdown beacon
                                IsMoving = true;
                                m_lastOwnerSeen = DateTime.Now;
                            }
                        }
                        else
                        { // if ship not moving, reset timer
                            m_lastNotInMotion = DateTime.Now;
                            IsMoving = false;
                            Logger.Log.Debug(" * set last not moving state at NOW");
                        }
                    }
                    else
                    {
                        Logger.Log.Error("BeaconSecurity: BS {0} no GRID FOUND!!!", Entity.EntityId);
                    }
                } // if flag is off, check that IsMoving must be false all time
                else
                    IsMoving = false;

                // Check the owner's presence near the beacon.
                // Check the search of all the players in relation to the current beacon.
                // one BS - all players.
                // preset owner sphere
                BoundingSphereD SphereOwner = new BoundingSphereD(GetPosition(), Core.Settings.DistanceBeforeTurningOn);

                List<IMyPlayer> players = new List<IMyPlayer>();
                MyAPIGateway.Players.GetPlayers(players, x => x.Controller != null && x.Controller.ControlledEntity != null);
                foreach (IMyPlayer player in players)
                {
                    // get relations between player and beacon
                    MyRelationsBetweenPlayerAndBlock relation = m_block.GetUserRelationToOwner(player.PlayerID);
                    if (relation != MyRelationsBetweenPlayerAndBlock.Owner && relation != MyRelationsBetweenPlayerAndBlock.FactionShare)
                        continue;
                    // if player has rights to this beacon, check in radius

                    if (Core.Settings.DistanceBeforeTurningOn <= 0)
                    { // we need just check if player online, any of group
                        m_lastOwnerSeen = DTNow;
                        break;
                    }

                    // spaceman or ship, get world boundingbox
                    BoundingBoxD playerObject = (player.Controller.ControlledEntity is IMyCharacter) ? player.Controller.ControlledEntity.Entity.WorldAABB : player.Controller.ControlledEntity.Entity.GetTopMostParent().WorldAABB;
                    if (SphereOwner.Contains(playerObject) != ContainmentType.Disjoint)
                    {   // user is in sphere, set last seen date
                        m_lastOwnerSeen = DTNow;
                        break;
                    }

                }

                // Next part - Check the switching conditions
                // 1 - owner away by DistanceBeforeTurningOn meters
                // 2 - delay before turning on DelayBeforeTurningOn seconds
                // 3 - IsMoving must be false
                // 4 - if set OnlyForStations, check grid isStatic
                // 5 - if not exceed sizes

                bool chkOnlyForStations = true;
                bool chkSizes = true;
                if (Core.Settings.OnlyForStations && grid != null) // check grid istatic property
                    chkOnlyForStations = grid.IsStatic;
                IMyEntity entGrid = grid as IMyEntity;
                if (entGrid != null)
                {
                    Vector3 size = entGrid.LocalAABB.Size;
                    long limit = Core.Settings.LimitGridSizes;
                    if (limit > 0)
                    {
                        Logger.Log.Debug("Limitation for sizes: {0}   {1}x{2}x{3}", limit, size.X, size.Y, size.Z);
                        if (size.X > limit || size.Y > limit || size.Z > limit)
                        {
                            chkSizes = false;
                        }
                    }
                }

                TimeSpan diff = DTNow - m_lastOwnerSeen;
                if (diff.TotalSeconds > Core.Settings.DelayBeforeTurningOn && !IsMoving && chkOnlyForStations && chkSizes && m_block.IsFunctional && IsPowered)
                {   // BeaconSecurity must be ON
                    if (!m_block.Enabled)
                    {
                        Logger.Log.Debug("BeaconSecurity is activated {0} ownerid {1}, sync date info to others...", m_block.EntityId, m_block.OwnerId);
                        RequestEnable(true);
                    }
                    else if (!m_block.IsWorking)
                    { // if enabled, but still don't working...
                        Logger.Log.Debug("BeaconSecurity is deactivated NOPOWER {0} ownerid {1}, sync date info to others...", m_block.EntityId, m_block.OwnerId);
                        RequestEnable(false);
                        m_lastOwnerSeen = DTNow.AddSeconds(10); // shift a power on by time;
                    }
                }
                else
                {
                    // must be off
                    if (m_block.Enabled)
                    {
                        Logger.Log.Debug("BeaconSecurity is deactivated {0} ownerid {1}, sync date info to others...", m_block.EntityId, m_block.OwnerId);
                        RequestEnable(false);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Log.Error("Exception in BeaconSecurity: {0}", ex.Message);
            }
        }
        protected override IEnumerator <bool> ProcessVoxels(HashSet <IMyVoxelBase> Voxels)
        {
            if (!MyKernel.Session.Settings.EnableDrilling)
            {
                yield return(false);
            }
            if (Voxels.Count == 0)
            {
                yield return(false);
            }
            if (MyKernel.TermControls.ToolMode == true)
            {
                yield return(false);
            }
            if (!SafeZonesHelper.IsActionAllowed(MyKernel.Block.GetPosition(), MySafeZoneAction.Drilling, MyKernel.Block.EntityId))
            {
                yield return(false);
            }
            //WriteToLog("ProcessVoxels", $"Processing {Voxels.Count} voxels");
            Stopwatch stopwatch  = Stopwatch.StartNew();
            LineD     WorkingRay = new LineD(MyKernel.BeamDrawer.BeamStart, MyKernel.BeamDrawer.BeamEnd);

            foreach (MyVoxelBase Voxel in Voxels.OfType <MyVoxelBase>())
            {
                if (!SafeZonesHelper.IsActionAllowed((Voxel as IMyEntity).WorldAABB, MySafeZoneAction.Drilling, MyKernel.Block.EntityId))
                {
                    continue;
                }
                if (Voxel.GetOrePriority() == -1)
                {
                    continue;                               // Idk why, but the same early exit is found in MyShipDrill
                }
                Vector3D?VoxelHit = Voxel.GetClosestPointOnRay(WorkingRay, step: 0.99f);
                if (VoxelHit.HasValue)
                {
                    MyKernel.ResponderModule.UpdateStatusReport($"\r\nFound a voxel", true);
                    lock (BlockedVoxels)
                    {
                        if (!BlockedVoxels.ContainsKey(Voxel.EntityId))
                        {
                            BlockedVoxels.Add(Voxel.EntityId, new List <Vector3I>());
                        }
                    }
                    Vector3D hitpos = VoxelHit.Value;
                    //MyVoxelMaterialDefinition Material = Voxel.GetMaterialAt(ref hitpos);
                    Vector3D CutoutSphereCenter = hitpos + (-WorkingRay.Direction * DrillingOffsetM);
                    //stopwatch.Stop();
                    //WriteToLog("ProcessVoxels", $"Hit: {Math.Round(Vector3D.Distance(WorkingRay.From, hitpos), 2)}m, cutout: {Math.Round(Vector3D.Distance(WorkingRay.From, CutoutSphereCenter), 2)} m away, Material: {(Material != null ? Material.MaterialTypeName : "null")}");
                    //stopwatch.Start();

                    BoundingSphereD Cutout = new BoundingSphereD(CutoutSphereCenter, CutoutRadius);

                    //List<Vector3I> VoxelPoints = Voxel.GetVoxelPointsInSphere(Cutout);
                    Vector3I      refCorner;
                    Vector3I      refMaxCorner;
                    MyStorageData cutoutVoxels = Voxel.GetVoxelCacheInSphere(Cutout, out refCorner, out refMaxCorner);
                    //WriteToLog("ProcessVoxels", $"Cutout cache Min is {Math.Round(Vector3D.Distance(hitpos, Voxel.PositionLeftBottomCorner + refCorner), 2)}m away");
                    //WriteToLog("ProcessVoxels", $"Cutout cache Max is {Math.Round(Vector3D.Distance(hitpos, Voxel.PositionLeftBottomCorner + refCorner + cutoutVoxels.Size3D), 2)}m away");
                    Dictionary <MyVoxelMaterialDefinition, float> Materials = new Dictionary <MyVoxelMaterialDefinition, float>();

                    int       nullMaterials   = 0;
                    int       totalPoints     = 0;
                    Stopwatch enumeratorWatch = new Stopwatch();
                    using (MyStorageData.MortonEnumerator VoxelLoop = new MyStorageData.MortonEnumerator(cutoutVoxels, MyStorageDataTypeEnum.Content | MyStorageDataTypeEnum.Material))
                    {
                        MyKernel.ResponderModule.UpdateStatusReport($"Entered enumerator", true);
                        enumeratorWatch.Start();
                        Dictionary <byte, float> RawMaterials = new Dictionary <byte, float>();
                        Vector3I VoxelInSphereCenter;
                        Vector3  CoordsSystemOutValue;
                        //MyVoxelCoordSystems.WorldPositionToLocalPosition(Cutout.Center, Voxel.PositionComp.WorldMatrix, Voxel.PositionComp.WorldMatrixInvScaled, Voxel.SizeInMetresHalf, out CoordsSystemOutValue);
                        //VoxelInSphereCenter = new Vector3I(CoordsSystemOutValue / 1f) + Voxel.StorageMin;
                        Vector3D sphereCenter = Cutout.Center;
                        MyVoxelCoordSystems.WorldPositionToLocalPosition(Voxel.PositionLeftBottomCorner, ref sphereCenter, out CoordsSystemOutValue);
                        VoxelInSphereCenter = new Vector3I(CoordsSystemOutValue / 1f) + Voxel.StorageMin;
                        Vector3D ReconstructedPosition = Voxel.PositionLeftBottomCorner + VoxelInSphereCenter;
                        //WriteToLog("ProcessVoxels", $"VoxelInSphereCenter is {Math.Round(Vector3D.Distance(hitpos, ReconstructedPosition), 2)}m away from hitpos");
                        double CutoutRadiusSquared = Cutout.Radius * Cutout.Radius;

                        int processedPoints = 0;
                        int skippedPoints   = 0;
                        int linearIndex     = -1;
                        for (bool move = true; move != false;)
                        {
                            enumeratorWatch.Start();
                            try
                            {
                                move = VoxelLoop.MoveNext();
                            }
                            catch
                            {
                                move = false;
                                MyKernel.ResponderModule.UpdateStatusReport("Keen enumerator died", true);
                            }
                            if (move)
                            {
                                linearIndex++;
                                Vector3I voxelPoint;
                                cutoutVoxels.ComputePosition(linearIndex, out voxelPoint);
                                voxelPoint += refCorner;
                                BoundingBoxD voxelBox = new BoundingBoxD(Voxel.PositionLeftBottomCorner + voxelPoint, Voxel.PositionLeftBottomCorner + voxelPoint + 1);

                                var  PointContainment = Cutout.Contains(voxelBox);
                                bool Contacts         = PointContainment.HasFlag(ContainmentType.Contains) || PointContainment.HasFlag(ContainmentType.Intersects);
                                if (Contacts || Vector3D.DistanceSquared(ReconstructedPosition, Voxel.PositionLeftBottomCorner + voxelPoint) <= CutoutRadiusSquared)
                                {
                                    bool pointBlocked = true;
                                    lock (BlockedVoxels)
                                    {
                                        pointBlocked = BlockedVoxels[Voxel.EntityId].Contains(voxelPoint);
                                        if (!pointBlocked)
                                        {
                                            BlockedVoxels[Voxel.EntityId].Add(voxelPoint);
                                        }
                                    }
                                    if (!pointBlocked)
                                    {
                                        byte  ContentFillLevel  = cutoutVoxels.Content(linearIndex);
                                        byte  MaterialId        = cutoutVoxels.Material(linearIndex);
                                        float MaterialFillRatio = ContentFillLevel / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT;

                                        if (!RawMaterials.ContainsKey(MaterialId))
                                        {
                                            RawMaterials.Add(MaterialId, MaterialFillRatio);
                                        }
                                        else
                                        {
                                            RawMaterials[MaterialId] += MaterialFillRatio;
                                        }

                                        processedPoints++;
                                    }
                                    else
                                    {
                                        skippedPoints++;
                                    }
                                }
                                else
                                {
                                    skippedPoints++;
                                }

                                int voxelIterationLimit = MyKernel.Session.Settings.SpeedMultiplierAcceleratesDrilling ? VoxelIterationLimit * MyKernel.TermControls.SpeedMultiplier : VoxelIterationLimit;
                                if (processedPoints > 0 && processedPoints % voxelIterationLimit == 0)
                                {
                                    //MyKernel.ResponderModule.UpdateStatusReport($"Cutting out {Math.Round(Cutout.Radius * 2, 1)}m sphere:\r\n{linearIndex} voxels processed", append: true);
                                    enumeratorWatch.Stop();
                                    yield return(true);
                                }
                            }
                            totalPoints = linearIndex;
                        }
                        MyKernel.ResponderModule.UpdateStatusReport($"Total processed points: {totalPoints} ({processedPoints}/{skippedPoints})", true);
                        enumeratorWatch.Stop();
                        MyKernel.ResponderModule.UpdateStatusReport($"EnumeratorWatch: {Math.Round(enumeratorWatch.Elapsed.TotalMilliseconds, 3)}ms", true);
                        //WriteToLog("ProcessVoxels", $"Found {processedPoints} valid voxel points out of {totalPoints}", EemRdx.SessionModules.LoggingLevelEnum.DebugLog, true, 2000);

                        foreach (KeyValuePair <byte, float> kvp in RawMaterials)
                        {
                            MyVoxelMaterialDefinition material = MyDefinitionManager.Static.GetVoxelMaterialDefinition(kvp.Key);
                            if (material != null)
                            {
                                Materials.Add(material, kvp.Value * DrillingYield);
                            }
                            else
                            {
                                nullMaterials++;
                                continue;
                            }
                        }
                    }
                    MyKernel.ResponderModule.UpdateStatusReport($"Quitted enumerator", true);
                    //WriteToLog("ProcessVoxels", $"Found {VoxelPoints.Count} valid voxel points", EemRdx.SessionModules.LoggingLevelEnum.DebugLog, true, 2000);
                    //WriteToLog("ProcessVoxels", $"Found {Materials.Count} valid materials{(nullMaterials > 0 ? $" and {nullMaterials} null materials" : "")}", EemRdx.SessionModules.LoggingLevelEnum.DebugLog, true, 2000);
                    //foreach (var kvp in Materials)
                    //{
                    //    WriteToLog("ProcessVoxels", $"Material: {kvp.Key.MaterialTypeName} (mined ore: {(kvp.Key.MinedOre != null ? kvp.Key.MinedOre : "null")}), amount: {kvp.Value}");
                    //}

                    MyKernel.ResponderModule.UpdateStatusReport($"Calculating materials", true);
                    Dictionary <MyObjectBuilder_Ore, float> MaterialsToAdd = new Dictionary <MyObjectBuilder_Ore, float>();
                    int nullMinedOres = 0;
                    foreach (KeyValuePair <MyVoxelMaterialDefinition, float> kvp in Materials)
                    {
                        MyVoxelMaterialDefinition material = kvp.Key;
                        if (string.IsNullOrWhiteSpace(material.MinedOre))
                        {
                            nullMinedOres++;
                            continue;
                        }
                        try
                        {
                            if (MyKernel.TermControls.DumpStone && material.MinedOre == "Stone")
                            {
                                continue;
                            }
                            MyObjectBuilder_Ore oreBuilder = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_Ore>(material.MinedOre);
                            oreBuilder.MaterialTypeName = new MyStringHash?(material.Id.SubtypeId);
                            MyPhysicalItemDefinition oreDef = MyDefinitionManager.Static.GetPhysicalItemDefinition(oreBuilder);
                            float MinedAmountInKg           = (kvp.Value / 1000 / oreDef.Volume) * oreDef.Mass * kvp.Key.MinedOreRatio * 32;
                            stopwatch.Stop();
                            //WriteToLog("ProcessVoxels", $"Found material {material.MaterialTypeName}, {Math.Round(kvp.Value)} points, mined amount would be {Math.Round(MinedAmountInKg)} kg");
                            stopwatch.Start();
                            MaterialsToAdd.Add(oreBuilder, MinedAmountInKg);
                        }
                        catch (Exception Scrap)
                        {
                            LogError("ProcessVoxels().dict_Materials.Iterate", $"Unknown error occurred on material {material.MinedOre}", Scrap);
                        }
                    }

                    Stopwatch cutoutWatch = Stopwatch.StartNew();
                    //Voxel.Storage.WriteRange(cutoutVoxels, MyStorageDataTypeFlags.ContentAndMaterial, refCorner - 1, refMaxCorner + 1);
                    Voxel.RootVoxel.PerformCutOutSphereFast(Cutout.Center, (float)Cutout.Radius, true);
                    cutoutWatch.Stop();
                    //WriteToLog("ProcessVoxels", $"Sphere was cut in {cutoutWatch.ElapsedTicks} ticks, which is {Math.Round(cutoutWatch.Elapsed.TotalMilliseconds, 4)} ms");

                    foreach (var kvp in MaterialsToAdd)
                    {
                        MyDefinitionId OreId       = kvp.Key.GetId();
                        MyItemType     oreItemType = new MyItemType(OreId.TypeId, OreId.SubtypeId);
                        float          amountToAdd = kvp.Value;
                        while (amountToAdd > 0.1f)
                        {
                            while (((float)ToolCargo.CurrentVolume / (float)ToolCargo.MaxVolume) > 0.9f)
                            {
                                yield return(true);
                            }

                            MyInventoryItem oreItem       = new MyInventoryItem(oreItemType, 0, (VRage.MyFixedPoint)amountToAdd);
                            float           FittingAmount = (float)(ToolCargo as Sandbox.Game.MyInventory).ComputeAmountThatFits(OreId);
                            if (FittingAmount > amountToAdd)
                            {
                                FittingAmount = amountToAdd;
                            }
                            ToolCargo.AddItems((VRage.MyFixedPoint)FittingAmount, kvp.Key);
                            amountToAdd -= FittingAmount;
                            //MyKernel.ResponderModule.UpdateStatusReport($"Adding {Math.Round(FittingAmount)}u of {OreId.SubtypeId}, {amountToAdd} remains", append: false);
                        }
                    }
                }
                else
                {
                    MyKernel.ResponderModule.UpdateStatusReport($"No voxel found", true);
                }
            }
            stopwatch.Stop();
            double ElapsedMs = stopwatch.Elapsed.TotalMilliseconds;

            //WriteToLog("ProcessVoxels", $"Voxels processed, elapsed time: {stopwatch.ElapsedTicks} ticks, which is {Math.Round(ElapsedMs, 3)} ms");
            MyKernel.ResponderModule.UpdateStatusReport($"Cycle finished", true);
            yield return(false);
        }
예제 #17
0
        private static bool FindRandomBlock(WeaponSystem system, GridAi ai, Target target, Vector3D weaponPos, TargetInfo info, ConcurrentCachingList <MyCubeBlock> subSystemList, Weapon w, WeaponRandomGenerator wRng, RandomType type, ref BoundingSphereD waterSphere, bool checkPower = true)
        {
            var totalBlocks = subSystemList.Count;

            var topEnt = info.Target.GetTopMostParent();

            var entSphere   = topEnt.PositionComp.WorldVolume;
            var distToEnt   = MyUtils.GetSmallestDistanceToSphere(ref weaponPos, ref entSphere);
            var turretCheck = w != null;
            var topBlocks   = system.Values.Targeting.TopBlocks;
            var lastBlocks  = topBlocks > 10 && distToEnt < 1000 ? topBlocks : 10;
            var isPriroity  = false;

            if (lastBlocks < 250)
            {
                TargetInfo priorityInfo;
                MyEntity   fTarget;
                if (ai.Construct.Data.Repo.FocusData.Target[0] > 0 && MyEntities.TryGetEntityById(ai.Construct.Data.Repo.FocusData.Target[0], out fTarget) && ai.Targets.TryGetValue(fTarget, out priorityInfo) && priorityInfo.Target?.GetTopMostParent() == topEnt)
                {
                    isPriroity = true;
                    lastBlocks = totalBlocks < 250 ? totalBlocks : 250;
                }
                else if (ai.Construct.Data.Repo.FocusData.Target[1] > 0 && MyEntities.TryGetEntityById(ai.Construct.Data.Repo.FocusData.Target[1], out fTarget) && ai.Targets.TryGetValue(fTarget, out priorityInfo) && priorityInfo.Target?.GetTopMostParent() == topEnt)
                {
                    isPriroity = true;
                    lastBlocks = totalBlocks < 250 ? totalBlocks : 250;
                }
            }

            if (totalBlocks < lastBlocks)
            {
                lastBlocks = totalBlocks;
            }
            var      deck          = GetDeck(ref target.BlockDeck, ref target.BlockPrevDeckLen, 0, totalBlocks, topBlocks, wRng, type);
            var      physics       = system.Session.Physics;
            var      iGrid         = topEnt as IMyCubeGrid;
            var      gridPhysics   = iGrid?.Physics;
            Vector3D targetLinVel  = gridPhysics?.LinearVelocity ?? Vector3D.Zero;
            Vector3D targetAccel   = (int)system.Values.HardPoint.AimLeadingPrediction > 1 ? info.Target.Physics?.LinearAcceleration ?? Vector3D.Zero : Vector3.Zero;
            var      foundBlock    = false;
            var      blocksChecked = 0;
            var      blocksSighted = 0;

            for (int i = 0; i < totalBlocks; i++)
            {
                if (turretCheck && (blocksChecked > lastBlocks || isPriroity && (blocksSighted > 100 || blocksChecked > 50 && system.Session.RandomRayCasts > 500 || blocksChecked > 25 && system.Session.RandomRayCasts > 1000)))
                {
                    break;
                }

                var card  = deck[i];
                var block = subSystemList[card];

                if (!(block is IMyTerminalBlock) || block.MarkedForClose || checkPower && !block.IsWorking)
                {
                    continue;
                }

                system.Session.BlockChecks++;

                var    blockPos = block.CubeGrid.GridIntegerToWorld(block.Position);
                double rayDist;
                if (turretCheck)
                {
                    double distSqr;
                    Vector3D.DistanceSquared(ref blockPos, ref weaponPos, out distSqr);
                    if (distSqr > w.MaxTargetDistanceSqr || distSqr < w.MinTargetDistanceSqr)
                    {
                        continue;
                    }

                    blocksChecked++;
                    ai.Session.CanShoot++;
                    Vector3D predictedPos;
                    if (!Weapon.CanShootTarget(w, ref blockPos, targetLinVel, targetAccel, out predictedPos))
                    {
                        continue;
                    }

                    if (system.Session.WaterApiLoaded && waterSphere.Radius > 2 && waterSphere.Contains(predictedPos) != ContainmentType.Disjoint)
                    {
                        continue;
                    }

                    blocksSighted++;

                    system.Session.RandomRayCasts++;
                    IHitInfo hitInfo;
                    physics.CastRay(weaponPos, blockPos, out hitInfo, 15);

                    if (hitInfo?.HitEntity == null || hitInfo.HitEntity is MyVoxelBase)
                    {
                        continue;
                    }

                    var hitGrid = hitInfo.HitEntity as MyCubeGrid;
                    if (hitGrid != null)
                    {
                        if (hitGrid.MarkedForClose || hitGrid != block.CubeGrid && hitGrid.IsSameConstructAs(ai.MyGrid))
                        {
                            continue;
                        }
                        bool enemy;

                        var bigOwners = hitGrid.BigOwners;
                        if (bigOwners.Count == 0)
                        {
                            enemy = true;
                        }
                        else
                        {
                            var relationship = target.FiringCube.GetUserRelationToOwner(hitGrid.BigOwners[0]);
                            enemy = relationship != MyRelationsBetweenPlayerAndBlock.Owner &&
                                    relationship != MyRelationsBetweenPlayerAndBlock.FactionShare;
                        }

                        if (!enemy)
                        {
                            continue;
                        }
                    }

                    Vector3D.Distance(ref weaponPos, ref blockPos, out rayDist);
                    var shortDist = rayDist * (1 - hitInfo.Fraction);
                    var origDist  = rayDist * hitInfo.Fraction;
                    var topEntId  = block.GetTopMostParent().EntityId;
                    target.Set(block, hitInfo.Position, shortDist, origDist, topEntId);
                    foundBlock = true;
                    break;
                }

                Vector3D.Distance(ref weaponPos, ref blockPos, out rayDist);
                target.Set(block, block.PositionComp.WorldAABB.Center, rayDist, rayDist, block.GetTopMostParent().EntityId);
                foundBlock = true;
                break;
            }
            return(foundBlock);
        }
예제 #18
0
        private bool RayCheckTest()
        {
            var tick         = Comp.Session.Tick;
            var masterWeapon = TrackTarget || Comp.TrackingWeapon == null ? this : Comp.TrackingWeapon;

            if (System.Values.HardPoint.Other.MuzzleCheck)
            {
                LastMuzzleCheck = tick;
                if (MuzzleHitSelf())
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed, !Comp.Data.Repo.Base.State.TrackingReticle);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed, !Comp.Data.Repo.Base.State.TrackingReticle);
                    }
                    return(false);
                }
                if (tick - Comp.LastRayCastTick <= 29)
                {
                    return(true);
                }
            }
            Comp.LastRayCastTick = tick;

            if (Target.IsFakeTarget)
            {
                Casting = true;
                Comp.Session.Physics.CastRayParallel(ref MyPivotPos, ref Target.TargetPos, CollisionLayers.DefaultCollisionLayer, ManualShootRayCallBack);
                return(true);
            }
            if (Comp.Data.Repo.Base.State.TrackingReticle)
            {
                return(true);
            }


            if (Target.IsProjectile)
            {
                if (!Comp.Ai.LiveProjectile.Contains(Target.Projectile))
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    }
                    return(false);
                }
            }
            if (!Target.IsProjectile)
            {
                var character = Target.Entity as IMyCharacter;
                if ((Target.Entity == null || Target.Entity.MarkedForClose) || character != null && (character.IsDead || character.Integrity <= 0 || Comp.Session.AdminMap.ContainsKey(character)))
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    }
                    return(false);
                }

                var cube = Target.Entity as MyCubeBlock;
                if (cube != null && !cube.IsWorking && !Comp.Ai.Construct.Focus.EntityIsFocused(Comp.Ai, cube.CubeGrid))
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    }
                    return(false);
                }
                var topMostEnt = Target.Entity.GetTopMostParent();
                if (Target.TopEntityId != topMostEnt.EntityId || !Comp.Ai.Targets.ContainsKey(topMostEnt))
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    }
                    return(false);
                }
            }

            var targetPos       = Target.Projectile?.Position ?? Target.Entity.PositionComp.WorldMatrixRef.Translation;
            var distToTargetSqr = Vector3D.DistanceSquared(targetPos, MyPivotPos);

            if (distToTargetSqr > MaxTargetDistanceSqr && distToTargetSqr < MinTargetDistanceSqr)
            {
                masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                if (masterWeapon != this)
                {
                    Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                }
                return(false);
            }

            Water water = null;

            if (System.Session.WaterApiLoaded && !ActiveAmmoDef.AmmoDef.IgnoreWater && Comp.Ai.InPlanetGravity && Comp.Ai.MyPlanet != null && System.Session.WaterMap.TryGetValue(Comp.Ai.MyPlanet, out water))
            {
                var waterSphere = new BoundingSphereD(Comp.Ai.MyPlanet.PositionComp.WorldAABB.Center, water.radius);
                if (waterSphere.Contains(targetPos) != ContainmentType.Disjoint)
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    }
                    return(false);
                }
            }

            Casting = true;

            Comp.Session.Physics.CastRayParallel(ref MyPivotPos, ref targetPos, CollisionLayers.DefaultCollisionLayer, RayCallBack.NormalShootRayCallBack);
            return(true);
        }
예제 #19
0
        public static List<MarketStruct> FindMarketsFromLocation(Vector3D position)
        {
            var list = new List<MarketStruct>();
            foreach (var market in EconomyScript.Instance.Data.Markets)
            {
                switch (market.MarketZoneType)
                {
                    case MarketZoneType.EntitySphere:
                        if (market.EntityId == 0 || !MyAPIGateway.Entities.EntityExists(market.EntityId))
                            continue;
                        if (!market.MarketZoneSphere.HasValue)
                            continue;
                        IMyEntity entity;
                        if (!MyAPIGateway.Entities.TryGetEntityById(market.EntityId, out entity))
                            continue;
                        if (entity.Closed || entity.MarkedForClose)
                            continue;
                        var sphere = new BoundingSphereD(entity.WorldMatrix.Translation, market.MarketZoneSphere.Value.Radius);
                        if (sphere.Contains(position) == ContainmentType.Contains)
                            list.Add(market);
                        break;

                    case MarketZoneType.FixedSphere:
                        if (!market.MarketZoneSphere.HasValue)
                            continue;
                        if (market.MarketZoneSphere.Value.Contains(position) == ContainmentType.Contains)
                            list.Add(market);
                        break;

                    case MarketZoneType.FixedBox:
                        if (!market.MarketZoneBox.HasValue)
                            continue;
                        if (market.MarketZoneBox.Value.Contains(position) == ContainmentType.Contains)
                            list.Add(market);
                        break;
                }
            }
            return list;
        }
        public override bool HandleCommand(ulong userId, string[] words)
        {
            Essentials.Log.Info("Asteroid cleanup");
            HashSet <IMyEntity> entities = new HashSet <IMyEntity>( );

            Wrapper.GameAction(() =>
            {
                MyAPIGateway.Entities.GetEntities(entities);
                foreach (IMyEntity entity in entities)
                {
                    if (entity == null)
                    {
                        continue;
                    }

                    if (entity is IMyVoxelMap)
                    {
                        asteroidPositions.Add(entity.PositionComp.GetPosition( ), (IMyVoxelMap)entity);
                    }
                    else
                    {
                        entityPositions.Add(entity.PositionComp.GetPosition( ));
                    }
                }
            });
            //TODO: Use a thread pool to speed this up?
            DateTime profile = DateTime.Now;

            Communication.SendPrivateInformation(userId, $"Found {asteroidPositions.Count} asteroids.");
            foreach (var asteroid in asteroidPositions)
            {
                bool            found = false;
                BoundingSphereD bound = new BoundingSphereD(asteroid.Key, 1000);
                foreach (Vector3D checkPosition in entityPositions)
                {
                    if (bound.Contains(checkPosition) == ContainmentType.Contains)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    toRemove.Add(asteroid.Value);
                }
            }
            Communication.SendPrivateInformation(userId, $"Found {toRemove.Count} asteroids to remove.");
            int count = 0;

            foreach (IMyVoxelMap asteroid in toRemove)
            {
                if (asteroid == null || asteroid.Closed)
                {
                    continue;
                }

                count++;

                Wrapper.GameAction(() => asteroid.Close( ));
            }
            Communication.SendPrivateInformation(userId, $"Removed {count} asteroids.");
            Essentials.Log.Info("Asteroid cleanup elapsed time: " + (DateTime.Now - profile));
            return(true);
        }
예제 #21
0
        private void refreshRadar(Dictionary <Vector3D, IMySensorBlock> cache, bool _activeMode)
        {
            //if (CoreHolo.instance.settings.new_scan_method)
            //{
            //	newRefreshRadar(cache, _activeMode);
            //	return;
            //}
            Random m_rand = new Random();

            if (!valid)
            {
                return;
            }
            if (Term == null)
            {
                return;
            }
            var     shipgrid   = (IMyCubeGrid)Term.CubeGrid;
            MatrixD panelWorld = MatrixD.CreateFromQuaternion(Base6Directions.GetOrientation(Base6Directions.Direction.Forward, Base6Directions.Direction.Up));

            panelWorld.Translation = Term.WorldMatrix.Translation;
            MatrixD                               normalizedWorld          = MatrixD.Normalize(panelWorld);
            MatrixD                               panelMatrixNormalizedInv = MatrixD.Invert(normalizedWorld);
            HashSet <Vector3I>                    check        = new HashSet <Vector3I>();
            HashSet <MyPlanet>                    planets      = new HashSet <MyPlanet>();
            HashSet <IMyVoxelBase>                voxels       = new HashSet <IMyVoxelBase>();
            HashSet <Vector3I>                    absolute     = new HashSet <Vector3I>();
            Dictionary <Vector3I, Vector3D>       toWorldCache = new Dictionary <Vector3I, Vector3D>();
            Dictionary <Vector3I, ResultType>     blockCache   = new Dictionary <Vector3I, ResultType>();
            Dictionary <Vector3I, IMySensorBlock> pingCache    = new Dictionary <Vector3I, IMySensorBlock>();
            //pingResult.Clear();
            Dictionary <Vector3I, ResultType> m_ColorData = new Dictionary <Vector3I, ResultType>();
            ResultType blockcolor = ResultType.Self_Point_Alt;

            try
            {
                if (blue && !CoreHolo.instance.settings.show_ship)
                {
                    blockcolor = ResultType.Self_Point;
                    blue       = false;
                }
                else
                {
                    blue = true;
                }
                Color SelfColor = RadarResult.getColor(blockcolor);
                //int NewEntityId = 1;
                check.Add(new Vector3I(0));
                m_ColorData.Add(new Vector3I(0), blockcolor);
                //p_grid.CubeBlocks.Add(whiteblock);
                //if (!_activeMode) Log.DebugWrite(DebugLevel.Info, cache.Count);
                foreach (KeyValuePair <Vector3D, IMySensorBlock> pl in cache)
                {
                    Vector3I plloc = new Vector3I(WorldtoGrid(pl.Value.WorldMatrix.Translation, panelMatrixNormalizedInv));
                    //Log.DebugWrite(DebugLevel.Info, plloc);
                    var owner = pl.Value.OwnerId;
                    blockcolor = ResultType.Enemy;
                    if (owner == Term.OwnerId)
                    {
                        blockcolor = ResultType.Self;
                    }
                    else
                    {
                        var ownerF = MyAPIGateway.Session.Factions.TryGetPlayerFaction(owner);
                        var Tfac   = MyAPIGateway.Session.Factions.TryGetPlayerFaction(Term.OwnerId);
                        if (ownerF != null && Tfac != null)
                        {
                            if (ownerF == Tfac)
                            {
                                blockcolor = ResultType.Faction;                                            //same faction
                            }
                            else
                            {
                                var relation = MyAPIGateway.Session.Factions.GetRelationBetweenFactions(ownerF.FactionId, Tfac.FactionId);
                                if (relation == MyRelationsBetweenFactions.Neutral)
                                {
                                    blockcolor = ResultType.Friend;                                                                                //allied
                                }
                            }
                        }
                        else
                        {
                            blockcolor = ResultType.Neutral;
                        }
                    }
                    if (!check.Contains(plloc))
                    {
                        check.Add(plloc);
                        if (blockCache.ContainsKey(plloc))
                        {
                            blockCache.Remove(plloc);
                        }
                        blockCache.Add(plloc, blockcolor);
                        if (!absolute.Contains(plloc))
                        {
                            absolute.Add(plloc);
                        }
                    }
                    else
                    {
                        if (blockCache.ContainsKey(plloc))
                        {
                            blockCache.Remove(plloc);
                        }
                        blockCache.Add(plloc, blockcolor);
                        if (!absolute.Contains(plloc))
                        {
                            absolute.Add(plloc);
                        }
                    }
                }
                BoundingSphereD sphere = new BoundingSphereD(panelWorld.Translation, 50 * Range * _resMult);
                //var ents = MyAPIGateway.Entities.GetEntitiesInSphere(ref sphere);
                List <MyEntity> ents = new List <MyEntity>();
                MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, ents);
                List <IMyEntity> planetcheck = new List <IMyEntity>(ents);
                if (_activeMode)
                {
                    #region planetcache
                    foreach (MyEntity ent in planetcheck)
                    {
                        if (ent is IMyVoxelBase)
                        {
                            var asteroid = (IMyVoxelBase)ent;
                            if (asteroid.LocalAABB.Extents.Length() < Range * _resMult)
                            {
                            }
                            else
                            if (!voxels.Contains(asteroid))
                            {
                                voxels.Add(asteroid);
                            }
                        }
                    }
                    if (voxels.Count > 0)
                    {
                        for (int xmin = -50; xmin <= 50; xmin++)
                        {
                            for (int ymin = -50; ymin <= 50; ymin++)
                            {
                                for (int zmin = -50; zmin < 50; zmin++)
                                {
                                    Vector3I voxPos = new Vector3I(xmin, ymin, zmin);
                                    Vector3D world  = new Vector3D(GridToWorld(voxPos, panelWorld));
                                    bool     ex     = excludeVoxelBase(world, ref voxels);
                                    if (!check.Contains(voxPos) && ex)
                                    {
                                        check.Add(voxPos);
                                    }
                                }
                            }
                        }
                        foreach (Vector3I vpos in check)
                        {
                            Vector3I px, py, pz, mx, my, mz;
                            px = py = pz = mx = my = mz = vpos;
                            px.X++;
                            mx.X--;
                            py.Y++;
                            my.Y--;
                            pz.Z++;
                            mz.Z--;
                            int found = 0;
                            if (check.Contains(px))
                            {
                                found++;
                            }
                            if (check.Contains(mx))
                            {
                                found++;
                            }
                            if (check.Contains(py))
                            {
                                found++;
                            }
                            if (check.Contains(my))
                            {
                                found++;
                            }
                            if (check.Contains(pz))
                            {
                                found++;
                            }
                            if (check.Contains(mz))
                            {
                                found++;
                            }
                            if (found <= 5)
                            {
                                Vector3D world = GridToWorld(vpos, panelWorld);
                                if (sphere.Contains(world) == ContainmentType.Contains)
                                {
                                    if (!blockCache.ContainsKey(vpos))
                                    {
                                        blockCache.Add(vpos, ResultType.Voxel);
                                    }
                                }
                            }
                        }
                    }
                    #endregion
                    #region entityscan
                    Vector3I pos;
                    foreach (MyEntity ent in ents)
                    {
                        bool small = false;
                        //Log.DebugWrite(DebugLevel.Info, ent);
                        if (!ent.Flags.HasFlag(EntityFlags.Save))
                        {
                            //ignore items that dont save.
                            //Log.DebugWrite(DebugLevel.Info, ent);
                            //Log.DebugWrite(DebugLevel.Info, "Has no save flag");
                            continue;
                        }
                        if (ent.Parent != null)
                        {
                            if (ent == Term.Parent)
                            {
                                continue;
                            }
                        }
                        Vector3D worldCenter = ent.WorldMatrix.Translation;
                        Vector3D center      = WorldtoGrid(worldCenter, panelMatrixNormalizedInv);
                        if (ent is MyCubeBlock)
                        {
                            continue;
                        }
                        if (ent is IMySlimBlock)
                        {
                            continue;
                        }
                        blockcolor = ResultType.Unknown;
                        if (ent is IMyVoxelBase)
                        {
                            blockcolor = ResultType.Voxel;                            //add
                            //	continue;
                        }
                        if (ent is MyFloatingObject || ent is MyInventoryBagEntity)
                        {
                            small      = true;
                            blockcolor = ResultType.FloatingObject;
                        }
                        if (ent is IMyCharacter)
                        {
                            small = true;
                            //var character = ent as IMyCharacter;
                            //character.
                            var playa = MyAPIGateway.Multiplayer.Players.GetPlayerControllingEntity(ent);
                            if (playa == null)
                            {
                                continue;
                            }
                            if (playa.Controller == null)
                            {
                                continue;
                            }
                            if (playa.Controller.ControlledEntity == null)
                            {
                                continue;
                            }
                            if (playa.Controller.ControlledEntity.Entity is IMyCharacter)
                            {
                                blockcolor = ResultType.Engineer;
                            }
                        }
                        if (ent is IMyMeteor)
                        {
                            small      = true;
                            blockcolor = ResultType.Meteor;
                        }
                        if (ent is IMyCubeGrid)
                        {
                            blockcolor = ResultType.Enemy;
                            var grid = (IMyCubeGrid)ent;
                            if (grid.EntityId == Entity.Parent.EntityId)
                            {
                                continue;
                            }
                            if (grid.BigOwners.Count > 0)
                            {
                                var idents = grid.BigOwners.GetInternalArray <long>();
                                var ident  = idents[0];
                                if (ident == 0)
                                {
                                    blockcolor = ResultType.Neutral;
                                }
                                if (ident == Term.OwnerId)
                                {
                                    blockcolor = ResultType.Self;
                                }
                                else
                                {
                                    var ownerF = MyAPIGateway.Session.Factions.TryGetPlayerFaction(ident);
                                    var Tfac   = MyAPIGateway.Session.Factions.TryGetPlayerFaction(Term.OwnerId);
                                    if (ownerF != null && Tfac != null)
                                    {
                                        if (ownerF == Tfac)
                                        {
                                            blockcolor = ResultType.Faction;                                                        //same faction
                                        }
                                        else
                                        {
                                            var relation = MyAPIGateway.Session.Factions.GetRelationBetweenFactions(ownerF.FactionId, Tfac.FactionId);
                                            if (relation == MyRelationsBetweenFactions.Neutral)
                                            {
                                                blockcolor = ResultType.Friend;                                                                                            //allied
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                blockcolor = ResultType.Neutral;
                            }
                            worldCenter = grid.WorldAABB.Center;
                            center      = WorldtoGrid(worldCenter, panelMatrixNormalizedInv);
                            //disable for now
                            //var attachedradar = CoreHolo.GetRadarAttachedToGrid(grid.EntityId);
                            //foreach (Radar retRadar in attachedradar)
                            //{
                            //	Vector3D blockWorldCenter = retRadar.Term.WorldMatrix.Translation;
                            //	Vector3D blockCenter = WorldtoGrid(blockWorldCenter, panelMatrixNormalizedInv);
                            //	var centerPing = new Vector3I(blockCenter);
                            //	if (!pingCache.ContainsKey(centerPing)) pingCache.Add(centerPing, retRadar.Term);
                            //}
                        }
                        //if (blockcolor == Color.Gray.ColorToHSV())
                        //{
                        //	Log.DebugWrite( DebugLevel.Info,"Unknown object");
                        //	Log.DebugWrite(DebugLevel.Info, ent);
                        //}
                        pos = new Vector3I(center);
                        if (!check.Contains(pos) && sphere.Contains(worldCenter) == ContainmentType.Contains)
                        {
                            if (!small)
                            {
                                check.Add(pos);
                            }
                            if (!blockCache.ContainsKey(pos))
                            {
                                blockCache.Add(pos, blockcolor);
                            }
                        }
                    }
                    #endregion
                    #region shipdraw
                    if (CoreHolo.instance.settings.show_ship)
                    {
                        List <IMySlimBlock> children = new List <IMySlimBlock>();
                        shipgrid.GetBlocks(children, delegate(IMySlimBlock a)
                        {
                            Vector3I plloc = new Vector3I(WorldtoGrid(shipgrid.GridIntegerToWorld(a.Position), panelMatrixNormalizedInv));
                            if (check.Contains(plloc))
                            {
                                return(false);
                            }
                            if (blockCache.ContainsKey(plloc))
                            {
                                return(false);
                            }
                            if (absolute.Contains(plloc))
                            {
                                return(false);
                            }
                            absolute.Add(plloc);
                            blockCache.Add(plloc, ResultType.Self_Point_Alt);
                            return(false);
                        });
                    }
                    #endregion
                }
                check.Remove(Vector3I.Zero);
                int cnt  = 0;
                int mod  = m_rand.Next(CoreHolo.instance.settings.vox_cnt);
                int hits = 0;
                foreach (KeyValuePair <Vector3I, ResultType> kpair in blockCache)
                {
                    cnt++;
                    bool     skip = false;
                    Vector3I spos = kpair.Key;
                    if (spos == Vector3I.Zero)
                    {
                        continue;
                    }
                    Vector3D trail = new Vector3D(spos);
                    double   dist = trail.Length();
                    double   x = 0.5, y = 0.5, z = 0.5;
                    if (!absolute.Contains(spos))
                    {
                        for (int step = 0; step < dist; step++)
                        {
                            x += trail.X / dist;
                            y += trail.Y / dist;
                            z += trail.Z / dist;
                            Vector3I checkPos   = new Vector3I((int)x, (int)y, (int)z);
                            Vector3I checkPosXp = new Vector3I((int)x + 1, (int)y, (int)z);
                            Vector3I checkPosXm = new Vector3I((int)x - 1, (int)y, (int)z);
                            Vector3I checkPosYp = new Vector3I((int)x, (int)y + 1, (int)z);
                            Vector3I checkPosYm = new Vector3I((int)x, (int)y - 1, (int)z);
                            Vector3I checkPosZp = new Vector3I((int)x, (int)y, (int)z + 1);
                            Vector3I checkPosZm = new Vector3I((int)x, (int)y, (int)z - 1);
                            if (check.Contains(checkPos))
                            {
                                if (checkPos != spos)
                                {
                                    if (x > 0)
                                    {
                                        if (!check.Contains(checkPosXp))
                                        {
                                            break;
                                        }
                                    }
                                    if (x < 0)
                                    {
                                        if (!check.Contains(checkPosXm))
                                        {
                                            break;
                                        }
                                    }
                                    if (y > 0)
                                    {
                                        if (!check.Contains(checkPosYp))
                                        {
                                            break;
                                        }
                                    }
                                    if (y < 0)
                                    {
                                        if (!check.Contains(checkPosYm))
                                        {
                                            break;
                                        }
                                    }
                                    if (z > 0)
                                    {
                                        if (!check.Contains(checkPosZp))
                                        {
                                            break;
                                        }
                                    }
                                    if (z < 0)
                                    {
                                        if (!check.Contains(checkPosZm))
                                        {
                                            break;
                                        }
                                    }
                                    skip = true;
                                }
                                break;
                            }
                        }
                        if (skip)
                        {
                            continue;
                        }
                    }
                    blockcolor = kpair.Value;
                    if (blockcolor == ResultType.Voxel)
                    {
                        hits++;
                        if (hits > 10)
                        {
                            if (cnt % CoreHolo.instance.settings.vox_cnt != mod)
                            {
                                continue;
                            }
                        }
                    }
                    IMySensorBlock result;
                    if (pingCache.TryGetValue(spos, out result))
                    {
                        pingResult.Add(spos, result);
                    }

                    /*MyObjectBuilder_CubeBlock bl = new MyObjectBuilder_CubeBlock()
                     * {
                     *      EntityId = NewEntityId++,
                     *      SubtypeName = "SC_RadarBlip",
                     *      Min = spos,
                     *      ColorMaskHSV = RadarResult.getColor(blockcolor).ColorToHSVDX11(),
                     *      BlockOrientation = new SerializableBlockOrientation(Base6Directions.Direction.Forward, Base6Directions.Direction.Up)
                     * };*/
                    //if(!p_grid.CubeBlocks.Contains(bl)) p_grid.CubeBlocks.Add(bl);
                    if (!m_ColorData.ContainsKey(spos))
                    {
                        m_ColorData.Add(spos, blockcolor);
                    }
                }
                //_result.AddCompleteGrid(p_grid);
                T_result.ColorData = m_ColorData;
            }
            catch (Exception ex)
            {
                //MyAPIGateway.Utilities.ShowMessage("Error", ex.ToString());
                //Log.DebugWrite(DebugLevel.Error, ex);
            }
        }
예제 #22
0
        private static void DamageProjectile(HitEntity hitEnt, ProInfo attacker)
        {
            var pTarget = hitEnt.Projectile;

            if (pTarget == null)
            {
                return;
            }

            attacker.ObjectsHit++;
            var objHp          = pTarget.Info.BaseHealthPool;
            var integrityCheck = attacker.AmmoDef.DamageScales.MaxIntegrity > 0;

            if (integrityCheck && objHp > attacker.AmmoDef.DamageScales.MaxIntegrity)
            {
                return;
            }

            float damageScale = 1;

            if (attacker.AmmoDef.Const.VirtualBeams)
            {
                damageScale *= attacker.WeaponCache.Hits;
            }

            var scaledDamage = attacker.BaseDamagePool * damageScale;

            var fallOff = attacker.AmmoDef.Const.FallOffScaling && attacker.DistanceTraveled > attacker.AmmoDef.DamageScales.FallOff.Distance;

            if (fallOff)
            {
                var fallOffMultipler = (float)MathHelperD.Clamp(1.0 - ((attacker.DistanceTraveled - attacker.AmmoDef.DamageScales.FallOff.Distance) / (attacker.AmmoDef.Const.MaxTrajectory - attacker.AmmoDef.DamageScales.FallOff.Distance)), attacker.AmmoDef.DamageScales.FallOff.MinMultipler, 1);
                scaledDamage *= fallOffMultipler;
            }

            if (scaledDamage >= objHp)
            {
                attacker.BaseDamagePool    -= objHp;
                pTarget.Info.BaseHealthPool = 0;
                pTarget.State = Projectile.ProjectileState.Destroy;
            }
            else
            {
                attacker.BaseDamagePool      = 0;
                pTarget.Info.BaseHealthPool -= scaledDamage;

                if (attacker.DetonationDamage > 0 && attacker.AmmoDef.AreaEffect.Detonation.DetonateOnEnd)
                {
                    var areaSphere = new BoundingSphereD(pTarget.Position, attacker.AmmoDef.AreaEffect.Detonation.DetonationRadius);
                    foreach (var sTarget in attacker.Ai.LiveProjectile)
                    {
                        if (areaSphere.Contains(sTarget.Position) != ContainmentType.Disjoint)
                        {
                            if (attacker.DetonationDamage >= sTarget.Info.BaseHealthPool)
                            {
                                sTarget.Info.BaseHealthPool = 0;
                                sTarget.State = Projectile.ProjectileState.Destroy;
                            }
                            else
                            {
                                sTarget.Info.BaseHealthPool -= attacker.DetonationDamage;
                            }
                        }
                    }
                }
            }
        }
예제 #23
0
        public void Apply(IReadOnlyList <IMyCubeGrid> group)
        {
            var totalAABB = BoundingBoxD.CreateInvalid();

            // ReSharper disable once LoopCanBeConvertedToQuery
            foreach (var grid in group)
            {
                totalAABB = totalAABB.Include(grid.WorldAABB);
            }
            var totalSphere = new BoundingSphereD(totalAABB.Center, totalAABB.HalfExtents.Length());

            foreach (var impact in m_impactDirectionRadius)
            {
                var      speed = impact.Velocity.Length();
                var      direction = (Vector3D)impact.Velocity / speed;
                Vector3D start, end;
                {
                    var rayOffset = totalAABB.HalfExtents * 0.8 * (Vector3D)impact.Shift;
                    // mag2(rayOffset + l*direction) == radius*radius
                    // (rayOffset + l*direction)*(rayOffset + l*direction)
                    // mag2(rayOffset) + 2*l*dot(direction, rayOffset) + l*l*mag2(direction)
                    // mag2(rayOffset) - (radius*radius) + 2*l*dot(direction, rayOffset) + l*l == 0
                    var         c   = rayOffset.LengthSquared() - totalSphere.Radius * totalSphere.Radius;
                    var         b   = 2 * Vector3D.Dot(direction, rayOffset);
                    const float a   = 1;
                    var         rad = b * b - 4 * a * c;
                    if (rad <= double.Epsilon)
                    {
                        continue;
                    }
                    var lLow  = (-b - Math.Sqrt(rad)) / (2 * a);
                    var lHigh = (-b + Math.Sqrt(rad)) / (2 * a);
                    start = totalSphere.Center + rayOffset + lLow * direction;
                    end   = totalSphere.Center + rayOffset + lHigh * direction;
                }
                var ray = new RayD(start, direction);

                var bestHitLocation        = default(Vector3D);
                var bestHitDistanceSquared = double.MaxValue;
                foreach (var grid in group)
                {
                    if (!grid.WorldAABB.Intersects(ray).HasValue)
                    {
                        continue;
                    }
                    var block = grid.RayCastBlocks(start, end);
                    if (!block.HasValue)
                    {
                        continue;
                    }
                    var world    = Vector3D.Transform(block.Value * grid.GridSize, grid.WorldMatrix);
                    var distance = Vector3D.DistanceSquared(world, start);
                    if (distance > bestHitDistanceSquared)
                    {
                        continue;
                    }
                    bestHitDistanceSquared = distance;
                    bestHitLocation        = world;
                }
                if (bestHitDistanceSquared > double.MaxValue / 2)
                {
                    continue;
                }
                var impactSphere = new BoundingSphereD(bestHitLocation, impact.Radius);
                var localSphere  = new BoundingSphereD();
                var damageAmount = impact.Mass * speed * speed * (4.0 / 3.0) * Math.PI;
                var damageTotals = new Dictionary <IMySlimBlock, double>();
                foreach (var grid in group)
                {
                    if (grid.WorldAABB.Intersects(impactSphere))
                    {
                        // compute local sphere.
                        localSphere.Center = Vector3D.Transform(impactSphere.Center, grid.WorldMatrixNormalizedInv) / grid.GridSize;
                        localSphere.Radius = impactSphere.Radius / grid.GridSize;
                        var min = Vector3I.Max(Vector3I.Floor(localSphere.Center - localSphere.Radius), grid.Min);
                        var max = Vector3I.Min(Vector3I.Ceiling(localSphere.Center + localSphere.Radius), grid.Max);
                        for (var itr = new Vector3I_RangeIterator(ref min, ref max); itr.IsValid(); itr.MoveNext())
                        {
                            if (localSphere.Contains(itr.Current) == ContainmentType.Disjoint)
                            {
                                continue;
                            }
                            var block = grid.GetCubeBlock(itr.Current);
                            if (block == null)
                            {
                                continue;
                            }
                            var distanceFactor = 1 - ((Vector3D)itr.Current - localSphere.Center).LengthSquared() / (localSphere.Radius * localSphere.Radius);
                            var blockDamage    = damageAmount * distanceFactor * ((block.BlockDefinition as MyCubeBlockDefinition)?.DeformationRatio ?? 1);
                            damageTotals.AddValue(block, blockDamage);
                        }
                    }
                }
                // No idea what shape key should be.
                Logger.Debug("Apply damage to {0} blocks", damageTotals.Count);
                var hitInfo = new MyHitInfo()
                {
                    Normal = direction, Position = impactSphere.Center, Velocity = impact.Velocity, ShapeKey = 0
                };
                foreach (var kv in damageTotals)
                {
                    kv.Key.DoDamage((float)kv.Value, MyDamageType.Explosion, true, hitInfo);
                }
            }
        }
예제 #24
0
        public override void UpdateBeforeSimulation10()
        {
            if (!IsBeaconSecurity)
            {
                return;
            }

            base.UpdateBeforeSimulation10();

            if (Core.Settings == null || MyAPIGateway.Session == null || MyAPIGateway.Utilities == null || MyAPIGateway.Multiplayer == null)
            {
                Logger.Log.Debug("UpdateBeforeSimulation10() - Exit early");
                return;
            }

            if (!Core.Settings.Enabled) // if some on just turn off the switch, try to turn off all BS
            {
                if (Core.IsServer && m_block.Enabled)
                {
                    Logger.Log.Debug("Beacon Security is EMERGENCY deactivated {0} ownerid {1}...", m_block.EntityId, m_block.OwnerId);
                    RequestEnable(false);
                }
                return;
            }

            // skip noowner BeaconSecurity
            if (m_block.OwnerId == 0)
            {
                if (m_block.Enabled)
                {
                    RequestEnable(false);
                }
                return;
            }

            if (!Core.IsServer)
            {
                Logger.Log.Debug("UpdateBeforeSimulation10() - Exit !Core.IsServer");
                return;
            }

            try
            {
                DateTime   DTNow = DateTime.Now;
                MyCubeGrid grid  = Entity.GetTopMostParent() as MyCubeGrid;

                // calculations only server side, that way i'm sync it with clients...
                if (Frame++ % 3 != 0) // every 3*10 frame check
                {
                    return;
                }

                // First of all, check the share mode...
                if ((Entity as MyCubeBlock).IDModule.Owner != 0 && (Entity as MyCubeBlock).IDModule.ShareMode != MyOwnershipShareModeEnum.Faction)
                {  // share it to faction, this request auto sync by game
                    (Entity as MyCubeBlock).ChangeBlockOwnerRequest(m_block.OwnerId, MyOwnershipShareModeEnum.Faction);
                    Logger.Log.Debug("BeaconSecurity changed share mode {0} {1}", m_block.EntityId, m_block.OwnerId);
                }

                // the next step, check whether the the ship is moving, if the appropriate flag
                if (Core.Settings.OnlyWithZeroSpeed)
                {
                    if (grid != null)
                    {
                        bool movingNow = (grid.Physics.LinearVelocity.Length() > 0.2f || grid.Physics.AngularVelocity.Length() > 0.01f) ? true : false;

                        Logger.Log.Debug("BeaconSecurity: grid with BS {0} MOVING CHECKS: LV:{1} LA:{2} AV:{3} AA:{4}", Entity.EntityId,
                                         grid.Physics.LinearVelocity.Length(), grid.Physics.LinearAcceleration.Length(), grid.Physics.AngularVelocity.Length(), grid.Physics.AngularAcceleration.Length()
                                         );

                        if (movingNow == true)
                        {   // ship is moving
                            TimeSpan ts = DTNow - m_lastNotInMotion;
                            if (ts.TotalSeconds > Core.Settings.MotionShutdownDelay)
                            {   // if still moving, after N secs, just shutdown beacon
                                IsMoving        = true;
                                m_lastOwnerSeen = DateTime.Now;
                            }
                        }
                        else
                        { // if ship not moving, reset timer
                            m_lastNotInMotion = DateTime.Now;
                            IsMoving          = false;
                            Logger.Log.Debug(" * set last not moving state at NOW");
                        }
                    }
                    else
                    {
                        Logger.Log.Error("BeaconSecurity: BS {0} no GRID FOUND!!!", Entity.EntityId);
                    }
                } // if flag is off, check that IsMoving must be false all time
                else
                {
                    IsMoving = false;
                }

                // Check the owner's presence near the beacon.
                // Check the search of all the players in relation to the current beacon.
                // one BS - all players.
                // preset owner sphere
                BoundingSphereD SphereOwner = new BoundingSphereD(GetPosition(), Core.Settings.DistanceBeforeTurningOn);

                List <IMyPlayer> players = new List <IMyPlayer>();
                MyAPIGateway.Players.GetPlayers(players, x => x.Controller != null && x.Controller.ControlledEntity != null);
                foreach (IMyPlayer player in players)
                {
                    // get relations between player and beacon
                    MyRelationsBetweenPlayerAndBlock relation = m_block.GetUserRelationToOwner(player.PlayerID);
                    if (relation != MyRelationsBetweenPlayerAndBlock.Owner && relation != MyRelationsBetweenPlayerAndBlock.FactionShare)
                    {
                        continue;
                    }
                    // if player has rights to this beacon, check in radius

                    if (Core.Settings.DistanceBeforeTurningOn <= 0)
                    { // we need just check if player online, any of group
                        m_lastOwnerSeen = DTNow;
                        break;
                    }

                    // spaceman or ship, get world boundingbox
                    BoundingBoxD playerObject = (player.Controller.ControlledEntity is IMyCharacter) ? player.Controller.ControlledEntity.Entity.WorldAABB : player.Controller.ControlledEntity.Entity.GetTopMostParent().WorldAABB;
                    if (SphereOwner.Contains(playerObject) != ContainmentType.Disjoint)
                    {   // user is in sphere, set last seen date
                        m_lastOwnerSeen = DTNow;
                        break;
                    }
                }

                // Next part - Check the switching conditions
                // 1 - owner away by DistanceBeforeTurningOn meters
                // 2 - delay before turning on DelayBeforeTurningOn seconds
                // 3 - IsMoving must be false
                // 4 - if set OnlyForStations, check grid isStatic
                // 5 - if not exceed sizes

                bool chkOnlyForStations = true;
                bool chkSizes           = true;
                if (Core.Settings.OnlyForStations && grid != null) // check grid istatic property
                {
                    chkOnlyForStations = grid.IsStatic;
                }
                IMyEntity entGrid = grid as IMyEntity;
                if (entGrid != null)
                {
                    Vector3 size  = entGrid.LocalAABB.Size;
                    long    limit = Core.Settings.LimitGridSizes;
                    if (limit > 0)
                    {
                        Logger.Log.Debug("Limitation for sizes: {0}   {1}x{2}x{3}", limit, size.X, size.Y, size.Z);
                        if (size.X > limit || size.Y > limit || size.Z > limit)
                        {
                            chkSizes = false;
                        }
                    }
                }

                TimeSpan diff = DTNow - m_lastOwnerSeen;
                if (diff.TotalSeconds > Core.Settings.DelayBeforeTurningOn && !IsMoving && chkOnlyForStations && chkSizes && m_block.IsFunctional && IsPowered)
                {   // BeaconSecurity must be ON
                    if (!m_block.Enabled)
                    {
                        Logger.Log.Debug("BeaconSecurity is activated {0} ownerid {1}, sync date info to others...", m_block.EntityId, m_block.OwnerId);
                        RequestEnable(true);
                    }
                    else if (!m_block.IsWorking)
                    { // if enabled, but still don't working...
                        Logger.Log.Debug("BeaconSecurity is deactivated NOPOWER {0} ownerid {1}, sync date info to others...", m_block.EntityId, m_block.OwnerId);
                        RequestEnable(false);
                        m_lastOwnerSeen = DTNow.AddSeconds(10); // shift a power on by time;
                    }
                }
                else
                {
                    // must be off
                    if (m_block.Enabled)
                    {
                        Logger.Log.Debug("BeaconSecurity is deactivated {0} ownerid {1}, sync date info to others...", m_block.EntityId, m_block.OwnerId);
                        RequestEnable(false);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Log.Error("Exception in BeaconSecurity: {0}", ex.Message);
            }
        }
예제 #25
0
        private Vector3D AvoidCollisions(Vector3D delta, ref float autopilotSpeedLimit)
        {
            if (m_collisionCtr <= 0)
            {
                m_collisionCtr = 0;
            }
            else
            {
                m_collisionCtr--;
                return m_oldCollisionDelta;
            }

            bool drawDebug = MyDebugDrawSettings.ENABLE_DEBUG_DRAW;// && MyDebugDrawSettings.DEBUG_DRAW_DRONES;

            Vector3D originalDelta = delta;

            Vector3D origin = this.CubeGrid.Physics.CenterOfMassWorld;
            double shipRadius = this.CubeGrid.PositionComp.WorldVolume.Radius * 1.3f;
            if (MyFakes.ENABLE_VR_DRONE_COLLISIONS) //TODO VR: this MyFake should be enabled in VR but disabled in SE
                shipRadius = this.CubeGrid.PositionComp.WorldVolume.Radius * 1f;

            Vector3D linVel = this.CubeGrid.Physics.LinearVelocity;

            double vel = linVel.Length();
            double detectionRadius = this.CubeGrid.PositionComp.WorldVolume.Radius * 10.0f + (vel * vel) * 0.05;
            if (MyFakes.ENABLE_VR_DRONE_COLLISIONS)
                detectionRadius = this.CubeGrid.PositionComp.WorldVolume.Radius + (vel * vel) * 0.05;
            BoundingSphereD sphere = new BoundingSphereD(origin, detectionRadius);

            Vector3D testPoint = sphere.Center + linVel * 2.0f;
            if (MyFakes.ENABLE_VR_DRONE_COLLISIONS)
                testPoint = sphere.Center + linVel;

            if (drawDebug)
            {
                MyRenderProxy.DebugDrawSphere(sphere.Center, (float)shipRadius, Color.HotPink, 1.0f, false);
                MyRenderProxy.DebugDrawSphere(sphere.Center + linVel, 1.0f, Color.HotPink, 1.0f, false);
                MyRenderProxy.DebugDrawSphere(sphere.Center, (float)detectionRadius, Color.White, 1.0f, false);
            }

            Vector3D steeringVector = Vector3D.Zero;
            Vector3D avoidanceVector = Vector3D.Zero;
            int n = 0;

            double maxAvCoeff = 0.0f;

            var entities = MyEntities.GetTopMostEntitiesInSphere(ref sphere);
            IMyGravityProvider well;
            if (MyGravityProviderSystem.GetStrongestNaturalGravityWell(origin, out well) > 0 && well is MyGravityProviderComponent)
            {
                MyEntity e = (MyEntity)((MyGravityProviderComponent)well).Entity;
                if (!entities.Contains(e)) entities.Add(e);
            }

            for (int i = 0; i < entities.Count; ++i)
            {
                var entity = entities[i];

                if (entity == this.Parent) continue;

                Vector3D steeringDelta = Vector3D.Zero;
                Vector3D avoidanceDelta = Vector3D.Zero;

                if ((entity is MyCubeGrid) || (entity is MyVoxelMap) || (entity is MySkinnedEntity))
                {
                    if (MyFakes.ENABLE_VR_DRONE_COLLISIONS && (entity is MyCubeGrid))
                    {
                        var grid = entity as MyCubeGrid;
                        if (grid.IsStatic)
                        {
                            continue;
                        }
                    }

                    if (entity is MyCubeGrid)
                    {
                        var grid = entity as MyCubeGrid;
                        if(MyCubeGridGroups.Static.Physical.GetGroup(CubeGrid) == MyCubeGridGroups.Static.Physical.GetGroup(grid))
                        {
                            continue;
                        }
                    }

                    var otherSphere = entity.PositionComp.WorldVolume;
                    otherSphere.Radius += shipRadius;
                    Vector3D offset = otherSphere.Center - sphere.Center;

                    if (this.CubeGrid.Physics.LinearVelocity.LengthSquared() > 5.0f && Vector3D.Dot(delta, this.CubeGrid.Physics.LinearVelocity) < 0) continue;

                    // Collision avoidance
                    double dist = offset.Length();
                    BoundingSphereD forbiddenSphere = new BoundingSphereD(otherSphere.Center + linVel, otherSphere.Radius + vel);
                    if (forbiddenSphere.Contains(testPoint) == ContainmentType.Contains)
                    {
                        autopilotSpeedLimit = 2.0f;
                        if (drawDebug)
                        {
                            MyRenderProxy.DebugDrawSphere(forbiddenSphere.Center, (float)forbiddenSphere.Radius, Color.Red, 1.0f, false);
                        }
                    }
                    else
                    {
                        if (Vector3D.Dot(offset, linVel) < 0)
                        {
                            if (drawDebug)
                            {
                                MyRenderProxy.DebugDrawSphere(forbiddenSphere.Center, (float)forbiddenSphere.Radius, Color.Red, 1.0f, false);
                            }
                        }
                        else if (drawDebug)
                        {
                            MyRenderProxy.DebugDrawSphere(forbiddenSphere.Center, (float)forbiddenSphere.Radius, Color.DarkOrange, 1.0f, false);
                        }
                    }

                    // 0.693 is log(2), because we want svLength(otherSphere.radius) -> 1 and svLength(0) -> 2
                    double exponent = -0.693 * dist / (otherSphere.Radius + this.CubeGrid.PositionComp.WorldVolume.Radius + vel);
                    double svLength = 2 * Math.Exp(exponent);
                    double avCoeff = Math.Min(1.0f, Math.Max(0.0f, -(forbiddenSphere.Center - sphere.Center).Length() / forbiddenSphere.Radius + 2));
                    maxAvCoeff = Math.Max(maxAvCoeff, avCoeff);

                    Vector3D normOffset = offset / dist;
                    steeringDelta = -normOffset * svLength;
                    avoidanceDelta = -normOffset * avCoeff;
                }
                else if (entity is MyPlanet)
                {
                    var planet = entity as MyPlanet;
                    float gravityLimit = ((MySphericalNaturalGravityComponent)planet.Components.Get<MyGravityProviderComponent>()).GravityLimit;

                    Vector3D planetPos = planet.WorldMatrix.Translation;
                    Vector3D offset = planetPos - origin;

                    double dist = offset.Length();

                    double distFromGravity = dist - gravityLimit;
                    if (distFromGravity > PLANET_AVOIDANCE_RADIUS || distFromGravity < -PLANET_AVOIDANCE_TOLERANCE) continue;

                    Vector3D repulsionPoleDir = planetPos - m_currentWaypoint.Coords;
                    if (Vector3D.IsZero(repulsionPoleDir)) repulsionPoleDir = Vector3.Up;
                    else repulsionPoleDir.Normalize();

                    Vector3D repulsionPole = planetPos + repulsionPoleDir * gravityLimit;

                    Vector3D toCenter = offset;
                    toCenter.Normalize();

                    double repulsionDistSq = (repulsionPole - origin).LengthSquared();
                    if (repulsionDistSq < PLANET_REPULSION_RADIUS * PLANET_REPULSION_RADIUS)
                    {
                        double centerDist = Math.Sqrt(repulsionDistSq);
                        double repCoeff = centerDist / PLANET_REPULSION_RADIUS;
                        Vector3D repulsionTangent = origin - repulsionPole;
                        if (Vector3D.IsZero(repulsionTangent))
                        {
                            repulsionTangent = Vector3D.CalculatePerpendicularVector(repulsionPoleDir);
                        }
                        else
                        {
                            repulsionTangent = Vector3D.Reject(repulsionTangent, repulsionPoleDir);
                            repulsionTangent.Normalize();
                        }
                        // Don't bother with quaternions...
                        steeringDelta = Vector3D.Lerp(repulsionPoleDir, repulsionTangent, repCoeff);
                    }
                    else
                    {
                        Vector3D toTarget = m_currentWaypoint.Coords - origin;
                        toTarget.Normalize();

                        if (Vector3D.Dot(toTarget, toCenter) > 0)
                        {
                            steeringDelta = Vector3D.Reject(toTarget, toCenter);
                            if (Vector3D.IsZero(steeringDelta))
                            {
                                steeringDelta = Vector3D.CalculatePerpendicularVector(toCenter);
                            }
                            else
                            {
                                steeringDelta.Normalize();
                            }
                        }
                    }

                    double testPointDist = (testPoint - planetPos).Length();
                    if (testPointDist < gravityLimit) m_autopilotSpeedLimit.Value = 2.0f;

                    double avCoeff = (gravityLimit + PLANET_AVOIDANCE_RADIUS - testPointDist) / PLANET_AVOIDANCE_RADIUS;

                    steeringDelta *= avCoeff; // avCoeff == svLength
                    avoidanceDelta = -toCenter * avCoeff;
                }
                else
                {
                    continue;
                }

                steeringVector += steeringDelta;
                avoidanceVector += avoidanceDelta;
                n++;
            }
            entities.Clear();

            /*if (minTmin < vel)
            {
                delta = origin + minTmin * vel;
            }*/

            if (n > 0)
            {
                double l = delta.Length();
                delta = delta / l;
                steeringVector *= (1.0f - maxAvCoeff) * 0.1f / n;

                Vector3D debugDraw = steeringVector + delta;

                delta += steeringVector + avoidanceVector;
                delta *= l;

                if (drawDebug)
                {
                    MyRenderProxy.DebugDrawArrow3D(origin, origin + delta / l * 100.0f, Color.Green, Color.Green, false);
                    MyRenderProxy.DebugDrawArrow3D(origin, origin + avoidanceVector * 100.0f, Color.Red, Color.Red, false);
                    MyRenderProxy.DebugDrawSphere(origin, 100.0f, Color.Gray, 0.5f, false);
                }
            }

            m_oldCollisionDelta = delta;
            return delta;
        }
예제 #26
0
        public override bool Handle(ulong remoteUserId, CallSite site, BitStream stream, object obj)
        {
            if (!PluginSettings.Instance.ProtectionZonesEnabled)
            {
                return(false);
            }

            Author           author      = new Author();
            DefinitionIdBlit blit        = new DefinitionIdBlit();
            BuildData        data        = new BuildData();
            bool             instant     = false;
            bool             forceStatic = false;
            uint             hsf         = 0;

            base.Serialize(site.MethodInfo, stream, ref author, ref blit, ref data, ref instant, ref forceStatic, ref hsf);

            bool found = false;

            foreach (var item in PluginSettings.Instance.ProtectionItems)
            {
                if (!item.Enabled || !item.StopBuild)
                {
                    continue;
                }

                MyCubeGrid grid;
                if (!MyEntities.TryGetEntityById(item.EntityId, out grid))
                {
                    continue;
                }

                var sphere = new BoundingSphereD(grid.Center(), item.Radius);

                if (sphere.Contains(data.Position) == ContainmentType.Disjoint)
                {
                    continue;
                }

                if (item.AdminExempt && PlayerManager.Instance.IsUserAdmin(remoteUserId))
                {
                    continue;
                }

                found = true;
                break;
            }

            if (!found)
            {
                return(false);
            }

            NoGrief.Log.Info($"Intercepted grid spawn request from {PlayerMap.Instance.GetFastPlayerNameFromSteamId(remoteUserId)}");
            Communication.SendPrivateInformation(remoteUserId, "You cannot build blocks in this protected area!");

            //send the fail message to make the client play the paste fail sound
            //just because we can
            var inf = typeof(MyCubeBuilder).GetMethod("SpawnGridReply", BindingFlags.NonPublic | BindingFlags.Static);

            ServerNetworkManager.Instance.RaiseStaticEvent(inf, remoteUserId, false);

            return(true);
        }
        private void GenerateObjectSeeds(BoundingSphereD sphere)
        {
            ProfilerShort.Begin("GenerateObjectSeedsInBox");

            BoundingBoxD box = new BoundingBoxD(sphere.Center - sphere.Radius, sphere.Center + sphere.Radius);

            Vector3I cellId = Vector3I.Floor(box.Min / CELL_SIZE);
            for (var iter = GetCellsIterator(sphere); iter.IsValid(); iter.GetNext(out cellId))
            {
                if (!m_cells.ContainsKey(cellId))
                {
                    var cellBox = new BoundingBoxD(cellId * CELL_SIZE, (cellId + 1) * CELL_SIZE);
                    if (sphere.Contains(cellBox) == ContainmentType.Disjoint)
                    {
                        continue;
                    }
                    var cell = GenerateObjectSeedsCell(ref cellId);
                    if (cell != null)
                    {
                        m_cells.Add(cellId, cell);
                        var cellBBox = cell.BoundingVolume;
                        cell.proxyId = m_cellsTree.AddProxy(ref cellBBox, cell, 0);
                    }
                }
            }
            ProfilerShort.End();
        }
예제 #28
0
 private static void TestClipSpheres(ref MyCellCoord cell, ref BoundingSphereD nearClipSphere, ref BoundingSphereD farClipSphere, out ContainmentType nearClipRes, out ContainmentType farClipRes)
 {
     BoundingBoxD localAabb;
     MyVoxelCoordSystems.RenderCellCoordToLocalAABB(ref cell, out localAabb);
     localAabb.Inflate(MyVoxelConstants.VOXEL_SIZE_IN_METRES * (1 << cell.Lod));
     nearClipSphere.Contains(ref localAabb, out nearClipRes);
     farClipSphere.Contains(ref localAabb, out farClipRes);
 }
예제 #29
0
        public override void Handle()
        {
            if (!PluginSettings.Instance.ProtectionZonesEnabled && !PluginSettings.Instance.ExclusionZonesEnabled)
            {
                return;
            }

            //the type is MyHashSetReader<MyProjectile>, but MyProjectile is private
            //cast to generic IEnumberable so we can get around this
            var projectiles = projPool.GetType().GetProperty("Active", BindingFlags.Instance | BindingFlags.Public).GetValue(projPool) as IEnumerable;

            //thread safety
            var projArray = projectiles.Cast <object>().ToArray();

            if (projArray == null)
            {
                throw new Exception("Try the other one");
            }

            var entities = MyEntities.GetEntities().ToArray();

            if (entities.Length == 0)
            {
                NoGrief.Log.Info("Failed to get entities in zone boundary update. Skipping update");
                return;
            }

            if (PluginSettings.Instance.ProtectionZonesEnabled)
            {
                foreach (var item in PluginSettings.Instance.ProtectionItems)
                {
                    if (!item.Enabled)
                    {
                        continue;
                    }

                    MyEntity ent;
                    if (!MyEntities.TryGetEntityById(item.EntityId, out ent))
                    {
                        continue;
                    }

                    if (ent.Closed || ent.MarkedForClose || ent.Physics == null)
                    {
                        continue;
                    }

                    if (!Vector3.IsZero(ent.Physics.LinearVelocity) || !Vector3.IsZero(ent.Physics.AngularVelocity))
                    {
                        continue;
                    }

                    var sphere      = new BoundingSphereD(ent.Center(), item.Radius);
                    var outerSphere = new BoundingSphereD(ent.Center(), item.Radius + 50);

                    //destroy any missiles crossing the zone boundary
                    foreach (var entity in entities)
                    {
                        if (entity.Closed || entity.MarkedForClose || entity.Physics == null)
                        {
                            continue;
                        }

                        if (!(entity is MyAmmoBase))
                        {
                            continue;
                        }

                        if (outerSphere.Contains(entity.Center()) != ContainmentType.Disjoint && sphere.Contains(entity.Center()) == ContainmentType.Disjoint)
                        {
                            Wrapper.BeginGameAction(() => ((IMyDestroyableObject)entity).DoDamage(100, MyStringHash.GetOrCompute("Explosion"), true));
                        }
                    }

                    //delete any bullets that are crossing the zone boundary
                    foreach (object obj in projArray)
                    {
                        FieldInfo posField = obj.GetType().GetField("m_position", BindingFlags.NonPublic | BindingFlags.Instance);

                        var pos = (Vector3D)posField.GetValue(obj);
                        if (outerSphere.Contains(pos) != ContainmentType.Disjoint && sphere.Contains(pos) == ContainmentType.Disjoint)
                        {
                            //obj.GetType().GetMethod("Close", BindingFlags.Public | BindingFlags.Instance).Invoke(obj, null);
                            FieldInfo state = obj.GetType().GetField("m_state", BindingFlags.NonPublic | BindingFlags.Instance);

                            //set state to KILLED_AND_DRAWN(2) to trick the game into removing the bullet on the next update
                            //this doesn't sync :(
                            state.SetValue(obj, (byte)2);
                        }
                    }
                }
            }
            if (PluginSettings.Instance.ExclusionZonesEnabled)
            {
                foreach (var item in PluginSettings.Instance.ExclusionItems)
                {
                    if (!item.Enabled)
                    {
                        continue;
                    }

                    MyEntity ent;
                    if (!MyEntities.TryGetEntityById(item.EntityId, out ent))
                    {
                        continue;
                    }

                    if (ent.Closed || ent.MarkedForClose || ent.Physics == null)
                    {
                        continue;
                    }

                    if (!Vector3.IsZero(ent.Physics.LinearVelocity) || !Vector3.IsZero(ent.Physics.AngularVelocity))
                    {
                        continue;
                    }

                    var sphere      = new BoundingSphereD(ent.Center(), item.Radius);
                    var outerSphere = new BoundingSphereD(ent.Center(), item.Radius + 50);

                    //destroy any missiles crossing the zone boundary
                    foreach (var entity in entities)
                    {
                        if (entity.Closed || entity.MarkedForClose || entity.Physics == null)
                        {
                            continue;
                        }

                        if (!(entity is MyAmmoBase))
                        {
                            continue;
                        }

                        if (outerSphere.Contains(entity.Center()) != ContainmentType.Disjoint && sphere.Contains(entity.Center()) == ContainmentType.Disjoint)
                        {
                            Wrapper.BeginGameAction(() => ((IMyDestroyableObject)entity).DoDamage(100, MyStringHash.GetOrCompute("Explosion"), true));
                        }
                    }

                    //delete any bullets that are crossing the zone boundary
                    foreach (object obj in projArray)
                    {
                        FieldInfo posField = obj.GetType().GetField("m_position", BindingFlags.NonPublic | BindingFlags.Instance);

                        var pos = (Vector3D)posField.GetValue(obj);
                        if (outerSphere.Contains(pos) != ContainmentType.Disjoint && sphere.Contains(pos) == ContainmentType.Disjoint)
                        {
                            //obj.GetType().GetMethod("Close", BindingFlags.Public | BindingFlags.Instance).Invoke(obj, null);
                            FieldInfo state = obj.GetType().GetField("m_state", BindingFlags.NonPublic | BindingFlags.Instance);

                            //set state to KILLED_AND_DRAWN(2) to trick the game into removing the bullet on the next update
                            //this doesn't sync :(
                            state.SetValue(obj, (byte)2);
                        }
                    }
                }
            }
        }
예제 #30
0
        private bool RayCheckTest()
        {
            var trackingCheckPosition = GetScope.Info.Position;

            if (System.Session.DebugLos && Target.Entity != null)
            {
                var      trackPos      = BarrelOrigin + (MyPivotFwd * MuzzleDistToBarrelCenter);
                var      targetTestPos = Target.Entity.PositionComp.WorldAABB.Center;
                var      topEntity     = Target.Entity.GetTopMostParent();
                IHitInfo hitInfo;
                if (System.Session.Physics.CastRay(trackPos, targetTestPos, out hitInfo) && hitInfo.HitEntity == topEntity)
                {
                    var    hitPos = hitInfo.Position;
                    double closestDist;
                    MyUtils.GetClosestPointOnLine(ref trackingCheckPosition, ref targetTestPos, ref hitPos, out closestDist);
                    var tDir       = Vector3D.Normalize(targetTestPos - trackingCheckPosition);
                    var closestPos = trackingCheckPosition + (tDir * closestDist);

                    var missAmount = Vector3D.Distance(hitPos, closestPos);
                    System.Session.Rays++;
                    System.Session.RayMissAmounts += missAmount;
                }
            }

            var tick         = Comp.Session.Tick;
            var masterWeapon = TrackTarget || Comp.TrackingWeapon == null ? this : Comp.TrackingWeapon;

            if (System.Values.HardPoint.Other.MuzzleCheck)
            {
                LastMuzzleCheck = tick;
                if (MuzzleHitSelf())
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckSelfHit, !Comp.FakeMode);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckSelfHit, !Comp.FakeMode);
                    }
                    return(false);
                }
                if (tick - Comp.LastRayCastTick <= 29)
                {
                    return(true);
                }
            }

            if (Target.Entity is IMyCharacter && !Comp.Data.Repo.Base.Set.Overrides.Biologicals || Target.Entity is MyCubeBlock && !Comp.Data.Repo.Base.Set.Overrides.Grids)
            {
                masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckProjectile);
                if (masterWeapon != this)
                {
                    Target.Reset(Comp.Session.Tick, Target.States.RayCheckProjectile);
                }
                return(false);
            }

            Comp.LastRayCastTick = tick;

            if (Target.IsFakeTarget)
            {
                Casting = true;
                Comp.Session.Physics.CastRayParallel(ref trackingCheckPosition, ref Target.TargetPos, CollisionLayers.DefaultCollisionLayer, ManualShootRayCallBack);
                return(true);
            }

            if (Comp.FakeMode)
            {
                return(true);
            }


            if (Target.IsProjectile)
            {
                if (!Comp.Ai.LiveProjectile.Contains(Target.Projectile))
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckProjectile);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckProjectile);
                    }
                    return(false);
                }
            }
            if (!Target.IsProjectile)
            {
                var character = Target.Entity as IMyCharacter;
                if ((Target.Entity == null || Target.Entity.MarkedForClose) || character != null && (character.IsDead || character.Integrity <= 0 || Comp.Session.AdminMap.ContainsKey(character)))
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckOther);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckOther);
                    }
                    return(false);
                }

                var cube = Target.Entity as MyCubeBlock;
                if (cube != null && !cube.IsWorking && !Comp.Ai.Construct.Focus.EntityIsFocused(Comp.Ai, cube.CubeGrid))
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckDeadBlock);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckDeadBlock);
                    }
                    FastTargetResetTick = System.Session.Tick;
                    return(false);
                }
                var topMostEnt = Target.Entity.GetTopMostParent();
                if (Target.TopEntityId != topMostEnt.EntityId || !Comp.Ai.Targets.ContainsKey(topMostEnt))
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    }
                    return(false);
                }
            }

            var targetPos       = Target.Projectile?.Position ?? Target.Entity?.PositionComp.WorldMatrixRef.Translation ?? Vector3D.Zero;
            var distToTargetSqr = Vector3D.DistanceSquared(targetPos, trackingCheckPosition);

            if (distToTargetSqr > MaxTargetDistanceSqr && distToTargetSqr < MinTargetDistanceSqr)
            {
                masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckDistExceeded);
                if (masterWeapon != this)
                {
                    Target.Reset(Comp.Session.Tick, Target.States.RayCheckDistExceeded);
                }
                return(false);
            }
            WaterData water = null;

            if (System.Session.WaterApiLoaded && !ActiveAmmoDef.AmmoDef.IgnoreWater && Comp.Ai.InPlanetGravity && Comp.Ai.MyPlanet != null && System.Session.WaterMap.TryGetValue(Comp.Ai.MyPlanet.EntityId, out water))
            {
                var waterSphere = new BoundingSphereD(Comp.Ai.MyPlanet.PositionComp.WorldAABB.Center, water.MinRadius);
                if (waterSphere.Contains(targetPos) != ContainmentType.Disjoint)
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    }
                    return(false);
                }
            }
            Casting = true;

            Comp.Session.Physics.CastRayParallel(ref trackingCheckPosition, ref targetPos, CollisionLayers.DefaultCollisionLayer, RayCallBack.NormalShootRayCallBack);
            return(true);
        }
예제 #31
0
        /// <summary>
        /// Finds all available markets that are within range that can be traded with.
        /// This is onyl called from the Client side, so any configuration must be passed in.
        /// </summary>
        public static List <MarketStruct> ClientFindMarketsFromLocation(List <MarketStruct> markets, Vector3D position,
                                                                        bool enablePlayerTradezones, bool enableNpcTradezones)
        {
            var list = new List <MarketStruct>();

            foreach (var market in markets)
            {
                if (!market.Open)
                {
                    continue;
                }

                switch (market.MarketZoneType)
                {
                case MarketZoneType.EntitySphere:
                    if (!enablePlayerTradezones)
                    {
                        continue;
                    }
                    if (market.EntityId == 0 || !MyAPIGateway.Entities.EntityExists(market.EntityId))
                    {
                        continue;
                    }
                    IMyEntity entity;
                    if (!MyAPIGateway.Entities.TryGetEntityById(market.EntityId, out entity))
                    {
                        // Not in range of player, or no longer exists.
                        continue;
                    }
                    if (entity.Closed || entity.MarkedForClose)
                    {
                        // Not in range of player, or no longer exists.
                        continue;
                    }
                    IMyBeacon beacon = entity as IMyBeacon;
                    if (beacon == null)
                    {
                        continue;
                    }
                    if (!beacon.IsWorking)
                    {
                        continue;
                    }

                    var sphere = new BoundingSphereD(entity.WorldMatrix.Translation, market.MarketZoneSphere?.Radius ?? 1);
                    if (sphere.Contains(position) == ContainmentType.Contains)
                    {
                        list.Add(market);
                    }
                    break;

                case MarketZoneType.FixedSphere:
                    if (!enableNpcTradezones)
                    {
                        continue;
                    }
                    if (market.MarketZoneSphere == null)
                    {
                        continue;
                    }
                    if (((BoundingSphereD)market.MarketZoneSphere).Contains(position) == ContainmentType.Contains)
                    {
                        list.Add(market);
                    }
                    break;

                case MarketZoneType.FixedBox:
                    if (!enableNpcTradezones)
                    {
                        continue;
                    }
                    if (!market.MarketZoneBox.HasValue)
                    {
                        continue;
                    }
                    if (market.MarketZoneBox.Value.Contains(position) == ContainmentType.Contains)
                    {
                        list.Add(market);
                    }
                    break;
                }
            }

            return(list);
        }
예제 #32
0
        internal static bool GetClosestHitableBlockOfType(ConcurrentCachingList <MyCubeBlock> cubes, GridAi ai, Target target, Vector3D currentPos, Vector3D targetLinVel, Vector3D targetAccel, ref BoundingSphereD waterSphere, Weapon w = null, bool checkPower = true)
        {
            var minValue  = double.MaxValue;
            var minValue0 = double.MaxValue;
            var minValue1 = double.MaxValue;
            var minValue2 = double.MaxValue;
            var minValue3 = double.MaxValue;

            MyCubeBlock newEntity   = null;
            MyCubeBlock newEntity0  = null;
            MyCubeBlock newEntity1  = null;
            MyCubeBlock newEntity2  = null;
            MyCubeBlock newEntity3  = null;
            var         bestCubePos = Vector3D.Zero;
            var         top5Count   = target.Top5.Count;
            var         testPos     = currentPos;
            var         top5        = target.Top5;
            IHitInfo    hitInfo     = null;

            for (int i = 0; i < cubes.Count + top5Count; i++)
            {
                ai.Session.BlockChecks++;
                var index = i < top5Count ? i : i - top5Count;
                var cube  = i < top5Count ? top5[index] : cubes[index];

                var grid = cube.CubeGrid;
                if (grid == null || grid.MarkedForClose)
                {
                    continue;
                }
                if (!(cube is IMyTerminalBlock) || cube.MarkedForClose || cube == newEntity || cube == newEntity0 || cube == newEntity1 || cube == newEntity2 || cube == newEntity3 || checkPower && !cube.IsWorking)
                {
                    continue;
                }

                var cubePos = grid.GridIntegerToWorld(cube.Position);
                var range   = cubePos - testPos;
                var test    = (range.X * range.X) + (range.Y * range.Y) + (range.Z * range.Z);

                if (ai.Session.WaterApiLoaded && waterSphere.Radius > 2 && waterSphere.Contains(cubePos) != ContainmentType.Disjoint)
                {
                    continue;
                }

                if (test < minValue3)
                {
                    IHitInfo hit      = null;
                    var      best     = test < minValue;
                    var      bestTest = false;
                    if (best)
                    {
                        if (w != null && !(!w.IsTurret && w.ActiveAmmoDef.AmmoDef.Trajectory.Smarts.OverideTarget))
                        {
                            ai.Session.CanShoot++;
                            Vector3D predictedPos;
                            if (Weapon.CanShootTarget(w, ref cubePos, targetLinVel, targetAccel, out predictedPos))
                            {
                                ai.Session.ClosestRayCasts++;
                                if (ai.Session.Physics.CastRay(testPos, cubePos, out hit, CollisionLayers.DefaultCollisionLayer))
                                {
                                    var hitEnt  = hit.HitEntity?.GetTopMostParent() as MyEntity;
                                    var hitGrid = hitEnt as MyCubeGrid;
                                    if (hitGrid != null && grid == hitGrid || hit.HitEntity is MyFloatingObject || hit.HitEntity is IMyCharacter || hitEnt != null && w.Comp.Ai.Targets.ContainsKey(hitEnt))
                                    {
                                        bestTest = true;
                                    }
                                }
                            }
                        }
                        else
                        {
                            bestTest = true;
                        }
                    }

                    if (best && bestTest)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = minValue0;
                        newEntity1 = newEntity0;
                        minValue0  = minValue;
                        newEntity0 = newEntity;
                        minValue   = test;

                        newEntity   = cube;
                        bestCubePos = cubePos;
                        hitInfo     = hit;
                    }
                    else if (test < minValue0)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = minValue0;
                        newEntity1 = newEntity0;
                        minValue0  = test;

                        newEntity0 = cube;
                    }
                    else if (test < minValue1)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = test;

                        newEntity1 = cube;
                    }
                    else if (test < minValue2)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = test;

                        newEntity2 = cube;
                    }
                    else
                    {
                        minValue3  = test;
                        newEntity3 = cube;
                    }
                }
            }
            top5.Clear();
            if (newEntity != null && hitInfo != null)
            {
                double rayDist;
                Vector3D.Distance(ref testPos, ref bestCubePos, out rayDist);
                var shortDist = rayDist * (1 - hitInfo.Fraction);
                var origDist  = rayDist * hitInfo.Fraction;
                var topEntId  = newEntity.GetTopMostParent().EntityId;
                target.Set(newEntity, hitInfo.Position, shortDist, origDist, topEntId);
                top5.Add(newEntity);
            }
            else if (newEntity != null)
            {
                double rayDist;
                Vector3D.Distance(ref testPos, ref bestCubePos, out rayDist);
                var shortDist = rayDist;
                var origDist  = rayDist;
                var topEntId  = newEntity.GetTopMostParent().EntityId;
                target.Set(newEntity, bestCubePos, shortDist, origDist, topEntId);
                top5.Add(newEntity);
            }
            else
            {
                target.Reset(ai.Session.Tick, Target.States.NoTargetsSeen, w == null);
            }

            if (newEntity0 != null)
            {
                top5.Add(newEntity0);
            }
            if (newEntity1 != null)
            {
                top5.Add(newEntity1);
            }
            if (newEntity2 != null)
            {
                top5.Add(newEntity2);
            }
            if (newEntity3 != null)
            {
                top5.Add(newEntity3);
            }

            return(top5.Count > 0);
        }
예제 #33
0
		private bool ProjectileIsThreat(IMyEntity projectile, TargetType tType)
		{
			if (projectile.Closed)
				return false;

			Vector3D projectilePosition = projectile.GetPosition();
			BoundingSphereD ignoreArea = new BoundingSphereD(ProjectilePosition(), Options.TargetingRange / 10f);
			if (ignoreArea.Contains(projectilePosition) == ContainmentType.Contains)
				return false;

			Vector3D weaponPosition = ProjectilePosition();
			Vector3D nextPosition = projectilePosition + projectile.GetLinearVelocity() / 60f;
			if (Vector3D.DistanceSquared(weaponPosition, nextPosition) < Vector3D.DistanceSquared(weaponPosition, projectilePosition))
			{
				myLogger.debugLog("projectile: " + projectile.getBestName() + ", is moving towards weapon. D0 = " + Vector3D.DistanceSquared(weaponPosition, nextPosition) + ", D1 = " + Vector3D.DistanceSquared(weaponPosition, projectilePosition), "ProjectileIsThreat()");
				return true;
			}
			else
			{
				myLogger.debugLog("projectile: " + projectile.getBestName() + ", is moving away from weapon. D0 = " + Vector3D.DistanceSquared(weaponPosition, nextPosition) + ", D1 = " + Vector3D.DistanceSquared(weaponPosition, projectilePosition), "ProjectileIsThreat()");
				return false;
			}
		}
예제 #34
0
        public override void Handle()
        {
            lock (ProcessShipyardHandler.ShipyardsList)
            {
                foreach (ShipyardItem item in ProcessShipyardHandler.ShipyardsList.Where(item => item.YardType == ShipyardItem.ShipyardType.Grind))
                {
                    //check if the grid we're looking at is done grinding and ready to be deleted
                    if (item.HasGrid)
                    {
                        if (item.Grid?.Physics == null || item.Grid.Closed)
                        {
                            //item.HasGrid = false;
                            //item.Clear();
                            //continue;

                            //check if there's any other grids in our list to process
                            if (item.YardGrids.Count < 1)
                            {
                                item.Clear();
                                continue;
                            }

                            item.ProcessBlocks.Clear();
                            item.Grid = item.YardGrids[0];
                            item.YardGrids.RemoveAt(0);
                            //just in case this grid is also closed for some reason
                            if (item.Grid?.Physics == null || item.Grid.Closed)
                            {
                                continue;
                            }
                        }

                        //check if the target ship has left the shipyard
                        var testBox = MathUtility.CreateOrientedBoundingBox(item.Grid);
                        if (testBox == null)
                        {
                            UtilityPlugin.Log.Info("grid left yard");
                            item.Clear();
                            continue;
                        }
                        var gridBox = testBox.Value;
                        if (item.ShipyardBox.Contains(ref gridBox) != ContainmentType.Contains)
                        {
                            UtilityPlugin.Log.Info("grid left yard");
                            item.Clear();
                            continue;
                        }

                        StepGrind(item);
                        continue;
                    }

                    item.Grid.Stop();
                    foreach (MyCubeGrid yardGrid in item.YardGrids)
                    {
                        yardGrid.Stop();
                    }

                    var allEntities = new HashSet <MyEntity>();
                    var grids       = new HashSet <MyCubeGrid>();

                    //we can't get entities in a oriented bounding box, so create a sphere around the whole thing
                    //this is just to find entities in the general area, we check later against the box
                    var entitySphere = new BoundingSphereD(item.ShipyardBox.Center,
                                                           item.ShipyardBox.HalfExtent.AbsMax());

                    Wrapper.GameAction(() => allEntities = MyEntities.GetEntities());

                    foreach (MyEntity entity in allEntities.Where(x => x is MyCubeGrid))
                    {
                        if (entitySphere.Contains(entity.PositionComp.GetPosition()) == ContainmentType.Contains)
                        {
                            grids.Add(entity as MyCubeGrid);
                        }
                    }

                    if (grids.Count < 1)
                    {
                        continue;
                    }

                    foreach (MyCubeGrid grid in grids)
                    {
                        if (grid?.Physics == null || grid.Closed)
                        {
                            continue;
                        }

                        //no grinding stations
                        if (grid.Physics.IsStatic)
                        {
                            continue;
                        }

                        //create a bounding box around the ship
                        MyOrientedBoundingBoxD?testBox = MathUtility.CreateOrientedBoundingBox(grid);

                        if (!testBox.HasValue)
                        {
                            continue;
                        }

                        MyOrientedBoundingBoxD gridBox = testBox.Value;

                        //check if the ship bounding box is completely inside the yard box
                        if (item.ShipyardBox.Contains(ref gridBox) == ContainmentType.Contains)
                        {
                            if (!item.HasGrid)
                            {
                                item.HasGrid = true;
                                item.Grid    = grid;
                            }
                            else
                            {
                                item.YardGrids.Add(grid);
                            }
                        }
                    }
                }
            }

            base.Handle();
        }
 public bool ExistsInCell(ref BoundingBoxD bbox)
 {
     return(m_sphereMax.Contains(bbox) != ContainmentType.Disjoint);
 }
 private void MarkCellsDirty(BoundingSphereD toMark, BoundingSphereD toExclude)
 {
     ProfilerShort.Begin("Mark dirty cells");
     Vector3I cellId = Vector3I.Floor((toMark.Center - toMark.Radius) / CELL_SIZE);
     for (var iter = GetCellsIterator(toMark); iter.IsValid(); iter.GetNext(out cellId))
     {
         MyProceduralCell cell;
         if (m_cells.TryGetValue(cellId, out cell))
         {
             if (toExclude.Contains(cell.BoundingVolume) == ContainmentType.Disjoint)
             {
                 m_dirtyCellsToAdd.Add(cell);
             }
         }
     }
     ProfilerShort.End();
 }
예제 #37
0
        /// <summary>
        /// Finds all available markets that are within range that can be traded with.
        /// </summary>
        /// <param name="position"></param>
        /// <returns></returns>
        public static List <MarketStruct> FindMarketsFromLocation(Vector3D position)
        {
            var list = new List <MarketStruct>();

            foreach (var market in EconomyScript.Instance.Data.Markets)
            {
                if (!market.Open)
                {
                    continue;
                }

                switch (market.MarketZoneType)
                {
                case MarketZoneType.EntitySphere:
                    if (!EconomyScript.Instance.ServerConfig.EnablePlayerTradezones)
                    {
                        continue;
                    }
                    if (market.EntityId == 0 || !MyAPIGateway.Entities.EntityExists(market.EntityId))
                    {
                        continue;
                    }
                    IMyEntity entity;
                    if (!MyAPIGateway.Entities.TryGetEntityById(market.EntityId, out entity))
                    {
                        // Close the market, because the cube no longer exists.
                        market.Open = false;
                        continue;
                    }
                    if (entity.Closed || entity.MarkedForClose)
                    {
                        // Close the market, because the cube no longer exists.
                        market.Open = false;
                        continue;
                    }
                    IMyBeacon beacon = entity as IMyBeacon;
                    if (beacon == null)
                    {
                        continue;
                    }
                    if (!beacon.IsWorking)
                    {
                        continue;
                    }

                    // TODO: I'm not sure if these two commands will impact perfomance.

                    // player will be null if the player is not online.
                    // I'm not sure if there is a way to may a steamId to a playerId without them been online.
                    var player = MyAPIGateway.Players.FindPlayerBySteamId(market.MarketId);
                    if (player != null && beacon.GetUserRelationToOwner(player.IdentityId) != MyRelationsBetweenPlayerAndBlock.Owner)
                    {
                        // Close the market, because it's no longer owner by the player.
                        market.Open = false;
                        continue;
                    }

                    var sphere = new BoundingSphereD(entity.WorldMatrix.Translation, market.MarketZoneSphere.HasValue ? market.MarketZoneSphere.Value.Radius : 1);
                    if (sphere.Contains(position) == ContainmentType.Contains)
                    {
                        list.Add(market);
                    }
                    break;

                case MarketZoneType.FixedSphere:
                    if (!EconomyScript.Instance.ServerConfig.EnableNpcTradezones)
                    {
                        continue;
                    }
                    if (!market.MarketZoneSphere.HasValue)
                    {
                        continue;
                    }
                    if (market.MarketZoneSphere.Value.Contains(position) == ContainmentType.Contains)
                    {
                        list.Add(market);
                    }
                    break;

                case MarketZoneType.FixedBox:
                    if (!EconomyScript.Instance.ServerConfig.EnableNpcTradezones)
                    {
                        continue;
                    }
                    if (!market.MarketZoneBox.HasValue)
                    {
                        continue;
                    }
                    if (market.MarketZoneBox.Value.Contains(position) == ContainmentType.Contains)
                    {
                        list.Add(market);
                    }
                    break;
                }
            }
            return(list);
        }
예제 #38
0
        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;
        }
예제 #39
0
        public override void Handle()
        {
            if (!PluginSettings.Instance.ExclusionZonesEnabled)
            {
                return;
            }

            MyEntity[] entities = MyEntities.GetEntities().ToArray();
            if (entities.Length == 0)
            {
                NoGrief.Log.Info("Failed to get entity list in exclusion zone update. Skipping update.");
                return;
            }

            foreach (SettingsExclusionItem item in PluginSettings.Instance.ExclusionItems)
            {
                if (!item.Enabled)
                {
                    continue;
                }

                if (!_redirectedEntites.ContainsKey(item.EntityId))
                {
                    _redirectedEntites.Add(item.EntityId, new HashSet <long>());
                }

                MyEntity grid;
                if (!MyEntities.TryGetEntityById(item.EntityId, out grid))
                {
                    continue;
                }

                bool init = item.ContainsEntities.Count == 0;

                //zones don't work on moving entities
                if (!Vector3.IsZero(grid.Physics.LinearVelocity) || !Vector3.IsZero(grid.Physics.AngularVelocity))
                {
                    continue;
                }

                var sphere = new BoundingSphereD(grid.Center(), item.Radius);

                if (init)
                {
                    foreach (MyEntity entity in entities)
                    {
                        if (sphere.Contains(entity.PositionComp.WorldVolume) == ContainmentType.Contains)
                        {
                            item.ContainsEntities.Add(entity.EntityId);
                        }
                    }
                    if (item.TransportAdd)
                    {
                        item.AllowedEntities = item.ContainsEntities.ToList();
                    }
                }

                var outerSphere = new BoundingSphereD(sphere.Center, sphere.Radius + 50);

                var approaching = new HashSet <long>();
                foreach (MyEntity entity in entities)
                {
                    if (entity?.Physics == null)
                    {
                        continue;
                    }

                    if (entity.Closed || entity.MarkedForClose)
                    {
                        continue;
                    }

                    if (entity is MyVoxelBase)
                    {
                        continue;
                    }

                    if (entity is MyAmmoBase)
                    {
                        continue;
                    }

                    //entity is trying to enter the exclusion zone. push them away
                    if (outerSphere.Contains(entity.Center()) != ContainmentType.Disjoint && !item.ContainsEntities.Contains(entity.EntityId))
                    {
                        approaching.Add(entity.EntityId);
                        MyPlayer controller = MySession.Static.Players.GetControllingPlayer(entity);
                        try
                        {
                            if (controller?.Client != null)
                            {
                                if (!string.IsNullOrEmpty(item.FactionTag) && MySession.Static.Factions.GetPlayerFaction(controller.Identity.IdentityId).Tag == item.FactionTag)
                                {
                                    ExcludeEntities(entity, item);
                                    if (item.TransportAdd && !item.AllowedPlayers.Contains(controller.Client.SteamUserId))
                                    {
                                        item.AllowedPlayers.Add(controller.Client.SteamUserId);
                                    }
                                    continue;
                                }

                                if (item.AllowAdmins && controller.IsAdmin)
                                {
                                    ExcludeEntities(entity, item);
                                    continue;
                                }

                                if (item.AllowedPlayers.Contains(controller.Client.SteamUserId))
                                {
                                    ExcludeEntities(entity, item);
                                    continue;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            NoGrief.Log.Error(ex);
                        }

                        if (item.AllowedEntities.Contains(entity.EntityId))
                        {
                            ExcludeEntities(entity, item);
                            continue;
                        }

                        Vector3D direction = Vector3D.Normalize(entity.Center() - sphere.Center);
                        Vector3D velocity  = entity.Physics.LinearVelocity;
                        if (Vector3D.IsZero(velocity))
                        {
                            velocity += direction;
                        }

                        if (!_redirectedEntites[item.EntityId].Contains(entity.EntityId))
                        {
                            _redirectedEntites[item.EntityId].Add(entity.EntityId);

                            Vector3D forceDir = Vector3D.Reflect(Vector3D.Normalize(velocity), direction);
                            //Vector3D force = forceDir * (velocity.Length()+10) * entity.Physics.Mass * 5 + -entity.Physics.LinearAcceleration * entity.Physics.Mass;
                            //if (!force.IsValid())
                            //{
                            //    NoGrief.Log.Error("Invalid Force");
                            //    continue;
                            //}
                            if (controller?.Client != null && !string.IsNullOrEmpty(item.ExclusionMessage))
                            {
                                Communication.Notification(controller.Client.SteamUserId, MyFontEnum.White, 10000, item.ExclusionMessage);
                            }
                            if (!(entity is MyCharacter))
                            {
                                Vector3 force = forceDir * velocity.Length() * entity.Physics.Mass * 60 * 1.5;
                                force += entity.Physics.LinearAcceleration.Length() * entity.Physics.Mass * 60;
                                Wrapper.BeginGameAction(() => entity.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, force, entity.Physics.CenterOfMassWorld, Vector3.Zero));
                            }
                            else
                            {
                                //characres require a different method
                                var      character     = (MyCharacter)entity;
                                Vector3D bodyDirection = -Vector3D.Normalize(Vector3D.Transform(direction, character.PositionComp.WorldMatrixInvScaled));
                                Vector3D bodyForce     = bodyDirection * character.Physics.LinearVelocity.Length() * character.Physics.Mass * 60 * 1.5;
                                bodyForce += character.Physics.LinearAcceleration.Length() * character.Physics.Mass * 60;
                                Wrapper.BeginGameAction(() => character.Physics.AddForce(MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE, bodyForce, character.Center(), Vector3.Zero));
                            }
                        }
                        if (sphere.Contains(entity.Center()) != ContainmentType.Disjoint)
                        {
                            if (!(entity is MyCharacter))
                            {
                                Vector3D force = direction * (velocity.Length() + 5) * entity.Physics.Mass * 60 * 2;
                                force += entity.Physics.LinearAcceleration.Length() * entity.Physics.Mass * 60;
                                Wrapper.BeginGameAction(() => entity.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, force, entity.Physics.CenterOfMassWorld, Vector3.Zero));
                            }
                            else
                            {
                                var      character     = (MyCharacter)entity;
                                Vector3D bodyDirection = -Vector3D.Normalize(Vector3D.Transform(direction, character.PositionComp.WorldMatrixInvScaled));
                                Vector3D bodyForce     = bodyDirection * (character.Physics.LinearVelocity.Length() + 5) * character.Physics.Mass * 60 * 2;
                                bodyForce += character.Physics.LinearAcceleration.Length() * character.Physics.Mass * 60;
                                Wrapper.BeginGameAction(() => character.Physics.AddForce(MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE, bodyForce, character.Center(), Vector3.Zero));
                            }
                        }
                    }
                }

                var toRemove = new List <long>();
                //TODO: We're searching the dictionary way too much. Do something about it later
                foreach (long id in _redirectedEntites[item.EntityId])
                {
                    if (!approaching.Contains(id))
                    {
                        toRemove.Add(id);
                    }
                }
                foreach (long rem in toRemove)
                {
                    _redirectedEntites[item.EntityId].Remove(rem);
                }
            }
        }