Aller au contenu principal

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​

ChampTypeDéfautNotes
isEnabledbooltrueLes fichiers désactivés ne sont pas chargés ; les niveaux dépendants ne peuvent pas démarrer sans cette configuration de vagues
baseMobAmountint20Quantité par défaut utilisée lorsqu'une entrée ne spécifie pas amount=
waveEntitiesliste de chaînesrequisEntrées d'ennemis vague par vague
suddenDeathWaveEntitiesliste de chaînesoptionnelRéserve cyclique optionnelle de vagues qui s'exécute après l'épuisement des vagues configurées
prewaveMessagesliste de mapsoptionnelMessages indexés par le compteur actuel : 0 à l'entrée, N après la fin de la vague N
waveMessagesliste de mapsoptionnelMessages affichés au début d'une vague

Sans entrée de mort subite, la session se termine lorsque la transition vers la vague suivante ne trouve aucune vague configurée. Cela suit normalement la dernière fenêtre de construction, sauf si le joueur avance plus tôt.

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éTypeNotes
waveintRequis. Numéro de la vague à laquelle cette entrée appartient
entityTypeenumRequis. Valeur exacte de l'enum Bukkit EntityType ; choisissez une entité vivante pouvant apparaître
healthMultiplierdoubleOptionnel, 1.0 par défaut. Multiplie la vie maximale de l'entité
amountintOptionnel. Remplace baseMobAmount pour cette entrée
namestringOptionnel. 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)
resistflagMarque l'entité comme insensible au ralentissement
fastflagAugmente la vitesse de déplacement
treasureflagDouble la prime d'or à l'élimination
bossflagUtilise la règle de quantité des boss ci-dessous, une vie ajustée et une barre pour chaque boss
hordeflagDouble amount et divise la vie par deux
airflagL'entité apparaît 4 blocs au-dessus du chemin et ignore les murs au sol

Écrivez les clés et flags sans espaces autour, les types d'entité en majuscules et des numéros de vague, quantités et multiplicateurs de vie positifs. L'analyseur ne retire pas les espaces et ne rejette pas toutes les plages invalides. Les clés inconnues sont ignorées. Une entrée normale mal formée désactive la configuration ; une entrée de mort subite mal formée produit un avertissement et peut laisser les entrées déjà analysées dans la réserve. Une analyse réussie ne prouve pas que les entités pourront apparaître.

Calculs internes de quantité​

  • amount est incrémenté de wave / 10 puis tronqué à un nombre entier : une entrée avec amount=20 donne donc 21 créatures à la vague 15 et 22 à la vague 20.
  • Les entrées boss remplacent amount par max(1, floor(wave / 10)).
  • Les entrées horde doublent le amount final.
  • 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=20 fournit 20 indices consécutifs, et non un seul. Pour chaque indice pair i (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'indice i est ajouté. Les entrées boss ne sont jamais clonées de cette manière. Le nombre de créatures bonus vaut donc approximativement ceil(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.

L'intervalle d'apparition est de min(floor(200 / totalEntities), 20) ticks. Pour une apparition normale, le compteur doit dépasser deux fois cet intervalle ; pour le rythme de horde, il doit dépasser deux fois l'intervalle divisé par deux en entier. La comparaison stricte ajoute donc un tick de compteur à cet intervalle doublé. Le rythme de horde dépend du premier mob restant dans la liste : mélanger des entrées horde et ordinaires peut ainsi modifier le rythme au fil des apparitions. Chaque mob choisit au hasard une case de départ du niveau lorsqu'il apparaît.

Format des blocs de message​

prewaveMessages et waveMessages acceptent tous deux une liste de maps :

prewaveMessages:
- wave: 0
message:
- "&aWelcome! Build a couple of basic towers along the path."
- wave: 4
message:
- "&6Heads up: a boss is coming next wave."

prewaveMessages[0] s'exécute à l'entrée. Après la vague N, prewaveMessages[N] s'exécute pendant la construction pour la suivante : utilisez la clé 4 pour annoncer la vague 5. waveMessages[N] s'exécute au début de la vague N. Ces clés utilisent le compteur affiché de la session, y compris en mort subite. Des entrées répétées pour la même clé remplacent les précédentes.

Cycle de vie d'une vague​

Une session passe par ces états :

  • STARTING — avant que le joueur n'exécute /etd start pour 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.

Le minuteur normal de construction dure 10 secondes. /etd start ou l'outil Next Wave permettent d'avancer plus tôt, mais les exigences du tutoriel restent applicables (voir Cas particulier du niveau tutoriel). La phase initiale attend une action de démarrage ; le tutoriel peut avancer lorsque sa dernière exigence est acceptée.

Comportement de fin de vague :

  • Terminer une vague accorde waveNumber * 10 d'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.
  • Après la fin d'une vague, la chaîne des modificateurs de la suivante est annoncée si elle n'est pas vide. Elle provient du premier ennemi configuré, pas de toutes les entrées d'une vague mixte.

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 parcourt les numéros de vague configurés. Chaque fois qu'elle est nécessaire, EternalTD choisit la plus petite clé non négative supérieure à la clé actuelle de la réserve, ou revient à la plus petite s'il n'en existe aucune au-dessus. Le compteur initial vaut 0 : une clé configurée 0 est donc sautée au premier passage si des clés positives existent. Utilisez des clés positives ; les trous sont acceptés et la clé 0 ne convient pas non plus à la formule de vie ci-dessous.

Le compteur affiché continue d'augmenter. La vie, l'armure, la vitesse, la prime de base et les seuils des splitterlings utilisent le wave= configuré de l'entrée choisie ; ils ne suivent pas automatiquement le compteur affiché. Les clones supplémentaires et les tirages élémentaires utilisent ce compteur affiché. Par exemple, les entrées 10 et 20 conservent ces valeurs d'évolution même à la vague affichée 100. La recherche de la vague suivante vérifie toujours l'existence d'une entrée normale à chaque numéro affiché : une clé normale ultérieure peut donc être utilisée après un trou.

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é normale de vague apparaît, sa probabilité d'hériter de l'élément est le waveNumber / 100 affiché ; à partir de la vague affichée 100, le tirage réussit toujours. Une étiquette colorée indique l'élément. Les splitterlings sont créés séparément et ne reçoivent pas ce tirage.

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 suivent le tableau ci-dessous. Les autres combinaisons non correspondantes infligent des dégâts ×1.
  • Une tour sans affinité inflige des dégâts ×1 à tout le monde.
Affinité de la tourDégâts ×2 contreDégâts ×0,5 contre
MagmaAir, EauTerre, Feu, Magma
SouffleTerre, EauAir, Feu, Souffle
TempêteFeu, TerreAir, Eau, Tempête
BoueFeu, AirTerre, Eau, Boue

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 :

CombinaisonFusion résultante
Feu + TerreMagma
Feu + AirSouffle
Eau + AirTempête
Eau + TerreBoue

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.

Chaque recalcul part de l'élément propre de la Tour de base, Sans affinité : retirer le dernier soutien élémentaire rend donc la tour Sans affinité.

Évolution de la vie, de l'armure et du butin​

WaveEntity applique ces étapes à l'apparition avec son numéro de vague configuré (ou la moitié de celui du parent pour un splitterling), dans cet ordre :

  1. La vie de base commence à 0.5 et croît avec la vague : health = 0.5 + ((wave - 1)^1.2) / 2.
  2. Les entités boss multiplient cette valeur par baseMobAmount × 0.5.
  3. Les entités horde la divisent par deux.
  4. Le butin est calculé ici, comme ceil(health) — avant healthMultiplier et avant la pénalité aérienne. Les entrées treasure le doublent ensuite.
  5. maxHealth = health × healthMultiplier.
  6. Les entités aériennes divisent de nouveau maxHealth par deux.
  7. 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 sans modifier la prime de base, et les ennemis aériens rapportent la même prime de base que leurs équivalents terrestres malgré une vie divisée par deux. La Mine d'or ajoute son bonus au coup fatal, puis le résultat est tronqué à un entier ; les petites primes peuvent ne rapporter aucun or supplémentaire.

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 utilise la vague configurée de l'ennemi et s'ajoute après les multiplicateurs aérien et de ralentissement. Cette valeur contrôle l'attribut de vitesse de déplacement des mobs. Pour les entités qui ne sont pas des Mob, le mécanisme de remplacement téléporte de 0.1 bloc vers la prochaine destination à chaque tick de déplacement : la formule n'est donc pas une vitesse universelle en blocs par tick.

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 des SILVERFISH. Sinon, ce sont des CAVE_SPIDER.
  • Les splitterlings utilisent floor(parentWave / 2) et héritent de la position actuelle sur le trajet. Leur constructeur utilise un multiplicateur de vie de 0.5 ; ils n'héritent ni des flags ni de l'affinité élémentaire du parent. À des vagues configurées suffisamment élevées, leur mort peut produire d'autres splitterlings.
  • 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​

Le niveau tutorial.yml utilise un script codé en dur lié aux coordonnées de sa carte :

  • Les types de tours requis doivent être placés sur les cases indiquées, ou améliorés sur place si la tour correspondante existe déjà. Vendre une mauvaise tour sur une case requise est autorisé ; les autres placements, ventes et améliorations sont refusés pendant cette étape du script. La dernière exigence acceptée demande immédiatement la vague suivante.
  • Le béton coloré marque les cases requises. Si FMM et le modèle reddownarrow sont disponibles, une flèche rouge indique la tour ou l'amélioration demandée au-dessus de chaque case.
  • À l'entrée en construction après les vagues 1, 2 et 3, le tutoriel ajoute +100 d'or ; après la vague 4, il ajoute +200. C'est un revenu supplémentaire, pas une garantie de pouvoir payer. Les autres numéros de vague ne reçoivent aucun ajout.
  • 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.
  • Pendant chaque étape scriptée, une barre de boss verte compte les tours requises déjà placées, sous la forme Build towers! done/total!. Toutes les deux minutes, le tutoriel rappelle que /etd quit permet de quitter et, tant que des exigences restent à remplir, répète le message d'avant-vague en cours.

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.
  • Chaque bascule de /etd cheat, y compris sa désactivation, remet l'or à 10,000,000 et les vies à 1,000,000. La session reste définitivement exclue des meilleurs scores.
  • /etd setwave <n> modifie le compteur de session et la protection des récompenses, et marque la partie comme trichée. Il ne remplace pas les ennemis actifs et ne lance pas immédiatement cette vague. La prochaine transition utilise n + 1.

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.