static void ProxyExplosionSuccess(ref ProxyExplosionMsg msg, MyNetworkClient sender) { //Dont create explosion particles if message is bufferred, it is useless to create hundred explosion after scene load if (MySession.Ready) { // Create explosion MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = 0, //Damage = m_ammoProperties.Damage, Damage = 200, ExplosionType = msg.Type, ExplosionSphere = new BoundingSphere(msg.Center, msg.Radius), LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadeLevel = 0, HitEntity = null, ParticleScale = msg.ParticleScale, OwnerEntity = null, Direction = Vector3.Forward, VoxelExplosionCenter = msg.VoxelCenter, ExplosionFlags = MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_SHRAPNELS, VoxelCutoutScale = 1.0f, PlaySound = true, ObjectsRemoveDelayInMiliseconds = 40 }; MyExplosions.AddExplosion(ref info, false); } }
public static void CreateFakeSmallExplosion(Vector3D position) { MyExplosionInfo explosionInfo = new MyExplosionInfo() { PlayerDamage = 0.0f, Damage = 0f, ExplosionType = MyExplosionTypeEnum.WARHEAD_EXPLOSION_02, ExplosionSphere = new BoundingSphereD(position, 0d), LifespanMiliseconds = 0, ParticleScale = 1f, Direction = Vector3.Down, VoxelExplosionCenter = position, ExplosionFlags = MyExplosionFlags.CREATE_PARTICLE_EFFECT, VoxelCutoutScale = 0f, PlaySound = true, ApplyForceAndDamage = false, ObjectsRemoveDelayInMiliseconds = 0 }; MyExplosions.AddExplosion(ref explosionInfo); }
protected override void OnContactStart(MyContactEventInfo contactInfo) { var collidedEntity = contactInfo.GetOtherEntity(this); if (!(collidedEntity is MyMeteor)) { MyParticleEffect pe = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Explosion_Meteor); pe.WorldMatrix = this.WorldMatrix; pe.UserScale = this.m_size * 0.01f; MyExplosion newExplosion = MyExplosions.AddExplosion(); MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = 100, Damage = 100, EmpDamage = 0, ExplosionType = MyExplosionTypeEnum.METEOR_EXPLOSION, ExplosionSphere = new BoundingSphere(GetPosition(), m_size), LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, ParticleScale = 1, OwnerEntity = this, HitEntity = collidedEntity, ExplosionFlags = MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.CREATE_DEBRIS /*| MyExplosionFlags.FORCE_DEBRIS*/, PlaySound = true, VoxelCutoutScale = 1, VoxelExplosionCenter = GetPosition() }; if (newExplosion != null) { newExplosion.Start(ref info); } this.MarkForClose(); } }
void CreateExplosion(Vector3D position, Vector3D direction, float radius, float damage, float scale = 1f) { var m_explosionFullSphere = new BoundingSphere(position, radius); MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = 100, Damage = damage, ExplosionType = MyExplosionTypeEnum.WARHEAD_EXPLOSION_02, ExplosionSphere = m_explosionFullSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, ParticleScale = scale, Direction = direction, VoxelExplosionCenter = m_explosionFullSphere.Center, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.APPLY_DEFORMATION, VoxelCutoutScale = 0.1f, PlaySound = true, ApplyForceAndDamage = false, //to stop from flinging objects to orbit ObjectsRemoveDelayInMiliseconds = 40 }; MyExplosions.AddExplosion(ref info); }
public bool DoDamage(float damage, MyStringHash damageType, bool sync, long attackerId) { if (MarkedForClose) { return(false); } if (sync) { if (Sync.IsServer) { MySyncDamage.DoDamageSynced(this, damage, damageType, attackerId); return(true); } else { return(false); } } MyDamageInformation damageinfo = new MyDamageInformation(false, damage, damageType, attackerId); if (UseDamageSystem) { MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref damageinfo); } var typeId = Item.Content.TypeId; if (typeId == typeof(MyObjectBuilder_Ore) || typeId == typeof(MyObjectBuilder_Ingot)) { if (Item.Amount < 1) { //TODO: SYNC particle MyParticleEffect effect; if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Construction, out effect)) { effect.WorldMatrix = WorldMatrix; effect.UserScale = 0.4f; } if (Sync.IsServer) { MyFloatingObjects.RemoveFloatingObject(this); } } else { if (Sync.IsServer) { MyFloatingObjects.RemoveFloatingObject(this, (MyFixedPoint)damageinfo.Amount); } } } else { m_health -= 10 * damageinfo.Amount; if (UseDamageSystem) { MyDamageSystem.Static.RaiseAfterDamageApplied(this, damageinfo); } if (m_health < 0) { //TODO: SYNC particle MyParticleEffect effect; if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Construction, out effect)) { effect.WorldMatrix = WorldMatrix; effect.UserScale = 0.4f; } if (Sync.IsServer) { MyFloatingObjects.RemoveFloatingObject(this); } //TODO: dont compare to string? if (Item.Content.SubtypeId == m_explosives && Sync.IsServer) { var expSphere = new BoundingSphere(WorldMatrix.Translation, (float)Item.Amount * 0.01f + 0.5f);// MathHelper.Clamp((float)Item.Amount, 0, 300) * 0.5f); MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = 0, Damage = 800, ExplosionType = MyExplosionTypeEnum.WARHEAD_EXPLOSION_15, ExplosionSphere = expSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadeLevel = 0, HitEntity = this, ParticleScale = 1, OwnerEntity = this, Direction = WorldMatrix.Forward, VoxelExplosionCenter = expSphere.Center, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION, VoxelCutoutScale = 0.5f, PlaySound = true, ApplyForceAndDamage = true, ObjectsRemoveDelayInMiliseconds = 40 }; MyExplosions.AddExplosion(ref info); } if (MyFakes.ENABLE_SCRAP && Sync.IsServer) { if (Item.Content.SubtypeId == ScrapBuilder.SubtypeId) { return(true); } var contentDefinitionId = Item.Content.GetId(); if (contentDefinitionId.TypeId == typeof(MyObjectBuilder_Component)) { var definition = MyDefinitionManager.Static.GetComponentDefinition((Item.Content as MyObjectBuilder_Component).GetId()); if (MyRandom.Instance.NextFloat() < definition.DropProbability) { MyFloatingObjects.Spawn(new MyPhysicalInventoryItem(Item.Amount * 0.8f, ScrapBuilder), PositionComp.GetPosition(), WorldMatrix.Forward, WorldMatrix.Up); } } } if (ItemDefinition != null && ItemDefinition.DestroyedPieceId.HasValue && Sync.IsServer) { MyPhysicalItemDefinition pieceDefinition; if (MyDefinitionManager.Static.TryGetPhysicalItemDefinition(ItemDefinition.DestroyedPieceId.Value, out pieceDefinition)) { MyFloatingObjects.Spawn(pieceDefinition, WorldMatrix.Translation, WorldMatrix.Forward, WorldMatrix.Up, ItemDefinition.DestroyedPieces); } else { System.Diagnostics.Debug.Fail("Trying to spawn piece of the item after being destroyed, but definition wasn't found! - " + ItemDefinition.DestroyedPieceId.Value); } } if (UseDamageSystem) { MyDamageSystem.Static.RaiseDestroyed(this, damageinfo); } } } return(true); }
public void DoDamage(float damage, MyDamageType damageType, bool sync, long attackerId) { if (MarkedForClose) return; if (sync) { if (!Sync.IsServer) return; else { MySyncHelper.DoDamageSynced(this, damage, damageType, attackerId); return; } } MyDamageInformation damageinfo = new MyDamageInformation(false, damage, damageType, attackerId); if(UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref damageinfo); var typeId = Item.Content.TypeId; if (typeId == typeof(MyObjectBuilder_Ore) || typeId == typeof(MyObjectBuilder_Ingot)) { if (Item.Amount < 1) { //TODO: SYNC particle MyParticleEffect effect; if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Construction, out effect)) { effect.WorldMatrix = WorldMatrix; effect.UserScale = 0.4f; MyFloatingObjects.RemoveFloatingObject(this); } } else { if (Sync.IsServer) MyFloatingObjects.RemoveFloatingObject(this, (MyFixedPoint)damageinfo.Amount); } } else { m_health -= (10 + 90 * DamageMultiplier) * damageinfo.Amount; if(UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(this, damageinfo); if (m_health < 0) { //TODO: SYNC particle MyParticleEffect effect; if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Construction, out effect)) { effect.WorldMatrix = WorldMatrix; effect.UserScale = 0.4f; } if (Sync.IsServer) MyFloatingObjects.RemoveFloatingObject(this); //TODO: dont compare to string? if (Item.Content.SubtypeId == m_explosives && Sync.IsServer) { var expSphere = new BoundingSphere(WorldMatrix.Translation, (float)Item.Amount * 0.01f + 0.5f);// MathHelper.Clamp((float)Item.Amount, 0, 300) * 0.5f); MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = 0, Damage = 800, ExplosionType = MyExplosionTypeEnum.WARHEAD_EXPLOSION_15, ExplosionSphere = expSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadeLevel = 0, HitEntity = this, ParticleScale = 1, OwnerEntity = this, Direction = WorldMatrix.Forward, VoxelExplosionCenter = expSphere.Center, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION, VoxelCutoutScale = 0.5f, PlaySound = true, ApplyForceAndDamage = true, ObjectsRemoveDelayInMiliseconds = 40 }; MyExplosions.AddExplosion(ref info); } if (MyFakes.ENABLE_SCRAP && Sync.IsServer) { if (Item.Content.SubtypeId == ScrapBuilder.SubtypeId) return; var contentDefinitionId = Item.Content.GetId(); if (contentDefinitionId.TypeId == typeof(MyObjectBuilder_Component)) { var definition = MyDefinitionManager.Static.GetComponentDefinition((Item.Content as MyObjectBuilder_Component).GetId()); if (MyRandom.Instance.NextFloat() < definition.DropProbability) MyFloatingObjects.Spawn(new MyPhysicalInventoryItem(Item.Amount * 0.8f, ScrapBuilder), PositionComp.GetPosition(), WorldMatrix.Forward, WorldMatrix.Up); } } if(UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(this, damageinfo); } } return; }
public static void CreateFakeExplosion(Session session, double radius, Vector3D position, Vector3D direction, MyEntity hitEnt, WeaponDefinition.AmmoDef ammoDef, Vector3 velocity) { var af = ammoDef.AreaEffect; var eInfo = af.Explosions; if (radius > 10) { radius = 10; } var sphere = new BoundingSphereD(position, radius); var cullSphere = sphere; cullSphere.Radius = radius * 5; var drawParticles = !eInfo.NoVisuals && session.Camera.IsInFrustum(ref cullSphere); MyExplosionFlags eFlags; if (drawParticles) { eFlags = MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT; } else { eFlags = MyExplosionFlags.CREATE_DECALS; } var customParticle = eInfo.CustomParticle != string.Empty; var explosionType = !customParticle ? MyExplosionTypeEnum.MISSILE_EXPLOSION : MyExplosionTypeEnum.CUSTOM; MySoundPair customSound = null; if (ammoDef.Const.CustomExplosionSound && !eInfo.NoSound) { customSound = ammoDef.Const.CustomSoundPairs.Count > 0 ? ammoDef.Const.CustomSoundPairs.Pop() : new MySoundPair(eInfo.CustomSound, false); session.FutureEvents.Schedule(ammoDef.Const.ReturnSoundPair, customSound, 1800); } MyExplosionInfo explosionInfo = new MyExplosionInfo { PlayerDamage = 0.0f, Damage = 0f, ExplosionType = explosionType, ExplosionSphere = sphere, LifespanMiliseconds = 0, ParticleScale = eInfo.Scale, Direction = direction, VoxelExplosionCenter = position, ExplosionFlags = eFlags, VoxelCutoutScale = 0f, HitEntity = hitEnt, PlaySound = !eInfo.NoSound, ApplyForceAndDamage = false, ObjectsRemoveDelayInMiliseconds = 0, CustomEffect = eInfo.CustomParticle, CreateParticleEffect = drawParticles, Velocity = velocity, CustomSound = customSound, }; if (hitEnt?.Physics != null) { explosionInfo.Velocity = hitEnt.Physics.LinearVelocity; } MyExplosions.AddExplosion(ref explosionInfo); }
public static void CreateMissileExplosion(Session session, float damage, double radius, Vector3D position, Vector3D direction, MyEntity owner, MyEntity hitEnt, WeaponDefinition.AmmoDef ammoDef, bool forceNoDraw = false) { var af = ammoDef.AreaEffect; var justShrapnel = !af.Explosions.NoShrapnel && af.Explosions.NoDeformation; var justDeform = af.Explosions.NoShrapnel && !af.Explosions.NoDeformation; var eInfo = af.Explosions; var playSound = !eInfo.NoSound && !forceNoDraw; var sphere = new BoundingSphereD(position, radius); var cullSphere = sphere; cullSphere.Radius = radius * 5; MyExplosionFlags eFlags; var drawParticles = !forceNoDraw && !eInfo.NoVisuals && session.Camera.IsInFrustum(ref cullSphere); if (drawParticles) { if (justShrapnel) { eFlags = MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_SHRAPNELS; } else if (justDeform) { eFlags = MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.APPLY_DEFORMATION; } else { eFlags = MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION; } } else { if (justShrapnel) { eFlags = MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_SHRAPNELS; } else if (justDeform) { eFlags = MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.APPLY_DEFORMATION; } else { eFlags = MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION; } } var customParticle = eInfo.CustomParticle != string.Empty; var explosionType = !customParticle ? MyExplosionTypeEnum.MISSILE_EXPLOSION : MyExplosionTypeEnum.CUSTOM; var explosionInfo = new MyExplosionInfo { PlayerDamage = 0.1f, Damage = damage, ExplosionType = explosionType, ExplosionSphere = sphere, LifespanMiliseconds = 700, HitEntity = hitEnt, ParticleScale = eInfo.Scale, OwnerEntity = owner, Direction = direction, VoxelExplosionCenter = sphere.Center, ExplosionFlags = eFlags, VoxelCutoutScale = 0.3f, PlaySound = playSound, ApplyForceAndDamage = true, KeepAffectedBlocks = true, CustomEffect = eInfo.CustomParticle, CreateParticleEffect = drawParticles, }; if (hitEnt?.Physics != null) { explosionInfo.Velocity = hitEnt.Physics.LinearVelocity; } MyExplosions.AddExplosion(ref explosionInfo); }
public void DoDamage(float damage, MyDamageType damageType, bool sync) { if (MarkedForClose) { return; } if (sync) { if (!Sync.IsServer) { return; } else { MySyncHelper.DoDamageSynced(this, damage, damageType); return; } } var typeId = Item.Content.TypeId; if (typeId == typeof(MyObjectBuilder_Ore) || typeId == typeof(MyObjectBuilder_Ingot)) { if (Item.Amount < 1) { //TODO: SYNC particle MyParticleEffect effect; if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Construction, out effect)) { effect.WorldMatrix = WorldMatrix; effect.UserScale = 0.4f; MyFloatingObjects.RemoveFloatingObject(this); } } else { if (Sync.IsServer) { MyFloatingObjects.RemoveFloatingObject(this, (MyFixedPoint)damage); } } } else { m_health -= (10 + 90 * DamageMultiplier) * damage; if (m_health < 0) { //TODO: SYNC particle MyParticleEffect effect; if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Construction, out effect)) { effect.WorldMatrix = WorldMatrix; effect.UserScale = 0.4f; } if (Sync.IsServer) { MyFloatingObjects.RemoveFloatingObject(this); } //TODO: dont compare to string? if (Item.Content.SubtypeId == m_explosives && Sync.IsServer) { var expSphere = new BoundingSphere(WorldMatrix.Translation, (float)Item.Amount * 0.01f + 0.5f);// MathHelper.Clamp((float)Item.Amount, 0, 300) * 0.5f); MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = 0, Damage = 800, ExplosionType = MyExplosionTypeEnum.WARHEAD_EXPLOSION_15, ExplosionSphere = expSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadeLevel = 0, HitEntity = this, ParticleScale = 1, OwnerEntity = this, Direction = WorldMatrix.Forward, VoxelExplosionCenter = expSphere.Center, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION, VoxelCutoutScale = 0.5f, PlaySound = true, ApplyForceAndDamage = true, ObjectsRemoveDelayInMiliseconds = 40 }; MyExplosions.AddExplosion(ref info); } if (MyFakes.ENABLE_SCRAP && Sync.IsServer) { if (Item.Content.SubtypeId == ScrapBuilder.SubtypeId) { return; } var contentDefinitionId = Item.Content.GetId(); if (contentDefinitionId.TypeId == typeof(MyObjectBuilder_Component)) { var definition = MyDefinitionManager.Static.GetComponentDefinition((Item.Content as MyObjectBuilder_Component).GetId()); if (MyRandom.Instance.NextFloat() < definition.DropProbability) { MyFloatingObjects.Spawn(new MyInventoryItem(Item.Amount * 0.8f, ScrapBuilder), PositionComp.GetPosition(), WorldMatrix.Forward, WorldMatrix.Up); } } } } } return; }
public override void UpdateBeforeSimulation() { try { MyRender.GetRenderProfiler().StartProfilingBlock("MyCannonShot.UpdateBeforeSimulation"); if (this.WorldMatrix.Translation != m_previousPosition) { MyLine line = new MyLine(this.WorldMatrix.Translation, m_previousPosition); MyDangerZones.Instance.Notify(line, OwnerEntity); } // Kill this missile if (m_isExploded && !m_wasPenetration) { // Create explosion MyExplosion newExplosion = MyExplosions.AddExplosion(); if (newExplosion != null) { float radius = MyMwcUtils.GetRandomFloat(m_ammoProperties.ExplosionRadius - 2, m_ammoProperties.ExplosionRadius + 2); BoundingSphere explosionSphere = new BoundingSphere((m_collisionPoint.HasValue ? m_collisionPoint.Value : GetPosition()), radius); MyExplosionInfo info = new MyExplosionInfo(m_ammoProperties.HealthDamage, m_ammoProperties.ShipDamage, m_ammoProperties.EMPDamage, explosionSphere, m_explosionType, true) { GroupMask = Physics.GroupMask, CascadeLevel = CascadedExplosionLevel, HitEntity = m_collidedEntity, OwnerEntity = this.OwnerEntity, Direction = WorldMatrix.Forward, ParticleScale = 1.5f, VoxelExplosionCenter = explosionSphere.Center + radius * WorldMatrix.Forward * 0.6f, }; info.CreateParticleEffect = !m_hasExplosion; newExplosion.Start(ref info); } if (m_collidedEntity != null && !m_collidedEntity.IsExploded()) { m_collidedEntity.Physics.AddForce( MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, WorldMatrix.Forward * MyMissileConstants.HIT_STRENGTH_IMPULSE, GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 2, MyMissileConstants.HIT_STRENGTH_IMPULSE * MyMwcUtils.GetRandomVector3Normalized()); } MarkForClose(); return; } base.UpdateBeforeSimulation(); // Chech timeout and max distance if ((m_elapsedMiliseconds > MyCannonConstants.SHOT_TIMEOUT) || (Vector3.Distance(this.WorldMatrix.Translation, m_origin) >= m_ammoProperties.MaxTrajectory)) { MarkForClose(); return; } Matrix orientation = GetWorldRotation(); // Update thruster cue/sound MyAudio.UpdateCuePosition(m_thrusterCue, this.WorldMatrix.Translation, orientation.Forward, orientation.Up, this.Physics.LinearVelocity); Vector3 pos = this.WorldMatrix.Translation; if (m_penetratedVoxelMap == null) { if (m_smokeEffect != null) { m_smokeEffect.WorldMatrix = WorldMatrix; } } /* * if (m_wasPenetration) * { * // Create explosion * MyExplosion newExplosion = MyExplosions.AddExplosion(); * if (newExplosion != null) * { * float radius = MyMwcUtils.GetRandomFloat(1, 2); * float particleScale = 2.2f; // must be large enough to cover the hole * newExplosion.StartWithPositionOffset(m_ammoProperties.HealthDamage, m_ammoProperties.ShipDamage, m_ammoProperties.EMPDamage, m_explosionType, m_penetrationOrigin - WorldMatrix.Forward * 2, radius, MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadedExplosionLevel, particleScale: particleScale, hitEntity: m_collidedEntity, ownerEntity: m_ownerEntity); * } * m_wasPenetration = false; * m_hasExplosion = true; * } */ if (m_usedAmmo.AmmoType == MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Proximity_Explosive) { // Look for small ships in shots's proximity BoundingSphere boundingSphere = new BoundingSphere(GetPosition(), MyCannonShotConstants.PROXIMITY_DETECTION_RADIUS); BoundingBox boundingBox = new BoundingBox(); BoundingBox.CreateFromSphere(ref boundingSphere, out boundingBox); var elements = MyEntities.GetElementsInBox(ref boundingBox); for (int i = 0; i < elements.Count; i++) { var rigidBody = (MyPhysicsBody)elements[i].GetRigidBody().m_UserData; var entity = rigidBody.Entity; if (!(entity is MinerWars.AppCode.Game.Entities.MySmallShip)) { continue; } if (entity == OwnerEntity) { continue; } if (entity == this) { continue; } Explode(entity); break; } elements.Clear(); } /* * if (m_usedAmmo.AmmoType == MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Tunnel_Buster) * { * m_cuttingSphere.Center = GetPosition(); * * // We found voxel so lets make tunel into it * MyPhysObjectBase collisionResult = MyEntities.GetIntersectionWithSphere(ref m_cuttingSphere, this, (MySmallShip)Parent); * if (collisionResult is MyVoxelMap) * { * MyVoxelMap voxelMap = collisionResult as MyVoxelMap; * if (m_penetratedVoxelMap == null) * { * m_penetratedVoxelMap = voxelMap; * m_penetrationOrigin = GetPosition(); * } * * Game.Voxels.MyVoxelGenerator.CutOutSphereFast(voxelMap, m_cuttingSphere); * } * } */ /* * if (m_usedAmmo.AmmoType == MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Tunnel_Buster) * { * if (m_penetratedVoxelMap != null) * { * //MyCannonShotConstants.BUSTER_PENETRATION_LENGTH * float busterPenetrationLength = m_ammoProperties.ExplosionRadius * 0.75f; * if (Vector3.Distance(m_penetrationOrigin, GetPosition()) >= busterPenetrationLength) * { * m_collisionPoint = GetPosition(); //We want to explode inside voxel, not on collision point * Explode(m_penetratedVoxelMap); * } * } * } */ } finally { MyRender.GetRenderProfiler().EndProfilingBlock(); } }
/// <summary> /// Updates resource. /// </summary> public override void UpdateBeforeSimulation() { try { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyMissile.UpdateBeforeSimulation"); if (m_isExploded) { if (Sandbox.Game.Multiplayer.Sync.IsServer) { // Create explosion float radius = m_missileAmmoDefinition.MissileExplosionRadius; BoundingSphereD explosionSphere = new BoundingSphereD(m_collisionPoint.HasValue ? m_collisionPoint.Value : PositionComp.GetPosition(), radius); MyEntity ownerEntity = null; var ownerId = Sync.Players.TryGetIdentity(m_owner); if (ownerId != null) { ownerEntity = ownerId.Character; } //MyEntities.TryGetEntityById(m_owner, out ownerEntity); // Call main explosion starter MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = 0, //Damage = m_ammoProperties.Damage, Damage = MyFakes.ENABLE_VOLUMETRIC_EXPLOSION ? m_missileAmmoDefinition.MissileExplosionDamage : 200, ExplosionType = m_explosionType, ExplosionSphere = explosionSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadeLevel = CascadedExplosionLevel, HitEntity = m_collidedEntity, ParticleScale = 0.2f, OwnerEntity = ownerEntity, Direction = WorldMatrix.Forward, VoxelExplosionCenter = explosionSphere.Center + radius * WorldMatrix.Forward * 0.25f, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION, VoxelCutoutScale = 0.3f, PlaySound = true, ApplyForceAndDamage = true }; if (!MarkedToDestroy) { info.ExplosionFlags |= MyExplosionFlags.CREATE_PARTICLE_EFFECT; } MyExplosions.AddExplosion(ref info); if (m_collidedEntity != null && !(m_collidedEntity is MyAmmoBase)) { if (!m_collidedEntity.Physics.IsStatic) { m_collidedEntity.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, 100 * Physics.LinearVelocity, m_collisionPoint, null); } } } Close(); return; } base.UpdateBeforeSimulation(); if (m_missileAmmoDefinition.MissileSkipAcceleration) { Physics.LinearVelocity = WorldMatrix.Forward * m_missileAmmoDefinition.DesiredSpeed * 0.7f; } else { Physics.LinearVelocity += PositionComp.WorldMatrix.Forward * m_missileAmmoDefinition.MissileAcceleration * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; } if (m_smokeEffect == null) { // if (MyCamera.GetDistanceWithFOV(GetPosition()) < 150) { if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Missile, out m_smokeEffect)) { m_smokeEffect.UserScale = 0.3f; var matrix = PositionComp.WorldMatrix; matrix.Translation -= matrix.Forward * m_smokeEffectOffsetMultiplier; m_smokeEffect.WorldMatrix = matrix; //m_smokeEffect.WorldMatrix = PositionComp.WorldMatrix; m_smokeEffect.AutoDelete = false; m_smokeEffect.CalculateDeltaMatrix = true; } } } Physics.AngularVelocity = Vector3.Zero; if ((Vector3.Distance(PositionComp.GetPosition(), m_origin) >= m_maxTrajectory)) { Explode(); return; } } finally { VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } }
public override void Update() { base.Update(); if (m_selfDestruct && MySandboxGame.TotalGamePlayTimeInMilliseconds >= m_selfDestructStartedInTime + SELF_DESTRUCT_TIME_MS) { MyAIComponent.Static.RemoveBot(AgentBot.Player.Id.SerialId, removeCharacter: true); var explosionSphere = new BoundingSphere(AgentBot.Player.GetPosition(), EXPLOSION_RADIUS); MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = EXPLOSION_PLAYER_DAMAGE, Damage = EXPLOSION_DAMAGE, ExplosionType = MyExplosionTypeEnum.BOMB_EXPLOSION, ExplosionSphere = explosionSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadeLevel = 0, HitEntity = AgentBot.Player.Character, ParticleScale = 0.5f, OwnerEntity = AgentBot.Player.Character, Direction = Vector3.Zero, VoxelExplosionCenter = AgentBot.Player.Character.PositionComp.GetPosition(),// + 2 * WorldMatrix.Forward * 0.5f, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION, VoxelCutoutScale = 0.6f, PlaySound = true, ApplyForceAndDamage = true, ObjectsRemoveDelayInMiliseconds = 40 }; MyExplosions.AddExplosion(ref info); } var target = (AiTarget as MyCyberhoundTarget); Debug.Assert(target != null); if (AgentBot.Player.Character.UseNewAnimationSystem == false) // obsolete in new animation system { if ((!target.IsAttacking && !m_lastWasAttacking) && target.HasTarget() && !target.PositionIsNearTarget(AgentBot.Player.Character.PositionComp.GetPosition(), 1.5f)) { if (AgentBot.Navigation.Stuck) { // correct aiming (aim in front of dog) Vector3D houndPosition = AgentBot.Player.Character.PositionComp.GetPosition(); Vector3D gravity = MyGravityProviderSystem.CalculateNaturalGravityInPoint(houndPosition); Vector3D aimingDirection = AgentBot.Player.Character.AimedPoint - houndPosition; Vector3D newAimVector = aimingDirection - gravity * Vector3D.Dot(aimingDirection, gravity) / gravity.LengthSquared(); newAimVector.Normalize(); AgentBot.Navigation.AimAt(null, houndPosition + 100.0f * newAimVector); // play idle animation AgentBot.Player.Character.PlayCharacterAnimation("CyberhoundIdle1", MyBlendOption.Immediate, MyFrameOption.Loop, 0); AgentBot.Player.Character.DisableAnimationCommands(); } else { AgentBot.Player.Character.EnableAnimationCommands(); } } } m_lastWasAttacking = target.IsAttacking; }
public bool DoDamage(float damage, MyStringHash damageType, bool sync, long attackerId) { if (base.MarkedForClose) { return(false); } if (sync) { if (!Sync.IsServer) { return(false); } MySyncDamage.DoDamageSynced(this, damage, damageType, attackerId); return(true); } MyDamageInformation information = new MyDamageInformation(false, damage, damageType, attackerId); if (this.UseDamageSystem) { MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref information); } MyObjectBuilderType typeId = this.Item.Content.TypeId; if ((typeId == typeof(MyObjectBuilder_Ore)) || (typeId == typeof(MyObjectBuilder_Ingot))) { if (this.Item.Amount >= 1) { if (Sync.IsServer) { MyFloatingObjects.RemoveFloatingObject(this, (MyFixedPoint)information.Amount); } } else { MyParticleEffect effect; if (MyParticlesManager.TryCreateParticleEffect("Smoke_Construction", base.WorldMatrix, out effect)) { effect.UserScale = 0.4f; } if (Sync.IsServer) { MyFloatingObjects.RemoveFloatingObject(this); } } } else { this.m_health -= 10f * information.Amount; if (this.UseDamageSystem) { MyDamageSystem.Static.RaiseAfterDamageApplied(this, information); } if (this.m_health < 0f) { MyParticleEffect effect2; MyPhysicalItemDefinition definition2; if (MyParticlesManager.TryCreateParticleEffect("Smoke_Construction", base.WorldMatrix, out effect2)) { effect2.UserScale = 0.4f; } if (Sync.IsServer) { MyFloatingObjects.RemoveFloatingObject(this); } if ((this.Item.Content.SubtypeId == m_explosives) && Sync.IsServer) { BoundingSphere sphere = new BoundingSphere((Vector3)base.WorldMatrix.Translation, (((float)this.Item.Amount) * 0.01f) + 0.5f); MyExplosionInfo explosionInfo = new MyExplosionInfo { PlayerDamage = 0f, Damage = 800f, ExplosionType = MyExplosionTypeEnum.WARHEAD_EXPLOSION_15, ExplosionSphere = sphere, LifespanMiliseconds = 700, HitEntity = this, ParticleScale = 1f, OwnerEntity = this, Direction = new Vector3?((Vector3)base.WorldMatrix.Forward), VoxelExplosionCenter = sphere.Center, ExplosionFlags = MyExplosionFlags.APPLY_DEFORMATION | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.CREATE_DEBRIS, VoxelCutoutScale = 0.5f, PlaySound = true, ApplyForceAndDamage = true, ObjectsRemoveDelayInMiliseconds = 40 }; if (this.Physics != null) { explosionInfo.Velocity = this.Physics.LinearVelocity; } MyExplosions.AddExplosion(ref explosionInfo, true); } if (MyFakes.ENABLE_SCRAP && Sync.IsServer) { if (this.Item.Content.SubtypeId == ScrapBuilder.SubtypeId) { return(true); } if (this.Item.Content.GetId().TypeId == typeof(MyObjectBuilder_Component)) { MyComponentDefinition componentDefinition = MyDefinitionManager.Static.GetComponentDefinition((this.Item.Content as MyObjectBuilder_Component).GetId()); if (MyRandom.Instance.NextFloat() < componentDefinition.DropProbability) { MyFloatingObjects.Spawn(new MyPhysicalInventoryItem(this.Item.Amount * 0.8f, ScrapBuilder, 1f), base.PositionComp.GetPosition(), base.WorldMatrix.Forward, base.WorldMatrix.Up, null, null); } } } if (((this.ItemDefinition != null) && ((this.ItemDefinition.DestroyedPieceId != null) && Sync.IsServer)) && MyDefinitionManager.Static.TryGetPhysicalItemDefinition(this.ItemDefinition.DestroyedPieceId.Value, out definition2)) { MyFloatingObjects.Spawn(definition2, base.WorldMatrix.Translation, base.WorldMatrix.Forward, base.WorldMatrix.Up, this.ItemDefinition.DestroyedPieces, 1f); } if (this.UseDamageSystem) { MyDamageSystem.Static.RaiseDestroyed(this, information); } } } return(true); }
public void Explode() { if (m_isExploded || !MySession.Static.WeaponsEnabled || CubeGrid.Physics == null) return; m_isExploded = true; if (!m_marked) MarkForExplosion(); MyExplosionTypeEnum particleID = MyExplosionTypeEnum.WARHEAD_EXPLOSION_02; if (m_explosionFullSphere.Radius <= 6) { particleID = MyExplosionTypeEnum.WARHEAD_EXPLOSION_02; } else if (m_explosionFullSphere.Radius <= 20) { particleID = MyExplosionTypeEnum.WARHEAD_EXPLOSION_15; } else if (m_explosionFullSphere.Radius <= 40) { particleID = MyExplosionTypeEnum.WARHEAD_EXPLOSION_30; } else { particleID = MyExplosionTypeEnum.WARHEAD_EXPLOSION_50; } // Create explosion MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = 0, //Damage = m_ammoProperties.Damage, Damage = MyFakes.ENABLE_VOLUMETRIC_EXPLOSION ? m_warheadDefinition.WarheadExplosionDamage : 5000, ExplosionType = particleID, ExplosionSphere = m_explosionFullSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadeLevel = 0, HitEntity = this, ParticleScale = 1, OwnerEntity = CubeGrid, Direction = (Vector3)WorldMatrix.Forward, VoxelExplosionCenter = m_explosionFullSphere.Center,// + 2 * WorldMatrix.Forward * 0.5f, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION, VoxelCutoutScale = 1.0f, PlaySound = true, ApplyForceAndDamage = true, ObjectsRemoveDelayInMiliseconds = 40 }; MyExplosions.AddExplosion(ref info); }
/// <summary> /// Updates resource. /// </summary> public override void UpdateBeforeSimulation() { try { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyMissile.UpdateBeforeSimulation"); if (m_isExploded) { if (Sandbox.Game.Multiplayer.Sync.IsServer) { // Create explosion float radius = m_missileAmmoDefinition.MissileExplosionRadius; BoundingSphereD explosionSphere = new BoundingSphereD(m_collisionPoint.HasValue ? m_collisionPoint.Value : PositionComp.GetPosition(), radius); // Call main explosion starter MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = 0, //Damage = m_ammoProperties.Damage, Damage = MyFakes.ENABLE_VOLUMETRIC_EXPLOSION ? m_missileAmmoDefinition.MissileExplosionDamage : 200, ExplosionType = m_explosionType, ExplosionSphere = explosionSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadeLevel = CascadedExplosionLevel, HitEntity = m_collidedEntity, ParticleScale = 0.2f, OwnerEntity = null, Direction = WorldMatrix.Forward, VoxelExplosionCenter = explosionSphere.Center + radius * WorldMatrix.Forward * 0.25f, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION, VoxelCutoutScale = 0.3f, PlaySound = true, ApplyForceAndDamage = true }; if (!MarkedToDestroy) info.ExplosionFlags |= MyExplosionFlags.CREATE_PARTICLE_EFFECT; MyExplosions.AddExplosion(ref info); if (m_collidedEntity != null && !(m_collidedEntity is MyAmmoBase)) { if (!m_collidedEntity.Physics.IsStatic) { m_collidedEntity.Physics.AddForce(Engine.Physics.MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, 100 * Physics.LinearVelocity, m_collisionPoint, null); } } } Close(); return; } base.UpdateBeforeSimulation(); if (m_missileAmmoDefinition.MissileSkipAcceleration) Physics.LinearVelocity = WorldMatrix.Forward * m_missileAmmoDefinition.DesiredSpeed * 0.7f; else Physics.LinearVelocity += PositionComp.WorldMatrix.Forward * m_missileAmmoDefinition.MissileAcceleration * MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; if (m_smokeEffect == null) { // if (MyCamera.GetDistanceWithFOV(GetPosition()) < 150) { if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Missile, out m_smokeEffect)) { m_smokeEffect.UserScale = 0.3f; var matrix = PositionComp.WorldMatrix; matrix.Translation -= matrix.Forward * m_smokeEffectOffsetMultiplier; m_smokeEffect.WorldMatrix = matrix; //m_smokeEffect.WorldMatrix = PositionComp.WorldMatrix; m_smokeEffect.AutoDelete = false; m_smokeEffect.CalculateDeltaMatrix = true; } } } Physics.AngularVelocity = Vector3.Zero; if ((Vector3.Distance(PositionComp.GetPosition(), m_origin) >= m_maxTrajectory)) { Explode(); return; } } finally { VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } }
/// <summary> /// Updates resource. /// </summary> public override void UpdateBeforeSimulation() { try { MyRender.GetRenderProfiler().StartProfilingBlock("MyMissile.UpdateBeforeSimulation"); //Large ship weapons wont make bots curious if ((!(OwnerEntity is MyLargeShipMissileLauncherBarrel)) && MyMwcUtils.HasValidLength(this.WorldMatrix.Translation - m_previousPosition)) { MyLine line = new MyLine(this.WorldMatrix.Translation, m_previousPosition); MyDangerZones.Instance.Notify(line, OwnerEntity); } if (m_isExploded) { // Create explosion MyExplosion newExplosion = MyExplosions.AddExplosion(); if (newExplosion != null) { float radius = m_ammoProperties.ExplosionRadius; // Explicitly on Marek's request (ticket 4740) bool amplifyRadius = m_collidedEntity != null ? MyFactions.GetFactionsRelation(m_collidedEntity.Faction, Faction) != MyFactionRelationEnum.Friend : false; if (amplifyRadius) { radius *= 2; } BoundingSphere explosionSphere = new BoundingSphere(m_collisionPoint.HasValue ? m_collisionPoint.Value : GetPosition(), radius); // Call main explosion starter MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = m_ammoProperties.HealthDamage, Damage = m_ammoProperties.ShipDamage, EmpDamage = m_ammoProperties.EMPDamage, ExplosionType = m_explosionType, ExplosionSphere = explosionSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, ExplosionForceDirection = MyExplosionForceDirection.EXPLOSION, GroupMask = Physics.GroupMask, CascadeLevel = CascadedExplosionLevel, HitEntity = m_collidedEntity, ParticleScale = 1.5f, OwnerEntity = this.OwnerEntity, Direction = WorldMatrix.Forward, VoxelExplosionCenter = explosionSphere.Center + m_ammoProperties.ExplosionRadius * WorldMatrix.Forward * 0.5f, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT, VoxelCutoutScale = amplifyRadius ? 0.5f : 1.0f, PlaySound = true, }; newExplosion.Start(ref info); } if (m_collidedEntity != null && !m_collidedEntity.IsExploded()) { m_collidedEntity.Physics.AddForce( MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, WorldMatrix.Forward * MyMissileConstants.HIT_STRENGTH_IMPULSE, GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 2, MyMissileConstants.HIT_STRENGTH_IMPULSE * MyMwcUtils.GetRandomVector3Normalized()); m_collidedEntity.OnClose -= m_collidedEntity_OnClose; } MarkForClose(); return; } bool firstTargetting = m_elapsedMiliseconds == 0; base.UpdateBeforeSimulation(); m_missileTargetUpdate += MyConstants.PHYSICS_STEP_SIZE_IN_MILLISECONDS; if (m_missileTargetUpdate >= MyGuidedMissileConstants.MISSILE_TARGET_UPDATE_INTERVAL_IN_MS || firstTargetting) { m_missileTargetUpdate = 0; switch (m_missileType) { case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Radar_Detection: { MySmallShip targetShip = m_targetEntity as MySmallShip; if (targetShip != null && targetShip.IsRadarJammed()) { m_targetEntity = null; } } break; case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Engine_Detection: { m_targetEntities.Clear(); Matrix proj = Matrix.CreateOrthographic(MyGuidedMissileConstants.ENGINE_GUIDED_MISSILE_RADIUS, MyGuidedMissileConstants.ENGINE_GUIDED_MISSILE_RADIUS, 0, 1000); Matrix view = Matrix.CreateLookAt(GetPosition(), GetPosition() + WorldMatrix.Forward, WorldMatrix.Up); m_visualFrustum.Matrix = view * proj; MyEntities.GetAllIntersectionWithBoundingFrustum(ref m_visualFrustum, m_targetEntities); if (m_targetEntities.Contains(m_targetEntity)) break; MyEntity target = null; float closestToMissileDirection = float.MaxValue; foreach (MyEntity entity in m_targetEntities) { if (CanTarget(entity)) { MySmallShip targetShip = entity as MySmallShip; if (targetShip != null) { if ((targetShip.IsEngineTurnedOff())) continue; } Vector3 targetPos = entity.GetPosition(); Vector3 missilePos = this.GetPosition(); Vector3 missilePosEnd = this.GetPosition() + this.WorldMatrix.Forward * 10000; Vector3 closestPos = MyUtils.GetClosestPointOnLine(ref missilePos, ref missilePosEnd, ref targetPos); float distance = Vector3.Distance(closestPos, targetPos); if (distance < closestToMissileDirection) { closestToMissileDirection = distance; target = entity; } } } UpdateTarget(target); } break; case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Visual_Detection: { Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(MyGuidedMissileConstants.VISUAL_GUIDED_MISSILE_FOV), 1, 10, MyGuidedMissileConstants.VISUAL_GUIDED_MISSILE_RANGE); m_visualFrustum.Matrix = Matrix.Invert(WorldMatrix) * projectionMatrix; m_targetEntities.Clear(); MyEntities.GetAllIntersectionWithBoundingFrustum(ref m_visualFrustum, m_targetEntities); int testsLimit = 8; if (m_targetEntities.Contains(m_targetEntity)) break; MyEntity target = null; //looks better if missile gets "lost" float closestToMissileDirection = float.MaxValue; foreach (MyEntity entity in m_targetEntities) { if (!CanTarget(entity)) continue; if (testsLimit-- == 0) break; if (MyEnemyTargeting.CanSee(this, entity) == null) { Vector3 targetPos = entity.GetPosition(); Vector3 missilePos = this.GetPosition(); Vector3 missilePosEnd = this.GetPosition() + this.WorldMatrix.Forward * 10000; Vector3 closestPos = MyUtils.GetClosestPointOnLine(ref missilePos, ref missilePosEnd, ref targetPos); float distance = Vector3.Distance(closestPos, targetPos); if (distance < closestToMissileDirection) { closestToMissileDirection = distance; target = entity; } } } UpdateTarget(target); } break; } } if ((m_initTime - m_elapsedMiliseconds) > 0) { //simulating missile launch and engine ignition MyEntity owner = OwnerEntity; if (owner != null) { Vector3 transformedInitDir = Vector3.TransformNormal(m_initDir, owner.WorldMatrix); // Vector3 initialVelocity = Vector3.Zero; if (owner.Physics != null) { initialVelocity = owner.Physics.LinearVelocity; } Physics.LinearVelocity = transformedInitDir * m_ammoProperties.InitialSpeed + initialVelocity; } } else { // This will help blend "initial velocity" and "thrust velocity" so at the beginning missile is powered by initiatal velocity only, but later float velocityBlend = MathHelper.Clamp((float)(m_elapsedMiliseconds - m_initTime) / m_blendVelocities, 0, 1); if (velocityBlend == 1.0f) { m_actualSpeed = m_ammoProperties.DesiredSpeed; } else { float initialSpeed = 0.0f; MyEntity owner = OwnerEntity; if (owner != null) { if (owner.Physics != null) { initialSpeed = owner.Physics.LinearVelocity.Length(); } } m_actualSpeed = velocityBlend * m_ammoProperties.DesiredSpeed + ((1.0f - velocityBlend) * (m_ammoProperties.InitialSpeed + initialSpeed)); if (m_missileType != MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Missile_Basic && m_smokeEffect == null) { // if (MyCamera.GetDistanceWithFOV(GetPosition()) < 150) { /* MyParticleEffect startEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_MissileStart); startEffect.WorldMatrix = WorldMatrix; */ m_smokeEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Missile); m_smokeEffect.WorldMatrix = WorldMatrix; m_smokeEffect.AutoDelete = false; } } } m_desiredVelocity = GetDesiredVelocity(m_targetEntity); Physics.LinearVelocity = m_desiredVelocity * m_actualSpeed * 1.0f; } Physics.AngularVelocity = Vector3.Zero; if ((m_elapsedMiliseconds > m_missileTimeout) || (Vector3.Distance(GetPosition(), m_origin) >= m_maxTrajectory)) { Explode(); return; } if (m_smokeEffect != null) { Matrix smokeMatrix = Matrix.CreateWorld(WorldMatrix.Translation - 0.5f * WorldMatrix.Forward, WorldMatrix.Forward, WorldMatrix.Up); m_smokeEffect.WorldMatrix = smokeMatrix; } if (m_targetEntity != null) { if (m_targetEntity.Physics != null) m_targetVelocity = m_targetEntity.Physics.LinearVelocity; else m_targetVelocity = Vector3.Zero; } } finally { MyRender.GetRenderProfiler().EndProfilingBlock(); } }
/// <summary> /// Updates resource. /// </summary> public override void UpdateBeforeSimulation() { try { MyRender.GetRenderProfiler().StartProfilingBlock("MyMissile.UpdateBeforeSimulation"); //Large ship weapons wont make bots curious if ((!(OwnerEntity is MyLargeShipMissileLauncherBarrel)) && MyMwcUtils.HasValidLength(this.WorldMatrix.Translation - m_previousPosition)) { MyLine line = new MyLine(this.WorldMatrix.Translation, m_previousPosition); MyDangerZones.Instance.Notify(line, OwnerEntity); } if (m_isExploded) { // Create explosion MyExplosion newExplosion = MyExplosions.AddExplosion(); if (newExplosion != null) { float radius = m_ammoProperties.ExplosionRadius; // Explicitly on Marek's request (ticket 4740) bool amplifyRadius = m_collidedEntity != null?MyFactions.GetFactionsRelation(m_collidedEntity.Faction, Faction) != MyFactionRelationEnum.Friend : false; if (amplifyRadius) { radius *= 2; } BoundingSphere explosionSphere = new BoundingSphere(m_collisionPoint.HasValue ? m_collisionPoint.Value : GetPosition(), radius); // Call main explosion starter MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = m_ammoProperties.HealthDamage, Damage = m_ammoProperties.ShipDamage, EmpDamage = m_ammoProperties.EMPDamage, ExplosionType = m_explosionType, ExplosionSphere = explosionSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, ExplosionForceDirection = MyExplosionForceDirection.EXPLOSION, GroupMask = Physics.GroupMask, CascadeLevel = CascadedExplosionLevel, HitEntity = m_collidedEntity, ParticleScale = 1.5f, OwnerEntity = this.OwnerEntity, Direction = WorldMatrix.Forward, VoxelExplosionCenter = explosionSphere.Center + m_ammoProperties.ExplosionRadius * WorldMatrix.Forward * 0.5f, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT, VoxelCutoutScale = amplifyRadius ? 0.5f : 1.0f, PlaySound = true, }; newExplosion.Start(ref info); } if (m_collidedEntity != null && !m_collidedEntity.IsExploded()) { m_collidedEntity.Physics.AddForce( MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, WorldMatrix.Forward * MyMissileConstants.HIT_STRENGTH_IMPULSE, GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 2, MyMissileConstants.HIT_STRENGTH_IMPULSE * MyMwcUtils.GetRandomVector3Normalized()); m_collidedEntity.OnClose -= m_collidedEntity_OnClose; } MarkForClose(); return; } bool firstTargetting = m_elapsedMiliseconds == 0; base.UpdateBeforeSimulation(); m_missileTargetUpdate += MyConstants.PHYSICS_STEP_SIZE_IN_MILLISECONDS; if (m_missileTargetUpdate >= MyGuidedMissileConstants.MISSILE_TARGET_UPDATE_INTERVAL_IN_MS || firstTargetting) { m_missileTargetUpdate = 0; switch (m_missileType) { case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Radar_Detection: { MySmallShip targetShip = m_targetEntity as MySmallShip; if (targetShip != null && targetShip.IsRadarJammed()) { m_targetEntity = null; } } break; case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Engine_Detection: { m_targetEntities.Clear(); Matrix proj = Matrix.CreateOrthographic(MyGuidedMissileConstants.ENGINE_GUIDED_MISSILE_RADIUS, MyGuidedMissileConstants.ENGINE_GUIDED_MISSILE_RADIUS, 0, 1000); Matrix view = Matrix.CreateLookAt(GetPosition(), GetPosition() + WorldMatrix.Forward, WorldMatrix.Up); m_visualFrustum.Matrix = view * proj; MyEntities.GetAllIntersectionWithBoundingFrustum(ref m_visualFrustum, m_targetEntities); if (m_targetEntities.Contains(m_targetEntity)) { break; } MyEntity target = null; float closestToMissileDirection = float.MaxValue; foreach (MyEntity entity in m_targetEntities) { if (CanTarget(entity)) { MySmallShip targetShip = entity as MySmallShip; if (targetShip != null) { if ((targetShip.IsEngineTurnedOff())) { continue; } } Vector3 targetPos = entity.GetPosition(); Vector3 missilePos = this.GetPosition(); Vector3 missilePosEnd = this.GetPosition() + this.WorldMatrix.Forward * 10000; Vector3 closestPos = MyUtils.GetClosestPointOnLine(ref missilePos, ref missilePosEnd, ref targetPos); float distance = Vector3.Distance(closestPos, targetPos); if (distance < closestToMissileDirection) { closestToMissileDirection = distance; target = entity; } } } UpdateTarget(target); } break; case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Visual_Detection: { Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(MyGuidedMissileConstants.VISUAL_GUIDED_MISSILE_FOV), 1, 10, MyGuidedMissileConstants.VISUAL_GUIDED_MISSILE_RANGE); m_visualFrustum.Matrix = Matrix.Invert(WorldMatrix) * projectionMatrix; m_targetEntities.Clear(); MyEntities.GetAllIntersectionWithBoundingFrustum(ref m_visualFrustum, m_targetEntities); int testsLimit = 8; if (m_targetEntities.Contains(m_targetEntity)) { break; } MyEntity target = null; //looks better if missile gets "lost" float closestToMissileDirection = float.MaxValue; foreach (MyEntity entity in m_targetEntities) { if (!CanTarget(entity)) { continue; } if (testsLimit-- == 0) { break; } if (MyEnemyTargeting.CanSee(this, entity) == null) { Vector3 targetPos = entity.GetPosition(); Vector3 missilePos = this.GetPosition(); Vector3 missilePosEnd = this.GetPosition() + this.WorldMatrix.Forward * 10000; Vector3 closestPos = MyUtils.GetClosestPointOnLine(ref missilePos, ref missilePosEnd, ref targetPos); float distance = Vector3.Distance(closestPos, targetPos); if (distance < closestToMissileDirection) { closestToMissileDirection = distance; target = entity; } } } UpdateTarget(target); } break; } } if ((m_initTime - m_elapsedMiliseconds) > 0) { //simulating missile launch and engine ignition MyEntity owner = OwnerEntity; if (owner != null) { Vector3 transformedInitDir = Vector3.TransformNormal(m_initDir, owner.WorldMatrix); // Vector3 initialVelocity = Vector3.Zero; if (owner.Physics != null) { initialVelocity = owner.Physics.LinearVelocity; } Physics.LinearVelocity = transformedInitDir * m_ammoProperties.InitialSpeed + initialVelocity; } } else { // This will help blend "initial velocity" and "thrust velocity" so at the beginning missile is powered by initiatal velocity only, but later float velocityBlend = MathHelper.Clamp((float)(m_elapsedMiliseconds - m_initTime) / m_blendVelocities, 0, 1); if (velocityBlend == 1.0f) { m_actualSpeed = m_ammoProperties.DesiredSpeed; } else { float initialSpeed = 0.0f; MyEntity owner = OwnerEntity; if (owner != null) { if (owner.Physics != null) { initialSpeed = owner.Physics.LinearVelocity.Length(); } } m_actualSpeed = velocityBlend * m_ammoProperties.DesiredSpeed + ((1.0f - velocityBlend) * (m_ammoProperties.InitialSpeed + initialSpeed)); if (m_missileType != MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Missile_Basic && m_smokeEffect == null) { // if (MyCamera.GetDistanceWithFOV(GetPosition()) < 150) { /* * MyParticleEffect startEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_MissileStart); * startEffect.WorldMatrix = WorldMatrix; */ m_smokeEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Missile); m_smokeEffect.WorldMatrix = WorldMatrix; m_smokeEffect.AutoDelete = false; } } } m_desiredVelocity = GetDesiredVelocity(m_targetEntity); Physics.LinearVelocity = m_desiredVelocity * m_actualSpeed * 1.0f; } Physics.AngularVelocity = Vector3.Zero; if ((m_elapsedMiliseconds > m_missileTimeout) || (Vector3.Distance(GetPosition(), m_origin) >= m_maxTrajectory)) { Explode(); return; } if (m_smokeEffect != null) { Matrix smokeMatrix = Matrix.CreateWorld(WorldMatrix.Translation - 0.5f * WorldMatrix.Forward, WorldMatrix.Forward, WorldMatrix.Up); m_smokeEffect.WorldMatrix = smokeMatrix; } if (m_targetEntity != null) { if (m_targetEntity.Physics != null) { m_targetVelocity = m_targetEntity.Physics.LinearVelocity; } else { m_targetVelocity = Vector3.Zero; } } } finally { MyRender.GetRenderProfiler().EndProfilingBlock(); } }