private void interceptPods(bool flag_InterceptDropPod) { if (!this.shieldInterceptDropPod || !flag_InterceptDropPod) { return; } IEnumerable <Thing> source = (IEnumerable <Thing>)Find.get_ListerThings().ThingsOfDef((ThingDef)ThingDefOf.DropPod); if (source == null) { return; } using (List <Thing> .Enumerator enumerator = source.Where <Thing>((Func <Thing, bool>)(t => { IntVec3 position = t.get_Position(); // ISSUE: explicit reference operation return(((IntVec3)@position).InHorDistOf(this.position, (float)this.shieldShieldRadius)); })).ToList <Thing>().GetEnumerator()) { while (enumerator.MoveNext()) { DropPod current = (DropPod)enumerator.Current; ((Thing)current).Destroy((DestroyMode)0); BodyPartDamageInfo bodyPartDamageInfo = new BodyPartDamageInfo(new BodyPartHeight?(), new BodyPartDepth?((BodyPartDepth)2)); ExplosionInfo explosionInfo = (ExplosionInfo)null; explosionInfo.center = (__Null)((Thing)current).get_Position(); explosionInfo.radius = (__Null)1.0; explosionInfo.dinfo = (__Null) new DamageInfo((DamageDef)DamageDefOf.Flame, 10, (Thing)current, new BodyPartDamageInfo?(), (ThingDef)null); // ISSUE: explicit reference operation ((ExplosionInfo)@explosionInfo).DoExplosion(); } } }
void Explode() { // play the correct soundFx ExplosionInfo info = new ExplosionInfo(); info.origin = transform.position; switch (level) { case 1: Instantiate(sndLevel1); info.strength = 0.1f; break; case 2: info.strength = 0.1f; Instantiate(sndLevel2); break; case 3: info.strength = 0.1f; Instantiate(sndLevel3); break; } GameObject.Find("GameController").SendMessage("MakeExplosion", info); GameObject.Find("GameController").SendMessage("DecrementAsteroid"); Destroy(gameObject); }
void HyperspaceIn(bool center = false) { GetComponent <Rigidbody>().velocity = new Vector3(0.0f, 0.0f, 0.0f); GetComponent <Rigidbody>().rotation = Quaternion.Euler(0.0f, 0.0f, 0.0f); transform.rotation = Quaternion.identity; if (center) { // center transform.position = new Vector3(0.0f, 0.0f, 0.0f); heading = 0.0f; } else { // random float x, y, a; x = Random.Range(-15, 15); y = Random.Range(-8, 8); a = Random.Range(0.0f, 360.0f); transform.position = new Vector3(x, 0.0f, y); heading = a; } ExplosionInfo info = new ExplosionInfo(); info.origin = transform.position; info.strength = 0.1f; GameObject.Find("GameController").SendMessage("MakeExplosion", info); Show(); }
void Explode() { if (hasShields > 0) { hasShields -= 1; if (hasShields < 1) { shields.SetActive(false); } } else { hasTrishots = 0; hasShields = 0; Instantiate(explosion, transform.position, Quaternion.identity); Hide(); GameObject.Find("GameController").SendMessage("KillPlayer"); ExplosionInfo info = new ExplosionInfo(); info.origin = transform.position; info.strength = 1.0f; GameObject.Find("GameController").SendMessage("MakeExplosion", info); } }
public static GameObject Create(Vector2 position, ExplosionInfo info) { GameObject explosion = MonoBehaviour.Instantiate(ExplosionCatalogue.Template, position, Quaternion.identity) as GameObject; var explosionController = explosion.GetMasterObject().GetComponent <ExplosionController>(); explosionController.OnInitialize(info); return(explosion); }
public void OnInitialize(ExplosionInfo info) { _radius = info.Radius; _damage = info.Damage; _force = info.Force; _method = info.PropagationMethod; _tag = info.Tag; }
void ImExploding(ExplosionInfo expInfo) { if (GetComponent <Rigidbody>()) { GetComponent <Rigidbody>().AddForce(-transform.forward * expInfo.impactForce, ForceMode.Impulse); } Health -= expInfo.damage; }
//Explosion method private void ExplosionThing(IntVec3 position) { BodyPartDamageInfo value1 = new BodyPartDamageInfo(null, new BodyPartDepth?(BodyPartDepth.Outside)); //What body parts will be damaged, you can use Inside, Outside and Inherit(no ide what this means and do) ExplosionInfo explosionInfo = new ExplosionInfo(); //This create new explosion instance explosionInfo.center = position; // Center of explosion, if hitThing exist it will use hitThing position, if not then it will use bullet position explosionInfo.radius = UnityEngine.Random.Range(1f, 5f); // This is randome range from 1 to 5 but you can set any you want. "Exeample: explosionInfo.radius =5f" this is 5 square radius explosionInfo.dinfo = new DamageInfo(this.def.projectile.damageDef, this.def.projectile.damageAmountBase, this.launcher, new BodyPartDamageInfo?(value1), null);// This packs all our explosion info stuff above into dinfo so explosion class can use it(i think :D) explosionInfo.DoExplosion(); // This starts explosion class with our info pack to do BOOM! }
public void OnInitialize(ProjectileInfo _info, Vector2 direction) { var info = _info as GrenadeBulletInfo; _bounceVelocityMultiplier = info.OnHitVeclocityMultiplier; _hopUp = info.HopUpFactor; _explosionInfo = info.ExplosionInfo; Fire(direction.normalized * info.InitialSpeed); ExpireCheckCoroutineHandler = StartCoroutine(ExpireCheckCorutine()); }
void MakeExplosion(ExplosionInfo info) { GameObject[] objs = GameObject.FindObjectsOfType <GameObject>(); for (int i = 0; i < objs.Length; i++) { Rigidbody rb = objs[i].GetComponent <Rigidbody>(); if (rb) { rb.AddExplosionForce(info.strength, info.origin, 10f, 0f, ForceMode.Impulse); } } }
private void Command_Detonate() { radius = base.GetComp <CompExplosive>().props.explosiveRadius; dmgdef = base.GetComp <CompExplosive>().props.explosiveDamageType; BodyPartDamageInfo value = new BodyPartDamageInfo(null, new BodyPartDepth?(BodyPartDepth.Outside)); ExplosionInfo explosionInfo = default(ExplosionInfo); explosionInfo.center = base.Position; explosionInfo.radius = radius; explosionInfo.dinfo = new DamageInfo(dmgdef, 30, this, new BodyPartDamageInfo?(value), null); explosionInfo.Explode(); }
private void ProcessExplosion(Vector3 blastPoint) { bool success = false; //Debug.DrawLine(transform.position, transform.position + Vector3.up * BlastRadius, Color.red, 5.0f); //Debug.DrawLine(transform.position, transform.position + Vector3.down * BlastRadius, Color.red, 5.0f); //Debug.DrawLine(transform.position, transform.position + Vector3.right * BlastRadius, Color.red, 5.0f); //Debug.DrawLine(transform.position, transform.position + Vector3.left * BlastRadius, Color.red, 5.0f); //Debug.DrawLine(transform.position, transform.position + Vector3.forward * BlastRadius, Color.red, 5.0f); //Debug.DrawLine(transform.position, transform.position + Vector3.back * BlastRadius, Color.red, 5.0f); Collider[] Blast = Physics.OverlapSphere(blastPoint, BlastRadius, BlastableLayers); if (Blast != null) { //Debug.Log("Blast Area: " + Blast.Length + "\n"); for (int i = 0; i < Blast.Length; i++) { Explodable affected = Blast[i].GetComponent <Explodable>(); if (affected && BlastRadius > 0) { //Debug.Log("Blast Area: " + Blast.Length + "\n" + affected.gameObject.name + " " + name, this); if (affected.gameObject != gameObject) { float range = Vector3.Distance(blastPoint, Blast[i].gameObject.transform.position); //A multiplier for objects being knocked around float damage = Mathf.Clamp(1 - ((range - affected.MinSphereRadius) / BlastRadius), .25f, 1); //Debug.Log("Radius [" + BlastRadius + "] Dist [" + range + "] bonusRadius [" + affected.MinSphereRadius + "]\n"); Vector3 startPoint = (alternateExplosionPoint == null) ? transform.position : alternateExplosionPoint.transform.position; ExplosionInfo info = new ExplosionInfo(this, affected, startPoint, new Vector3(1, 1.25f, 1) * damage * BlastForce / 4); info.ClampBlastDamage = ClampBlastDamage; info.explosionSequence = explosionSequence; //Debug.Log(info.ToString() + "\n"); success = affected.RecieveExplosion(info); if (!success) { Debug.Log("Failed to apply explosion\n" + info.ToString() + "\n"); } } } } } if (ShockwaveSize > 0) { ProcessShockwave(blastPoint); } }
void PlayerBlast() { // player has hit this saucer Instantiate(explosion, transform.position, Quaternion.identity); Destroy(gameObject); ExplosionInfo info = new ExplosionInfo(); info.origin = transform.position; info.strength = 2.0f; GameObject.Find("GameController").SendMessage("MakeExplosion", info); GameObject.Find("GameController").SendMessage("ScoreSaucer", isSmall); }
public void RenderExplosions(float opacity) { if (listExplosionInfo_ != null) { int nExplosions = listExplosionInfo_.Count; for (int i = 0; i < nExplosions; i++) { ExplosionInfo exInfo = listExplosionInfo_[i]; RenderExplosion(exInfo, opacity); } } }
protected virtual void Explode() { this.Destroy(DestroyMode.Vanish); BodyPartDamageInfo value = new BodyPartDamageInfo(null, new BodyPartDepth?(BodyPartDepth.Outside)); ExplosionInfo explosionInfo = default(ExplosionInfo); explosionInfo.center = base.Position; explosionInfo.radius = this.def.projectile.explosionRadius; explosionInfo.dinfo = new DamageInfo(this.def.projectile.damageDef, 999, this.launcher, new BodyPartDamageInfo?(value), null); explosionInfo.postExplosionSpawnThingDef = this.def.projectile.postExplosionSpawnThingDef; explosionInfo.explosionSpawnChance = this.def.projectile.explosionSpawnChance; explosionInfo.explosionSound = this.def.projectile.soundExplode; explosionInfo.projectile = this.def; explosionInfo.DoExplosion(); }
protected virtual void Explode() { this.Destroy(DestroyMode.Vanish); BodyPartDamageInfo value = new BodyPartDamageInfo(null, new BodyPartDepth?(BodyPartDepth.Outside)); ExplosionInfo explosionInfo = default(ExplosionInfo); explosionInfo.center = base.Position; explosionInfo.radius = this.def.projectile.explosionRadius; explosionInfo.dinfo = new DamageInfo(DamageDefOf.Bomb, 999, this.launcher, new BodyPartDamageInfo?(value), null); explosionInfo.postExplosionSpawnThingDef = this.def.projectile.postExplosionSpawnThingDef; explosionInfo.explosionSpawnChance = this.def.projectile.explosionSpawnChance; explosionInfo.explosionSound = this.def.projectile.soundExplode; explosionInfo.projectile = this.def; explosionInfo.DoExplosion(); ThrowBigExplode(explosionInfo.center.ToVector3Shifted() + Gen.RandomHorizontalVector(explosionInfo.radius * 0.7f), explosionInfo.radius * 0.6f); }
private void Command_Detonate() { radius = base.GetComp <CompExplosive>().props.explosiveRadius; dmgdef = base.GetComp <CompExplosive>().props.explosiveDamageType; this.Destroy(DestroyMode.Vanish); BodyPartDamageInfo value = new BodyPartDamageInfo(null, new BodyPartDepth?(BodyPartDepth.Outside)); ExplosionInfo explosionInfo = default(ExplosionInfo); explosionInfo.center = Position; explosionInfo.radius = radius; explosionInfo.dinfo = new DamageInfo(dmgdef, 100, this, new BodyPartDamageInfo?(value), null); explosionInfo.Explode(); explosionInfo.dinfo = new DamageInfo(dmgdef, 100, this, new BodyPartDamageInfo?(value), null); explosionInfo.dinfo = new DamageInfo(dmgdef, 100, this, new BodyPartDamageInfo?(value), null); explosionInfo.dinfo = new DamageInfo(dmgdef, 100, this, new BodyPartDamageInfo?(value), null); MoteMaker.TryThrowMicroSparks(Position.ToVector3Shifted()); if (Position.GetRoof() != null) { if (Find.RoofGrid.RoofDefAt(Position).isThickRoof == true) { RoofDef roofType = DefDatabase <RoofDef> .GetNamed("RoofRockThin"); Find.RoofGrid.SetRoof(Position, roofType); } else { Find.RoofGrid.SetRoof(Position, null); } } foreach (IntVec3 current in GenAdj.AdjacentSquares8Way(this)) { if (current.GetRoof() != null) { if (Find.RoofGrid.RoofDefAt(current).isThickRoof == true) { RoofDef roofType = DefDatabase <RoofDef> .GetNamed("RoofRockThin"); Find.RoofGrid.SetRoof(current, roofType); } else { Find.RoofGrid.SetRoof(current, null); } } } }
void OnCollisionEnter(Collision collision) { // Instantiate explosion at the impact point and rotate the explosion // so that the y-axis faces along the surface normal ContactPoint contact = collision.contacts[0]; Quaternion rotation = Quaternion.FromToRotation(Vector3.up, contact.normal); GameObject exp = Instantiate(explosion, contact.point, rotation) as GameObject; ExplosionInfo expInfo = new ExplosionInfo(); expInfo.owner = owner; expInfo.damage = damage; expInfo.impactForce = impactForce; exp.GetComponent <Explosion>().expInfo = expInfo; // And kill our selves Kill(); }
public void RenderExplosions(float opacity) { bool isSimulating = CaronteSharp.SimulationManager.IsSimulating(); bool isReplaying = CaronteSharp.SimulationManager.IsReplaying(); bool isSimulatingOrReplaying = (isSimulating || isReplaying); if (listExplosionInfo_ != null && ( (isSimulatingOrReplaying && frameNumber_ != 0) || !isSimulatingOrReplaying) ) { int nExplosions = listExplosionInfo_.Count; for (int i = 0; i < nExplosions; i++) { ExplosionInfo exInfo = listExplosionInfo_[i]; RenderExplosion(exInfo, opacity, isSimulatingOrReplaying); } } }
private void RenderExplosion( ExplosionInfo exInfo, float opacity, bool isSimulatingOrReplaying ) { CNExplosion exNode = eManager_.GetExplosionNode(exInfo.idEntity_); if (exNode == null) { return; } Vector3 center = exInfo.center_; List<BeamInfo> arrBeamInfo = exInfo.listBeam_; int nBeams = arrBeamInfo.Count; Color red = Color.red; red.a = opacity; Color yellow = Color.yellow; yellow.a = opacity; Color cyan = Color.cyan; cyan.a = opacity; int step = (int)Mathf.Log(nBeams); step = exNode.RenderStepSize; Quaternion rotation = Quaternion.identity; if ( exNode.Explosion_Transform != null && !isSimulatingOrReplaying ) { Transform tr = exNode.Explosion_Transform; center = tr.position; rotation = tr.rotation; } for ( int i = 0; i < nBeams; i += step ) { BeamInfo beamInfo = arrBeamInfo[i]; Vector3 beam_u = rotation * beamInfo.beam_u_; Vector3 segmentLengths = beamInfo.segmentLenths_; if (segmentLengths.x < float.Epsilon ) continue; Handles.color = red; Vector3 pos_A = center; Vector3 pos_B = pos_A + (beam_u * segmentLengths.x); Handles.DrawLine(pos_A, pos_B); if (segmentLengths.y < float.Epsilon ) continue; Handles.color = yellow; pos_A = pos_B; pos_B += beam_u * segmentLengths.y; Handles.DrawLine(pos_A, pos_B); if (segmentLengths.z < float.Epsilon) continue; Handles.color = cyan; pos_A = pos_B; pos_B += beam_u * segmentLengths.z; Handles.DrawLine(pos_A, pos_B); } }
/// <summary> /// [Note: this does not work] /// /// </summary> /// <param name="playerBody"></param> /// <param name="info"></param> public void DynamiteExplosionSample(GameObject playerBody, ExplosionInfo info) { //Again, we checked what was the closest place to the explosion for starting an impulse. AreaFlag loc = FindNearest(playerBody, info.explosionCenter); if (loc != AreaFlag.None) { //This is a little gross but the idea is simple: Closer to the explosion, the longer the effect. //If you're close to dynamite the visuals take longer to dissipate and you'll spend longer thinking 'Oh man I screwed up' even though you're unharmed. //This is accomplished in a couple of ways: //The emanation will traverse farther across the user's body. int depth = 8; //The emanation will restart several times int repeats = 3; //The starting strength of the effect will be stronger. float strength = 1.0f; //The delay between the repetitions will be shorter. float delay = .15f; //We do a simple bit of checking based on the distance from the blast. if (info.dist > 0) { //We base the depth off of the distance from the explosion. //There is some magic-numbering going on here. You can tune it or standardize your distances. //The farther, the less depth of the emanation depth = (int)(8 / info.dist); //The farther, the less initial strength - NOTE: this is just Effect strength, not using the Attenuation which is still a bit incomplete. strength = 2 / info.dist; } //The closer the player is to the explosion, the more the explosion will 'reverberate' by repeating. repeats = Mathf.RoundToInt(Mathf.Clamp(7 / info.dist, 0, 7)); //If we're going to experience it a lot, we'll get a shorter delay between the repeats. if (repeats > 4) { delay = .1f; } //Start at the correct spot. ImpulseGenerator.Impulse impulse = ImpulseGenerator.BeginEmanatingEffect(loc, depth) //Give the total effect a short duration (which you could choose to modify) .WithDuration(.15f) //Start with a natural duration click for the initial hit. This is good because it gets the motors going earlier on .WithEffect("click", .00f, strength) //Finish with a buzz which will last longer than natural duration. This gives the explosion a residual impact feeling .WithEffect("buzz", .15f, strength); //Finally, we call the coroutine that will repeatedly create new handles of the impulse with Play(). //Remember, an Impulse is like a prefab or a building plan for haptics. You can 'instantiate' multiple haptic effects off the same Impulse. StartCoroutine(RepeatedEmanations(impulse, delay, repeats)); } else { Debug.LogWarning("Invalid Hit at " + info.explosionCenter + "\n"); } }
public GrenadeBulletInfoBuilder SetExplosionInfo(ExplosionInfo explosionInfo) { _info.ExplosionInfo = explosionInfo; return(this); }
private void PerformDeformation(ref HkBreakOffPointInfo pt, bool fromBreakParts, float separatingVelocity) { ProfilerShort.Begin("PerformDeformation"); Debug.Assert(Sync.IsServer, "Function PerformDeformation should not be called from client"); var mass = this.Mass; if (IsStatic) { mass = pt.CollidingBody.Mass; } float velocity = separatingVelocity; float deltaV = pt.BreakingImpulse / mass; // Calculate deformation offset float deformationOffset = 0.3f + Math.Max(0, (Math.Abs(velocity) - deltaV) / 15); deformationOffset *= 2; deformationOffset *= MyFakes.DEFORMATION_RATIO; const float maxDeformationHardLimit = 25; // Happens during copy pasting //Debug.Assert(deformationOffset < maxDeformationHardLimit, "Deformation is bigger than maximum."); deformationOffset = Math.Min(deformationOffset, maxDeformationHardLimit); float explosionRadius = Math.Max(m_grid.GridSize, deformationOffset); MyEntity otherEntity = pt.CollidingBody.GetEntity() as MyEntity; bool hitVoxel = otherEntity is MyVoxelMap; if (hitVoxel) { // Hardness from 0 to 1 float hardness = 0.0f; deformationOffset *= 1 + hardness; explosionRadius *= 1 - hardness; } float softAreaPlanar = m_grid.GridSizeEnum == MyCubeSize.Large ? 4 : 1.2f; // About 4 meters for large grid and 1.2m for small float softAreaVertical = 2 * deformationOffset; var invWorld = m_grid.PositionComp.GetWorldMatrixNormalizedInv(); var pos = Vector3D.Transform(pt.ContactPosition, invWorld); var normal = Vector3D.TransformNormal(pt.ContactPoint.Normal, invWorld) * pt.ContactPointDirection; bool destroyed = ApplyDeformation(deformationOffset, softAreaPlanar, softAreaVertical, pos, normal, MyDamageType.Deformation); if (explosionRadius > 0 && deformationOffset > m_grid.GridSize / 2 && destroyed) { var info = new ExplosionInfo() { Position = pt.ContactPosition, //ExplosionType = destroyed ? MyExplosionTypeEnum.GRID_DESTRUCTION : MyExplosionTypeEnum.GRID_DEFORMATION, ExplosionType = MyExplosionTypeEnum.GRID_DESTRUCTION, Radius = explosionRadius, ModelDebris = destroyed, }; m_explosions.Add(info); } else { //cannot be here since its onlyexecuted on server //AddCollisionEffect(pt.ContactPoint.Position, normal); } ProfilerShort.End(); }
public void PerformMeteoritDeformation(ref HkBreakOffPointInfo pt, float separatingVelocity) { ProfilerShort.Begin("PerformDeformation"); Debug.Assert(Sync.IsServer, "Function PerformDeformation should not be called from client"); // Calculate deformation offset float deformationOffset = 0.3f + Math.Max(0, ((float)Math.Sqrt(Math.Abs(separatingVelocity) + Math.Pow(pt.CollidingBody.Mass, 0.72))) / 10); deformationOffset *= 6; const float maxDeformationHardLimit = 5; // Max offset is 5 for meteors deformationOffset = Math.Min(deformationOffset, maxDeformationHardLimit); float softAreaPlanar = (float)Math.Pow(pt.CollidingBody.Mass, 0.15f); softAreaPlanar -= 0.3f; softAreaPlanar *= m_grid.GridSizeEnum == MyCubeSize.Large ? 4 : 1f; // About 4 meters for large grid and 1m for small float softAreaVertical = deformationOffset; softAreaVertical *= m_grid.GridSizeEnum == MyCubeSize.Large ? 1 : 0.2f; var invWorld = m_grid.PositionComp.GetWorldMatrixNormalizedInv(); var pos = Vector3D.Transform(pt.ContactPosition, invWorld); var normal = Vector3.TransformNormal(pt.ContactPoint.Normal, invWorld) * pt.ContactPointDirection; bool destroyed = ApplyDeformation(deformationOffset, softAreaPlanar, softAreaVertical, pos, normal, MyDamageType.Deformation, 0, m_grid.GridSizeEnum == MyCubeSize.Large ? 0.6f : 0.16f); MyPhysics.CastRay(pt.ContactPoint.Position, pt.ContactPoint.Position - softAreaVertical * Vector3.Normalize(pt.ContactPoint.Normal), m_hitList); foreach (var hit in m_hitList) { var entity = hit.HkHitInfo.Body.GetEntity(); if (entity != m_grid.Components && entity is MyCubeGrid) { var grid = entity as MyCubeGrid; invWorld = grid.PositionComp.GetWorldMatrixNormalizedInv(); pos = Vector3D.Transform(pt.ContactPosition, invWorld); normal = Vector3.TransformNormal(pt.ContactPoint.Normal, invWorld) * pt.ContactPointDirection; grid.Physics.ApplyDeformation(deformationOffset, softAreaPlanar * (m_grid.GridSizeEnum == grid.GridSizeEnum ? 1 : grid.GridSizeEnum == MyCubeSize.Large ? 2 : 0.25f), softAreaVertical * (m_grid.GridSizeEnum == grid.GridSizeEnum ? 1 : grid.GridSizeEnum == MyCubeSize.Large ? 2.5f : 0.2f), pos, normal, MyDamageType.Deformation, 0, grid.GridSizeEnum == MyCubeSize.Large ? 0.6f : 0.16f); } } m_hitList.Clear(); float explosionRadius = Math.Max(m_grid.GridSize, deformationOffset * (m_grid.GridSizeEnum == MyCubeSize.Large ? 0.25f : 0.05f)); if (explosionRadius > 0 && deformationOffset > m_grid.GridSize / 2 && destroyed) { var info = new ExplosionInfo() { Position = pt.ContactPosition, ExplosionType = MyExplosionTypeEnum.GRID_DESTRUCTION, Radius = explosionRadius, ModelDebris = destroyed, }; m_explosions.Add(info); } else { AddCollisionEffect(pt.ContactPosition, normal); } ProfilerShort.End(); }
private bool PerformDeformation(ref HkBreakOffPointInfo pt, bool fromBreakParts, float separatingVelocity, MyEntity otherEntity) { if (!m_grid.BlocksDestructionEnabled) return false; ProfilerShort.Begin("PerformDeformation"); Debug.Assert(Sync.IsServer, "Function PerformDeformation should not be called from client"); var mass = this.Mass; if (IsStatic) { mass = pt.CollidingBody.Mass; } float velocity = separatingVelocity; float deltaV = pt.BreakingImpulse / mass; // Calculate deformation offset float deformationOffset = 0.3f + Math.Max(0, (Math.Abs(velocity) - deltaV) / 15); deformationOffset *= 3; deformationOffset *= MyFakes.DEFORMATION_RATIO; const float maxDeformationHardLimit = 20; // Happens during copy pasting //Debug.Assert(deformationOffset < maxDeformationHardLimit, "Deformation is bigger than maximum."); deformationOffset = Math.Min(deformationOffset, maxDeformationHardLimit); float explosionRadius = Math.Max(m_grid.GridSize, deformationOffset); explosionRadius = Math.Min(explosionRadius, 10); bool hitVoxel = otherEntity is MyVoxelBase; if (hitVoxel) { // Hardness from 0 to 1 float hardness = 0.0f; deformationOffset *= 1 + hardness; explosionRadius *= 1 - hardness; } float softAreaPlanar = m_grid.GridSizeEnum == MyCubeSize.Large ? 4 : 1.2f; // About 4 meters for large grid and 1.2m for small float softAreaVertical = 1.5f * deformationOffset; var invWorld = m_grid.PositionComp.WorldMatrixNormalizedInv; var pos = Vector3D.Transform(pt.ContactPosition, invWorld); var velAtPoint = GetVelocityAtPoint(pt.ContactPosition); if (!velAtPoint.IsValid() || velAtPoint == Vector3.Zero) velAtPoint = pt.ContactPoint.Normal; var len = velAtPoint.Normalize(); Vector3 normal; if (len > 5) { normal = Vector3.TransformNormal(velAtPoint, invWorld) * pt.ContactPointDirection; normal.Normalize(); } else normal = pt.ContactPointDirection * pt.ContactPoint.Normal; int destroyed = ApplyDeformation(deformationOffset, softAreaPlanar, softAreaVertical, pos, normal, MyDamageType.Deformation, attackerId: otherEntity != null ? otherEntity.EntityId : 0); if (destroyed != 0) { if (len > 1) len = len / 10; RigidBody.ApplyPointImpulse(-velAtPoint *0.3f* Math.Min(destroyed * len * (Mass / 5), Mass * 5), pt.ContactPoint.Position); RigidBody.Gravity = Vector3.Zero; DisableGravity = 1; } if (explosionRadius > 0 && deformationOffset > m_grid.GridSize / 2 && destroyed != 0) { var info = new ExplosionInfo() { Position = pt.ContactPosition + pt.ContactPointDirection * pt.ContactPoint.Normal * explosionRadius * 0.5f, //ExplosionType = destroyed ? MyExplosionTypeEnum.GRID_DESTRUCTION : MyExplosionTypeEnum.GRID_DEFORMATION, ExplosionType = MyExplosionTypeEnum.GRID_DESTRUCTION, Radius = explosionRadius, ShowParticles = (otherEntity is MyVoxelPhysics) == false && (otherEntity is MyTrees) == false, GenerateDebris = true }; m_explosions.Add(info); } else { //cannot be here since its onlyexecuted on server //AddCollisionEffect(pt.ContactPoint.Position, normal); } ProfilerShort.End(); return destroyed != 0; }