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); }); }
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); }
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; }
/// <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); }
/// <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); }
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); }
/// <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(); }
public void SetForce(ForceData fd) { force = fd; }
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}"); } }
public static void SetPlayers(this ForceData force, params PlayerData[] players) { force.Players = new Bitmask32(players.Select(player => player.Id).ToArray()); }
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}"); } }
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; } }
public static void Write(this BinaryWriter writer, ForceData forceData, MapInfoFormatVersion formatVersion) => forceData.WriteTo(writer, formatVersion);