# Script MasterFire

MasterFire : simulation d'incendies pour FiveM (MasterMods).

# Présentation

MasterFire est le script d'incendies de MasterMods pour FiveM. Il fait apparaître des feux qui se propagent, évoluent et se combattent de façon réaliste, avec une gestion complète des interventions pour les serveurs pompiers.

## Ce que fait le script

- **Feux vivants** : chaque feu naît petit, se développe, peut s'embraser puis décliner quand son combustible s'épuise. Une attaque rapide évite le pire.
- **Propagation réaliste** : selon la surface (herbe, bois, béton, route, eau), le vent, la météo et les murs. Un feu ne traverse pas un mur et ne se propage pas sur l'eau.
- **Bon agent, bon feu** : eau, lance canon, mousse, poudre, CO₂. L'eau aggrave un feu de carburant et électrise sur un feu électrique.
- **Feux en intérieur** : chaleur qui s'accumule, fumée sous plafond, et phénomènes dangereux : **flashover**, **backdraft**, **BLEVE** de citerne, avec signes précurseurs.
- **Fumée** : dégâts sans appareil respiratoire (ARI), visibilité réduite.
- **Interventions** : un ou plusieurs foyers = une intervention, avec un seul appel, un blip, une fin d'intervention automatique et un rapport (durée, intervenants, agents utilisés).
- **Menu `/mfire`** : allumer un feu, choisir un préréglage (poubelle, voiture, habitation, entrepôt, citerne…), régler flammes et fumée, **placer plusieurs foyers à la souris** avec aperçu, enregistrer des scénarios, générateur aléatoire.
- **Dispatch** : intégré (notification, blip, GPS), ps-dispatch, cd_dispatch, ou votre propre système.
- **MasterLadder** : la lance canon de l'échelle éteint les feux MasterFire.
- **Sécurité** : le serveur décide de tout. Les joueurs ne peuvent ni créer, ni supprimer, ni éteindre un feu à distance par triche.
- **Performances** : les effets ne sont affichés qu'à proximité (160 m) et retirés en s'éloignant.

## Compatibilité

- **OneSync** obligatoire
- **Frameworks** : ESX, QBCore, QBox, ox_core, Standalone
- **Notifications** : ox_lib, ESX, QBCore, QBox, okok, GTA
- **Dispatch** : intégré, ps-dispatch, cd_dispatch, autre (événement serveur)
- **Langues** : français, anglais

## Licence

MasterFire est **gratuit**. Il nécessite une **MasterKey**, gratuite elle aussi, la même que pour les autres scripts MasterMods : voir [Installation](installation).

Support : [discord.mastermods.dev](https://discord.mastermods.dev)

# Installation

## 1. MasterKey

MasterFire est gratuit mais nécessite une **MasterKey**. Si vous en avez déjà une pour MasterStretcher ou MasterLadder, c'est la même.

Sinon, créez-la sur [ressources.mastermods.dev/CreerMasterKey.php](https://ressources.mastermods.dev/CreerMasterKey.php).

## 2. Ressource

1. Décompressez l'archive et placez le dossier `MasterFire` dans `resources/`. **Ne le renommez pas** : les autres scripts l'appellent par `exports.MasterFire`.
2. Dans `server.cfg`, **après** votre framework :

```cfg
set mastermods_key "MM-XXXXX"
ensure MasterFire

# Administrateurs : tous les droits (menu /mfire, /fire…)
add_ace group.admin masterfire.admin allow

# Facultatif : rapports d'intervention sur votre Discord
set masterfire_webhook "https://discord.com/api/webhooks/..."
```

3. Ouvrez `config/config.lua` et réglez au minimum :
   - `Config.FrameworkMetier` : `esx`, `qb`, `qbx`, `ox` ou `standalone` ;
   - `Config.NotifySystem` : votre système de notifications ;
   - les droits : voir [Permissions & administration](permissions-administration).

4. Redémarrez le serveur. La console doit afficher :

```
[MasterFire] Licence MasterMods validée pour : <nom de votre serveur>
```

## 3. Premier test

En jeu, en administrateur : `/mfire`, choisissez « Incendie d'habitation », puis « Allumer devant moi ». Éteignez-le à l'extincteur (arme `WEAPON_FIREEXTINGUISHER`).

## Mise à jour

Remplacez le dossier en **conservant** vos fichiers `config/*.lua` et `data/scenarios.json` (vos scénarios enregistrés). Comparez vos fichiers de config avec ceux de la nouvelle version : les nouvelles options sont listées dans les [Journaux des changements](journaux-des-changements).

# Guide d'utilisation

## Pour les pompiers

### Recevoir l'appel
Avec le dispatch intégré, les pompiers en service reçoivent une notification (type de feu, adresse, nombre de foyers) et un blip clignotant. `/firegps` pose l'itinéraire vers le dernier appel, `/firegps 2` vers l'avant-dernier.

### Éteindre
| Moyen | Agent | Portée |
|---|---|---|
| Extincteur du jeu (viser, tirer) | Poudre | 10 m |
| Canon à eau d'un engin (`firetruk` par défaut) | Lance canon | 75 m |
| Lance canon de MasterLadder | Lance canon | portée de l'échelle |
| Script de lance compatible | Eau | 30 m |

- Chaque flamme a des points de vie. Une flamme qu'on cesse d'arroser **reprend des forces** au bout de 4 s.
- **Feu électrique** : l'eau est sans effet et vous électrise. Utilisez la poudre ou le CO₂.
- **Feu de liquide** (carburant) : l'eau l'aggrave. Utilisez la mousse, la poudre ou la lance canon.
- Arroser **refroidit** aussi le feu : c'est ce qui empêche l'embrasement et les phénomènes dangereux (voir [Réalisme](realisme)).

### Se protéger
- **Fumée** : à proximité d'un feu important, elle blesse sans ARI et réduit la visibilité (ARI ou non).
- **Signes précurseurs** : une notification vous prévient d'un risque de flashover, de backdraft ou d'explosion de citerne. Un compte à rebours s'affiche à l'écran pour une citerne en surpression.

### Fin d'intervention
Quand le dernier foyer est éteint, tous les pompiers et tous ceux qui ont arrosé reçoivent « Fin d'intervention », et le blip disparaît.

## Pour l'administration : menu `/mfire`

### Onglet Feux
- **Nouveau feu** : préréglage, type, nombre de flammes, propagation, et section **Apparence** (effet et taille des flammes, effet, taille, densité et opacité de la fumée, effet supplémentaire).
- **Allumer devant moi** ou **📍 Placer les foyers** (voir ci-dessous). La case « Envoyer l'appel aux pompiers » déclenche le dispatch.
- **Interventions en cours** : foyers, flammes, distance, durée, phase, intérieur, compte à rebours BLEVE, attaquée ou non, nombre d'intervenants. Bouton « Éteindre » par intervention, « Éteindre le plus proche », « Tout éteindre » (deux clics).

### Mode placement
« 📍 Placer les foyers » ferme le menu et passe en visée :
- **clic gauche** : poser un foyer, avec un aperçu réel des flammes et de la fumée (visible par vous seul) ;
- **clic droit** : retirer le dernier ;
- **Entrée** : valider, **Échap** : annuler.

Le cercle au sol montre la surface que le feu occupera environ. Tous les foyers forment **une seule intervention**.

### Onglet Scénarios
- Pour créer un scénario : réglez le feu dans l'onglet Feux, puis « Enregistrer ici » (un foyer devant vous) ou « 📍 Placer » (plusieurs foyers). Un scénario garde tous ses réglages.
- Pour chaque scénario : le lancer, le marquer « aléatoire », le supprimer.
- **Générateur aléatoire** : lance au hasard un scénario marqué « aléatoire », toutes les 30 min avec 50 % de chance, s'il y a au moins 3 pompiers en service (réglable).

## Commandes

| Commande | Effet |
|---|---|
| `/mfire` | Menu de gestion |
| `/fire start [type\|préréglage] [taille] [dispatch]` | Allume un feu 3 m devant soi |
| `/fire stop [n°]` | Annule l'intervention indiquée, ou la plus proche (60 m) |
| `/fire stopall` · `/fire list` | Annule toutes les interventions · les liste |
| `/fire scenario add <type\|préréglage> <taille> <nom>` | Enregistre un scénario à sa position |
| `/fire scenario del\|list\|start <n°>` | Gère les scénarios |
| `/fire scenario random <n°> on\|off` | Ajoute / retire du générateur |
| `/fire spawner on\|off` | Active / désactive le générateur |
| `/firegps [n]` | Itinéraire vers le n-ième appel reçu (tous les joueurs) |
| `/mfsurface` | Surface visée (diagnostic, `Config.Debug = true`) |
| `mfireHeartbeat` | Console serveur, `Config.Debug = true` : force licence, télémétrie et carte |

Types : `solid`, `liquid`, `electrical`, `vehicle`. Préréglages : `trash`, `car`, `house`, `warehouse`, `tanker`, `transformer`, `brush`.

# Configuration générale

Fichier `config/config.lua`. Il reste lisible après l'escrow.

## Licence et langue
- `Config.MasterModsKey` : votre MasterKey. Préférez `set mastermods_key "…"` dans `server.cfg`, prioritaire et jamais envoyé aux joueurs.
- `Config.Locale` : `fr` ou `en`.

## Framework et permissions
- `Config.FrameworkMetier` : `esx`, `qb`, `qbx`, `ox`, `standalone`.
- `Config.NotifySystem` : `ox`, `esx`, `qb`, `qbx`, `okok`, `gta`. Si le système choisi est absent, la notification native GTA prend le relais.
- `Config.JobRestriction`, `Config.AuthorizedJobs`, `Config.RequireOnDuty`, `Config.AdminAce`, `Config.FirefighterAce` : voir [Permissions & administration](permissions-administration).

## Gameplay
| Option | Défaut | Rôle |
|---|---|---|
| `MaxFires` | 20 | Foyers actifs simultanés sur le serveur |
| `MaxFlamesPerFire` | 60 | Plafond de flammes par foyer |
| `DefaultSize` | 15 | Flammes visées si la taille n'est pas précisée |
| `SpreadInterval` | 4000 | ms entre deux tentatives de propagation |
| `SpreadChance` | 35 | % de chance de propagation à chaque tentative (avant phase, surface et météo) |
| `SpreadMinDistance` / `SpreadMaxDistance` | 1,5 / 3,5 | Distance (m) entre une flamme et la suivante |
| `SpreadMaxHeightGap` | 3,0 | Dénivelé maximal accepté |
| `SpreadInitialBurst` | 0,4 | Part de la taille créée dès le départ |
| `RegenPerSecond` | 1,5 | Points de vie regagnés par une flamme non arrosée |

## Fumée
| Option | Défaut | Rôle |
|---|---|---|
| `EnableSmokeDamage` | true | Dégâts de fumée sans ARI |
| `SmokeRadius` / `SmokeDamage` / `SmokeTick` | 5 m / 2 / 2000 ms | Zone, dégâts et fréquence |
| `SmokeMinFlames` | 4 | Taille de foyer à partir de laquelle la fumée blesse |
| `SmokeVision` | true | Visibilité réduite dans la fumée |
| `SmokeVisionRadius` / `SmokeVisionStrength` | 9 m / 0,85 | Distance et intensité du voile |
| `SmokeVisionModifier` | `BarryFadeOut` | Timecycle GTA utilisé |

## Dispatch
- `Config.DispatchSystem` : `builtin`, `ps-dispatch`, `cd_dispatch`, `none`. Pour un autre système, écoutez l'événement serveur `masterfire:server:dispatch` (voir [Exports et événements](exports-et-evenements)).
- `DispatchDelay` (15 s) : délai entre l'apparition du feu et l'appel.
- `DispatchBlip`, `DispatchBlipTime`, `DispatchSound`, `DispatchKeepLast` (appels mémorisés pour `/firegps`).
- `NotifyEndOfIntervention` : message de fin d'intervention.

## Générateur aléatoire
`SpawnerOnStart`, `SpawnerInterval` (minutes), `SpawnerChance` (%), `SpawnerMinFirefighters`.

## Sécurité réseau
- `MaxAgentReportsPerSecond`, `MaxScoutRepliesPerSecond` : anti-spam par joueur.
- `ScoutRange` (150 m) : un feu ne se propage que si un joueur est à cette distance.
- `InterventionReport` : rapport Discord en fin d'intervention, sur le webhook `set masterfire_webhook "…"` de `server.cfg`.

## Rendu
`StreamInDistance` / `StreamOutDistance` (160 / 190 m), `RenderTick`, `NativeFire` (feux natifs GTA sous les effets : ils brûlent les joueurs et réagissent à l'eau du jeu), `FireSound`.

## Commandes et placement
`Command` (`fire`), `GpsCommand` (`firegps`), `MenuCommand` (`mfire`), `PlacementRange` (120 m), `MaxOriginsPerIncident` (8 foyers).

## Debug
- `Config.Debug` : journal détaillé dans la console, commandes `/mfsurface` et `mfireHeartbeat`.
- `Config.BypassPermissions` : **développement uniquement**, tous les joueurs ont tous les droits. Bandeau rouge dans le menu et avertissement dans la console. Laissez `false` en production.

# Feux, apparence et préréglages

Fichier `config/fire.lua`.

## Types de feu
| Type | Feu | PV d'une flamme | Remarque |
|---|---|---|---|
| `solid` | Sec (bois, papier, mobilier) | 100 | L'eau est l'agent idéal |
| `liquid` | Liquide (carburant, huile) | 130 | L'eau l'**aggrave** : mousse, poudre ou lance |
| `electrical` | Électrique | 80 | L'eau est sans effet et **électrise** : poudre ou CO₂ |
| `vehicle` | Véhicule | 120 | Mousse recommandée |

`effectiveness` donne le multiplicateur de chaque agent : `0` sans effet, valeur négative = aggrave. `waterShockDamage` : dégâts infligés à qui arrose un feu électrique. `spreadMultiplier` : vitesse de propagation propre au type.

## Agents
| Agent | Portée | Remarque |
|---|---|---|
| `water` | 30 m | Scripts de lance, eau du jeu |
| `cannon` | 75 m | Joueur dans un véhicule (`Config.CannonVehicles`) ; MasterLadder |
| `foam` | 30 m | Réservée à l'action `extinguish` (pompiers) |
| `powder` | 10 m | Extincteur du jeu (arme vérifiée par le serveur) |
| `co2` | 7 m | Scripts d'extincteur CO₂ |

`maxReach` est vérifié par le serveur : un impact plus loin que la portée est refusé et signalé dans les logs.

## Particules
`Config.Particles` liste les effets proposés dans le menu, par type : `flame`, `smoke`, `extra`. Ajoutez n'importe quel effet natif de GTA :

```lua
mon_effet = { kind = "smoke", label = "Ma fumée", asset = "core", name = "nom_de_l_effet", offset = 1.0 },
```

Un effet introuvable n'empêche rien : la console affiche « Effet introuvable : Config.Particles.mon_effet ».

## Préréglages
`Config.Presets` : feux prêts à l'emploi, proposés dans le menu et utilisables par `/fire start house` ou `CreateFire(coords, nil, { preset = 'house' })`.

| Préréglage | Type | Flammes | Particularité |
|---|---|---|---|
| `trash` (poubelle) | solid | 2 | Ne se propage pas |
| `car` (voiture) | vehicle | 6 | Foyer principal plus gros, fumée noire |
| `house` (habitation) | solid | 30 | Fumée noire épaisse |
| `warehouse` (entrepôt) | solid | 55 | Grands panaches |
| `tanker` (citerne) | liquid | 20 | `bleve = true` : peut exploser |
| `transformer` | electrical | 4 | Étincelles |
| `brush` (broussailles) | solid | 45 | Propagation rapide, fumée blanche |

Réglages visuels d'un préréglage (`visual`) : `flame`, `flameScale`, `mainBoost` (taille du foyer d'origine), `smoke`, `smokeScale`, `smokeEvery` (1 = fumée sur chaque flamme, 6 = légère), `smokeAlpha`, `extra`, `extraScale`, `extraEvery`. Tous sont aussi réglables dans le menu, feu par feu.

# Réalisme

Fichier `config/realism.lua`. Chaque section a un `enabled` pour la désactiver.

## Phases du feu
Chaque foyer a une **chaleur** de 0 à 100. Elle monte tant qu'il brûle (plus vite s'il est grand) et baisse quand on l'arrose : l'eau et la lance refroidissent bien, la poudre et le CO₂ peu.

| Phase | Quand | Effet |
|---|---|---|
| Éclosion | chaleur < 25 | Petites flammes, propagation ×0,5 |
| Développement | chaleur < 70 | Comportement normal |
| Embrasement | chaleur ≥ 70 | Grandes flammes, fumée épaisse, propagation ×1,8 |
| Couvant | intérieur embrasé et fermé | Flammes basses, fumée dense, ne se propage plus (voir backdraft) |
| Déclin | combustible épuisé | Le feu s'éteint de lui-même |

**Combustible** (`fuelMinutes`) : durée de vie d'un feu laissé seul, par type (sec 25 min, liquide 15, électrique et véhicule 10), plus longue pour un grand feu. `0` = illimité. Un feu éteint ainsi apparaît comme « éteint faute de combustible ».

## Surfaces
La propagation dépend de la surface sous la flamme :

| Surface | Coefficient |
|---|---|
| Végétation | ×1,7 |
| Bois | ×1,3 |
| Intérieur | ×1,1 |
| Terre | ×0,8 |
| Béton, pierre | ×0,45 |
| Métal | ×0,4 |
| Route | ×0,3 |
| Sable | ×0,2 |
| Eau | 0 (jamais) |

Un départ de feu sur une route reste donc petit, un feu de broussailles part vite.

Les surfaces sont reconnues par leur **hash de matériau** (`Config.Surfaces.materials`). Pour compléter la table : `Config.Debug = true`, visez le sol et tapez `/mfsurface`, qui affiche le hash et la catégorie retenue. Un hash inconnu compte comme « autre » (×1), et les routes sont reconnues même sans hash.

## Vent et météo
- Par vent fort, jusqu'à 75 % des nouvelles flammes partent **sous le vent**, et un peu plus loin.
- La météo multiplie la propagation et la chaleur : pluie ×0,5, orage ×0,4, neige ×0,3, canicule ×1,2…
- Seuls les feux extérieurs sont concernés. Compatible avec les scripts de synchronisation météo.

## Feux en intérieur
Détectés automatiquement dans les intérieurs du jeu et les **MLO**. Un bâtiment sans intérieur (façade seule) est traité comme un feu extérieur.
- La chaleur monte 1,6 fois plus vite.
- Flammes plus basses, fumée qui s'étale sous le plafond, visibilité encore plus réduite pour ceux qui sont dans la pièce.
- La propagation ne franchit pas la limite intérieur / extérieur ; une porte fermée l'arrête.

## Phénomènes dangereux
L'ARI ne protège pas de leurs dégâts. Les joueurs à moins de 60 m reçoivent les signes précurseurs.

### Flashover (embrasement généralisé éclair)
Un intérieur dont la chaleur atteint 90 s'embrase d'un coup : +10 flammes, dégâts dans un rayon de 9 m. À 75, l'avertissement « fumées chaudes sous plafond » invite à **refroidir**.

### Backdraft (explosion de fumées)
Un intérieur embrasé que personne n'ouvre manque d'air au bout de 2 min et devient **couvant**. Entrer alors qu'il est encore chaud (≥ 65) provoque l'explosion : +8 flammes, dégâts dans 7 m. **Refroidir depuis l'entrée** avant d'entrer l'évite, et le feu repart normalement.

### BLEVE (explosion de citerne)
Une citerne (préréglage `tanker`, ou `bleve = true`) monte en pression tant qu'elle chauffe. À mi-parcours, la soupape siffle, une alerte part et un **compte à rebours** s'affiche à l'écran. Au bout (4 min sans refroidissement), elle explose : rayon de 35 m, +20 flammes. **Arroser le foyer** fait redescendre la pression.

`nativeExplosion` ajoute l'explosion native de GTA (dégâts aux véhicules). Désactivée par défaut : beaucoup d'anticheats bloquent les explosions.

# Permissions & administration

## Les 6 actions
| Action | Donne accès à |
|---|---|
| `extinguish` | Agents réservés (mousse) |
| `dispatch` | Recevoir les appels incendie ; compte comme pompier pour le générateur |
| `stop` | `/fire stop`, `/fire stopall`, `/fire list`, liste des interventions dans le menu |
| `start` | Allumer un feu (commande, menu, placement) |
| `scenario` | Créer, lancer, supprimer des scénarios |
| `spawner` | Activer / désactiver le générateur aléatoire |

Le menu `/mfire` n'affiche que ce que le joueur a le droit de faire, et **chaque clic est revérifié par le serveur**.

## ACE (tous les modes)
```cfg
add_ace group.admin masterfire.admin allow             # toutes les actions
add_ace group.pompiers masterfire.firefighter allow    # extinguish + dispatch
add_principal identifier.license:xxxx group.pompiers
```

## Sans restriction métier
`Config.JobRestriction = false` (ou framework `standalone`) : tout le monde peut éteindre, les appels et l'administration passent **uniquement** par les ACE ci-dessus.

## Avec restriction métier
`Config.JobRestriction = true` : chaque action exige le grade minimum indiqué par métier.

```lua
Config.AuthorizedJobs = {
    ['pompier']   = { extinguish = 0, dispatch = 0, stop = 3, start = 4, scenario = 4, spawner = 4 },
    ['ambulance'] = { dispatch = 2 },
}
Config.RequireOnDuty = true -- QBCore / QBox : il faut être en service
```

Une action absente pour un métier lui est interdite. Les ACE restent prioritaires.

## Mode développement
`Config.BypassPermissions = true` donne **tous les droits à tous les joueurs**, pour tester sans rien configurer. Un bandeau rouge s'affiche dans le menu et un avertissement dans la console. **À remettre à `false` avant d'ouvrir le serveur.**

## Journaux
- **Votre Discord** : `set masterfire_webhook "https://discord.com/api/webhooks/…"` dans `server.cfg`. Vous recevez la création des feux, les rapports d'intervention (durée, foyers, intervenants, agents, phénomènes) et les comportements suspects (impact hors de portée…).
- Le webhook ne se met **jamais** dans les fichiers de config.

# Intégrations

## MasterLadder
La lance canon de la nacelle éteint les feux MasterFire : chaque impact compte comme agent `cannon`, avec son efficacité selon le type de feu, et le porteur de la lance est crédité dans le rapport d'intervention.

Côté MasterLadder (`config/config.lua`) :
```lua
Config.WaterMonitor = {
    -- …
    masterFire = { enabled = true, resource = "MasterFire", radius = 3.0, multiplier = 1.0 },
}
```

## Scripts de lance à incendie
Deux possibilités :
- le script appelle l'export client `SprayAt` pendant que l'eau coule (environ toutes les 250 ms) :
  ```lua
  exports.MasterFire:SprayAt('water', pointImpact, 1.5)
  ```
- sans intégration : si le script éteint les feux natifs de GTA (`StopFireInRange`), MasterFire le détecte et compte un impact d'eau pour le joueur à portée (`Config.ReportUnknownAsWater`).

## Appareil respiratoire (ARI)
L'ARI protège des dégâts de fumée (pas de la perte de visibilité). Un script d'ARI le déclare côté client :
```lua
exports.MasterFire:SetBreathingApparatus(true)   -- ou false à la dépose
-- ou :
LocalPlayer.state:set('masterfire:scba', true, true)
```

## Dispatch
- `Config.DispatchSystem = "ps-dispatch"` ou `"cd_dispatch"` : les appels partent vers ces scripts, pour les métiers qui ont l'action `dispatch`.
- Autre système : `Config.DispatchSystem = "none"` et écoutez l'événement serveur :
```lua
AddEventHandler('masterfire:server:dispatch', function(data)
    -- data.incidentId, data.label, data.typeLabel, data.foyers, data.coords, data.jobs
end)
```

## Autres scripts (braquages, accidents…)
```lua
-- feu de véhicule après un accident, avec appel des pompiers
exports.MasterFire:CreateFire(coords, nil, { preset = 'car', dispatch = true })
```
Voir [Exports et événements](exports-et-evenements).

# Exports et événements

## Exports serveur
```lua
-- Un foyer → fireId, incidentId (ou nil, erreur)
local fireId, incId = exports.MasterFire:CreateFire(coords, 'liquid', {
    size = 20, preset = nil, label = 'Station-service', dispatch = true,
    difficulty = 1.0, spreadChance = 35, bleve = false, visual = nil,
})

-- Plusieurs foyers = une intervention (un appel, un rapport) → incidentId, fireIds
local incId, fireIds = exports.MasterFire:CreateIncident({ c1, c2, c3 }, nil, { preset = 'house', dispatch = true })

exports.MasterFire:RemoveIncident(incId)
exports.MasterFire:RemoveFire(fireId)
exports.MasterFire:RemoveAllFires()

exports.MasterFire:GetIncidents()               -- interventions en cours (résumé)
exports.MasterFire:GetFire(fireId)              -- foyer : flammes, phase, chaleur, intérieur, BLEVE…
exports.MasterFire:GetFires()
exports.MasterFire:GetNearestFire(coords, radius) -- → foyer, distance
exports.MasterFire:IsOnFire(coords, radius)
exports.MasterFire:IsLicensed()

-- Appel de confiance (canon, échelle, bras élévateur) : pas de contrôle de portée
local flammes = exports.MasterFire:ApplyAgent('cannon', impact, 2.5, 1.0, sourceJoueur)

exports.MasterFire:StartScenario(scenarioId, dispatch) -- → incidentId
exports.MasterFire:SetSpawner(true)
```

Erreurs possibles : `license` (licence non validée), `limit` (trop de feux), `origins` (foyers invalides), `type`, `coords`.

## Exports client
```lua
exports.MasterFire:SprayAt('water', impact, 1.5)          -- validé par le serveur
exports.MasterFire:SetBreathingApparatus(true [, silencieux])
exports.MasterFire:HasBreathingApparatus()
exports.MasterFire:GetNearestFlame(coords, radius)        -- → fireId, flameId, distance
exports.MasterFire:IsNearFire(coords, radius)
exports.MasterFire:GetFires()
```

## Événements serveur (`AddEventHandler`)
| Événement | Paramètres |
|---|---|
| `masterfire:server:incidentStarted` | `incidentId, { label, type, coords, fires, scenarioId }` |
| `masterfire:server:incidentClosed` | `incidentId, résumé` (outcome `extinguished` / `burned_out` / `cancelled`, durée, intervenants, agents, phénomènes…) |
| `masterfire:server:fireCreated` | `fireId, { type, coords, size, scenarioId, incidentId }` |
| `masterfire:server:fireRemoved` | `fireId, raison, { scenarioId, incidentId }` |
| `masterfire:server:phaseChanged` | `fireId, nouvellePhase, anciennePhase` |
| `masterfire:server:phenomenon` | `fireId, 'flashover' \| 'backdraft' \| 'bleve'` |
| `masterfire:server:dispatch` | `{ incidentId, label, typeLabel, foyers, coords, jobs }` |
| `masterfire:server:licenseChanged` | `valide` |

# En cas d'erreur

Activez d'abord `Config.Debug = true` : la console détaille ce que fait le script.

## « Licence MasterMods refusée »
La console explique la raison. À vérifier :
- la clé est exacte (copier-coller depuis le portail, sans espace) et active ;
- `set mastermods_key` est placé **avant** `ensure MasterFire` ;
- moins de 3 serveurs différents l'ont utilisée ces dernières 24 h.

Tant que la licence n'est pas validée, aucun feu ne peut être créé (l'extinction reste possible).

## « API MasterMods injoignable (code 0) »
Le serveur ne peut pas sortir sur Internet (pare-feu, DNS, hébergeur). Le script tolère environ 1 h 30 de coupure avant de bloquer la création de feux.

## « DÉMARRAGE BLOQUÉ : fichier(s) manquant(s) »
Un fichier de la ressource a été supprimé ou vidé. Réinstallez depuis l'archive d'origine.

## « Vous n'avez pas la permission »
Voir [Permissions & administration](permissions-administration). Pour tester rapidement : `Config.BypassPermissions = true` (puis remettez `false`).

## Un feu existe (`/fire list`) mais rien ne s'affiche
- Un effet de `Config.Particles` est introuvable : la console F8 affiche « Effet introuvable » avec la clé. Corrigez l'asset ou le nom.
- Vous êtes à plus de 160 m (`StreamInDistance`).

## Le feu ne se propage pas
- Aucun joueur à moins de 150 m (`ScoutRange`) : c'est voulu.
- Surface peu combustible (route, sable, eau), pluie, ou propagation à 0 % (poubelle).
- Phase « couvant » ou « déclin ».
- `/mfsurface` (debug) montre la surface et la catégorie retenue.

## Le feu ne s'éteint pas
- Mauvais agent : eau sur un feu électrique (sans effet) ou de carburant (l'aggrave).
- Trop loin : chaque agent a une portée vérifiée par le serveur.
- Arrosage interrompu : une flamme reprend des forces au bout de 4 s.

## Les appels n'arrivent pas
- Personne n'a l'action `dispatch` (ACE `masterfire.firefighter`, ou métier + service).
- `Config.DispatchSystem` pointe vers un script non démarré.
- La case « Envoyer l'appel » n'était pas cochée.

## Support
[discord.mastermods.dev](https://discord.mastermods.dev) : joignez la console serveur et la console F8 avec `Config.Debug = true`.

# Journaux des changements

## 1.0.0 - 2026-10-24

Première version publique.

### Ajouté
- **Feux autoritaires côté serveur** : aucun événement réseau ne permet de créer, supprimer ou éteindre un feu à distance ; impacts vérifiés (portée, arme, véhicule, droits) et limités en débit.
- **Propagation validée par la géométrie** : un joueur proche vérifie sol, murs et eau ; pas de flamme à travers un mur ni sur l'eau.
- **Types de feu** (sec, liquide, électrique, véhicule) et **agents** (eau, lance canon, mousse, poudre, CO₂) avec efficacité propre ; l'eau aggrave un feu de liquide et électrise sur un feu électrique.
- **Réalisme** : phases du feu (éclosion, développement, embrasement, couvant, déclin), chaleur et refroidissement, combustible qui s'épuise, surfaces (végétation, béton, route, eau…), vent et météo, feux en intérieur.
- **Phénomènes dangereux** : flashover, backdraft et BLEVE de citerne, avec signes précurseurs et compte à rebours.
- **Fumée** : dégâts sans ARI, visibilité réduite ; export `SetBreathingApparatus`.
- **Interventions** : plusieurs foyers = un appel, un blip, une fin d'intervention automatique et un rapport (durée, intervenants, agents, phénomènes).
- **Menu `/mfire`** : préréglages, réglage des flammes et de la fumée, **mode placement** multi-foyers avec aperçu, scénarios, générateur aléatoire.
- **Dispatch** intégré (notification, blip, `/firegps`), ps-dispatch, cd_dispatch, ou événement serveur.
- **Intégration MasterLadder** : la lance canon éteint les feux MasterFire.
- **Permissions** par ACE ou par métier et grade (ESX, QBCore, QBox, ox_core, Standalone).
- Licence **MasterKey** (gratuite), télémétrie anonyme, carte en direct MasterMods.
- Langues : français, anglais.