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 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 override void UpdateBeforeSimulation() { base.UpdateBeforeSimulation(); if (m_elapsedMiliseconds > TimeToActivate && !m_smokeFired) { StartSmokeEffect(); Physics.LinearVelocity = Vector3.Zero; Explode(); m_smokeCue = MyAudio.AddCue2dOr3d(this, MySoundCuesEnum.WepBombSmartSmoke, GetPosition(), WorldMatrix.Forward, WorldMatrix.Up, Physics.LinearVelocity); } if (m_isExploded) { var effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_SmallGunShot); effect.WorldMatrix = this.WorldMatrix; effect.UserScale = 2f; MarkForClose(); } if (m_smokeEnded) { MarkForClose(); } else if (m_smokeFired) { // Aggro near bots MyDangerZones.Instance.NotifyArea(GetPosition(), 300, OwnerEntity); } }
public override void UpdateAfterSimulation() { base.UpdateAfterSimulation(); if (CurrentState == MyDrillStateEnum.Drilling) { if (m_trailEffect == null) { m_trailEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Drill_Thermal); //Must be done with handler because we need to set world matrix until effect totally dies m_trailEffect.OnDelete += OnTrailEffectDeleted; } } else { if (m_trailEffect != null) { m_trailEffect.Stop(); m_trailEffect = null; } } if (m_trailEffect != null) { Matrix effectMatrix = Matrix.CreateWorld(m_positionMuzzleInWorldSpace + MySmallShipConstants.ALL_SMALL_SHIP_MODEL_SCALE * 2 * WorldMatrix.Forward, WorldMatrix.Forward, WorldMatrix.Up); m_trailEffect.WorldMatrix = effectMatrix; } if (m_drillHead != null) { m_drillHead.SetWorldMatrixForCockpit(ref m_worldMatrixForRenderingFromCockpitView); m_drillHead.RotationSpeed = -m_rotatingSpeed; } }
static MyParticleEffect GetEffectForWeapon(MyEntity weapon, int effectID) { Dictionary <int, MyParticleEffect> effects; m_hitParticles.TryGetValue(weapon, out effects); if (effects == null) { effects = new Dictionary <int, MyParticleEffect>(); m_hitParticles.Add(weapon, effects); } MyParticleEffect effect; effects.TryGetValue(effectID, out effect); if (effect == null) { effect = MyParticlesManager.CreateParticleEffect(effectID); effects.Add(effectID, effect); effect.Tag = weapon; effect.OnDelete += new EventHandler(effect_OnDelete); } else { effect.Restart(); } return(effect); }
public override bool Shot(MyMwcObjectBuilder_SmallShip_Ammo usedAmmo) { if (usedAmmo == null || (MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeShoot) < MySniperConstants.SHOT_INTERVAL_IN_MILISECONDS && !IsDummy) { return(false); } MyAmmoProperties ammoProperties = MyAmmoConstants.GetAmmoProperties(usedAmmo.AmmoType); AddProjectile(ammoProperties, this); m_lastTimeShoot = MyMinerGame.TotalGamePlayTimeInMilliseconds; AddWeaponCue(ammoProperties.ShotSound); if (SysUtils.MyMwcFinalBuildConstants.ENABLE_TRAILER_SAVE) { MinerWars.AppCode.Game.Trailer.MyTrailerSave.UpdateGunShot(this.Parent, Trailer.MyTrailerGunsShotTypeEnum.PROJECTILE); } MyParticleEffect startEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_SmallGunShot); startEffect.WorldMatrix = Matrix.CreateWorld(GetMuzzlePosition(), GetForward(), GetUp()); return(true); }
public void Explode() { var explosionEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Explosion_Bomb); explosionEffect.WorldMatrix = this.WorldMatrix; explosionEffect.UserScale = .05f * this.WorldVolume.Radius; this.MarkForClose(); }
protected static void CreateImpactEffect(Vector3 position, Vector3 normal, MyParticleEffectsIDEnum effectID) { var effect = MyParticlesManager.CreateParticleEffect((int)effectID); Vector3 tangent; MyUtils.GetPerpendicularVector(ref normal, out tangent); effect.WorldMatrix = Matrix.CreateWorld(position, normal, tangent); }
// This mine collides with something after which it must explode public void StartSmokeEffect() { Debug.Assert(!m_smokeFired); { m_smokeFired = true; var effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.UniversalLauncher_SmokeBomb); effect.WorldMatrix = WorldMatrix; effect.OnDelete += delegate { m_smokeEnded = true; }; } }
public void StartEffect() { if ((DummyFlags & MyDummyPointFlags.PARTICLE) != 0) { ParticleEffect = MyParticlesManager.CreateParticleEffect((int)ParticleID, true); ParticleEffect.WorldMatrix = WorldMatrix; ParticleEffect.UserRadiusMultiplier = 1.0f; ParticleEffect.UserScale = UserScale; RefreshParticleSound(); } }
// Create smoke and debris particle at the place of voxel/model hit static void CreateBasicHitParticles(ref Vector3 hitPoint, ref Vector3 normal, ref Vector3 direction, MyEntity physObject, MyEntity weapon, MyEntity ownerEntity = null) { Vector3 reflectedDirection = Vector3.Reflect(direction, normal); MyUtilRandomVector3ByDeviatingVector randomVector = new MyUtilRandomVector3ByDeviatingVector(reflectedDirection); if (MyCamera.GetDistanceWithFOV(hitPoint) < 200) { MyParticleEffect effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Hit_BasicAmmo); Matrix dirMatrix = MyMath.MatrixFromDir(reflectedDirection); effect.WorldMatrix = Matrix.CreateWorld(hitPoint, dirMatrix.Forward, dirMatrix.Up); } }
protected override void DoDamageInternal(float playerDamage, float damage, float empDamage, MyDamageType damageType, MyAmmoType ammoType, MyEntity damageSource, bool justDeactivate) { base.DoDamageInternal(playerDamage, damage, empDamage, damageType, ammoType, damageSource, justDeactivate); if (IsDead()) { MarkForClose(); var effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Explosion_SmallPrefab); effect.WorldMatrix = WorldMatrix; effect.UserScale = 0.5f; } }
// Create smoke and debris particle at the place of voxel/model hit public static void CreateCollisionParticles(Vector3 hitPoint, Vector3 direction, bool doSmoke, bool doSparks) { Matrix dirMatrix = MyMath.MatrixFromDir(direction); if (doSmoke) { MyParticleEffect effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Collision_Smoke); effect.WorldMatrix = Matrix.CreateWorld(hitPoint, dirMatrix.Forward, dirMatrix.Up); } if (doSparks) { MyParticleEffect effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Collision_Sparks); effect.WorldMatrix = Matrix.CreateWorld(hitPoint, dirMatrix.Forward, dirMatrix.Up); } }
// Start shooting on the presented target in the queue: public override bool StartShooting() { // start shooting this kind of ammo ... if (!base.StartShooting()) { return(false); } if ((MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeShoot) < (MyMachineGunConstants.SHOT_INTERVAL_IN_MILISECONDS /* * 0.75f*/)) { 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 muzzel flash positions: List <MyModelDummy> muzzles = GetMuzzleFlashMatrix(); m_activeMuzzle = muzzles.Count == 1 ? 0 : MyMwcUtils.GetRandomInt(muzzles.Count); m_muzzleFlashPosition = MyUtils.GetTransform(muzzles[m_activeMuzzle].Matrix.Translation, ref worldMatrix); 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(m_muzzleFlashPosition); m_shotSmoke.UserScale = 5; GetWeaponBase().PlayShootingSound(); // Shoot projectiles AddProjectile(MyAmmoConstants.GetAmmoProperties(GetAmmoType()), m_muzzleFlashPosition); // dont decrease ammo count ... m_lastTimeShoot = MyMinerGame.TotalGamePlayTimeInMilliseconds; return(true); }
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 override void UpdateBeforeSimulation() { if (m_elapsedMiliseconds > 1000) { Physics.GroupMask = AppCode.Physics.MyGroupMask.Empty; } if (m_isExploded) { var effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Damage_Sparks); effect.WorldMatrix = WorldMatrix; effect.UserScale = .20f; MarkForClose(); return; } base.UpdateBeforeSimulation(); }
// 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; }
// 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(); } }
void OnParticleStressTest(MyGuiControlButton sender) { MyEntities.CloseAll(false); Vector3 position = MyCamera.Position + MyCamera.ForwardVector * 300; int explosionCount = 50; float particlesDistance = 60; Vector3 particlePosition = position + MyCamera.LeftVector * particlesDistance * (explosionCount / 2); for (int i = 0; i < explosionCount; i++) { MyParticleEffect effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Explosion_Blaster); effect.WorldMatrix = Matrix.CreateTranslation(particlePosition); effect.OnDelete += new EventHandler(effect_OnDelete); particlePosition += -MyCamera.LeftVector * particlesDistance; } }
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(); } }
public override void UpdateAfterSimulation() { base.UpdateAfterSimulation(); if (CurrentState == MyDrillStateEnum.Drilling) { if (m_directionalEffect == null) { m_directionalEffect = MyParticlesManager.CreateParticleEffect((int)m_directionalEffectID); } m_directionalEffect.WorldMatrix = Matrix.CreateWorld( m_positionMuzzleInWorldSpace + MySmallShipConstants.ALL_SMALL_SHIP_MODEL_SCALE * WorldMatrix.Forward, WorldMatrix.Forward, WorldMatrix.Up); } else { if (m_directionalEffect != null) { m_directionalEffect.Stop(); m_directionalEffect = null; } StopDustEffect(); } }
/// <summary> /// Initialize flares to fire /// </summary> private void FireFlares() { m_flareDeploy = MyAudio.AddCue2dOr3d(this, MySoundCuesEnum.SfxFlareDeploy, GetPosition(), WorldMatrix.Forward, WorldMatrix.Up, Physics.LinearVelocity); MyAudio.UpdateCuePosition(m_flareDeploy, GetPosition(), GetForward(), GetUp(), Physics.LinearVelocity); foreach (FlareParticle particle in m_particles) { particle.Position = WorldMatrix.Translation; Matrix rot = Matrix.CreateFromAxisAngle(WorldMatrix.Forward, MyMwcUtils.GetRandomFloat(0.0f, MathHelper.TwoPi)); particle.Dir = Vector3.TransformNormal(MyUtilRandomVector3ByDeviatingVector.GetRandom(WorldMatrix.Up, 0.2f), rot); particle.FlyTime = MyMwcUtils.GetRandomFloat(500, 8000); particle.Life = MyMwcUtils.GetRandomFloat(8000, MyDecoyFlareConstants.MAX_LIVING_TIME); var effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.UniversalLauncher_DecoyFlare); effect.UserBirthMultiplier = 0.3f; particle.ParticleEffect = effect; } m_startParticleTime = MyMinerGame.TotalGamePlayTimeInMilliseconds; m_flaresFired = true; }
// Generate explosion particles. These will be smoke, explosion and some polyline particles. void GenerateExplosionParticles(MyParticleEffectsIDEnum newParticlesType, BoundingSphere explosionSphere, float particleScale) { Vector3 dirToCamera = MyCamera.Position - explosionSphere.Center; if (MyMwcUtils.IsZero(dirToCamera)) { dirToCamera = MyCamera.ForwardVector; } else { dirToCamera = MyMwcUtils.Normalize(dirToCamera); } // Move explosion particles in the direction of camera, so we won't see billboards intersecting the large ship BoundingSphere tempExplosionSphere = m_explosionSphere; tempExplosionSphere.Center = m_explosionSphere.Center + dirToCamera * 0.9f; MyParticleEffect explosionEffect = MyParticlesManager.CreateParticleEffect((int)newParticlesType); explosionEffect.WorldMatrix = Matrix.CreateTranslation(tempExplosionSphere.Center); explosionEffect.UserRadiusMultiplier = tempExplosionSphere.Radius; explosionEffect.UserScale = particleScale; }
// 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(); }
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); }
public static void Update() { // Update only if sun wind is active if (IsActive == false) { return; } float darkeningPhase; float dt; int relTime = GetDarkeningPhase(out darkeningPhase, out dt); if (relTime > MaxTimeMs) { Clear(); return; } MyAudio.UpdateCuePosition(ambientSound, MyCamera.Position + MyCamera.ForwardVector * -MaxSoundDistance * (1 - darkeningPhase), MyCamera.ForwardVector, MyCamera.UpVector, Vector3.Zero); MyAudio.UpdateCueVolume(ambientSound, darkeningPhase * MaxAmbientVolume); // update smoke foreach (SmokeParticle part in smokeParticles) { Vector3 toCamera = (MyCamera.Position - part.Pos); toCamera.Normalize(); float alpha = darkeningPhase * MaxSmokeAlpha; part.Color = new Vector4(alpha, alpha, alpha, alpha); //part.Color.W = darkeningPhase; part.Pos += part.Velocity * dt + toCamera * CenterBias * dt; part.Angle += part.AngularVelocity * dt; } // remove old ice and sparks m_iceList.Clear(); foreach (IceParticle particle in iceParticles) { if (particle.StartTime + 4000 < relTime) { m_iceList.Add(particle); } } foreach (IceParticle ice in m_iceList) { ice.AsteroidEntity.MarkForClose(); Debug.Assert(ice.TrailEffect != null, "ice.TrailEffect != null"); ice.TrailEffect.Stop(); ice.TrailEffect = null; StopCue(ice.Sound); iceParticles.Remove(ice); } int c = 0; while (c < storms.Count) { ElectricStorm storm = storms[c]; if (storm.StartTime + 1500 < relTime) { storms.RemoveAt(c); continue; } c++; } // if its dark add new sparks and ice balls if (darkeningPhase >= 1) { if (storms.Count < MaxSparkCount && MyMwcUtils.GetRandomInt(SparkEveryMs) < dt * 1000.0f) { var storm = new ElectricStorm { Position = MyCamera.Position + MyCamera.ForwardVector * 250 + MyMwcUtils.GetRandomVector3HemisphereNormalized(MyCamera.ForwardVector) * MyMwcUtils.GetRandomFloat(0, 300), StartTime = relTime, Effect = MyParticlesManager.CreateParticleEffect( (int)MyParticleEffectsIDEnum.Damage_Sparks), }; storm.Effect.WorldMatrix = Matrix.CreateTranslation(storm.Position); storm.Effect.AutoDelete = true; storm.Effect.UserScale = 2; storm.Sound = MyAudio.AddCue2D(MySoundCuesEnum.SfxSpark); storms.Add(storm); } if (iceParticles.Count < MaxIceCount && MyMwcUtils.GetRandomInt(IceEveryMs) < dt * 1000.0f) { Vector3 dir = MyMwcUtils.GetRandomVector3HemisphereNormalized(MyCamera.ForwardVector); Vector3 pos = MyCamera.Position + MyCamera.ForwardVector * 250 + MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 200) + dir * MyMwcUtils.GetRandomFloat(0, 500); MyMwcObjectBuilder_StaticAsteroid rockModel = MySectorGenerator.GenerateStaticAsteroid(MyMwcUtils.GetRandomFloat(0.1f, 2f), MyStaticAsteroidTypeSetEnum.A, MyMwcVoxelMaterialsEnum.Ice_01, pos, random, asteroidTypes); Matrix matrix = Matrix.CreateFromAxisAngle(MyMwcUtils.GetRandomVector3Normalized(), MyMwcUtils.GetRandomFloat(0, MathHelper.Pi)); matrix.Translation = pos; MyEntity asteroid = MyEntities.CreateFromObjectBuilderAndAdd(null, rockModel, matrix); asteroid.Physics.Enabled = false; asteroid.CastShadows = false; MyParticleEffect effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_CannonShot); Vector3 velocity = -dir *MyMwcUtils.GetRandomInt(150, 400); iceParticles.Add(new IceParticle { StartTime = relTime, Position = pos, Direction = -dir, AsteroidEntity = asteroid, TrailEffect = effect, RotAxis = MyMwcUtils.GetRandomVector3Normalized(), RotAngle = MyMwcUtils.GetRandomRadian(), AngularVelocity = MyMwcUtils.GetRandomFloat(0.2f, 10f), Velocity = velocity, Sound = MyAudio.AddCue3D(MySoundCuesEnum.WepSniperHighFire2d, pos, dir, dir * -dir, velocity) }); } } // update ice parts foreach (IceParticle particle in iceParticles) { particle.RotAngle += particle.AngularVelocity * dt; particle.Position += particle.Velocity * dt; Matrix matrix = Matrix.CreateFromAxisAngle(particle.RotAxis, particle.RotAngle); matrix.Translation = particle.Position; particle.AsteroidEntity.SetWorldMatrix(matrix); Matrix trans = Matrix.CreateTranslation(-particle.Direction * 10); particle.TrailEffect.WorldMatrix = matrix * trans; MyAudio.UpdateCuePosition(particle.Sound, particle.Position, particle.Direction, particle.Direction * -particle.Direction, particle.Velocity); } lastUpdateMs = MyMinerGame.TotalGamePlayTimeInMilliseconds; }
protected override void Drill() { // Sphere which is used to make tunnel to voxel and sphere for testing collision with voxel m_fakeCollisionSphere = new BoundingSphere(m_fakeSpherePositionTransformed, m_radius); // Check for collision with drill and world //MyEntity collisionResult = MyEntities.GetIntersectionWithSphere(ref m_fakeCollisionSphere, this, Parent, false, true); // bSphere collision doesn't work - the sphere is tested against LOD0 model, but it is hidden inside the COL model and the bSphere is too small to reach it - so I use line instead MyEntity collisionResult = null; MyLine line; if (MySession.Is25DSector) { line = new MyLine(m_positionMuzzleInWorldSpace - 10 * WorldMatrix.Forward, m_positionMuzzleInWorldSpace + 20 * WorldMatrix.Forward, true); } else { line = new MyLine(m_positionMuzzleInWorldSpace - 10 * WorldMatrix.Forward, m_positionMuzzleInWorldSpace + 5 * WorldMatrix.Forward, true); } MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, Parent, this, true, true); if (intersection != null && intersection.Value.Entity.Physics != null) { collisionResult = intersection.Value.Entity; } if (!(collisionResult is MyVoxelMap)) { m_lastTimeDrillNotCollidedWithVoxelMapInMiliseconds = MyMinerGame.TotalGamePlayTimeInMilliseconds; if (!MySession.Is25DSector) { ((MySmallShip)Parent).IncreaseHeadShake(MyDrillDeviceConstants.SHAKE_DURING_ROTATION); } StopDustEffect(); if (collisionResult != null) { var effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.MaterialHit_Autocannon_Metal); effect.WorldMatrix = Matrix.CreateTranslation(m_fakeCollisionSphere.Center); collisionResult.DoDamage(0, m_damage * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS, 0, MyDamageType.Drill, MyAmmoType.Basic, Parent); } } // Display particles when we are in contact with voxel else { if (m_dustEffect == null) { m_dustEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_DrillDust); } m_dustEffect.WorldMatrix = Matrix.CreateTranslation(m_fakeSpherePositionTransformed); m_dustEffect.UserScale = MySession.Is25DSector ? 3 : 1; ((MySmallShip)Parent).IncreaseHeadShake(MyDrillDeviceConstants.SHAKE_DURING_IN_VOXELS); } // Play sound if there is collision with voxel if (collisionResult != null) { if (collisionResult is MyStaticAsteroid) { if (!collisionResult.IsDestructible) { MinerWars.AppCode.Game.HUD.MyHud.ShowIndestructableAsteroidNotification(); } } StartDrillingCue(collisionResult is MyVoxelMap); StopMovingCue(); } else { StartMovingCue(); StopDrillingCue(); } // We found voxel so lets make tunel into it using (var voxelMapsFound = PoolList <MyVoxelMap> .Get()) { bool drilled = false; bool drilledSomeDestructibleContent = false; MyVoxelMaps.GetListOfVoxelMapsWhoseBoundingSphereIntersectsSphere(ref m_fakeCollisionSphere, voxelMapsFound, null); int drillInterval = MySession.Is25DSector ? 100 : (int)MyDrillDeviceConstants.DRILL_INTERVAL_IN_MILISECONDS; int timerToDrillInterval = MySession.Is25DSector ? 100 : (int)MyDrillDeviceConstants.TIME_TO_DRILL_VOXEL_IN_MILISECONDS; foreach (MyVoxelMap voxelMap in voxelMapsFound) { if ((collisionResult is MyVoxelMap) && ((MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeDrilled) > drillInterval) && (MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeDrillNotCollidedWithVoxelMapInMiliseconds) > timerToDrillInterval) { drilled = true; float rangeStep = 0; float radius = GetRadiusNeededForTunel(); BoundingSphere bigSphereForTunnel = new BoundingSphere(m_fakeCollisionSphere.Center, radius); while (rangeStep < m_range) { MyMwcVector3Int exactCenterOfDrilling = voxelMap.GetVoxelCoordinateFromMeters(bigSphereForTunnel.Center); // we don't want to drill indestructible voxels or empty space if (voxelMap.IsVoxelInVoxelMap(ref exactCenterOfDrilling) && voxelMap.GetVoxelMaterialIndestructibleContent(ref exactCenterOfDrilling) == MyVoxelConstants.VOXEL_CONTENT_FULL) { break; } else { drilledSomeDestructibleContent = true; } CutOutFromVoxel(voxelMap, ref bigSphereForTunnel); bigSphereForTunnel.Center += 2 * WorldMatrix.Forward; rangeStep += 1; } } } if (drilled) { m_lastTimeDrilled = MyMinerGame.TotalGamePlayTimeInMilliseconds; if (!drilledSomeDestructibleContent) { HUD.MyHud.ShowIndestructableAsteroidNotification(); } } } }
/// <summary> /// Starts the explosion. /// </summary> /// <param name="damage"></param> /// <param name="type"></param> /// <param name="explosionSphere"></param> /// <param name="lifespanInMiliseconds"></param> /// <param name="explosionForceDirection"></param> /// <param name="groupMask"></param> /// <param name="createExplosionDebris"></param> /// <param name="cascadeLevel"></param> /// <param name="hitEntity"></param> /// <param name="particleScale"></param> /// <param name="ownerEntity"></param> /// <param name="affectVoxels"></param> /// <param name="applyForceAndDamage"></param> /// <param name="createDecals"></param> /// <param name="direction">If applicable, gives the direction of the explosion, e.g. when it was caused by a missile (with its moving direction).</param> public void Start(ref MyExplosionInfo explosionInfo) { //MyCommonDebugUtils.AssertDebug(explosionInfo.ExplosionSphere.Radius <= MyExplosionsConstants.EXPLOSION_RADIUS_MAX); MyCommonDebugUtils.AssertDebug(explosionInfo.ExplosionSphere.Radius > 0); MyRender.GetRenderProfiler().StartProfilingBlock("MyExplosion.Start"); m_explosionSphere = explosionInfo.ExplosionSphere; m_elapsedMiliseconds = 0; m_lifespanInMiliseconds = explosionInfo.LifespanMiliseconds; if (explosionInfo.PlaySound) { MyRender.GetRenderProfiler().StartProfilingBlock("Sound"); // Play explosion sound if (m_explosionCue != null && m_explosionCue.Value.IsPlaying) { m_explosionCue.Value.Stop(SharpDX.XACT3.StopFlags.Immediate); } m_explosionCue = MyAudio.AddCue3D(GetCueEnumByExplosionType(explosionInfo.ExplosionType), m_explosionSphere.Center, Vector3.Zero, Vector3.Zero, Vector3.Zero); MyRender.GetRenderProfiler().EndProfilingBlock(); } MyRender.GetRenderProfiler().StartProfilingBlock("Light"); // Light of explosion /* * m_light = MyLights.AddLight(); * if (m_light != null) * { * m_light.Start(MyLight.LightTypeEnum.PointLight, m_explosionSphere.Center, MyExplosionsConstants.EXPLOSION_LIGHT_COLOR, 1, Math.Min(m_explosionSphere.Radius * 8.0f, MyLightsConstants.MAX_POINTLIGHT_RADIUS)); * m_light.Intensity = 2.0f; * } */ MyRender.GetRenderProfiler().EndProfilingBlock(); // close explosion check bool close = IsExplosionClose(explosionInfo.ExplosionSphere); MyParticleEffectsIDEnum newParticlesType; switch (explosionInfo.ExplosionType) { case MyExplosionTypeEnum.SMALL_SHIP_EXPLOSION: // Create metal debris objects thrown from the explosion // This must be called before ApplyExplosionForceAndDamage (because there we apply impulses to the debris) // Throw a lot of debrises, more than only if some metalic object is hit (because this is destruction of a ship) //MyPhysObjectExplosionDebrises.CreateExplosionDebris(m_explosionSphere.Center, 1); newParticlesType = MyParticleEffectsIDEnum.Explosion_Smallship; break; case MyExplosionTypeEnum.MISSILE_EXPLOSION: newParticlesType = // ? MyParticleEffectsIDEnum.Explosion_Missile_Close MyParticleEffectsIDEnum.Explosion_Missile; break; case MyExplosionTypeEnum.BOMB_EXPLOSION: case MyExplosionTypeEnum.GRAVITY_EXPLOSION: newParticlesType = MyParticleEffectsIDEnum.Explosion_Bomb; break; case MyExplosionTypeEnum.AMMO_EXPLOSION: newParticlesType = MyParticleEffectsIDEnum.Explosion_Ammo; break; case MyExplosionTypeEnum.BLASTER_EXPLOSION: newParticlesType = MyParticleEffectsIDEnum.Explosion_Blaster; break; case MyExplosionTypeEnum.BIOCHEM_EXPLOSION: newParticlesType = MyParticleEffectsIDEnum.Explosion_BioChem; break; case MyExplosionTypeEnum.EMP_EXPLOSION: case MyExplosionTypeEnum.FLASH_EXPLOSION: newParticlesType = MyParticleEffectsIDEnum.Explosion_EMP; break; case MyExplosionTypeEnum.METEOR_EXPLOSION: newParticlesType = MyParticleEffectsIDEnum.Explosion_Meteor; break; case MyExplosionTypeEnum.NUCLEAR_EXPLOSION: newParticlesType = MyParticleEffectsIDEnum.Explosion_Nuclear; break; case MyExplosionTypeEnum.PLASMA_EXPLOSION: newParticlesType = MyParticleEffectsIDEnum.Explosion_Plasma; break; case MyExplosionTypeEnum.SMALL_EXPLOSION: newParticlesType = MyParticleEffectsIDEnum.Explosion_SmallPrefab; break; case MyExplosionTypeEnum.LARGE_SHIP_EXPLOSION: newParticlesType = MyParticleEffectsIDEnum.Explosion_Huge; break; case MyExplosionTypeEnum.LARGE_PREFAB_EXPLOSION: newParticlesType = MyParticleEffectsIDEnum.Explosion_Large; break; case MyExplosionTypeEnum.MEDIUM_PREFAB_EXPLOSION: newParticlesType = MyParticleEffectsIDEnum.Explosion_Medium; break; case MyExplosionTypeEnum.ASTEROID_EXPLOSION: newParticlesType = MyParticleEffectsIDEnum.Explosion_Asteroid; break; default: throw new System.NotImplementedException(); break; } if (explosionInfo.Damage > 0) { MyRender.GetRenderProfiler().StartProfilingBlock("Voxel or collision"); // If explosion sphere intersects a voxel map, we need to cut out a sphere, spawn debrises, etc MyVoxelMap voxelMap = explosionInfo.AffectVoxels && explosionInfo.EmpDamage == 0 ? MyVoxelMaps.GetOverlappingWithSphere(ref m_explosionSphere) : null; if (voxelMap != null) { // Dirty explosion with a lot of dust MyMwcVoxelMaterialsEnum?voxelMaterial = null; float voxelContentRemovedInPercent = 0; bool createDebris = true; // We want to create debris if (explosionInfo.HitEntity != null) // but not when we hit prefab { createDebris &= explosionInfo.HitEntity is MyVoxelMap; } //cut off BoundingSphere voxelExpSphere = new BoundingSphere(explosionInfo.VoxelExplosionCenter, m_explosionSphere.Radius * explosionInfo.VoxelCutoutScale); if (MyVoxelGenerator.CutOutSphereFast(voxelMap, voxelExpSphere, out voxelContentRemovedInPercent, out voxelMaterial, (explosionInfo.OwnerEntity is MySmallShip && explosionInfo.OwnerEntity == Managers.Session.MySession.PlayerShip), MyFakes.VOXELS_REMOVE_RATIO)) { if (explosionInfo.HitEntity is MyVoxelMap) { HUD.MyHud.ShowIndestructableAsteroidNotification(); } createDebris = false; // and no debris when voxel is indestructible } // Only if at least something was removed from voxel map // If voxelContentRemovedInPercent is more than zero than also voxelMaterial shouldn't be null, but I rather check both of them. if ((voxelContentRemovedInPercent > 0) && (voxelMaterial != null)) { //remove decals MyDecals.HideTrianglesAfterExplosion(voxelMap, ref voxelExpSphere); MyRender.GetRenderProfiler().StartProfilingBlock("CreateDebris"); if (explosionInfo.CreateDebris && (createDebris || explosionInfo.ForceDebris) && MyRenderConstants.RenderQualityProfile.ExplosionDebrisCountMultiplier > 0) { // Create debris rocks thrown from the explosion // This must be called before ApplyExplosionForceAndDamage (because there we apply impulses to the debris) MyExplosionDebrisVoxel.CreateExplosionDebris(ref voxelExpSphere, voxelContentRemovedInPercent, voxelMaterial.Value, explosionInfo.GroupMask, voxelMap); } MyRender.GetRenderProfiler().EndProfilingBlock(); MyRender.GetRenderProfiler().StartProfilingBlock("CreateParticleEffect"); MyParticleEffect explosionEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.MaterialExplosion_Destructible); explosionEffect.WorldMatrix = Matrix.CreateTranslation(voxelExpSphere.Center); explosionEffect.UserRadiusMultiplier = voxelExpSphere.Radius; MyRender.GetRenderProfiler().EndProfilingBlock(); } } MyRender.GetRenderProfiler().EndProfilingBlock(); } if (explosionInfo.Damage > 0) { // Create dirt decals in player's cockpit glass MyRender.GetRenderProfiler().StartProfilingBlock("Cockpit Decals"); CreateDirtDecalOnCockpitGlass(ref m_explosionSphere); MyRender.GetRenderProfiler().EndProfilingBlock(); } if (DEBUG_EXPLOSIONS) { MyRender.GetRenderProfiler().EndProfilingBlock(); return; } if (explosionInfo.Damage > 0) { BoundingSphere influenceExplosionSphere = m_explosionSphere; influenceExplosionSphere.Radius *= MyExplosionsConstants.EXPLOSION_RADIUS_MULTPLIER_FOR_IMPULSE; for (int i = 0; i < explosionInfo.CascadeLevel; i++) { influenceExplosionSphere.Radius *= MyExplosionsConstants.EXPLOSION_CASCADE_FALLOFF; } // Throws surrounding objects away from centre of the explosion. if (explosionInfo.ApplyForceAndDamage) { if (explosionInfo.ExplosionType == MyExplosionTypeEnum.LARGE_PREFAB_EXPLOSION || explosionInfo.ExplosionType == MyExplosionTypeEnum.LARGE_SHIP_EXPLOSION || explosionInfo.ExplosionType == MyExplosionTypeEnum.MEDIUM_PREFAB_EXPLOSION) { DisableContainedDummyParticles(ref explosionInfo); } explosionInfo.StrengthImpulse = MyExplosionsConstants.EXPLOSION_STRENGTH_IMPULSE * m_explosionSphere.Radius / 20; explosionInfo.StrengthAngularImpulse = MyExplosionsConstants.EXPLOSION_STRENGTH_ANGULAR_IMPULSE; explosionInfo.HitEntity = explosionInfo.HitEntity != null?explosionInfo.HitEntity.GetBaseEntity() : null; MyRender.GetRenderProfiler().StartProfilingBlock("ApplyExplosionForceAndDamage"); MyEntities.ApplyExplosionForceAndDamage(ref explosionInfo); MyRender.GetRenderProfiler().EndProfilingBlock(); } // Look for objects in explosion radius BoundingBox boundingBox; BoundingBox.CreateFromSphere(ref influenceExplosionSphere, out boundingBox); //if (explosionInfo.CreateDecals && explosionInfo.Direction.HasValue && explosionInfo.EmpDamage == 0) //{ // CreateDecals(explosionInfo.Direction.Value); //} } if (explosionInfo.CreateParticleEffect) { MyRender.GetRenderProfiler().StartProfilingBlock("Particles"); if (explosionInfo.CustomEffect != null) { if (explosionInfo.CustomEffect.ParticleID == 0) { explosionInfo.CustomEffect.ParticleID = (int)newParticlesType; } //Reload effect explosionInfo.CustomEffect.Enabled = false; explosionInfo.CustomEffect.Enabled = true; } else { // Explosion particles GenerateExplosionParticles(newParticlesType, m_explosionSphere, explosionInfo.ParticleScale); } MyRender.GetRenderProfiler().EndProfilingBlock(); } MyRender.GetRenderProfiler().EndProfilingBlock(); /* * // When MyAmmoBase entity is closed to explosion it will explode * if (entity is MyAmmoBase) * { * (entity as MyAmmoBase).ExplodeCascade(cascadeLevel + 1); * } */ // Smut decals - must be called after the explosion, after voxels are cutted out /*if ((intersection.PhysObject is MyVoxelMap) == false) * { * if (intersection.PhysObject is MyCockpitGlass) * { * // Change phys object so rest of the code will think we hit the parent * // Same fix is in projectile too - because cockpit glass is only helper object, we don't use it for real rendering and stuff * // And if not changed, it can make problem in "phys object decals" * intersection.PhysObject = intersection.PhysObject.Parent; * } * * // Create explosion smut decal on model we hit by this missile * MyDecals.Add( * MyDecalTexturesEnum.ExplosionSmut, * MyMwcUtils.GetRandomFloat(m_explosionSphere.Radius * 0.7f, m_explosionSphere.Radius * 1.3f), * MyMwcUtils.GetRandomRadian(), * GetSmutDecalRandomColor(), * true, * ref intersection); * } * else * { * // Creating explosion smut decal on voxel is more complicated than on voxel. We will project few lines * // from explosion epicentrum to the surounding world (random directions) and place decal where intersection detected. * //if (knownMissileDirection != null) * //{ * // MyLine linePrologned = new MyLine(knownIntersection.Value.IntersectionPointInObjectSpace, * // knownIntersection.Value.IntersectionPointInObjectSpace + knownMissileDirection.Value * MyExplosionsConstants.EXPLOSION_RANDOM_RADIUS_MAX * 2, * // true); * // MyLineTriangleIntersectionResult intersectionForSmut = knownIntersection.Value.VoxelMap.GetIntersectionWithLine(ref linePrologned); * // if (intersectionForSmut.Found == true) * // { * // MyDecals.Add( * // MyDecalTexturesEnum.ExplosionSmut, * // MyMwcUtils.GetRandomFloat(m_explosionSphere.Radius * 0.5f, m_explosionSphere.Radius * 1.0f), * // MyMwcUtils.GetRandomRadian(), * // GetSmutDecalRandomColor(), * // false, * // ref intersectionForSmut); * // } * //} * }*/ // Generate dust particles that will stay in place of the explosion //doesnt look good in final //GenerateStatisDustParticles(m_explosionSphere); }
// Called when we finished harvesting current voxel void StartReleaseVoxel() { if (m_parentMinerShip == null || m_parentMinerShip.IsDead() || m_parentMinerShip.Inventory == null) { return; } StartImplodeCue(); BoundingSphere explosion = new BoundingSphere(m_headPositionTransformed, MyVoxelConstants.VOXEL_SIZE_IN_METRES * 1); //remove decals MyDecals.HideTrianglesAfterExplosion(m_inVoxelMap, ref explosion); //cut off var minedMaterialsWithContents = MyVoxelGenerator.CutOutSphereFastWithMaterials(m_inVoxelMap, explosion); var dustEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Harvester_Finished); dustEffect.WorldMatrix = Matrix.CreateTranslation(m_headPositionTransformed); bool hudHarvestingCompletePlayed = false; bool harvestingFinishedAsyncSent = false; var minedOres = new Dictionary <int, float>(); foreach (var minedMaterialWithContent in minedMaterialsWithContents) { MyOreRatioFromVoxelMaterial[] oreFromVoxel = MyVoxelMapOreMaterials.GetOreFromVoxelMaterial(minedMaterialWithContent.Key); if (oreFromVoxel != null && this.Parent == MySession.PlayerShip) { // accumulate amounts of the same type foreach (MyOreRatioFromVoxelMaterial oreRatio in oreFromVoxel) { float amount = minedMaterialWithContent.Value * oreRatio.Ratio * MyHarvestingTubeConstants.MINED_CONTENT_RATIO; float oldAmount = 0; minedOres.TryGetValue((int)oreRatio.OreType, out oldAmount); minedOres[(int)oreRatio.OreType] = amount + oldAmount; } if (!harvestingFinishedAsyncSent) { try { // Disabled, still unused on server //var client = MySectorServiceClient.GetCheckedInstance(); //client.HarvestingFinishedAsync(minedMaterialWithContent.Key, (byte)(minedMaterialWithContent.Value * MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT)); } catch (Exception) { Debug.Fail("Cannot send harvesting to server"); } harvestingFinishedAsyncSent = true; } if (!hudHarvestingCompletePlayed) { hudHarvestingCompletePlayed = true; MyAudio.AddCue2D(MySoundCuesEnum.HudHarvestingComplete); } } } bool inventoryFullWarningPlayed = false; // add ores to inventory foreach (var ore in minedOres) { float amountLeft = m_parentMinerShip.Inventory.AddInventoryItem(MyMwcObjectBuilderTypeEnum.Ore, ore.Key, ore.Value, false); float amountAdded = ore.Value - amountLeft; if (amountAdded > 0f) { MyHudNotification.AddNotification(new MyHudNotification.MyNotification(MyTextsWrapperEnum.HarvestNotification, 3500, textFormatArguments: new object[] { amountAdded, ((MyGuiOreHelper)MyGuiObjectBuilderHelpers.GetGuiHelper(MyMwcObjectBuilderTypeEnum.Ore, ore.Key)).Name } )); } if (amountLeft > 0f) { MyHudNotification.AddNotification(new MyHudNotification.MyNotification(MyTextsWrapperEnum.HarvestNotificationInventoryFull, MyGuiManager.GetFontMinerWarsRed(), 3500, textFormatArguments: new object[] { amountLeft, ((MyGuiOreHelper)MyGuiObjectBuilderHelpers.GetGuiHelper(MyMwcObjectBuilderTypeEnum.Ore, ore.Key)).Name } )); if (!inventoryFullWarningPlayed) { MyAudio.AddCue2D(MySoundCuesEnum.HudInventoryFullWarning); inventoryFullWarningPlayed = true; } } } StartReturningBack(); }
public override void UpdateAfterSimulation() { base.UpdateAfterSimulation(); // Cannon is rotating while shoting. After that, it will slow-down. float normalizedRotationSpeed = 1.0f - MathHelper.Clamp((float)(MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeShoot) / m_rotationTimeout, 0, 1); normalizedRotationSpeed = MathHelper.SmoothStep(0, 1, normalizedRotationSpeed); m_rotationAngle -= normalizedRotationSpeed * MyAutocanonConstants.ROTATION_SPEED_PER_SECOND * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; Matrix worldMatrix = this.WorldMatrix; m_positionMuzzleInWorldSpace = GetMuzzlePosition(m_barrel.GetMuzzlePosition()); m_barrel.SetData(ref m_worldMatrixForRenderingFromCockpitView, m_rotationAngle); // Handle 'motor loop and motor end' cues if ((m_cannonMotorEndPlayed == false) && ((MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeShoot) > MyAutocanonConstants.SHOT_INTERVAL_IN_MILISECONDS)) { // Stop 'shooting loop' cue if (MyMinerGame.TotalGamePlayTimeInMilliseconds > m_lastTimeShoot + MyAutocanonConstants.MIN_TIME_RELEASE_INTERVAL_IN_MILISECONDS) { MySoundCue?autocanonAttackLoopCue = GetParentMinerShip().UnifiedWeaponCueGet(AUTOCANON_ATTACK_LOOP); if ((autocanonAttackLoopCue != null) && (autocanonAttackLoopCue.Value.IsPlaying == true)) { autocanonAttackLoopCue.Value.Stop(SharpDX.XACT3.StopFlags.Immediate); } autocanonAttackLoopCue = GetParentMinerShip().UnifiedWeaponCueGet(AUTOCANON_ATTACK); if ((autocanonAttackLoopCue != null) && (autocanonAttackLoopCue.Value.IsPlaying == true)) { autocanonAttackLoopCue.Value.Stop(SharpDX.XACT3.StopFlags.Immediate); } // Start 'release' cue MySoundCue?autocanonReleaseCue = GetParentMinerShip().UnifiedWeaponCueGet(AUTOCANON_RELEASE); if ((autocanonReleaseCue == null) || (autocanonReleaseCue.Value.IsPlaying == false)) { GetParentMinerShip().UnifiedWeaponCueSet( AUTOCANON_RELEASE, MyAudio.AddCue2dOr3d(GetParentMinerShip(), AUTOCANON_RELEASE, Parent.GetPosition(), Parent.WorldMatrix.Forward, Parent.WorldMatrix.Up, Parent.Physics.LinearVelocity)); } m_cannonMotorEndPlayed = true; } } // Update sound position MySoundCue?updateAutocanonAttackLoopCue = GetParentMinerShip().UnifiedWeaponCueGet(AUTOCANON_ATTACK_LOOP); if ((updateAutocanonAttackLoopCue != null) && (updateAutocanonAttackLoopCue.Value.IsPlaying == true)) { MyAudio.UpdateCuePosition(updateAutocanonAttackLoopCue, m_positionMuzzleInWorldSpace, WorldMatrix.Forward, WorldMatrix.Up, Parent.Physics.LinearVelocity); } updateAutocanonAttackLoopCue = GetParentMinerShip().UnifiedWeaponCueGet(AUTOCANON_ATTACK); if ((updateAutocanonAttackLoopCue != null) && (updateAutocanonAttackLoopCue.Value.IsPlaying == true)) { MyAudio.UpdateCuePosition(updateAutocanonAttackLoopCue, m_positionMuzzleInWorldSpace, WorldMatrix.Forward, WorldMatrix.Up, Parent.Physics.LinearVelocity); } // Update sound position MySoundCue?updateAutocanonReleaseCue = GetParentMinerShip().UnifiedWeaponCueGet(AUTOCANON_RELEASE); if ((updateAutocanonReleaseCue != null) && (updateAutocanonReleaseCue.Value.IsPlaying == true)) { MyAudio.UpdateCuePosition(updateAutocanonReleaseCue, m_positionMuzzleInWorldSpace, WorldMatrix.Forward, WorldMatrix.Up, Parent.Physics.LinearVelocity); } // If gun fires too much, we start generating smokes at the muzzle if ((MyMinerGame.TotalGamePlayTimeInMilliseconds - m_smokeLastTime) >= (MyAutocanonConstants.SMOKES_INTERVAL_IN_MILISECONDS)) { m_smokeLastTime = MyMinerGame.TotalGamePlayTimeInMilliseconds; SmokesToGenerateDecrease(); if (m_smokesToGenerate > 0 && m_smokeEffect == null) { if (MyCamera.GetDistanceWithFOV(GetPosition()) < 150) { m_smokeEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Autocannon); m_smokeEffect.WorldMatrix = WorldMatrix; m_smokeEffect.OnDelete += new EventHandler(m_smokeEffect_OnDelete); } } } if (m_smokeEffect != null) { float smokeOffset = 0.2f; if ((MinerWars.AppCode.Game.GUI.MyGuiScreenGamePlay.Static.CameraAttachedTo == MinerWars.AppCode.Game.GUI.MyCameraAttachedToEnum.PlayerMinerShip) && (Parent == MySession.PlayerShip)) { smokeOffset = 0.0f; } m_smokeEffect.WorldMatrix = Matrix.CreateTranslation(m_positionMuzzleInWorldSpace + worldMatrix.Forward * smokeOffset); m_smokeEffect.UserBirthMultiplier = m_smokesToGenerate; } }