Static lookup table for ammunition ballistics in HorizonRP. Maps ammo ident strings to a Round record holding muzzle energy, penetration and caliber, with derived hole scale; unknown ammo falls back to a default handgun round.
namespace HorizonRP;
/// <summary>
/// Ce qu'une munition fait à un véhicule, d'après l'énergie de sa balle à la bouche (en joules,
/// ordres de grandeur réels) : la caisse perd l'énergie ÷ 45, le moteur — balle arrivée à
/// l'avant — l'énergie ÷ 30 multipliée par la pénétration. Un 9 mm entame à peine la tôle
/// (11 points sur 1 000), une 5,56 en ôte 39, une .50 BMG 380 : trois balles et la caisse est
/// à terre, une seule dans le compartiment moteur et il cale.
///
/// La chevrotine : l'énergie de la cartouche est répartie entre ses plombs (WeaponEntry.Bullets),
/// chacun touchant pour son compte. Une munition inconnue compte comme une balle de pistolet
/// un peu forte.
/// </summary>
public static class Ballistics
{
/// <summary>Énergie (J), pénétration (1 : une balle de fusil), diamètre de l'impact (mm).</summary>
public sealed record Round( float Energy, float Penetration, float Caliber )
{
/// <summary>La taille du trou laissé dans la tôle (1 : une balle de 5,56).</summary>
public float HoleScale => 0.6f + Caliber / 14f;
}
static readonly Dictionary<string, Round> rounds = new()
{
["munitions_9mm"] = new( 500, 0.35f, 9 ),
["munitions_9x18"] = new( 300, 0.3f, 9 ),
["munitions_45"] = new( 550, 0.35f, 11.4f ),
["munitions_357"] = new( 1000, 0.6f, 9.1f ),
["munitions_50ae"] = new( 2000, 0.6f, 12.7f ),
["munitions_454"] = new( 2400, 0.65f, 11.5f ),
["munitions_57"] = new( 500, 0.8f, 5.7f ), // conçue pour percer : peu d'énergie, passe bien
["munitions_545"] = new( 1350, 1f, 5.45f ),
["munitions_556"] = new( 1750, 1f, 5.56f ),
["munitions_762"] = new( 2050, 1f, 7.62f ),
["munitions_308"] = new( 3400, 1.2f, 7.62f ),
["munitions_762r"] = new( 3600, 1.2f, 7.62f ),
["munitions_9x39"] = new( 700, 0.9f, 9 ), // subsonique, mais perforante (SP-6)
["munitions_127"] = new( 2800, 1.3f, 12.7f ),
["munitions_50bmg"] = new( 17000, 2f, 12.7f ),
["munitions_12"] = new( 3200, 0.3f, 8 ), // la cartouche entière, partagée entre les plombs
["munitions_23"] = new( 9000, 0.6f, 23 ),
};
static readonly Round Unknown = new( 800, 0.5f, 9 );
public static Round Of( string ammo ) => ammo is not null && rounds.TryGetValue( ammo, out var r ) ? r : Unknown;
}