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); }
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); }
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); } } }