private void GetHitEntityAndPosition(LineD line, out IMyEntity entity, out Vector3D hitPosition, out Vector3 hitNormal) { entity = null; hitPosition = hitNormal = Vector3.Zero; VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyEntities.GetIntersectionWithLine()"); m_intersection = MyEntities.GetIntersectionWithLine(ref line, m_ignoreEntity, m_weapon, false, false, true, IntersectionFlags.ALL_TRIANGLES, MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * CHECK_INTERSECTION_INTERVAL); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); if (m_intersection != null) { entity = m_intersection.Value.Entity; hitPosition = m_intersection.Value.IntersectionPointInWorldSpace; hitNormal = m_intersection.Value.NormalInWorldSpace; } if (entity == null) { var hitRigidBody = MyPhysics.CastRay(line.From, line.To, out hitPosition, out hitNormal); entity = hitRigidBody.GetEntity() as MyEntity; } if (entity == null) { return; } if (!(entity is MyCharacter)) { entity = entity.GetTopMostParent(); } }
private static bool IsTargetVisible(MySmallShip smallShip, MyEntity otherEntity) { MyLine line = new MyLine(smallShip.WorldVolume.Center, otherEntity.GetPosition(), true); MyIntersectionResultLineTriangleEx?result = MyEntities.GetIntersectionWithLine(ref line, smallShip, null, ignoreChilds: true); return(result != null && result.Value.Entity.GetBaseEntity() == otherEntity); }
public void DrawLocationMarkers(MyHudLocationMarkers locationMarkers) { ProfilerShort.Begin("MyHudMarkerRender.DrawLocationMarkers"); m_sortedMarkers.Clear(); foreach (var entityMarker in locationMarkers.MarkerEntities) { m_sortedMarkers.Add(entityMarker.Value); } m_sortedMarkers.Sort(m_distanceComparer); foreach (var entityMarker in m_sortedMarkers) { MyEntity entity = entityMarker.Entity; if (entityMarker.ShouldDraw != null && !entityMarker.ShouldDraw()) { continue; } float distance = (float)(MySector.MainCamera.Position - entity.PositionComp.WorldVolume.Center).Length(); if ((entityMarker.TargetMode == MyRelationsBetweenPlayerAndBlock.NoOwnership || entityMarker.TargetMode == MyRelationsBetweenPlayerAndBlock.FactionShare) && m_friendAntennaRange < distance) { continue; } if ((entityMarker.TargetMode == MyRelationsBetweenPlayerAndBlock.Neutral || entityMarker.TargetMode == MyRelationsBetweenPlayerAndBlock.Enemies) && m_enemyAntennaRange < distance) { continue; } if (entityMarker.TargetMode == MyRelationsBetweenPlayerAndBlock.Owner && m_ownerAntennaRange < distance) { continue; } if (entityMarker.MustBeDirectlyVisible) { LineD raycast = new LineD(MySector.MainCamera.Position, (Vector3)entity.PositionComp.WorldVolume.Center); raycast.From += raycast.Direction; var result = MyEntities.GetIntersectionWithLine(ref raycast, entity, MySession.ControlledEntity as MyEntity); if (result.HasValue && !(result.Value.Entity == entity || result.Value.Entity.Parent == entity || result.Value.Entity == entity.Parent)) { continue; } } DrawLocationMarker( GetStyleForRelation(entityMarker.TargetMode), entity.LocationForHudMarker, entityMarker, 0, 0); } m_hudScreen.DrawTexts(); ProfilerShort.End(); }
public MyIntersectionResultLineTriangleEx?Intersect() { float maxDist = 200; MyLine line = new MyLine(MyCamera.Position, MyCamera.Position + MyCamera.ForwardVector * maxDist); var result = MyEntities.GetIntersectionWithLine(ref line, MySession.PlayerShip, null, true, true, false, false, true); return(result); }
private void DebugDrawVertexNames() { //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(10, 0), "Voxel names searching", Color.Yellow, 0.5f); LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * 500); VRage.Game.Models.MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, MySession.Static.LocalCharacter, null, false, true, true, VRage.Game.Components.IntersectionFlags.ALL_TRIANGLES, 0, false); if (intersection.HasValue) { if (intersection.Value.Entity is MyVoxelBase) { MyVoxelBase voxels = intersection.Value.Entity as MyVoxelBase; Vector3D point = intersection.Value.IntersectionPointInWorldSpace; if (intersection.Value.Entity is MyPlanet) { VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Type: planet/moon", Color.Yellow, 0.5f); VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 30), "Terrain: " + voxels.GetMaterialAt(ref point).ToString(), Color.Yellow, 0.5f); } else { VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Type: asteroid", Color.Yellow, 0.5f); VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 30), "Terrain: " + voxels.GetMaterialAt(ref point).ToString(), Color.Yellow, 0.5f); } VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 40), "Object size: " + voxels.SizeInMetres.ToString(), Color.Yellow, 0.5f); //location /* * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 50), "Location:", Color.Yellow, 0.5f); * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 60), "x " + Math.Round(point.X, 3).ToString(), Color.Yellow, 0.5f); * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 70), "y " + Math.Round(point.Y, 3).ToString(), Color.Yellow, 0.5f); * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 80), "z " + Math.Round(point.Z, 3).ToString(), Color.Yellow, 0.5f);*/ } else if (intersection.Value.Entity is MyCubeGrid) { VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Detected grid object", Color.Yellow, 0.5f); VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 30), "Grid name: " + intersection.Value.Entity.DisplayName.ToString(), Color.Yellow, 0.5f); int row = 4; MyCubeGrid grid = intersection.Value.Entity as MyCubeGrid; VRage.Game.Models.MyIntersectionResultLineTriangleEx?t = null; MySlimBlock block = null; if (grid.GetIntersectionWithLine(ref line, out t, out block) && t.HasValue && block != null) { DebugDrawModelTextures(block.FatBlock, ref row); } } else { VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Unknown object detected", Color.Yellow, 0.5f); } } else { VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Nothing detected nearby", Color.Yellow, 0.5f); } }
private static bool IsLookAtTarget(MySmallShip smallShip, MyEntity otherEntity) { if (!MUST_LOOK_AT_TARGET || MySession.Is25DSector) { return(true); } float length = Vector3.Distance(smallShip.WorldVolume.Center, otherEntity.WorldVolume.Center); MyLine line = new MyLine(smallShip.WorldVolume.Center, smallShip.WorldVolume.Center + smallShip.WorldMatrix.Forward * length * 1.5f, true); MyIntersectionResultLineTriangleEx?result = MyEntities.GetIntersectionWithLine(ref line, smallShip, null, ignoreChilds: true); return(result != null && result.Value.Entity.GetBaseEntity() == otherEntity); }
/// <summary> /// Check if the missile does not collide too close to ship /// after shooting and correct its starting position if it does. /// </summary> private Vector3 CorrectPosition(Vector3 position, Vector3 direction, MyEntity viewerEntity) { var predictedTrajectory = new MyLine( position - MyMissileConstants.DISTANCE_TO_CHECK_MISSILE_CORRECTION * direction, position + MyMissileConstants.DISTANCE_TO_CHECK_MISSILE_CORRECTION * direction, false); var intersection = MyEntities.GetIntersectionWithLine(ref predictedTrajectory, this, viewerEntity); if (intersection != null) { position = viewerEntity.GetPosition(); } return(position); }
private void UpdateTargetVisibility(MySmallShipBot bot) { if (locationVisibleCheckTimer <= 0) { MyLine line = new MyLine(bot.GetPosition(), location, true); var result = MyEntities.GetIntersectionWithLine(ref line, bot, null, true, ignoreChilds: true); locationVisible = !result.HasValue; locationVisibleCheckTimer = 0.25f; } else { locationVisibleCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; } }
private static void ComputeMaxDistance(MySunWindBillboardSmall billboard) { Vector3D vectord = -m_directionFromSunNormalized * 30000.0; LineD line = new LineD(((m_directionFromSunNormalized * 30000.0) + billboard.InitialAbsolutePosition) + vectord, billboard.InitialAbsolutePosition + (m_directionFromSunNormalized * 60000.0)); MyIntersectionResultLineTriangleEx?nullable = MyEntities.GetIntersectionWithLine(ref line, null, null, false, true, true, IntersectionFlags.ALL_TRIANGLES, 0f, true); if (nullable != null) { billboard.MaxDistance = nullable.Value.Triangle.Distance - billboard.Radius; } else { billboard.MaxDistance = 60000f; } }
private void UpdateTargetVisibility(MySmallShipBot bot) { if (m_target != null && m_visibilityCheckTimer <= 0) { Debug.Assert(!m_target.Closed); MyLine line = new MyLine(bot.GetPosition(), m_target.GetPosition(), true); var result = MyEntities.GetIntersectionWithLine(ref line, bot, m_target, true, ignoreChilds: true); m_targetVisible = !result.HasValue; m_visibilityCheckTimer = 0.25f; } else { m_visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; } }
public virtual void DrawLocationMarkers(MyHudLocationMarkers locationMarkers) { ProfilerShort.Begin("MyHudMarkerRender.DrawLocationMarkers"); m_sortedMarkers.Clear(); foreach (var entityMarker in locationMarkers.MarkerEntities) { if (entityMarker.Value.Entity.PositionComp == null) //to draw marker entity must have position { continue; } m_sortedMarkers.Add(entityMarker.Value); } m_sortedMarkers.Sort(m_distanceComparer); foreach (var entityMarker in m_sortedMarkers) { MyEntity entity = entityMarker.Entity as MyEntity; if (entityMarker.ShouldDraw != null && !entityMarker.ShouldDraw()) { continue; } if (entityMarker.MustBeDirectlyVisible) { LineD raycast = new LineD(MySector.MainCamera.Position, (Vector3)entity.PositionComp.WorldVolume.Center); raycast.From += raycast.Direction; var result = MyEntities.GetIntersectionWithLine(ref raycast, entity, MySession.Static.ControlledEntity as MyEntity); if (result.HasValue && !(result.Value.Entity == entity || result.Value.Entity.Parent == entity || result.Value.Entity == entity.Parent)) { continue; } } DrawLocationMarker( GetStyleForRelation(entityMarker.TargetMode), entity.LocationForHudMarker, entityMarker, 0, 0); } m_hudScreen.DrawTexts(); ProfilerShort.End(); }
/// <summary> /// Chceck if ship can see target /// </summary> /// <param name="position">Target position</param> /// <param name="target">Target entity.</param> /// <returns>True, if bot can see position.</returns> public static MyEntity CanSee(MyEntity source, Vector3 position, MyEntity ignoreEntity) { MyIntersectionResultLineTriangleEx?result = null; MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MySmallShip CanSee"); //There is 100 multiplier because Epsilon can get lost during transformation inside GetAllIntersectionWithLine //and normalization assert then appears if ((source.GetPosition() - position).Length() > MyMwcMathConstants.EPSILON * 100.0f) { var line = new MyLine(source.GetPosition(), position, true); result = MyEntities.GetIntersectionWithLine(ref line, source, ignoreEntity, ignoreChilds: true); } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); return(result.HasValue ? result.Value.Entity : null); }
private static void ComputeMaxDistance(MySunWindBillboardSmall billboard) { Vector3 sunWindVector = m_directionFromSunNormalized * MySunWindConstants.SUN_WIND_LENGTH_HALF; var offset = (-m_directionFromSunNormalized * MySunWindConstants.RAY_CAST_DISTANCE); // This line start where billboard starts and end at place that is farest possible place billboard can reach // If intersection found, we will mark that place as small billboard's destination. It can't go further. LineD line = new LineD((sunWindVector + billboard.InitialAbsolutePosition) + offset, billboard.InitialAbsolutePosition + m_directionFromSunNormalized * MySunWindConstants.SUN_WIND_LENGTH_TOTAL); MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, null, null); if (intersection != null) { billboard.MaxDistance = (float)(intersection.Value.Triangle.Distance - billboard.Radius); } else { billboard.MaxDistance = MySunWindConstants.SUN_WIND_LENGTH_TOTAL; } }
public void DoWork() { try { MyEntities.EntityCloseLock.AcquireShared(); if (m_bot == null) { return; } BoundingSphere boundingSphere = new BoundingSphere(m_position, m_bot.WorldVolume.Radius * 2.0f); if (MyEntities.GetIntersectionWithSphere(ref boundingSphere) != null) { return; } Matrix transform = Matrix.CreateWorld(m_position, MyMwcUtils.Normalize(m_targetPosition - m_position), m_up); float distanceToRoutePoint = Vector3.Dot(m_targetPosition - m_position, transform.Forward); for (int i = 0; i < m_points.Length; i++) { Vector3 transformedPoint = Vector3.Transform(m_points[i], transform); MyLine line = new MyLine(transformedPoint, transformedPoint + transform.Forward * distanceToRoutePoint, true); var result = MyEntities.GetIntersectionWithLine(ref line, m_bot, null, true); if (result.HasValue) { // Collision detected return; } } Result = m_position; } finally { if (m_bot != null) { m_bot.OnClose -= m_bot_OnClose; } MyEntities.EntityCloseLock.ReleaseShared(); } }
private void DebugDrawGeneratingBlock() { LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * 200); MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, MySession.LocalCharacter, null); if (intersection.HasValue && intersection.Value.Entity is MyCubeGrid) { MyCubeGrid grid = intersection.Value.Entity as MyCubeGrid; MyIntersectionResultLineTriangleEx?t = null; MySlimBlock block = null; if (grid.GetIntersectionWithLine(ref line, out t, out block) && t.HasValue && block != null) { if (block.BlockDefinition.IsGeneratedBlock) { DebugDrawGeneratingBlock(block); } } } }
private void GetHitEntityAndPosition(LineD line, out IMyEntity entity, out Vector3D hitPosition, out Vector3 hitNormal, out bool hitHead) { entity = null; hitPosition = hitNormal = Vector3.Zero; hitHead = false; VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyEntities.GetIntersectionWithLine()"); m_intersection = MyEntities.GetIntersectionWithLine(ref line, m_ignoreEntity, m_weapon, false, false, true, IntersectionFlags.ALL_TRIANGLES, MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * CHECK_INTERSECTION_INTERVAL); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); if (m_intersection != null) { entity = m_intersection.Value.Entity; hitPosition = m_intersection.Value.IntersectionPointInWorldSpace; hitNormal = m_intersection.Value.NormalInWorldSpace; } if (entity == null) { var hitInfo = MyPhysics.CastRay(line.From, line.To); if (hitInfo.HasValue) { entity = hitInfo.Value.HkHitInfo.GetHitEntity() as MyEntity; hitPosition = hitInfo.Value.Position; hitNormal = hitInfo.Value.HkHitInfo.Normal; } } if (entity == null) { return; } if (m_projectileAmmoDefinition.HeadShot && entity is MyCharacter) { MyCharacter hitCharacter = entity as MyCharacter; MyIntersectionResultLineTriangleEx?t; hitCharacter.GetIntersectionWithLine(ref line, out t, out hitHead); } if (!(entity is MyCharacter)) { entity = entity.GetTopMostParent(); } }
/// <summary> /// GetIntersectedEntity /// </summary> /// <returns></returns> private MyEntity GetIntersectedEntity() { MyLine mouseSelectionLine = MyUtils.ConvertMouseToLine(); var result = MyEntities.GetIntersectionWithLine(ref mouseSelectionLine, null, null); MyEntity entity = result.HasValue ? result.Value.Entity : null; if (entity is MyLargeShipGunBase) { entity = ((MyLargeShipGunBase)entity).PrefabParent; } if (m_bEnableAABBUnderMouse) { m_physOverlapElemList.Clear(); MyEntities.GetIntersectedElements(ref mouseSelectionLine, m_physOverlapElemList); } return(entity); }
private static bool IsCustomLookAtTarget(MySmallShip smallShip, MyEntity otherEntity, float radius) { if (!MUST_LOOK_AT_TARGET) { return(true); } BoundingSphere sphere = new BoundingSphere(otherEntity.WorldVolume.Center, radius); Ray ray = new Ray(smallShip.GetPosition(), smallShip.WorldMatrix.Forward); float? rayIntersection = ray.Intersects(sphere); if (rayIntersection.HasValue) { MyLine line = new MyLine(smallShip.WorldVolume.Center, otherEntity.WorldVolume.Center, true); MyIntersectionResultLineTriangleEx?result = MyEntities.GetIntersectionWithLine(ref line, smallShip, null, ignoreChilds: true); return(!result.HasValue || !result.HasValue || result.Value.Entity == otherEntity); } return(false); }
private void DebugDrawModelTextures() { LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * 200); MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, MySession.LocalCharacter, null); if (intersection.HasValue) { int row = 0; if (intersection.Value.Entity is MyCubeGrid) { MyCubeGrid grid = intersection.Value.Entity as MyCubeGrid; MyIntersectionResultLineTriangleEx?t = null; MySlimBlock block = null; if (grid.GetIntersectionWithLine(ref line, out t, out block) && t.HasValue && block != null) { DebugDrawModelTextures(block.FatBlock, ref row); } } } }
private void UpdateVisibility(MySmallShipBot bot, Vector3 targetPosition) { if (m_visibilityCheckTimer <= 0) { if (bot.GetPosition() == targetPosition) { m_targetVisible = true; } else { MyLine line = new MyLine(bot.GetPosition(), targetPosition, true); var result = MyEntities.GetIntersectionWithLine(ref line, bot, null, true, ignoreChilds: true); m_targetVisible = !result.HasValue; } m_visibilityCheckTimer = 0.5f; } else { m_visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; } }
void AssignBotTargets() { MyEntity transporterShip = MyScriptWrapper.TryGetEntity((uint)EntityID.TransporterShip); if (transporterShip != null) { for (int i = m_attackerBots.Count - 1; i >= 0; i--) { var bot = m_attackerBots[i]; MyLine line = new MyLine(bot.GetPosition(), transporterShip.GetPosition(), true); var result = MyEntities.GetIntersectionWithLine(ref line, bot, transporterShip, true, ignoreChilds: true); if (!result.HasValue) { bot.Attack(transporterShip); bot.SpeedModifier = 0; m_attackerWaitingForPass.Add(bot); m_attackerBots.RemoveAt(i); } } } }
// Update position, check collisions, etc. // Return false if projectile dies/timeouts in this tick. public bool Update() { // Projectile was killed , but still not last time drawn, so we don't need to do update (we are waiting for last draw) if (m_state == MyProjectileStateEnum.KILLED) { return(true); } // Projectile was killed and last time drawn, so we can finally remove it from buffer if (m_state == MyProjectileStateEnum.KILLED_AND_DRAWN) { if (m_trailEffect != null) { // stop the trail effect m_trailEffect.Stop(); m_trailEffect = null; } return(false); } Vector3 position = m_position; m_position += m_velocity * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; m_velocity = m_externalVelocity * m_externalAddition + m_directionNormalized * m_speed; if (m_externalAddition < 1.0f) { m_externalAddition *= 0.5f; } // Distance timeout float trajectoryLength = Vector3.Distance(m_position, m_origin); if (trajectoryLength >= m_maxTrajectory) { if (m_trailEffect != null) { // stop the trail effect m_trailEffect.Stop(); m_trailEffect = null; } m_state = MyProjectileStateEnum.KILLED; return(true); } if (m_trailEffect != null) { m_trailEffect.WorldMatrix = Matrix.CreateTranslation(m_position); } m_checkIntersectionIndex++; m_checkIntersectionIndex = m_checkIntersectionIndex % CHECK_INTERSECTION_INTERVAL; //check only each n-th intersection if (m_checkIntersectionIndex != 0) { return(true); } // Calculate hit point, create decal and throw debris particles Vector3 lineEndPosition = position + CHECK_INTERSECTION_INTERVAL * (m_velocity * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS); MyLine line = new MyLine(m_positionChecked ? position : m_origin, lineEndPosition, true); m_positionChecked = true; MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MyEntities.GetIntersectionWithLine()"); MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, m_ignorePhysObject, null, false); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MyEntity physObject = intersection != null ? intersection.Value.Entity : null; if (physObject != null) { while (physObject.Physics == null && physObject.Parent != null) { physObject = physObject.Parent; } } if ((intersection != null) && (physObject != null) && (physObject.Physics.CollisionLayer != MyConstants.COLLISION_LAYER_UNCOLLIDABLE) && m_ignorePhysObject != physObject) { MyIntersectionResultLineTriangleEx intersectionValue = intersection.Value; bool isPlayerShip = MySession.PlayerShip == physObject; MyMaterialType materialType = isPlayerShip ? MyMaterialType.PLAYERSHIP : physObject.Physics.MaterialType; //material properties MyMaterialTypeProperties materialProperties = MyMaterialsConstants.GetMaterialProperties(materialType); bool isProjectileGroupKilled = false; if (m_sharedGroup != null) { isProjectileGroupKilled = m_sharedGroup.Killed; m_sharedGroup.Killed = true; } if (!isProjectileGroupKilled) { // Play bullet hit cue MyAudio.AddCue3D(m_ammoProperties.IsExplosive ? materialProperties.ExpBulletHitCue : materialProperties.BulletHitCue, intersectionValue.IntersectionPointInWorldSpace, Vector3.Zero, Vector3.Zero, Vector3.Zero); } float decalAngle = MyMwcUtils.GetRandomRadian(); // If we hit the glass of a miner ship, we need to create special bullet hole decals // drawn from inside the cockpit and change phys object so rest of the code will think we hit the parent // IMPORTANT: Intersection between projectile and glass is calculated only for mining ship in which player sits. So for enemies this will be never calculated. if (intersection.Value.Entity is MyCockpitGlassEntity) { if (!isProjectileGroupKilled) { MyCockpitGlassDecalTexturesEnum bulletHoleDecalTexture; float bulletHoleDecalSize; if (MyMwcUtils.GetRandomBool(3)) { bulletHoleDecalTexture = MyCockpitGlassDecalTexturesEnum.BulletHoleOnGlass; bulletHoleDecalSize = 0.25f; } else { bulletHoleDecalTexture = MyCockpitGlassDecalTexturesEnum.BulletHoleSmallOnGlass; bulletHoleDecalSize = 0.1f; } // Place bullet hole decal on player's cockpit glass (seen from inside the ship) MyCockpitGlassDecals.Add(bulletHoleDecalTexture, bulletHoleDecalSize, decalAngle, 1.0f, ref intersectionValue, false); // Create hit particles throwed into the cockpit (it's simulation of broken glass particles) // IMPORTANT: This particles will be relative to miner ship, so we create them in object space coordinates and update them by object WorldMatrix every time we draw them //MyParticleEffects.CreateHitParticlesGlass(ref intersectionValue.IntersectionPointInObjectSpace, ref intersectionValue.NormalInWorldSpace, ref line.Direction, physObject.Parent); } } // If this was "mine", it must explode else if (physObject is MyMineBase) { m_state = MyProjectileStateEnum.KILLED; if (!IsDummy) { (physObject as MyAmmoBase).Explode(); } return(true); } // If this was missile, cannon shot, it must explode if it is not mine missile else if (physObject is MyAmmoBase) { if (((MyAmmoBase)physObject).OwnerEntity == m_ignorePhysObject) { m_state = MyProjectileStateEnum.KILLED; if (!IsDummy) { (physObject as MyAmmoBase).Explode(); } return(true); } } else if (this.OwnerEntity is MySmallShip && (MySmallShip)this.OwnerEntity == MySession.PlayerShip && physObject is MyStaticAsteroid && !physObject.IsDestructible) { if (this.m_ammoProperties.IsExplosive || (this.m_ammoProperties.AmmoType == MyAmmoType.Explosive && this.m_weapon is Weapons.MyShotGun)) { HUD.MyHud.ShowIndestructableAsteroidNotification(); } } else if (!isProjectileGroupKilled && !isPlayerShip) { // Create smoke and debris particle at the place of voxel/model hit m_ammoProperties.OnHitParticles(ref intersectionValue.IntersectionPointInWorldSpace, ref intersectionValue.Triangle.InputTriangleNormal, ref line.Direction, physObject, m_weapon, OwnerEntity); MySurfaceImpactEnum surfaceImpact; if (intersectionValue.Entity is MyVoxelMap) { var voxelMap = intersectionValue.Entity as MyVoxelMap; var voxelCoord = voxelMap.GetVoxelCenterCoordinateFromMeters(ref intersectionValue.IntersectionPointInWorldSpace); var material = voxelMap.GetVoxelMaterial(ref voxelCoord); if (material == MyMwcVoxelMaterialsEnum.Indestructible_01 || material == MyMwcVoxelMaterialsEnum.Indestructible_02 || material == MyMwcVoxelMaterialsEnum.Indestructible_03 || material == MyMwcVoxelMaterialsEnum.Indestructible_04 || material == MyMwcVoxelMaterialsEnum.Indestructible_05_Craters_01) { surfaceImpact = MySurfaceImpactEnum.INDESTRUCTIBLE; } else { surfaceImpact = MySurfaceImpactEnum.DESTRUCTIBLE; } } else if (intersectionValue.Entity is MyStaticAsteroid) { surfaceImpact = MySurfaceImpactEnum.INDESTRUCTIBLE; } else { surfaceImpact = MySurfaceImpactEnum.METAL; } m_ammoProperties.OnHitMaterialSpecificParticles(ref intersectionValue.IntersectionPointInWorldSpace, ref intersectionValue.Triangle.InputTriangleNormal, ref line.Direction, physObject, surfaceImpact, m_weapon); } if (!(physObject is MyExplosionDebrisBase) && physObject != MySession.PlayerShip) { // Decal size depends on material. But for mining ship create smaller decal as original size looks to large on the ship. float decalSize = MyMwcUtils.GetRandomFloat(materialProperties.BulletHoleSizeMin, materialProperties.BulletHoleSizeMax); // Place bullet hole decal float randomColor = MyMwcUtils.GetRandomFloat(0.5f, 1.0f); MyDecals.Add( materialProperties.BulletHoleDecal, decalSize, decalAngle, new Vector4(randomColor, randomColor, randomColor, 1), false, ref intersectionValue, 0.0f, m_ammoProperties.DecalEmissivity, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL); } if (!(physObject is MyVoxelMap) && !IsDummy) { ApplyProjectileForce(physObject, intersectionValue.IntersectionPointInWorldSpace, m_directionNormalized, isPlayerShip); } // If this object is miner ship, then shake his head little bit if (physObject is MySmallShip && !IsDummy) { MySmallShip minerShip = (MySmallShip)physObject; minerShip.IncreaseHeadShake(MyHeadShakeConstants.HEAD_SHAKE_AMOUNT_AFTER_PROJECTILE_HIT); } //Handle damage MyEntity damagedObject = intersectionValue.Entity; // not a very nice way to damage actual prefab associated with the large ship weapon (if MyPrefabLargeWeapon is reworked, it might change) if (damagedObject is MyLargeShipBarrelBase) { damagedObject = damagedObject.Parent; } if (damagedObject is MyLargeShipGunBase) { MyLargeShipGunBase physObj = damagedObject as MyLargeShipGunBase; if (physObj.PrefabParent != null) { damagedObject = physObj.PrefabParent; } } // Decrease health of stricken object if (!IsDummy) { damagedObject.DoDamage(m_ammoProperties.HealthDamage, m_ammoProperties.ShipDamage, m_ammoProperties.EMPDamage, m_ammoProperties.DamageType, m_ammoProperties.AmmoType, m_ignorePhysObject); if (MyMultiplayerGameplay.IsRunning) { var ammo = MyAmmoConstants.FindAmmo(m_ammoProperties); MyMultiplayerGameplay.Static.ProjectileHit(damagedObject, intersectionValue.IntersectionPointInWorldSpace, this.m_directionNormalized, ammo, this.OwnerEntity); } } if (m_trailEffect != null) { // stop the trail effect m_trailEffect.Stop(); m_trailEffect = null; } // Kill this projectile (set the position to intersection point, so we draw trail polyline only up to this point) m_position = intersectionValue.IntersectionPointInWorldSpace; m_state = MyProjectileStateEnum.KILLED; return(true); } return(true); }
internal override void Update(MySmallShipBot bot) { base.Update(bot); if (bot.Leader != null) { if (ShouldFallAsleep(bot)) { bot.IsSleeping = true; return; } Vector3 leaderToBot = bot.GetPosition() - bot.Leader.GetPosition(); Vector3 formationPositionActual = bot.Leader.GetFormationPosition(bot); Vector3 botToFormationPosition = formationPositionActual - bot.GetPosition(); float leaderDistance = leaderToBot.Length(); float formationPositionDistance = botToFormationPosition.Length(); Vector3 flyTo; if (formationPositionDistance > MyMwcMathConstants.EPSILON_SQUARED && leaderDistance > MyMwcMathConstants.EPSILON) { float leaderFactor = MathHelper.Clamp(leaderDistance - 5, 0, 25) / 20; flyTo = (1.0f - leaderFactor) * leaderToBot / leaderDistance + leaderFactor * botToFormationPosition / formationPositionDistance; flyTo = MyMwcUtils.Normalize(flyTo); flyTo = bot.GetPosition() + flyTo * formationPositionDistance; // Update leader visibility if (visibilityCheckTimer <= 0) { MyLine line = new MyLine(bot.GetPosition(), formationPositionActual, true); leaderVisible = !MyEntities.GetIntersectionWithLine(ref line, bot, bot.Leader, true, ignoreSmallShips: true).HasValue; visibilityCheckTimer = 0.5f; } else { visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; } } else { // Bot is on formation position flyTo = bot.GetPosition() + bot.WorldMatrix.Forward; leaderVisible = true; } if (leaderVisible) { bool afterburner = /*bot.Leader.IsAfterburnerOn() || */ formationPositionDistance > AFTERBURNER_DISTANCE; Vector3 lookTarget = formationPositionDistance < LOOK_DISTANCE ? formationPositionActual + bot.Leader.WorldMatrix.Forward * 5000 : formationPositionActual; float factor = MathHelper.Clamp(formationPositionDistance / 200, 0.5f, 1.0f); factor = factor * factor * factor; bot.Move(flyTo, lookTarget, bot.Leader.WorldMatrix.Up, afterburner, 1, 25, factor, slowRotation: true); checkTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; findSmallship.Init(bot); } else { if (leaderDistance > MIN_LEADER_DISTANCE) { findSmallship.Update(bot, bot.Leader); if (findSmallship.PathNotFound) { //We dont want our friends sleeping elsewhere // bot.IsSleeping = true; } } } } }
public void RequestJump(string destinationName, Vector3D destination, long userId) { if (!Vector3.IsZero(MyGravityProviderSystem.CalculateNaturalGravityInPoint(m_grid.WorldMatrix.Translation))) { var notification = new MyHudNotification(MySpaceTexts.NotificationCannotJumpFromGravity, 1500); MyHud.Notifications.Add(notification); return; } if (!Vector3.IsZero(MyGravityProviderSystem.CalculateNaturalGravityInPoint(destination))) { var notification = new MyHudNotification(MySpaceTexts.NotificationCannotJumpIntoGravity, 1500); MyHud.Notifications.Add(notification); return; } if (!IsJumpValid(userId)) { return; } if (MySession.Static.Settings.WorldSizeKm > 0 && destination.Length() > MySession.Static.Settings.WorldSizeKm * 500) { var notification = new MyHudNotification(MySpaceTexts.NotificationCannotJumpOutsideWorld, 1500); MyHud.Notifications.Add(notification); return; } m_selectedDestination = destination; double maxJumpDistance = GetMaxJumpDistance(userId); m_jumpDirection = destination - m_grid.WorldMatrix.Translation; double jumpDistance = m_jumpDirection.Length(); double actualDistance = jumpDistance; if (jumpDistance > maxJumpDistance) { double ratio = maxJumpDistance / jumpDistance; actualDistance = maxJumpDistance; m_jumpDirection *= ratio; } //By Gregory: Check for obstacle not that fast but happens rarely(on Jump drive enable) //TODO: make compatible with GetMaxJumpDistance and refactor to much code checks for actual jump var direction = Vector3D.Normalize(destination - m_grid.WorldMatrix.Translation); var startPos = m_grid.WorldMatrix.Translation + m_grid.PositionComp.LocalAABB.Extents.Max() * direction; var line = new LineD(startPos, destination); var intersection = MyEntities.GetIntersectionWithLine(ref line, m_grid, null, ignoreObjectsWithoutPhysics: false); Vector3D newDestination = Vector3D.Zero; Vector3D newDirection = Vector3D.Zero; if (intersection.HasValue) { MyEntity MyEntity = intersection.Value.Entity as MyEntity; var targetPos = MyEntity.WorldMatrix.Translation; var obstaclePoint = MyUtils.GetClosestPointOnLine(ref startPos, ref destination, ref targetPos); MyPlanet MyEntityPlanet = intersection.Value.Entity as MyPlanet; if (MyEntityPlanet != null) { var notification = new MyHudNotification(MySpaceTexts.NotificationCannotJumpIntoGravity, 1500); MyHud.Notifications.Add(notification); return; } //var Radius = MyEntityPlanet != null ? MyEntityPlanet.MaximumRadius : MyEntity.PositionComp.LocalAABB.Extents.Length(); var Radius = MyEntity.PositionComp.LocalAABB.Extents.Length(); destination = obstaclePoint - direction * (Radius + m_grid.PositionComp.LocalAABB.HalfExtents.Length()); m_selectedDestination = destination; m_jumpDirection = m_selectedDestination - startPos; actualDistance = m_jumpDirection.Length(); } if (actualDistance < MIN_JUMP_DISTANCE) { MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox( buttonType: MyMessageBoxButtonsType.OK, messageText: GetWarningText(actualDistance, intersection.HasValue), messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionWarning) )); } else { MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox( buttonType : MyMessageBoxButtonsType.YES_NO, messageText : GetConfimationText(destinationName, jumpDistance, actualDistance, userId, intersection.HasValue), messageCaption : MyTexts.Get(MyCommonTexts.MessageBoxCaptionPleaseConfirm), size : new Vector2(0.839375f, 0.3675f), callback : delegate(MyGuiScreenMessageBox.ResultEnum result) { if (result == MyGuiScreenMessageBox.ResultEnum.YES && IsJumpValid(userId)) { RequestJump(m_selectedDestination, userId); } else { AbortJump(); } } )); } }
private void DebugDrawVertexNames() { //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(10, 0), "Voxel names searching", Color.Yellow, 0.5f); LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * 500); MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, MySession.Static.LocalCharacter, null, false, true, true, VRage.Game.Components.IntersectionFlags.ALL_TRIANGLES, 0, false); float yPos = 20; if (intersection.HasValue) { if (intersection.Value.Entity is MyVoxelBase) { MyVoxelBase voxels = (MyVoxelBase)intersection.Value.Entity; Vector3D point = intersection.Value.IntersectionPointInWorldSpace; if (intersection.Value.Entity is MyPlanet) { MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), "Type: planet/moon", Color.Yellow, DEBUG_SCALE); yPos += 10; MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), "Terrain: " + voxels.GetMaterialAt(ref point), Color.Yellow, DEBUG_SCALE); yPos += 10; } else { MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), "Type: asteroid", Color.Yellow, DEBUG_SCALE); yPos += 10; MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), "Terrain: " + voxels.GetMaterialAt(ref point), Color.Yellow, DEBUG_SCALE); yPos += 10; } MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), "Object size: " + voxels.SizeInMetres, Color.Yellow, DEBUG_SCALE); yPos += 10; //location /* * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 50), "Location:", Color.Yellow, 0.5f); * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 60), "x " + Math.Round(point.X, 3).ToString(), Color.Yellow, 0.5f); * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 70), "y " + Math.Round(point.Y, 3).ToString(), Color.Yellow, 0.5f); * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 80), "z " + Math.Round(point.Z, 3).ToString(), Color.Yellow, 0.5f);*/ } else if (intersection.Value.Entity is MyCubeGrid) { MyCubeGrid grid = (MyCubeGrid)intersection.Value.Entity; MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), "Detected grid object", Color.Yellow, DEBUG_SCALE); yPos += 10; MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), String.Format("Grid name: {0}", grid.DisplayName), Color.Yellow, DEBUG_SCALE); yPos += 10; MyIntersectionResultLineTriangleEx?t; MySlimBlock block; if (grid.GetIntersectionWithLine(ref line, out t, out block) && t.HasValue && block != null) { if (block.FatBlock != null) { DebugDrawModelTextures(block.FatBlock, ref yPos); } else { DebugDrawBareBlockInfo(block, ref yPos); } } } else { MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), "Unknown object detected @ distance " + intersection.Value.Triangle.Distance + "m", Color.Yellow, DEBUG_SCALE); yPos += 10; } MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), "Distance " + intersection.Value.Triangle.Distance + "m", Color.Yellow, DEBUG_SCALE); } else { MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Nothing detected nearby", Color.Yellow, DEBUG_SCALE); } }
public void DoWork() { try { MyEntities.EntityCloseLock.AcquireShared(); if (m_entity == null) { return; } //if (m_entity.EntityId.HasValue && m_entity.EntityId.Value.NumericValue == 119150) // { // } // if (m_entity == MinerWars.AppCode.Game.Managers.Session.MySession.PlayerShip) // { // } Vector3 directionToSunNormalized = MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized(); VisibleFromSun = false; MyLine line2 = new MyLine(m_entity.WorldAABB.GetCenter(), m_entity.WorldAABB.GetCenter() + directionToSunNormalized * MyShadowRenderer.SHADOW_MAX_OFFSET * 0.5f, true); var result2 = MyEntities.GetIntersectionWithLine(ref line2, m_entity, null, true, true, true); VisibleFromSun |= IsVisibleFromSun(result2); if (m_entity.RenderObjects != null && m_entity.RenderObjects[0].FastCastShadowResolve) { return; } Vector3[] corners = new Vector3[8]; m_entity.LocalAABB.GetCorners(corners); for (int i = 0; i < 8; i++) { corners[i] = Vector3.Transform(corners[i], m_entity.WorldMatrix); } for (int i = 0; i < 8; i++) { MyLine line = new MyLine(corners[i], corners[i] + directionToSunNormalized * MyShadowRenderer.SHADOW_MAX_OFFSET * 0.5f, true); var result = MyEntities.GetIntersectionWithLine(ref line, m_entity, null, true, true, true); VisibleFromSun |= IsVisibleFromSun(result); if (VisibleFromSun) { break; } } } finally { if (m_entity != null) { m_entity.OnClose -= m_entity_OnMarkForClose; } MyEntities.EntityCloseLock.ReleaseShared(); } }
protected override void DoDetection(bool useHead) { ProfilerShort.Begin("DoDetection"); if (Character == MySession.Static.ControlledEntity) { MyHud.SelectedObjectHighlight.RemoveHighlight(); } var head = Character.GetHeadMatrix(false); var headPos = head.Translation - (Vector3D)head.Forward * 0.3; // Move to center of head, we don't want eyes (in front of head) Vector3D from; Vector3D dir; if (!useHead) { //Ondrej version var cameraMatrix = MySector.MainCamera.WorldMatrix; dir = cameraMatrix.Forward; from = MyUtils.LinePlaneIntersection(headPos, (Vector3)dir, cameraMatrix.Translation, (Vector3)dir); } else { //Petr version dir = head.Forward; from = headPos; } Vector3D to = from + dir * MyConstants.DEFAULT_INTERACTIVE_DISTANCE; StartPosition = from; LineD intersectionLine = new LineD(from, to); // Processing of hit entities var geometryHit = MyEntities.GetIntersectionWithLine(ref intersectionLine, null, null, ignoreFloatingObjects: false); bool hasUseObject = false; if (geometryHit.HasValue) { var hitEntity = geometryHit.Value.Entity; // Cube Grids are special case var cubeGrid = hitEntity as MyCubeGrid; if (cubeGrid != null) { // For hit cube grids get the fat hit fatblock instead. var slimBlock = cubeGrid.GetTargetedBlock(geometryHit.Value.IntersectionPointInWorldSpace); if (slimBlock != null && slimBlock.FatBlock != null) { hitEntity = slimBlock.FatBlock; } } m_hitUseComponents.Clear(); var hitUseObject = hitEntity as IMyUseObject; // Retrive all above use components from parent structure. (Because of subParts) GetUseComponentsFromParentStructure(hitEntity, m_hitUseComponents); // Check for UseObjects and entities with UseObjectComponentBase. // Assuming that entity cannot be IMyUseObject and have UseObjectComponentBase in hierarchy // at the same time. if (hitUseObject != null || m_hitUseComponents.Count > 0) { if (m_hitUseComponents.Count > 0) { // Process the valid hit entity var closestDetectorDistance = float.MaxValue; double physicalHitDistance = Vector3D.Distance(from, geometryHit.Value.IntersectionPointInWorldSpace); MyUseObjectsComponentBase hitUseComp = null; // Evaluate the set of found detectors and try to find the closest one foreach (var hitUseComponent in m_hitUseComponents) { float detectorDistance; var interactive = hitUseComponent.RaycastDetectors(from, to, out detectorDistance); detectorDistance *= MyConstants.DEFAULT_INTERACTIVE_DISTANCE; if (Math.Abs(detectorDistance) < Math.Abs(closestDetectorDistance) && (detectorDistance < physicalHitDistance)) // Remove to fix the problem with picking through physic bodies, { // but will introduce new problem with detectors inside physic bodies. closestDetectorDistance = detectorDistance; hitUseComp = hitUseComponent; hitEntity = hitUseComponent.Entity; hitUseObject = interactive; } } // Detector found if (hitUseComp != null) { // Process successful hit with results var detectorPhysics = hitUseComp.DetectorPhysics; HitMaterial = detectorPhysics.GetMaterialAt(HitPosition); HitBody = geometryHit.Value.Entity.Physics.RigidBody; HitPosition = geometryHit.Value.IntersectionPointInWorldSpace; DetectedEntity = hitEntity; } } else { // Case for hitting IMyUseObject already before even looking for UseComponent. // Floating object case. HitMaterial = hitEntity.Physics.GetMaterialAt(HitPosition); HitBody = hitEntity.Physics.RigidBody; } // General logic for processing both cases. if (hitUseObject != null) { HitPosition = geometryHit.Value.IntersectionPointInWorldSpace; DetectedEntity = hitEntity; if (UseObject != null && UseObject != hitEntity && UseObject != hitUseObject) { UseObject.OnSelectionLost(); } if (Character == MySession.Static.ControlledEntity && hitUseObject.SupportedActions != UseActionEnum.None) { HandleInteractiveObject(hitUseObject); UseObject = hitUseObject; hasUseObject = true; } } } } if (!hasUseObject) { if (UseObject != null) { UseObject.OnSelectionLost(); } UseObject = null; } ProfilerShort.End(); }
public void DoWork() { // Search for target to attack ClosestEnemy = null; ClosestVisual = null; float distanceSqr = m_seeDistance * m_seeDistance; float closestEnemyDistanceSqr = float.PositiveInfinity; float closestVisualDistanceSqr = float.PositiveInfinity; using (var rbFounded = PoolList <MyRBElement> .Get()) { try { MyEntities.EntityCloseLock.AcquireShared(); MyDynamicAABBTree prunningStructure = MyPhysics.physicsSystem.GetRigidBodyModule().GetPruningStructure(); BoundingBox rbInputElementGetWorldSpaceAABB = new BoundingBox( m_botWorldMatrix.Translation - new Vector3(m_seeDistance), m_botWorldMatrix.Translation + new Vector3(m_seeDistance)); prunningStructure.OverlapAllBoundingBox(ref rbInputElementGetWorldSpaceAABB, rbFounded, (uint)MyElementFlag.EF_RB_ELEMENT); //now try find spot foreach (MyRBElement rb in rbFounded) { if (m_bot == null) { return; } var rigidBody = rb.GetRigidBody(); if (rigidBody == null) { continue; } MyEntity entity = ((MyPhysicsBody)rigidBody.m_UserData).Entity; if (entity == m_bot || entity == null || entity.AIPriority == -1) { continue; } entity = entity.GetBaseEntity(); // Large weapons // Ignore spoiled holograms if (m_bot.IsSpoiledHologram(entity)) { continue; } // Don't attack disabled weapons MyPrefabLargeWeapon largeWeapon = entity as MyPrefabLargeWeapon; MySmallShip smallShip = entity as MySmallShip; MyPrefabLargeShip largeShip = entity as MyPrefabLargeShip; if (largeWeapon != null && !largeWeapon.IsWorking()) { continue; } // Test smallships and largeweapons if (smallShip != null || largeWeapon != null || largeShip != null) { // Is enemy? if (MyFactions.GetFactionsRelation(m_bot, entity) == MyFactionRelationEnum.Enemy && CanSeeTarget(m_bot, entity)) { var entityDistanceSqr = Vector3.DistanceSquared(entity.GetPosition(), m_position); if (entityDistanceSqr < distanceSqr && (ClosestEnemy == null || entity.AIPriority >= ClosestEnemy.AIPriority) && (entityDistanceSqr < closestEnemyDistanceSqr || entity.AIPriority > ClosestEnemy.AIPriority)) { MyLine line = new MyLine(m_position, entity.GetPosition(), true); var result = MyEntities.GetIntersectionWithLine(ref line, m_bot, entity, true, ignoreChilds: true); if (!result.HasValue) { // Visual Detection - ignore visualy detected targets if they are further than any normaly detected target if (IsVisualyDetected(smallShip)) { if (entityDistanceSqr < closestVisualDistanceSqr) { ClosestVisual = entity; closestVisualDistanceSqr = entityDistanceSqr; } } else { closestEnemyDistanceSqr = entityDistanceSqr; ClosestEnemy = entity; } } } } } } } finally { MyEntities.EntityCloseLock.ReleaseShared(); } } }
private void CreateDecals(Vector3 direction) { MyRender.GetRenderProfiler().StartProfilingBlock("Collisions"); MyRender.GetRenderProfiler().StartProfilingBlock("Raycast"); var intersectionEndPoint = m_explosionSphere.Center + 1.5f * m_explosionSphere.Radius * direction; var intersectionStartPoint = m_explosionSphere.Center - 1.5f * m_explosionSphere.Radius * direction; var line = new MyLine(intersectionStartPoint, intersectionEndPoint); var result = MyEntities.GetIntersectionWithLine(ref line, null, null, true, true, false, false, true, AppCode.Physics.Collisions.IntersectionFlags.ALL_TRIANGLES, true); MyRender.GetRenderProfiler().EndProfilingBlock(); MyRender.GetRenderProfiler().StartProfilingBlock("Add decal"); if (result.HasValue) { MyIntersectionResultLineTriangleEx intersection = result.Value; var radius = m_explosionSphere.Radius * (result.Value.Entity is MyVoxelMap ? 1.0f : MyMwcUtils.GetRandomFloat(0.4f, 0.6f)); MyDecals.Add( MyDecalTexturesEnum.ExplosionSmut, radius, MyMwcUtils.GetRandomRadian(), GetSmutDecalRandomColor(), true, ref intersection, 0, 0, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL_FOR_SMUT_DECALS); } MyRender.GetRenderProfiler().EndProfilingBlock(); MyRender.GetRenderProfiler().EndProfilingBlock(); //var elements = MyEntities.GetElementsInBox(ref boundingBox); //foreach (MyRBElement element in elements) //{ // var rigidBody = (MyPhysicsBody)element.GetRigidBody().m_UserData; // var entity = rigidBody.Entity; // if (entity is MyExplosionDebrisBase || entity is MyPrefabContainer) // continue; // // Making interesection of line from the explosion center to every object closed to explosion // // and placing smut decals // // FIX : when hitting another samll boat explosion and entity position are equal !!! // //if (m_explosionSphere.Center == entity.GetPosition()) // // continue; // // FIX : when hitting another samll boat explosion and direction is < Epsilon !!! // if ((entity.GetPosition() - m_explosionSphere.Center).LengthSquared() < // 2 * MyMwcMathConstants.EPSILON_SQUARED) // continue; // MyRender.GetRenderProfiler().StartProfilingBlock("Line intersection"); // MyIntersectionResultLineTriangleEx? intersection = null; // if (direction.HasValue) // { // var intersectionEndPoint = m_explosionSphere.Center + 1.5f * m_explosionSphere.Radius * direction.Value; // var intersectionStartPoint = m_explosionSphere.Center - 1.5f * m_explosionSphere.Radius * direction.Value; // MyLine intersectionLine = new MyLine(intersectionStartPoint, intersectionEndPoint, true); // entity.GetIntersectionWithLine(ref intersectionLine, out intersection); // } // else if (intersection == null && entity is MyVoxelMap) // { // // fall back if we dont have direction // var intersectionEndPoint = entity.GetPosition(); // MyLine intersectionLine = new MyLine(m_explosionSphere.Center, intersectionEndPoint, true); // entity.GetIntersectionWithLine(ref intersectionLine, out intersection); // } // MyRender.GetRenderProfiler().EndProfilingBlock(); // if (intersection == null) // continue; // MyIntersectionResultLineTriangleEx intersectionValue = intersection.Value; // if (entity is MyVoxelMap) // { // MyRender.GetRenderProfiler().StartProfilingBlock("Decals"); // MyDecals.Add( // MyDecalTexturesEnum.ExplosionSmut, // m_explosionSphere.Radius, // MyMwcUtils.GetRandomRadian(), // GetSmutDecalRandomColor(), // true, // ref intersectionValue, // 0, // 0, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL_FOR_SMUT_DECALS); // MyRender.GetRenderProfiler().EndProfilingBlock(); // } // else if (((entity is MySmallShip) == false) && // ((entity is MySmallDebris) == false) // && ((entity is MyAmmoBase) == false)) // { // // Create explosion smut decal on model we hit by this missile // MyDecals.Add( // MyDecalTexturesEnum.ExplosionSmut, // MyMwcUtils.GetRandomFloat(m_explosionSphere.Radius * 0.4f, m_explosionSphere.Radius * 0.6f), // MyMwcUtils.GetRandomRadian(), // GetSmutDecalRandomColor(), // true, // ref intersectionValue, // 0, // 0, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL); // } //} //elements.Clear(); }
/// <summary> /// Updates resource. /// </summary> public override void UpdateAfterSimulation() { base.UpdateAfterSimulation(); if ((!GetParentMinerShip().Config.Engine.On || GetParentMinerShip().Fuel <= 0) && (CurrentState == MyHarvestingDeviceEnum.InVoxel || CurrentState == MyHarvestingDeviceEnum.FindingVoxel)) { StartFastReturningBack(); } if (CurrentState == MyHarvestingDeviceEnum.InsideShip) { // Do nothing return; } if (CurrentState == MyHarvestingDeviceEnum.FindingVoxel) { // Head in local space m_headPositionLocal += this.LocalMatrix.Forward * MyHarvestingTubeConstants.EJECTION_SPEED_IN_METERS_PER_SECOND; } else if (CurrentState == MyHarvestingDeviceEnum.ReturningBack) { // Head in local space m_headPositionLocal -= this.LocalMatrix.Forward * MyHarvestingTubeConstants.EJECTION_SPEED_IN_METERS_PER_SECOND; } else if (CurrentState == MyHarvestingDeviceEnum.FastReturningBack) { // Head in local space m_headPositionLocal -= this.LocalMatrix.Forward * MyHarvestingTubeConstants.FAST_PULL_BACK_IN_METERS_PER_SECOND; } // Transform head position into world space Matrix worldMatrix = Parent.WorldMatrix; m_harvestingOreHead.LocalMatrix = Matrix.CreateWorld(m_headPositionLocal, m_harvestingOreHead.LocalMatrix.Forward, m_harvestingOreHead.LocalMatrix.Up); m_headPositionTransformed = m_harvestingOreHead.WorldMatrix.Translation; // Distance must carry sign (plus/minus) because when we need to know if head is behind it's starting point when pulling back // IMPORTANT: Forward is in -Z direction, so that's why I subtract position from head and not oppositely float distance = this.LocalMatrix.Translation.Z - m_headPositionLocal.Z; if (CurrentState == MyHarvestingDeviceEnum.ReturningBack || CurrentState == MyHarvestingDeviceEnum.FastReturningBack) { if (distance <= MyHarvestingTubeConstants.DISTANCE_TO_PLUG_IN_THE_TUBE) { StartInsideShip(); } } else { if (distance >= MyHarvestingTubeConstants.MAX_DISTANCE_OF_HARVESTING_DEVICE) { StartReturningBack(); } } // Sphere for head of harvester BoundingSphere headSphere = new BoundingSphere(m_headPositionTransformed, m_harvestingOreHead.ModelLod0.BoundingSphere.Radius); if (CurrentState == MyHarvestingDeviceEnum.FindingVoxel) { // Check if head doesn't collide with anything MyEntity sphereResult = MyEntities.GetIntersectionWithSphere(ref headSphere, m_parentMinerShip, null); if (sphereResult != null) { if (sphereResult is MyVoxelMap) { StartInVoxel((MyVoxelMap)sphereResult); } else { // Intersection between sphere and anything else but voxels, so we start pulling back quickly StartFastReturningBack(); } } } // If we are connected to voxel check permanently if the voxel is still there if ((CurrentState == MyHarvestingDeviceEnum.InVoxel) && (MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeCheckedForVoxelPresence) > MyHarvestingTubeConstants.INTERVAL_TO_CHECK_FOR_VOXEL_CONNECTION_IN_MILISECONDS) { m_lastTimeCheckedForVoxelPresence = MyMinerGame.TotalGamePlayTimeInMilliseconds; // Check if head doesn't collide with anything MyEntity sphereResult = MyEntities.GetIntersectionWithSphere(ref headSphere, m_parentMinerShip, null); if (!(sphereResult is MyVoxelMap)) { StartFastReturningBack(); } } // If we are connected to voxel we can harvest it if (CurrentState == MyHarvestingDeviceEnum.InVoxel) { m_actualVoxelContent -= m_harvestingSpeed; if (m_actualVoxelContent <= 0) { StartReleaseVoxel(); } } if ((WorldMatrix.Translation - m_headPositionTransformed).Length() > MyMwcMathConstants.EPSILON) { // Check if tube doesn't colide with something MyLine tubeLine = new MyLine(WorldMatrix.Translation, m_headPositionTransformed, true); MyIntersectionResultLineTriangleEx?tubeIntersection = MyEntities.GetIntersectionWithLine(ref tubeLine, this, m_parentMinerShip); // We colide with something and we need fast return back if (tubeIntersection != null) { StartFastReturningBack(); } } if (CurrentState == MyHarvestingDeviceEnum.InVoxel) { m_parentMinerShip.IncreaseHeadShake(MyHarvestingTubeConstants.SHAKE_DURING_IN_VOXELS); } else if ((CurrentState == MyHarvestingDeviceEnum.FastReturningBack) || (CurrentState == MyHarvestingDeviceEnum.FindingVoxel) || (CurrentState == MyHarvestingDeviceEnum.ReturningBack)) { m_parentMinerShip.IncreaseHeadShake(MyHarvestingTubeConstants.SHAKE_DURING_EJECTION); } if (m_light != null) { m_light.SetPosition(m_headPositionTransformed - WorldMatrix.Forward); } if ((m_tubeMovingCue != null) && (m_tubeMovingCue.Value.IsPlaying == true)) { MyAudio.UpdateCuePosition(m_tubeMovingCue, WorldMatrix.Translation, WorldMatrix.Forward, WorldMatrix.Up, Parent.Physics.LinearVelocity); } if ((m_grindingCue != null) && (m_grindingCue.Value.IsPlaying == true)) { MyAudio.UpdateCuePosition(m_grindingCue, m_headPositionTransformed, WorldMatrix.Forward, WorldMatrix.Up, Parent.Physics.LinearVelocity); } m_harvestingOreHead.SetData(ref m_worldMatrixForRenderingFromCockpitView); }