Vagues et ennemis d'EternalTD
Un fichier de vagues sous plugins/EternalTD/waves/ définit l'ensemble du contingent ennemi pour un niveau, y compris les vagues normales, les vagues de mort subite et, éventuellement, les messages pré-vague ou de vague. Chaque configuration de niveau référence un fichier de vagues via wavesConfigFile:.
Champs de premier niveau
| Champ | Type | Défaut | Notes |
|---|---|---|---|
isEnabled | bool | true | Désactiver ici désactive également le niveau qui dépend de ce fichier |
baseMobAmount | int | 20 | Quantité par défaut utilisée lorsqu'une entrée ne spécifie pas amount= |
waveEntities | liste de chaînes | requis | Entrées d'ennemis vague par vague |
suddenDeathWaveEntities | liste de chaînes | optionnel | Réserve cyclique optionnelle de vagues qui s'exécute après l'épuisement des vagues configurées |
prewaveMessages | liste de maps | optionnel | Messages affichés avant le démarrage d'une vague spécifique |
waveMessages | liste de maps | optionnel | Messages affichés au début d'une vague |
Si le fichier de vagues ne définit aucune entrée de mort subite, le niveau se termine dès l'épuisement des vagues configurées.
Format des entrées d'entité de vague
Chaque ligne de waveEntities (ou suddenDeathWaveEntities) est une entrée séparée par des deux-points :
- wave=1:entityType=ZOMBIE:healthMultiplier=1.0:amount=10
- wave=2:entityType=SKELETON:fast:treasure
- wave=5:entityType=WITHER_SKELETON:boss
- wave=8:entityType=PHANTOM:air:horde
| Clé | Type | Notes |
|---|---|---|
wave | int | Requis. Numéro de la vague à laquelle cette entrée appartient |
entityType | enum | Requis. Valeur de l'enum Bukkit EntityType |
healthMultiplier | double | Optionnel, 1.0 par défaut. Multiplie la vie maximale de l'entité |
amount | int | Optionnel. Remplace baseMobAmount pour cette entrée |
name | string | Optionnel. Chaîne de nom personnalisée. Analysée et stockée, mais le plugin ne l'applique pas actuellement à la créature apparue (les plaques de nom sont les barres de vie/d'armure à la place) |
resist | flag | Marque l'entité comme insensible au ralentissement |
fast | flag | Augmente la vitesse de déplacement |
treasure | flag | Double la prime d'or à l'élimination |
boss | flag | Apparaît comme un boss unique avec une vie augmentée et une barre de boss |
horde | flag | Double amount et divise la vie par deux |
air | flag | L'entité apparaît 4 blocs au-dessus du chemin et ignore les murs au sol |
Calculs internes de quantité
amountest incrémenté dewave / 10puis tronqué à un nombre entier : une entrée avecamount=20donne donc 21 créatures à la vague 15 et 22 à la vague 20.- Les entrées
bossremplacentamountparmax(1, floor(wave / 10)). - Les entrées
hordedoublent leamountfinal. - En plus de la quantité par entrée, le runtime de vague ajoute des duplicatas lors de la construction de la vague. Notez que la liste qu'il indexe est la liste de créatures entièrement développée — l'analyseur de configuration a déjà émis un objet par créature, donc une seule ligne
amount=20fournit 20 indices consécutifs, et non un seul. Pour chaque indice pairi(0, 2, 4, ...) qui est à la fois un indice valide de cette liste développée et inférieur au numéro de vague, un clone supplémentaire de la créature à l'indiceiest ajouté. Les entrées boss ne sont jamais clonées de cette manière. Le nombre de créatures bonus vaut donc approximativementceil(min(waveNumber, listSize) / 2): 1 créature supplémentaire à la vague 1, 2 aux vagues 3-4, 5 aux vagues 9-10, 8 aux vagues 15-16, et ainsi de suite jusqu'à ce que le numéro de vague dépasse la taille de la liste.
La cadence d'apparition au sein d'une vague est de min(200 / totalEntities, 20) ticks, et le runtime attend le double de cette durée avant de libérer chaque créature. Les vagues horde réduisent l'écart de moitié et libèrent leurs créatures à un rythme deux fois plus rapide. Chaque créature choisit au hasard l'une des cases de départ du niveau lorsqu'elle apparaît.
Format des blocs de message
prewaveMessages et waveMessages acceptent tous deux une liste de maps :
prewaveMessages:
- wave: 1
message:
- "&aWelcome! Build a couple of basic towers along the path."
- wave: 5
message:
- "&6Heads up: a boss is coming next wave."
prewaveMessages s'exécute au début de la phase de construction de cette vague. waveMessages s'exécute à l'instant où la phase défensive commence.
Cycle de vie d'une vague
Une session passe par ces états :
STARTING— avant que le joueur n'exécute/etd startpour la première fois.CONSTRUCTION_PHASE— fenêtre de construction de 10 secondes entre les phases défensives.DEFENSIVE_PHASE— les ennemis apparaissent et parcourent le chemin.ENDING— le joueur a quitté, perdu ou le niveau a épuisé ses vagues.
La phase de construction dure toujours 10 secondes sauf si le tutoriel la maintient (voir Cas particulier du niveau tutoriel).
Comportement de fin de vague :
- Terminer une vague accorde
waveNumber * 10d'or. - Si vous n'avez perdu aucune vie pendant la vague, vous recevez un bonus « Parfait » valant la moitié du bonus de vague (
waveNumber * 10 * 0.5). Le nombre annoncé et l'or réellement accordé correspondent désormais. - Chaque vague ne peut être payée qu'une seule fois — une vague qui signalerait sa complétion deux fois est ignorée la seconde fois, et aucun paiement n'a lieu une fois la session en cours de fermeture.
- La liste des modificateurs de la vague suivante est annoncée après la fin de chaque vague.
Quand un niveau se termine
La session n'avance que si le numéro de la vague suivante existe comme clé dans waveEntities ; les numéros de vague doivent donc se suivre sans interruption à partir de 1. Lorsque le numéro suivant est absent :
- si le fichier définit
suddenDeathWaveEntities, la partie bascule en mort subite ; - sinon, le niveau se termine immédiatement, sans compter la vague qui n'a jamais été jouée. Le meilleur score enregistré et le titre de fin utilisent la dernière vague réellement jouée par le joueur.
Mort subite
Si suddenDeathWaveEntities est défini, le niveau continue de s'exécuter au-delà de la liste des vagues configurées.
La réserve de mort subite tourne par numéro de vague configuré, et non par un compteur courant : chaque fois qu'une vague de mort subite est nécessaire, EternalTD choisit le plus petit numéro wave= de la réserve qui est supérieur au numéro actuel, et revient au plus petit numéro configuré lorsqu'il n'y a rien de plus élevé. La réserve n'a donc pas besoin d'être numérotée 1, 2, 3, ... — les trous et les numéros de départ arbitraires tournent correctement.
Le numéro de vague affiché continue de croître à partir de la liste des vagues normales ; seule l'entrée de la réserve qui apparaît effectue le cycle.
Affinité élémentaire des entités de vague
Chaque vague a sa propre affinité élémentaire qui tourne d'une vague à l'autre :
- Vague 1 → Feu
- Vague 2 → Air
- Vague 3 → Eau
- Vague 4 → Terre
- (puis répète)
Lorsqu'une entité de vague apparaît, il y a une chance de waveNumber / 100 que l'entité hérite de l'affinité élémentaire de la vague, affichée sous forme d'étiquette colorée flottant au-dessus de la créature.
Les règles de dégâts élémentaires sont gérées par la classe DamageTower de la tour :
- Même affinité attaquant contre même affinité cible — dégâts ×0,5 (résistance).
- Éléments simples opposés (Feu contre Eau, Air contre Terre) — dégâts ×2 (critique).
- Les affinités de fusion (Magma, Souffle, Tempête, Boue) suivent des interactions appariées ; consultez le code source pour la matrice complète.
- Une tour sans affinité inflige des dégâts ×1 à tout le monde.
Les affinités de fusion se forment lorsqu'une Tour de base est touchée par des tours de soutien aux affinités élémentaires combinables :
| Combinaison | Fusion résultante |
|---|---|
| Feu + Terre | Magma |
| Feu + Air | Souffle |
| Eau + Air | Tempête |
| Eau + Terre | Boue |
Les règles de conflit sont plus étroites qu'il n'y paraît :
- Terre + Air sur la même tour la ramène toujours à l'état Sans affinité, quoi qu'il soit attaché par ailleurs.
- Feu + Eau ne ramène à Sans affinité que lorsque trois affinités distinctes ou plus sont en jeu. Une tour touchée par exactement un soutien Feu et un soutien Eau conserve arbitrairement l'une des deux, car le code retombe sur « prendre la première affinité de l'ensemble » et cet ensemble n'est pas ordonné.
- Les tours de soutien sans affinité (Tour à longue-vue, Mine d'or) n'influencent jamais le résultat ; elles sont retirées de l'ensemble dès qu'une tour avec affinité est attachée.
Mise à l'échelle de la vie, de l'armure et du butin
WaveEntity applique ces étapes à l'apparition, dans cet ordre exact :
- La vie de base commence à
0.5et croît avec la vague :health = 0.5 + ((wave - 1)^1.2) / 2. - Les entités boss multiplient cette valeur par
baseMobAmount × 0.5. - Les entités horde la divisent par deux.
- Le butin est calculé ici, comme
ceil(health)— avanthealthMultiplieret avant la pénalité aérienne. Les entréestreasurele doublent ensuite. maxHealth = health × healthMultiplier.- Les entités aériennes divisent de nouveau
maxHealthpar deux. - L'armure n'apparaît qu'à partir de la vague 10, fixée à
maxHealth / 80.
L'ordre de l'étape 4 est important : un healthMultiplier de 3.0 triple la vie d'un ennemi sans changer son gain en or, et les ennemis aériens rapportent le même butin que leurs équivalents terrestres malgré une vie divisée par deux. Les tours de soutien Mine d'or ajoutent leur bonus au butin au moment du coup fatal.
La vitesse de déplacement est :
speed = 0.3 × (1 - slow)
× 1.5 × (1 - slow) if fast
× 0.5 if air
+ wave / 1000
Le terme final wave / 1000 signifie que les ennemis deviennent très légèrement plus rapides à chaque vague quels que soient leurs flags, et il est appliqué après les multiplicateurs aérien et de ralentissement plutôt que d'être mis à l'échelle par eux.
Engeance scindée (Splitterlings)
À partir de la vague 20, les ennemis non aériens font apparaître à la mort de petites créatures supplémentaires (« splitterlings »).
- Nombre :
floor(wave / 20)par élimination. - Si le parent était un
CAVE_SPIDER, les splitterlings sont desSILVERFISH. Sinon, ce sont desCAVE_SPIDER. - Les splitterlings apparaissent à
wave / 2de la vague du parent, donc une partie suffisamment avancée peut encore enchaîner un splitterling en d'autres splitterlings lors de sa propre mort. - Les splitterlings ne donnent aucun or à la mort et les ennemis aériens ne font jamais apparaître de splitterlings.
Cas particulier du niveau tutoriel
La carte du tutoriel fournie s'exécute via un script de vague tutoriel codé en dur :
- La phase de construction ne se termine pas automatiquement tant que vous n'avez pas placé les tours exactes requises sur les cases mises en évidence.
- Les tours codées en dur sont indiquées par des plaques de béton coloré sous la case ciblée et, si FMM est installé, par un modèle de flèche rouge pointant vers le bas flottant au-dessus.
- Le tutoriel injecte de l'or supplémentaire lors des premières vagues afin que la composition de tours scriptée reste toujours abordable :
+100aux vagues 1, 2 et 3, et+200à la vague 4. Les vagues suivantes ne reçoivent rien de plus. - Chaque case de tour requise est colorée selon la tour qu'elle attend : béton vert pour la Tour de base, marron pour la Barricade, blanc pour la Tour de sucre, cyan pour la Tour à longue-vue, jaune pour le Générateur de faisceau, rouge pour l'Usine d'explosion, bleu pour la Boîte de glace, gris pour le Broyeur d'armure, orange pour la Mine d'or, violet pour la Carrière d'obsidienne, noir pour tout le reste.
Vies et or du joueur
- Vies de départ : 20.
- Or de départ : 150.
- Les boss coûtent 5 vies s'ils atteignent la sortie. Toutes les autres créatures coûtent 1 vie.
- La triche (
/etd cheat) règle l'or sur10 000 000et les vies sur1 000 000, et marque la session comme trichée pour les besoins du meilleur score. Désactiver de nouveau le mode triche ne restaure pas les valeurs d'origine, et l'indicateur de triche est permanent pour cette session. /etd setwave <n>active également l'indicateur de triche, et rebase la protection de récompense de vague afin que la vague vers laquelle vous sautez rapporte quand même à sa complétion.
Suivi des meilleurs scores
Chaque configuration de niveau conserve highscoreWave et highscorePlayerName. À la fin d'une session sans triche, le plugin enregistre le nouveau numéro de vague dans le fichier de niveau et diffuse un message à l'échelle du serveur s'il a battu le score précédent.