Пример #1
0
 private bool GridInside(MyCubeGrid grid, MyOrientedBoundingBoxD bOriBBoxD)
 {
     if (grid != null && CustomCollision.PointInShield(grid.PositionComp.WorldVolume.Center, DetectMatrixOutsideInv))
     {
         if (CustomCollision.ObbCornersInShield(bOriBBoxD, DetectMatrixOutsideInv, _obbCorners))
         {
             var sMass      = ((MyCubeGrid)Shield.CubeGrid).GetCurrentMass();
             var bPhysics   = ((IMyCubeGrid)grid).Physics;
             var sPhysics   = Shield.CubeGrid.Physics;
             var sLSpeed    = sPhysics.LinearVelocity;
             var sASpeed    = sPhysics.AngularVelocity * 50;
             var sLSpeedLen = sLSpeed.LengthSquared();
             var sASpeedLen = sASpeed.LengthSquared();
             var sSpeedLen  = sLSpeedLen > sASpeedLen ? sLSpeedLen : sASpeedLen;
             var forceData  = new MyAddForceData {
                 MyGrid = grid, Force = -(grid.PositionComp.WorldAABB.Center - sPhysics.CenterOfMassWorld) * -sMass, MaxSpeed = sSpeedLen + 3
             };
             if (!bPhysics.IsStatic)
             {
                 ForceData.Enqueue(forceData);
             }
             return(true);
         }
     }
     return(false);
 }
 void Positioning_OnForce(ForceData force)
 {
     Dispatcher.BeginInvoke((Action) delegate
     {
         sld_Force.Value = Convert.ToDouble(force.Zforce * 10);
     });
 }
Пример #3
0
        public ForceData ReadURForce()
        {
            ForceData forceData = new ForceData();

            if (MBmaster != null)
            {
                ushort ID           = 4;
                byte   unit         = 0;
                ushort StartAddress = 137;
                byte   Length       = Convert.ToByte("6");

                byte[] respons = new byte[1];

                MBmaster.ReadInputRegister(ID, unit, StartAddress, Length, ref respons);

                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(respons);
                }

                if (respons.Length == 12)
                {
                    forceData.Xforce  = Convert.ToDouble(BitConverter.ToInt16(respons, 10)) / 100;
                    forceData.Yforce  = Convert.ToDouble(BitConverter.ToInt16(respons, 8)) / 100;
                    forceData.Zforce  = Convert.ToDouble(BitConverter.ToInt16(respons, 6)) / 100;
                    forceData.RXforce = Convert.ToDouble(BitConverter.ToInt16(respons, 4)) / 100;
                    forceData.RYforce = Convert.ToDouble(BitConverter.ToInt16(respons, 2)) / 100;
                    forceData.RZforce = Convert.ToDouble(BitConverter.ToInt16(respons, 0)) / 100;
                }
            }
            return(forceData);
        }
        /// <summary>Calculates a moving average based on the latest collected force values.</summary>
        /// <param name="force">New force data to calculate a new average.</param>
        private ForceData MovingAverage(ForceData force)
        {
            if (avgForceList.Count == samples)
            {
                avgForceList.RemoveAt(0);                                                                                   // When the list has reached the sample size, the oldest collected value is removed
            }                                                                                                               // from the list to maintain the list size equal to number of samples
            avgForceList.Add(force);                                                                                        // Adds the newest force value

            ForceData avgForce = new ForceData();

            foreach (ForceData f in avgForceList)                                                                           // Calculates the total force values for each directions
            {
                avgForce.Xforce += f.Xforce;
                avgForce.Yforce += f.Yforce;
                avgForce.Zforce += f.Zforce;
            }

            avgForce.Xforce = (avgForce.Xforce / samples) / scale;                                                          // Calculates the average force in each directions and scales the values
            avgForce.Yforce = (avgForce.Yforce / samples) / scale;
            avgForce.Zforce = (avgForce.Zforce / samples) / scale;

            if (OnForce != null)
            {
                OnForce(avgForce);
            }

            return(avgForce);
        }
Пример #5
0
        public static void ApplyToMapInfo(MapInfo mapInfo)
        {
            // Create players
            var player0 = new PlayerData()
            {
                PlayerNumber       = 0,
                PlayerName         = "Player 1",
                PlayerController   = PlayerController.User,
                PlayerRace         = PlayerRace.Human,
                IsRaceSelectable   = true,
                StartPosition      = new System.Drawing.PointF(0f, 0f),
                FixedStartPosition = true,
            };
            var player1 = new PlayerData()
            {
                PlayerNumber       = 1,
                PlayerName         = "Player 2",
                PlayerController   = PlayerController.User,
                PlayerRace         = PlayerRace.Human,
                IsRaceSelectable   = true,
                StartPosition      = new System.Drawing.PointF(0f, 0f),
                FixedStartPosition = true,
            };
            var player2 = new PlayerData()
            {
                PlayerNumber       = 23,
                PlayerName         = "Enemies",
                PlayerController   = PlayerController.Computer,
                PlayerRace         = PlayerRace.Orc,
                IsRaceSelectable   = false,
                StartPosition      = new System.Drawing.PointF(0f, 0f),
                FixedStartPosition = true,
            };

            // Add players to MapInfo
            mapInfo.SetPlayerData(player0, player1, player2);

            // Create teams
            var team0 = new ForceData()
            {
                ForceName  = "Team 1",
                ForceFlags = ForceFlags.Allied | ForceFlags.ShareVision,
            };
            var team1 = new ForceData()
            {
                ForceName = "Team 2",
            };

            // Add players to teams
            team0.SetPlayers(player0, player1);
            team1.SetPlayers(player2);

            // Add teams to MapInfo
            mapInfo.SetForceData(team0, team1);

            // Update map flags
            mapInfo.MapFlags |= MapFlags.UseCustomForces | MapFlags.FixedPlayerSettingsForCustomForces;
        }
 /// <summary>Updates the labels in the window with the configurations received.</summary>
 /// <param name="conf">Object containing the received configurations.</param>
 void Connection_OnCurrentConfig(ConfigurationData conf, ForceData force)
 {
     Dispatcher.BeginInvoke((Action) delegate
     {
         lb_currentOffset.Content  = conf.OffsetZ.ToString();
         lb_currentPayload.Content = conf.Payload.ToString();
         lb_currentAcc.Content     = conf.Acceleration.ToString();
         lb_currentSpeed.Content   = conf.Speed.ToString();
     });
 }
        /// <summary>Gets the forcefeedback from the robots modbus server and sets the force on the GeoMagicTouch, based on if the robot should move or not.</summary>
        private void HandleForce()
        {
            if (isMoving)
            {
                ForceData f = connection.modBus.ReadURForce();                                                              // Gets the forcefeedback from the modbus server

                connection.gmt.SetForce(MovingAverage(f));                                                                  // Sets the new force on the GeoMagicTouch based on the averaging
            }
            else
            {
                connection.gmt.SetForce(new ForceData(0, 0, 0, 0, 0, 0));                                                   // When the robot is not moving sets the force to zero
            }
        }
        public static void ApplyToMapInfo(MapInfo mapInfo)
        {
            // Create players
            var team0Players = new PlayerData[PlayerConstants.PlayerSlotCount];

            for (var i = 0; i < PlayerConstants.PlayerSlotCount; i++)
            {
                var playerData = PlayerData.Create(i);
                playerData.PlayerController   = PlayerController.User;
                playerData.PlayerRace         = PlayerRace.Human;
                playerData.IsRaceSelectable   = true;
                playerData.StartPosition      = new System.Drawing.PointF(0f, 0f);
                playerData.FixedStartPosition = true;

                team0Players[i] = playerData;
            }

            var team1Player = PlayerData.Create(23);

            team1Player.PlayerName         = "Enemies";
            team1Player.PlayerController   = PlayerController.Computer;
            team1Player.PlayerRace         = PlayerRace.Orc;
            team1Player.IsRaceSelectable   = false;
            team1Player.StartPosition      = new System.Drawing.PointF(0f, 0f);
            team1Player.FixedStartPosition = true;

            // Add players to MapInfo
            mapInfo.SetPlayerData(team0Players.Append(team1Player).ToArray());

            // Create teams
            var team0 = new ForceData()
            {
                ForceName  = "Team 1",
                ForceFlags = ForceFlags.Allied | ForceFlags.ShareVision,
            };
            var team1 = new ForceData()
            {
                ForceName = "Team 2",
            };

            // Add players to teams
            team0.SetPlayers(team0Players);
            team1.SetPlayers(team1Player);

            // Add teams to MapInfo
            mapInfo.SetForceData(team0, team1);

            // Update map flags
            mapInfo.MapFlags |= MapFlags.UseCustomForces | MapFlags.FixedPlayerSettingsForCustomForces;
        }
Пример #9
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <Point3d> targets    = new List <Point3d>();
            List <double>  thresholds = new List <double>();
            double         av         = new double();
            double         ma         = new double();

            if (!DA.GetDataList(0, targets))
            {
                return;
            }
            if (!DA.GetDataList(1, thresholds))
            {
                return;
            }
            if (!DA.GetData(2, ref av))
            {
                return;
            }
            if (!DA.GetData(3, ref ma))
            {
                return;
            }
            if (targets.Count != thresholds.Count)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "List lengths for targets and thresholds must match, please check your inputs"); return;
            }

            List <Circle> circles = new List <Circle>();
            int           count   = 0;

            foreach (Point3d p in targets)
            {
                circles.Add(new Circle(p, thresholds[count]));
                count++;
            }

            List <float> floatThresholds = thresholds.Select <double, float>(i => (float)i).ToList();
            ForceData    forceData       = new ForceData(targets, floatThresholds);

            forceData.repelValue = (float)av;
            forceData.maxRepel   = (float)ma;
            forceData.forceType  = "Repel";

            DA.SetData(0, forceData);
            DA.SetDataList(1, circles);
        }
Пример #10
0
        /// <summary>Reads the force data from the modbus general purpose register.</summary>
        public ForceData ReadURForce()
        {
            ForceData forceData = new ForceData();

            if (MBmaster != null)
            {
                ushort ID           = 4;
                byte   unit         = 0;
                ushort StartAddress = 137;                  // StartAddress in the general purpose register
                byte   Length       = 6;                    // Length of the desired data array. A representation of the number of registers to be read.

                byte[] respons = new byte[1];

                MBmaster.ReadInputRegister(ID, unit, StartAddress, Length, ref respons);

                if (respons != null && respons.Length == 12)
                {
                    if (BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(respons);

                        // When the computers byte order is little endian the respons array is reversed
                        // And therefor the first value of the ForceData is collected from the buttom and up.
                        forceData.Xforce  = Convert.ToDouble(BitConverter.ToInt16(respons, 10)) / 100;
                        forceData.Yforce  = Convert.ToDouble(BitConverter.ToInt16(respons, 8)) / 100;
                        forceData.Zforce  = Convert.ToDouble(BitConverter.ToInt16(respons, 6)) / 100;
                        forceData.RXforce = Convert.ToDouble(BitConverter.ToInt16(respons, 4)) / 100;
                        forceData.RYforce = Convert.ToDouble(BitConverter.ToInt16(respons, 2)) / 100;
                        forceData.RZforce = Convert.ToDouble(BitConverter.ToInt16(respons, 0)) / 100;
                    }
                    else
                    {
                        forceData.Xforce  = Convert.ToDouble(BitConverter.ToInt16(respons, 0)) / 100;
                        forceData.Yforce  = Convert.ToDouble(BitConverter.ToInt16(respons, 2)) / 100;
                        forceData.Zforce  = Convert.ToDouble(BitConverter.ToInt16(respons, 4)) / 100;
                        forceData.RXforce = Convert.ToDouble(BitConverter.ToInt16(respons, 6)) / 100;
                        forceData.RYforce = Convert.ToDouble(BitConverter.ToInt16(respons, 8)) / 100;
                        forceData.RZforce = Convert.ToDouble(BitConverter.ToInt16(respons, 10)) / 100;
                    }
                }
            }
            return(forceData);
        }
Пример #11
0
        void SetData()
        {
            ForceData[] OutputData = new ForceData[Sources.Count];

            if (ForceBuffer.Count != OutputData.Length)
            {
                UpdateCount();
            }

            for (int i = OutputData.Length - 1; i >= 0; i--)
            {
                if (Sources[i] == null)
                {
                    RemoveSource(i);
                }

                OutputData[i] = Sources[i].gameObject.activeSelf ? Sources[i].GetForceData() : PsyiaForce.EmptyForceData;
            }
            ForceBuffer.SetData(OutputData);
        }
Пример #12
0
 /// <summary>Gets the current configurations while the connection to the modbus server i alive.</summary>
 public void CheckConfigurations()
 {
     configThread = new Thread(() =>
     {
         ConfigurationData currentConfig = new ConfigurationData();
         while (true)
         {
             currentConfig   = modBus.GetConfigurations();
             ForceData force = modBus.ReadURForce();
             if (OnCurrentConfig != null)
             {
                 OnCurrentConfig(currentConfig, force);
             }
             Thread.Sleep(10);                                               // Sleep thread to optain a frequency on 100Hz
         }
     });
     configThread.IsBackground = true;
     configThread.Name         = "configThread";
     configThread.Start();
 }
Пример #13
0
 public void SetForce(ForceData fd)
 {
     force = fd;
 }
Пример #14
0
        private void SyncThreadedEnts(bool clear = false, bool client = false)
        {
            try
            {
                if (clear)
                {
                    Eject.Clear();
                    DestroyedBlocks.Clear();
                    MissileDmg.Clear();
                    MeteorDmg.Clear();
                    VoxelDmg.Clear();
                    CharacterDmg.Clear();
                    FewDmgBlocks.Clear();
                    CollidingBlocks.Clear();
                    ForceData.Clear();
                    ImpulseData.Clear();
                    return;
                }

                try
                {
                    if (!Eject.IsEmpty)
                    {
                        MyCubeGrid myGrid;
                        while (Eject.TryDequeue(out myGrid))
                        {
                            if (myGrid == null || myGrid.MarkedForClose)
                            {
                                continue;
                            }
                            myGrid.Physics.LinearVelocity *= -0.25f;
                        }
                    }
                }
                catch (Exception ex) { Log.Line($"Exception in Eject: {ex}"); }

                try
                {
                    if (!ForceData.IsEmpty)
                    {
                        MyAddForceData data;
                        while (ForceData.TryDequeue(out data))
                        {
                            var myGrid = data.MyGrid;
                            if (myGrid == null || myGrid.MarkedForClose)
                            {
                                continue;
                            }
                            myGrid.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, data.Force, null, Vector3D.Zero, data.MaxSpeed, data.Immediate);
                        }
                    }
                }
                catch (Exception ex) { Log.Line($"Exception in forceData: {ex}"); }

                try
                {
                    if (!ImpulseData.IsEmpty)
                    {
                        MyImpulseData data;
                        while (ImpulseData.TryDequeue(out data))
                        {
                            var myGrid = data.MyGrid;
                            if (myGrid == null || myGrid.MarkedForClose)
                            {
                                continue;
                            }
                            myGrid.Physics.ApplyImpulse(data.Direction, data.Position);
                        }
                    }
                }
                catch (Exception ex) { Log.Line($"Exception in impulseData: {ex}"); }

                if (client)
                {
                    return;
                }

                try
                {
                    if (!DestroyedBlocks.IsEmpty)
                    {
                        IMySlimBlock block;
                        var          nullCount = 0;
                        while (DestroyedBlocks.TryDequeue(out block))
                        {
                            var myGrid = block.CubeGrid as MyCubeGrid;
                            if (myGrid == null)
                            {
                                continue;
                            }
                            EntIntersectInfo entInfo;
                            WebEnts.TryGetValue(myGrid, out entInfo);
                            if (entInfo == null)
                            {
                                nullCount++;
                                myGrid.EnqueueDestroyedBlock(block.Position);
                                continue;
                            }

                            EntIntersectInfo entRemoved;
                            if (nullCount > 0)
                            {
                                WebEnts.TryRemove(myGrid, out entRemoved);
                            }
                            entInfo.CacheBlockList.Remove(block);
                            myGrid.EnqueueDestroyedBlock(block.Position);
                        }
                    }
                }
                catch (Exception ex) { Log.Line($"Exception in destroyedBlocks: {ex}"); }

                try
                {
                    if (!MissileDmg.IsEmpty)
                    {
                        MyEntity ent;
                        while (MissileDmg.TryDequeue(out ent))
                        {
                            if (ent == null || !ent.InScene || ent.MarkedForClose)
                            {
                                continue;
                            }
                            var computedDamage = ComputeAmmoDamage(ent);

                            var damage = computedDamage * DsState.State.ModulateKinetic;
                            if (computedDamage < 0)
                            {
                                damage = computedDamage;
                            }

                            var rayDir    = Vector3D.Normalize(ent.Physics.LinearVelocity);
                            var ray       = new RayD(ent.PositionComp.WorldVolume.Center, rayDir);
                            var intersect = CustomCollision.IntersectEllipsoid(DetectMatrixOutsideInv, DetectionMatrix, ray);
                            var hitDist   = intersect ?? 0;
                            var hitPos    = ray.Position + (ray.Direction * -hitDist);

                            if (_mpActive)
                            {
                                AddShieldHit(ent.EntityId, damage, Session.Instance.MPExplosion, null, false, hitPos);
                                ent.Close();
                                ent.InScene = false;
                            }
                            else
                            {
                                EnergyHit           = true;
                                WorldImpactPosition = hitPos;
                                Absorb    += damage;
                                ImpactSize = damage;
                                UtilsStatic.CreateFakeSmallExplosion(hitPos);
                                ent.Close();
                                ent.InScene = false;
                            }
                        }
                    }
                }
                catch (Exception ex) { Log.Line($"Exception in missileDmg: {ex}"); }

                try
                {
                    if (!MeteorDmg.IsEmpty)
                    {
                        IMyMeteor meteor;
                        while (MeteorDmg.TryDequeue(out meteor))
                        {
                            if (meteor == null || meteor.MarkedForClose || meteor.Closed)
                            {
                                continue;
                            }
                            var damage = 5000 * DsState.State.ModulateEnergy;
                            if (_mpActive)
                            {
                                AddShieldHit(meteor.EntityId, damage, Session.Instance.MPKinetic, null, false, meteor.PositionComp.WorldVolume.Center);
                                meteor.DoDamage(10000f, Session.Instance.MpIgnoreDamage, true, null, MyCube.EntityId);
                            }
                            else
                            {
                                WorldImpactPosition = meteor.PositionComp.WorldVolume.Center;
                                Absorb    += damage;
                                ImpactSize = damage;
                                meteor.DoDamage(10000f, Session.Instance.MpIgnoreDamage, true, null, MyCube.EntityId);
                            }
                        }
                    }
                }
                catch (Exception ex) { Log.Line($"Exception in missileDmg: {ex}"); }

                try
                {
                    if (!VoxelDmg.IsEmpty)
                    {
                        MyVoxelBase voxel;
                        while (VoxelDmg.TryDequeue(out voxel))
                        {
                            if (voxel == null || voxel.RootVoxel.MarkedForClose || voxel.RootVoxel.Closed)
                            {
                                continue;
                            }
                            voxel.RootVoxel.RequestVoxelOperationElipsoid(Vector3.One * 1.0f, DetectMatrixOutside, 0, MyVoxelBase.OperationType.Cut);
                        }
                    }
                }
                catch (Exception ex) { Log.Line($"Exception in missileDmg: {ex}"); }

                try
                {
                    if (!CharacterDmg.IsEmpty)
                    {
                        IMyCharacter character;
                        while (CharacterDmg.TryDequeue(out character))
                        {
                            var npcname = character.ToString();
                            if (npcname.Equals("Space_Wolf"))
                            {
                                character.Delete();
                                continue;
                            }
                            var hId            = MyCharacterOxygenComponent.HydrogenId;
                            var playerGasLevel = character.GetSuitGasFillLevel(hId);
                            character.Components.Get <MyCharacterOxygenComponent>().UpdateStoredGasLevel(ref hId, (playerGasLevel * -0.0001f) + .002f);
                            MyVisualScriptLogicProvider.CreateExplosion(character.GetPosition(), 0, 0);
                            character.DoDamage(50f, Session.Instance.MpIgnoreDamage, true, null, MyCube.EntityId);
                            var vel = character.Physics.LinearVelocity;
                            if (vel == new Vector3D(0, 0, 0))
                            {
                                vel = MyUtils.GetRandomVector3Normalized();
                            }
                            var speedDir        = Vector3D.Normalize(vel);
                            var rnd             = new Random();
                            var randomSpeed     = rnd.Next(10, 20);
                            var additionalSpeed = vel + (speedDir * randomSpeed);
                            character.Physics.LinearVelocity = additionalSpeed;
                        }
                    }
                }
                catch (Exception ex) { Log.Line($"Exception in missileDmg: {ex}"); }

                try
                {
                    if (!CollidingBlocks.IsEmpty)
                    {
                        IMySlimBlock block;
                        var          damageMulti = 350;
                        if (ShieldMode == ShieldType.Station && DsState.State.Enhancer)
                        {
                            damageMulti = 10000;
                        }
                        while (CollidingBlocks.TryDequeue(out block))
                        {
                            if (block == null)
                            {
                                continue;
                            }
                            var myGrid = block.CubeGrid as MyCubeGrid;
                            if (block.IsDestroyed)
                            {
                                myGrid.EnqueueDestroyedBlock(block.Position);
                                continue;
                            }
                            block.DoDamage(damageMulti, Session.Instance.MpIgnoreDamage, true, null, MyCube.EntityId);
                            if (myGrid.BlocksCount == 0)
                            {
                                myGrid.SendGridCloseRequest();
                            }
                        }
                    }
                }
                catch (Exception ex) { Log.Line($"Exception in dmgBlocks: {ex}"); }

                try
                {
                    if (!FewDmgBlocks.IsEmpty)
                    {
                        IMySlimBlock block;
                        while (FewDmgBlocks.TryDequeue(out block))
                        {
                            if (block == null)
                            {
                                continue;
                            }
                            var myGrid = block.CubeGrid as MyCubeGrid;

                            if (block.IsDestroyed)
                            {
                                myGrid.EnqueueDestroyedBlock(block.Position);
                                myGrid.Close();
                                continue;
                            }
                            block.DoDamage(block.MaxIntegrity * 0.9f, Session.Instance.MpIgnoreDamage, true, null, MyCube.EntityId);
                            if (myGrid.BlocksCount == 0)
                            {
                                myGrid.SendGridCloseRequest();
                            }
                        }
                    }
                }
                catch (Exception ex) { Log.Line($"Exception in fewBlocks: {ex}"); }

                try
                {
                    if (Session.Instance.EmpWork.EventRunning && Vector3D.DistanceSquared(DetectionCenter, Session.Instance.EmpWork.EpiCenter) <= Session.Instance.EmpWork.RangeCapSqr)
                    {
                        var        empResistenceRatio    = 1f;
                        const long AttackerId            = 0L;
                        var        energyResistenceRatio = DsState.State.ModulateKinetic;
                        var        epiCenter             = Session.Instance.EmpWork.EpiCenter;
                        var        rangeCap    = Session.Instance.EmpWork.RangeCap;
                        var        empDirYield = Session.Instance.EmpWork.DirYield;

                        if (DsState.State.EmpProtection)
                        {
                            if (energyResistenceRatio < 0.4)
                            {
                                energyResistenceRatio = 0.4f;
                            }
                            empResistenceRatio = 0.1f;
                        }
                        //if (Session.Enforced.Debug >= 2) Log.Line($"[EmpBlastShield - Start] ShieldOwner:{MyGrid.DebugName} - Yield:{warHeadYield} - StackCount:{stackCount} - ProtectionRatio:{energyResistenceRatio * empResistenceRatio} - epiCenter:{epiCenter}");
                        var line      = new LineD(epiCenter, SOriBBoxD.Center);
                        var testDir   = Vector3D.Normalize(line.From - line.To);
                        var ray       = new RayD(line.From, -testDir);
                        var ellipsoid = CustomCollision.IntersectEllipsoid(DetectMatrixOutsideInv, DetectionMatrix, ray);
                        if (!ellipsoid.HasValue)
                        {
                            //if (Session.Enforced.Debug >= 2) Log.Line($"[EmpBlastShield - Ellipsoid null hit] ShieldOwner:{MyGrid.DebugName} - Yield:{warHeadYield} - StackCount:{stackCount} - ProtectionRatio:{energyResistenceRatio * empResistenceRatio} - epiCenter:{epiCenter}");
                            return;
                        }
                        var      impactPos = line.From + (testDir * -ellipsoid.Value);
                        IHitInfo hitInfo;
                        MyAPIGateway.Physics.CastRay(epiCenter, impactPos, out hitInfo, CollisionLayers.DefaultCollisionLayer);
                        if (hitInfo != null)
                        {
                            //if (Session.Enforced.Debug >= 2) Log.Line($"[EmpBlastShield - occluded] ShieldOwner:{MyGrid.DebugName} - by {((MyEntity)hitInfo.HitEntity).DebugName}");
                            return;
                        }
                        var gridLocalMatrix    = MyGrid.PositionComp.LocalMatrix;
                        var worldDirection     = impactPos - gridLocalMatrix.Translation;
                        var localPosition      = Vector3D.TransformNormal(worldDirection, MatrixD.Transpose(gridLocalMatrix));
                        var hitFaceSurfaceArea = UtilsStatic.GetIntersectingSurfaceArea(ShieldShapeMatrix, localPosition);

                        var invSqrDist   = UtilsStatic.InverseSqrDist(epiCenter, impactPos, rangeCap);
                        var damageScaler = invSqrDist * hitFaceSurfaceArea;
                        if (invSqrDist <= 0)
                        {
                            //if (Session.Enforced.Debug >= 2) Log.Line($"[EmpBlastShield - Range] ShieldOwner:{MyGrid.DebugName} - insqrDist was 0");
                            return;
                        }

                        var targetDamage = (float)(((empDirYield * damageScaler) * energyResistenceRatio) * empResistenceRatio);

                        if (targetDamage >= DsState.State.Charge * ConvToHp)
                        {
                            _empOverLoad = true;
                        }
                        //if (Session.Enforced.Debug >= 2) Log.Line($"-----------------------] epiDist:{Vector3D.Distance(epiCenter, impactPos)} - iSqrDist:{invSqrDist} - RangeCap:{rangeCap} - SurfaceA:{hitFaceSurfaceArea}({_ellipsoidSurfaceArea * 0.5}) - dirYield:{empDirYield} - damageScaler:{damageScaler} - Damage:{targetDamage}(toOver:{(targetDamage / (DsState.State.Charge * ConvToHp))})");

                        if (_isServer && _mpActive)
                        {
                            AddEmpBlastHit(AttackerId, targetDamage, Session.Instance.MPEMP, impactPos);
                        }

                        EnergyHit           = true;
                        WorldImpactPosition = epiCenter;
                        Absorb += targetDamage;
                    }
                }
                catch (Exception ex) { Log.Line($"Exception in EmpBlast: {ex}"); }
            }
            catch (Exception ex) { Log.Line($"Exception in DamageGrids: {ex}"); }
        }
Пример #15
0
 public static void SetPlayers(this ForceData force, params PlayerData[] players)
 {
     force.Players = new Bitmask32(players.Select(player => player.Id).ToArray());
 }
Пример #16
0
        private void BlockIntersect(MyCubeGrid breaching, MyOrientedBoundingBoxD bOriBBoxD, EntIntersectInfo entInfo)
        {
            var collisionAvg = Vector3D.Zero;
            var transformInv = DetectMatrixOutsideInv;
            var normalMat    = MatrixD.Transpose(transformInv);
            var damageBlocks = Session.Enforced.DisableBlockDamage == 0;

            var blockDmgNum = 5;

            if (ShieldMode == ShieldType.Station && DsState.State.Enhancer)
            {
                blockDmgNum = 50;
            }
            var intersection = bOriBBoxD.Intersects(ref SOriBBoxD);

            try
            {
                if (intersection)
                {
                    var      cacheBlockList = entInfo.CacheBlockList;
                    var      bPhysics       = ((IMyCubeGrid)breaching).Physics;
                    var      sPhysics       = Shield.CubeGrid.Physics;
                    var      sGrid          = (MyCubeGrid)Shield.CubeGrid;
                    var      bMass          = breaching.GetCurrentMass();
                    var      sMass          = sGrid.GetCurrentMass();
                    var      momentum       = (bMass * bPhysics.LinearVelocity) + (sMass * sPhysics.LinearVelocity);
                    var      resultVelocity = momentum / (bMass + sMass);
                    Vector3D bBlockCenter;
                    var      stale     = false;
                    var      rawDamage = 0f;
                    var      blockSize = breaching.GridSize;
                    var      gc        = breaching.WorldToGridInteger(DetectionCenter);
                    var      rc        = ShieldSize.AbsMax() / blockSize;
                    rc *= rc;
                    rc  = rc + 1;
                    rc  = Math.Ceiling(rc);
                    var hits        = 0;
                    var blockPoints = new Vector3D[9];
                    for (int i = 0; i < cacheBlockList.Count; i++)
                    {
                        var block    = cacheBlockList[i];
                        var blockPos = block.Position;
                        var num1     = gc.X - blockPos.X;
                        var num2     = gc.Y - blockPos.Y;
                        var num3     = gc.Z - blockPos.Z;
                        var result   = (num1 * num1) + (num2 * num2) + (num3 * num3);

                        if (_isServer)
                        {
                            if (result > rc)
                            {
                                continue;
                            }
                            if (damageBlocks && block.IsDestroyed)
                            {
                                DestroyedBlocks.Enqueue(block);
                                continue;
                            }
                            if (block.CubeGrid != breaching)
                            {
                                stale = true;
                                continue;
                            }
                        }
                        else
                        {
                            if (hits > blockDmgNum)
                            {
                                break;
                            }
                            if (result > rc || block.IsDestroyed || block.CubeGrid != breaching)
                            {
                                continue;
                            }
                        }
                        BoundingBoxD blockBox;
                        block.GetWorldBoundingBox(out blockBox);

                        blockBox.GetCorners(blockPoints);
                        blockPoints[8] = blockBox.Center;
                        for (int j = 8; j > -1; j--)
                        {
                            var point = blockPoints[j];
                            if (Vector3.Transform(point, DetectMatrixOutsideInv).LengthSquared() > 1)
                            {
                                continue;
                            }
                            collisionAvg += point;
                            hits++;
                            if (!_isServer)
                            {
                                break;
                            }

                            if (!damageBlocks)
                            {
                                if (hits > blockDmgNum)
                                {
                                    break;
                                }
                            }
                            else if (CollidingBlocks.Count > blockDmgNum)
                            {
                                break;
                            }

                            rawDamage += MathHelper.Clamp(block.Integrity, 0, 350);
                            if (damageBlocks)
                            {
                                CollidingBlocks.Enqueue(block);
                            }
                            break;
                        }
                    }

                    entInfo.MarkForClose = stale;

                    if (collisionAvg != Vector3D.Zero)
                    {
                        collisionAvg /= hits;

                        if (sPhysics.IsStatic && !bPhysics.IsStatic)
                        {
                            var bLSpeed    = bPhysics.LinearVelocity;
                            var bASpeed    = bPhysics.AngularVelocity * 100;
                            var bLSpeedLen = bLSpeed.Length();
                            var bASpeedLen = bASpeed.Length();
                            bASpeedLen = MathHelper.Clamp(bASpeedLen, 0, 50);
                            var bSpeedLen   = bLSpeedLen > bASpeedLen ? bLSpeedLen : bASpeedLen;
                            var surfaceMass = (bMass > sMass) ? sMass : bMass;

                            var surfaceMulti  = (hits > 5) ? 5 : hits;
                            var localNormal   = Vector3D.Transform(collisionAvg, transformInv);
                            var surfaceNormal = Vector3D.Normalize(Vector3D.TransformNormal(localNormal, normalMat));

                            var impulseData1 = new MyImpulseData {
                                MyGrid = breaching, Direction = (resultVelocity - bLSpeed) * bMass, Position = bPhysics.CenterOfMassWorld
                            };
                            var impulseData2 = new MyImpulseData {
                                MyGrid = breaching, Direction = surfaceMulti * (surfaceMass * 0.025) * -Vector3D.Dot(bLSpeed, surfaceNormal) * surfaceNormal, Position = collisionAvg
                            };
                            var forceData = new MyAddForceData {
                                MyGrid = breaching, Force = (bPhysics.CenterOfMassWorld - collisionAvg) * (bMass * bSpeedLen), MaxSpeed = MathHelper.Clamp(bSpeedLen, 1f, bSpeedLen * 0.5f)
                            };
                            ImpulseData.Enqueue(impulseData1);
                            ImpulseData.Enqueue(impulseData2);
                            ForceData.Enqueue(forceData);
                        }
                        else
                        {
                            var bLSpeed    = bPhysics.LinearVelocity;
                            var bASpeed    = bPhysics.AngularVelocity * 100;
                            var bLSpeedLen = bLSpeed.Length();
                            var bASpeedLen = bASpeed.Length();
                            bASpeedLen = MathHelper.Clamp(bASpeedLen, 0, 50);
                            var   bSpeedLen = bLSpeedLen > bASpeedLen ? bLSpeedLen : bASpeedLen;
                            float?speed;


                            if (!bPhysics.IsStatic)
                            {
                                var bImpulseData = new MyImpulseData {
                                    MyGrid = breaching, Direction = (resultVelocity - bLSpeed) * bMass, Position = bPhysics.CenterOfMassWorld
                                };
                                ImpulseData.Enqueue(bImpulseData);
                            }

                            if (!sPhysics.IsStatic)
                            {
                                var sImpulseData = new MyImpulseData {
                                    MyGrid = sGrid, Direction = (resultVelocity - sPhysics.LinearVelocity) * sMass, Position = sPhysics.CenterOfMassWorld
                                };
                                ImpulseData.Enqueue(sImpulseData);
                            }

                            if (!sPhysics.IsStatic)
                            {
                                if (bMass / sMass > 20)
                                {
                                    speed = MathHelper.Clamp(bSpeedLen, 1f, bSpeedLen * 0.5f);
                                }
                                else
                                {
                                    speed = null;
                                }

                                var sForceData = new MyAddForceData {
                                    MyGrid = sGrid, Force = (sPhysics.CenterOfMassWorld - collisionAvg) * bMass, MaxSpeed = speed
                                };
                                ForceData.Enqueue(sForceData);
                            }

                            if (!bPhysics.IsStatic)
                            {
                                if (sMass / bMass > 20)
                                {
                                    speed = MathHelper.Clamp(bSpeedLen, 1f, bSpeedLen * 0.5f);
                                }
                                else
                                {
                                    speed = null;
                                }

                                var bForceData = new MyAddForceData {
                                    MyGrid = breaching, Force = (bPhysics.CenterOfMassWorld - collisionAvg) * sMass, MaxSpeed = speed
                                };
                                ForceData.Enqueue(bForceData);
                            }
                        }
                        WebDamage    = true;
                        bBlockCenter = collisionAvg;
                    }
                    else
                    {
                        return;
                    }
                    if (!_isServer)
                    {
                        return;
                    }

                    var damage = rawDamage * DsState.State.ModulateEnergy;

                    entInfo.Damage = damage;
                    if (_mpActive)
                    {
                        if (_isServer && bBlockCenter != Vector3D.NegativeInfinity)
                        {
                            AddShieldHit(breaching.EntityId, damage, Session.Instance.MPKinetic, null, false, collisionAvg);
                        }
                    }
                    else
                    {
                        if (bBlockCenter != Vector3D.NegativeInfinity)
                        {
                            entInfo.ContactPoint = bBlockCenter;
                            ImpactSize           = entInfo.Damage;

                            entInfo.Damage      = 0;
                            entInfo.EmpSize     = 0;
                            WorldImpactPosition = bBlockCenter;
                        }
                    }
                    Absorb += damage;
                }
            }
            catch (Exception ex) { Log.Line($"Exception in BlockIntersect: {ex}"); }
        }
Пример #17
0
        private void ShieldIntersect(MyEntity ent)
        {
            var grid = ent as MyCubeGrid;

            if (grid == null)
            {
                return;
            }

            if (GridInside(grid, MyOrientedBoundingBoxD.CreateFromBoundingBox(grid.PositionComp.WorldAABB)))
            {
                return;
            }
            ShieldGridComponent shieldComponent;

            grid.Components.TryGet(out shieldComponent);
            if (shieldComponent?.DefenseShields == null)
            {
                return;
            }

            var ds = shieldComponent.DefenseShields;

            if (!ds.WasOnline)
            {
                EntIntersectInfo entInfo;
                WebEnts.TryRemove(ent, out entInfo);
            }
            var dsVerts     = ds.ShieldComp.PhysicsOutside;
            var dsMatrixInv = ds.DetectMatrixOutsideInv;
            var myGrid      = Shield.CubeGrid;

            var insidePoints = new List <Vector3D>();

            if (_isServer)
            {
                CustomCollision.ShieldX2PointsInside(dsVerts, dsMatrixInv, ShieldComp.PhysicsOutside, DetectMatrixOutsideInv, insidePoints);
            }
            else
            {
                CustomCollision.ClientShieldX2PointsInside(dsVerts, dsMatrixInv, ShieldComp.PhysicsOutsideLow, DetectMatrixOutsideInv, insidePoints);
            }

            var bPhysics = ((IMyCubeGrid)grid).Physics;
            var sPhysics = myGrid.Physics;

            var bMass = grid.GetCurrentMass();
            var sMass = ((MyCubeGrid)myGrid).GetCurrentMass();

            if (bMass <= 0)
            {
                bMass = int.MaxValue;
            }
            if (sMass <= 0)
            {
                sMass = int.MaxValue;
            }

            var bVel           = bPhysics.LinearVelocity;
            var bVelLen        = bVel.Length();
            var momentum       = (bMass * bVel) + (sMass * sPhysics.LinearVelocity);
            var resultVelocity = momentum / (bMass + sMass);

            var collisionAvg      = Vector3D.Zero;
            var numOfPointsInside = insidePoints.Count;

            for (int i = 0; i < numOfPointsInside; i++)
            {
                collisionAvg += insidePoints[i];
            }

            collisionAvg /= numOfPointsInside;

            if (numOfPointsInside > 0 && !bPhysics.IsStatic)
            {
                var ejectorAccel = numOfPointsInside > 10 ? numOfPointsInside : 10;
                var impulseData  = new MyImpulseData {
                    MyGrid = grid, Direction = (resultVelocity - bVel) * bMass, Position = bPhysics.CenterOfMassWorld
                };
                var forceData = new MyAddForceData {
                    MyGrid = grid, Force = (bPhysics.CenterOfMassWorld - collisionAvg) * bMass * ejectorAccel, MaxSpeed = MathHelper.Clamp(bVelLen, 1f, 50f)
                };
                ImpulseData.Enqueue(impulseData);
                ForceData.Enqueue(forceData);
            }
            if (!_isServer || numOfPointsInside <= 0)
            {
                return;
            }

            var shieldMaxChargeRate = ds._shieldMaxChargeRate;
            var damage = ((shieldMaxChargeRate * ConvToHp) * DsState.State.ModulateKinetic) * 0.01666666666f;

            if (_mpActive)
            {
                if (_isServer)
                {
                    AddShieldHit(ds.Shield.EntityId, damage, Session.Instance.MPEnergy, null, false, collisionAvg);
                }
            }
            else
            {
                EnergyHit           = true;
                WorldImpactPosition = collisionAvg;

                ds.EnergyHit           = true;
                ds.WorldImpactPosition = collisionAvg;

                Absorb    += damage;
                ImpactSize = damage;
                WebDamage  = true;
            }
        }
Пример #18
0
 public static void Write(this BinaryWriter writer, ForceData forceData, MapInfoFormatVersion formatVersion) => forceData.WriteTo(writer, formatVersion);