extends RefCounted

# Pas de `class_name`: un nom global neuf n'existe qu'apres une passe d'editeur,
# et l'editeur de l'auteur peut etre ouvert. Les appelants preloadent ce script.

## Les effets d'entree des creatures (ligne 81 du suivi, 14/10/2026).
##
## Chaque fiche de monstre, niveau par niveau, nomme son effet d'entree
## (`entrance_effect`). Il ne joue que pour les renforts et les invocations: ce
## qui attendait a l'ouverture de la salle, ou qu'un dialogue reveille, est deja
## en place (`Enemy.ARRIVAL_*`).
##
## Pendant son entree, la creature est HORS COMBAT: ni frappable, ni ciblee, ni
## dangereuse, et elle ne bouge pas d'elle-meme. Elle compte deja dans la salle.
## C'est la fuite a l'envers. Cette table donne a la logique 2D la seule chose
## qu'elle doit savoir: combien de temps dure l'entree. Le pont 3D en tire
## l'image (`entrance_fx_3d.gd`), sans rien decider.
##
## La liste `IDS` est partagee mot pour mot avec `ENTRANCE_EFFECTS` de
## `config.php` et de `app.js` (test `entrance_effect_test.js`).

const DEFAULT := "instant"
const IDS := ["instant", "fade", "poof", "lightning", "fireball", "rift", "beam", "roll", "drop", "burrow"]

## Duree hors combat, en secondes. La roulade se mesure a sa course.
const DURATIONS := {
	"instant": 0.0,
	"fade": 0.5,
	"poof": 0.45,
	"lightning": 0.6,
	"fireball": 0.85,
	"rift": 0.95,
	"beam": 0.85,
	"roll": 0.0,
	"drop": 0.8,
	"burrow": 0.85,
}

## Un groupe qui arrive ensemble ne joue pas d'un seul bloc: chaque creature
## attend un peu, invisible, avant de commencer la sienne.
const STAGGER_MAX := 0.3

## La roulade part du bord le plus proche de l'arene, au plus `ROLL_MAX_DISTANCE`
## pixels de sa place, et roule a `ROLL_SPEED` px/s. Sa duree reste dans des
## bornes lisibles, quelle que soit la salle.
const ROLL_SPEED := 1100.0
const ROLL_MAX_DISTANCE := 900.0
const ROLL_MARGIN := 80.0
const ROLL_MIN_SECONDS := 0.45
const ROLL_MAX_SECONDS := 1.0


static func is_known(effect: Variant) -> bool:
	return effect is String and IDS.has(effect)


## L'effet tel qu'il se joue: un inconnu retombe sur l'apparition instantanee.
static func resolve(effect: Variant) -> String:
	return str(effect) if is_known(effect) else DEFAULT


static func duration(effect: String) -> float:
	return float(DURATIONS.get(effect, 0.0))
