Пример #1
0
        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();
                }
            }
        }
Пример #2
0
    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);
    }
Пример #3
0
    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();
    }
Пример #4
0
    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);
        }
    }
Пример #5
0
    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);
    }
Пример #6
0
 public void OnInitialize(ExplosionInfo info)
 {
     _radius = info.Radius;
     _damage = info.Damage;
     _force  = info.Force;
     _method = info.PropagationMethod;
     _tag    = info.Tag;
 }
Пример #7
0
 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!
 }
Пример #9
0
    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());
    }
Пример #10
0
 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);
         }
     }
 }
Пример #11
0
        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();
        }
Пример #12
0
        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);
            }
        }
Пример #13
0
    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);
    }
Пример #14
0
    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);
        }
      }

    }
Пример #15
0
        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();
        }
Пример #16
0
        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);
        }
Пример #17
0
        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);
                    }
                }
            }
        }
Пример #18
0
    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();
    }
Пример #19
0
    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);
        }
      }

    }
Пример #20
0
    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);
      }
    }
Пример #21
0
        /// <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");
            }
        }
Пример #22
0
 public GrenadeBulletInfoBuilder SetExplosionInfo(ExplosionInfo explosionInfo)
 {
     _info.ExplosionInfo = explosionInfo;
     return(this);
 }
Пример #23
0
        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();
        }
Пример #24
0
        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();
        }
Пример #25
0
        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;
        }