private float AddDamage(float damage, AttackType attackType, MetaDataNode data,
                            BasicTile basicTile, Vector3 worldPosition)
    {
        data.AddTileDamage(Layer.LayerType, basicTile.Armor.GetDamage(damage < basicTile.damageDeflection? 0: damage, attackType));
        SoundManager.PlayNetworkedAtPos(basicTile.SoundOnHit, worldPosition);
        if (data.GetTileDamage(Layer.LayerType) >= basicTile.MaxHealth)
        {
            data.RemoveTileDamage(Layer.LayerType);
            tileChangeManager.RemoveTile(data.Position, Layer.LayerType);
            basicTile.LootOnDespawn?.SpawnLoot(worldPosition);
        }

        return(CalculateAbsorbDamaged(attackType, data, basicTile));
    }
    private float CalculateAbsorbDamaged(AttackType attackType, MetaDataNode data, BasicTile basicTile)
    {
        var damage = basicTile.MaxHealth - data.GetTileDamage(Layer.LayerType);

        if (basicTile.MaxHealth < damage)
        {
            data.ResetDamage(Layer.LayerType);
        }

        if (basicTile.Armor.GetRatingValue(attackType) > 0 && damage > 0)
        {
            return(damage / basicTile.Armor.GetRatingValue(attackType));
        }

        return(0);
    }
Beispiel #3
0
    private float AddDamage(float damage, AttackType attackType, MetaDataNode data,
                            BasicTile basicTile, Vector3 worldPosition)
    {
        if (basicTile.indestructible || damage < basicTile.damageDeflection)
        {
            return(0);
        }

        var damageTaken = basicTile.Armor.GetDamage(damage < basicTile.damageDeflection ? 0 : damage, attackType);

        data.AddTileDamage(Layer.LayerType, damageTaken);

        if (basicTile.SoundOnHit != null && !string.IsNullOrEmpty(basicTile.SoundOnHit.AssetAddress) && basicTile.SoundOnHit.AssetAddress != "null")
        {
            if (damage >= 1)
            {
                SoundManager.PlayNetworkedAtPos(basicTile.SoundOnHit, worldPosition);
            }
        }

        var totalDamageTaken = data.GetTileDamage(Layer.LayerType);

        if (totalDamageTaken >= basicTile.MaxHealth)
        {
            if (basicTile.SoundOnDestroy.Count > 0)
            {
                SoundManager.PlayNetworkedAtPos(basicTile.SoundOnDestroy.RandomElement(), worldPosition);
            }
            data.RemoveTileDamage(Layer.LayerType);
            tileChangeManager.RemoveTile(data.Position, Layer.LayerType);
            tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Effects, TileChangeManager.OverlayType.Damage);

            if (Layer.LayerType == LayerType.Floors || Layer.LayerType == LayerType.Base)
            {
                tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Floors, TileChangeManager.OverlayType.Cleanable);
            }

            if (Layer.LayerType == LayerType.Walls)
            {
                tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Walls, TileChangeManager.OverlayType.Cleanable);
            }

            //Add new tile if needed
            //TODO change floors to using overlays, but generic overlay will need to be sprited
            if (basicTile.ToTileWhenDestroyed != null)
            {
                var damageLeft = totalDamageTaken - basicTile.MaxHealth;
                var tile       = basicTile.ToTileWhenDestroyed as BasicTile;

                var overFlowProtection = 0;

                while (damageLeft > 0 && tile != null)
                {
                    overFlowProtection++;

                    if (tile.MaxHealth <= damageLeft)
                    {
                        damageLeft -= tile.MaxHealth;
                        tile        = tile.ToTileWhenDestroyed as BasicTile;
                    }
                    else
                    {
                        //Atm we just set remaining damage to 0, instead of absorbing it for the new tile
                        damageLeft = 0;
                        tileChangeManager.UpdateTile(data.Position, tile);
                        break;
                    }

                    if (overFlowProtection > maxOverflowProtection)
                    {
                        Logger.LogError($"Overflow protection triggered on {basicTile.name}, ToTileWhenDestroyed is spawning tiles in a loop", Category.TileMaps);
                        break;
                    }
                }

                damageTaken = damageLeft;
            }

            if (basicTile.SpawnOnDestroy != null)
            {
                basicTile.SpawnOnDestroy.SpawnAt(SpawnDestination.At(worldPosition, metaTileMap.ObjectLayer.gameObject.transform));
            }

            basicTile.LootOnDespawn?.SpawnLoot(worldPosition);
        }
        else
        {
            if (basicTile.DamageOverlayList != null)
            {
                foreach (var overlayData in basicTile.DamageOverlayList.DamageOverlays)
                {
                    if (overlayData.damagePercentage <= totalDamageTaken / basicTile.MaxHealth)
                    {
                        tileChangeManager.AddOverlay(data.Position, overlayData.overlayTile);
                        break;
                    }
                }
            }

            //All the damage was absorbed, none left to return for next layer
            damageTaken = 0;
        }

        if (basicTile.MaxHealth < basicTile.MaxHealth - totalDamageTaken)
        {
            data.ResetDamage(Layer.LayerType);
        }

        if (damageTaken > totalDamageTaken)
        {
            Logger.LogError($"Applying damage to {basicTile.DisplayName} increased the damage to be dealt, when it should have decreased!", Category.Damage);
            return(totalDamageTaken);
        }

        //Return how much damage is left
        return(damageTaken);
    }
Beispiel #4
0
    private float AddDamage(float Energy, AttackType attackType, MetaDataNode data,
                            BasicTile basicTile, Vector3 worldPosition)
    {
        float energyAbsorbed = 0;

        if (basicTile.indestructible || Energy < basicTile.damageDeflection)
        {
            if (attackType == AttackType.Bomb && basicTile.ExplosionImpassable == false)
            {
                return(Energy * 0.375f);
            }
            else
            {
                if (attackType == AttackType.Bomb)
                {
                    return(energyAbsorbed * 0.85f);
                }
                else
                {
                    return(energyAbsorbed);
                }
            }
        }

        var damageTaken = basicTile.Armor.GetDamage(Energy, attackType);

        data.AddTileDamage(Layer.LayerType, damageTaken);

        if (basicTile.SoundOnHit != null && !string.IsNullOrEmpty(basicTile.SoundOnHit.AssetAddress) && basicTile.SoundOnHit.AssetAddress != "null")
        {
            if (damageTaken >= 1)
            {
                SoundManager.PlayNetworkedAtPos(basicTile.SoundOnHit, worldPosition);
            }
        }

        var totalDamageTaken = data.GetTileDamage(Layer.LayerType);

        if (totalDamageTaken >= basicTile.MaxHealth)
        {
            float excessEnergy = basicTile.Armor.GetForce(totalDamageTaken - basicTile.MaxHealth, attackType);
            if (basicTile.SoundOnDestroy.Count > 0)
            {
                SoundManager.PlayNetworkedAtPos(basicTile.SoundOnDestroy.RandomElement(), worldPosition);
            }
            data.RemoveTileDamage(Layer.LayerType);
            tileChangeManager.RemoveTile(data.Position, Layer.LayerType);
            tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Effects, OverlayType.Damage);

            if (Layer.LayerType == LayerType.Floors || Layer.LayerType == LayerType.Base)
            {
                tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Floors, OverlayType.Cleanable);
            }

            if (Layer.LayerType == LayerType.Walls)
            {
                tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Walls, OverlayType.Cleanable);
                tileChangeManager.RemoveOverlaysOfType(data.Position, LayerType.Effects, OverlayType.Mining);
            }

            //Add new tile if needed
            //TODO change floors to using overlays, but generic overlay will need to be sprited
            //TODO Use Armour values
            //TODO have tiles present but one z down
            if (basicTile.ToTileWhenDestroyed != null)
            {
                var tile = basicTile.ToTileWhenDestroyed as BasicTile;

                var overFlowProtection = 0;

                while (excessEnergy > 0 && tile != null)
                {
                    overFlowProtection++;

                    if (tile.MaxHealth <= excessEnergy)
                    {
                        excessEnergy -= tile.MaxHealth;
                        tile          = tile.ToTileWhenDestroyed as BasicTile;
                    }
                    else
                    {
                        //Atm we just set remaining damage to 0, instead of absorbing it for the new tile
                        excessEnergy = 0;
                        tileChangeManager.UpdateTile(data.Position, tile);
                        break;
                    }

                    if (overFlowProtection > maxOverflowProtection)
                    {
                        Logger.LogError($"Overflow protection triggered on {basicTile.name}, ToTileWhenDestroyed is spawning tiles in a loop", Category.TileMaps);
                        break;
                    }
                }

                energyAbsorbed = Energy - excessEnergy;
            }

            if (basicTile.SpawnOnDestroy != null)
            {
                basicTile.SpawnOnDestroy.SpawnAt(SpawnDestination.At(worldPosition, metaTileMap.ObjectLayer.gameObject.transform));
            }

            basicTile.LootOnDespawn?.SpawnLoot(worldPosition);
        }
        else
        {
            if (basicTile.DamageOverlayList != null)
            {
                foreach (var overlayData in basicTile.DamageOverlayList.DamageOverlays)
                {
                    if (overlayData.damagePercentage <= totalDamageTaken / basicTile.MaxHealth)
                    {
                        tileChangeManager.AddOverlay(data.Position, overlayData.overlayTile);
                        break;
                    }
                }
            }

            //All the damage was absorbed, none left to return for next layer
            energyAbsorbed = Energy;
        }

        if (basicTile.MaxHealth < basicTile.MaxHealth - totalDamageTaken)
        {
            data.ResetDamage(Layer.LayerType);
        }

        if (attackType == AttackType.Bomb && basicTile.ExplosionImpassable == false)
        {
            return(energyAbsorbed * 0.375f);
        }
        else
        {
            if (attackType == AttackType.Bomb)
            {
                return(energyAbsorbed * 0.85f);
            }
            else
            {
                return(energyAbsorbed);
            }
        }
    }