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; }
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; } }
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; }
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); } } }
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); }
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(); }
/// <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(); }
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; }
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); }
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; }
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); }
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); }
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); }
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); }
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); } }
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; } } } } } }
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); } } }
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); } }
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; }
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(); }
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); }
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); } } } } }
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); }
/// <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); }
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); }
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; } }
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); }
/// <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); }
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; }
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); } } }