Exemplo n.º 1
0
    /// <summary>
    /// Plays explosion sound and shakes ground
    /// </summary>
    private void PlaySoundAndShake(Vector3Int explosionPosition)
    {
        byte shakeIntensity = (byte)Mathf.Clamp(damage / 5, byte.MinValue, byte.MaxValue);

        ExplosionUtils.PlaySoundAndShake(explosionPosition, shakeIntensity, (int)shakeDistance);
    }
Exemplo n.º 2
0
    private void CheckTileCollisions(MatrixIntersection i)
    {
        if (i.Matrix1 == null || i.Matrix2 == null)
        {
            return;
        }

        byte collisions = 0;

        foreach (var worldPos in i.Rect.allPositionsWithin())
        {
            Vector3Int cellPos1 = i.Matrix1.MetaTileMap.WorldToCell(worldPos);

            if (!i.Matrix1.Matrix.HasTile(cellPos1, true))
            {
                continue;
            }

            Vector3Int cellPos2 = i.Matrix2.MetaTileMap.WorldToCell(worldPos);
            if (!i.Matrix2.Matrix.HasTile(cellPos2, true))
            {
                continue;
            }

            float resistance1 = i.Matrix1.MetaTileMap.Resistance(cellPos1, true);
            if (resistance1 <= 0f)
            {
                continue;
            }

            float resistance2 = i.Matrix2.MetaTileMap.Resistance(cellPos2, true);
            if (resistance2 <= 0f)
            {
                continue;
            }

            collisionLocations.Add(worldPos);

            //
            // ******** DESTROY STUFF!!! ********
            //

            //total damage to apply to victim tile
            if (resistance1 + (10 * i.Matrix1.Speed) >= resistance2 + (10 * i.Matrix2.Speed))
            {
                //attacker tile is stronger:

                //destroy victim tile
                TryPushing(i.Matrix2, cellPos2, i.Matrix1.MovementVector, i.Matrix1.Speed);
                ApplyCritDamage(i.Matrix2, cellPos2, worldPos);

                //slightly damage adjacent victim tiles
                ApplyTilemapDamage(i.Matrix2, cellPos2 + Vector3Int.up, resistance1 * 0.4f, worldPos);
                ApplyTilemapDamage(i.Matrix2, cellPos2 + Vector3Int.down, resistance1 * 0.4f, worldPos);
                ApplyTilemapDamage(i.Matrix2, cellPos2 + Vector3Int.left, resistance1 * 0.4f, worldPos);
                ApplyTilemapDamage(i.Matrix2, cellPos2 + Vector3Int.right, resistance1 * 0.4f, worldPos);

                //damage back attacker
                TryPushing(i.Matrix1, cellPos1, i.Matrix2.MovementVector, i.Matrix2.Speed);
                ApplyDamage(i.Matrix1, cellPos1, resistance2, worldPos);
                if (resistance2 > EXTRA_COLLISION_THRESHOLD)
                {
                    collisions += (byte)((resistance2 - EXTRA_COLLISION_THRESHOLD) / EXTRA_COLLISION_THRESHOLD);
                }
            }
            else
            {
                //victim tile is stronger

                //destroy weaker tile
                TryPushing(i.Matrix1, cellPos1, i.Matrix2.MovementVector, i.Matrix2.Speed);
                ApplyCritDamage(i.Matrix1, cellPos1, worldPos);

                //slightly damage adjacent tiles
                ApplyTilemapDamage(i.Matrix1, cellPos1 + Vector3Int.up, resistance2 * 0.4f, worldPos);
                ApplyTilemapDamage(i.Matrix1, cellPos1 + Vector3Int.down, resistance2 * 0.4f, worldPos);
                ApplyTilemapDamage(i.Matrix1, cellPos1 + Vector3Int.left, resistance2 * 0.4f, worldPos);
                ApplyTilemapDamage(i.Matrix1, cellPos1 + Vector3Int.right, resistance2 * 0.4f, worldPos);

                //damage back
                TryPushing(i.Matrix2, cellPos2, i.Matrix1.MovementVector, i.Matrix1.Speed);
                ApplyDamage(i.Matrix2, cellPos2, resistance1, worldPos);
                if (resistance1 > EXTRA_COLLISION_THRESHOLD)
                {
                    collisions += (byte)((resistance1 - EXTRA_COLLISION_THRESHOLD) / EXTRA_COLLISION_THRESHOLD);
                }
            }

            collisions++;

            //Wires (since they don't have Integrity)
            ApplyWireDamage(i.Matrix1, cellPos1);
            ApplyWireDamage(i.Matrix2, cellPos2);

            //Heat shit up
            i.Matrix1.ReactionManager.ExposeHotspot(cellPos1, 500);
            i.Matrix2.ReactionManager.ExposeHotspot(cellPos2, 500);

            //Other
            foreach (var layer in layersToRemove)
            {
                i.Matrix1.TileChangeManager.MetaTileMap.RemoveTileWithlayer(cellPos1, layer);
                i.Matrix2.TileChangeManager.MetaTileMap.RemoveTileWithlayer(cellPos2, layer);
            }
            foreach (var layer in effectsToRemove)
            {
                i.Matrix1.TileChangeManager.MetaTileMap.RemoveAllOverlays(cellPos1, layer);
                i.Matrix2.TileChangeManager.MetaTileMap.RemoveAllOverlays(cellPos2, layer);
            }
        }

        if (collisions > 0)
        {
            var epicenter = collisionLocations[collisionLocations.Count / 2];

            ExplosionUtils.PlaySoundAndShake(
                epicenter,
                (byte)Mathf.Clamp(collisions * 12, 16, byte.MaxValue),
                Mathf.Clamp(collisions * 8, 15, 127)
                );
            SlowDown(i, collisions);

            if (collisions > 6 && Mathf.Max(i.Matrix1.Speed, i.Matrix2.Speed) > 6)
            {
                i.Matrix1.Matrix.OnEarthquake.Invoke(epicenter, collisions);
                i.Matrix2.Matrix.OnEarthquake.Invoke(epicenter, collisions);
            }
            collisionLocations.Clear();
        }

        //Damage methods
        void ApplyDamage(MatrixInfo victimMatrix, Vector3Int cellPos, float hitEnergy, Vector3Int worldPos)
        {
            //LivingHealthBehaviour
            hitEnergy -= ApplyLivingDamage(victimMatrix, cellPos, hitEnergy);

            //TilemapDamage
            ApplyTilemapDamage(victimMatrix, cellPos, hitEnergy, worldPos);

//			//Integrity
            ApplyIntegrityDamage(victimMatrix, cellPos, hitEnergy);
        }

        void ApplyCritDamage(MatrixInfo victimMatrix, Vector3Int cellPos, Vector3Int worldPos)
        {
            //LivingHealthBehaviour
            ApplyLivingDamage(victimMatrix, cellPos, 9001);

            //TilemapDamage
            ApplyTilemapDamage(victimMatrix, cellPos, 9001, worldPos);

            //Integrity
            ApplyIntegrityDamage(victimMatrix, cellPos, 9001);

            //Underfloor
            RemoveUnderfloor(victimMatrix, cellPos);
        }

        void RemoveUnderfloor(MatrixInfo matrix, Vector3Int cellPos)
        {
            if (matrix == null)
            {
                return;
            }

            var Node = matrix.Matrix.GetMetaDataNode(cellPos);

            if (Node != null)
            {
                foreach (var electricalData in Node.ElectricalData)
                {
                    electricalData.InData.DestroyThisPlease();
                }
            }
        }

        void ApplyTilemapDamage(MatrixInfo matrix, Vector3Int cellPos, float damage, Vector3Int worldPos)
        {
            if (matrix == null)
            {
                return;
            }

            matrix.MetaTileMap.ApplyDamage(cellPos, damage, worldPos);
            if (damage > 9000)
            {
                foreach (var damageableLayer in matrix.MetaTileMap.LayersValues)
                {
                    if (damageableLayer.LayerType == LayerType.Objects)
                    {
                        continue;
                    }
                    matrix.TileChangeManager.MetaTileMap.RemoveTileWithlayer(cellPos, damageableLayer.LayerType);
                }
            }
        }

        void ApplyWireDamage(MatrixInfo matrix, Vector3Int cellPos)
        {
            if (matrix == null)
            {
                return;
            }

            foreach (var wire in matrix.Matrix.Get <CableInheritance>(cellPos, true))
            {
                if (Random.value >= 0.5)
                {
                    // Sparks
                    wire.QueueForDemolition(wire);
                    StartCoroutine(DestroyWireWithDelay(wire, (byte)(Random.value * 20f)));
                }
                else
                {
                    // Destruction
                    wire.ToDestroy();
                }
            }
        }

        float ApplyIntegrityDamage(MatrixInfo matrix, Vector3Int cellPos, float damage)
        {
            if (matrix == null)
            {
                return(0);
            }

            float resistance = 0f;

            foreach (var integrity in matrix.Matrix.Get <Integrity>(cellPos, true))
            {
                resistance += integrity.integrity;
                integrity.ApplyDamage(damage, AttackType.Melee, DamageType.Brute);
            }

            return(resistance);
        }

        float ApplyLivingDamage(MatrixInfo matrix, Vector3Int cellPos, float damage)
        {
            if (matrix == null)
            {
                return(0);
            }

            byte count = 0;

            foreach (var healthBehaviour in matrix.Matrix.Get <LivingHealthMasterBase>(cellPos, true))
            {
                healthBehaviour.ApplyDamageToBodyPart(matrix.GameObject, damage, AttackType.Melee, DamageType.Brute);
                count++;
            }

            return(count * 50);
        }

        void TryPushing(MatrixInfo matrix, Vector3Int cellPos, Vector2Int pushVector, float speed)
        {
            if (matrix == null || pushVector == Vector2Int.zero)
            {
                return;
            }

            foreach (var pushPull in matrix.Matrix.Get <PushPull>(cellPos, true))
            {
                byte pushes = (byte)Mathf.Clamp(speed / 4, 1, 4);
                for (int j = 0; j < pushes; j++)
                {
                    pushPull.QueuePush(pushVector, speed * Random.Range(0.8f, 1.1f));
                }
            }
        }

        IEnumerator DestroyWireWithDelay(CableInheritance wire, byte timer)
        {
            yield return(WaitFor.Seconds(timer));

            if (wire != null)
            {
                wire.ToDestroy();
            }
        }
    }
Exemplo n.º 3
0
    /// <summary>
    /// Plays explosion sound and shakes ground
    /// </summary>
    private void PlaySoundAndShake()
    {
        byte shakeIntensity = (byte)Mathf.Clamp(damage / 5, byte.MinValue, byte.MaxValue);

        ExplosionUtils.PlaySoundAndShake(objectBehaviour.AssumedWorldPositionServer().RoundToInt(), shakeIntensity, (int)shakeDistance);
    }