public static MyParticleEffect CreateParticleEffect(int id, bool userDraw = false) { //Because XNA can call Update() more times per frame WaitUntilUpdateCompleted(); MyParticleEffect effect = MyParticlesLibrary.CreateParticleEffect(id); // This could more likely be caused by empty generation pool (which is allowed) then error in xml //System.Diagnostics.Debug.Assert(effect.GetGenerations().Count > 0); if (effect != null) { System.Diagnostics.Debug.Assert(m_updaterTask.IsComplete == true); if (!userDraw) { m_particleEffectsForUpdate.Add(effect); } else { effect.AutoDelete = false; } effect.UserDraw = userDraw; m_particleEffectsAll.Add(effect); } return(effect); }
public void Start(Vector3 direction, int? trailEffectId) { this.Physics.LinearVelocity = direction; this.Physics.AngularVelocity = new Vector3(MyMwcUtils.GetRandomFloat(0.2f, 1.5f), MyMwcUtils.GetRandomFloat(0.2f, 1.5f), 0); if (m_size == 0) { m_size = this.WorldVolume.Radius; } if (trailEffectId != null) { m_trailEffect = MyParticlesManager.CreateParticleEffect(trailEffectId.Value); m_trailEffect.AutoDelete = true; m_trailEffect.UserScale = this.WorldVolume.Radius / 10; m_trailEffect.UserBirthMultiplier /= 2; m_trailEffect.WorldMatrix = this.WorldMatrix;// worldMatrix; } m_burningCue = MyAudio.AddCue3D(MySoundCuesEnum.SfxMeteorFly, this.GetPosition(), this.GetForward(), Vector3.Up, direction); m_startTime = MyMinerGame.TotalGamePlayTimeInMilliseconds; if (MyMultiplayerGameplay.IsHosting) { MyMultiplayerGameplay.Static.NewEntity(GetObjectBuilder(true), WorldMatrix); } }
public MyParticleEffect CreateInstance() { MyParticleEffect effect = MyParticlesManager.EffectsPool.Allocate(); effect.Start(m_particleID); effect.Name = Name; effect.Enabled = Enabled; effect.SetLength(GetLength()); effect.SetPreload(GetPreload()); effect.LowRes = LowRes; foreach (MyParticleGeneration generation in m_generations) { MyParticleGeneration gen = generation.CreateInstance(effect); if (gen != null) { effect.AddGeneration(gen); } } if (m_instances == null) { m_instances = new List <MyParticleEffect>(); } m_instances.Add(effect); return(effect); }
public override bool Shot(MyMwcObjectBuilder_SmallShip_Ammo usedAmmo) { if (usedAmmo == null || (MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeShoot) < MyMachineGunConstants.SHOT_INTERVAL_IN_MILISECONDS && !IsDummy) return false; if (m_smokeEffect == null) { if (MyCamera.GetDistanceWithFOV(GetPosition()) < 150) { m_smokeEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Autocannon); m_smokeEffect.WorldMatrix = WorldMatrix; m_smokeEffect.OnDelete += OnSmokeEffectDelete; } } MyAmmoProperties ammoProperties = MyAmmoConstants.GetAmmoProperties(usedAmmo.AmmoType); if (MyMwcFinalBuildConstants.ENABLE_TRAILER_SAVE) { MinerWars.AppCode.Game.Trailer.MyTrailerSave.UpdateGunShot(this.Parent, Trailer.MyTrailerGunsShotTypeEnum.PROJECTILE); } AddProjectile(ammoProperties, this); m_lastTimeShoot = MyMinerGame.TotalGamePlayTimeInMilliseconds; StartLoopSound(ammoProperties.ShotSound); return true; }
public void RemoveInstance(MyParticleEffect effect) { if (m_instances != null) { if (m_instances.Contains(effect)) { m_instances.Remove(effect); } } }
public void Close() { Clear(); for (int i = 0; i < m_properties.Length; i++) { m_properties[i] = null; } m_emitter.Close(); m_effect = null; }
public override void UpdateBeforeSimulation() { base.UpdateBeforeSimulation(); if (m_elapsedMiliseconds > MyIlluminatingShellsConstants.MAX_LIVING_TIME + MyIlluminatingShellsConstants.DIYNG_TIME) { if (m_particleEffect != null) { m_particleEffect.Stop(); m_particleEffect = null; } // Free the light if (m_light != null) { MyLights.RemoveLight(m_light); m_light = null; } MarkForClose(); } // Update light position if (m_light != null) { // Aggro near bots if (m_light.LightOn) { if (this.WorldMatrix.Translation != m_previousPosition) { MyLine line = new MyLine(m_previousPosition, WorldMatrix.Translation); MyDangerZones.Instance.Notify(line, OwnerEntity); } } if ((m_elapsedMiliseconds > MyIlluminatingShellsConstants.MAX_LIVING_TIME) && (m_elapsedMiliseconds < MyIlluminatingShellsConstants.MAX_LIVING_TIME + MyIlluminatingShellsConstants.DIYNG_TIME)) { m_light.LightOn = MyMwcUtils.GetRandomBool(2); m_particleEffect.UserScale = m_light.LightOn ? 1.0f : 0.001f; } m_light.SetPosition(GetPosition()); m_light.Color = MyIlluminatingShellsConstants.LIGHT_COLOR; m_light.Range = MyIlluminatingShellsConstants.LIGHT_RADIUS; } }
static public void RemoveParticleEffectInstance(MyParticleEffect effect) { effect.Close(false); //if (effect.Enabled) { if (m_libraryEffects[effect.GetID()].GetInstances().Contains(effect)) { MyParticlesManager.EffectsPool.Deallocate(effect); m_libraryEffects[effect.GetID()].RemoveInstance(effect); } else { System.Diagnostics.Debug.Assert(false, "Effect deleted twice!"); } } }
protected override void InitPrefab(string displayName, Vector3 relativePosition, Matrix localOrientation, MyMwcObjectBuilder_PrefabBase objectBuilder, MyPrefabConfiguration prefabConfig) { MyPrefabConfigurationParticles prefabParticleConfig = prefabConfig as MyPrefabConfigurationParticles; m_lastTimeParticle = MyMinerGame.TotalGamePlayTimeInMilliseconds; MyModel model = MyModels.GetModelOnlyDummies(prefabParticleConfig.ModelLod0Enum); m_pointLocalMatrix = Matrix.Identity; foreach (KeyValuePair<string, MyModelDummy> pair in model.Dummies) { m_pointLocalMatrix = pair.Value.Matrix; } m_particleEffect = MyParticlesManager.CreateParticleEffect((int)prefabParticleConfig.EffectID, true); m_particleEffect.AutoDelete = false; m_particleEffect.WorldMatrix = WorldMatrix; }
public void Start(MyParticleEffect effect) { System.Diagnostics.Debug.Assert(m_effect == null); System.Diagnostics.Debug.Assert(m_particles.Count == 0); System.Diagnostics.Debug.Assert(Birth == null); m_effect = effect; m_name = "ParticleGeneration"; m_emitter.Start(); m_lastEffectPosition = null; IsInherited = false; m_birthRate = 0.0f; m_particlesToCreate = 0.0f; m_AABB = m_AABB.CreateInvalid(); }
public MyParticleGeneration Duplicate(MyParticleEffect effect) { MyParticleGeneration generation = MyParticlesManager.GenerationsPool.Allocate(); generation.Start(effect); generation.Name = Name; for (int i = 0; i < m_properties.Length; i++) { generation.m_properties[i] = m_properties[i].Duplicate(); } m_emitter.Duplicate(generation.m_emitter); return(generation); }
public MyParticleEffect Duplicate() { MyParticleEffect effect = MyParticlesManager.EffectsPool.Allocate(); effect.Start(0); effect.Name = Name; effect.m_preload = m_preload; effect.m_length = m_length; foreach (MyParticleGeneration generation in m_generations) { MyParticleGeneration duplicatedGeneration = generation.Duplicate(effect); effect.AddGeneration(duplicatedGeneration); } return(effect); }
// This method realy initiates/starts the missile // IMPORTANT: Direction vector must be normalized! public void Start(Vector3 position, Vector3 initialVelocity, Vector3 direction, float impulseMultiplier, MyEntity owner) { base.Start(position, initialVelocity, direction, impulseMultiplier, owner, MyTextsWrapper.Get(MyTextsWrapperEnum.IlluminatingShellHud)); this.Physics.AddForce( MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, initialVelocity * 2, position, null); // Setting a torque here make trouble for recycled mines... so for now we don't use it. Maybe in future in other physics engine than JLX. m_light = MyLights.AddLight(); if (m_light != null) { m_light.Start(MyLight.LightTypeEnum.PointLight, position, MyIlluminatingShellsConstants.LIGHT_COLOR, 1, MyIlluminatingShellsConstants.LIGHT_RADIUS); } m_particleEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.UniversalLauncher_IlluminatingShell); m_particleEffect.WorldMatrix = WorldMatrix; }
public static void RemoveParticleEffect(MyParticleEffect effect, bool fromBackground = false) { //System.Diagnostics.Debug.Assert(m_updateCompleted == true); //Because XNA can call Update() more times per frame if (!fromBackground) { WaitUntilUpdateCompleted(); } if (!effect.UserDraw /*&& effect.Enabled*/) { System.Diagnostics.Debug.Assert(m_particleEffectsForUpdate.Contains(effect)); m_particleEffectsForUpdate.Remove(effect); } m_particleEffectsAll.Remove(effect); MyParticlesLibrary.RemoveParticleEffectInstance(effect); }
static public void Deserialize(XmlReader reader) { Close(); RedundancyDetected = 0; reader.ReadStartElement(); //MinerWarsParticlesLibrary int version = reader.ReadElementContentAsInt(); reader.ReadStartElement(); //ParticleEffects while (reader.NodeType != XmlNodeType.EndElement) { MyParticleEffect effect = MyParticlesManager.EffectsPool.Allocate(); effect.Deserialize(reader); m_libraryEffects.Add(effect.GetID(), effect); } reader.ReadEndElement(); //ParticleEffects reader.ReadEndElement(); //root }
public MyParticleGeneration CreateInstance(MyParticleEffect effect) { MyParticleGeneration generation = MyParticlesManager.GenerationsPool.Allocate(true); if (generation == null) { return(null); } generation.Start(effect); generation.Name = Name; for (int i = 0; i < m_properties.Length; i++) { generation.m_properties[i] = m_properties[i]; } generation.m_emitter.CreateInstance(m_emitter); return(generation); }
public override void Close() { base.Close(); if (m_particleEffect != null) { MyParticlesManager.RemoveParticleEffect(m_particleEffect); m_particleEffect = null; } }
// This method realy initiates/starts the missile // IMPORTANT: Direction vector must be normalized! public void Start(MyAmmoProperties ammoProperties, MyEntity ignoreEntity, Vector3 origin, Vector3 initialVelocity, Vector3 directionNormalized, bool groupStart, float thicknessMultiplier, MyEntity weapon ) { if (MySession.Is25DSector) { directionNormalized.Y = 0; directionNormalized.Normalize(); initialVelocity.Y = 0; } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Projectile.Start"); m_ammoProperties = ammoProperties; m_state = MyProjectileStateEnum.ACTIVE; m_ignorePhysObject = ignoreEntity; m_origin = origin; m_position = origin; m_externalAddition = 1.0f; m_weapon = weapon; IsDummy = weapon != null && weapon.IsDummy; LengthMultiplier = 1; FrontBillboardMaterial = null; FrontBillboardSize = 1; BlendByCameraDirection = false; Vector3? correctedDirection = null; if (MyGameplayConstants.GameplayDifficultyProfile.EnableAimCorrection) { MyEntity entityToCheck; if (MyGuiScreenGamePlay.Static.ControlledEntity is MyPrefabLargeWeapon) { entityToCheck = (MyGuiScreenGamePlay.Static.ControlledEntity as MyPrefabLargeWeapon).GetGun(); } else { entityToCheck = MyGuiScreenGamePlay.Static.ControlledEntity; } // TODO: Make proper test that source off projectile is player ship, testing ignore object is STUPID! if (m_ammoProperties.AllowAimCorrection && (ignoreEntity == entityToCheck)) // Autoaim only available for player { MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Projectile.Start autoaim generic"); //Intersection ignores children of "ignoreEntity", thus we must not hit our own barrels correctedDirection = MyEntities.GetDirectionFromStartPointToHitPointOfNearestObject(ignoreEntity, origin, m_ammoProperties.MaxTrajectory); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); } } if (correctedDirection != null) { m_directionNormalized = correctedDirection.Value; } else { m_directionNormalized = directionNormalized; } m_speed = ammoProperties.DesiredSpeed * (ammoProperties.SpeedVar > 0.0f ? MyMwcUtils.GetRandomFloat(1 - ammoProperties.SpeedVar, 1 + ammoProperties.SpeedVar) : 1.0f); m_externalVelocity = initialVelocity; m_velocity = m_directionNormalized * m_speed; m_maxTrajectory = ammoProperties.MaxTrajectory * MyMwcUtils.GetRandomFloat(0.8f, 1.2f); // +/- 20% m_thicknessMultiplier = thicknessMultiplier; m_checkIntersectionIndex = checkIntersectionCounter % CHECK_INTERSECTION_INTERVAL; checkIntersectionCounter += 3; m_positionChecked = false; m_groupStart = groupStart; if (groupStart) { m_trailEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Trail_Shotgun); m_trailEffect.AutoDelete = false; m_trailEffect.WorldMatrix = Matrix.CreateTranslation(m_position); } if (groupStart) { LastProjectileGroup = m_ownGroup; m_ownGroup.Killed = false; } if (LastProjectileGroup != null && LastProjectileGroup.Killed == false) { m_sharedGroup = LastProjectileGroup; } else m_sharedGroup = null; MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); }
// Kills this missile. Must be called at her end (after explosion or timeout) public override void Close() { base.Close(); if (m_collidedEntity != null) { m_collidedEntity.OnClose -= m_collidedEntityClosedHandler; m_collidedEntity = null; } // Free the light if (m_light != null) { MyLights.RemoveLight(m_light); m_light = null; } // Stop thruster cue if ((m_thrusterCue != null) && (m_thrusterCue.Value.IsPlaying == true)) { m_thrusterCue.Value.Stop(SharpDX.XACT3.StopFlags.Immediate); } if (m_smokeEffect != null) { m_smokeEffect.Stop(); m_smokeEffect = null; } MyCannonShots.Remove(this); }
public override void Close() { if (m_dangerZoneId != -1) { MyDangerZones.Instance.Unregister(this); m_dangerZoneId = -1; } MyEntities.OnEntityRemove -= MyEntities_OnEntityRemove; MySession.Static.LinkEntities -= OnLinkEntities; if (Followers.Count > 0) { MySmallShipBot newLeader = Followers[0]; Debug.Assert(newLeader != this); newLeader.Leader = null; Debug.Assert(!newLeader.Closed); if (m_aiTemplate.IsPatroling() && newLeader.WaypointPath != null) { SetWaypointPath(newLeader.WaypointPath.Name); newLeader.Patrol(); } else { Idle(); } var followers = Followers.ToArray(); for (int i = 1; i < followers.Length; i++) { followers[i].Follow(newLeader); } Followers.Remove(newLeader); Debug.Assert(Followers.Count == 0); } StopFollow(); if (m_currentBehavior != null) { m_currentBehavior.Close(this); m_currentBehavior = null; } if (m_biochemEffect != null) { m_biochemEffect.Stop(); m_biochemEffect = null; } WaypointPath = null; if (!IsSleeping) MySmallShipBot.TotalAliveBots--; base.Close(); }
public static void AddParticleEffect(MyParticleEffect effect) { m_libraryEffects.Add(effect.GetID(), effect); }
public static void RemoveParticleEffect(MyParticleEffect effect) { RemoveParticleEffect(effect.GetID()); }
// 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; }
public static void CustomDraw(MyParticleEffect effect) { System.Diagnostics.Debug.Assert(effect != null); m_effectsForCustomDraw.Add(effect); }
// Kills this missile. Must be called at her end (after explosion or timeout) // This method must be called when this object dies or is removed // E.g. it removes lights, sounds, etc public override void Close() { UpdateTarget(null); base.Close(); this.Physics.Clear(); MyMissiles.Remove(this); if (m_collidedEntity != null) { m_collidedEntity.OnClose -= m_collidedEntity_OnClose; m_collidedEntity = null; } if (m_smokeEffect != null) { m_smokeEffect.Stop(); m_smokeEffect = null; } // Free the light if (m_light != null) { MyLights.RemoveLight(m_light); m_light = null; } // Stop thruster cue if ((m_thrusterCue != null) && (m_thrusterCue.Value.IsPlaying == true)) { m_thrusterCue.Value.Stop(SharpDX.XACT3.StopFlags.Immediate); } m_thrusterCue = null; }
public override void Close() { if (m_smokeEffect != null) { m_smokeEffect.Stop(); m_smokeEffect = null; } base.Close(); }
private void UpdateDamageEffect() { var damageRatio = GetDamageRatio(); bool threshold = damageRatio > MyShipConstants.DAMAGED_HEALTH; if (m_damageEffect == null && threshold) { m_damageEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Damage_Smoke); m_damageEffect.AutoDelete = false; m_damageEffect.UserBirthMultiplier = 0; m_damageEffect.WorldMatrix = m_damageEffectLocalMatrix != null ? m_damageEffectLocalMatrix.Value * WorldMatrix : WorldMatrix; } }
/// <summary> /// /// </summary> public override void Close() { Debug.Assert(!Closed, "Closing already closed entity"); MySession.Static.Inventory.OnInventoryContentChange -= CheckPointInventory_OnInventoryContentChange; if (ToolKits != null) { ToolKits.Close(); ToolKits = null; } TradeDetector = null; BuildDetector = null; MotherShipDetector = null; UseableEntityDetector = null; if (!m_groupMask.Equals(MyGroupMask.Empty)) MyPhysics.physicsSystem.GetRigidBodyModule().GetGroupMaskManager().PushBackGroupMask(GroupMask); RemoveLight(); m_subObjectEngineThrustBackwardSmallLeftside.Clear(); m_subObjectEngineThrustBackwardSmallRightside.Clear(); m_subObjectEngineThrustBackwardLeftside.Clear(); m_subObjectEngineThrustBackwardRightside.Clear(); m_subObjectEngineThrustBackward2Leftside.Clear(); m_subObjectEngineThrustBackward2Rightside.Clear(); m_subObjectEngineThrustBackward2Middle.Clear(); m_subObjectEngineThrustForwardLeftside.Clear(); m_subObjectEngineThrustForwardRightside.Clear(); m_subObjectEngineThrustStrafeLeft.Clear(); m_subObjectEngineThrustStrafeRight.Clear(); m_subObjectEngineThrustUpLeftside.Clear(); m_subObjectEngineThrustUpRightside.Clear(); m_subObjectEngineThrustDownLeftside.Clear(); m_subObjectEngineThrustDownRightside.Clear(); m_subObjectReflectorLeft.Clear(); m_subObjectReflectorRight.Clear(); foreach (MyModelShipSubOject subObject in m_subObjects) { if (subObject.Light != null) { MyLights.RemoveLight(subObject.Light); subObject.Light = null; } m_modelSubObjectsPool.Deallocate(subObject); } StopSounds(); Weapons.Close(); if (m_damageEffect != null) { m_damageEffect.Stop(); m_damageEffect = null; } if (m_tradeNotification != null) { m_tradeNotification.Disappear(); } if (m_buildNotification != null) { m_buildNotification.Disappear(); } if (m_travelNotification != null) { m_travelNotification.Disappear(); } if (m_securityControlHUBNotification != null) { m_securityControlHUBNotification.Disappear(); } MyHudWarnings.Remove(this); MyGuiScreenInventoryManagerForGame.OpeningInventoryScreen -= OpeningInventoryScreen; MyGuiScreenInventoryManagerForGame.InventoryScreenClosed -= InventoryScreenClosed; base.Close(); m_unifiedWeaponCues = null; m_smallShipWeapons = null; }
public override void Close() { if (m_trailEffect != null) { //MyParticlesManager.RemoveParticleEffect(m_trailEffect); m_trailEffect.Stop(); m_trailEffect = null; } StopCue(); base.Close(); }
// When tube/head mounted into voxels and is harvesting void StartInVoxel(MyVoxelMap voxelMap) { // We found voxel so we stop here m_inVoxelMap = voxelMap; CurrentState = MyHarvestingDeviceEnum.InVoxel; StopTubeMovingCue(); StartGrindingCue(); m_lastTimeParticleAdded = null; m_parentMinerShip.Physics.Clear(); m_parentMinerShip.Physics.Immovable = true; MyMwcVector3Int tempVoxelCoord = voxelMap.GetVoxelCenterCoordinateFromMeters(ref m_headPositionTransformed); m_originalVoxelContent = voxelMap.GetVoxelContent(ref tempVoxelCoord); m_voxelMaterial = voxelMap.GetVoxelMaterial(ref tempVoxelCoord); m_harvestingParticleEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Harvester_Harvesting); m_harvestingParticleEffect.UserBirthMultiplier = 0.25f; m_harvestingParticleEffect.UserRadiusMultiplier = 1; m_harvestingParticleEffect.UserColorMultiplier = new Vector4(3, 3, 3, 3); Matrix dirMatrix = MyMath.MatrixFromDir(WorldMatrix.Forward); m_harvestingParticleEffect.WorldMatrix = Matrix.CreateWorld(m_headPositionTransformed, dirMatrix.Forward, dirMatrix.Up); // Empty voxels are problematic and can lead to "extremely fast harvesting". So here we do this // trick and its effect will be that even empty voxels will take few seconds to harvest. if (m_originalVoxelContent == 0) m_originalVoxelContent = 1; m_actualVoxelContent = (float)m_originalVoxelContent; m_harvestingSpeed = m_actualVoxelContent / TIME_TO_HARVEST_WHOLE_VOXEL_IN_UPDATE_TIMES; if (!MyVoxelMapOreMaterials.CanBeHarvested(m_voxelMaterial)) { HUD.MyHud.ShowIndestructableAsteroidNotification(); StartReturningBack(); } }
public void RemoveInstance(MyParticleEffect effect) { if (m_instances != null) { if (m_instances.Contains(effect)) m_instances.Remove(effect); } }
private void CloseEffect() { if (m_harvestingParticleEffect != null) { m_harvestingParticleEffect.Stop(); m_harvestingParticleEffect = null; } }
public override bool StartShooting() { if (!base.StartShooting()) return false; if ((MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeShoot) < MyAutocanonConstants.SHOT_INTERVAL_IN_MILISECONDS) return false; // Set muzzle flashes: m_muzzleFlashLength = MyMwcUtils.GetRandomFloat(4, 6); m_muzzleFlashRadius = MyMwcUtils.GetRandomFloat(1.2f, 2.0f); // Increse smoke to generate IncreaseSmoke(); // Make random trajectories for the bullet: Matrix worldMatrix = WorldMatrix; // get muzzle flashes: List<MyModelDummy> muzzles = GetMuzzleFlashMatrix(); muzzleFlashPosition1 = MyUtils.GetTransform(muzzles[0].Matrix.Translation, ref worldMatrix); muzzleFlashPosition2 = MyUtils.GetTransform(muzzles[1].Matrix.Translation, ref worldMatrix); // if (!IsControlledByPlayer()) { if (m_shotSmoke == null) { m_shotSmoke = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_LargeGunShot); m_shotSmoke.AutoDelete = false; } m_shotSmoke.UserEmitterScale = m_smokeToGenerate; m_shotSmoke.WorldMatrix = Matrix.CreateTranslation(muzzleFlashPosition1); if (m_shotSmoke2 == null) { m_shotSmoke2 = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_LargeGunShot); m_shotSmoke2.AutoDelete = false; } m_shotSmoke2.UserEmitterScale = m_smokeToGenerate; m_shotSmoke2.WorldMatrix = Matrix.CreateTranslation(muzzleFlashPosition2); } int randSoundSource = MyMwcUtils.GetRandomInt(2); MySoundCue? shootingSound = GetWeaponBase().UnifiedWeaponCueGet(MySoundCuesEnum.WepMachineGunNormFire3d); if (shootingSound == null || !shootingSound.Value.IsPlaying) { GetWeaponBase().UnifiedWeaponCueSet(Audio.MySoundCuesEnum.WepMachineGunNormFire3d, MyAudio.AddCue2dOr3d(this.GetWeaponBase().PrefabParent, Audio.MySoundCuesEnum.WepMachineGunNormFire3d, randSoundSource == 1 ? muzzleFlashPosition1 : muzzleFlashPosition2, WorldMatrix.Forward, WorldMatrix.Up, Vector3.Zero)); //MyAudio.AddCue3D(Audio.MySoundCuesEnum.WepAutocanonFire3d, randSoundSource == 1 ? muzzleFlashPosition1 : muzzleFlashPosition2, WorldMatrix.Forward, WorldMatrix.Up, Vector3.Zero)); } AddProjectile(MyAmmoConstants.GetAmmoProperties(MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Autocannon_Basic), muzzleFlashPosition1); AddProjectile(MyAmmoConstants.GetAmmoProperties(MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Autocannon_Basic), muzzleFlashPosition2); m_lastTimeShoot = MyMinerGame.TotalGamePlayTimeInMilliseconds; return true; }
private void UpdateBioChemEffect(bool start) { if (m_biochemEffect == null && start) { m_biochemEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Damage_SmokeBiochem); m_biochemEffect.AutoDelete = false; m_biochemEffect.UserBirthMultiplier = 0; m_biochemEffect.WorldMatrix = m_biochemEffectLocalMatrix.HasValue ? m_biochemEffectLocalMatrix.Value * WorldMatrix : WorldMatrix; } }
public static void RemoveParticleEffect(MyParticleEffect effect, bool fromBackground = false) { //System.Diagnostics.Debug.Assert(m_updateCompleted == true); //Because XNA can call Update() more times per frame if (!fromBackground) WaitUntilUpdateCompleted(); if (!effect.UserDraw /*&& effect.Enabled*/) { System.Diagnostics.Debug.Assert(m_particleEffectsForUpdate.Contains(effect)); m_particleEffectsForUpdate.Remove(effect); } m_particleEffectsAll.Remove(effect); MyParticlesLibrary.RemoveParticleEffectInstance(effect); }
// This method realy initiates/starts the missile // IMPORTANT: Direction vector must be normalized! public void Start(Vector3 position, Vector3 initialVelocity, Vector3 directionNormalized, MyMwcObjectBuilder_SmallShip_Ammo usedAmmo, MySmallShip minerShip) { m_usedAmmo = usedAmmo; m_ammoProperties = MyAmmoConstants.GetAmmoProperties(usedAmmo.AmmoType); m_gameplayProperties = MyGameplayConstants.GetGameplayProperties(m_usedAmmo, Faction); m_penetratedVoxelMap = null; m_wasPenetration = false; m_hasExplosion = false; m_isExploded = false; m_collidedEntity = null; m_collisionPoint = null; Matrix orientation = GetWorldRotation(); Vector3 pos = position; // Play missile thrust cue (looping) m_thrusterCue = MyAudio.AddCue3D(MySoundCuesEnum.WepMissileFly, pos, orientation.Forward, orientation.Up, this.Physics.LinearVelocity); m_light = MyLights.AddLight(); if (m_light != null) { m_light.Start(MyLight.LightTypeEnum.PointLight, GetPosition(), MyMissileHelperUtil.GetCannonShotLightColor(), 1, MyMissileConstants.MISSILE_LIGHT_RANGE); } m_diffuseColor = m_ammoProperties.TrailColor; switch (usedAmmo.AmmoType) { case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Basic: case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_High_Speed: case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Armor_Piercing_Incendiary: case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_SAPHEI: case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Proximity_Explosive: m_explosionType = MyExplosionTypeEnum.MISSILE_EXPLOSION; break; case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_BioChem: m_explosionType = MyExplosionTypeEnum.BIOCHEM_EXPLOSION; break; case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_EMP: m_explosionType = MyExplosionTypeEnum.EMP_EXPLOSION; break; case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Tunnel_Buster: m_explosionType = MyExplosionTypeEnum.BLASTER_EXPLOSION; break; default: throw new MyMwcExceptionApplicationShouldNotGetHere(); break; } this.Physics.Mass = m_gameplayProperties.WeightPerUnit; Vector3? correctedDirection = null; if (MyGameplayConstants.GameplayDifficultyProfile.EnableAimCorrection) { if (minerShip == MinerWars.AppCode.Game.Managers.Session.MySession.PlayerShip) { correctedDirection = MyEntities.GetDirectionFromStartPointToHitPointOfNearestObject(minerShip, position, m_ammoProperties.MaxTrajectory); } } if (correctedDirection != null) directionNormalized = correctedDirection.Value; base.Start(position, initialVelocity, directionNormalized, m_ammoProperties.DesiredSpeed, minerShip); if (correctedDirection != null) //override the base class behaviour, update the missile direction { Matrix ammoWorld = minerShip.WorldMatrix; ammoWorld.Translation = position; ammoWorld.Forward = correctedDirection.Value; SetWorldMatrix(ammoWorld); } m_smokeEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_CannonShot); m_smokeEffect.AutoDelete = false; m_smokeEffect.WorldMatrix = WorldMatrix; }
/// <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(); } }
private void OnSmokeEffectDelete(object sender, EventArgs eventArgs) { m_smokeEffect = null; }
// This method realy initiates/starts the missile // IMPORTANT: Direction vector must be normalized! public virtual void Start(MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum type, Vector3 position, Vector3 initialVelocity, Vector3 direction, Vector3 relativePos, MyEntity minerShip, MyEntity target, float customMaxDistance, bool isDummy, bool isLightWeight) { m_ammoProperties = MyAmmoConstants.GetAmmoProperties(type); m_missileType = type; m_isExploded = false; m_collidedEntity = null; m_collisionPoint = null; m_maxTrajectory = customMaxDistance > 0 ? customMaxDistance : m_ammoProperties.MaxTrajectory; IsDummy = isDummy; Faction = minerShip.Faction; Vector3? correctedDirection = null; if (MyGameplayConstants.GameplayDifficultyProfile.EnableAimCorrection) { if (minerShip == MinerWars.AppCode.Game.Managers.Session.MySession.PlayerShip) { correctedDirection = MyEntities.GetDirectionFromStartPointToHitPointOfNearestObject(minerShip, position, m_ammoProperties.MaxTrajectory); } } if (correctedDirection != null) direction = correctedDirection.Value; base.Start(position, initialVelocity, direction, 0, minerShip); if (correctedDirection != null) //override the base class behaviour, update the missile direction { Matrix ammoWorld = minerShip.WorldMatrix; ammoWorld.Translation = position; ammoWorld.Forward = correctedDirection.Value; SetWorldMatrix(ammoWorld); } switch (m_missileType) { //just going forward (deprecated) case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Missile_Basic: m_initTime = MyMissileConstants.MISSILE_INIT_TIME; m_initDir = MyMissileConstants.MISSILE_INIT_DIR; m_blendVelocities = MyMissileConstants.MISSILE_BLEND_VELOCITIES_IN_MILISECONDS; m_missileTimeout = MyMissileConstants.MISSILE_TIMEOUT; m_explosionType = MyExplosionTypeEnum.MISSILE_EXPLOSION; break; case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Missile_BioChem: m_initTime = MyMissileConstants.MISSILE_INIT_TIME; m_initDir = MyMissileConstants.MISSILE_INIT_DIR; m_blendVelocities = MyMissileConstants.MISSILE_BLEND_VELOCITIES_IN_MILISECONDS; m_missileTimeout = MyMissileConstants.MISSILE_TIMEOUT; m_explosionType = MyExplosionTypeEnum.BIOCHEM_EXPLOSION; break; case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Missile_EMP: m_initTime = MyMissileConstants.MISSILE_INIT_TIME; m_initDir = MyMissileConstants.MISSILE_INIT_DIR; m_blendVelocities = MyMissileConstants.MISSILE_BLEND_VELOCITIES_IN_MILISECONDS; m_missileTimeout = MyMissileConstants.MISSILE_TIMEOUT; m_explosionType = MyExplosionTypeEnum.EMP_EXPLOSION; break; //Missile is guided to the nearest enemy in the radius case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Engine_Detection: //Missile is guided to the closest enemy in the visible spot case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Visual_Detection: //Missile is guided to actual selected target by smallship radar case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Radar_Detection: m_initDir.X = 5.0f * MathHelper.Clamp(relativePos.X, -1, 1); m_blendVelocities = MyGuidedMissileConstants.MISSILE_BLEND_VELOCITIES_IN_MILISECONDS; m_missileTimeout = MyGuidedMissileConstants.MISSILE_TIMEOUT; m_turnSpeed = MyGuidedMissileConstants.MISSILE_TURN_SPEED; m_explosionType = MyExplosionTypeEnum.MISSILE_EXPLOSION; GuidedInMultiplayer = true; break; default: throw new NotImplementedException(); } UpdateTarget(target); if (!isLightWeight) { // Play missile thrust cue (looping) m_thrusterCue = MyAudio.AddCue3D(m_ammoProperties.ShotSound, GetPosition(), WorldMatrix.Forward, WorldMatrix.Up, m_initialVelocity); m_light = MyLights.AddLight(); if (m_light != null) { m_light.Start(MyLight.LightTypeEnum.PointLight, GetPosition(), MyMissileHelperUtil.GetMissileLightColor(), 1, MyMissileConstants.MISSILE_LIGHT_RANGE); } } #if DEBUG_MISSILE m_trailDebug.Clear(); #endif if (m_missileType == MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Missile_Basic) { /* 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; } }
public override void Close() { base.Close(); if (m_shotSmoke != null) { MyParticlesManager.RemoveParticleEffect(m_shotSmoke); m_shotSmoke = null; } }